From 431656f3a5f07004f996c368602df825688b6d80 Mon Sep 17 00:00:00 2001 From: speckitor Date: Mon, 11 May 2026 12:46:20 +0700 Subject: [PATCH] workspaces --- include/config.h | 7 ++++- include/focus.h | 1 + include/keybinds.h | 1 + src/absinthe.c | 1 + src/focus.c | 66 ++++++++++------------------------------------ src/keybinds.c | 54 +++++++++++++++++++++++++++++++++---- src/layout.c | 7 ++--- src/server.c | 1 + 8 files changed, 75 insertions(+), 63 deletions(-) diff --git a/include/config.h b/include/config.h index 3f4154a..8980335 100644 --- a/include/config.h +++ b/include/config.h @@ -50,7 +50,12 @@ static const absn_keybind keybinds[] = { { ALT, XKB_KEY_3, switch_workspace, { .v = "3" } }, { ALT, XKB_KEY_4, switch_workspace, { .v = "4" } }, { ALT, XKB_KEY_5, switch_workspace, { .v = "5" } }, - { ALT, XKB_KEY_E, quit, { 0 } }, + { ALT | SHIFT, XKB_KEY_exclam, focus_move_to_workspace, { .v = "1" } }, + { ALT | SHIFT, XKB_KEY_2, focus_move_to_workspace, { .v = "2" } }, + { ALT | SHIFT, XKB_KEY_3, focus_move_to_workspace, { .v = "3" } }, + { ALT | SHIFT, XKB_KEY_4, focus_move_to_workspace, { .v = "4" } }, + { ALT | SHIFT, XKB_KEY_5, focus_move_to_workspace, { .v = "5" } }, + { ALT, XKB_KEY_Escape, quit, { 0 } }, }; #endif diff --git a/include/focus.h b/include/focus.h index 1abf77a..c96804e 100644 --- a/include/focus.h +++ b/include/focus.h @@ -3,6 +3,7 @@ #include "types.h" +void unfocus_toplevel(absn_toplevel *toplevel); void focus_toplevel(absn_toplevel *toplevel); absn_toplevel *focus_get_topmost(absn_server *server); diff --git a/include/keybinds.h b/include/keybinds.h index 0ded31b..be959b8 100644 --- a/include/keybinds.h +++ b/include/keybinds.h @@ -13,6 +13,7 @@ void increase_master_width(absn_server *server, const absn_arg *arg); void increase_master_count(absn_server *server, const absn_arg *arg); void switch_workspace(absn_server *server, const absn_arg *arg); +void focus_move_to_workspace(absn_server *server, const absn_arg *arg); void quit(absn_server *server, const absn_arg *arg); diff --git a/src/absinthe.c b/src/absinthe.c index d398e1c..c229fe4 100644 --- a/src/absinthe.c +++ b/src/absinthe.c @@ -159,6 +159,7 @@ setup(absn_server *server) server->workspaces[i].name = workspaces[i]; server->workspaces[i].count = STACK_COUNT; server->workspaces[i].size = STACK_SIZE; + server->workspaces[i].output = NULL; } unsetenv("DISPLAY"); diff --git a/src/focus.c b/src/focus.c index cf2910d..4737919 100644 --- a/src/focus.c +++ b/src/focus.c @@ -6,6 +6,17 @@ #include "toplevel.h" #include "types.h" +void +unfocus_toplevel(absn_toplevel *toplevel) +{ + if (!toplevel) + return; + + if (toplevel->type == TOPLEVEL_XDG) + wlr_xdg_toplevel_set_activated(toplevel->xdg, false); + toplevel_set_border_color(toplevel, unfocused_bc); +} + void focus_toplevel(absn_toplevel *toplevel) { @@ -26,23 +37,8 @@ focus_toplevel(absn_toplevel *toplevel) if (surface == prev_surface) return; - if (prev_surface) { - struct wlr_xdg_toplevel *prev_toplevel = - wlr_xdg_toplevel_try_from_wlr_surface(prev_surface); - if (prev_toplevel) { - wlr_xdg_toplevel_set_activated(prev_toplevel, false); - toplevel_set_border_color(prev_toplevel->base->data, - unfocused_bc); - } - -#ifdef XWAYLAND - struct wlr_xwayland_surface *prev_xwayland_surface = - wlr_xwayland_surface_try_from_wlr_surface(prev_surface); - if (prev_xwayland_surface) - toplevel_set_border_color(prev_xwayland_surface->data, - unfocused_bc); -#endif - } + if (prev_surface) + unfocus_toplevel(prev_surface->data); toplevel->server->focused_toplevel = toplevel; @@ -70,42 +66,8 @@ focus_get_topmost(absn_server *server) absn_toplevel *toplevel; wl_list_for_each(toplevel, &server->focus_stack, flink) { - if (toplevel) + if (toplevel && toplevel->workspace == server->focused_output->workspace) return toplevel; } return NULL; } - -void -focus_next(absn_server *server) -{ - absn_toplevel *toplevel = focus_get_topmost(server); - if (!toplevel) - return; - - absn_toplevel *next; - wl_list_for_each(next, &toplevel->link, link) - { - if (&next->link == &toplevel->server->toplevels) - continue; - break; - } - focus_toplevel(next); -} - -void -focus_prev(absn_server *server) -{ - absn_toplevel *toplevel = focus_get_topmost(server); - if (!toplevel) - return; - - absn_toplevel *prev; - wl_list_for_each_reverse(prev, &toplevel->link, link) - { - if (&prev->link == &toplevel->server->toplevels) - continue; - break; - } - focus_toplevel(prev); -} diff --git a/src/keybinds.c b/src/keybinds.c index be199bf..7d3f090 100644 --- a/src/keybinds.c +++ b/src/keybinds.c @@ -50,14 +50,16 @@ cycle_focus(absn_server *server, const absn_arg *arg) { if (&new_focus->link == &toplevel->server->toplevels) continue; - break; + if (toplevel->workspace == new_focus->workspace) + break; } } else { wl_list_for_each_reverse(new_focus, &toplevel->link, link) { if (&new_focus->link == &toplevel->server->toplevels) continue; - break; + if (toplevel->workspace == new_focus->workspace) + break; } } focus_toplevel(new_focus); @@ -79,8 +81,7 @@ increase_master_width(absn_server *server, const absn_arg *arg) { absn_workspace *workspace = server->focused_output->workspace; - if (workspace->size + arg->f >= 1.0 || - workspace->size + arg->f <= 0.0) + if (workspace->size + arg->f >= 1.0 || workspace->size + arg->f <= 0.0) return; workspace->size += arg->f; @@ -137,10 +138,53 @@ switch_workspace(absn_server *server, const absn_arg *arg) } } - focus_toplevel(focus); + unfocus_toplevel(server->focused_toplevel); + if (focus) { + /* crazy way to make it focus client if it was focused before */ + struct wlr_surface *surface; +#ifdef XWAYLAND + if (focus->type == TOPLEVEL_X11) + surface = focus->xw->surface; + else +#endif + surface = focus->xdg->base->surface; + + if (surface == server->seat->keyboard_state.focused_surface) + server->seat->keyboard_state.focused_surface = NULL; + + focus_toplevel(focus); + } + layout_arrange(server->focused_output); } +void +focus_move_to_workspace(absn_server *server, const absn_arg *arg) +{ + if (!server->focused_toplevel) + return; + + int i; + for (i = 0; i < server->workspaces_count; ++i) { + if (arg->v == server->workspaces[i].name) + break; /* found it */ + } + + if (&server->workspaces[i] == server->focused_toplevel->workspace) + return; + + if (!server->workspaces[i].output) + server->workspaces[i].output = server->focused_output; + server->focused_toplevel->output = server->workspaces[i].output; + + server->focused_toplevel->workspace = &server->workspaces[i]; + + focus_toplevel(focus_get_topmost(server)); + + layout_arrange(server->focused_output); + layout_arrange(server->focused_toplevel->output); +} + noreturn void quit(absn_server *server, const absn_arg *arg) { diff --git a/src/layout.c b/src/layout.c index d5fa83a..2e9e190 100644 --- a/src/layout.c +++ b/src/layout.c @@ -57,11 +57,8 @@ layout_arrange(struct absn_output *output) int32_t main_stack_width = (toplevels_count <= mcount) ? output->geom.width - 2 * og : msize * (output->geom.width - 2 * og); - int32_t w = output->geom.width - main_stack_width - 2 * og - lg; - wlr_log(WLR_ERROR, "%d, %d", main_stack_width, w); - int32_t pure_h; int32_t h; int32_t cur_h; @@ -100,8 +97,8 @@ layout_arrange(struct absn_output *output) wl_list_for_each(toplevel, &output->server->toplevels, link) { - if (toplevel->workspace != output->workspace || toplevel->floating || - toplevel->fullscreen) + if (toplevel->workspace != output->workspace || + toplevel->floating || toplevel->fullscreen) continue; if (i < mcount) { diff --git a/src/server.c b/src/server.c index 2942305..8e13a2b 100644 --- a/src/server.c +++ b/src/server.c @@ -86,6 +86,7 @@ new_xdg_toplevel(struct wl_listener *listener, void *data) toplevel->server = server; toplevel->xdg = xdg_toplevel; toplevel->xdg->base->data = toplevel; + toplevel->xdg->base->surface->data = toplevel; wlr_surface_set_preferred_buffer_scale(toplevel->xdg->base->surface, 1);