##// END OF EJS Templates
test
Tsuki -
r4:49359be7c342 default
parent child Browse files
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