From 66fc7d0bf54f91a1bd9509683bf811da6ac886e0 Mon Sep 17 00:00:00 2001 From: speckitor Date: Tue, 28 Apr 2026 18:46:46 +0700 Subject: [PATCH] formatting, focus, toplevel handlers to separate file --- .clang-format | 23 ++ Makefile | 4 + include/absinthe-toplevel-handlers.h | 9 + include/absinthe-toplevel.h | 19 +- include/focus.h | 2 +- include/types.h | 13 +- src/absinthe-toplevel-handlers.c | 139 ++++++++++++ src/absinthe-toplevel.c | 325 ++++++++------------------- src/cursor.c | 26 ++- src/focus.c | 22 +- src/keyboard.c | 10 +- src/layout.c | 21 +- src/main.c | 38 ++-- src/output.c | 17 +- src/server.c | 36 +-- src/xdg-decoration.c | 3 +- src/xdg-popup.c | 1 - src/xdg-toplevel.c | 5 +- src/xwayland.c | 11 +- 19 files changed, 381 insertions(+), 343 deletions(-) create mode 100644 .clang-format create mode 100644 include/absinthe-toplevel-handlers.h create mode 100644 src/absinthe-toplevel-handlers.c diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..92ed799 --- /dev/null +++ b/.clang-format @@ -0,0 +1,23 @@ +BasedOnStyle: LLVM +Language: C +PointerAlignment: Right +IndentWidth: 8 +TabWidth: 8 +ColumnLimit: 120 +UseTab: Always +SpaceAfterCStyleCast: false +SortIncludes: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false +BreakBeforeBraces: Custom + diff --git a/Makefile b/Makefile index 915d456..951e6aa 100644 --- a/Makefile +++ b/Makefile @@ -10,3 +10,7 @@ compile: proto -I./ -I./include -DWLR_USE_UNSTABLE $(shell pkg-config wlroots-0.20 --libs --cflags) -lwayland-server -lxkbcommon \ -O3 \ -g + +format: + find src/ -type f -print0 | xargs -0 clang-format -i + find include/ -type f -print0 | xargs -0 clang-format -i diff --git a/include/absinthe-toplevel-handlers.h b/include/absinthe-toplevel-handlers.h new file mode 100644 index 0000000..286acd5 --- /dev/null +++ b/include/absinthe-toplevel-handlers.h @@ -0,0 +1,9 @@ +#pragma once + +void absinthe_toplevel_map(struct wl_listener *listener, void *data); +void absinthe_toplevel_unmap(struct wl_listener *listener, void *data); +void absinthe_toplevel_destroy(struct wl_listener *listener, void *data); +void absinthe_toplevel_request_move(struct wl_listener *listener, void *data); +void absinthe_toplevel_request_resize(struct wl_listener *listener, void *data); +void absinthe_toplevel_request_maximize(struct wl_listener *listener, void *data); +void absinthe_toplevel_request_fullscreen(struct wl_listener *listener, void *data); diff --git a/include/absinthe-toplevel.h b/include/absinthe-toplevel.h index 2a937ea..a58adf3 100644 --- a/include/absinthe-toplevel.h +++ b/include/absinthe-toplevel.h @@ -1,21 +1,16 @@ +#pragma once + #include "types.h" -bool absinthe_toplevel_is_x11(struct absinthe_toplevel *toplevel); +struct absinthe_toplevel *absinthe_toplevel_at(struct absinthe_server *server, double lx, double ly, + struct wlr_surface **surface, double *sx, double *sy); + bool absinthe_toplevel_is_unmanaged(struct absinthe_toplevel *toplevel); -void absinthe_toplevel_map(struct wl_listener *listener, void *data); -void absinthe_toplevel_unmap(struct wl_listener *listener, void *data); -void absinthe_toplevel_destroy(struct wl_listener *listener, void *data); -void absinthe_toplevel_request_move(struct wl_listener *listener, void *data); -void absinthe_toplevel_request_resize(struct wl_listener *listener, void *data); -void absinthe_toplevel_request_maximize(struct wl_listener *listener, void *data); -void absinthe_toplevel_request_fullscreen(struct wl_listener *listener, void *data); - -struct absinthe_toplevel *absinthe_toplevel_at(struct absinthe_server *server, double lx, double ly, struct wlr_surface **surface, double *sx, double *sy); +void absinthe_toplevel_update_geometry(struct absinthe_toplevel *toplevel); +void absinthe_toplevel_update_borders_geometry(struct absinthe_toplevel *toplevel); void absinthe_toplevel_set_position(struct absinthe_toplevel *toplevel, int32_t x, int32_t y); void absinthe_toplevel_set_size(struct absinthe_toplevel *toplevel, int32_t width, int32_t height); void absinthe_toplevel_set_fullscreen(struct absinthe_toplevel *toplevel, bool fullscreen); - void absinthe_toplevel_set_border_color(struct absinthe_toplevel *toplevel, const float color[4]); -void absinthe_toplevel_update_borders_geometry(struct absinthe_toplevel *toplevel); diff --git a/include/focus.h b/include/focus.h index cdf2c71..4fbfcd9 100644 --- a/include/focus.h +++ b/include/focus.h @@ -6,7 +6,7 @@ void focus_toplevel(struct absinthe_toplevel *toplevel); struct absinthe_toplevel *focus_get_topmost(struct absinthe_server *server); -void focus_logical_next(struct absinthe_toplevel *toplevel); +void focus_after_unmap(struct absinthe_toplevel *toplevel); void focus_next(struct absinthe_server *server, bool tiled); void focus_prev(struct absinthe_server *server, bool tiled); diff --git a/include/types.h b/include/types.h index 35129ac..9cab68a 100644 --- a/include/types.h +++ b/include/types.h @@ -1,20 +1,19 @@ #pragma once #include - #include #include -#include #include -#include +#include +#include +#include #include #include -#include -#include -#include -#include #include +#include +#include #include +#include #ifdef XWAYLAND #include diff --git a/src/absinthe-toplevel-handlers.c b/src/absinthe-toplevel-handlers.c new file mode 100644 index 0000000..95d3ffb --- /dev/null +++ b/src/absinthe-toplevel-handlers.c @@ -0,0 +1,139 @@ +#include + +#include "absinthe-toplevel.h" +#include "focus.h" +#include "layout.h" +#include "output.h" + +void absinthe_toplevel_map(struct wl_listener *listener, void *data) +{ + UNUSED(data); + struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, map); + + toplevel->scene_tree = wlr_scene_tree_create(&toplevel->server->scene->tree); + toplevel->scene_tree->node.data = toplevel; + wlr_scene_node_set_enabled(&toplevel->scene_tree->node, absinthe_toplevel_is_unmanaged(toplevel)); + + toplevel->tiled = true; + + if (toplevel->type != ABSINTHE_TOPLEVEL_X11 && + wl_resource_get_version(toplevel->toplevel.xdg->resource) >= XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION) { + wlr_xdg_toplevel_set_tiled(toplevel->toplevel.xdg, + WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT); + } else { + wlr_xdg_toplevel_set_maximized(toplevel->toplevel.xdg, true); + } + + toplevel->border_width = absinthe_toplevel_is_unmanaged(toplevel) ? 0 : ABSINTHE_TOPLEVEL_BORDER_WIDTH; + +#ifdef XWAYLAND + if (toplevel->type == ABSINTHE_TOPLEVEL_X11) { + toplevel->scene_surface = + wlr_scene_subsurface_tree_create(toplevel->scene_tree, toplevel->toplevel.x11->surface); + } else +#endif + { + toplevel->scene_surface = + wlr_scene_subsurface_tree_create(toplevel->scene_tree, toplevel->toplevel.xdg->base->surface); + } + toplevel->scene_surface->node.data = toplevel; + + absinthe_toplevel_update_geometry(toplevel); + toplevel->border_width = absinthe_toplevel_is_unmanaged(toplevel) ? 0 : ABSINTHE_TOPLEVEL_BORDER_WIDTH; + + for (int i = 0; i < 4; ++i) { + toplevel->border[i] = wlr_scene_rect_create(toplevel->scene_tree, 0, 0, unfocused_border_color); + toplevel->border[i]->node.data = toplevel; + } + + update_focused_output(toplevel->server); + toplevel->output = toplevel->server->focused_output; + toplevel->fullscreen = false; + + wl_list_insert(&toplevel->server->toplevels, &toplevel->link); + wl_list_insert(&toplevel->server->focus_stack, &toplevel->flink); + + layout_arrange(toplevel->output); + focus_toplevel(focus_get_topmost(toplevel->server)); +} + +void absinthe_toplevel_unmap(struct wl_listener *listener, void *data) +{ + UNUSED(data); + struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, unmap); + + if (toplevel == toplevel->server->focused_toplevel) { + toplevel->server->focused_toplevel = NULL; + toplevel->server->seat->keyboard_state.focused_surface = NULL; + } + + if (toplevel->output == toplevel->server->focused_output && toplevel->tiled) + focus_after_unmap(toplevel); + + wl_list_remove(&toplevel->link); + wl_list_remove(&toplevel->flink); + + layout_arrange(toplevel->output); + + wlr_scene_node_destroy(&toplevel->scene_tree->node); +} + +void absinthe_toplevel_destroy(struct wl_listener *listener, void *data) +{ + UNUSED(data); + struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, destroy); + +#ifdef XWAYLAND + if (toplevel->type == ABSINTHE_TOPLEVEL_X11) { + wl_list_remove(&toplevel->xwayland_activate.link); + wl_list_remove(&toplevel->xwayland_associate.link); + wl_list_remove(&toplevel->xwayland_dissociate.link); + wl_list_remove(&toplevel->xwayland_configure.link); + wl_list_remove(&toplevel->xwayland_set_hints.link); + } else +#endif + { + wl_list_remove(&toplevel->map.link); + wl_list_remove(&toplevel->unmap.link); + wl_list_remove(&toplevel->commit.link); + wl_list_remove(&toplevel->request_move.link); + wl_list_remove(&toplevel->request_resize.link); + } + + wl_list_remove(&toplevel->destroy.link); + wl_list_remove(&toplevel->request_maximize.link); + wl_list_remove(&toplevel->request_fullscreen.link); + + free(toplevel); +} + +void absinthe_toplevel_request_move(struct wl_listener *listener, void *data) +{ + UNUSED(data); + struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, request_maximize); + if (toplevel->toplevel.xdg->base->initialized) + wlr_xdg_surface_schedule_configure(toplevel->toplevel.xdg->base); +} + +void absinthe_toplevel_request_resize(struct wl_listener *listener, void *data) +{ + UNUSED(data); + struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, request_maximize); + if (toplevel->toplevel.xdg->base->initialized) + wlr_xdg_surface_schedule_configure(toplevel->toplevel.xdg->base); +} + +void absinthe_toplevel_request_maximize(struct wl_listener *listener, void *data) +{ + UNUSED(data); + struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, request_maximize); + if (toplevel->toplevel.xdg->base->initialized) + wlr_xdg_surface_schedule_configure(toplevel->toplevel.xdg->base); +} + +void absinthe_toplevel_request_fullscreen(struct wl_listener *listener, void *data) +{ + UNUSED(data); + struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, request_fullscreen); + absinthe_toplevel_set_fullscreen(toplevel, toplevel->toplevel.xdg->requested.fullscreen); +} diff --git a/src/absinthe-toplevel.c b/src/absinthe-toplevel.c index 425315b..fb37a6e 100644 --- a/src/absinthe-toplevel.c +++ b/src/absinthe-toplevel.c @@ -1,183 +1,15 @@ #include - #include #include -#include -#include "types.h" #include "absinthe-toplevel.h" -#include "output.h" -#include "layout.h" #include "focus.h" +#include "layout.h" +#include "output.h" +#include "types.h" -bool absinthe_toplevel_is_unmanaged(struct absinthe_toplevel *toplevel) -{ -#ifdef XWAYLAND - if (toplevel->type == ABSINTHE_TOPLEVEL_X11) - return toplevel->toplevel.x11->override_redirect; -#endif - return false; -} - -void absinthe_toplevel_update_geometry(struct absinthe_toplevel *toplevel) -{ -#ifdef XWAYLAND - if (toplevel->type == ABSINTHE_TOPLEVEL_X11) { - toplevel->geometry.x = toplevel->toplevel.x11->x; - toplevel->geometry.y = toplevel->toplevel.x11->y; - toplevel->geometry.width = toplevel->toplevel.x11->width; - toplevel->geometry.height = toplevel->toplevel.x11->height; - } else -#endif - { - toplevel->geometry = toplevel->toplevel.xdg->base->geometry; - } -} - -struct wlr_surface *absinthe_toplevel_surface(struct absinthe_toplevel *toplevel) -{ -#ifdef XWAYLAND - if (toplevel->type == ABSINTHE_TOPLEVEL_X11) - return toplevel->toplevel.x11->surface; -#endif - return toplevel->toplevel.xdg->base->surface; -} - -void absinthe_toplevel_map(struct wl_listener *listener, void *data) -{ - UNUSED(data); - struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, map); - - toplevel->scene_tree = wlr_scene_tree_create(&toplevel->server->scene->tree); - toplevel->scene_tree->node.data = toplevel; - wlr_scene_node_set_enabled(&toplevel->scene_tree->node, absinthe_toplevel_is_unmanaged(toplevel)); - - toplevel->tiled = true; - - if (toplevel->type != ABSINTHE_TOPLEVEL_X11 && - wl_resource_get_version(toplevel->toplevel.xdg->resource) >= XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION) { - wlr_xdg_toplevel_set_tiled(toplevel->toplevel.xdg, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT); - } else { - wlr_xdg_toplevel_set_maximized(toplevel->toplevel.xdg, true); - } - - toplevel->border_width = absinthe_toplevel_is_unmanaged(toplevel) - ? 0 - : ABSINTHE_TOPLEVEL_BORDER_WIDTH; - -#ifdef XWAYLAND - if (toplevel->type == ABSINTHE_TOPLEVEL_X11) { - toplevel->scene_surface = wlr_scene_subsurface_tree_create(toplevel->scene_tree, toplevel->toplevel.x11->surface); - } else -#endif - { - toplevel->scene_surface = wlr_scene_subsurface_tree_create(toplevel->scene_tree, toplevel->toplevel.xdg->base->surface); - } - toplevel->scene_surface->node.data = toplevel; - - absinthe_toplevel_update_geometry(toplevel); - toplevel->border_width = absinthe_toplevel_is_unmanaged(toplevel) - ? 0 - : ABSINTHE_TOPLEVEL_BORDER_WIDTH; - - for (int i = 0; i < 4; ++i) { - toplevel->border[i] = wlr_scene_rect_create(toplevel->scene_tree, 0, 0, unfocused_border_color); - toplevel->border[i]->node.data = toplevel; - } - - update_focused_output(toplevel->server); - toplevel->output = toplevel->server->focused_output; - toplevel->fullscreen = false; - - wl_list_insert(&toplevel->server->toplevels, &toplevel->link); - wl_list_insert(&toplevel->server->focus_stack, &toplevel->flink); - - layout_arrange(toplevel->output); - focus_toplevel(focus_get_topmost(toplevel->server)); -} - -void absinthe_toplevel_unmap(struct wl_listener *listener, void *data) -{ - UNUSED(data); - struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, unmap); - - if (toplevel == toplevel->server->focused_toplevel) { - toplevel->server->focused_toplevel = NULL; - toplevel->server->seat->keyboard_state.focused_surface = NULL; - } - - if (toplevel->output == toplevel->server->focused_output && toplevel->tiled) - focus_logical_next(toplevel); - - wl_list_remove(&toplevel->link); - wl_list_remove(&toplevel->flink); - - layout_arrange(toplevel->output); - - wlr_scene_node_destroy(&toplevel->scene_tree->node); -} - -void absinthe_toplevel_destroy(struct wl_listener *listener, void *data) -{ - UNUSED(data); - struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, destroy); - -#ifdef XWAYLAND - if (toplevel->type == ABSINTHE_TOPLEVEL_X11) { - wl_list_remove(&toplevel->xwayland_activate.link); - wl_list_remove(&toplevel->xwayland_associate.link); - wl_list_remove(&toplevel->xwayland_dissociate.link); - wl_list_remove(&toplevel->xwayland_configure.link); - wl_list_remove(&toplevel->xwayland_set_hints.link); - } else -#endif - { - wl_list_remove(&toplevel->map.link); - wl_list_remove(&toplevel->unmap.link); - wl_list_remove(&toplevel->commit.link); - wl_list_remove(&toplevel->request_move.link); - wl_list_remove(&toplevel->request_resize.link); - } - - wl_list_remove(&toplevel->destroy.link); - wl_list_remove(&toplevel->request_maximize.link); - wl_list_remove(&toplevel->request_fullscreen.link); - - free(toplevel); -} - -void absinthe_toplevel_request_move(struct wl_listener *listener, void *data) -{ - UNUSED(data); - struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, request_maximize); - if (toplevel->toplevel.xdg->base->initialized) - wlr_xdg_surface_schedule_configure(toplevel->toplevel.xdg->base); -} - -void absinthe_toplevel_request_resize(struct wl_listener *listener, void *data) -{ - UNUSED(data); - struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, request_maximize); - if (toplevel->toplevel.xdg->base->initialized) - wlr_xdg_surface_schedule_configure(toplevel->toplevel.xdg->base); -} - -void absinthe_toplevel_request_maximize(struct wl_listener *listener, void *data) -{ - UNUSED(data); - struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, request_maximize); - if (toplevel->toplevel.xdg->base->initialized) - wlr_xdg_surface_schedule_configure(toplevel->toplevel.xdg->base); -} - -void absinthe_toplevel_request_fullscreen(struct wl_listener *listener, void *data) -{ - UNUSED(data); - struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, request_fullscreen); - absinthe_toplevel_set_fullscreen(toplevel, toplevel->toplevel.xdg->requested.fullscreen); -} - -struct absinthe_toplevel *absinthe_toplevel_at(struct absinthe_server *server, double lx, double ly, struct wlr_surface **surface, double *sx, double *sy) +struct absinthe_toplevel *absinthe_toplevel_at(struct absinthe_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) { @@ -207,74 +39,27 @@ struct absinthe_toplevel *absinthe_toplevel_at(struct absinthe_server *server, d } } -void absinthe_toplevel_set_position(struct absinthe_toplevel *toplevel, int32_t x, int32_t y) +bool absinthe_toplevel_is_unmanaged(struct absinthe_toplevel *toplevel) { - toplevel->geometry.x = x; - toplevel->geometry.y = y; - wlr_scene_node_set_position(&toplevel->scene_tree->node, x, y); -} - -void absinthe_toplevel_set_size(struct absinthe_toplevel *toplevel, int32_t width, int32_t height) -{ - if (width <= 2 * toplevel->border_width || height <= 2 * toplevel->border_width || (width == toplevel->geometry.width && height == toplevel->geometry.height)) - return; - - toplevel->geometry.width = width; - toplevel->geometry.height = height; - - struct wlr_box clip = { - .x = 0, - .y = 0, - .width = width - toplevel->border_width, - .height = height - toplevel->border_width, - }; - wlr_scene_subsurface_tree_set_clip(&toplevel->scene_surface->node, &clip); - - if (toplevel->type == ABSINTHE_TOPLEVEL_XDG) { - toplevel->resizing = wlr_xdg_toplevel_set_size(toplevel->toplevel.xdg, - width - 2 * toplevel->border_width, height - 2 * toplevel->border_width); - } #ifdef XWAYLAND - else if (toplevel->type == ABSINTHE_TOPLEVEL_X11) { - wlr_xwayland_surface_configure(toplevel->toplevel.x11, - toplevel->geometry.x, toplevel->geometry.y, - width - 2 * toplevel->border_width, height - 2 * toplevel->border_width); - absinthe_toplevel_set_position(toplevel, toplevel->geometry.x + toplevel->border_width, toplevel->geometry.y + toplevel->border_width); - } + if (toplevel->type == ABSINTHE_TOPLEVEL_X11) + return toplevel->toplevel.x11->override_redirect; #endif - - absinthe_toplevel_update_borders_geometry(toplevel); + return false; } -void absinthe_toplevel_set_fullscreen(struct absinthe_toplevel *toplevel, bool fullscreen) +void absinthe_toplevel_update_geometry(struct absinthe_toplevel *toplevel) { - if (!toplevel || toplevel->fullscreen == fullscreen) - return; - - struct absinthe_output *output = toplevel->server->focused_output; - toplevel->fullscreen = fullscreen; - wlr_xdg_toplevel_set_fullscreen(toplevel->toplevel.xdg, fullscreen); - - if (fullscreen) { - toplevel->prev_geometry = toplevel->geometry; - toplevel->border_width = 0; - absinthe_toplevel_set_size(toplevel, output->geometry.width, output->geometry.height); - absinthe_toplevel_set_position(toplevel, output->geometry.x, output->geometry.y); - } else { - toplevel->border_width = absinthe_toplevel_is_unmanaged(toplevel) - ? 0 - : ABSINTHE_TOPLEVEL_BORDER_WIDTH; - absinthe_toplevel_set_size(toplevel, toplevel->prev_geometry.width, toplevel->prev_geometry.height); - absinthe_toplevel_set_position(toplevel, toplevel->prev_geometry.x, toplevel->prev_geometry.y); - } - - absinthe_toplevel_update_borders_geometry(toplevel); -} - -void absinthe_toplevel_set_border_color(struct absinthe_toplevel *toplevel, const float color[4]) -{ - for (int i = 0; i < 4; ++i) { - wlr_scene_rect_set_color(toplevel->border[i], color); +#ifdef XWAYLAND + if (toplevel->type == ABSINTHE_TOPLEVEL_X11) { + toplevel->geometry.x = toplevel->toplevel.x11->x; + toplevel->geometry.y = toplevel->toplevel.x11->y; + toplevel->geometry.width = toplevel->toplevel.x11->width; + toplevel->geometry.height = toplevel->toplevel.x11->height; + } else +#endif + { + toplevel->geometry = toplevel->toplevel.xdg->base->geometry; } } @@ -298,3 +83,73 @@ void absinthe_toplevel_update_borders_geometry(struct absinthe_toplevel *topleve wlr_scene_node_set_position(&toplevel->border[2]->node, 0, 0); wlr_scene_node_set_position(&toplevel->border[3]->node, toplevel->geometry.width - border_width, 0); } + +void absinthe_toplevel_set_position(struct absinthe_toplevel *toplevel, int32_t x, int32_t y) +{ + toplevel->geometry.x = x; + toplevel->geometry.y = y; + wlr_scene_node_set_position(&toplevel->scene_tree->node, x, y); +} + +void absinthe_toplevel_set_size(struct absinthe_toplevel *toplevel, int32_t width, int32_t height) +{ + if (width <= 2 * toplevel->border_width || height <= 2 * toplevel->border_width || + (width == toplevel->geometry.width && height == toplevel->geometry.height)) + return; + + toplevel->geometry.width = width; + toplevel->geometry.height = height; + + struct wlr_box clip = { + .x = 0, + .y = 0, + .width = width - toplevel->border_width, + .height = height - toplevel->border_width, + }; + wlr_scene_subsurface_tree_set_clip(&toplevel->scene_surface->node, &clip); + + if (toplevel->type == ABSINTHE_TOPLEVEL_XDG) { + toplevel->resizing = wlr_xdg_toplevel_set_size( + toplevel->toplevel.xdg, width - 2 * toplevel->border_width, height - 2 * toplevel->border_width); + } +#ifdef XWAYLAND + else if (toplevel->type == ABSINTHE_TOPLEVEL_X11) { + wlr_xwayland_surface_configure(toplevel->toplevel.x11, toplevel->geometry.x, toplevel->geometry.y, + width - 2 * toplevel->border_width, height - 2 * toplevel->border_width); + absinthe_toplevel_set_position(toplevel, toplevel->geometry.x + toplevel->border_width, + toplevel->geometry.y + toplevel->border_width); + } +#endif + + absinthe_toplevel_update_borders_geometry(toplevel); +} + +void absinthe_toplevel_set_fullscreen(struct absinthe_toplevel *toplevel, bool fullscreen) +{ + if (!toplevel || toplevel->fullscreen == fullscreen) + return; + + struct absinthe_output *output = toplevel->server->focused_output; + toplevel->fullscreen = fullscreen; + wlr_xdg_toplevel_set_fullscreen(toplevel->toplevel.xdg, fullscreen); + + if (fullscreen) { + toplevel->prev_geometry = toplevel->geometry; + toplevel->border_width = 0; + absinthe_toplevel_set_size(toplevel, output->geometry.width, output->geometry.height); + absinthe_toplevel_set_position(toplevel, output->geometry.x, output->geometry.y); + } else { + toplevel->border_width = absinthe_toplevel_is_unmanaged(toplevel) ? 0 : ABSINTHE_TOPLEVEL_BORDER_WIDTH; + absinthe_toplevel_set_size(toplevel, toplevel->prev_geometry.width, toplevel->prev_geometry.height); + absinthe_toplevel_set_position(toplevel, toplevel->prev_geometry.x, toplevel->prev_geometry.y); + } + + absinthe_toplevel_update_borders_geometry(toplevel); +} + +void absinthe_toplevel_set_border_color(struct absinthe_toplevel *toplevel, const float color[4]) +{ + for (int i = 0; i < 4; ++i) { + wlr_scene_rect_set_color(toplevel->border[i], color); + } +} diff --git a/src/cursor.c b/src/cursor.c index 1696c18..7eebc45 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -1,9 +1,9 @@ #include #include -#include "types.h" #include "absinthe-toplevel.h" #include "layout.h" +#include "types.h" void reset_cursor_mode(struct absinthe_server *server) { @@ -14,7 +14,8 @@ void reset_cursor_mode(struct absinthe_server *server) } } -static void process_cursor_move(struct absinthe_server *server) { +static void process_cursor_move(struct absinthe_server *server) +{ struct absinthe_toplevel *toplevel = server->focused_toplevel; if (!toplevel) @@ -33,7 +34,7 @@ static void process_cursor_move(struct absinthe_server *server) { absinthe_toplevel_set_position(toplevel, new_x, new_y); if (toplevel->tiled) { - toplevel->tiled = false; + toplevel->tiled = false; layout_arrange(toplevel->output); } } @@ -54,19 +55,20 @@ static void apply_resize(struct absinthe_toplevel *toplevel, struct wlr_box *new if (!(new_geometry->width >= min_width && new_geometry->width <= max_width)) { new_geometry->width = toplevel->geometry.width; - new_geometry->x = toplevel->geometry.x; + new_geometry->x = toplevel->geometry.x; } - + if (!(new_geometry->height >= min_height && new_geometry->height <= max_height)) { new_geometry->height = toplevel->geometry.height; - new_geometry->y = toplevel->geometry.y; + new_geometry->y = toplevel->geometry.y; } absinthe_toplevel_set_size(toplevel, new_geometry->width, new_geometry->height); absinthe_toplevel_set_position(toplevel, new_geometry->x, new_geometry->y); } -static void process_cursor_resize(struct absinthe_server *server) { +static void process_cursor_resize(struct absinthe_server *server) +{ struct absinthe_toplevel *toplevel = server->focused_toplevel; if (!toplevel) @@ -79,7 +81,7 @@ static void process_cursor_resize(struct absinthe_server *server) { absinthe_toplevel_set_fullscreen(toplevel, false); if (toplevel->tiled) { - toplevel->tiled = false; + toplevel->tiled = false; layout_arrange(toplevel->output); } @@ -122,10 +124,10 @@ static void process_cursor_resize(struct absinthe_server *server) { if (new_width > 0 && new_height > 0) { struct wlr_box new_geometry = { - .x = new_x, - .y = new_y, - .width = new_width, - .height = new_height, + .x = new_x, + .y = new_y, + .width = new_width, + .height = new_height, }; apply_resize(server->focused_toplevel, &new_geometry); diff --git a/src/focus.c b/src/focus.c index bfc6aa0..88d6e0d 100644 --- a/src/focus.c +++ b/src/focus.c @@ -1,9 +1,9 @@ #include #include -#include "types.h" #include "absinthe-toplevel.h" #include "focus.h" +#include "types.h" void focus_toplevel(struct absinthe_toplevel *toplevel) { @@ -31,7 +31,8 @@ void focus_toplevel(struct absinthe_toplevel *toplevel) absinthe_toplevel_set_border_color(prev_toplevel->base->data, unfocused_border_color); } - struct wlr_xwayland_surface *prev_xwayland_surface = wlr_xwayland_surface_try_from_wlr_surface(prev_surface); + struct wlr_xwayland_surface *prev_xwayland_surface = + wlr_xwayland_surface_try_from_wlr_surface(prev_surface); if (prev_xwayland_surface) absinthe_toplevel_set_border_color(prev_surface->data, unfocused_border_color); } @@ -47,24 +48,27 @@ void focus_toplevel(struct absinthe_toplevel *toplevel) absinthe_toplevel_set_border_color(toplevel, focused_border_color); if (keyboard) - wlr_seat_keyboard_notify_enter(seat, surface, keyboard->keycodes, keyboard->num_keycodes, &keyboard->modifiers); + wlr_seat_keyboard_notify_enter(seat, surface, keyboard->keycodes, keyboard->num_keycodes, + &keyboard->modifiers); } struct absinthe_toplevel *focus_get_topmost(struct absinthe_server *server) { struct absinthe_toplevel *toplevel; - wl_list_for_each(toplevel, &server->focus_stack, flink) { + wl_list_for_each(toplevel, &server->focus_stack, flink) + { if (toplevel) return toplevel; } return NULL; } -void focus_logical_next(struct absinthe_toplevel *toplevel) +void focus_after_unmap(struct absinthe_toplevel *toplevel) { struct absinthe_toplevel *temp; size_t i = 0; - wl_list_for_each(temp, &toplevel->server->toplevels, link) { + wl_list_for_each(temp, &toplevel->server->toplevels, link) + { if (toplevel == temp && i == 0) { focus_next(toplevel->server, true); return; @@ -82,7 +86,8 @@ void focus_next(struct absinthe_server *server, bool tiled) return; struct absinthe_toplevel *next; - wl_list_for_each(next, &toplevel->link, link) { + wl_list_for_each(next, &toplevel->link, link) + { if (&next->link == &toplevel->server->toplevels) continue; if (tiled && !next->tiled) @@ -103,7 +108,8 @@ void focus_prev(struct absinthe_server *server, bool tiled) return; struct absinthe_toplevel *prev; - wl_list_for_each_reverse(prev, &toplevel->link, link) { + wl_list_for_each_reverse(prev, &toplevel->link, link) + { if (&prev->link == &toplevel->server->toplevels) continue; if (tiled && !prev->tiled) diff --git a/src/keyboard.c b/src/keyboard.c index f903723..0601461 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1,15 +1,14 @@ #include #include - #include -#include #include #include +#include -#include "types.h" #include "absinthe-toplevel.h" #include "focus.h" #include "layout.h" +#include "types.h" void keyboard_handle_modifiers(struct wl_listener *listener, void *data) { @@ -28,7 +27,7 @@ static bool keyboard_handle_keybind(struct absinthe_server *server, xkb_keysym_t break; case XKB_KEY_Return: if (fork() == 0) - execl("/bin/sh", "sh", "-c", "alacritty", NULL); + execl("/bin/sh", "sh", "-c", "ghostty", NULL); break; case XKB_KEY_r: if (fork() == 0) @@ -36,7 +35,8 @@ static bool keyboard_handle_keybind(struct absinthe_server *server, xkb_keysym_t break; case XKB_KEY_f: if (server->focused_toplevel) - absinthe_toplevel_set_fullscreen(server->focused_toplevel, !server->focused_toplevel->fullscreen); + absinthe_toplevel_set_fullscreen(server->focused_toplevel, + !server->focused_toplevel->fullscreen); break; case XKB_KEY_j: focus_next(server, false); diff --git a/src/layout.c b/src/layout.c index c8e7e65..761e5b7 100644 --- a/src/layout.c +++ b/src/layout.c @@ -9,7 +9,8 @@ void layout_arrange(struct absinthe_output *output) struct absinthe_toplevel *toplevel; size_t toplevels_count = 0; - wl_list_for_each(toplevel, &output->server->toplevels, link) { + wl_list_for_each(toplevel, &output->server->toplevels, link) + { if (toplevel->output == output && toplevel->tiled) { toplevels_count++; wlr_scene_node_set_enabled(&toplevel->scene_tree->node, true); @@ -22,29 +23,30 @@ void layout_arrange(struct absinthe_output *output) int32_t output_gap = ABSINTHE_OUTPUT_GAP; if (toplevels_count == 1) { - wl_list_for_each(toplevel, &output->server->toplevels, link) { + wl_list_for_each(toplevel, &output->server->toplevels, link) + { if (toplevel->output == output && toplevel->tiled) break; } toplevel->geometry.x = output->geometry.x + output_gap; toplevel->geometry.y = output->geometry.y + output_gap; - absinthe_toplevel_set_size(toplevel, - output->geometry.width - 2 * output_gap, - output->geometry.height - 2 * output_gap); + absinthe_toplevel_set_size(toplevel, output->geometry.width - 2 * output_gap, + output->geometry.height - 2 * output_gap); return; } int32_t layout_gap = ABSINTHE_LAYOUT_GAP; int32_t main_stack_width = (toplevels_count <= output->main_stack_size) - ? output->geometry.width - 2 * output_gap - : output->main_stack_width * (output->geometry.width - 2 * output_gap); + ? output->geometry.width - 2 * output_gap + : output->main_stack_width * (output->geometry.width - 2 * output_gap); int32_t width = output->geometry.width - main_stack_width - 2 * output_gap - layout_gap; int32_t height; int32_t dy = output_gap; size_t i = 0; if (toplevels_count <= output->main_stack_size) { - wl_list_for_each(toplevel, &output->server->toplevels, link) { + wl_list_for_each(toplevel, &output->server->toplevels, link) + { if (toplevel->output != output || !toplevel->tiled) continue; @@ -59,7 +61,8 @@ void layout_arrange(struct absinthe_output *output) return; } - wl_list_for_each(toplevel, &output->server->toplevels, link) { + wl_list_for_each(toplevel, &output->server->toplevels, link) + { if (toplevel->output != output || !toplevel->tiled) continue; diff --git a/src/main.c b/src/main.c index e7c7c72..e319c74 100644 --- a/src/main.c +++ b/src/main.c @@ -1,26 +1,26 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include +#include +#include +#include #include #include -#include +#include #include +#include +#include +#include +#include +#include +#include +#include #include +#include -#include "types.h" -#include "server.h" -#include "seat.h" #include "output.h" +#include "seat.h" +#include "server.h" +#include "types.h" int main(void) { @@ -51,7 +51,8 @@ int main(void) server.scene = wlr_scene_create(); if (wlr_renderer_get_texture_formats(server.renderer, WLR_BUFFER_CAP_DMABUF)) { wlr_drm_create(server.display, server.renderer); - wlr_scene_set_linux_dmabuf_v1(server.scene, wlr_linux_dmabuf_v1_create_with_renderer(server.display, 5, server.renderer)); + wlr_scene_set_linux_dmabuf_v1( + server.scene, wlr_linux_dmabuf_v1_create_with_renderer(server.display, 5, server.renderer)); } server.allocator = wlr_allocator_autocreate(server.backend, server.renderer); @@ -73,9 +74,8 @@ int main(void) wlr_export_dmabuf_manager_v1_create(server.display); wlr_ext_foreign_toplevel_list_v1_create(server.display, 1); - wlr_server_decoration_manager_set_default_mode( - wlr_server_decoration_manager_create(server.display), - WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); + wlr_server_decoration_manager_set_default_mode(wlr_server_decoration_manager_create(server.display), + WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); server.xdg_decoration_mgr = wlr_xdg_decoration_manager_v1_create(server.display); server.new_xdg_decoration.notify = server_new_xdg_decoration; wl_signal_add(&server.xdg_decoration_mgr->events.new_toplevel_decoration, &server.new_xdg_decoration); diff --git a/src/output.c b/src/output.c index 2cc7e81..f97e6db 100644 --- a/src/output.c +++ b/src/output.c @@ -1,5 +1,4 @@ #include - #include #include "types.h" @@ -13,7 +12,8 @@ void output_frame(struct wl_listener *listener, void *data) struct wlr_scene_output *scene_output = wlr_scene_get_scene_output(scene, output->wlr_output); struct absinthe_toplevel *toplevel; - wl_list_for_each(toplevel, &output->server->toplevels, link) { + wl_list_for_each(toplevel, &output->server->toplevels, link) + { if (toplevel->resizing && toplevel->output == output) goto skip; } @@ -50,7 +50,8 @@ void outputs_update(struct wl_listener *listener, void *data) UNUSED(data); struct absinthe_server *server = wl_container_of(listener, server, output_layout_change); struct absinthe_output *output; - wl_list_for_each(output, &server->outputs, link) { + wl_list_for_each(output, &server->outputs, link) + { wlr_output_layout_get_box(server->output_layout, output->wlr_output, &output->geometry); } } @@ -60,13 +61,15 @@ void update_focused_output(struct absinthe_server *server) struct absinthe_output *output; int32_t cursor_x = server->cursor->x; int32_t cursor_y = server->cursor->y; - wl_list_for_each(output, &server->outputs, link) { - bool cursor_in_output_x = cursor_x >= output->geometry.x && cursor_x <= output->geometry.x + output->geometry.width; - bool cursor_in_output_y = cursor_y >= output->geometry.y && cursor_y <= output->geometry.y + output->geometry.height; + wl_list_for_each(output, &server->outputs, link) + { + bool cursor_in_output_x = + cursor_x >= output->geometry.x && cursor_x <= output->geometry.x + output->geometry.width; + bool cursor_in_output_y = + cursor_y >= output->geometry.y && cursor_y <= output->geometry.y + output->geometry.height; if (cursor_in_output_x && cursor_in_output_y) { server->focused_output = output; break; } } } - diff --git a/src/server.c b/src/server.c index 582837b..3d6ad13 100644 --- a/src/server.c +++ b/src/server.c @@ -1,22 +1,23 @@ #include #include - -#include #include +#include -#include "types.h" -#include "output.h" -#include "xdg-toplevel.h" -#include "xdg-popup.h" -#include "xdg-decoration.h" +#include "absinthe-toplevel-handlers.h" #include "absinthe-toplevel.h" +#include "config.h" +#include "cursor.h" #include "focus.h" #include "keyboard.h" -#include "cursor.h" -#include "config.h" +#include "output.h" +#include "types.h" +#include "xdg-decoration.h" +#include "xdg-popup.h" +#include "xdg-toplevel.h" #ifdef XWAYLAND #include + #include "xwayland.h" #endif @@ -53,7 +54,8 @@ void server_new_output(struct wl_listener *listener, void *data) wl_list_insert(&server->outputs, &output->link); - struct wlr_output_layout_output *l_layout = wlr_output_layout_add_auto(server->output_layout, output->wlr_output); + struct wlr_output_layout_output *l_layout = + wlr_output_layout_add_auto(server->output_layout, output->wlr_output); struct wlr_scene_output *scene_output = wlr_scene_output_create(server->scene, wlr_output); wlr_scene_output_layout_add_output(server->scene_layout, l_layout, scene_output); wlr_output_layout_get_box(server->output_layout, output->wlr_output, &output->geometry); @@ -141,8 +143,8 @@ void server_xwayland_ready(struct wl_listener *listener, void *data) struct wlr_xcursor *xcursor; if ((xcursor = wlr_xcursor_manager_get_xcursor(server->cursor_mgr, "default", 1))) { struct wlr_buffer *buffer = wlr_xcursor_image_get_buffer(xcursor->images[0]); - wlr_xwayland_set_cursor(server->xwayland, buffer, - xcursor->images[0]->hotspot_x, xcursor->images[0]->hotspot_y); + wlr_xwayland_set_cursor(server->xwayland, buffer, xcursor->images[0]->hotspot_x, + xcursor->images[0]->hotspot_y); } } @@ -155,9 +157,7 @@ void server_xwayland_new_surface(struct wl_listener *listener, void *data) toplevel->type = ABSINTHE_TOPLEVEL_X11; toplevel->server = server; toplevel->toplevel.x11 = surface; - toplevel->border_width = absinthe_toplevel_is_unmanaged(toplevel) - ? 0 - : ABSINTHE_TOPLEVEL_BORDER_WIDTH; + toplevel->border_width = absinthe_toplevel_is_unmanaged(toplevel) ? 0 : ABSINTHE_TOPLEVEL_BORDER_WIDTH; toplevel->destroy.notify = absinthe_toplevel_destroy; wl_signal_add(&surface->events.destroy, &toplevel->destroy); @@ -208,7 +208,8 @@ void server_cursor_button(struct wl_listener *listener, void *data) } else { double sx, sy; struct wlr_surface *surface = NULL; - struct absinthe_toplevel *toplevel = absinthe_toplevel_at(server, server->cursor->x, server->cursor->y, &surface, &sx, &sy); + struct absinthe_toplevel *toplevel = + absinthe_toplevel_at(server, server->cursor->x, server->cursor->y, &surface, &sx, &sy); if (!toplevel) goto handle; @@ -270,7 +271,8 @@ void server_cursor_axis(struct wl_listener *listener, void *data) { struct absinthe_server *server = wl_container_of(listener, server, cursor_axis); struct wlr_pointer_axis_event *event = data; - wlr_seat_pointer_notify_axis(server->seat, event->time_msec, event->orientation, event->delta, event->delta_discrete, event->source, event->relative_direction); + wlr_seat_pointer_notify_axis(server->seat, event->time_msec, event->orientation, event->delta, + event->delta_discrete, event->source, event->relative_direction); } void server_cursor_frame(struct wl_listener *listener, void *data) diff --git a/src/xdg-decoration.c b/src/xdg-decoration.c index a3c0cf3..2cf8e1f 100644 --- a/src/xdg-decoration.c +++ b/src/xdg-decoration.c @@ -7,7 +7,8 @@ void xdg_decoration_request_mode(struct wl_listener *listener, void *data) UNUSED(data); struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, decoration_request_mode); if (toplevel->toplevel.xdg->base->initialized) - wlr_xdg_toplevel_decoration_v1_set_mode(toplevel->decoration, WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); + wlr_xdg_toplevel_decoration_v1_set_mode(toplevel->decoration, + WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); } void xdg_decoration_destroy(struct wl_listener *listener, void *data) diff --git a/src/xdg-popup.c b/src/xdg-popup.c index 5c6763b..42a941b 100644 --- a/src/xdg-popup.c +++ b/src/xdg-popup.c @@ -1,5 +1,4 @@ #include - #include #include "types.h" diff --git a/src/xdg-toplevel.c b/src/xdg-toplevel.c index 9d207ca..751eae3 100644 --- a/src/xdg-toplevel.c +++ b/src/xdg-toplevel.c @@ -1,13 +1,12 @@ -#include #include - +#include #include #include -#include "types.h" #include "absinthe-toplevel.h" #include "layout.h" #include "output.h" +#include "types.h" #include "xdg-decoration.h" void xdg_toplevel_commit(struct wl_listener *listener, void *data) diff --git a/src/xwayland.c b/src/xwayland.c index 59e4ddd..f94969a 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -1,9 +1,10 @@ #ifdef XWAYLAND -#include "types.h" -#include "absinthe-toplevel.h" -#include "xdg-toplevel.h" #include "xwayland.h" +#include "absinthe-toplevel-handlers.h" +#include "absinthe-toplevel.h" +#include "types.h" +#include "xdg-toplevel.h" void xwayland_activate(struct wl_listener *listener, void *data) { @@ -47,8 +48,7 @@ void xwayland_configure(struct wl_listener *listener, void *data) if (absinthe_toplevel_is_unmanaged(toplevel)) { wlr_scene_node_set_position(&toplevel->scene_tree->node, event->x, event->y); - wlr_xwayland_surface_configure(toplevel->toplevel.x11, - event->x, event->y, event->width, event->height); + wlr_xwayland_surface_configure(toplevel->toplevel.x11, event->x, event->y, event->width, event->height); return; } } @@ -58,5 +58,4 @@ void xwayland_set_hints(struct wl_listener *listener, void *data) UNUSED(listener); UNUSED(data); } - #endif