Mercurial > myrepo
view include/ext-workspace.h @ 1:50bab568625d default tip
lol
| author | tsukasa <qwerasdnoob@gmail.com> |
|---|---|
| date | Sat, 11 Jul 2026 17:56:41 +0800 |
| parents | |
| children |
line wrap: on
line source
/* My shitty port of Mango's ext-workspace.h for my compositor; * thanks DreamMaoMao for doing most of the heavy lifting * by actually writing the thing, it didn't work the first * few tries and I barely have any idea how this code works anyway. * To say that it's the eighth wonder of the world * would be an understatement */ #include "wlr_ext_workspace_v1.h" #define EXT_WORKSPACE_CAPS \ (EXT_WORKSPACE_HANDLE_V1_WORKSPACE_CAPABILITIES_ACTIVATE | \ EXT_WORKSPACE_HANDLE_V1_WORKSPACE_CAPABILITIES_DEACTIVATE) /* types */ struct ext_workspace { struct wl_list link; uint32_t tag; Monitor *m; struct wlr_ext_workspace_handle_v1 *handle; }; /* global */ static struct wlr_ext_workspace_manager_v1 *ext_workspace_manager; static struct wl_list ext_workspaces; static struct wl_listener ext_commit_listener; static struct wl_listener ext_destroy_listener; /* helpers */ static int get_tag_status(uint32_t tag, Monitor *m) { Client *c; uint32_t mask = 1 << (tag - 1); wl_list_for_each(c, &clients, link) { if (c->mon != m) continue; if (!(c->tags & mask)) continue; if (c->isurgent) return 2; return 1; } return 0; } static const char * tag_name(uint32_t tag) { static const char *names[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", }; if (tag >= 1 && tag <= LENGTH(names)) return names[tag - 1]; return "?"; } /* workspace lifecycle */ static void ext_workspace_destroy(struct ext_workspace *ws) { wlr_ext_workspace_handle_v1_destroy(ws->handle); wl_list_remove(&ws->link); free(ws); } static void ext_workspace_create(uint32_t tag, Monitor *m) { const char *name = tag_name(tag); struct ext_workspace *ws = ecalloc(1, sizeof(*ws)); ws->tag = tag; ws->m = m; ws->handle = wlr_ext_workspace_handle_v1_create( ext_workspace_manager, name, EXT_WORKSPACE_CAPS); ws->handle->data = ws; wlr_ext_workspace_handle_v1_set_group(ws->handle, m->ext_group); wlr_ext_workspace_handle_v1_set_name(ws->handle, name); wl_list_insert(ext_workspaces.prev, &ws->link); } /* monitor integration */ static void ext_workspace_createmon(Monitor *m) { uint32_t i; m->ext_group = wlr_ext_workspace_group_handle_v1_create( ext_workspace_manager, 0); wlr_ext_workspace_group_handle_v1_output_enter( m->ext_group, m->wlr_output); for (i = 1; i <= TAGCOUNT; i++) ext_workspace_create(i, m); } static void ext_workspace_cleanupmon(Monitor *m) { struct ext_workspace *ws, *tmp; wl_list_for_each_safe(ws, tmp, &ext_workspaces, link) if (ws->m == m) ext_workspace_destroy(ws); wlr_ext_workspace_group_handle_v1_output_leave( m->ext_group, m->wlr_output); wlr_ext_workspace_group_handle_v1_destroy(m->ext_group); m->ext_group = NULL; } /* status */ static void ext_workspace_printstatus(Monitor *m) { struct ext_workspace *ws; wl_list_for_each(ws, &ext_workspaces, link) { if (ws->m != m) continue; int status = get_tag_status(ws->tag, m); int active = !!(m->tagset[m->seltags] & (1 << (ws->tag - 1)) & TAGMASK); wlr_ext_workspace_handle_v1_set_urgent(ws->handle, status == 2); wlr_ext_workspace_handle_v1_set_hidden(ws->handle, 0); wlr_ext_workspace_handle_v1_set_active(ws->handle, active); } } /* commit handler */ static void handle_ext_commit(struct wl_listener *listener, void *data) { struct wlr_ext_workspace_v1_commit_event *event = data; struct wlr_ext_workspace_v1_request *req; wl_list_for_each(req, event->requests, link) { struct ext_workspace *ws = NULL; struct ext_workspace *w; switch (req->type) { case WLR_EXT_WORKSPACE_V1_REQUEST_ACTIVATE: if (!req->activate.workspace) break; wl_list_for_each(w, &ext_workspaces, link) { if (w->handle == req->activate.workspace) { ws = w; break; } } if (!ws) break; view(&(Arg){.ui = 1 << (ws->tag - 1)}); break; case WLR_EXT_WORKSPACE_V1_REQUEST_DEACTIVATE: if (!req->deactivate.workspace) break; wl_list_for_each(w, &ext_workspaces, link) { if (w->handle == req->deactivate.workspace) { ws = w; break; } } if (!ws) break; toggleview(&(Arg){.ui = 1 << (ws->tag - 1)}); break; default: break; } } } /* init */ static void handle_ext_destroy(struct wl_listener *listener, void *data) { wl_list_remove(&ext_commit_listener.link); wl_list_remove(&ext_destroy_listener.link); } static void workspaces_init(void) { ext_workspace_manager = wlr_ext_workspace_manager_v1_create(dpy, 1); wl_list_init(&ext_workspaces); ext_commit_listener.notify = handle_ext_commit; wl_signal_add(&ext_workspace_manager->events.commit, &ext_commit_listener); ext_destroy_listener.notify = handle_ext_destroy; wl_signal_add(&ext_workspace_manager->events.destroy, &ext_destroy_listener); }
