feat: add overview workspace

This commit is contained in:
DreamMaoMao 2025-06-19 10:14:29 +08:00
parent 5849b6eaff
commit fcd1a49934
2 changed files with 65 additions and 3 deletions

View file

@ -58,10 +58,12 @@ static void handle_ext_workspace_activate(struct wl_listener *listener,
wlr_log(WLR_INFO, "ext activating workspace %s", workspace->name); wlr_log(WLR_INFO, "ext activating workspace %s", workspace->name);
} }
/* Internal API */ static char *get_name_from_tag(unsigned int tag) {
static void add_workspace(int tag, Monitor *m) {
char *name = NULL; char *name = NULL;
switch (tag) { switch (tag) {
case 0:
name = "overview";
break;
case 1: case 1:
name = "1"; name = "1";
break; break;
@ -90,6 +92,53 @@ static void add_workspace(int tag, Monitor *m) {
name = "9"; name = "9";
break; break;
} }
return name;
}
static void remove_workspace(unsigned int tag, Monitor *m) {
char *name = get_name_from_tag(tag);
struct workspace *workspace, *tmp;
wl_list_for_each_safe(workspace, tmp, &workspaces, link) {
if (strcmp(workspace->name, name) == 0 && workspace->m == m) {
// If this is the current workspace, we need to handle that
if (m->workspace_current == workspace) {
// Find another workspace to make current (maybe the overview?)
struct workspace *new_current = NULL;
if (!wl_list_empty(&workspaces)) {
struct workspace *first =
wl_container_of(workspaces.next, first, link);
if (first != workspace) {
new_current = first;
} else if (workspaces.next->next != &workspaces) {
new_current = wl_container_of(workspaces.next->next,
new_current, link);
}
}
m->workspace_current = new_current;
if (new_current) {
wlr_scene_node_set_enabled(&new_current->tree->node, true);
dwl_ext_workspace_set_active(new_current->ext_workspace,
true);
}
}
// Clean up external workspace
wl_list_remove(&workspace->on_ext.activate.link);
dwl_ext_workspace_destroy(workspace->ext_workspace);
// Remove from the list and free resources
wl_list_remove(&workspace->link);
wlr_scene_node_destroy(&workspace->tree->node);
free(workspace->name);
free(workspace);
return;
}
}
}
/* Internal API */
static void add_workspace(int tag, Monitor *m) {
char *name = get_name_from_tag(tag);
struct workspace *workspace = znew(*workspace); struct workspace *workspace = znew(*workspace);
workspace->name = xstrdup(name); workspace->name = xstrdup(name);
workspace->tag = tag; workspace->tag = tag;

View file

@ -5111,7 +5111,7 @@ void dwl_ext_workspace_printstatus(Monitor *m) {
wl_list_for_each(w, &workspaces, link) { wl_list_for_each(w, &workspaces, link) {
if (w && w->m == m) { if (w && w->m == m) {
is_active = (w->tag == current_tag) && !m->isoverview; is_active = (w->tag == current_tag) || m->isoverview;
has_clients = tag_has_clients(w->tag); has_clients = tag_has_clients(w->tag);
if (is_active) { if (is_active) {
dwl_ext_workspace_set_hidden(w->ext_workspace, false); dwl_ext_workspace_set_hidden(w->ext_workspace, false);
@ -7037,6 +7037,7 @@ void increase_proportion(const Arg *arg) {
void toggleoverview(const Arg *arg) { void toggleoverview(const Arg *arg) {
Client *c; Client *c;
int i;
if (selmon->isoverview && ov_tab_mode && arg->i != -1 && selmon->sel) { if (selmon->isoverview && ov_tab_mode && arg->i != -1 && selmon->sel) {
focusstack(&(Arg){.i = 1}); focusstack(&(Arg){.i = 1});
@ -7086,6 +7087,18 @@ void toggleoverview(const Arg *arg) {
} }
} }
if (selmon->isoverview) {
for (i = 1; i <= LENGTH(tags); i++) {
remove_workspace(i, selmon);
}
add_workspace(0, selmon);
} else {
remove_workspace(0, selmon);
for (i = 1; i <= LENGTH(tags); i++) {
add_workspace(i, selmon);
}
}
view(&(Arg){.ui = target}, false); view(&(Arg){.ui = target}, false);
if (ov_tab_mode && selmon->isoverview && selmon->sel) { if (ov_tab_mode && selmon->isoverview && selmon->sel) {