From 0bb721e52b8f0603bf5480c6e00d6f4afb28342b Mon Sep 17 00:00:00 2001 From: speckitor Date: Tue, 12 May 2026 12:55:22 +0700 Subject: [PATCH] monocle and set_layout func --- include/config.h | 43 +++++++++++++++++++++++---- include/keybinds.h | 4 ++- include/types.h | 3 +- src/absinthe.c | 1 + src/focus.c | 3 +- src/keybinds.c | 23 ++++++++++++-- src/layout.c | 74 +++++++++++++++++++++++++++++++++++++++------- src/toplevel.c | 2 ++ 8 files changed, 130 insertions(+), 23 deletions(-) diff --git a/include/config.h b/include/config.h index 8980335..9cc8414 100644 --- a/include/config.h +++ b/include/config.h @@ -33,29 +33,60 @@ static const char *workspaces[] = { "3", "4", "5", + "6", + "7", + "8", + "9", + "10", }; static const absn_keybind keybinds[] = { + { ALT, XKB_KEY_Escape, quit, { 0 } }, + { ALT, XKB_KEY_Return, &run, { .v = "alacritty" } }, { ALT, XKB_KEY_q, kill_focus, { 0 } }, + { ALT, XKB_KEY_j, cycle_focus, { .i = +1 } }, { ALT, XKB_KEY_k, cycle_focus, { .i = -1 } }, + { ALT, XKB_KEY_f, toggle_fullscreen, { 0 } }, + { ALT, XKB_KEY_h, increase_master_count, { .i = +1 } }, { ALT, XKB_KEY_l, increase_master_count, { .i = -1 } }, + { ALT | SHIFT, XKB_KEY_h, increase_master_width, { .f = -0.05 } }, { ALT | SHIFT, XKB_KEY_l, increase_master_width, { .f = +0.05 } }, + + { ALT, XKB_KEY_t, set_layout, { .i = LAYOUT_TILE } }, + { ALT, XKB_KEY_m, set_layout, { .i = LAYOUT_MONOCLE } }, + { ALT, XKB_KEY_1, switch_workspace, { .v = "1" } }, { ALT, XKB_KEY_2, switch_workspace, { .v = "2" } }, { 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 | 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 } }, + { ALT, XKB_KEY_6, switch_workspace, { .v = "6" } }, + { ALT, XKB_KEY_7, switch_workspace, { .v = "7" } }, + { ALT, XKB_KEY_8, switch_workspace, { .v = "8" } }, + { ALT, XKB_KEY_9, switch_workspace, { .v = "9" } }, + { ALT, XKB_KEY_0, switch_workspace, { .v = "10" } }, + + { ALT | SHIFT, XKB_KEY_exclam, move_focus_to_workspace, { .v = "1" } }, + { ALT | SHIFT, XKB_KEY_at, move_focus_to_workspace, { .v = "2" } }, + { ALT | SHIFT, XKB_KEY_numbersign, move_focus_to_workspace, + { .v = "3" } }, + { ALT | SHIFT, XKB_KEY_dollar, move_focus_to_workspace, { .v = "4" } }, + { ALT | SHIFT, XKB_KEY_percent, move_focus_to_workspace, { .v = "5" } }, + { ALT | SHIFT, XKB_KEY_asciicircum, move_focus_to_workspace, + { .v = "6" } }, + { ALT | SHIFT, XKB_KEY_ampersand, move_focus_to_workspace, + { .v = "7" } }, + { ALT | SHIFT, XKB_KEY_asterisk, move_focus_to_workspace, + { .v = "8" } }, + { ALT | SHIFT, XKB_KEY_parenleft, move_focus_to_workspace, + { .v = "9" } }, + { ALT | SHIFT, XKB_KEY_parenright, move_focus_to_workspace, + { .v = "10" } }, }; #endif diff --git a/include/keybinds.h b/include/keybinds.h index be959b8..8ad4159 100644 --- a/include/keybinds.h +++ b/include/keybinds.h @@ -13,7 +13,9 @@ 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 move_focus_to_workspace(absn_server *server, const absn_arg *arg); + +void set_layout(absn_server *server, const absn_arg *arg); void quit(absn_server *server, const absn_arg *arg); diff --git a/include/types.h b/include/types.h index 5d36f76..afa8e4e 100644 --- a/include/types.h +++ b/include/types.h @@ -79,13 +79,12 @@ static const int layermap[] = { enum { LAYOUT_TILE, - LAYOUT_FLOAT, + LAYOUT_MONOCLE, LAYOUT_TILELEFT, LAYOUT_TILETOP, LAYOUT_TILEBOTTOM, LAYOUT_SPIRAL, LAYOUT_DWINDLE, - LAYOUT_MAX, LAYOUT_VGRID, LAYOUT_HGRID, }; diff --git a/src/absinthe.c b/src/absinthe.c index c229fe4..6a35b7a 100644 --- a/src/absinthe.c +++ b/src/absinthe.c @@ -156,6 +156,7 @@ setup(absn_server *server) server->workspaces_count = workspaces_count; server->workspaces = calloc(workspaces_count, sizeof(absn_workspace)); for (int i = 0; i < workspaces_count; ++i) { + server->workspaces[i].layout = LAYOUT_TILE; server->workspaces[i].name = workspaces[i]; server->workspaces[i].count = STACK_COUNT; server->workspaces[i].size = STACK_SIZE; diff --git a/src/focus.c b/src/focus.c index 4737919..4559d9f 100644 --- a/src/focus.c +++ b/src/focus.c @@ -66,7 +66,8 @@ focus_get_topmost(absn_server *server) absn_toplevel *toplevel; wl_list_for_each(toplevel, &server->focus_stack, flink) { - if (toplevel && toplevel->workspace == server->focused_output->workspace) + if (toplevel && + toplevel->workspace == server->focused_output->workspace) return toplevel; } return NULL; diff --git a/src/keybinds.c b/src/keybinds.c index 7d3f090..6c3a029 100644 --- a/src/keybinds.c +++ b/src/keybinds.c @@ -132,8 +132,15 @@ switch_workspace(absn_server *server, const absn_arg *arg) absn_toplevel *toplevel; wl_list_for_each(toplevel, &server->toplevels, link) { - if (toplevel && toplevel->workspace == &server->workspaces[i]) { + if (!focus && toplevel && toplevel->workspace == &server->workspaces[i]) { focus = toplevel; /* found it */ + } + + if (toplevel && toplevel->workspace == &server->workspaces[i] && + toplevel->fullscreen) + { + /* overwrite if there is a fullscreen window */ + focus = toplevel; break; } } @@ -148,7 +155,7 @@ switch_workspace(absn_server *server, const absn_arg *arg) else #endif surface = focus->xdg->base->surface; - + if (surface == server->seat->keyboard_state.focused_surface) server->seat->keyboard_state.focused_surface = NULL; @@ -159,11 +166,14 @@ switch_workspace(absn_server *server, const absn_arg *arg) } void -focus_move_to_workspace(absn_server *server, const absn_arg *arg) +move_focus_to_workspace(absn_server *server, const absn_arg *arg) { if (!server->focused_toplevel) return; + if (server->focused_toplevel->fullscreen) + toplevel_set_fullscreen(server->focused_toplevel, false); + int i; for (i = 0; i < server->workspaces_count; ++i) { if (arg->v == server->workspaces[i].name) @@ -185,6 +195,13 @@ focus_move_to_workspace(absn_server *server, const absn_arg *arg) layout_arrange(server->focused_toplevel->output); } +void +set_layout(absn_server *server, const absn_arg *arg) +{ + server->focused_output->workspace->layout = arg->i; + layout_arrange(server->focused_output); +} + noreturn void quit(absn_server *server, const absn_arg *arg) { diff --git a/src/layout.c b/src/layout.c index 2e9e190..11b63c5 100644 --- a/src/layout.c +++ b/src/layout.c @@ -4,21 +4,19 @@ #include "toplevel.h" #include "types.h" -void -layout_arrange(struct absn_output *output) +/* returns number of toplevels on workspace */ +static int +prepare_output(struct absn_output *output) { - if (!output) - return; - - struct absn_toplevel *toplevel; - int toplevels_count = 0; + int res = 0; + absn_toplevel *toplevel; wl_list_for_each(toplevel, &output->server->toplevels, link) { - if (toplevel->workspace == output->workspace && - !toplevel->floating && !toplevel->fullscreen) { - toplevels_count++; + if (toplevel->workspace == output->workspace) { wlr_scene_node_set_enabled(&toplevel->scene_tree->node, true); + if (!toplevel->floating && !toplevel->fullscreen) + res++; } else if (toplevel->output == output && toplevel->workspace != output->workspace) { wlr_scene_node_set_enabled(&toplevel->scene_tree->node, @@ -26,12 +24,21 @@ layout_arrange(struct absn_output *output) } } + return res; +} + +static void +tile(struct absn_output *output) +{ + int toplevels_count = prepare_output(output); + if (toplevels_count < 1) return; int32_t og = OUTPUT_GAP; struct wlr_box new_geom; + absn_toplevel *toplevel; if (toplevels_count == 1) { wl_list_for_each(toplevel, &output->server->toplevels, link) { @@ -143,3 +150,50 @@ layout_arrange(struct absn_output *output) i++; } } + +static void +monocle(struct absn_output *output) +{ + int toplevels_count = prepare_output(output); + + if (toplevels_count < 1) + return; + + int32_t og = OUTPUT_GAP; + + struct wlr_box new_geom = { + .x = output->geom.x + og, + .y = output->geom.y + og, + .width = output->geom.width - 2 * og, + .height = output->geom.height - 2 * og, + }; + + absn_toplevel *toplevel; + wl_list_for_each(toplevel, &output->server->toplevels, link) + { + if (toplevel->workspace != output->workspace || + toplevel->floating || toplevel->fullscreen) + continue; + + toplevel_set_geom(toplevel, &new_geom); + } +} + +void +layout_arrange(struct absn_output *output) +{ + if (!output) + return; + + switch (output->workspace->layout) { + case LAYOUT_TILE: + tile(output); + break; + case LAYOUT_MONOCLE: + monocle(output); + break; + default: /* currently not implemented layouts */ + tile(output); + break; + } +} diff --git a/src/toplevel.c b/src/toplevel.c index 52db2ea..629d67e 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -211,6 +211,8 @@ toplevel_set_fullscreen(absn_toplevel *toplevel, bool fullscreen) } toplevel_update_borders_geom(toplevel); + + layout_arrange(toplevel->output); } void