From d98771900c23cfd5973cdac34f87f5a6a547e260 Mon Sep 17 00:00:00 2001 From: speckitor Date: Tue, 19 May 2026 12:17:13 +0700 Subject: [PATCH] layer shell --- .clang-format | 3 +- include/config.h | 88 +++++++++++++++++++++++----------------------- include/cursor.h | 2 ++ include/toplevel.h | 2 -- include/types.h | 4 ++- src/cursor.c | 51 ++++++++++++++++++++++++--- src/server.c | 27 ++++++++------ src/toplevel.c | 39 -------------------- 8 files changed, 113 insertions(+), 103 deletions(-) diff --git a/.clang-format b/.clang-format index efe0be2..0898284 100644 --- a/.clang-format +++ b/.clang-format @@ -5,7 +5,6 @@ UseTab: Never ColumnLimit: 200 AllowShortFunctionsOnASingleLine: false SortIncludes: true -InsertBraces: true BreakBeforeBraces: Custom BraceWrapping: AfterFunction: true @@ -15,4 +14,4 @@ BraceWrapping: AfterEnum: false AfterStruct: false AfterUnion: false - AfterExternBlock: false \ No newline at end of file + AfterExternBlock: false diff --git a/include/config.h b/include/config.h index 8e981c1..d4521fc 100644 --- a/include/config.h +++ b/include/config.h @@ -4,11 +4,7 @@ #include "keybinds.h" #include "types.h" -#define CURSOR_MOD WLR_MODIFIER_ALT -#define CURSOR_MOVE_BUTTON BTN_LEFT -#define CURSOR_RESIZE_BUTTON BTN_RIGHT - -#define TOPLEVEL_BW 2 +#define TOPLEVEL_BW 1 static const float bgcolor[4] = {0.0, 0.0, 0.0, 1.0}; @@ -19,8 +15,8 @@ static const float unfocused_bc[4] = {0.28, 0.28, 0.28, 1.0}; #define STACK_COUNT 1 #define STACK_SIZE 0.5 -#define OUTPUT_GAP 10 -#define LAYOUT_GAP 5 +#define OUTPUT_GAP 0 +#define LAYOUT_GAP 0 #define ALT WLR_MODIFIER_ALT #define CTRL WLR_MODIFIER_CTRL @@ -31,53 +27,57 @@ static const char *workspaces[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", }; +#define CURSOR_MOD ALT +#define CURSOR_MOVE_BUTTON BTN_LEFT +#define CURSOR_RESIZE_BUTTON BTN_RIGHT + static const absn_keybind keybinds[] = { - {LOGO, XKB_KEY_Escape, quit, {0}}, + {ALT, XKB_KEY_Escape, quit, {0}}, - {LOGO, XKB_KEY_Return, &run, {.v = "alacritty"}}, - {LOGO, XKB_KEY_d, &run, {.v = "wofi --show drun"}}, - {LOGO, XKB_KEY_q, kill_focus, {0}}, + {ALT, XKB_KEY_Return, &run, {.v = "alacritty"}}, + {ALT, XKB_KEY_d, &run, {.v = "wofi --show drun"}}, + {ALT, XKB_KEY_q, kill_focus, {0}}, - {LOGO, XKB_KEY_j, cycle_focus, {.i = +1}}, - {LOGO, XKB_KEY_k, cycle_focus, {.i = -1}}, + {ALT, XKB_KEY_j, cycle_focus, {.i = +1}}, + {ALT, XKB_KEY_k, cycle_focus, {.i = -1}}, - {LOGO | SHIFT, XKB_KEY_j, swap_focus, {.i = +1}}, - {LOGO | SHIFT, XKB_KEY_k, swap_focus, {.i = -1}}, + {ALT | SHIFT, XKB_KEY_j, swap_focus, {.i = +1}}, + {ALT | SHIFT, XKB_KEY_k, swap_focus, {.i = -1}}, - {LOGO, XKB_KEY_f, toggle_fullscreen, {0}}, - {LOGO, XKB_KEY_v, toggle_floating, {0}}, + {ALT, XKB_KEY_f, toggle_fullscreen, {0}}, + {ALT, XKB_KEY_v, toggle_floating, {0}}, - {LOGO, XKB_KEY_h, increase_master_count, {.i = +1}}, - {LOGO, XKB_KEY_l, increase_master_count, {.i = -1}}, + {ALT, XKB_KEY_h, increase_master_count, {.i = +1}}, + {ALT, XKB_KEY_l, increase_master_count, {.i = -1}}, - {LOGO | SHIFT, XKB_KEY_h, increase_master_width, {.f = -0.05}}, - {LOGO | SHIFT, XKB_KEY_l, increase_master_width, {.f = +0.05}}, + {ALT | SHIFT, XKB_KEY_h, increase_master_width, {.f = -0.05}}, + {ALT | SHIFT, XKB_KEY_l, increase_master_width, {.f = +0.05}}, - {LOGO, XKB_KEY_t, set_layout, {.i = LAYOUT_TILE}}, - {LOGO, XKB_KEY_r, set_layout, {.i = LAYOUT_TILELEFT}}, - {LOGO, XKB_KEY_m, set_layout, {.i = LAYOUT_MONOCLE}}, + {ALT, XKB_KEY_t, set_layout, {.i = LAYOUT_TILE}}, + {ALT, XKB_KEY_r, set_layout, {.i = LAYOUT_TILELEFT}}, + {ALT, XKB_KEY_m, set_layout, {.i = LAYOUT_MONOCLE}}, - {LOGO, XKB_KEY_1, switch_workspace, {.v = "1"}}, - {LOGO, XKB_KEY_2, switch_workspace, {.v = "2"}}, - {LOGO, XKB_KEY_3, switch_workspace, {.v = "3"}}, - {LOGO, XKB_KEY_4, switch_workspace, {.v = "4"}}, - {LOGO, XKB_KEY_5, switch_workspace, {.v = "5"}}, - {LOGO, XKB_KEY_6, switch_workspace, {.v = "6"}}, - {LOGO, XKB_KEY_7, switch_workspace, {.v = "7"}}, - {LOGO, XKB_KEY_8, switch_workspace, {.v = "8"}}, - {LOGO, XKB_KEY_9, switch_workspace, {.v = "9"}}, - {LOGO, XKB_KEY_0, switch_workspace, {.v = "10"}}, + {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, 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"}}, - {LOGO | SHIFT, XKB_KEY_exclam, move_focus_to_workspace, {.v = "1"}}, - {LOGO | SHIFT, XKB_KEY_at, move_focus_to_workspace, {.v = "2"}}, - {LOGO | SHIFT, XKB_KEY_numbersign, move_focus_to_workspace, {.v = "3"}}, - {LOGO | SHIFT, XKB_KEY_dollar, move_focus_to_workspace, {.v = "4"}}, - {LOGO | SHIFT, XKB_KEY_percent, move_focus_to_workspace, {.v = "5"}}, - {LOGO | SHIFT, XKB_KEY_asciicircum, move_focus_to_workspace, {.v = "6"}}, - {LOGO | SHIFT, XKB_KEY_ampersand, move_focus_to_workspace, {.v = "7"}}, - {LOGO | SHIFT, XKB_KEY_asterisk, move_focus_to_workspace, {.v = "8"}}, - {LOGO | SHIFT, XKB_KEY_parenleft, move_focus_to_workspace, {.v = "9"}}, - {LOGO | SHIFT, XKB_KEY_parenright, move_focus_to_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/cursor.h b/include/cursor.h index b9da335..7f2d15e 100644 --- a/include/cursor.h +++ b/include/cursor.h @@ -1,4 +1,6 @@ #include "types.h" +void client_from_coords(absn_server *server, double x, double y, struct wlr_surface **rsurface, absn_toplevel **rtoplevel, absn_layer_surface **rlayer_surface, double *rx, double *ry); + void reset_cursor_mode(absn_server *server); void process_cursor_motion(absn_server *server, uint32_t time); diff --git a/include/toplevel.h b/include/toplevel.h index fa07b36..06141c6 100644 --- a/include/toplevel.h +++ b/include/toplevel.h @@ -3,8 +3,6 @@ #include "types.h" -absn_toplevel *toplevel_at(absn_server *server, double lx, double ly, struct wlr_surface **surface, double *sx, double *sy); - bool toplevel_is_unmanaged(absn_toplevel *toplevel); void toplevel_get_geom(absn_toplevel *toplevel); diff --git a/include/types.h b/include/types.h index 7ed2ed1..62a2725 100644 --- a/include/types.h +++ b/include/types.h @@ -183,6 +183,7 @@ struct absn_output { }; typedef struct { + int type; struct wl_list link; absn_server *server; @@ -201,6 +202,8 @@ typedef struct { } absn_layer_surface; struct absn_toplevel { + int type; + struct wl_list link; struct wl_list flink; /* link for focus stack */ uint32_t tag; @@ -223,7 +226,6 @@ struct absn_toplevel { struct wlr_box geom; struct wlr_box prev_geom; - int type; union { struct wlr_xdg_toplevel *xdg; struct wlr_xwayland_surface *xw; diff --git a/src/cursor.c b/src/cursor.c index bb801fb..7fcb638 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -1,10 +1,51 @@ #include -#include +#include "cursor.h" #include "layout.h" #include "toplevel.h" #include "types.h" +/* + * returns surface at given cursor coordinates + * and coordinates inside of it to process input event + */ +void client_from_coords(absn_server *server, double x, double y, struct wlr_surface **rsurface, absn_toplevel **rtoplevel, absn_layer_surface **rlayer_surface, double *rx, double *ry) +{ + struct wlr_scene_node *pnode = NULL, *node = NULL; + struct wlr_scene_buffer *buffer = NULL; + struct wlr_surface *surface = NULL; + + absn_layer_surface *layer_surface = NULL; + absn_toplevel *toplevel = NULL; + + for (int i = LAYERS_COUNT - 1; i > 0; --i) { + node = wlr_scene_node_at(&server->layers[i]->node, x, y, rx, ry); + if (!node) { + continue; + } + + if (node->type == WLR_SCENE_NODE_BUFFER) { + buffer = wlr_scene_buffer_from_node(node); + surface = wlr_scene_surface_try_from_buffer(buffer)->surface; + } + + for (pnode = node; pnode && !toplevel; pnode = &pnode->parent->node) + toplevel = pnode->data; + + if (toplevel && toplevel->type == LAYER_SURFACE) { + toplevel = NULL; + layer_surface = pnode->data; + } + } + + if (rsurface) + *rsurface = surface; + if (rtoplevel) + *rtoplevel = toplevel; + if (rlayer_surface) + *rlayer_surface = layer_surface; +} + void reset_cursor_mode(absn_server *server) { server->cursor_mode = CURSOR_PASSTHROUGH; @@ -140,9 +181,9 @@ static void process_cursor_resize(absn_server *server) void process_cursor_motion(absn_server *server, uint32_t time) { - double sx, sy; + double x, y; struct wlr_surface *surface = NULL; - toplevel_at(server, server->cursor->x, server->cursor->y, &surface, &sx, &sy); + client_from_coords(server, server->cursor->x, server->cursor->y, &surface, NULL, NULL, &x, &y); struct wlr_seat *seat = server->seat; if (server->cursor_mode == CURSOR_MOVE) { @@ -154,8 +195,8 @@ void process_cursor_motion(absn_server *server, uint32_t time) } if (surface) { - wlr_seat_pointer_notify_enter(seat, surface, sx, sy); - wlr_seat_pointer_notify_motion(seat, time, sx, sy); + wlr_seat_pointer_notify_enter(seat, surface, x, y); + wlr_seat_pointer_notify_motion(seat, time, x, y); } else { wlr_seat_pointer_clear_focus(seat); } diff --git a/src/server.c b/src/server.c index c504676..71124da 100644 --- a/src/server.c +++ b/src/server.c @@ -1,8 +1,8 @@ #include #include + #include #include -#include #include "config.h" #include "cursor.h" @@ -143,6 +143,7 @@ void new_layer_surface(struct wl_listener *listener, void *data) } absn_layer_surface *layer_surface = calloc(1, sizeof(*layer_surface)); + layer_surface->type = LAYER_SURFACE; layer_surface->server = server; layer_surface->wlr = surface; layer_surface->output = surface->output->data; @@ -227,9 +228,15 @@ void cursor_button(struct wl_listener *listener, void *data) if (event->state == WL_POINTER_BUTTON_STATE_RELEASED) { reset_cursor_mode(server); } else { - double sx, sy; + double x, y; struct wlr_surface *surface = NULL; - absn_toplevel *toplevel = toplevel_at(server, server->cursor->x, server->cursor->y, &surface, &sx, &sy); + absn_toplevel *toplevel; + absn_layer_surface *layer_surface; + client_from_coords(server, server->cursor->x, server->cursor->y, &surface, &toplevel, &layer_surface, &x, &y); + + if (server->exclusive_focus) { + goto handle; + } if (!toplevel) { goto handle; @@ -252,10 +259,10 @@ void cursor_button(struct wl_listener *listener, void *data) server->grab_x = server->cursor->x; server->grab_y = server->cursor->y; - int32_t lx, ly; - wlr_scene_node_coords(&toplevel->scene_tree->node, &lx, &ly); - server->grab_geom.x = lx; - server->grab_geom.y = ly; + int32_t nx, ny; + wlr_scene_node_coords(&toplevel->scene_tree->node, &nx, &ny); + server->grab_geom.x = nx; + server->grab_geom.y = ny; server->grab_geom.width = toplevel->geom.width; server->grab_geom.height = toplevel->geom.height; @@ -266,13 +273,13 @@ void cursor_button(struct wl_listener *listener, void *data) int32_t width = toplevel->xdg->base->geometry.width; int32_t height = toplevel->xdg->base->geometry.height; - if (server->grab_x > (lx + width / 2) && server->grab_y > (ly + height / 2)) { + if (server->grab_x > (x + width / 2) && server->grab_y > (y + height / 2)) { server->resize_corner = BOTTOM_RIGHT; wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr, "se-resize"); - } else if (server->grab_x < (lx + width / 2) && server->grab_y > (ly + height / 2)) { + } else if (server->grab_x < (x + width / 2) && server->grab_y > (y + height / 2)) { server->resize_corner = BOTTOM_LEFT; wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr, "sw-resize"); - } else if (server->grab_x > (lx + width / 2) && server->grab_y < (ly + height / 2)) { + } else if (server->grab_x > (x + width / 2) && server->grab_y < (y + height / 2)) { server->resize_corner = TOP_RIGHT; wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr, "ne-resize"); } else { diff --git a/src/toplevel.c b/src/toplevel.c index d294514..4e93a05 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -1,5 +1,4 @@ #include -#include #include "config.h" #include "layout.h" @@ -7,44 +6,6 @@ #include "types.h" #include "xdg-shell-protocol.h" -/* - * returns toplevel at given cursor coordinates, - * its surface and coordinates inside of it - * to process input event - */ -absn_toplevel *toplevel_at(absn_server *server, double lx, double ly, struct wlr_surface **surface, double *sx, double *sy) -{ - struct wlr_scene_node *node = wlr_scene_node_at(&server->scene->tree.node, lx, ly, sx, sy); - if (!node) { - return NULL; - } - - struct wlr_scene_buffer *scene_buffer = NULL; - struct wlr_scene_surface *scene_surface = NULL; - - switch (node->type) { - case WLR_SCENE_NODE_BUFFER: - scene_buffer = wlr_scene_buffer_from_node(node); - scene_surface = wlr_scene_surface_try_from_buffer(scene_buffer); - if (!scene_surface) { - return NULL; - } - - *surface = scene_surface->surface; - struct wlr_scene_tree *tree = node->parent; - while (tree && !tree->node.data) { - tree = tree->node.parent; - } - return tree->node.data; - break; - case WLR_SCENE_NODE_RECT: - return node->data; - break; - default: - return NULL; - } -} - /* * if toplevel is unmanaged we should not * move or resize it and just draw it