Show More
| @@ -1,210 +1,209 | |||
|
|
1 | 1 | /* My shitty port of Mango's ext-workspace.h for my compositor; |
|
|
2 | 2 | * thanks DreamMaoMao for doing most of the heavy lifting |
|
|
3 | 3 | * by actually writing the thing, it didn't work the first |
|
|
4 | 4 | * few tries and I barely have any idea how this code works anyway. |
|
|
5 | 5 | * To say that it's the eighth wonder of the world |
|
|
6 | 6 | * would be an understatement |
|
|
7 | 7 | */ |
|
|
8 | 8 | |
|
|
9 | 9 | #include "wlr_ext_workspace_v1.h" |
|
|
10 | 10 | |
|
|
11 | 11 | #define EXT_WORKSPACE_CAPS \ |
|
|
12 | 12 | (EXT_WORKSPACE_HANDLE_V1_WORKSPACE_CAPABILITIES_ACTIVATE | \ |
|
|
13 | 13 | EXT_WORKSPACE_HANDLE_V1_WORKSPACE_CAPABILITIES_DEACTIVATE) |
|
|
14 | 14 | |
|
|
15 | 15 | /* types */ |
|
|
16 | 16 | |
|
|
17 | 17 | struct ext_workspace { |
|
|
18 | 18 | struct wl_list link; |
|
|
19 | 19 | uint32_t tag; |
|
|
20 | 20 | Monitor *m; |
|
|
21 | 21 | struct wlr_ext_workspace_handle_v1 *handle; |
|
|
22 | 22 | }; |
|
|
23 | 23 | |
|
|
24 | 24 | /* global */ |
|
|
25 | 25 | |
|
|
26 | 26 | static struct wlr_ext_workspace_manager_v1 *ext_workspace_manager; |
|
|
27 | 27 | static struct wl_list ext_workspaces; |
|
|
28 | 28 | static struct wl_listener ext_commit_listener; |
|
|
29 | 29 | static struct wl_listener ext_destroy_listener; |
|
|
30 | 30 | |
|
|
31 | 31 | /* helpers */ |
|
|
32 | 32 | |
|
|
33 | 33 | |
|
|
34 | 34 | static int |
|
|
35 | 35 | get_tag_status(uint32_t tag, Monitor *m) |
|
|
36 | 36 | { |
|
|
37 | 37 | Client *c; |
|
|
38 | 38 | uint32_t mask = 1 << (tag - 1); |
|
|
39 | 39 | |
|
|
40 | 40 | wl_list_for_each(c, &clients, link) { |
|
|
41 | 41 | if (c->mon != m) |
|
|
42 | 42 | continue; |
|
|
43 | 43 | if (!(c->tags & mask)) |
|
|
44 | 44 | continue; |
|
|
45 | 45 | if (c->isurgent) |
|
|
46 | 46 | return 2; |
|
|
47 | 47 | return 1; |
|
|
48 | 48 | } |
|
|
49 | 49 | return 0; |
|
|
50 | 50 | } |
|
|
51 | 51 | |
|
|
52 | 52 | static const char * |
|
|
53 | 53 | tag_name(uint32_t tag) |
|
|
54 | 54 | { |
|
|
55 | 55 | static const char *names[] = { |
|
|
56 | 56 | "1", "2", "3", "4", "5", "6", "7", "8", "9", |
|
|
57 | 57 | }; |
|
|
58 | 58 | if (tag >= 1 && tag <= LENGTH(names)) |
|
|
59 | 59 | return names[tag - 1]; |
|
|
60 | 60 | return "?"; |
|
|
61 | 61 | } |
|
|
62 | 62 | |
|
|
63 | 63 | /* workspace lifecycle */ |
|
|
64 | 64 | |
|
|
65 | 65 | static void |
|
|
66 | 66 | ext_workspace_destroy(struct ext_workspace *ws) |
|
|
67 | 67 | { |
|
|
68 | 68 | wlr_ext_workspace_handle_v1_destroy(ws->handle); |
|
|
69 | 69 | wl_list_remove(&ws->link); |
|
|
70 | 70 | free(ws); |
|
|
71 | 71 | } |
|
|
72 | 72 | |
|
|
73 | 73 | static void |
|
|
74 | 74 | ext_workspace_create(uint32_t tag, Monitor *m) |
|
|
75 | 75 | { |
|
|
76 | 76 | const char *name = tag_name(tag); |
|
|
77 | ||
|
|
78 | 77 | struct ext_workspace *ws = ecalloc(1, sizeof(*ws)); |
|
|
79 | 78 | ws->tag = tag; |
|
|
80 | 79 | ws->m = m; |
|
|
81 | 80 | ws->handle = wlr_ext_workspace_handle_v1_create( |
|
|
82 | 81 | ext_workspace_manager, name, EXT_WORKSPACE_CAPS); |
|
|
83 | 82 | ws->handle->data = ws; |
|
|
84 | 83 | |
|
|
85 | 84 | wlr_ext_workspace_handle_v1_set_group(ws->handle, m->ext_group); |
|
|
86 | 85 | wlr_ext_workspace_handle_v1_set_name(ws->handle, name); |
|
|
87 | 86 | |
|
|
88 | 87 | wl_list_insert(ext_workspaces.prev, &ws->link); |
|
|
89 | 88 | } |
|
|
90 | 89 | |
|
|
91 | 90 | /* monitor integration */ |
|
|
92 | 91 | |
|
|
93 | 92 | static void |
|
|
94 | 93 | ext_workspace_createmon(Monitor *m) |
|
|
95 | 94 | { |
|
|
96 | 95 | uint32_t i; |
|
|
97 | 96 | |
|
|
98 | 97 | m->ext_group = wlr_ext_workspace_group_handle_v1_create( |
|
|
99 | 98 | ext_workspace_manager, 0); |
|
|
100 | 99 | wlr_ext_workspace_group_handle_v1_output_enter( |
|
|
101 | 100 | m->ext_group, m->wlr_output); |
|
|
102 | 101 | |
|
|
103 | 102 | for (i = 1; i <= TAGCOUNT; i++) |
|
|
104 | 103 | ext_workspace_create(i, m); |
|
|
105 | 104 | } |
|
|
106 | 105 | |
|
|
107 | 106 | static void |
|
|
108 | 107 | ext_workspace_cleanupmon(Monitor *m) |
|
|
109 | 108 | { |
|
|
110 | 109 | struct ext_workspace *ws, *tmp; |
|
|
111 | 110 | wl_list_for_each_safe(ws, tmp, &ext_workspaces, link) |
|
|
112 | 111 | if (ws->m == m) |
|
|
113 | 112 | ext_workspace_destroy(ws); |
|
|
114 | 113 | |
|
|
115 | 114 | wlr_ext_workspace_group_handle_v1_output_leave( |
|
|
116 | 115 | m->ext_group, m->wlr_output); |
|
|
117 | 116 | wlr_ext_workspace_group_handle_v1_destroy(m->ext_group); |
|
|
118 | 117 | m->ext_group = NULL; |
|
|
119 | 118 | } |
|
|
120 | 119 | |
|
|
121 | 120 | /* status */ |
|
|
122 | 121 | |
|
|
123 | 122 | static void |
|
|
124 | 123 | ext_workspace_printstatus(Monitor *m) |
|
|
125 | 124 | { |
|
|
126 | 125 | struct ext_workspace *ws; |
|
|
127 | 126 | |
|
|
128 | 127 | wl_list_for_each(ws, &ext_workspaces, link) { |
|
|
129 | 128 | if (ws->m != m) |
|
|
130 | 129 | continue; |
|
|
131 | 130 | |
|
|
132 | 131 | int status = get_tag_status(ws->tag, m); |
|
|
133 | 132 | int active = !!(m->tagset[m->seltags] & (1 << (ws->tag - 1)) & TAGMASK); |
|
|
134 | 133 | |
|
|
135 | 134 | wlr_ext_workspace_handle_v1_set_urgent(ws->handle, status == 2); |
|
|
136 | 135 | wlr_ext_workspace_handle_v1_set_hidden(ws->handle, 0); |
|
|
137 | 136 | wlr_ext_workspace_handle_v1_set_active(ws->handle, active); |
|
|
138 | 137 | } |
|
|
139 | 138 | } |
|
|
140 | 139 | |
|
|
141 | 140 | /* commit handler */ |
|
|
142 | 141 | |
|
|
143 | 142 | static void |
|
|
144 | 143 | handle_ext_commit(struct wl_listener *listener, void *data) |
|
|
145 | 144 | { |
|
|
146 | 145 | struct wlr_ext_workspace_v1_commit_event *event = data; |
|
|
147 | 146 | struct wlr_ext_workspace_v1_request *req; |
|
|
148 | 147 | |
|
|
149 | 148 | wl_list_for_each(req, event->requests, link) { |
|
|
150 | 149 | struct ext_workspace *ws = NULL; |
|
|
151 | 150 | struct ext_workspace *w; |
|
|
152 | 151 | |
|
|
153 | 152 | switch (req->type) { |
|
|
154 | 153 | case WLR_EXT_WORKSPACE_V1_REQUEST_ACTIVATE: |
|
|
155 | 154 | if (!req->activate.workspace) |
|
|
156 | 155 | break; |
|
|
157 | 156 | wl_list_for_each(w, &ext_workspaces, link) { |
|
|
158 | 157 | if (w->handle == req->activate.workspace) { |
|
|
159 | 158 | ws = w; |
|
|
160 | 159 | break; |
|
|
161 | 160 | } |
|
|
162 | 161 | } |
|
|
163 | 162 | if (!ws) |
|
|
164 | 163 | break; |
|
|
165 | 164 | view(&(Arg){.ui = 1 << (ws->tag - 1)}); |
|
|
166 | 165 | break; |
|
|
167 | 166 | |
|
|
168 | 167 | case WLR_EXT_WORKSPACE_V1_REQUEST_DEACTIVATE: |
|
|
169 | 168 | if (!req->deactivate.workspace) |
|
|
170 | 169 | break; |
|
|
171 | 170 | wl_list_for_each(w, &ext_workspaces, link) { |
|
|
172 | 171 | if (w->handle == req->deactivate.workspace) { |
|
|
173 | 172 | ws = w; |
|
|
174 | 173 | break; |
|
|
175 | 174 | } |
|
|
176 | 175 | } |
|
|
177 | 176 | if (!ws) |
|
|
178 | 177 | break; |
|
|
179 | 178 | toggleview(&(Arg){.ui = 1 << (ws->tag - 1)}); |
|
|
180 | 179 | break; |
|
|
181 | 180 | |
|
|
182 | 181 | default: |
|
|
183 | 182 | break; |
|
|
184 | 183 | } |
|
|
185 | 184 | } |
|
|
186 | 185 | } |
|
|
187 | 186 | |
|
|
188 | 187 | /* init */ |
|
|
189 | 188 | |
|
|
190 | 189 | static void |
|
|
191 | 190 | handle_ext_destroy(struct wl_listener *listener, void *data) |
|
|
192 | 191 | { |
|
|
193 | 192 | wl_list_remove(&ext_commit_listener.link); |
|
|
194 | 193 | wl_list_remove(&ext_destroy_listener.link); |
|
|
195 | 194 | } |
|
|
196 | 195 | |
|
|
197 | 196 | static void |
|
|
198 | 197 | workspaces_init(void) |
|
|
199 | 198 | { |
|
|
200 | 199 | ext_workspace_manager = wlr_ext_workspace_manager_v1_create(dpy, 1); |
|
|
201 | 200 | wl_list_init(&ext_workspaces); |
|
|
202 | 201 | |
|
|
203 | 202 | ext_commit_listener.notify = handle_ext_commit; |
|
|
204 | 203 | wl_signal_add(&ext_workspace_manager->events.commit, |
|
|
205 | 204 | &ext_commit_listener); |
|
|
206 | 205 | |
|
|
207 | 206 | ext_destroy_listener.notify = handle_ext_destroy; |
|
|
208 | 207 | wl_signal_add(&ext_workspace_manager->events.destroy, |
|
|
209 | 208 | &ext_destroy_listener); |
|
|
210 | 209 | } |
General Comments 0
You need to be logged in to leave comments.
Login now
