From d4ca1dfb69dc8227e7637e4259f45088af476542 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Sat, 21 Feb 2026 12:55:30 -0500 Subject: [PATCH 001/146] view: make view_move_to_cursor() static --- include/view.h | 1 - src/action.c | 3 ++- src/view.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/view.h b/include/view.h index 7c4a24d9..77c2a0cb 100644 --- a/include/view.h +++ b/include/view.h @@ -486,7 +486,6 @@ void view_resize_relative(struct view *view, int left, int right, int top, int bottom); void view_move_relative(struct view *view, int x, int y); void view_move(struct view *view, int x, int y); -void view_move_to_cursor(struct view *view); void view_moved(struct view *view); void view_minimize(struct view *view, bool minimized); bool view_compute_centered_position(struct view *view, diff --git a/src/action.c b/src/action.c index 2f956d95..90535112 100644 --- a/src/action.c +++ b/src/action.c @@ -1354,7 +1354,8 @@ run_action(struct view *view, struct server *server, struct action *action, "Action MoveToCursor is deprecated. To ensure your config works in future labwc " "releases, please use "); if (view) { - view_move_to_cursor(view); + view_place_by_policy(view, /* allow_cursor */ true, + LAB_PLACE_CURSOR); } break; case ACTION_TYPE_SEND_TO_DESKTOP: diff --git a/src/view.c b/src/view.c index cb82ab22..ed9f133e 100644 --- a/src/view.c +++ b/src/view.c @@ -625,7 +625,7 @@ view_move_relative(struct view *view, int x, int y) view_move(view, view->pending.x + x, view->pending.y + y); } -void +static void view_move_to_cursor(struct view *view) { assert(view); From 7be407c8e495395803ac61666eadc35231add71d Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Sat, 21 Feb 2026 14:43:33 -0500 Subject: [PATCH 002/146] view: un-fullscreen/maximize/tile before any placement policy --- src/view.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/view.c b/src/view.c index ed9f133e..405263ff 100644 --- a/src/view.c +++ b/src/view.c @@ -634,12 +634,6 @@ view_move_to_cursor(struct view *view) if (!output_is_usable(pending_output)) { return; } - view_set_fullscreen(view, false); - view_maximize(view, VIEW_AXIS_NONE); - if (view_is_tiled(view)) { - view_set_untiled(view); - view_move_resize(view, view->natural_geometry); - } struct border margin = ssd_thickness(view); struct wlr_box geo = view->pending; @@ -1075,6 +1069,13 @@ void view_place_by_policy(struct view *view, bool allow_cursor, enum lab_placement_policy policy) { + view_set_fullscreen(view, false); + view_maximize(view, VIEW_AXIS_NONE); + if (view_is_tiled(view)) { + view_set_untiled(view); + view_move_resize(view, view->natural_geometry); + } + if (allow_cursor && policy == LAB_PLACE_CURSOR) { view_move_to_cursor(view); return; From 04cd38f251396385407a865507c02c8a77e31439 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Sat, 21 Feb 2026 14:45:58 -0500 Subject: [PATCH 003/146] view: factor out view_compute_near_cursor_position() --- src/view.c | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/view.c b/src/view.c index 405263ff..ad89515d 100644 --- a/src/view.c +++ b/src/view.c @@ -625,24 +625,12 @@ view_move_relative(struct view *view, int x, int y) view_move(view, view->pending.x + x, view->pending.y + y); } -static void -view_move_to_cursor(struct view *view) +static bool +view_compute_near_cursor_position(struct view *view, struct wlr_box *geom) { assert(view); struct output *pending_output = output_nearest_to_cursor(view->server); - if (!output_is_usable(pending_output)) { - return; - } - - struct border margin = ssd_thickness(view); - struct wlr_box geo = view->pending; - geo.width += margin.left + margin.right; - geo.height += margin.top + margin.bottom; - - int x = view->server->seat.cursor->x - (geo.width / 2); - int y = view->server->seat.cursor->y - (geo.height / 2); - struct wlr_box usable = output_usable_area_in_layout_coords(pending_output); /* Limit usable region to account for gap */ @@ -651,17 +639,26 @@ view_move_to_cursor(struct view *view) usable.width -= 2 * rc.gap; usable.height -= 2 * rc.gap; - if (x + geo.width > usable.x + usable.width) { - x = usable.x + usable.width - geo.width; + if (wlr_box_empty(geom) || wlr_box_empty(&usable)) { + return false; } - x = MAX(x, usable.x) + margin.left; - if (y + geo.height > usable.y + usable.height) { - y = usable.y + usable.height - geo.height; - } - y = MAX(y, usable.y) + margin.top; + struct border margin = ssd_thickness(view); + struct seat *seat = &view->server->seat; - view_move(view, x, y); + int total_width = geom->width + margin.left + margin.right; + int total_height = geom->height + margin.top + margin.bottom; + + int x = (int)seat->cursor->x - (total_width / 2); + int y = (int)seat->cursor->y - (total_height / 2); + + /* Order of MIN/MAX is significant here */ + x = MIN(x, usable.x + usable.width - total_width); + geom->x = MAX(x, usable.x) + margin.left; + y = MIN(y, usable.y + usable.height - total_height); + geom->y = MAX(y, usable.y) + margin.top; + + return true; } struct view_size_hints @@ -1077,8 +1074,11 @@ view_place_by_policy(struct view *view, bool allow_cursor, } if (allow_cursor && policy == LAB_PLACE_CURSOR) { - view_move_to_cursor(view); - return; + struct wlr_box geometry = view->pending; + if (view_compute_near_cursor_position(view, &geometry)) { + view_move(view, geometry.x, geometry.y); + return; + } } else if (policy == LAB_PLACE_AUTOMATIC) { struct wlr_box geometry = view->pending; if (placement_find_best(view, &geometry)) { From 6a9e6dcae11df17bc565eab4e7739329e4444a8f Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Sat, 21 Feb 2026 14:56:40 -0500 Subject: [PATCH 004/146] view: factor out view_compute_cascaded_position() --- src/view.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/view.c b/src/view.c index ad89515d..0aee1b00 100644 --- a/src/view.c +++ b/src/view.c @@ -978,13 +978,16 @@ view_center(struct view *view, const struct wlr_box *ref) * Algorithm based on KWin's implementation: * https://github.com/KDE/kwin/blob/df9f8f8346b5b7645578e37365dabb1a7b02ca5a/src/placement.cpp#L589 */ -static void -view_cascade(struct view *view) +static bool +view_compute_cascaded_position(struct view *view, struct wlr_box *geom) { /* "cascade" policy places a new view at center by default */ - struct wlr_box center = view->pending; - view_compute_centered_position(view, NULL, - center.width, center.height, ¢er.x, ¢er.y); + struct wlr_box center = *geom; + if (!view_compute_centered_position(view, NULL, center.width, + center.height, ¢er.x, ¢er.y)) { + return false; + } + struct border margin = ssd_get_margin(view->ssd); center.x -= margin.left; center.y -= margin.top; @@ -1059,7 +1062,9 @@ view_cascade(struct view *view) } } - view_move(view, candidate.x + margin.left, candidate.y + margin.top); + geom->x = candidate.x + margin.left; + geom->y = candidate.y + margin.top; + return true; } void @@ -1086,8 +1091,11 @@ view_place_by_policy(struct view *view, bool allow_cursor, return; } } else if (policy == LAB_PLACE_CASCADE) { - view_cascade(view); - return; + struct wlr_box geometry = view->pending; + if (view_compute_cascaded_position(view, &geometry)) { + view_move(view, geometry.x, geometry.y); + return; + } } view_center(view, NULL); From 5238dcaa088293d2b2c24f361caaa6addb152a9c Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Sat, 21 Feb 2026 15:06:02 -0500 Subject: [PATCH 005/146] view: factor out view_compute_position_by_policy() --- include/view.h | 8 ++++++++ src/view.c | 39 +++++++++++++++++++-------------------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/include/view.h b/include/view.h index 77c2a0cb..5353686b 100644 --- a/include/view.h +++ b/include/view.h @@ -514,6 +514,14 @@ int view_effective_height(struct view *view, bool use_pending); */ void view_center(struct view *view, const struct wlr_box *ref); +/* + * Like view_place_by_policy() but doesn't actually move the view. + * Returns false if position could not be computed (for example, if no + * outputs are connected). In that case, @geom is not modified. + */ +bool view_compute_position_by_policy(struct view *view, struct wlr_box *geom, + bool allow_cursor, enum lab_placement_policy policy); + /** * view_place_by_policy - apply placement strategy to view * @view: view to be placed diff --git a/src/view.c b/src/view.c index 0aee1b00..2a49973e 100644 --- a/src/view.c +++ b/src/view.c @@ -1067,6 +1067,22 @@ view_compute_cascaded_position(struct view *view, struct wlr_box *geom) return true; } +bool +view_compute_position_by_policy(struct view *view, struct wlr_box *geom, + bool allow_cursor, enum lab_placement_policy policy) +{ + if (allow_cursor && policy == LAB_PLACE_CURSOR) { + return view_compute_near_cursor_position(view, geom); + } else if (policy == LAB_PLACE_AUTOMATIC) { + return placement_find_best(view, geom); + } else if (policy == LAB_PLACE_CASCADE) { + return view_compute_cascaded_position(view, geom); + } else { + return view_compute_centered_position(view, NULL, + geom->width, geom->height, &geom->x, &geom->y); + } +} + void view_place_by_policy(struct view *view, bool allow_cursor, enum lab_placement_policy policy) @@ -1078,27 +1094,10 @@ view_place_by_policy(struct view *view, bool allow_cursor, view_move_resize(view, view->natural_geometry); } - if (allow_cursor && policy == LAB_PLACE_CURSOR) { - struct wlr_box geometry = view->pending; - if (view_compute_near_cursor_position(view, &geometry)) { - view_move(view, geometry.x, geometry.y); - return; - } - } else if (policy == LAB_PLACE_AUTOMATIC) { - struct wlr_box geometry = view->pending; - if (placement_find_best(view, &geometry)) { - view_move(view, geometry.x, geometry.y); - return; - } - } else if (policy == LAB_PLACE_CASCADE) { - struct wlr_box geometry = view->pending; - if (view_compute_cascaded_position(view, &geometry)) { - view_move(view, geometry.x, geometry.y); - return; - } + struct wlr_box geom = view->pending; + if (view_compute_position_by_policy(view, &geom, allow_cursor, policy)) { + view_move(view, geom.x, geom.y); } - - view_center(view, NULL); } void From 1211c43a472f2abb4ad669d9971a83133a8467fe Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Sat, 21 Feb 2026 15:14:32 -0500 Subject: [PATCH 006/146] view: honor placement policy in more scenarios --- src/view.c | 16 ++++------------ src/xdg.c | 6 ++---- src/xwayland.c | 9 +++------ 3 files changed, 9 insertions(+), 22 deletions(-) diff --git a/src/view.c b/src/view.c index 2a49973e..94c5c2a9 100644 --- a/src/view.c +++ b/src/view.c @@ -898,16 +898,8 @@ adjust_floating_geometry(struct view *view, struct wlr_box *geometry, } /* Reposition offscreen automatically if configured to do so */ - if (rc.placement_policy == LAB_PLACE_AUTOMATIC) { - if (placement_find_best(view, geometry)) { - return true; - } - } - - /* If automatic placement failed or was not enabled, just center */ - return view_compute_centered_position(view, NULL, - geometry->width, geometry->height, - &geometry->x, &geometry->y); + return view_compute_position_by_policy(view, geometry, + /* allow_cursor */ true, rc.placement_policy); } struct wlr_box @@ -917,8 +909,8 @@ view_get_fallback_natural_geometry(struct view *view) .width = VIEW_FALLBACK_WIDTH, .height = VIEW_FALLBACK_HEIGHT, }; - view_compute_centered_position(view, NULL, - box.width, box.height, &box.x, &box.y); + view_compute_position_by_policy(view, &box, + /* allow_cursor */ true, rc.placement_policy); return box; } diff --git a/src/xdg.c b/src/xdg.c index d3774801..84455efa 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -123,10 +123,8 @@ do_late_positioning(struct view *view) /* Reposition the view while anchoring it to cursor */ interactive_anchor_to_cursor(server, &view->pending); } else { - /* TODO: smart placement? */ - view_compute_centered_position(view, NULL, - view->pending.width, view->pending.height, - &view->pending.x, &view->pending.y); + view_compute_position_by_policy(view, &view->pending, + /* allow_cursor */ true, rc.placement_policy); } } diff --git a/src/xwayland.c b/src/xwayland.c index 707ab390..d04d7768 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -769,15 +769,12 @@ set_initial_position(struct view *view, /* allow_cursor */ true, rc.placement_policy); } else { /* - * View is maximized/fullscreen. Center the + * View is maximized/fullscreen. Place the * stored natural geometry without actually * moving the view. */ - view_compute_centered_position(view, NULL, - view->natural_geometry.width, - view->natural_geometry.height, - &view->natural_geometry.x, - &view->natural_geometry.y); + view_compute_position_by_policy(view, &view->natural_geometry, + /* allow_cursor */ true, rc.placement_policy); } } From 658df83280ea5a53a9a10cc73dd216f6518d5b6a Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Sun, 22 Feb 2026 23:06:07 -0500 Subject: [PATCH 007/146] xdg: set initial output at initial commit This seems to be the best point to do it, since the parent view is known but initial maximized/fullscreen state hasn't been applied yet. --- src/xdg.c | 45 ++++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/src/xdg.c b/src/xdg.c index 84455efa..02a0b683 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -55,6 +55,13 @@ xdg_toplevel_from_view(struct view *view) return xdg_surface->toplevel; } +static struct view * +xdg_toplevel_view_get_parent(struct view *view) +{ + struct wlr_xdg_toplevel *toplevel = xdg_toplevel_from_view(view); + return toplevel->parent ? toplevel->parent->base->data : NULL; +} + static struct view_size_hints xdg_toplevel_view_get_size_hints(struct view *view) { @@ -204,7 +211,15 @@ handle_commit(struct wl_listener *listener, void *data) | WLR_XDG_TOPLEVEL_WM_CAPABILITIES_MINIMIZE; wlr_xdg_toplevel_set_wm_capabilities(toplevel, wm_caps); - if (view->output) { + /* Put view on the same output as its parent if possible */ + struct view *parent = xdg_toplevel_view_get_parent(view); + if (parent && output_is_usable(parent->output)) { + view_set_output(view, parent->output); + } else { + view_set_output(view, output_nearest_to_cursor(view->server)); + } + + if (output_is_usable(view->output)) { wlr_xdg_toplevel_set_bounds(toplevel, view->output->usable_area.width, view->output->usable_area.height); @@ -498,9 +513,6 @@ handle_request_maximize(struct wl_listener *listener, void *data) return; } - if (!view->mapped && !output_is_usable(view->output)) { - view_set_output(view, output_nearest_to_cursor(view->server)); - } bool maximized = toplevel->requested.maximized; view_maximize(view, maximized ? VIEW_AXIS_BOTH : VIEW_AXIS_NONE); } @@ -519,9 +531,6 @@ handle_request_fullscreen(struct wl_listener *listener, void *data) return; } - if (!view->mapped && !output_is_usable(view->output)) { - view_set_output(view, output_nearest_to_cursor(view->server)); - } set_fullscreen_from_request(view, &xdg_toplevel_from_view(view)->requested); } @@ -634,14 +643,6 @@ xdg_toplevel_view_minimize(struct view *view, bool minimized) /* noop */ } -static struct view * -xdg_toplevel_view_get_parent(struct view *view) -{ - struct wlr_xdg_toplevel *toplevel = xdg_toplevel_from_view(view); - return toplevel->parent ? - (struct view *)toplevel->parent->base->data : NULL; -} - static struct wlr_xdg_toplevel * top_parent_of(struct view *view) { @@ -796,7 +797,6 @@ set_initial_position(struct view *view) struct view *parent = xdg_toplevel_view_get_parent(view); if (parent) { /* Child views are center-aligned relative to their parents */ - view_set_output(view, parent->output); view_center(view, &parent->pending); return; } @@ -813,14 +813,6 @@ handle_map(struct wl_listener *listener, void *data) return; } - /* - * An output should have been chosen when the surface was first - * created, but take one more opportunity to assign an output if not. - */ - if (!output_is_usable(view->output)) { - view_set_output(view, output_nearest_to_cursor(view->server)); - } - view->mapped = true; if (!view->been_mapped) { @@ -1009,9 +1001,12 @@ handle_new_xdg_toplevel(struct wl_listener *listener, void *data) * Pick an output for the surface as soon as its created, so that the * client can be notified about any fractional scale before it is given * the chance to configure itself (and possibly pick its dimensions). + * + * FIXME: this may be the wrong output since the parent view isn't + * known yet. The correct output will be set at initial commit. */ view_set_output(view, output_nearest_to_cursor(server)); - if (view->output) { + if (output_is_usable(view->output)) { wlr_fractional_scale_v1_notify_scale(xdg_surface->surface, view->output->wlr_output->scale); } From 3f223fe5b08c2ae780cb703fbc16ebf487e5fa69 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Sat, 21 Feb 2026 15:36:47 -0500 Subject: [PATCH 008/146] xdg: unify initial positioning logic --- src/xdg.c | 77 +++++++++++++++++-------------------------------------- 1 file changed, 23 insertions(+), 54 deletions(-) diff --git a/src/xdg.c b/src/xdg.c index 02a0b683..a756f9de 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -121,17 +121,32 @@ set_fullscreen_from_request(struct view *view, view_set_fullscreen(view, requested->fullscreen); } +/* Called from commit handler and updates view->pending.x/y directly */ static void -do_late_positioning(struct view *view) +set_initial_position(struct view *view) { + if (!view_is_floating(view)) { + return; + } + + view_constrain_size_to_that_of_usable_area(view); + struct server *server = view->server; if (server->input_mode == LAB_INPUT_STATE_MOVE && view == server->grabbed_view) { /* Reposition the view while anchoring it to cursor */ interactive_anchor_to_cursor(server, &view->pending); } else { - view_compute_position_by_policy(view, &view->pending, - /* allow_cursor */ true, rc.placement_policy); + struct view *parent = xdg_toplevel_view_get_parent(view); + if (parent) { + /* Center relative to parent view */ + view_compute_centered_position(view, &parent->pending, + view->pending.width, view->pending.height, + &view->pending.x, &view->pending.y); + } else { + view_compute_position_by_policy(view, &view->pending, + /* allow_cursor */ true, rc.placement_policy); + } } } @@ -247,15 +262,15 @@ handle_commit(struct wl_listener *listener, void *data) bool update_required = false; /* - * If we didn't know the natural size when leaving fullscreen or - * unmaximizing, then the pending size will be 0x0. In this case, - * the pending x/y is also unset and we still need to position - * the window. + * The pending size will be empty in two cases: + * (1) when the view is first mapped + * (2) when leaving fullscreen or un-maximizing, + * if natural geometry wasn't known */ if (wlr_box_empty(&view->pending) && !wlr_box_empty(&size)) { view->pending.width = size.width; view->pending.height = size.height; - do_late_positioning(view); + set_initial_position(view); update_required = true; } @@ -789,22 +804,6 @@ xdg_toplevel_view_notify_tiled(struct view *view) } } -static void -set_initial_position(struct view *view) -{ - view_constrain_size_to_that_of_usable_area(view); - - struct view *parent = xdg_toplevel_view_get_parent(view); - if (parent) { - /* Child views are center-aligned relative to their parents */ - view_center(view, &parent->pending); - return; - } - - /* All other views are placed according to a configured strategy */ - view_place_by_policy(view, /* allow_cursor */ true, rc.placement_policy); -} - static void handle_map(struct wl_listener *listener, void *data) { @@ -821,36 +820,6 @@ handle_map(struct wl_listener *listener, void *data) } else { view_set_ssd_mode(view, LAB_SSD_MODE_NONE); } - - /* - * Set initial "pending" dimensions. "Current" - * dimensions remain zero until handle_commit(). - */ - if (wlr_box_empty(&view->pending)) { - struct wlr_xdg_surface *xdg_surface = - xdg_surface_from_view(view); - view->pending.width = xdg_surface->geometry.width; - view->pending.height = xdg_surface->geometry.height; - } - - /* - * Set initial "pending" position for floating views. - */ - if (view_is_floating(view)) { - set_initial_position(view); - } - - /* Disable background fill at map (paranoid?) */ - disable_fullscreen_bg(view); - - /* - * Set initial "current" position directly before - * calling view_moved() to reduce flicker - */ - view->current.x = view->pending.x; - view->current.y = view->pending.y; - - view_moved(view); } view_impl_map(view); From df73a97efa6678f555ac1813115d6859558d1e77 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Tue, 24 Feb 2026 11:29:00 -0500 Subject: [PATCH 009/146] view: add/improve some comments --- include/view.h | 19 +++++++++++++++---- src/view.c | 6 +++++- src/xdg.c | 5 +++-- src/xwayland.c | 8 ++++++++ 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/include/view.h b/include/view.h index 5353686b..f5590fa2 100644 --- a/include/view.h +++ b/include/view.h @@ -514,10 +514,17 @@ int view_effective_height(struct view *view, bool use_pending); */ void view_center(struct view *view, const struct wlr_box *ref); -/* - * Like view_place_by_policy() but doesn't actually move the view. - * Returns false if position could not be computed (for example, if no - * outputs are connected). In that case, @geom is not modified. +/** + * view_compute_position_by_policy() - compute view placement + * @view: view to be placed + * @geom: floating view geometry to update (in/out) + * @allow_cursor: set to false to ignore center-on-cursor policy + * @policy: placement policy to apply + * + * Computes floating view placement according to configured strategy. + * Unlike view_place_by_policy(), this function doesn't actually move + * the view. It returns false if position could not be computed (e.g. + * if no outputs are connected). In that case, @geom is not modified. */ bool view_compute_position_by_policy(struct view *view, struct wlr_box *geom, bool allow_cursor, enum lab_placement_policy policy); @@ -527,6 +534,10 @@ bool view_compute_position_by_policy(struct view *view, struct wlr_box *geom, * @view: view to be placed * @allow_cursor: set to false to ignore center-on-cursor policy * @policy: placement policy to apply + * + * Places a floating view according to configured placement strategy. + * Clears any maximized/fullscreen/tiled state and restores natural + * geometry of the view before positioning. */ void view_place_by_policy(struct view *view, bool allow_cursor, enum lab_placement_policy policy); diff --git a/src/view.c b/src/view.c index 94c5c2a9..ecbcb7a1 100644 --- a/src/view.c +++ b/src/view.c @@ -652,7 +652,11 @@ view_compute_near_cursor_position(struct view *view, struct wlr_box *geom) int x = (int)seat->cursor->x - (total_width / 2); int y = (int)seat->cursor->y - (total_height / 2); - /* Order of MIN/MAX is significant here */ + /* + * Order of MIN/MAX is significant here (so that the top-left + * corner of the view remains visible even if the view is larger + * than the usable output area) + */ x = MIN(x, usable.x + usable.width - total_width); geom->x = MAX(x, usable.x) + margin.left; y = MIN(y, usable.y + usable.height - total_height); diff --git a/src/xdg.c b/src/xdg.c index a756f9de..b2889a21 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -264,8 +264,9 @@ handle_commit(struct wl_listener *listener, void *data) /* * The pending size will be empty in two cases: * (1) when the view is first mapped - * (2) when leaving fullscreen or un-maximizing, - * if natural geometry wasn't known + * (2) when leaving fullscreen or un-maximizing, if the view + * was initially fullscreen/maximized and the natural + * geometry isn't known yet */ if (wlr_box_empty(&view->pending) && !wlr_box_empty(&size)) { view->pending.width = size.width; diff --git a/src/xwayland.c b/src/xwayland.c index d04d7768..5ddff9df 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -772,6 +772,14 @@ set_initial_position(struct view *view, * View is maximized/fullscreen. Place the * stored natural geometry without actually * moving the view. + * + * FIXME: this positioning will be slightly off + * since it uses border widths computed for the + * current (non-floating) state of the view. + * Possible fixes would be (1) adjust the natural + * geometry earlier, while still floating, or + * (2) add a variant of ssd_thickness() that + * disregards the current view state. */ view_compute_position_by_policy(view, &view->natural_geometry, /* allow_cursor */ true, rc.placement_policy); From 00f63622b566e8d6d7cf90932251dbf2f1207a5a Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Tue, 24 Feb 2026 16:05:30 +0900 Subject: [PATCH 010/146] interactive: subtle refactor to interactive_set_grab_context() - Add `server` argument to `interactive_set_grab_context()` to clarify it updates something in `server`. - Add `const` qualifier to `ctx` argument of `interactive_set_grab_context()` and `cursor_get_resize_edges()` --- include/input/cursor.h | 2 +- include/labwc.h | 3 ++- src/action.c | 4 ++-- src/input/cursor.c | 4 ++-- src/interactive.c | 3 +-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/input/cursor.h b/include/input/cursor.h index 12b96aac..aa5c77af 100644 --- a/include/input/cursor.h +++ b/include/input/cursor.h @@ -92,7 +92,7 @@ void cursor_context_save(struct cursor_context_saved *saved_ctx, * keyboard modifier or when using the Resize action from a keybind. */ enum lab_edge cursor_get_resize_edges(struct wlr_cursor *cursor, - struct cursor_context *ctx); + const struct cursor_context *ctx); /** * cursor_get_from_edge - translate lab_edge enum to lab_cursor enum diff --git a/include/labwc.h b/include/labwc.h index 88860de2..728deaf9 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -411,7 +411,8 @@ void seat_focus_override_end(struct seat *seat, bool restore_focus); */ void interactive_anchor_to_cursor(struct server *server, struct wlr_box *geo); -void interactive_set_grab_context(struct cursor_context *ctx); +void interactive_set_grab_context(struct server *server, + const struct cursor_context *ctx); void interactive_begin(struct view *view, enum input_mode mode, enum lab_edge edges); void interactive_finish(struct view *view); diff --git a/src/action.c b/src/action.c index 90535112..dd6011ce 100644 --- a/src/action.c +++ b/src/action.c @@ -1268,7 +1268,7 @@ run_action(struct view *view, struct server *server, struct action *action, * Move, set it now from current cursor position. */ if (view != server->seat.pressed.ctx.view) { - interactive_set_grab_context(ctx); + interactive_set_grab_context(server, ctx); } interactive_begin(view, LAB_INPUT_STATE_MOVE, LAB_EDGE_NONE); @@ -1299,7 +1299,7 @@ run_action(struct view *view, struct server *server, struct action *action, * Resize, set it now from current cursor position. */ if (view != server->seat.pressed.ctx.view) { - interactive_set_grab_context(ctx); + interactive_set_grab_context(server, ctx); } interactive_begin(view, LAB_INPUT_STATE_RESIZE, resize_edges); diff --git a/src/input/cursor.c b/src/input/cursor.c index 98679565..ababb2cd 100644 --- a/src/input/cursor.c +++ b/src/input/cursor.c @@ -604,7 +604,7 @@ cursor_update_common(struct server *server, const struct cursor_context *ctx, } enum lab_edge -cursor_get_resize_edges(struct wlr_cursor *cursor, struct cursor_context *ctx) +cursor_get_resize_edges(struct wlr_cursor *cursor, const struct cursor_context *ctx) { enum lab_edge resize_edges = node_type_to_edges(ctx->type); if (ctx->view && !resize_edges) { @@ -1147,7 +1147,7 @@ cursor_process_button_press(struct seat *seat, uint32_t button, uint32_t time_ms if (ctx.view || ctx.surface) { /* Store cursor context for later action processing */ cursor_context_save(&seat->pressed, &ctx); - interactive_set_grab_context(&ctx); + interactive_set_grab_context(server, &ctx); } if (server->input_mode == LAB_INPUT_STATE_MENU) { diff --git a/src/interactive.c b/src/interactive.c index 28f428e7..efbe54b2 100644 --- a/src/interactive.c +++ b/src/interactive.c @@ -60,12 +60,11 @@ interactive_anchor_to_cursor(struct server *server, struct wlr_box *geo) * then interactive_begin() is called. */ void -interactive_set_grab_context(struct cursor_context *ctx) +interactive_set_grab_context(struct server *server, const struct cursor_context *ctx) { if (!ctx->view) { return; } - struct server *server = ctx->view->server; if (server->input_mode != LAB_INPUT_STATE_PASSTHROUGH) { return; } From d6dab9139f97a5e48f6d5e138f8f20f002c00e43 Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Tue, 24 Feb 2026 16:08:13 +0900 Subject: [PATCH 011/146] action: reorder ACTION_TYPE_MOVE enum entry This makes the code a bit easier to read by aligning ACTION_TYPE_MOVE and ACTION_TYPE_MOVE together. --- src/action.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/action.c b/src/action.c index dd6011ce..a195f67c 100644 --- a/src/action.c +++ b/src/action.c @@ -97,9 +97,9 @@ enum action_type { ACTION_TYPE_FOCUS, ACTION_TYPE_UNFOCUS, ACTION_TYPE_ICONIFY, - ACTION_TYPE_MOVE, ACTION_TYPE_RAISE, ACTION_TYPE_LOWER, + ACTION_TYPE_MOVE, ACTION_TYPE_RESIZE, ACTION_TYPE_RESIZE_RELATIVE, ACTION_TYPE_MOVETO, @@ -1260,6 +1260,16 @@ run_action(struct view *view, struct server *server, struct action *action, view_minimize(view, true); } break; + case ACTION_TYPE_RAISE: + if (view) { + view_move_to_front(view); + } + break; + case ACTION_TYPE_LOWER: + if (view) { + view_move_to_back(view); + } + break; case ACTION_TYPE_MOVE: if (view) { /* @@ -1274,16 +1284,6 @@ run_action(struct view *view, struct server *server, struct action *action, LAB_EDGE_NONE); } break; - case ACTION_TYPE_RAISE: - if (view) { - view_move_to_front(view); - } - break; - case ACTION_TYPE_LOWER: - if (view) { - view_move_to_back(view); - } - break; case ACTION_TYPE_RESIZE: if (view) { /* From 8d8654db021732f9a67314b0dcd0cf1c89be7f44 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Thu, 5 Mar 2026 15:01:58 +0100 Subject: [PATCH 012/146] action: sync action arrays The previous commit desynchronized the action type arrays causing Move operations to be treated as Raise actions. Fixes: #3398 Reported-By: Domo via IRC --- src/action.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/action.c b/src/action.c index a195f67c..6d8c8419 100644 --- a/src/action.c +++ b/src/action.c @@ -68,6 +68,7 @@ struct action_arg_list { struct wl_list value; }; +/* Warning: Any change in this enum needs to be reflected in the action_names[] array below */ enum action_type { ACTION_TYPE_INVALID = 0, ACTION_TYPE_NONE, @@ -137,6 +138,7 @@ enum action_type { ACTION_TYPE_HIDE_CURSOR, }; +/* Warning: Any change in this array needs to be reflected in the action_type enum above */ const char *action_names[] = { "INVALID", "None", @@ -166,9 +168,9 @@ const char *action_names[] = { "Focus", "Unfocus", "Iconify", - "Move", "Raise", "Lower", + "Move", "Resize", "ResizeRelative", "MoveTo", From 9de35d7b4fbf95c5ed999bfe61d222022b50550e Mon Sep 17 00:00:00 2001 From: Tobias Bengfort Date: Sat, 7 Mar 2026 04:29:29 +0100 Subject: [PATCH 013/146] src/server.c: fix name of xdg-dialog-v1 global for sandbox permission --- src/server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server.c b/src/server.c index 93d95503..b8abc633 100644 --- a/src/server.c +++ b/src/server.c @@ -277,7 +277,7 @@ allow_for_sandbox(const struct wlr_security_context_v1_state *security_state, "zxdg_importer_v1", "zxdg_importer_v2", "xdg_toplevel_icon_manager_v1", - "xdg_dialog_v1", + "xdg_wm_dialog_v1", /* plus */ "wp_alpha_modifier_v1", "wp_linux_drm_syncobj_manager_v1", From 1f776466a886dbbe99a5d8568475f3740bffb3df Mon Sep 17 00:00:00 2001 From: Alexander Ziaee Date: Fri, 6 Mar 2026 18:12:13 -0500 Subject: [PATCH 014/146] labwc-config.5: document mouse cursor variables It was written that mouse cursor size can be set with XCURSOR_SIZE. However, XCURSOR_THEME is also required, which exists in the context of XCURSOR_PATH. Break them down in the ENVIRONMENT VARIABLES section. Reported by: Consolatis (PATH) Reported by: Jan Beich (THEME) Reported by: Thomas Dickey (SIZE) --- docs/labwc-config.5.scd | 22 +++++++++++++++++++--- docs/labwc.1.scd | 2 +- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index e72354a3..ea740693 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -1429,9 +1429,25 @@ situation. ## ENVIRONMENT VARIABLES -*XCURSOR_THEME* and *XCURSOR_SIZE* are supported to set cursor theme -and size respectively. The default size is 24. System cursor themes can -typically be found with a command such as: +*XCURSOR_PATH* + Specify a colon-separated list of paths to look for mouse cursors in. + Default + ~/.local/share/icons: + ~/.icons: + /usr/share/icons: + /usr/share/pixmaps: + ~/.cursors: + /usr/share/cursors/xorg-x11: + /usr/X11R6/lib/X11/icons: + +*XCURSOR_SIZE* + Specify an alternative mouse cursor size in pixels. Requires + XCURSOR_THEME to be set also. Default 24. + +*XCURSOR_THEME* + Specify a mouse cursor theme within XCURSOR_PATH. + +System cursor themes can typically be found with a command such as: ``` find /usr/share/icons/ -type d -name "cursors" diff --git a/docs/labwc.1.scd b/docs/labwc.1.scd index 4840c0fa..2dab30a5 100644 --- a/docs/labwc.1.scd +++ b/docs/labwc.1.scd @@ -141,7 +141,7 @@ example: *LABWC_DEBUG_FOO=1 labwc*. *LABWC_DEBUG_KEY_STATE* Enable logging of press and release events for bound keys (generally - key-combinations like *Ctrl-Alt-t*) + key-combinations like *Ctrl-Alt-t*). # SEE ALSO From 3bb4ccd22d55a787d4e2288185ae547b1da324a3 Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Sun, 8 Mar 2026 18:44:59 +0900 Subject: [PATCH 015/146] view: save `view->last_placement` on initial positioning Fix a regression introduced in 3f223fe5 where output layout changes may move xdg views outside of the output layout with the error: `view has no last placement info`. This happens also for X11 views if they don't specify its own geometry on map. Recent changes introduced `view->last_placement` which is used to restore view positions after layout changes. This is supposed to be updated when a view is mapped or manually moved by the user. However, 3f223fe5 replaced `view_place_by_policy()` with `view_compute_position_by_policy()` in the xdg view map handler. Unlike `view_place_by_policy()`, this function does not update `view->last_placement`, leaving it unset at the time of output layout changes. Therefore, this patch adds explicit calls to `view_save_last_placement()` in the map handler to ensure `view->last_placement` is always set for mapped views. --- include/view.h | 8 ++++++++ src/view.c | 8 +++----- src/xdg.c | 2 ++ src/xwayland.c | 3 +++ 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/include/view.h b/include/view.h index f5590fa2..6c0fdf58 100644 --- a/include/view.h +++ b/include/view.h @@ -564,7 +564,15 @@ bool view_titlebar_visible(struct view *view); void view_set_ssd_mode(struct view *view, enum lab_ssd_mode mode); void view_set_decorations(struct view *view, enum lab_ssd_mode mode, bool force_ssd); void view_toggle_fullscreen(struct view *view); + +/* + * Saves the window position in view->last_placement. This should be called + * when a view is first mapped or manually moved by the user. + */ +void view_save_last_placement(struct view *view); +/* Restores and adjusts the view's position from the view->last_placement */ void view_adjust_for_layout_change(struct view *view); + void view_move_to_edge(struct view *view, enum lab_edge direction, bool snap_to_windows); void view_grow_to_edge(struct view *view, enum lab_edge direction); void view_shrink_to_edge(struct view *view, enum lab_edge direction); diff --git a/src/view.c b/src/view.c index ecbcb7a1..e833d264 100644 --- a/src/view.c +++ b/src/view.c @@ -568,8 +568,6 @@ view_moved(struct view *view) } } -static void save_last_placement(struct view *view); - void view_move_resize(struct view *view, struct wlr_box geo) { @@ -589,7 +587,7 @@ view_move_resize(struct view *view, struct wlr_box geo) * Not sure if it might have other side-effects though. */ if (!view->adjusting_for_layout_change) { - save_last_placement(view); + view_save_last_placement(view); } } @@ -1722,8 +1720,8 @@ view_set_fullscreen(struct view *view, bool fullscreen) cursor_update_focus(view->server); } -static void -save_last_placement(struct view *view) +void +view_save_last_placement(struct view *view) { assert(view); struct output *output = view->output; diff --git a/src/xdg.c b/src/xdg.c index b2889a21..d3b96d48 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -148,6 +148,8 @@ set_initial_position(struct view *view) /* allow_cursor */ true, rc.placement_policy); } } + + view_save_last_placement(view); } static void diff --git a/src/xwayland.c b/src/xwayland.c index 5ddff9df..6050c21b 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -786,6 +786,9 @@ set_initial_position(struct view *view, } } + /* view->last_placement is still unset if has_position=true */ + view_save_last_placement(view); + /* * Always make sure the view is onscreen and adjusted for any * layout changes that could have occurred between map_request From f0589810ad9227fc4faade31ccecbccb51e7a846 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Sat, 7 Mar 2026 18:40:14 +0100 Subject: [PATCH 016/146] src/cycle: handle views without output Fixes: #3425 Reported-By: kode54 --- src/cycle/cycle.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cycle/cycle.c b/src/cycle/cycle.c index cec5cac5..8d1c7612 100644 --- a/src/cycle/cycle.c +++ b/src/cycle/cycle.c @@ -346,8 +346,10 @@ init_cycle(struct server *server, struct cycle_filter filter) struct view *view; for_each_view(view, &server->views, criteria) { - if (!(cycle_outputs & view->output->id_bit)) { - continue; + if (filter.output != CYCLE_OUTPUT_ALL) { + if (!view->output || !(cycle_outputs & view->output->id_bit)) { + continue; + } } if (cycle_app_id && strcmp(view->app_id, cycle_app_id) != 0) { continue; From b36b4ab8161eb59c0bb731a2aba20d6d7588b42b Mon Sep 17 00:00:00 2001 From: Jonathan Marler Date: Tue, 10 Mar 2026 22:54:54 -0600 Subject: [PATCH 017/146] output: exit compositor when last nested output is destroyed When running on the X11 or Wayland backend, each output corresponds to a window in the parent compositor. Unlike DRM outputs, these cannot be reconnected after being destroyed. Terminate the compositor when the last output is destroyed on these nested backends, matching the expected behavior when the user closes the window. --- src/output.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/output.c b/src/output.c index f62dd87e..4533cab3 100644 --- a/src/output.c +++ b/src/output.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -195,6 +196,17 @@ handle_output_destroy(struct wl_listener *listener, void *data) */ output->wlr_output->data = NULL; + /* + * On nested backends (X11/Wayland), outputs correspond to + * windows and cannot be reconnected. Exit the compositor + * when the last one is destroyed. + */ + if (wl_list_empty(&server->outputs) + && (wlr_output_is_x11(output->wlr_output) + || wlr_output_is_wl(output->wlr_output))) { + wl_display_terminate(server->wl_display); + } + /* * output->scene_output (if still around at this point) is * destroyed automatically when the wlr_output is destroyed From 89574772d04d05fcb34bc2223db0093611d9154e Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Sat, 7 Mar 2026 16:51:24 +0100 Subject: [PATCH 018/146] src/output.c: handle outputs with all modes failing - To reset the mode request we were using wlr_output_state_set_mode(NULL) which is not allowed in wlroots. Replace it with removing the mode from the commit manually. - Before this patch, we would assume that we can't configure an output if it doesn't have any fixed mode. This is not true for wayland backed nested outputs. Replace the fixed return false with wlr_output_test_state(). - Prevent configuring the output if the test fails as the current behavior was a workaround for the hardcoded return false in case there were no fixed modes available. Fixes: #3428 Reported-By: kode54 --- src/output.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/output.c b/src/output.c index 4533cab3..d297f83b 100644 --- a/src/output.c +++ b/src/output.c @@ -374,8 +374,10 @@ output_test_auto(struct wlr_output *wlr_output, struct wlr_output_state *state, } /* Reset mode if none worked (we may still try to commit) */ - wlr_output_state_set_mode(state, NULL); - return false; + wlr_log(WLR_DEBUG, "no working fixed mode found for output %s", wlr_output->name); + state->committed &= ~WLR_OUTPUT_STATE_MODE; + + return wlr_output_test_state(wlr_output, state); } static void @@ -390,10 +392,8 @@ configure_new_output(struct server *server, struct output *output) /* is_client_request */ false)) { wlr_log(WLR_INFO, "mode test failed for output %s", wlr_output->name); - /* - * Continue anyway. For some reason, the test fails when - * running nested, yet the following commit succeeds. - */ + wlr_output_state_set_enabled(&output->pending, false); + return; } if (rc.adaptive_sync == LAB_ADAPTIVE_SYNC_ENABLED) { From 93029ca5830f4952b39e763cd1f17ed62d019798 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Wed, 11 Mar 2026 14:51:20 +0100 Subject: [PATCH 019/146] src/output.c: guard against wlroots not providing the X11 backend Reported-By: Flrian via IRC --- src/output.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/output.c b/src/output.c index d297f83b..addb2706 100644 --- a/src/output.c +++ b/src/output.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include @@ -39,6 +39,10 @@ #include "view.h" #include "xwayland.h" +#if WLR_HAS_X11_BACKEND +#include +#endif + bool output_get_tearing_allowance(struct output *output) { @@ -201,9 +205,12 @@ handle_output_destroy(struct wl_listener *listener, void *data) * windows and cannot be reconnected. Exit the compositor * when the last one is destroyed. */ - if (wl_list_empty(&server->outputs) - && (wlr_output_is_x11(output->wlr_output) - || wlr_output_is_wl(output->wlr_output))) { + if (wl_list_empty(&server->outputs) && ( + wlr_output_is_wl(output->wlr_output) +#if WLR_HAS_X11_BACKEND + || wlr_output_is_x11(output->wlr_output) +#endif + )) { wl_display_terminate(server->wl_display); } From ab60379c7f3e46655f1c81dc76f25adae0b6c6f9 Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Thu, 12 Mar 2026 00:48:10 +0900 Subject: [PATCH 020/146] ssd-titlebar: update title buffer when title gets empty Before this commit, ssd_update_title() returned early and the title was not updated when the title gets empty. Furthermore, this caused the title buffer to be misplaced outside of the titlebar when the window is resized. Reproducer: 1. Build and launch https://github.com/tokyo4j/wayland-demo/tree/repro-labwc-ssd-title-not-updated 2. One second later, the window title gets empty. But the title in SSD is not updated. 3. Un-minimize the window. Now the title buffer is misplaced outside of the titlebar. --- src/ssd/ssd-titlebar.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ssd/ssd-titlebar.c b/src/ssd/ssd-titlebar.c index 09f5362a..8e9fbc97 100644 --- a/src/ssd/ssd-titlebar.c +++ b/src/ssd/ssd-titlebar.c @@ -440,9 +440,8 @@ ssd_update_title(struct ssd *ssd) } struct view *view = ssd->view; - if (string_null_or_empty(view->title)) { - return; - } + /* view->title is never NULL (instead it can be an empty string) */ + assert(view->title); struct theme *theme = view->server->theme; struct ssd_state_title *state = &ssd->state.title; From a3646721bc6eacb63c0611a070ada35a9b4dacdc Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Thu, 12 Mar 2026 01:17:11 +0900 Subject: [PATCH 021/146] view: clear view->{title,app_id} later in view_destroy() ...as it *feels* unsafe to call functions like `undecorate()` after clearing view->{title,app_id}, which are expected to be non-NULL. --- src/view.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/view.c b/src/view.c index e833d264..0333d6e6 100644 --- a/src/view.c +++ b/src/view.c @@ -2501,9 +2501,6 @@ view_destroy(struct view *view) wl_list_remove(&view->set_title.link); wl_list_remove(&view->destroy.link); - zfree(view->title); - zfree(view->app_id); - if (view->foreign_toplevel) { foreign_toplevel_destroy(view->foreign_toplevel); view->foreign_toplevel = NULL; @@ -2558,6 +2555,9 @@ view_destroy(struct view *view) assert(wl_list_empty(&view->events.set_icon.listener_list)); assert(wl_list_empty(&view->events.destroy.listener_list)); + zfree(view->title); + zfree(view->app_id); + /* Remove view from server->views */ wl_list_remove(&view->link); free(view); From 4faab834f9e72b861b8fddbd20f104790c18db94 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Thu, 12 Mar 2026 13:08:18 +0100 Subject: [PATCH 022/146] xwayland: make X11 always-on-top request opt-in Fixes: #3441 --- docs/labwc-config.5.scd | 7 +++++++ include/window-rules.h | 1 + src/config/rcxml.c | 2 ++ src/view.c | 3 +++ src/window-rules.c | 4 ++++ src/xwayland.c | 12 ++++++++++-- 6 files changed, 27 insertions(+), 2 deletions(-) diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index ea740693..03d5fc24 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -1354,6 +1354,13 @@ situation. *ignoreConfigureRequest* prevents a X11 window to position and size itself. +** [yes|no|default] + *allowAlwaysOnTop* allows a X11 window to control its always-on-top + state ('above' in X11 terms). + + Note: X11 window always-on-top requests are disallowed by default. + This window rule offers a means of allowing it. + ** [yes|no|default] *fixedPosition* disallows interactive move/resize and prevents re-positioning in response to changes in reserved output space, which diff --git a/include/window-rules.h b/include/window-rules.h index 1bee4c09..624f3b85 100644 --- a/include/window-rules.h +++ b/include/window-rules.h @@ -40,6 +40,7 @@ struct window_rule { enum property ignore_configure_request; enum property fixed_position; enum property icon_prefer_client; + enum property allow_always_on_top; struct wl_list link; /* struct rcxml.window_rules */ }; diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 95285776..45093781 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -300,6 +300,8 @@ fill_window_rule(xmlNode *node) set_property(content, &window_rule->ignore_configure_request); } else if (!strcasecmp(key, "fixedPosition")) { set_property(content, &window_rule->fixed_position); + } else if (!strcasecmp(key, "allowAlwaysOnTop")) { + set_property(content, &window_rule->allow_always_on_top); } } diff --git a/src/view.c b/src/view.c index 0333d6e6..7eb381de 100644 --- a/src/view.c +++ b/src/view.c @@ -1543,6 +1543,9 @@ void view_set_layer(struct view *view, enum view_layer layer) { assert(view); + if (view->layer == layer) { + return; + } view->layer = layer; wlr_scene_node_reparent(&view->scene_tree->node, view->workspace->view_trees[layer]); diff --git a/src/window-rules.c b/src/window-rules.c index 0b8f1101..bfeacfe7 100644 --- a/src/window-rules.c +++ b/src/window-rules.c @@ -110,6 +110,10 @@ window_rules_get_property(struct view *view, const char *property) && !strcasecmp(property, "iconPreferClient")) { return rule->icon_prefer_client; } + if (rule->allow_always_on_top + && !strcasecmp(property, "allowAlwaysOnTop")) { + return rule->allow_always_on_top; + } } } return LAB_PROP_UNSPECIFIED; diff --git a/src/xwayland.c b/src/xwayland.c index 6050c21b..d16e41ac 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -431,6 +431,11 @@ handle_request_above(struct wl_listener *listener, void *data) wl_container_of(listener, xwayland_view, request_above); struct view *view = &xwayland_view->base; + if (window_rules_get_property(view, "allowAlwaysOnTop") != LAB_PROP_TRUE) { + wlr_log(WLR_INFO, "X11 client side always on top request rejected"); + return; + } + view_set_layer(view, xwayland_view->xwayland_surface->above ? VIEW_LAYER_ALWAYS_ON_TOP : VIEW_LAYER_NORMAL); } @@ -727,8 +732,11 @@ handle_map_request(struct wl_listener *listener, void *data) axis |= VIEW_AXIS_VERTICAL; } view_maximize(view, axis); - view_set_layer(view, xsurface->above - ? VIEW_LAYER_ALWAYS_ON_TOP : VIEW_LAYER_NORMAL); + + if (window_rules_get_property(view, "allowAlwaysOnTop") == LAB_PROP_TRUE) { + view_set_layer(view, xsurface->above + ? VIEW_LAYER_ALWAYS_ON_TOP : VIEW_LAYER_NORMAL); + } /* * We could also call set_initial_position() here, but it's not * really necessary until the view is actually mapped (and at From 7c39ee30e93f908f7c4b9285b72d18af06e9f122 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Thu, 12 Mar 2026 21:48:23 +0000 Subject: [PATCH 023/146] NEWS.md: update notes for 0.9.6 --- NEWS.md | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/NEWS.md b/NEWS.md index 79a3c918..3699c61c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,6 +9,8 @@ The format is based on [Keep a Changelog] | Date | All Changes | wlroots version | lines-of-code | |------------|---------------|-----------------|---------------| +| 2026-03-15 | [unreleased] | 0.19.2 | 29244 | +| 2026-03-15 | [0.9.6] | 0.19.2 | 29271 | | 2026-03-04 | [0.9.5] | 0.19.2 | 29251 | | 2026-02-27 | [0.9.4] | 0.19.2 | 29225 | | 2025-12-19 | [0.9.3] | 0.19.2 | 28968 | @@ -42,6 +44,7 @@ The format is based on [Keep a Changelog] | 2021-03-05 | [0.1.0] | 0.12.0 | 4627 | [unreleased]: NEWS.md#unreleased +[0.9.6]: NEWS.md#096---2026-03-15 [0.9.5]: NEWS.md#095---2026-03-04 [0.9.4]: NEWS.md#094---2026-02-27 [0.9.3]: NEWS.md#093---2025-12-19 @@ -112,6 +115,55 @@ There are some regression warnings worth noting for the switch to wlroots 0.19: [unreleased-commits] +### Fixed + +- Update titlebar title when set to empty and fix an associated issue causing + the title to be misplaced outside of the titlebar when the window is resized. + [#3443] @tokyo4j +- When running nested, exit compositor when last output is destroyed because + in this situation, each output corresponds to a window in the parent + compositor and, unlike DRM outputs, these cannot be reconnected after being + destroyed. [#3440] @marler8997 +- Allow policy-based placement to apply when an initially-maximized/fullscreen + view is restored to floating geometry. [#3387] @jlindgren90 + +## 0.9.6 - 2026-03-15 + +[0.9.6-commits] + +This is an earlier-than-usual release containing bug fixes only. It has been +done on a separate branch (0.9.5-maintenance) to avoid the inclusion of +refactoring and new features. + +``` + 0.9.6 <--- bug-fixes only + / + / +0.9.4--------0.9.5-------- <-- master +``` + +### Fixed + +- Disable outputs where all modes fail [#3428] [#3429] @Consolatis @kode54 +- Fix regression in `0.9.4` that causes `NextWindow` action to segfault when + no outputs are connected. This fixes a window-switcher crash with some + Nvidia GPUs/drivers after suspend [#3425] [#3430] @Consolatis +- Fix typo to allow `xdg-dialog-v1` global [#3426] @xi + +### Changed + +- Disallow X11 window always-on-top requests by default to fix an issue whereby + Alt+Tab cannot be used to switch to other windows when using some XWayland + Wine games [#3441]. Add window-rule property `allowAlwaysOnTop` to optionally + allow this always-on-top requests. Add the snippet below to the `rc.xml` file + to restore the previous behaviour. [#3445] @Consolatis + +``` + + + +``` + ## 0.9.5 - 2026-03-04 [0.9.5-commits] @@ -2608,6 +2660,7 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 [Keep a Changelog]: https://keepachangelog.com/en/1.0.0/ [unreleased-commits]: https://github.com/labwc/labwc/compare/0.9.5...HEAD +[0.9.6-commits]: https://github.com/labwc/labwc/compare/0.9.5...0.9.6 [0.9.5-commits]: https://github.com/labwc/labwc/compare/0.9.4...0.9.5 [0.9.4-commits]: https://github.com/labwc/labwc/compare/0.9.3...0.9.4 [0.9.3-commits]: https://github.com/labwc/labwc/compare/0.9.2...0.9.3 @@ -3135,8 +3188,18 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 [#3365]: https://github.com/labwc/labwc/pull/3365 [#3372]: https://github.com/labwc/labwc/pull/3372 [#3373]: https://github.com/labwc/labwc/pull/3373 +[#3387]: https://github.com/labwc/labwc/pull/3387 [#3400]: https://github.com/labwc/labwc/pull/3400 [#3406]: https://github.com/labwc/labwc/pull/3406 [#3410]: https://github.com/labwc/labwc/pull/3410 [#3411]: https://github.com/labwc/labwc/pull/3411 [#3412]: https://github.com/labwc/labwc/pull/3412 +[#3425]: https://github.com/labwc/labwc/pull/3425 +[#3426]: https://github.com/labwc/labwc/pull/3426 +[#3428]: https://github.com/labwc/labwc/pull/3428 +[#3429]: https://github.com/labwc/labwc/pull/3429 +[#3430]: https://github.com/labwc/labwc/pull/3430 +[#3440]: https://github.com/labwc/labwc/pull/3440 +[#3441]: https://github.com/labwc/labwc/pull/3441 +[#3443]: https://github.com/labwc/labwc/pull/3443 +[#3445]: https://github.com/labwc/labwc/pull/3445 From 5a9ae663322941b90143e31dc95ddffd80880e0a Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Sun, 15 Mar 2026 11:36:59 +0000 Subject: [PATCH 024/146] labnag.c: initialize sigset_t mask --- clients/labnag.c | 1 + 1 file changed, 1 insertion(+) diff --git a/clients/labnag.c b/clients/labnag.c index 31ac4e9d..237ee958 100644 --- a/clients/labnag.c +++ b/clients/labnag.c @@ -1388,6 +1388,7 @@ nag_setup(struct nag *nag) } sigset_t mask; + sigemptyset(&mask); sigaddset(&mask, SIGINT); sigaddset(&mask, SIGTERM); sigprocmask(SIG_BLOCK, &mask, NULL); From c4effef0ec918f9f269d260dd02741d5d33621a6 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Sat, 14 Mar 2026 02:34:23 -0400 Subject: [PATCH 025/146] xwayland: fix missing title and icon with override-redirect toggle When an X11 client clears override-redirect on a window (i.e. it becomes "managed") without an unmap/map cycle, wlroots doesn't re-emit the set_title/class/icon events. We need to synthesize them to re-read the values from the surface. From what I can tell, only older/misbehaving X11 clients would actually do this (toggle override-redirect without unmap/map), so this is perhaps a bit pedantic, but an easy fix anyway. --- src/xwayland.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/xwayland.c b/src/xwayland.c index d16e41ac..77eaf3a1 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -1091,6 +1091,16 @@ xwayland_view_create(struct server *server, if (xsurface->surface) { handle_associate(&xwayland_view->associate, NULL); + /* + * If a surface is already associated, then we've + * missed the various initial set_* events as well. + * + * TODO: update_icon() -> handle_set_icon() after + * https://github.com/labwc/labwc/pull/2760 + */ + handle_set_title(&view->set_title, NULL); + handle_set_class(&xwayland_view->set_class, NULL); + update_icon(xwayland_view); } if (mapped) { handle_map(&xwayland_view->base.mappable.map, NULL); From 16c5373be5eafad3d3b854341d39b68c8d21203d Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Mon, 23 Feb 2026 16:34:36 -0500 Subject: [PATCH 026/146] tree-wide: use die_if_null() for wlr_scene alloc failures wlr_scene_*_create() functions all allocate memory via calloc() and return NULL if the allocation fails. Previously, the failures were handled in any of 3 different ways: - sending a wayland protocol error - exiting labwc with an error - segfault (no NULL check at all) Since labwc does not attempt to survive heap exhaustion in other allocation paths (such as `znew`), it seems more consistent to use the same die_if_null() check used in those paths to exit with an error. For the three most common create() functions (tree, rect, buffer), add small lab_wlr_ wrappers to common/scene-helpers. --- include/common/scene-helpers.h | 8 ++++++++ src/common/lab-scene-rect.c | 15 ++++++++------- src/common/scene-helpers.c | 29 +++++++++++++++++++++++++++++ src/cycle/cycle.c | 2 +- src/cycle/osd-classic.c | 13 +++++++------ src/cycle/osd-scroll.c | 3 ++- src/cycle/osd-thumbnail.c | 11 ++++++----- src/dnd.c | 3 ++- src/input/ime.c | 5 ++++- src/layers.c | 23 ++--------------------- src/menu/menu.c | 24 ++++++++++++------------ src/output.c | 8 ++++---- src/scaled-buffer/scaled-buffer.c | 8 ++------ src/server.c | 18 +++++++++--------- src/session-lock.c | 25 ++++++------------------- src/ssd/resize-indicator.c | 7 ++++--- src/ssd/ssd-border.c | 13 +++++++------ src/ssd/ssd-button.c | 5 +++-- src/ssd/ssd-extents.c | 11 ++++++----- src/ssd/ssd-shadow.c | 7 ++++--- src/ssd/ssd-titlebar.c | 12 ++++++------ src/ssd/ssd.c | 3 ++- src/workspaces.c | 11 ++++++----- src/xdg-popup.c | 2 ++ src/xdg.c | 13 +++++-------- src/xwayland-unmanaged.c | 8 +++++--- src/xwayland.c | 9 +++------ 27 files changed, 155 insertions(+), 141 deletions(-) diff --git a/include/common/scene-helpers.h b/include/common/scene-helpers.h index 453052fb..3b9b9521 100644 --- a/include/common/scene-helpers.h +++ b/include/common/scene-helpers.h @@ -4,6 +4,7 @@ #include +struct wlr_buffer; struct wlr_scene_node; struct wlr_surface; struct wlr_scene_output; @@ -11,6 +12,13 @@ struct wlr_output_state; struct wlr_surface *lab_wlr_surface_from_node(struct wlr_scene_node *node); +/* variants of wlr_scene_*_create() functions that don't return NULL */ +struct wlr_scene_tree *lab_wlr_scene_tree_create(struct wlr_scene_tree *parent); +struct wlr_scene_rect *lab_wlr_scene_rect_create(struct wlr_scene_tree *parent, + int width, int height, const float color[static 4]); +struct wlr_scene_buffer *lab_wlr_scene_buffer_create( + struct wlr_scene_tree *parent, struct wlr_buffer *buffer); + /** * lab_get_prev_node - return previous (sibling) node * @node: node to find the previous node from diff --git a/src/common/lab-scene-rect.c b/src/common/lab-scene-rect.c index 2d0c7408..6689d48f 100644 --- a/src/common/lab-scene-rect.c +++ b/src/common/lab-scene-rect.c @@ -3,6 +3,7 @@ #include #include #include "common/mem.h" +#include "common/scene-helpers.h" struct border_scene { struct wlr_scene_tree *tree; @@ -26,20 +27,20 @@ lab_scene_rect_create(struct wlr_scene_tree *parent, rect->border_width = opts->border_width; rect->nr_borders = opts->nr_borders; rect->borders = znew_n(rect->borders[0], opts->nr_borders); - rect->tree = wlr_scene_tree_create(parent); + rect->tree = lab_wlr_scene_tree_create(parent); if (opts->bg_color) { - rect->fill = wlr_scene_rect_create(rect->tree, 0, 0, opts->bg_color); + rect->fill = lab_wlr_scene_rect_create(rect->tree, 0, 0, opts->bg_color); } for (int i = 0; i < rect->nr_borders; i++) { struct border_scene *border = &rect->borders[i]; float *color = opts->border_colors[i]; - border->tree = wlr_scene_tree_create(rect->tree); - border->top = wlr_scene_rect_create(border->tree, 0, 0, color); - border->right = wlr_scene_rect_create(border->tree, 0, 0, color); - border->bottom = wlr_scene_rect_create(border->tree, 0, 0, color); - border->left = wlr_scene_rect_create(border->tree, 0, 0, color); + border->tree = lab_wlr_scene_tree_create(rect->tree); + border->top = lab_wlr_scene_rect_create(border->tree, 0, 0, color); + border->right = lab_wlr_scene_rect_create(border->tree, 0, 0, color); + border->bottom = lab_wlr_scene_rect_create(border->tree, 0, 0, color); + border->left = lab_wlr_scene_rect_create(border->tree, 0, 0, color); } rect->node_destroy.notify = handle_node_destroy; diff --git a/src/common/scene-helpers.c b/src/common/scene-helpers.c index 517789c0..e9c80bb9 100644 --- a/src/common/scene-helpers.c +++ b/src/common/scene-helpers.c @@ -5,6 +5,7 @@ #include #include #include +#include "common/mem.h" #include "magnifier.h" #include "output.h" @@ -24,6 +25,34 @@ lab_wlr_surface_from_node(struct wlr_scene_node *node) return NULL; } +struct wlr_scene_tree * +lab_wlr_scene_tree_create(struct wlr_scene_tree *parent) +{ + struct wlr_scene_tree *tree = wlr_scene_tree_create(parent); + die_if_null(tree); + return tree; +} + +struct wlr_scene_rect * +lab_wlr_scene_rect_create(struct wlr_scene_tree *parent, + int width, int height, const float color[static 4]) +{ + struct wlr_scene_rect *rect = + wlr_scene_rect_create(parent, width, height, color); + die_if_null(rect); + return rect; +} + +struct wlr_scene_buffer * +lab_wlr_scene_buffer_create(struct wlr_scene_tree *parent, + struct wlr_buffer *buffer) +{ + struct wlr_scene_buffer *scene_buffer = + wlr_scene_buffer_create(parent, buffer); + die_if_null(scene_buffer); + return scene_buffer; +} + struct wlr_scene_node * lab_wlr_scene_get_prev_node(struct wlr_scene_node *node) { diff --git a/src/cycle/cycle.c b/src/cycle/cycle.c index 8d1c7612..ef323110 100644 --- a/src/cycle/cycle.c +++ b/src/cycle/cycle.c @@ -231,7 +231,7 @@ preview_selected_view(struct view *view) cycle->preview_node = &view->scene_tree->node; /* Create a dummy node at the original place of the previewed window */ - struct wlr_scene_rect *dummy_rect = wlr_scene_rect_create( + struct wlr_scene_rect *dummy_rect = lab_wlr_scene_rect_create( cycle->preview_node->parent, 0, 0, (float [4]) {0}); wlr_scene_node_place_below(&dummy_rect->node, cycle->preview_node); wlr_scene_node_set_enabled(&dummy_rect->node, false); diff --git a/src/cycle/osd-classic.c b/src/cycle/osd-classic.c index c9b5497d..3deeaa81 100644 --- a/src/cycle/osd-classic.c +++ b/src/cycle/osd-classic.c @@ -9,6 +9,7 @@ #include "common/lab-scene-rect.h" #include "common/list.h" #include "common/mem.h" +#include "common/scene-helpers.h" #include "common/string-helpers.h" #include "config/rcxml.h" #include "cycle.h" @@ -108,7 +109,7 @@ cycle_osd_classic_init(struct cycle_osd_output *osd_output) int h = workspace_name_h + nr_visible_views * switcher_theme->item_height + 2 * padding; - osd_output->tree = wlr_scene_tree_create(output->cycle_osd_tree); + osd_output->tree = lab_wlr_scene_tree_create(output->cycle_osd_tree); float *text_color = theme->osd_label_text_color; float *bg_color = theme->osd_bg_color; @@ -161,7 +162,7 @@ cycle_osd_classic_init(struct cycle_osd_output *osd_output) float *active_bg_color = switcher_theme->item_active_bg_color; float *active_border_color = switcher_theme->item_active_border_color; - osd_output->items_tree = wlr_scene_tree_create(osd_output->tree); + osd_output->items_tree = lab_wlr_scene_tree_create(osd_output->tree); /* Draw text for each node */ struct view *view; @@ -169,7 +170,7 @@ cycle_osd_classic_init(struct cycle_osd_output *osd_output) struct cycle_osd_classic_item *item = znew(*item); wl_list_append(&osd_output->items, &item->base.link); item->base.view = view; - item->base.tree = wlr_scene_tree_create(osd_output->items_tree); + item->base.tree = lab_wlr_scene_tree_create(osd_output->items_tree); node_descriptor_create(&item->base.tree->node, LAB_NODE_CYCLE_OSD_ITEM, NULL, item); /* @@ -191,8 +192,8 @@ cycle_osd_classic_init(struct cycle_osd_output *osd_output) int x = padding + switcher_theme->item_active_border_width + switcher_theme->item_padding_x; - item->normal_tree = wlr_scene_tree_create(item->base.tree); - item->active_tree = wlr_scene_tree_create(item->base.tree); + item->normal_tree = lab_wlr_scene_tree_create(item->base.tree); + item->active_tree = lab_wlr_scene_tree_create(item->base.tree); wlr_scene_node_set_enabled(&item->active_tree->node, false); /* Highlight around selected window's item */ @@ -209,7 +210,7 @@ cycle_osd_classic_init(struct cycle_osd_output *osd_output) wlr_scene_node_set_position(&highlight_rect->tree->node, padding, y); /* hitbox for mouse clicks */ - struct wlr_scene_rect *hitbox = wlr_scene_rect_create(item->base.tree, + struct wlr_scene_rect *hitbox = lab_wlr_scene_rect_create(item->base.tree, w - 2 * padding, switcher_theme->item_height, (float[4]) {0}); wlr_scene_node_set_position(&hitbox->node, padding, y); diff --git a/src/cycle/osd-scroll.c b/src/cycle/osd-scroll.c index 2bca8021..a1559932 100644 --- a/src/cycle/osd-scroll.c +++ b/src/cycle/osd-scroll.c @@ -2,6 +2,7 @@ #include #include #include "common/lab-scene-rect.h" +#include "common/scene-helpers.h" #include "labwc.h" #include "cycle.h" #include "output.h" @@ -23,7 +24,7 @@ cycle_osd_scroll_init(struct cycle_osd_output *osd_output, struct wlr_box bar_ar scroll->top_row_idx = 0; scroll->bar_area = bar_area; scroll->delta_y = delta_y; - scroll->bar_tree = wlr_scene_tree_create(osd_output->tree); + scroll->bar_tree = lab_wlr_scene_tree_create(osd_output->tree); wlr_scene_node_set_position(&scroll->bar_tree->node, bar_area.x, bar_area.y); diff --git a/src/cycle/osd-thumbnail.c b/src/cycle/osd-thumbnail.c index d5a0bf3e..bf6b6026 100644 --- a/src/cycle/osd-thumbnail.c +++ b/src/cycle/osd-thumbnail.c @@ -10,6 +10,7 @@ #include "common/lab-scene-rect.h" #include "common/list.h" #include "common/mem.h" +#include "common/scene-helpers.h" #include "cycle.h" #include "labwc.h" #include "node.h" @@ -138,7 +139,7 @@ create_item_scene(struct wlr_scene_tree *parent, struct view *view, struct cycle_osd_thumbnail_item *item = znew(*item); wl_list_append(&osd_output->items, &item->base.link); - struct wlr_scene_tree *tree = wlr_scene_tree_create(parent); + struct wlr_scene_tree *tree = lab_wlr_scene_tree_create(parent); node_descriptor_create(&tree->node, LAB_NODE_CYCLE_OSD_ITEM, NULL, item); item->base.tree = tree; item->base.view = view; @@ -155,14 +156,14 @@ create_item_scene(struct wlr_scene_tree *parent, struct view *view, item->active_bg = lab_scene_rect_create(tree, &opts); /* hitbox for mouse clicks */ - wlr_scene_rect_create(tree, switcher_theme->item_width, + lab_wlr_scene_rect_create(tree, switcher_theme->item_width, switcher_theme->item_height, (float[4]) {0}); /* thumbnail */ struct wlr_buffer *thumb_buffer = render_thumb(osd_output->output, view); if (thumb_buffer) { struct wlr_scene_buffer *thumb_scene_buffer = - wlr_scene_buffer_create(tree, thumb_buffer); + lab_wlr_scene_buffer_create(tree, thumb_buffer); wlr_buffer_drop(thumb_buffer); struct wlr_box thumb_box = box_fit_within( thumb_buffer->width, thumb_buffer->height, @@ -239,8 +240,8 @@ cycle_osd_thumbnail_init(struct cycle_osd_output *osd_output) &theme->osd_window_switcher_thumbnail; int padding = theme->osd_border_width + switcher_theme->padding; - osd_output->tree = wlr_scene_tree_create(output->cycle_osd_tree); - osd_output->items_tree = wlr_scene_tree_create(osd_output->tree); + osd_output->tree = lab_wlr_scene_tree_create(output->cycle_osd_tree); + osd_output->items_tree = lab_wlr_scene_tree_create(osd_output->tree); int nr_views = wl_list_length(&server->cycle.views); assert(nr_views > 0); diff --git a/src/dnd.c b/src/dnd.c index ff65cffa..6b4a5ac7 100644 --- a/src/dnd.c +++ b/src/dnd.c @@ -4,6 +4,7 @@ #include #include #include +#include "common/scene-helpers.h" #include "config/rcxml.h" #include "input/cursor.h" #include "labwc.h" /* for struct seat */ @@ -83,7 +84,7 @@ handle_drag_destroy(struct wl_listener *listener, void *data) void dnd_init(struct seat *seat) { - seat->drag.icons = wlr_scene_tree_create(&seat->server->scene->tree); + seat->drag.icons = lab_wlr_scene_tree_create(&seat->server->scene->tree); wlr_scene_node_set_enabled(&seat->drag.icons->node, false); seat->drag.events.request.notify = handle_drag_request; diff --git a/src/input/ime.c b/src/input/ime.c index 92d88ffe..02feec0b 100644 --- a/src/input/ime.c +++ b/src/input/ime.c @@ -12,6 +12,7 @@ #include #include #include "common/mem.h" +#include "common/scene-helpers.h" #include "input/keyboard.h" #include "labwc.h" #include "node.h" @@ -398,6 +399,8 @@ handle_input_method_new_popup_surface(struct wl_listener *listener, void *data) popup->tree = wlr_scene_subsurface_tree_create( relay->popup_tree, popup->popup_surface->surface); + die_if_null(popup->tree); + node_descriptor_create(&popup->tree->node, LAB_NODE_IME_POPUP, /*view*/ NULL, /*data*/ NULL); @@ -580,7 +583,7 @@ input_method_relay_create(struct seat *seat) relay->seat = seat; wl_list_init(&relay->text_inputs); wl_list_init(&relay->popups); - relay->popup_tree = wlr_scene_tree_create(&seat->server->scene->tree); + relay->popup_tree = lab_wlr_scene_tree_create(&seat->server->scene->tree); relay->new_text_input.notify = handle_new_text_input; wl_signal_add(&seat->server->text_input_manager->events.text_input, diff --git a/src/layers.c b/src/layers.c index 60421e39..040b110c 100644 --- a/src/layers.c +++ b/src/layers.c @@ -561,10 +561,7 @@ create_popup(struct server *server, struct wlr_xdg_popup *wlr_popup, popup->wlr_popup = wlr_popup; popup->scene_tree = wlr_scene_xdg_surface_create(parent, wlr_popup->base); - if (!popup->scene_tree) { - free(popup); - return NULL; - } + die_if_null(popup->scene_tree); /* In support of IME popup */ wlr_popup->base->surface->data = popup->scene_tree; @@ -598,12 +595,6 @@ handle_popup_new_popup(struct wl_listener *listener, void *data) lab_layer_popup->server, wlr_popup, lab_layer_popup->scene_tree); - if (!new_popup) { - wl_resource_post_no_memory(wlr_popup->resource); - wlr_xdg_popup_destroy(wlr_popup); - return; - } - new_popup->output_toplevel_sx_box = lab_layer_popup->output_toplevel_sx_box; } @@ -664,12 +655,6 @@ handle_new_popup(struct wl_listener *listener, void *data) }; struct lab_layer_popup *popup = create_popup(server, wlr_popup, surface->tree); - if (!popup) { - wl_resource_post_no_memory(wlr_popup->resource); - wlr_xdg_popup_destroy(wlr_popup); - return; - } - popup->output_toplevel_sx_box = output_toplevel_sx_box; if (surface->layer_surface->current.layer @@ -716,11 +701,7 @@ handle_new_layer_surface(struct wl_listener *listener, void *data) surface->scene_layer_surface = wlr_scene_layer_surface_v1_create( selected_layer, layer_surface); - if (!surface->scene_layer_surface) { - wlr_layer_surface_v1_destroy(layer_surface); - wlr_log(WLR_ERROR, "could not create layer surface"); - return; - } + die_if_null(surface->scene_layer_surface); /* In support of IME popup */ layer_surface->surface->data = surface->scene_layer_surface->tree; diff --git a/src/menu/menu.c b/src/menu/menu.c index 0c87f44d..45495a57 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include @@ -19,6 +18,7 @@ #include "common/lab-scene-rect.h" #include "common/list.h" #include "common/mem.h" +#include "common/scene-helpers.h" #include "common/spawn.h" #include "common/string-helpers.h" #include "common/xml.h" @@ -170,7 +170,7 @@ item_create_scene_for_state(struct menuitem *item, float *text_color, struct theme *theme = menu->server->theme; /* Tree to hold background and label buffers */ - struct wlr_scene_tree *tree = wlr_scene_tree_create(item->tree); + struct wlr_scene_tree *tree = lab_wlr_scene_tree_create(item->tree); int icon_width = 0; int icon_size = ICON_SIZE; @@ -190,7 +190,7 @@ item_create_scene_for_state(struct menuitem *item, float *text_color, } /* Create background */ - wlr_scene_rect_create(tree, bg_width, theme->menu_item_height, bg_color); + lab_wlr_scene_rect_create(tree, bg_width, theme->menu_item_height, bg_color); /* Create icon */ bool show_app_icon = !strcmp(item->parent->id, "client-list-combined-menu") @@ -246,7 +246,7 @@ item_create_scene(struct menuitem *menuitem, int *item_y) struct theme *theme = menu->server->theme; /* Menu item root node */ - menuitem->tree = wlr_scene_tree_create(menu->scene_tree); + menuitem->tree = lab_wlr_scene_tree_create(menu->scene_tree); node_descriptor_create(&menuitem->tree->node, LAB_NODE_MENUITEM, /*view*/ NULL, menuitem); @@ -295,12 +295,12 @@ separator_create_scene(struct menuitem *menuitem, int *item_y) struct theme *theme = menu->server->theme; /* Menu item root node */ - menuitem->tree = wlr_scene_tree_create(menu->scene_tree); + menuitem->tree = lab_wlr_scene_tree_create(menu->scene_tree); node_descriptor_create(&menuitem->tree->node, LAB_NODE_MENUITEM, /*view*/ NULL, menuitem); /* Tree to hold background and line buffer */ - menuitem->normal_tree = wlr_scene_tree_create(menuitem->tree); + menuitem->normal_tree = lab_wlr_scene_tree_create(menuitem->tree); int bg_height = theme->menu_separator_line_thickness + 2 * theme->menu_separator_padding_height; @@ -313,11 +313,11 @@ separator_create_scene(struct menuitem *menuitem, int *item_y) } /* Item background nodes */ - wlr_scene_rect_create(menuitem->normal_tree, bg_width, bg_height, + lab_wlr_scene_rect_create(menuitem->normal_tree, bg_width, bg_height, theme->menu_items_bg_color); /* Draw separator line */ - struct wlr_scene_rect *line_rect = wlr_scene_rect_create( + struct wlr_scene_rect *line_rect = lab_wlr_scene_rect_create( menuitem->normal_tree, line_width, theme->menu_separator_line_thickness, theme->menu_separator_color); @@ -343,12 +343,12 @@ title_create_scene(struct menuitem *menuitem, int *item_y) float *text_color = theme->menu_title_text_color; /* Menu item root node */ - menuitem->tree = wlr_scene_tree_create(menu->scene_tree); + menuitem->tree = lab_wlr_scene_tree_create(menu->scene_tree); node_descriptor_create(&menuitem->tree->node, LAB_NODE_MENUITEM, /*view*/ NULL, menuitem); /* Tree to hold background and text buffer */ - menuitem->normal_tree = wlr_scene_tree_create(menuitem->tree); + menuitem->normal_tree = lab_wlr_scene_tree_create(menuitem->tree); int bg_width = menu->size.width - 2 * theme->menu_border_width; int text_width = bg_width - 2 * theme->menu_items_padding_x; @@ -359,7 +359,7 @@ title_create_scene(struct menuitem *menuitem, int *item_y) } /* Background */ - wlr_scene_rect_create(menuitem->normal_tree, + lab_wlr_scene_rect_create(menuitem->normal_tree, bg_width, theme->menu_header_height, bg_color); /* Draw separator title */ @@ -416,7 +416,7 @@ menu_create_scene(struct menu *menu) assert(!menu->scene_tree); - menu->scene_tree = wlr_scene_tree_create(menu->server->menu_tree); + menu->scene_tree = lab_wlr_scene_tree_create(menu->server->menu_tree); wlr_scene_node_set_enabled(&menu->scene_tree->node, false); /* Menu width is the maximum item width, capped by menu.width.{min,max} */ diff --git a/src/output.c b/src/output.c index addb2706..b4b40d64 100644 --- a/src/output.c +++ b/src/output.c @@ -557,11 +557,11 @@ handle_new_output(struct wl_listener *listener, void *data) */ for (size_t i = 0; i < ARRAY_SIZE(output->layer_tree); i++) { output->layer_tree[i] = - wlr_scene_tree_create(&server->scene->tree); + lab_wlr_scene_tree_create(&server->scene->tree); } - output->layer_popup_tree = wlr_scene_tree_create(&server->scene->tree); - output->cycle_osd_tree = wlr_scene_tree_create(&server->scene->tree); - output->session_lock_tree = wlr_scene_tree_create(&server->scene->tree); + output->layer_popup_tree = lab_wlr_scene_tree_create(&server->scene->tree); + output->cycle_osd_tree = lab_wlr_scene_tree_create(&server->scene->tree); + output->session_lock_tree = lab_wlr_scene_tree_create(&server->scene->tree); /* * Set the z-positions to achieve the following order (from top to diff --git a/src/scaled-buffer/scaled-buffer.c b/src/scaled-buffer/scaled-buffer.c index 8bef0a75..95ec896b 100644 --- a/src/scaled-buffer/scaled-buffer.c +++ b/src/scaled-buffer/scaled-buffer.c @@ -12,6 +12,7 @@ #include "common/list.h" #include "common/macros.h" #include "common/mem.h" +#include "common/scene-helpers.h" #include "node.h" /* @@ -191,12 +192,7 @@ scaled_buffer_create(struct wlr_scene_tree *parent, assert(impl->create_buffer); struct scaled_buffer *self = znew(*self); - self->scene_buffer = wlr_scene_buffer_create(parent, NULL); - if (!self->scene_buffer) { - wlr_log(WLR_ERROR, "Failed to create scene buffer"); - free(self); - return NULL; - } + self->scene_buffer = lab_wlr_scene_buffer_create(parent, NULL); self->impl = impl; /* diff --git a/src/server.c b/src/server.c index b8abc633..fbbe02dc 100644 --- a/src/server.c +++ b/src/server.c @@ -46,6 +46,8 @@ #include "action.h" #include "common/macros.h" +#include "common/mem.h" +#include "common/scene-helpers.h" #include "config/rcxml.h" #include "config/session.h" #include "decorations.h" @@ -555,10 +557,8 @@ server_init(struct server *server) wl_list_init(&server->cycle.osd_outputs); server->scene = wlr_scene_create(); - if (!server->scene) { - wlr_log(WLR_ERROR, "unable to create scene"); - exit(EXIT_FAILURE); - } + die_if_null(server->scene); + server->direct_scanout_enabled = server->scene->WLR_PRIVATE.direct_scanout; /* @@ -586,13 +586,13 @@ server_init(struct server *server) * | output->layer_tree[0] | background layer surfaces (e.g. swaybg) */ - server->workspace_tree = wlr_scene_tree_create(&server->scene->tree); - server->xdg_popup_tree = wlr_scene_tree_create(&server->scene->tree); + server->workspace_tree = lab_wlr_scene_tree_create(&server->scene->tree); + server->xdg_popup_tree = lab_wlr_scene_tree_create(&server->scene->tree); #if HAVE_XWAYLAND - server->unmanaged_tree = wlr_scene_tree_create(&server->scene->tree); + server->unmanaged_tree = lab_wlr_scene_tree_create(&server->scene->tree); #endif - server->menu_tree = wlr_scene_tree_create(&server->scene->tree); - server->cycle_preview_tree = wlr_scene_tree_create(&server->scene->tree); + server->menu_tree = lab_wlr_scene_tree_create(&server->scene->tree); + server->cycle_preview_tree = lab_wlr_scene_tree_create(&server->scene->tree); workspaces_init(server); diff --git a/src/session-lock.c b/src/session-lock.c index a370241e..3b41e400 100644 --- a/src/session-lock.c +++ b/src/session-lock.c @@ -6,6 +6,7 @@ #include #include #include "common/mem.h" +#include "common/scene-helpers.h" #include "labwc.h" #include "node.h" #include "output.h" @@ -135,8 +136,11 @@ handle_new_surface(struct wl_listener *listener, void *data) } lock_output->surface = lock_surface; + struct wlr_scene_tree *surface_tree = wlr_scene_subsurface_tree_create(lock_output->tree, lock_surface->surface); + die_if_null(surface_tree); + node_descriptor_create(&surface_tree->node, LAB_NODE_SESSION_LOCK_SURFACE, /*view*/ NULL, /*data*/ NULL); @@ -209,12 +213,7 @@ session_lock_output_create(struct session_lock_manager *manager, struct output * struct session_lock_output *lock_output = znew(*lock_output); - struct wlr_scene_tree *tree = wlr_scene_tree_create(output->session_lock_tree); - if (!tree) { - wlr_log(WLR_ERROR, "session-lock: wlr_scene_tree_create()"); - free(lock_output); - goto exit_session; - } + struct wlr_scene_tree *tree = lab_wlr_scene_tree_create(output->session_lock_tree); /* * The ext-session-lock protocol says that the compositor should blank @@ -222,13 +221,7 @@ session_lock_output_create(struct session_lock_manager *manager, struct output * * fully hidden */ float black[4] = { 0.f, 0.f, 0.f, 1.f }; - struct wlr_scene_rect *background = wlr_scene_rect_create(tree, 0, 0, black); - if (!background) { - wlr_log(WLR_ERROR, "session-lock: wlr_scene_rect_create()"); - wlr_scene_node_destroy(&tree->node); - free(lock_output); - goto exit_session; - } + struct wlr_scene_rect *background = lab_wlr_scene_rect_create(tree, 0, 0, black); /* * Delay blanking output by 100ms to prevent flicker. If the session is @@ -258,12 +251,6 @@ session_lock_output_create(struct session_lock_manager *manager, struct output * lock_output_reconfigure(lock_output); wl_list_insert(&manager->lock_outputs, &lock_output->link); - return; - -exit_session: - /* TODO: Consider a better - but secure - way to deal with this */ - wlr_log(WLR_ERROR, "out of memory"); - exit(EXIT_FAILURE); } static void diff --git a/src/ssd/resize-indicator.c b/src/ssd/resize-indicator.c index 3a635edc..d12bda14 100644 --- a/src/ssd/resize-indicator.c +++ b/src/ssd/resize-indicator.c @@ -3,6 +3,7 @@ #include #include #include +#include "common/scene-helpers.h" #include "config/rcxml.h" #include "labwc.h" #include "resize-indicator.h" @@ -44,10 +45,10 @@ resize_indicator_init(struct view *view) struct resize_indicator *indicator = &view->resize_indicator; assert(!indicator->tree); - indicator->tree = wlr_scene_tree_create(view->scene_tree); - indicator->border = wlr_scene_rect_create( + indicator->tree = lab_wlr_scene_tree_create(view->scene_tree); + indicator->border = lab_wlr_scene_rect_create( indicator->tree, 0, 0, rc.theme->osd_border_color); - indicator->background = wlr_scene_rect_create( + indicator->background = lab_wlr_scene_rect_create( indicator->tree, 0, 0, rc.theme->osd_bg_color); indicator->text = scaled_font_buffer_create(indicator->tree); diff --git a/src/ssd/ssd-border.c b/src/ssd/ssd-border.c index f0db4fff..aee592a4 100644 --- a/src/ssd/ssd-border.c +++ b/src/ssd/ssd-border.c @@ -3,6 +3,7 @@ #include #include #include "common/macros.h" +#include "common/scene-helpers.h" #include "labwc.h" #include "ssd.h" #include "ssd-internal.h" @@ -22,32 +23,32 @@ ssd_border_create(struct ssd *ssd) int full_width = width + 2 * theme->border_width; int corner_width = ssd_get_corner_width(); - ssd->border.tree = wlr_scene_tree_create(ssd->tree); + ssd->border.tree = lab_wlr_scene_tree_create(ssd->tree); wlr_scene_node_set_position(&ssd->border.tree->node, -theme->border_width, 0); enum ssd_active_state active; FOR_EACH_ACTIVE_STATE(active) { struct ssd_border_subtree *subtree = &ssd->border.subtrees[active]; - subtree->tree = wlr_scene_tree_create(ssd->border.tree); + subtree->tree = lab_wlr_scene_tree_create(ssd->border.tree); struct wlr_scene_tree *parent = subtree->tree; wlr_scene_node_set_enabled(&parent->node, active); float *color = theme->window[active].border_color; - subtree->left = wlr_scene_rect_create(parent, + subtree->left = lab_wlr_scene_rect_create(parent, theme->border_width, height, color); wlr_scene_node_set_position(&subtree->left->node, 0, 0); - subtree->right = wlr_scene_rect_create(parent, + subtree->right = lab_wlr_scene_rect_create(parent, theme->border_width, height, color); wlr_scene_node_set_position(&subtree->right->node, theme->border_width + width, 0); - subtree->bottom = wlr_scene_rect_create(parent, + subtree->bottom = lab_wlr_scene_rect_create(parent, full_width, theme->border_width, color); wlr_scene_node_set_position(&subtree->bottom->node, 0, height); - subtree->top = wlr_scene_rect_create(parent, + subtree->top = lab_wlr_scene_rect_create(parent, MAX(width - 2 * corner_width, 0), theme->border_width, color); wlr_scene_node_set_position(&subtree->top->node, theme->border_width + corner_width, diff --git a/src/ssd/ssd-button.c b/src/ssd/ssd-button.c index 50131a12..b500126e 100644 --- a/src/ssd/ssd-button.c +++ b/src/ssd/ssd-button.c @@ -5,6 +5,7 @@ #include "config/rcxml.h" #include "common/list.h" #include "common/mem.h" +#include "common/scene-helpers.h" #include "node.h" #include "scaled-buffer/scaled-icon-buffer.h" #include "scaled-buffer/scaled-img-buffer.h" @@ -19,7 +20,7 @@ attach_ssd_button(struct wl_list *button_parts, enum lab_node_type type, struct lab_img *imgs[LAB_BS_ALL + 1], int x, int y, struct view *view) { - struct wlr_scene_tree *root = wlr_scene_tree_create(parent); + struct wlr_scene_tree *root = lab_wlr_scene_tree_create(parent); wlr_scene_node_set_position(&root->node, x, y); assert(node_type_contains(LAB_NODE_BUTTON, type)); @@ -31,7 +32,7 @@ attach_ssd_button(struct wl_list *button_parts, enum lab_node_type type, /* Hitbox */ float invisible[4] = { 0, 0, 0, 0 }; - wlr_scene_rect_create(root, rc.theme->window_button_width, + lab_wlr_scene_rect_create(root, rc.theme->window_button_width, rc.theme->window_button_height, invisible); /* Icons */ diff --git a/src/ssd/ssd-extents.c b/src/ssd/ssd-extents.c index 1a301f29..d8122ad9 100644 --- a/src/ssd/ssd-extents.c +++ b/src/ssd/ssd-extents.c @@ -2,6 +2,7 @@ #include #include +#include "common/scene-helpers.h" #include "config/rcxml.h" #include "labwc.h" #include "output.h" @@ -17,7 +18,7 @@ ssd_extents_create(struct ssd *ssd) int border_width = MAX(0, MAX(rc.resize_minimum_area, theme->border_width)); - ssd->extents.tree = wlr_scene_tree_create(ssd->tree); + ssd->extents.tree = lab_wlr_scene_tree_create(ssd->tree); struct wlr_scene_tree *parent = ssd->extents.tree; if (view->fullscreen || view->maximized == VIEW_AXIS_BOTH) { wlr_scene_node_set_enabled(&parent->node, false); @@ -26,10 +27,10 @@ ssd_extents_create(struct ssd *ssd) -border_width, -(ssd->titlebar.height + border_width)); float invisible[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; - ssd->extents.top = wlr_scene_rect_create(parent, 0, 0, invisible); - ssd->extents.left = wlr_scene_rect_create(parent, 0, 0, invisible); - ssd->extents.right = wlr_scene_rect_create(parent, 0, 0, invisible); - ssd->extents.bottom = wlr_scene_rect_create(parent, 0, 0, invisible); + ssd->extents.top = lab_wlr_scene_rect_create(parent, 0, 0, invisible); + ssd->extents.left = lab_wlr_scene_rect_create(parent, 0, 0, invisible); + ssd->extents.right = lab_wlr_scene_rect_create(parent, 0, 0, invisible); + ssd->extents.bottom = lab_wlr_scene_rect_create(parent, 0, 0, invisible); /* Initial manual update to keep X11 applications happy */ ssd_extents_update(ssd); diff --git a/src/ssd/ssd-shadow.c b/src/ssd/ssd-shadow.c index 2ead17ce..16ff278f 100644 --- a/src/ssd/ssd-shadow.c +++ b/src/ssd/ssd-shadow.c @@ -3,6 +3,7 @@ #include #include #include "buffer.h" +#include "common/scene-helpers.h" #include "config/rcxml.h" #include "labwc.h" #include "ssd.h" @@ -183,7 +184,7 @@ make_shadow(struct view *view, enum wl_output_transform tx) { struct wlr_scene_buffer *scene_buf = - wlr_scene_buffer_create(parent, buf); + lab_wlr_scene_buffer_create(parent, buf); wlr_scene_buffer_set_transform(scene_buf, tx); scene_buf->point_accepts_input = never_accepts_input; /* @@ -200,7 +201,7 @@ ssd_shadow_create(struct ssd *ssd) assert(ssd); assert(!ssd->shadow.tree); - ssd->shadow.tree = wlr_scene_tree_create(ssd->tree); + ssd->shadow.tree = lab_wlr_scene_tree_create(ssd->tree); struct theme *theme = ssd->view->server->theme; struct view *view = ssd->view; @@ -218,7 +219,7 @@ ssd_shadow_create(struct ssd *ssd) continue; } - subtree->tree = wlr_scene_tree_create(ssd->shadow.tree); + subtree->tree = lab_wlr_scene_tree_create(ssd->shadow.tree); struct wlr_scene_tree *parent = subtree->tree; struct wlr_buffer *corner_top_buffer = &theme->window[active].shadow_corner_top->base; diff --git a/src/ssd/ssd-titlebar.c b/src/ssd/ssd-titlebar.c index 8e9fbc97..0d859260 100644 --- a/src/ssd/ssd-titlebar.c +++ b/src/ssd/ssd-titlebar.c @@ -7,7 +7,7 @@ #include #include "buffer.h" #include "common/mem.h" -#include "common/string-helpers.h" +#include "common/scene-helpers.h" #include "config/rcxml.h" #include "labwc.h" #include "node.h" @@ -31,14 +31,14 @@ ssd_titlebar_create(struct ssd *ssd) int width = view->current.width; int corner_width = ssd_get_corner_width(); - ssd->titlebar.tree = wlr_scene_tree_create(ssd->tree); + ssd->titlebar.tree = lab_wlr_scene_tree_create(ssd->tree); node_descriptor_create(&ssd->titlebar.tree->node, LAB_NODE_TITLEBAR, view, /*data*/ NULL); enum ssd_active_state active; FOR_EACH_ACTIVE_STATE(active) { struct ssd_titlebar_subtree *subtree = &ssd->titlebar.subtrees[active]; - subtree->tree = wlr_scene_tree_create(ssd->titlebar.tree); + subtree->tree = lab_wlr_scene_tree_create(ssd->titlebar.tree); struct wlr_scene_tree *parent = subtree->tree; wlr_scene_node_set_enabled(&parent->node, active); wlr_scene_node_set_position(&parent->node, 0, -theme->titlebar_height); @@ -51,7 +51,7 @@ ssd_titlebar_create(struct ssd *ssd) &theme->window[active].corner_top_right_normal->base; /* Background */ - subtree->bar = wlr_scene_buffer_create(parent, titlebar_fill); + subtree->bar = lab_wlr_scene_buffer_create(parent, titlebar_fill); /* * Work around the wlroots/pixman bug that widened 1px buffer * becomes translucent when bilinear filtering is used. @@ -64,11 +64,11 @@ ssd_titlebar_create(struct ssd *ssd) } wlr_scene_node_set_position(&subtree->bar->node, corner_width, 0); - subtree->corner_left = wlr_scene_buffer_create(parent, corner_top_left); + subtree->corner_left = lab_wlr_scene_buffer_create(parent, corner_top_left); wlr_scene_node_set_position(&subtree->corner_left->node, -rc.theme->border_width, -rc.theme->border_width); - subtree->corner_right = wlr_scene_buffer_create(parent, corner_top_right); + subtree->corner_right = lab_wlr_scene_buffer_create(parent, corner_top_right); wlr_scene_node_set_position(&subtree->corner_right->node, width - corner_width, -rc.theme->border_width); diff --git a/src/ssd/ssd.c b/src/ssd/ssd.c index d1381c1a..8e0b472c 100644 --- a/src/ssd/ssd.c +++ b/src/ssd/ssd.c @@ -12,6 +12,7 @@ #include #include #include "common/mem.h" +#include "common/scene-helpers.h" #include "config/rcxml.h" #include "labwc.h" #include "node.h" @@ -145,7 +146,7 @@ ssd_create(struct view *view, bool active) struct ssd *ssd = znew(*ssd); ssd->view = view; - ssd->tree = wlr_scene_tree_create(view->scene_tree); + ssd->tree = lab_wlr_scene_tree_create(view->scene_tree); /* * Attach node_descriptor to the root node so that get_cursor_context() diff --git a/src/workspaces.c b/src/workspaces.c index 95e1fb25..e8d4d7a5 100644 --- a/src/workspaces.c +++ b/src/workspaces.c @@ -15,6 +15,7 @@ #include "common/graphic-helpers.h" #include "common/list.h" #include "common/mem.h" +#include "common/scene-helpers.h" #include "config/rcxml.h" #include "input/keyboard.h" #include "labwc.h" @@ -163,7 +164,7 @@ _osd_update(struct server *server) cairo_destroy(cairo); if (!output->workspace_osd) { - output->workspace_osd = wlr_scene_buffer_create( + output->workspace_osd = lab_wlr_scene_buffer_create( &server->scene->tree, NULL); } /* Position the whole thing */ @@ -234,13 +235,13 @@ add_workspace(struct server *server, const char *name) struct workspace *workspace = znew(*workspace); workspace->server = server; workspace->name = xstrdup(name); - workspace->tree = wlr_scene_tree_create(server->workspace_tree); + workspace->tree = lab_wlr_scene_tree_create(server->workspace_tree); workspace->view_trees[VIEW_LAYER_ALWAYS_ON_BOTTOM] = - wlr_scene_tree_create(workspace->tree); + lab_wlr_scene_tree_create(workspace->tree); workspace->view_trees[VIEW_LAYER_NORMAL] = - wlr_scene_tree_create(workspace->tree); + lab_wlr_scene_tree_create(workspace->tree); workspace->view_trees[VIEW_LAYER_ALWAYS_ON_TOP] = - wlr_scene_tree_create(workspace->tree); + lab_wlr_scene_tree_create(workspace->tree); wl_list_append(&server->workspaces.all, &workspace->link); wlr_scene_node_set_enabled(&workspace->tree->node, false); diff --git a/src/xdg-popup.c b/src/xdg-popup.c index aded80b5..d4a3b7fc 100644 --- a/src/xdg-popup.c +++ b/src/xdg-popup.c @@ -164,6 +164,8 @@ xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup) } wlr_popup->base->surface->data = wlr_scene_xdg_surface_create(parent_tree, wlr_popup->base); + die_if_null(wlr_popup->base->surface->data); + node_descriptor_create(wlr_popup->base->surface->data, LAB_NODE_XDG_POPUP, view, /*data*/ NULL); } diff --git a/src/xdg.c b/src/xdg.c index d3b96d48..0994a962 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -13,6 +13,7 @@ #include "common/box.h" #include "common/macros.h" #include "common/mem.h" +#include "common/scene-helpers.h" #include "config/rcxml.h" #include "decorations.h" #include "foreign-toplevel/foreign.h" @@ -193,7 +194,7 @@ center_fullscreen_if_needed(struct view *view) if (!xdg_view->fullscreen_bg) { const float black[4] = {0, 0, 0, 1}; xdg_view->fullscreen_bg = - wlr_scene_rect_create(view->scene_tree, 0, 0, black); + lab_wlr_scene_rect_create(view->scene_tree, 0, 0, black); wlr_scene_node_lower_to_bottom(&xdg_view->fullscreen_bg->node); } @@ -984,18 +985,14 @@ handle_new_xdg_toplevel(struct wl_listener *listener, void *data) } view->workspace = server->workspaces.current; - view->scene_tree = wlr_scene_tree_create( + view->scene_tree = lab_wlr_scene_tree_create( view->workspace->view_trees[VIEW_LAYER_NORMAL]); wlr_scene_node_set_enabled(&view->scene_tree->node, false); struct wlr_scene_tree *tree = wlr_scene_xdg_surface_create( view->scene_tree, xdg_surface); - if (!tree) { - /* TODO: might need further clean up */ - wl_resource_post_no_memory(xdg_surface->resource); - free(xdg_toplevel_view); - return; - } + die_if_null(tree); + view->content_tree = tree; node_descriptor_create(&view->scene_tree->node, LAB_NODE_VIEW, view, /*data*/ NULL); diff --git a/src/xwayland-unmanaged.c b/src/xwayland-unmanaged.c index 00fd2f55..c25cc073 100644 --- a/src/xwayland-unmanaged.c +++ b/src/xwayland-unmanaged.c @@ -68,9 +68,11 @@ handle_map(struct wl_listener *listener, void *data) seat_focus_surface(&unmanaged->server->seat, xsurface->surface); } - unmanaged->node = &wlr_scene_surface_create( - unmanaged->server->unmanaged_tree, - xsurface->surface)->buffer->node; + struct wlr_scene_surface *scene_surface = wlr_scene_surface_create( + unmanaged->server->unmanaged_tree, xsurface->surface); + die_if_null(scene_surface); + unmanaged->node = &scene_surface->buffer->node; + wlr_scene_node_set_position(unmanaged->node, xsurface->x, xsurface->y); cursor_update_focus(unmanaged->server); } diff --git a/src/xwayland.c b/src/xwayland.c index 77eaf3a1..a60edf64 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -13,6 +13,7 @@ #include "common/array.h" #include "common/macros.h" #include "common/mem.h" +#include "common/scene-helpers.h" #include "config/rcxml.h" #include "config/session.h" #include "foreign-toplevel/foreign.h" @@ -850,11 +851,7 @@ handle_map(struct wl_listener *listener, void *data) if (!view->content_tree) { view->content_tree = wlr_scene_subsurface_tree_create( view->scene_tree, view->surface); - if (!view->content_tree) { - /* TODO: might need further clean up */ - wl_resource_post_no_memory(view->surface->resource); - return; - } + die_if_null(view->content_tree); } wlr_scene_node_set_enabled(&view->content_tree->node, !view->shaded); @@ -1058,7 +1055,7 @@ xwayland_view_create(struct server *server, xsurface->data = view; view->workspace = server->workspaces.current; - view->scene_tree = wlr_scene_tree_create( + view->scene_tree = lab_wlr_scene_tree_create( view->workspace->view_trees[VIEW_LAYER_NORMAL]); node_descriptor_create(&view->scene_tree->node, LAB_NODE_VIEW, view, /*data*/ NULL); From 3b6fe26301b3d4f9db5d508b4b3a175b2eab36d0 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Thu, 12 Mar 2026 13:24:55 +0100 Subject: [PATCH 027/146] view: add always-on-top signal --- include/view.h | 1 + src/view.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/include/view.h b/include/view.h index 6c0fdf58..dcc0d058 100644 --- a/include/view.h +++ b/include/view.h @@ -280,6 +280,7 @@ struct view { struct wl_signal minimized; struct wl_signal fullscreened; struct wl_signal activated; /* bool *activated */ + struct wl_signal always_on_top; /* * This is emitted when app_id, or icon set via xdg_toplevel_icon * is updated. This is listened by scaled_icon_buffer. diff --git a/src/view.c b/src/view.c index 7eb381de..57baa22d 100644 --- a/src/view.c +++ b/src/view.c @@ -1549,6 +1549,8 @@ view_set_layer(struct view *view, enum view_layer layer) view->layer = layer; wlr_scene_node_reparent(&view->scene_tree->node, view->workspace->view_trees[layer]); + + wl_signal_emit_mutable(&view->events.always_on_top, NULL); } void @@ -2476,6 +2478,7 @@ view_init(struct view *view) wl_signal_init(&view->events.minimized); wl_signal_init(&view->events.fullscreened); wl_signal_init(&view->events.activated); + wl_signal_init(&view->events.always_on_top); wl_signal_init(&view->events.set_icon); wl_signal_init(&view->events.destroy); @@ -2555,6 +2558,7 @@ view_destroy(struct view *view) assert(wl_list_empty(&view->events.minimized.listener_list)); assert(wl_list_empty(&view->events.fullscreened.listener_list)); assert(wl_list_empty(&view->events.activated.listener_list)); + assert(wl_list_empty(&view->events.always_on_top.listener_list)); assert(wl_list_empty(&view->events.set_icon.listener_list)); assert(wl_list_empty(&view->events.destroy.listener_list)); From 17d6c290374e42c822c2ff8cfd4cd747ef403fd4 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Thu, 12 Mar 2026 13:25:50 +0100 Subject: [PATCH 028/146] xwayland: sync always-on-top to X11 --- include/xwayland.h | 6 ++++++ src/xwayland.c | 14 ++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/include/xwayland.h b/include/xwayland.h index dad4689d..f313e165 100644 --- a/include/xwayland.h +++ b/include/xwayland.h @@ -59,6 +59,12 @@ struct xwayland_view { /* Not (yet) implemented */ /* struct wl_listener set_role; */ /* struct wl_listener set_hints; */ + + /* Events coming in from the view itself */ + struct { + struct wl_listener always_on_top; + } on_view; + }; void xwayland_unmanaged_create(struct server *server, diff --git a/src/xwayland.c b/src/xwayland.c index a60edf64..da78871d 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -368,6 +368,8 @@ handle_destroy(struct wl_listener *listener, void *data) wl_list_remove(&xwayland_view->focus_in.link); wl_list_remove(&xwayland_view->map_request.link); + wl_list_remove(&xwayland_view->on_view.always_on_top.link); + view_destroy(view); } @@ -1032,6 +1034,15 @@ static const struct view_impl xwayland_view_impl = { .get_pid = xwayland_view_get_pid, }; +static void +handle_always_on_top(struct wl_listener *listener, void *data) +{ + struct xwayland_view *xwayland_view = + wl_container_of(listener, xwayland_view, on_view.always_on_top); + wlr_xwayland_surface_set_above(xwayland_view->xwayland_surface, + xwayland_view->base.layer == VIEW_LAYER_ALWAYS_ON_TOP); +} + void xwayland_view_create(struct server *server, struct wlr_xwayland_surface *xsurface, bool mapped) @@ -1083,6 +1094,9 @@ xwayland_view_create(struct server *server, CONNECT_SIGNAL(xsurface, xwayland_view, focus_in); CONNECT_SIGNAL(xsurface, xwayland_view, map_request); + /* Events from the view itself */ + CONNECT_SIGNAL(view, &xwayland_view->on_view, always_on_top); + wl_list_insert(&view->server->views, &view->link); view->creation_id = view->server->next_view_creation_id++; From 50bb882cf0c140ad094f7d2f1a746b96818b841f Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Tue, 17 Mar 2026 20:40:20 +0000 Subject: [PATCH 029/146] NEWS.md: fix 0.9.6 release notes ...by removing the comment about crashes after suspend on some Nvidia GPUs because this only happens after #3387 has is not yet in any release. Ref: - https://github.com/labwc/labwc/pull/3430#discussion_r2911781637 - https://github.com/labwc/labwc/pull/3448#discussion_r2948247530 Helped-by: @tokyo4j --- NEWS.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index 3699c61c..8787fef2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -146,8 +146,7 @@ refactoring and new features. - Disable outputs where all modes fail [#3428] [#3429] @Consolatis @kode54 - Fix regression in `0.9.4` that causes `NextWindow` action to segfault when - no outputs are connected. This fixes a window-switcher crash with some - Nvidia GPUs/drivers after suspend [#3425] [#3430] @Consolatis + no outputs are connected. [#3425] [#3430] @Consolatis - Fix typo to allow `xdg-dialog-v1` global [#3426] @xi ### Changed From 60ac8f07bb6e9642ac4b46bc9a72138f0dc4889b Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Mon, 23 Feb 2026 11:46:45 -0500 Subject: [PATCH 030/146] tree-wide: add g_server global and prep for auto-replace --- include/config/rcxml.h | 1 + include/labwc.h | 3 +++ src/config/session.c | 2 -- src/input/keyboard.c | 5 ++--- src/main.c | 33 +++++++++++++++++++++------------ src/regions.c | 1 - src/server.c | 14 +++++++------- src/xwayland.c | 3 +-- 8 files changed, 35 insertions(+), 27 deletions(-) diff --git a/include/config/rcxml.h b/include/config/rcxml.h index a6f1a7d7..aa950234 100644 --- a/include/config/rcxml.h +++ b/include/config/rcxml.h @@ -211,6 +211,7 @@ struct rcxml { bool mag_filter; }; +/* defined in main.c */ extern struct rcxml rc; void rcxml_read(const char *filename); diff --git a/include/labwc.h b/include/labwc.h index 728deaf9..513be15a 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -313,6 +313,9 @@ struct server { pid_t primary_client_pid; }; +/* defined in main.c */ +extern struct server g_server; + void xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup); void xdg_shell_init(struct server *server); void xdg_shell_finish(struct server *server); diff --git a/src/config/session.c b/src/config/session.c index 515b6803..1c2f6cb7 100644 --- a/src/config/session.c +++ b/src/config/session.c @@ -187,8 +187,6 @@ backend_check_drm(struct wlr_backend *backend, void *is_drm) static bool should_update_activation(struct server *server) { - assert(server); - static const char *act_env = "LABWC_UPDATE_ACTIVATION_ENV"; char *env = getenv(act_env); if (env) { diff --git a/src/input/keyboard.c b/src/input/keyboard.c index 0171dcd0..ec13f3f8 100644 --- a/src/input/keyboard.c +++ b/src/input/keyboard.c @@ -483,11 +483,10 @@ static enum lab_key_handled handle_compositor_keybindings(struct keyboard *keyboard, struct wlr_keyboard_key_event *event) { - struct seat *seat = keyboard->base.seat; - struct server *server = seat->server; + struct server *server = &g_server; struct wlr_keyboard *wlr_keyboard = keyboard->wlr_keyboard; struct keyinfo keyinfo = get_keyinfo(wlr_keyboard, event->keycode); - bool locked = seat->server->session_lock_manager->locked; + bool locked = server->session_lock_manager->locked; key_state_set_pressed(event->keycode, event->state == WL_KEYBOARD_KEY_STATE_PRESSED); diff --git a/src/main.c b/src/main.c index 755a0a0c..2ffc68b7 100644 --- a/src/main.c +++ b/src/main.c @@ -14,7 +14,16 @@ #include "translate.h" #include "menu/menu.h" +/* + * Globals + * + * Rationale: these are unlikely to ever have more than one instance + * per process, and need to last for the lifetime of the process. + * Accessing them indirectly through pointers embedded in every other + * struct just adds noise to the code. + */ struct rcxml rc = { 0 }; +struct server g_server = { 0 }; static const struct option long_options[] = { {"config", required_argument, NULL, 'c'}, @@ -246,35 +255,35 @@ main(int argc, char *argv[]) increase_nofile_limit(); - struct server server = { 0 }; - server_init(&server); - server_start(&server); + struct server *server = &g_server; + server_init(server); + server_start(server); struct theme theme = { 0 }; - theme_init(&theme, &server, rc.theme_name); + theme_init(&theme, server, rc.theme_name); rc.theme = &theme; - server.theme = &theme; + server->theme = &theme; - menu_init(&server); + menu_init(server); /* Delay startup of applications until the event loop is ready */ struct idle_ctx idle_ctx = { - .server = &server, + .server = server, .primary_client = primary_client, .startup_cmd = startup_cmd }; - wl_event_loop_add_idle(server.wl_event_loop, idle_callback, &idle_ctx); + wl_event_loop_add_idle(server->wl_event_loop, idle_callback, &idle_ctx); - wl_display_run(server.wl_display); + wl_display_run(server->wl_display); - session_shutdown(&server); + session_shutdown(server); - menu_finish(&server); + menu_finish(server); theme_finish(&theme); rcxml_finish(); font_finish(); - server_finish(&server); + server_finish(server); return 0; } diff --git a/src/regions.c b/src/regions.c index 8ee20169..9dace707 100644 --- a/src/regions.c +++ b/src/regions.c @@ -46,7 +46,6 @@ regions_from_name(const char *region_name, struct output *output) struct region * regions_from_cursor(struct server *server) { - assert(server); double lx = server->seat.cursor->x; double ly = server->seat.cursor->y; diff --git a/src/server.c b/src/server.c index fbbe02dc..a526f2aa 100644 --- a/src/server.c +++ b/src/server.c @@ -111,7 +111,7 @@ reload_config_and_theme(struct server *server) static int handle_sighup(int signal, void *data) { - struct server *server = data; + struct server *server = &g_server; keyboard_cancel_all_keybind_repeats(&server->seat); session_environment_init(); @@ -134,7 +134,7 @@ handle_sigchld(int signal, void *data) { siginfo_t info; info.si_pid = 0; - struct server *server = data; + struct server *server = &g_server; /* First call waitid() with NOWAIT which doesn't consume the zombie */ if (waitid(P_ALL, /*id*/ 0, &info, WEXITED | WNOHANG | WNOWAIT) == -1) { @@ -302,9 +302,9 @@ static bool server_global_filter(const struct wl_client *client, const struct wl_global *global, void *data) { const struct wl_interface *iface = wl_global_get_interface(global); - struct server *server = (struct server *)data; + struct server *server = &g_server; /* Silence unused var compiler warnings */ - (void)iface; (void)server; + (void)iface; #if HAVE_XWAYLAND struct wl_client *xwayland_client = (server->xwayland && server->xwayland->server) @@ -436,18 +436,18 @@ server_init(struct server *server) /* Increase max client buffer size to make slow clients less likely to terminate */ wl_display_set_default_max_buffer_size(server->wl_display, 1024 * 1024); - wl_display_set_global_filter(server->wl_display, server_global_filter, server); + wl_display_set_global_filter(server->wl_display, server_global_filter, NULL); server->wl_event_loop = wl_display_get_event_loop(server->wl_display); /* Catch signals */ server->sighup_source = wl_event_loop_add_signal( - server->wl_event_loop, SIGHUP, handle_sighup, server); + server->wl_event_loop, SIGHUP, handle_sighup, NULL); server->sigint_source = wl_event_loop_add_signal( server->wl_event_loop, SIGINT, handle_sigterm, server->wl_display); server->sigterm_source = wl_event_loop_add_signal( server->wl_event_loop, SIGTERM, handle_sigterm, server->wl_display); server->sigchld_source = wl_event_loop_add_signal( - server->wl_event_loop, SIGCHLD, handle_sigchld, server); + server->wl_event_loop, SIGCHLD, handle_sigchld, NULL); /* * Prevent wayland clients that request the X11 clipboard but closing diff --git a/src/xwayland.c b/src/xwayland.c index da78871d..70b889f3 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -606,8 +606,7 @@ update_icon(struct xwayland_view *xwayland_view) xcb_window_t window_id = xwayland_view->xwayland_surface->window_id; - xcb_connection_t *xcb_conn = wlr_xwayland_get_xwm_connection( - xwayland_view->base.server->xwayland); + xcb_connection_t *xcb_conn = wlr_xwayland_get_xwm_connection(g_server.xwayland); xcb_get_property_cookie_t cookie = xcb_get_property(xcb_conn, 0, window_id, atoms[ATOM_NET_WM_ICON], XCB_ATOM_CARDINAL, 0, 0x10000); xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_conn, cookie, NULL); From cb49bddf63ee0e123667992a1d622ba086eae918 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Mon, 23 Feb 2026 11:56:39 -0500 Subject: [PATCH 031/146] tree-wide: auto-replace of (struct server *) #!/bin/bash read -r -d '' EXPRS << EOF s/xwayland->server/xwayland->svr/g; s/\t*struct server \*server;\n//g; s/\t*struct server \*server =.*?;\n//gs; s/\t*.* = ([a-z_]*->)*server[;,]\n//g; s/\{\n\n/\{\n/g; s/\n\n+/\n\n/g; s/\(\s*struct server \*server\)/(void)/g; s/\(\s*struct server \*server,\s*/(/g; s/,\s*struct server \*server\)/)/g; s/,\s*struct server \*server,\s*/, /g; s/\(\s*([a-z_]*->)*server\)/()/g; s/\(\s*([a-z_]*->)*server,\s*/(/g; s/,\s*([a-z_]*->)*server\)/)/g; s/,\s*([a-z_]*->)*server,\s*/, /g; s/([a-z_]*->)*server->/g_server./g; s/xwayland->svr/xwayland->server/g; EOF find src include \( -name \*.c -o -name \*.h \) -exec \ perl -0777 -i -pe "$EXPRS" \{\} \; --- include/action.h | 3 +- include/config/keybind.h | 2 +- include/config/session.h | 4 +- include/cycle.h | 14 +- include/debug.h | 2 +- include/decorations.h | 8 +- include/desktop-entry.h | 13 +- include/edges.h | 2 +- include/input/cursor.h | 8 +- include/labwc.h | 34 +- include/layers.h | 6 +- include/magnifier.h | 4 +- include/menu/menu.h | 33 +- include/output-virtual.h | 6 +- include/output.h | 16 +- include/regions.h | 6 +- include/resize-indicator.h | 2 +- include/scaled-buffer/scaled-icon-buffer.h | 4 +- include/session-lock.h | 5 +- include/ssd.h | 3 +- include/theme.h | 2 +- include/view.h | 9 +- include/workspaces.h | 7 +- include/xwayland.h | 18 +- src/action.c | 125 ++++--- src/config/keybind.c | 4 +- src/config/session.c | 16 +- src/cycle/cycle.c | 188 +++++----- src/cycle/osd-classic.c | 25 +- src/cycle/osd-field.c | 4 +- src/cycle/osd-scroll.c | 4 +- src/cycle/osd-thumbnail.c | 32 +- src/debug.c | 74 ++-- src/decorations/kde-deco.c | 12 +- src/decorations/xdg-deco.c | 12 +- src/desktop-entry.c | 27 +- src/desktop.c | 56 ++- src/dnd.c | 4 +- src/edges.c | 12 +- src/foreign-toplevel/ext-foreign.c | 4 +- src/foreign-toplevel/wlr-foreign.c | 8 +- src/input/cursor.c | 225 ++++++------ src/input/gestures.c | 2 +- src/input/ime.c | 11 +- src/input/keyboard.c | 103 +++--- src/input/tablet-pad.c | 4 +- src/input/tablet.c | 17 +- src/input/touch.c | 8 +- src/interactive.c | 91 +++-- src/layers.c | 72 ++-- src/magnifier.c | 43 ++- src/main.c | 31 +- src/menu/menu.c | 239 ++++++------- src/output-virtual.c | 26 +- src/output.c | 281 +++++++-------- src/overlay.c | 13 +- src/placement.c | 12 +- src/regions.c | 30 +- src/resistance.c | 2 +- src/resize-outlines.c | 6 +- src/scaled-buffer/scaled-icon-buffer.c | 14 +- src/seat.c | 61 ++-- src/server.c | 392 ++++++++++----------- src/session-lock.c | 39 +- src/ssd/resize-indicator.c | 16 +- src/ssd/ssd-border.c | 4 +- src/ssd/ssd-button.c | 3 +- src/ssd/ssd-extents.c | 6 +- src/ssd/ssd-shadow.c | 6 +- src/ssd/ssd-titlebar.c | 30 +- src/ssd/ssd.c | 15 +- src/tearing.c | 3 +- src/theme.c | 8 +- src/view-impl-common.c | 14 +- src/view.c | 109 +++--- src/window-rules.c | 4 +- src/workspaces.c | 165 +++++---- src/xdg-popup.c | 12 +- src/xdg.c | 86 +++-- src/xwayland-unmanaged.c | 42 +-- src/xwayland.c | 141 ++++---- 81 files changed, 1522 insertions(+), 1682 deletions(-) diff --git a/include/action.h b/include/action.h index 7692e383..b09aa35c 100644 --- a/include/action.h +++ b/include/action.h @@ -47,8 +47,7 @@ bool actions_contain_toggle_keybinds(struct wl_list *action_list); * direction of resize or the position of the window menu button for ShowMenu * action. */ -void actions_run(struct view *activator, struct server *server, - struct wl_list *actions, struct cursor_context *ctx); +void actions_run(struct view *activator, struct wl_list *actions, struct cursor_context *ctx); void action_prompts_destroy(void); bool action_check_prompt_result(pid_t pid, int exit_code); diff --git a/include/config/keybind.h b/include/config/keybind.h index bef3e189..e3c9e21b 100644 --- a/include/config/keybind.h +++ b/include/config/keybind.h @@ -45,5 +45,5 @@ bool keybind_the_same(struct keybind *a, struct keybind *b); bool keybind_contains_keycode(struct keybind *keybind, xkb_keycode_t keycode); bool keybind_contains_keysym(struct keybind *keybind, xkb_keysym_t keysym); -void keybind_update_keycodes(struct server *server); +void keybind_update_keycodes(void); #endif /* LABWC_KEYBIND_H */ diff --git a/include/config/session.h b/include/config/session.h index 61a95cf9..dec57feb 100644 --- a/include/config/session.h +++ b/include/config/session.h @@ -21,12 +21,12 @@ void session_environment_init(void); * session_autostart_init - run autostart file as shell script * Note: Same as `sh ~/.config/labwc/autostart` (or equivalent XDG config dir) */ -void session_autostart_init(struct server *server); +void session_autostart_init(void); /** * session_shutdown - run session shutdown file as shell script * Note: Same as `sh ~/.config/labwc/shutdown` (or equivalent XDG config dir) */ -void session_shutdown(struct server *server); +void session_shutdown(void); #endif /* LABWC_SESSION_H */ diff --git a/include/cycle.h b/include/cycle.h index c6e42810..8caf2b98 100644 --- a/include/cycle.h +++ b/include/cycle.h @@ -91,20 +91,20 @@ struct server; struct wlr_scene_node; /* Begin window switcher */ -void cycle_begin(struct server *server, enum lab_cycle_dir direction, +void cycle_begin(enum lab_cycle_dir direction, struct cycle_filter filter); /* Cycle the selected view in the window switcher */ -void cycle_step(struct server *server, enum lab_cycle_dir direction); +void cycle_step(enum lab_cycle_dir direction); /* Closes the OSD */ -void cycle_finish(struct server *server, bool switch_focus); +void cycle_finish(bool switch_focus); /* Re-initialize the window switcher */ -void cycle_reinitialize(struct server *server); +void cycle_reinitialize(void); /* Focus the clicked window and close OSD */ -void cycle_on_cursor_release(struct server *server, struct wlr_scene_node *node); +void cycle_on_cursor_release(struct wlr_scene_node *node); /* Used by osd.c internally to render window switcher fields */ void cycle_osd_field_get_content(struct cycle_osd_field *field, @@ -133,7 +133,7 @@ struct cycle_osd_impl { */ void (*init)(struct cycle_osd_output *osd_output); /* - * Update the OSD to highlight server->cycle.selected_view. + * Update the OSD to highlight g_server.cycle.selected_view. */ void (*update)(struct cycle_osd_output *osd_output); }; @@ -157,7 +157,7 @@ void cycle_osd_scroll_init(struct cycle_osd_output *osd_output, int nr_cols, int nr_rows, int nr_visible_rows, float *border_color, float *bg_color); -/* Scroll the OSD to show server->cycle.selected_view if needed */ +/* Scroll the OSD to show g_server.cycle.selected_view if needed */ void cycle_osd_scroll_update(struct cycle_osd_output *osd_output); extern struct cycle_osd_impl cycle_osd_classic_impl; diff --git a/include/debug.h b/include/debug.h index ad128ee6..6ca96ee4 100644 --- a/include/debug.h +++ b/include/debug.h @@ -4,6 +4,6 @@ struct server; -void debug_dump_scene(struct server *server); +void debug_dump_scene(void); #endif /* LABWC_DEBUG_H */ diff --git a/include/decorations.h b/include/decorations.h index 4d23c14f..20ea3c6a 100644 --- a/include/decorations.h +++ b/include/decorations.h @@ -6,13 +6,13 @@ struct server; struct view; struct wlr_surface; -void kde_server_decoration_init(struct server *server); -void xdg_server_decoration_init(struct server *server); +void kde_server_decoration_init(void); +void xdg_server_decoration_init(void); void kde_server_decoration_update_default(void); void kde_server_decoration_set_view(struct view *view, struct wlr_surface *surface); -void kde_server_decoration_finish(struct server *server); -void xdg_server_decoration_finish(struct server *server); +void kde_server_decoration_finish(void); +void xdg_server_decoration_finish(void); #endif /* LABWC_DECORATIONS_H */ diff --git a/include/desktop-entry.h b/include/desktop-entry.h index f0d93e3a..4321cbd3 100644 --- a/include/desktop-entry.h +++ b/include/desktop-entry.h @@ -6,14 +6,12 @@ struct server; -void desktop_entry_init(struct server *server); -void desktop_entry_finish(struct server *server); +void desktop_entry_init(void); +void desktop_entry_finish(void); -struct lab_img *desktop_entry_load_icon_from_app_id( - struct server *server, const char *app_id, int size, float scale); +struct lab_img *desktop_entry_load_icon_from_app_id(const char *app_id, int size, float scale); -struct lab_img *desktop_entry_load_icon( - struct server *server, const char *icon_name, int size, float scale); +struct lab_img *desktop_entry_load_icon(const char *icon_name, int size, float scale); /** * desktop_entry_name_lookup() - return the application name @@ -22,8 +20,7 @@ struct lab_img *desktop_entry_load_icon( * The lifetime of the returned value is the same as that * of sfdo_desktop_db (from `struct sfdo.desktop_db`) */ -const char *desktop_entry_name_lookup(struct server *server, - const char *app_id); +const char *desktop_entry_name_lookup(const char *app_id); #endif /* HAVE_LIBSFDO */ #endif /* LABWC_DESKTOP_ENTRY_H */ diff --git a/include/edges.h b/include/edges.h index 439b5a34..922e637b 100644 --- a/include/edges.h +++ b/include/edges.h @@ -117,6 +117,6 @@ void edges_adjust_resize_geom(struct view *view, struct border edges, bool edges_traverse_edge(struct edge current, struct edge target, struct edge edge); -void edges_calculate_visibility(struct server *server, struct view *ignored_view); +void edges_calculate_visibility(struct view *ignored_view); #endif /* LABWC_EDGES_H */ diff --git a/include/input/cursor.h b/include/input/cursor.h index aa5c77af..9042d50f 100644 --- a/include/input/cursor.h +++ b/include/input/cursor.h @@ -62,7 +62,7 @@ struct cursor_context_saved { * * If no node is found at cursor, ctx.type is set to ROOT. */ -struct cursor_context get_cursor_context(struct server *server); +struct cursor_context get_cursor_context(void); /** * cursor_set - set cursor icon @@ -82,7 +82,7 @@ void cursor_context_save(struct cursor_context_saved *saved_ctx, /** * cursor_get_resize_edges - calculate resize edge based on cursor position - * @cursor - the current cursor (usually server->seat.cursor) + * @cursor - the current cursor (usually g_server.seat.cursor) * @cursor_context - result of get_cursor_context() * * Calculates the resize edge combination that is most appropriate based @@ -113,7 +113,7 @@ enum lab_cursors cursor_get_from_edge(enum lab_edge resize_edges); * or to force an update of the cursor icon by sending an exit and enter * event to an already focused surface. */ -void cursor_update_focus(struct server *server); +void cursor_update_focus(void); /** * cursor_update_image - re-set the labwc cursor image @@ -130,7 +130,7 @@ void cursor_update_image(struct seat *seat); * should be notified. Parameters sx, sy holds the surface coordinates * in that case. */ -bool cursor_process_motion(struct server *server, uint32_t time, double *sx, double *sy); +bool cursor_process_motion(uint32_t time, double *sx, double *sy); /** * Processes cursor button press. The return value indicates if a client diff --git a/include/labwc.h b/include/labwc.h index 513be15a..2d122540 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -24,7 +24,6 @@ enum input_mode { struct seat { struct wlr_seat *seat; - struct server *server; struct wlr_keyboard_group *keyboard_group; struct wl_list touch_points; /* struct touch_point.link */ @@ -317,8 +316,8 @@ struct server { extern struct server g_server; void xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup); -void xdg_shell_init(struct server *server); -void xdg_shell_finish(struct server *server); +void xdg_shell_init(void); +void xdg_shell_finish(void); /* * desktop.c routines deal with a collection of views @@ -353,14 +352,14 @@ void desktop_focus_view(struct view *view, bool raise); void desktop_focus_view_or_surface(struct seat *seat, struct view *view, struct wlr_surface *surface, bool raise); -void desktop_arrange_all_views(struct server *server); +void desktop_arrange_all_views(void); void desktop_focus_output(struct output *output); /** * Toggles the (output local) visibility of the layershell top layer * based on the existence of a fullscreen window on the current workspace. */ -void desktop_update_top_layer_visibility(struct server *server); +void desktop_update_top_layer_visibility(void); /** * desktop_focus_topmost_view() - focus the topmost view on the current @@ -370,11 +369,11 @@ void desktop_update_top_layer_visibility(struct server *server); * This function is typically called when the focused view is hidden * (closes, is minimized, etc.) to focus the "next" view underneath. */ -void desktop_focus_topmost_view(struct server *server); +void desktop_focus_topmost_view(void); -void seat_init(struct server *server); -void seat_finish(struct server *server); -void seat_reconfigure(struct server *server); +void seat_init(void); +void seat_finish(void); +void seat_reconfigure(void); void seat_force_focus_surface(struct seat *seat, struct wlr_surface *surface); void seat_focus_surface(struct seat *seat, struct wlr_surface *surface); @@ -406,16 +405,15 @@ void seat_focus_override_end(struct seat *seat, bool restore_focus); /** * interactive_anchor_to_cursor() - repositions the geometry to remain * underneath the cursor when its size changes during interactive move. - * This function also resizes server->grab_box and repositions it to remain - * underneath server->grab_{x,y}. + * This function also resizes g_server.grab_box and repositions it to remain + * underneath g_server.grab_{x,y}. * * geo->{width,height} are provided by the caller. * geo->{x,y} are computed by this function. */ -void interactive_anchor_to_cursor(struct server *server, struct wlr_box *geo); +void interactive_anchor_to_cursor(struct wlr_box *geo); -void interactive_set_grab_context(struct server *server, - const struct cursor_context *ctx); +void interactive_set_grab_context(const struct cursor_context *ctx); void interactive_begin(struct view *view, enum input_mode mode, enum lab_edge edges); void interactive_finish(struct view *view); @@ -433,12 +431,12 @@ bool edge_from_cursor(struct seat *seat, struct output **dest_output, void handle_tearing_new_object(struct wl_listener *listener, void *data); -void server_init(struct server *server); -void server_start(struct server *server); -void server_finish(struct server *server); +void server_init(void); +void server_start(void); +void server_finish(void); void create_constraint(struct wl_listener *listener, void *data); -void constrain_cursor(struct server *server, struct wlr_pointer_constraint_v1 +void constrain_cursor(struct wlr_pointer_constraint_v1 *constraint); #endif /* LABWC_H */ diff --git a/include/layers.h b/include/layers.h index 001347c8..8aaf23d3 100644 --- a/include/layers.h +++ b/include/layers.h @@ -12,7 +12,6 @@ struct seat; struct lab_layer_surface { struct wlr_layer_surface_v1 *layer_surface; struct wlr_scene_layer_surface_v1 *scene_layer_surface; - struct server *server; bool mapped; /* true only inside handle_unmap() */ @@ -29,7 +28,6 @@ struct lab_layer_surface { struct lab_layer_popup { struct wlr_xdg_popup *wlr_popup; struct wlr_scene_tree *scene_tree; - struct server *server; bool parent_was_focused; /* To simplify moving popup nodes from the bottom to the top layer */ @@ -41,8 +39,8 @@ struct lab_layer_popup { struct wl_listener reposition; }; -void layers_init(struct server *server); -void layers_finish(struct server *server); +void layers_init(void); +void layers_finish(void); void layers_arrange(struct output *output); void layer_try_set_focus(struct seat *seat, diff --git a/include/magnifier.h b/include/magnifier.h index afe79e22..aebc5721 100644 --- a/include/magnifier.h +++ b/include/magnifier.h @@ -14,8 +14,8 @@ enum magnify_dir { MAGNIFY_DECREASE }; -void magnifier_toggle(struct server *server); -void magnifier_set_scale(struct server *server, enum magnify_dir dir); +void magnifier_toggle(void); +void magnifier_set_scale(enum magnify_dir dir); bool output_wants_magnification(struct output *output); void magnifier_draw(struct output *output, struct wlr_buffer *output_buffer, struct wlr_box *damage); diff --git a/include/menu/menu.h b/include/menu/menu.h index f65ff9a3..31e94622 100644 --- a/include/menu/menu.h +++ b/include/menu/menu.h @@ -49,7 +49,6 @@ struct menu { int height; } size; struct wl_list menuitems; - struct server *server; struct { struct menu *menu; struct menuitem *item; @@ -65,14 +64,14 @@ struct menu { }; /* For keyboard support */ -void menu_item_select_next(struct server *server); -void menu_item_select_previous(struct server *server); -void menu_submenu_enter(struct server *server); -void menu_submenu_leave(struct server *server); -bool menu_call_selected_actions(struct server *server); +void menu_item_select_next(void); +void menu_item_select_previous(void); +void menu_submenu_enter(void); +void menu_submenu_leave(void); +bool menu_call_selected_actions(void); -void menu_init(struct server *server); -void menu_finish(struct server *server); +void menu_init(void); +void menu_finish(void); void menu_on_view_destroy(struct view *view); /** @@ -80,15 +79,15 @@ void menu_on_view_destroy(struct view *view); * * @id id string defined in menu.xml like "root-menu" */ -struct menu *menu_get_by_id(struct server *server, const char *id); +struct menu *menu_get_by_id(const char *id); /** * menu_open_root - open menu on position (x, y) * - * This function will close server->menu_current, open the - * new menu and assign @menu to server->menu_current. + * This function will close g_server.menu_current, open the + * new menu and assign @menu to g_server.menu_current. * - * Additionally, server->input_mode will be set to LAB_INPUT_STATE_MENU. + * Additionally, g_server.input_mode will be set to LAB_INPUT_STATE_MENU. */ void menu_open_root(struct menu *menu, int x, int y); @@ -103,14 +102,14 @@ void menu_process_cursor_motion(struct wlr_scene_node *node); /** * menu_close_root- close root menu * - * This function will close server->menu_current and set it to NULL. - * Asserts that server->input_mode is set to LAB_INPUT_STATE_MENU. + * This function will close g_server.menu_current and set it to NULL. + * Asserts that g_server.input_mode is set to LAB_INPUT_STATE_MENU. * - * Additionally, server->input_mode will be set to LAB_INPUT_STATE_PASSTHROUGH. + * Additionally, g_server.input_mode will be set to LAB_INPUT_STATE_PASSTHROUGH. */ -void menu_close_root(struct server *server); +void menu_close_root(void); /* menu_reconfigure - reload theme and content */ -void menu_reconfigure(struct server *server); +void menu_reconfigure(void); #endif /* LABWC_MENU_H */ diff --git a/include/output-virtual.h b/include/output-virtual.h index 7822e4f7..33d05e9a 100644 --- a/include/output-virtual.h +++ b/include/output-virtual.h @@ -5,9 +5,9 @@ struct server; struct wlr_output; -void output_virtual_add(struct server *server, const char *output_name, +void output_virtual_add(const char *output_name, struct wlr_output **store_wlr_output); -void output_virtual_remove(struct server *server, const char *output_name); -void output_virtual_update_fallback(struct server *server); +void output_virtual_remove(const char *output_name); +void output_virtual_update_fallback(void); #endif diff --git a/include/output.h b/include/output.h index 2b1e4bcf..4d5d63ae 100644 --- a/include/output.h +++ b/include/output.h @@ -9,7 +9,6 @@ struct output { struct wl_list link; /* server.outputs */ - struct server *server; struct wlr_output *wlr_output; struct wlr_output_state pending; struct wlr_scene_output *scene_output; @@ -45,13 +44,12 @@ struct output { #undef LAB_NR_LAYERS -void output_init(struct server *server); -void output_finish(struct server *server); -struct output *output_from_wlr_output(struct server *server, - struct wlr_output *wlr_output); -struct output *output_from_name(struct server *server, const char *name); -struct output *output_nearest_to(struct server *server, int lx, int ly); -struct output *output_nearest_to_cursor(struct server *server); +void output_init(void); +void output_finish(void); +struct output *output_from_wlr_output(struct wlr_output *wlr_output); +struct output *output_from_name(const char *name); +struct output *output_nearest_to(int lx, int ly); +struct output *output_nearest_to_cursor(void); /** * output_get_adjacent() - get next output, in a given direction, @@ -69,7 +67,7 @@ struct output *output_get_adjacent(struct output *output, bool output_is_usable(struct output *output); void output_update_usable_area(struct output *output); -void output_update_all_usable_areas(struct server *server, bool layout_changed); +void output_update_all_usable_areas(bool layout_changed); bool output_get_tearing_allowance(struct output *output); struct wlr_box output_usable_area_in_layout_coords(struct output *output); void handle_output_power_manager_set_mode(struct wl_listener *listener, diff --git a/include/regions.h b/include/regions.h index abe472be..1035400c 100644 --- a/include/regions.h +++ b/include/regions.h @@ -26,7 +26,7 @@ struct region { }; /* Returns true if we should show the region overlay or snap to region */ -bool regions_should_snap(struct server *server); +bool regions_should_snap(void); /** * regions_reconfigure*() - re-initializes all regions from struct rc. @@ -36,7 +36,7 @@ bool regions_should_snap(struct server *server); * - new output local regions are created from struct rc * - the region geometry is re-calculated */ -void regions_reconfigure(struct server *server); +void regions_reconfigure(void); void regions_reconfigure_output(struct output *output); /* re-calculate the geometry based on usable area */ @@ -62,7 +62,7 @@ void regions_evacuate_output(struct output *output); void regions_destroy(struct seat *seat, struct wl_list *regions); /* Get output local region from cursor or name, may be NULL */ -struct region *regions_from_cursor(struct server *server); +struct region *regions_from_cursor(void); struct region *regions_from_name(const char *region_name, struct output *output); #endif /* LABWC_REGIONS_H */ diff --git a/include/resize-indicator.h b/include/resize-indicator.h index e8fe8480..54f5c025 100644 --- a/include/resize-indicator.h +++ b/include/resize-indicator.h @@ -5,7 +5,7 @@ struct server; struct view; -void resize_indicator_reconfigure(struct server *server); +void resize_indicator_reconfigure(void); void resize_indicator_show(struct view *view); void resize_indicator_update(struct view *view); void resize_indicator_hide(struct view *view); diff --git a/include/scaled-buffer/scaled-icon-buffer.h b/include/scaled-buffer/scaled-icon-buffer.h index 45492ec2..45f83c91 100644 --- a/include/scaled-buffer/scaled-icon-buffer.h +++ b/include/scaled-buffer/scaled-icon-buffer.h @@ -12,7 +12,6 @@ struct wlr_scene_buffer; struct scaled_icon_buffer { struct scaled_buffer *scaled_buffer; struct wlr_scene_buffer *scene_buffer; - struct server *server; /* for window icon */ struct view *view; char *view_app_id; @@ -39,8 +38,7 @@ struct scaled_icon_buffer { * wlr_scene_buffer (or one of its parents) is being destroyed. */ struct scaled_icon_buffer *scaled_icon_buffer_create( - struct wlr_scene_tree *parent, struct server *server, - int width, int height); + struct wlr_scene_tree *parent, int width, int height); void scaled_icon_buffer_set_view(struct scaled_icon_buffer *self, struct view *view); diff --git a/include/session-lock.h b/include/session-lock.h index 207f0393..52e4e4f2 100644 --- a/include/session-lock.h +++ b/include/session-lock.h @@ -8,7 +8,6 @@ struct output; struct server; struct session_lock_manager { - struct server *server; struct wlr_session_lock_manager_v1 *wlr_manager; /* View re-focused on unlock */ struct view *last_active_view; @@ -31,8 +30,8 @@ struct session_lock_manager { struct wl_listener lock_destroy; }; -void session_lock_init(struct server *server); +void session_lock_init(void); void session_lock_output_create(struct session_lock_manager *manager, struct output *output); -void session_lock_update_for_layout_change(struct server *server); +void session_lock_update_for_layout_change(void); #endif /* LABWC_SESSION_LOCK_H */ diff --git a/include/ssd.h b/include/ssd.h index 1340c8dc..9c617474 100644 --- a/include/ssd.h +++ b/include/ssd.h @@ -51,8 +51,7 @@ void ssd_set_titlebar(struct ssd *ssd, bool enabled); void ssd_enable_keybind_inhibit_indicator(struct ssd *ssd, bool enable); void ssd_enable_shade(struct ssd *ssd, bool enable); -void ssd_update_hovered_button(struct server *server, - struct wlr_scene_node *node); +void ssd_update_hovered_button(struct wlr_scene_node *node); void ssd_button_free(struct ssd_button *button); diff --git a/include/theme.h b/include/theme.h index beba06cc..575fa93a 100644 --- a/include/theme.h +++ b/include/theme.h @@ -222,7 +222,7 @@ struct server; * @theme_name: theme-name in //labwc/themerc * Note is obtained in theme-dir.c */ -void theme_init(struct theme *theme, struct server *server, const char *theme_name); +void theme_init(struct theme *theme, const char *theme_name); /** * theme_finish - free button textures diff --git a/include/view.h b/include/view.h index dcc0d058..25469594 100644 --- a/include/view.h +++ b/include/view.h @@ -135,7 +135,6 @@ struct view_impl { }; struct view { - struct server *server; enum view_type type; const struct view_impl *impl; struct wl_list link; @@ -358,7 +357,7 @@ bool view_matches_query(struct view *view, struct view_query *query); * @criteria: Criteria to match against. * Example: * struct view *view; - * for_each_view(view, &server->views, LAB_VIEW_CRITERIA_NONE) { + * for_each_view(view, &g_server.views, LAB_VIEW_CRITERIA_NONE) { * printf("%s\n", view_get_string_prop(view, "app_id")); * } */ @@ -374,7 +373,7 @@ bool view_matches_query(struct view *view, struct view_query *query); * @criteria: Criteria to match against. * Example: * struct view *view; - * for_each_view_reverse(view, &server->views, LAB_VIEW_CRITERIA_NONE) { + * for_each_view_reverse(view, &g_server.views, LAB_VIEW_CRITERIA_NONE) { * printf("%s\n", view_get_string_prop(view, "app_id")); * } */ @@ -424,13 +423,13 @@ struct view *view_prev(struct wl_list *head, struct view *view, * struct view **view; * struct wl_array views; * wl_array_init(&views); - * view_array_append(server, &views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE); + * view_array_append(&views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE); * wl_array_for_each(view, &views) { * // Do something with *view * } * wl_array_release(&views); */ -void view_array_append(struct server *server, struct wl_array *views, +void view_array_append(struct wl_array *views, enum lab_view_criteria criteria); enum view_wants_focus view_wants_focus(struct view *view); diff --git a/include/workspaces.h b/include/workspaces.h index c12a9c45..5c0f4e7a 100644 --- a/include/workspaces.h +++ b/include/workspaces.h @@ -12,7 +12,6 @@ struct wlr_scene_tree; struct workspace { struct wl_list link; /* struct server.workspaces */ - struct server *server; char *name; struct wlr_scene_tree *tree; @@ -34,12 +33,12 @@ struct workspace { } on_ext; }; -void workspaces_init(struct server *server); +void workspaces_init(void); void workspaces_switch_to(struct workspace *target, bool update_focus); -void workspaces_destroy(struct server *server); +void workspaces_destroy(void); void workspaces_osd_hide(struct seat *seat); struct workspace *workspaces_find(struct workspace *anchor, const char *name, bool wrap); -void workspaces_reconfigure(struct server *server); +void workspaces_reconfigure(void); #endif /* LABWC_WORKSPACES_H */ diff --git a/include/xwayland.h b/include/xwayland.h index f313e165..48330a14 100644 --- a/include/xwayland.h +++ b/include/xwayland.h @@ -11,7 +11,6 @@ struct wlr_output; struct wlr_output_layout; struct xwayland_unmanaged { - struct server *server; struct wlr_xwayland_surface *xwayland_surface; struct wlr_scene_node *node; struct wl_list link; @@ -67,25 +66,22 @@ struct xwayland_view { }; -void xwayland_unmanaged_create(struct server *server, - struct wlr_xwayland_surface *xsurface, bool mapped); +void xwayland_unmanaged_create(struct wlr_xwayland_surface *xsurface, bool mapped); -void xwayland_view_create(struct server *server, - struct wlr_xwayland_surface *xsurface, bool mapped); +void xwayland_view_create(struct wlr_xwayland_surface *xsurface, bool mapped); -void xwayland_server_init(struct server *server, - struct wlr_compositor *compositor); -void xwayland_server_finish(struct server *server); +void xwayland_server_init(struct wlr_compositor *compositor); +void xwayland_server_finish(void); void xwayland_adjust_usable_area(struct view *view, struct wlr_output_layout *layout, struct wlr_output *output, struct wlr_box *usable); -void xwayland_update_workarea(struct server *server); +void xwayland_update_workarea(void); -void xwayland_reset_cursor(struct server *server); +void xwayland_reset_cursor(void); -void xwayland_flush(struct server *server); +void xwayland_flush(void); #endif /* HAVE_XWAYLAND */ #endif /* LABWC_XWAYLAND_H */ diff --git a/src/action.c b/src/action.c index 6d8c8419..04f0ca16 100644 --- a/src/action.c +++ b/src/action.c @@ -741,23 +741,23 @@ action_list_free(struct wl_list *action_list) } static void -show_menu(struct server *server, struct view *view, struct cursor_context *ctx, +show_menu(struct view *view, struct cursor_context *ctx, const char *menu_name, bool at_cursor, const char *pos_x, const char *pos_y) { - if (server->input_mode != LAB_INPUT_STATE_PASSTHROUGH - && server->input_mode != LAB_INPUT_STATE_MENU) { + if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH + && g_server.input_mode != LAB_INPUT_STATE_MENU) { /* Prevent opening a menu while resizing / moving a view */ return; } - struct menu *menu = menu_get_by_id(server, menu_name); + struct menu *menu = menu_get_by_id(menu_name); if (!menu) { return; } - int x = server->seat.cursor->x; - int y = server->seat.cursor->y; + int x = g_server.seat.cursor->x; + int y = g_server.seat.cursor->y; /* The client menu needs an active client */ bool is_client_menu = !strcasecmp(menu_name, "client-menu"); @@ -776,7 +776,7 @@ show_menu(struct server *server, struct view *view, struct cursor_context *ctx, int lx, ly; wlr_scene_node_coords(ctx->node, &lx, &ly); /* MAX() prevents negative x when the window is maximized */ - x = MAX(x, lx - server->theme->menu_border_width); + x = MAX(x, lx - g_server.theme->menu_border_width); } } @@ -785,8 +785,7 @@ show_menu(struct server *server, struct view *view, struct cursor_context *ctx, * x/y can be number, "center" or a %percent of screen dimensions */ if (pos_x && pos_y) { - struct output *output = output_nearest_to(server, - server->seat.cursor->x, server->seat.cursor->y); + struct output *output = output_nearest_to(g_server.seat.cursor->x, g_server.seat.cursor->y); struct wlr_box usable = output_usable_area_in_layout_coords(output); if (!strcasecmp(pos_x, "center")) { @@ -830,8 +829,7 @@ show_menu(struct server *server, struct view *view, struct cursor_context *ctx, } static struct view * -view_for_action(struct view *activator, struct server *server, - struct action *action, struct cursor_context *ctx) +view_for_action(struct view *activator, struct action *action, struct cursor_context *ctx) { /* View is explicitly specified for mousebinds */ if (activator) { @@ -843,17 +841,16 @@ view_for_action(struct view *activator, struct server *server, case ACTION_TYPE_FOCUS: case ACTION_TYPE_MOVE: case ACTION_TYPE_RESIZE: { - *ctx = get_cursor_context(server); + *ctx = get_cursor_context(); return ctx->view; } default: - return server->active_view; + return g_server.active_view; } } struct action_prompt { /* Set when created */ - struct server *server; struct action *action; struct view *view; @@ -930,7 +927,7 @@ print_prompt_command(struct buf *buf, const char *format, } static void -action_prompt_create(struct view *view, struct server *server, struct action *action) +action_prompt_create(struct view *view, struct action *action) { struct buf command = BUF_INIT; print_prompt_command(&command, rc.prompt_command, action, rc.theme); @@ -947,7 +944,6 @@ action_prompt_create(struct view *view, struct server *server, struct action *ac close(pipe_fd); struct action_prompt *prompt = znew(*prompt); - prompt->server = server; prompt->action = action; prompt->view = view; prompt->pid = prompt_pid; @@ -996,8 +992,7 @@ action_check_prompt_result(pid_t pid, int exit_code) } if (actions) { wlr_log(WLR_INFO, "Running actions"); - actions_run(prompt->view, prompt->server, - actions, /*cursor_ctx*/ NULL); + actions_run(prompt->view, actions, /*cursor_ctx*/ NULL); } else { wlr_log(WLR_INFO, "No actions for selected branch"); } @@ -1028,14 +1023,13 @@ match_queries(struct view *view, struct action *action) } static struct output * -get_target_output(struct output *output, struct server *server, - struct action *action) +get_target_output(struct output *output, struct action *action) { const char *output_name = action_get_str(action, "output", NULL); struct output *target = NULL; if (output_name) { - target = output_from_name(server, output_name); + target = output_from_name(output_name); } else { enum lab_edge edge = action_get_int(action, "direction", LAB_EDGE_NONE); @@ -1051,9 +1045,9 @@ get_target_output(struct output *output, struct server *server, } static void -warp_cursor(struct server *server, struct view *view, const char *to, const char *x, const char *y) +warp_cursor(struct view *view, const char *to, const char *x, const char *y) { - struct output *output = output_nearest_to_cursor(server); + struct output *output = output_nearest_to_cursor(); struct wlr_box target_area = {0}; int goto_x; int goto_y; @@ -1084,12 +1078,12 @@ warp_cursor(struct server *server, struct view *view, const char *to, const char target_area.y + target_area.height + offset_y; } - wlr_cursor_warp(server->seat.cursor, NULL, goto_x, goto_y); - cursor_update_focus(server); + wlr_cursor_warp(g_server.seat.cursor, NULL, goto_x, goto_y); + cursor_update_focus(); } static void -run_action(struct view *view, struct server *server, struct action *action, +run_action(struct view *view, struct action *action, struct cursor_context *ctx) { switch (action->type) { @@ -1111,7 +1105,7 @@ run_action(struct view *view, struct server *server, struct action *action, } break; case ACTION_TYPE_DEBUG: - debug_dump_scene(server); + debug_dump_scene(); break; case ACTION_TYPE_EXECUTE: { struct buf cmd = BUF_INIT; @@ -1122,7 +1116,7 @@ run_action(struct view *view, struct server *server, struct action *action, break; } case ACTION_TYPE_EXIT: - wl_display_terminate(server->wl_display); + wl_display_terminate(g_server.wl_display); break; case ACTION_TYPE_MOVE_TO_EDGE: if (view) { @@ -1177,10 +1171,10 @@ run_action(struct view *view, struct server *server, struct action *action, .app_id = action_get_int(action, "identifier", CYCLE_APP_ID_ALL), }; - if (server->input_mode == LAB_INPUT_STATE_CYCLE) { - cycle_step(server, dir); + if (g_server.input_mode == LAB_INPUT_STATE_CYCLE) { + cycle_step(dir); } else { - cycle_begin(server, dir, filter); + cycle_begin(dir, filter); } break; } @@ -1188,7 +1182,7 @@ run_action(struct view *view, struct server *server, struct action *action, kill(getpid(), SIGHUP); break; case ACTION_TYPE_SHOW_MENU: - show_menu(server, view, ctx, + show_menu(view, ctx, action_get_str(action, "menu", NULL), action_get_bool(action, "atCursor", true), action_get_str(action, "x.position", NULL), @@ -1255,7 +1249,7 @@ run_action(struct view *view, struct server *server, struct action *action, } break; case ACTION_TYPE_UNFOCUS: - seat_focus_surface(&server->seat, NULL); + seat_focus_surface(&g_server.seat, NULL); break; case ACTION_TYPE_ICONIFY: if (view) { @@ -1279,8 +1273,8 @@ run_action(struct view *view, struct server *server, struct action *action, * set by button press handling. For keybind-triggered * Move, set it now from current cursor position. */ - if (view != server->seat.pressed.ctx.view) { - interactive_set_grab_context(server, ctx); + if (view != g_server.seat.pressed.ctx.view) { + interactive_set_grab_context(ctx); } interactive_begin(view, LAB_INPUT_STATE_MOVE, LAB_EDGE_NONE); @@ -1300,8 +1294,8 @@ run_action(struct view *view, struct server *server, struct action *action, * set by button press handling. For keybind-triggered * Resize, set it now from current cursor position. */ - if (view != server->seat.pressed.ctx.view) { - interactive_set_grab_context(server, ctx); + if (view != g_server.seat.pressed.ctx.view) { + interactive_set_grab_context(ctx); } interactive_begin(view, LAB_INPUT_STATE_RESIZE, resize_edges); @@ -1375,12 +1369,12 @@ run_action(struct view *view, struct server *server, struct action *action, * a required argument for both SendToDesktop and GoToDesktop. */ struct workspace *target_workspace = workspaces_find( - server->workspaces.current, to, wrap); + g_server.workspaces.current, to, wrap); if (action->type == ACTION_TYPE_GO_TO_DESKTOP) { bool toggle = action_get_bool(action, "toggle", false); - if (target_workspace == server->workspaces.current + if (target_workspace == g_server.workspaces.current && toggle) { - target_workspace = server->workspaces.last; + target_workspace = g_server.workspaces.last; } } if (!target_workspace) { @@ -1391,8 +1385,8 @@ run_action(struct view *view, struct server *server, struct action *action, follow = action_get_bool(action, "follow", true); /* Ensure that the focus is not on another desktop */ - if (!follow && server->active_view == view) { - desktop_focus_topmost_view(server); + if (!follow && g_server.active_view == view) { + desktop_focus_topmost_view(); } } if (follow) { @@ -1406,7 +1400,7 @@ run_action(struct view *view, struct server *server, struct action *action, break; } struct output *target_output = - get_target_output(view->output, server, action); + get_target_output(view->output, action); if (target_output) { view_move_to_output(view, target_output); } @@ -1458,9 +1452,9 @@ run_action(struct view *view, struct server *server, struct action *action, } break; case ACTION_TYPE_FOCUS_OUTPUT: { - struct output *output = output_nearest_to_cursor(server); + struct output *output = output_nearest_to_cursor(); struct output *target_output = - get_target_output(output, server, action); + get_target_output(output, action); if (target_output) { desktop_focus_output(target_output); } @@ -1473,7 +1467,7 @@ run_action(struct view *view, struct server *server, struct action *action, * We delay the selection and execution of the * branch until we get a response from the user. */ - action_prompt_create(view, server, action); + action_prompt_create(view, action); } else if (view) { struct wl_list *actions; if (match_queries(view, action)) { @@ -1482,7 +1476,7 @@ run_action(struct view *view, struct server *server, struct action *action, actions = action_get_actionlist(action, "else"); } if (actions) { - actions_run(view, server, actions, ctx); + actions_run(view, actions, ctx); } } break; @@ -1493,7 +1487,7 @@ run_action(struct view *view, struct server *server, struct action *action, struct wl_array views; wl_array_init(&views); - view_array_append(server, &views, LAB_VIEW_CRITERIA_NONE); + view_array_append(&views, LAB_VIEW_CRITERIA_NONE); struct view **item; wl_array_for_each(item, &views) { @@ -1504,14 +1498,14 @@ run_action(struct view *view, struct server *server, struct action *action, actions = action_get_actionlist(action, "else"); } if (actions) { - actions_run(*item, server, actions, ctx); + actions_run(*item, actions, ctx); } } wl_array_release(&views); if (!matches) { actions = action_get_actionlist(action, "none"); if (actions) { - actions_run(view, server, actions, NULL); + actions_run(view, actions, NULL); } } break; @@ -1520,7 +1514,7 @@ run_action(struct view *view, struct server *server, struct action *action, /* TODO: rename this argument to "outputName" */ const char *output_name = action_get_str(action, "output_name", NULL); - output_virtual_add(server, output_name, + output_virtual_add(output_name, /*store_wlr_output*/ NULL); break; } @@ -1528,7 +1522,7 @@ run_action(struct view *view, struct server *server, struct action *action, /* TODO: rename this argument to "outputName" */ const char *output_name = action_get_str(action, "output_name", NULL); - output_virtual_remove(server, output_name); + output_virtual_remove(output_name); break; } case ACTION_TYPE_AUTO_PLACE: @@ -1575,14 +1569,14 @@ run_action(struct view *view, struct server *server, struct action *action, } break; case ACTION_TYPE_ENABLE_SCROLL_WHEEL_EMULATION: - server->seat.cursor_scroll_wheel_emulation = true; + g_server.seat.cursor_scroll_wheel_emulation = true; break; case ACTION_TYPE_DISABLE_SCROLL_WHEEL_EMULATION: - server->seat.cursor_scroll_wheel_emulation = false; + g_server.seat.cursor_scroll_wheel_emulation = false; break; case ACTION_TYPE_TOGGLE_SCROLL_WHEEL_EMULATION: - server->seat.cursor_scroll_wheel_emulation = - !server->seat.cursor_scroll_wheel_emulation; + g_server.seat.cursor_scroll_wheel_emulation = + !g_server.seat.cursor_scroll_wheel_emulation; break; case ACTION_TYPE_ENABLE_TABLET_MOUSE_EMULATION: rc.tablet.force_mouse_emulation = true; @@ -1594,23 +1588,23 @@ run_action(struct view *view, struct server *server, struct action *action, rc.tablet.force_mouse_emulation = !rc.tablet.force_mouse_emulation; break; case ACTION_TYPE_TOGGLE_MAGNIFY: - magnifier_toggle(server); + magnifier_toggle(); break; case ACTION_TYPE_ZOOM_IN: - magnifier_set_scale(server, MAGNIFY_INCREASE); + magnifier_set_scale(MAGNIFY_INCREASE); break; case ACTION_TYPE_ZOOM_OUT: - magnifier_set_scale(server, MAGNIFY_DECREASE); + magnifier_set_scale(MAGNIFY_DECREASE); break; case ACTION_TYPE_WARP_CURSOR: { const char *to = action_get_str(action, "to", "output"); const char *x = action_get_str(action, "x", "center"); const char *y = action_get_str(action, "y", "center"); - warp_cursor(server, view, to, x, y); + warp_cursor(view, to, x, y); break; } case ACTION_TYPE_HIDE_CURSOR: - cursor_set_visible(&server->seat, false); + cursor_set_visible(&g_server.seat, false); break; case ACTION_TYPE_INVALID: wlr_log(WLR_ERROR, "Not executing unknown action"); @@ -1628,8 +1622,7 @@ run_action(struct view *view, struct server *server, struct action *action, } void -actions_run(struct view *activator, struct server *server, - struct wl_list *actions, struct cursor_context *cursor_ctx) +actions_run(struct view *activator, struct wl_list *actions, struct cursor_context *cursor_ctx) { if (!actions) { wlr_log(WLR_ERROR, "empty actions"); @@ -1646,7 +1639,7 @@ actions_run(struct view *activator, struct server *server, struct action *action; wl_list_for_each(action, actions, link) { - if (server->input_mode == LAB_INPUT_STATE_CYCLE + if (g_server.input_mode == LAB_INPUT_STATE_CYCLE && action->type != ACTION_TYPE_NEXT_WINDOW && action->type != ACTION_TYPE_PREVIOUS_WINDOW) { wlr_log(WLR_INFO, "Only NextWindow or PreviousWindow " @@ -1661,8 +1654,8 @@ actions_run(struct view *activator, struct server *server, * Refetch view because it may have been changed due to the * previous action */ - struct view *view = view_for_action(activator, server, action, &ctx); + struct view *view = view_for_action(activator, action, &ctx); - run_action(view, server, action, &ctx); + run_action(view, action, &ctx); } } diff --git a/src/config/keybind.c b/src/config/keybind.c index 1705983a..fd0832d9 100644 --- a/src/config/keybind.c +++ b/src/config/keybind.c @@ -121,9 +121,9 @@ update_keycodes_iter(struct xkb_keymap *keymap, xkb_keycode_t key, void *data) } void -keybind_update_keycodes(struct server *server) +keybind_update_keycodes(void) { - struct xkb_state *state = server->seat.keyboard_group->keyboard.xkb_state; + struct xkb_state *state = g_server.seat.keyboard_group->keyboard.xkb_state; struct xkb_keymap *keymap = xkb_state_get_keymap(state); struct keybind *keybind; diff --git a/src/config/session.c b/src/config/session.c index 1c2f6cb7..e7e77412 100644 --- a/src/config/session.c +++ b/src/config/session.c @@ -185,7 +185,7 @@ backend_check_drm(struct wlr_backend *backend, void *is_drm) } static bool -should_update_activation(struct server *server) +should_update_activation(void) { static const char *act_env = "LABWC_UPDATE_ACTIVATION_ENV"; char *env = getenv(act_env); @@ -204,14 +204,14 @@ should_update_activation(struct server *server) /* With no valid preference, update when a DRM backend is in use */ bool have_drm = false; - wlr_multi_for_each_backend(server->backend, backend_check_drm, &have_drm); + wlr_multi_for_each_backend(g_server.backend, backend_check_drm, &have_drm); return have_drm; } static void -update_activation_env(struct server *server, bool initialize) +update_activation_env(bool initialize) { - if (!should_update_activation(server)) { + if (!should_update_activation()) { return; } @@ -312,18 +312,18 @@ session_run_script(const char *script) } void -session_autostart_init(struct server *server) +session_autostart_init(void) { /* Update dbus and systemd user environment, each may fail gracefully */ - update_activation_env(server, /* initialize */ true); + update_activation_env(/* initialize */ true); session_run_script("autostart"); } void -session_shutdown(struct server *server) +session_shutdown(void) { session_run_script("shutdown"); /* Clear the dbus and systemd user environment, each may fail gracefully */ - update_activation_env(server, /* initialize */ false); + update_activation_env(/* initialize */ false); } diff --git a/src/cycle/cycle.c b/src/cycle/cycle.c index ef323110..c09000e8 100644 --- a/src/cycle/cycle.c +++ b/src/cycle/cycle.c @@ -18,17 +18,16 @@ #include "theme.h" #include "view.h" -static bool init_cycle(struct server *server, struct cycle_filter filter); -static void update_cycle(struct server *server); -static void destroy_cycle(struct server *server); +static bool init_cycle(struct cycle_filter filter); +static void update_cycle(void); +static void destroy_cycle(void); static void update_preview_outlines(struct view *view) { /* Create / Update preview outline tree */ - struct server *server = view->server; - struct theme *theme = server->theme; - struct lab_scene_rect *rect = view->server->cycle.preview_outline; + struct theme *theme = g_server.theme; + struct lab_scene_rect *rect = g_server.cycle.preview_outline; if (!rect) { struct lab_scene_rect_options opts = { .border_colors = (float *[3]) { @@ -39,10 +38,10 @@ update_preview_outlines(struct view *view) .nr_borders = 3, .border_width = theme->osd_window_switcher_preview_border_width, }; - rect = lab_scene_rect_create(&server->scene->tree, &opts); + rect = lab_scene_rect_create(&g_server.scene->tree, &opts); wlr_scene_node_place_above(&rect->tree->node, - &server->cycle_preview_tree->node); - server->cycle.preview_outline = rect; + &g_server.cycle_preview_tree->node); + g_server.cycle.preview_outline = rect; } struct wlr_box geo = ssd_max_extents(view); @@ -52,21 +51,21 @@ update_preview_outlines(struct view *view) /* Returns the view to select next in the window switcher. */ static struct view * -get_next_selected_view(struct server *server, enum lab_cycle_dir dir) +get_next_selected_view(enum lab_cycle_dir dir) { - struct cycle_state *cycle = &server->cycle; + struct cycle_state *cycle = &g_server.cycle; assert(cycle->selected_view); - assert(!wl_list_empty(&server->cycle.views)); + assert(!wl_list_empty(&g_server.cycle.views)); struct wl_list *link; if (dir == LAB_CYCLE_DIR_FORWARD) { link = cycle->selected_view->cycle_link.next; - if (link == &server->cycle.views) { + if (link == &g_server.cycle.views) { link = link->next; } } else { link = cycle->selected_view->cycle_link.prev; - if (link == &server->cycle.views) { + if (link == &g_server.cycle.views) { link = link->prev; } } @@ -83,22 +82,22 @@ get_first_view(struct wl_list *views) } void -cycle_reinitialize(struct server *server) +cycle_reinitialize(void) { - struct cycle_state *cycle = &server->cycle; + struct cycle_state *cycle = &g_server.cycle; - if (server->input_mode != LAB_INPUT_STATE_CYCLE) { + if (g_server.input_mode != LAB_INPUT_STATE_CYCLE) { /* OSD not active, no need for clean up */ return; } struct view *selected_view = cycle->selected_view; struct view *selected_view_prev = - get_next_selected_view(server, LAB_CYCLE_DIR_BACKWARD); + get_next_selected_view(LAB_CYCLE_DIR_BACKWARD); struct cycle_filter filter = cycle->filter; - destroy_cycle(server); - if (init_cycle(server, filter)) { + destroy_cycle(); + if (init_cycle(filter)) { /* * Preserve the selected view (or its previous view) if it's * still in the cycle list @@ -110,104 +109,104 @@ cycle_reinitialize(struct server *server) } else { /* should be unreachable */ wlr_log(WLR_ERROR, "could not find view to select"); - cycle->selected_view = get_first_view(&server->cycle.views); + cycle->selected_view = get_first_view(&g_server.cycle.views); } - update_cycle(server); + update_cycle(); } else { /* Failed to re-init window switcher, exit */ - cycle_finish(server, /*switch_focus*/ false); + cycle_finish(/*switch_focus*/ false); } } void -cycle_on_cursor_release(struct server *server, struct wlr_scene_node *node) +cycle_on_cursor_release(struct wlr_scene_node *node) { - assert(server->input_mode == LAB_INPUT_STATE_CYCLE); + assert(g_server.input_mode == LAB_INPUT_STATE_CYCLE); struct cycle_osd_item *item = node_cycle_osd_item_from_node(node); - server->cycle.selected_view = item->view; - cycle_finish(server, /*switch_focus*/ true); + g_server.cycle.selected_view = item->view; + cycle_finish(/*switch_focus*/ true); } static void -restore_preview_node(struct server *server) +restore_preview_node(void) { - if (server->cycle.preview_node) { - wlr_scene_node_reparent(server->cycle.preview_node, - server->cycle.preview_dummy->parent); - wlr_scene_node_place_above(server->cycle.preview_node, - server->cycle.preview_dummy); - wlr_scene_node_destroy(server->cycle.preview_dummy); + if (g_server.cycle.preview_node) { + wlr_scene_node_reparent(g_server.cycle.preview_node, + g_server.cycle.preview_dummy->parent); + wlr_scene_node_place_above(g_server.cycle.preview_node, + g_server.cycle.preview_dummy); + wlr_scene_node_destroy(g_server.cycle.preview_dummy); /* Node was disabled / minimized before, disable again */ - if (!server->cycle.preview_was_enabled) { - wlr_scene_node_set_enabled(server->cycle.preview_node, false); + if (!g_server.cycle.preview_was_enabled) { + wlr_scene_node_set_enabled(g_server.cycle.preview_node, false); } - if (server->cycle.preview_was_shaded) { - struct view *view = node_view_from_node(server->cycle.preview_node); + if (g_server.cycle.preview_was_shaded) { + struct view *view = node_view_from_node(g_server.cycle.preview_node); view_set_shade(view, true); } - server->cycle.preview_node = NULL; - server->cycle.preview_dummy = NULL; - server->cycle.preview_was_enabled = false; - server->cycle.preview_was_shaded = false; + g_server.cycle.preview_node = NULL; + g_server.cycle.preview_dummy = NULL; + g_server.cycle.preview_was_enabled = false; + g_server.cycle.preview_was_shaded = false; } } void -cycle_begin(struct server *server, enum lab_cycle_dir direction, +cycle_begin(enum lab_cycle_dir direction, struct cycle_filter filter) { - if (server->input_mode != LAB_INPUT_STATE_PASSTHROUGH) { + if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { return; } - if (!init_cycle(server, filter)) { + if (!init_cycle(filter)) { return; } - struct view *active_view = server->active_view; + struct view *active_view = g_server.active_view; if (active_view && active_view->cycle_link.next) { /* Select the active view it's in the cycle list */ - server->cycle.selected_view = active_view; + g_server.cycle.selected_view = active_view; } else { /* Otherwise, select the first view in the cycle list */ - server->cycle.selected_view = get_first_view(&server->cycle.views); + g_server.cycle.selected_view = get_first_view(&g_server.cycle.views); } /* Pre-select the next view in the given direction */ - server->cycle.selected_view = get_next_selected_view(server, direction); + g_server.cycle.selected_view = get_next_selected_view(direction); - seat_focus_override_begin(&server->seat, + seat_focus_override_begin(&g_server.seat, LAB_INPUT_STATE_CYCLE, LAB_CURSOR_DEFAULT); - update_cycle(server); + update_cycle(); /* Update cursor, in case it is within the area covered by OSD */ - cursor_update_focus(server); + cursor_update_focus(); } void -cycle_step(struct server *server, enum lab_cycle_dir direction) +cycle_step(enum lab_cycle_dir direction) { - assert(server->input_mode == LAB_INPUT_STATE_CYCLE); + assert(g_server.input_mode == LAB_INPUT_STATE_CYCLE); - server->cycle.selected_view = get_next_selected_view(server, direction); - update_cycle(server); + g_server.cycle.selected_view = get_next_selected_view(direction); + update_cycle(); } void -cycle_finish(struct server *server, bool switch_focus) +cycle_finish(bool switch_focus) { - if (server->input_mode != LAB_INPUT_STATE_CYCLE) { + if (g_server.input_mode != LAB_INPUT_STATE_CYCLE) { return; } - struct view *selected_view = server->cycle.selected_view; - destroy_cycle(server); + struct view *selected_view = g_server.cycle.selected_view; + destroy_cycle(); - seat_focus_override_end(&server->seat, /*restore_focus*/ false); + seat_focus_override_end(&g_server.seat, /*restore_focus*/ false); /* Hiding OSD may need a cursor change */ - cursor_update_focus(server); + cursor_update_focus(); if (switch_focus && selected_view) { if (rc.window_switcher.unshade) { @@ -222,11 +221,10 @@ preview_selected_view(struct view *view) { assert(view); assert(view->scene_tree); - struct server *server = view->server; - struct cycle_state *cycle = &server->cycle; + struct cycle_state *cycle = &g_server.cycle; /* Move previous selected node back to its original place */ - restore_preview_node(server); + restore_preview_node(); cycle->preview_node = &view->scene_tree->node; @@ -246,7 +244,7 @@ preview_selected_view(struct view *view) } wlr_scene_node_reparent(cycle->preview_node, - view->server->cycle_preview_tree); + g_server.cycle_preview_tree); /* Finally raise selected node to the top */ wlr_scene_node_raise_to_top(cycle->preview_node); @@ -265,8 +263,7 @@ get_osd_impl(void) } static uint64_t -get_outputs_by_filter(struct server *server, - enum cycle_output_filter output_filter) +get_outputs_by_filter(enum cycle_output_filter output_filter) { struct output *output = NULL; @@ -274,15 +271,15 @@ get_outputs_by_filter(struct server *server, case CYCLE_OUTPUT_ALL: break; case CYCLE_OUTPUT_CURSOR: - output = output_nearest_to_cursor(server); + output = output_nearest_to_cursor(); break; case CYCLE_OUTPUT_FOCUSED: { - struct view *view = server->active_view; + struct view *view = g_server.active_view; if (view && output_is_usable(view->output)) { output = view->output; } else { /* Fallback to pointer */ - output = output_nearest_to_cursor(server); + output = output_nearest_to_cursor(); } break; } @@ -327,7 +324,7 @@ handle_osd_tree_destroy(struct wl_listener *listener, void *data) /* Return false on failure */ static bool -init_cycle(struct server *server, struct cycle_filter filter) +init_cycle(struct cycle_filter filter) { enum lab_view_criteria criteria = LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER @@ -337,15 +334,15 @@ init_cycle(struct server *server, struct cycle_filter filter) } uint64_t cycle_outputs = - get_outputs_by_filter(server, filter.output); + get_outputs_by_filter(filter.output); const char *cycle_app_id = NULL; - if (filter.app_id == CYCLE_APP_ID_CURRENT && server->active_view) { - cycle_app_id = server->active_view->app_id; + if (filter.app_id == CYCLE_APP_ID_CURRENT && g_server.active_view) { + cycle_app_id = g_server.active_view->app_id; } struct view *view; - for_each_view(view, &server->views, criteria) { + for_each_view(view, &g_server.views, criteria) { if (filter.output != CYCLE_OUTPUT_ALL) { if (!view->output || !(cycle_outputs & view->output->id_bit)) { continue; @@ -356,23 +353,22 @@ init_cycle(struct server *server, struct cycle_filter filter) } if (rc.window_switcher.order == WINDOW_SWITCHER_ORDER_AGE) { - insert_view_ordered_by_age(&server->cycle.views, view); + insert_view_ordered_by_age(&g_server.cycle.views, view); } else { - wl_list_append(&server->cycle.views, &view->cycle_link); + wl_list_append(&g_server.cycle.views, &view->cycle_link); } } - if (wl_list_empty(&server->cycle.views)) { + if (wl_list_empty(&g_server.cycle.views)) { wlr_log(WLR_DEBUG, "no views to switch between"); return false; } - server->cycle.filter = filter; + g_server.cycle.filter = filter; if (rc.window_switcher.osd.show) { /* Create OSD */ - uint64_t osd_outputs = get_outputs_by_filter(server, - rc.window_switcher.osd.output_filter); + uint64_t osd_outputs = get_outputs_by_filter(rc.window_switcher.osd.output_filter); struct output *output; - wl_list_for_each(output, &server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { if (!(osd_outputs & output->id_bit)) { continue; } @@ -381,7 +377,7 @@ init_cycle(struct server *server, struct cycle_filter filter) } struct cycle_osd_output *osd_output = znew(*osd_output); - wl_list_append(&server->cycle.osd_outputs, &osd_output->link); + wl_list_append(&g_server.cycle.osd_outputs, &osd_output->link); osd_output->output = output; wl_list_init(&osd_output->items); @@ -397,9 +393,9 @@ init_cycle(struct server *server, struct cycle_filter filter) } static void -update_cycle(struct server *server) +update_cycle(void) { - struct cycle_state *cycle = &server->cycle; + struct cycle_state *cycle = &g_server.cycle; if (rc.window_switcher.osd.show) { struct cycle_osd_output *osd_output; @@ -420,29 +416,29 @@ update_cycle(struct server *server) } } -/* Resets all the states in server->cycle */ +/* Resets all the states in g_server.cycle */ static void -destroy_cycle(struct server *server) +destroy_cycle(void) { struct cycle_osd_output *osd_output, *tmp; - wl_list_for_each_safe(osd_output, tmp, &server->cycle.osd_outputs, link) { + wl_list_for_each_safe(osd_output, tmp, &g_server.cycle.osd_outputs, link) { /* calls handle_osd_tree_destroy() */ wlr_scene_node_destroy(&osd_output->tree->node); } - restore_preview_node(server); + restore_preview_node(); - if (server->cycle.preview_outline) { - wlr_scene_node_destroy(&server->cycle.preview_outline->tree->node); + if (g_server.cycle.preview_outline) { + wlr_scene_node_destroy(&g_server.cycle.preview_outline->tree->node); } struct view *view, *tmp2; - wl_list_for_each_safe(view, tmp2, &server->cycle.views, cycle_link) { + wl_list_for_each_safe(view, tmp2, &g_server.cycle.views, cycle_link) { wl_list_remove(&view->cycle_link); view->cycle_link = (struct wl_list){0}; } - server->cycle = (struct cycle_state){0}; - wl_list_init(&server->cycle.views); - wl_list_init(&server->cycle.osd_outputs); + g_server.cycle = (struct cycle_state){0}; + wl_list_init(&g_server.cycle.views); + wl_list_init(&g_server.cycle.osd_outputs); } diff --git a/src/cycle/osd-classic.c b/src/cycle/osd-classic.c index 3deeaa81..38b12a7c 100644 --- a/src/cycle/osd-classic.c +++ b/src/cycle/osd-classic.c @@ -28,11 +28,11 @@ struct cycle_osd_classic_item { }; static void -create_fields_scene(struct server *server, struct view *view, +create_fields_scene(struct view *view, struct wlr_scene_tree *parent, const float *text_color, const float *bg_color, int field_widths_sum, int x, int y) { - struct theme *theme = server->theme; + struct theme *theme = g_server.theme; struct window_switcher_classic_theme *switcher_theme = &theme->osd_window_switcher_classic; @@ -46,8 +46,7 @@ create_fields_scene(struct server *server, struct view *view, int icon_size = MIN(field_width, switcher_theme->item_icon_size); struct scaled_icon_buffer *icon_buffer = - scaled_icon_buffer_create(parent, - server, icon_size, icon_size); + scaled_icon_buffer_create(parent, icon_size, icon_size); scaled_icon_buffer_set_view(icon_buffer, view); node = &icon_buffer->scene_buffer->node; height = icon_size; @@ -81,17 +80,16 @@ static void cycle_osd_classic_init(struct cycle_osd_output *osd_output) { struct output *output = osd_output->output; - struct server *server = output->server; - struct theme *theme = server->theme; + struct theme *theme = g_server.theme; struct window_switcher_classic_theme *switcher_theme = &theme->osd_window_switcher_classic; int padding = theme->osd_border_width + switcher_theme->padding; bool show_workspace = wl_list_length(&rc.workspace_config.workspaces) > 1; - const char *workspace_name = server->workspaces.current->name; - int nr_views = wl_list_length(&server->cycle.views); + const char *workspace_name = g_server.workspaces.current->name; + int nr_views = wl_list_length(&g_server.cycle.views); struct wlr_box output_box; - wlr_output_layout_get_box(server->output_layout, output->wlr_output, + wlr_output_layout_get_box(g_server.output_layout, output->wlr_output, &output_box); int w = switcher_theme->width; @@ -166,7 +164,7 @@ cycle_osd_classic_init(struct cycle_osd_output *osd_output) /* Draw text for each node */ struct view *view; - wl_list_for_each(view, &server->cycle.views, cycle_link) { + wl_list_for_each(view, &g_server.cycle.views, cycle_link) { struct cycle_osd_classic_item *item = znew(*item); wl_list_append(&osd_output->items, &item->base.link); item->base.view = view; @@ -214,9 +212,9 @@ cycle_osd_classic_init(struct cycle_osd_output *osd_output) w - 2 * padding, switcher_theme->item_height, (float[4]) {0}); wlr_scene_node_set_position(&hitbox->node, padding, y); - create_fields_scene(server, view, item->normal_tree, + create_fields_scene(view, item->normal_tree, text_color, bg_color, field_widths_sum, x, y); - create_fields_scene(server, view, item->active_tree, + create_fields_scene(view, item->active_tree, text_color, active_bg_color, field_widths_sum, x, y); y += switcher_theme->item_height; @@ -243,12 +241,11 @@ error:; static void cycle_osd_classic_update(struct cycle_osd_output *osd_output) { - struct server *server = osd_output->output->server; cycle_osd_scroll_update(osd_output); struct cycle_osd_classic_item *item; wl_list_for_each(item, &osd_output->items, base.link) { - bool active = item->base.view == server->cycle.selected_view; + bool active = item->base.view == g_server.cycle.selected_view; wlr_scene_node_set_enabled(&item->normal_tree->node, !active); wlr_scene_node_set_enabled(&item->active_tree->node, active); } diff --git a/src/cycle/osd-field.c b/src/cycle/osd-field.c index cfc32811..f12f5dcc 100644 --- a/src/cycle/osd-field.c +++ b/src/cycle/osd-field.c @@ -45,7 +45,7 @@ static const char * get_desktop_name(struct view *view) { #if HAVE_LIBSFDO - const char *name = desktop_entry_name_lookup(view->server, view->app_id); + const char *name = desktop_entry_name_lookup(view->app_id); if (name) { return name; } @@ -148,7 +148,7 @@ static void field_set_output_short(struct buf *buf, struct view *view, const char *format) { /* custom type conversion-specifier: o */ - if (wl_list_length(&view->server->outputs) > 1 && + if (wl_list_length(&g_server.outputs) > 1 && output_is_usable(view->output)) { buf_add(buf, view->output->wlr_output->name); } diff --git a/src/cycle/osd-scroll.c b/src/cycle/osd-scroll.c index a1559932..c31ecff3 100644 --- a/src/cycle/osd-scroll.c +++ b/src/cycle/osd-scroll.c @@ -42,12 +42,10 @@ cycle_osd_scroll_init(struct cycle_osd_output *osd_output, struct wlr_box bar_ar static int get_cycle_idx(struct cycle_osd_output *osd_output) { - struct server *server = osd_output->output->server; - int idx = 0; struct cycle_osd_item *item; wl_list_for_each(item, &osd_output->items, link) { - if (item->view == server->cycle.selected_view) { + if (item->view == g_server.cycle.selected_view) { return idx; } idx++; diff --git a/src/cycle/osd-thumbnail.c b/src/cycle/osd-thumbnail.c index bf6b6026..98dcbaf0 100644 --- a/src/cycle/osd-thumbnail.c +++ b/src/cycle/osd-thumbnail.c @@ -28,7 +28,7 @@ struct cycle_osd_thumbnail_item { }; static void -render_node(struct server *server, struct wlr_render_pass *pass, +render_node(struct wlr_render_pass *pass, struct wlr_scene_node *node, int x, int y) { switch (node->type) { @@ -36,7 +36,7 @@ render_node(struct server *server, struct wlr_render_pass *pass, struct wlr_scene_tree *tree = wlr_scene_tree_from_node(node); struct wlr_scene_node *child; wl_list_for_each(child, &tree->children, link) { - render_node(server, pass, child, x + node->x, y + node->y); + render_node(pass, child, x + node->x, y + node->y); } break; } @@ -47,7 +47,7 @@ render_node(struct server *server, struct wlr_render_pass *pass, break; } struct wlr_texture *texture = wlr_texture_from_buffer( - server->renderer, scene_buffer->buffer); + g_server.renderer, scene_buffer->buffer); if (!texture) { break; } @@ -82,13 +82,12 @@ render_thumb(struct output *output, struct view *view) */ return NULL; } - struct server *server = output->server; - struct wlr_buffer *buffer = wlr_allocator_create_buffer(server->allocator, + struct wlr_buffer *buffer = wlr_allocator_create_buffer(g_server.allocator, view->current.width, view->current.height, &output->wlr_output->swapchain->format); struct wlr_render_pass *pass = wlr_renderer_begin_buffer_pass( - server->renderer, buffer, NULL); - render_node(server, pass, &view->content_tree->node, 0, 0); + g_server.renderer, buffer, NULL); + render_node(pass, &view->content_tree->node, 0, 0); if (!wlr_render_pass_submit(pass)) { wlr_log(WLR_ERROR, "failed to submit render pass"); wlr_buffer_drop(buffer); @@ -120,8 +119,7 @@ static struct cycle_osd_thumbnail_item * create_item_scene(struct wlr_scene_tree *parent, struct view *view, struct cycle_osd_output *osd_output) { - struct server *server = osd_output->output->server; - struct theme *theme = server->theme; + struct theme *theme = g_server.theme; struct window_switcher_thumbnail_theme *switcher_theme = &theme->osd_window_switcher_thumbnail; int padding = theme->border_width + switcher_theme->item_padding; @@ -185,7 +183,7 @@ create_item_scene(struct wlr_scene_tree *parent, struct view *view, /* icon */ int icon_size = switcher_theme->item_icon_size; struct scaled_icon_buffer *icon_buffer = - scaled_icon_buffer_create(tree, server, icon_size, icon_size); + scaled_icon_buffer_create(tree, icon_size, icon_size); scaled_icon_buffer_set_view(icon_buffer, view); int x = (switcher_theme->item_width - icon_size) / 2; int y = title_y - padding - icon_size + 10; /* slide by 10px */ @@ -198,7 +196,7 @@ static void get_items_geometry(struct output *output, int nr_thumbs, int *nr_cols, int *nr_rows, int *nr_visible_rows) { - struct theme *theme = output->server->theme; + struct theme *theme = g_server.theme; struct window_switcher_thumbnail_theme *switcher_theme = &theme->osd_window_switcher_thumbnail; int output_width, output_height; @@ -234,8 +232,7 @@ static void cycle_osd_thumbnail_init(struct cycle_osd_output *osd_output) { struct output *output = osd_output->output; - struct server *server = output->server; - struct theme *theme = server->theme; + struct theme *theme = g_server.theme; struct window_switcher_thumbnail_theme *switcher_theme = &theme->osd_window_switcher_thumbnail; int padding = theme->osd_border_width + switcher_theme->padding; @@ -243,7 +240,7 @@ cycle_osd_thumbnail_init(struct cycle_osd_output *osd_output) osd_output->tree = lab_wlr_scene_tree_create(output->cycle_osd_tree); osd_output->items_tree = lab_wlr_scene_tree_create(osd_output->tree); - int nr_views = wl_list_length(&server->cycle.views); + int nr_views = wl_list_length(&g_server.cycle.views); assert(nr_views > 0); int nr_cols, nr_rows, nr_visible_rows; get_items_geometry(output, nr_views, &nr_cols, &nr_rows, &nr_visible_rows); @@ -251,7 +248,7 @@ cycle_osd_thumbnail_init(struct cycle_osd_output *osd_output) /* items */ struct view *view; int index = 0; - wl_list_for_each(view, &server->cycle.views, cycle_link) { + wl_list_for_each(view, &g_server.cycle.views, cycle_link) { struct cycle_osd_thumbnail_item *item = create_item_scene( osd_output->items_tree, view, osd_output); if (!item) { @@ -292,7 +289,7 @@ cycle_osd_thumbnail_init(struct cycle_osd_output *osd_output) /* center */ struct wlr_box output_box; - wlr_output_layout_get_box(server->output_layout, output->wlr_output, + wlr_output_layout_get_box(g_server.output_layout, output->wlr_output, &output_box); int lx = output_box.x + (output_box.width - bg_opts.width) / 2; int ly = output_box.y + (output_box.height - bg_opts.height) / 2; @@ -302,12 +299,11 @@ cycle_osd_thumbnail_init(struct cycle_osd_output *osd_output) static void cycle_osd_thumbnail_update(struct cycle_osd_output *osd_output) { - struct server *server = osd_output->output->server; cycle_osd_scroll_update(osd_output); struct cycle_osd_thumbnail_item *item; wl_list_for_each(item, &osd_output->items, base.link) { - bool active = (item->base.view == server->cycle.selected_view); + bool active = (item->base.view == g_server.cycle.selected_view); wlr_scene_node_set_enabled(&item->active_bg->tree->node, active); wlr_scene_node_set_enabled( &item->active_label->scene_buffer->node, active); diff --git a/src/debug.c b/src/debug.c index 62c90b52..f0656f04 100644 --- a/src/debug.c +++ b/src/debug.c @@ -89,10 +89,10 @@ get_view_part(struct view *view, struct wlr_scene_node *node) } static struct workspace * -get_workspace_from_node(struct server *server, struct wlr_scene_node *node) +get_workspace_from_node(struct wlr_scene_node *node) { struct workspace *workspace; - wl_list_for_each(workspace, &server->workspaces.all, link) { + wl_list_for_each(workspace, &g_server.workspaces.all, link) { if (&workspace->tree->node == node) { return workspace; } @@ -101,31 +101,31 @@ get_workspace_from_node(struct server *server, struct wlr_scene_node *node) } static const char * -get_special(struct server *server, struct wlr_scene_node *node) +get_special(struct wlr_scene_node *node) { struct wlr_scene_tree *grand_parent = node->parent ? node->parent->node.parent : NULL; struct wlr_scene_tree *grand_grand_parent = grand_parent ? grand_parent->node.parent : NULL; - if (node == &server->scene->tree.node) { - return "server->scene"; + if (node == &g_server.scene->tree.node) { + return "g_server.scene"; } - if (node == &server->menu_tree->node) { - return "server->menu_tree"; + if (node == &g_server.menu_tree->node) { + return "g_server.menu_tree"; } - if (node == &server->workspace_tree->node) { - return "server->workspace_tree"; + if (node == &g_server.workspace_tree->node) { + return "g_server.workspace_tree"; } - if (node->parent == server->workspace_tree) { - struct workspace *workspace = get_workspace_from_node(server, node); + if (node->parent == g_server.workspace_tree) { + struct workspace *workspace = get_workspace_from_node(node); if (workspace) { return workspace->name; } return "unknown workspace"; } - if (grand_parent == server->workspace_tree) { + if (grand_parent == g_server.workspace_tree) { struct workspace *workspace = - get_workspace_from_node(server, &node->parent->node); + get_workspace_from_node(&node->parent->node); if (workspace) { struct wlr_scene_tree **trees = workspace->view_trees; if (node == &trees[VIEW_LAYER_NORMAL]->node) { @@ -138,9 +138,9 @@ get_special(struct server *server, struct wlr_scene_node *node) } return "unknown tree"; } - if (node->parent == &server->scene->tree) { + if (node->parent == &g_server.scene->tree) { struct output *output; - wl_list_for_each(output, &server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { if (node == &output->cycle_osd_tree->node) { return "output->osd_tree"; } @@ -157,33 +157,33 @@ get_special(struct server *server, struct wlr_scene_node *node) } } } - if (node == &server->xdg_popup_tree->node) { - return "server->xdg_popup_tree"; + if (node == &g_server.xdg_popup_tree->node) { + return "g_server.xdg_popup_tree"; } - if (node == &server->seat.drag.icons->node) { + if (node == &g_server.seat.drag.icons->node) { return "seat->drag.icons"; } - if (server->seat.overlay.rect - && node == &server->seat.overlay.rect->tree->node) { + if (g_server.seat.overlay.rect + && node == &g_server.seat.overlay.rect->tree->node) { /* Created on-demand */ return "seat->overlay.rect"; } - if (server->seat.input_method_relay->popup_tree - && node == &server->seat.input_method_relay->popup_tree->node) { + if (g_server.seat.input_method_relay->popup_tree + && node == &g_server.seat.input_method_relay->popup_tree->node) { /* Created on-demand */ return "seat->im_relay->popup_tree"; } - if (server->cycle.preview_outline - && node == &server->cycle.preview_outline->tree->node) { + if (g_server.cycle.preview_outline + && node == &g_server.cycle.preview_outline->tree->node) { /* Created on-demand */ return "cycle_state->preview_outline"; } #if HAVE_XWAYLAND - if (node == &server->unmanaged_tree->node) { - return "server->unmanaged_tree"; + if (node == &g_server.unmanaged_tree->node) { + return "g_server.unmanaged_tree"; } #endif - if (grand_grand_parent == server->workspace_tree && node->data) { + if (grand_grand_parent == g_server.workspace_tree && node->data) { last_view = node_view_from_node(node); } const char *view_part = get_view_part(last_view, node); @@ -209,10 +209,10 @@ get_center_padding(const char *text, uint8_t max_width) } static void -dump_tree(struct server *server, struct wlr_scene_node *node, +dump_tree(struct wlr_scene_node *node, int pos, int x, int y) { - const char *type = get_special(server, node); + const char *type = get_special(node); if (pos) { printf("%*c+-- ", pos, ' '); @@ -234,13 +234,13 @@ dump_tree(struct server *server, struct wlr_scene_node *node, } printf("%.*s %*c %4d %4d [%p]\n", max_width - 1, type, padding, ' ', x, y, node); - if ((IGNORE_MENU && node == &server->menu_tree->node) + if ((IGNORE_MENU && node == &g_server.menu_tree->node) || (IGNORE_SSD && last_view && ssd_debug_is_root_node(last_view->ssd, node)) - || (IGNORE_CYCLE_PREVIEW_OUTLINE && server->cycle.preview_outline - && node == &server->cycle.preview_outline->tree->node) - || (IGNORE_SNAPPING_OVERLAY && server->seat.overlay.rect - && node == &server->seat.overlay.rect->tree->node)) { + || (IGNORE_CYCLE_PREVIEW_OUTLINE && g_server.cycle.preview_outline + && node == &g_server.cycle.preview_outline->tree->node) + || (IGNORE_SNAPPING_OVERLAY && g_server.seat.overlay.rect + && node == &g_server.seat.overlay.rect->tree->node)) { printf("%*c%s\n", pos + 4 + INDENT_SIZE, ' ', ""); return; } @@ -249,17 +249,17 @@ dump_tree(struct server *server, struct wlr_scene_node *node, struct wlr_scene_node *child; struct wlr_scene_tree *tree = wlr_scene_tree_from_node(node); wl_list_for_each(child, &tree->children, link) { - dump_tree(server, child, pos + INDENT_SIZE, + dump_tree(child, pos + INDENT_SIZE, x + child->x, y + child->y); } } } void -debug_dump_scene(struct server *server) +debug_dump_scene(void) { printf("\n"); - dump_tree(server, &server->scene->tree.node, 0, 0, 0); + dump_tree(&g_server.scene->tree.node, 0, 0, 0); printf("\n"); /* diff --git a/src/decorations/kde-deco.c b/src/decorations/kde-deco.c index bf746163..98034e53 100644 --- a/src/decorations/kde-deco.c +++ b/src/decorations/kde-deco.c @@ -119,10 +119,10 @@ kde_server_decoration_update_default(void) } void -kde_server_decoration_init(struct server *server) +kde_server_decoration_init(void) { assert(!kde_deco_mgr); - kde_deco_mgr = wlr_server_decoration_manager_create(server->wl_display); + kde_deco_mgr = wlr_server_decoration_manager_create(g_server.wl_display); if (!kde_deco_mgr) { wlr_log(WLR_ERROR, "unable to create the kde server deco manager"); exit(EXIT_FAILURE); @@ -131,12 +131,12 @@ kde_server_decoration_init(struct server *server) wl_list_init(&decorations); kde_server_decoration_update_default(); - wl_signal_add(&kde_deco_mgr->events.new_decoration, &server->kde_server_decoration); - server->kde_server_decoration.notify = handle_new_server_decoration; + wl_signal_add(&kde_deco_mgr->events.new_decoration, &g_server.kde_server_decoration); + g_server.kde_server_decoration.notify = handle_new_server_decoration; } void -kde_server_decoration_finish(struct server *server) +kde_server_decoration_finish(void) { - wl_list_remove(&server->kde_server_decoration.link); + wl_list_remove(&g_server.kde_server_decoration.link); } diff --git a/src/decorations/xdg-deco.c b/src/decorations/xdg-deco.c index d9eb3918..5374e6d4 100644 --- a/src/decorations/xdg-deco.c +++ b/src/decorations/xdg-deco.c @@ -115,22 +115,22 @@ xdg_toplevel_decoration(struct wl_listener *listener, void *data) } void -xdg_server_decoration_init(struct server *server) +xdg_server_decoration_init(void) { struct wlr_xdg_decoration_manager_v1 *xdg_deco_mgr = NULL; - xdg_deco_mgr = wlr_xdg_decoration_manager_v1_create(server->wl_display); + xdg_deco_mgr = wlr_xdg_decoration_manager_v1_create(g_server.wl_display); if (!xdg_deco_mgr) { wlr_log(WLR_ERROR, "unable to create the XDG deco manager"); exit(EXIT_FAILURE); } wl_signal_add(&xdg_deco_mgr->events.new_toplevel_decoration, - &server->xdg_toplevel_decoration); - server->xdg_toplevel_decoration.notify = xdg_toplevel_decoration; + &g_server.xdg_toplevel_decoration); + g_server.xdg_toplevel_decoration.notify = xdg_toplevel_decoration; } void -xdg_server_decoration_finish(struct server *server) +xdg_server_decoration_finish(void) { - wl_list_remove(&server->xdg_toplevel_decoration.link); + wl_list_remove(&g_server.xdg_toplevel_decoration.link); } diff --git a/src/desktop-entry.c b/src/desktop-entry.c index 5ba8a2f6..22e54951 100644 --- a/src/desktop-entry.c +++ b/src/desktop-entry.c @@ -55,7 +55,7 @@ log_handler(enum sfdo_log_level level, const char *fmt, va_list args, void *tag) } void -desktop_entry_init(struct server *server) +desktop_entry_init(void) { struct sfdo *sfdo = znew(*sfdo); @@ -134,7 +134,7 @@ desktop_entry_init(struct server *server) /* basedir_ctx is not referenced by other objects */ sfdo_basedir_ctx_destroy(basedir_ctx); - server->sfdo = sfdo; + g_server.sfdo = sfdo; return; err_icon_theme: @@ -155,9 +155,9 @@ err_basedir_ctx: } void -desktop_entry_finish(struct server *server) +desktop_entry_finish(void) { - struct sfdo *sfdo = server->sfdo; + struct sfdo *sfdo = g_server.sfdo; if (!sfdo) { return; } @@ -167,7 +167,7 @@ desktop_entry_finish(struct server *server) sfdo_icon_ctx_destroy(sfdo->icon_ctx); sfdo_desktop_ctx_destroy(sfdo->desktop_ctx); free(sfdo); - server->sfdo = NULL; + g_server.sfdo = NULL; } struct icon_ctx { @@ -348,14 +348,14 @@ convert_img_type(enum sfdo_icon_file_format fmt) } struct lab_img * -desktop_entry_load_icon(struct server *server, const char *icon_name, int size, float scale) +desktop_entry_load_icon(const char *icon_name, int size, float scale) { /* static analyzer isn't able to detect the NULL check in string_null_or_empty() */ if (string_null_or_empty(icon_name) || !icon_name) { return NULL; } - struct sfdo *sfdo = server->sfdo; + struct sfdo *sfdo = g_server.sfdo; if (!sfdo) { return NULL; } @@ -387,14 +387,13 @@ desktop_entry_load_icon(struct server *server, const char *icon_name, int size, } struct lab_img * -desktop_entry_load_icon_from_app_id(struct server *server, - const char *app_id, int size, float scale) +desktop_entry_load_icon_from_app_id(const char *app_id, int size, float scale) { if (string_null_or_empty(app_id)) { return NULL; } - struct sfdo *sfdo = server->sfdo; + struct sfdo *sfdo = g_server.sfdo; if (!sfdo) { return NULL; } @@ -405,22 +404,22 @@ desktop_entry_load_icon_from_app_id(struct server *server, icon_name = sfdo_desktop_entry_get_icon(entry, NULL); } - struct lab_img *img = desktop_entry_load_icon(server, icon_name, size, scale); + struct lab_img *img = desktop_entry_load_icon(icon_name, size, scale); if (!img) { /* Icon not defined in .desktop file or could not be loaded */ - img = desktop_entry_load_icon(server, app_id, size, scale); + img = desktop_entry_load_icon(app_id, size, scale); } return img; } const char * -desktop_entry_name_lookup(struct server *server, const char *app_id) +desktop_entry_name_lookup(const char *app_id) { if (string_null_or_empty(app_id)) { return NULL; } - struct sfdo *sfdo = server->sfdo; + struct sfdo *sfdo = g_server.sfdo; if (!sfdo) { return NULL; } diff --git a/src/desktop.c b/src/desktop.c index e5a33a78..36e8bd8e 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -23,7 +23,7 @@ #endif void -desktop_arrange_all_views(struct server *server) +desktop_arrange_all_views(void) { /* * Adjust window positions/sizes. Skip views with no size since @@ -36,7 +36,7 @@ desktop_arrange_all_views(struct server *server) * views. */ struct view *view; - wl_list_for_each(view, &server->views, link) { + wl_list_for_each(view, &g_server.views, link) { if (!wlr_box_empty(&view->pending)) { view_adjust_for_layout_change(view); } @@ -46,7 +46,7 @@ desktop_arrange_all_views(struct server *server) static void set_or_offer_focus(struct view *view) { - struct seat *seat = &view->server->seat; + struct seat *seat = &g_server.seat; switch (view_wants_focus(view)) { case VIEW_WANTS_FOCUS_ALWAYS: if (view->surface != seat->seat->keyboard_state.focused_surface) { @@ -76,7 +76,7 @@ desktop_focus_view(struct view *view, bool raise) return; } - if (view->server->input_mode == LAB_INPUT_STATE_CYCLE) { + if (g_server.input_mode == LAB_INPUT_STATE_CYCLE) { wlr_log(WLR_DEBUG, "not focusing window while window switching"); return; } @@ -135,10 +135,10 @@ desktop_focus_view_or_surface(struct seat *seat, struct view *view, } static struct view * -desktop_topmost_focusable_view(struct server *server) +desktop_topmost_focusable_view(void) { struct view *view; - for_each_view(view, &server->views, + for_each_view(view, &g_server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { if (!view->minimized) { return view; @@ -148,9 +148,9 @@ desktop_topmost_focusable_view(struct server *server) } void -desktop_focus_topmost_view(struct server *server) +desktop_focus_topmost_view(void) { - struct view *view = desktop_topmost_focusable_view(server); + struct view *view = desktop_topmost_focusable_view(); if (view) { desktop_focus_view(view, /*raise*/ true); } else { @@ -158,49 +158,47 @@ desktop_focus_topmost_view(struct server *server) * Defocus previous focused surface/view if no longer * focusable (e.g. unmapped or on a different workspace). */ - seat_focus_surface(&server->seat, NULL); + seat_focus_surface(&g_server.seat, NULL); } } void desktop_focus_output(struct output *output) { - struct server *server = output->server; - - if (!output_is_usable(output) || server->input_mode + if (!output_is_usable(output) || g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { return; } struct view *view; - for_each_view(view, &server->views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { + for_each_view(view, &g_server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { if (view->outputs & output->id_bit) { desktop_focus_view(view, /*raise*/ false); - wlr_cursor_warp(server->seat.cursor, NULL, + wlr_cursor_warp(g_server.seat.cursor, NULL, view->current.x + view->current.width / 2, view->current.y + view->current.height / 2); - cursor_update_focus(server); + cursor_update_focus(); return; } } /* No view found on desired output */ struct wlr_box layout_box; - wlr_output_layout_get_box(server->output_layout, + wlr_output_layout_get_box(g_server.output_layout, output->wlr_output, &layout_box); - wlr_cursor_warp(server->seat.cursor, NULL, + wlr_cursor_warp(g_server.seat.cursor, NULL, layout_box.x + output->usable_area.x + output->usable_area.width / 2, layout_box.y + output->usable_area.y + output->usable_area.height / 2); - cursor_update_focus(server); + cursor_update_focus(); } void -desktop_update_top_layer_visibility(struct server *server) +desktop_update_top_layer_visibility(void) { struct view *view; struct output *output; uint32_t top = ZWLR_LAYER_SHELL_V1_LAYER_TOP; /* Enable all top layers */ - wl_list_for_each(output, &server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { if (!output_is_usable(output)) { continue; } @@ -212,7 +210,7 @@ desktop_update_top_layer_visibility(struct server *server) * any views above it */ uint64_t outputs_covered = 0; - for_each_view(view, &server->views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { + for_each_view(view, &g_server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { if (view->minimized) { continue; } @@ -262,22 +260,22 @@ avoid_edge_rounding_issues(struct cursor_context *ctx) /* TODO: make this less big and scary */ struct cursor_context -get_cursor_context(struct server *server) +get_cursor_context(void) { struct cursor_context ret = {.type = LAB_NODE_NONE}; - struct wlr_cursor *cursor = server->seat.cursor; + struct wlr_cursor *cursor = g_server.seat.cursor; /* Prevent drag icons to be on top of the hitbox detection */ - if (server->seat.drag.active) { - dnd_icons_show(&server->seat, false); + if (g_server.seat.drag.active) { + dnd_icons_show(&g_server.seat, false); } struct wlr_scene_node *node = - wlr_scene_node_at(&server->scene->tree.node, + wlr_scene_node_at(&g_server.scene->tree.node, cursor->x, cursor->y, &ret.sx, &ret.sy); - if (server->seat.drag.active) { - dnd_icons_show(&server->seat, true); + if (g_server.seat.drag.active) { + dnd_icons_show(&g_server.seat, true); } if (!node) { @@ -292,7 +290,7 @@ get_cursor_context(struct server *server) #if HAVE_XWAYLAND /* TODO: attach LAB_NODE_UNMANAGED node-descriptor to unmanaged surfaces */ if (node->type == WLR_SCENE_NODE_BUFFER) { - if (node->parent == server->unmanaged_tree) { + if (node->parent == g_server.unmanaged_tree) { ret.type = LAB_NODE_UNMANAGED; return ret; } diff --git a/src/dnd.c b/src/dnd.c index 6b4a5ac7..7542e5d7 100644 --- a/src/dnd.c +++ b/src/dnd.c @@ -68,7 +68,7 @@ handle_drag_destroy(struct wl_listener *listener, void *data) return; } - struct cursor_context ctx = get_cursor_context(seat->server); + struct cursor_context ctx = get_cursor_context(); if (!ctx.surface) { return; } @@ -84,7 +84,7 @@ handle_drag_destroy(struct wl_listener *listener, void *data) void dnd_init(struct seat *seat) { - seat->drag.icons = lab_wlr_scene_tree_create(&seat->server->scene->tree); + seat->drag.icons = lab_wlr_scene_tree_create(&g_server.scene->tree); wlr_scene_node_set_enabled(&seat->drag.icons->node, false); seat->drag.events.request.notify = handle_drag_request; diff --git a/src/edges.c b/src/edges.c index 56fb8bfa..24c0528d 100644 --- a/src/edges.c +++ b/src/edges.c @@ -328,7 +328,7 @@ subtract_node_tree(struct wlr_scene_tree *tree, pixman_region32_t *available, } void -edges_calculate_visibility(struct server *server, struct view *ignored_view) +edges_calculate_visibility(struct view *ignored_view) { /* * The region stores the available output layout space @@ -353,17 +353,17 @@ edges_calculate_visibility(struct server *server, struct view *ignored_view) */ struct output *output; struct wlr_box layout_box; - wl_list_for_each(output, &server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { if (!output_is_usable(output)) { continue; } - wlr_output_layout_get_box(server->output_layout, + wlr_output_layout_get_box(g_server.output_layout, output->wlr_output, &layout_box); pixman_region32_union_rect(®ion, ®ion, layout_box.x, layout_box.y, layout_box.width, layout_box.height); } - subtract_node_tree(&server->scene->tree, ®ion, ignored_view); + subtract_node_tree(&g_server.scene->tree, ®ion, ignored_view); pixman_region32_fini(®ion); } @@ -389,7 +389,7 @@ edges_find_neighbors(struct border *nearest_edges, struct view *view, edges_for_target_geometry(&target_edges, view, target); struct view *v; - for_each_view(v, &view->server->views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { + for_each_view(v, &g_server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { if (v == view || v->minimized || !output_is_usable(v->output)) { continue; } @@ -447,7 +447,7 @@ edges_find_outputs(struct border *nearest_edges, struct view *view, edges_for_target_geometry(&target_edges, view, target); struct output *o; - wl_list_for_each(o, &view->server->outputs, link) { + wl_list_for_each(o, &g_server.outputs, link) { if (!output_is_usable(o)) { continue; } diff --git a/src/foreign-toplevel/ext-foreign.c b/src/foreign-toplevel/ext-foreign.c index 748050fa..99954c4d 100644 --- a/src/foreign-toplevel/ext-foreign.c +++ b/src/foreign-toplevel/ext-foreign.c @@ -59,7 +59,7 @@ void ext_foreign_toplevel_init(struct ext_foreign_toplevel *ext_toplevel, struct view *view) { - assert(view->server->foreign_toplevel_list); + assert(g_server.foreign_toplevel_list); ext_toplevel->view = view; struct wlr_ext_foreign_toplevel_handle_v1_state state = { @@ -67,7 +67,7 @@ ext_foreign_toplevel_init(struct ext_foreign_toplevel *ext_toplevel, .app_id = view->app_id, }; ext_toplevel->handle = wlr_ext_foreign_toplevel_handle_v1_create( - view->server->foreign_toplevel_list, &state); + g_server.foreign_toplevel_list, &state); if (!ext_toplevel->handle) { wlr_log(WLR_ERROR, "cannot create ext toplevel handle for (%s)", diff --git a/src/foreign-toplevel/wlr-foreign.c b/src/foreign-toplevel/wlr-foreign.c index 70ce0890..f4076c5a 100644 --- a/src/foreign-toplevel/wlr-foreign.c +++ b/src/foreign-toplevel/wlr-foreign.c @@ -123,7 +123,7 @@ handle_new_outputs(struct wl_listener *listener, void *data) * wlr_foreign_toplevel handle the rest. */ struct output *output; - wl_list_for_each(output, &wlr_toplevel->view->server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { if (view_on_output(wlr_toplevel->view, output)) { wlr_foreign_toplevel_handle_v1_output_enter( wlr_toplevel->handle, output->wlr_output); @@ -184,11 +184,11 @@ void wlr_foreign_toplevel_init(struct wlr_foreign_toplevel *wlr_toplevel, struct view *view) { - assert(view->server->foreign_toplevel_manager); + assert(g_server.foreign_toplevel_manager); wlr_toplevel->view = view; wlr_toplevel->handle = wlr_foreign_toplevel_handle_v1_create( - view->server->foreign_toplevel_manager); + g_server.foreign_toplevel_manager); if (!wlr_toplevel->handle) { wlr_log(WLR_ERROR, "cannot create wlr foreign toplevel handle for (%s)", view->title); @@ -203,7 +203,7 @@ wlr_foreign_toplevel_init(struct wlr_foreign_toplevel *wlr_toplevel, handle_minimized(&wlr_toplevel->on_view.minimized, NULL); handle_fullscreened(&wlr_toplevel->on_view.fullscreened, NULL); handle_activated(&wlr_toplevel->on_view.activated, - &(bool){view == view->server->active_view}); + &(bool){view == g_server.active_view}); /* Client side requests */ CONNECT_SIGNAL(wlr_toplevel->handle, &wlr_toplevel->on, request_maximize); diff --git a/src/input/cursor.c b/src/input/cursor.c index ababb2cd..77ff74f4 100644 --- a/src/input/cursor.c +++ b/src/input/cursor.c @@ -148,7 +148,7 @@ handle_request_set_cursor(struct wl_listener *listener, void *data) { struct seat *seat = wl_container_of(listener, seat, request_set_cursor); - if (seat->server->input_mode != LAB_INPUT_STATE_PASSTHROUGH) { + if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { /* Prevent setting a cursor image when moving or resizing */ return; } @@ -208,7 +208,7 @@ handle_request_set_shape(struct wl_listener *listener, void *data) struct wlr_seat_client *focused_client = seat->seat->pointer_state.focused_client; /* Prevent setting a cursor image when moving or resizing */ - if (seat->server->input_mode != LAB_INPUT_STATE_PASSTHROUGH) { + if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { return; } @@ -265,12 +265,12 @@ handle_request_set_primary_selection(struct wl_listener *listener, void *data) } static void -process_cursor_move(struct server *server, uint32_t time) +process_cursor_move(uint32_t time) { - struct view *view = server->grabbed_view; + struct view *view = g_server.grabbed_view; - int x = server->grab_box.x + (server->seat.cursor->x - server->grab_x); - int y = server->grab_box.y + (server->seat.cursor->y - server->grab_y); + int x = g_server.grab_box.x + (g_server.seat.cursor->x - g_server.grab_x); + int y = g_server.grab_box.y + (g_server.seat.cursor->y - g_server.grab_y); /* Apply resistance for maximized/tiled view */ bool needs_untile = resistance_unsnap_apply(view, &x, &y); @@ -286,7 +286,7 @@ process_cursor_move(struct server *server, uint32_t time) .width = view->natural_geometry.width, .height = view->natural_geometry.height, }; - interactive_anchor_to_cursor(server, &new_geo); + interactive_anchor_to_cursor(&new_geo); /* Shaded clients will not process resize events until unshaded */ view_set_shade(view, false); view_set_maximized(view, VIEW_AXIS_NONE); @@ -300,18 +300,18 @@ process_cursor_move(struct server *server, uint32_t time) resistance_move_apply(view, &x, &y); view_move(view, x, y); - overlay_update(&server->seat); + overlay_update(&g_server.seat); } static void -process_cursor_resize(struct server *server, uint32_t time) +process_cursor_resize(uint32_t time) { /* Rate-limit resize events respecting monitor refresh rate */ static uint32_t last_resize_time = 0; static struct view *last_resize_view = NULL; - assert(server->grabbed_view); - if (server->grabbed_view == last_resize_view) { + assert(g_server.grabbed_view); + if (g_server.grabbed_view == last_resize_view) { int32_t refresh = 0; if (output_is_usable(last_resize_view->output)) { refresh = last_resize_view->output->wlr_output->refresh; @@ -327,43 +327,43 @@ process_cursor_resize(struct server *server, uint32_t time) } last_resize_time = time; - last_resize_view = server->grabbed_view; + last_resize_view = g_server.grabbed_view; - double dx = server->seat.cursor->x - server->grab_x; - double dy = server->seat.cursor->y - server->grab_y; + double dx = g_server.seat.cursor->x - g_server.grab_x; + double dy = g_server.seat.cursor->y - g_server.grab_y; - struct view *view = server->grabbed_view; + struct view *view = g_server.grabbed_view; struct wlr_box new_view_geo = view->current; - if (server->resize_edges & LAB_EDGE_TOP) { + if (g_server.resize_edges & LAB_EDGE_TOP) { /* Shift y to anchor bottom edge when resizing top */ - new_view_geo.y = server->grab_box.y + dy; - new_view_geo.height = server->grab_box.height - dy; - } else if (server->resize_edges & LAB_EDGE_BOTTOM) { - new_view_geo.height = server->grab_box.height + dy; + new_view_geo.y = g_server.grab_box.y + dy; + new_view_geo.height = g_server.grab_box.height - dy; + } else if (g_server.resize_edges & LAB_EDGE_BOTTOM) { + new_view_geo.height = g_server.grab_box.height + dy; } - if (server->resize_edges & LAB_EDGE_LEFT) { + if (g_server.resize_edges & LAB_EDGE_LEFT) { /* Shift x to anchor right edge when resizing left */ - new_view_geo.x = server->grab_box.x + dx; - new_view_geo.width = server->grab_box.width - dx; - } else if (server->resize_edges & LAB_EDGE_RIGHT) { - new_view_geo.width = server->grab_box.width + dx; + new_view_geo.x = g_server.grab_box.x + dx; + new_view_geo.width = g_server.grab_box.width - dx; + } else if (g_server.resize_edges & LAB_EDGE_RIGHT) { + new_view_geo.width = g_server.grab_box.width + dx; } resistance_resize_apply(view, &new_view_geo); view_adjust_size(view, &new_view_geo.width, &new_view_geo.height); - if (server->resize_edges & LAB_EDGE_TOP) { + if (g_server.resize_edges & LAB_EDGE_TOP) { /* After size adjustments, make sure to anchor bottom edge */ - new_view_geo.y = server->grab_box.y + - server->grab_box.height - new_view_geo.height; + new_view_geo.y = g_server.grab_box.y + + g_server.grab_box.height - new_view_geo.height; } - if (server->resize_edges & LAB_EDGE_LEFT) { + if (g_server.resize_edges & LAB_EDGE_LEFT) { /* After size adjustments, make sure to anchor bottom right */ - new_view_geo.x = server->grab_box.x + - server->grab_box.width - new_view_geo.width; + new_view_geo.x = g_server.grab_box.x + + g_server.grab_box.width - new_view_geo.width; } if (rc.resize_draw_contents) { @@ -422,7 +422,7 @@ cursor_update_image(struct seat *seat) seat->server_cursor = LAB_CURSOR_DEFAULT; wlr_cursor_set_xcursor(seat->cursor, seat->xcursor_manager, ""); wlr_seat_pointer_clear_focus(seat->seat); - cursor_update_focus(seat->server); + cursor_update_focus(); } return; } @@ -533,15 +533,15 @@ update_pressed_surface(struct seat *seat, const struct cursor_context *ctx) * and process_cursor_axis() */ static void -cursor_update_common(struct server *server, const struct cursor_context *ctx, +cursor_update_common(const struct cursor_context *ctx, struct cursor_context *notified_ctx) { - struct seat *seat = &server->seat; + struct seat *seat = &g_server.seat; struct wlr_seat *wlr_seat = seat->seat; - ssd_update_hovered_button(server, ctx->node); + ssd_update_hovered_button(ctx->node); - if (server->input_mode != LAB_INPUT_STATE_PASSTHROUGH) { + if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { /* * Prevent updating focus/cursor image during * interactive move/resize, window switcher and @@ -565,8 +565,8 @@ cursor_update_common(struct server *server, const struct cursor_context *ctx, int lx, ly; wlr_scene_node_coords(seat->pressed.ctx.node, &lx, &ly); *notified_ctx = seat->pressed.ctx; - notified_ctx->sx = server->seat.cursor->x - lx; - notified_ctx->sy = server->seat.cursor->y - ly; + notified_ctx->sx = g_server.seat.cursor->x - lx; + notified_ctx->sy = g_server.seat.cursor->y - ly; } return; } @@ -620,24 +620,24 @@ cursor_get_resize_edges(struct wlr_cursor *cursor, const struct cursor_context * } bool -cursor_process_motion(struct server *server, uint32_t time, double *sx, double *sy) +cursor_process_motion(uint32_t time, double *sx, double *sy) { /* If the mode is non-passthrough, delegate to those functions. */ - if (server->input_mode == LAB_INPUT_STATE_MOVE) { - process_cursor_move(server, time); + if (g_server.input_mode == LAB_INPUT_STATE_MOVE) { + process_cursor_move(time); return false; - } else if (server->input_mode == LAB_INPUT_STATE_RESIZE) { - process_cursor_resize(server, time); + } else if (g_server.input_mode == LAB_INPUT_STATE_RESIZE) { + process_cursor_resize(time); return false; } /* Otherwise, find view under the pointer and send the event along */ - struct cursor_context ctx = get_cursor_context(server); - struct seat *seat = &server->seat; + struct cursor_context ctx = get_cursor_context(); + struct seat *seat = &g_server.seat; if (ctx.type == LAB_NODE_MENUITEM) { menu_process_cursor_motion(ctx.node); - cursor_set(&server->seat, LAB_CURSOR_DEFAULT); + cursor_set(&g_server.seat, LAB_CURSOR_DEFAULT); return false; } @@ -659,8 +659,7 @@ cursor_process_motion(struct server *server, uint32_t time, double *sx, double * * moving/resizing the wrong view */ mousebind->pressed_in_context = false; - actions_run(seat->pressed.ctx.view, server, - &mousebind->actions, &seat->pressed.ctx); + actions_run(seat->pressed.ctx.view, &mousebind->actions, &seat->pressed.ctx); } } @@ -670,7 +669,7 @@ cursor_process_motion(struct server *server, uint32_t time, double *sx, double * * and the pressed view is set while out-of-surface dragging. */ struct cursor_context notified_ctx = {0}; - cursor_update_common(server, &ctx, ¬ified_ctx); + cursor_update_common(&ctx, ¬ified_ctx); if (rc.focus_follow_mouse) { /* @@ -701,10 +700,10 @@ cursor_process_motion(struct server *server, uint32_t time, double *sx, double * } static void -_cursor_update_focus(struct server *server) +_cursor_update_focus(void) { /* Focus surface under cursor if it isn't already focused */ - struct cursor_context ctx = get_cursor_context(server); + struct cursor_context ctx = get_cursor_context(); if ((ctx.view || ctx.surface) && rc.focus_follow_mouse && !rc.focus_follow_mouse_requires_movement) { @@ -712,21 +711,21 @@ _cursor_update_focus(struct server *server) * Always focus the surface below the cursor when * followMouse=yes and followMouseRequiresMovement=no. */ - desktop_focus_view_or_surface(&server->seat, ctx.view, + desktop_focus_view_or_surface(&g_server.seat, ctx.view, ctx.surface, rc.raise_on_focus); } - cursor_update_common(server, &ctx, NULL); + cursor_update_common(&ctx, NULL); } void -cursor_update_focus(struct server *server) +cursor_update_focus(void) { /* Prevent recursion via view_move_to_front() */ static bool updating_focus = false; if (!updating_focus) { updating_focus = true; - _cursor_update_focus(server); + _cursor_update_focus(); updating_focus = false; } } @@ -735,7 +734,7 @@ static void warp_cursor_to_constraint_hint(struct seat *seat, struct wlr_pointer_constraint_v1 *constraint) { - if (!seat->server->active_view) { + if (!g_server.active_view) { return; } @@ -744,8 +743,8 @@ warp_cursor_to_constraint_hint(struct seat *seat, double sx = constraint->current.cursor_hint.x; double sy = constraint->current.cursor_hint.y; wlr_cursor_warp(seat->cursor, NULL, - seat->server->active_view->current.x + sx, - seat->server->active_view->current.y + sy); + g_server.active_view->current.x + sx, + g_server.active_view->current.y + sy); /* Make sure we are not sending unnecessary surface movements */ wlr_seat_pointer_warp(seat->seat, sx, sy); @@ -788,26 +787,24 @@ void create_constraint(struct wl_listener *listener, void *data) { struct wlr_pointer_constraint_v1 *wlr_constraint = data; - struct server *server = wl_container_of(listener, server, - new_constraint); struct constraint *constraint = znew(*constraint); constraint->constraint = wlr_constraint; - constraint->seat = &server->seat; + constraint->seat = &g_server.seat; constraint->destroy.notify = handle_constraint_destroy; wl_signal_add(&wlr_constraint->events.destroy, &constraint->destroy); - struct view *view = server->active_view; + struct view *view = g_server.active_view; if (view && view->surface == wlr_constraint->surface) { - constrain_cursor(server, wlr_constraint); + constrain_cursor(wlr_constraint); } } void -constrain_cursor(struct server *server, struct wlr_pointer_constraint_v1 +constrain_cursor(struct wlr_pointer_constraint_v1 *constraint) { - struct seat *seat = &server->seat; + struct seat *seat = &g_server.seat; if (seat->current_constraint == constraint) { return; } @@ -837,7 +834,7 @@ constrain_cursor(struct server *server, struct wlr_pointer_constraint_v1 static void apply_constraint(struct seat *seat, struct wlr_pointer *pointer, double *x, double *y) { - if (!seat->server->active_view) { + if (!g_server.active_view) { return; } if (!seat->current_constraint @@ -850,8 +847,8 @@ apply_constraint(struct seat *seat, struct wlr_pointer *pointer, double *x, doub double sx = seat->cursor->x; double sy = seat->cursor->y; - sx -= seat->server->active_view->current.x; - sy -= seat->server->active_view->current.y; + sx -= g_server.active_view->current.x; + sy -= g_server.active_view->current.y; double sx_confined, sy_confined; if (!wlr_region_confine(&seat->current_constraint->region, sx, sy, @@ -892,7 +889,7 @@ preprocess_cursor_motion(struct seat *seat, struct wlr_pointer *pointer, */ wlr_cursor_move(seat->cursor, &pointer->base, dx, dy); double sx, sy; - bool notify = cursor_process_motion(seat->server, time_msec, &sx, &sy); + bool notify = cursor_process_motion(time_msec, &sx, &sy); if (notify) { wlr_seat_pointer_notify_motion(seat->seat, time_msec, sx, sy); } @@ -919,7 +916,6 @@ handle_motion(struct wl_listener *listener, void *data) * _relative_ pointer motion event (i.e. a delta) */ struct seat *seat = wl_container_of(listener, seat, on_cursor.motion); - struct server *server = seat->server; struct wlr_pointer_motion_event *event = data; idle_manager_notify_activity(seat->seat); cursor_set_visible(seat, /* visible */ true); @@ -952,7 +948,7 @@ handle_motion(struct wl_listener *listener, void *data) WL_POINTER_AXIS_SOURCE_CONTINUOUS, event->time_msec); } else { wlr_relative_pointer_manager_v1_send_relative_motion( - server->relative_pointer_manager, + g_server.relative_pointer_manager, seat->seat, (uint64_t)event->time_msec * 1000, event->delta_x, event->delta_y, event->unaccel_dx, event->unaccel_dy); @@ -990,15 +986,14 @@ handle_motion_absolute(struct wl_listener *listener, void *data) } static void -process_release_mousebinding(struct server *server, - struct cursor_context *ctx, uint32_t button) +process_release_mousebinding(struct cursor_context *ctx, uint32_t button) { - if (server->input_mode == LAB_INPUT_STATE_CYCLE) { + if (g_server.input_mode == LAB_INPUT_STATE_CYCLE) { return; } struct mousebind *mousebind; - uint32_t modifiers = keyboard_get_all_modifiers(&server->seat); + uint32_t modifiers = keyboard_get_all_modifiers(&g_server.seat); wl_list_for_each(mousebind, &rc.mousebinds, link) { if (ctx->type == LAB_NODE_CLIENT @@ -1019,7 +1014,7 @@ process_release_mousebinding(struct server *server, default: continue; } - actions_run(ctx->view, server, &mousebind->actions, ctx); + actions_run(ctx->view, &mousebind->actions, ctx); } } } @@ -1059,17 +1054,17 @@ is_double_click(long double_click_speed, uint32_t button, } static bool -process_press_mousebinding(struct server *server, struct cursor_context *ctx, +process_press_mousebinding(struct cursor_context *ctx, uint32_t button) { - if (server->input_mode == LAB_INPUT_STATE_CYCLE) { + if (g_server.input_mode == LAB_INPUT_STATE_CYCLE) { return false; } struct mousebind *mousebind; bool double_click = is_double_click(rc.doubleclick_time, button, ctx); bool consumed_by_frame_context = false; - uint32_t modifiers = keyboard_get_all_modifiers(&server->seat); + uint32_t modifiers = keyboard_get_all_modifiers(&g_server.seat); wl_list_for_each(mousebind, &rc.mousebinds, link) { if (ctx->type == LAB_NODE_CLIENT @@ -1108,7 +1103,7 @@ process_press_mousebinding(struct server *server, struct cursor_context *ctx, } consumed_by_frame_context |= mousebind->context == LAB_NODE_FRAME; consumed_by_frame_context |= mousebind->context == LAB_NODE_ALL; - actions_run(ctx->view, server, &mousebind->actions, ctx); + actions_run(ctx->view, &mousebind->actions, ctx); } } return consumed_by_frame_context; @@ -1138,8 +1133,7 @@ static uint32_t press_msec; bool cursor_process_button_press(struct seat *seat, uint32_t button, uint32_t time_msec) { - struct server *server = seat->server; - struct cursor_context ctx = get_cursor_context(server); + struct cursor_context ctx = get_cursor_context(); /* Used on next button release to check if it can close menu or select menu item */ press_msec = time_msec; @@ -1147,10 +1141,10 @@ cursor_process_button_press(struct seat *seat, uint32_t button, uint32_t time_ms if (ctx.view || ctx.surface) { /* Store cursor context for later action processing */ cursor_context_save(&seat->pressed, &ctx); - interactive_set_grab_context(server, &ctx); + interactive_set_grab_context(&ctx); } - if (server->input_mode == LAB_INPUT_STATE_MENU) { + if (g_server.input_mode == LAB_INPUT_STATE_MENU) { /* * If menu was already opened on press, set a very small value * so subsequent release always closes menu or selects menu item. @@ -1195,7 +1189,7 @@ cursor_process_button_press(struct seat *seat, uint32_t button, uint32_t time_ms /* Bindings to the Frame context swallow mouse events if activated */ bool consumed_by_frame_context = - process_press_mousebinding(server, &ctx, button); + process_press_mousebinding(&ctx, button); if (ctx.surface && !consumed_by_frame_context) { /* Notify client with pointer focus of button press */ @@ -1210,8 +1204,7 @@ bool cursor_process_button_release(struct seat *seat, uint32_t button, uint32_t time_msec) { - struct server *server = seat->server; - struct cursor_context ctx = get_cursor_context(server); + struct cursor_context ctx = get_cursor_context(); struct wlr_surface *pressed_surface = seat->pressed.ctx.surface; /* Always notify button release event when it's not bound */ @@ -1219,26 +1212,26 @@ cursor_process_button_release(struct seat *seat, uint32_t button, cursor_context_save(&seat->pressed, NULL); - if (server->input_mode == LAB_INPUT_STATE_MENU) { + if (g_server.input_mode == LAB_INPUT_STATE_MENU) { /* TODO: take into account overflow of time_msec */ if (time_msec - press_msec > rc.menu_ignore_button_release_period) { if (ctx.type == LAB_NODE_MENUITEM) { - menu_call_selected_actions(server); + menu_call_selected_actions(); } else { - menu_close_root(server); - cursor_update_focus(server); + menu_close_root(); + cursor_update_focus(); } } return notify; } - if (server->input_mode == LAB_INPUT_STATE_CYCLE) { + if (g_server.input_mode == LAB_INPUT_STATE_CYCLE) { if (ctx.type == LAB_NODE_CYCLE_OSD_ITEM) { - cycle_on_cursor_release(server, ctx.node); + cycle_on_cursor_release(ctx.node); } return notify; } - if (server->input_mode != LAB_INPUT_STATE_PASSTHROUGH) { + if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { return notify; } @@ -1250,7 +1243,7 @@ cursor_process_button_release(struct seat *seat, uint32_t button, return notify; } - process_release_mousebinding(server, &ctx, button); + process_release_mousebinding(&ctx, button); return notify; } @@ -1258,8 +1251,6 @@ cursor_process_button_release(struct seat *seat, uint32_t button, bool cursor_finish_button_release(struct seat *seat, uint32_t button) { - struct server *server = seat->server; - /* Clear "pressed" status for all bindings of this mouse button */ struct mousebind *mousebind; wl_list_for_each(mousebind, &rc.mousebinds, link) { @@ -1270,17 +1261,17 @@ cursor_finish_button_release(struct seat *seat, uint32_t button) lab_set_remove(&seat->bound_buttons, button); - if (server->input_mode == LAB_INPUT_STATE_MOVE - || server->input_mode == LAB_INPUT_STATE_RESIZE) { - if (resize_outlines_enabled(server->grabbed_view)) { - resize_outlines_finish(server->grabbed_view); + if (g_server.input_mode == LAB_INPUT_STATE_MOVE + || g_server.input_mode == LAB_INPUT_STATE_RESIZE) { + if (resize_outlines_enabled(g_server.grabbed_view)) { + resize_outlines_finish(g_server.grabbed_view); } /* Exit interactive move/resize mode */ - interactive_finish(server->grabbed_view); + interactive_finish(g_server.grabbed_view); return true; - } else if (server->grabbed_view) { + } else if (g_server.grabbed_view) { /* Button was released without starting move/resize */ - interactive_cancel(server->grabbed_view); + interactive_cancel(g_server.grabbed_view); } return false; @@ -1370,15 +1361,15 @@ compare_delta(double delta, double delta_discrete, struct accumulated_scroll *ac } static bool -process_cursor_axis(struct server *server, enum wl_pointer_axis orientation, +process_cursor_axis(enum wl_pointer_axis orientation, double delta, double delta_discrete) { - struct cursor_context ctx = get_cursor_context(server); - uint32_t modifiers = keyboard_get_all_modifiers(&server->seat); + struct cursor_context ctx = get_cursor_context(); + uint32_t modifiers = keyboard_get_all_modifiers(&g_server.seat); enum direction direction = LAB_DIRECTION_INVALID; struct scroll_info info = compare_delta(delta, delta_discrete, - &server->seat.accumulated_scrolls[orientation]); + &g_server.seat.accumulated_scrolls[orientation]); if (orientation == WL_POINTER_AXIS_HORIZONTAL_SCROLL) { if (info.direction < 0) { @@ -1415,7 +1406,7 @@ process_cursor_axis(struct server *server, enum wl_pointer_axis orientation, * on touchpads or hi-res mice doesn't exceed the threshold */ if (info.run_action) { - actions_run(ctx.view, server, &mousebind->actions, &ctx); + actions_run(ctx.view, &mousebind->actions, &ctx); } } } @@ -1424,7 +1415,7 @@ process_cursor_axis(struct server *server, enum wl_pointer_axis orientation, /* Bindings swallow mouse events if activated */ if (ctx.surface && !consumed) { /* Make sure we are sending the events to the surface under the cursor */ - cursor_update_common(server, &ctx, NULL); + cursor_update_common(&ctx, NULL); return true; } @@ -1440,7 +1431,6 @@ handle_axis(struct wl_listener *listener, void *data) * event, for example when you move the scroll wheel. */ struct seat *seat = wl_container_of(listener, seat, on_cursor.axis); - struct server *server = seat->server; struct wlr_pointer_axis_event *event = data; idle_manager_notify_activity(seat->seat); cursor_set_visible(seat, /* visible */ true); @@ -1451,7 +1441,7 @@ handle_axis(struct wl_listener *listener, void *data) struct input *input = event->pointer->base.data; double scroll_factor = input->scroll_factor; - bool notify = process_cursor_axis(server, event->orientation, + bool notify = process_cursor_axis(event->orientation, event->delta, event->delta_discrete); if (notify) { @@ -1483,7 +1473,6 @@ cursor_emulate_axis(struct seat *seat, struct wlr_input_device *device, enum wl_pointer_axis orientation, double delta, double delta_discrete, enum wl_pointer_axis_source source, uint32_t time_msec) { - struct server *server = seat->server; struct input *input = device->data; double scroll_factor = 1.0; @@ -1493,7 +1482,7 @@ cursor_emulate_axis(struct seat *seat, struct wlr_input_device *device, scroll_factor = input->scroll_factor; } - bool notify = process_cursor_axis(server, orientation, delta, delta_discrete); + bool notify = process_cursor_axis(orientation, delta, delta_discrete); if (notify) { /* Notify the client with pointer focus of the axis event. */ wlr_seat_pointer_notify_axis(seat->seat, time_msec, @@ -1514,13 +1503,13 @@ cursor_emulate_move(struct seat *seat, struct wlr_input_device *device, } wlr_relative_pointer_manager_v1_send_relative_motion( - seat->server->relative_pointer_manager, + g_server.relative_pointer_manager, seat->seat, (uint64_t)time_msec * 1000, dx, dy, dx, dy); wlr_cursor_move(seat->cursor, device, dx, dy); double sx, sy; - bool notify = cursor_process_motion(seat->server, time_msec, &sx, &sy); + bool notify = cursor_process_motion(time_msec, &sx, &sy); if (notify) { wlr_seat_pointer_notify_motion(seat->seat, time_msec, sx, sy); } @@ -1615,7 +1604,7 @@ cursor_reload(struct seat *seat) { cursor_load(seat); #if HAVE_XWAYLAND - xwayland_reset_cursor(seat->server); + xwayland_reset_cursor(); #endif cursor_update_image(seat); } @@ -1643,7 +1632,7 @@ cursor_init(struct seat *seat) CONNECT_SIGNAL(seat->seat, seat, request_set_cursor); struct wlr_cursor_shape_manager_v1 *cursor_shape_manager = - wlr_cursor_shape_manager_v1_create(seat->server->wl_display, + wlr_cursor_shape_manager_v1_create(g_server.wl_display, LAB_CURSOR_SHAPE_V1_VERSION); if (!cursor_shape_manager) { wlr_log(WLR_ERROR, "unable to create cursor_shape interface"); diff --git a/src/input/gestures.c b/src/input/gestures.c index b40da82c..05a24243 100644 --- a/src/input/gestures.c +++ b/src/input/gestures.c @@ -114,7 +114,7 @@ handle_hold_end(struct wl_listener *listener, void *data) void gestures_init(struct seat *seat) { - seat->pointer_gestures = wlr_pointer_gestures_v1_create(seat->server->wl_display); + seat->pointer_gestures = wlr_pointer_gestures_v1_create(g_server.wl_display); CONNECT_SIGNAL(seat->cursor, seat, pinch_begin); CONNECT_SIGNAL(seat->cursor, seat, pinch_update); diff --git a/src/input/ime.c b/src/input/ime.c index 02feec0b..f9e033c4 100644 --- a/src/input/ime.c +++ b/src/input/ime.c @@ -179,7 +179,6 @@ static void update_popup_position(struct input_method_popup *popup) { struct input_method_relay *relay = popup->relay; - struct server *server = relay->seat->server; struct text_input *text_input = relay->active_text_input; if (!text_input || !relay->focused_surface @@ -220,7 +219,7 @@ update_popup_position(struct input_method_popup *popup) } struct output *output = - output_nearest_to(server, cursor_rect.x, cursor_rect.y); + output_nearest_to(cursor_rect.x, cursor_rect.y); if (!output_is_usable(output)) { wlr_log(WLR_ERROR, "Cannot position IME popup (unusable output)"); @@ -228,7 +227,7 @@ update_popup_position(struct input_method_popup *popup) } struct wlr_box output_box; wlr_output_layout_get_box( - server->output_layout, output->wlr_output, &output_box); + g_server.output_layout, output->wlr_output, &output_box); /* Use xdg-positioner utilities to position popup */ struct wlr_xdg_positioner_rules rules = { @@ -583,14 +582,14 @@ input_method_relay_create(struct seat *seat) relay->seat = seat; wl_list_init(&relay->text_inputs); wl_list_init(&relay->popups); - relay->popup_tree = lab_wlr_scene_tree_create(&seat->server->scene->tree); + relay->popup_tree = lab_wlr_scene_tree_create(&g_server.scene->tree); relay->new_text_input.notify = handle_new_text_input; - wl_signal_add(&seat->server->text_input_manager->events.text_input, + wl_signal_add(&g_server.text_input_manager->events.text_input, &relay->new_text_input); relay->new_input_method.notify = handle_new_input_method; - wl_signal_add(&seat->server->input_method_manager->events.input_method, + wl_signal_add(&g_server.input_method_manager->events.input_method, &relay->new_input_method); relay->focused_surface_destroy.notify = handle_focused_surface_destroy; diff --git a/src/input/keyboard.c b/src/input/keyboard.c index ec13f3f8..6badbb12 100644 --- a/src/input/keyboard.c +++ b/src/input/keyboard.c @@ -52,9 +52,9 @@ keyboard_reset_current_keybind(void) } static void -change_vt(struct server *server, unsigned int vt) +change_vt(unsigned int vt) { - wlr_session_change_vt(server->session, vt); + wlr_session_change_vt(g_server.session, vt); } uint32_t @@ -131,17 +131,16 @@ handle_modifiers(struct wl_listener *listener, void *data) { struct keyboard *keyboard = wl_container_of(listener, keyboard, modifiers); struct seat *seat = keyboard->base.seat; - struct server *server = seat->server; struct wlr_keyboard *wlr_keyboard = keyboard->wlr_keyboard; - if (server->input_mode == LAB_INPUT_STATE_MOVE) { + if (g_server.input_mode == LAB_INPUT_STATE_MOVE) { /* Any change to the modifier state re-enable region snap */ seat->region_prevent_snap = false; /* Pressing/releasing modifier key may show/hide region overlay */ overlay_update(seat); } - bool cycling = server->input_mode == LAB_INPUT_STATE_CYCLE; + bool cycling = g_server.input_mode == LAB_INPUT_STATE_CYCLE; if ((cycling || seat->workspace_osd_shown_by_modifier) && !keyboard_get_all_modifiers(seat)) { @@ -150,7 +149,7 @@ handle_modifiers(struct wl_listener *listener, void *data) should_cancel_cycling_on_next_key_release = true; } else { should_cancel_cycling_on_next_key_release = false; - cycle_finish(server, /*switch_focus*/ true); + cycle_finish(/*switch_focus*/ true); } } if (seat->workspace_osd_shown_by_modifier) { @@ -188,7 +187,7 @@ handle_modifiers(struct wl_listener *listener, void *data) } static struct keybind * -match_keybinding_for_sym(struct server *server, uint32_t modifiers, +match_keybinding_for_sym(uint32_t modifiers, xkb_keysym_t sym, xkb_keycode_t xkb_keycode) { struct keybind *keybind; @@ -196,7 +195,7 @@ match_keybinding_for_sym(struct server *server, uint32_t modifiers, if (modifiers ^ keybind->modifiers) { continue; } - if (view_inhibits_actions(server->active_view, &keybind->actions)) { + if (view_inhibits_actions(g_server.active_view, &keybind->actions)) { continue; } if (sym == XKB_KEY_NoSymbol) { @@ -241,13 +240,12 @@ match_keybinding_for_sym(struct server *server, uint32_t modifiers, * the raw keysym fallback. */ static struct keybind * -match_keybinding(struct server *server, struct keyinfo *keyinfo, +match_keybinding(struct keyinfo *keyinfo, bool is_virtual) { if (!is_virtual) { /* First try keycodes */ - struct keybind *keybind = match_keybinding_for_sym(server, - keyinfo->modifiers, XKB_KEY_NoSymbol, keyinfo->xkb_keycode); + struct keybind *keybind = match_keybinding_for_sym(keyinfo->modifiers, XKB_KEY_NoSymbol, keyinfo->xkb_keycode); if (keybind) { wlr_log(WLR_DEBUG, "keycode matched"); return keybind; @@ -257,7 +255,7 @@ match_keybinding(struct server *server, struct keyinfo *keyinfo, /* Then fall back to keysyms */ for (int i = 0; i < keyinfo->translated.nr_syms; i++) { struct keybind *keybind = - match_keybinding_for_sym(server, keyinfo->modifiers, + match_keybinding_for_sym(keyinfo->modifiers, keyinfo->translated.syms[i], keyinfo->xkb_keycode); if (keybind) { wlr_log(WLR_DEBUG, "translated keysym matched"); @@ -268,7 +266,7 @@ match_keybinding(struct server *server, struct keyinfo *keyinfo, /* And finally test for keysyms without modifier */ for (int i = 0; i < keyinfo->raw.nr_syms; i++) { struct keybind *keybind = - match_keybinding_for_sym(server, keyinfo->modifiers, + match_keybinding_for_sym(keyinfo->modifiers, keyinfo->raw.syms[i], keyinfo->xkb_keycode); if (keybind) { wlr_log(WLR_DEBUG, "raw keysym matched"); @@ -366,7 +364,7 @@ get_keyinfo(struct wlr_keyboard *wlr_keyboard, uint32_t evdev_keycode) } static enum lab_key_handled -handle_key_release(struct server *server, uint32_t evdev_keycode) +handle_key_release(uint32_t evdev_keycode) { /* * Release events for keys that were not bound should always be @@ -387,7 +385,7 @@ handle_key_release(struct server *server, uint32_t evdev_keycode) */ if (should_cancel_cycling_on_next_key_release) { should_cancel_cycling_on_next_key_release = false; - cycle_finish(server, /*switch_focus*/ true); + cycle_finish(/*switch_focus*/ true); } /* @@ -399,7 +397,7 @@ handle_key_release(struct server *server, uint32_t evdev_keycode) } static bool -handle_change_vt_key(struct server *server, struct keyboard *keyboard, +handle_change_vt_key(struct keyboard *keyboard, struct keysyms *translated) { for (int i = 0; i < translated->nr_syms; i++) { @@ -407,7 +405,7 @@ handle_change_vt_key(struct server *server, struct keyboard *keyboard, translated->syms[i] - XKB_KEY_XF86Switch_VT_1 + 1; if (vt >= 1 && vt <= 12) { keyboard_cancel_keybind_repeat(keyboard); - change_vt(server, vt); + change_vt(vt); return true; } } @@ -415,31 +413,31 @@ handle_change_vt_key(struct server *server, struct keyboard *keyboard, } static void -handle_menu_keys(struct server *server, struct keysyms *syms) +handle_menu_keys(struct keysyms *syms) { - assert(server->input_mode == LAB_INPUT_STATE_MENU); + assert(g_server.input_mode == LAB_INPUT_STATE_MENU); for (int i = 0; i < syms->nr_syms; i++) { switch (syms->syms[i]) { case XKB_KEY_Down: - menu_item_select_next(server); + menu_item_select_next(); break; case XKB_KEY_Up: - menu_item_select_previous(server); + menu_item_select_previous(); break; case XKB_KEY_Right: - menu_submenu_enter(server); + menu_submenu_enter(); break; case XKB_KEY_Left: - menu_submenu_leave(server); + menu_submenu_leave(); break; case XKB_KEY_Return: case XKB_KEY_KP_Enter: - menu_call_selected_actions(server); + menu_call_selected_actions(); break; case XKB_KEY_Escape: - menu_close_root(server); - cursor_update_focus(server); + menu_close_root(); + cursor_update_focus(); break; default: continue; @@ -450,7 +448,7 @@ handle_menu_keys(struct server *server, struct keysyms *syms) /* Returns true if the keystroke is consumed */ static bool -handle_cycle_view_key(struct server *server, struct keyinfo *keyinfo) +handle_cycle_view_key(struct keyinfo *keyinfo) { if (keyinfo->is_modifier) { return false; @@ -460,19 +458,19 @@ handle_cycle_view_key(struct server *server, struct keyinfo *keyinfo) for (int i = 0; i < keyinfo->translated.nr_syms; i++) { if (keyinfo->translated.syms[i] == XKB_KEY_Escape) { /* Esc deactivates window switcher */ - cycle_finish(server, /*switch_focus*/ false); + cycle_finish(/*switch_focus*/ false); return true; } if (keyinfo->translated.syms[i] == XKB_KEY_Up || keyinfo->translated.syms[i] == XKB_KEY_Left) { /* Up/Left cycles the window backward */ - cycle_step(server, LAB_CYCLE_DIR_BACKWARD); + cycle_step(LAB_CYCLE_DIR_BACKWARD); return true; } if (keyinfo->translated.syms[i] == XKB_KEY_Down || keyinfo->translated.syms[i] == XKB_KEY_Right) { /* Down/Right cycles the window forward */ - cycle_step(server, LAB_CYCLE_DIR_FORWARD); + cycle_step(LAB_CYCLE_DIR_FORWARD); return true; } } @@ -483,10 +481,9 @@ static enum lab_key_handled handle_compositor_keybindings(struct keyboard *keyboard, struct wlr_keyboard_key_event *event) { - struct server *server = &g_server; struct wlr_keyboard *wlr_keyboard = keyboard->wlr_keyboard; struct keyinfo keyinfo = get_keyinfo(wlr_keyboard, event->keycode); - bool locked = server->session_lock_manager->locked; + bool locked = g_server.session_lock_manager->locked; key_state_set_pressed(event->keycode, event->state == WL_KEYBOARD_KEY_STATE_PRESSED); @@ -498,15 +495,15 @@ handle_compositor_keybindings(struct keyboard *keyboard, cur_keybind = NULL; return LAB_KEY_HANDLED_TRUE; } - actions_run(NULL, server, &cur_keybind->actions, NULL); + actions_run(NULL, &cur_keybind->actions, NULL); return LAB_KEY_HANDLED_TRUE; } else { - return handle_key_release(server, event->keycode); + return handle_key_release(event->keycode); } } /* Catch C-A-F1 to C-A-F12 to change tty */ - if (handle_change_vt_key(server, keyboard, &keyinfo.translated)) { + if (handle_change_vt_key(keyboard, &keyinfo.translated)) { key_state_store_pressed_key_as_bound(event->keycode); return LAB_KEY_HANDLED_TRUE_AND_VT_CHANGED; } @@ -517,12 +514,12 @@ handle_compositor_keybindings(struct keyboard *keyboard, * _all_ key press/releases are registered */ if (!locked) { - if (server->input_mode == LAB_INPUT_STATE_MENU) { + if (g_server.input_mode == LAB_INPUT_STATE_MENU) { key_state_store_pressed_key_as_bound(event->keycode); - handle_menu_keys(server, &keyinfo.translated); + handle_menu_keys(&keyinfo.translated); return LAB_KEY_HANDLED_TRUE; - } else if (server->input_mode == LAB_INPUT_STATE_CYCLE) { - if (handle_cycle_view_key(server, &keyinfo)) { + } else if (g_server.input_mode == LAB_INPUT_STATE_CYCLE) { + if (handle_cycle_view_key(&keyinfo)) { key_state_store_pressed_key_as_bound(event->keycode); return LAB_KEY_HANDLED_TRUE; } @@ -532,7 +529,7 @@ handle_compositor_keybindings(struct keyboard *keyboard, /* * Handle compositor keybinds */ - cur_keybind = match_keybinding(server, &keyinfo, keyboard->is_virtual); + cur_keybind = match_keybinding(&keyinfo, keyboard->is_virtual); if (cur_keybind && (!locked || cur_keybind->allow_when_locked)) { /* * Update key-state before action_run() because the action @@ -541,7 +538,7 @@ handle_compositor_keybindings(struct keyboard *keyboard, */ key_state_store_pressed_key_as_bound(event->keycode); if (!cur_keybind->on_release) { - actions_run(NULL, server, &cur_keybind->actions, NULL); + actions_run(NULL, &cur_keybind->actions, NULL); } return LAB_KEY_HANDLED_TRUE; } @@ -571,7 +568,7 @@ handle_keybind_repeat(void *data) } static void -start_keybind_repeat(struct server *server, struct keyboard *keyboard, +start_keybind_repeat(struct keyboard *keyboard, struct wlr_keyboard_key_event *event) { struct wlr_keyboard *wlr_keyboard = keyboard->wlr_keyboard; @@ -582,7 +579,7 @@ start_keybind_repeat(struct server *server, struct keyboard *keyboard, keyboard->keybind_repeat_keycode = event->keycode; keyboard->keybind_repeat_rate = wlr_keyboard->repeat_info.rate; keyboard->keybind_repeat = wl_event_loop_add_timer( - server->wl_event_loop, handle_keybind_repeat, keyboard); + g_server.wl_event_loop, handle_keybind_repeat, keyboard); wl_event_source_timer_update(keyboard->keybind_repeat, wlr_keyboard->repeat_info.delay); } @@ -638,7 +635,7 @@ handle_key(struct wl_listener *listener, void *data) */ if (!is_modifier(keyboard->wlr_keyboard, event->keycode) && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { - start_keybind_repeat(seat->server, keyboard, event); + start_keybind_repeat(keyboard, event); } } else if (!input_method_keyboard_grab_forward_key(keyboard, event)) { wlr_seat_set_keyboard(wlr_seat, keyboard->wlr_keyboard); @@ -714,7 +711,7 @@ keyboard_update_layout(struct seat *seat, xkb_layout_index_t layout) } static void -reset_window_keyboard_layout_groups(struct server *server) +reset_window_keyboard_layout_groups(void) { if (!rc.kb_layout_per_window) { return; @@ -726,15 +723,15 @@ reset_window_keyboard_layout_groups(struct server *server) * but let's keep it simple for now and just reset them all. */ struct view *view; - for_each_view(view, &server->views, LAB_VIEW_CRITERIA_NONE) { + for_each_view(view, &g_server.views, LAB_VIEW_CRITERIA_NONE) { view->keyboard_layout = 0; } - struct view *active_view = server->active_view; + struct view *active_view = g_server.active_view; if (!active_view) { return; } - keyboard_update_layout(&server->seat, active_view->keyboard_layout); + keyboard_update_layout(&g_server.seat, active_view->keyboard_layout); } /* @@ -742,7 +739,7 @@ reset_window_keyboard_layout_groups(struct server *server) * XKB_DEFAULT_OPTIONS, and friends. */ static void -set_layout(struct server *server, struct wlr_keyboard *kb) +set_layout(struct wlr_keyboard *kb) { static bool fallback_mode; @@ -761,7 +758,7 @@ set_layout(struct server *server, struct wlr_keyboard *kb) if (keymap && !layout_empty) { if (!wlr_keyboard_keymaps_match(kb->keymap, keymap)) { wlr_keyboard_set_keymap(kb, keymap); - reset_window_keyboard_layout_groups(server); + reset_window_keyboard_layout_groups(); } xkb_keymap_unref(keymap); } else { @@ -771,7 +768,7 @@ set_layout(struct server *server, struct wlr_keyboard *kb) wlr_log(WLR_ERROR, "entering fallback mode with layout 'us'"); fallback_mode = true; setenv("XKB_DEFAULT_LAYOUT", "us", 1); - set_layout(server, kb); + set_layout(kb); } } xkb_context_unref(context); @@ -781,10 +778,10 @@ void keyboard_configure(struct seat *seat, struct wlr_keyboard *kb, bool is_virtual) { if (!is_virtual) { - set_layout(seat->server, kb); + set_layout(kb); } wlr_keyboard_set_repeat_info(kb, rc.repeat_rate, rc.repeat_delay); - keybind_update_keycodes(seat->server); + keybind_update_keycodes(); } void diff --git a/src/input/tablet-pad.c b/src/input/tablet-pad.c index 230b6e6b..2b1e34f4 100644 --- a/src/input/tablet-pad.c +++ b/src/input/tablet-pad.c @@ -183,9 +183,9 @@ tablet_pad_create(struct seat *seat, struct wlr_input_device *wlr_device) pad->seat = seat; pad->wlr_input_device = wlr_device; pad->pad = wlr_tablet_pad_from_input_device(wlr_device); - if (seat->server->tablet_manager) { + if (g_server.tablet_manager) { pad->pad_v2 = wlr_tablet_pad_create( - seat->server->tablet_manager, seat->seat, wlr_device); + g_server.tablet_manager, seat->seat, wlr_device); } pad->pad->data = pad; wlr_log(WLR_INFO, "tablet pad capabilities: %zu button(s) %zu strip(s) %zu ring(s)", diff --git a/src/input/tablet.c b/src/input/tablet.c index 319c06b3..107e8c27 100644 --- a/src/input/tablet.c +++ b/src/input/tablet.c @@ -44,7 +44,7 @@ handle_set_cursor(struct wl_listener *listener, void *data) struct wlr_seat_client *focused_client = seat->seat->pointer_state.focused_client; - if (seat->server->input_mode != LAB_INPUT_STATE_PASSTHROUGH) { + if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { return; } @@ -76,7 +76,7 @@ tablet_tool_create(struct seat *seat, struct drawing_tablet_tool *tool = znew(*tool); tool->seat = seat; tool->tool_v2 = - wlr_tablet_tool_create(seat->server->tablet_manager, + wlr_tablet_tool_create(g_server.tablet_manager, seat->seat, wlr_tablet_tool); wlr_tablet_tool->data = tool; wlr_log(WLR_INFO, "tablet tool capabilities:%s%s%s%s%s%s", @@ -239,7 +239,7 @@ tablet_get_coords(struct drawing_tablet *tablet, struct drawing_tablet_tool *too double sx, sy; struct wlr_scene_node *node = - wlr_scene_node_at(&tablet->seat->server->scene->tree.node, lx, ly, &sx, &sy); + wlr_scene_node_at(&g_server.scene->tree.node, lx, ly, &sx, &sy); /* find the surface and return it if it accepts tablet events */ struct wlr_surface *surface = lab_wlr_surface_from_node(node); @@ -275,7 +275,7 @@ notify_motion(struct drawing_tablet *tablet, struct drawing_tablet_tool *tool, } double sx, sy; - bool notify = cursor_process_motion(tablet->seat->server, time, &sx, &sy); + bool notify = cursor_process_motion(time, &sx, &sy); if (notify) { wlr_tablet_v2_tablet_tool_notify_motion(tool->tool_v2, sx, sy); if (enter_surface) { @@ -449,7 +449,7 @@ handle_tablet_tool_axis(struct wl_listener *listener, void *data) * Note that surface is also NULL when mouse emulation is forced. */ if (!is_down_mouse_emulation && ((surface - && tablet->seat->server->input_mode == LAB_INPUT_STATE_PASSTHROUGH) + && g_server.input_mode == LAB_INPUT_STATE_PASSTHROUGH) || wlr_tablet_tool_v2_has_implicit_grab(tool->tool_v2))) { /* motion seems to be supported by all tools */ notify_motion(tablet, tool, surface, x, y, dx, dy, ev->time_msec); @@ -667,8 +667,7 @@ handle_tablet_tool_button(struct wl_listener *listener, void *data) if (mousebind->mouse_event == MOUSE_ACTION_PRESS && mousebind->button == button && mousebind->context == LAB_NODE_CLIENT) { - actions_run(view, tool->seat->server, - &mousebind->actions, NULL); + actions_run(view, &mousebind->actions, NULL); } } } @@ -720,9 +719,9 @@ tablet_create(struct seat *seat, struct wlr_input_device *wlr_device) tablet->wlr_input_device = wlr_device; tablet->tablet = wlr_tablet_from_input_device(wlr_device); tablet->tablet->data = tablet; - if (seat->server->tablet_manager) { + if (g_server.tablet_manager) { tablet->tablet_v2 = wlr_tablet_create( - seat->server->tablet_manager, seat->seat, wlr_device); + g_server.tablet_manager, seat->seat, wlr_device); } wlr_log(WLR_INFO, "tablet dimensions: %.2fmm x %.2fmm", tablet->tablet->width_mm, tablet->tablet->height_mm); diff --git a/src/input/touch.c b/src/input/touch.c index d6557014..bddbc8e0 100644 --- a/src/input/touch.c +++ b/src/input/touch.c @@ -52,7 +52,7 @@ touch_get_coords(struct seat *seat, struct wlr_touch *touch, double x, double y, * This matches normal pointer/mouse behavior where the first click on * a surface closes a root/client menu. */ - if (seat->server->input_mode == LAB_INPUT_STATE_MENU) { + if (g_server.input_mode == LAB_INPUT_STATE_MENU) { return NULL; } @@ -63,7 +63,7 @@ touch_get_coords(struct seat *seat, struct wlr_touch *touch, double x, double y, double sx, sy; struct wlr_scene_node *node = - wlr_scene_node_at(&seat->server->scene->tree.node, lx, ly, &sx, &sy); + wlr_scene_node_at(&g_server.scene->tree.node, lx, ly, &sx, &sy); *x_offset = lx - sx; *y_offset = ly - sy; @@ -169,7 +169,7 @@ handle_touch_down(struct wl_listener *listener, void *data) if (mousebind->mouse_event == MOUSE_ACTION_PRESS && mousebind->button == BTN_LEFT && mousebind->context == LAB_NODE_CLIENT) { - actions_run(view, seat->server, &mousebind->actions, NULL); + actions_run(view, &mousebind->actions, NULL); } } @@ -207,7 +207,7 @@ handle_touch_up(struct wl_listener *listener, void *data) } else { cursor_emulate_button(seat, BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED, event->time_msec); - ssd_update_hovered_button(seat->server, NULL); + ssd_update_hovered_button(NULL); } wl_list_remove(&touch_point->link); zfree(touch_point); diff --git a/src/interactive.c b/src/interactive.c index efbe54b2..d3894a3f 100644 --- a/src/interactive.c +++ b/src/interactive.c @@ -36,22 +36,22 @@ max_move_scale(double pos_cursor, double pos_old, double size_old, } void -interactive_anchor_to_cursor(struct server *server, struct wlr_box *geo) +interactive_anchor_to_cursor(struct wlr_box *geo) { - assert(server->input_mode == LAB_INPUT_STATE_MOVE); + assert(g_server.input_mode == LAB_INPUT_STATE_MOVE); if (wlr_box_empty(geo)) { return; } /* Resize grab_box while anchoring it to grab_{x,y} */ - server->grab_box.x = max_move_scale(server->grab_x, server->grab_box.x, - server->grab_box.width, geo->width); - server->grab_box.y = max_move_scale(server->grab_y, server->grab_box.y, - server->grab_box.height, geo->height); - server->grab_box.width = geo->width; - server->grab_box.height = geo->height; + g_server.grab_box.x = max_move_scale(g_server.grab_x, g_server.grab_box.x, + g_server.grab_box.width, geo->width); + g_server.grab_box.y = max_move_scale(g_server.grab_y, g_server.grab_box.y, + g_server.grab_box.height, geo->height); + g_server.grab_box.width = geo->width; + g_server.grab_box.height = geo->height; - geo->x = server->grab_box.x + (server->seat.cursor->x - server->grab_x); - geo->y = server->grab_box.y + (server->seat.cursor->y - server->grab_y); + geo->x = g_server.grab_box.x + (g_server.seat.cursor->x - g_server.grab_x); + geo->y = g_server.grab_box.y + (g_server.seat.cursor->y - g_server.grab_y); } /* @@ -60,21 +60,21 @@ interactive_anchor_to_cursor(struct server *server, struct wlr_box *geo) * then interactive_begin() is called. */ void -interactive_set_grab_context(struct server *server, const struct cursor_context *ctx) +interactive_set_grab_context(const struct cursor_context *ctx) { if (!ctx->view) { return; } - if (server->input_mode != LAB_INPUT_STATE_PASSTHROUGH) { + if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { return; } - server->grabbed_view = ctx->view; - server->grab_x = server->seat.cursor->x; - server->grab_y = server->seat.cursor->y; - server->grab_box = ctx->view->current; - server->resize_edges = - cursor_get_resize_edges(server->seat.cursor, ctx); + g_server.grabbed_view = ctx->view; + g_server.grab_x = g_server.seat.cursor->x; + g_server.grab_y = g_server.seat.cursor->y; + g_server.grab_box = ctx->view->current; + g_server.resize_edges = + cursor_get_resize_edges(g_server.seat.cursor, ctx); } void @@ -86,11 +86,10 @@ interactive_begin(struct view *view, enum input_mode mode, enum lab_edge edges) * the compositor stops propagating pointer events to clients and * instead consumes them itself, to move or resize windows. */ - struct server *server = view->server; - struct seat *seat = &server->seat; + struct seat *seat = &g_server.seat; - if (server->input_mode != LAB_INPUT_STATE_PASSTHROUGH - || view != server->grabbed_view) { + if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH + || view != g_server.grabbed_view) { return; } @@ -138,7 +137,7 @@ interactive_begin(struct view *view, enum input_mode mode, enum lab_edge edges) * Otherwise, they were set already from cursor context. */ if (edges != LAB_EDGE_NONE) { - server->resize_edges = edges; + g_server.resize_edges = edges; } /* @@ -147,15 +146,15 @@ interactive_begin(struct view *view, enum input_mode mode, enum lab_edge edges) * keep the same geometry as the starting point. */ enum view_axis maximized = view->maximized; - if (server->resize_edges & LAB_EDGES_LEFT_RIGHT) { + if (g_server.resize_edges & LAB_EDGES_LEFT_RIGHT) { maximized &= ~VIEW_AXIS_HORIZONTAL; } - if (server->resize_edges & LAB_EDGES_TOP_BOTTOM) { + if (g_server.resize_edges & LAB_EDGES_TOP_BOTTOM) { maximized &= ~VIEW_AXIS_VERTICAL; } view_set_maximized(view, maximized); view_set_untiled(view); - cursor_shape = cursor_get_from_edge(server->resize_edges); + cursor_shape = cursor_get_from_edge(g_server.resize_edges); break; } default: @@ -175,7 +174,7 @@ interactive_begin(struct view *view, enum input_mode mode, enum lab_edge edges) if (mode == LAB_INPUT_STATE_MOVE && !view_is_floating(view) && rc.unsnap_threshold <= 0) { struct wlr_box natural_geo = view->natural_geometry; - interactive_anchor_to_cursor(server, &natural_geo); + interactive_anchor_to_cursor(&natural_geo); /* Shaded clients will not process resize events until unshaded */ view_set_shade(view, false); view_set_maximized(view, VIEW_AXIS_NONE); @@ -187,7 +186,7 @@ interactive_begin(struct view *view, enum input_mode mode, enum lab_edge edges) resize_indicator_show(view); } if (rc.window_edge_strength) { - edges_calculate_visibility(server, view); + edges_calculate_visibility(view); } } @@ -199,7 +198,7 @@ edge_from_cursor(struct seat *seat, struct output **dest_output, *edge1 = LAB_EDGE_NONE; *edge2 = LAB_EDGE_NONE; - if (!view_is_floating(seat->server->grabbed_view)) { + if (!view_is_floating(g_server.grabbed_view)) { return false; } @@ -207,7 +206,7 @@ edge_from_cursor(struct seat *seat, struct output **dest_output, return false; } - struct output *output = output_nearest_to_cursor(seat->server); + struct output *output = output_nearest_to_cursor(); if (!output_is_usable(output)) { wlr_log(WLR_ERROR, "output at cursor is unusable"); return false; @@ -221,25 +220,25 @@ edge_from_cursor(struct seat *seat, struct output **dest_output, int bottom_range = rc.snap_edge_range_outer; int left_range = rc.snap_edge_range_outer; int right_range = rc.snap_edge_range_outer; - if (wlr_output_layout_adjacent_output(seat->server->output_layout, WLR_DIRECTION_UP, + if (wlr_output_layout_adjacent_output(g_server.output_layout, WLR_DIRECTION_UP, output->wlr_output, cursor_x, cursor_y)) { top_range = rc.snap_edge_range_inner; } - if (wlr_output_layout_adjacent_output(seat->server->output_layout, WLR_DIRECTION_DOWN, + if (wlr_output_layout_adjacent_output(g_server.output_layout, WLR_DIRECTION_DOWN, output->wlr_output, cursor_x, cursor_y)) { bottom_range = rc.snap_edge_range_inner; } - if (wlr_output_layout_adjacent_output(seat->server->output_layout, WLR_DIRECTION_LEFT, + if (wlr_output_layout_adjacent_output(g_server.output_layout, WLR_DIRECTION_LEFT, output->wlr_output, cursor_x, cursor_y)) { left_range = rc.snap_edge_range_inner; } - if (wlr_output_layout_adjacent_output(seat->server->output_layout, WLR_DIRECTION_RIGHT, + if (wlr_output_layout_adjacent_output(g_server.output_layout, WLR_DIRECTION_RIGHT, output->wlr_output, cursor_x, cursor_y)) { right_range = rc.snap_edge_range_inner; } /* Translate into output local coordinates */ - wlr_output_layout_output_coords(seat->server->output_layout, + wlr_output_layout_output_coords(g_server.output_layout, output->wlr_output, &cursor_x, &cursor_y); struct wlr_box *area = &output->usable_area; @@ -284,7 +283,7 @@ snap_to_edge(struct view *view) { struct output *output; enum lab_edge edge1, edge2; - if (!edge_from_cursor(&view->server->seat, &output, &edge1, &edge2)) { + if (!edge_from_cursor(&g_server.seat, &output, &edge1, &edge2)) { return false; } enum lab_edge edge = edge1 | edge2; @@ -304,11 +303,11 @@ snap_to_edge(struct view *view) static bool snap_to_region(struct view *view) { - if (!regions_should_snap(view->server)) { + if (!regions_should_snap()) { return false; } - struct region *region = regions_from_cursor(view->server); + struct region *region = regions_from_cursor(); if (region) { view_snap_to_region(view, region); return true; @@ -321,11 +320,11 @@ interactive_finish(struct view *view) { assert(view); - if (view->server->grabbed_view != view) { + if (g_server.grabbed_view != view) { return; } - if (view->server->input_mode == LAB_INPUT_STATE_MOVE) { + if (g_server.input_mode == LAB_INPUT_STATE_MOVE) { if (!snap_to_region(view)) { snap_to_edge(view); } @@ -344,25 +343,25 @@ interactive_cancel(struct view *view) { assert(view); - if (view->server->grabbed_view != view) { + if (g_server.grabbed_view != view) { return; } - view->server->grabbed_view = NULL; + g_server.grabbed_view = NULL; /* * It's possible that grabbed_view was set but interactive_begin() * wasn't called yet. In that case, we are done. */ - if (view->server->input_mode != LAB_INPUT_STATE_MOVE - && view->server->input_mode != LAB_INPUT_STATE_RESIZE) { + if (g_server.input_mode != LAB_INPUT_STATE_MOVE + && g_server.input_mode != LAB_INPUT_STATE_RESIZE) { return; } - overlay_finish(&view->server->seat); + overlay_finish(&g_server.seat); resize_indicator_hide(view); /* Restore keyboard/pointer focus */ - seat_focus_override_end(&view->server->seat, /*restore_focus*/ true); + seat_focus_override_end(&g_server.seat, /*restore_focus*/ true); } diff --git a/src/layers.c b/src/layers.c index 040b110c..0abbd09b 100644 --- a/src/layers.c +++ b/src/layers.c @@ -78,9 +78,8 @@ layers_arrange(struct output *output) apply_override(output, &usable_area); - struct server *server = output->server; struct wlr_scene_output *scene_output = - wlr_scene_get_scene_output(server->scene, output->wlr_output); + wlr_scene_get_scene_output(g_server.scene, output->wlr_output); if (!scene_output) { wlr_log(WLR_DEBUG, "no wlr_scene_output"); return; @@ -141,10 +140,10 @@ has_exclusive_interactivity(struct wlr_scene_layer_surface_v1 *scene) * toplevel if one exists. */ static void -try_to_focus_next_layer_or_toplevel(struct server *server) +try_to_focus_next_layer_or_toplevel(void) { - struct seat *seat = &server->seat; - struct output *output = output_nearest_to_cursor(server); + struct seat *seat = &g_server.seat; + struct output *output = output_nearest_to_cursor(); if (!output_is_usable(output)) { goto no_output; } @@ -235,7 +234,7 @@ layer_try_set_focus(struct seat *seat, struct wlr_layer_surface_v1 *layer_surfac case ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE: wlr_log(WLR_DEBUG, "interactive-none '%p'", layer_surface); if (seat->focused_layer == layer_surface) { - try_to_focus_next_layer_or_toplevel(seat->server); + try_to_focus_next_layer_or_toplevel(); } break; } @@ -278,19 +277,18 @@ handle_surface_commit(struct wl_listener *listener, void *data) * cursor-button-press). */ if (is_on_demand(layer_surface)) { - struct seat *seat = &layer->server->seat; + struct seat *seat = &g_server.seat; if (seat->focused_layer == layer_surface) { /* * Must be change from EXCLUSIVE to ON_DEMAND, * so we should give us focus. */ - struct server *server = layer->server; - try_to_focus_next_layer_or_toplevel(server); + try_to_focus_next_layer_or_toplevel(); } goto out; } /* Handle EXCLUSIVE and NONE requests */ - struct seat *seat = &layer->server->seat; + struct seat *seat = &g_server.seat; layer_try_set_focus(seat, layer_surface); } out: @@ -302,7 +300,7 @@ out: * Update cursor focus here to ensure we * enter a new/moved/resized layer surface. */ - cursor_update_focus(layer->server); + cursor_update_focus(); } } @@ -312,7 +310,7 @@ handle_node_destroy(struct wl_listener *listener, void *data) struct lab_layer_surface *layer = wl_container_of(listener, layer, node_destroy); - struct seat *seat = &layer->server->seat; + struct seat *seat = &g_server.seat; /* * If the surface of this node has the current keyboard focus, then we @@ -374,11 +372,11 @@ handle_unmap(struct wl_listener *listener, void *data) if (layer_surface->output) { output_update_usable_area(layer_surface->output->data); } - struct seat *seat = &layer->server->seat; + struct seat *seat = &g_server.seat; if (seat->focused_layer == layer_surface) { - try_to_focus_next_layer_or_toplevel(layer->server); + try_to_focus_next_layer_or_toplevel(); } - cursor_update_focus(layer->server); + cursor_update_focus(); layer->being_unmapped = false; } @@ -424,7 +422,7 @@ handle_map(struct wl_listener *listener, void *data) return; } - struct seat *seat = &layer->server->seat; + struct seat *seat = &g_server.seat; layer_try_set_focus(seat, layer->scene_layer_surface->layer_surface); } @@ -439,7 +437,7 @@ handle_popup_destroy(struct wl_listener *listener, void *data) { struct lab_layer_popup *popup = wl_container_of(listener, popup, destroy); - struct seat *seat = &popup->server->seat; + struct seat *seat = &g_server.seat; struct wlr_xdg_popup *_popup, *tmp; wl_list_for_each_safe(_popup, tmp, &popup->wlr_popup->base->popups, link) { @@ -461,10 +459,10 @@ handle_popup_destroy(struct wl_listener *listener, void *data) if (popup->parent_was_focused && popup->wlr_popup->parent) { seat_force_focus_surface(seat, popup->wlr_popup->parent); } else { - desktop_focus_topmost_view(popup->server); + desktop_focus_topmost_view(); } } - cursor_update_focus(popup->server); + cursor_update_focus(); free(popup); } @@ -529,8 +527,7 @@ handle_popup_commit(struct wl_listener *listener, void *data) popup->commit.notify = NULL; /* Force focus when popup was triggered by IPC */ - struct server *server = popup->server; - struct seat *seat = &server->seat; + struct seat *seat = &g_server.seat; bool requesting_grab = !!popup->wlr_popup->seat; if (requesting_grab) { if (surface_is_focused(seat, popup->wlr_popup->parent)) { @@ -553,11 +550,10 @@ handle_popup_reposition(struct wl_listener *listener, void *data) static void handle_popup_new_popup(struct wl_listener *listener, void *data); static struct lab_layer_popup * -create_popup(struct server *server, struct wlr_xdg_popup *wlr_popup, +create_popup(struct wlr_xdg_popup *wlr_popup, struct wlr_scene_tree *parent) { struct lab_layer_popup *popup = znew(*popup); - popup->server = server; popup->wlr_popup = wlr_popup; popup->scene_tree = wlr_scene_xdg_surface_create(parent, wlr_popup->base); @@ -591,8 +587,7 @@ handle_popup_new_popup(struct wl_listener *listener, void *data) struct lab_layer_popup *lab_layer_popup = wl_container_of(listener, lab_layer_popup, new_popup); struct wlr_xdg_popup *wlr_popup = data; - struct lab_layer_popup *new_popup = create_popup( - lab_layer_popup->server, wlr_popup, + struct lab_layer_popup *new_popup = create_popup(wlr_popup, lab_layer_popup->scene_tree); new_popup->output_toplevel_sx_box = @@ -607,12 +602,11 @@ static void move_popup_to_top_layer(struct lab_layer_surface *toplevel, struct lab_layer_popup *popup) { - struct server *server = toplevel->server; struct wlr_output *wlr_output = toplevel->scene_layer_surface->layer_surface->output; struct output *output = (struct output *)wlr_output->data; struct wlr_box box = { 0 }; - wlr_output_layout_get_box(server->output_layout, wlr_output, &box); + wlr_output_layout_get_box(g_server.output_layout, wlr_output, &box); int lx = toplevel->scene_layer_surface->tree->node.x + box.x; int ly = toplevel->scene_layer_surface->tree->node.y + box.y; @@ -630,7 +624,6 @@ handle_new_popup(struct wl_listener *listener, void *data) wl_container_of(listener, toplevel, new_popup); struct wlr_xdg_popup *wlr_popup = data; - struct server *server = toplevel->server; struct wlr_scene_layer_surface_v1 *surface = toplevel->scene_layer_surface; struct output *output = surface->layer_surface->output->data; @@ -638,7 +631,7 @@ handle_new_popup(struct wl_listener *listener, void *data) wlr_scene_node_coords(&surface->tree->node, &lx, &ly); struct wlr_box output_box = { 0 }; - wlr_output_layout_get_box(server->output_layout, + wlr_output_layout_get_box(g_server.output_layout, output->wlr_output, &output_box); /* @@ -654,7 +647,7 @@ handle_new_popup(struct wl_listener *listener, void *data) .height = output_box.height, }; struct lab_layer_popup *popup = - create_popup(server, wlr_popup, surface->tree); + create_popup(wlr_popup, surface->tree); popup->output_toplevel_sx_box = output_toplevel_sx_box; if (surface->layer_surface->current.layer @@ -666,12 +659,10 @@ handle_new_popup(struct wl_listener *listener, void *data) static void handle_new_layer_surface(struct wl_listener *listener, void *data) { - struct server *server = wl_container_of( - listener, server, new_layer_surface); struct wlr_layer_surface_v1 *layer_surface = data; if (!layer_surface->output) { - struct output *output = output_nearest_to_cursor(server); + struct output *output = output_nearest_to_cursor(); if (!output || !output->scene_output) { /* * We are not using output_is_usable() here because @@ -709,7 +700,6 @@ handle_new_layer_surface(struct wl_listener *listener, void *data) node_descriptor_create(&surface->scene_layer_surface->tree->node, LAB_NODE_LAYER_SURFACE, /*view*/ NULL, surface); - surface->server = server; surface->scene_layer_surface->layer_surface = layer_surface; surface->surface_commit.notify = handle_surface_commit; @@ -735,17 +725,17 @@ handle_new_layer_surface(struct wl_listener *listener, void *data) } void -layers_init(struct server *server) +layers_init(void) { - server->layer_shell = wlr_layer_shell_v1_create(server->wl_display, + g_server.layer_shell = wlr_layer_shell_v1_create(g_server.wl_display, LAB_LAYERSHELL_VERSION); - server->new_layer_surface.notify = handle_new_layer_surface; - wl_signal_add(&server->layer_shell->events.new_surface, - &server->new_layer_surface); + g_server.new_layer_surface.notify = handle_new_layer_surface; + wl_signal_add(&g_server.layer_shell->events.new_surface, + &g_server.new_layer_surface); } void -layers_finish(struct server *server) +layers_finish(void) { - wl_list_remove(&server->new_layer_surface.link); + wl_list_remove(&g_server.new_layer_surface.link); } diff --git a/src/magnifier.c b/src/magnifier.c index 424865c9..e635f722 100644 --- a/src/magnifier.c +++ b/src/magnifier.c @@ -41,8 +41,7 @@ box_logical_to_physical(struct wlr_box *box, struct wlr_output *output) void magnifier_draw(struct output *output, struct wlr_buffer *output_buffer, struct wlr_box *damage) { - struct server *server = output->server; - struct theme *theme = server->theme; + struct theme *theme = g_server.theme; bool fullscreen = (rc.mag_width == -1 || rc.mag_height == -1); struct wlr_box output_box = { @@ -51,9 +50,9 @@ magnifier_draw(struct output *output, struct wlr_buffer *output_buffer, struct w }; /* Cursor position in per-output logical coordinate */ - double cursor_logical_x = server->seat.cursor->x; - double cursor_logical_y = server->seat.cursor->y; - wlr_output_layout_output_coords(server->output_layout, + double cursor_logical_x = g_server.seat.cursor->x; + double cursor_logical_y = g_server.seat.cursor->y; + wlr_output_layout_output_coords(g_server.output_layout, output->wlr_output, &cursor_logical_x, &cursor_logical_y); /* Cursor position in per-output physical coordinate */ struct wlr_box cursor_pos = { @@ -96,7 +95,7 @@ magnifier_draw(struct output *output, struct wlr_buffer *output_buffer, struct w } if (!tmp_buffer) { tmp_buffer = wlr_allocator_create_buffer( - server->allocator, mag_box.width, mag_box.height, + g_server.allocator, mag_box.width, mag_box.height, &output->wlr_output->swapchain->format); } if (!tmp_buffer) { @@ -105,7 +104,7 @@ magnifier_draw(struct output *output, struct wlr_buffer *output_buffer, struct w } if (!tmp_texture) { - tmp_texture = wlr_texture_from_buffer(server->renderer, tmp_buffer); + tmp_texture = wlr_texture_from_buffer(g_server.renderer, tmp_buffer); } if (!tmp_texture) { wlr_log(WLR_ERROR, "Failed to allocate temporary magnifier texture"); @@ -116,7 +115,7 @@ magnifier_draw(struct output *output, struct wlr_buffer *output_buffer, struct w /* Extract source region into temporary buffer */ struct wlr_render_pass *tmp_render_pass = wlr_renderer_begin_buffer_pass( - server->renderer, tmp_buffer, NULL); + g_server.renderer, tmp_buffer, NULL); if (!tmp_render_pass) { wlr_log(WLR_ERROR, "Failed to begin magnifier render pass"); return; @@ -124,7 +123,7 @@ magnifier_draw(struct output *output, struct wlr_buffer *output_buffer, struct w wlr_buffer_lock(output_buffer); struct wlr_texture *output_texture = wlr_texture_from_buffer( - server->renderer, output_buffer); + g_server.renderer, output_buffer); if (!output_texture) { goto cleanup; } @@ -151,7 +150,7 @@ magnifier_draw(struct output *output, struct wlr_buffer *output_buffer, struct w /* Render to the output buffer itself */ tmp_render_pass = wlr_renderer_begin_buffer_pass( - server->renderer, output_buffer, NULL); + g_server.renderer, output_buffer, NULL); if (!tmp_render_pass) { wlr_log(WLR_ERROR, "Failed to begin second magnifier render pass"); goto cleanup; @@ -224,7 +223,7 @@ output_wants_magnification(struct output *output) { static double x = -1; static double y = -1; - struct wlr_cursor *cursor = output->server->seat.cursor; + struct wlr_cursor *cursor = g_server.seat.cursor; if (!magnify_on) { x = -1; y = -1; @@ -235,24 +234,24 @@ output_wants_magnification(struct output *output) } x = cursor->x; y = cursor->y; - return output_nearest_to_cursor(output->server) == output; + return output_nearest_to_cursor() == output; } static void -enable_magnifier(struct server *server, bool enable) +enable_magnifier(bool enable) { magnify_on = enable; - server->scene->WLR_PRIVATE.direct_scanout = enable ? false - : server->direct_scanout_enabled; + g_server.scene->WLR_PRIVATE.direct_scanout = enable ? false + : g_server.direct_scanout_enabled; } /* Toggles magnification on and off */ void -magnifier_toggle(struct server *server) +magnifier_toggle(void) { - enable_magnifier(server, !magnify_on); + enable_magnifier(!magnify_on); - struct output *output = output_nearest_to_cursor(server); + struct output *output = output_nearest_to_cursor(); if (output) { wlr_output_schedule_frame(output->wlr_output); } @@ -260,22 +259,22 @@ magnifier_toggle(struct server *server) /* Increases and decreases magnification scale */ void -magnifier_set_scale(struct server *server, enum magnify_dir dir) +magnifier_set_scale(enum magnify_dir dir) { - struct output *output = output_nearest_to_cursor(server); + struct output *output = output_nearest_to_cursor(); if (dir == MAGNIFY_INCREASE) { if (magnify_on) { mag_scale += rc.mag_increment; } else { - enable_magnifier(server, true); + enable_magnifier(true); mag_scale = 1.0 + rc.mag_increment; } } else { if (magnify_on && mag_scale > 1.0 + rc.mag_increment) { mag_scale -= rc.mag_increment; } else { - enable_magnifier(server, false); + enable_magnifier(false); } } diff --git a/src/main.c b/src/main.c index 2ffc68b7..363a2f7a 100644 --- a/src/main.c +++ b/src/main.c @@ -130,7 +130,6 @@ send_signal_to_labwc_pid(int signal) } struct idle_ctx { - struct server *server; const char *primary_client; const char *startup_cmd; }; @@ -143,16 +142,16 @@ idle_callback(void *data) /* Start session-manager if one is specified by -S|--session */ if (ctx->primary_client) { - ctx->server->primary_client_pid = spawn_primary_client(ctx->primary_client); - if (ctx->server->primary_client_pid < 0) { + g_server.primary_client_pid = spawn_primary_client(ctx->primary_client); + if (g_server.primary_client_pid < 0) { wlr_log(WLR_ERROR, "fatal error starting primary client: %s", ctx->primary_client); - wl_display_terminate(ctx->server->wl_display); + wl_display_terminate(g_server.wl_display); return; } } - session_autostart_init(ctx->server); + session_autostart_init(); if (ctx->startup_cmd) { spawn_async_no_shell(ctx->startup_cmd); } @@ -255,35 +254,33 @@ main(int argc, char *argv[]) increase_nofile_limit(); - struct server *server = &g_server; - server_init(server); - server_start(server); + server_init(); + server_start(); struct theme theme = { 0 }; - theme_init(&theme, server, rc.theme_name); + theme_init(&theme, rc.theme_name); rc.theme = &theme; - server->theme = &theme; + g_server.theme = &theme; - menu_init(server); + menu_init(); /* Delay startup of applications until the event loop is ready */ struct idle_ctx idle_ctx = { - .server = server, .primary_client = primary_client, .startup_cmd = startup_cmd }; - wl_event_loop_add_idle(server->wl_event_loop, idle_callback, &idle_ctx); + wl_event_loop_add_idle(g_server.wl_event_loop, idle_callback, &idle_ctx); - wl_display_run(server->wl_display); + wl_display_run(g_server.wl_display); - session_shutdown(server); + session_shutdown(); - menu_finish(server); + menu_finish(); theme_finish(&theme); rcxml_finish(); font_finish(); - server_finish(server); + server_finish(); return 0; } diff --git a/src/menu/menu.c b/src/menu/menu.c index 45495a57..98185ce8 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -54,10 +54,10 @@ struct menu_pipe_context { /* TODO: split this whole file into parser.c and actions.c*/ static bool -is_unique_id(struct server *server, const char *id) +is_unique_id(const char *id) { struct menu *menu; - wl_list_for_each(menu, &server->menus, link) { + wl_list_for_each(menu, &g_server.menus, link) { if (!strcmp(menu->id, id)) { return false; } @@ -66,33 +66,32 @@ is_unique_id(struct server *server, const char *id) } static struct menu * -menu_create(struct server *server, struct menu *parent, const char *id, +menu_create(struct menu *parent, const char *id, const char *label) { - if (!is_unique_id(server, id)) { + if (!is_unique_id(id)) { wlr_log(WLR_ERROR, "menu id %s already exists", id); } struct menu *menu = znew(*menu); - wl_list_append(&server->menus, &menu->link); + wl_list_append(&g_server.menus, &menu->link); wl_list_init(&menu->menuitems); menu->id = xstrdup(id); menu->label = xstrdup(label ? label : id); menu->parent = parent; - menu->server = server; menu->is_pipemenu_child = waiting_for_pipe_menu; return menu; } struct menu * -menu_get_by_id(struct server *server, const char *id) +menu_get_by_id(const char *id) { if (!id) { return NULL; } struct menu *menu; - wl_list_for_each(menu, &server->menus, link) { + wl_list_for_each(menu, &g_server.menus, link) { if (!strcmp(menu->id, id)) { return menu; } @@ -122,10 +121,10 @@ validate_menu(struct menu *menu) } static void -validate(struct server *server) +validate(void) { struct menu *menu; - wl_list_for_each(menu, &server->menus, link) { + wl_list_for_each(menu, &g_server.menus, link) { validate_menu(menu); } } @@ -136,7 +135,7 @@ item_create(struct menu *menu, const char *text, const char *icon_name, bool sho assert(menu); assert(text); - struct theme *theme = menu->server->theme; + struct theme *theme = g_server.theme; struct menuitem *menuitem = znew(*menuitem); menuitem->parent = menu; menuitem->selectable = true; @@ -167,7 +166,7 @@ item_create_scene_for_state(struct menuitem *item, float *text_color, float *bg_color) { struct menu *menu = item->parent; - struct theme *theme = menu->server->theme; + struct theme *theme = g_server.theme; /* Tree to hold background and label buffers */ struct wlr_scene_tree *tree = lab_wlr_scene_tree_create(item->tree); @@ -197,7 +196,7 @@ item_create_scene_for_state(struct menuitem *item, float *text_color, && item->client_list_view; if (item->icon_name || show_app_icon) { struct scaled_icon_buffer *icon_buffer = scaled_icon_buffer_create( - tree, menu->server, icon_size, icon_size); + tree, icon_size, icon_size); if (item->icon_name) { /* icon set via */ scaled_icon_buffer_set_icon_name(icon_buffer, item->icon_name); @@ -243,7 +242,7 @@ item_create_scene(struct menuitem *menuitem, int *item_y) assert(menuitem); assert(menuitem->type == LAB_MENU_ITEM); struct menu *menu = menuitem->parent; - struct theme *theme = menu->server->theme; + struct theme *theme = g_server.theme; /* Menu item root node */ menuitem->tree = lab_wlr_scene_tree_create(menu->scene_tree); @@ -292,7 +291,7 @@ separator_create_scene(struct menuitem *menuitem, int *item_y) assert(menuitem); assert(menuitem->type == LAB_MENU_SEPARATOR_LINE); struct menu *menu = menuitem->parent; - struct theme *theme = menu->server->theme; + struct theme *theme = g_server.theme; /* Menu item root node */ menuitem->tree = lab_wlr_scene_tree_create(menu->scene_tree); @@ -338,7 +337,7 @@ title_create_scene(struct menuitem *menuitem, int *item_y) assert(menuitem); assert(menuitem->type == LAB_MENU_TITLE); struct menu *menu = menuitem->parent; - struct theme *theme = menu->server->theme; + struct theme *theme = g_server.theme; float *bg_color = theme->menu_title_bg_color; float *text_color = theme->menu_title_text_color; @@ -412,11 +411,11 @@ static void menu_create_scene(struct menu *menu) { struct menuitem *item; - struct theme *theme = menu->server->theme; + struct theme *theme = g_server.theme; assert(!menu->scene_tree); - menu->scene_tree = lab_wlr_scene_tree_create(menu->server->menu_tree); + menu->scene_tree = lab_wlr_scene_tree_create(g_server.menu_tree); wlr_scene_node_set_enabled(&menu->scene_tree->node, false); /* Menu width is the maximum item width, capped by menu.width.{min,max} */ @@ -504,10 +503,10 @@ item_destroy(struct menuitem *item) free(item); } -static bool parse_buf(struct server *server, struct menu *menu, struct buf *buf); +static bool parse_buf(struct menu *menu, struct buf *buf); static int handle_pipemenu_readable(int fd, uint32_t mask, void *_ctx); static int handle_pipemenu_timeout(void *_ctx); -static void fill_menu_children(struct server *server, struct menu *parent, xmlNode *n); +static void fill_menu_children(struct menu *parent, xmlNode *n); /* * elements have three different roles: @@ -516,7 +515,7 @@ static void fill_menu_children(struct server *server, struct menu *parent, xmlNo * * Menuitem of submenu type - has ID only */ static void -fill_menu(struct server *server, struct menu *parent, xmlNode *n) +fill_menu(struct menu *parent, xmlNode *n) { char *label = (char *)xmlGetProp(n, (const xmlChar *)"label"); char *icon_name = (char *)xmlGetProp(n, (const xmlChar *)"icon"); @@ -531,7 +530,7 @@ fill_menu(struct server *server, struct menu *parent, xmlNode *n) if (execute && label) { wlr_log(WLR_DEBUG, "pipemenu '%s:%s:%s'", id, label, execute); - struct menu *pipemenu = menu_create(server, parent, id, label); + struct menu *pipemenu = menu_create(parent, id, label); pipemenu->execute = xstrdup(execute); if (!parent) { /* @@ -568,7 +567,7 @@ fill_menu(struct server *server, struct menu *parent, xmlNode *n) * attribute to make it easier for users to define "root-menu" * and "client-menu". */ - struct menu *menu = menu_create(server, parent, id, label); + struct menu *menu = menu_create(parent, id, label); if (icon_name) { menu->icon_name = xstrdup(icon_name); } @@ -581,7 +580,7 @@ fill_menu(struct server *server, struct menu *parent, xmlNode *n) icon_name, true); item->submenu = menu; } - fill_menu_children(server, menu, n); + fill_menu_children(menu, n); } else { /* * (when inside another element) creates an @@ -598,7 +597,7 @@ fill_menu(struct server *server, struct menu *parent, xmlNode *n) goto error; } - struct menu *menu = menu_get_by_id(server, id); + struct menu *menu = menu_get_by_id(id); if (!menu) { wlr_log(WLR_ERROR, "no menu with id '%s'", id); goto error; @@ -636,13 +635,13 @@ fill_separator(struct menu *menu, xmlNode *n) /* parent==NULL when processing toplevel menus in menu.xml */ static void -fill_menu_children(struct server *server, struct menu *parent, xmlNode *n) +fill_menu_children(struct menu *parent, xmlNode *n) { xmlNode *child; char *key, *content; LAB_XML_FOR_EACH(n, child, key, content) { if (!strcasecmp(key, "menu")) { - fill_menu(server, parent, child); + fill_menu(parent, child); } else if (!strcasecmp(key, "separator")) { if (!parent) { wlr_log(WLR_ERROR, @@ -662,7 +661,7 @@ fill_menu_children(struct server *server, struct menu *parent, xmlNode *n) } static bool -parse_buf(struct server *server, struct menu *parent, struct buf *buf) +parse_buf(struct menu *parent, struct buf *buf) { int options = 0; xmlDoc *d = xmlReadMemory(buf->data, buf->len, NULL, NULL, options); @@ -672,7 +671,7 @@ parse_buf(struct server *server, struct menu *parent, struct buf *buf) } xmlNode *root = xmlDocGetRootElement(d); - fill_menu_children(server, parent, root); + fill_menu_children(parent, root); xmlFreeDoc(d); xmlCleanupParser(); @@ -680,7 +679,7 @@ parse_buf(struct server *server, struct menu *parent, struct buf *buf) } static void -parse_xml(const char *filename, struct server *server) +parse_xml(const char *filename) { struct wl_list paths; paths_config_create(&paths, filename); @@ -696,7 +695,7 @@ parse_xml(const char *filename, struct server *server) continue; } wlr_log(WLR_INFO, "read menu file %s", path->string); - parse_buf(server, /*parent*/ NULL, &buf); + parse_buf(/*parent*/ NULL, &buf); buf_reset(&buf); if (!should_merge_config) { break; @@ -729,8 +728,7 @@ static void menu_reposition(struct menu *menu, struct wlr_box anchor_rect) { /* Get output usable area to place the menu within */ - struct output *output = output_nearest_to(menu->server, - anchor_rect.x, anchor_rect.y); + struct output *output = output_nearest_to(anchor_rect.x, anchor_rect.y); if (!output_is_usable(output)) { wlr_log(WLR_ERROR, "no output found around (%d,%d)", anchor_rect.x, anchor_rect.y); @@ -775,14 +773,14 @@ menu_reposition(struct menu *menu, struct wlr_box anchor_rect) } static void -menu_hide_submenu(struct server *server, const char *id) +menu_hide_submenu(const char *id) { struct menu *menu, *hide_menu; - hide_menu = menu_get_by_id(server, id); + hide_menu = menu_get_by_id(id); if (!hide_menu) { return; } - wl_list_for_each(menu, &server->menus, link) { + wl_list_for_each(menu, &g_server.menus, link) { struct menuitem *item, *next; wl_list_for_each_safe(item, next, &menu->menuitems, link) { if (item->submenu == hide_menu) { @@ -809,9 +807,9 @@ item_add_action(struct menuitem *item, const char *action_name) * SendToDesktop, left/right options are included. */ static void -update_client_send_to_menu(struct server *server) +update_client_send_to_menu(void) { - struct menu *menu = menu_get_by_id(server, "client-send-to-menu"); + struct menu *menu = menu_get_by_id("client-send-to-menu"); assert(menu); reset_menu(menu); @@ -823,8 +821,8 @@ update_client_send_to_menu(struct server *server) * GoToDesktop will be called as part of the action. */ struct buf buf = BUF_INIT; - wl_list_for_each(workspace, &server->workspaces.all, link) { - if (workspace == server->workspaces.current) { + wl_list_for_each(workspace, &g_server.workspaces.all, link) { + if (workspace == g_server.workspaces.current) { buf_add_fmt(&buf, ">%s<", workspace->name); } else { buf_add(&buf, workspace->name); @@ -856,9 +854,9 @@ update_client_send_to_menu(struct server *server) * name. Active view is indicated by "*" preceding title. */ static void -update_client_list_combined_menu(struct server *server) +update_client_list_combined_menu(void) { - struct menu *menu = menu_get_by_id(server, "client-list-combined-menu"); + struct menu *menu = menu_get_by_id("client-list-combined-menu"); assert(menu); reset_menu(menu); @@ -868,20 +866,20 @@ update_client_list_combined_menu(struct server *server) struct view *view; struct buf buffer = BUF_INIT; - wl_list_for_each(workspace, &server->workspaces.all, link) { - buf_add_fmt(&buffer, workspace == server->workspaces.current ? ">%s<" : "%s", + wl_list_for_each(workspace, &g_server.workspaces.all, link) { + buf_add_fmt(&buffer, workspace == g_server.workspaces.current ? ">%s<" : "%s", workspace->name); separator_create(menu, buffer.data); buf_clear(&buffer); - wl_list_for_each(view, &server->views, link) { + wl_list_for_each(view, &g_server.views, link) { if (view->workspace == workspace) { if (!view->foreign_toplevel || string_null_or_empty(view->title)) { continue; } - if (view == server->active_view) { + if (view == g_server.active_view) { buf_add(&buffer, "*"); } if (view->minimized) { @@ -908,14 +906,14 @@ update_client_list_combined_menu(struct server *server) } static void -init_rootmenu(struct server *server) +init_rootmenu(void) { - struct menu *menu = menu_get_by_id(server, "root-menu"); + struct menu *menu = menu_get_by_id("root-menu"); struct menuitem *item; /* Default menu if no menu.xml found */ if (!menu) { - menu = menu_create(server, NULL, "root-menu", ""); + menu = menu_create(NULL, "root-menu", ""); item = item_create(menu, _("Terminal"), NULL, false); struct action *action = item_add_action(item, "Execute"); @@ -931,14 +929,14 @@ init_rootmenu(struct server *server) } static void -init_windowmenu(struct server *server) +init_windowmenu(void) { - struct menu *menu = menu_get_by_id(server, "client-menu"); + struct menu *menu = menu_get_by_id("client-menu"); struct menuitem *item; /* Default menu if no menu.xml found */ if (!menu) { - menu = menu_create(server, NULL, "client-menu", ""); + menu = menu_create(NULL, "client-menu", ""); item = item_create(menu, _("Minimize"), NULL, false); item_add_action(item, "Iconify"); item = item_create(menu, _("Maximize"), NULL, false); @@ -954,37 +952,37 @@ init_windowmenu(struct server *server) /* Workspace sub-menu */ item = item_create(menu, _("Workspace"), NULL, true); - item->submenu = menu_get_by_id(server, "client-send-to-menu"); + item->submenu = menu_get_by_id("client-send-to-menu"); item = item_create(menu, _("Close"), NULL, false); item_add_action(item, "Close"); } if (wl_list_length(&rc.workspace_config.workspaces) == 1) { - menu_hide_submenu(server, "workspaces"); + menu_hide_submenu("workspaces"); } } void -menu_init(struct server *server) +menu_init(void) { - wl_list_init(&server->menus); + wl_list_init(&g_server.menus); /* Just create placeholder. Contents will be created when launched */ - menu_create(server, NULL, "client-list-combined-menu", _("Windows")); - menu_create(server, NULL, "client-send-to-menu", _("Workspace")); + menu_create(NULL, "client-list-combined-menu", _("Windows")); + menu_create(NULL, "client-send-to-menu", _("Workspace")); - parse_xml("menu.xml", server); - init_rootmenu(server); - init_windowmenu(server); - validate(server); + parse_xml("menu.xml"); + init_rootmenu(); + init_windowmenu(); + validate(); } static void nullify_item_pointing_to_this_menu(struct menu *menu) { struct menu *iter; - wl_list_for_each(iter, &menu->server->menus, link) { + wl_list_for_each(iter, &g_server.menus, link) { struct menuitem *item; wl_list_for_each(item, &iter->menuitems, link) { if (item->submenu == menu) { @@ -1015,8 +1013,8 @@ menu_free(struct menu *menu) /* Keep items clean on pipemenu destruction */ nullify_item_pointing_to_this_menu(menu); - if (menu->server->menu_current == menu) { - menu_close_root(menu->server); + if (g_server.menu_current == menu) { + menu_close_root(); } struct menuitem *item, *next; @@ -1045,10 +1043,10 @@ menu_free(struct menu *menu) } void -menu_finish(struct server *server) +menu_finish(void) { struct menu *menu, *tmp_menu; - wl_list_for_each_safe(menu, tmp_menu, &server->menus, link) { + wl_list_for_each_safe(menu, tmp_menu, &g_server.menus, link) { menu_free(menu); } } @@ -1056,12 +1054,10 @@ menu_finish(struct server *server) void menu_on_view_destroy(struct view *view) { - struct server *server = view->server; - /* If the view being destroy has an open window menu, then close it */ - if (server->menu_current - && server->menu_current->triggered_by_view == view) { - menu_close_root(server); + if (g_server.menu_current + && g_server.menu_current->triggered_by_view == view) { + menu_close_root(); } /* @@ -1071,7 +1067,7 @@ menu_on_view_destroy(struct view *view) */ /* Also nullify the destroyed view in client-list-combined-menu */ - struct menu *menu = menu_get_by_id(server, "client-list-combined-menu"); + struct menu *menu = menu_get_by_id("client-list-combined-menu"); if (menu) { struct menuitem *item; wl_list_for_each(item, &menu->menuitems, link) { @@ -1109,13 +1105,13 @@ menu_set_selection(struct menu *menu, struct menuitem *item) * item may be selected multiple times. */ static void -reset_pipemenus(struct server *server) +reset_pipemenus(void) { wlr_log(WLR_DEBUG, "number of menus before close=%d", - wl_list_length(&server->menus)); + wl_list_length(&g_server.menus)); struct menu *iter, *tmp; - wl_list_for_each_safe(iter, tmp, &server->menus, link) { + wl_list_for_each_safe(iter, tmp, &g_server.menus, link) { if (iter->is_pipemenu_child) { /* Destroy submenus of pipemenus */ menu_free(iter); @@ -1129,7 +1125,7 @@ reset_pipemenus(struct server *server) } wlr_log(WLR_DEBUG, "number of menus after close=%d", - wl_list_length(&server->menus)); + wl_list_length(&g_server.menus)); } static void @@ -1163,9 +1159,9 @@ static void open_menu(struct menu *menu, struct wlr_box anchor_rect) { if (!strcmp(menu->id, "client-list-combined-menu")) { - update_client_list_combined_menu(menu->server); + update_client_list_combined_menu(); } else if (!strcmp(menu->id, "client-send-to-menu")) { - update_client_send_to_menu(menu->server); + update_client_send_to_menu(); } if (!menu->scene_tree) { @@ -1183,11 +1179,11 @@ menu_open_root(struct menu *menu, int x, int y) { assert(menu); - if (menu->server->input_mode != LAB_INPUT_STATE_PASSTHROUGH) { + if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { return; } - assert(!menu->server->menu_current); + assert(!g_server.menu_current); struct wlr_box anchor_rect = {.x = x, .y = y}; if (menu->execute) { @@ -1196,21 +1192,20 @@ menu_open_root(struct menu *menu, int x, int y) open_menu(menu, anchor_rect); } - menu->server->menu_current = menu; + g_server.menu_current = menu; selected_item = NULL; - seat_focus_override_begin(&menu->server->seat, + seat_focus_override_begin(&g_server.seat, LAB_INPUT_STATE_MENU, LAB_CURSOR_DEFAULT); } static void create_pipe_menu(struct menu_pipe_context *ctx) { - struct server *server = ctx->pipemenu->server; - if (!parse_buf(server, ctx->pipemenu, &ctx->buf)) { + if (!parse_buf(ctx->pipemenu, &ctx->buf)) { return; } /* TODO: apply validate() only for generated pipemenus */ - validate(server); + validate(); /* Finally open the new submenu tree */ open_menu(ctx->pipemenu, ctx->anchor_rect); @@ -1292,8 +1287,6 @@ clean_up: static void open_pipemenu_async(struct menu *pipemenu, struct wlr_box anchor_rect) { - struct server *server = pipemenu->server; - assert(!pipemenu->pipe_ctx); assert(!pipemenu->scene_tree); @@ -1314,10 +1307,10 @@ open_pipemenu_async(struct menu *pipemenu, struct wlr_box anchor_rect) ctx->pipemenu = pipemenu; pipemenu->pipe_ctx = ctx; - ctx->event_read = wl_event_loop_add_fd(server->wl_event_loop, + ctx->event_read = wl_event_loop_add_fd(g_server.wl_event_loop, pipe_fd, WL_EVENT_READABLE, handle_pipemenu_readable, ctx); - ctx->event_timeout = wl_event_loop_add_timer(server->wl_event_loop, + ctx->event_timeout = wl_event_loop_add_timer(g_server.wl_event_loop, handle_pipemenu_timeout, ctx); wl_event_source_timer_update(ctx->event_timeout, PIPEMENU_TIMEOUT_IN_MS); @@ -1358,7 +1351,7 @@ menu_process_item_selection(struct menuitem *item) item->submenu->parent = item->parent; /* And open the new submenu tree */ struct wlr_box anchor_rect = - get_item_anchor_rect(item->submenu->server->theme, item); + get_item_anchor_rect(g_server.theme, item); if (item->submenu->execute && !item->submenu->scene_tree) { open_pipemenu_async(item->submenu, anchor_rect); } else { @@ -1371,9 +1364,9 @@ menu_process_item_selection(struct menuitem *item) /* Get the deepest submenu with active item selection or the root menu itself */ static struct menu * -get_selection_leaf(struct server *server) +get_selection_leaf(void) { - struct menu *menu = server->menu_current; + struct menu *menu = g_server.menu_current; if (!menu) { return NULL; } @@ -1390,9 +1383,9 @@ get_selection_leaf(struct server *server) /* Selects the next or previous sibling of the currently selected item */ static void -menu_item_select(struct server *server, bool forward) +menu_item_select(bool forward) { - struct menu *menu = get_selection_leaf(server); + struct menu *menu = get_selection_leaf(); if (!menu) { return; } @@ -1427,10 +1420,9 @@ menu_execute_item(struct menuitem *item) return false; } - struct server *server = item->parent->server; - menu_close(server->menu_current); - server->menu_current = NULL; - seat_focus_override_end(&server->seat, /*restore_focus*/ true); + menu_close(g_server.menu_current); + g_server.menu_current = NULL; + seat_focus_override_end(&g_server.seat, /*restore_focus*/ true); /* * We call the actions after closing the menu so that virtual keyboard @@ -1446,33 +1438,32 @@ menu_execute_item(struct menuitem *item) if (item->client_list_view->shaded) { view_set_shade(item->client_list_view, false); } - actions_run(item->client_list_view, server, &item->actions, NULL); + actions_run(item->client_list_view, &item->actions, NULL); } else { - actions_run(item->parent->triggered_by_view, server, - &item->actions, NULL); + actions_run(item->parent->triggered_by_view, &item->actions, NULL); } - reset_pipemenus(server); + reset_pipemenus(); return true; } /* Keyboard based selection */ void -menu_item_select_next(struct server *server) +menu_item_select_next(void) { - menu_item_select(server, /* forward */ true); + menu_item_select(/* forward */ true); } void -menu_item_select_previous(struct server *server) +menu_item_select_previous(void) { - menu_item_select(server, /* forward */ false); + menu_item_select(/* forward */ false); } bool -menu_call_selected_actions(struct server *server) +menu_call_selected_actions(void) { - struct menu *menu = get_selection_leaf(server); + struct menu *menu = get_selection_leaf(); if (!menu || !menu->selection.item) { return false; } @@ -1482,9 +1473,9 @@ menu_call_selected_actions(struct server *server) /* Selects the first item on the submenu attached to the current selection */ void -menu_submenu_enter(struct server *server) +menu_submenu_enter(void) { - struct menu *menu = get_selection_leaf(server); + struct menu *menu = get_selection_leaf(); if (!menu || !menu->selection.menu) { return; } @@ -1505,9 +1496,9 @@ menu_submenu_enter(struct server *server) /* Re-selects the selected item on the parent menu of the current selection */ void -menu_submenu_leave(struct server *server) +menu_submenu_leave(void) { - struct menu *menu = get_selection_leaf(server); + struct menu *menu = get_selection_leaf(); if (!menu || !menu->parent || !menu->parent->selection.item) { return; } @@ -1525,21 +1516,21 @@ menu_process_cursor_motion(struct wlr_scene_node *node) } void -menu_close_root(struct server *server) +menu_close_root(void) { - assert(server->input_mode == LAB_INPUT_STATE_MENU); - assert(server->menu_current); + assert(g_server.input_mode == LAB_INPUT_STATE_MENU); + assert(g_server.menu_current); - menu_close(server->menu_current); - server->menu_current = NULL; - reset_pipemenus(server); - seat_focus_override_end(&server->seat, /*restore_focus*/ true); + menu_close(g_server.menu_current); + g_server.menu_current = NULL; + reset_pipemenus(); + seat_focus_override_end(&g_server.seat, /*restore_focus*/ true); } void -menu_reconfigure(struct server *server) +menu_reconfigure(void) { - menu_finish(server); - server->menu_current = NULL; - menu_init(server); + menu_finish(); + g_server.menu_current = NULL; + menu_init(); } diff --git a/src/output-virtual.c b/src/output-virtual.c index f3a40e10..1bc45bf6 100644 --- a/src/output-virtual.c +++ b/src/output-virtual.c @@ -12,13 +12,13 @@ static struct wlr_output *fallback_output = NULL; void -output_virtual_add(struct server *server, const char *output_name, +output_virtual_add(const char *output_name, struct wlr_output **store_wlr_output) { if (output_name) { /* Prevent creating outputs with the same name */ struct output *output; - wl_list_for_each(output, &server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { if (wlr_output_is_headless(output->wlr_output) && !strcmp(output->wlr_output->name, output_name)) { wlr_log(WLR_DEBUG, @@ -46,13 +46,13 @@ output_virtual_add(struct server *server, const char *output_name, * we may end up calling the new output handler twice, one time manually * and one time by the headless backend when it starts up and sends the * signal for all its configured outputs. Rather than keeping a global - * server->headless.started state around that we could check here we just + * g_server.headless.started state around that we could check here we just * ignore duplicated new output calls in handle_new_output(). */ - wl_list_remove(&server->new_output.link); + wl_list_remove(&g_server.new_output.link); struct wlr_output *wlr_output = wlr_headless_add_output( - server->headless.backend, 1920, 1080); + g_server.headless.backend, 1920, 1080); if (!wlr_output) { wlr_log(WLR_ERROR, "Failed to create virtual output %s", @@ -69,20 +69,20 @@ output_virtual_add(struct server *server, const char *output_name, } /* Notify about the new output manually */ - if (server->new_output.notify) { - server->new_output.notify(&server->new_output, wlr_output); + if (g_server.new_output.notify) { + g_server.new_output.notify(&g_server.new_output, wlr_output); } restore_handler: /* And finally restore output notifications */ - wl_signal_add(&server->backend->events.new_output, &server->new_output); + wl_signal_add(&g_server.backend->events.new_output, &g_server.new_output); } void -output_virtual_remove(struct server *server, const char *output_name) +output_virtual_remove(const char *output_name) { struct output *output; - wl_list_for_each(output, &server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { if (!wlr_output_is_headless(output->wlr_output) || output->wlr_output == fallback_output) { continue; @@ -109,16 +109,16 @@ output_virtual_remove(struct server *server, const char *output_name) } void -output_virtual_update_fallback(struct server *server) +output_virtual_update_fallback(void) { - struct wl_list *layout_outputs = &server->output_layout->outputs; + struct wl_list *layout_outputs = &g_server.output_layout->outputs; const char *fallback_output_name = getenv("LABWC_FALLBACK_OUTPUT"); if (!fallback_output && wl_list_empty(layout_outputs) && !string_null_or_empty(fallback_output_name)) { wlr_log(WLR_DEBUG, "adding fallback output %s", fallback_output_name); - output_virtual_add(server, fallback_output_name, &fallback_output); + output_virtual_add(fallback_output_name, &fallback_output); } else if (fallback_output && (wl_list_length(layout_outputs) > 1 || string_null_or_empty(fallback_output_name))) { wlr_log(WLR_DEBUG, "destroying fallback output %s", diff --git a/src/output.c b/src/output.c index b4b40d64..0f390cd6 100644 --- a/src/output.c +++ b/src/output.c @@ -46,14 +46,12 @@ bool output_get_tearing_allowance(struct output *output) { - struct server *server = output->server; - /* never allow tearing when disabled */ if (!rc.allow_tearing) { return false; } - struct view *view = server->active_view; + struct view *view = g_server.active_view; /* tearing is only allowed for the output with the active view */ if (!view || view->output != output) { @@ -90,7 +88,6 @@ output_apply_gamma(struct output *output) assert(output); assert(output->gamma_lut_changed); - struct server *server = output->server; struct wlr_scene_output *scene_output = output->scene_output; struct wlr_output_state pending; @@ -99,7 +96,7 @@ output_apply_gamma(struct output *output) output->gamma_lut_changed = false; struct wlr_gamma_control_v1 *gamma_control = wlr_gamma_control_manager_v1_get_control( - server->gamma_control_manager_v1, + g_server.gamma_control_manager_v1, output->wlr_output); if (!wlr_gamma_control_v1_apply(gamma_control, &pending)) { @@ -129,7 +126,7 @@ handle_output_frame(struct wl_listener *listener, void *data) /* * skip painting the session when it exists but is not active. */ - if (output->server->session && !output->server->session->active) { + if (g_server.session && !g_server.session->active) { return; } @@ -160,8 +157,7 @@ static void handle_output_destroy(struct wl_listener *listener, void *data) { struct output *output = wl_container_of(listener, output, destroy); - struct server *server = output->server; - struct seat *seat = &server->seat; + struct seat *seat = &g_server.seat; regions_evacuate_output(output); regions_destroy(seat, &output->regions); if (seat->overlay.active.output == output) { @@ -185,7 +181,7 @@ handle_output_destroy(struct wl_listener *listener, void *data) } struct view *view; - wl_list_for_each(view, &server->views, link) { + wl_list_for_each(view, &g_server.views, link) { if (view->output == output) { view_on_output_destroy(view); } @@ -205,13 +201,13 @@ handle_output_destroy(struct wl_listener *listener, void *data) * windows and cannot be reconnected. Exit the compositor * when the last one is destroyed. */ - if (wl_list_empty(&server->outputs) && ( + if (wl_list_empty(&g_server.outputs) && ( wlr_output_is_wl(output->wlr_output) #if WLR_HAS_X11_BACKEND || wlr_output_is_x11(output->wlr_output) #endif )) { - wl_display_terminate(server->wl_display); + wl_display_terminate(g_server.wl_display); } /* @@ -260,14 +256,14 @@ handle_output_request_state(struct wl_listener *listener, void *data) } } -static void do_output_layout_change(struct server *server); +static void do_output_layout_change(void); static void -add_output_to_layout(struct server *server, struct output *output) +add_output_to_layout(struct output *output) { struct wlr_output *wlr_output = output->wlr_output; struct wlr_output_layout_output *layout_output = - wlr_output_layout_add_auto(server->output_layout, wlr_output); + wlr_output_layout_add_auto(g_server.output_layout, wlr_output); if (!layout_output) { wlr_log(WLR_ERROR, "unable to add output to layout"); return; @@ -275,7 +271,7 @@ add_output_to_layout(struct server *server, struct output *output) if (!output->scene_output) { output->scene_output = - wlr_scene_output_create(server->scene, wlr_output); + wlr_scene_output_create(g_server.scene, wlr_output); if (!output->scene_output) { wlr_log(WLR_ERROR, "unable to create scene output"); return; @@ -285,21 +281,21 @@ add_output_to_layout(struct server *server, struct output *output) * safe to call twice, so we call it only when initially * creating the scene_output. */ - wlr_scene_output_layout_add_output(server->scene_layout, + wlr_scene_output_layout_add_output(g_server.scene_layout, layout_output, output->scene_output); } lab_cosmic_workspace_group_output_enter( - server->workspaces.cosmic_group, output->wlr_output); + g_server.workspaces.cosmic_group, output->wlr_output); lab_ext_workspace_group_output_enter( - server->workspaces.ext_group, output->wlr_output); + g_server.workspaces.ext_group, output->wlr_output); /* (Re-)create regions from config */ regions_reconfigure_output(output); /* Create lock surface if needed */ - if (server->session_lock_manager->locked) { - session_lock_output_create(server->session_lock_manager, output); + if (g_server.session_lock_manager->locked) { + session_lock_output_create(g_server.session_lock_manager, output); } } @@ -388,7 +384,7 @@ output_test_auto(struct wlr_output *wlr_output, struct wlr_output_state *state, } static void -configure_new_output(struct server *server, struct output *output) +configure_new_output(struct output *output) { struct wlr_output *wlr_output = output->wlr_output; @@ -417,17 +413,17 @@ configure_new_output(struct server *server, struct output *output) * calling do_output_layout_change(); this ensures that the * wlr_output_cursor is created for the new output. */ - server->pending_output_layout_change++; - add_output_to_layout(server, output); - server->pending_output_layout_change--; + g_server.pending_output_layout_change++; + add_output_to_layout(output); + g_server.pending_output_layout_change--; } static uint64_t -get_unused_output_id_bit(struct server *server) +get_unused_output_id_bit(void) { uint64_t used_id_bits = 0; struct output *output; - wl_list_for_each(output, &server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { used_id_bits |= output->id_bit; } @@ -435,7 +431,7 @@ get_unused_output_id_bit(struct server *server) return 0; } - uint64_t id_bit = server->next_output_id_bit; + uint64_t id_bit = g_server.next_output_id_bit; /* * __builtin_popcountll() should be supported by GCC & clang. * If it causes portability issues, just remove the assert. @@ -452,7 +448,7 @@ get_unused_output_id_bit(struct server *server) * can cycle through all 64 available bits, making re-use less * frequent (on a best-effort basis). */ - server->next_output_id_bit = (id_bit << 1) | (id_bit >> 63); + g_server.next_output_id_bit = (id_bit << 1) | (id_bit >> 63); return id_bit; } @@ -464,11 +460,10 @@ handle_new_output(struct wl_listener *listener, void *data) * This event is raised by the backend when a new output (aka display * or monitor) becomes available. */ - struct server *server = wl_container_of(listener, server, new_output); struct wlr_output *wlr_output = data; struct output *output; - wl_list_for_each(output, &server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { if (output->wlr_output == wlr_output) { /* * This is a duplicated notification. @@ -480,7 +475,7 @@ handle_new_output(struct wl_listener *listener, void *data) } } - uint64_t id_bit = get_unused_output_id_bit(server); + uint64_t id_bit = get_unused_output_id_bit(); if (!id_bit) { wlr_log(WLR_ERROR, "Cannot add more than 64 outputs"); return; @@ -508,9 +503,9 @@ handle_new_output(struct wl_listener *listener, void *data) * TODO: remove once labwc starts tracking 0.20.x and the fix has been merged. */ #if LAB_WLR_VERSION_AT_LEAST(0, 19, 1) - if (server->drm_lease_manager && wlr_output_is_drm(wlr_output)) { + if (g_server.drm_lease_manager && wlr_output_is_drm(wlr_output)) { wlr_drm_lease_v1_manager_offer_output( - server->drm_lease_manager, wlr_output); + g_server.drm_lease_manager, wlr_output); } #endif @@ -526,8 +521,8 @@ handle_new_output(struct wl_listener *listener, void *data) * Configures the output created by the backend to use our allocator * and our renderer. Must be done once, before committing the output */ - if (!wlr_output_init_render(wlr_output, server->allocator, - server->renderer)) { + if (!wlr_output_init_render(wlr_output, g_server.allocator, + g_server.renderer)) { wlr_log(WLR_ERROR, "unable to init output renderer"); return; } @@ -535,11 +530,10 @@ handle_new_output(struct wl_listener *listener, void *data) output = znew(*output); output->wlr_output = wlr_output; wlr_output->data = output; - output->server = server; output->id_bit = id_bit; output_state_init(output); - wl_list_insert(&server->outputs, &output->link); + wl_list_insert(&g_server.outputs, &output->link); output->destroy.notify = handle_output_destroy; wl_signal_add(&wlr_output->events.destroy, &output->destroy); @@ -557,11 +551,11 @@ handle_new_output(struct wl_listener *listener, void *data) */ for (size_t i = 0; i < ARRAY_SIZE(output->layer_tree); i++) { output->layer_tree[i] = - lab_wlr_scene_tree_create(&server->scene->tree); + lab_wlr_scene_tree_create(&g_server.scene->tree); } - output->layer_popup_tree = lab_wlr_scene_tree_create(&server->scene->tree); - output->cycle_osd_tree = lab_wlr_scene_tree_create(&server->scene->tree); - output->session_lock_tree = lab_wlr_scene_tree_create(&server->scene->tree); + output->layer_popup_tree = lab_wlr_scene_tree_create(&g_server.scene->tree); + output->cycle_osd_tree = lab_wlr_scene_tree_create(&g_server.scene->tree); + output->session_lock_tree = lab_wlr_scene_tree_create(&g_server.scene->tree); /* * Set the z-positions to achieve the following order (from top to @@ -579,7 +573,7 @@ handle_new_output(struct wl_listener *listener, void *data) wlr_scene_node_lower_to_bottom(&output->layer_tree[1]->node); wlr_scene_node_lower_to_bottom(&output->layer_tree[0]->node); - struct wlr_scene_node *menu_node = &server->menu_tree->node; + struct wlr_scene_node *menu_node = &g_server.menu_tree->node; wlr_scene_node_place_below(&output->layer_tree[2]->node, menu_node); wlr_scene_node_place_below(&output->layer_tree[3]->node, menu_node); wlr_scene_node_place_below(&output->layer_popup_tree->node, menu_node); @@ -594,84 +588,83 @@ handle_new_output(struct wl_listener *listener, void *data) * might need tweaking if wlroots adds other output backends. */ if (rc.auto_enable_outputs || !wlr_output_is_drm(wlr_output)) { - configure_new_output(server, output); + configure_new_output(output); } - do_output_layout_change(server); + do_output_layout_change(); } -static void output_manager_init(struct server *server); +static void output_manager_init(void); void -output_init(struct server *server) +output_init(void) { - server->gamma_control_manager_v1 = - wlr_gamma_control_manager_v1_create(server->wl_display); + g_server.gamma_control_manager_v1 = + wlr_gamma_control_manager_v1_create(g_server.wl_display); - server->new_output.notify = handle_new_output; - wl_signal_add(&server->backend->events.new_output, &server->new_output); + g_server.new_output.notify = handle_new_output; + wl_signal_add(&g_server.backend->events.new_output, &g_server.new_output); /* * Create an output layout, which is a wlroots utility for working with * an arrangement of screens in a physical layout. */ - server->output_layout = wlr_output_layout_create(server->wl_display); - if (!server->output_layout) { + g_server.output_layout = wlr_output_layout_create(g_server.wl_display); + if (!g_server.output_layout) { wlr_log(WLR_ERROR, "unable to create output layout"); exit(EXIT_FAILURE); } - server->scene_layout = wlr_scene_attach_output_layout(server->scene, - server->output_layout); - if (!server->scene_layout) { + g_server.scene_layout = wlr_scene_attach_output_layout(g_server.scene, + g_server.output_layout); + if (!g_server.scene_layout) { wlr_log(WLR_ERROR, "unable to create scene layout"); exit(EXIT_FAILURE); } /* Enable screen recording with wf-recorder */ - wlr_xdg_output_manager_v1_create(server->wl_display, - server->output_layout); + wlr_xdg_output_manager_v1_create(g_server.wl_display, + g_server.output_layout); - wl_list_init(&server->outputs); - server->next_output_id_bit = (1 << 0); + wl_list_init(&g_server.outputs); + g_server.next_output_id_bit = (1 << 0); - output_manager_init(server); + output_manager_init(); } -static void output_manager_finish(struct server *server); +static void output_manager_finish(void); void -output_finish(struct server *server) +output_finish(void) { - wl_list_remove(&server->new_output.link); - output_manager_finish(server); + wl_list_remove(&g_server.new_output.link); + output_manager_finish(); } static void -output_update_for_layout_change(struct server *server) +output_update_for_layout_change(void) { - output_update_all_usable_areas(server, /*layout_changed*/ true); - session_lock_update_for_layout_change(server); + output_update_all_usable_areas(/*layout_changed*/ true); + session_lock_update_for_layout_change(); /* * "Move" each wlr_output_cursor (in per-output coordinates) to * align with the seat cursor. Re-set the cursor image so that * the cursor isn't invisible on new outputs. */ - wlr_cursor_move(server->seat.cursor, NULL, 0, 0); - cursor_update_image(&server->seat); + wlr_cursor_move(g_server.seat.cursor, NULL, 0, 0); + cursor_update_image(&g_server.seat); } static bool -output_config_apply(struct server *server, - struct wlr_output_configuration_v1 *config) +output_config_apply(struct wlr_output_configuration_v1 *config) { bool success = true; - server->pending_output_layout_change++; + g_server.pending_output_layout_change++; struct wlr_output_configuration_head_v1 *head; wl_list_for_each(head, &config->heads, link) { struct wlr_output *o = head->state.output; - struct output *output = output_from_wlr_output(server, o); + struct output *output = output_from_wlr_output(o); struct wlr_output_state *os = &output->pending; bool output_enabled = head->state.enabled; @@ -715,31 +708,31 @@ output_config_apply(struct server *server, * been enabled but not yet been added to the layout. */ bool was_in_layout = - !!wlr_output_layout_get(server->output_layout, o); + !!wlr_output_layout_get(g_server.output_layout, o); if (output_enabled) { if (!was_in_layout) { - add_output_to_layout(server, output); + add_output_to_layout(output); } struct wlr_box pos = {0}; - wlr_output_layout_get_box(server->output_layout, o, &pos); + wlr_output_layout_get_box(g_server.output_layout, o, &pos); if (pos.x != head->state.x || pos.y != head->state.y) { /* * This overrides the automatic layout * * wlr_output_layout_add() in fact means _move() */ - wlr_output_layout_add(server->output_layout, o, + wlr_output_layout_add(g_server.output_layout, o, head->state.x, head->state.y); } } else if (was_in_layout) { regions_evacuate_output(output); lab_cosmic_workspace_group_output_leave( - server->workspaces.cosmic_group, output->wlr_output); + g_server.workspaces.cosmic_group, output->wlr_output); lab_ext_workspace_group_output_leave( - server->workspaces.ext_group, output->wlr_output); + g_server.workspaces.ext_group, output->wlr_output); /* * At time of writing, wlr_output_layout_remove() @@ -750,13 +743,13 @@ output_config_apply(struct server *server, * calling wlr_output_layout_remove(). */ wlr_scene_output_destroy(output->scene_output); - wlr_output_layout_remove(server->output_layout, o); + wlr_output_layout_remove(g_server.output_layout, o); output->scene_output = NULL; } } - server->pending_output_layout_change--; - do_output_layout_change(server); + g_server.pending_output_layout_change--; + do_output_layout_change(); return success; } @@ -835,27 +828,25 @@ handle_output_manager_test(struct wl_listener *listener, void *data) static void handle_output_manager_apply(struct wl_listener *listener, void *data) { - struct server *server = - wl_container_of(listener, server, output_manager_apply); struct wlr_output_configuration_v1 *config = data; bool config_is_good = verify_output_config_v1(config); - if (config_is_good && output_config_apply(server, config)) { + if (config_is_good && output_config_apply(config)) { wlr_output_configuration_v1_send_succeeded(config); } else { wlr_output_configuration_v1_send_failed(config); } wlr_output_configuration_v1_destroy(config); struct output *output; - wl_list_for_each(output, &server->outputs, link) { - wlr_xcursor_manager_load(server->seat.xcursor_manager, + wl_list_for_each(output, &g_server.outputs, link) { + wlr_xcursor_manager_load(g_server.seat.xcursor_manager, output->wlr_output->scale); } /* Re-set cursor image in case scale changed */ - cursor_update_focus(server); - cursor_update_image(&server->seat); + cursor_update_focus(); + cursor_update_image(&g_server.seat); } /* @@ -864,7 +855,7 @@ handle_output_manager_apply(struct wl_listener *listener, void *data) * interface */ static struct -wlr_output_configuration_v1 *create_output_config(struct server *server) +wlr_output_configuration_v1 *create_output_config(void) { struct wlr_output_configuration_v1 *config = wlr_output_configuration_v1_create(); @@ -874,7 +865,7 @@ wlr_output_configuration_v1 *create_output_config(struct server *server) } struct output *output; - wl_list_for_each(output, &server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { struct wlr_output_configuration_head_v1 *head = wlr_output_configuration_head_v1_create(config, output->wlr_output); @@ -893,35 +884,32 @@ wlr_output_configuration_v1 *create_output_config(struct server *server) } static void -do_output_layout_change(struct server *server) +do_output_layout_change(void) { - if (!server->pending_output_layout_change) { + if (!g_server.pending_output_layout_change) { struct wlr_output_configuration_v1 *config = - create_output_config(server); + create_output_config(); if (config) { wlr_output_manager_v1_set_configuration( - server->output_manager, config); + g_server.output_manager, config); } else { wlr_log(WLR_ERROR, "wlr_output_manager_v1_set_configuration()"); } - output_update_for_layout_change(server); - seat_output_layout_changed(&server->seat); + output_update_for_layout_change(); + seat_output_layout_changed(&g_server.seat); } } static void handle_output_layout_change(struct wl_listener *listener, void *data) { - struct server *server = - wl_container_of(listener, server, output_layout_change); - /* Prevents unnecessary layout recalculations */ - server->pending_output_layout_change++; - output_virtual_update_fallback(server); - server->pending_output_layout_change--; + g_server.pending_output_layout_change++; + output_virtual_update_fallback(); + g_server.pending_output_layout_change--; - do_output_layout_change(server); + do_output_layout_change(); } static void @@ -938,41 +926,41 @@ handle_gamma_control_set_gamma(struct wl_listener *listener, void *data) } static void -output_manager_init(struct server *server) +output_manager_init(void) { - server->output_manager = wlr_output_manager_v1_create(server->wl_display); + g_server.output_manager = wlr_output_manager_v1_create(g_server.wl_display); - server->output_layout_change.notify = handle_output_layout_change; - wl_signal_add(&server->output_layout->events.change, - &server->output_layout_change); + g_server.output_layout_change.notify = handle_output_layout_change; + wl_signal_add(&g_server.output_layout->events.change, + &g_server.output_layout_change); - server->output_manager_apply.notify = handle_output_manager_apply; - wl_signal_add(&server->output_manager->events.apply, - &server->output_manager_apply); + g_server.output_manager_apply.notify = handle_output_manager_apply; + wl_signal_add(&g_server.output_manager->events.apply, + &g_server.output_manager_apply); - server->output_manager_test.notify = handle_output_manager_test; - wl_signal_add(&server->output_manager->events.test, - &server->output_manager_test); + g_server.output_manager_test.notify = handle_output_manager_test; + wl_signal_add(&g_server.output_manager->events.test, + &g_server.output_manager_test); - server->gamma_control_set_gamma.notify = handle_gamma_control_set_gamma; - wl_signal_add(&server->gamma_control_manager_v1->events.set_gamma, - &server->gamma_control_set_gamma); + g_server.gamma_control_set_gamma.notify = handle_gamma_control_set_gamma; + wl_signal_add(&g_server.gamma_control_manager_v1->events.set_gamma, + &g_server.gamma_control_set_gamma); } static void -output_manager_finish(struct server *server) +output_manager_finish(void) { - wl_list_remove(&server->output_layout_change.link); - wl_list_remove(&server->output_manager_apply.link); - wl_list_remove(&server->output_manager_test.link); - wl_list_remove(&server->gamma_control_set_gamma.link); + wl_list_remove(&g_server.output_layout_change.link); + wl_list_remove(&g_server.output_manager_apply.link); + wl_list_remove(&g_server.output_manager_test.link); + wl_list_remove(&g_server.gamma_control_set_gamma.link); } struct output * -output_from_wlr_output(struct server *server, struct wlr_output *wlr_output) +output_from_wlr_output(struct wlr_output *wlr_output) { struct output *output; - wl_list_for_each(output, &server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { if (output->wlr_output == wlr_output) { return output; } @@ -981,10 +969,10 @@ output_from_wlr_output(struct server *server, struct wlr_output *wlr_output) } struct output * -output_from_name(struct server *server, const char *name) +output_from_name(const char *name) { struct output *output; - wl_list_for_each(output, &server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { if (!output_is_usable(output) || !output->wlr_output->name) { continue; } @@ -996,22 +984,21 @@ output_from_name(struct server *server, const char *name) } struct output * -output_nearest_to(struct server *server, int lx, int ly) +output_nearest_to(int lx, int ly) { double closest_x, closest_y; - wlr_output_layout_closest_point(server->output_layout, NULL, lx, ly, + wlr_output_layout_closest_point(g_server.output_layout, NULL, lx, ly, &closest_x, &closest_y); - return output_from_wlr_output(server, - wlr_output_layout_output_at(server->output_layout, + return output_from_wlr_output(wlr_output_layout_output_at(g_server.output_layout, closest_x, closest_y)); } struct output * -output_nearest_to_cursor(struct server *server) +output_nearest_to_cursor(void) { - return output_nearest_to(server, server->seat.cursor->x, - server->seat.cursor->y); + return output_nearest_to(g_server.seat.cursor->x, + g_server.seat.cursor->y); } struct output * @@ -1035,7 +1022,7 @@ output_get_adjacent(struct output *output, enum lab_edge edge, bool wrap) /* Determine any adjacent output in the appropriate direction */ struct wlr_output *new_output = NULL; struct wlr_output *current_output = output->wlr_output; - struct wlr_output_layout *layout = output->server->output_layout; + struct wlr_output_layout *layout = g_server.output_layout; /* Cast from enum lab_edge to enum wlr_direction is safe */ new_output = wlr_output_layout_adjacent_output(layout, (enum wlr_direction)edge, current_output, lx, ly); @@ -1058,7 +1045,7 @@ output_get_adjacent(struct output *output, enum lab_edge edge, bool wrap) return NULL; } - output = output_from_wlr_output(output->server, new_output); + output = output_from_wlr_output(new_output); if (!output_is_usable(output)) { wlr_log(WLR_ERROR, "invalid output in layout"); return NULL; @@ -1089,10 +1076,10 @@ update_usable_area(struct output *output) #if HAVE_XWAYLAND struct view *view; - wl_list_for_each(view, &output->server->views, link) { + wl_list_for_each(view, &g_server.views, link) { if (view->mapped && view->type == LAB_XWAYLAND_VIEW) { xwayland_adjust_usable_area(view, - output->server->output_layout, + g_server.output_layout, output->wlr_output, &output->usable_area); } } @@ -1106,19 +1093,19 @@ output_update_usable_area(struct output *output) if (update_usable_area(output)) { regions_update_geometry(output); #if HAVE_XWAYLAND - xwayland_update_workarea(output->server); + xwayland_update_workarea(); #endif - desktop_arrange_all_views(output->server); + desktop_arrange_all_views(); } } void -output_update_all_usable_areas(struct server *server, bool layout_changed) +output_update_all_usable_areas(bool layout_changed) { bool usable_area_changed = false; struct output *output; - wl_list_for_each(output, &server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { if (update_usable_area(output)) { usable_area_changed = true; regions_update_geometry(output); @@ -1128,9 +1115,9 @@ output_update_all_usable_areas(struct server *server, bool layout_changed) } if (usable_area_changed || layout_changed) { #if HAVE_XWAYLAND - xwayland_update_workarea(server); + xwayland_update_workarea(); #endif - desktop_arrange_all_views(server); + desktop_arrange_all_views(); } } @@ -1142,7 +1129,7 @@ output_usable_area_in_layout_coords(struct output *output) } struct wlr_box box = output->usable_area; double ox = 0, oy = 0; - wlr_output_layout_output_coords(output->server->output_layout, + wlr_output_layout_output_coords(g_server.output_layout, output->wlr_output, &ox, &oy); box.x -= ox; box.y -= oy; @@ -1152,8 +1139,6 @@ output_usable_area_in_layout_coords(struct output *output) void handle_output_power_manager_set_mode(struct wl_listener *listener, void *data) { - struct server *server = wl_container_of(listener, server, - output_power_manager_set_mode); struct wlr_output_power_v1_set_mode_event *event = data; struct output *output = event->output->data; assert(output); @@ -1176,7 +1161,7 @@ handle_output_power_manager_set_mode(struct wl_listener *listener, void *data) * Re-set the cursor image so that the cursor * isn't invisible on the newly enabled output. */ - cursor_update_image(&server->seat); + cursor_update_image(&g_server.seat); break; } } diff --git a/src/overlay.c b/src/overlay.c index 508a531a..d37c7238 100644 --- a/src/overlay.c +++ b/src/overlay.c @@ -16,8 +16,7 @@ static void show_overlay(struct seat *seat, struct theme_snapping_overlay *overlay_theme, struct wlr_box *box) { - struct server *server = seat->server; - struct view *view = server->grabbed_view; + struct view *view = g_server.grabbed_view; assert(view); assert(!seat->overlay.rect); @@ -94,7 +93,7 @@ edge_has_adjacent_output_from_cursor(struct seat *seat, struct output *output, } /* Cast from enum lab_edge to enum wlr_direction is safe */ return wlr_output_layout_adjacent_output( - seat->server->output_layout, (enum wlr_direction)edge, + g_server.output_layout, (enum wlr_direction)edge, output->wlr_output, seat->cursor->x, seat->cursor->y); } @@ -124,7 +123,7 @@ show_edge_overlay(struct seat *seat, enum lab_edge edge1, enum lab_edge edge2, if (delay > 0) { if (!seat->overlay.timer) { seat->overlay.timer = wl_event_loop_add_timer( - seat->server->wl_event_loop, + g_server.wl_event_loop, handle_edge_overlay_timeout, seat); } /* Show overlay ms later */ @@ -138,11 +137,9 @@ show_edge_overlay(struct seat *seat, enum lab_edge edge1, enum lab_edge edge2, void overlay_update(struct seat *seat) { - struct server *server = seat->server; - /* Region-snapping overlay */ - if (regions_should_snap(server)) { - struct region *region = regions_from_cursor(server); + if (regions_should_snap()) { + struct region *region = regions_from_cursor(); if (region) { show_region_overlay(seat, region); return; diff --git a/src/placement.c b/src/placement.c index 2b5cdf61..09618ba4 100644 --- a/src/placement.c +++ b/src/placement.c @@ -46,8 +46,6 @@ count_views(struct view *view) { assert(view); - struct server *server = view->server; - struct output *output = view->output; if (!output_is_usable(output)) { return 0; @@ -56,7 +54,7 @@ count_views(struct view *view) int nviews = 0; struct view *v; - for_each_view(v, &server->views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { + for_each_view(v, &g_server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { /* Ignore the target view or anything on a different output */ if (v == view || v->output != output) { continue; @@ -105,8 +103,6 @@ build_grid(struct overlap_bitmap *bmp, struct view *view) assert(bmp); assert(view); - struct server *server = view->server; - /* Always start with a fresh bitmap */ destroy_bitmap(bmp); @@ -145,7 +141,7 @@ build_grid(struct overlap_bitmap *bmp, struct view *view) int nr_cols = 2; struct view *v; - for_each_view(v, &server->views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { + for_each_view(v, &g_server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { if (v == view || v->output != output) { continue; } @@ -236,8 +232,6 @@ build_overlap(struct overlap_bitmap *bmp, struct view *view) assert(bmp); assert(view); - struct server *server = view->server; - if (bmp->nr_rows < 1 || bmp->nr_cols < 1) { return; } @@ -248,7 +242,7 @@ build_overlap(struct overlap_bitmap *bmp, struct view *view) } struct view *v; - for_each_view(v, &server->views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { + for_each_view(v, &g_server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { if (v == view || v->output != output) { continue; } diff --git a/src/regions.c b/src/regions.c index 9dace707..d0886989 100644 --- a/src/regions.c +++ b/src/regions.c @@ -17,16 +17,16 @@ #include "view.h" bool -regions_should_snap(struct server *server) +regions_should_snap(void) { - if (server->input_mode != LAB_INPUT_STATE_MOVE + if (g_server.input_mode != LAB_INPUT_STATE_MOVE || wl_list_empty(&rc.regions) - || server->seat.region_prevent_snap - || !view_is_floating(server->grabbed_view)) { + || g_server.seat.region_prevent_snap + || !view_is_floating(g_server.grabbed_view)) { return false; } - return keyboard_get_all_modifiers(&server->seat); + return keyboard_get_all_modifiers(&g_server.seat); } struct region * @@ -44,14 +44,14 @@ regions_from_name(const char *region_name, struct output *output) } struct region * -regions_from_cursor(struct server *server) +regions_from_cursor(void) { - double lx = server->seat.cursor->x; - double ly = server->seat.cursor->y; + double lx = g_server.seat.cursor->x; + double ly = g_server.seat.cursor->y; struct wlr_output *wlr_output = wlr_output_layout_output_at( - server->output_layout, lx, ly); - struct output *output = output_from_wlr_output(server, wlr_output); + g_server.output_layout, lx, ly); + struct output *output = output_from_wlr_output(wlr_output); if (!output_is_usable(output)) { return NULL; } @@ -81,7 +81,7 @@ regions_reconfigure_output(struct output *output) /* Evacuate views and destroy current regions */ if (!wl_list_empty(&output->regions)) { regions_evacuate_output(output); - regions_destroy(&output->server->seat, &output->regions); + regions_destroy(&g_server.seat, &output->regions); } /* Initialize regions from config */ @@ -100,17 +100,17 @@ regions_reconfigure_output(struct output *output) } void -regions_reconfigure(struct server *server) +regions_reconfigure(void) { struct output *output; /* Evacuate views and initialize regions from config */ - wl_list_for_each(output, &server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { regions_reconfigure_output(output); } /* Tries to match the evacuated views to the new regions */ - desktop_arrange_all_views(server); + desktop_arrange_all_views(); } void @@ -149,7 +149,7 @@ regions_evacuate_output(struct output *output) { assert(output); struct view *view; - wl_list_for_each(view, &output->server->views, link) { + wl_list_for_each(view, &g_server.views, link) { if (view->tiled_region && view->tiled_region->output == output) { view_evacuate_region(view); } diff --git a/src/resistance.c b/src/resistance.c index 12cbec90..d5d65a5f 100644 --- a/src/resistance.c +++ b/src/resistance.c @@ -165,7 +165,7 @@ resistance_resize_apply(struct view *view, struct wlr_box *new_geom) edges_initialize(&next_edges); /* Use a constrained, effective geometry for snapping if appropriate */ - enum lab_edge resize_edges = view->server->resize_edges; + enum lab_edge resize_edges = g_server.resize_edges; struct wlr_box origin = snap_constraints_effective(view, resize_edges, /* use_pending */ false); diff --git a/src/resize-outlines.c b/src/resize-outlines.c index fdb8baa1..5e9f2622 100644 --- a/src/resize-outlines.c +++ b/src/resize-outlines.c @@ -25,9 +25,9 @@ resize_outlines_update(struct view *view, struct wlr_box new_geo) if (!outlines->rect) { struct lab_scene_rect_options opts = { .border_colors = (float *[3]) { - view->server->theme->osd_bg_color, - view->server->theme->osd_label_text_color, - view->server->theme->osd_bg_color, + g_server.theme->osd_bg_color, + g_server.theme->osd_label_text_color, + g_server.theme->osd_bg_color, }, .nr_borders = 3, .border_width = 1, diff --git a/src/scaled-buffer/scaled-icon-buffer.c b/src/scaled-buffer/scaled-icon-buffer.c index ceab0509..00e2036a 100644 --- a/src/scaled-buffer/scaled-icon-buffer.c +++ b/src/scaled-buffer/scaled-icon-buffer.c @@ -59,8 +59,7 @@ img_to_buffer(struct lab_img *img, int width, int height, double scale) static struct lab_data_buffer * load_client_icon(struct scaled_icon_buffer *self, int icon_size, double scale) { - struct lab_img *img = desktop_entry_load_icon(self->server, - self->view_icon_name, icon_size, scale); + struct lab_img *img = desktop_entry_load_icon(self->view_icon_name, icon_size, scale); if (img) { wlr_log(WLR_DEBUG, "loaded icon from client icon name"); return img_to_buffer(img, self->width, self->height, scale); @@ -83,8 +82,7 @@ load_client_icon(struct scaled_icon_buffer *self, int icon_size, double scale) static struct lab_data_buffer * load_server_icon(struct scaled_icon_buffer *self, int icon_size, double scale) { - struct lab_img *img = desktop_entry_load_icon_from_app_id(self->server, - self->view_app_id, icon_size, scale); + struct lab_img *img = desktop_entry_load_icon_from_app_id(self->view_app_id, icon_size, scale); if (img) { wlr_log(WLR_DEBUG, "loaded icon by app_id"); return img_to_buffer(img, self->width, self->height, scale); @@ -106,7 +104,7 @@ _create_buffer(struct scaled_buffer *scaled_buffer, double scale) if (self->icon_name) { /* generic icon (e.g. menu icons) */ - img = desktop_entry_load_icon(self->server, self->icon_name, + img = desktop_entry_load_icon(self->icon_name, icon_size, scale); if (img) { wlr_log(WLR_DEBUG, "loaded icon by icon name"); @@ -136,7 +134,7 @@ _create_buffer(struct scaled_buffer *scaled_buffer, double scale) } } /* If both client and server icons are unavailable, use the fallback icon */ - img = desktop_entry_load_icon(self->server, rc.fallback_app_icon_name, + img = desktop_entry_load_icon(rc.fallback_app_icon_name, icon_size, scale); if (img) { wlr_log(WLR_DEBUG, "loaded fallback icon"); @@ -215,8 +213,7 @@ static struct scaled_buffer_impl impl = { }; struct scaled_icon_buffer * -scaled_icon_buffer_create(struct wlr_scene_tree *parent, struct server *server, - int width, int height) +scaled_icon_buffer_create(struct wlr_scene_tree *parent, int width, int height) { assert(parent); assert(width >= 0 && height >= 0); @@ -226,7 +223,6 @@ scaled_icon_buffer_create(struct wlr_scene_tree *parent, struct server *server, struct scaled_icon_buffer *self = znew(*self); self->scaled_buffer = scaled_buffer; self->scene_buffer = scaled_buffer->scene_buffer; - self->server = server; self->width = width; self->height = height; diff --git a/src/seat.c b/src/seat.c index 8aa395cf..f49b9e0e 100644 --- a/src/seat.c +++ b/src/seat.c @@ -350,11 +350,11 @@ configure_libinput(struct wlr_input_device *wlr_input_device) } static struct wlr_output * -output_by_name(struct server *server, const char *name) +output_by_name(const char *name) { assert(name); struct output *output; - wl_list_for_each(output, &server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { if (!strcasecmp(output->wlr_output->name, name)) { return output->wlr_output; } @@ -367,7 +367,7 @@ map_input_to_output(struct seat *seat, struct wlr_input_device *dev, char *outpu { struct wlr_output *output = NULL; if (output_name) { - output = output_by_name(seat->server, output_name); + output = output_by_name(output_name); } wlr_cursor_map_input_to_output(seat->cursor, dev, output); wlr_cursor_map_input_to_region(seat->cursor, dev, NULL); @@ -594,7 +594,6 @@ handle_focus_change(struct wl_listener *listener, void *data) { struct seat *seat = wl_container_of(listener, seat, focus_change); struct wlr_seat_keyboard_focus_change_event *event = data; - struct server *server = seat->server; struct wlr_surface *surface = event->new_surface; struct view *view = surface ? view_from_wlr_surface(surface) : NULL; @@ -610,29 +609,28 @@ handle_focus_change(struct wl_listener *listener, void *data) * We clear the keyboard focus at the beginning of Move/Resize, window * switcher and opening menus, but don't want to deactivate the view. */ - if (server->input_mode != LAB_INPUT_STATE_PASSTHROUGH) { + if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { return; } - if (view != server->active_view) { - if (server->active_view) { - view_set_activated(server->active_view, false); + if (view != g_server.active_view) { + if (g_server.active_view) { + view_set_activated(g_server.active_view, false); } if (view) { view_set_activated(view, true); tablet_pad_enter_surface(seat, surface); } - server->active_view = view; + g_server.active_view = view; } } void -seat_init(struct server *server) +seat_init(void) { - struct seat *seat = &server->seat; - seat->server = server; + struct seat *seat = &g_server.seat; - seat->seat = wlr_seat_create(server->wl_display, "seat0"); + seat->seat = wlr_seat_create(g_server.wl_display, "seat0"); if (!seat->seat) { wlr_log(WLR_ERROR, "cannot allocate seat"); exit(EXIT_FAILURE); @@ -642,15 +640,15 @@ seat_init(struct server *server) wl_list_init(&seat->constraint_commit.link); wl_list_init(&seat->inputs); - CONNECT_SIGNAL(server->backend, seat, new_input); + CONNECT_SIGNAL(g_server.backend, seat, new_input); CONNECT_SIGNAL(&seat->seat->keyboard_state, seat, focus_change); seat->virtual_pointer = wlr_virtual_pointer_manager_v1_create( - server->wl_display); + g_server.wl_display); CONNECT_SIGNAL(seat->virtual_pointer, seat, new_virtual_pointer); seat->virtual_keyboard = wlr_virtual_keyboard_manager_v1_create( - server->wl_display); + g_server.wl_display); CONNECT_SIGNAL(seat->virtual_keyboard, seat, new_virtual_keyboard); seat->input_method_relay = input_method_relay_create(seat); @@ -662,7 +660,7 @@ seat_init(struct server *server) wlr_log(WLR_ERROR, "unable to create cursor"); exit(EXIT_FAILURE); } - wlr_cursor_attach_output_layout(seat->cursor, server->output_layout); + wlr_cursor_attach_output_layout(seat->cursor, g_server.output_layout); wl_list_init(&seat->tablets); wl_list_init(&seat->tablet_tools); @@ -672,9 +670,9 @@ seat_init(struct server *server) } void -seat_finish(struct server *server) +seat_finish(void) { - struct seat *seat = &server->seat; + struct seat *seat = &g_server.seat; wl_list_remove(&seat->new_input.link); wl_list_remove(&seat->focus_change.link); wl_list_remove(&seat->new_virtual_pointer.link); @@ -729,9 +727,9 @@ seat_pointer_end_grab(struct seat *seat, struct wlr_surface *surface) /* This is called on SIGHUP (generally in response to labwc --reconfigure */ void -seat_reconfigure(struct server *server) +seat_reconfigure(void) { - struct seat *seat = &server->seat; + struct seat *seat = &g_server.seat; struct input *input; cursor_reload(seat); overlay_finish(seat); @@ -762,7 +760,7 @@ seat_reconfigure(struct server *server) void seat_force_focus_surface(struct seat *seat, struct wlr_surface *surface) { - if (seat->server->session_lock_manager->locked) { + if (g_server.session_lock_manager->locked) { return; } uint32_t *pressed_sent_keycodes = key_state_pressed_sent_keycodes(); @@ -789,8 +787,7 @@ seat_focus(struct seat *seat, struct wlr_surface *surface, * It should also come before the !surface condition, or the * lock screen may lose focus and become impossible to unlock. */ - struct server *server = seat->server; - if (server->session_lock_manager->locked && !is_lock_surface) { + if (g_server.session_lock_manager->locked && !is_lock_surface) { return; } @@ -826,16 +823,16 @@ seat_focus(struct seat *seat, struct wlr_surface *surface, input_method_relay_set_focus(seat->input_method_relay, surface); struct wlr_pointer_constraint_v1 *constraint = - wlr_pointer_constraints_v1_constraint_for_surface(server->constraints, + wlr_pointer_constraints_v1_constraint_for_surface(g_server.constraints, surface, seat->seat); - constrain_cursor(server, constraint); + constrain_cursor(constraint); } void seat_focus_surface(struct seat *seat, struct wlr_surface *surface) { /* Don't update focus while window switcher, Move/Resize and menu interaction */ - if (seat->server->input_mode != LAB_INPUT_STATE_PASSTHROUGH) { + if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { return; } seat_focus(seat, surface, /*replace_exclusive_layer*/ false, @@ -854,7 +851,7 @@ seat_set_focus_layer(struct seat *seat, struct wlr_layer_surface_v1 *layer) { if (!layer) { seat->focused_layer = NULL; - desktop_focus_topmost_view(seat->server); + desktop_focus_topmost_view(); return; } seat_focus(seat, layer->surface, /*replace_exclusive_layer*/ true, @@ -897,9 +894,9 @@ seat_focus_override_begin(struct seat *seat, enum input_mode input_mode, enum lab_cursors cursor_shape) { assert(!seat->focus_override.surface); - assert(seat->server->input_mode == LAB_INPUT_STATE_PASSTHROUGH); + assert(g_server.input_mode == LAB_INPUT_STATE_PASSTHROUGH); - seat->server->input_mode = input_mode; + g_server.input_mode = input_mode; seat->focus_override.surface = seat->seat->keyboard_state.focused_surface; if (seat->focus_override.surface) { @@ -918,7 +915,7 @@ seat_focus_override_begin(struct seat *seat, enum input_mode input_mode, void seat_focus_override_end(struct seat *seat, bool restore_focus) { - seat->server->input_mode = LAB_INPUT_STATE_PASSTHROUGH; + g_server.input_mode = LAB_INPUT_STATE_PASSTHROUGH; if (seat->focus_override.surface) { if (restore_focus) { @@ -931,6 +928,6 @@ seat_focus_override_end(struct seat *seat, bool restore_focus) } if (restore_focus) { - cursor_update_focus(seat->server); + cursor_update_focus(); } } diff --git a/src/server.c b/src/server.c index a526f2aa..e8467ac1 100644 --- a/src/server.c +++ b/src/server.c @@ -78,7 +78,7 @@ #define LAB_WLR_PRESENTATION_TIME_VERSION 2 static void -reload_config_and_theme(struct server *server) +reload_config_and_theme(void) { /* Avoid UAF when dialog client is used during reconfigure */ action_prompts_destroy(); @@ -86,37 +86,35 @@ reload_config_and_theme(struct server *server) scaled_buffer_invalidate_sharing(); rcxml_finish(); rcxml_read(rc.config_file); - theme_finish(server->theme); - theme_init(server->theme, server, rc.theme_name); + theme_finish(g_server.theme); + theme_init(g_server.theme, rc.theme_name); #if HAVE_LIBSFDO - desktop_entry_finish(server); - desktop_entry_init(server); + desktop_entry_finish(); + desktop_entry_init(); #endif struct view *view; - wl_list_for_each(view, &server->views, link) { + wl_list_for_each(view, &g_server.views, link) { view_reload_ssd(view); } - cycle_finish(server, /*switch_focus*/ false); - menu_reconfigure(server); - seat_reconfigure(server); - regions_reconfigure(server); - resize_indicator_reconfigure(server); + cycle_finish(/*switch_focus*/ false); + menu_reconfigure(); + seat_reconfigure(); + regions_reconfigure(); + resize_indicator_reconfigure(); kde_server_decoration_update_default(); - workspaces_reconfigure(server); + workspaces_reconfigure(); } static int handle_sighup(int signal, void *data) { - struct server *server = &g_server; - - keyboard_cancel_all_keybind_repeats(&server->seat); + keyboard_cancel_all_keybind_repeats(&g_server.seat); session_environment_init(); - reload_config_and_theme(server); - output_virtual_update_fallback(server); + reload_config_and_theme(); + output_virtual_update_fallback(); return 0; } @@ -134,7 +132,6 @@ handle_sigchld(int signal, void *data) { siginfo_t info; info.si_pid = 0; - struct server *server = &g_server; /* First call waitid() with NOWAIT which doesn't consume the zombie */ if (waitid(P_ALL, /*id*/ 0, &info, WEXITED | WNOHANG | WNOWAIT) == -1) { @@ -148,8 +145,8 @@ handle_sigchld(int signal, void *data) #if HAVE_XWAYLAND /* Ensure that we do not break xwayland lazy initialization */ - if (server->xwayland && server->xwayland->server - && info.si_pid == server->xwayland->server->pid) { + if (g_server.xwayland && g_server.xwayland->server + && info.si_pid == g_server.xwayland->server->pid) { return 0; } #endif @@ -187,9 +184,9 @@ handle_sigchld(int signal, void *data) " please report", (long)info.si_pid, info.si_code); } - if (info.si_pid == server->primary_client_pid) { + if (info.si_pid == g_server.primary_client_pid) { wlr_log(WLR_INFO, "primary client %ld exited", (long)info.si_pid); - wl_display_terminate(server->wl_display); + wl_display_terminate(g_server.wl_display); } return 0; @@ -302,13 +299,12 @@ static bool server_global_filter(const struct wl_client *client, const struct wl_global *global, void *data) { const struct wl_interface *iface = wl_global_get_interface(global); - struct server *server = &g_server; /* Silence unused var compiler warnings */ (void)iface; #if HAVE_XWAYLAND - struct wl_client *xwayland_client = (server->xwayland && server->xwayland->server) - ? server->xwayland->server->client + struct wl_client *xwayland_client = (g_server.xwayland && g_server.xwayland->server) + ? g_server.xwayland->server->client : NULL; if (client != xwayland_client && !strcmp(iface->name, xwayland_shell_v1_interface.name)) { @@ -320,8 +316,8 @@ server_global_filter(const struct wl_client *client, const struct wl_global *glo /* Do not allow security_context_manager_v1 to clients with a security context attached */ const struct wlr_security_context_v1_state *security_context = wlr_security_context_manager_v1_lookup_client( - server->security_context_manager_v1, (struct wl_client *)client); - if (security_context && global == server->security_context_manager_v1->global) { + g_server.security_context_manager_v1, (struct wl_client *)client); + if (security_context && global == g_server.security_context_manager_v1->global) { return false; } else if (security_context) { /* @@ -382,41 +378,39 @@ get_headless_backend(struct wlr_backend *backend, void *data) static void handle_renderer_lost(struct wl_listener *listener, void *data) { - struct server *server = wl_container_of(listener, server, renderer_lost); - wlr_log(WLR_INFO, "Re-creating renderer after GPU reset"); - struct wlr_renderer *renderer = wlr_renderer_autocreate(server->backend); + struct wlr_renderer *renderer = wlr_renderer_autocreate(g_server.backend); if (!renderer) { wlr_log(WLR_ERROR, "Unable to create renderer"); return; } struct wlr_allocator *allocator = - wlr_allocator_autocreate(server->backend, renderer); + wlr_allocator_autocreate(g_server.backend, renderer); if (!allocator) { wlr_log(WLR_ERROR, "Unable to create allocator"); wlr_renderer_destroy(renderer); return; } - struct wlr_renderer *old_renderer = server->renderer; - struct wlr_allocator *old_allocator = server->allocator; - server->renderer = renderer; - server->allocator = allocator; + struct wlr_renderer *old_renderer = g_server.renderer; + struct wlr_allocator *old_allocator = g_server.allocator; + g_server.renderer = renderer; + g_server.allocator = allocator; - wl_list_remove(&server->renderer_lost.link); - wl_signal_add(&server->renderer->events.lost, &server->renderer_lost); + wl_list_remove(&g_server.renderer_lost.link); + wl_signal_add(&g_server.renderer->events.lost, &g_server.renderer_lost); - wlr_compositor_set_renderer(server->compositor, renderer); + wlr_compositor_set_renderer(g_server.compositor, renderer); struct output *output; - wl_list_for_each(output, &server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { wlr_output_init_render(output->wlr_output, - server->allocator, server->renderer); + g_server.allocator, g_server.renderer); } - reload_config_and_theme(server); + reload_config_and_theme(); magnifier_reset(); @@ -425,29 +419,29 @@ handle_renderer_lost(struct wl_listener *listener, void *data) } void -server_init(struct server *server) +server_init(void) { - server->primary_client_pid = -1; - server->wl_display = wl_display_create(); - if (!server->wl_display) { + g_server.primary_client_pid = -1; + g_server.wl_display = wl_display_create(); + if (!g_server.wl_display) { wlr_log(WLR_ERROR, "cannot allocate a wayland display"); exit(EXIT_FAILURE); } /* Increase max client buffer size to make slow clients less likely to terminate */ - wl_display_set_default_max_buffer_size(server->wl_display, 1024 * 1024); + wl_display_set_default_max_buffer_size(g_server.wl_display, 1024 * 1024); - wl_display_set_global_filter(server->wl_display, server_global_filter, NULL); - server->wl_event_loop = wl_display_get_event_loop(server->wl_display); + wl_display_set_global_filter(g_server.wl_display, server_global_filter, NULL); + g_server.wl_event_loop = wl_display_get_event_loop(g_server.wl_display); /* Catch signals */ - server->sighup_source = wl_event_loop_add_signal( - server->wl_event_loop, SIGHUP, handle_sighup, NULL); - server->sigint_source = wl_event_loop_add_signal( - server->wl_event_loop, SIGINT, handle_sigterm, server->wl_display); - server->sigterm_source = wl_event_loop_add_signal( - server->wl_event_loop, SIGTERM, handle_sigterm, server->wl_display); - server->sigchld_source = wl_event_loop_add_signal( - server->wl_event_loop, SIGCHLD, handle_sigchld, NULL); + g_server.sighup_source = wl_event_loop_add_signal( + g_server.wl_event_loop, SIGHUP, handle_sighup, NULL); + g_server.sigint_source = wl_event_loop_add_signal( + g_server.wl_event_loop, SIGINT, handle_sigterm, g_server.wl_display); + g_server.sigterm_source = wl_event_loop_add_signal( + g_server.wl_event_loop, SIGTERM, handle_sigterm, g_server.wl_display); + g_server.sigchld_source = wl_event_loop_add_signal( + g_server.wl_event_loop, SIGCHLD, handle_sigchld, NULL); /* * Prevent wayland clients that request the X11 clipboard but closing @@ -465,31 +459,31 @@ server_init(struct server *server) * backend based on the current environment, such as opening an x11 * window if an x11 server is running. */ - server->backend = wlr_backend_autocreate( - server->wl_event_loop, &server->session); - if (!server->backend) { + g_server.backend = wlr_backend_autocreate( + g_server.wl_event_loop, &g_server.session); + if (!g_server.backend) { wlr_log(WLR_ERROR, "unable to create backend"); fprintf(stderr, helpful_seat_error_message); exit(EXIT_FAILURE); } /* Create headless backend to enable adding virtual outputs later on */ - wlr_multi_for_each_backend(server->backend, - get_headless_backend, &server->headless.backend); + wlr_multi_for_each_backend(g_server.backend, + get_headless_backend, &g_server.headless.backend); - if (!server->headless.backend) { + if (!g_server.headless.backend) { wlr_log(WLR_DEBUG, "manually creating headless backend"); - server->headless.backend = wlr_headless_backend_create( - server->wl_event_loop); + g_server.headless.backend = wlr_headless_backend_create( + g_server.wl_event_loop); } else { wlr_log(WLR_DEBUG, "headless backend already exists"); } - if (!server->headless.backend) { + if (!g_server.headless.backend) { wlr_log(WLR_ERROR, "unable to create headless backend"); exit(EXIT_FAILURE); } - wlr_multi_backend_add(server->backend, server->headless.backend); + wlr_multi_backend_add(g_server.backend, g_server.headless.backend); /* * If we don't populate headless backend with a virtual output (that we @@ -497,7 +491,7 @@ server_init(struct server *server) * later do not work properly when overlaid on real output. Content is * drawn on the virtual output, but not drawn on the real output. */ - wlr_output_destroy(wlr_headless_add_output(server->headless.backend, 0, 0)); + wlr_output_destroy(wlr_headless_add_output(g_server.headless.backend, 0, 0)); /* * Autocreates a renderer, either Pixman, GLES2 or Vulkan for us. The @@ -505,38 +499,38 @@ server_init(struct server *server) * The renderer is responsible for defining the various pixel formats it * supports for shared memory, this configures that for clients. */ - server->renderer = wlr_renderer_autocreate(server->backend); - if (!server->renderer) { + g_server.renderer = wlr_renderer_autocreate(g_server.backend); + if (!g_server.renderer) { wlr_log(WLR_ERROR, "unable to create renderer"); exit(EXIT_FAILURE); } - server->renderer_lost.notify = handle_renderer_lost; - wl_signal_add(&server->renderer->events.lost, &server->renderer_lost); + g_server.renderer_lost.notify = handle_renderer_lost; + wl_signal_add(&g_server.renderer->events.lost, &g_server.renderer_lost); - if (!wlr_renderer_init_wl_shm(server->renderer, server->wl_display)) { + if (!wlr_renderer_init_wl_shm(g_server.renderer, g_server.wl_display)) { wlr_log(WLR_ERROR, "Failed to initialize shared memory pool"); exit(EXIT_FAILURE); } if (wlr_renderer_get_texture_formats( - server->renderer, WLR_BUFFER_CAP_DMABUF)) { - if (wlr_renderer_get_drm_fd(server->renderer) >= 0) { - wlr_drm_create(server->wl_display, server->renderer); + g_server.renderer, WLR_BUFFER_CAP_DMABUF)) { + if (wlr_renderer_get_drm_fd(g_server.renderer) >= 0) { + wlr_drm_create(g_server.wl_display, g_server.renderer); } - server->linux_dmabuf = wlr_linux_dmabuf_v1_create_with_renderer( - server->wl_display, + g_server.linux_dmabuf = wlr_linux_dmabuf_v1_create_with_renderer( + g_server.wl_display, LAB_WLR_LINUX_DMABUF_VERSION, - server->renderer); + g_server.renderer); } else { wlr_log(WLR_DEBUG, "unable to initialize dmabuf"); } - if (wlr_renderer_get_drm_fd(server->renderer) >= 0 && - server->renderer->features.timeline && - server->backend->features.timeline) { - wlr_linux_drm_syncobj_manager_v1_create(server->wl_display, 1, - wlr_renderer_get_drm_fd(server->renderer)); + if (wlr_renderer_get_drm_fd(g_server.renderer) >= 0 && + g_server.renderer->features.timeline && + g_server.backend->features.timeline) { + wlr_linux_drm_syncobj_manager_v1_create(g_server.wl_display, 1, + wlr_renderer_get_drm_fd(g_server.renderer)); } /* @@ -544,22 +538,22 @@ server_init(struct server *server) * the renderer and the backend. It handles the buffer creation, * allowing wlroots to render onto the screen */ - server->allocator = wlr_allocator_autocreate( - server->backend, server->renderer); - if (!server->allocator) { + g_server.allocator = wlr_allocator_autocreate( + g_server.backend, g_server.renderer); + if (!g_server.allocator) { wlr_log(WLR_ERROR, "unable to create allocator"); exit(EXIT_FAILURE); } - wl_list_init(&server->views); - wl_list_init(&server->unmanaged_surfaces); - wl_list_init(&server->cycle.views); - wl_list_init(&server->cycle.osd_outputs); + wl_list_init(&g_server.views); + wl_list_init(&g_server.unmanaged_surfaces); + wl_list_init(&g_server.cycle.views); + wl_list_init(&g_server.cycle.osd_outputs); - server->scene = wlr_scene_create(); - die_if_null(server->scene); + g_server.scene = wlr_scene_create(); + die_if_null(g_server.scene); - server->direct_scanout_enabled = server->scene->WLR_PRIVATE.direct_scanout; + g_server.direct_scanout_enabled = g_server.scene->WLR_PRIVATE.direct_scanout; /* * The order in which the scene-trees below are created determines the @@ -570,14 +564,14 @@ server_init(struct server *server) * | ---------------------------------- | ------------------------------------- * | output->session_lock_tree | session lock surfaces (e.g. swaylock) * | output->cycle_osd_tree | window switcher's on-screen display - * | server->cycle_preview_tree | window switcher's previewed window - * | server->menu_tree | labwc's server-side menus + * | g_server.cycle_preview_tree | window switcher's previewed window + * | g_server.menu_tree | labwc's server-side menus * | output->layer_popup_tree | xdg popups on layer surfaces * | output->layer_tree[3] | overlay layer surfaces (e.g. rofi) * | output->layer_tree[2] | top layer surfaces (e.g. waybar) - * | server->unmanaged_tree | unmanaged X11 surfaces (e.g. dmenu) - * | server->xdg_popup_tree | xdg popups on xdg windows - * | server->workspace_tree | + * | g_server.unmanaged_tree | unmanaged X11 surfaces (e.g. dmenu) + * | g_server.xdg_popup_tree | xdg popups on xdg windows + * | g_server.workspace_tree | * | + workspace->tree | * | + workspace->view_trees[1] | always-on-top xdg/X11 windows * | + workspace->view_trees[0] | normal xdg/X11 windows (e.g. firefox) @@ -586,17 +580,17 @@ server_init(struct server *server) * | output->layer_tree[0] | background layer surfaces (e.g. swaybg) */ - server->workspace_tree = lab_wlr_scene_tree_create(&server->scene->tree); - server->xdg_popup_tree = lab_wlr_scene_tree_create(&server->scene->tree); + g_server.workspace_tree = lab_wlr_scene_tree_create(&g_server.scene->tree); + g_server.xdg_popup_tree = lab_wlr_scene_tree_create(&g_server.scene->tree); #if HAVE_XWAYLAND - server->unmanaged_tree = lab_wlr_scene_tree_create(&server->scene->tree); + g_server.unmanaged_tree = lab_wlr_scene_tree_create(&g_server.scene->tree); #endif - server->menu_tree = lab_wlr_scene_tree_create(&server->scene->tree); - server->cycle_preview_tree = lab_wlr_scene_tree_create(&server->scene->tree); + g_server.menu_tree = lab_wlr_scene_tree_create(&g_server.scene->tree); + g_server.cycle_preview_tree = lab_wlr_scene_tree_create(&g_server.scene->tree); - workspaces_init(server); + workspaces_init(); - output_init(server); + output_init(); /* * Create some hands-off wlroots interfaces. The compositor is @@ -605,16 +599,16 @@ server_init(struct server *server) * room for you to dig your fingers in and play with their behavior if * you want. */ - server->compositor = wlr_compositor_create(server->wl_display, - LAB_WLR_COMPOSITOR_VERSION, server->renderer); - if (!server->compositor) { + g_server.compositor = wlr_compositor_create(g_server.wl_display, + LAB_WLR_COMPOSITOR_VERSION, g_server.renderer); + if (!g_server.compositor) { wlr_log(WLR_ERROR, "unable to create the wlroots compositor"); exit(EXIT_FAILURE); } - wlr_subcompositor_create(server->wl_display); + wlr_subcompositor_create(g_server.wl_display); struct wlr_data_device_manager *device_manager = NULL; - device_manager = wlr_data_device_manager_create(server->wl_display); + device_manager = wlr_data_device_manager_create(g_server.wl_display); if (!device_manager) { wlr_log(WLR_ERROR, "unable to create data device manager"); exit(EXIT_FAILURE); @@ -631,111 +625,111 @@ server_init(struct server *server) * https://wayfire.org/2020/08/04/Wayfire-0-5.html */ if (rc.primary_selection) { - wlr_primary_selection_v1_device_manager_create(server->wl_display); + wlr_primary_selection_v1_device_manager_create(g_server.wl_display); } - server->input_method_manager = wlr_input_method_manager_v2_create( - server->wl_display); - server->text_input_manager = wlr_text_input_manager_v3_create( - server->wl_display); - seat_init(server); - xdg_shell_init(server); - kde_server_decoration_init(server); - xdg_server_decoration_init(server); + g_server.input_method_manager = wlr_input_method_manager_v2_create( + g_server.wl_display); + g_server.text_input_manager = wlr_text_input_manager_v3_create( + g_server.wl_display); + seat_init(); + xdg_shell_init(); + kde_server_decoration_init(); + xdg_server_decoration_init(); struct wlr_presentation *presentation = wlr_presentation_create( - server->wl_display, server->backend, + g_server.wl_display, g_server.backend, LAB_WLR_PRESENTATION_TIME_VERSION); if (!presentation) { wlr_log(WLR_ERROR, "unable to create presentation interface"); exit(EXIT_FAILURE); } - if (server->linux_dmabuf) { - wlr_scene_set_linux_dmabuf_v1(server->scene, server->linux_dmabuf); + if (g_server.linux_dmabuf) { + wlr_scene_set_linux_dmabuf_v1(g_server.scene, g_server.linux_dmabuf); } - wlr_export_dmabuf_manager_v1_create(server->wl_display); - wlr_screencopy_manager_v1_create(server->wl_display); - wlr_ext_image_copy_capture_manager_v1_create(server->wl_display, 1); - wlr_ext_output_image_capture_source_manager_v1_create(server->wl_display, 1); - wlr_data_control_manager_v1_create(server->wl_display); - wlr_ext_data_control_manager_v1_create(server->wl_display, + wlr_export_dmabuf_manager_v1_create(g_server.wl_display); + wlr_screencopy_manager_v1_create(g_server.wl_display); + wlr_ext_image_copy_capture_manager_v1_create(g_server.wl_display, 1); + wlr_ext_output_image_capture_source_manager_v1_create(g_server.wl_display, 1); + wlr_data_control_manager_v1_create(g_server.wl_display); + wlr_ext_data_control_manager_v1_create(g_server.wl_display, LAB_EXT_DATA_CONTROL_VERSION); - server->security_context_manager_v1 = - wlr_security_context_manager_v1_create(server->wl_display); - wlr_viewporter_create(server->wl_display); - wlr_single_pixel_buffer_manager_v1_create(server->wl_display); - wlr_fractional_scale_manager_v1_create(server->wl_display, + g_server.security_context_manager_v1 = + wlr_security_context_manager_v1_create(g_server.wl_display); + wlr_viewporter_create(g_server.wl_display); + wlr_single_pixel_buffer_manager_v1_create(g_server.wl_display); + wlr_fractional_scale_manager_v1_create(g_server.wl_display, LAB_WLR_FRACTIONAL_SCALE_V1_VERSION); - idle_manager_create(server->wl_display); + idle_manager_create(g_server.wl_display); - server->relative_pointer_manager = wlr_relative_pointer_manager_v1_create( - server->wl_display); - server->constraints = wlr_pointer_constraints_v1_create( - server->wl_display); + g_server.relative_pointer_manager = wlr_relative_pointer_manager_v1_create( + g_server.wl_display); + g_server.constraints = wlr_pointer_constraints_v1_create( + g_server.wl_display); - server->new_constraint.notify = create_constraint; - wl_signal_add(&server->constraints->events.new_constraint, - &server->new_constraint); + g_server.new_constraint.notify = create_constraint; + wl_signal_add(&g_server.constraints->events.new_constraint, + &g_server.new_constraint); - server->foreign_toplevel_manager = - wlr_foreign_toplevel_manager_v1_create(server->wl_display); + g_server.foreign_toplevel_manager = + wlr_foreign_toplevel_manager_v1_create(g_server.wl_display); - server->foreign_toplevel_list = + g_server.foreign_toplevel_list = wlr_ext_foreign_toplevel_list_v1_create( - server->wl_display, LAB_EXT_FOREIGN_TOPLEVEL_LIST_VERSION); + g_server.wl_display, LAB_EXT_FOREIGN_TOPLEVEL_LIST_VERSION); - wlr_alpha_modifier_v1_create(server->wl_display); + wlr_alpha_modifier_v1_create(g_server.wl_display); - session_lock_init(server); + session_lock_init(); - server->drm_lease_manager = wlr_drm_lease_v1_manager_create( - server->wl_display, server->backend); - if (server->drm_lease_manager) { - server->drm_lease_request.notify = handle_drm_lease_request; - wl_signal_add(&server->drm_lease_manager->events.request, - &server->drm_lease_request); + g_server.drm_lease_manager = wlr_drm_lease_v1_manager_create( + g_server.wl_display, g_server.backend); + if (g_server.drm_lease_manager) { + g_server.drm_lease_request.notify = handle_drm_lease_request; + wl_signal_add(&g_server.drm_lease_manager->events.request, + &g_server.drm_lease_request); } else { wlr_log(WLR_DEBUG, "Failed to create wlr_drm_lease_device_v1"); wlr_log(WLR_INFO, "VR will not be available"); } - server->output_power_manager_v1 = - wlr_output_power_manager_v1_create(server->wl_display); - server->output_power_manager_set_mode.notify = + g_server.output_power_manager_v1 = + wlr_output_power_manager_v1_create(g_server.wl_display); + g_server.output_power_manager_set_mode.notify = handle_output_power_manager_set_mode; - wl_signal_add(&server->output_power_manager_v1->events.set_mode, - &server->output_power_manager_set_mode); + wl_signal_add(&g_server.output_power_manager_v1->events.set_mode, + &g_server.output_power_manager_set_mode); - server->tearing_control = wlr_tearing_control_manager_v1_create(server->wl_display, 1); - server->tearing_new_object.notify = handle_tearing_new_object; - wl_signal_add(&server->tearing_control->events.new_object, &server->tearing_new_object); + g_server.tearing_control = wlr_tearing_control_manager_v1_create(g_server.wl_display, 1); + g_server.tearing_new_object.notify = handle_tearing_new_object; + wl_signal_add(&g_server.tearing_control->events.new_object, &g_server.tearing_new_object); - server->tablet_manager = wlr_tablet_v2_create(server->wl_display); + g_server.tablet_manager = wlr_tablet_v2_create(g_server.wl_display); - layers_init(server); + layers_init(); /* These get cleaned up automatically on display destroy */ struct wlr_xdg_foreign_registry *registry = - wlr_xdg_foreign_registry_create(server->wl_display); - wlr_xdg_foreign_v1_create(server->wl_display, registry); - wlr_xdg_foreign_v2_create(server->wl_display, registry); + wlr_xdg_foreign_registry_create(g_server.wl_display); + wlr_xdg_foreign_v1_create(g_server.wl_display, registry); + wlr_xdg_foreign_v2_create(g_server.wl_display, registry); #if HAVE_LIBSFDO - desktop_entry_init(server); + desktop_entry_init(); #endif #if HAVE_XWAYLAND - xwayland_server_init(server, server->compositor); + xwayland_server_init(g_server.compositor); #endif } void -server_start(struct server *server) +server_start(void) { /* Add a Unix socket to the Wayland display. */ - const char *socket = wl_display_add_socket_auto(server->wl_display); + const char *socket = wl_display_add_socket_auto(g_server.wl_display); if (!socket) { wlr_log_errno(WLR_ERROR, "unable to open wayland socket"); exit(EXIT_FAILURE); @@ -745,13 +739,13 @@ server_start(struct server *server) * Start the backend. This will enumerate outputs and inputs, become * the DRM master, etc */ - if (!wlr_backend_start(server->backend)) { + if (!wlr_backend_start(g_server.backend)) { wlr_log(WLR_ERROR, "unable to start the wlroots backend"); exit(EXIT_FAILURE); } /* Potentially set up the initial fallback output */ - output_virtual_update_fallback(server); + output_virtual_update_fallback(); if (setenv("WAYLAND_DISPLAY", socket, true) < 0) { wlr_log_errno(WLR_ERROR, "unable to set WAYLAND_DISPLAY"); @@ -761,43 +755,43 @@ server_start(struct server *server) } void -server_finish(struct server *server) +server_finish(void) { #if HAVE_XWAYLAND - xwayland_server_finish(server); + xwayland_server_finish(); #endif #if HAVE_LIBSFDO - desktop_entry_finish(server); + desktop_entry_finish(); #endif - wl_event_source_remove(server->sighup_source); - wl_event_source_remove(server->sigint_source); - wl_event_source_remove(server->sigterm_source); - wl_event_source_remove(server->sigchld_source); + wl_event_source_remove(g_server.sighup_source); + wl_event_source_remove(g_server.sigint_source); + wl_event_source_remove(g_server.sigterm_source); + wl_event_source_remove(g_server.sigchld_source); - wl_display_destroy_clients(server->wl_display); + wl_display_destroy_clients(g_server.wl_display); - seat_finish(server); - output_finish(server); - xdg_shell_finish(server); - layers_finish(server); - kde_server_decoration_finish(server); - xdg_server_decoration_finish(server); - wl_list_remove(&server->new_constraint.link); - wl_list_remove(&server->output_power_manager_set_mode.link); - wl_list_remove(&server->tearing_new_object.link); - if (server->drm_lease_request.notify) { - wl_list_remove(&server->drm_lease_request.link); - server->drm_lease_request.notify = NULL; + seat_finish(); + output_finish(); + xdg_shell_finish(); + layers_finish(); + kde_server_decoration_finish(); + xdg_server_decoration_finish(); + wl_list_remove(&g_server.new_constraint.link); + wl_list_remove(&g_server.output_power_manager_set_mode.link); + wl_list_remove(&g_server.tearing_new_object.link); + if (g_server.drm_lease_request.notify) { + wl_list_remove(&g_server.drm_lease_request.link); + g_server.drm_lease_request.notify = NULL; } - wlr_backend_destroy(server->backend); - wlr_allocator_destroy(server->allocator); + wlr_backend_destroy(g_server.backend); + wlr_allocator_destroy(g_server.allocator); - wl_list_remove(&server->renderer_lost.link); - wlr_renderer_destroy(server->renderer); + wl_list_remove(&g_server.renderer_lost.link); + wlr_renderer_destroy(g_server.renderer); - workspaces_destroy(server); - wlr_scene_node_destroy(&server->scene->tree.node); + workspaces_destroy(); + wlr_scene_node_destroy(&g_server.scene->tree.node); - wl_display_destroy(server->wl_display); + wl_display_destroy(g_server.wl_display); } diff --git a/src/session-lock.c b/src/session-lock.c index 3b41e400..d848dc7a 100644 --- a/src/session-lock.c +++ b/src/session-lock.c @@ -31,7 +31,7 @@ static void focus_surface(struct session_lock_manager *manager, struct wlr_surface *focused) { manager->focused = focused; - seat_focus_lock_surface(&manager->server->seat, focused); + seat_focus_lock_surface(&g_server.seat, focused); } static void @@ -59,7 +59,7 @@ static void update_focus(void *data) { struct session_lock_output *output = data; - cursor_update_focus(output->manager->server); + cursor_update_focus(); if (!output->manager->focused) { focus_surface(output->manager, output->surface->surface); } @@ -78,7 +78,7 @@ handle_surface_map(struct wl_listener *listener, void *data) * buffer has not been actually attached to the surface. */ wl_event_loop_add_idle( - output->manager->server->wl_event_loop, update_focus, output); + g_server.wl_event_loop, update_focus, output); } static void @@ -98,7 +98,7 @@ static void lock_output_reconfigure(struct session_lock_output *output) { struct wlr_box box; - wlr_output_layout_get_box(output->manager->server->output_layout, + wlr_output_layout_get_box(g_server.output_layout, output->output->wlr_output, &box); wlr_scene_rect_set_size(output->background, box.width, box.height); if (output->surface) { @@ -191,7 +191,7 @@ static void align_session_lock_tree(struct output *output) { struct wlr_box box; - wlr_output_layout_get_box(output->server->output_layout, + wlr_output_layout_get_box(g_server.output_layout, output->wlr_output, &box); wlr_scene_node_set_position(&output->session_lock_tree->node, box.x, box.y); } @@ -228,7 +228,7 @@ session_lock_output_create(struct session_lock_manager *manager, struct output * * already locked, blank immediately. */ lock_output->blank_timer = - wl_event_loop_add_timer(manager->server->wl_event_loop, + wl_event_loop_add_timer(g_server.wl_event_loop, handle_output_blank_timeout, lock_output); if (!manager->locked) { wlr_scene_node_set_enabled(&background->node, false); @@ -279,11 +279,11 @@ handle_lock_unlock(struct wl_listener *listener, void *data) if (manager->last_active_view) { desktop_focus_view(manager->last_active_view, /* raise */ false); } else { - desktop_focus_topmost_view(manager->server); + desktop_focus_topmost_view(); } manager->last_active_view = NULL; - cursor_update_focus(manager->server); + cursor_update_focus(); } /* Called when session-lock is destroyed without unlock */ @@ -323,11 +323,11 @@ handle_new_session_lock(struct wl_listener *listener, void *data) assert(wl_list_empty(&manager->lock_outputs)); /* Remember the focused view to restore it on unlock */ - manager->last_active_view = manager->server->active_view; - seat_focus_surface(&manager->server->seat, NULL); + manager->last_active_view = g_server.active_view; + seat_focus_surface(&g_server.seat, NULL); struct output *output; - wl_list_for_each(output, &manager->server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { session_lock_output_create(manager, output); } @@ -353,17 +353,16 @@ handle_manager_destroy(struct wl_listener *listener, void *data) session_lock_destroy(manager); wl_list_remove(&manager->new_lock.link); wl_list_remove(&manager->destroy.link); - manager->server->session_lock_manager = NULL; + g_server.session_lock_manager = NULL; free(manager); } void -session_lock_init(struct server *server) +session_lock_init(void) { struct session_lock_manager *manager = znew(*manager); - server->session_lock_manager = manager; - manager->server = server; - manager->wlr_manager = wlr_session_lock_manager_v1_create(server->wl_display); + g_server.session_lock_manager = manager; + manager->wlr_manager = wlr_session_lock_manager_v1_create(g_server.wl_display); wl_list_init(&manager->lock_outputs); manager->new_lock.notify = handle_new_session_lock; @@ -374,18 +373,18 @@ session_lock_init(struct server *server) } void -session_lock_update_for_layout_change(struct server *server) +session_lock_update_for_layout_change(void) { - if (!server->session_lock_manager->locked) { + if (!g_server.session_lock_manager->locked) { return; } struct output *output; - wl_list_for_each(output, &server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { align_session_lock_tree(output); } - struct session_lock_manager *manager = server->session_lock_manager; + struct session_lock_manager *manager = g_server.session_lock_manager; struct session_lock_output *lock_output; wl_list_for_each(lock_output, &manager->lock_outputs, link) { lock_output_reconfigure(lock_output); diff --git a/src/ssd/resize-indicator.c b/src/ssd/resize-indicator.c index d12bda14..0777b00f 100644 --- a/src/ssd/resize-indicator.c +++ b/src/ssd/resize-indicator.c @@ -62,7 +62,7 @@ wants_indicator(struct view *view) assert(view); if (rc.resize_indicator == LAB_RESIZE_INDICATOR_NON_PIXEL) { - if (view->server->input_mode != LAB_INPUT_STATE_RESIZE) { + if (g_server.input_mode != LAB_INPUT_STATE_RESIZE) { return false; } struct view_size_hints hints = view_get_size_hints(view); @@ -74,15 +74,15 @@ wants_indicator(struct view *view) } void -resize_indicator_reconfigure(struct server *server) +resize_indicator_reconfigure(void) { struct view *view; - wl_list_for_each(view, &server->views, link) { + wl_list_for_each(view, &g_server.views, link) { struct resize_indicator *indicator = &view->resize_indicator; if (indicator->tree) { resize_indicator_reconfigure_view(indicator); } - if (view != server->grabbed_view) { + if (view != g_server.grabbed_view) { continue; } @@ -143,7 +143,7 @@ void resize_indicator_update(struct view *view) { assert(view); - assert(view == view->server->grabbed_view); + assert(view == g_server.grabbed_view); if (!wants_indicator(view)) { return; @@ -173,21 +173,21 @@ resize_indicator_update(struct view *view) view_box.height = view_effective_height(view, /* use_pending */ false); } - if (view->server->input_mode == LAB_INPUT_STATE_RESIZE) { + if (g_server.input_mode == LAB_INPUT_STATE_RESIZE) { struct view_size_hints hints = view_get_size_hints(view); snprintf(text, sizeof(text), "%d x %d", MAX(0, view_box.width - hints.base_width) / MAX(1, hints.width_inc), MAX(0, view_box.height - hints.base_height) / MAX(1, hints.height_inc)); - } else if (view->server->input_mode == LAB_INPUT_STATE_MOVE) { + } else if (g_server.input_mode == LAB_INPUT_STATE_MOVE) { struct border margin = ssd_get_margin(view->ssd); snprintf(text, sizeof(text), "%d , %d", view_box.x - margin.left, view_box.y - margin.top); } else { wlr_log(WLR_ERROR, "Invalid input mode for indicator update %u", - view->server->input_mode); + g_server.input_mode); return; } diff --git a/src/ssd/ssd-border.c b/src/ssd/ssd-border.c index aee592a4..9157ebfc 100644 --- a/src/ssd/ssd-border.c +++ b/src/ssd/ssd-border.c @@ -17,7 +17,7 @@ ssd_border_create(struct ssd *ssd) assert(!ssd->border.tree); struct view *view = ssd->view; - struct theme *theme = view->server->theme; + struct theme *theme = g_server.theme; int width = view->current.width; int height = view_effective_height(view, /* use_pending */ false); int full_width = width + 2 * theme->border_width; @@ -90,7 +90,7 @@ ssd_border_update(struct ssd *ssd) ssd->margin = ssd_thickness(ssd->view); } - struct theme *theme = view->server->theme; + struct theme *theme = g_server.theme; int width = view->current.width; int height = view_effective_height(view, /* use_pending */ false); diff --git a/src/ssd/ssd-button.c b/src/ssd/ssd-button.c index b500126e..4a3cf16e 100644 --- a/src/ssd/ssd-button.c +++ b/src/ssd/ssd-button.c @@ -50,8 +50,7 @@ attach_ssd_button(struct wl_list *button_parts, enum lab_node_type type, if (type == LAB_NODE_BUTTON_WINDOW_ICON) { struct scaled_icon_buffer *icon_buffer = - scaled_icon_buffer_create(root, view->server, - button_width - 2 * icon_padding, button_height); + scaled_icon_buffer_create(root, button_width - 2 * icon_padding, button_height); assert(icon_buffer); struct wlr_scene_node *icon_node = &icon_buffer->scene_buffer->node; scaled_icon_buffer_set_view(icon_buffer, view); diff --git a/src/ssd/ssd-extents.c b/src/ssd/ssd-extents.c index d8122ad9..9e650825 100644 --- a/src/ssd/ssd-extents.c +++ b/src/ssd/ssd-extents.c @@ -14,7 +14,7 @@ void ssd_extents_create(struct ssd *ssd) { struct view *view = ssd->view; - struct theme *theme = view->server->theme; + struct theme *theme = g_server.theme; int border_width = MAX(0, MAX(rc.resize_minimum_area, theme->border_width)); @@ -100,7 +100,7 @@ ssd_extents_update(struct ssd *ssd) return; } - struct theme *theme = view->server->theme; + struct theme *theme = g_server.theme; int width = view->current.width; int height = view_effective_height(view, /* use_pending */ false); @@ -120,7 +120,7 @@ ssd_extents_update(struct ssd *ssd) pixman_region32_t usable; pixman_region32_init(&usable); struct output *output; - wl_list_for_each(output, &view->server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { if (!view_on_output(view, output)) { continue; } diff --git a/src/ssd/ssd-shadow.c b/src/ssd/ssd-shadow.c index 16ff278f..da864944 100644 --- a/src/ssd/ssd-shadow.c +++ b/src/ssd/ssd-shadow.c @@ -145,7 +145,7 @@ static void set_shadow_geometry(struct ssd *ssd) { struct view *view = ssd->view; - struct theme *theme = view->server->theme; + struct theme *theme = g_server.theme; int titlebar_height = ssd->titlebar.height; int width = view->current.width; int height = view_effective_height(view, false) + titlebar_height; @@ -203,7 +203,7 @@ ssd_shadow_create(struct ssd *ssd) ssd->shadow.tree = lab_wlr_scene_tree_create(ssd->tree); - struct theme *theme = ssd->view->server->theme; + struct theme *theme = g_server.theme; struct view *view = ssd->view; enum ssd_active_state active; @@ -256,7 +256,7 @@ ssd_shadow_update(struct ssd *ssd) assert(ssd->shadow.tree); struct view *view = ssd->view; - struct theme *theme = ssd->view->server->theme; + struct theme *theme = g_server.theme; bool maximized = view->maximized == VIEW_AXIS_BOTH; bool tiled_shadows = false; if (rc.shadows_on_tiled) { diff --git a/src/ssd/ssd-titlebar.c b/src/ssd/ssd-titlebar.c index 0d859260..ab9aa0db 100644 --- a/src/ssd/ssd-titlebar.c +++ b/src/ssd/ssd-titlebar.c @@ -27,7 +27,7 @@ void ssd_titlebar_create(struct ssd *ssd) { struct view *view = ssd->view; - struct theme *theme = view->server->theme; + struct theme *theme = g_server.theme; int width = view->current.width; int corner_width = ssd_get_corner_width(); @@ -58,7 +58,7 @@ ssd_titlebar_create(struct ssd *ssd) * TODO: remove once https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3990 * is solved */ - if (wlr_renderer_is_pixman(view->server->renderer)) { + if (wlr_renderer_is_pixman(g_server.renderer)) { wlr_scene_buffer_set_filter_mode( subtree->bar, WLR_SCALE_FILTER_NEAREST); } @@ -160,7 +160,7 @@ set_squared_corners(struct ssd *ssd, bool enable) struct view *view = ssd->view; int width = view->current.width; int corner_width = ssd_get_corner_width(); - struct theme *theme = view->server->theme; + struct theme *theme = g_server.theme; int x = enable ? 0 : corner_width; @@ -220,7 +220,7 @@ static void update_visible_buttons(struct ssd *ssd) { struct view *view = ssd->view; - struct theme *theme = view->server->theme; + struct theme *theme = g_server.theme; int width = MAX(view->current.width - 2 * theme->window_titlebar_padding_width, 0); int button_width = theme->window_button_width; int button_spacing = theme->window_button_spacing; @@ -273,7 +273,7 @@ ssd_titlebar_update(struct ssd *ssd) struct view *view = ssd->view; int width = view->current.width; int corner_width = ssd_get_corner_width(); - struct theme *theme = view->server->theme; + struct theme *theme = g_server.theme; bool maximized = view->maximized == VIEW_AXIS_BOTH; bool squared = ssd_should_be_squared(ssd); @@ -365,7 +365,7 @@ static void ssd_update_title_positions(struct ssd *ssd, int offset_left, int offset_right) { struct view *view = ssd->view; - struct theme *theme = view->server->theme; + struct theme *theme = g_server.theme; int width = view->current.width; int title_bg_width = width - offset_left - offset_right; @@ -413,9 +413,9 @@ static void get_title_offsets(struct ssd *ssd, int *offset_left, int *offset_right) { struct ssd_titlebar_subtree *subtree = &ssd->titlebar.subtrees[SSD_ACTIVE]; - int button_width = ssd->view->server->theme->window_button_width; - int button_spacing = ssd->view->server->theme->window_button_spacing; - int padding_width = ssd->view->server->theme->window_titlebar_padding_width; + int button_width = g_server.theme->window_button_width; + int button_spacing = g_server.theme->window_button_spacing; + int padding_width = g_server.theme->window_titlebar_padding_width; *offset_left = padding_width; *offset_right = padding_width; @@ -443,7 +443,7 @@ ssd_update_title(struct ssd *ssd) /* view->title is never NULL (instead it can be an empty string) */ assert(view->title); - struct theme *theme = view->server->theme; + struct theme *theme = g_server.theme; struct ssd_state_title *state = &ssd->state.title; bool title_unchanged = state->text && !strcmp(view->title, state->text); @@ -487,23 +487,23 @@ ssd_update_title(struct ssd *ssd) } void -ssd_update_hovered_button(struct server *server, struct wlr_scene_node *node) +ssd_update_hovered_button(struct wlr_scene_node *node) { struct ssd_button *button = NULL; if (node && node->data) { button = node_try_ssd_button_from_node(node); - if (button == server->hovered_button) { + if (button == g_server.hovered_button) { /* Cursor is still on the same button */ return; } } /* Disable old hover */ - if (server->hovered_button) { - update_button_state(server->hovered_button, LAB_BS_HOVERED, false); + if (g_server.hovered_button) { + update_button_state(g_server.hovered_button, LAB_BS_HOVERED, false); } - server->hovered_button = button; + g_server.hovered_button = button; if (button) { update_button_state(button, LAB_BS_HOVERED, true); } diff --git a/src/ssd/ssd.c b/src/ssd/ssd.c index 8e0b472c..afd7d4de 100644 --- a/src/ssd/ssd.c +++ b/src/ssd/ssd.c @@ -39,7 +39,7 @@ ssd_thickness(struct view *view) return (struct border){ 0 }; } - struct theme *theme = view->server->theme; + struct theme *theme = g_server.theme; if (view->maximized == VIEW_AXIS_BOTH) { struct border thickness = { 0 }; @@ -101,7 +101,7 @@ ssd_get_resizing_type(const struct ssd *ssd, struct wlr_cursor *cursor) if (view_titlebar_visible(view)) { /* If the titlebar is visible, consider it part of the view */ - int titlebar_height = view->server->theme->titlebar_height; + int titlebar_height = g_server.theme->titlebar_height; view_box.y -= titlebar_height; view_box.height += titlebar_height; } @@ -156,7 +156,7 @@ ssd_create(struct view *view, bool active) LAB_NODE_SSD_ROOT, view, /*data*/ NULL); wlr_scene_node_lower_to_bottom(&ssd->tree->node); - ssd->titlebar.height = view->server->theme->titlebar_height; + ssd->titlebar.height = g_server.theme->titlebar_height; ssd_shadow_create(ssd); ssd_extents_create(ssd); /* @@ -257,7 +257,7 @@ ssd_set_titlebar(struct ssd *ssd, bool enabled) return; } wlr_scene_node_set_enabled(&ssd->titlebar.tree->node, enabled); - ssd->titlebar.height = enabled ? ssd->view->server->theme->titlebar_height : 0; + ssd->titlebar.height = enabled ? g_server.theme->titlebar_height : 0; ssd_border_update(ssd); ssd_extents_update(ssd); ssd_shadow_update(ssd); @@ -273,10 +273,9 @@ ssd_destroy(struct ssd *ssd) /* Maybe reset hover view */ struct view *view = ssd->view; - struct server *server = view->server; - if (server->hovered_button && node_view_from_node( - server->hovered_button->node) == view) { - server->hovered_button = NULL; + if (g_server.hovered_button && node_view_from_node( + g_server.hovered_button->node) == view) { + g_server.hovered_button = NULL; } /* Destroy subcomponents */ diff --git a/src/tearing.c b/src/tearing.c index eaba51a0..b39e8184 100644 --- a/src/tearing.c +++ b/src/tearing.c @@ -40,12 +40,11 @@ handle_controller_destroy(struct wl_listener *listener, void *data) void handle_tearing_new_object(struct wl_listener *listener, void *data) { - struct server *server = wl_container_of(listener, server, tearing_new_object); struct wlr_tearing_control_v1 *tearing_control = data; enum wp_tearing_control_v1_presentation_hint hint = wlr_tearing_control_manager_v1_surface_hint_from_surface - (server->tearing_control, tearing_control->surface); + (g_server.tearing_control, tearing_control->surface); wlr_log(WLR_DEBUG, "New presentation hint %d received for surface %p", hint, tearing_control->surface); diff --git a/src/theme.c b/src/theme.c index eeba3050..468e1840 100644 --- a/src/theme.c +++ b/src/theme.c @@ -529,7 +529,7 @@ parse_justification(const char *str) * theme_builtin() applies a theme that is similar to vanilla GTK */ static void -theme_builtin(struct theme *theme, struct server *server) +theme_builtin(struct theme *theme) { theme->border_width = 1; theme->window_titlebar_padding_height = 0; @@ -634,7 +634,7 @@ theme_builtin(struct theme *theme, struct server *server) theme->osd_border_color[0] = FLT_MIN; theme->osd_label_text_color[0] = FLT_MIN; - if (wlr_renderer_is_pixman(server->renderer)) { + if (wlr_renderer_is_pixman(g_server.renderer)) { /* Draw only outlined overlay by default to save CPU resource */ theme->snapping_overlay_region.bg_enabled = false; theme->snapping_overlay_edge.bg_enabled = false; @@ -1815,13 +1815,13 @@ post_processing(struct theme *theme) } void -theme_init(struct theme *theme, struct server *server, const char *theme_name) +theme_init(struct theme *theme, const char *theme_name) { /* * Set some default values. This is particularly important on * reconfigure as not all themes set all options */ - theme_builtin(theme, server); + theme_builtin(theme); struct wl_list paths; diff --git a/src/view-impl-common.c b/src/view-impl-common.c index 23f37321..cff0651a 100644 --- a/src/view-impl-common.c +++ b/src/view-impl-common.c @@ -50,13 +50,12 @@ view_impl_unmap(struct view *view) * When exiting an xwayland application with multiple views * mapped, a race condition can occur: after the topmost view * is unmapped, the next view under it is offered focus, but is - * also unmapped before accepting focus (so server->active_view + * also unmapped before accepting focus (so g_server.active_view * remains NULL). To avoid being left with no active view at * all, check for that case also. */ - struct server *server = view->server; - if (view == server->active_view || !server->active_view) { - desktop_focus_topmost_view(server); + if (view == g_server.active_view || !g_server.active_view) { + desktop_focus_topmost_view(); } /* @@ -72,10 +71,9 @@ view_impl_unmap(struct view *view) static bool resizing_edge(struct view *view, enum lab_edge edge) { - struct server *server = view->server; - return server->input_mode == LAB_INPUT_STATE_RESIZE - && server->grabbed_view == view - && (server->resize_edges & edge); + return g_server.input_mode == LAB_INPUT_STATE_RESIZE + && g_server.grabbed_view == view + && (g_server.resize_edges & edge); } void diff --git a/src/view.c b/src/view.c index 57baa22d..7c6067af 100644 --- a/src/view.c +++ b/src/view.c @@ -69,7 +69,7 @@ security_context_from_view(struct view *view) if (view && view->surface && view->surface->resource) { struct wl_client *client = wl_resource_get_client(view->surface->resource); return wlr_security_context_manager_v1_lookup_client( - view->server->security_context_manager_v1, client); + g_server.security_context_manager_v1, client); } return NULL; } @@ -176,7 +176,7 @@ view_matches_query(struct view *view, struct view_query *query) return false; } - if (!query_tristate_match(query->focused, view->server->active_view == view)) { + if (!query_tristate_match(query->focused, g_server.active_view == view)) { return false; } @@ -202,7 +202,7 @@ view_matches_query(struct view *view, struct view_query *query) if (query->desktop) { const char *view_workspace = view->workspace->name; - struct workspace *current = view->server->workspaces.current; + struct workspace *current = g_server.workspaces.current; if (!strcasecmp(query->desktop, "other")) { /* "other" means the view is NOT on the current desktop */ @@ -225,7 +225,7 @@ view_matches_query(struct view *view, struct view_query *query) } if (query->monitor) { - struct output *current = output_nearest_to_cursor(view->server); + struct output *current = output_nearest_to_cursor(); if (!strcasecmp(query->monitor, "current")) { if (current != view->output) { return false; @@ -241,7 +241,7 @@ view_matches_query(struct view *view, struct view_query *query) return false; } } else { - if (output_from_name(view->server, query->monitor) + if (output_from_name(query->monitor) != view->output) { return false; } @@ -268,7 +268,7 @@ matches_criteria(struct view *view, enum lab_view_criteria criteria) return false; } if (criteria & LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { - if (view->workspace != view->server->workspaces.current) { + if (view->workspace != g_server.workspaces.current) { return false; } } @@ -338,11 +338,11 @@ view_prev(struct wl_list *head, struct view *view, enum lab_view_criteria criter } void -view_array_append(struct server *server, struct wl_array *views, +view_array_append(struct wl_array *views, enum lab_view_criteria criteria) { struct view *view; - for_each_view(view, &server->views, criteria) { + for_each_view(view, &g_server.views, criteria) { struct view **entry = wl_array_add(views, sizeof(*entry)); if (!entry) { wlr_log(WLR_ERROR, "wl_array_add(): out of memory"); @@ -446,8 +446,7 @@ view_discover_output(struct view *view, struct wlr_box *geometry) } struct output *output = - output_nearest_to(view->server, - geometry->x + geometry->width / 2, + output_nearest_to(geometry->x + geometry->width / 2, geometry->y + geometry->height / 2); if (output && output != view->output) { @@ -473,10 +472,10 @@ view_set_activated(struct view *view, bool activated) if (!activated) { /* Store configured keyboard layout per view */ view->keyboard_layout = - view->server->seat.keyboard_group->keyboard.modifiers.group; + g_server.seat.keyboard_group->keyboard.modifiers.group; } else { /* Switch to previously stored keyboard layout */ - keyboard_update_layout(&view->server->seat, view->keyboard_layout); + keyboard_update_layout(&g_server.seat, view->keyboard_layout); } } output_set_has_fullscreen_view(view->output, view->fullscreen); @@ -493,7 +492,7 @@ view_set_output(struct view *view, struct output *output) view->output = output; /* Show fullscreen views above top-layer */ if (view->fullscreen) { - desktop_update_top_layer_visibility(view->server); + desktop_update_top_layer_visibility(); } } @@ -510,10 +509,10 @@ static void view_update_outputs(struct view *view) { struct output *output; - struct wlr_output_layout *layout = view->server->output_layout; + struct wlr_output_layout *layout = g_server.output_layout; uint64_t new_outputs = 0; - wl_list_for_each(output, &view->server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { if (output_is_usable(output) && wlr_output_layout_intersects( layout, output->wlr_output, &view->current)) { new_outputs |= output->id_bit; @@ -523,7 +522,7 @@ view_update_outputs(struct view *view) if (new_outputs != view->outputs) { view->outputs = new_outputs; wl_signal_emit_mutable(&view->events.new_outputs, NULL); - desktop_update_top_layer_visibility(view->server); + desktop_update_top_layer_visibility(); } } @@ -562,8 +561,8 @@ view_moved(struct view *view) } view_update_outputs(view); ssd_update_geometry(view->ssd); - cursor_update_focus(view->server); - if (rc.resize_indicator && view->server->grabbed_view == view) { + cursor_update_focus(); + if (rc.resize_indicator && g_server.grabbed_view == view) { resize_indicator_update(view); } } @@ -628,7 +627,7 @@ view_compute_near_cursor_position(struct view *view, struct wlr_box *geom) { assert(view); - struct output *pending_output = output_nearest_to_cursor(view->server); + struct output *pending_output = output_nearest_to_cursor(); struct wlr_box usable = output_usable_area_in_layout_coords(pending_output); /* Limit usable region to account for gap */ @@ -642,7 +641,7 @@ view_compute_near_cursor_position(struct view *view, struct wlr_box *geom) } struct border margin = ssd_thickness(view); - struct seat *seat = &view->server->seat; + struct seat *seat = &g_server.seat; int total_width = geom->width + margin.left + margin.right; int total_height = geom->height + margin.top + margin.bottom; @@ -747,7 +746,7 @@ _minimize(struct view *view, bool minimized, bool *need_refocus) * - unminimizing any mapped view */ *need_refocus |= (minimized ? - (view == view->server->active_view) : view->mapped); + (view == g_server.active_view) : view->mapped); } static void @@ -784,10 +783,9 @@ void view_minimize(struct view *view, bool minimized) { assert(view); - struct server *server = view->server; bool need_refocus = false; - if (server->input_mode == LAB_INPUT_STATE_CYCLE) { + if (g_server.input_mode == LAB_INPUT_STATE_CYCLE) { wlr_log(WLR_ERROR, "not minimizing window while window switching"); return; } @@ -807,7 +805,7 @@ view_minimize(struct view *view, bool minimized) */ if (need_refocus) { if (minimized) { - desktop_focus_topmost_view(server); + desktop_focus_topmost_view(); } else { desktop_focus_view(view, /* raise */ true); } @@ -862,7 +860,7 @@ adjust_floating_geometry(struct view *view, struct wlr_box *geometry, bool adjusted = false; bool onscreen = false; - if (wlr_output_layout_intersects(view->server->output_layout, + if (wlr_output_layout_intersects(g_server.output_layout, view->output->wlr_output, geometry)) { /* Always make sure the titlebar starts within the usable area */ struct border margin = ssd_get_margin(view->ssd); @@ -996,7 +994,7 @@ view_compute_cascaded_position(struct view *view, struct wlr_box *geom) /* TODO: move this logic to rcxml.c */ int offset_x = rc.placement_cascade_offset_x; int offset_y = rc.placement_cascade_offset_y; - struct theme *theme = view->server->theme; + struct theme *theme = g_server.theme; int default_offset = theme->titlebar_height + theme->border_width + 5; if (offset_x <= 0) { offset_x = default_offset; @@ -1016,7 +1014,7 @@ view_compute_cascaded_position(struct view *view, struct wlr_box *geom) /* Iterate over views from top to bottom */ struct view *other_view; - for_each_view(other_view, &view->server->views, + for_each_view(other_view, &g_server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { struct wlr_box other = ssd_max_extents(other_view); if (other_view == view @@ -1251,7 +1249,7 @@ view_apply_fullscreen_geometry(struct view *view) assert(output_is_usable(view->output)); struct wlr_box box = { 0 }; - wlr_output_layout_get_box(view->server->output_layout, + wlr_output_layout_get_box(g_server.output_layout, view->output->wlr_output, &box); view_move_resize(view, box); } @@ -1405,8 +1403,8 @@ view_set_untiled(struct view *view) static bool in_interactive_move(struct view *view) { - return (view->server->input_mode == LAB_INPUT_STATE_MOVE - && view->server->grabbed_view == view); + return (g_server.input_mode == LAB_INPUT_STATE_MOVE + && g_server.grabbed_view == view); } void @@ -1600,7 +1598,7 @@ decorate(struct view *view) { if (!view->ssd) { view->ssd = ssd_create(view, - view == view->server->active_view); + view == g_server.active_view); } } @@ -1685,7 +1683,7 @@ set_fullscreen(struct view *view, bool fullscreen) /* Show fullscreen views above top-layer */ if (view->output) { - desktop_update_top_layer_visibility(view->server); + desktop_update_top_layer_visibility(); } } @@ -1722,7 +1720,7 @@ view_set_fullscreen(struct view *view, bool fullscreen) * scene node ending up under the cursor even if view_moved() * isn't called. Update cursor focus explicitly for that case. */ - cursor_update_focus(view->server); + cursor_update_focus(); } void @@ -1766,8 +1764,7 @@ view_adjust_for_layout_change(struct view *view) view->adjusting_for_layout_change = true; struct wlr_box new_geo; - struct output *output = output_from_name(view->server, - view->last_placement.output_name); + struct output *output = output_from_name(view->last_placement.output_name); if (output_is_usable(output)) { /* * When the previous output (which might have been reconnected @@ -2169,7 +2166,7 @@ static void move_to_front(struct view *view) { wl_list_remove(&view->link); - wl_list_insert(&view->server->views, &view->link); + wl_list_insert(&g_server.views, &view->link); wlr_scene_node_raise_to_top(&view->scene_tree->node); } @@ -2177,7 +2174,7 @@ static void move_to_back(struct view *view) { wl_list_remove(&view->link); - wl_list_append(&view->server->views, &view->link); + wl_list_append(&g_server.views, &view->link); wlr_scene_node_lower_to_bottom(&view->scene_tree->node); } @@ -2191,15 +2188,14 @@ void view_move_to_front(struct view *view) { assert(view); - struct server *server = view->server; - assert(!wl_list_empty(&server->views)); + assert(!wl_list_empty(&g_server.views)); /* * Check whether the view is already in front, or is the root * parent of the view in front (in which case we don't want to * raise it in front of its sub-view). */ - struct view *front = wl_container_of(server->views.next, front, link); + struct view *front = wl_container_of(g_server.views.next, front, link); if (view == front || view == view_get_root(front)) { return; } @@ -2224,11 +2220,11 @@ view_move_to_front(struct view *view) * race, perform an explicit flush after restacking. */ if (view->type == LAB_XWAYLAND_VIEW) { - xwayland_flush(view->server); + xwayland_flush(); } #endif - cursor_update_focus(view->server); - desktop_update_top_layer_visibility(view->server); + cursor_update_focus(); + desktop_update_top_layer_visibility(); } void @@ -2241,8 +2237,8 @@ view_move_to_back(struct view *view) for_each_subview(root, move_to_back); move_to_back(root); - cursor_update_focus(view->server); - desktop_update_top_layer_visibility(view->server); + cursor_update_focus(); + desktop_update_top_layer_visibility(); } bool @@ -2387,7 +2383,7 @@ view_update_visibility(struct view *view) * Show top layer when a fullscreen view is hidden. * Hide it if a fullscreen view is shown (or uncovered). */ - desktop_update_top_layer_visibility(view->server); + desktop_update_top_layer_visibility(); /* * We may need to disable adaptive sync if view was fullscreen. @@ -2402,7 +2398,7 @@ view_update_visibility(struct view *view) /* Update usable area to account for XWayland "struts" (panels) */ if (view_has_strut_partial(view)) { - output_update_all_usable_areas(view->server, false); + output_update_all_usable_areas(false); } /* View might have been unmapped/minimized during move/resize */ @@ -2426,7 +2422,7 @@ view_set_shade(struct view *view, bool shaded) } /* If this window is being resized, cancel the resize when shading */ - if (shaded && view->server->input_mode == LAB_INPUT_STATE_RESIZE) { + if (shaded && g_server.input_mode == LAB_INPUT_STATE_RESIZE) { interactive_cancel(view); } @@ -2490,7 +2486,6 @@ void view_destroy(struct view *view) { assert(view); - struct server *server = view->server; wl_signal_emit_mutable(&view->events.destroy, NULL); snap_constraints_invalidate(view); @@ -2516,16 +2511,16 @@ view_destroy(struct view *view) * This check is (in theory) redundant since interactive_cancel() * is called at unmap. Leaving it here just to be sure. */ - if (server->grabbed_view == view) { + if (g_server.grabbed_view == view) { interactive_cancel(view); } - if (server->active_view == view) { - server->active_view = NULL; + if (g_server.active_view == view) { + g_server.active_view = NULL; } - if (server->session_lock_manager->last_active_view == view) { - server->session_lock_manager->last_active_view = NULL; + if (g_server.session_lock_manager->last_active_view == view) { + g_server.session_lock_manager->last_active_view = NULL; } if (view->tiled_region_evacuate) { @@ -2533,7 +2528,7 @@ view_destroy(struct view *view) } /* TODO: call this on map/unmap instead */ - cycle_reinitialize(server); + cycle_reinitialize(); undecorate(view); @@ -2565,9 +2560,9 @@ view_destroy(struct view *view) zfree(view->title); zfree(view->app_id); - /* Remove view from server->views */ + /* Remove view from g_server.views */ wl_list_remove(&view->link); free(view); - cursor_update_focus(server); + cursor_update_focus(); } diff --git a/src/window-rules.c b/src/window-rules.c index bfeacfe7..9cbcbd4e 100644 --- a/src/window-rules.c +++ b/src/window-rules.c @@ -12,7 +12,7 @@ static bool other_instances_exist(struct view *self, struct view_query *query) { - struct wl_list *views = &self->server->views; + struct wl_list *views = &g_server.views; struct view *view; wl_list_for_each(view, views, link) { @@ -53,7 +53,7 @@ window_rules_apply(struct view *view, enum window_rule_event event) continue; } if (view_matches_criteria(rule, view)) { - actions_run(view, view->server, &rule->actions, NULL); + actions_run(view, &rule->actions, NULL); } } } diff --git a/src/workspaces.c b/src/workspaces.c index e8d4d7a5..340dd372 100644 --- a/src/workspaces.c +++ b/src/workspaces.c @@ -62,9 +62,9 @@ parse_workspace_index(const char *name) } static void -_osd_update(struct server *server) +_osd_update(void) { - struct theme *theme = server->theme; + struct theme *theme = g_server.theme; /* Settings */ uint16_t margin = 10; @@ -75,7 +75,7 @@ _osd_update(struct server *server) theme->osd_workspace_switcher_boxes_height == 0; /* Dimensions */ - size_t workspace_count = wl_list_length(&server->workspaces.all); + size_t workspace_count = wl_list_length(&g_server.workspaces.all); uint16_t marker_width = workspace_count * (rect_width + padding) - padding; uint16_t width = margin * 2 + (marker_width < 200 ? 200 : marker_width); uint16_t height = margin * (hide_boxes ? 2 : 3) + rect_height + font_height(&rc.font_osd); @@ -85,7 +85,7 @@ _osd_update(struct server *server) struct workspace *workspace; struct output *output; - wl_list_for_each(output, &server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { if (!output_is_usable(output)) { continue; } @@ -115,9 +115,9 @@ _osd_update(struct server *server) uint16_t x; if (!hide_boxes) { x = (width - marker_width) / 2; - wl_list_for_each(workspace, &server->workspaces.all, link) { - bool active = workspace == server->workspaces.current; - set_cairo_color(cairo, server->theme->osd_label_text_color); + wl_list_for_each(workspace, &g_server.workspaces.all, link) { + bool active = workspace == g_server.workspaces.current; + set_cairo_color(cairo, g_server.theme->osd_label_text_color); struct wlr_fbox fbox = { .x = x, .y = margin, @@ -136,13 +136,13 @@ _osd_update(struct server *server) } /* Text */ - set_cairo_color(cairo, server->theme->osd_label_text_color); + set_cairo_color(cairo, g_server.theme->osd_label_text_color); PangoLayout *layout = pango_cairo_create_layout(cairo); pango_context_set_round_glyph_positions(pango_layout_get_context(layout), false); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); /* Center workspace indicator on the x axis */ - int req_width = font_width(&rc.font_osd, server->workspaces.current->name); + int req_width = font_width(&rc.font_osd, g_server.workspaces.current->name); req_width = MIN(req_width, width - 2 * margin); x = (width - req_width) / 2; if (!hide_boxes) { @@ -155,7 +155,7 @@ _osd_update(struct server *server) pango_layout_set_font_description(layout, desc); pango_layout_set_width(layout, req_width * PANGO_SCALE); pango_font_description_free(desc); - pango_layout_set_text(layout, server->workspaces.current->name, -1); + pango_layout_set_text(layout, g_server.workspaces.current->name, -1); pango_cairo_show_layout(cairo, layout); g_object_unref(layout); @@ -165,11 +165,11 @@ _osd_update(struct server *server) if (!output->workspace_osd) { output->workspace_osd = lab_wlr_scene_buffer_create( - &server->scene->tree, NULL); + &g_server.scene->tree, NULL); } /* Position the whole thing */ struct wlr_box output_box; - wlr_output_layout_get_box(output->server->output_layout, + wlr_output_layout_get_box(g_server.output_layout, output->wlr_output, &output_box); int lx = output_box.x + (output_box.width - width) / 2; int ly = output_box.y + (output_box.height - height) / 2; @@ -184,7 +184,7 @@ _osd_update(struct server *server) } static struct workspace * -workspace_find_by_name(struct server *server, const char *name) +workspace_find_by_name(const char *name) { struct workspace *workspace; @@ -192,7 +192,7 @@ workspace_find_by_name(struct server *server, const char *name) size_t parsed_index = parse_workspace_index(name); if (parsed_index) { size_t index = 0; - wl_list_for_each(workspace, &server->workspaces.all, link) { + wl_list_for_each(workspace, &g_server.workspaces.all, link) { if (parsed_index == ++index) { return workspace; } @@ -200,7 +200,7 @@ workspace_find_by_name(struct server *server, const char *name) } /* by name */ - wl_list_for_each(workspace, &server->workspaces.all, link) { + wl_list_for_each(workspace, &g_server.workspaces.all, link) { if (!strcmp(workspace->name, name)) { return workspace; } @@ -230,23 +230,22 @@ handle_ext_workspace_activate(struct wl_listener *listener, void *data) /* Internal API */ static void -add_workspace(struct server *server, const char *name) +add_workspace(const char *name) { struct workspace *workspace = znew(*workspace); - workspace->server = server; workspace->name = xstrdup(name); - workspace->tree = lab_wlr_scene_tree_create(server->workspace_tree); + workspace->tree = lab_wlr_scene_tree_create(g_server.workspace_tree); workspace->view_trees[VIEW_LAYER_ALWAYS_ON_BOTTOM] = lab_wlr_scene_tree_create(workspace->tree); workspace->view_trees[VIEW_LAYER_NORMAL] = lab_wlr_scene_tree_create(workspace->tree); workspace->view_trees[VIEW_LAYER_ALWAYS_ON_TOP] = lab_wlr_scene_tree_create(workspace->tree); - wl_list_append(&server->workspaces.all, &workspace->link); + wl_list_append(&g_server.workspaces.all, &workspace->link); wlr_scene_node_set_enabled(&workspace->tree->node, false); /* cosmic */ - workspace->cosmic_workspace = lab_cosmic_workspace_create(server->workspaces.cosmic_group); + workspace->cosmic_workspace = lab_cosmic_workspace_create(g_server.workspaces.cosmic_group); lab_cosmic_workspace_set_name(workspace->cosmic_workspace, name); workspace->on_cosmic.activate.notify = handle_cosmic_workspace_activate; @@ -255,8 +254,8 @@ add_workspace(struct server *server, const char *name) /* ext */ workspace->ext_workspace = lab_ext_workspace_create( - server->workspaces.ext_manager, /*id*/ NULL); - lab_ext_workspace_assign_to_group(workspace->ext_workspace, server->workspaces.ext_group); + g_server.workspaces.ext_manager, /*id*/ NULL); + lab_ext_workspace_assign_to_group(workspace->ext_workspace, g_server.workspaces.ext_group); lab_ext_workspace_set_name(workspace->ext_workspace, name); workspace->on_ext.activate.notify = handle_ext_workspace_activate; @@ -295,11 +294,11 @@ get_next(struct workspace *current, struct wl_list *workspaces, bool wrap) } static bool -workspace_has_views(struct workspace *workspace, struct server *server) +workspace_has_views(struct workspace *workspace) { struct view *view; - for_each_view(view, &server->views, LAB_VIEW_CRITERIA_NO_OMNIPRESENT) { + for_each_view(view, &g_server.views, LAB_VIEW_CRITERIA_NO_OMNIPRESENT) { if (view->workspace == workspace) { return true; } @@ -311,7 +310,6 @@ static struct workspace * get_adjacent_occupied(struct workspace *current, struct wl_list *workspaces, bool wrap, bool reverse) { - struct server *server = current->server; struct wl_list *start = ¤t->link; struct wl_list *link = reverse ? start->prev : start->next; bool has_wrapped = false; @@ -340,7 +338,7 @@ get_adjacent_occupied(struct workspace *current, struct wl_list *workspaces, } /* Check if it's occupied (and not current) */ - if (target != current && workspace_has_views(target, server)) { + if (target != current && workspace_has_views(target)) { return target; } @@ -373,56 +371,56 @@ _osd_handle_timeout(void *data) } static void -_osd_show(struct server *server) +_osd_show(void) { if (!rc.workspace_config.popuptime) { return; } - _osd_update(server); + _osd_update(); struct output *output; - wl_list_for_each(output, &server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { if (output_is_usable(output) && output->workspace_osd) { wlr_scene_node_set_enabled(&output->workspace_osd->node, true); } } - if (keyboard_get_all_modifiers(&server->seat)) { + if (keyboard_get_all_modifiers(&g_server.seat)) { /* Hidden by release of all modifiers */ - server->seat.workspace_osd_shown_by_modifier = true; + g_server.seat.workspace_osd_shown_by_modifier = true; } else { /* Hidden by timer */ - if (!server->seat.workspace_osd_timer) { - server->seat.workspace_osd_timer = wl_event_loop_add_timer( - server->wl_event_loop, _osd_handle_timeout, &server->seat); + if (!g_server.seat.workspace_osd_timer) { + g_server.seat.workspace_osd_timer = wl_event_loop_add_timer( + g_server.wl_event_loop, _osd_handle_timeout, &g_server.seat); } - wl_event_source_timer_update(server->seat.workspace_osd_timer, + wl_event_source_timer_update(g_server.seat.workspace_osd_timer, rc.workspace_config.popuptime); } } /* Public API */ void -workspaces_init(struct server *server) +workspaces_init(void) { - server->workspaces.cosmic_manager = lab_cosmic_workspace_manager_create( - server->wl_display, /* capabilities */ CW_CAP_WS_ACTIVATE, + g_server.workspaces.cosmic_manager = lab_cosmic_workspace_manager_create( + g_server.wl_display, /* capabilities */ CW_CAP_WS_ACTIVATE, COSMIC_WORKSPACES_VERSION); - server->workspaces.ext_manager = lab_ext_workspace_manager_create( - server->wl_display, /* capabilities */ WS_CAP_WS_ACTIVATE, + g_server.workspaces.ext_manager = lab_ext_workspace_manager_create( + g_server.wl_display, /* capabilities */ WS_CAP_WS_ACTIVATE, EXT_WORKSPACES_VERSION); - server->workspaces.cosmic_group = lab_cosmic_workspace_group_create( - server->workspaces.cosmic_manager); + g_server.workspaces.cosmic_group = lab_cosmic_workspace_group_create( + g_server.workspaces.cosmic_manager); - server->workspaces.ext_group = lab_ext_workspace_group_create( - server->workspaces.ext_manager); + g_server.workspaces.ext_group = lab_ext_workspace_group_create( + g_server.workspaces.ext_manager); - wl_list_init(&server->workspaces.all); + wl_list_init(&g_server.workspaces.all); struct workspace_config *conf; wl_list_for_each(conf, &rc.workspace_config.workspaces, link) { - add_workspace(server, conf->name); + add_workspace(conf->name); } /* @@ -432,16 +430,16 @@ workspaces_init(struct server *server) char *initial_name = rc.workspace_config.initial_workspace_name; struct workspace *initial = NULL; struct workspace *first = wl_container_of( - server->workspaces.all.next, first, link); + g_server.workspaces.all.next, first, link); if (initial_name) { - initial = workspace_find_by_name(server, initial_name); + initial = workspace_find_by_name(initial_name); } if (!initial) { initial = first; } - server->workspaces.current = initial; + g_server.workspaces.current = initial; wlr_scene_node_set_enabled(&initial->tree->node, true); lab_cosmic_workspace_set_active(initial->cosmic_workspace, true); lab_ext_workspace_set_active(initial->ext_workspace, true); @@ -456,19 +454,18 @@ void workspaces_switch_to(struct workspace *target, bool update_focus) { assert(target); - struct server *server = target->server; - if (target == server->workspaces.current) { + if (target == g_server.workspaces.current) { return; } /* Disable the old workspace */ wlr_scene_node_set_enabled( - &server->workspaces.current->tree->node, false); + &g_server.workspaces.current->tree->node, false); lab_cosmic_workspace_set_active( - server->workspaces.current->cosmic_workspace, false); + g_server.workspaces.current->cosmic_workspace, false); lab_ext_workspace_set_active( - server->workspaces.current->ext_workspace, false); + g_server.workspaces.current->ext_workspace, false); /* * Move Omnipresent views to new workspace. @@ -476,7 +473,7 @@ workspaces_switch_to(struct workspace *target, bool update_focus) * view_is_focusable() returns false (e.g. Conky). */ struct view *view; - wl_list_for_each_reverse(view, &server->views, link) { + wl_list_for_each_reverse(view, &g_server.views, link) { if (view->visible_on_all_workspaces) { view_move_to_workspace(view, target); } @@ -486,12 +483,12 @@ workspaces_switch_to(struct workspace *target, bool update_focus) wlr_scene_node_set_enabled(&target->tree->node, true); /* Save the last visited workspace */ - server->workspaces.last = server->workspaces.current; + g_server.workspaces.last = g_server.workspaces.current; /* Make sure new views will spawn on the new workspace */ - server->workspaces.current = target; + g_server.workspaces.current = target; - struct view *grabbed_view = server->grabbed_view; + struct view *grabbed_view = g_server.grabbed_view; if (grabbed_view) { view_move_to_workspace(grabbed_view, target); } @@ -501,23 +498,23 @@ workspaces_switch_to(struct workspace *target, bool update_focus) * the focus is not already on an omnipresent view. */ if (update_focus) { - struct view *active_view = server->active_view; + struct view *active_view = g_server.active_view; if (!(active_view && active_view->visible_on_all_workspaces)) { - desktop_focus_topmost_view(server); + desktop_focus_topmost_view(); } } /* And finally show the OSD */ - _osd_show(server); + _osd_show(); /* * Make sure we are not carrying around a * cursor image from the previous desktop */ - cursor_update_focus(server); + cursor_update_focus(); /* Ensure that only currently visible fullscreen windows hide the top layer */ - desktop_update_top_layer_visibility(server); + desktop_update_top_layer_visibility(); lab_cosmic_workspace_set_active(target->cosmic_workspace, true); lab_ext_workspace_set_active(target->ext_workspace, true); @@ -528,8 +525,7 @@ workspaces_osd_hide(struct seat *seat) { assert(seat); struct output *output; - struct server *server = seat->server; - wl_list_for_each(output, &server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { if (!output->workspace_osd) { continue; } @@ -539,7 +535,7 @@ workspaces_osd_hide(struct seat *seat) seat->workspace_osd_shown_by_modifier = false; /* Update the cursor focus in case it was on top of the OSD before */ - cursor_update_focus(server); + cursor_update_focus(); } struct workspace * @@ -549,13 +545,12 @@ workspaces_find(struct workspace *anchor, const char *name, bool wrap) if (!name) { return NULL; } - struct server *server = anchor->server; - struct wl_list *workspaces = &server->workspaces.all; + struct wl_list *workspaces = &g_server.workspaces.all; if (!strcasecmp(name, "current")) { return anchor; } else if (!strcasecmp(name, "last")) { - return server->workspaces.last; + return g_server.workspaces.last; } else if (!strcasecmp(name, "left")) { return get_prev(anchor, workspaces, wrap); } else if (!strcasecmp(name, "right")) { @@ -565,7 +560,7 @@ workspaces_find(struct workspace *anchor, const char *name, bool wrap) } else if (!strcasecmp(name, "right-occupied")) { return get_next_occupied(anchor, workspaces, wrap); } - return workspace_find_by_name(server, name); + return workspace_find_by_name(name); } static void @@ -583,7 +578,7 @@ destroy_workspace(struct workspace *workspace) } void -workspaces_reconfigure(struct server *server) +workspaces_reconfigure(void) { /* * Compare actual workspace list with the new desired configuration to: @@ -592,18 +587,18 @@ workspaces_reconfigure(struct server *server) * - Destroy workspaces if fewer workspace are desired */ - struct wl_list *workspace_link = server->workspaces.all.next; + struct wl_list *workspace_link = g_server.workspaces.all.next; struct workspace_config *conf; wl_list_for_each(conf, &rc.workspace_config.workspaces, link) { struct workspace *workspace = wl_container_of( workspace_link, workspace, link); - if (workspace_link == &server->workspaces.all) { + if (workspace_link == &g_server.workspaces.all) { /* # of configured workspaces increased */ wlr_log(WLR_DEBUG, "Adding workspace \"%s\"", conf->name); - add_workspace(server, conf->name); + add_workspace(conf->name); continue; } if (strcmp(workspace->name, conf->name)) { @@ -619,16 +614,16 @@ workspaces_reconfigure(struct server *server) workspace_link = workspace_link->next; } - if (workspace_link == &server->workspaces.all) { + if (workspace_link == &g_server.workspaces.all) { return; } /* # of configured workspaces decreased */ - overlay_finish(&server->seat); + overlay_finish(&g_server.seat); struct workspace *first_workspace = - wl_container_of(server->workspaces.all.next, first_workspace, link); + wl_container_of(g_server.workspaces.all.next, first_workspace, link); - while (workspace_link != &server->workspaces.all) { + while (workspace_link != &g_server.workspaces.all) { struct workspace *workspace = wl_container_of( workspace_link, workspace, link); @@ -636,18 +631,18 @@ workspaces_reconfigure(struct server *server) workspace->name); struct view *view; - wl_list_for_each(view, &server->views, link) { + wl_list_for_each(view, &g_server.views, link) { if (view->workspace == workspace) { view_move_to_workspace(view, first_workspace); } } - if (server->workspaces.current == workspace) { + if (g_server.workspaces.current == workspace) { workspaces_switch_to(first_workspace, /* update_focus */ true); } - if (server->workspaces.last == workspace) { - server->workspaces.last = first_workspace; + if (g_server.workspaces.last == workspace) { + g_server.workspaces.last = first_workspace; } workspace_link = workspace_link->next; @@ -656,11 +651,11 @@ workspaces_reconfigure(struct server *server) } void -workspaces_destroy(struct server *server) +workspaces_destroy(void) { struct workspace *workspace, *tmp; - wl_list_for_each_safe(workspace, tmp, &server->workspaces.all, link) { + wl_list_for_each_safe(workspace, tmp, &g_server.workspaces.all, link) { destroy_workspace(workspace); } - assert(wl_list_empty(&server->workspaces.all)); + assert(wl_list_empty(&g_server.workspaces.all)); } diff --git a/src/xdg-popup.c b/src/xdg-popup.c index d4a3b7fc..f4c623f9 100644 --- a/src/xdg-popup.c +++ b/src/xdg-popup.c @@ -30,7 +30,6 @@ static void popup_unconstrain(struct xdg_popup *popup) { struct view *view = popup->parent_view; - struct server *server = view->server; /* Get position of parent toplevel/popup */ int parent_lx, parent_ly; @@ -46,8 +45,7 @@ popup_unconstrain(struct xdg_popup *popup) * output. */ struct wlr_box *popup_box = &popup->wlr_popup->scheduled.geometry; - struct output *output = output_nearest_to(server, - parent_lx + MAX(popup_box->x, 0), + struct output *output = output_nearest_to(parent_lx + MAX(popup_box->x, 0), parent_ly + MAX(popup_box->y, 0)); struct wlr_box usable = output_usable_area_in_layout_coords(output); @@ -91,7 +89,7 @@ handle_destroy(struct wl_listener *listener, void *data) wl_list_remove(&popup->commit.link); } - cursor_update_focus(popup->parent_view->server); + cursor_update_focus(); free(popup); } @@ -151,15 +149,15 @@ xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup) * this, we always set the user data field of wlr_surfaces to the * corresponding scene node. * - * xdg-popups live in server->xdg_popup_tree so that they can be + * xdg-popups live in g_server.xdg_popup_tree so that they can be * rendered above always-on-top windows */ struct wlr_scene_tree *parent_tree = NULL; if (parent->role == WLR_XDG_SURFACE_ROLE_POPUP) { parent_tree = parent->surface->data; } else { - parent_tree = view->server->xdg_popup_tree; - wlr_scene_node_set_position(&view->server->xdg_popup_tree->node, + parent_tree = g_server.xdg_popup_tree; + wlr_scene_node_set_position(&g_server.xdg_popup_tree->node, view->current.x, view->current.y); } wlr_popup->base->surface->data = diff --git a/src/xdg.c b/src/xdg.c index 0994a962..b3da3e74 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -116,8 +116,7 @@ set_fullscreen_from_request(struct view *view, { if (!view->fullscreen && requested->fullscreen && requested->fullscreen_output) { - view_set_output(view, output_from_wlr_output(view->server, - requested->fullscreen_output)); + view_set_output(view, output_from_wlr_output(requested->fullscreen_output)); } view_set_fullscreen(view, requested->fullscreen); } @@ -132,11 +131,10 @@ set_initial_position(struct view *view) view_constrain_size_to_that_of_usable_area(view); - struct server *server = view->server; - if (server->input_mode == LAB_INPUT_STATE_MOVE - && view == server->grabbed_view) { + if (g_server.input_mode == LAB_INPUT_STATE_MOVE + && view == g_server.grabbed_view) { /* Reposition the view while anchoring it to cursor */ - interactive_anchor_to_cursor(server, &view->pending); + interactive_anchor_to_cursor(&view->pending); } else { struct view *parent = xdg_toplevel_view_get_parent(view); if (parent) { @@ -175,7 +173,7 @@ center_fullscreen_if_needed(struct view *view) } struct wlr_box output_box = {0}; - wlr_output_layout_get_box(view->server->output_layout, + wlr_output_layout_get_box(g_server.output_layout, view->output->wlr_output, &output_box); box_center(view->current.width, view->current.height, &output_box, &output_box, &view->current.x, &view->current.y); @@ -234,7 +232,7 @@ handle_commit(struct wl_listener *listener, void *data) if (parent && output_is_usable(parent->output)) { view_set_output(view, parent->output); } else { - view_set_output(view, output_nearest_to_cursor(view->server)); + view_set_output(view, output_nearest_to_cursor()); } if (output_is_usable(view->output)) { @@ -439,7 +437,7 @@ set_pending_configure_serial(struct view *view, uint32_t serial) view->pending_configure_serial = serial; if (!view->pending_configure_timeout) { view->pending_configure_timeout = - wl_event_loop_add_timer(view->server->wl_event_loop, + wl_event_loop_add_timer(g_server.wl_event_loop, handle_configure_timeout, view); } wl_event_source_timer_update(view->pending_configure_timeout, @@ -487,7 +485,7 @@ handle_request_move(struct wl_listener *listener, void *data) * this client, to prevent the client from requesting this whenever they * want. * - * Note: interactive_begin() checks that view == server->grabbed_view. + * Note: interactive_begin() checks that view == g_server.grabbed_view. */ struct view *view = wl_container_of(listener, view, request_move); interactive_begin(view, LAB_INPUT_STATE_MOVE, LAB_EDGE_NONE); @@ -504,7 +502,7 @@ handle_request_resize(struct wl_listener *listener, void *data) * this client, to prevent the client from requesting this whenever they * want. * - * Note: interactive_begin() checks that view == server->grabbed_view. + * Note: interactive_begin() checks that view == g_server.grabbed_view. */ struct wlr_xdg_toplevel_resize_event *event = data; struct view *view = wl_container_of(listener, view, request_resize); @@ -559,13 +557,12 @@ handle_request_show_window_menu(struct wl_listener *listener, void *data) { struct xdg_toplevel_view *xdg_toplevel_view = wl_container_of( listener, xdg_toplevel_view, request_show_window_menu); - struct server *server = xdg_toplevel_view->base.server; - struct menu *menu = menu_get_by_id(server, "client-menu"); + struct menu *menu = menu_get_by_id("client-menu"); assert(menu); menu->triggered_by_view = &xdg_toplevel_view->base; - struct wlr_cursor *cursor = server->seat.cursor; + struct wlr_cursor *cursor = g_server.seat.cursor; menu_open_root(menu, cursor->x, cursor->y); } @@ -686,7 +683,7 @@ xdg_toplevel_view_append_children(struct view *self, struct wl_array *children) struct wlr_xdg_toplevel *toplevel = xdg_toplevel_from_view(self); struct view *view; - wl_list_for_each_reverse(view, &self->server->views, link) { + wl_list_for_each_reverse(view, &g_server.views, link) { if (view == self) { continue; } @@ -953,8 +950,6 @@ handle_xdg_activation_request(struct wl_listener *listener, void *data) static void handle_new_xdg_toplevel(struct wl_listener *listener, void *data) { - struct server *server = - wl_container_of(listener, server, new_xdg_toplevel); struct wlr_xdg_toplevel *xdg_toplevel = data; struct wlr_xdg_surface *xdg_surface = xdg_toplevel->base; @@ -963,7 +958,6 @@ handle_new_xdg_toplevel(struct wl_listener *listener, void *data) struct xdg_toplevel_view *xdg_toplevel_view = znew(*xdg_toplevel_view); struct view *view = &xdg_toplevel_view->base; - view->server = server; view->type = LAB_XDG_SHELL_VIEW; view->impl = &xdg_toplevel_view_impl; view_init(view); @@ -978,13 +972,13 @@ handle_new_xdg_toplevel(struct wl_listener *listener, void *data) * FIXME: this may be the wrong output since the parent view isn't * known yet. The correct output will be set at initial commit. */ - view_set_output(view, output_nearest_to_cursor(server)); + view_set_output(view, output_nearest_to_cursor()); if (output_is_usable(view->output)) { wlr_fractional_scale_v1_notify_scale(xdg_surface->surface, view->output->wlr_output->scale); } - view->workspace = server->workspaces.current; + view->workspace = g_server.workspaces.current; view->scene_tree = lab_wlr_scene_tree_create( view->workspace->view_trees[VIEW_LAYER_NORMAL]); wlr_scene_node_set_enabled(&view->scene_tree->node, false); @@ -1045,8 +1039,8 @@ handle_new_xdg_toplevel(struct wl_listener *listener, void *data) CONNECT_SIGNAL(toplevel, xdg_toplevel_view, request_show_window_menu); CONNECT_SIGNAL(xdg_surface, xdg_toplevel_view, new_popup); - wl_list_insert(&server->views, &view->link); - view->creation_id = server->next_view_creation_id++; + wl_list_insert(&g_server.views, &view->link); + view->creation_id = g_server.next_view_creation_id++; } static void @@ -1080,46 +1074,46 @@ handle_xdg_toplevel_icon_set_icon(struct wl_listener *listener, void *data) } void -xdg_shell_init(struct server *server) +xdg_shell_init(void) { - server->xdg_shell = wlr_xdg_shell_create(server->wl_display, + g_server.xdg_shell = wlr_xdg_shell_create(g_server.wl_display, LAB_XDG_SHELL_VERSION); - if (!server->xdg_shell) { + if (!g_server.xdg_shell) { wlr_log(WLR_ERROR, "unable to create the XDG shell interface"); exit(EXIT_FAILURE); } - server->new_xdg_toplevel.notify = handle_new_xdg_toplevel; - wl_signal_add(&server->xdg_shell->events.new_toplevel, &server->new_xdg_toplevel); + g_server.new_xdg_toplevel.notify = handle_new_xdg_toplevel; + wl_signal_add(&g_server.xdg_shell->events.new_toplevel, &g_server.new_xdg_toplevel); - server->xdg_activation = wlr_xdg_activation_v1_create(server->wl_display); - if (!server->xdg_activation) { + g_server.xdg_activation = wlr_xdg_activation_v1_create(g_server.wl_display); + if (!g_server.xdg_activation) { wlr_log(WLR_ERROR, "unable to create xdg_activation interface"); exit(EXIT_FAILURE); } - server->xdg_activation_request.notify = handle_xdg_activation_request; - wl_signal_add(&server->xdg_activation->events.request_activate, - &server->xdg_activation_request); + g_server.xdg_activation_request.notify = handle_xdg_activation_request; + wl_signal_add(&g_server.xdg_activation->events.request_activate, + &g_server.xdg_activation_request); - server->xdg_activation_new_token.notify = handle_xdg_activation_new_token; - wl_signal_add(&server->xdg_activation->events.new_token, - &server->xdg_activation_new_token); + g_server.xdg_activation_new_token.notify = handle_xdg_activation_new_token; + wl_signal_add(&g_server.xdg_activation->events.new_token, + &g_server.xdg_activation_new_token); - server->xdg_toplevel_icon_manager = wlr_xdg_toplevel_icon_manager_v1_create( - server->wl_display, 1); - server->xdg_toplevel_icon_set_icon.notify = handle_xdg_toplevel_icon_set_icon; - wl_signal_add(&server->xdg_toplevel_icon_manager->events.set_icon, - &server->xdg_toplevel_icon_set_icon); + g_server.xdg_toplevel_icon_manager = wlr_xdg_toplevel_icon_manager_v1_create( + g_server.wl_display, 1); + g_server.xdg_toplevel_icon_set_icon.notify = handle_xdg_toplevel_icon_set_icon; + wl_signal_add(&g_server.xdg_toplevel_icon_manager->events.set_icon, + &g_server.xdg_toplevel_icon_set_icon); - wlr_xdg_wm_dialog_v1_create(server->wl_display, 1); + wlr_xdg_wm_dialog_v1_create(g_server.wl_display, 1); } void -xdg_shell_finish(struct server *server) +xdg_shell_finish(void) { - wl_list_remove(&server->new_xdg_toplevel.link); - wl_list_remove(&server->xdg_activation_request.link); - wl_list_remove(&server->xdg_activation_new_token.link); - wl_list_remove(&server->xdg_toplevel_icon_set_icon.link); + wl_list_remove(&g_server.new_xdg_toplevel.link); + wl_list_remove(&g_server.xdg_activation_request.link); + wl_list_remove(&g_server.xdg_activation_new_token.link); + wl_list_remove(&g_server.xdg_toplevel_icon_set_icon.link); } diff --git a/src/xwayland-unmanaged.c b/src/xwayland-unmanaged.c index c25cc073..65801ce2 100644 --- a/src/xwayland-unmanaged.c +++ b/src/xwayland-unmanaged.c @@ -19,7 +19,7 @@ handle_grab_focus(struct wl_listener *listener, void *data) unmanaged->ever_grabbed_focus = true; if (unmanaged->node) { assert(unmanaged->xwayland_surface->surface); - seat_focus_surface(&unmanaged->server->seat, + seat_focus_surface(&g_server.seat, unmanaged->xwayland_surface->surface); } } @@ -34,7 +34,7 @@ handle_request_configure(struct wl_listener *listener, void *data) wlr_xwayland_surface_configure(xsurface, ev->x, ev->y, ev->width, ev->height); if (unmanaged->node) { wlr_scene_node_set_position(unmanaged->node, ev->x, ev->y); - cursor_update_focus(unmanaged->server); + cursor_update_focus(); } } @@ -46,7 +46,7 @@ handle_set_geometry(struct wl_listener *listener, void *data) struct wlr_xwayland_surface *xsurface = unmanaged->xwayland_surface; if (unmanaged->node) { wlr_scene_node_set_position(unmanaged->node, xsurface->x, xsurface->y); - cursor_update_focus(unmanaged->server); + cursor_update_focus(); } } @@ -59,35 +59,35 @@ handle_map(struct wl_listener *listener, void *data) assert(!unmanaged->node); /* Stack new surface on top */ - wl_list_append(&unmanaged->server->unmanaged_surfaces, &unmanaged->link); + wl_list_append(&g_server.unmanaged_surfaces, &unmanaged->link); CONNECT_SIGNAL(xsurface, unmanaged, set_geometry); if (wlr_xwayland_surface_override_redirect_wants_focus(xsurface) || unmanaged->ever_grabbed_focus) { - seat_focus_surface(&unmanaged->server->seat, xsurface->surface); + seat_focus_surface(&g_server.seat, xsurface->surface); } struct wlr_scene_surface *scene_surface = wlr_scene_surface_create( - unmanaged->server->unmanaged_tree, xsurface->surface); + g_server.unmanaged_tree, xsurface->surface); die_if_null(scene_surface); unmanaged->node = &scene_surface->buffer->node; wlr_scene_node_set_position(unmanaged->node, xsurface->x, xsurface->y); - cursor_update_focus(unmanaged->server); + cursor_update_focus(); } static void -focus_next_surface(struct server *server, struct wlr_xwayland_surface *xsurface) +focus_next_surface(struct wlr_xwayland_surface *xsurface) { /* Try to focus on last created unmanaged xwayland surface */ struct xwayland_unmanaged *u; - struct wl_list *list = &server->unmanaged_surfaces; + struct wl_list *list = &g_server.unmanaged_surfaces; wl_list_for_each_reverse(u, list, link) { struct wlr_xwayland_surface *prev = u->xwayland_surface; if (wlr_xwayland_surface_override_redirect_wants_focus(prev) || u->ever_grabbed_focus) { - seat_focus_surface(&server->seat, prev->surface); + seat_focus_surface(&g_server.seat, prev->surface); return; } } @@ -113,8 +113,8 @@ focus_next_surface(struct server *server, struct wlr_xwayland_surface *xsurface) * If modifying this logic, please test for regressions with * menus/tooltips in JetBrains CLion or similar. */ - if (server->active_view) { - seat_focus_surface(&server->seat, server->active_view->surface); + if (g_server.active_view) { + seat_focus_surface(&g_server.seat, g_server.active_view->surface); } } @@ -124,7 +124,7 @@ handle_unmap(struct wl_listener *listener, void *data) struct xwayland_unmanaged *unmanaged = wl_container_of(listener, unmanaged, mappable.unmap); struct wlr_xwayland_surface *xsurface = unmanaged->xwayland_surface; - struct seat *seat = &unmanaged->server->seat; + struct seat *seat = &g_server.seat; assert(unmanaged->node); wl_list_remove(&unmanaged->link); @@ -138,10 +138,10 @@ handle_unmap(struct wl_listener *listener, void *data) wlr_scene_node_destroy(unmanaged->node); unmanaged->node = NULL; - cursor_update_focus(unmanaged->server); + cursor_update_focus(); if (seat->seat->keyboard_state.focused_surface == xsurface->surface) { - focus_next_surface(unmanaged->server, xsurface); + focus_next_surface(xsurface); } } @@ -194,7 +194,6 @@ handle_set_override_redirect(struct wl_listener *listener, void *data) struct xwayland_unmanaged *unmanaged = wl_container_of(listener, unmanaged, set_override_redirect); struct wlr_xwayland_surface *xsurface = unmanaged->xwayland_surface; - struct server *server = unmanaged->server; bool mapped = xsurface->surface && xsurface->surface->mapped; if (mapped) { @@ -202,7 +201,7 @@ handle_set_override_redirect(struct wl_listener *listener, void *data) } handle_destroy(&unmanaged->destroy, NULL); - xwayland_view_create(server, xsurface, mapped); + xwayland_view_create(xsurface, mapped); } static void @@ -215,8 +214,7 @@ handle_request_activate(struct wl_listener *listener, void *data) if (!xsurface->surface || !xsurface->surface->mapped) { return; } - struct server *server = unmanaged->server; - struct seat *seat = &server->seat; + struct seat *seat = &g_server.seat; /* * Validate that the unmanaged surface trying to grab focus is actually @@ -225,7 +223,7 @@ handle_request_activate(struct wl_listener *listener, void *data) * FIXME: this logic is a bit incomplete/inconsistent. Refer to * https://github.com/labwc/labwc/discussions/2821 for more info. */ - struct view *view = server->active_view; + struct view *view = g_server.active_view; if (view && view->type == LAB_XWAYLAND_VIEW) { struct wlr_xwayland_surface *surf = wlr_xwayland_surface_try_from_wlr_surface(view->surface); @@ -238,11 +236,9 @@ handle_request_activate(struct wl_listener *listener, void *data) } void -xwayland_unmanaged_create(struct server *server, - struct wlr_xwayland_surface *xsurface, bool mapped) +xwayland_unmanaged_create(struct wlr_xwayland_surface *xsurface, bool mapped) { struct xwayland_unmanaged *unmanaged = znew(*unmanaged); - unmanaged->server = server; unmanaged->xwayland_surface = xsurface; /* * xsurface->data is presumed to be a (struct view *) if set, diff --git a/src/xwayland.c b/src/xwayland.c index 70b889f3..4f9a6729 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -234,7 +234,7 @@ ensure_initial_geometry_and_output(struct view *view) * Just use the cursor output since we don't know yet * whether the surface position is meaningful. */ - view_set_output(view, output_nearest_to_cursor(view->server)); + view_set_output(view, output_nearest_to_cursor()); } } @@ -290,7 +290,7 @@ handle_request_move(struct wl_listener *listener, void *data) * this client, to prevent the client from requesting this whenever they * want. * - * Note: interactive_begin() checks that view == server->grabbed_view. + * Note: interactive_begin() checks that view == g_server.grabbed_view. */ struct view *view = wl_container_of(listener, view, request_move); interactive_begin(view, LAB_INPUT_STATE_MOVE, LAB_EDGE_NONE); @@ -307,7 +307,7 @@ handle_request_resize(struct wl_listener *listener, void *data) * this client, to prevent the client from requesting this whenever they * want. * - * Note: interactive_begin() checks that view == server->grabbed_view. + * Note: interactive_begin() checks that view == g_server.grabbed_view. */ struct wlr_xwayland_resize_event *event = data; struct view *view = wl_container_of(listener, view, request_resize); @@ -388,7 +388,7 @@ xwayland_view_configure(struct view *view, struct wlr_box geo) * workaround, move offscreen surfaces immediately. */ bool is_offscreen = !wlr_box_empty(&view->current) && - !wlr_output_layout_intersects(view->server->output_layout, NULL, + !wlr_output_layout_intersects(g_server.output_layout, NULL, &view->current); /* If not resizing, process the move immediately */ @@ -575,14 +575,13 @@ handle_set_override_redirect(struct wl_listener *listener, void *data) struct view *view = &xwayland_view->base; struct wlr_xwayland_surface *xsurface = xwayland_view->xwayland_surface; - struct server *server = view->server; bool mapped = xsurface->surface && xsurface->surface->mapped; if (mapped) { handle_unmap(&view->mappable.unmap, NULL); } handle_destroy(&view->destroy, xsurface); /* view is invalid after this point */ - xwayland_unmanaged_create(server, xsurface, mapped); + xwayland_unmanaged_create(xsurface, mapped); } static void @@ -593,7 +592,7 @@ handle_set_strut_partial(struct wl_listener *listener, void *data) struct view *view = &xwayland_view->base; if (view->mapped) { - output_update_all_usable_areas(view->server, false); + output_update_all_usable_areas(false); } } @@ -659,7 +658,7 @@ handle_focus_in(struct wl_listener *listener, void *data) struct xwayland_view *xwayland_view = wl_container_of(listener, xwayland_view, focus_in); struct view *view = &xwayland_view->base; - struct seat *seat = &view->server->seat; + struct seat *seat = &g_server.seat; if (!view->surface) { /* @@ -879,7 +878,7 @@ handle_map(struct wl_listener *listener, void *data) */ if (xwayland_view->focused_before_map) { xwayland_view->focused_before_map = false; - seat_focus_surface(&view->server->seat, view->surface); + seat_focus_surface(&g_server.seat, view->surface); } view_impl_map(view); @@ -942,7 +941,7 @@ xwayland_view_append_children(struct view *self, struct wl_array *children) struct wlr_xwayland_surface *surface = xwayland_surface_from_view(self); struct view *view; - wl_list_for_each_reverse(view, &self->server->views, link) { + wl_list_for_each_reverse(view, &g_server.views, link) { if (view == self) { continue; } @@ -991,7 +990,7 @@ xwayland_view_set_activated(struct view *view, bool activated) * activated window, if it receives mouse/pointer events over the * parallel wayland connection first. */ - xwayland_flush(view->server); + xwayland_flush(); } static void @@ -1043,13 +1042,11 @@ handle_always_on_top(struct wl_listener *listener, void *data) } void -xwayland_view_create(struct server *server, - struct wlr_xwayland_surface *xsurface, bool mapped) +xwayland_view_create(struct wlr_xwayland_surface *xsurface, bool mapped) { struct xwayland_view *xwayland_view = znew(*xwayland_view); struct view *view = &xwayland_view->base; - view->server = server; view->type = LAB_XWAYLAND_VIEW; view->impl = &xwayland_view_impl; view_init(view); @@ -1064,7 +1061,7 @@ xwayland_view_create(struct server *server, xwayland_view->xwayland_surface = xsurface; xsurface->data = view; - view->workspace = server->workspaces.current; + view->workspace = g_server.workspaces.current; view->scene_tree = lab_wlr_scene_tree_create( view->workspace->view_trees[VIEW_LAYER_NORMAL]); node_descriptor_create(&view->scene_tree->node, @@ -1096,8 +1093,8 @@ xwayland_view_create(struct server *server, /* Events from the view itself */ CONNECT_SIGNAL(view, &xwayland_view->on_view, always_on_top); - wl_list_insert(&view->server->views, &view->link); - view->creation_id = view->server->next_view_creation_id++; + wl_list_insert(&g_server.views, &view->link); + view->creation_id = g_server.next_view_creation_id++; if (xsurface->surface) { handle_associate(&xwayland_view->associate, NULL); @@ -1120,8 +1117,6 @@ xwayland_view_create(struct server *server, static void handle_new_surface(struct wl_listener *listener, void *data) { - struct server *server = - wl_container_of(listener, server, xwayland_new_surface); struct wlr_xwayland_surface *xsurface = data; /* @@ -1129,17 +1124,17 @@ handle_new_surface(struct wl_listener *listener, void *data) * but add them to server.unmanaged_surfaces so that we can render them */ if (xsurface->override_redirect) { - xwayland_unmanaged_create(server, xsurface, /* mapped */ false); + xwayland_unmanaged_create(xsurface, /* mapped */ false); } else { - xwayland_view_create(server, xsurface, /* mapped */ false); + xwayland_view_create(xsurface, /* mapped */ false); } } static struct xwayland_view * -xwayland_view_from_window_id(struct server *server, xcb_window_t id) +xwayland_view_from_window_id(xcb_window_t id) { struct view *view; - wl_list_for_each(view, &server->views, link) { + wl_list_for_each(view, &g_server.views, link) { if (view->type != LAB_XWAYLAND_VIEW) { continue; } @@ -1160,9 +1155,8 @@ handle_x11_event(struct wlr_xwayland *wlr_xwayland, xcb_generic_event_t *event) case XCB_PROPERTY_NOTIFY: { xcb_property_notify_event_t *ev = (void *)event; if (ev->atom == atoms[ATOM_NET_WM_ICON]) { - struct server *server = wlr_xwayland->data; struct xwayland_view *xwayland_view = - xwayland_view_from_window_id(server, ev->window); + xwayland_view_from_window_id(ev->window); if (xwayland_view) { update_icon(xwayland_view); } else { @@ -1180,10 +1174,10 @@ handle_x11_event(struct wlr_xwayland *wlr_xwayland, xcb_generic_event_t *event) } static void -sync_atoms(struct server *server) +sync_atoms(void) { xcb_connection_t *xcb_conn = - wlr_xwayland_get_xwm_connection(server->xwayland); + wlr_xwayland_get_xwm_connection(g_server.xwayland); assert(xcb_conn); wlr_log(WLR_DEBUG, "Syncing X11 atoms"); @@ -1220,58 +1214,53 @@ handle_server_ready(struct wl_listener *listener, void *data) /* Fire an Xwayland startup script if one (or many) can be found */ session_run_script("xinitrc"); - struct server *server = - wl_container_of(listener, server, xwayland_server_ready); - sync_atoms(server); + sync_atoms(); } static void handle_xwm_ready(struct wl_listener *listener, void *data) { - struct server *server = - wl_container_of(listener, server, xwayland_xwm_ready); - wlr_xwayland_set_seat(server->xwayland, server->seat.seat); - xwayland_update_workarea(server); + wlr_xwayland_set_seat(g_server.xwayland, g_server.seat.seat); + xwayland_update_workarea(); } void -xwayland_server_init(struct server *server, struct wlr_compositor *compositor) +xwayland_server_init(struct wlr_compositor *compositor) { - server->xwayland = - wlr_xwayland_create(server->wl_display, + g_server.xwayland = + wlr_xwayland_create(g_server.wl_display, compositor, /* lazy */ !rc.xwayland_persistence); - if (!server->xwayland) { + if (!g_server.xwayland) { wlr_log(WLR_ERROR, "cannot create xwayland server"); exit(EXIT_FAILURE); } - server->xwayland_new_surface.notify = handle_new_surface; - wl_signal_add(&server->xwayland->events.new_surface, - &server->xwayland_new_surface); + g_server.xwayland_new_surface.notify = handle_new_surface; + wl_signal_add(&g_server.xwayland->events.new_surface, + &g_server.xwayland_new_surface); - server->xwayland_server_ready.notify = handle_server_ready; - wl_signal_add(&server->xwayland->server->events.ready, - &server->xwayland_server_ready); + g_server.xwayland_server_ready.notify = handle_server_ready; + wl_signal_add(&g_server.xwayland->server->events.ready, + &g_server.xwayland_server_ready); - server->xwayland_xwm_ready.notify = handle_xwm_ready; - wl_signal_add(&server->xwayland->events.ready, - &server->xwayland_xwm_ready); + g_server.xwayland_xwm_ready.notify = handle_xwm_ready; + wl_signal_add(&g_server.xwayland->events.ready, + &g_server.xwayland_xwm_ready); - server->xwayland->data = server; - server->xwayland->user_event_handler = handle_x11_event; + g_server.xwayland->user_event_handler = handle_x11_event; - if (setenv("DISPLAY", server->xwayland->display_name, true) < 0) { + if (setenv("DISPLAY", g_server.xwayland->display_name, true) < 0) { wlr_log_errno(WLR_ERROR, "unable to set DISPLAY for xwayland"); } else { wlr_log(WLR_DEBUG, "xwayland is running on display %s", - server->xwayland->display_name); + g_server.xwayland->display_name); } struct wlr_xcursor *xcursor; xcursor = wlr_xcursor_manager_get_xcursor( - server->seat.xcursor_manager, XCURSOR_DEFAULT, 1); + g_server.seat.xcursor_manager, XCURSOR_DEFAULT, 1); if (xcursor) { struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_xwayland_set_cursor(server->xwayland, image->buffer, + wlr_xwayland_set_cursor(g_server.xwayland, image->buffer, image->width * 4, image->width, image->height, image->hotspot_x, image->hotspot_y); @@ -1279,7 +1268,7 @@ xwayland_server_init(struct server *server, struct wlr_compositor *compositor) } void -xwayland_reset_cursor(struct server *server) +xwayland_reset_cursor(void) { /* * As xwayland caches the pixel data when not yet started up @@ -1299,24 +1288,24 @@ xwayland_reset_cursor(struct server *server) * - Start some X11 client */ - if (!server->xwayland) { + if (!g_server.xwayland) { return; } struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor( - server->seat.xcursor_manager, XCURSOR_DEFAULT, 1); + g_server.seat.xcursor_manager, XCURSOR_DEFAULT, 1); - if (xcursor && !server->xwayland->xwm) { + if (xcursor && !g_server.xwayland->xwm) { /* Prevents setting the cursor on an active xwayland server */ struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_xwayland_set_cursor(server->xwayland, image->buffer, + wlr_xwayland_set_cursor(g_server.xwayland, image->buffer, image->width * 4, image->width, image->height, image->hotspot_x, image->hotspot_y); return; } - if (server->xwayland->cursor) { + if (g_server.xwayland->cursor) { /* * The previous configured theme has set the * default cursor or the xwayland server is @@ -1324,23 +1313,23 @@ xwayland_reset_cursor(struct server *server) * xcursor set that will be used on the next * xwayland destroy -> lazy startup cycle. */ - zfree(server->xwayland->cursor); + zfree(g_server.xwayland->cursor); } } void -xwayland_server_finish(struct server *server) +xwayland_server_finish(void) { - struct wlr_xwayland *xwayland = server->xwayland; - wl_list_remove(&server->xwayland_new_surface.link); - wl_list_remove(&server->xwayland_server_ready.link); - wl_list_remove(&server->xwayland_xwm_ready.link); + struct wlr_xwayland *xwayland = g_server.xwayland; + wl_list_remove(&g_server.xwayland_new_surface.link); + wl_list_remove(&g_server.xwayland_server_ready.link); + wl_list_remove(&g_server.xwayland_xwm_ready.link); /* - * Reset server->xwayland to NULL first to prevent callbacks (like + * Reset g_server.xwayland to NULL first to prevent callbacks (like * server_global_filter) from accessing it as it is destroyed */ - server->xwayland = NULL; + g_server.xwayland = NULL; wlr_xwayland_destroy(xwayland); } @@ -1433,18 +1422,18 @@ xwayland_adjust_usable_area(struct view *view, struct wlr_output_layout *layout, } void -xwayland_update_workarea(struct server *server) +xwayland_update_workarea(void) { /* * Do nothing if called during destroy or before xwayland is ready. * This function will be called again from the ready signal handler. */ - if (!server->xwayland || !server->xwayland->xwm) { + if (!g_server.xwayland || !g_server.xwayland->xwm) { return; } struct wlr_box lb; - wlr_output_layout_get_box(server->output_layout, NULL, &lb); + wlr_output_layout_get_box(g_server.output_layout, NULL, &lb); /* Compute outer edges of layout (excluding negative regions) */ int layout_left = MAX(0, lb.x); @@ -1459,13 +1448,13 @@ xwayland_update_workarea(struct server *server) int workarea_bottom = layout_bottom; struct output *output; - wl_list_for_each(output, &server->outputs, link) { + wl_list_for_each(output, &g_server.outputs, link) { if (!output_is_usable(output)) { continue; } struct wlr_box ob; - wlr_output_layout_get_box(server->output_layout, + wlr_output_layout_get_box(g_server.output_layout, output->wlr_output, &ob); /* Compute edges of output */ @@ -1508,15 +1497,15 @@ xwayland_update_workarea(struct server *server) .width = workarea_right - workarea_left, .height = workarea_bottom - workarea_top, }; - wlr_xwayland_set_workareas(server->xwayland, &workarea, 1); + wlr_xwayland_set_workareas(g_server.xwayland, &workarea, 1); } void -xwayland_flush(struct server *server) +xwayland_flush(void) { - if (!server->xwayland || !server->xwayland->xwm) { + if (!g_server.xwayland || !g_server.xwayland->xwm) { return; } - xcb_flush(wlr_xwayland_get_xwm_connection(server->xwayland)); + xcb_flush(wlr_xwayland_get_xwm_connection(g_server.xwayland)); } From 8d46da9db1dcd83a87759ab19a1589dc4048bc0f Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Thu, 5 Mar 2026 21:36:02 -0500 Subject: [PATCH 032/146] tree-wide: wrap a few extra-long lines --- src/action.c | 3 ++- src/input/cursor.c | 3 ++- src/input/keyboard.c | 3 ++- src/scaled-buffer/scaled-icon-buffer.c | 3 ++- src/ssd/ssd-button.c | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/action.c b/src/action.c index 04f0ca16..75cd49c3 100644 --- a/src/action.c +++ b/src/action.c @@ -785,7 +785,8 @@ show_menu(struct view *view, struct cursor_context *ctx, * x/y can be number, "center" or a %percent of screen dimensions */ if (pos_x && pos_y) { - struct output *output = output_nearest_to(g_server.seat.cursor->x, g_server.seat.cursor->y); + struct output *output = output_nearest_to( + g_server.seat.cursor->x, g_server.seat.cursor->y); struct wlr_box usable = output_usable_area_in_layout_coords(output); if (!strcasecmp(pos_x, "center")) { diff --git a/src/input/cursor.c b/src/input/cursor.c index 77ff74f4..7d2970f5 100644 --- a/src/input/cursor.c +++ b/src/input/cursor.c @@ -659,7 +659,8 @@ cursor_process_motion(uint32_t time, double *sx, double *sy) * moving/resizing the wrong view */ mousebind->pressed_in_context = false; - actions_run(seat->pressed.ctx.view, &mousebind->actions, &seat->pressed.ctx); + actions_run(seat->pressed.ctx.view, + &mousebind->actions, &seat->pressed.ctx); } } diff --git a/src/input/keyboard.c b/src/input/keyboard.c index 6badbb12..f859eb2b 100644 --- a/src/input/keyboard.c +++ b/src/input/keyboard.c @@ -245,7 +245,8 @@ match_keybinding(struct keyinfo *keyinfo, { if (!is_virtual) { /* First try keycodes */ - struct keybind *keybind = match_keybinding_for_sym(keyinfo->modifiers, XKB_KEY_NoSymbol, keyinfo->xkb_keycode); + struct keybind *keybind = match_keybinding_for_sym( + keyinfo->modifiers, XKB_KEY_NoSymbol, keyinfo->xkb_keycode); if (keybind) { wlr_log(WLR_DEBUG, "keycode matched"); return keybind; diff --git a/src/scaled-buffer/scaled-icon-buffer.c b/src/scaled-buffer/scaled-icon-buffer.c index 00e2036a..f4cfb140 100644 --- a/src/scaled-buffer/scaled-icon-buffer.c +++ b/src/scaled-buffer/scaled-icon-buffer.c @@ -82,7 +82,8 @@ load_client_icon(struct scaled_icon_buffer *self, int icon_size, double scale) static struct lab_data_buffer * load_server_icon(struct scaled_icon_buffer *self, int icon_size, double scale) { - struct lab_img *img = desktop_entry_load_icon_from_app_id(self->view_app_id, icon_size, scale); + struct lab_img *img = desktop_entry_load_icon_from_app_id( + self->view_app_id, icon_size, scale); if (img) { wlr_log(WLR_DEBUG, "loaded icon by app_id"); return img_to_buffer(img, self->width, self->height, scale); diff --git a/src/ssd/ssd-button.c b/src/ssd/ssd-button.c index 4a3cf16e..7342dfad 100644 --- a/src/ssd/ssd-button.c +++ b/src/ssd/ssd-button.c @@ -50,7 +50,8 @@ attach_ssd_button(struct wl_list *button_parts, enum lab_node_type type, if (type == LAB_NODE_BUTTON_WINDOW_ICON) { struct scaled_icon_buffer *icon_buffer = - scaled_icon_buffer_create(root, button_width - 2 * icon_padding, button_height); + scaled_icon_buffer_create(root, button_width + - 2 * icon_padding, button_height); assert(icon_buffer); struct wlr_scene_node *icon_node = &icon_buffer->scene_buffer->node; scaled_icon_buffer_set_view(icon_buffer, view); From 4f72e6775ea671cd07330a7a0b3039bd7d9e99aa Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Thu, 19 Mar 2026 12:05:43 -0400 Subject: [PATCH 033/146] tree-wide: rename g_server to just server --- include/cycle.h | 4 +- include/decorations.h | 4 +- include/input/cursor.h | 2 +- include/labwc.h | 6 +- include/menu/menu.h | 12 +- include/view.h | 4 +- src/action.c | 46 ++--- src/config/keybind.c | 2 +- src/config/session.c | 2 +- src/cycle/cycle.c | 120 +++++------ src/cycle/osd-classic.c | 14 +- src/cycle/osd-field.c | 2 +- src/cycle/osd-scroll.c | 2 +- src/cycle/osd-thumbnail.c | 20 +- src/debug.c | 58 +++--- src/decorations/kde-deco.c | 8 +- src/decorations/xdg-deco.c | 12 +- src/desktop-entry.c | 12 +- src/desktop.c | 38 ++-- src/dnd.c | 2 +- src/edges.c | 10 +- src/foreign-toplevel/ext-foreign.c | 4 +- src/foreign-toplevel/wlr-foreign.c | 8 +- src/input/cursor.c | 132 ++++++------ src/input/gestures.c | 2 +- src/input/ime.c | 8 +- src/input/keyboard.c | 24 +-- src/input/tablet-pad.c | 4 +- src/input/tablet.c | 12 +- src/input/touch.c | 4 +- src/interactive.c | 76 +++---- src/layers.c | 32 +-- src/magnifier.c | 24 +-- src/main.c | 14 +- src/menu/menu.c | 88 ++++---- src/output-virtual.c | 18 +- src/output.c | 184 ++++++++--------- src/overlay.c | 6 +- src/placement.c | 6 +- src/regions.c | 20 +- src/resistance.c | 2 +- src/resize-outlines.c | 6 +- src/seat.c | 42 ++-- src/server.c | 322 ++++++++++++++--------------- src/session-lock.c | 28 +-- src/ssd/resize-indicator.c | 14 +- src/ssd/ssd-border.c | 4 +- src/ssd/ssd-extents.c | 6 +- src/ssd/ssd-shadow.c | 6 +- src/ssd/ssd-titlebar.c | 28 +-- src/ssd/ssd.c | 14 +- src/tearing.c | 2 +- src/theme.c | 2 +- src/view-impl-common.c | 10 +- src/view.c | 62 +++--- src/window-rules.c | 2 +- src/workspaces.c | 122 +++++------ src/xdg-popup.c | 6 +- src/xdg.c | 66 +++--- src/xwayland-unmanaged.c | 22 +- src/xwayland.c | 98 ++++----- 61 files changed, 955 insertions(+), 955 deletions(-) diff --git a/include/cycle.h b/include/cycle.h index 8caf2b98..9bb4cb69 100644 --- a/include/cycle.h +++ b/include/cycle.h @@ -133,7 +133,7 @@ struct cycle_osd_impl { */ void (*init)(struct cycle_osd_output *osd_output); /* - * Update the OSD to highlight g_server.cycle.selected_view. + * Update the OSD to highlight server.cycle.selected_view. */ void (*update)(struct cycle_osd_output *osd_output); }; @@ -157,7 +157,7 @@ void cycle_osd_scroll_init(struct cycle_osd_output *osd_output, int nr_cols, int nr_rows, int nr_visible_rows, float *border_color, float *bg_color); -/* Scroll the OSD to show g_server.cycle.selected_view if needed */ +/* Scroll the OSD to show server.cycle.selected_view if needed */ void cycle_osd_scroll_update(struct cycle_osd_output *osd_output); extern struct cycle_osd_impl cycle_osd_classic_impl; diff --git a/include/decorations.h b/include/decorations.h index 20ea3c6a..f3bff3d2 100644 --- a/include/decorations.h +++ b/include/decorations.h @@ -7,12 +7,12 @@ struct view; struct wlr_surface; void kde_server_decoration_init(void); -void xdg_server_decoration_init(void); +void xdserver_decoration_init(void); void kde_server_decoration_update_default(void); void kde_server_decoration_set_view(struct view *view, struct wlr_surface *surface); void kde_server_decoration_finish(void); -void xdg_server_decoration_finish(void); +void xdserver_decoration_finish(void); #endif /* LABWC_DECORATIONS_H */ diff --git a/include/input/cursor.h b/include/input/cursor.h index 9042d50f..3d7aa71a 100644 --- a/include/input/cursor.h +++ b/include/input/cursor.h @@ -82,7 +82,7 @@ void cursor_context_save(struct cursor_context_saved *saved_ctx, /** * cursor_get_resize_edges - calculate resize edge based on cursor position - * @cursor - the current cursor (usually g_server.seat.cursor) + * @cursor - the current cursor (usually server.seat.cursor) * @cursor_context - result of get_cursor_context() * * Calculates the resize edge combination that is most appropriate based diff --git a/include/labwc.h b/include/labwc.h index 2d122540..fac9539d 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -313,7 +313,7 @@ struct server { }; /* defined in main.c */ -extern struct server g_server; +extern struct server server; void xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup); void xdg_shell_init(void); @@ -405,8 +405,8 @@ void seat_focus_override_end(struct seat *seat, bool restore_focus); /** * interactive_anchor_to_cursor() - repositions the geometry to remain * underneath the cursor when its size changes during interactive move. - * This function also resizes g_server.grab_box and repositions it to remain - * underneath g_server.grab_{x,y}. + * This function also resizes server.grab_box and repositions it to remain + * underneath server.grab_{x,y}. * * geo->{width,height} are provided by the caller. * geo->{x,y} are computed by this function. diff --git a/include/menu/menu.h b/include/menu/menu.h index 31e94622..46bbca12 100644 --- a/include/menu/menu.h +++ b/include/menu/menu.h @@ -84,10 +84,10 @@ struct menu *menu_get_by_id(const char *id); /** * menu_open_root - open menu on position (x, y) * - * This function will close g_server.menu_current, open the - * new menu and assign @menu to g_server.menu_current. + * This function will close server.menu_current, open the + * new menu and assign @menu to server.menu_current. * - * Additionally, g_server.input_mode will be set to LAB_INPUT_STATE_MENU. + * Additionally, server.input_mode will be set to LAB_INPUT_STATE_MENU. */ void menu_open_root(struct menu *menu, int x, int y); @@ -102,10 +102,10 @@ void menu_process_cursor_motion(struct wlr_scene_node *node); /** * menu_close_root- close root menu * - * This function will close g_server.menu_current and set it to NULL. - * Asserts that g_server.input_mode is set to LAB_INPUT_STATE_MENU. + * This function will close server.menu_current and set it to NULL. + * Asserts that server.input_mode is set to LAB_INPUT_STATE_MENU. * - * Additionally, g_server.input_mode will be set to LAB_INPUT_STATE_PASSTHROUGH. + * Additionally, server.input_mode will be set to LAB_INPUT_STATE_PASSTHROUGH. */ void menu_close_root(void); diff --git a/include/view.h b/include/view.h index 25469594..c2764f94 100644 --- a/include/view.h +++ b/include/view.h @@ -357,7 +357,7 @@ bool view_matches_query(struct view *view, struct view_query *query); * @criteria: Criteria to match against. * Example: * struct view *view; - * for_each_view(view, &g_server.views, LAB_VIEW_CRITERIA_NONE) { + * for_each_view(view, &server.views, LAB_VIEW_CRITERIA_NONE) { * printf("%s\n", view_get_string_prop(view, "app_id")); * } */ @@ -373,7 +373,7 @@ bool view_matches_query(struct view *view, struct view_query *query); * @criteria: Criteria to match against. * Example: * struct view *view; - * for_each_view_reverse(view, &g_server.views, LAB_VIEW_CRITERIA_NONE) { + * for_each_view_reverse(view, &server.views, LAB_VIEW_CRITERIA_NONE) { * printf("%s\n", view_get_string_prop(view, "app_id")); * } */ diff --git a/src/action.c b/src/action.c index 75cd49c3..76f8eaa0 100644 --- a/src/action.c +++ b/src/action.c @@ -745,8 +745,8 @@ show_menu(struct view *view, struct cursor_context *ctx, const char *menu_name, bool at_cursor, const char *pos_x, const char *pos_y) { - if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH - && g_server.input_mode != LAB_INPUT_STATE_MENU) { + if (server.input_mode != LAB_INPUT_STATE_PASSTHROUGH + && server.input_mode != LAB_INPUT_STATE_MENU) { /* Prevent opening a menu while resizing / moving a view */ return; } @@ -756,8 +756,8 @@ show_menu(struct view *view, struct cursor_context *ctx, return; } - int x = g_server.seat.cursor->x; - int y = g_server.seat.cursor->y; + int x = server.seat.cursor->x; + int y = server.seat.cursor->y; /* The client menu needs an active client */ bool is_client_menu = !strcasecmp(menu_name, "client-menu"); @@ -776,7 +776,7 @@ show_menu(struct view *view, struct cursor_context *ctx, int lx, ly; wlr_scene_node_coords(ctx->node, &lx, &ly); /* MAX() prevents negative x when the window is maximized */ - x = MAX(x, lx - g_server.theme->menu_border_width); + x = MAX(x, lx - server.theme->menu_border_width); } } @@ -786,7 +786,7 @@ show_menu(struct view *view, struct cursor_context *ctx, */ if (pos_x && pos_y) { struct output *output = output_nearest_to( - g_server.seat.cursor->x, g_server.seat.cursor->y); + server.seat.cursor->x, server.seat.cursor->y); struct wlr_box usable = output_usable_area_in_layout_coords(output); if (!strcasecmp(pos_x, "center")) { @@ -846,7 +846,7 @@ view_for_action(struct view *activator, struct action *action, struct cursor_con return ctx->view; } default: - return g_server.active_view; + return server.active_view; } } @@ -1079,7 +1079,7 @@ warp_cursor(struct view *view, const char *to, const char *x, const char *y) target_area.y + target_area.height + offset_y; } - wlr_cursor_warp(g_server.seat.cursor, NULL, goto_x, goto_y); + wlr_cursor_warp(server.seat.cursor, NULL, goto_x, goto_y); cursor_update_focus(); } @@ -1117,7 +1117,7 @@ run_action(struct view *view, struct action *action, break; } case ACTION_TYPE_EXIT: - wl_display_terminate(g_server.wl_display); + wl_display_terminate(server.wl_display); break; case ACTION_TYPE_MOVE_TO_EDGE: if (view) { @@ -1172,7 +1172,7 @@ run_action(struct view *view, struct action *action, .app_id = action_get_int(action, "identifier", CYCLE_APP_ID_ALL), }; - if (g_server.input_mode == LAB_INPUT_STATE_CYCLE) { + if (server.input_mode == LAB_INPUT_STATE_CYCLE) { cycle_step(dir); } else { cycle_begin(dir, filter); @@ -1250,7 +1250,7 @@ run_action(struct view *view, struct action *action, } break; case ACTION_TYPE_UNFOCUS: - seat_focus_surface(&g_server.seat, NULL); + seat_focus_surface(&server.seat, NULL); break; case ACTION_TYPE_ICONIFY: if (view) { @@ -1274,7 +1274,7 @@ run_action(struct view *view, struct action *action, * set by button press handling. For keybind-triggered * Move, set it now from current cursor position. */ - if (view != g_server.seat.pressed.ctx.view) { + if (view != server.seat.pressed.ctx.view) { interactive_set_grab_context(ctx); } interactive_begin(view, LAB_INPUT_STATE_MOVE, @@ -1295,7 +1295,7 @@ run_action(struct view *view, struct action *action, * set by button press handling. For keybind-triggered * Resize, set it now from current cursor position. */ - if (view != g_server.seat.pressed.ctx.view) { + if (view != server.seat.pressed.ctx.view) { interactive_set_grab_context(ctx); } interactive_begin(view, LAB_INPUT_STATE_RESIZE, @@ -1370,12 +1370,12 @@ run_action(struct view *view, struct action *action, * a required argument for both SendToDesktop and GoToDesktop. */ struct workspace *target_workspace = workspaces_find( - g_server.workspaces.current, to, wrap); + server.workspaces.current, to, wrap); if (action->type == ACTION_TYPE_GO_TO_DESKTOP) { bool toggle = action_get_bool(action, "toggle", false); - if (target_workspace == g_server.workspaces.current + if (target_workspace == server.workspaces.current && toggle) { - target_workspace = g_server.workspaces.last; + target_workspace = server.workspaces.last; } } if (!target_workspace) { @@ -1386,7 +1386,7 @@ run_action(struct view *view, struct action *action, follow = action_get_bool(action, "follow", true); /* Ensure that the focus is not on another desktop */ - if (!follow && g_server.active_view == view) { + if (!follow && server.active_view == view) { desktop_focus_topmost_view(); } } @@ -1570,14 +1570,14 @@ run_action(struct view *view, struct action *action, } break; case ACTION_TYPE_ENABLE_SCROLL_WHEEL_EMULATION: - g_server.seat.cursor_scroll_wheel_emulation = true; + server.seat.cursor_scroll_wheel_emulation = true; break; case ACTION_TYPE_DISABLE_SCROLL_WHEEL_EMULATION: - g_server.seat.cursor_scroll_wheel_emulation = false; + server.seat.cursor_scroll_wheel_emulation = false; break; case ACTION_TYPE_TOGGLE_SCROLL_WHEEL_EMULATION: - g_server.seat.cursor_scroll_wheel_emulation = - !g_server.seat.cursor_scroll_wheel_emulation; + server.seat.cursor_scroll_wheel_emulation = + !server.seat.cursor_scroll_wheel_emulation; break; case ACTION_TYPE_ENABLE_TABLET_MOUSE_EMULATION: rc.tablet.force_mouse_emulation = true; @@ -1605,7 +1605,7 @@ run_action(struct view *view, struct action *action, break; } case ACTION_TYPE_HIDE_CURSOR: - cursor_set_visible(&g_server.seat, false); + cursor_set_visible(&server.seat, false); break; case ACTION_TYPE_INVALID: wlr_log(WLR_ERROR, "Not executing unknown action"); @@ -1640,7 +1640,7 @@ actions_run(struct view *activator, struct wl_list *actions, struct cursor_conte struct action *action; wl_list_for_each(action, actions, link) { - if (g_server.input_mode == LAB_INPUT_STATE_CYCLE + if (server.input_mode == LAB_INPUT_STATE_CYCLE && action->type != ACTION_TYPE_NEXT_WINDOW && action->type != ACTION_TYPE_PREVIOUS_WINDOW) { wlr_log(WLR_INFO, "Only NextWindow or PreviousWindow " diff --git a/src/config/keybind.c b/src/config/keybind.c index fd0832d9..8205ea93 100644 --- a/src/config/keybind.c +++ b/src/config/keybind.c @@ -123,7 +123,7 @@ update_keycodes_iter(struct xkb_keymap *keymap, xkb_keycode_t key, void *data) void keybind_update_keycodes(void) { - struct xkb_state *state = g_server.seat.keyboard_group->keyboard.xkb_state; + struct xkb_state *state = server.seat.keyboard_group->keyboard.xkb_state; struct xkb_keymap *keymap = xkb_state_get_keymap(state); struct keybind *keybind; diff --git a/src/config/session.c b/src/config/session.c index e7e77412..9a05d255 100644 --- a/src/config/session.c +++ b/src/config/session.c @@ -204,7 +204,7 @@ should_update_activation(void) /* With no valid preference, update when a DRM backend is in use */ bool have_drm = false; - wlr_multi_for_each_backend(g_server.backend, backend_check_drm, &have_drm); + wlr_multi_for_each_backend(server.backend, backend_check_drm, &have_drm); return have_drm; } diff --git a/src/cycle/cycle.c b/src/cycle/cycle.c index c09000e8..01785be3 100644 --- a/src/cycle/cycle.c +++ b/src/cycle/cycle.c @@ -26,8 +26,8 @@ static void update_preview_outlines(struct view *view) { /* Create / Update preview outline tree */ - struct theme *theme = g_server.theme; - struct lab_scene_rect *rect = g_server.cycle.preview_outline; + struct theme *theme = server.theme; + struct lab_scene_rect *rect = server.cycle.preview_outline; if (!rect) { struct lab_scene_rect_options opts = { .border_colors = (float *[3]) { @@ -38,10 +38,10 @@ update_preview_outlines(struct view *view) .nr_borders = 3, .border_width = theme->osd_window_switcher_preview_border_width, }; - rect = lab_scene_rect_create(&g_server.scene->tree, &opts); + rect = lab_scene_rect_create(&server.scene->tree, &opts); wlr_scene_node_place_above(&rect->tree->node, - &g_server.cycle_preview_tree->node); - g_server.cycle.preview_outline = rect; + &server.cycle_preview_tree->node); + server.cycle.preview_outline = rect; } struct wlr_box geo = ssd_max_extents(view); @@ -53,19 +53,19 @@ update_preview_outlines(struct view *view) static struct view * get_next_selected_view(enum lab_cycle_dir dir) { - struct cycle_state *cycle = &g_server.cycle; + struct cycle_state *cycle = &server.cycle; assert(cycle->selected_view); - assert(!wl_list_empty(&g_server.cycle.views)); + assert(!wl_list_empty(&server.cycle.views)); struct wl_list *link; if (dir == LAB_CYCLE_DIR_FORWARD) { link = cycle->selected_view->cycle_link.next; - if (link == &g_server.cycle.views) { + if (link == &server.cycle.views) { link = link->next; } } else { link = cycle->selected_view->cycle_link.prev; - if (link == &g_server.cycle.views) { + if (link == &server.cycle.views) { link = link->prev; } } @@ -84,9 +84,9 @@ get_first_view(struct wl_list *views) void cycle_reinitialize(void) { - struct cycle_state *cycle = &g_server.cycle; + struct cycle_state *cycle = &server.cycle; - if (g_server.input_mode != LAB_INPUT_STATE_CYCLE) { + if (server.input_mode != LAB_INPUT_STATE_CYCLE) { /* OSD not active, no need for clean up */ return; } @@ -109,7 +109,7 @@ cycle_reinitialize(void) } else { /* should be unreachable */ wlr_log(WLR_ERROR, "could not find view to select"); - cycle->selected_view = get_first_view(&g_server.cycle.views); + cycle->selected_view = get_first_view(&server.cycle.views); } update_cycle(); } else { @@ -121,35 +121,35 @@ cycle_reinitialize(void) void cycle_on_cursor_release(struct wlr_scene_node *node) { - assert(g_server.input_mode == LAB_INPUT_STATE_CYCLE); + assert(server.input_mode == LAB_INPUT_STATE_CYCLE); struct cycle_osd_item *item = node_cycle_osd_item_from_node(node); - g_server.cycle.selected_view = item->view; + server.cycle.selected_view = item->view; cycle_finish(/*switch_focus*/ true); } static void restore_preview_node(void) { - if (g_server.cycle.preview_node) { - wlr_scene_node_reparent(g_server.cycle.preview_node, - g_server.cycle.preview_dummy->parent); - wlr_scene_node_place_above(g_server.cycle.preview_node, - g_server.cycle.preview_dummy); - wlr_scene_node_destroy(g_server.cycle.preview_dummy); + if (server.cycle.preview_node) { + wlr_scene_node_reparent(server.cycle.preview_node, + server.cycle.preview_dummy->parent); + wlr_scene_node_place_above(server.cycle.preview_node, + server.cycle.preview_dummy); + wlr_scene_node_destroy(server.cycle.preview_dummy); /* Node was disabled / minimized before, disable again */ - if (!g_server.cycle.preview_was_enabled) { - wlr_scene_node_set_enabled(g_server.cycle.preview_node, false); + if (!server.cycle.preview_was_enabled) { + wlr_scene_node_set_enabled(server.cycle.preview_node, false); } - if (g_server.cycle.preview_was_shaded) { - struct view *view = node_view_from_node(g_server.cycle.preview_node); + if (server.cycle.preview_was_shaded) { + struct view *view = node_view_from_node(server.cycle.preview_node); view_set_shade(view, true); } - g_server.cycle.preview_node = NULL; - g_server.cycle.preview_dummy = NULL; - g_server.cycle.preview_was_enabled = false; - g_server.cycle.preview_was_shaded = false; + server.cycle.preview_node = NULL; + server.cycle.preview_dummy = NULL; + server.cycle.preview_was_enabled = false; + server.cycle.preview_was_shaded = false; } } @@ -157,7 +157,7 @@ void cycle_begin(enum lab_cycle_dir direction, struct cycle_filter filter) { - if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { + if (server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { return; } @@ -165,18 +165,18 @@ cycle_begin(enum lab_cycle_dir direction, return; } - struct view *active_view = g_server.active_view; + struct view *active_view = server.active_view; if (active_view && active_view->cycle_link.next) { /* Select the active view it's in the cycle list */ - g_server.cycle.selected_view = active_view; + server.cycle.selected_view = active_view; } else { /* Otherwise, select the first view in the cycle list */ - g_server.cycle.selected_view = get_first_view(&g_server.cycle.views); + server.cycle.selected_view = get_first_view(&server.cycle.views); } /* Pre-select the next view in the given direction */ - g_server.cycle.selected_view = get_next_selected_view(direction); + server.cycle.selected_view = get_next_selected_view(direction); - seat_focus_override_begin(&g_server.seat, + seat_focus_override_begin(&server.seat, LAB_INPUT_STATE_CYCLE, LAB_CURSOR_DEFAULT); update_cycle(); @@ -187,23 +187,23 @@ cycle_begin(enum lab_cycle_dir direction, void cycle_step(enum lab_cycle_dir direction) { - assert(g_server.input_mode == LAB_INPUT_STATE_CYCLE); + assert(server.input_mode == LAB_INPUT_STATE_CYCLE); - g_server.cycle.selected_view = get_next_selected_view(direction); + server.cycle.selected_view = get_next_selected_view(direction); update_cycle(); } void cycle_finish(bool switch_focus) { - if (g_server.input_mode != LAB_INPUT_STATE_CYCLE) { + if (server.input_mode != LAB_INPUT_STATE_CYCLE) { return; } - struct view *selected_view = g_server.cycle.selected_view; + struct view *selected_view = server.cycle.selected_view; destroy_cycle(); - seat_focus_override_end(&g_server.seat, /*restore_focus*/ false); + seat_focus_override_end(&server.seat, /*restore_focus*/ false); /* Hiding OSD may need a cursor change */ cursor_update_focus(); @@ -221,7 +221,7 @@ preview_selected_view(struct view *view) { assert(view); assert(view->scene_tree); - struct cycle_state *cycle = &g_server.cycle; + struct cycle_state *cycle = &server.cycle; /* Move previous selected node back to its original place */ restore_preview_node(); @@ -244,7 +244,7 @@ preview_selected_view(struct view *view) } wlr_scene_node_reparent(cycle->preview_node, - g_server.cycle_preview_tree); + server.cycle_preview_tree); /* Finally raise selected node to the top */ wlr_scene_node_raise_to_top(cycle->preview_node); @@ -274,7 +274,7 @@ get_outputs_by_filter(enum cycle_output_filter output_filter) output = output_nearest_to_cursor(); break; case CYCLE_OUTPUT_FOCUSED: { - struct view *view = g_server.active_view; + struct view *view = server.active_view; if (view && output_is_usable(view->output)) { output = view->output; } else { @@ -337,12 +337,12 @@ init_cycle(struct cycle_filter filter) get_outputs_by_filter(filter.output); const char *cycle_app_id = NULL; - if (filter.app_id == CYCLE_APP_ID_CURRENT && g_server.active_view) { - cycle_app_id = g_server.active_view->app_id; + if (filter.app_id == CYCLE_APP_ID_CURRENT && server.active_view) { + cycle_app_id = server.active_view->app_id; } struct view *view; - for_each_view(view, &g_server.views, criteria) { + for_each_view(view, &server.views, criteria) { if (filter.output != CYCLE_OUTPUT_ALL) { if (!view->output || !(cycle_outputs & view->output->id_bit)) { continue; @@ -353,22 +353,22 @@ init_cycle(struct cycle_filter filter) } if (rc.window_switcher.order == WINDOW_SWITCHER_ORDER_AGE) { - insert_view_ordered_by_age(&g_server.cycle.views, view); + insert_view_ordered_by_age(&server.cycle.views, view); } else { - wl_list_append(&g_server.cycle.views, &view->cycle_link); + wl_list_append(&server.cycle.views, &view->cycle_link); } } - if (wl_list_empty(&g_server.cycle.views)) { + if (wl_list_empty(&server.cycle.views)) { wlr_log(WLR_DEBUG, "no views to switch between"); return false; } - g_server.cycle.filter = filter; + server.cycle.filter = filter; if (rc.window_switcher.osd.show) { /* Create OSD */ uint64_t osd_outputs = get_outputs_by_filter(rc.window_switcher.osd.output_filter); struct output *output; - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { if (!(osd_outputs & output->id_bit)) { continue; } @@ -377,7 +377,7 @@ init_cycle(struct cycle_filter filter) } struct cycle_osd_output *osd_output = znew(*osd_output); - wl_list_append(&g_server.cycle.osd_outputs, &osd_output->link); + wl_list_append(&server.cycle.osd_outputs, &osd_output->link); osd_output->output = output; wl_list_init(&osd_output->items); @@ -395,7 +395,7 @@ init_cycle(struct cycle_filter filter) static void update_cycle(void) { - struct cycle_state *cycle = &g_server.cycle; + struct cycle_state *cycle = &server.cycle; if (rc.window_switcher.osd.show) { struct cycle_osd_output *osd_output; @@ -416,29 +416,29 @@ update_cycle(void) } } -/* Resets all the states in g_server.cycle */ +/* Resets all the states in server.cycle */ static void destroy_cycle(void) { struct cycle_osd_output *osd_output, *tmp; - wl_list_for_each_safe(osd_output, tmp, &g_server.cycle.osd_outputs, link) { + wl_list_for_each_safe(osd_output, tmp, &server.cycle.osd_outputs, link) { /* calls handle_osd_tree_destroy() */ wlr_scene_node_destroy(&osd_output->tree->node); } restore_preview_node(); - if (g_server.cycle.preview_outline) { - wlr_scene_node_destroy(&g_server.cycle.preview_outline->tree->node); + if (server.cycle.preview_outline) { + wlr_scene_node_destroy(&server.cycle.preview_outline->tree->node); } struct view *view, *tmp2; - wl_list_for_each_safe(view, tmp2, &g_server.cycle.views, cycle_link) { + wl_list_for_each_safe(view, tmp2, &server.cycle.views, cycle_link) { wl_list_remove(&view->cycle_link); view->cycle_link = (struct wl_list){0}; } - g_server.cycle = (struct cycle_state){0}; - wl_list_init(&g_server.cycle.views); - wl_list_init(&g_server.cycle.osd_outputs); + server.cycle = (struct cycle_state){0}; + wl_list_init(&server.cycle.views); + wl_list_init(&server.cycle.osd_outputs); } diff --git a/src/cycle/osd-classic.c b/src/cycle/osd-classic.c index 38b12a7c..1180074c 100644 --- a/src/cycle/osd-classic.c +++ b/src/cycle/osd-classic.c @@ -32,7 +32,7 @@ create_fields_scene(struct view *view, struct wlr_scene_tree *parent, const float *text_color, const float *bg_color, int field_widths_sum, int x, int y) { - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; struct window_switcher_classic_theme *switcher_theme = &theme->osd_window_switcher_classic; @@ -80,16 +80,16 @@ static void cycle_osd_classic_init(struct cycle_osd_output *osd_output) { struct output *output = osd_output->output; - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; struct window_switcher_classic_theme *switcher_theme = &theme->osd_window_switcher_classic; int padding = theme->osd_border_width + switcher_theme->padding; bool show_workspace = wl_list_length(&rc.workspace_config.workspaces) > 1; - const char *workspace_name = g_server.workspaces.current->name; - int nr_views = wl_list_length(&g_server.cycle.views); + const char *workspace_name = server.workspaces.current->name; + int nr_views = wl_list_length(&server.cycle.views); struct wlr_box output_box; - wlr_output_layout_get_box(g_server.output_layout, output->wlr_output, + wlr_output_layout_get_box(server.output_layout, output->wlr_output, &output_box); int w = switcher_theme->width; @@ -164,7 +164,7 @@ cycle_osd_classic_init(struct cycle_osd_output *osd_output) /* Draw text for each node */ struct view *view; - wl_list_for_each(view, &g_server.cycle.views, cycle_link) { + wl_list_for_each(view, &server.cycle.views, cycle_link) { struct cycle_osd_classic_item *item = znew(*item); wl_list_append(&osd_output->items, &item->base.link); item->base.view = view; @@ -245,7 +245,7 @@ cycle_osd_classic_update(struct cycle_osd_output *osd_output) struct cycle_osd_classic_item *item; wl_list_for_each(item, &osd_output->items, base.link) { - bool active = item->base.view == g_server.cycle.selected_view; + bool active = item->base.view == server.cycle.selected_view; wlr_scene_node_set_enabled(&item->normal_tree->node, !active); wlr_scene_node_set_enabled(&item->active_tree->node, active); } diff --git a/src/cycle/osd-field.c b/src/cycle/osd-field.c index f12f5dcc..5bc671ff 100644 --- a/src/cycle/osd-field.c +++ b/src/cycle/osd-field.c @@ -148,7 +148,7 @@ static void field_set_output_short(struct buf *buf, struct view *view, const char *format) { /* custom type conversion-specifier: o */ - if (wl_list_length(&g_server.outputs) > 1 && + if (wl_list_length(&server.outputs) > 1 && output_is_usable(view->output)) { buf_add(buf, view->output->wlr_output->name); } diff --git a/src/cycle/osd-scroll.c b/src/cycle/osd-scroll.c index c31ecff3..e788a479 100644 --- a/src/cycle/osd-scroll.c +++ b/src/cycle/osd-scroll.c @@ -45,7 +45,7 @@ get_cycle_idx(struct cycle_osd_output *osd_output) int idx = 0; struct cycle_osd_item *item; wl_list_for_each(item, &osd_output->items, link) { - if (item->view == g_server.cycle.selected_view) { + if (item->view == server.cycle.selected_view) { return idx; } idx++; diff --git a/src/cycle/osd-thumbnail.c b/src/cycle/osd-thumbnail.c index 98dcbaf0..4371bac8 100644 --- a/src/cycle/osd-thumbnail.c +++ b/src/cycle/osd-thumbnail.c @@ -47,7 +47,7 @@ render_node(struct wlr_render_pass *pass, break; } struct wlr_texture *texture = wlr_texture_from_buffer( - g_server.renderer, scene_buffer->buffer); + server.renderer, scene_buffer->buffer); if (!texture) { break; } @@ -82,11 +82,11 @@ render_thumb(struct output *output, struct view *view) */ return NULL; } - struct wlr_buffer *buffer = wlr_allocator_create_buffer(g_server.allocator, + struct wlr_buffer *buffer = wlr_allocator_create_buffer(server.allocator, view->current.width, view->current.height, &output->wlr_output->swapchain->format); struct wlr_render_pass *pass = wlr_renderer_begin_buffer_pass( - g_server.renderer, buffer, NULL); + server.renderer, buffer, NULL); render_node(pass, &view->content_tree->node, 0, 0); if (!wlr_render_pass_submit(pass)) { wlr_log(WLR_ERROR, "failed to submit render pass"); @@ -119,7 +119,7 @@ static struct cycle_osd_thumbnail_item * create_item_scene(struct wlr_scene_tree *parent, struct view *view, struct cycle_osd_output *osd_output) { - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; struct window_switcher_thumbnail_theme *switcher_theme = &theme->osd_window_switcher_thumbnail; int padding = theme->border_width + switcher_theme->item_padding; @@ -196,7 +196,7 @@ static void get_items_geometry(struct output *output, int nr_thumbs, int *nr_cols, int *nr_rows, int *nr_visible_rows) { - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; struct window_switcher_thumbnail_theme *switcher_theme = &theme->osd_window_switcher_thumbnail; int output_width, output_height; @@ -232,7 +232,7 @@ static void cycle_osd_thumbnail_init(struct cycle_osd_output *osd_output) { struct output *output = osd_output->output; - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; struct window_switcher_thumbnail_theme *switcher_theme = &theme->osd_window_switcher_thumbnail; int padding = theme->osd_border_width + switcher_theme->padding; @@ -240,7 +240,7 @@ cycle_osd_thumbnail_init(struct cycle_osd_output *osd_output) osd_output->tree = lab_wlr_scene_tree_create(output->cycle_osd_tree); osd_output->items_tree = lab_wlr_scene_tree_create(osd_output->tree); - int nr_views = wl_list_length(&g_server.cycle.views); + int nr_views = wl_list_length(&server.cycle.views); assert(nr_views > 0); int nr_cols, nr_rows, nr_visible_rows; get_items_geometry(output, nr_views, &nr_cols, &nr_rows, &nr_visible_rows); @@ -248,7 +248,7 @@ cycle_osd_thumbnail_init(struct cycle_osd_output *osd_output) /* items */ struct view *view; int index = 0; - wl_list_for_each(view, &g_server.cycle.views, cycle_link) { + wl_list_for_each(view, &server.cycle.views, cycle_link) { struct cycle_osd_thumbnail_item *item = create_item_scene( osd_output->items_tree, view, osd_output); if (!item) { @@ -289,7 +289,7 @@ cycle_osd_thumbnail_init(struct cycle_osd_output *osd_output) /* center */ struct wlr_box output_box; - wlr_output_layout_get_box(g_server.output_layout, output->wlr_output, + wlr_output_layout_get_box(server.output_layout, output->wlr_output, &output_box); int lx = output_box.x + (output_box.width - bg_opts.width) / 2; int ly = output_box.y + (output_box.height - bg_opts.height) / 2; @@ -303,7 +303,7 @@ cycle_osd_thumbnail_update(struct cycle_osd_output *osd_output) struct cycle_osd_thumbnail_item *item; wl_list_for_each(item, &osd_output->items, base.link) { - bool active = (item->base.view == g_server.cycle.selected_view); + bool active = (item->base.view == server.cycle.selected_view); wlr_scene_node_set_enabled(&item->active_bg->tree->node, active); wlr_scene_node_set_enabled( &item->active_label->scene_buffer->node, active); diff --git a/src/debug.c b/src/debug.c index f0656f04..fef4d819 100644 --- a/src/debug.c +++ b/src/debug.c @@ -92,7 +92,7 @@ static struct workspace * get_workspace_from_node(struct wlr_scene_node *node) { struct workspace *workspace; - wl_list_for_each(workspace, &g_server.workspaces.all, link) { + wl_list_for_each(workspace, &server.workspaces.all, link) { if (&workspace->tree->node == node) { return workspace; } @@ -107,23 +107,23 @@ get_special(struct wlr_scene_node *node) node->parent ? node->parent->node.parent : NULL; struct wlr_scene_tree *grand_grand_parent = grand_parent ? grand_parent->node.parent : NULL; - if (node == &g_server.scene->tree.node) { - return "g_server.scene"; + if (node == &server.scene->tree.node) { + return "server.scene"; } - if (node == &g_server.menu_tree->node) { - return "g_server.menu_tree"; + if (node == &server.menu_tree->node) { + return "server.menu_tree"; } - if (node == &g_server.workspace_tree->node) { - return "g_server.workspace_tree"; + if (node == &server.workspace_tree->node) { + return "server.workspace_tree"; } - if (node->parent == g_server.workspace_tree) { + if (node->parent == server.workspace_tree) { struct workspace *workspace = get_workspace_from_node(node); if (workspace) { return workspace->name; } return "unknown workspace"; } - if (grand_parent == g_server.workspace_tree) { + if (grand_parent == server.workspace_tree) { struct workspace *workspace = get_workspace_from_node(&node->parent->node); if (workspace) { @@ -138,9 +138,9 @@ get_special(struct wlr_scene_node *node) } return "unknown tree"; } - if (node->parent == &g_server.scene->tree) { + if (node->parent == &server.scene->tree) { struct output *output; - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { if (node == &output->cycle_osd_tree->node) { return "output->osd_tree"; } @@ -157,33 +157,33 @@ get_special(struct wlr_scene_node *node) } } } - if (node == &g_server.xdg_popup_tree->node) { - return "g_server.xdg_popup_tree"; + if (node == &server.xdg_popup_tree->node) { + return "server.xdg_popup_tree"; } - if (node == &g_server.seat.drag.icons->node) { + if (node == &server.seat.drag.icons->node) { return "seat->drag.icons"; } - if (g_server.seat.overlay.rect - && node == &g_server.seat.overlay.rect->tree->node) { + if (server.seat.overlay.rect + && node == &server.seat.overlay.rect->tree->node) { /* Created on-demand */ return "seat->overlay.rect"; } - if (g_server.seat.input_method_relay->popup_tree - && node == &g_server.seat.input_method_relay->popup_tree->node) { + if (server.seat.input_method_relay->popup_tree + && node == &server.seat.input_method_relay->popup_tree->node) { /* Created on-demand */ return "seat->im_relay->popup_tree"; } - if (g_server.cycle.preview_outline - && node == &g_server.cycle.preview_outline->tree->node) { + if (server.cycle.preview_outline + && node == &server.cycle.preview_outline->tree->node) { /* Created on-demand */ return "cycle_state->preview_outline"; } #if HAVE_XWAYLAND - if (node == &g_server.unmanaged_tree->node) { - return "g_server.unmanaged_tree"; + if (node == &server.unmanaged_tree->node) { + return "server.unmanaged_tree"; } #endif - if (grand_grand_parent == g_server.workspace_tree && node->data) { + if (grand_grand_parent == server.workspace_tree && node->data) { last_view = node_view_from_node(node); } const char *view_part = get_view_part(last_view, node); @@ -234,13 +234,13 @@ dump_tree(struct wlr_scene_node *node, } printf("%.*s %*c %4d %4d [%p]\n", max_width - 1, type, padding, ' ', x, y, node); - if ((IGNORE_MENU && node == &g_server.menu_tree->node) + if ((IGNORE_MENU && node == &server.menu_tree->node) || (IGNORE_SSD && last_view && ssd_debug_is_root_node(last_view->ssd, node)) - || (IGNORE_CYCLE_PREVIEW_OUTLINE && g_server.cycle.preview_outline - && node == &g_server.cycle.preview_outline->tree->node) - || (IGNORE_SNAPPING_OVERLAY && g_server.seat.overlay.rect - && node == &g_server.seat.overlay.rect->tree->node)) { + || (IGNORE_CYCLE_PREVIEW_OUTLINE && server.cycle.preview_outline + && node == &server.cycle.preview_outline->tree->node) + || (IGNORE_SNAPPING_OVERLAY && server.seat.overlay.rect + && node == &server.seat.overlay.rect->tree->node)) { printf("%*c%s\n", pos + 4 + INDENT_SIZE, ' ', ""); return; } @@ -259,7 +259,7 @@ void debug_dump_scene(void) { printf("\n"); - dump_tree(&g_server.scene->tree.node, 0, 0, 0); + dump_tree(&server.scene->tree.node, 0, 0, 0); printf("\n"); /* diff --git a/src/decorations/kde-deco.c b/src/decorations/kde-deco.c index 98034e53..9b3a55f8 100644 --- a/src/decorations/kde-deco.c +++ b/src/decorations/kde-deco.c @@ -122,7 +122,7 @@ void kde_server_decoration_init(void) { assert(!kde_deco_mgr); - kde_deco_mgr = wlr_server_decoration_manager_create(g_server.wl_display); + kde_deco_mgr = wlr_server_decoration_manager_create(server.wl_display); if (!kde_deco_mgr) { wlr_log(WLR_ERROR, "unable to create the kde server deco manager"); exit(EXIT_FAILURE); @@ -131,12 +131,12 @@ kde_server_decoration_init(void) wl_list_init(&decorations); kde_server_decoration_update_default(); - wl_signal_add(&kde_deco_mgr->events.new_decoration, &g_server.kde_server_decoration); - g_server.kde_server_decoration.notify = handle_new_server_decoration; + wl_signal_add(&kde_deco_mgr->events.new_decoration, &server.kde_server_decoration); + server.kde_server_decoration.notify = handle_new_server_decoration; } void kde_server_decoration_finish(void) { - wl_list_remove(&g_server.kde_server_decoration.link); + wl_list_remove(&server.kde_server_decoration.link); } diff --git a/src/decorations/xdg-deco.c b/src/decorations/xdg-deco.c index 5374e6d4..678a481d 100644 --- a/src/decorations/xdg-deco.c +++ b/src/decorations/xdg-deco.c @@ -115,22 +115,22 @@ xdg_toplevel_decoration(struct wl_listener *listener, void *data) } void -xdg_server_decoration_init(void) +xdserver_decoration_init(void) { struct wlr_xdg_decoration_manager_v1 *xdg_deco_mgr = NULL; - xdg_deco_mgr = wlr_xdg_decoration_manager_v1_create(g_server.wl_display); + xdg_deco_mgr = wlr_xdg_decoration_manager_v1_create(server.wl_display); if (!xdg_deco_mgr) { wlr_log(WLR_ERROR, "unable to create the XDG deco manager"); exit(EXIT_FAILURE); } wl_signal_add(&xdg_deco_mgr->events.new_toplevel_decoration, - &g_server.xdg_toplevel_decoration); - g_server.xdg_toplevel_decoration.notify = xdg_toplevel_decoration; + &server.xdg_toplevel_decoration); + server.xdg_toplevel_decoration.notify = xdg_toplevel_decoration; } void -xdg_server_decoration_finish(void) +xdserver_decoration_finish(void) { - wl_list_remove(&g_server.xdg_toplevel_decoration.link); + wl_list_remove(&server.xdg_toplevel_decoration.link); } diff --git a/src/desktop-entry.c b/src/desktop-entry.c index 22e54951..a708073e 100644 --- a/src/desktop-entry.c +++ b/src/desktop-entry.c @@ -134,7 +134,7 @@ desktop_entry_init(void) /* basedir_ctx is not referenced by other objects */ sfdo_basedir_ctx_destroy(basedir_ctx); - g_server.sfdo = sfdo; + server.sfdo = sfdo; return; err_icon_theme: @@ -157,7 +157,7 @@ err_basedir_ctx: void desktop_entry_finish(void) { - struct sfdo *sfdo = g_server.sfdo; + struct sfdo *sfdo = server.sfdo; if (!sfdo) { return; } @@ -167,7 +167,7 @@ desktop_entry_finish(void) sfdo_icon_ctx_destroy(sfdo->icon_ctx); sfdo_desktop_ctx_destroy(sfdo->desktop_ctx); free(sfdo); - g_server.sfdo = NULL; + server.sfdo = NULL; } struct icon_ctx { @@ -355,7 +355,7 @@ desktop_entry_load_icon(const char *icon_name, int size, float scale) return NULL; } - struct sfdo *sfdo = g_server.sfdo; + struct sfdo *sfdo = server.sfdo; if (!sfdo) { return NULL; } @@ -393,7 +393,7 @@ desktop_entry_load_icon_from_app_id(const char *app_id, int size, float scale) return NULL; } - struct sfdo *sfdo = g_server.sfdo; + struct sfdo *sfdo = server.sfdo; if (!sfdo) { return NULL; } @@ -419,7 +419,7 @@ desktop_entry_name_lookup(const char *app_id) return NULL; } - struct sfdo *sfdo = g_server.sfdo; + struct sfdo *sfdo = server.sfdo; if (!sfdo) { return NULL; } diff --git a/src/desktop.c b/src/desktop.c index 36e8bd8e..fd1fb1ad 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -36,7 +36,7 @@ desktop_arrange_all_views(void) * views. */ struct view *view; - wl_list_for_each(view, &g_server.views, link) { + wl_list_for_each(view, &server.views, link) { if (!wlr_box_empty(&view->pending)) { view_adjust_for_layout_change(view); } @@ -46,7 +46,7 @@ desktop_arrange_all_views(void) static void set_or_offer_focus(struct view *view) { - struct seat *seat = &g_server.seat; + struct seat *seat = &server.seat; switch (view_wants_focus(view)) { case VIEW_WANTS_FOCUS_ALWAYS: if (view->surface != seat->seat->keyboard_state.focused_surface) { @@ -76,7 +76,7 @@ desktop_focus_view(struct view *view, bool raise) return; } - if (g_server.input_mode == LAB_INPUT_STATE_CYCLE) { + if (server.input_mode == LAB_INPUT_STATE_CYCLE) { wlr_log(WLR_DEBUG, "not focusing window while window switching"); return; } @@ -138,7 +138,7 @@ static struct view * desktop_topmost_focusable_view(void) { struct view *view; - for_each_view(view, &g_server.views, + for_each_view(view, &server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { if (!view->minimized) { return view; @@ -158,22 +158,22 @@ desktop_focus_topmost_view(void) * Defocus previous focused surface/view if no longer * focusable (e.g. unmapped or on a different workspace). */ - seat_focus_surface(&g_server.seat, NULL); + seat_focus_surface(&server.seat, NULL); } } void desktop_focus_output(struct output *output) { - if (!output_is_usable(output) || g_server.input_mode + if (!output_is_usable(output) || server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { return; } struct view *view; - for_each_view(view, &g_server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { + for_each_view(view, &server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { if (view->outputs & output->id_bit) { desktop_focus_view(view, /*raise*/ false); - wlr_cursor_warp(g_server.seat.cursor, NULL, + wlr_cursor_warp(server.seat.cursor, NULL, view->current.x + view->current.width / 2, view->current.y + view->current.height / 2); cursor_update_focus(); @@ -182,9 +182,9 @@ desktop_focus_output(struct output *output) } /* No view found on desired output */ struct wlr_box layout_box; - wlr_output_layout_get_box(g_server.output_layout, + wlr_output_layout_get_box(server.output_layout, output->wlr_output, &layout_box); - wlr_cursor_warp(g_server.seat.cursor, NULL, + wlr_cursor_warp(server.seat.cursor, NULL, layout_box.x + output->usable_area.x + output->usable_area.width / 2, layout_box.y + output->usable_area.y + output->usable_area.height / 2); cursor_update_focus(); @@ -198,7 +198,7 @@ desktop_update_top_layer_visibility(void) uint32_t top = ZWLR_LAYER_SHELL_V1_LAYER_TOP; /* Enable all top layers */ - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { if (!output_is_usable(output)) { continue; } @@ -210,7 +210,7 @@ desktop_update_top_layer_visibility(void) * any views above it */ uint64_t outputs_covered = 0; - for_each_view(view, &g_server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { + for_each_view(view, &server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { if (view->minimized) { continue; } @@ -263,19 +263,19 @@ struct cursor_context get_cursor_context(void) { struct cursor_context ret = {.type = LAB_NODE_NONE}; - struct wlr_cursor *cursor = g_server.seat.cursor; + struct wlr_cursor *cursor = server.seat.cursor; /* Prevent drag icons to be on top of the hitbox detection */ - if (g_server.seat.drag.active) { - dnd_icons_show(&g_server.seat, false); + if (server.seat.drag.active) { + dnd_icons_show(&server.seat, false); } struct wlr_scene_node *node = - wlr_scene_node_at(&g_server.scene->tree.node, + wlr_scene_node_at(&server.scene->tree.node, cursor->x, cursor->y, &ret.sx, &ret.sy); - if (g_server.seat.drag.active) { - dnd_icons_show(&g_server.seat, true); + if (server.seat.drag.active) { + dnd_icons_show(&server.seat, true); } if (!node) { @@ -290,7 +290,7 @@ get_cursor_context(void) #if HAVE_XWAYLAND /* TODO: attach LAB_NODE_UNMANAGED node-descriptor to unmanaged surfaces */ if (node->type == WLR_SCENE_NODE_BUFFER) { - if (node->parent == g_server.unmanaged_tree) { + if (node->parent == server.unmanaged_tree) { ret.type = LAB_NODE_UNMANAGED; return ret; } diff --git a/src/dnd.c b/src/dnd.c index 7542e5d7..2b8dfaaa 100644 --- a/src/dnd.c +++ b/src/dnd.c @@ -84,7 +84,7 @@ handle_drag_destroy(struct wl_listener *listener, void *data) void dnd_init(struct seat *seat) { - seat->drag.icons = lab_wlr_scene_tree_create(&g_server.scene->tree); + seat->drag.icons = lab_wlr_scene_tree_create(&server.scene->tree); wlr_scene_node_set_enabled(&seat->drag.icons->node, false); seat->drag.events.request.notify = handle_drag_request; diff --git a/src/edges.c b/src/edges.c index 24c0528d..4e5d7ca9 100644 --- a/src/edges.c +++ b/src/edges.c @@ -353,17 +353,17 @@ edges_calculate_visibility(struct view *ignored_view) */ struct output *output; struct wlr_box layout_box; - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { if (!output_is_usable(output)) { continue; } - wlr_output_layout_get_box(g_server.output_layout, + wlr_output_layout_get_box(server.output_layout, output->wlr_output, &layout_box); pixman_region32_union_rect(®ion, ®ion, layout_box.x, layout_box.y, layout_box.width, layout_box.height); } - subtract_node_tree(&g_server.scene->tree, ®ion, ignored_view); + subtract_node_tree(&server.scene->tree, ®ion, ignored_view); pixman_region32_fini(®ion); } @@ -389,7 +389,7 @@ edges_find_neighbors(struct border *nearest_edges, struct view *view, edges_for_target_geometry(&target_edges, view, target); struct view *v; - for_each_view(v, &g_server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { + for_each_view(v, &server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { if (v == view || v->minimized || !output_is_usable(v->output)) { continue; } @@ -447,7 +447,7 @@ edges_find_outputs(struct border *nearest_edges, struct view *view, edges_for_target_geometry(&target_edges, view, target); struct output *o; - wl_list_for_each(o, &g_server.outputs, link) { + wl_list_for_each(o, &server.outputs, link) { if (!output_is_usable(o)) { continue; } diff --git a/src/foreign-toplevel/ext-foreign.c b/src/foreign-toplevel/ext-foreign.c index 99954c4d..78774433 100644 --- a/src/foreign-toplevel/ext-foreign.c +++ b/src/foreign-toplevel/ext-foreign.c @@ -59,7 +59,7 @@ void ext_foreign_toplevel_init(struct ext_foreign_toplevel *ext_toplevel, struct view *view) { - assert(g_server.foreign_toplevel_list); + assert(server.foreign_toplevel_list); ext_toplevel->view = view; struct wlr_ext_foreign_toplevel_handle_v1_state state = { @@ -67,7 +67,7 @@ ext_foreign_toplevel_init(struct ext_foreign_toplevel *ext_toplevel, .app_id = view->app_id, }; ext_toplevel->handle = wlr_ext_foreign_toplevel_handle_v1_create( - g_server.foreign_toplevel_list, &state); + server.foreign_toplevel_list, &state); if (!ext_toplevel->handle) { wlr_log(WLR_ERROR, "cannot create ext toplevel handle for (%s)", diff --git a/src/foreign-toplevel/wlr-foreign.c b/src/foreign-toplevel/wlr-foreign.c index f4076c5a..3e589ef0 100644 --- a/src/foreign-toplevel/wlr-foreign.c +++ b/src/foreign-toplevel/wlr-foreign.c @@ -123,7 +123,7 @@ handle_new_outputs(struct wl_listener *listener, void *data) * wlr_foreign_toplevel handle the rest. */ struct output *output; - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { if (view_on_output(wlr_toplevel->view, output)) { wlr_foreign_toplevel_handle_v1_output_enter( wlr_toplevel->handle, output->wlr_output); @@ -184,11 +184,11 @@ void wlr_foreign_toplevel_init(struct wlr_foreign_toplevel *wlr_toplevel, struct view *view) { - assert(g_server.foreign_toplevel_manager); + assert(server.foreign_toplevel_manager); wlr_toplevel->view = view; wlr_toplevel->handle = wlr_foreign_toplevel_handle_v1_create( - g_server.foreign_toplevel_manager); + server.foreign_toplevel_manager); if (!wlr_toplevel->handle) { wlr_log(WLR_ERROR, "cannot create wlr foreign toplevel handle for (%s)", view->title); @@ -203,7 +203,7 @@ wlr_foreign_toplevel_init(struct wlr_foreign_toplevel *wlr_toplevel, handle_minimized(&wlr_toplevel->on_view.minimized, NULL); handle_fullscreened(&wlr_toplevel->on_view.fullscreened, NULL); handle_activated(&wlr_toplevel->on_view.activated, - &(bool){view == g_server.active_view}); + &(bool){view == server.active_view}); /* Client side requests */ CONNECT_SIGNAL(wlr_toplevel->handle, &wlr_toplevel->on, request_maximize); diff --git a/src/input/cursor.c b/src/input/cursor.c index 7d2970f5..19128b85 100644 --- a/src/input/cursor.c +++ b/src/input/cursor.c @@ -148,7 +148,7 @@ handle_request_set_cursor(struct wl_listener *listener, void *data) { struct seat *seat = wl_container_of(listener, seat, request_set_cursor); - if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { + if (server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { /* Prevent setting a cursor image when moving or resizing */ return; } @@ -208,7 +208,7 @@ handle_request_set_shape(struct wl_listener *listener, void *data) struct wlr_seat_client *focused_client = seat->seat->pointer_state.focused_client; /* Prevent setting a cursor image when moving or resizing */ - if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { + if (server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { return; } @@ -267,10 +267,10 @@ handle_request_set_primary_selection(struct wl_listener *listener, void *data) static void process_cursor_move(uint32_t time) { - struct view *view = g_server.grabbed_view; + struct view *view = server.grabbed_view; - int x = g_server.grab_box.x + (g_server.seat.cursor->x - g_server.grab_x); - int y = g_server.grab_box.y + (g_server.seat.cursor->y - g_server.grab_y); + int x = server.grab_box.x + (server.seat.cursor->x - server.grab_x); + int y = server.grab_box.y + (server.seat.cursor->y - server.grab_y); /* Apply resistance for maximized/tiled view */ bool needs_untile = resistance_unsnap_apply(view, &x, &y); @@ -300,7 +300,7 @@ process_cursor_move(uint32_t time) resistance_move_apply(view, &x, &y); view_move(view, x, y); - overlay_update(&g_server.seat); + overlay_update(&server.seat); } static void @@ -310,8 +310,8 @@ process_cursor_resize(uint32_t time) static uint32_t last_resize_time = 0; static struct view *last_resize_view = NULL; - assert(g_server.grabbed_view); - if (g_server.grabbed_view == last_resize_view) { + assert(server.grabbed_view); + if (server.grabbed_view == last_resize_view) { int32_t refresh = 0; if (output_is_usable(last_resize_view->output)) { refresh = last_resize_view->output->wlr_output->refresh; @@ -327,43 +327,43 @@ process_cursor_resize(uint32_t time) } last_resize_time = time; - last_resize_view = g_server.grabbed_view; + last_resize_view = server.grabbed_view; - double dx = g_server.seat.cursor->x - g_server.grab_x; - double dy = g_server.seat.cursor->y - g_server.grab_y; + double dx = server.seat.cursor->x - server.grab_x; + double dy = server.seat.cursor->y - server.grab_y; - struct view *view = g_server.grabbed_view; + struct view *view = server.grabbed_view; struct wlr_box new_view_geo = view->current; - if (g_server.resize_edges & LAB_EDGE_TOP) { + if (server.resize_edges & LAB_EDGE_TOP) { /* Shift y to anchor bottom edge when resizing top */ - new_view_geo.y = g_server.grab_box.y + dy; - new_view_geo.height = g_server.grab_box.height - dy; - } else if (g_server.resize_edges & LAB_EDGE_BOTTOM) { - new_view_geo.height = g_server.grab_box.height + dy; + new_view_geo.y = server.grab_box.y + dy; + new_view_geo.height = server.grab_box.height - dy; + } else if (server.resize_edges & LAB_EDGE_BOTTOM) { + new_view_geo.height = server.grab_box.height + dy; } - if (g_server.resize_edges & LAB_EDGE_LEFT) { + if (server.resize_edges & LAB_EDGE_LEFT) { /* Shift x to anchor right edge when resizing left */ - new_view_geo.x = g_server.grab_box.x + dx; - new_view_geo.width = g_server.grab_box.width - dx; - } else if (g_server.resize_edges & LAB_EDGE_RIGHT) { - new_view_geo.width = g_server.grab_box.width + dx; + new_view_geo.x = server.grab_box.x + dx; + new_view_geo.width = server.grab_box.width - dx; + } else if (server.resize_edges & LAB_EDGE_RIGHT) { + new_view_geo.width = server.grab_box.width + dx; } resistance_resize_apply(view, &new_view_geo); view_adjust_size(view, &new_view_geo.width, &new_view_geo.height); - if (g_server.resize_edges & LAB_EDGE_TOP) { + if (server.resize_edges & LAB_EDGE_TOP) { /* After size adjustments, make sure to anchor bottom edge */ - new_view_geo.y = g_server.grab_box.y + - g_server.grab_box.height - new_view_geo.height; + new_view_geo.y = server.grab_box.y + + server.grab_box.height - new_view_geo.height; } - if (g_server.resize_edges & LAB_EDGE_LEFT) { + if (server.resize_edges & LAB_EDGE_LEFT) { /* After size adjustments, make sure to anchor bottom right */ - new_view_geo.x = g_server.grab_box.x + - g_server.grab_box.width - new_view_geo.width; + new_view_geo.x = server.grab_box.x + + server.grab_box.width - new_view_geo.width; } if (rc.resize_draw_contents) { @@ -536,12 +536,12 @@ static void cursor_update_common(const struct cursor_context *ctx, struct cursor_context *notified_ctx) { - struct seat *seat = &g_server.seat; + struct seat *seat = &server.seat; struct wlr_seat *wlr_seat = seat->seat; ssd_update_hovered_button(ctx->node); - if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { + if (server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { /* * Prevent updating focus/cursor image during * interactive move/resize, window switcher and @@ -565,8 +565,8 @@ cursor_update_common(const struct cursor_context *ctx, int lx, ly; wlr_scene_node_coords(seat->pressed.ctx.node, &lx, &ly); *notified_ctx = seat->pressed.ctx; - notified_ctx->sx = g_server.seat.cursor->x - lx; - notified_ctx->sy = g_server.seat.cursor->y - ly; + notified_ctx->sx = server.seat.cursor->x - lx; + notified_ctx->sy = server.seat.cursor->y - ly; } return; } @@ -623,21 +623,21 @@ bool cursor_process_motion(uint32_t time, double *sx, double *sy) { /* If the mode is non-passthrough, delegate to those functions. */ - if (g_server.input_mode == LAB_INPUT_STATE_MOVE) { + if (server.input_mode == LAB_INPUT_STATE_MOVE) { process_cursor_move(time); return false; - } else if (g_server.input_mode == LAB_INPUT_STATE_RESIZE) { + } else if (server.input_mode == LAB_INPUT_STATE_RESIZE) { process_cursor_resize(time); return false; } /* Otherwise, find view under the pointer and send the event along */ struct cursor_context ctx = get_cursor_context(); - struct seat *seat = &g_server.seat; + struct seat *seat = &server.seat; if (ctx.type == LAB_NODE_MENUITEM) { menu_process_cursor_motion(ctx.node); - cursor_set(&g_server.seat, LAB_CURSOR_DEFAULT); + cursor_set(&server.seat, LAB_CURSOR_DEFAULT); return false; } @@ -712,7 +712,7 @@ _cursor_update_focus(void) * Always focus the surface below the cursor when * followMouse=yes and followMouseRequiresMovement=no. */ - desktop_focus_view_or_surface(&g_server.seat, ctx.view, + desktop_focus_view_or_surface(&server.seat, ctx.view, ctx.surface, rc.raise_on_focus); } @@ -735,7 +735,7 @@ static void warp_cursor_to_constraint_hint(struct seat *seat, struct wlr_pointer_constraint_v1 *constraint) { - if (!g_server.active_view) { + if (!server.active_view) { return; } @@ -744,8 +744,8 @@ warp_cursor_to_constraint_hint(struct seat *seat, double sx = constraint->current.cursor_hint.x; double sy = constraint->current.cursor_hint.y; wlr_cursor_warp(seat->cursor, NULL, - g_server.active_view->current.x + sx, - g_server.active_view->current.y + sy); + server.active_view->current.x + sx, + server.active_view->current.y + sy); /* Make sure we are not sending unnecessary surface movements */ wlr_seat_pointer_warp(seat->seat, sx, sy); @@ -791,11 +791,11 @@ create_constraint(struct wl_listener *listener, void *data) struct constraint *constraint = znew(*constraint); constraint->constraint = wlr_constraint; - constraint->seat = &g_server.seat; + constraint->seat = &server.seat; constraint->destroy.notify = handle_constraint_destroy; wl_signal_add(&wlr_constraint->events.destroy, &constraint->destroy); - struct view *view = g_server.active_view; + struct view *view = server.active_view; if (view && view->surface == wlr_constraint->surface) { constrain_cursor(wlr_constraint); } @@ -805,7 +805,7 @@ void constrain_cursor(struct wlr_pointer_constraint_v1 *constraint) { - struct seat *seat = &g_server.seat; + struct seat *seat = &server.seat; if (seat->current_constraint == constraint) { return; } @@ -835,7 +835,7 @@ constrain_cursor(struct wlr_pointer_constraint_v1 static void apply_constraint(struct seat *seat, struct wlr_pointer *pointer, double *x, double *y) { - if (!g_server.active_view) { + if (!server.active_view) { return; } if (!seat->current_constraint @@ -848,8 +848,8 @@ apply_constraint(struct seat *seat, struct wlr_pointer *pointer, double *x, doub double sx = seat->cursor->x; double sy = seat->cursor->y; - sx -= g_server.active_view->current.x; - sy -= g_server.active_view->current.y; + sx -= server.active_view->current.x; + sy -= server.active_view->current.y; double sx_confined, sy_confined; if (!wlr_region_confine(&seat->current_constraint->region, sx, sy, @@ -949,7 +949,7 @@ handle_motion(struct wl_listener *listener, void *data) WL_POINTER_AXIS_SOURCE_CONTINUOUS, event->time_msec); } else { wlr_relative_pointer_manager_v1_send_relative_motion( - g_server.relative_pointer_manager, + server.relative_pointer_manager, seat->seat, (uint64_t)event->time_msec * 1000, event->delta_x, event->delta_y, event->unaccel_dx, event->unaccel_dy); @@ -989,12 +989,12 @@ handle_motion_absolute(struct wl_listener *listener, void *data) static void process_release_mousebinding(struct cursor_context *ctx, uint32_t button) { - if (g_server.input_mode == LAB_INPUT_STATE_CYCLE) { + if (server.input_mode == LAB_INPUT_STATE_CYCLE) { return; } struct mousebind *mousebind; - uint32_t modifiers = keyboard_get_all_modifiers(&g_server.seat); + uint32_t modifiers = keyboard_get_all_modifiers(&server.seat); wl_list_for_each(mousebind, &rc.mousebinds, link) { if (ctx->type == LAB_NODE_CLIENT @@ -1058,14 +1058,14 @@ static bool process_press_mousebinding(struct cursor_context *ctx, uint32_t button) { - if (g_server.input_mode == LAB_INPUT_STATE_CYCLE) { + if (server.input_mode == LAB_INPUT_STATE_CYCLE) { return false; } struct mousebind *mousebind; bool double_click = is_double_click(rc.doubleclick_time, button, ctx); bool consumed_by_frame_context = false; - uint32_t modifiers = keyboard_get_all_modifiers(&g_server.seat); + uint32_t modifiers = keyboard_get_all_modifiers(&server.seat); wl_list_for_each(mousebind, &rc.mousebinds, link) { if (ctx->type == LAB_NODE_CLIENT @@ -1145,7 +1145,7 @@ cursor_process_button_press(struct seat *seat, uint32_t button, uint32_t time_ms interactive_set_grab_context(&ctx); } - if (g_server.input_mode == LAB_INPUT_STATE_MENU) { + if (server.input_mode == LAB_INPUT_STATE_MENU) { /* * If menu was already opened on press, set a very small value * so subsequent release always closes menu or selects menu item. @@ -1213,7 +1213,7 @@ cursor_process_button_release(struct seat *seat, uint32_t button, cursor_context_save(&seat->pressed, NULL); - if (g_server.input_mode == LAB_INPUT_STATE_MENU) { + if (server.input_mode == LAB_INPUT_STATE_MENU) { /* TODO: take into account overflow of time_msec */ if (time_msec - press_msec > rc.menu_ignore_button_release_period) { if (ctx.type == LAB_NODE_MENUITEM) { @@ -1225,14 +1225,14 @@ cursor_process_button_release(struct seat *seat, uint32_t button, } return notify; } - if (g_server.input_mode == LAB_INPUT_STATE_CYCLE) { + if (server.input_mode == LAB_INPUT_STATE_CYCLE) { if (ctx.type == LAB_NODE_CYCLE_OSD_ITEM) { cycle_on_cursor_release(ctx.node); } return notify; } - if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { + if (server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { return notify; } @@ -1262,17 +1262,17 @@ cursor_finish_button_release(struct seat *seat, uint32_t button) lab_set_remove(&seat->bound_buttons, button); - if (g_server.input_mode == LAB_INPUT_STATE_MOVE - || g_server.input_mode == LAB_INPUT_STATE_RESIZE) { - if (resize_outlines_enabled(g_server.grabbed_view)) { - resize_outlines_finish(g_server.grabbed_view); + if (server.input_mode == LAB_INPUT_STATE_MOVE + || server.input_mode == LAB_INPUT_STATE_RESIZE) { + if (resize_outlines_enabled(server.grabbed_view)) { + resize_outlines_finish(server.grabbed_view); } /* Exit interactive move/resize mode */ - interactive_finish(g_server.grabbed_view); + interactive_finish(server.grabbed_view); return true; - } else if (g_server.grabbed_view) { + } else if (server.grabbed_view) { /* Button was released without starting move/resize */ - interactive_cancel(g_server.grabbed_view); + interactive_cancel(server.grabbed_view); } return false; @@ -1366,11 +1366,11 @@ process_cursor_axis(enum wl_pointer_axis orientation, double delta, double delta_discrete) { struct cursor_context ctx = get_cursor_context(); - uint32_t modifiers = keyboard_get_all_modifiers(&g_server.seat); + uint32_t modifiers = keyboard_get_all_modifiers(&server.seat); enum direction direction = LAB_DIRECTION_INVALID; struct scroll_info info = compare_delta(delta, delta_discrete, - &g_server.seat.accumulated_scrolls[orientation]); + &server.seat.accumulated_scrolls[orientation]); if (orientation == WL_POINTER_AXIS_HORIZONTAL_SCROLL) { if (info.direction < 0) { @@ -1504,7 +1504,7 @@ cursor_emulate_move(struct seat *seat, struct wlr_input_device *device, } wlr_relative_pointer_manager_v1_send_relative_motion( - g_server.relative_pointer_manager, + server.relative_pointer_manager, seat->seat, (uint64_t)time_msec * 1000, dx, dy, dx, dy); @@ -1633,7 +1633,7 @@ cursor_init(struct seat *seat) CONNECT_SIGNAL(seat->seat, seat, request_set_cursor); struct wlr_cursor_shape_manager_v1 *cursor_shape_manager = - wlr_cursor_shape_manager_v1_create(g_server.wl_display, + wlr_cursor_shape_manager_v1_create(server.wl_display, LAB_CURSOR_SHAPE_V1_VERSION); if (!cursor_shape_manager) { wlr_log(WLR_ERROR, "unable to create cursor_shape interface"); diff --git a/src/input/gestures.c b/src/input/gestures.c index 05a24243..7e65ea46 100644 --- a/src/input/gestures.c +++ b/src/input/gestures.c @@ -114,7 +114,7 @@ handle_hold_end(struct wl_listener *listener, void *data) void gestures_init(struct seat *seat) { - seat->pointer_gestures = wlr_pointer_gestures_v1_create(g_server.wl_display); + seat->pointer_gestures = wlr_pointer_gestures_v1_create(server.wl_display); CONNECT_SIGNAL(seat->cursor, seat, pinch_begin); CONNECT_SIGNAL(seat->cursor, seat, pinch_update); diff --git a/src/input/ime.c b/src/input/ime.c index f9e033c4..add29f92 100644 --- a/src/input/ime.c +++ b/src/input/ime.c @@ -227,7 +227,7 @@ update_popup_position(struct input_method_popup *popup) } struct wlr_box output_box; wlr_output_layout_get_box( - g_server.output_layout, output->wlr_output, &output_box); + server.output_layout, output->wlr_output, &output_box); /* Use xdg-positioner utilities to position popup */ struct wlr_xdg_positioner_rules rules = { @@ -582,14 +582,14 @@ input_method_relay_create(struct seat *seat) relay->seat = seat; wl_list_init(&relay->text_inputs); wl_list_init(&relay->popups); - relay->popup_tree = lab_wlr_scene_tree_create(&g_server.scene->tree); + relay->popup_tree = lab_wlr_scene_tree_create(&server.scene->tree); relay->new_text_input.notify = handle_new_text_input; - wl_signal_add(&g_server.text_input_manager->events.text_input, + wl_signal_add(&server.text_input_manager->events.text_input, &relay->new_text_input); relay->new_input_method.notify = handle_new_input_method; - wl_signal_add(&g_server.input_method_manager->events.input_method, + wl_signal_add(&server.input_method_manager->events.input_method, &relay->new_input_method); relay->focused_surface_destroy.notify = handle_focused_surface_destroy; diff --git a/src/input/keyboard.c b/src/input/keyboard.c index f859eb2b..41fab773 100644 --- a/src/input/keyboard.c +++ b/src/input/keyboard.c @@ -54,7 +54,7 @@ keyboard_reset_current_keybind(void) static void change_vt(unsigned int vt) { - wlr_session_change_vt(g_server.session, vt); + wlr_session_change_vt(server.session, vt); } uint32_t @@ -133,14 +133,14 @@ handle_modifiers(struct wl_listener *listener, void *data) struct seat *seat = keyboard->base.seat; struct wlr_keyboard *wlr_keyboard = keyboard->wlr_keyboard; - if (g_server.input_mode == LAB_INPUT_STATE_MOVE) { + if (server.input_mode == LAB_INPUT_STATE_MOVE) { /* Any change to the modifier state re-enable region snap */ seat->region_prevent_snap = false; /* Pressing/releasing modifier key may show/hide region overlay */ overlay_update(seat); } - bool cycling = g_server.input_mode == LAB_INPUT_STATE_CYCLE; + bool cycling = server.input_mode == LAB_INPUT_STATE_CYCLE; if ((cycling || seat->workspace_osd_shown_by_modifier) && !keyboard_get_all_modifiers(seat)) { @@ -195,7 +195,7 @@ match_keybinding_for_sym(uint32_t modifiers, if (modifiers ^ keybind->modifiers) { continue; } - if (view_inhibits_actions(g_server.active_view, &keybind->actions)) { + if (view_inhibits_actions(server.active_view, &keybind->actions)) { continue; } if (sym == XKB_KEY_NoSymbol) { @@ -416,7 +416,7 @@ handle_change_vt_key(struct keyboard *keyboard, static void handle_menu_keys(struct keysyms *syms) { - assert(g_server.input_mode == LAB_INPUT_STATE_MENU); + assert(server.input_mode == LAB_INPUT_STATE_MENU); for (int i = 0; i < syms->nr_syms; i++) { switch (syms->syms[i]) { @@ -484,7 +484,7 @@ handle_compositor_keybindings(struct keyboard *keyboard, { struct wlr_keyboard *wlr_keyboard = keyboard->wlr_keyboard; struct keyinfo keyinfo = get_keyinfo(wlr_keyboard, event->keycode); - bool locked = g_server.session_lock_manager->locked; + bool locked = server.session_lock_manager->locked; key_state_set_pressed(event->keycode, event->state == WL_KEYBOARD_KEY_STATE_PRESSED); @@ -515,11 +515,11 @@ handle_compositor_keybindings(struct keyboard *keyboard, * _all_ key press/releases are registered */ if (!locked) { - if (g_server.input_mode == LAB_INPUT_STATE_MENU) { + if (server.input_mode == LAB_INPUT_STATE_MENU) { key_state_store_pressed_key_as_bound(event->keycode); handle_menu_keys(&keyinfo.translated); return LAB_KEY_HANDLED_TRUE; - } else if (g_server.input_mode == LAB_INPUT_STATE_CYCLE) { + } else if (server.input_mode == LAB_INPUT_STATE_CYCLE) { if (handle_cycle_view_key(&keyinfo)) { key_state_store_pressed_key_as_bound(event->keycode); return LAB_KEY_HANDLED_TRUE; @@ -580,7 +580,7 @@ start_keybind_repeat(struct keyboard *keyboard, keyboard->keybind_repeat_keycode = event->keycode; keyboard->keybind_repeat_rate = wlr_keyboard->repeat_info.rate; keyboard->keybind_repeat = wl_event_loop_add_timer( - g_server.wl_event_loop, handle_keybind_repeat, keyboard); + server.wl_event_loop, handle_keybind_repeat, keyboard); wl_event_source_timer_update(keyboard->keybind_repeat, wlr_keyboard->repeat_info.delay); } @@ -724,15 +724,15 @@ reset_window_keyboard_layout_groups(void) * but let's keep it simple for now and just reset them all. */ struct view *view; - for_each_view(view, &g_server.views, LAB_VIEW_CRITERIA_NONE) { + for_each_view(view, &server.views, LAB_VIEW_CRITERIA_NONE) { view->keyboard_layout = 0; } - struct view *active_view = g_server.active_view; + struct view *active_view = server.active_view; if (!active_view) { return; } - keyboard_update_layout(&g_server.seat, active_view->keyboard_layout); + keyboard_update_layout(&server.seat, active_view->keyboard_layout); } /* diff --git a/src/input/tablet-pad.c b/src/input/tablet-pad.c index 2b1e34f4..d7c7f6d9 100644 --- a/src/input/tablet-pad.c +++ b/src/input/tablet-pad.c @@ -183,9 +183,9 @@ tablet_pad_create(struct seat *seat, struct wlr_input_device *wlr_device) pad->seat = seat; pad->wlr_input_device = wlr_device; pad->pad = wlr_tablet_pad_from_input_device(wlr_device); - if (g_server.tablet_manager) { + if (server.tablet_manager) { pad->pad_v2 = wlr_tablet_pad_create( - g_server.tablet_manager, seat->seat, wlr_device); + server.tablet_manager, seat->seat, wlr_device); } pad->pad->data = pad; wlr_log(WLR_INFO, "tablet pad capabilities: %zu button(s) %zu strip(s) %zu ring(s)", diff --git a/src/input/tablet.c b/src/input/tablet.c index 107e8c27..186c9adf 100644 --- a/src/input/tablet.c +++ b/src/input/tablet.c @@ -44,7 +44,7 @@ handle_set_cursor(struct wl_listener *listener, void *data) struct wlr_seat_client *focused_client = seat->seat->pointer_state.focused_client; - if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { + if (server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { return; } @@ -76,7 +76,7 @@ tablet_tool_create(struct seat *seat, struct drawing_tablet_tool *tool = znew(*tool); tool->seat = seat; tool->tool_v2 = - wlr_tablet_tool_create(g_server.tablet_manager, + wlr_tablet_tool_create(server.tablet_manager, seat->seat, wlr_tablet_tool); wlr_tablet_tool->data = tool; wlr_log(WLR_INFO, "tablet tool capabilities:%s%s%s%s%s%s", @@ -239,7 +239,7 @@ tablet_get_coords(struct drawing_tablet *tablet, struct drawing_tablet_tool *too double sx, sy; struct wlr_scene_node *node = - wlr_scene_node_at(&g_server.scene->tree.node, lx, ly, &sx, &sy); + wlr_scene_node_at(&server.scene->tree.node, lx, ly, &sx, &sy); /* find the surface and return it if it accepts tablet events */ struct wlr_surface *surface = lab_wlr_surface_from_node(node); @@ -449,7 +449,7 @@ handle_tablet_tool_axis(struct wl_listener *listener, void *data) * Note that surface is also NULL when mouse emulation is forced. */ if (!is_down_mouse_emulation && ((surface - && g_server.input_mode == LAB_INPUT_STATE_PASSTHROUGH) + && server.input_mode == LAB_INPUT_STATE_PASSTHROUGH) || wlr_tablet_tool_v2_has_implicit_grab(tool->tool_v2))) { /* motion seems to be supported by all tools */ notify_motion(tablet, tool, surface, x, y, dx, dy, ev->time_msec); @@ -719,9 +719,9 @@ tablet_create(struct seat *seat, struct wlr_input_device *wlr_device) tablet->wlr_input_device = wlr_device; tablet->tablet = wlr_tablet_from_input_device(wlr_device); tablet->tablet->data = tablet; - if (g_server.tablet_manager) { + if (server.tablet_manager) { tablet->tablet_v2 = wlr_tablet_create( - g_server.tablet_manager, seat->seat, wlr_device); + server.tablet_manager, seat->seat, wlr_device); } wlr_log(WLR_INFO, "tablet dimensions: %.2fmm x %.2fmm", tablet->tablet->width_mm, tablet->tablet->height_mm); diff --git a/src/input/touch.c b/src/input/touch.c index bddbc8e0..8344f971 100644 --- a/src/input/touch.c +++ b/src/input/touch.c @@ -52,7 +52,7 @@ touch_get_coords(struct seat *seat, struct wlr_touch *touch, double x, double y, * This matches normal pointer/mouse behavior where the first click on * a surface closes a root/client menu. */ - if (g_server.input_mode == LAB_INPUT_STATE_MENU) { + if (server.input_mode == LAB_INPUT_STATE_MENU) { return NULL; } @@ -63,7 +63,7 @@ touch_get_coords(struct seat *seat, struct wlr_touch *touch, double x, double y, double sx, sy; struct wlr_scene_node *node = - wlr_scene_node_at(&g_server.scene->tree.node, lx, ly, &sx, &sy); + wlr_scene_node_at(&server.scene->tree.node, lx, ly, &sx, &sy); *x_offset = lx - sx; *y_offset = ly - sy; diff --git a/src/interactive.c b/src/interactive.c index d3894a3f..f4d8eea1 100644 --- a/src/interactive.c +++ b/src/interactive.c @@ -38,20 +38,20 @@ max_move_scale(double pos_cursor, double pos_old, double size_old, void interactive_anchor_to_cursor(struct wlr_box *geo) { - assert(g_server.input_mode == LAB_INPUT_STATE_MOVE); + assert(server.input_mode == LAB_INPUT_STATE_MOVE); if (wlr_box_empty(geo)) { return; } /* Resize grab_box while anchoring it to grab_{x,y} */ - g_server.grab_box.x = max_move_scale(g_server.grab_x, g_server.grab_box.x, - g_server.grab_box.width, geo->width); - g_server.grab_box.y = max_move_scale(g_server.grab_y, g_server.grab_box.y, - g_server.grab_box.height, geo->height); - g_server.grab_box.width = geo->width; - g_server.grab_box.height = geo->height; + server.grab_box.x = max_move_scale(server.grab_x, server.grab_box.x, + server.grab_box.width, geo->width); + server.grab_box.y = max_move_scale(server.grab_y, server.grab_box.y, + server.grab_box.height, geo->height); + server.grab_box.width = geo->width; + server.grab_box.height = geo->height; - geo->x = g_server.grab_box.x + (g_server.seat.cursor->x - g_server.grab_x); - geo->y = g_server.grab_box.y + (g_server.seat.cursor->y - g_server.grab_y); + geo->x = server.grab_box.x + (server.seat.cursor->x - server.grab_x); + geo->y = server.grab_box.y + (server.seat.cursor->y - server.grab_y); } /* @@ -65,16 +65,16 @@ interactive_set_grab_context(const struct cursor_context *ctx) if (!ctx->view) { return; } - if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { + if (server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { return; } - g_server.grabbed_view = ctx->view; - g_server.grab_x = g_server.seat.cursor->x; - g_server.grab_y = g_server.seat.cursor->y; - g_server.grab_box = ctx->view->current; - g_server.resize_edges = - cursor_get_resize_edges(g_server.seat.cursor, ctx); + server.grabbed_view = ctx->view; + server.grab_x = server.seat.cursor->x; + server.grab_y = server.seat.cursor->y; + server.grab_box = ctx->view->current; + server.resize_edges = + cursor_get_resize_edges(server.seat.cursor, ctx); } void @@ -86,10 +86,10 @@ interactive_begin(struct view *view, enum input_mode mode, enum lab_edge edges) * the compositor stops propagating pointer events to clients and * instead consumes them itself, to move or resize windows. */ - struct seat *seat = &g_server.seat; + struct seat *seat = &server.seat; - if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH - || view != g_server.grabbed_view) { + if (server.input_mode != LAB_INPUT_STATE_PASSTHROUGH + || view != server.grabbed_view) { return; } @@ -137,7 +137,7 @@ interactive_begin(struct view *view, enum input_mode mode, enum lab_edge edges) * Otherwise, they were set already from cursor context. */ if (edges != LAB_EDGE_NONE) { - g_server.resize_edges = edges; + server.resize_edges = edges; } /* @@ -146,15 +146,15 @@ interactive_begin(struct view *view, enum input_mode mode, enum lab_edge edges) * keep the same geometry as the starting point. */ enum view_axis maximized = view->maximized; - if (g_server.resize_edges & LAB_EDGES_LEFT_RIGHT) { + if (server.resize_edges & LAB_EDGES_LEFT_RIGHT) { maximized &= ~VIEW_AXIS_HORIZONTAL; } - if (g_server.resize_edges & LAB_EDGES_TOP_BOTTOM) { + if (server.resize_edges & LAB_EDGES_TOP_BOTTOM) { maximized &= ~VIEW_AXIS_VERTICAL; } view_set_maximized(view, maximized); view_set_untiled(view); - cursor_shape = cursor_get_from_edge(g_server.resize_edges); + cursor_shape = cursor_get_from_edge(server.resize_edges); break; } default: @@ -198,7 +198,7 @@ edge_from_cursor(struct seat *seat, struct output **dest_output, *edge1 = LAB_EDGE_NONE; *edge2 = LAB_EDGE_NONE; - if (!view_is_floating(g_server.grabbed_view)) { + if (!view_is_floating(server.grabbed_view)) { return false; } @@ -220,25 +220,25 @@ edge_from_cursor(struct seat *seat, struct output **dest_output, int bottom_range = rc.snap_edge_range_outer; int left_range = rc.snap_edge_range_outer; int right_range = rc.snap_edge_range_outer; - if (wlr_output_layout_adjacent_output(g_server.output_layout, WLR_DIRECTION_UP, + if (wlr_output_layout_adjacent_output(server.output_layout, WLR_DIRECTION_UP, output->wlr_output, cursor_x, cursor_y)) { top_range = rc.snap_edge_range_inner; } - if (wlr_output_layout_adjacent_output(g_server.output_layout, WLR_DIRECTION_DOWN, + if (wlr_output_layout_adjacent_output(server.output_layout, WLR_DIRECTION_DOWN, output->wlr_output, cursor_x, cursor_y)) { bottom_range = rc.snap_edge_range_inner; } - if (wlr_output_layout_adjacent_output(g_server.output_layout, WLR_DIRECTION_LEFT, + if (wlr_output_layout_adjacent_output(server.output_layout, WLR_DIRECTION_LEFT, output->wlr_output, cursor_x, cursor_y)) { left_range = rc.snap_edge_range_inner; } - if (wlr_output_layout_adjacent_output(g_server.output_layout, WLR_DIRECTION_RIGHT, + if (wlr_output_layout_adjacent_output(server.output_layout, WLR_DIRECTION_RIGHT, output->wlr_output, cursor_x, cursor_y)) { right_range = rc.snap_edge_range_inner; } /* Translate into output local coordinates */ - wlr_output_layout_output_coords(g_server.output_layout, + wlr_output_layout_output_coords(server.output_layout, output->wlr_output, &cursor_x, &cursor_y); struct wlr_box *area = &output->usable_area; @@ -283,7 +283,7 @@ snap_to_edge(struct view *view) { struct output *output; enum lab_edge edge1, edge2; - if (!edge_from_cursor(&g_server.seat, &output, &edge1, &edge2)) { + if (!edge_from_cursor(&server.seat, &output, &edge1, &edge2)) { return false; } enum lab_edge edge = edge1 | edge2; @@ -320,11 +320,11 @@ interactive_finish(struct view *view) { assert(view); - if (g_server.grabbed_view != view) { + if (server.grabbed_view != view) { return; } - if (g_server.input_mode == LAB_INPUT_STATE_MOVE) { + if (server.input_mode == LAB_INPUT_STATE_MOVE) { if (!snap_to_region(view)) { snap_to_edge(view); } @@ -343,25 +343,25 @@ interactive_cancel(struct view *view) { assert(view); - if (g_server.grabbed_view != view) { + if (server.grabbed_view != view) { return; } - g_server.grabbed_view = NULL; + server.grabbed_view = NULL; /* * It's possible that grabbed_view was set but interactive_begin() * wasn't called yet. In that case, we are done. */ - if (g_server.input_mode != LAB_INPUT_STATE_MOVE - && g_server.input_mode != LAB_INPUT_STATE_RESIZE) { + if (server.input_mode != LAB_INPUT_STATE_MOVE + && server.input_mode != LAB_INPUT_STATE_RESIZE) { return; } - overlay_finish(&g_server.seat); + overlay_finish(&server.seat); resize_indicator_hide(view); /* Restore keyboard/pointer focus */ - seat_focus_override_end(&g_server.seat, /*restore_focus*/ true); + seat_focus_override_end(&server.seat, /*restore_focus*/ true); } diff --git a/src/layers.c b/src/layers.c index 0abbd09b..dba103f4 100644 --- a/src/layers.c +++ b/src/layers.c @@ -79,7 +79,7 @@ layers_arrange(struct output *output) apply_override(output, &usable_area); struct wlr_scene_output *scene_output = - wlr_scene_get_scene_output(g_server.scene, output->wlr_output); + wlr_scene_get_scene_output(server.scene, output->wlr_output); if (!scene_output) { wlr_log(WLR_DEBUG, "no wlr_scene_output"); return; @@ -142,7 +142,7 @@ has_exclusive_interactivity(struct wlr_scene_layer_surface_v1 *scene) static void try_to_focus_next_layer_or_toplevel(void) { - struct seat *seat = &g_server.seat; + struct seat *seat = &server.seat; struct output *output = output_nearest_to_cursor(); if (!output_is_usable(output)) { goto no_output; @@ -277,7 +277,7 @@ handle_surface_commit(struct wl_listener *listener, void *data) * cursor-button-press). */ if (is_on_demand(layer_surface)) { - struct seat *seat = &g_server.seat; + struct seat *seat = &server.seat; if (seat->focused_layer == layer_surface) { /* * Must be change from EXCLUSIVE to ON_DEMAND, @@ -288,7 +288,7 @@ handle_surface_commit(struct wl_listener *listener, void *data) goto out; } /* Handle EXCLUSIVE and NONE requests */ - struct seat *seat = &g_server.seat; + struct seat *seat = &server.seat; layer_try_set_focus(seat, layer_surface); } out: @@ -310,7 +310,7 @@ handle_node_destroy(struct wl_listener *listener, void *data) struct lab_layer_surface *layer = wl_container_of(listener, layer, node_destroy); - struct seat *seat = &g_server.seat; + struct seat *seat = &server.seat; /* * If the surface of this node has the current keyboard focus, then we @@ -372,7 +372,7 @@ handle_unmap(struct wl_listener *listener, void *data) if (layer_surface->output) { output_update_usable_area(layer_surface->output->data); } - struct seat *seat = &g_server.seat; + struct seat *seat = &server.seat; if (seat->focused_layer == layer_surface) { try_to_focus_next_layer_or_toplevel(); } @@ -422,7 +422,7 @@ handle_map(struct wl_listener *listener, void *data) return; } - struct seat *seat = &g_server.seat; + struct seat *seat = &server.seat; layer_try_set_focus(seat, layer->scene_layer_surface->layer_surface); } @@ -437,7 +437,7 @@ handle_popup_destroy(struct wl_listener *listener, void *data) { struct lab_layer_popup *popup = wl_container_of(listener, popup, destroy); - struct seat *seat = &g_server.seat; + struct seat *seat = &server.seat; struct wlr_xdg_popup *_popup, *tmp; wl_list_for_each_safe(_popup, tmp, &popup->wlr_popup->base->popups, link) { @@ -527,7 +527,7 @@ handle_popup_commit(struct wl_listener *listener, void *data) popup->commit.notify = NULL; /* Force focus when popup was triggered by IPC */ - struct seat *seat = &g_server.seat; + struct seat *seat = &server.seat; bool requesting_grab = !!popup->wlr_popup->seat; if (requesting_grab) { if (surface_is_focused(seat, popup->wlr_popup->parent)) { @@ -606,7 +606,7 @@ move_popup_to_top_layer(struct lab_layer_surface *toplevel, toplevel->scene_layer_surface->layer_surface->output; struct output *output = (struct output *)wlr_output->data; struct wlr_box box = { 0 }; - wlr_output_layout_get_box(g_server.output_layout, wlr_output, &box); + wlr_output_layout_get_box(server.output_layout, wlr_output, &box); int lx = toplevel->scene_layer_surface->tree->node.x + box.x; int ly = toplevel->scene_layer_surface->tree->node.y + box.y; @@ -631,7 +631,7 @@ handle_new_popup(struct wl_listener *listener, void *data) wlr_scene_node_coords(&surface->tree->node, &lx, &ly); struct wlr_box output_box = { 0 }; - wlr_output_layout_get_box(g_server.output_layout, + wlr_output_layout_get_box(server.output_layout, output->wlr_output, &output_box); /* @@ -727,15 +727,15 @@ handle_new_layer_surface(struct wl_listener *listener, void *data) void layers_init(void) { - g_server.layer_shell = wlr_layer_shell_v1_create(g_server.wl_display, + server.layer_shell = wlr_layer_shell_v1_create(server.wl_display, LAB_LAYERSHELL_VERSION); - g_server.new_layer_surface.notify = handle_new_layer_surface; - wl_signal_add(&g_server.layer_shell->events.new_surface, - &g_server.new_layer_surface); + server.new_layer_surface.notify = handle_new_layer_surface; + wl_signal_add(&server.layer_shell->events.new_surface, + &server.new_layer_surface); } void layers_finish(void) { - wl_list_remove(&g_server.new_layer_surface.link); + wl_list_remove(&server.new_layer_surface.link); } diff --git a/src/magnifier.c b/src/magnifier.c index e635f722..475d7d9c 100644 --- a/src/magnifier.c +++ b/src/magnifier.c @@ -41,7 +41,7 @@ box_logical_to_physical(struct wlr_box *box, struct wlr_output *output) void magnifier_draw(struct output *output, struct wlr_buffer *output_buffer, struct wlr_box *damage) { - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; bool fullscreen = (rc.mag_width == -1 || rc.mag_height == -1); struct wlr_box output_box = { @@ -50,9 +50,9 @@ magnifier_draw(struct output *output, struct wlr_buffer *output_buffer, struct w }; /* Cursor position in per-output logical coordinate */ - double cursor_logical_x = g_server.seat.cursor->x; - double cursor_logical_y = g_server.seat.cursor->y; - wlr_output_layout_output_coords(g_server.output_layout, + double cursor_logical_x = server.seat.cursor->x; + double cursor_logical_y = server.seat.cursor->y; + wlr_output_layout_output_coords(server.output_layout, output->wlr_output, &cursor_logical_x, &cursor_logical_y); /* Cursor position in per-output physical coordinate */ struct wlr_box cursor_pos = { @@ -95,7 +95,7 @@ magnifier_draw(struct output *output, struct wlr_buffer *output_buffer, struct w } if (!tmp_buffer) { tmp_buffer = wlr_allocator_create_buffer( - g_server.allocator, mag_box.width, mag_box.height, + server.allocator, mag_box.width, mag_box.height, &output->wlr_output->swapchain->format); } if (!tmp_buffer) { @@ -104,7 +104,7 @@ magnifier_draw(struct output *output, struct wlr_buffer *output_buffer, struct w } if (!tmp_texture) { - tmp_texture = wlr_texture_from_buffer(g_server.renderer, tmp_buffer); + tmp_texture = wlr_texture_from_buffer(server.renderer, tmp_buffer); } if (!tmp_texture) { wlr_log(WLR_ERROR, "Failed to allocate temporary magnifier texture"); @@ -115,7 +115,7 @@ magnifier_draw(struct output *output, struct wlr_buffer *output_buffer, struct w /* Extract source region into temporary buffer */ struct wlr_render_pass *tmp_render_pass = wlr_renderer_begin_buffer_pass( - g_server.renderer, tmp_buffer, NULL); + server.renderer, tmp_buffer, NULL); if (!tmp_render_pass) { wlr_log(WLR_ERROR, "Failed to begin magnifier render pass"); return; @@ -123,7 +123,7 @@ magnifier_draw(struct output *output, struct wlr_buffer *output_buffer, struct w wlr_buffer_lock(output_buffer); struct wlr_texture *output_texture = wlr_texture_from_buffer( - g_server.renderer, output_buffer); + server.renderer, output_buffer); if (!output_texture) { goto cleanup; } @@ -150,7 +150,7 @@ magnifier_draw(struct output *output, struct wlr_buffer *output_buffer, struct w /* Render to the output buffer itself */ tmp_render_pass = wlr_renderer_begin_buffer_pass( - g_server.renderer, output_buffer, NULL); + server.renderer, output_buffer, NULL); if (!tmp_render_pass) { wlr_log(WLR_ERROR, "Failed to begin second magnifier render pass"); goto cleanup; @@ -223,7 +223,7 @@ output_wants_magnification(struct output *output) { static double x = -1; static double y = -1; - struct wlr_cursor *cursor = g_server.seat.cursor; + struct wlr_cursor *cursor = server.seat.cursor; if (!magnify_on) { x = -1; y = -1; @@ -241,8 +241,8 @@ static void enable_magnifier(bool enable) { magnify_on = enable; - g_server.scene->WLR_PRIVATE.direct_scanout = enable ? false - : g_server.direct_scanout_enabled; + server.scene->WLR_PRIVATE.direct_scanout = enable ? false + : server.direct_scanout_enabled; } /* Toggles magnification on and off */ diff --git a/src/main.c b/src/main.c index 363a2f7a..9a21f4a9 100644 --- a/src/main.c +++ b/src/main.c @@ -23,7 +23,7 @@ * struct just adds noise to the code. */ struct rcxml rc = { 0 }; -struct server g_server = { 0 }; +struct server server = { 0 }; static const struct option long_options[] = { {"config", required_argument, NULL, 'c'}, @@ -142,11 +142,11 @@ idle_callback(void *data) /* Start session-manager if one is specified by -S|--session */ if (ctx->primary_client) { - g_server.primary_client_pid = spawn_primary_client(ctx->primary_client); - if (g_server.primary_client_pid < 0) { + server.primary_client_pid = spawn_primary_client(ctx->primary_client); + if (server.primary_client_pid < 0) { wlr_log(WLR_ERROR, "fatal error starting primary client: %s", ctx->primary_client); - wl_display_terminate(g_server.wl_display); + wl_display_terminate(server.wl_display); return; } } @@ -260,7 +260,7 @@ main(int argc, char *argv[]) struct theme theme = { 0 }; theme_init(&theme, rc.theme_name); rc.theme = &theme; - g_server.theme = &theme; + server.theme = &theme; menu_init(); @@ -269,9 +269,9 @@ main(int argc, char *argv[]) .primary_client = primary_client, .startup_cmd = startup_cmd }; - wl_event_loop_add_idle(g_server.wl_event_loop, idle_callback, &idle_ctx); + wl_event_loop_add_idle(server.wl_event_loop, idle_callback, &idle_ctx); - wl_display_run(g_server.wl_display); + wl_display_run(server.wl_display); session_shutdown(); diff --git a/src/menu/menu.c b/src/menu/menu.c index 98185ce8..f961f8c4 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -57,7 +57,7 @@ static bool is_unique_id(const char *id) { struct menu *menu; - wl_list_for_each(menu, &g_server.menus, link) { + wl_list_for_each(menu, &server.menus, link) { if (!strcmp(menu->id, id)) { return false; } @@ -74,7 +74,7 @@ menu_create(struct menu *parent, const char *id, } struct menu *menu = znew(*menu); - wl_list_append(&g_server.menus, &menu->link); + wl_list_append(&server.menus, &menu->link); wl_list_init(&menu->menuitems); menu->id = xstrdup(id); @@ -91,7 +91,7 @@ menu_get_by_id(const char *id) return NULL; } struct menu *menu; - wl_list_for_each(menu, &g_server.menus, link) { + wl_list_for_each(menu, &server.menus, link) { if (!strcmp(menu->id, id)) { return menu; } @@ -124,7 +124,7 @@ static void validate(void) { struct menu *menu; - wl_list_for_each(menu, &g_server.menus, link) { + wl_list_for_each(menu, &server.menus, link) { validate_menu(menu); } } @@ -135,7 +135,7 @@ item_create(struct menu *menu, const char *text, const char *icon_name, bool sho assert(menu); assert(text); - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; struct menuitem *menuitem = znew(*menuitem); menuitem->parent = menu; menuitem->selectable = true; @@ -166,7 +166,7 @@ item_create_scene_for_state(struct menuitem *item, float *text_color, float *bg_color) { struct menu *menu = item->parent; - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; /* Tree to hold background and label buffers */ struct wlr_scene_tree *tree = lab_wlr_scene_tree_create(item->tree); @@ -242,7 +242,7 @@ item_create_scene(struct menuitem *menuitem, int *item_y) assert(menuitem); assert(menuitem->type == LAB_MENU_ITEM); struct menu *menu = menuitem->parent; - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; /* Menu item root node */ menuitem->tree = lab_wlr_scene_tree_create(menu->scene_tree); @@ -291,7 +291,7 @@ separator_create_scene(struct menuitem *menuitem, int *item_y) assert(menuitem); assert(menuitem->type == LAB_MENU_SEPARATOR_LINE); struct menu *menu = menuitem->parent; - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; /* Menu item root node */ menuitem->tree = lab_wlr_scene_tree_create(menu->scene_tree); @@ -337,7 +337,7 @@ title_create_scene(struct menuitem *menuitem, int *item_y) assert(menuitem); assert(menuitem->type == LAB_MENU_TITLE); struct menu *menu = menuitem->parent; - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; float *bg_color = theme->menu_title_bg_color; float *text_color = theme->menu_title_text_color; @@ -411,11 +411,11 @@ static void menu_create_scene(struct menu *menu) { struct menuitem *item; - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; assert(!menu->scene_tree); - menu->scene_tree = lab_wlr_scene_tree_create(g_server.menu_tree); + menu->scene_tree = lab_wlr_scene_tree_create(server.menu_tree); wlr_scene_node_set_enabled(&menu->scene_tree->node, false); /* Menu width is the maximum item width, capped by menu.width.{min,max} */ @@ -780,7 +780,7 @@ menu_hide_submenu(const char *id) if (!hide_menu) { return; } - wl_list_for_each(menu, &g_server.menus, link) { + wl_list_for_each(menu, &server.menus, link) { struct menuitem *item, *next; wl_list_for_each_safe(item, next, &menu->menuitems, link) { if (item->submenu == hide_menu) { @@ -821,8 +821,8 @@ update_client_send_to_menu(void) * GoToDesktop will be called as part of the action. */ struct buf buf = BUF_INIT; - wl_list_for_each(workspace, &g_server.workspaces.all, link) { - if (workspace == g_server.workspaces.current) { + wl_list_for_each(workspace, &server.workspaces.all, link) { + if (workspace == server.workspaces.current) { buf_add_fmt(&buf, ">%s<", workspace->name); } else { buf_add(&buf, workspace->name); @@ -866,20 +866,20 @@ update_client_list_combined_menu(void) struct view *view; struct buf buffer = BUF_INIT; - wl_list_for_each(workspace, &g_server.workspaces.all, link) { - buf_add_fmt(&buffer, workspace == g_server.workspaces.current ? ">%s<" : "%s", + wl_list_for_each(workspace, &server.workspaces.all, link) { + buf_add_fmt(&buffer, workspace == server.workspaces.current ? ">%s<" : "%s", workspace->name); separator_create(menu, buffer.data); buf_clear(&buffer); - wl_list_for_each(view, &g_server.views, link) { + wl_list_for_each(view, &server.views, link) { if (view->workspace == workspace) { if (!view->foreign_toplevel || string_null_or_empty(view->title)) { continue; } - if (view == g_server.active_view) { + if (view == server.active_view) { buf_add(&buffer, "*"); } if (view->minimized) { @@ -966,7 +966,7 @@ init_windowmenu(void) void menu_init(void) { - wl_list_init(&g_server.menus); + wl_list_init(&server.menus); /* Just create placeholder. Contents will be created when launched */ menu_create(NULL, "client-list-combined-menu", _("Windows")); @@ -982,7 +982,7 @@ static void nullify_item_pointing_to_this_menu(struct menu *menu) { struct menu *iter; - wl_list_for_each(iter, &g_server.menus, link) { + wl_list_for_each(iter, &server.menus, link) { struct menuitem *item; wl_list_for_each(item, &iter->menuitems, link) { if (item->submenu == menu) { @@ -1013,7 +1013,7 @@ menu_free(struct menu *menu) /* Keep items clean on pipemenu destruction */ nullify_item_pointing_to_this_menu(menu); - if (g_server.menu_current == menu) { + if (server.menu_current == menu) { menu_close_root(); } @@ -1046,7 +1046,7 @@ void menu_finish(void) { struct menu *menu, *tmp_menu; - wl_list_for_each_safe(menu, tmp_menu, &g_server.menus, link) { + wl_list_for_each_safe(menu, tmp_menu, &server.menus, link) { menu_free(menu); } } @@ -1055,8 +1055,8 @@ void menu_on_view_destroy(struct view *view) { /* If the view being destroy has an open window menu, then close it */ - if (g_server.menu_current - && g_server.menu_current->triggered_by_view == view) { + if (server.menu_current + && server.menu_current->triggered_by_view == view) { menu_close_root(); } @@ -1108,10 +1108,10 @@ static void reset_pipemenus(void) { wlr_log(WLR_DEBUG, "number of menus before close=%d", - wl_list_length(&g_server.menus)); + wl_list_length(&server.menus)); struct menu *iter, *tmp; - wl_list_for_each_safe(iter, tmp, &g_server.menus, link) { + wl_list_for_each_safe(iter, tmp, &server.menus, link) { if (iter->is_pipemenu_child) { /* Destroy submenus of pipemenus */ menu_free(iter); @@ -1125,7 +1125,7 @@ reset_pipemenus(void) } wlr_log(WLR_DEBUG, "number of menus after close=%d", - wl_list_length(&g_server.menus)); + wl_list_length(&server.menus)); } static void @@ -1179,11 +1179,11 @@ menu_open_root(struct menu *menu, int x, int y) { assert(menu); - if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { + if (server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { return; } - assert(!g_server.menu_current); + assert(!server.menu_current); struct wlr_box anchor_rect = {.x = x, .y = y}; if (menu->execute) { @@ -1192,9 +1192,9 @@ menu_open_root(struct menu *menu, int x, int y) open_menu(menu, anchor_rect); } - g_server.menu_current = menu; + server.menu_current = menu; selected_item = NULL; - seat_focus_override_begin(&g_server.seat, + seat_focus_override_begin(&server.seat, LAB_INPUT_STATE_MENU, LAB_CURSOR_DEFAULT); } @@ -1307,10 +1307,10 @@ open_pipemenu_async(struct menu *pipemenu, struct wlr_box anchor_rect) ctx->pipemenu = pipemenu; pipemenu->pipe_ctx = ctx; - ctx->event_read = wl_event_loop_add_fd(g_server.wl_event_loop, + ctx->event_read = wl_event_loop_add_fd(server.wl_event_loop, pipe_fd, WL_EVENT_READABLE, handle_pipemenu_readable, ctx); - ctx->event_timeout = wl_event_loop_add_timer(g_server.wl_event_loop, + ctx->event_timeout = wl_event_loop_add_timer(server.wl_event_loop, handle_pipemenu_timeout, ctx); wl_event_source_timer_update(ctx->event_timeout, PIPEMENU_TIMEOUT_IN_MS); @@ -1351,7 +1351,7 @@ menu_process_item_selection(struct menuitem *item) item->submenu->parent = item->parent; /* And open the new submenu tree */ struct wlr_box anchor_rect = - get_item_anchor_rect(g_server.theme, item); + get_item_anchor_rect(server.theme, item); if (item->submenu->execute && !item->submenu->scene_tree) { open_pipemenu_async(item->submenu, anchor_rect); } else { @@ -1366,7 +1366,7 @@ menu_process_item_selection(struct menuitem *item) static struct menu * get_selection_leaf(void) { - struct menu *menu = g_server.menu_current; + struct menu *menu = server.menu_current; if (!menu) { return NULL; } @@ -1420,9 +1420,9 @@ menu_execute_item(struct menuitem *item) return false; } - menu_close(g_server.menu_current); - g_server.menu_current = NULL; - seat_focus_override_end(&g_server.seat, /*restore_focus*/ true); + menu_close(server.menu_current); + server.menu_current = NULL; + seat_focus_override_end(&server.seat, /*restore_focus*/ true); /* * We call the actions after closing the menu so that virtual keyboard @@ -1518,19 +1518,19 @@ menu_process_cursor_motion(struct wlr_scene_node *node) void menu_close_root(void) { - assert(g_server.input_mode == LAB_INPUT_STATE_MENU); - assert(g_server.menu_current); + assert(server.input_mode == LAB_INPUT_STATE_MENU); + assert(server.menu_current); - menu_close(g_server.menu_current); - g_server.menu_current = NULL; + menu_close(server.menu_current); + server.menu_current = NULL; reset_pipemenus(); - seat_focus_override_end(&g_server.seat, /*restore_focus*/ true); + seat_focus_override_end(&server.seat, /*restore_focus*/ true); } void menu_reconfigure(void) { menu_finish(); - g_server.menu_current = NULL; + server.menu_current = NULL; menu_init(); } diff --git a/src/output-virtual.c b/src/output-virtual.c index 1bc45bf6..07d07784 100644 --- a/src/output-virtual.c +++ b/src/output-virtual.c @@ -18,7 +18,7 @@ output_virtual_add(const char *output_name, if (output_name) { /* Prevent creating outputs with the same name */ struct output *output; - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { if (wlr_output_is_headless(output->wlr_output) && !strcmp(output->wlr_output->name, output_name)) { wlr_log(WLR_DEBUG, @@ -46,13 +46,13 @@ output_virtual_add(const char *output_name, * we may end up calling the new output handler twice, one time manually * and one time by the headless backend when it starts up and sends the * signal for all its configured outputs. Rather than keeping a global - * g_server.headless.started state around that we could check here we just + * server.headless.started state around that we could check here we just * ignore duplicated new output calls in handle_new_output(). */ - wl_list_remove(&g_server.new_output.link); + wl_list_remove(&server.new_output.link); struct wlr_output *wlr_output = wlr_headless_add_output( - g_server.headless.backend, 1920, 1080); + server.headless.backend, 1920, 1080); if (!wlr_output) { wlr_log(WLR_ERROR, "Failed to create virtual output %s", @@ -69,20 +69,20 @@ output_virtual_add(const char *output_name, } /* Notify about the new output manually */ - if (g_server.new_output.notify) { - g_server.new_output.notify(&g_server.new_output, wlr_output); + if (server.new_output.notify) { + server.new_output.notify(&server.new_output, wlr_output); } restore_handler: /* And finally restore output notifications */ - wl_signal_add(&g_server.backend->events.new_output, &g_server.new_output); + wl_signal_add(&server.backend->events.new_output, &server.new_output); } void output_virtual_remove(const char *output_name) { struct output *output; - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { if (!wlr_output_is_headless(output->wlr_output) || output->wlr_output == fallback_output) { continue; @@ -111,7 +111,7 @@ output_virtual_remove(const char *output_name) void output_virtual_update_fallback(void) { - struct wl_list *layout_outputs = &g_server.output_layout->outputs; + struct wl_list *layout_outputs = &server.output_layout->outputs; const char *fallback_output_name = getenv("LABWC_FALLBACK_OUTPUT"); if (!fallback_output && wl_list_empty(layout_outputs) diff --git a/src/output.c b/src/output.c index 0f390cd6..1fd0a03d 100644 --- a/src/output.c +++ b/src/output.c @@ -51,7 +51,7 @@ output_get_tearing_allowance(struct output *output) return false; } - struct view *view = g_server.active_view; + struct view *view = server.active_view; /* tearing is only allowed for the output with the active view */ if (!view || view->output != output) { @@ -96,7 +96,7 @@ output_apply_gamma(struct output *output) output->gamma_lut_changed = false; struct wlr_gamma_control_v1 *gamma_control = wlr_gamma_control_manager_v1_get_control( - g_server.gamma_control_manager_v1, + server.gamma_control_manager_v1, output->wlr_output); if (!wlr_gamma_control_v1_apply(gamma_control, &pending)) { @@ -126,7 +126,7 @@ handle_output_frame(struct wl_listener *listener, void *data) /* * skip painting the session when it exists but is not active. */ - if (g_server.session && !g_server.session->active) { + if (server.session && !server.session->active) { return; } @@ -157,7 +157,7 @@ static void handle_output_destroy(struct wl_listener *listener, void *data) { struct output *output = wl_container_of(listener, output, destroy); - struct seat *seat = &g_server.seat; + struct seat *seat = &server.seat; regions_evacuate_output(output); regions_destroy(seat, &output->regions); if (seat->overlay.active.output == output) { @@ -181,7 +181,7 @@ handle_output_destroy(struct wl_listener *listener, void *data) } struct view *view; - wl_list_for_each(view, &g_server.views, link) { + wl_list_for_each(view, &server.views, link) { if (view->output == output) { view_on_output_destroy(view); } @@ -201,13 +201,13 @@ handle_output_destroy(struct wl_listener *listener, void *data) * windows and cannot be reconnected. Exit the compositor * when the last one is destroyed. */ - if (wl_list_empty(&g_server.outputs) && ( + if (wl_list_empty(&server.outputs) && ( wlr_output_is_wl(output->wlr_output) #if WLR_HAS_X11_BACKEND || wlr_output_is_x11(output->wlr_output) #endif )) { - wl_display_terminate(g_server.wl_display); + wl_display_terminate(server.wl_display); } /* @@ -263,7 +263,7 @@ add_output_to_layout(struct output *output) { struct wlr_output *wlr_output = output->wlr_output; struct wlr_output_layout_output *layout_output = - wlr_output_layout_add_auto(g_server.output_layout, wlr_output); + wlr_output_layout_add_auto(server.output_layout, wlr_output); if (!layout_output) { wlr_log(WLR_ERROR, "unable to add output to layout"); return; @@ -271,7 +271,7 @@ add_output_to_layout(struct output *output) if (!output->scene_output) { output->scene_output = - wlr_scene_output_create(g_server.scene, wlr_output); + wlr_scene_output_create(server.scene, wlr_output); if (!output->scene_output) { wlr_log(WLR_ERROR, "unable to create scene output"); return; @@ -281,21 +281,21 @@ add_output_to_layout(struct output *output) * safe to call twice, so we call it only when initially * creating the scene_output. */ - wlr_scene_output_layout_add_output(g_server.scene_layout, + wlr_scene_output_layout_add_output(server.scene_layout, layout_output, output->scene_output); } lab_cosmic_workspace_group_output_enter( - g_server.workspaces.cosmic_group, output->wlr_output); + server.workspaces.cosmic_group, output->wlr_output); lab_ext_workspace_group_output_enter( - g_server.workspaces.ext_group, output->wlr_output); + server.workspaces.ext_group, output->wlr_output); /* (Re-)create regions from config */ regions_reconfigure_output(output); /* Create lock surface if needed */ - if (g_server.session_lock_manager->locked) { - session_lock_output_create(g_server.session_lock_manager, output); + if (server.session_lock_manager->locked) { + session_lock_output_create(server.session_lock_manager, output); } } @@ -413,9 +413,9 @@ configure_new_output(struct output *output) * calling do_output_layout_change(); this ensures that the * wlr_output_cursor is created for the new output. */ - g_server.pending_output_layout_change++; + server.pending_output_layout_change++; add_output_to_layout(output); - g_server.pending_output_layout_change--; + server.pending_output_layout_change--; } static uint64_t @@ -423,7 +423,7 @@ get_unused_output_id_bit(void) { uint64_t used_id_bits = 0; struct output *output; - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { used_id_bits |= output->id_bit; } @@ -431,7 +431,7 @@ get_unused_output_id_bit(void) return 0; } - uint64_t id_bit = g_server.next_output_id_bit; + uint64_t id_bit = server.next_output_id_bit; /* * __builtin_popcountll() should be supported by GCC & clang. * If it causes portability issues, just remove the assert. @@ -448,7 +448,7 @@ get_unused_output_id_bit(void) * can cycle through all 64 available bits, making re-use less * frequent (on a best-effort basis). */ - g_server.next_output_id_bit = (id_bit << 1) | (id_bit >> 63); + server.next_output_id_bit = (id_bit << 1) | (id_bit >> 63); return id_bit; } @@ -463,7 +463,7 @@ handle_new_output(struct wl_listener *listener, void *data) struct wlr_output *wlr_output = data; struct output *output; - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { if (output->wlr_output == wlr_output) { /* * This is a duplicated notification. @@ -503,9 +503,9 @@ handle_new_output(struct wl_listener *listener, void *data) * TODO: remove once labwc starts tracking 0.20.x and the fix has been merged. */ #if LAB_WLR_VERSION_AT_LEAST(0, 19, 1) - if (g_server.drm_lease_manager && wlr_output_is_drm(wlr_output)) { + if (server.drm_lease_manager && wlr_output_is_drm(wlr_output)) { wlr_drm_lease_v1_manager_offer_output( - g_server.drm_lease_manager, wlr_output); + server.drm_lease_manager, wlr_output); } #endif @@ -521,8 +521,8 @@ handle_new_output(struct wl_listener *listener, void *data) * Configures the output created by the backend to use our allocator * and our renderer. Must be done once, before committing the output */ - if (!wlr_output_init_render(wlr_output, g_server.allocator, - g_server.renderer)) { + if (!wlr_output_init_render(wlr_output, server.allocator, + server.renderer)) { wlr_log(WLR_ERROR, "unable to init output renderer"); return; } @@ -533,7 +533,7 @@ handle_new_output(struct wl_listener *listener, void *data) output->id_bit = id_bit; output_state_init(output); - wl_list_insert(&g_server.outputs, &output->link); + wl_list_insert(&server.outputs, &output->link); output->destroy.notify = handle_output_destroy; wl_signal_add(&wlr_output->events.destroy, &output->destroy); @@ -551,11 +551,11 @@ handle_new_output(struct wl_listener *listener, void *data) */ for (size_t i = 0; i < ARRAY_SIZE(output->layer_tree); i++) { output->layer_tree[i] = - lab_wlr_scene_tree_create(&g_server.scene->tree); + lab_wlr_scene_tree_create(&server.scene->tree); } - output->layer_popup_tree = lab_wlr_scene_tree_create(&g_server.scene->tree); - output->cycle_osd_tree = lab_wlr_scene_tree_create(&g_server.scene->tree); - output->session_lock_tree = lab_wlr_scene_tree_create(&g_server.scene->tree); + output->layer_popup_tree = lab_wlr_scene_tree_create(&server.scene->tree); + output->cycle_osd_tree = lab_wlr_scene_tree_create(&server.scene->tree); + output->session_lock_tree = lab_wlr_scene_tree_create(&server.scene->tree); /* * Set the z-positions to achieve the following order (from top to @@ -573,7 +573,7 @@ handle_new_output(struct wl_listener *listener, void *data) wlr_scene_node_lower_to_bottom(&output->layer_tree[1]->node); wlr_scene_node_lower_to_bottom(&output->layer_tree[0]->node); - struct wlr_scene_node *menu_node = &g_server.menu_tree->node; + struct wlr_scene_node *menu_node = &server.menu_tree->node; wlr_scene_node_place_below(&output->layer_tree[2]->node, menu_node); wlr_scene_node_place_below(&output->layer_tree[3]->node, menu_node); wlr_scene_node_place_below(&output->layer_popup_tree->node, menu_node); @@ -599,34 +599,34 @@ static void output_manager_init(void); void output_init(void) { - g_server.gamma_control_manager_v1 = - wlr_gamma_control_manager_v1_create(g_server.wl_display); + server.gamma_control_manager_v1 = + wlr_gamma_control_manager_v1_create(server.wl_display); - g_server.new_output.notify = handle_new_output; - wl_signal_add(&g_server.backend->events.new_output, &g_server.new_output); + server.new_output.notify = handle_new_output; + wl_signal_add(&server.backend->events.new_output, &server.new_output); /* * Create an output layout, which is a wlroots utility for working with * an arrangement of screens in a physical layout. */ - g_server.output_layout = wlr_output_layout_create(g_server.wl_display); - if (!g_server.output_layout) { + server.output_layout = wlr_output_layout_create(server.wl_display); + if (!server.output_layout) { wlr_log(WLR_ERROR, "unable to create output layout"); exit(EXIT_FAILURE); } - g_server.scene_layout = wlr_scene_attach_output_layout(g_server.scene, - g_server.output_layout); - if (!g_server.scene_layout) { + server.scene_layout = wlr_scene_attach_output_layout(server.scene, + server.output_layout); + if (!server.scene_layout) { wlr_log(WLR_ERROR, "unable to create scene layout"); exit(EXIT_FAILURE); } /* Enable screen recording with wf-recorder */ - wlr_xdg_output_manager_v1_create(g_server.wl_display, - g_server.output_layout); + wlr_xdg_output_manager_v1_create(server.wl_display, + server.output_layout); - wl_list_init(&g_server.outputs); - g_server.next_output_id_bit = (1 << 0); + wl_list_init(&server.outputs); + server.next_output_id_bit = (1 << 0); output_manager_init(); } @@ -636,7 +636,7 @@ static void output_manager_finish(void); void output_finish(void) { - wl_list_remove(&g_server.new_output.link); + wl_list_remove(&server.new_output.link); output_manager_finish(); } @@ -651,15 +651,15 @@ output_update_for_layout_change(void) * align with the seat cursor. Re-set the cursor image so that * the cursor isn't invisible on new outputs. */ - wlr_cursor_move(g_server.seat.cursor, NULL, 0, 0); - cursor_update_image(&g_server.seat); + wlr_cursor_move(server.seat.cursor, NULL, 0, 0); + cursor_update_image(&server.seat); } static bool output_config_apply(struct wlr_output_configuration_v1 *config) { bool success = true; - g_server.pending_output_layout_change++; + server.pending_output_layout_change++; struct wlr_output_configuration_head_v1 *head; wl_list_for_each(head, &config->heads, link) { @@ -708,7 +708,7 @@ output_config_apply(struct wlr_output_configuration_v1 *config) * been enabled but not yet been added to the layout. */ bool was_in_layout = - !!wlr_output_layout_get(g_server.output_layout, o); + !!wlr_output_layout_get(server.output_layout, o); if (output_enabled) { if (!was_in_layout) { @@ -716,23 +716,23 @@ output_config_apply(struct wlr_output_configuration_v1 *config) } struct wlr_box pos = {0}; - wlr_output_layout_get_box(g_server.output_layout, o, &pos); + wlr_output_layout_get_box(server.output_layout, o, &pos); if (pos.x != head->state.x || pos.y != head->state.y) { /* * This overrides the automatic layout * * wlr_output_layout_add() in fact means _move() */ - wlr_output_layout_add(g_server.output_layout, o, + wlr_output_layout_add(server.output_layout, o, head->state.x, head->state.y); } } else if (was_in_layout) { regions_evacuate_output(output); lab_cosmic_workspace_group_output_leave( - g_server.workspaces.cosmic_group, output->wlr_output); + server.workspaces.cosmic_group, output->wlr_output); lab_ext_workspace_group_output_leave( - g_server.workspaces.ext_group, output->wlr_output); + server.workspaces.ext_group, output->wlr_output); /* * At time of writing, wlr_output_layout_remove() @@ -743,12 +743,12 @@ output_config_apply(struct wlr_output_configuration_v1 *config) * calling wlr_output_layout_remove(). */ wlr_scene_output_destroy(output->scene_output); - wlr_output_layout_remove(g_server.output_layout, o); + wlr_output_layout_remove(server.output_layout, o); output->scene_output = NULL; } } - g_server.pending_output_layout_change--; + server.pending_output_layout_change--; do_output_layout_change(); return success; } @@ -839,14 +839,14 @@ handle_output_manager_apply(struct wl_listener *listener, void *data) } wlr_output_configuration_v1_destroy(config); struct output *output; - wl_list_for_each(output, &g_server.outputs, link) { - wlr_xcursor_manager_load(g_server.seat.xcursor_manager, + wl_list_for_each(output, &server.outputs, link) { + wlr_xcursor_manager_load(server.seat.xcursor_manager, output->wlr_output->scale); } /* Re-set cursor image in case scale changed */ cursor_update_focus(); - cursor_update_image(&g_server.seat); + cursor_update_image(&server.seat); } /* @@ -865,7 +865,7 @@ wlr_output_configuration_v1 *create_output_config(void) } struct output *output; - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { struct wlr_output_configuration_head_v1 *head = wlr_output_configuration_head_v1_create(config, output->wlr_output); @@ -886,18 +886,18 @@ wlr_output_configuration_v1 *create_output_config(void) static void do_output_layout_change(void) { - if (!g_server.pending_output_layout_change) { + if (!server.pending_output_layout_change) { struct wlr_output_configuration_v1 *config = create_output_config(); if (config) { wlr_output_manager_v1_set_configuration( - g_server.output_manager, config); + server.output_manager, config); } else { wlr_log(WLR_ERROR, "wlr_output_manager_v1_set_configuration()"); } output_update_for_layout_change(); - seat_output_layout_changed(&g_server.seat); + seat_output_layout_changed(&server.seat); } } @@ -905,9 +905,9 @@ static void handle_output_layout_change(struct wl_listener *listener, void *data) { /* Prevents unnecessary layout recalculations */ - g_server.pending_output_layout_change++; + server.pending_output_layout_change++; output_virtual_update_fallback(); - g_server.pending_output_layout_change--; + server.pending_output_layout_change--; do_output_layout_change(); } @@ -928,39 +928,39 @@ handle_gamma_control_set_gamma(struct wl_listener *listener, void *data) static void output_manager_init(void) { - g_server.output_manager = wlr_output_manager_v1_create(g_server.wl_display); + server.output_manager = wlr_output_manager_v1_create(server.wl_display); - g_server.output_layout_change.notify = handle_output_layout_change; - wl_signal_add(&g_server.output_layout->events.change, - &g_server.output_layout_change); + server.output_layout_change.notify = handle_output_layout_change; + wl_signal_add(&server.output_layout->events.change, + &server.output_layout_change); - g_server.output_manager_apply.notify = handle_output_manager_apply; - wl_signal_add(&g_server.output_manager->events.apply, - &g_server.output_manager_apply); + server.output_manager_apply.notify = handle_output_manager_apply; + wl_signal_add(&server.output_manager->events.apply, + &server.output_manager_apply); - g_server.output_manager_test.notify = handle_output_manager_test; - wl_signal_add(&g_server.output_manager->events.test, - &g_server.output_manager_test); + server.output_manager_test.notify = handle_output_manager_test; + wl_signal_add(&server.output_manager->events.test, + &server.output_manager_test); - g_server.gamma_control_set_gamma.notify = handle_gamma_control_set_gamma; - wl_signal_add(&g_server.gamma_control_manager_v1->events.set_gamma, - &g_server.gamma_control_set_gamma); + server.gamma_control_set_gamma.notify = handle_gamma_control_set_gamma; + wl_signal_add(&server.gamma_control_manager_v1->events.set_gamma, + &server.gamma_control_set_gamma); } static void output_manager_finish(void) { - wl_list_remove(&g_server.output_layout_change.link); - wl_list_remove(&g_server.output_manager_apply.link); - wl_list_remove(&g_server.output_manager_test.link); - wl_list_remove(&g_server.gamma_control_set_gamma.link); + wl_list_remove(&server.output_layout_change.link); + wl_list_remove(&server.output_manager_apply.link); + wl_list_remove(&server.output_manager_test.link); + wl_list_remove(&server.gamma_control_set_gamma.link); } struct output * output_from_wlr_output(struct wlr_output *wlr_output) { struct output *output; - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { if (output->wlr_output == wlr_output) { return output; } @@ -972,7 +972,7 @@ struct output * output_from_name(const char *name) { struct output *output; - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { if (!output_is_usable(output) || !output->wlr_output->name) { continue; } @@ -987,18 +987,18 @@ struct output * output_nearest_to(int lx, int ly) { double closest_x, closest_y; - wlr_output_layout_closest_point(g_server.output_layout, NULL, lx, ly, + wlr_output_layout_closest_point(server.output_layout, NULL, lx, ly, &closest_x, &closest_y); - return output_from_wlr_output(wlr_output_layout_output_at(g_server.output_layout, + return output_from_wlr_output(wlr_output_layout_output_at(server.output_layout, closest_x, closest_y)); } struct output * output_nearest_to_cursor(void) { - return output_nearest_to(g_server.seat.cursor->x, - g_server.seat.cursor->y); + return output_nearest_to(server.seat.cursor->x, + server.seat.cursor->y); } struct output * @@ -1022,7 +1022,7 @@ output_get_adjacent(struct output *output, enum lab_edge edge, bool wrap) /* Determine any adjacent output in the appropriate direction */ struct wlr_output *new_output = NULL; struct wlr_output *current_output = output->wlr_output; - struct wlr_output_layout *layout = g_server.output_layout; + struct wlr_output_layout *layout = server.output_layout; /* Cast from enum lab_edge to enum wlr_direction is safe */ new_output = wlr_output_layout_adjacent_output(layout, (enum wlr_direction)edge, current_output, lx, ly); @@ -1076,10 +1076,10 @@ update_usable_area(struct output *output) #if HAVE_XWAYLAND struct view *view; - wl_list_for_each(view, &g_server.views, link) { + wl_list_for_each(view, &server.views, link) { if (view->mapped && view->type == LAB_XWAYLAND_VIEW) { xwayland_adjust_usable_area(view, - g_server.output_layout, + server.output_layout, output->wlr_output, &output->usable_area); } } @@ -1105,7 +1105,7 @@ output_update_all_usable_areas(bool layout_changed) bool usable_area_changed = false; struct output *output; - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { if (update_usable_area(output)) { usable_area_changed = true; regions_update_geometry(output); @@ -1129,7 +1129,7 @@ output_usable_area_in_layout_coords(struct output *output) } struct wlr_box box = output->usable_area; double ox = 0, oy = 0; - wlr_output_layout_output_coords(g_server.output_layout, + wlr_output_layout_output_coords(server.output_layout, output->wlr_output, &ox, &oy); box.x -= ox; box.y -= oy; @@ -1161,7 +1161,7 @@ handle_output_power_manager_set_mode(struct wl_listener *listener, void *data) * Re-set the cursor image so that the cursor * isn't invisible on the newly enabled output. */ - cursor_update_image(&g_server.seat); + cursor_update_image(&server.seat); break; } } diff --git a/src/overlay.c b/src/overlay.c index d37c7238..817bb3fc 100644 --- a/src/overlay.c +++ b/src/overlay.c @@ -16,7 +16,7 @@ static void show_overlay(struct seat *seat, struct theme_snapping_overlay *overlay_theme, struct wlr_box *box) { - struct view *view = g_server.grabbed_view; + struct view *view = server.grabbed_view; assert(view); assert(!seat->overlay.rect); @@ -93,7 +93,7 @@ edge_has_adjacent_output_from_cursor(struct seat *seat, struct output *output, } /* Cast from enum lab_edge to enum wlr_direction is safe */ return wlr_output_layout_adjacent_output( - g_server.output_layout, (enum wlr_direction)edge, + server.output_layout, (enum wlr_direction)edge, output->wlr_output, seat->cursor->x, seat->cursor->y); } @@ -123,7 +123,7 @@ show_edge_overlay(struct seat *seat, enum lab_edge edge1, enum lab_edge edge2, if (delay > 0) { if (!seat->overlay.timer) { seat->overlay.timer = wl_event_loop_add_timer( - g_server.wl_event_loop, + server.wl_event_loop, handle_edge_overlay_timeout, seat); } /* Show overlay ms later */ diff --git a/src/placement.c b/src/placement.c index 09618ba4..002303f9 100644 --- a/src/placement.c +++ b/src/placement.c @@ -54,7 +54,7 @@ count_views(struct view *view) int nviews = 0; struct view *v; - for_each_view(v, &g_server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { + for_each_view(v, &server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { /* Ignore the target view or anything on a different output */ if (v == view || v->output != output) { continue; @@ -141,7 +141,7 @@ build_grid(struct overlap_bitmap *bmp, struct view *view) int nr_cols = 2; struct view *v; - for_each_view(v, &g_server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { + for_each_view(v, &server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { if (v == view || v->output != output) { continue; } @@ -242,7 +242,7 @@ build_overlap(struct overlap_bitmap *bmp, struct view *view) } struct view *v; - for_each_view(v, &g_server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { + for_each_view(v, &server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { if (v == view || v->output != output) { continue; } diff --git a/src/regions.c b/src/regions.c index d0886989..9f195723 100644 --- a/src/regions.c +++ b/src/regions.c @@ -19,14 +19,14 @@ bool regions_should_snap(void) { - if (g_server.input_mode != LAB_INPUT_STATE_MOVE + if (server.input_mode != LAB_INPUT_STATE_MOVE || wl_list_empty(&rc.regions) - || g_server.seat.region_prevent_snap - || !view_is_floating(g_server.grabbed_view)) { + || server.seat.region_prevent_snap + || !view_is_floating(server.grabbed_view)) { return false; } - return keyboard_get_all_modifiers(&g_server.seat); + return keyboard_get_all_modifiers(&server.seat); } struct region * @@ -46,11 +46,11 @@ regions_from_name(const char *region_name, struct output *output) struct region * regions_from_cursor(void) { - double lx = g_server.seat.cursor->x; - double ly = g_server.seat.cursor->y; + double lx = server.seat.cursor->x; + double ly = server.seat.cursor->y; struct wlr_output *wlr_output = wlr_output_layout_output_at( - g_server.output_layout, lx, ly); + server.output_layout, lx, ly); struct output *output = output_from_wlr_output(wlr_output); if (!output_is_usable(output)) { return NULL; @@ -81,7 +81,7 @@ regions_reconfigure_output(struct output *output) /* Evacuate views and destroy current regions */ if (!wl_list_empty(&output->regions)) { regions_evacuate_output(output); - regions_destroy(&g_server.seat, &output->regions); + regions_destroy(&server.seat, &output->regions); } /* Initialize regions from config */ @@ -105,7 +105,7 @@ regions_reconfigure(void) struct output *output; /* Evacuate views and initialize regions from config */ - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { regions_reconfigure_output(output); } @@ -149,7 +149,7 @@ regions_evacuate_output(struct output *output) { assert(output); struct view *view; - wl_list_for_each(view, &g_server.views, link) { + wl_list_for_each(view, &server.views, link) { if (view->tiled_region && view->tiled_region->output == output) { view_evacuate_region(view); } diff --git a/src/resistance.c b/src/resistance.c index d5d65a5f..6d34c404 100644 --- a/src/resistance.c +++ b/src/resistance.c @@ -165,7 +165,7 @@ resistance_resize_apply(struct view *view, struct wlr_box *new_geom) edges_initialize(&next_edges); /* Use a constrained, effective geometry for snapping if appropriate */ - enum lab_edge resize_edges = g_server.resize_edges; + enum lab_edge resize_edges = server.resize_edges; struct wlr_box origin = snap_constraints_effective(view, resize_edges, /* use_pending */ false); diff --git a/src/resize-outlines.c b/src/resize-outlines.c index 5e9f2622..60b0b608 100644 --- a/src/resize-outlines.c +++ b/src/resize-outlines.c @@ -25,9 +25,9 @@ resize_outlines_update(struct view *view, struct wlr_box new_geo) if (!outlines->rect) { struct lab_scene_rect_options opts = { .border_colors = (float *[3]) { - g_server.theme->osd_bg_color, - g_server.theme->osd_label_text_color, - g_server.theme->osd_bg_color, + server.theme->osd_bg_color, + server.theme->osd_label_text_color, + server.theme->osd_bg_color, }, .nr_borders = 3, .border_width = 1, diff --git a/src/seat.c b/src/seat.c index f49b9e0e..f63ec8c3 100644 --- a/src/seat.c +++ b/src/seat.c @@ -354,7 +354,7 @@ output_by_name(const char *name) { assert(name); struct output *output; - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { if (!strcasecmp(output->wlr_output->name, name)) { return output->wlr_output; } @@ -609,28 +609,28 @@ handle_focus_change(struct wl_listener *listener, void *data) * We clear the keyboard focus at the beginning of Move/Resize, window * switcher and opening menus, but don't want to deactivate the view. */ - if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { + if (server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { return; } - if (view != g_server.active_view) { - if (g_server.active_view) { - view_set_activated(g_server.active_view, false); + if (view != server.active_view) { + if (server.active_view) { + view_set_activated(server.active_view, false); } if (view) { view_set_activated(view, true); tablet_pad_enter_surface(seat, surface); } - g_server.active_view = view; + server.active_view = view; } } void seat_init(void) { - struct seat *seat = &g_server.seat; + struct seat *seat = &server.seat; - seat->seat = wlr_seat_create(g_server.wl_display, "seat0"); + seat->seat = wlr_seat_create(server.wl_display, "seat0"); if (!seat->seat) { wlr_log(WLR_ERROR, "cannot allocate seat"); exit(EXIT_FAILURE); @@ -640,15 +640,15 @@ seat_init(void) wl_list_init(&seat->constraint_commit.link); wl_list_init(&seat->inputs); - CONNECT_SIGNAL(g_server.backend, seat, new_input); + CONNECT_SIGNAL(server.backend, seat, new_input); CONNECT_SIGNAL(&seat->seat->keyboard_state, seat, focus_change); seat->virtual_pointer = wlr_virtual_pointer_manager_v1_create( - g_server.wl_display); + server.wl_display); CONNECT_SIGNAL(seat->virtual_pointer, seat, new_virtual_pointer); seat->virtual_keyboard = wlr_virtual_keyboard_manager_v1_create( - g_server.wl_display); + server.wl_display); CONNECT_SIGNAL(seat->virtual_keyboard, seat, new_virtual_keyboard); seat->input_method_relay = input_method_relay_create(seat); @@ -660,7 +660,7 @@ seat_init(void) wlr_log(WLR_ERROR, "unable to create cursor"); exit(EXIT_FAILURE); } - wlr_cursor_attach_output_layout(seat->cursor, g_server.output_layout); + wlr_cursor_attach_output_layout(seat->cursor, server.output_layout); wl_list_init(&seat->tablets); wl_list_init(&seat->tablet_tools); @@ -672,7 +672,7 @@ seat_init(void) void seat_finish(void) { - struct seat *seat = &g_server.seat; + struct seat *seat = &server.seat; wl_list_remove(&seat->new_input.link); wl_list_remove(&seat->focus_change.link); wl_list_remove(&seat->new_virtual_pointer.link); @@ -729,7 +729,7 @@ seat_pointer_end_grab(struct seat *seat, struct wlr_surface *surface) void seat_reconfigure(void) { - struct seat *seat = &g_server.seat; + struct seat *seat = &server.seat; struct input *input; cursor_reload(seat); overlay_finish(seat); @@ -760,7 +760,7 @@ seat_reconfigure(void) void seat_force_focus_surface(struct seat *seat, struct wlr_surface *surface) { - if (g_server.session_lock_manager->locked) { + if (server.session_lock_manager->locked) { return; } uint32_t *pressed_sent_keycodes = key_state_pressed_sent_keycodes(); @@ -787,7 +787,7 @@ seat_focus(struct seat *seat, struct wlr_surface *surface, * It should also come before the !surface condition, or the * lock screen may lose focus and become impossible to unlock. */ - if (g_server.session_lock_manager->locked && !is_lock_surface) { + if (server.session_lock_manager->locked && !is_lock_surface) { return; } @@ -823,7 +823,7 @@ seat_focus(struct seat *seat, struct wlr_surface *surface, input_method_relay_set_focus(seat->input_method_relay, surface); struct wlr_pointer_constraint_v1 *constraint = - wlr_pointer_constraints_v1_constraint_for_surface(g_server.constraints, + wlr_pointer_constraints_v1_constraint_for_surface(server.constraints, surface, seat->seat); constrain_cursor(constraint); } @@ -832,7 +832,7 @@ void seat_focus_surface(struct seat *seat, struct wlr_surface *surface) { /* Don't update focus while window switcher, Move/Resize and menu interaction */ - if (g_server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { + if (server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { return; } seat_focus(seat, surface, /*replace_exclusive_layer*/ false, @@ -894,9 +894,9 @@ seat_focus_override_begin(struct seat *seat, enum input_mode input_mode, enum lab_cursors cursor_shape) { assert(!seat->focus_override.surface); - assert(g_server.input_mode == LAB_INPUT_STATE_PASSTHROUGH); + assert(server.input_mode == LAB_INPUT_STATE_PASSTHROUGH); - g_server.input_mode = input_mode; + server.input_mode = input_mode; seat->focus_override.surface = seat->seat->keyboard_state.focused_surface; if (seat->focus_override.surface) { @@ -915,7 +915,7 @@ seat_focus_override_begin(struct seat *seat, enum input_mode input_mode, void seat_focus_override_end(struct seat *seat, bool restore_focus) { - g_server.input_mode = LAB_INPUT_STATE_PASSTHROUGH; + server.input_mode = LAB_INPUT_STATE_PASSTHROUGH; if (seat->focus_override.surface) { if (restore_focus) { diff --git a/src/server.c b/src/server.c index e8467ac1..b2076c52 100644 --- a/src/server.c +++ b/src/server.c @@ -86,8 +86,8 @@ reload_config_and_theme(void) scaled_buffer_invalidate_sharing(); rcxml_finish(); rcxml_read(rc.config_file); - theme_finish(g_server.theme); - theme_init(g_server.theme, rc.theme_name); + theme_finish(server.theme); + theme_init(server.theme, rc.theme_name); #if HAVE_LIBSFDO desktop_entry_finish(); @@ -95,7 +95,7 @@ reload_config_and_theme(void) #endif struct view *view; - wl_list_for_each(view, &g_server.views, link) { + wl_list_for_each(view, &server.views, link) { view_reload_ssd(view); } @@ -111,7 +111,7 @@ reload_config_and_theme(void) static int handle_sighup(int signal, void *data) { - keyboard_cancel_all_keybind_repeats(&g_server.seat); + keyboard_cancel_all_keybind_repeats(&server.seat); session_environment_init(); reload_config_and_theme(); output_virtual_update_fallback(); @@ -145,8 +145,8 @@ handle_sigchld(int signal, void *data) #if HAVE_XWAYLAND /* Ensure that we do not break xwayland lazy initialization */ - if (g_server.xwayland && g_server.xwayland->server - && info.si_pid == g_server.xwayland->server->pid) { + if (server.xwayland && server.xwayland->server + && info.si_pid == server.xwayland->server->pid) { return 0; } #endif @@ -184,9 +184,9 @@ handle_sigchld(int signal, void *data) " please report", (long)info.si_pid, info.si_code); } - if (info.si_pid == g_server.primary_client_pid) { + if (info.si_pid == server.primary_client_pid) { wlr_log(WLR_INFO, "primary client %ld exited", (long)info.si_pid); - wl_display_terminate(g_server.wl_display); + wl_display_terminate(server.wl_display); } return 0; @@ -303,8 +303,8 @@ server_global_filter(const struct wl_client *client, const struct wl_global *glo (void)iface; #if HAVE_XWAYLAND - struct wl_client *xwayland_client = (g_server.xwayland && g_server.xwayland->server) - ? g_server.xwayland->server->client + struct wl_client *xwayland_client = (server.xwayland && server.xwayland->server) + ? server.xwayland->server->client : NULL; if (client != xwayland_client && !strcmp(iface->name, xwayland_shell_v1_interface.name)) { @@ -316,8 +316,8 @@ server_global_filter(const struct wl_client *client, const struct wl_global *glo /* Do not allow security_context_manager_v1 to clients with a security context attached */ const struct wlr_security_context_v1_state *security_context = wlr_security_context_manager_v1_lookup_client( - g_server.security_context_manager_v1, (struct wl_client *)client); - if (security_context && global == g_server.security_context_manager_v1->global) { + server.security_context_manager_v1, (struct wl_client *)client); + if (security_context && global == server.security_context_manager_v1->global) { return false; } else if (security_context) { /* @@ -380,34 +380,34 @@ handle_renderer_lost(struct wl_listener *listener, void *data) { wlr_log(WLR_INFO, "Re-creating renderer after GPU reset"); - struct wlr_renderer *renderer = wlr_renderer_autocreate(g_server.backend); + struct wlr_renderer *renderer = wlr_renderer_autocreate(server.backend); if (!renderer) { wlr_log(WLR_ERROR, "Unable to create renderer"); return; } struct wlr_allocator *allocator = - wlr_allocator_autocreate(g_server.backend, renderer); + wlr_allocator_autocreate(server.backend, renderer); if (!allocator) { wlr_log(WLR_ERROR, "Unable to create allocator"); wlr_renderer_destroy(renderer); return; } - struct wlr_renderer *old_renderer = g_server.renderer; - struct wlr_allocator *old_allocator = g_server.allocator; - g_server.renderer = renderer; - g_server.allocator = allocator; + struct wlr_renderer *old_renderer = server.renderer; + struct wlr_allocator *old_allocator = server.allocator; + server.renderer = renderer; + server.allocator = allocator; - wl_list_remove(&g_server.renderer_lost.link); - wl_signal_add(&g_server.renderer->events.lost, &g_server.renderer_lost); + wl_list_remove(&server.renderer_lost.link); + wl_signal_add(&server.renderer->events.lost, &server.renderer_lost); - wlr_compositor_set_renderer(g_server.compositor, renderer); + wlr_compositor_set_renderer(server.compositor, renderer); struct output *output; - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { wlr_output_init_render(output->wlr_output, - g_server.allocator, g_server.renderer); + server.allocator, server.renderer); } reload_config_and_theme(); @@ -421,27 +421,27 @@ handle_renderer_lost(struct wl_listener *listener, void *data) void server_init(void) { - g_server.primary_client_pid = -1; - g_server.wl_display = wl_display_create(); - if (!g_server.wl_display) { + server.primary_client_pid = -1; + server.wl_display = wl_display_create(); + if (!server.wl_display) { wlr_log(WLR_ERROR, "cannot allocate a wayland display"); exit(EXIT_FAILURE); } /* Increase max client buffer size to make slow clients less likely to terminate */ - wl_display_set_default_max_buffer_size(g_server.wl_display, 1024 * 1024); + wl_display_set_default_max_buffer_size(server.wl_display, 1024 * 1024); - wl_display_set_global_filter(g_server.wl_display, server_global_filter, NULL); - g_server.wl_event_loop = wl_display_get_event_loop(g_server.wl_display); + wl_display_set_global_filter(server.wl_display, server_global_filter, NULL); + server.wl_event_loop = wl_display_get_event_loop(server.wl_display); /* Catch signals */ - g_server.sighup_source = wl_event_loop_add_signal( - g_server.wl_event_loop, SIGHUP, handle_sighup, NULL); - g_server.sigint_source = wl_event_loop_add_signal( - g_server.wl_event_loop, SIGINT, handle_sigterm, g_server.wl_display); - g_server.sigterm_source = wl_event_loop_add_signal( - g_server.wl_event_loop, SIGTERM, handle_sigterm, g_server.wl_display); - g_server.sigchld_source = wl_event_loop_add_signal( - g_server.wl_event_loop, SIGCHLD, handle_sigchld, NULL); + server.sighup_source = wl_event_loop_add_signal( + server.wl_event_loop, SIGHUP, handle_sighup, NULL); + server.sigint_source = wl_event_loop_add_signal( + server.wl_event_loop, SIGINT, handle_sigterm, server.wl_display); + server.sigterm_source = wl_event_loop_add_signal( + server.wl_event_loop, SIGTERM, handle_sigterm, server.wl_display); + server.sigchld_source = wl_event_loop_add_signal( + server.wl_event_loop, SIGCHLD, handle_sigchld, NULL); /* * Prevent wayland clients that request the X11 clipboard but closing @@ -459,31 +459,31 @@ server_init(void) * backend based on the current environment, such as opening an x11 * window if an x11 server is running. */ - g_server.backend = wlr_backend_autocreate( - g_server.wl_event_loop, &g_server.session); - if (!g_server.backend) { + server.backend = wlr_backend_autocreate( + server.wl_event_loop, &server.session); + if (!server.backend) { wlr_log(WLR_ERROR, "unable to create backend"); fprintf(stderr, helpful_seat_error_message); exit(EXIT_FAILURE); } /* Create headless backend to enable adding virtual outputs later on */ - wlr_multi_for_each_backend(g_server.backend, - get_headless_backend, &g_server.headless.backend); + wlr_multi_for_each_backend(server.backend, + get_headless_backend, &server.headless.backend); - if (!g_server.headless.backend) { + if (!server.headless.backend) { wlr_log(WLR_DEBUG, "manually creating headless backend"); - g_server.headless.backend = wlr_headless_backend_create( - g_server.wl_event_loop); + server.headless.backend = wlr_headless_backend_create( + server.wl_event_loop); } else { wlr_log(WLR_DEBUG, "headless backend already exists"); } - if (!g_server.headless.backend) { + if (!server.headless.backend) { wlr_log(WLR_ERROR, "unable to create headless backend"); exit(EXIT_FAILURE); } - wlr_multi_backend_add(g_server.backend, g_server.headless.backend); + wlr_multi_backend_add(server.backend, server.headless.backend); /* * If we don't populate headless backend with a virtual output (that we @@ -491,7 +491,7 @@ server_init(void) * later do not work properly when overlaid on real output. Content is * drawn on the virtual output, but not drawn on the real output. */ - wlr_output_destroy(wlr_headless_add_output(g_server.headless.backend, 0, 0)); + wlr_output_destroy(wlr_headless_add_output(server.headless.backend, 0, 0)); /* * Autocreates a renderer, either Pixman, GLES2 or Vulkan for us. The @@ -499,38 +499,38 @@ server_init(void) * The renderer is responsible for defining the various pixel formats it * supports for shared memory, this configures that for clients. */ - g_server.renderer = wlr_renderer_autocreate(g_server.backend); - if (!g_server.renderer) { + server.renderer = wlr_renderer_autocreate(server.backend); + if (!server.renderer) { wlr_log(WLR_ERROR, "unable to create renderer"); exit(EXIT_FAILURE); } - g_server.renderer_lost.notify = handle_renderer_lost; - wl_signal_add(&g_server.renderer->events.lost, &g_server.renderer_lost); + server.renderer_lost.notify = handle_renderer_lost; + wl_signal_add(&server.renderer->events.lost, &server.renderer_lost); - if (!wlr_renderer_init_wl_shm(g_server.renderer, g_server.wl_display)) { + if (!wlr_renderer_init_wl_shm(server.renderer, server.wl_display)) { wlr_log(WLR_ERROR, "Failed to initialize shared memory pool"); exit(EXIT_FAILURE); } if (wlr_renderer_get_texture_formats( - g_server.renderer, WLR_BUFFER_CAP_DMABUF)) { - if (wlr_renderer_get_drm_fd(g_server.renderer) >= 0) { - wlr_drm_create(g_server.wl_display, g_server.renderer); + server.renderer, WLR_BUFFER_CAP_DMABUF)) { + if (wlr_renderer_get_drm_fd(server.renderer) >= 0) { + wlr_drm_create(server.wl_display, server.renderer); } - g_server.linux_dmabuf = wlr_linux_dmabuf_v1_create_with_renderer( - g_server.wl_display, + server.linux_dmabuf = wlr_linux_dmabuf_v1_create_with_renderer( + server.wl_display, LAB_WLR_LINUX_DMABUF_VERSION, - g_server.renderer); + server.renderer); } else { wlr_log(WLR_DEBUG, "unable to initialize dmabuf"); } - if (wlr_renderer_get_drm_fd(g_server.renderer) >= 0 && - g_server.renderer->features.timeline && - g_server.backend->features.timeline) { - wlr_linux_drm_syncobj_manager_v1_create(g_server.wl_display, 1, - wlr_renderer_get_drm_fd(g_server.renderer)); + if (wlr_renderer_get_drm_fd(server.renderer) >= 0 && + server.renderer->features.timeline && + server.backend->features.timeline) { + wlr_linux_drm_syncobj_manager_v1_create(server.wl_display, 1, + wlr_renderer_get_drm_fd(server.renderer)); } /* @@ -538,22 +538,22 @@ server_init(void) * the renderer and the backend. It handles the buffer creation, * allowing wlroots to render onto the screen */ - g_server.allocator = wlr_allocator_autocreate( - g_server.backend, g_server.renderer); - if (!g_server.allocator) { + server.allocator = wlr_allocator_autocreate( + server.backend, server.renderer); + if (!server.allocator) { wlr_log(WLR_ERROR, "unable to create allocator"); exit(EXIT_FAILURE); } - wl_list_init(&g_server.views); - wl_list_init(&g_server.unmanaged_surfaces); - wl_list_init(&g_server.cycle.views); - wl_list_init(&g_server.cycle.osd_outputs); + wl_list_init(&server.views); + wl_list_init(&server.unmanaged_surfaces); + wl_list_init(&server.cycle.views); + wl_list_init(&server.cycle.osd_outputs); - g_server.scene = wlr_scene_create(); - die_if_null(g_server.scene); + server.scene = wlr_scene_create(); + die_if_null(server.scene); - g_server.direct_scanout_enabled = g_server.scene->WLR_PRIVATE.direct_scanout; + server.direct_scanout_enabled = server.scene->WLR_PRIVATE.direct_scanout; /* * The order in which the scene-trees below are created determines the @@ -564,14 +564,14 @@ server_init(void) * | ---------------------------------- | ------------------------------------- * | output->session_lock_tree | session lock surfaces (e.g. swaylock) * | output->cycle_osd_tree | window switcher's on-screen display - * | g_server.cycle_preview_tree | window switcher's previewed window - * | g_server.menu_tree | labwc's server-side menus + * | server.cycle_preview_tree | window switcher's previewed window + * | server.menu_tree | labwc's server-side menus * | output->layer_popup_tree | xdg popups on layer surfaces * | output->layer_tree[3] | overlay layer surfaces (e.g. rofi) * | output->layer_tree[2] | top layer surfaces (e.g. waybar) - * | g_server.unmanaged_tree | unmanaged X11 surfaces (e.g. dmenu) - * | g_server.xdg_popup_tree | xdg popups on xdg windows - * | g_server.workspace_tree | + * | server.unmanaged_tree | unmanaged X11 surfaces (e.g. dmenu) + * | server.xdg_popup_tree | xdg popups on xdg windows + * | server.workspace_tree | * | + workspace->tree | * | + workspace->view_trees[1] | always-on-top xdg/X11 windows * | + workspace->view_trees[0] | normal xdg/X11 windows (e.g. firefox) @@ -580,13 +580,13 @@ server_init(void) * | output->layer_tree[0] | background layer surfaces (e.g. swaybg) */ - g_server.workspace_tree = lab_wlr_scene_tree_create(&g_server.scene->tree); - g_server.xdg_popup_tree = lab_wlr_scene_tree_create(&g_server.scene->tree); + server.workspace_tree = lab_wlr_scene_tree_create(&server.scene->tree); + server.xdg_popup_tree = lab_wlr_scene_tree_create(&server.scene->tree); #if HAVE_XWAYLAND - g_server.unmanaged_tree = lab_wlr_scene_tree_create(&g_server.scene->tree); + server.unmanaged_tree = lab_wlr_scene_tree_create(&server.scene->tree); #endif - g_server.menu_tree = lab_wlr_scene_tree_create(&g_server.scene->tree); - g_server.cycle_preview_tree = lab_wlr_scene_tree_create(&g_server.scene->tree); + server.menu_tree = lab_wlr_scene_tree_create(&server.scene->tree); + server.cycle_preview_tree = lab_wlr_scene_tree_create(&server.scene->tree); workspaces_init(); @@ -599,16 +599,16 @@ server_init(void) * room for you to dig your fingers in and play with their behavior if * you want. */ - g_server.compositor = wlr_compositor_create(g_server.wl_display, - LAB_WLR_COMPOSITOR_VERSION, g_server.renderer); - if (!g_server.compositor) { + server.compositor = wlr_compositor_create(server.wl_display, + LAB_WLR_COMPOSITOR_VERSION, server.renderer); + if (!server.compositor) { wlr_log(WLR_ERROR, "unable to create the wlroots compositor"); exit(EXIT_FAILURE); } - wlr_subcompositor_create(g_server.wl_display); + wlr_subcompositor_create(server.wl_display); struct wlr_data_device_manager *device_manager = NULL; - device_manager = wlr_data_device_manager_create(g_server.wl_display); + device_manager = wlr_data_device_manager_create(server.wl_display); if (!device_manager) { wlr_log(WLR_ERROR, "unable to create data device manager"); exit(EXIT_FAILURE); @@ -625,103 +625,103 @@ server_init(void) * https://wayfire.org/2020/08/04/Wayfire-0-5.html */ if (rc.primary_selection) { - wlr_primary_selection_v1_device_manager_create(g_server.wl_display); + wlr_primary_selection_v1_device_manager_create(server.wl_display); } - g_server.input_method_manager = wlr_input_method_manager_v2_create( - g_server.wl_display); - g_server.text_input_manager = wlr_text_input_manager_v3_create( - g_server.wl_display); + server.input_method_manager = wlr_input_method_manager_v2_create( + server.wl_display); + server.text_input_manager = wlr_text_input_manager_v3_create( + server.wl_display); seat_init(); xdg_shell_init(); kde_server_decoration_init(); - xdg_server_decoration_init(); + xdserver_decoration_init(); struct wlr_presentation *presentation = wlr_presentation_create( - g_server.wl_display, g_server.backend, + server.wl_display, server.backend, LAB_WLR_PRESENTATION_TIME_VERSION); if (!presentation) { wlr_log(WLR_ERROR, "unable to create presentation interface"); exit(EXIT_FAILURE); } - if (g_server.linux_dmabuf) { - wlr_scene_set_linux_dmabuf_v1(g_server.scene, g_server.linux_dmabuf); + if (server.linux_dmabuf) { + wlr_scene_set_linux_dmabuf_v1(server.scene, server.linux_dmabuf); } - wlr_export_dmabuf_manager_v1_create(g_server.wl_display); - wlr_screencopy_manager_v1_create(g_server.wl_display); - wlr_ext_image_copy_capture_manager_v1_create(g_server.wl_display, 1); - wlr_ext_output_image_capture_source_manager_v1_create(g_server.wl_display, 1); - wlr_data_control_manager_v1_create(g_server.wl_display); - wlr_ext_data_control_manager_v1_create(g_server.wl_display, + wlr_export_dmabuf_manager_v1_create(server.wl_display); + wlr_screencopy_manager_v1_create(server.wl_display); + wlr_ext_image_copy_capture_manager_v1_create(server.wl_display, 1); + wlr_ext_output_image_capture_source_manager_v1_create(server.wl_display, 1); + wlr_data_control_manager_v1_create(server.wl_display); + wlr_ext_data_control_manager_v1_create(server.wl_display, LAB_EXT_DATA_CONTROL_VERSION); - g_server.security_context_manager_v1 = - wlr_security_context_manager_v1_create(g_server.wl_display); - wlr_viewporter_create(g_server.wl_display); - wlr_single_pixel_buffer_manager_v1_create(g_server.wl_display); - wlr_fractional_scale_manager_v1_create(g_server.wl_display, + server.security_context_manager_v1 = + wlr_security_context_manager_v1_create(server.wl_display); + wlr_viewporter_create(server.wl_display); + wlr_single_pixel_buffer_manager_v1_create(server.wl_display); + wlr_fractional_scale_manager_v1_create(server.wl_display, LAB_WLR_FRACTIONAL_SCALE_V1_VERSION); - idle_manager_create(g_server.wl_display); + idle_manager_create(server.wl_display); - g_server.relative_pointer_manager = wlr_relative_pointer_manager_v1_create( - g_server.wl_display); - g_server.constraints = wlr_pointer_constraints_v1_create( - g_server.wl_display); + server.relative_pointer_manager = wlr_relative_pointer_manager_v1_create( + server.wl_display); + server.constraints = wlr_pointer_constraints_v1_create( + server.wl_display); - g_server.new_constraint.notify = create_constraint; - wl_signal_add(&g_server.constraints->events.new_constraint, - &g_server.new_constraint); + server.new_constraint.notify = create_constraint; + wl_signal_add(&server.constraints->events.new_constraint, + &server.new_constraint); - g_server.foreign_toplevel_manager = - wlr_foreign_toplevel_manager_v1_create(g_server.wl_display); + server.foreign_toplevel_manager = + wlr_foreign_toplevel_manager_v1_create(server.wl_display); - g_server.foreign_toplevel_list = + server.foreign_toplevel_list = wlr_ext_foreign_toplevel_list_v1_create( - g_server.wl_display, LAB_EXT_FOREIGN_TOPLEVEL_LIST_VERSION); + server.wl_display, LAB_EXT_FOREIGN_TOPLEVEL_LIST_VERSION); - wlr_alpha_modifier_v1_create(g_server.wl_display); + wlr_alpha_modifier_v1_create(server.wl_display); session_lock_init(); - g_server.drm_lease_manager = wlr_drm_lease_v1_manager_create( - g_server.wl_display, g_server.backend); - if (g_server.drm_lease_manager) { - g_server.drm_lease_request.notify = handle_drm_lease_request; - wl_signal_add(&g_server.drm_lease_manager->events.request, - &g_server.drm_lease_request); + server.drm_lease_manager = wlr_drm_lease_v1_manager_create( + server.wl_display, server.backend); + if (server.drm_lease_manager) { + server.drm_lease_request.notify = handle_drm_lease_request; + wl_signal_add(&server.drm_lease_manager->events.request, + &server.drm_lease_request); } else { wlr_log(WLR_DEBUG, "Failed to create wlr_drm_lease_device_v1"); wlr_log(WLR_INFO, "VR will not be available"); } - g_server.output_power_manager_v1 = - wlr_output_power_manager_v1_create(g_server.wl_display); - g_server.output_power_manager_set_mode.notify = + server.output_power_manager_v1 = + wlr_output_power_manager_v1_create(server.wl_display); + server.output_power_manager_set_mode.notify = handle_output_power_manager_set_mode; - wl_signal_add(&g_server.output_power_manager_v1->events.set_mode, - &g_server.output_power_manager_set_mode); + wl_signal_add(&server.output_power_manager_v1->events.set_mode, + &server.output_power_manager_set_mode); - g_server.tearing_control = wlr_tearing_control_manager_v1_create(g_server.wl_display, 1); - g_server.tearing_new_object.notify = handle_tearing_new_object; - wl_signal_add(&g_server.tearing_control->events.new_object, &g_server.tearing_new_object); + server.tearing_control = wlr_tearing_control_manager_v1_create(server.wl_display, 1); + server.tearing_new_object.notify = handle_tearing_new_object; + wl_signal_add(&server.tearing_control->events.new_object, &server.tearing_new_object); - g_server.tablet_manager = wlr_tablet_v2_create(g_server.wl_display); + server.tablet_manager = wlr_tablet_v2_create(server.wl_display); layers_init(); /* These get cleaned up automatically on display destroy */ struct wlr_xdg_foreign_registry *registry = - wlr_xdg_foreign_registry_create(g_server.wl_display); - wlr_xdg_foreign_v1_create(g_server.wl_display, registry); - wlr_xdg_foreign_v2_create(g_server.wl_display, registry); + wlr_xdg_foreign_registry_create(server.wl_display); + wlr_xdg_foreign_v1_create(server.wl_display, registry); + wlr_xdg_foreign_v2_create(server.wl_display, registry); #if HAVE_LIBSFDO desktop_entry_init(); #endif #if HAVE_XWAYLAND - xwayland_server_init(g_server.compositor); + xwayland_server_init(server.compositor); #endif } @@ -729,7 +729,7 @@ void server_start(void) { /* Add a Unix socket to the Wayland display. */ - const char *socket = wl_display_add_socket_auto(g_server.wl_display); + const char *socket = wl_display_add_socket_auto(server.wl_display); if (!socket) { wlr_log_errno(WLR_ERROR, "unable to open wayland socket"); exit(EXIT_FAILURE); @@ -739,7 +739,7 @@ server_start(void) * Start the backend. This will enumerate outputs and inputs, become * the DRM master, etc */ - if (!wlr_backend_start(g_server.backend)) { + if (!wlr_backend_start(server.backend)) { wlr_log(WLR_ERROR, "unable to start the wlroots backend"); exit(EXIT_FAILURE); } @@ -763,35 +763,35 @@ server_finish(void) #if HAVE_LIBSFDO desktop_entry_finish(); #endif - wl_event_source_remove(g_server.sighup_source); - wl_event_source_remove(g_server.sigint_source); - wl_event_source_remove(g_server.sigterm_source); - wl_event_source_remove(g_server.sigchld_source); + wl_event_source_remove(server.sighup_source); + wl_event_source_remove(server.sigint_source); + wl_event_source_remove(server.sigterm_source); + wl_event_source_remove(server.sigchld_source); - wl_display_destroy_clients(g_server.wl_display); + wl_display_destroy_clients(server.wl_display); seat_finish(); output_finish(); xdg_shell_finish(); layers_finish(); kde_server_decoration_finish(); - xdg_server_decoration_finish(); - wl_list_remove(&g_server.new_constraint.link); - wl_list_remove(&g_server.output_power_manager_set_mode.link); - wl_list_remove(&g_server.tearing_new_object.link); - if (g_server.drm_lease_request.notify) { - wl_list_remove(&g_server.drm_lease_request.link); - g_server.drm_lease_request.notify = NULL; + xdserver_decoration_finish(); + wl_list_remove(&server.new_constraint.link); + wl_list_remove(&server.output_power_manager_set_mode.link); + wl_list_remove(&server.tearing_new_object.link); + if (server.drm_lease_request.notify) { + wl_list_remove(&server.drm_lease_request.link); + server.drm_lease_request.notify = NULL; } - wlr_backend_destroy(g_server.backend); - wlr_allocator_destroy(g_server.allocator); + wlr_backend_destroy(server.backend); + wlr_allocator_destroy(server.allocator); - wl_list_remove(&g_server.renderer_lost.link); - wlr_renderer_destroy(g_server.renderer); + wl_list_remove(&server.renderer_lost.link); + wlr_renderer_destroy(server.renderer); workspaces_destroy(); - wlr_scene_node_destroy(&g_server.scene->tree.node); + wlr_scene_node_destroy(&server.scene->tree.node); - wl_display_destroy(g_server.wl_display); + wl_display_destroy(server.wl_display); } diff --git a/src/session-lock.c b/src/session-lock.c index d848dc7a..4e5eb8ab 100644 --- a/src/session-lock.c +++ b/src/session-lock.c @@ -31,7 +31,7 @@ static void focus_surface(struct session_lock_manager *manager, struct wlr_surface *focused) { manager->focused = focused; - seat_focus_lock_surface(&g_server.seat, focused); + seat_focus_lock_surface(&server.seat, focused); } static void @@ -78,7 +78,7 @@ handle_surface_map(struct wl_listener *listener, void *data) * buffer has not been actually attached to the surface. */ wl_event_loop_add_idle( - g_server.wl_event_loop, update_focus, output); + server.wl_event_loop, update_focus, output); } static void @@ -98,7 +98,7 @@ static void lock_output_reconfigure(struct session_lock_output *output) { struct wlr_box box; - wlr_output_layout_get_box(g_server.output_layout, + wlr_output_layout_get_box(server.output_layout, output->output->wlr_output, &box); wlr_scene_rect_set_size(output->background, box.width, box.height); if (output->surface) { @@ -191,7 +191,7 @@ static void align_session_lock_tree(struct output *output) { struct wlr_box box; - wlr_output_layout_get_box(g_server.output_layout, + wlr_output_layout_get_box(server.output_layout, output->wlr_output, &box); wlr_scene_node_set_position(&output->session_lock_tree->node, box.x, box.y); } @@ -228,7 +228,7 @@ session_lock_output_create(struct session_lock_manager *manager, struct output * * already locked, blank immediately. */ lock_output->blank_timer = - wl_event_loop_add_timer(g_server.wl_event_loop, + wl_event_loop_add_timer(server.wl_event_loop, handle_output_blank_timeout, lock_output); if (!manager->locked) { wlr_scene_node_set_enabled(&background->node, false); @@ -323,11 +323,11 @@ handle_new_session_lock(struct wl_listener *listener, void *data) assert(wl_list_empty(&manager->lock_outputs)); /* Remember the focused view to restore it on unlock */ - manager->last_active_view = g_server.active_view; - seat_focus_surface(&g_server.seat, NULL); + manager->last_active_view = server.active_view; + seat_focus_surface(&server.seat, NULL); struct output *output; - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { session_lock_output_create(manager, output); } @@ -353,7 +353,7 @@ handle_manager_destroy(struct wl_listener *listener, void *data) session_lock_destroy(manager); wl_list_remove(&manager->new_lock.link); wl_list_remove(&manager->destroy.link); - g_server.session_lock_manager = NULL; + server.session_lock_manager = NULL; free(manager); } @@ -361,8 +361,8 @@ void session_lock_init(void) { struct session_lock_manager *manager = znew(*manager); - g_server.session_lock_manager = manager; - manager->wlr_manager = wlr_session_lock_manager_v1_create(g_server.wl_display); + server.session_lock_manager = manager; + manager->wlr_manager = wlr_session_lock_manager_v1_create(server.wl_display); wl_list_init(&manager->lock_outputs); manager->new_lock.notify = handle_new_session_lock; @@ -375,16 +375,16 @@ session_lock_init(void) void session_lock_update_for_layout_change(void) { - if (!g_server.session_lock_manager->locked) { + if (!server.session_lock_manager->locked) { return; } struct output *output; - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { align_session_lock_tree(output); } - struct session_lock_manager *manager = g_server.session_lock_manager; + struct session_lock_manager *manager = server.session_lock_manager; struct session_lock_output *lock_output; wl_list_for_each(lock_output, &manager->lock_outputs, link) { lock_output_reconfigure(lock_output); diff --git a/src/ssd/resize-indicator.c b/src/ssd/resize-indicator.c index 0777b00f..fa1166a3 100644 --- a/src/ssd/resize-indicator.c +++ b/src/ssd/resize-indicator.c @@ -62,7 +62,7 @@ wants_indicator(struct view *view) assert(view); if (rc.resize_indicator == LAB_RESIZE_INDICATOR_NON_PIXEL) { - if (g_server.input_mode != LAB_INPUT_STATE_RESIZE) { + if (server.input_mode != LAB_INPUT_STATE_RESIZE) { return false; } struct view_size_hints hints = view_get_size_hints(view); @@ -77,12 +77,12 @@ void resize_indicator_reconfigure(void) { struct view *view; - wl_list_for_each(view, &g_server.views, link) { + wl_list_for_each(view, &server.views, link) { struct resize_indicator *indicator = &view->resize_indicator; if (indicator->tree) { resize_indicator_reconfigure_view(indicator); } - if (view != g_server.grabbed_view) { + if (view != server.grabbed_view) { continue; } @@ -143,7 +143,7 @@ void resize_indicator_update(struct view *view) { assert(view); - assert(view == g_server.grabbed_view); + assert(view == server.grabbed_view); if (!wants_indicator(view)) { return; @@ -173,21 +173,21 @@ resize_indicator_update(struct view *view) view_box.height = view_effective_height(view, /* use_pending */ false); } - if (g_server.input_mode == LAB_INPUT_STATE_RESIZE) { + if (server.input_mode == LAB_INPUT_STATE_RESIZE) { struct view_size_hints hints = view_get_size_hints(view); snprintf(text, sizeof(text), "%d x %d", MAX(0, view_box.width - hints.base_width) / MAX(1, hints.width_inc), MAX(0, view_box.height - hints.base_height) / MAX(1, hints.height_inc)); - } else if (g_server.input_mode == LAB_INPUT_STATE_MOVE) { + } else if (server.input_mode == LAB_INPUT_STATE_MOVE) { struct border margin = ssd_get_margin(view->ssd); snprintf(text, sizeof(text), "%d , %d", view_box.x - margin.left, view_box.y - margin.top); } else { wlr_log(WLR_ERROR, "Invalid input mode for indicator update %u", - g_server.input_mode); + server.input_mode); return; } diff --git a/src/ssd/ssd-border.c b/src/ssd/ssd-border.c index 9157ebfc..0589b0c8 100644 --- a/src/ssd/ssd-border.c +++ b/src/ssd/ssd-border.c @@ -17,7 +17,7 @@ ssd_border_create(struct ssd *ssd) assert(!ssd->border.tree); struct view *view = ssd->view; - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; int width = view->current.width; int height = view_effective_height(view, /* use_pending */ false); int full_width = width + 2 * theme->border_width; @@ -90,7 +90,7 @@ ssd_border_update(struct ssd *ssd) ssd->margin = ssd_thickness(ssd->view); } - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; int width = view->current.width; int height = view_effective_height(view, /* use_pending */ false); diff --git a/src/ssd/ssd-extents.c b/src/ssd/ssd-extents.c index 9e650825..389ae70d 100644 --- a/src/ssd/ssd-extents.c +++ b/src/ssd/ssd-extents.c @@ -14,7 +14,7 @@ void ssd_extents_create(struct ssd *ssd) { struct view *view = ssd->view; - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; int border_width = MAX(0, MAX(rc.resize_minimum_area, theme->border_width)); @@ -100,7 +100,7 @@ ssd_extents_update(struct ssd *ssd) return; } - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; int width = view->current.width; int height = view_effective_height(view, /* use_pending */ false); @@ -120,7 +120,7 @@ ssd_extents_update(struct ssd *ssd) pixman_region32_t usable; pixman_region32_init(&usable); struct output *output; - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { if (!view_on_output(view, output)) { continue; } diff --git a/src/ssd/ssd-shadow.c b/src/ssd/ssd-shadow.c index da864944..cbcdc7bc 100644 --- a/src/ssd/ssd-shadow.c +++ b/src/ssd/ssd-shadow.c @@ -145,7 +145,7 @@ static void set_shadow_geometry(struct ssd *ssd) { struct view *view = ssd->view; - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; int titlebar_height = ssd->titlebar.height; int width = view->current.width; int height = view_effective_height(view, false) + titlebar_height; @@ -203,7 +203,7 @@ ssd_shadow_create(struct ssd *ssd) ssd->shadow.tree = lab_wlr_scene_tree_create(ssd->tree); - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; struct view *view = ssd->view; enum ssd_active_state active; @@ -256,7 +256,7 @@ ssd_shadow_update(struct ssd *ssd) assert(ssd->shadow.tree); struct view *view = ssd->view; - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; bool maximized = view->maximized == VIEW_AXIS_BOTH; bool tiled_shadows = false; if (rc.shadows_on_tiled) { diff --git a/src/ssd/ssd-titlebar.c b/src/ssd/ssd-titlebar.c index ab9aa0db..97214ea6 100644 --- a/src/ssd/ssd-titlebar.c +++ b/src/ssd/ssd-titlebar.c @@ -27,7 +27,7 @@ void ssd_titlebar_create(struct ssd *ssd) { struct view *view = ssd->view; - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; int width = view->current.width; int corner_width = ssd_get_corner_width(); @@ -58,7 +58,7 @@ ssd_titlebar_create(struct ssd *ssd) * TODO: remove once https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3990 * is solved */ - if (wlr_renderer_is_pixman(g_server.renderer)) { + if (wlr_renderer_is_pixman(server.renderer)) { wlr_scene_buffer_set_filter_mode( subtree->bar, WLR_SCALE_FILTER_NEAREST); } @@ -160,7 +160,7 @@ set_squared_corners(struct ssd *ssd, bool enable) struct view *view = ssd->view; int width = view->current.width; int corner_width = ssd_get_corner_width(); - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; int x = enable ? 0 : corner_width; @@ -220,7 +220,7 @@ static void update_visible_buttons(struct ssd *ssd) { struct view *view = ssd->view; - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; int width = MAX(view->current.width - 2 * theme->window_titlebar_padding_width, 0); int button_width = theme->window_button_width; int button_spacing = theme->window_button_spacing; @@ -273,7 +273,7 @@ ssd_titlebar_update(struct ssd *ssd) struct view *view = ssd->view; int width = view->current.width; int corner_width = ssd_get_corner_width(); - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; bool maximized = view->maximized == VIEW_AXIS_BOTH; bool squared = ssd_should_be_squared(ssd); @@ -365,7 +365,7 @@ static void ssd_update_title_positions(struct ssd *ssd, int offset_left, int offset_right) { struct view *view = ssd->view; - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; int width = view->current.width; int title_bg_width = width - offset_left - offset_right; @@ -413,9 +413,9 @@ static void get_title_offsets(struct ssd *ssd, int *offset_left, int *offset_right) { struct ssd_titlebar_subtree *subtree = &ssd->titlebar.subtrees[SSD_ACTIVE]; - int button_width = g_server.theme->window_button_width; - int button_spacing = g_server.theme->window_button_spacing; - int padding_width = g_server.theme->window_titlebar_padding_width; + int button_width = server.theme->window_button_width; + int button_spacing = server.theme->window_button_spacing; + int padding_width = server.theme->window_titlebar_padding_width; *offset_left = padding_width; *offset_right = padding_width; @@ -443,7 +443,7 @@ ssd_update_title(struct ssd *ssd) /* view->title is never NULL (instead it can be an empty string) */ assert(view->title); - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; struct ssd_state_title *state = &ssd->state.title; bool title_unchanged = state->text && !strcmp(view->title, state->text); @@ -493,17 +493,17 @@ ssd_update_hovered_button(struct wlr_scene_node *node) if (node && node->data) { button = node_try_ssd_button_from_node(node); - if (button == g_server.hovered_button) { + if (button == server.hovered_button) { /* Cursor is still on the same button */ return; } } /* Disable old hover */ - if (g_server.hovered_button) { - update_button_state(g_server.hovered_button, LAB_BS_HOVERED, false); + if (server.hovered_button) { + update_button_state(server.hovered_button, LAB_BS_HOVERED, false); } - g_server.hovered_button = button; + server.hovered_button = button; if (button) { update_button_state(button, LAB_BS_HOVERED, true); } diff --git a/src/ssd/ssd.c b/src/ssd/ssd.c index afd7d4de..b71de1c4 100644 --- a/src/ssd/ssd.c +++ b/src/ssd/ssd.c @@ -39,7 +39,7 @@ ssd_thickness(struct view *view) return (struct border){ 0 }; } - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; if (view->maximized == VIEW_AXIS_BOTH) { struct border thickness = { 0 }; @@ -101,7 +101,7 @@ ssd_get_resizing_type(const struct ssd *ssd, struct wlr_cursor *cursor) if (view_titlebar_visible(view)) { /* If the titlebar is visible, consider it part of the view */ - int titlebar_height = g_server.theme->titlebar_height; + int titlebar_height = server.theme->titlebar_height; view_box.y -= titlebar_height; view_box.height += titlebar_height; } @@ -156,7 +156,7 @@ ssd_create(struct view *view, bool active) LAB_NODE_SSD_ROOT, view, /*data*/ NULL); wlr_scene_node_lower_to_bottom(&ssd->tree->node); - ssd->titlebar.height = g_server.theme->titlebar_height; + ssd->titlebar.height = server.theme->titlebar_height; ssd_shadow_create(ssd); ssd_extents_create(ssd); /* @@ -257,7 +257,7 @@ ssd_set_titlebar(struct ssd *ssd, bool enabled) return; } wlr_scene_node_set_enabled(&ssd->titlebar.tree->node, enabled); - ssd->titlebar.height = enabled ? g_server.theme->titlebar_height : 0; + ssd->titlebar.height = enabled ? server.theme->titlebar_height : 0; ssd_border_update(ssd); ssd_extents_update(ssd); ssd_shadow_update(ssd); @@ -273,9 +273,9 @@ ssd_destroy(struct ssd *ssd) /* Maybe reset hover view */ struct view *view = ssd->view; - if (g_server.hovered_button && node_view_from_node( - g_server.hovered_button->node) == view) { - g_server.hovered_button = NULL; + if (server.hovered_button && node_view_from_node( + server.hovered_button->node) == view) { + server.hovered_button = NULL; } /* Destroy subcomponents */ diff --git a/src/tearing.c b/src/tearing.c index b39e8184..541bf813 100644 --- a/src/tearing.c +++ b/src/tearing.c @@ -44,7 +44,7 @@ handle_tearing_new_object(struct wl_listener *listener, void *data) enum wp_tearing_control_v1_presentation_hint hint = wlr_tearing_control_manager_v1_surface_hint_from_surface - (g_server.tearing_control, tearing_control->surface); + (server.tearing_control, tearing_control->surface); wlr_log(WLR_DEBUG, "New presentation hint %d received for surface %p", hint, tearing_control->surface); diff --git a/src/theme.c b/src/theme.c index 468e1840..93ac1c5e 100644 --- a/src/theme.c +++ b/src/theme.c @@ -634,7 +634,7 @@ theme_builtin(struct theme *theme) theme->osd_border_color[0] = FLT_MIN; theme->osd_label_text_color[0] = FLT_MIN; - if (wlr_renderer_is_pixman(g_server.renderer)) { + if (wlr_renderer_is_pixman(server.renderer)) { /* Draw only outlined overlay by default to save CPU resource */ theme->snapping_overlay_region.bg_enabled = false; theme->snapping_overlay_edge.bg_enabled = false; diff --git a/src/view-impl-common.c b/src/view-impl-common.c index cff0651a..092ca55f 100644 --- a/src/view-impl-common.c +++ b/src/view-impl-common.c @@ -50,11 +50,11 @@ view_impl_unmap(struct view *view) * When exiting an xwayland application with multiple views * mapped, a race condition can occur: after the topmost view * is unmapped, the next view under it is offered focus, but is - * also unmapped before accepting focus (so g_server.active_view + * also unmapped before accepting focus (so server.active_view * remains NULL). To avoid being left with no active view at * all, check for that case also. */ - if (view == g_server.active_view || !g_server.active_view) { + if (view == server.active_view || !server.active_view) { desktop_focus_topmost_view(); } @@ -71,9 +71,9 @@ view_impl_unmap(struct view *view) static bool resizing_edge(struct view *view, enum lab_edge edge) { - return g_server.input_mode == LAB_INPUT_STATE_RESIZE - && g_server.grabbed_view == view - && (g_server.resize_edges & edge); + return server.input_mode == LAB_INPUT_STATE_RESIZE + && server.grabbed_view == view + && (server.resize_edges & edge); } void diff --git a/src/view.c b/src/view.c index 7c6067af..b9f33697 100644 --- a/src/view.c +++ b/src/view.c @@ -69,7 +69,7 @@ security_context_from_view(struct view *view) if (view && view->surface && view->surface->resource) { struct wl_client *client = wl_resource_get_client(view->surface->resource); return wlr_security_context_manager_v1_lookup_client( - g_server.security_context_manager_v1, client); + server.security_context_manager_v1, client); } return NULL; } @@ -176,7 +176,7 @@ view_matches_query(struct view *view, struct view_query *query) return false; } - if (!query_tristate_match(query->focused, g_server.active_view == view)) { + if (!query_tristate_match(query->focused, server.active_view == view)) { return false; } @@ -202,7 +202,7 @@ view_matches_query(struct view *view, struct view_query *query) if (query->desktop) { const char *view_workspace = view->workspace->name; - struct workspace *current = g_server.workspaces.current; + struct workspace *current = server.workspaces.current; if (!strcasecmp(query->desktop, "other")) { /* "other" means the view is NOT on the current desktop */ @@ -268,7 +268,7 @@ matches_criteria(struct view *view, enum lab_view_criteria criteria) return false; } if (criteria & LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { - if (view->workspace != g_server.workspaces.current) { + if (view->workspace != server.workspaces.current) { return false; } } @@ -342,7 +342,7 @@ view_array_append(struct wl_array *views, enum lab_view_criteria criteria) { struct view *view; - for_each_view(view, &g_server.views, criteria) { + for_each_view(view, &server.views, criteria) { struct view **entry = wl_array_add(views, sizeof(*entry)); if (!entry) { wlr_log(WLR_ERROR, "wl_array_add(): out of memory"); @@ -472,10 +472,10 @@ view_set_activated(struct view *view, bool activated) if (!activated) { /* Store configured keyboard layout per view */ view->keyboard_layout = - g_server.seat.keyboard_group->keyboard.modifiers.group; + server.seat.keyboard_group->keyboard.modifiers.group; } else { /* Switch to previously stored keyboard layout */ - keyboard_update_layout(&g_server.seat, view->keyboard_layout); + keyboard_update_layout(&server.seat, view->keyboard_layout); } } output_set_has_fullscreen_view(view->output, view->fullscreen); @@ -509,10 +509,10 @@ static void view_update_outputs(struct view *view) { struct output *output; - struct wlr_output_layout *layout = g_server.output_layout; + struct wlr_output_layout *layout = server.output_layout; uint64_t new_outputs = 0; - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { if (output_is_usable(output) && wlr_output_layout_intersects( layout, output->wlr_output, &view->current)) { new_outputs |= output->id_bit; @@ -562,7 +562,7 @@ view_moved(struct view *view) view_update_outputs(view); ssd_update_geometry(view->ssd); cursor_update_focus(); - if (rc.resize_indicator && g_server.grabbed_view == view) { + if (rc.resize_indicator && server.grabbed_view == view) { resize_indicator_update(view); } } @@ -641,7 +641,7 @@ view_compute_near_cursor_position(struct view *view, struct wlr_box *geom) } struct border margin = ssd_thickness(view); - struct seat *seat = &g_server.seat; + struct seat *seat = &server.seat; int total_width = geom->width + margin.left + margin.right; int total_height = geom->height + margin.top + margin.bottom; @@ -746,7 +746,7 @@ _minimize(struct view *view, bool minimized, bool *need_refocus) * - unminimizing any mapped view */ *need_refocus |= (minimized ? - (view == g_server.active_view) : view->mapped); + (view == server.active_view) : view->mapped); } static void @@ -785,7 +785,7 @@ view_minimize(struct view *view, bool minimized) assert(view); bool need_refocus = false; - if (g_server.input_mode == LAB_INPUT_STATE_CYCLE) { + if (server.input_mode == LAB_INPUT_STATE_CYCLE) { wlr_log(WLR_ERROR, "not minimizing window while window switching"); return; } @@ -860,7 +860,7 @@ adjust_floating_geometry(struct view *view, struct wlr_box *geometry, bool adjusted = false; bool onscreen = false; - if (wlr_output_layout_intersects(g_server.output_layout, + if (wlr_output_layout_intersects(server.output_layout, view->output->wlr_output, geometry)) { /* Always make sure the titlebar starts within the usable area */ struct border margin = ssd_get_margin(view->ssd); @@ -994,7 +994,7 @@ view_compute_cascaded_position(struct view *view, struct wlr_box *geom) /* TODO: move this logic to rcxml.c */ int offset_x = rc.placement_cascade_offset_x; int offset_y = rc.placement_cascade_offset_y; - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; int default_offset = theme->titlebar_height + theme->border_width + 5; if (offset_x <= 0) { offset_x = default_offset; @@ -1014,7 +1014,7 @@ view_compute_cascaded_position(struct view *view, struct wlr_box *geom) /* Iterate over views from top to bottom */ struct view *other_view; - for_each_view(other_view, &g_server.views, + for_each_view(other_view, &server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { struct wlr_box other = ssd_max_extents(other_view); if (other_view == view @@ -1249,7 +1249,7 @@ view_apply_fullscreen_geometry(struct view *view) assert(output_is_usable(view->output)); struct wlr_box box = { 0 }; - wlr_output_layout_get_box(g_server.output_layout, + wlr_output_layout_get_box(server.output_layout, view->output->wlr_output, &box); view_move_resize(view, box); } @@ -1403,8 +1403,8 @@ view_set_untiled(struct view *view) static bool in_interactive_move(struct view *view) { - return (g_server.input_mode == LAB_INPUT_STATE_MOVE - && g_server.grabbed_view == view); + return (server.input_mode == LAB_INPUT_STATE_MOVE + && server.grabbed_view == view); } void @@ -1598,7 +1598,7 @@ decorate(struct view *view) { if (!view->ssd) { view->ssd = ssd_create(view, - view == g_server.active_view); + view == server.active_view); } } @@ -2166,7 +2166,7 @@ static void move_to_front(struct view *view) { wl_list_remove(&view->link); - wl_list_insert(&g_server.views, &view->link); + wl_list_insert(&server.views, &view->link); wlr_scene_node_raise_to_top(&view->scene_tree->node); } @@ -2174,7 +2174,7 @@ static void move_to_back(struct view *view) { wl_list_remove(&view->link); - wl_list_append(&g_server.views, &view->link); + wl_list_append(&server.views, &view->link); wlr_scene_node_lower_to_bottom(&view->scene_tree->node); } @@ -2188,14 +2188,14 @@ void view_move_to_front(struct view *view) { assert(view); - assert(!wl_list_empty(&g_server.views)); + assert(!wl_list_empty(&server.views)); /* * Check whether the view is already in front, or is the root * parent of the view in front (in which case we don't want to * raise it in front of its sub-view). */ - struct view *front = wl_container_of(g_server.views.next, front, link); + struct view *front = wl_container_of(server.views.next, front, link); if (view == front || view == view_get_root(front)) { return; } @@ -2422,7 +2422,7 @@ view_set_shade(struct view *view, bool shaded) } /* If this window is being resized, cancel the resize when shading */ - if (shaded && g_server.input_mode == LAB_INPUT_STATE_RESIZE) { + if (shaded && server.input_mode == LAB_INPUT_STATE_RESIZE) { interactive_cancel(view); } @@ -2511,16 +2511,16 @@ view_destroy(struct view *view) * This check is (in theory) redundant since interactive_cancel() * is called at unmap. Leaving it here just to be sure. */ - if (g_server.grabbed_view == view) { + if (server.grabbed_view == view) { interactive_cancel(view); } - if (g_server.active_view == view) { - g_server.active_view = NULL; + if (server.active_view == view) { + server.active_view = NULL; } - if (g_server.session_lock_manager->last_active_view == view) { - g_server.session_lock_manager->last_active_view = NULL; + if (server.session_lock_manager->last_active_view == view) { + server.session_lock_manager->last_active_view = NULL; } if (view->tiled_region_evacuate) { @@ -2560,7 +2560,7 @@ view_destroy(struct view *view) zfree(view->title); zfree(view->app_id); - /* Remove view from g_server.views */ + /* Remove view from server.views */ wl_list_remove(&view->link); free(view); diff --git a/src/window-rules.c b/src/window-rules.c index 9cbcbd4e..3911be7d 100644 --- a/src/window-rules.c +++ b/src/window-rules.c @@ -12,7 +12,7 @@ static bool other_instances_exist(struct view *self, struct view_query *query) { - struct wl_list *views = &g_server.views; + struct wl_list *views = &server.views; struct view *view; wl_list_for_each(view, views, link) { diff --git a/src/workspaces.c b/src/workspaces.c index 340dd372..c11690da 100644 --- a/src/workspaces.c +++ b/src/workspaces.c @@ -64,7 +64,7 @@ parse_workspace_index(const char *name) static void _osd_update(void) { - struct theme *theme = g_server.theme; + struct theme *theme = server.theme; /* Settings */ uint16_t margin = 10; @@ -75,7 +75,7 @@ _osd_update(void) theme->osd_workspace_switcher_boxes_height == 0; /* Dimensions */ - size_t workspace_count = wl_list_length(&g_server.workspaces.all); + size_t workspace_count = wl_list_length(&server.workspaces.all); uint16_t marker_width = workspace_count * (rect_width + padding) - padding; uint16_t width = margin * 2 + (marker_width < 200 ? 200 : marker_width); uint16_t height = margin * (hide_boxes ? 2 : 3) + rect_height + font_height(&rc.font_osd); @@ -85,7 +85,7 @@ _osd_update(void) struct workspace *workspace; struct output *output; - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { if (!output_is_usable(output)) { continue; } @@ -115,9 +115,9 @@ _osd_update(void) uint16_t x; if (!hide_boxes) { x = (width - marker_width) / 2; - wl_list_for_each(workspace, &g_server.workspaces.all, link) { - bool active = workspace == g_server.workspaces.current; - set_cairo_color(cairo, g_server.theme->osd_label_text_color); + wl_list_for_each(workspace, &server.workspaces.all, link) { + bool active = workspace == server.workspaces.current; + set_cairo_color(cairo, server.theme->osd_label_text_color); struct wlr_fbox fbox = { .x = x, .y = margin, @@ -136,13 +136,13 @@ _osd_update(void) } /* Text */ - set_cairo_color(cairo, g_server.theme->osd_label_text_color); + set_cairo_color(cairo, server.theme->osd_label_text_color); PangoLayout *layout = pango_cairo_create_layout(cairo); pango_context_set_round_glyph_positions(pango_layout_get_context(layout), false); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); /* Center workspace indicator on the x axis */ - int req_width = font_width(&rc.font_osd, g_server.workspaces.current->name); + int req_width = font_width(&rc.font_osd, server.workspaces.current->name); req_width = MIN(req_width, width - 2 * margin); x = (width - req_width) / 2; if (!hide_boxes) { @@ -155,7 +155,7 @@ _osd_update(void) pango_layout_set_font_description(layout, desc); pango_layout_set_width(layout, req_width * PANGO_SCALE); pango_font_description_free(desc); - pango_layout_set_text(layout, g_server.workspaces.current->name, -1); + pango_layout_set_text(layout, server.workspaces.current->name, -1); pango_cairo_show_layout(cairo, layout); g_object_unref(layout); @@ -165,11 +165,11 @@ _osd_update(void) if (!output->workspace_osd) { output->workspace_osd = lab_wlr_scene_buffer_create( - &g_server.scene->tree, NULL); + &server.scene->tree, NULL); } /* Position the whole thing */ struct wlr_box output_box; - wlr_output_layout_get_box(g_server.output_layout, + wlr_output_layout_get_box(server.output_layout, output->wlr_output, &output_box); int lx = output_box.x + (output_box.width - width) / 2; int ly = output_box.y + (output_box.height - height) / 2; @@ -192,7 +192,7 @@ workspace_find_by_name(const char *name) size_t parsed_index = parse_workspace_index(name); if (parsed_index) { size_t index = 0; - wl_list_for_each(workspace, &g_server.workspaces.all, link) { + wl_list_for_each(workspace, &server.workspaces.all, link) { if (parsed_index == ++index) { return workspace; } @@ -200,7 +200,7 @@ workspace_find_by_name(const char *name) } /* by name */ - wl_list_for_each(workspace, &g_server.workspaces.all, link) { + wl_list_for_each(workspace, &server.workspaces.all, link) { if (!strcmp(workspace->name, name)) { return workspace; } @@ -234,18 +234,18 @@ add_workspace(const char *name) { struct workspace *workspace = znew(*workspace); workspace->name = xstrdup(name); - workspace->tree = lab_wlr_scene_tree_create(g_server.workspace_tree); + workspace->tree = lab_wlr_scene_tree_create(server.workspace_tree); workspace->view_trees[VIEW_LAYER_ALWAYS_ON_BOTTOM] = lab_wlr_scene_tree_create(workspace->tree); workspace->view_trees[VIEW_LAYER_NORMAL] = lab_wlr_scene_tree_create(workspace->tree); workspace->view_trees[VIEW_LAYER_ALWAYS_ON_TOP] = lab_wlr_scene_tree_create(workspace->tree); - wl_list_append(&g_server.workspaces.all, &workspace->link); + wl_list_append(&server.workspaces.all, &workspace->link); wlr_scene_node_set_enabled(&workspace->tree->node, false); /* cosmic */ - workspace->cosmic_workspace = lab_cosmic_workspace_create(g_server.workspaces.cosmic_group); + workspace->cosmic_workspace = lab_cosmic_workspace_create(server.workspaces.cosmic_group); lab_cosmic_workspace_set_name(workspace->cosmic_workspace, name); workspace->on_cosmic.activate.notify = handle_cosmic_workspace_activate; @@ -254,8 +254,8 @@ add_workspace(const char *name) /* ext */ workspace->ext_workspace = lab_ext_workspace_create( - g_server.workspaces.ext_manager, /*id*/ NULL); - lab_ext_workspace_assign_to_group(workspace->ext_workspace, g_server.workspaces.ext_group); + server.workspaces.ext_manager, /*id*/ NULL); + lab_ext_workspace_assign_to_group(workspace->ext_workspace, server.workspaces.ext_group); lab_ext_workspace_set_name(workspace->ext_workspace, name); workspace->on_ext.activate.notify = handle_ext_workspace_activate; @@ -298,7 +298,7 @@ workspace_has_views(struct workspace *workspace) { struct view *view; - for_each_view(view, &g_server.views, LAB_VIEW_CRITERIA_NO_OMNIPRESENT) { + for_each_view(view, &server.views, LAB_VIEW_CRITERIA_NO_OMNIPRESENT) { if (view->workspace == workspace) { return true; } @@ -379,21 +379,21 @@ _osd_show(void) _osd_update(); struct output *output; - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { if (output_is_usable(output) && output->workspace_osd) { wlr_scene_node_set_enabled(&output->workspace_osd->node, true); } } - if (keyboard_get_all_modifiers(&g_server.seat)) { + if (keyboard_get_all_modifiers(&server.seat)) { /* Hidden by release of all modifiers */ - g_server.seat.workspace_osd_shown_by_modifier = true; + server.seat.workspace_osd_shown_by_modifier = true; } else { /* Hidden by timer */ - if (!g_server.seat.workspace_osd_timer) { - g_server.seat.workspace_osd_timer = wl_event_loop_add_timer( - g_server.wl_event_loop, _osd_handle_timeout, &g_server.seat); + if (!server.seat.workspace_osd_timer) { + server.seat.workspace_osd_timer = wl_event_loop_add_timer( + server.wl_event_loop, _osd_handle_timeout, &server.seat); } - wl_event_source_timer_update(g_server.seat.workspace_osd_timer, + wl_event_source_timer_update(server.seat.workspace_osd_timer, rc.workspace_config.popuptime); } } @@ -402,21 +402,21 @@ _osd_show(void) void workspaces_init(void) { - g_server.workspaces.cosmic_manager = lab_cosmic_workspace_manager_create( - g_server.wl_display, /* capabilities */ CW_CAP_WS_ACTIVATE, + server.workspaces.cosmic_manager = lab_cosmic_workspace_manager_create( + server.wl_display, /* capabilities */ CW_CAP_WS_ACTIVATE, COSMIC_WORKSPACES_VERSION); - g_server.workspaces.ext_manager = lab_ext_workspace_manager_create( - g_server.wl_display, /* capabilities */ WS_CAP_WS_ACTIVATE, + server.workspaces.ext_manager = lab_ext_workspace_manager_create( + server.wl_display, /* capabilities */ WS_CAP_WS_ACTIVATE, EXT_WORKSPACES_VERSION); - g_server.workspaces.cosmic_group = lab_cosmic_workspace_group_create( - g_server.workspaces.cosmic_manager); + server.workspaces.cosmic_group = lab_cosmic_workspace_group_create( + server.workspaces.cosmic_manager); - g_server.workspaces.ext_group = lab_ext_workspace_group_create( - g_server.workspaces.ext_manager); + server.workspaces.ext_group = lab_ext_workspace_group_create( + server.workspaces.ext_manager); - wl_list_init(&g_server.workspaces.all); + wl_list_init(&server.workspaces.all); struct workspace_config *conf; wl_list_for_each(conf, &rc.workspace_config.workspaces, link) { @@ -430,7 +430,7 @@ workspaces_init(void) char *initial_name = rc.workspace_config.initial_workspace_name; struct workspace *initial = NULL; struct workspace *first = wl_container_of( - g_server.workspaces.all.next, first, link); + server.workspaces.all.next, first, link); if (initial_name) { initial = workspace_find_by_name(initial_name); @@ -439,7 +439,7 @@ workspaces_init(void) initial = first; } - g_server.workspaces.current = initial; + server.workspaces.current = initial; wlr_scene_node_set_enabled(&initial->tree->node, true); lab_cosmic_workspace_set_active(initial->cosmic_workspace, true); lab_ext_workspace_set_active(initial->ext_workspace, true); @@ -454,18 +454,18 @@ void workspaces_switch_to(struct workspace *target, bool update_focus) { assert(target); - if (target == g_server.workspaces.current) { + if (target == server.workspaces.current) { return; } /* Disable the old workspace */ wlr_scene_node_set_enabled( - &g_server.workspaces.current->tree->node, false); + &server.workspaces.current->tree->node, false); lab_cosmic_workspace_set_active( - g_server.workspaces.current->cosmic_workspace, false); + server.workspaces.current->cosmic_workspace, false); lab_ext_workspace_set_active( - g_server.workspaces.current->ext_workspace, false); + server.workspaces.current->ext_workspace, false); /* * Move Omnipresent views to new workspace. @@ -473,7 +473,7 @@ workspaces_switch_to(struct workspace *target, bool update_focus) * view_is_focusable() returns false (e.g. Conky). */ struct view *view; - wl_list_for_each_reverse(view, &g_server.views, link) { + wl_list_for_each_reverse(view, &server.views, link) { if (view->visible_on_all_workspaces) { view_move_to_workspace(view, target); } @@ -483,12 +483,12 @@ workspaces_switch_to(struct workspace *target, bool update_focus) wlr_scene_node_set_enabled(&target->tree->node, true); /* Save the last visited workspace */ - g_server.workspaces.last = g_server.workspaces.current; + server.workspaces.last = server.workspaces.current; /* Make sure new views will spawn on the new workspace */ - g_server.workspaces.current = target; + server.workspaces.current = target; - struct view *grabbed_view = g_server.grabbed_view; + struct view *grabbed_view = server.grabbed_view; if (grabbed_view) { view_move_to_workspace(grabbed_view, target); } @@ -498,7 +498,7 @@ workspaces_switch_to(struct workspace *target, bool update_focus) * the focus is not already on an omnipresent view. */ if (update_focus) { - struct view *active_view = g_server.active_view; + struct view *active_view = server.active_view; if (!(active_view && active_view->visible_on_all_workspaces)) { desktop_focus_topmost_view(); } @@ -525,7 +525,7 @@ workspaces_osd_hide(struct seat *seat) { assert(seat); struct output *output; - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { if (!output->workspace_osd) { continue; } @@ -545,12 +545,12 @@ workspaces_find(struct workspace *anchor, const char *name, bool wrap) if (!name) { return NULL; } - struct wl_list *workspaces = &g_server.workspaces.all; + struct wl_list *workspaces = &server.workspaces.all; if (!strcasecmp(name, "current")) { return anchor; } else if (!strcasecmp(name, "last")) { - return g_server.workspaces.last; + return server.workspaces.last; } else if (!strcasecmp(name, "left")) { return get_prev(anchor, workspaces, wrap); } else if (!strcasecmp(name, "right")) { @@ -587,14 +587,14 @@ workspaces_reconfigure(void) * - Destroy workspaces if fewer workspace are desired */ - struct wl_list *workspace_link = g_server.workspaces.all.next; + struct wl_list *workspace_link = server.workspaces.all.next; struct workspace_config *conf; wl_list_for_each(conf, &rc.workspace_config.workspaces, link) { struct workspace *workspace = wl_container_of( workspace_link, workspace, link); - if (workspace_link == &g_server.workspaces.all) { + if (workspace_link == &server.workspaces.all) { /* # of configured workspaces increased */ wlr_log(WLR_DEBUG, "Adding workspace \"%s\"", conf->name); @@ -614,16 +614,16 @@ workspaces_reconfigure(void) workspace_link = workspace_link->next; } - if (workspace_link == &g_server.workspaces.all) { + if (workspace_link == &server.workspaces.all) { return; } /* # of configured workspaces decreased */ - overlay_finish(&g_server.seat); + overlay_finish(&server.seat); struct workspace *first_workspace = - wl_container_of(g_server.workspaces.all.next, first_workspace, link); + wl_container_of(server.workspaces.all.next, first_workspace, link); - while (workspace_link != &g_server.workspaces.all) { + while (workspace_link != &server.workspaces.all) { struct workspace *workspace = wl_container_of( workspace_link, workspace, link); @@ -631,18 +631,18 @@ workspaces_reconfigure(void) workspace->name); struct view *view; - wl_list_for_each(view, &g_server.views, link) { + wl_list_for_each(view, &server.views, link) { if (view->workspace == workspace) { view_move_to_workspace(view, first_workspace); } } - if (g_server.workspaces.current == workspace) { + if (server.workspaces.current == workspace) { workspaces_switch_to(first_workspace, /* update_focus */ true); } - if (g_server.workspaces.last == workspace) { - g_server.workspaces.last = first_workspace; + if (server.workspaces.last == workspace) { + server.workspaces.last = first_workspace; } workspace_link = workspace_link->next; @@ -654,8 +654,8 @@ void workspaces_destroy(void) { struct workspace *workspace, *tmp; - wl_list_for_each_safe(workspace, tmp, &g_server.workspaces.all, link) { + wl_list_for_each_safe(workspace, tmp, &server.workspaces.all, link) { destroy_workspace(workspace); } - assert(wl_list_empty(&g_server.workspaces.all)); + assert(wl_list_empty(&server.workspaces.all)); } diff --git a/src/xdg-popup.c b/src/xdg-popup.c index f4c623f9..04f82f9e 100644 --- a/src/xdg-popup.c +++ b/src/xdg-popup.c @@ -149,15 +149,15 @@ xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup) * this, we always set the user data field of wlr_surfaces to the * corresponding scene node. * - * xdg-popups live in g_server.xdg_popup_tree so that they can be + * xdg-popups live in server.xdg_popup_tree so that they can be * rendered above always-on-top windows */ struct wlr_scene_tree *parent_tree = NULL; if (parent->role == WLR_XDG_SURFACE_ROLE_POPUP) { parent_tree = parent->surface->data; } else { - parent_tree = g_server.xdg_popup_tree; - wlr_scene_node_set_position(&g_server.xdg_popup_tree->node, + parent_tree = server.xdg_popup_tree; + wlr_scene_node_set_position(&server.xdg_popup_tree->node, view->current.x, view->current.y); } wlr_popup->base->surface->data = diff --git a/src/xdg.c b/src/xdg.c index b3da3e74..5092ab7a 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -131,8 +131,8 @@ set_initial_position(struct view *view) view_constrain_size_to_that_of_usable_area(view); - if (g_server.input_mode == LAB_INPUT_STATE_MOVE - && view == g_server.grabbed_view) { + if (server.input_mode == LAB_INPUT_STATE_MOVE + && view == server.grabbed_view) { /* Reposition the view while anchoring it to cursor */ interactive_anchor_to_cursor(&view->pending); } else { @@ -173,7 +173,7 @@ center_fullscreen_if_needed(struct view *view) } struct wlr_box output_box = {0}; - wlr_output_layout_get_box(g_server.output_layout, + wlr_output_layout_get_box(server.output_layout, view->output->wlr_output, &output_box); box_center(view->current.width, view->current.height, &output_box, &output_box, &view->current.x, &view->current.y); @@ -437,7 +437,7 @@ set_pending_configure_serial(struct view *view, uint32_t serial) view->pending_configure_serial = serial; if (!view->pending_configure_timeout) { view->pending_configure_timeout = - wl_event_loop_add_timer(g_server.wl_event_loop, + wl_event_loop_add_timer(server.wl_event_loop, handle_configure_timeout, view); } wl_event_source_timer_update(view->pending_configure_timeout, @@ -485,7 +485,7 @@ handle_request_move(struct wl_listener *listener, void *data) * this client, to prevent the client from requesting this whenever they * want. * - * Note: interactive_begin() checks that view == g_server.grabbed_view. + * Note: interactive_begin() checks that view == server.grabbed_view. */ struct view *view = wl_container_of(listener, view, request_move); interactive_begin(view, LAB_INPUT_STATE_MOVE, LAB_EDGE_NONE); @@ -502,7 +502,7 @@ handle_request_resize(struct wl_listener *listener, void *data) * this client, to prevent the client from requesting this whenever they * want. * - * Note: interactive_begin() checks that view == g_server.grabbed_view. + * Note: interactive_begin() checks that view == server.grabbed_view. */ struct wlr_xdg_toplevel_resize_event *event = data; struct view *view = wl_container_of(listener, view, request_resize); @@ -562,7 +562,7 @@ handle_request_show_window_menu(struct wl_listener *listener, void *data) assert(menu); menu->triggered_by_view = &xdg_toplevel_view->base; - struct wlr_cursor *cursor = g_server.seat.cursor; + struct wlr_cursor *cursor = server.seat.cursor; menu_open_root(menu, cursor->x, cursor->y); } @@ -683,7 +683,7 @@ xdg_toplevel_view_append_children(struct view *self, struct wl_array *children) struct wlr_xdg_toplevel *toplevel = xdg_toplevel_from_view(self); struct view *view; - wl_list_for_each_reverse(view, &g_server.views, link) { + wl_list_for_each_reverse(view, &server.views, link) { if (view == self) { continue; } @@ -978,7 +978,7 @@ handle_new_xdg_toplevel(struct wl_listener *listener, void *data) view->output->wlr_output->scale); } - view->workspace = g_server.workspaces.current; + view->workspace = server.workspaces.current; view->scene_tree = lab_wlr_scene_tree_create( view->workspace->view_trees[VIEW_LAYER_NORMAL]); wlr_scene_node_set_enabled(&view->scene_tree->node, false); @@ -1039,8 +1039,8 @@ handle_new_xdg_toplevel(struct wl_listener *listener, void *data) CONNECT_SIGNAL(toplevel, xdg_toplevel_view, request_show_window_menu); CONNECT_SIGNAL(xdg_surface, xdg_toplevel_view, new_popup); - wl_list_insert(&g_server.views, &view->link); - view->creation_id = g_server.next_view_creation_id++; + wl_list_insert(&server.views, &view->link); + view->creation_id = server.next_view_creation_id++; } static void @@ -1076,44 +1076,44 @@ handle_xdg_toplevel_icon_set_icon(struct wl_listener *listener, void *data) void xdg_shell_init(void) { - g_server.xdg_shell = wlr_xdg_shell_create(g_server.wl_display, + server.xdg_shell = wlr_xdg_shell_create(server.wl_display, LAB_XDG_SHELL_VERSION); - if (!g_server.xdg_shell) { + if (!server.xdg_shell) { wlr_log(WLR_ERROR, "unable to create the XDG shell interface"); exit(EXIT_FAILURE); } - g_server.new_xdg_toplevel.notify = handle_new_xdg_toplevel; - wl_signal_add(&g_server.xdg_shell->events.new_toplevel, &g_server.new_xdg_toplevel); + server.new_xdg_toplevel.notify = handle_new_xdg_toplevel; + wl_signal_add(&server.xdg_shell->events.new_toplevel, &server.new_xdg_toplevel); - g_server.xdg_activation = wlr_xdg_activation_v1_create(g_server.wl_display); - if (!g_server.xdg_activation) { + server.xdg_activation = wlr_xdg_activation_v1_create(server.wl_display); + if (!server.xdg_activation) { wlr_log(WLR_ERROR, "unable to create xdg_activation interface"); exit(EXIT_FAILURE); } - g_server.xdg_activation_request.notify = handle_xdg_activation_request; - wl_signal_add(&g_server.xdg_activation->events.request_activate, - &g_server.xdg_activation_request); + server.xdg_activation_request.notify = handle_xdg_activation_request; + wl_signal_add(&server.xdg_activation->events.request_activate, + &server.xdg_activation_request); - g_server.xdg_activation_new_token.notify = handle_xdg_activation_new_token; - wl_signal_add(&g_server.xdg_activation->events.new_token, - &g_server.xdg_activation_new_token); + server.xdg_activation_new_token.notify = handle_xdg_activation_new_token; + wl_signal_add(&server.xdg_activation->events.new_token, + &server.xdg_activation_new_token); - g_server.xdg_toplevel_icon_manager = wlr_xdg_toplevel_icon_manager_v1_create( - g_server.wl_display, 1); - g_server.xdg_toplevel_icon_set_icon.notify = handle_xdg_toplevel_icon_set_icon; - wl_signal_add(&g_server.xdg_toplevel_icon_manager->events.set_icon, - &g_server.xdg_toplevel_icon_set_icon); + server.xdg_toplevel_icon_manager = wlr_xdg_toplevel_icon_manager_v1_create( + server.wl_display, 1); + server.xdg_toplevel_icon_set_icon.notify = handle_xdg_toplevel_icon_set_icon; + wl_signal_add(&server.xdg_toplevel_icon_manager->events.set_icon, + &server.xdg_toplevel_icon_set_icon); - wlr_xdg_wm_dialog_v1_create(g_server.wl_display, 1); + wlr_xdg_wm_dialog_v1_create(server.wl_display, 1); } void xdg_shell_finish(void) { - wl_list_remove(&g_server.new_xdg_toplevel.link); - wl_list_remove(&g_server.xdg_activation_request.link); - wl_list_remove(&g_server.xdg_activation_new_token.link); - wl_list_remove(&g_server.xdg_toplevel_icon_set_icon.link); + wl_list_remove(&server.new_xdg_toplevel.link); + wl_list_remove(&server.xdg_activation_request.link); + wl_list_remove(&server.xdg_activation_new_token.link); + wl_list_remove(&server.xdg_toplevel_icon_set_icon.link); } diff --git a/src/xwayland-unmanaged.c b/src/xwayland-unmanaged.c index 65801ce2..5f0266ff 100644 --- a/src/xwayland-unmanaged.c +++ b/src/xwayland-unmanaged.c @@ -19,7 +19,7 @@ handle_grab_focus(struct wl_listener *listener, void *data) unmanaged->ever_grabbed_focus = true; if (unmanaged->node) { assert(unmanaged->xwayland_surface->surface); - seat_focus_surface(&g_server.seat, + seat_focus_surface(&server.seat, unmanaged->xwayland_surface->surface); } } @@ -59,17 +59,17 @@ handle_map(struct wl_listener *listener, void *data) assert(!unmanaged->node); /* Stack new surface on top */ - wl_list_append(&g_server.unmanaged_surfaces, &unmanaged->link); + wl_list_append(&server.unmanaged_surfaces, &unmanaged->link); CONNECT_SIGNAL(xsurface, unmanaged, set_geometry); if (wlr_xwayland_surface_override_redirect_wants_focus(xsurface) || unmanaged->ever_grabbed_focus) { - seat_focus_surface(&g_server.seat, xsurface->surface); + seat_focus_surface(&server.seat, xsurface->surface); } struct wlr_scene_surface *scene_surface = wlr_scene_surface_create( - g_server.unmanaged_tree, xsurface->surface); + server.unmanaged_tree, xsurface->surface); die_if_null(scene_surface); unmanaged->node = &scene_surface->buffer->node; @@ -82,12 +82,12 @@ focus_next_surface(struct wlr_xwayland_surface *xsurface) { /* Try to focus on last created unmanaged xwayland surface */ struct xwayland_unmanaged *u; - struct wl_list *list = &g_server.unmanaged_surfaces; + struct wl_list *list = &server.unmanaged_surfaces; wl_list_for_each_reverse(u, list, link) { struct wlr_xwayland_surface *prev = u->xwayland_surface; if (wlr_xwayland_surface_override_redirect_wants_focus(prev) || u->ever_grabbed_focus) { - seat_focus_surface(&g_server.seat, prev->surface); + seat_focus_surface(&server.seat, prev->surface); return; } } @@ -113,8 +113,8 @@ focus_next_surface(struct wlr_xwayland_surface *xsurface) * If modifying this logic, please test for regressions with * menus/tooltips in JetBrains CLion or similar. */ - if (g_server.active_view) { - seat_focus_surface(&g_server.seat, g_server.active_view->surface); + if (server.active_view) { + seat_focus_surface(&server.seat, server.active_view->surface); } } @@ -124,7 +124,7 @@ handle_unmap(struct wl_listener *listener, void *data) struct xwayland_unmanaged *unmanaged = wl_container_of(listener, unmanaged, mappable.unmap); struct wlr_xwayland_surface *xsurface = unmanaged->xwayland_surface; - struct seat *seat = &g_server.seat; + struct seat *seat = &server.seat; assert(unmanaged->node); wl_list_remove(&unmanaged->link); @@ -214,7 +214,7 @@ handle_request_activate(struct wl_listener *listener, void *data) if (!xsurface->surface || !xsurface->surface->mapped) { return; } - struct seat *seat = &g_server.seat; + struct seat *seat = &server.seat; /* * Validate that the unmanaged surface trying to grab focus is actually @@ -223,7 +223,7 @@ handle_request_activate(struct wl_listener *listener, void *data) * FIXME: this logic is a bit incomplete/inconsistent. Refer to * https://github.com/labwc/labwc/discussions/2821 for more info. */ - struct view *view = g_server.active_view; + struct view *view = server.active_view; if (view && view->type == LAB_XWAYLAND_VIEW) { struct wlr_xwayland_surface *surf = wlr_xwayland_surface_try_from_wlr_surface(view->surface); diff --git a/src/xwayland.c b/src/xwayland.c index 4f9a6729..72879ec4 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -290,7 +290,7 @@ handle_request_move(struct wl_listener *listener, void *data) * this client, to prevent the client from requesting this whenever they * want. * - * Note: interactive_begin() checks that view == g_server.grabbed_view. + * Note: interactive_begin() checks that view == server.grabbed_view. */ struct view *view = wl_container_of(listener, view, request_move); interactive_begin(view, LAB_INPUT_STATE_MOVE, LAB_EDGE_NONE); @@ -307,7 +307,7 @@ handle_request_resize(struct wl_listener *listener, void *data) * this client, to prevent the client from requesting this whenever they * want. * - * Note: interactive_begin() checks that view == g_server.grabbed_view. + * Note: interactive_begin() checks that view == server.grabbed_view. */ struct wlr_xwayland_resize_event *event = data; struct view *view = wl_container_of(listener, view, request_resize); @@ -388,7 +388,7 @@ xwayland_view_configure(struct view *view, struct wlr_box geo) * workaround, move offscreen surfaces immediately. */ bool is_offscreen = !wlr_box_empty(&view->current) && - !wlr_output_layout_intersects(g_server.output_layout, NULL, + !wlr_output_layout_intersects(server.output_layout, NULL, &view->current); /* If not resizing, process the move immediately */ @@ -605,7 +605,7 @@ update_icon(struct xwayland_view *xwayland_view) xcb_window_t window_id = xwayland_view->xwayland_surface->window_id; - xcb_connection_t *xcb_conn = wlr_xwayland_get_xwm_connection(g_server.xwayland); + xcb_connection_t *xcb_conn = wlr_xwayland_get_xwm_connection(server.xwayland); xcb_get_property_cookie_t cookie = xcb_get_property(xcb_conn, 0, window_id, atoms[ATOM_NET_WM_ICON], XCB_ATOM_CARDINAL, 0, 0x10000); xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_conn, cookie, NULL); @@ -658,7 +658,7 @@ handle_focus_in(struct wl_listener *listener, void *data) struct xwayland_view *xwayland_view = wl_container_of(listener, xwayland_view, focus_in); struct view *view = &xwayland_view->base; - struct seat *seat = &g_server.seat; + struct seat *seat = &server.seat; if (!view->surface) { /* @@ -878,7 +878,7 @@ handle_map(struct wl_listener *listener, void *data) */ if (xwayland_view->focused_before_map) { xwayland_view->focused_before_map = false; - seat_focus_surface(&g_server.seat, view->surface); + seat_focus_surface(&server.seat, view->surface); } view_impl_map(view); @@ -941,7 +941,7 @@ xwayland_view_append_children(struct view *self, struct wl_array *children) struct wlr_xwayland_surface *surface = xwayland_surface_from_view(self); struct view *view; - wl_list_for_each_reverse(view, &g_server.views, link) { + wl_list_for_each_reverse(view, &server.views, link) { if (view == self) { continue; } @@ -1061,7 +1061,7 @@ xwayland_view_create(struct wlr_xwayland_surface *xsurface, bool mapped) xwayland_view->xwayland_surface = xsurface; xsurface->data = view; - view->workspace = g_server.workspaces.current; + view->workspace = server.workspaces.current; view->scene_tree = lab_wlr_scene_tree_create( view->workspace->view_trees[VIEW_LAYER_NORMAL]); node_descriptor_create(&view->scene_tree->node, @@ -1093,8 +1093,8 @@ xwayland_view_create(struct wlr_xwayland_surface *xsurface, bool mapped) /* Events from the view itself */ CONNECT_SIGNAL(view, &xwayland_view->on_view, always_on_top); - wl_list_insert(&g_server.views, &view->link); - view->creation_id = g_server.next_view_creation_id++; + wl_list_insert(&server.views, &view->link); + view->creation_id = server.next_view_creation_id++; if (xsurface->surface) { handle_associate(&xwayland_view->associate, NULL); @@ -1134,7 +1134,7 @@ static struct xwayland_view * xwayland_view_from_window_id(xcb_window_t id) { struct view *view; - wl_list_for_each(view, &g_server.views, link) { + wl_list_for_each(view, &server.views, link) { if (view->type != LAB_XWAYLAND_VIEW) { continue; } @@ -1177,7 +1177,7 @@ static void sync_atoms(void) { xcb_connection_t *xcb_conn = - wlr_xwayland_get_xwm_connection(g_server.xwayland); + wlr_xwayland_get_xwm_connection(server.xwayland); assert(xcb_conn); wlr_log(WLR_DEBUG, "Syncing X11 atoms"); @@ -1220,47 +1220,47 @@ handle_server_ready(struct wl_listener *listener, void *data) static void handle_xwm_ready(struct wl_listener *listener, void *data) { - wlr_xwayland_set_seat(g_server.xwayland, g_server.seat.seat); + wlr_xwayland_set_seat(server.xwayland, server.seat.seat); xwayland_update_workarea(); } void xwayland_server_init(struct wlr_compositor *compositor) { - g_server.xwayland = - wlr_xwayland_create(g_server.wl_display, + server.xwayland = + wlr_xwayland_create(server.wl_display, compositor, /* lazy */ !rc.xwayland_persistence); - if (!g_server.xwayland) { + if (!server.xwayland) { wlr_log(WLR_ERROR, "cannot create xwayland server"); exit(EXIT_FAILURE); } - g_server.xwayland_new_surface.notify = handle_new_surface; - wl_signal_add(&g_server.xwayland->events.new_surface, - &g_server.xwayland_new_surface); + server.xwayland_new_surface.notify = handle_new_surface; + wl_signal_add(&server.xwayland->events.new_surface, + &server.xwayland_new_surface); - g_server.xwayland_server_ready.notify = handle_server_ready; - wl_signal_add(&g_server.xwayland->server->events.ready, - &g_server.xwayland_server_ready); + server.xwayland_server_ready.notify = handle_server_ready; + wl_signal_add(&server.xwayland->server->events.ready, + &server.xwayland_server_ready); - g_server.xwayland_xwm_ready.notify = handle_xwm_ready; - wl_signal_add(&g_server.xwayland->events.ready, - &g_server.xwayland_xwm_ready); + server.xwayland_xwm_ready.notify = handle_xwm_ready; + wl_signal_add(&server.xwayland->events.ready, + &server.xwayland_xwm_ready); - g_server.xwayland->user_event_handler = handle_x11_event; + server.xwayland->user_event_handler = handle_x11_event; - if (setenv("DISPLAY", g_server.xwayland->display_name, true) < 0) { + if (setenv("DISPLAY", server.xwayland->display_name, true) < 0) { wlr_log_errno(WLR_ERROR, "unable to set DISPLAY for xwayland"); } else { wlr_log(WLR_DEBUG, "xwayland is running on display %s", - g_server.xwayland->display_name); + server.xwayland->display_name); } struct wlr_xcursor *xcursor; xcursor = wlr_xcursor_manager_get_xcursor( - g_server.seat.xcursor_manager, XCURSOR_DEFAULT, 1); + server.seat.xcursor_manager, XCURSOR_DEFAULT, 1); if (xcursor) { struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_xwayland_set_cursor(g_server.xwayland, image->buffer, + wlr_xwayland_set_cursor(server.xwayland, image->buffer, image->width * 4, image->width, image->height, image->hotspot_x, image->hotspot_y); @@ -1288,24 +1288,24 @@ xwayland_reset_cursor(void) * - Start some X11 client */ - if (!g_server.xwayland) { + if (!server.xwayland) { return; } struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor( - g_server.seat.xcursor_manager, XCURSOR_DEFAULT, 1); + server.seat.xcursor_manager, XCURSOR_DEFAULT, 1); - if (xcursor && !g_server.xwayland->xwm) { + if (xcursor && !server.xwayland->xwm) { /* Prevents setting the cursor on an active xwayland server */ struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_xwayland_set_cursor(g_server.xwayland, image->buffer, + wlr_xwayland_set_cursor(server.xwayland, image->buffer, image->width * 4, image->width, image->height, image->hotspot_x, image->hotspot_y); return; } - if (g_server.xwayland->cursor) { + if (server.xwayland->cursor) { /* * The previous configured theme has set the * default cursor or the xwayland server is @@ -1313,23 +1313,23 @@ xwayland_reset_cursor(void) * xcursor set that will be used on the next * xwayland destroy -> lazy startup cycle. */ - zfree(g_server.xwayland->cursor); + zfree(server.xwayland->cursor); } } void xwayland_server_finish(void) { - struct wlr_xwayland *xwayland = g_server.xwayland; - wl_list_remove(&g_server.xwayland_new_surface.link); - wl_list_remove(&g_server.xwayland_server_ready.link); - wl_list_remove(&g_server.xwayland_xwm_ready.link); + struct wlr_xwayland *xwayland = server.xwayland; + wl_list_remove(&server.xwayland_new_surface.link); + wl_list_remove(&server.xwayland_server_ready.link); + wl_list_remove(&server.xwayland_xwm_ready.link); /* - * Reset g_server.xwayland to NULL first to prevent callbacks (like + * Reset server.xwayland to NULL first to prevent callbacks (like * server_global_filter) from accessing it as it is destroyed */ - g_server.xwayland = NULL; + server.xwayland = NULL; wlr_xwayland_destroy(xwayland); } @@ -1428,12 +1428,12 @@ xwayland_update_workarea(void) * Do nothing if called during destroy or before xwayland is ready. * This function will be called again from the ready signal handler. */ - if (!g_server.xwayland || !g_server.xwayland->xwm) { + if (!server.xwayland || !server.xwayland->xwm) { return; } struct wlr_box lb; - wlr_output_layout_get_box(g_server.output_layout, NULL, &lb); + wlr_output_layout_get_box(server.output_layout, NULL, &lb); /* Compute outer edges of layout (excluding negative regions) */ int layout_left = MAX(0, lb.x); @@ -1448,13 +1448,13 @@ xwayland_update_workarea(void) int workarea_bottom = layout_bottom; struct output *output; - wl_list_for_each(output, &g_server.outputs, link) { + wl_list_for_each(output, &server.outputs, link) { if (!output_is_usable(output)) { continue; } struct wlr_box ob; - wlr_output_layout_get_box(g_server.output_layout, + wlr_output_layout_get_box(server.output_layout, output->wlr_output, &ob); /* Compute edges of output */ @@ -1497,15 +1497,15 @@ xwayland_update_workarea(void) .width = workarea_right - workarea_left, .height = workarea_bottom - workarea_top, }; - wlr_xwayland_set_workareas(g_server.xwayland, &workarea, 1); + wlr_xwayland_set_workareas(server.xwayland, &workarea, 1); } void xwayland_flush(void) { - if (!g_server.xwayland || !g_server.xwayland->xwm) { + if (!server.xwayland || !server.xwayland->xwm) { return; } - xcb_flush(wlr_xwayland_get_xwm_connection(g_server.xwayland)); + xcb_flush(wlr_xwayland_get_xwm_connection(server.xwayland)); } From a2e0de767660bcc806ed19d0b2af51a14fc77b34 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Mon, 23 Feb 2026 12:25:24 -0500 Subject: [PATCH 034/146] tree-wide: rename seat->seat to seat->wlr_seat for clarity As we use "seat" to refer to the labwc struct, this makes it clearer at a quick glance which code is using the wlr struct instead. --- include/idle.h | 2 +- include/labwc.h | 2 +- src/desktop.c | 4 +-- src/dnd.c | 8 ++--- src/idle.c | 4 +-- src/input/cursor.c | 66 ++++++++++++++++++++-------------------- src/input/gestures.c | 32 +++++++++---------- src/input/ime.c | 6 ++-- src/input/keyboard.c | 14 ++++----- src/input/tablet-pad.c | 2 +- src/input/tablet.c | 16 +++++----- src/input/touch.c | 18 +++++------ src/layers.c | 2 +- src/seat.c | 30 +++++++++--------- src/xwayland-unmanaged.c | 2 +- src/xwayland.c | 4 +-- 16 files changed, 106 insertions(+), 106 deletions(-) diff --git a/include/idle.h b/include/idle.h index 845fdf41..80371d30 100644 --- a/include/idle.h +++ b/include/idle.h @@ -6,6 +6,6 @@ struct wl_display; struct wlr_seat; void idle_manager_create(struct wl_display *display); -void idle_manager_notify_activity(struct wlr_seat *seat); +void idle_manager_notify_activity(struct wlr_seat *wlr_seat); #endif /* LABWC_IDLE_H */ diff --git a/include/labwc.h b/include/labwc.h index fac9539d..67aa612c 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -23,7 +23,7 @@ enum input_mode { }; struct seat { - struct wlr_seat *seat; + struct wlr_seat *wlr_seat; struct wlr_keyboard_group *keyboard_group; struct wl_list touch_points; /* struct touch_point.link */ diff --git a/src/desktop.c b/src/desktop.c index fd1fb1ad..28bf4464 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -49,13 +49,13 @@ set_or_offer_focus(struct view *view) struct seat *seat = &server.seat; switch (view_wants_focus(view)) { case VIEW_WANTS_FOCUS_ALWAYS: - if (view->surface != seat->seat->keyboard_state.focused_surface) { + if (view->surface != seat->wlr_seat->keyboard_state.focused_surface) { seat_focus_surface(seat, view->surface); } break; case VIEW_WANTS_FOCUS_LIKELY: case VIEW_WANTS_FOCUS_UNLIKELY: - if (view->surface != seat->seat->keyboard_state.focused_surface) { + if (view->surface != seat->wlr_seat->keyboard_state.focused_surface) { view_offer_focus(view); } break; diff --git a/src/dnd.c b/src/dnd.c index 2b8dfaaa..5d7d050e 100644 --- a/src/dnd.c +++ b/src/dnd.c @@ -18,8 +18,8 @@ handle_drag_request(struct wl_listener *listener, void *data) struct wlr_seat_request_start_drag_event *event = data; if (wlr_seat_validate_pointer_grab_serial( - seat->seat, event->origin, event->serial)) { - wlr_seat_start_pointer_drag(seat->seat, event->drag, + seat->wlr_seat, event->origin, event->serial)) { + wlr_seat_start_pointer_drag(seat->wlr_seat, event->drag, event->serial); } else { wlr_data_source_destroy(event->drag->source); @@ -91,9 +91,9 @@ dnd_init(struct seat *seat) seat->drag.events.start.notify = handle_drag_start; seat->drag.events.destroy.notify = handle_drag_destroy; - wl_signal_add(&seat->seat->events.request_start_drag, + wl_signal_add(&seat->wlr_seat->events.request_start_drag, &seat->drag.events.request); - wl_signal_add(&seat->seat->events.start_drag, &seat->drag.events.start); + wl_signal_add(&seat->wlr_seat->events.start_drag, &seat->drag.events.start); /* * destroy.notify is listened to in handle_drag_start() and reset in * handle_drag_destroy() diff --git a/src/idle.c b/src/idle.c index b8e96c2d..8fc17366 100644 --- a/src/idle.c +++ b/src/idle.c @@ -84,7 +84,7 @@ idle_manager_create(struct wl_display *display) } void -idle_manager_notify_activity(struct wlr_seat *seat) +idle_manager_notify_activity(struct wlr_seat *wlr_seat) { /* * The display destroy event might have been triggered @@ -96,5 +96,5 @@ idle_manager_notify_activity(struct wlr_seat *seat) return; } - wlr_idle_notifier_v1_notify_activity(manager->ext, seat); + wlr_idle_notifier_v1_notify_activity(manager->ext, wlr_seat); } diff --git a/src/input/cursor.c b/src/input/cursor.c index 19128b85..a7cba87d 100644 --- a/src/input/cursor.c +++ b/src/input/cursor.c @@ -180,7 +180,7 @@ handle_request_set_cursor(struct wl_listener *listener, void *data) */ struct wlr_seat_pointer_request_set_cursor_event *event = data; struct wlr_seat_client *focused_client = - seat->seat->pointer_state.focused_client; + seat->wlr_seat->pointer_state.focused_client; /* * This can be sent by any client, so we check to make sure this one @@ -205,7 +205,7 @@ handle_request_set_shape(struct wl_listener *listener, void *data) struct wlr_cursor_shape_manager_v1_request_set_shape_event *event = data; const char *shape_name = wlr_cursor_shape_v1_name(event->shape); struct seat *seat = wl_container_of(listener, seat, request_set_shape); - struct wlr_seat_client *focused_client = seat->seat->pointer_state.focused_client; + struct wlr_seat_client *focused_client = seat->wlr_seat->pointer_state.focused_client; /* Prevent setting a cursor image when moving or resizing */ if (server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { @@ -250,7 +250,7 @@ handle_request_set_selection(struct wl_listener *listener, void *data) struct seat *seat = wl_container_of( listener, seat, request_set_selection); struct wlr_seat_request_set_selection_event *event = data; - wlr_seat_set_selection(seat->seat, event->source, + wlr_seat_set_selection(seat->wlr_seat, event->source, event->serial); } @@ -260,7 +260,7 @@ handle_request_set_primary_selection(struct wl_listener *listener, void *data) struct seat *seat = wl_container_of( listener, seat, request_set_primary_selection); struct wlr_seat_request_set_primary_selection_event *event = data; - wlr_seat_set_primary_selection(seat->seat, event->source, + wlr_seat_set_primary_selection(seat->wlr_seat, event->source, event->serial); } @@ -418,10 +418,10 @@ cursor_update_image(struct seat *seat) * a new output instance), we have to force a re-enter of * the surface so the client sets its own cursor again. */ - if (seat->seat->pointer_state.focused_surface) { + if (seat->wlr_seat->pointer_state.focused_surface) { seat->server_cursor = LAB_CURSOR_DEFAULT; wlr_cursor_set_xcursor(seat->cursor, seat->xcursor_manager, ""); - wlr_seat_pointer_clear_focus(seat->seat); + wlr_seat_pointer_clear_focus(seat->wlr_seat); cursor_update_focus(); } return; @@ -515,7 +515,7 @@ update_pressed_surface(struct seat *seat, const struct cursor_context *ctx) * context menus (in contrast) do not use an XDG popup grab and * do not work properly if we send leave/enter events. */ - if (!wlr_seat_pointer_has_grab(seat->seat)) { + if (!wlr_seat_pointer_has_grab(seat->wlr_seat)) { return false; } if (seat->pressed.ctx.surface && ctx->surface != seat->pressed.ctx.surface) { @@ -537,7 +537,7 @@ cursor_update_common(const struct cursor_context *ctx, struct cursor_context *notified_ctx) { struct seat *seat = &server.seat; - struct wlr_seat *wlr_seat = seat->seat; + struct wlr_seat *wlr_seat = seat->wlr_seat; ssd_update_hovered_button(ctx->node); @@ -748,7 +748,7 @@ warp_cursor_to_constraint_hint(struct seat *seat, server.active_view->current.y + sy); /* Make sure we are not sending unnecessary surface movements */ - wlr_seat_pointer_warp(seat->seat, sx, sy); + wlr_seat_pointer_warp(seat->wlr_seat, sx, sy); } } @@ -868,7 +868,7 @@ cursor_locked(struct seat *seat, struct wlr_pointer *pointer) && pointer->base.type == WLR_INPUT_DEVICE_POINTER && seat->current_constraint->type == WLR_POINTER_CONSTRAINT_V1_LOCKED && seat->current_constraint->surface - == seat->seat->pointer_state.focused_surface; + == seat->wlr_seat->pointer_state.focused_surface; } static void @@ -892,7 +892,7 @@ preprocess_cursor_motion(struct seat *seat, struct wlr_pointer *pointer, double sx, sy; bool notify = cursor_process_motion(time_msec, &sx, &sy); if (notify) { - wlr_seat_pointer_notify_motion(seat->seat, time_msec, sx, sy); + wlr_seat_pointer_notify_motion(seat->wlr_seat, time_msec, sx, sy); } } @@ -918,7 +918,7 @@ handle_motion(struct wl_listener *listener, void *data) */ struct seat *seat = wl_container_of(listener, seat, on_cursor.motion); struct wlr_pointer_motion_event *event = data; - idle_manager_notify_activity(seat->seat); + idle_manager_notify_activity(seat->wlr_seat); cursor_set_visible(seat, /* visible */ true); if (seat->cursor_scroll_wheel_emulation) { @@ -950,7 +950,7 @@ handle_motion(struct wl_listener *listener, void *data) } else { wlr_relative_pointer_manager_v1_send_relative_motion( server.relative_pointer_manager, - seat->seat, (uint64_t)event->time_msec * 1000, + seat->wlr_seat, (uint64_t)event->time_msec * 1000, event->delta_x, event->delta_y, event->unaccel_dx, event->unaccel_dy); @@ -972,7 +972,7 @@ handle_motion_absolute(struct wl_listener *listener, void *data) */ struct seat *seat = wl_container_of(listener, seat, on_cursor.motion_absolute); struct wlr_pointer_motion_absolute_event *event = data; - idle_manager_notify_activity(seat->seat); + idle_manager_notify_activity(seat->wlr_seat); cursor_set_visible(seat, /* visible */ true); double lx, ly; @@ -1174,7 +1174,7 @@ cursor_process_button_press(struct seat *seat, uint32_t button, uint32_t time_ms } if (ctx.type != LAB_NODE_CLIENT && ctx.type != LAB_NODE_LAYER_SURFACE - && wlr_seat_pointer_has_grab(seat->seat)) { + && wlr_seat_pointer_has_grab(seat->wlr_seat)) { /* * If we have an active popup grab (an open popup) we want to * cancel that grab whenever the user presses on anything that @@ -1183,7 +1183,7 @@ cursor_process_button_press(struct seat *seat, uint32_t button, uint32_t time_ms * * Note: This does not work for XWayland clients */ - wlr_seat_pointer_end_grab(seat->seat); + wlr_seat_pointer_end_grab(seat->wlr_seat); lab_set_add(&seat->bound_buttons, button); return false; } @@ -1287,7 +1287,7 @@ handle_button(struct wl_listener *listener, void *data) */ struct seat *seat = wl_container_of(listener, seat, on_cursor.button); struct wlr_pointer_button_event *event = data; - idle_manager_notify_activity(seat->seat); + idle_manager_notify_activity(seat->wlr_seat); cursor_set_visible(seat, /* visible */ true); bool notify; @@ -1296,7 +1296,7 @@ handle_button(struct wl_listener *listener, void *data) notify = cursor_process_button_press(seat, event->button, event->time_msec); if (notify) { - wlr_seat_pointer_notify_button(seat->seat, event->time_msec, + wlr_seat_pointer_notify_button(seat->wlr_seat, event->time_msec, event->button, event->state); } break; @@ -1304,7 +1304,7 @@ handle_button(struct wl_listener *listener, void *data) notify = cursor_process_button_release(seat, event->button, event->time_msec); if (notify) { - wlr_seat_pointer_notify_button(seat->seat, event->time_msec, + wlr_seat_pointer_notify_button(seat->wlr_seat, event->time_msec, event->button, event->state); } cursor_finish_button_release(seat, event->button); @@ -1433,7 +1433,7 @@ handle_axis(struct wl_listener *listener, void *data) */ struct seat *seat = wl_container_of(listener, seat, on_cursor.axis); struct wlr_pointer_axis_event *event = data; - idle_manager_notify_activity(seat->seat); + idle_manager_notify_activity(seat->wlr_seat); cursor_set_visible(seat, /* visible */ true); /* input->scroll_factor is set for pointer/touch devices */ @@ -1447,7 +1447,7 @@ handle_axis(struct wl_listener *listener, void *data) if (notify) { /* Notify the client with pointer focus of the axis event. */ - wlr_seat_pointer_notify_axis(seat->seat, event->time_msec, + wlr_seat_pointer_notify_axis(seat->wlr_seat, event->time_msec, event->orientation, scroll_factor * event->delta, round(scroll_factor * event->delta_discrete), event->source, event->relative_direction); @@ -1466,7 +1466,7 @@ handle_frame(struct wl_listener *listener, void *data) */ struct seat *seat = wl_container_of(listener, seat, on_cursor.frame); /* Notify the client with pointer focus of the frame event. */ - wlr_seat_pointer_notify_frame(seat->seat); + wlr_seat_pointer_notify_frame(seat->wlr_seat); } void @@ -1486,12 +1486,12 @@ cursor_emulate_axis(struct seat *seat, struct wlr_input_device *device, bool notify = process_cursor_axis(orientation, delta, delta_discrete); if (notify) { /* Notify the client with pointer focus of the axis event. */ - wlr_seat_pointer_notify_axis(seat->seat, time_msec, + wlr_seat_pointer_notify_axis(seat->wlr_seat, time_msec, orientation, scroll_factor * delta, round(scroll_factor * delta_discrete), source, WL_POINTER_AXIS_RELATIVE_DIRECTION_IDENTICAL); } - wlr_seat_pointer_notify_frame(seat->seat); + wlr_seat_pointer_notify_frame(seat->wlr_seat); } void @@ -1505,16 +1505,16 @@ cursor_emulate_move(struct seat *seat, struct wlr_input_device *device, wlr_relative_pointer_manager_v1_send_relative_motion( server.relative_pointer_manager, - seat->seat, (uint64_t)time_msec * 1000, + seat->wlr_seat, (uint64_t)time_msec * 1000, dx, dy, dx, dy); wlr_cursor_move(seat->cursor, device, dx, dy); double sx, sy; bool notify = cursor_process_motion(time_msec, &sx, &sy); if (notify) { - wlr_seat_pointer_notify_motion(seat->seat, time_msec, sx, sy); + wlr_seat_pointer_notify_motion(seat->wlr_seat, time_msec, sx, sy); } - wlr_seat_pointer_notify_frame(seat->seat); + wlr_seat_pointer_notify_frame(seat->wlr_seat); } void @@ -1540,18 +1540,18 @@ cursor_emulate_button(struct seat *seat, uint32_t button, case WL_POINTER_BUTTON_STATE_PRESSED: notify = cursor_process_button_press(seat, button, time_msec); if (notify) { - wlr_seat_pointer_notify_button(seat->seat, time_msec, button, state); + wlr_seat_pointer_notify_button(seat->wlr_seat, time_msec, button, state); } break; case WL_POINTER_BUTTON_STATE_RELEASED: notify = cursor_process_button_release(seat, button, time_msec); if (notify) { - wlr_seat_pointer_notify_button(seat->seat, time_msec, button, state); + wlr_seat_pointer_notify_button(seat->wlr_seat, time_msec, button, state); } cursor_finish_button_release(seat, button); break; } - wlr_seat_pointer_notify_frame(seat->seat); + wlr_seat_pointer_notify_frame(seat->wlr_seat); } static void @@ -1630,7 +1630,7 @@ cursor_init(struct seat *seat) touch_init(seat); tablet_init(seat); - CONNECT_SIGNAL(seat->seat, seat, request_set_cursor); + CONNECT_SIGNAL(seat->wlr_seat, seat, request_set_cursor); struct wlr_cursor_shape_manager_v1 *cursor_shape_manager = wlr_cursor_shape_manager_v1_create(server.wl_display, @@ -1641,8 +1641,8 @@ cursor_init(struct seat *seat) } CONNECT_SIGNAL(cursor_shape_manager, seat, request_set_shape); - CONNECT_SIGNAL(seat->seat, seat, request_set_selection); - CONNECT_SIGNAL(seat->seat, seat, request_set_primary_selection); + CONNECT_SIGNAL(seat->wlr_seat, seat, request_set_selection); + CONNECT_SIGNAL(seat->wlr_seat, seat, request_set_primary_selection); } void cursor_finish(struct seat *seat) diff --git a/src/input/gestures.c b/src/input/gestures.c index 7e65ea46..6b488ed2 100644 --- a/src/input/gestures.c +++ b/src/input/gestures.c @@ -12,11 +12,11 @@ handle_pinch_begin(struct wl_listener *listener, void *data) struct seat *seat = wl_container_of(listener, seat, pinch_begin); struct wlr_pointer_pinch_begin_event *event = data; - idle_manager_notify_activity(seat->seat); + idle_manager_notify_activity(seat->wlr_seat); cursor_set_visible(seat, /* visible */ true); wlr_pointer_gestures_v1_send_pinch_begin(seat->pointer_gestures, - seat->seat, event->time_msec, event->fingers); + seat->wlr_seat, event->time_msec, event->fingers); } static void @@ -25,11 +25,11 @@ handle_pinch_update(struct wl_listener *listener, void *data) struct seat *seat = wl_container_of(listener, seat, pinch_update); struct wlr_pointer_pinch_update_event *event = data; - idle_manager_notify_activity(seat->seat); + idle_manager_notify_activity(seat->wlr_seat); cursor_set_visible(seat, /* visible */ true); wlr_pointer_gestures_v1_send_pinch_update(seat->pointer_gestures, - seat->seat, event->time_msec, event->dx, event->dy, + seat->wlr_seat, event->time_msec, event->dx, event->dy, event->scale, event->rotation); } @@ -39,11 +39,11 @@ handle_pinch_end(struct wl_listener *listener, void *data) struct seat *seat = wl_container_of(listener, seat, pinch_end); struct wlr_pointer_pinch_end_event *event = data; - idle_manager_notify_activity(seat->seat); + idle_manager_notify_activity(seat->wlr_seat); cursor_set_visible(seat, /* visible */ true); wlr_pointer_gestures_v1_send_pinch_end(seat->pointer_gestures, - seat->seat, event->time_msec, event->cancelled); + seat->wlr_seat, event->time_msec, event->cancelled); } static void @@ -52,11 +52,11 @@ handle_swipe_begin(struct wl_listener *listener, void *data) struct seat *seat = wl_container_of(listener, seat, swipe_begin); struct wlr_pointer_swipe_begin_event *event = data; - idle_manager_notify_activity(seat->seat); + idle_manager_notify_activity(seat->wlr_seat); cursor_set_visible(seat, /* visible */ true); wlr_pointer_gestures_v1_send_swipe_begin(seat->pointer_gestures, - seat->seat, event->time_msec, event->fingers); + seat->wlr_seat, event->time_msec, event->fingers); } static void @@ -65,11 +65,11 @@ handle_swipe_update(struct wl_listener *listener, void *data) struct seat *seat = wl_container_of(listener, seat, swipe_update); struct wlr_pointer_swipe_update_event *event = data; - idle_manager_notify_activity(seat->seat); + idle_manager_notify_activity(seat->wlr_seat); cursor_set_visible(seat, /* visible */ true); wlr_pointer_gestures_v1_send_swipe_update(seat->pointer_gestures, - seat->seat, event->time_msec, event->dx, event->dy); + seat->wlr_seat, event->time_msec, event->dx, event->dy); } static void @@ -78,11 +78,11 @@ handle_swipe_end(struct wl_listener *listener, void *data) struct seat *seat = wl_container_of(listener, seat, swipe_end); struct wlr_pointer_swipe_end_event *event = data; - idle_manager_notify_activity(seat->seat); + idle_manager_notify_activity(seat->wlr_seat); cursor_set_visible(seat, /* visible */ true); wlr_pointer_gestures_v1_send_swipe_end(seat->pointer_gestures, - seat->seat, event->time_msec, event->cancelled); + seat->wlr_seat, event->time_msec, event->cancelled); } static void @@ -91,11 +91,11 @@ handle_hold_begin(struct wl_listener *listener, void *data) struct seat *seat = wl_container_of(listener, seat, hold_begin); struct wlr_pointer_hold_begin_event *event = data; - idle_manager_notify_activity(seat->seat); + idle_manager_notify_activity(seat->wlr_seat); cursor_set_visible(seat, /* visible */ true); wlr_pointer_gestures_v1_send_hold_begin(seat->pointer_gestures, - seat->seat, event->time_msec, event->fingers); + seat->wlr_seat, event->time_msec, event->fingers); } static void @@ -104,11 +104,11 @@ handle_hold_end(struct wl_listener *listener, void *data) struct seat *seat = wl_container_of(listener, seat, hold_end); struct wlr_pointer_hold_end_event *event = data; - idle_manager_notify_activity(seat->seat); + idle_manager_notify_activity(seat->wlr_seat); cursor_set_visible(seat, /* visible */ true); wlr_pointer_gestures_v1_send_hold_end(seat->pointer_gestures, - seat->seat, event->time_msec, event->cancelled); + seat->wlr_seat, event->time_msec, event->cancelled); } void diff --git a/src/input/ime.c b/src/input/ime.c index add29f92..b55e816c 100644 --- a/src/input/ime.c +++ b/src/input/ime.c @@ -330,7 +330,7 @@ handle_input_method_grab_keyboard(struct wl_listener *listener, void *data) struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data; struct wlr_keyboard *active_keyboard = - wlr_seat_get_keyboard(relay->seat->seat); + wlr_seat_get_keyboard(relay->seat->wlr_seat); if (!is_keyboard_emulated_by_input_method( active_keyboard, relay->input_method)) { @@ -414,7 +414,7 @@ handle_new_input_method(struct wl_listener *listener, void *data) struct input_method_relay *relay = wl_container_of(listener, relay, new_input_method); struct wlr_input_method_v2 *input_method = data; - if (relay->seat->seat != input_method->seat) { + if (relay->seat->wlr_seat != input_method->seat) { return; } @@ -536,7 +536,7 @@ handle_new_text_input(struct wl_listener *listener, void *data) struct input_method_relay *relay = wl_container_of(listener, relay, new_text_input); struct wlr_text_input_v3 *wlr_text_input = data; - if (relay->seat->seat != wlr_text_input->seat) { + if (relay->seat->wlr_seat != wlr_text_input->seat) { return; } diff --git a/src/input/keyboard.c b/src/input/keyboard.c index 41fab773..8e5c1f78 100644 --- a/src/input/keyboard.c +++ b/src/input/keyboard.c @@ -90,7 +90,7 @@ seat_client_from_keyboard_resource(struct wl_resource *resource) } static void -broadcast_modifiers_to_unfocused_clients(struct wlr_seat *seat, +broadcast_modifiers_to_unfocused_clients(struct wlr_seat *wlr_seat, const struct keyboard *keyboard, const struct wlr_keyboard_modifiers *modifiers) { @@ -100,8 +100,8 @@ broadcast_modifiers_to_unfocused_clients(struct wlr_seat *seat, } struct wlr_seat_client *client; - wl_list_for_each(client, &seat->clients, link) { - if (client == seat->keyboard_state.focused_client) { + wl_list_for_each(client, &wlr_seat->clients, link) { + if (client == wlr_seat->keyboard_state.focused_client) { /* * We've already notified the focused client by calling * wlr_seat_keyboard_notify_modifiers() @@ -159,7 +159,7 @@ handle_modifiers(struct wl_listener *listener, void *data) if (!input_method_keyboard_grab_forward_modifiers(keyboard)) { /* Send modifiers to focused client */ - wlr_seat_keyboard_notify_modifiers(seat->seat, + wlr_seat_keyboard_notify_modifiers(seat->wlr_seat, &wlr_keyboard->modifiers); /* @@ -181,7 +181,7 @@ handle_modifiers(struct wl_listener *listener, void *data) * consequences. If so, modifiers ought to still be passed to * clients with pointer-focus (see issue #2271) */ - broadcast_modifiers_to_unfocused_clients(seat->seat, + broadcast_modifiers_to_unfocused_clients(seat->wlr_seat, keyboard, &wlr_keyboard->modifiers); } } @@ -615,8 +615,8 @@ handle_key(struct wl_listener *listener, void *data) struct keyboard *keyboard = wl_container_of(listener, keyboard, key); struct seat *seat = keyboard->base.seat; struct wlr_keyboard_key_event *event = data; - struct wlr_seat *wlr_seat = seat->seat; - idle_manager_notify_activity(seat->seat); + struct wlr_seat *wlr_seat = seat->wlr_seat; + idle_manager_notify_activity(seat->wlr_seat); /* any new press/release cancels current keybind repeat */ keyboard_cancel_keybind_repeat(keyboard); diff --git a/src/input/tablet-pad.c b/src/input/tablet-pad.c index d7c7f6d9..44b71847 100644 --- a/src/input/tablet-pad.c +++ b/src/input/tablet-pad.c @@ -185,7 +185,7 @@ tablet_pad_create(struct seat *seat, struct wlr_input_device *wlr_device) pad->pad = wlr_tablet_pad_from_input_device(wlr_device); if (server.tablet_manager) { pad->pad_v2 = wlr_tablet_pad_create( - server.tablet_manager, seat->seat, wlr_device); + server.tablet_manager, seat->wlr_seat, wlr_device); } pad->pad->data = pad; wlr_log(WLR_INFO, "tablet pad capabilities: %zu button(s) %zu strip(s) %zu ring(s)", diff --git a/src/input/tablet.c b/src/input/tablet.c index 186c9adf..ed596e15 100644 --- a/src/input/tablet.c +++ b/src/input/tablet.c @@ -42,7 +42,7 @@ handle_set_cursor(struct wl_listener *listener, void *data) struct seat *seat = tool->seat; struct wlr_seat_client *focused_client = - seat->seat->pointer_state.focused_client; + seat->wlr_seat->pointer_state.focused_client; if (server.input_mode != LAB_INPUT_STATE_PASSTHROUGH) { return; @@ -77,7 +77,7 @@ tablet_tool_create(struct seat *seat, tool->seat = seat; tool->tool_v2 = wlr_tablet_tool_create(server.tablet_manager, - seat->seat, wlr_tablet_tool); + seat->wlr_seat, wlr_tablet_tool); wlr_tablet_tool->data = tool; wlr_log(WLR_INFO, "tablet tool capabilities:%s%s%s%s%s%s", wlr_tablet_tool->tilt ? " tilt" : "", @@ -309,7 +309,7 @@ notify_motion(struct drawing_tablet *tablet, struct drawing_tablet_tool *tool, * sure what will break since I have the feeling that a * lot of internals rely on correct pointer focus. */ - wlr_seat_pointer_notify_motion(tool->seat->seat, time, -1, -1); + wlr_seat_pointer_notify_motion(tool->seat->wlr_seat, time, -1, -1); } } } @@ -325,7 +325,7 @@ handle_tablet_tool_proximity(struct wl_listener *listener, void *data) return; } - idle_manager_notify_activity(tablet->seat->seat); + idle_manager_notify_activity(tablet->seat->wlr_seat); cursor_set_visible(tablet->seat, /* visible */ true); if (!tool) { @@ -393,7 +393,7 @@ handle_tablet_tool_axis(struct wl_listener *listener, void *data) return; } - idle_manager_notify_activity(tablet->seat->seat); + idle_manager_notify_activity(tablet->seat->wlr_seat); cursor_set_visible(tablet->seat, /* visible */ true); /* @@ -565,7 +565,7 @@ handle_tablet_tool_tip(struct wl_listener *listener, void *data) return; } - idle_manager_notify_activity(tablet->seat->seat); + idle_manager_notify_activity(tablet->seat->wlr_seat); cursor_set_visible(tablet->seat, /* visible */ true); double x, y, dx, dy; @@ -644,7 +644,7 @@ handle_tablet_tool_button(struct wl_listener *listener, void *data) return; } - idle_manager_notify_activity(tablet->seat->seat); + idle_manager_notify_activity(tablet->seat->wlr_seat); cursor_set_visible(tablet->seat, /* visible */ true); double x, y, dx, dy; @@ -721,7 +721,7 @@ tablet_create(struct seat *seat, struct wlr_input_device *wlr_device) tablet->tablet->data = tablet; if (server.tablet_manager) { tablet->tablet_v2 = wlr_tablet_create( - server.tablet_manager, seat->seat, wlr_device); + server.tablet_manager, seat->wlr_seat, wlr_device); } wlr_log(WLR_INFO, "tablet dimensions: %.2fmm x %.2fmm", tablet->tablet->width_mm, tablet->tablet->height_mm); diff --git a/src/input/touch.c b/src/input/touch.c index 8344f971..42fab358 100644 --- a/src/input/touch.c +++ b/src/input/touch.c @@ -71,7 +71,7 @@ touch_get_coords(struct seat *seat, struct wlr_touch *touch, double x, double y, /* Find the surface and return it if it accepts touch events */ struct wlr_surface *surface = lab_wlr_surface_from_node(node); - if (surface && !wlr_surface_accepts_touch(surface, seat->seat)) { + if (surface && !wlr_surface_accepts_touch(surface, seat->wlr_seat)) { surface = NULL; } return surface; @@ -83,7 +83,7 @@ handle_touch_motion(struct wl_listener *listener, void *data) struct seat *seat = wl_container_of(listener, seat, touch_motion); struct wlr_touch_motion_event *event = data; - idle_manager_notify_activity(seat->seat); + idle_manager_notify_activity(seat->wlr_seat); int touch_point_count = wl_list_length(&seat->touch_points); @@ -105,7 +105,7 @@ handle_touch_motion(struct wl_listener *listener, void *data) wlr_cursor_warp_absolute(seat->cursor, &event->touch->base, event->x, event->y); } - wlr_seat_touch_notify_motion(seat->seat, event->time_msec, + wlr_seat_touch_notify_motion(seat->wlr_seat, event->time_msec, event->touch_id, sx, sy); } else { if (touch_point_count == 1) { @@ -123,7 +123,7 @@ handle_touch_frame(struct wl_listener *listener, void *data) { struct seat *seat = wl_container_of(listener, seat, touch_frame); - wlr_seat_touch_notify_frame(seat->seat); + wlr_seat_touch_notify_frame(seat->wlr_seat); } static void @@ -132,7 +132,7 @@ handle_touch_down(struct wl_listener *listener, void *data) struct seat *seat = wl_container_of(listener, seat, touch_down); struct wlr_touch_down_event *event = data; - idle_manager_notify_activity(seat->seat); + idle_manager_notify_activity(seat->wlr_seat); /* Compute layout => surface offset and save for this touch point */ struct touch_point *touch_point = znew(*touch_point); @@ -152,7 +152,7 @@ handle_touch_down(struct wl_listener *listener, void *data) if (touch_point->surface) { seat_pointer_end_grab(seat, touch_point->surface); /* Clear focus to not interfere with touch input */ - wlr_seat_pointer_notify_clear_focus(seat->seat); + wlr_seat_pointer_notify_clear_focus(seat->wlr_seat); /* Convert coordinates: first [0, 1] => layout */ double lx, ly; @@ -177,7 +177,7 @@ handle_touch_down(struct wl_listener *listener, void *data) wlr_cursor_warp_absolute(seat->cursor, &event->touch->base, event->x, event->y); } - wlr_seat_touch_notify_down(seat->seat, touch_point->surface, + wlr_seat_touch_notify_down(seat->wlr_seat, touch_point->surface, event->time_msec, event->touch_id, sx, sy); } else { if (touch_point_count == 1) { @@ -195,14 +195,14 @@ handle_touch_up(struct wl_listener *listener, void *data) struct seat *seat = wl_container_of(listener, seat, touch_up); struct wlr_touch_up_event *event = data; - idle_manager_notify_activity(seat->seat); + idle_manager_notify_activity(seat->wlr_seat); /* Remove the touch point from the seat */ struct touch_point *touch_point, *tmp; wl_list_for_each_safe(touch_point, tmp, &seat->touch_points, link) { if (touch_point->touch_id == event->touch_id) { if (touch_point->surface) { - wlr_seat_touch_notify_up(seat->seat, event->time_msec, + wlr_seat_touch_notify_up(seat->wlr_seat, event->time_msec, event->touch_id); } else { cursor_emulate_button(seat, BTN_LEFT, diff --git a/src/layers.c b/src/layers.c index dba103f4..eaa93f25 100644 --- a/src/layers.c +++ b/src/layers.c @@ -429,7 +429,7 @@ handle_map(struct wl_listener *listener, void *data) static bool surface_is_focused(struct seat *seat, struct wlr_surface *surface) { - return seat->seat->keyboard_state.focused_surface == surface; + return seat->wlr_seat->keyboard_state.focused_surface == surface; } static void diff --git a/src/seat.c b/src/seat.c index f63ec8c3..aea16c7a 100644 --- a/src/seat.c +++ b/src/seat.c @@ -434,7 +434,7 @@ new_keyboard(struct seat *seat, struct wlr_input_device *device, bool is_virtual keyboard_setup_handlers(keyboard); - wlr_seat_set_keyboard(seat->seat, kb); + wlr_seat_set_keyboard(seat->wlr_seat, kb); return (struct input *)keyboard; } @@ -515,7 +515,7 @@ seat_update_capabilities(struct seat *seat) break; } } - wlr_seat_set_capabilities(seat->seat, caps); + wlr_seat_set_capabilities(seat->wlr_seat, caps); } static void @@ -630,8 +630,8 @@ seat_init(void) { struct seat *seat = &server.seat; - seat->seat = wlr_seat_create(server.wl_display, "seat0"); - if (!seat->seat) { + seat->wlr_seat = wlr_seat_create(server.wl_display, "seat0"); + if (!seat->wlr_seat) { wlr_log(WLR_ERROR, "cannot allocate seat"); exit(EXIT_FAILURE); } @@ -641,7 +641,7 @@ seat_init(void) wl_list_init(&seat->inputs); CONNECT_SIGNAL(server.backend, seat, new_input); - CONNECT_SIGNAL(&seat->seat->keyboard_state, seat, focus_change); + CONNECT_SIGNAL(&seat->wlr_seat->keyboard_state, seat, focus_change); seat->virtual_pointer = wlr_virtual_pointer_manager_v1_create( server.wl_display); @@ -706,7 +706,7 @@ configure_keyboard(struct seat *seat, struct input *input) void seat_pointer_end_grab(struct seat *seat, struct wlr_surface *surface) { - if (!surface || !wlr_seat_pointer_has_grab(seat->seat)) { + if (!surface || !wlr_seat_pointer_has_grab(seat->wlr_seat)) { return; } @@ -721,7 +721,7 @@ seat_pointer_end_grab(struct seat *seat, struct wlr_surface *surface) * on button notifications in another client (observed in GTK4), * so end the grab manually. */ - wlr_seat_pointer_end_grab(seat->seat); + wlr_seat_pointer_end_grab(seat->wlr_seat); } } @@ -767,7 +767,7 @@ seat_force_focus_surface(struct seat *seat, struct wlr_surface *surface) int nr_pressed_sent_keycodes = key_state_nr_pressed_sent_keycodes(); struct wlr_keyboard *kb = &seat->keyboard_group->keyboard; - wlr_seat_keyboard_enter(seat->seat, surface, + wlr_seat_keyboard_enter(seat->wlr_seat, surface, pressed_sent_keycodes, nr_pressed_sent_keycodes, &kb->modifiers); } @@ -792,18 +792,18 @@ seat_focus(struct seat *seat, struct wlr_surface *surface, } if (!surface) { - wlr_seat_keyboard_notify_clear_focus(seat->seat); + wlr_seat_keyboard_notify_clear_focus(seat->wlr_seat); input_method_relay_set_focus(seat->input_method_relay, NULL); return; } - if (!wlr_seat_get_keyboard(seat->seat)) { + if (!wlr_seat_get_keyboard(seat->wlr_seat)) { /* * wlr_seat_keyboard_notify_enter() sends wl_keyboard.modifiers, * but it may crash some apps (e.g. Chromium) if * wl_keyboard.keymap is not sent beforehand. */ - wlr_seat_set_keyboard(seat->seat, &seat->keyboard_group->keyboard); + wlr_seat_set_keyboard(seat->wlr_seat, &seat->keyboard_group->keyboard); } /* @@ -817,14 +817,14 @@ seat_focus(struct seat *seat, struct wlr_surface *surface, int nr_pressed_sent_keycodes = key_state_nr_pressed_sent_keycodes(); struct wlr_keyboard *kb = &seat->keyboard_group->keyboard; - wlr_seat_keyboard_notify_enter(seat->seat, surface, + wlr_seat_keyboard_notify_enter(seat->wlr_seat, surface, pressed_sent_keycodes, nr_pressed_sent_keycodes, &kb->modifiers); input_method_relay_set_focus(seat->input_method_relay, surface); struct wlr_pointer_constraint_v1 *constraint = wlr_pointer_constraints_v1_constraint_for_surface(server.constraints, - surface, seat->seat); + surface, seat->wlr_seat); constrain_cursor(constraint); } @@ -898,7 +898,7 @@ seat_focus_override_begin(struct seat *seat, enum input_mode input_mode, server.input_mode = input_mode; - seat->focus_override.surface = seat->seat->keyboard_state.focused_surface; + seat->focus_override.surface = seat->wlr_seat->keyboard_state.focused_surface; if (seat->focus_override.surface) { seat->focus_override.surface_destroy.notify = handle_focus_override_surface_destroy; @@ -908,7 +908,7 @@ seat_focus_override_begin(struct seat *seat, enum input_mode input_mode, seat_focus(seat, NULL, /*replace_exclusive_layer*/ false, /*is_lock_surface*/ false); - wlr_seat_pointer_clear_focus(seat->seat); + wlr_seat_pointer_clear_focus(seat->wlr_seat); cursor_set(seat, cursor_shape); } diff --git a/src/xwayland-unmanaged.c b/src/xwayland-unmanaged.c index 5f0266ff..89d40e84 100644 --- a/src/xwayland-unmanaged.c +++ b/src/xwayland-unmanaged.c @@ -140,7 +140,7 @@ handle_unmap(struct wl_listener *listener, void *data) cursor_update_focus(); - if (seat->seat->keyboard_state.focused_surface == xsurface->surface) { + if (seat->wlr_seat->keyboard_state.focused_surface == xsurface->surface) { focus_next_surface(xsurface); } } diff --git a/src/xwayland.c b/src/xwayland.c index 72879ec4..d6949c98 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -678,7 +678,7 @@ handle_focus_in(struct wl_listener *listener, void *data) return; } - if (view->surface != seat->seat->keyboard_state.focused_surface) { + if (view->surface != seat->wlr_seat->keyboard_state.focused_surface) { seat_focus_surface(seat, view->surface); } } @@ -1220,7 +1220,7 @@ handle_server_ready(struct wl_listener *listener, void *data) static void handle_xwm_ready(struct wl_listener *listener, void *data) { - wlr_xwayland_set_seat(server.xwayland, server.seat.seat); + wlr_xwayland_set_seat(server.xwayland, server.seat.wlr_seat); xwayland_update_workarea(); } From 9550bccef2921f7561a0ae07e2572050af50b2e1 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Sat, 21 Mar 2026 23:58:38 -0400 Subject: [PATCH 035/146] decorations: fix accidental rename Fixes: 4f72e6775ea671cd07330a7a0b3039bd7d9e99aa ("tree-wide: rename g_server to just server") --- include/decorations.h | 4 ++-- src/decorations/xdg-deco.c | 4 ++-- src/server.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/decorations.h b/include/decorations.h index f3bff3d2..20ea3c6a 100644 --- a/include/decorations.h +++ b/include/decorations.h @@ -7,12 +7,12 @@ struct view; struct wlr_surface; void kde_server_decoration_init(void); -void xdserver_decoration_init(void); +void xdg_server_decoration_init(void); void kde_server_decoration_update_default(void); void kde_server_decoration_set_view(struct view *view, struct wlr_surface *surface); void kde_server_decoration_finish(void); -void xdserver_decoration_finish(void); +void xdg_server_decoration_finish(void); #endif /* LABWC_DECORATIONS_H */ diff --git a/src/decorations/xdg-deco.c b/src/decorations/xdg-deco.c index 678a481d..e195e02f 100644 --- a/src/decorations/xdg-deco.c +++ b/src/decorations/xdg-deco.c @@ -115,7 +115,7 @@ xdg_toplevel_decoration(struct wl_listener *listener, void *data) } void -xdserver_decoration_init(void) +xdg_server_decoration_init(void) { struct wlr_xdg_decoration_manager_v1 *xdg_deco_mgr = NULL; xdg_deco_mgr = wlr_xdg_decoration_manager_v1_create(server.wl_display); @@ -130,7 +130,7 @@ xdserver_decoration_init(void) } void -xdserver_decoration_finish(void) +xdg_server_decoration_finish(void) { wl_list_remove(&server.xdg_toplevel_decoration.link); } diff --git a/src/server.c b/src/server.c index b2076c52..50927314 100644 --- a/src/server.c +++ b/src/server.c @@ -635,7 +635,7 @@ server_init(void) seat_init(); xdg_shell_init(); kde_server_decoration_init(); - xdserver_decoration_init(); + xdg_server_decoration_init(); struct wlr_presentation *presentation = wlr_presentation_create( server.wl_display, server.backend, @@ -775,7 +775,7 @@ server_finish(void) xdg_shell_finish(); layers_finish(); kde_server_decoration_finish(); - xdserver_decoration_finish(); + xdg_server_decoration_finish(); wl_list_remove(&server.new_constraint.link); wl_list_remove(&server.output_power_manager_set_mode.link); wl_list_remove(&server.tearing_new_object.link); From d4ad27e6365364acd5e1ec48e77c07f9bfc873b4 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Sat, 21 Mar 2026 22:47:22 -0400 Subject: [PATCH 036/146] tree-wide: use rc.theme instead of server.theme Having two global pointers to the same struct is redundant. --- include/labwc.h | 2 -- include/theme.h | 3 --- src/action.c | 2 +- src/cycle/cycle.c | 2 +- src/cycle/osd-classic.c | 4 ++-- src/cycle/osd-thumbnail.c | 6 +++--- src/magnifier.c | 2 +- src/main.c | 1 - src/menu/menu.c | 14 +++++++------- src/resize-outlines.c | 8 ++++---- src/server.c | 4 ++-- src/ssd/ssd-border.c | 6 +++--- src/ssd/ssd-extents.c | 4 ++-- src/ssd/ssd-shadow.c | 6 +++--- src/ssd/ssd-titlebar.c | 18 +++++++++--------- src/ssd/ssd.c | 8 ++++---- src/view.c | 2 +- src/workspaces.c | 6 +++--- 18 files changed, 46 insertions(+), 52 deletions(-) diff --git a/include/labwc.h b/include/labwc.h index 67aa612c..8b2cdf51 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -302,8 +302,6 @@ struct server { /* Set when in cycle (alt-tab) mode */ struct cycle_state cycle; - struct theme *theme; - struct menu *menu_current; struct wl_list menus; diff --git a/include/theme.h b/include/theme.h index 575fa93a..2fb499a9 100644 --- a/include/theme.h +++ b/include/theme.h @@ -213,12 +213,9 @@ struct theme { int mag_border_width; }; -struct server; - /** * theme_init - read openbox theme and generate button textures * @theme: theme data - * @server: server * @theme_name: theme-name in //labwc/themerc * Note is obtained in theme-dir.c */ diff --git a/src/action.c b/src/action.c index 76f8eaa0..2a0996e3 100644 --- a/src/action.c +++ b/src/action.c @@ -776,7 +776,7 @@ show_menu(struct view *view, struct cursor_context *ctx, int lx, ly; wlr_scene_node_coords(ctx->node, &lx, &ly); /* MAX() prevents negative x when the window is maximized */ - x = MAX(x, lx - server.theme->menu_border_width); + x = MAX(x, lx - rc.theme->menu_border_width); } } diff --git a/src/cycle/cycle.c b/src/cycle/cycle.c index 01785be3..77195176 100644 --- a/src/cycle/cycle.c +++ b/src/cycle/cycle.c @@ -26,7 +26,7 @@ static void update_preview_outlines(struct view *view) { /* Create / Update preview outline tree */ - struct theme *theme = server.theme; + struct theme *theme = rc.theme; struct lab_scene_rect *rect = server.cycle.preview_outline; if (!rect) { struct lab_scene_rect_options opts = { diff --git a/src/cycle/osd-classic.c b/src/cycle/osd-classic.c index 1180074c..7e5abfb6 100644 --- a/src/cycle/osd-classic.c +++ b/src/cycle/osd-classic.c @@ -32,7 +32,7 @@ create_fields_scene(struct view *view, struct wlr_scene_tree *parent, const float *text_color, const float *bg_color, int field_widths_sum, int x, int y) { - struct theme *theme = server.theme; + struct theme *theme = rc.theme; struct window_switcher_classic_theme *switcher_theme = &theme->osd_window_switcher_classic; @@ -80,7 +80,7 @@ static void cycle_osd_classic_init(struct cycle_osd_output *osd_output) { struct output *output = osd_output->output; - struct theme *theme = server.theme; + struct theme *theme = rc.theme; struct window_switcher_classic_theme *switcher_theme = &theme->osd_window_switcher_classic; int padding = theme->osd_border_width + switcher_theme->padding; diff --git a/src/cycle/osd-thumbnail.c b/src/cycle/osd-thumbnail.c index 4371bac8..aa853987 100644 --- a/src/cycle/osd-thumbnail.c +++ b/src/cycle/osd-thumbnail.c @@ -119,7 +119,7 @@ static struct cycle_osd_thumbnail_item * create_item_scene(struct wlr_scene_tree *parent, struct view *view, struct cycle_osd_output *osd_output) { - struct theme *theme = server.theme; + struct theme *theme = rc.theme; struct window_switcher_thumbnail_theme *switcher_theme = &theme->osd_window_switcher_thumbnail; int padding = theme->border_width + switcher_theme->item_padding; @@ -196,7 +196,7 @@ static void get_items_geometry(struct output *output, int nr_thumbs, int *nr_cols, int *nr_rows, int *nr_visible_rows) { - struct theme *theme = server.theme; + struct theme *theme = rc.theme; struct window_switcher_thumbnail_theme *switcher_theme = &theme->osd_window_switcher_thumbnail; int output_width, output_height; @@ -232,7 +232,7 @@ static void cycle_osd_thumbnail_init(struct cycle_osd_output *osd_output) { struct output *output = osd_output->output; - struct theme *theme = server.theme; + struct theme *theme = rc.theme; struct window_switcher_thumbnail_theme *switcher_theme = &theme->osd_window_switcher_thumbnail; int padding = theme->osd_border_width + switcher_theme->padding; diff --git a/src/magnifier.c b/src/magnifier.c index 475d7d9c..43a71746 100644 --- a/src/magnifier.c +++ b/src/magnifier.c @@ -41,7 +41,7 @@ box_logical_to_physical(struct wlr_box *box, struct wlr_output *output) void magnifier_draw(struct output *output, struct wlr_buffer *output_buffer, struct wlr_box *damage) { - struct theme *theme = server.theme; + struct theme *theme = rc.theme; bool fullscreen = (rc.mag_width == -1 || rc.mag_height == -1); struct wlr_box output_box = { diff --git a/src/main.c b/src/main.c index 9a21f4a9..373f4480 100644 --- a/src/main.c +++ b/src/main.c @@ -260,7 +260,6 @@ main(int argc, char *argv[]) struct theme theme = { 0 }; theme_init(&theme, rc.theme_name); rc.theme = &theme; - server.theme = &theme; menu_init(); diff --git a/src/menu/menu.c b/src/menu/menu.c index f961f8c4..251f9a30 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -135,7 +135,7 @@ item_create(struct menu *menu, const char *text, const char *icon_name, bool sho assert(menu); assert(text); - struct theme *theme = server.theme; + struct theme *theme = rc.theme; struct menuitem *menuitem = znew(*menuitem); menuitem->parent = menu; menuitem->selectable = true; @@ -166,7 +166,7 @@ item_create_scene_for_state(struct menuitem *item, float *text_color, float *bg_color) { struct menu *menu = item->parent; - struct theme *theme = server.theme; + struct theme *theme = rc.theme; /* Tree to hold background and label buffers */ struct wlr_scene_tree *tree = lab_wlr_scene_tree_create(item->tree); @@ -242,7 +242,7 @@ item_create_scene(struct menuitem *menuitem, int *item_y) assert(menuitem); assert(menuitem->type == LAB_MENU_ITEM); struct menu *menu = menuitem->parent; - struct theme *theme = server.theme; + struct theme *theme = rc.theme; /* Menu item root node */ menuitem->tree = lab_wlr_scene_tree_create(menu->scene_tree); @@ -291,7 +291,7 @@ separator_create_scene(struct menuitem *menuitem, int *item_y) assert(menuitem); assert(menuitem->type == LAB_MENU_SEPARATOR_LINE); struct menu *menu = menuitem->parent; - struct theme *theme = server.theme; + struct theme *theme = rc.theme; /* Menu item root node */ menuitem->tree = lab_wlr_scene_tree_create(menu->scene_tree); @@ -337,7 +337,7 @@ title_create_scene(struct menuitem *menuitem, int *item_y) assert(menuitem); assert(menuitem->type == LAB_MENU_TITLE); struct menu *menu = menuitem->parent; - struct theme *theme = server.theme; + struct theme *theme = rc.theme; float *bg_color = theme->menu_title_bg_color; float *text_color = theme->menu_title_text_color; @@ -411,7 +411,7 @@ static void menu_create_scene(struct menu *menu) { struct menuitem *item; - struct theme *theme = server.theme; + struct theme *theme = rc.theme; assert(!menu->scene_tree); @@ -1351,7 +1351,7 @@ menu_process_item_selection(struct menuitem *item) item->submenu->parent = item->parent; /* And open the new submenu tree */ struct wlr_box anchor_rect = - get_item_anchor_rect(server.theme, item); + get_item_anchor_rect(rc.theme, item); if (item->submenu->execute && !item->submenu->scene_tree) { open_pipemenu_async(item->submenu, anchor_rect); } else { diff --git a/src/resize-outlines.c b/src/resize-outlines.c index 60b0b608..113f128d 100644 --- a/src/resize-outlines.c +++ b/src/resize-outlines.c @@ -4,7 +4,7 @@ #include #include "common/border.h" #include "common/lab-scene-rect.h" -#include "labwc.h" +#include "config/rcxml.h" #include "resize-indicator.h" #include "ssd.h" #include "theme.h" @@ -25,9 +25,9 @@ resize_outlines_update(struct view *view, struct wlr_box new_geo) if (!outlines->rect) { struct lab_scene_rect_options opts = { .border_colors = (float *[3]) { - server.theme->osd_bg_color, - server.theme->osd_label_text_color, - server.theme->osd_bg_color, + rc.theme->osd_bg_color, + rc.theme->osd_label_text_color, + rc.theme->osd_bg_color, }, .nr_borders = 3, .border_width = 1, diff --git a/src/server.c b/src/server.c index 50927314..c5ca9fff 100644 --- a/src/server.c +++ b/src/server.c @@ -86,8 +86,8 @@ reload_config_and_theme(void) scaled_buffer_invalidate_sharing(); rcxml_finish(); rcxml_read(rc.config_file); - theme_finish(server.theme); - theme_init(server.theme, rc.theme_name); + theme_finish(rc.theme); + theme_init(rc.theme, rc.theme_name); #if HAVE_LIBSFDO desktop_entry_finish(); diff --git a/src/ssd/ssd-border.c b/src/ssd/ssd-border.c index 0589b0c8..c2c99f8d 100644 --- a/src/ssd/ssd-border.c +++ b/src/ssd/ssd-border.c @@ -4,7 +4,7 @@ #include #include "common/macros.h" #include "common/scene-helpers.h" -#include "labwc.h" +#include "config/rcxml.h" #include "ssd.h" #include "ssd-internal.h" #include "theme.h" @@ -17,7 +17,7 @@ ssd_border_create(struct ssd *ssd) assert(!ssd->border.tree); struct view *view = ssd->view; - struct theme *theme = server.theme; + struct theme *theme = rc.theme; int width = view->current.width; int height = view_effective_height(view, /* use_pending */ false); int full_width = width + 2 * theme->border_width; @@ -90,7 +90,7 @@ ssd_border_update(struct ssd *ssd) ssd->margin = ssd_thickness(ssd->view); } - struct theme *theme = server.theme; + struct theme *theme = rc.theme; int width = view->current.width; int height = view_effective_height(view, /* use_pending */ false); diff --git a/src/ssd/ssd-extents.c b/src/ssd/ssd-extents.c index 389ae70d..3840b107 100644 --- a/src/ssd/ssd-extents.c +++ b/src/ssd/ssd-extents.c @@ -14,7 +14,7 @@ void ssd_extents_create(struct ssd *ssd) { struct view *view = ssd->view; - struct theme *theme = server.theme; + struct theme *theme = rc.theme; int border_width = MAX(0, MAX(rc.resize_minimum_area, theme->border_width)); @@ -100,7 +100,7 @@ ssd_extents_update(struct ssd *ssd) return; } - struct theme *theme = server.theme; + struct theme *theme = rc.theme; int width = view->current.width; int height = view_effective_height(view, /* use_pending */ false); diff --git a/src/ssd/ssd-shadow.c b/src/ssd/ssd-shadow.c index cbcdc7bc..9a456124 100644 --- a/src/ssd/ssd-shadow.c +++ b/src/ssd/ssd-shadow.c @@ -145,7 +145,7 @@ static void set_shadow_geometry(struct ssd *ssd) { struct view *view = ssd->view; - struct theme *theme = server.theme; + struct theme *theme = rc.theme; int titlebar_height = ssd->titlebar.height; int width = view->current.width; int height = view_effective_height(view, false) + titlebar_height; @@ -203,7 +203,7 @@ ssd_shadow_create(struct ssd *ssd) ssd->shadow.tree = lab_wlr_scene_tree_create(ssd->tree); - struct theme *theme = server.theme; + struct theme *theme = rc.theme; struct view *view = ssd->view; enum ssd_active_state active; @@ -256,7 +256,7 @@ ssd_shadow_update(struct ssd *ssd) assert(ssd->shadow.tree); struct view *view = ssd->view; - struct theme *theme = server.theme; + struct theme *theme = rc.theme; bool maximized = view->maximized == VIEW_AXIS_BOTH; bool tiled_shadows = false; if (rc.shadows_on_tiled) { diff --git a/src/ssd/ssd-titlebar.c b/src/ssd/ssd-titlebar.c index 97214ea6..d1a08810 100644 --- a/src/ssd/ssd-titlebar.c +++ b/src/ssd/ssd-titlebar.c @@ -27,7 +27,7 @@ void ssd_titlebar_create(struct ssd *ssd) { struct view *view = ssd->view; - struct theme *theme = server.theme; + struct theme *theme = rc.theme; int width = view->current.width; int corner_width = ssd_get_corner_width(); @@ -160,7 +160,7 @@ set_squared_corners(struct ssd *ssd, bool enable) struct view *view = ssd->view; int width = view->current.width; int corner_width = ssd_get_corner_width(); - struct theme *theme = server.theme; + struct theme *theme = rc.theme; int x = enable ? 0 : corner_width; @@ -220,7 +220,7 @@ static void update_visible_buttons(struct ssd *ssd) { struct view *view = ssd->view; - struct theme *theme = server.theme; + struct theme *theme = rc.theme; int width = MAX(view->current.width - 2 * theme->window_titlebar_padding_width, 0); int button_width = theme->window_button_width; int button_spacing = theme->window_button_spacing; @@ -273,7 +273,7 @@ ssd_titlebar_update(struct ssd *ssd) struct view *view = ssd->view; int width = view->current.width; int corner_width = ssd_get_corner_width(); - struct theme *theme = server.theme; + struct theme *theme = rc.theme; bool maximized = view->maximized == VIEW_AXIS_BOTH; bool squared = ssd_should_be_squared(ssd); @@ -365,7 +365,7 @@ static void ssd_update_title_positions(struct ssd *ssd, int offset_left, int offset_right) { struct view *view = ssd->view; - struct theme *theme = server.theme; + struct theme *theme = rc.theme; int width = view->current.width; int title_bg_width = width - offset_left - offset_right; @@ -413,9 +413,9 @@ static void get_title_offsets(struct ssd *ssd, int *offset_left, int *offset_right) { struct ssd_titlebar_subtree *subtree = &ssd->titlebar.subtrees[SSD_ACTIVE]; - int button_width = server.theme->window_button_width; - int button_spacing = server.theme->window_button_spacing; - int padding_width = server.theme->window_titlebar_padding_width; + int button_width = rc.theme->window_button_width; + int button_spacing = rc.theme->window_button_spacing; + int padding_width = rc.theme->window_titlebar_padding_width; *offset_left = padding_width; *offset_right = padding_width; @@ -443,7 +443,7 @@ ssd_update_title(struct ssd *ssd) /* view->title is never NULL (instead it can be an empty string) */ assert(view->title); - struct theme *theme = server.theme; + struct theme *theme = rc.theme; struct ssd_state_title *state = &ssd->state.title; bool title_unchanged = state->text && !strcmp(view->title, state->text); diff --git a/src/ssd/ssd.c b/src/ssd/ssd.c index b71de1c4..e2ab6375 100644 --- a/src/ssd/ssd.c +++ b/src/ssd/ssd.c @@ -39,7 +39,7 @@ ssd_thickness(struct view *view) return (struct border){ 0 }; } - struct theme *theme = server.theme; + struct theme *theme = rc.theme; if (view->maximized == VIEW_AXIS_BOTH) { struct border thickness = { 0 }; @@ -101,7 +101,7 @@ ssd_get_resizing_type(const struct ssd *ssd, struct wlr_cursor *cursor) if (view_titlebar_visible(view)) { /* If the titlebar is visible, consider it part of the view */ - int titlebar_height = server.theme->titlebar_height; + int titlebar_height = rc.theme->titlebar_height; view_box.y -= titlebar_height; view_box.height += titlebar_height; } @@ -156,7 +156,7 @@ ssd_create(struct view *view, bool active) LAB_NODE_SSD_ROOT, view, /*data*/ NULL); wlr_scene_node_lower_to_bottom(&ssd->tree->node); - ssd->titlebar.height = server.theme->titlebar_height; + ssd->titlebar.height = rc.theme->titlebar_height; ssd_shadow_create(ssd); ssd_extents_create(ssd); /* @@ -257,7 +257,7 @@ ssd_set_titlebar(struct ssd *ssd, bool enabled) return; } wlr_scene_node_set_enabled(&ssd->titlebar.tree->node, enabled); - ssd->titlebar.height = enabled ? server.theme->titlebar_height : 0; + ssd->titlebar.height = enabled ? rc.theme->titlebar_height : 0; ssd_border_update(ssd); ssd_extents_update(ssd); ssd_shadow_update(ssd); diff --git a/src/view.c b/src/view.c index b9f33697..c44a2a6d 100644 --- a/src/view.c +++ b/src/view.c @@ -994,7 +994,7 @@ view_compute_cascaded_position(struct view *view, struct wlr_box *geom) /* TODO: move this logic to rcxml.c */ int offset_x = rc.placement_cascade_offset_x; int offset_y = rc.placement_cascade_offset_y; - struct theme *theme = server.theme; + struct theme *theme = rc.theme; int default_offset = theme->titlebar_height + theme->border_width + 5; if (offset_x <= 0) { offset_x = default_offset; diff --git a/src/workspaces.c b/src/workspaces.c index c11690da..9b4ed664 100644 --- a/src/workspaces.c +++ b/src/workspaces.c @@ -64,7 +64,7 @@ parse_workspace_index(const char *name) static void _osd_update(void) { - struct theme *theme = server.theme; + struct theme *theme = rc.theme; /* Settings */ uint16_t margin = 10; @@ -117,7 +117,7 @@ _osd_update(void) x = (width - marker_width) / 2; wl_list_for_each(workspace, &server.workspaces.all, link) { bool active = workspace == server.workspaces.current; - set_cairo_color(cairo, server.theme->osd_label_text_color); + set_cairo_color(cairo, rc.theme->osd_label_text_color); struct wlr_fbox fbox = { .x = x, .y = margin, @@ -136,7 +136,7 @@ _osd_update(void) } /* Text */ - set_cairo_color(cairo, server.theme->osd_label_text_color); + set_cairo_color(cairo, rc.theme->osd_label_text_color); PangoLayout *layout = pango_cairo_create_layout(cairo); pango_context_set_round_glyph_positions(pango_layout_get_context(layout), false); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); From 9903331995b4de7c99fb2c40c90ea9980ae70ad7 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Tue, 10 Mar 2026 14:35:36 -0400 Subject: [PATCH 037/146] xwayland: rework setting initial geometry from surface The basic idea is to set the initial geometry from the surface exactly once, just before we need it, i.e. either (1) when mapping the view or (2) right before processing an initial maximize/fullscreen request. I've consolidated various parts of the initial geometry setup to take place at this point (in ensure_initial_geometry_and_output()). The main motivation is to have a valid, adjusted floating geometry for the view *before* saving the natural geometry when processing an initial maximize/fullscreen request. This reduces code duplication and addresses a FIXME in set_initial_position(), as well as fixing an issue where the natural geometry could exceed the usable output area. Some other minor changes: - The initial output is now set directly from the surface geometry if the "application/user-set position" hint is given. This is unlikely to matter in practice, but theoretically an initially maximized view could now appear on a different (application-chosen) output. - Floating view size is now constrained to the usable area even if a position hint is set. It seemed inconsistent that `xterm -g 200x200` was constrained but `xterm -g 200x200+0+0` was not. --- include/xwayland.h | 1 + src/xwayland.c | 173 +++++++++++++++++++++------------------------ 2 files changed, 81 insertions(+), 93 deletions(-) diff --git a/include/xwayland.h b/include/xwayland.h index 48330a14..40fb17bc 100644 --- a/include/xwayland.h +++ b/include/xwayland.h @@ -39,6 +39,7 @@ struct xwayland_view { struct view base; struct wlr_xwayland_surface *xwayland_surface; bool focused_before_map; + bool initial_geometry_set; /* Events unique to XWayland views */ struct wl_listener associate; diff --git a/src/xwayland.c b/src/xwayland.c index d6949c98..7e033dfc 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -211,33 +211,6 @@ top_parent_of(struct view *view) return s; } -static void -ensure_initial_geometry_and_output(struct view *view) -{ - if (wlr_box_empty(&view->current)) { - struct wlr_xwayland_surface *xwayland_surface = - xwayland_surface_from_view(view); - view->current.x = xwayland_surface->x; - view->current.y = xwayland_surface->y; - view->current.width = xwayland_surface->width; - view->current.height = xwayland_surface->height; - /* - * If there is no pending move/resize yet, then set - * current values (used in map()). - */ - if (wlr_box_empty(&view->pending)) { - view->pending = view->current; - } - } - if (!output_is_usable(view->output)) { - /* - * Just use the cursor output since we don't know yet - * whether the surface position is meaningful. - */ - view_set_output(view, output_nearest_to_cursor()); - } -} - static bool want_deco(struct wlr_xwayland_surface *xwayland_surface) { @@ -257,6 +230,74 @@ want_deco(struct wlr_xwayland_surface *xwayland_surface) WLR_XWAYLAND_SURFACE_DECORATIONS_ALL; } +/* + * FIXME: this almost duplicates view_discover_output(), which however + * (1) is private to view.c and (2) uses current (not pending) geometry + */ +static void +set_output_from_pending_geometry(struct view *view) +{ + view_set_output(view, output_nearest_to( + view->pending.x + view->pending.width / 2, + view->pending.y + view->pending.height / 2)); +} + +static void +ensure_initial_geometry_and_output(struct view *view) +{ + struct xwayland_view *xwayland_view = xwayland_view_from_view(view); + if (xwayland_view->initial_geometry_set) { + /* Just make sure we still have an output */ + if (!output_is_usable(view->output)) { + set_output_from_pending_geometry(view); + } + return; + } + xwayland_view->initial_geometry_set = true; + + /* + * Note that wlr_xwayland_surface::x/y/width/height is subject + * to race conditions when wlr_xwayland_surface_configure() is + * called multiple times (e.g. due to client configure-requests), + * as newer values can get stomped on by an older ConfigureNotify. + * To avoid the issue, prefer view->pending when not empty. + */ + struct wlr_xwayland_surface *xsurface = xwayland_surface_from_view(view); + if (wlr_box_empty(&view->pending)) { + view->pending.x = xsurface->x; + view->pending.y = xsurface->y; + view->pending.width = xsurface->width; + view->pending.height = xsurface->height; + } + + /* + * Also set initial output and decoration mode at this point, + * since they affect the geometry calcs. (The decoration mode + * could still change again before map, so this is best-effort.) + */ + bool has_position = xsurface->size_hints && (xsurface->size_hints->flags + & (XCB_ICCCM_SIZE_HINT_US_POSITION | XCB_ICCCM_SIZE_HINT_P_POSITION)); + + if (has_position) { + set_output_from_pending_geometry(view); + } else { + view_set_output(view, output_nearest_to_cursor()); + } + + if (want_deco(xsurface)) { + view_set_ssd_mode(view, LAB_SSD_MODE_FULL); + } else { + view_set_ssd_mode(view, LAB_SSD_MODE_NONE); + } + + view_constrain_size_to_that_of_usable_area(view); + + if (!has_position) { + view_place_by_policy(view, /* allow_cursor */ true, + rc.placement_policy); + } +} + static void handle_commit(struct wl_listener *listener, void *data) { @@ -482,15 +523,6 @@ handle_request_maximize(struct wl_listener *listener, void *data) struct wlr_xwayland_surface *surf = xwayland_surface_from_view(view); if (!view->mapped) { ensure_initial_geometry_and_output(view); - /* - * Set decorations early to avoid changing geometry - * after maximize (reduces visual glitches). - */ - if (want_deco(surf)) { - view_set_ssd_mode(view, LAB_SSD_MODE_FULL); - } else { - view_set_ssd_mode(view, LAB_SSD_MODE_NONE); - } } enum view_axis maximize = VIEW_AXIS_NONE; @@ -738,11 +770,6 @@ handle_map_request(struct wl_listener *listener, void *data) view_set_layer(view, xsurface->above ? VIEW_LAYER_ALWAYS_ON_TOP : VIEW_LAYER_NORMAL); } - /* - * We could also call set_initial_position() here, but it's not - * really necessary until the view is actually mapped (and at - * that point the output layout is known for sure). - */ } static void @@ -760,52 +787,6 @@ check_natural_geometry(struct view *view) } } -static void -set_initial_position(struct view *view, - struct wlr_xwayland_surface *xwayland_surface) -{ - /* Don't center views with position explicitly specified */ - bool has_position = xwayland_surface->size_hints && - (xwayland_surface->size_hints->flags & ( - XCB_ICCCM_SIZE_HINT_US_POSITION | - XCB_ICCCM_SIZE_HINT_P_POSITION)); - - if (!has_position) { - view_constrain_size_to_that_of_usable_area(view); - - if (view_is_floating(view)) { - view_place_by_policy(view, - /* allow_cursor */ true, rc.placement_policy); - } else { - /* - * View is maximized/fullscreen. Place the - * stored natural geometry without actually - * moving the view. - * - * FIXME: this positioning will be slightly off - * since it uses border widths computed for the - * current (non-floating) state of the view. - * Possible fixes would be (1) adjust the natural - * geometry earlier, while still floating, or - * (2) add a variant of ssd_thickness() that - * disregards the current view state. - */ - view_compute_position_by_policy(view, &view->natural_geometry, - /* allow_cursor */ true, rc.placement_policy); - } - } - - /* view->last_placement is still unset if has_position=true */ - view_save_last_placement(view); - - /* - * Always make sure the view is onscreen and adjusted for any - * layout changes that could have occurred between map_request - * and the actual map event. - */ - view_adjust_for_layout_change(view); -} - static void set_surface(struct view *view, struct wlr_surface *surface) { @@ -828,11 +809,7 @@ handle_map(struct wl_listener *listener, void *data) { struct view *view = wl_container_of(listener, view, mappable.map); struct xwayland_view *xwayland_view = xwayland_view_from_view(view); - struct wlr_xwayland_surface *xwayland_surface = - xwayland_view->xwayland_surface; - assert(xwayland_surface); - assert(xwayland_surface->surface); - assert(xwayland_surface->surface == view->surface); + assert(view->surface); if (view->mapped) { return; @@ -858,7 +835,17 @@ handle_map(struct wl_listener *listener, void *data) if (!view->been_mapped) { check_natural_geometry(view); - set_initial_position(view, xwayland_surface); + /* + * view->last_placement might not have been set yet if + * view->pending is unchanged from the surface geometry. + */ + view_save_last_placement(view); + /* + * Make sure the view is onscreen and adjusted for any + * layout changes that could have occurred between + * ensure_initial_geometry_and_output() and map. + */ + view_adjust_for_layout_change(view); /* * When mapping the view for the first time, visual * artifacts are reduced if we display it immediately at From 4e25347791e01572d5c6fb8ddfa17fea0c8a3921 Mon Sep 17 00:00:00 2001 From: Tomi Ollila Date: Fri, 6 Mar 2026 20:18:40 +0200 Subject: [PATCH 038/146] use X macros to fill up enum action_type and const char *action_names[] To make it harder to have these 2 data structures go out of sync. No functional change. To understand X macros better, visit: - https://en.wikipedia.org/wiki/X_macro - https://philliptrudeau.com/blog/x-macro --- src/action.c | 229 +++++++++++++++++++++------------------------------ 1 file changed, 96 insertions(+), 133 deletions(-) diff --git a/src/action.c b/src/action.c index 2a0996e3..66fa9b20 100644 --- a/src/action.c +++ b/src/action.c @@ -68,147 +68,110 @@ struct action_arg_list { struct wl_list value; }; -/* Warning: Any change in this enum needs to be reflected in the action_names[] array below */ +#define ACTION_TYPE_LIST(X) \ + X(NONE, "None") \ + X(CLOSE, "Close") \ + X(KILL, "Kill") \ + X(DEBUG, "Debug") \ + X(EXECUTE, "Execute") \ + X(EXIT, "Exit") \ + X(MOVE_TO_EDGE, "MoveToEdge") \ + X(TOGGLE_SNAP_TO_EDGE, "ToggleSnapToEdge") \ + X(SNAP_TO_EDGE, "SnapToEdge") \ + X(GROW_TO_EDGE, "GrowToEdge") \ + X(SHRINK_TO_EDGE, "ShrinkToEdge") \ + X(NEXT_WINDOW, "NextWindow") \ + X(PREVIOUS_WINDOW, "PreviousWindow") \ + X(RECONFIGURE, "Reconfigure") \ + X(SHOW_MENU, "ShowMenu") \ + X(TOGGLE_MAXIMIZE, "ToggleMaximize") \ + X(MAXIMIZE, "Maximize") \ + X(UNMAXIMIZE, "UnMaximize") \ + X(TOGGLE_FULLSCREEN, "ToggleFullscreen") \ + X(SET_DECORATIONS, "SetDecorations") \ + X(TOGGLE_DECORATIONS, "ToggleDecorations") \ + X(TOGGLE_ALWAYS_ON_TOP, "ToggleAlwaysOnTop") \ + X(TOGGLE_ALWAYS_ON_BOTTOM, "ToggleAlwaysOnBottom") \ + X(TOGGLE_OMNIPRESENT, "ToggleOmnipresent") \ + X(FOCUS, "Focus") \ + X(UNFOCUS, "Unfocus") \ + X(ICONIFY, "Iconify") \ + X(RAISE, "Raise") \ + X(LOWER, "Lower") \ + X(MOVE, "Move") \ + X(RESIZE, "Resize") \ + X(RESIZE_RELATIVE, "ResizeRelative") \ + X(MOVETO, "MoveTo") \ + X(RESIZETO, "ResizeTo") \ + X(MOVETO_CURSOR, "MoveToCursor") \ + X(MOVE_RELATIVE, "MoveRelative") \ + X(SEND_TO_DESKTOP, "SendToDesktop") \ + X(GO_TO_DESKTOP, "GoToDesktop") \ + X(TOGGLE_SNAP_TO_REGION, "ToggleSnapToRegion") \ + X(SNAP_TO_REGION, "SnapToRegion") \ + X(UNSNAP, "UnSnap") \ + X(TOGGLE_KEYBINDS, "ToggleKeybinds") \ + X(FOCUS_OUTPUT, "FocusOutput") \ + X(MOVE_TO_OUTPUT, "MoveToOutput") \ + X(FIT_TO_OUTPUT, "FitToOutput") \ + X(IF, "If") \ + X(FOR_EACH, "ForEach") \ + X(VIRTUAL_OUTPUT_ADD, "VirtualOutputAdd") \ + X(VIRTUAL_OUTPUT_REMOVE, "VirtualOutputRemove") \ + X(AUTO_PLACE, "AutoPlace") \ + X(TOGGLE_TEARING, "ToggleTearing") \ + X(SHADE, "Shade") \ + X(UNSHADE, "Unshade") \ + X(TOGGLE_SHADE, "ToggleShade") \ + X(ENABLE_SCROLL_WHEEL_EMULATION, "EnableScrollWheelEmulation") \ + X(DISABLE_SCROLL_WHEEL_EMULATION, "DisableScrollWheelEmulation") \ + X(TOGGLE_SCROLL_WHEEL_EMULATION, "ToggleScrollWheelEmulation") \ + X(ENABLE_TABLET_MOUSE_EMULATION, "EnableTabletMouseEmulation") \ + X(DISABLE_TABLET_MOUSE_EMULATION, "DisableTabletMouseEmulation") \ + X(TOGGLE_TABLET_MOUSE_EMULATION, "ToggleTabletMouseEmulation") \ + X(TOGGLE_MAGNIFY, "ToggleMagnify") \ + X(ZOOM_IN, "ZoomIn") \ + X(ZOOM_OUT, "ZoomOut") \ + X(WARP_CURSOR, "WarpCursor") \ + X(HIDE_CURSOR, "HideCursor") + +/* + * Will expand to: + * + * enum action_type { + * ACTION_TYPE_INVALID, + * ACTION_TYPE_NONE, + * ACTION_TYPE_CLOSE, + * ACTION_TYPE_KILL, + * etc... + */ enum action_type { ACTION_TYPE_INVALID = 0, - ACTION_TYPE_NONE, - ACTION_TYPE_CLOSE, - ACTION_TYPE_KILL, - ACTION_TYPE_DEBUG, - ACTION_TYPE_EXECUTE, - ACTION_TYPE_EXIT, - ACTION_TYPE_MOVE_TO_EDGE, - ACTION_TYPE_TOGGLE_SNAP_TO_EDGE, - ACTION_TYPE_SNAP_TO_EDGE, - ACTION_TYPE_GROW_TO_EDGE, - ACTION_TYPE_SHRINK_TO_EDGE, - ACTION_TYPE_NEXT_WINDOW, - ACTION_TYPE_PREVIOUS_WINDOW, - ACTION_TYPE_RECONFIGURE, - ACTION_TYPE_SHOW_MENU, - ACTION_TYPE_TOGGLE_MAXIMIZE, - ACTION_TYPE_MAXIMIZE, - ACTION_TYPE_UNMAXIMIZE, - ACTION_TYPE_TOGGLE_FULLSCREEN, - ACTION_TYPE_SET_DECORATIONS, - ACTION_TYPE_TOGGLE_DECORATIONS, - ACTION_TYPE_TOGGLE_ALWAYS_ON_TOP, - ACTION_TYPE_TOGGLE_ALWAYS_ON_BOTTOM, - ACTION_TYPE_TOGGLE_OMNIPRESENT, - ACTION_TYPE_FOCUS, - ACTION_TYPE_UNFOCUS, - ACTION_TYPE_ICONIFY, - ACTION_TYPE_RAISE, - ACTION_TYPE_LOWER, - ACTION_TYPE_MOVE, - ACTION_TYPE_RESIZE, - ACTION_TYPE_RESIZE_RELATIVE, - ACTION_TYPE_MOVETO, - ACTION_TYPE_RESIZETO, - ACTION_TYPE_MOVETO_CURSOR, - ACTION_TYPE_MOVE_RELATIVE, - ACTION_TYPE_SEND_TO_DESKTOP, - ACTION_TYPE_GO_TO_DESKTOP, - ACTION_TYPE_TOGGLE_SNAP_TO_REGION, - ACTION_TYPE_SNAP_TO_REGION, - ACTION_TYPE_UNSNAP, - ACTION_TYPE_TOGGLE_KEYBINDS, - ACTION_TYPE_FOCUS_OUTPUT, - ACTION_TYPE_MOVE_TO_OUTPUT, - ACTION_TYPE_FIT_TO_OUTPUT, - ACTION_TYPE_IF, - ACTION_TYPE_FOR_EACH, - ACTION_TYPE_VIRTUAL_OUTPUT_ADD, - ACTION_TYPE_VIRTUAL_OUTPUT_REMOVE, - ACTION_TYPE_AUTO_PLACE, - ACTION_TYPE_TOGGLE_TEARING, - ACTION_TYPE_SHADE, - ACTION_TYPE_UNSHADE, - ACTION_TYPE_TOGGLE_SHADE, - ACTION_TYPE_ENABLE_SCROLL_WHEEL_EMULATION, - ACTION_TYPE_DISABLE_SCROLL_WHEEL_EMULATION, - ACTION_TYPE_TOGGLE_SCROLL_WHEEL_EMULATION, - ACTION_TYPE_ENABLE_TABLET_MOUSE_EMULATION, - ACTION_TYPE_DISABLE_TABLET_MOUSE_EMULATION, - ACTION_TYPE_TOGGLE_TABLET_MOUSE_EMULATION, - ACTION_TYPE_TOGGLE_MAGNIFY, - ACTION_TYPE_ZOOM_IN, - ACTION_TYPE_ZOOM_OUT, - ACTION_TYPE_WARP_CURSOR, - ACTION_TYPE_HIDE_CURSOR, +#define X(name, str) ACTION_TYPE_##name, + ACTION_TYPE_LIST(X) +#undef X }; -/* Warning: Any change in this array needs to be reflected in the action_type enum above */ +/* + * Will expand to: + * + * const char *action_names[] = { + * [ACTION_TYPE_INVALID] = "INVALID", + * [ACTION_TYPE_NONE] = "None", + * [ACTION_TYPE_CLOSE] = "Close", + * [ACTION_TYPE_KILL] = "Kill", + * etc... + */ const char *action_names[] = { - "INVALID", - "None", - "Close", - "Kill", - "Debug", - "Execute", - "Exit", - "MoveToEdge", - "ToggleSnapToEdge", - "SnapToEdge", - "GrowToEdge", - "ShrinkToEdge", - "NextWindow", - "PreviousWindow", - "Reconfigure", - "ShowMenu", - "ToggleMaximize", - "Maximize", - "UnMaximize", - "ToggleFullscreen", - "SetDecorations", - "ToggleDecorations", - "ToggleAlwaysOnTop", - "ToggleAlwaysOnBottom", - "ToggleOmnipresent", - "Focus", - "Unfocus", - "Iconify", - "Raise", - "Lower", - "Move", - "Resize", - "ResizeRelative", - "MoveTo", - "ResizeTo", - "MoveToCursor", - "MoveRelative", - "SendToDesktop", - "GoToDesktop", - "ToggleSnapToRegion", - "SnapToRegion", - "UnSnap", - "ToggleKeybinds", - "FocusOutput", - "MoveToOutput", - "FitToOutput", - "If", - "ForEach", - "VirtualOutputAdd", - "VirtualOutputRemove", - "AutoPlace", - "ToggleTearing", - "Shade", - "Unshade", - "ToggleShade", - "EnableScrollWheelEmulation", - "DisableScrollWheelEmulation", - "ToggleScrollWheelEmulation", - "EnableTabletMouseEmulation", - "DisableTabletMouseEmulation", - "ToggleTabletMouseEmulation", - "ToggleMagnify", - "ZoomIn", - "ZoomOut", - "WarpCursor", - "HideCursor", + [ACTION_TYPE_INVALID] = "INVALID", +#define X(name, str)[ACTION_TYPE_##name] = str, + ACTION_TYPE_LIST(X) +#undef X NULL }; +#undef ACTION_TYPE_LIST + void action_arg_add_str(struct action *action, const char *key, const char *value) { From fee38bceca0a16fb1685cfe83838d060582f3b6c Mon Sep 17 00:00:00 2001 From: Daniel Lublin Date: Wed, 25 Feb 2026 10:40:39 +0100 Subject: [PATCH 039/146] Handle xwayland not started (when HAVE_XWAYLAND, but lacking the binary) Closes https://github.com/labwc/labwc/issues/434 --- src/config/session.c | 35 ++++++++++++++++++++++++----------- src/input/cursor.c | 2 +- src/server.c | 2 ++ src/view.c | 2 ++ src/xwayland.c | 10 ++++++++-- 5 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/config/session.c b/src/config/session.c index 9a05d255..3ba7913b 100644 --- a/src/config/session.c +++ b/src/config/session.c @@ -21,7 +21,6 @@ #include "labwc.h" static const char *const env_vars[] = { - "DISPLAY", "WAYLAND_DISPLAY", "XDG_CURRENT_DESKTOP", "XCURSOR_SIZE", @@ -208,6 +207,21 @@ should_update_activation(void) return have_drm; } +static void +execute_update(const char *env_keys, const char *env_unset_keys, bool initialize) +{ + char *cmd = + strdup_printf("dbus-update-activation-environment %s", + initialize ? env_keys : env_unset_keys); + spawn_async_no_shell(cmd); + free(cmd); + + cmd = strdup_printf("systemctl --user %s %s", + initialize ? "import-environment" : "unset-environment", env_keys); + spawn_async_no_shell(cmd); + free(cmd); +} + static void update_activation_env(bool initialize) { @@ -227,19 +241,18 @@ update_activation_env(bool initialize) char *env_keys = str_join(env_vars, "%s", " "); char *env_unset_keys = initialize ? NULL : str_join(env_vars, "%s=", " "); - char *cmd = - strdup_printf("dbus-update-activation-environment %s", - initialize ? env_keys : env_unset_keys); - spawn_async_no_shell(cmd); - free(cmd); - - cmd = strdup_printf("systemctl --user %s %s", - initialize ? "import-environment" : "unset-environment", env_keys); - spawn_async_no_shell(cmd); - free(cmd); + execute_update(env_keys, env_unset_keys, initialize); free(env_keys); free(env_unset_keys); + +#if HAVE_XWAYLAND + if (server.xwayland) { + // DISPLAY is only set if xwayland was initialized successfully, + // so we only update the env in that case + execute_update("DISPLAY", "DISPLAY=", initialize); + } +#endif } void diff --git a/src/input/cursor.c b/src/input/cursor.c index a7cba87d..315898b7 100644 --- a/src/input/cursor.c +++ b/src/input/cursor.c @@ -1166,7 +1166,7 @@ cursor_process_button_press(struct seat *seat, uint32_t button, uint32_t time_ms if (layer && layer->current.keyboard_interactive) { layer_try_set_focus(seat, layer); } -#ifdef HAVE_XWAYLAND +#if HAVE_XWAYLAND } else if (ctx.type == LAB_NODE_UNMANAGED) { desktop_focus_view_or_surface(seat, NULL, ctx.surface, /*raise*/ false); diff --git a/src/server.c b/src/server.c index c5ca9fff..2e3ece02 100644 --- a/src/server.c +++ b/src/server.c @@ -583,6 +583,8 @@ server_init(void) server.workspace_tree = lab_wlr_scene_tree_create(&server.scene->tree); server.xdg_popup_tree = lab_wlr_scene_tree_create(&server.scene->tree); #if HAVE_XWAYLAND + // Creating/setting this is harmless when xwayland support is built-in + // but xwayland could not be successfully started. server.unmanaged_tree = lab_wlr_scene_tree_create(&server.scene->tree); #endif server.menu_tree = lab_wlr_scene_tree_create(&server.scene->tree); diff --git a/src/view.c b/src/view.c index c44a2a6d..1d43fcfa 100644 --- a/src/view.c +++ b/src/view.c @@ -54,6 +54,8 @@ view_from_wlr_surface(struct wlr_surface *surface) return xdg_surface->data; } #if HAVE_XWAYLAND + // Doing this is harmless even in the case that xwayland could not be + // successfully started. struct wlr_xwayland_surface *xsurface = wlr_xwayland_surface_try_from_wlr_surface(surface); if (xsurface) { diff --git a/src/xwayland.c b/src/xwayland.c index 7e033dfc..cfe7d691 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -1218,8 +1218,9 @@ xwayland_server_init(struct wlr_compositor *compositor) wlr_xwayland_create(server.wl_display, compositor, /* lazy */ !rc.xwayland_persistence); if (!server.xwayland) { - wlr_log(WLR_ERROR, "cannot create xwayland server"); - exit(EXIT_FAILURE); + wlr_log(WLR_ERROR, "failed to create xwayland server, continuing without"); + unsetenv("DISPLAY"); + return; } server.xwayland_new_surface.notify = handle_new_surface; wl_signal_add(&server.xwayland->events.new_surface, @@ -1308,6 +1309,11 @@ void xwayland_server_finish(void) { struct wlr_xwayland *xwayland = server.xwayland; + + if (!xwayland) { + return; + } + wl_list_remove(&server.xwayland_new_surface.link); wl_list_remove(&server.xwayland_server_ready.link); wl_list_remove(&server.xwayland_xwm_ready.link); From 3ce6328f6d18e5035f378b65bbf88217d9d3af26 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Fri, 27 Mar 2026 22:10:07 -0400 Subject: [PATCH 040/146] xwayland: set initial view state + geometry in handle_associate() Empirically, the associate event is always seen just after map_request but before surface map. Window properties are also read by wlroots just before emitting associate. So after some trial and error, this seems to be the best place to set initial view states and compute initial placement. Fixes initial positioning of "urxvt -g -0-0". urxvt placement regressed in: 9903331995b4de7c99fb2c40c90ea9980ae70ad7 ("xwayland: rework setting initial geometry from surface") map_request handler was added ~2 years ago in: c9018da4c4d9539341e4592caa48e94a5e47c6ea ("xwayland: set initial geometry in map_request handler") I'm not sure if the map_request handler was incorrect from day one, or if something changed in wlroots and/or Xwayland since then. --- include/xwayland.h | 1 - src/xwayland.c | 118 ++++++++++++++++++--------------------------- 2 files changed, 47 insertions(+), 72 deletions(-) diff --git a/include/xwayland.h b/include/xwayland.h index 40fb17bc..69833d06 100644 --- a/include/xwayland.h +++ b/include/xwayland.h @@ -54,7 +54,6 @@ struct xwayland_view { struct wl_listener set_strut_partial; struct wl_listener set_window_type; struct wl_listener focus_in; - struct wl_listener map_request; /* Not (yet) implemented */ /* struct wl_listener set_role; */ diff --git a/src/xwayland.c b/src/xwayland.c index cfe7d691..ff31a7f1 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -360,11 +360,53 @@ handle_associate(struct wl_listener *listener, void *data) { struct xwayland_view *xwayland_view = wl_container_of(listener, xwayland_view, associate); - assert(xwayland_view->xwayland_surface && - xwayland_view->xwayland_surface->surface); + struct view *view = &xwayland_view->base; + struct wlr_xwayland_surface *xsurface = xwayland_view->xwayland_surface; + assert(xsurface && xsurface->surface); - set_surface(&xwayland_view->base, - xwayland_view->xwayland_surface->surface); + set_surface(view, xsurface->surface); + + /* + * Empirically, the associate event is always seen just after + * map_request but before surface map. Window properties are + * also read by wlroots just before emitting associate. So after + * some trial and error, this seems to be the best place to set + * initial view states and compute initial placement. + */ + ensure_initial_geometry_and_output(view); + + /* + * Per the Extended Window Manager Hints (EWMH) spec: "The Window + * Manager SHOULD honor _NET_WM_STATE whenever a withdrawn window + * requests to be mapped." + * + * The following order of operations is intended to reduce the + * number of resize (Configure) events: + * 1. set fullscreen state + * 2. set decorations (depends on fullscreen state) + * 3. set maximized (geometry depends on decorations) + */ + view_set_fullscreen(view, xsurface->fullscreen); + if (!view->been_mapped) { + if (want_deco(xsurface)) { + view_set_ssd_mode(view, LAB_SSD_MODE_FULL); + } else { + view_set_ssd_mode(view, LAB_SSD_MODE_NONE); + } + } + enum view_axis axis = VIEW_AXIS_NONE; + if (xsurface->maximized_horz) { + axis |= VIEW_AXIS_HORIZONTAL; + } + if (xsurface->maximized_vert) { + axis |= VIEW_AXIS_VERTICAL; + } + view_maximize(view, axis); + + if (window_rules_get_property(view, "allowAlwaysOnTop") == LAB_PROP_TRUE) { + view_set_layer(view, xsurface->above + ? VIEW_LAYER_ALWAYS_ON_TOP : VIEW_LAYER_NORMAL); + } } static void @@ -407,7 +449,6 @@ handle_destroy(struct wl_listener *listener, void *data) wl_list_remove(&xwayland_view->set_strut_partial.link); wl_list_remove(&xwayland_view->set_window_type.link); wl_list_remove(&xwayland_view->focus_in.link); - wl_list_remove(&xwayland_view->map_request.link); wl_list_remove(&xwayland_view->on_view.always_on_top.link); @@ -715,63 +756,6 @@ handle_focus_in(struct wl_listener *listener, void *data) } } -/* - * Sets the initial geometry of maximized/fullscreen views before - * actually mapping them, so that they can do their initial layout and - * drawing with the correct geometry. This avoids visual glitches and - * also avoids undesired layout changes with some apps (e.g. HomeBank). - */ -static void -handle_map_request(struct wl_listener *listener, void *data) -{ - struct xwayland_view *xwayland_view = - wl_container_of(listener, xwayland_view, map_request); - struct view *view = &xwayland_view->base; - struct wlr_xwayland_surface *xsurface = xwayland_view->xwayland_surface; - - if (view->mapped) { - /* Probably shouldn't happen, but be sure */ - return; - } - - /* Keep the view invisible until actually mapped */ - wlr_scene_node_set_enabled(&view->scene_tree->node, false); - ensure_initial_geometry_and_output(view); - - /* - * Per the Extended Window Manager Hints (EWMH) spec: "The Window - * Manager SHOULD honor _NET_WM_STATE whenever a withdrawn window - * requests to be mapped." - * - * The following order of operations is intended to reduce the - * number of resize (Configure) events: - * 1. set fullscreen state - * 2. set decorations (depends on fullscreen state) - * 3. set maximized (geometry depends on decorations) - */ - view_set_fullscreen(view, xsurface->fullscreen); - if (!view->been_mapped) { - if (want_deco(xsurface)) { - view_set_ssd_mode(view, LAB_SSD_MODE_FULL); - } else { - view_set_ssd_mode(view, LAB_SSD_MODE_NONE); - } - } - enum view_axis axis = VIEW_AXIS_NONE; - if (xsurface->maximized_horz) { - axis |= VIEW_AXIS_HORIZONTAL; - } - if (xsurface->maximized_vert) { - axis |= VIEW_AXIS_VERTICAL; - } - view_maximize(view, axis); - - if (window_rules_get_property(view, "allowAlwaysOnTop") == LAB_PROP_TRUE) { - view_set_layer(view, xsurface->above - ? VIEW_LAYER_ALWAYS_ON_TOP : VIEW_LAYER_NORMAL); - } -} - static void check_natural_geometry(struct view *view) { @@ -815,14 +799,6 @@ handle_map(struct wl_listener *listener, void *data) return; } - /* - * The map_request event may not be received when an unmanaged - * (override-redirect) surface becomes managed. To make sure we - * have valid geometry in that case, call handle_map_request() - * explicitly (calling it twice is harmless). - */ - handle_map_request(&xwayland_view->map_request, NULL); - view->mapped = true; if (!view->content_tree) { @@ -1051,6 +1027,7 @@ xwayland_view_create(struct wlr_xwayland_surface *xsurface, bool mapped) view->workspace = server.workspaces.current; view->scene_tree = lab_wlr_scene_tree_create( view->workspace->view_trees[VIEW_LAYER_NORMAL]); + wlr_scene_node_set_enabled(&view->scene_tree->node, false); node_descriptor_create(&view->scene_tree->node, LAB_NODE_VIEW, view, /*data*/ NULL); @@ -1075,7 +1052,6 @@ xwayland_view_create(struct wlr_xwayland_surface *xsurface, bool mapped) CONNECT_SIGNAL(xsurface, xwayland_view, set_strut_partial); CONNECT_SIGNAL(xsurface, xwayland_view, set_window_type); CONNECT_SIGNAL(xsurface, xwayland_view, focus_in); - CONNECT_SIGNAL(xsurface, xwayland_view, map_request); /* Events from the view itself */ CONNECT_SIGNAL(view, &xwayland_view->on_view, always_on_top); From ea4e7e9a02e9e940d6ca12da7a04363a43d84f72 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Sat, 5 Jul 2025 18:10:07 +0200 Subject: [PATCH 041/146] CI: allow compiling wlroots as subproject --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ba7406cf..2308e80b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -95,6 +95,7 @@ jobs: apt-get install -y git gcc clang gdb xwayland apt-get build-dep -y labwc apt-get build-dep -y libwlroots-0.19-dev + apt-get build-dep -y libxkbcommon-dev - name: Install FreeBSD dependencies if: matrix.name == 'FreeBSD' @@ -121,7 +122,7 @@ jobs: xbps-install -y git meson gcc clang pkg-config scdoc \ cairo-devel glib-devel libpng-devel librsvg-devel libxml2-devel \ pango-devel wlroots0.19-devel gdb bash xorg-server-xwayland \ - dejavu-fonts-ttf libsfdo-devel foot + dejavu-fonts-ttf libsfdo-devel foot hwids # These builds are executed on all runners - name: Build with gcc From 48bcccddc3a0f44fb514f32edc354313cda0cb7f Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Sat, 5 Jul 2025 16:59:41 +0200 Subject: [PATCH 042/146] chase wlroots: increase wlroots meson dep --- meson.build | 4 ++-- subprojects/wlroots.wrap | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/meson.build b/meson.build index ddb3d42b..4b622b5e 100644 --- a/meson.build +++ b/meson.build @@ -51,9 +51,9 @@ endif add_project_arguments('-DLABWC_VERSION=@0@'.format(version), language: 'c') wlroots = dependency( - 'wlroots-0.19', + 'wlroots-0.20', default_options: ['default_library=static', 'examples=false'], - version: ['>=0.19.0', '<0.20.0'], + version: ['>=0.20.0', '<0.21.0'], ) wlroots_has_xwayland = wlroots.get_variable('have_xwayland') == 'true' diff --git a/subprojects/wlroots.wrap b/subprojects/wlroots.wrap index 25a947ed..c1d52098 100644 --- a/subprojects/wlroots.wrap +++ b/subprojects/wlroots.wrap @@ -1,7 +1,7 @@ [wrap-git] url = https://gitlab.freedesktop.org/wlroots/wlroots.git -revision = 0.19 +revision = f04ef79f619983bfb4a7c9908bdae62e0d0d5ba7 [provide] -dependency_names = wlroots-0.19 -wlroots-0.19=wlroots +dependency_names = wlroots-0.20 +wlroots-0.20=wlroots From 0c24252c85ed474cff77d508bc39a480b9993a5f Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Sat, 5 Jul 2025 17:03:38 +0200 Subject: [PATCH 043/146] chase wlroots: ime: rename to new_text_input (MR 5032) Ref: 536100488fc4c64528786801860f96cfa1a55765 (text-input-v3: Name new text input event correctly) --- src/input/ime.c | 2 +- subprojects/wlroots.wrap | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/input/ime.c b/src/input/ime.c index b55e816c..f622c639 100644 --- a/src/input/ime.c +++ b/src/input/ime.c @@ -585,7 +585,7 @@ input_method_relay_create(struct seat *seat) relay->popup_tree = lab_wlr_scene_tree_create(&server.scene->tree); relay->new_text_input.notify = handle_new_text_input; - wl_signal_add(&server.text_input_manager->events.text_input, + wl_signal_add(&server.text_input_manager->events.new_text_input, &relay->new_text_input); relay->new_input_method.notify = handle_new_input_method; diff --git a/subprojects/wlroots.wrap b/subprojects/wlroots.wrap index c1d52098..9199c211 100644 --- a/subprojects/wlroots.wrap +++ b/subprojects/wlroots.wrap @@ -1,6 +1,6 @@ [wrap-git] url = https://gitlab.freedesktop.org/wlroots/wlroots.git -revision = f04ef79f619983bfb4a7c9908bdae62e0d0d5ba7 +revision = 536100488fc4c64528786801860f96cfa1a55765 [provide] dependency_names = wlroots-0.20 From 511ed69c531bb5bddfe2a2e97586aab9f85ea300 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Wed, 13 Aug 2025 19:57:58 -0700 Subject: [PATCH 044/146] chase wlroots: add wl_fixes interface (MR 4685) Ref: 812675ba34ce612e9294e8a9814b1baf4b4775d4 (fixes: add implementation) --- src/server.c | 4 ++++ subprojects/wlroots.wrap | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/server.c b/src/server.c index 2e3ece02..727a8f08 100644 --- a/src/server.c +++ b/src/server.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -255,6 +256,7 @@ allow_for_sandbox(const struct wlr_security_context_v1_state *security_state, "wl_data_device_manager", /* would be great if we could drop this one */ "wl_seat", "xdg_wm_base", + "wl_fixes", /* enhanced */ "wl_output", "wl_drm", @@ -433,6 +435,8 @@ server_init(void) wl_display_set_global_filter(server.wl_display, server_global_filter, NULL); server.wl_event_loop = wl_display_get_event_loop(server.wl_display); + wlr_fixes_create(server.wl_display, 1); + /* Catch signals */ server.sighup_source = wl_event_loop_add_signal( server.wl_event_loop, SIGHUP, handle_sighup, NULL); diff --git a/subprojects/wlroots.wrap b/subprojects/wlroots.wrap index 9199c211..d1791ee0 100644 --- a/subprojects/wlroots.wrap +++ b/subprojects/wlroots.wrap @@ -1,6 +1,6 @@ [wrap-git] url = https://gitlab.freedesktop.org/wlroots/wlroots.git -revision = 536100488fc4c64528786801860f96cfa1a55765 +revision = 812675ba34ce612e9294e8a9814b1baf4b4775d4 [provide] dependency_names = wlroots-0.20 From 5f8a6395a1b26b5d361092a165a98df595920d95 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Tue, 9 Sep 2025 14:58:03 +0200 Subject: [PATCH 045/146] chase wlroots: ime: rename to new_input_method (MR 5107) Ref: 06aacb2a6fd237a5e1062d611909432bbcf5b566 (input-method: rename input_method event to new_input_method) --- src/input/ime.c | 2 +- subprojects/wlroots.wrap | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/input/ime.c b/src/input/ime.c index f622c639..954e2ea0 100644 --- a/src/input/ime.c +++ b/src/input/ime.c @@ -589,7 +589,7 @@ input_method_relay_create(struct seat *seat) &relay->new_text_input); relay->new_input_method.notify = handle_new_input_method; - wl_signal_add(&server.input_method_manager->events.input_method, + wl_signal_add(&server.input_method_manager->events.new_input_method, &relay->new_input_method); relay->focused_surface_destroy.notify = handle_focused_surface_destroy; diff --git a/subprojects/wlroots.wrap b/subprojects/wlroots.wrap index d1791ee0..253b83d7 100644 --- a/subprojects/wlroots.wrap +++ b/subprojects/wlroots.wrap @@ -1,6 +1,6 @@ [wrap-git] url = https://gitlab.freedesktop.org/wlroots/wlroots.git -revision = 812675ba34ce612e9294e8a9814b1baf4b4775d4 +revision = 06aacb2a6fd237a5e1062d611909432bbcf5b566 [provide] dependency_names = wlroots-0.20 From 863863fc7cb43bab9fc528d4591e0b188934b765 Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Sat, 18 Oct 2025 16:32:20 +0900 Subject: [PATCH 046/146] chase wlroots: ime: don't use `data` in kb grab destroy handler (MR 5170) Ref: 06275103f249cd2954630e59383342e102a6c1a3 (input-method-v2: Destroy keyboard grab before input method) Background: My MR in wlroots (!5107) stopped emitting `wlr_input_method_v2` on its `commit`/`destroy` events, but didn't stop emitting `wlr_input_method_keyboard_grab_v2` on its `destroy` event. That was because `handle_keyboard_grab_destroy()` was called *after* `handle_input_method_destroy()` for some reason, which caused segfault when dereferencing `relay->input_method.keyboard_grab` in `handle_keyboard_grab_destroy()`. MR 5170 reversed this weired order of destroy handler calls, and finally stopped emitting `wlr_input_method_keyboard_grab_v2` on its `destroy` event. --- src/input/ime.c | 3 ++- subprojects/wlroots.wrap | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/input/ime.c b/src/input/ime.c index 954e2ea0..1758d1c0 100644 --- a/src/input/ime.c +++ b/src/input/ime.c @@ -309,7 +309,8 @@ handle_keyboard_grab_destroy(struct wl_listener *listener, void *data) { struct input_method_relay *relay = wl_container_of(listener, relay, keyboard_grab_destroy); - struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data; + struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = + relay->input_method->keyboard_grab; assert(keyboard_grab); wl_list_remove(&relay->keyboard_grab_destroy.link); diff --git a/subprojects/wlroots.wrap b/subprojects/wlroots.wrap index 253b83d7..18e5ef98 100644 --- a/subprojects/wlroots.wrap +++ b/subprojects/wlroots.wrap @@ -1,6 +1,6 @@ [wrap-git] url = https://gitlab.freedesktop.org/wlroots/wlroots.git -revision = 06aacb2a6fd237a5e1062d611909432bbcf5b566 +revision = 06275103f249cd2954630e59383342e102a6c1a3 [provide] dependency_names = wlroots-0.20 From 76f166ae42eeb875da0b8a00ec269c89eb05ec71 Mon Sep 17 00:00:00 2001 From: Manuel Barrio Linares Date: Thu, 8 Jan 2026 15:15:22 -0300 Subject: [PATCH 047/146] chase wlroots: wlr_xwayland_set_cursor now takes a wlr_buffer (MR 5230) Ref: 84d603acc06a45dd3c3a4b2cf1fd08b2933ca2b5 (xwayland: take wlr_buffer in wlr_xwayland_set_cursor()) Ref: 6ae54dca23064e897b393283887986e5719a747f (xwayland: lock new buffer instead of the old one) Co-Authored-By: Consolatis This wlroots change fixes a potential UAF which we dealt with in labwc. We can thus remove the workaround completely. --- include/xwayland.h | 2 -- src/input/cursor.c | 3 -- src/xwayland.c | 59 ++++------------------------------------ subprojects/wlroots.wrap | 2 +- 4 files changed, 6 insertions(+), 60 deletions(-) diff --git a/include/xwayland.h b/include/xwayland.h index 69833d06..2be7d934 100644 --- a/include/xwayland.h +++ b/include/xwayland.h @@ -79,8 +79,6 @@ void xwayland_adjust_usable_area(struct view *view, void xwayland_update_workarea(void); -void xwayland_reset_cursor(void); - void xwayland_flush(void); #endif /* HAVE_XWAYLAND */ diff --git a/src/input/cursor.c b/src/input/cursor.c index 315898b7..3985e9d6 100644 --- a/src/input/cursor.c +++ b/src/input/cursor.c @@ -1604,9 +1604,6 @@ void cursor_reload(struct seat *seat) { cursor_load(seat); -#if HAVE_XWAYLAND - xwayland_reset_cursor(); -#endif cursor_update_image(seat); } diff --git a/src/xwayland.c b/src/xwayland.c index ff31a7f1..263833ff 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -1224,60 +1224,11 @@ xwayland_server_init(struct wlr_compositor *compositor) server.seat.xcursor_manager, XCURSOR_DEFAULT, 1); if (xcursor) { struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_xwayland_set_cursor(server.xwayland, image->buffer, - image->width * 4, image->width, - image->height, image->hotspot_x, - image->hotspot_y); - } -} - -void -xwayland_reset_cursor(void) -{ - /* - * As xwayland caches the pixel data when not yet started up - * due to the delayed lazy startup approach, we do have to - * re-set the xwayland cursor image. Otherwise the first X11 - * client connected will cause the xwayland server to use - * the cached (and potentially destroyed) pixel data. - * - * Calling this function after reloading the cursor theme - * ensures that the cached pixel data keeps being valid. - * - * To reproduce: - * - Compile with b_sanitize=address,undefined - * - Start labwc (nothing in autostart that could create - * a X11 connection, e.g. no GTK or X11 application) - * - Reconfigure - * - Start some X11 client - */ - - if (!server.xwayland) { - return; - } - - struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor( - server.seat.xcursor_manager, XCURSOR_DEFAULT, 1); - - if (xcursor && !server.xwayland->xwm) { - /* Prevents setting the cursor on an active xwayland server */ - struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_xwayland_set_cursor(server.xwayland, image->buffer, - image->width * 4, image->width, - image->height, image->hotspot_x, - image->hotspot_y); - return; - } - - if (server.xwayland->cursor) { - /* - * The previous configured theme has set the - * default cursor or the xwayland server is - * currently running but still has a cached - * xcursor set that will be used on the next - * xwayland destroy -> lazy startup cycle. - */ - zfree(server.xwayland->cursor); + struct wlr_buffer *cursor_buffer = wlr_xcursor_image_get_buffer(image); + if (cursor_buffer) { + wlr_xwayland_set_cursor(server.xwayland, cursor_buffer, + image->hotspot_x, image->hotspot_y); + } } } diff --git a/subprojects/wlroots.wrap b/subprojects/wlroots.wrap index 18e5ef98..004e3a20 100644 --- a/subprojects/wlroots.wrap +++ b/subprojects/wlroots.wrap @@ -1,6 +1,6 @@ [wrap-git] url = https://gitlab.freedesktop.org/wlroots/wlroots.git -revision = 06275103f249cd2954630e59383342e102a6c1a3 +revision = 6ae54dca23064e897b393283887986e5719a747f [provide] dependency_names = wlroots-0.20 From c3fc78286a7e21c554aafe6d844c85f5035e333a Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Sat, 5 Jul 2025 17:37:22 +0200 Subject: [PATCH 048/146] chase wlroots: track 0.20 branch And move CI to use system wide wlroots deps where availble. --- .github/workflows/build.yml | 4 ++-- subprojects/wlroots.wrap | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2308e80b..b693d54d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -82,7 +82,7 @@ jobs: run: | pacman-key --init pacman -Syu --noconfirm - pacman -S --noconfirm git meson clang wlroots0.19 libdrm libinput \ + pacman -S --noconfirm git meson clang wlroots0.20 libdrm libinput \ wayland-protocols cairo pango libxml2 xorg-xwayland librsvg \ libdisplay-info gdb ttf-dejavu foot libsfdo cmocka @@ -107,7 +107,7 @@ jobs: pkg set -yn pkg:mesa-dri # hack to skip llvm dependency pkg install -y git pcre2 meson gcc pkgconf cairo pango evdev-proto \ hwdata wayland-protocols libdisplay-info libepoll-shim \ - wlroots019 + wlroots020 run: echo "setup done" - name: Install Void Linux dependencies diff --git a/subprojects/wlroots.wrap b/subprojects/wlroots.wrap index 004e3a20..eb797ad5 100644 --- a/subprojects/wlroots.wrap +++ b/subprojects/wlroots.wrap @@ -1,6 +1,6 @@ [wrap-git] url = https://gitlab.freedesktop.org/wlroots/wlroots.git -revision = 6ae54dca23064e897b393283887986e5719a747f +revision = 0.20 [provide] dependency_names = wlroots-0.20 From 647e9b7658c916d2c8c5a16ea60d608e9b071097 Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Fri, 18 Jul 2025 18:47:39 +0900 Subject: [PATCH 049/146] Drop cosmic-workspace and use wlroots implementation of ext-workspace-v1 --- include/labwc.h | 9 +- .../protocols/cosmic-workspaces-internal.h | 24 - include/protocols/cosmic-workspaces.h | 94 --- include/protocols/ext-workspace-internal.h | 25 - include/protocols/ext-workspace.h | 109 --- include/protocols/transaction-addon.h | 84 -- include/workspaces.h | 15 +- protocols/cosmic-workspace-unstable-v1.xml | 364 --------- protocols/meson.build | 1 - src/meson.build | 1 - src/output.c | 11 +- .../cosmic_workspaces/cosmic-workspaces.c | 717 ---------------- src/protocols/cosmic_workspaces/meson.build | 4 - src/protocols/cosmic_workspaces/output.c | 174 ---- src/protocols/ext-workspace/ext-workspace.c | 762 ------------------ src/protocols/ext-workspace/meson.build | 4 - src/protocols/ext-workspace/output.c | 174 ---- src/protocols/meson.build | 6 - src/protocols/transaction-addon.c | 70 -- src/server.c | 1 - src/workspaces.c | 89 +- 21 files changed, 40 insertions(+), 2698 deletions(-) delete mode 100644 include/protocols/cosmic-workspaces-internal.h delete mode 100644 include/protocols/cosmic-workspaces.h delete mode 100644 include/protocols/ext-workspace-internal.h delete mode 100644 include/protocols/ext-workspace.h delete mode 100644 include/protocols/transaction-addon.h delete mode 100644 protocols/cosmic-workspace-unstable-v1.xml delete mode 100644 src/protocols/cosmic_workspaces/cosmic-workspaces.c delete mode 100644 src/protocols/cosmic_workspaces/meson.build delete mode 100644 src/protocols/cosmic_workspaces/output.c delete mode 100644 src/protocols/ext-workspace/ext-workspace.c delete mode 100644 src/protocols/ext-workspace/meson.build delete mode 100644 src/protocols/ext-workspace/output.c delete mode 100644 src/protocols/meson.build delete mode 100644 src/protocols/transaction-addon.c diff --git a/include/labwc.h b/include/labwc.h index 8b2cdf51..c579b06e 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -243,13 +243,14 @@ struct server { struct wl_list all; /* struct workspace.link */ struct workspace *current; struct workspace *last; - struct lab_cosmic_workspace_manager *cosmic_manager; - struct lab_cosmic_workspace_group *cosmic_group; - struct lab_ext_workspace_manager *ext_manager; - struct lab_ext_workspace_group *ext_group; + struct wlr_ext_workspace_manager_v1 *ext_manager; + struct wlr_ext_workspace_group_handle_v1 *ext_group; struct { struct wl_listener layout_output_added; } on; + struct { + struct wl_listener commit; + } on_ext_manager; } workspaces; struct wl_list outputs; diff --git a/include/protocols/cosmic-workspaces-internal.h b/include/protocols/cosmic-workspaces-internal.h deleted file mode 100644 index 50c7e75b..00000000 --- a/include/protocols/cosmic-workspaces-internal.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef LABWC_PROTOCOLS_COSMIC_WORKSPACES_INTERNAL_H -#define LABWC_PROTOCOLS_COSMIC_WORKSPACES_INTERNAL_H - -struct lab_cosmic_workspace; -struct lab_cosmic_workspace_group; -struct lab_cosmic_workspace_manager; - -enum pending_change { - /* group events */ - CW_PENDING_WS_CREATE = 1 << 0, - - /* ws events*/ - CW_PENDING_WS_ACTIVATE = 1 << 1, - CW_PENDING_WS_DEACTIVATE = 1 << 2, - CW_PENDING_WS_REMOVE = 1 << 3, -}; - -void cosmic_group_output_send_initial_state(struct lab_cosmic_workspace_group *group, - struct wl_resource *group_resource); - -void cosmic_manager_schedule_done_event(struct lab_cosmic_workspace_manager *manager); - -#endif /* LABWC_PROTOCOLS_COSMIC_WORKSPACES_INTERNAL_H */ diff --git a/include/protocols/cosmic-workspaces.h b/include/protocols/cosmic-workspaces.h deleted file mode 100644 index 8776bfad..00000000 --- a/include/protocols/cosmic-workspaces.h +++ /dev/null @@ -1,94 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef LABWC_PROTOCOLS_COSMIC_WORKSPACES_H -#define LABWC_PROTOCOLS_COSMIC_WORKSPACES_H - -#include -#include - -struct wlr_output; - -struct lab_cosmic_workspace_manager { - struct wl_global *global; - struct wl_list groups; - uint32_t caps; - struct wl_event_source *idle_source; - struct wl_event_loop *event_loop; - - struct { - struct wl_listener display_destroy; - } on; - - struct wl_list resources; -}; - -struct lab_cosmic_workspace_group { - struct lab_cosmic_workspace_manager *manager; - struct wl_list workspaces; - struct wl_array capabilities; - struct { - struct wl_signal create_workspace; - struct wl_signal destroy; - } events; - - struct wl_list link; - struct wl_list outputs; - struct wl_list resources; -}; - -struct lab_cosmic_workspace { - struct lab_cosmic_workspace_group *group; - char *name; - struct wl_array coordinates; - struct wl_array capabilities; - uint32_t state; /* enum lab_cosmic_workspace_state */ - uint32_t state_pending; /* enum lab_cosmic_workspace_state */ - - struct { - struct wl_signal activate; - struct wl_signal deactivate; - struct wl_signal remove; - struct wl_signal destroy; - } events; - - struct wl_list link; - struct wl_list resources; -}; - -enum lab_cosmic_workspace_caps { - CW_CAP_NONE = 0, - CW_CAP_GRP_ALL = 0x000000ff, - CW_CAP_WS_ALL = 0x0000ff00, - - /* group caps */ - CW_CAP_GRP_WS_CREATE = 1 << 0, - - /* workspace caps */ - CW_CAP_WS_ACTIVATE = 1 << 8, - CW_CAP_WS_DEACTIVATE = 1 << 9, - CW_CAP_WS_REMOVE = 1 << 10, -}; - -struct lab_cosmic_workspace_manager *lab_cosmic_workspace_manager_create( - struct wl_display *display, uint32_t caps, uint32_t version); - -struct lab_cosmic_workspace_group *lab_cosmic_workspace_group_create( - struct lab_cosmic_workspace_manager *manager); - -void lab_cosmic_workspace_group_output_enter( - struct lab_cosmic_workspace_group *group, struct wlr_output *output); - -void lab_cosmic_workspace_group_output_leave( - - struct lab_cosmic_workspace_group *group, struct wlr_output *output); -void lab_cosmic_workspace_group_destroy(struct lab_cosmic_workspace_group *group); - -struct lab_cosmic_workspace *lab_cosmic_workspace_create(struct lab_cosmic_workspace_group *group); -void lab_cosmic_workspace_set_name(struct lab_cosmic_workspace *workspace, const char *name); -void lab_cosmic_workspace_set_active(struct lab_cosmic_workspace *workspace, bool enabled); -void lab_cosmic_workspace_set_urgent(struct lab_cosmic_workspace *workspace, bool enabled); -void lab_cosmic_workspace_set_hidden(struct lab_cosmic_workspace *workspace, bool enabled); -void lab_cosmic_workspace_set_coordinates(struct lab_cosmic_workspace *workspace, - struct wl_array *coordinates); -void lab_cosmic_workspace_destroy(struct lab_cosmic_workspace *workspace); - -#endif /* LABWC_PROTOCOLS_COSMIC_WORKSPACES_H */ diff --git a/include/protocols/ext-workspace-internal.h b/include/protocols/ext-workspace-internal.h deleted file mode 100644 index c5e7575f..00000000 --- a/include/protocols/ext-workspace-internal.h +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef LABWC_PROTOCOLS_EXT_WORKSPACES_INTERNAL_H -#define LABWC_PROTOCOLS_EXT_WORKSPACES_INTERNAL_H - -struct wl_resource; -struct lab_ext_workspace_group; -struct lab_ext_workspace_manager; - -enum pending_ext_workspaces_change { - /* group events */ - WS_PENDING_WS_CREATE = 1 << 0, - - /* ws events*/ - WS_PENDING_WS_ACTIVATE = 1 << 1, - WS_PENDING_WS_DEACTIVATE = 1 << 2, - WS_PENDING_WS_REMOVE = 1 << 3, - WS_PENDING_WS_ASSIGN = 1 << 4, -}; - -void ext_group_output_send_initial_state(struct lab_ext_workspace_group *group, - struct wl_resource *group_resource); - -void ext_manager_schedule_done_event(struct lab_ext_workspace_manager *manager); - -#endif /* LABWC_PROTOCOLS_EXT_WORKSPACES_INTERNAL_H */ diff --git a/include/protocols/ext-workspace.h b/include/protocols/ext-workspace.h deleted file mode 100644 index cc422ac5..00000000 --- a/include/protocols/ext-workspace.h +++ /dev/null @@ -1,109 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef LABWC_PROTOCOLS_EXT_WORKSPACES_H -#define LABWC_PROTOCOLS_EXT_WORKSPACES_H - -#include -#include - -struct wlr_output; - -struct lab_ext_workspace_manager { - struct wl_global *global; - struct wl_list groups; - struct wl_list workspaces; - uint32_t caps; - struct wl_event_source *idle_source; - struct wl_event_loop *event_loop; - - struct { - struct wl_listener display_destroy; - } on; - - struct wl_list resources; -}; - -struct lab_ext_workspace_group { - struct lab_ext_workspace_manager *manager; - uint32_t capabilities; - struct { - struct wl_signal create_workspace; - struct wl_signal destroy; - } events; - - struct wl_list link; - struct wl_list outputs; - struct wl_list resources; -}; - -struct lab_ext_workspace { - struct lab_ext_workspace_manager *manager; - struct lab_ext_workspace_group *group; - char *id; - char *name; - struct wl_array coordinates; - uint32_t capabilities; - uint32_t state; /* enum lab_ext_workspace_state */ - uint32_t state_pending; /* enum lab_ext_workspace_state */ - - struct { - struct wl_signal activate; - struct wl_signal deactivate; - struct wl_signal remove; - struct wl_signal assign; - struct wl_signal destroy; - } events; - - struct wl_list link; - struct wl_list resources; -}; - -enum lab_ext_workspace_caps { - WS_CAP_NONE = 0, - WS_CAP_GRP_ALL = 0x0000ffff, - WS_CAP_WS_ALL = 0xffff0000, - - /* group caps */ - WS_CAP_GRP_WS_CREATE = 1 << 0, - - /* workspace caps */ - WS_CAP_WS_ACTIVATE = 1 << 16, - WS_CAP_WS_DEACTIVATE = 1 << 17, - WS_CAP_WS_REMOVE = 1 << 18, - WS_CAP_WS_ASSIGN = 1 << 19, -}; - -struct lab_ext_workspace_manager *lab_ext_workspace_manager_create( - struct wl_display *display, uint32_t caps, uint32_t version); - -struct lab_ext_workspace_group *lab_ext_workspace_group_create( - struct lab_ext_workspace_manager *manager); - -void lab_ext_workspace_group_output_enter( - struct lab_ext_workspace_group *group, struct wlr_output *output); - -void lab_ext_workspace_group_output_leave( - struct lab_ext_workspace_group *group, struct wlr_output *output); - -void lab_ext_workspace_group_destroy(struct lab_ext_workspace_group *group); - -/* Create a new workspace, id may be NULL */ -struct lab_ext_workspace *lab_ext_workspace_create( - struct lab_ext_workspace_manager *manager, const char *id); - -void lab_ext_workspace_assign_to_group(struct lab_ext_workspace *workspace, - struct lab_ext_workspace_group *group); - -void lab_ext_workspace_set_name(struct lab_ext_workspace *workspace, const char *name); - -void lab_ext_workspace_set_active(struct lab_ext_workspace *workspace, bool enabled); - -void lab_ext_workspace_set_urgent(struct lab_ext_workspace *workspace, bool enabled); - -void lab_ext_workspace_set_hidden(struct lab_ext_workspace *workspace, bool enabled); - -void lab_ext_workspace_set_coordinates(struct lab_ext_workspace *workspace, - struct wl_array *coordinates); - -void lab_ext_workspace_destroy(struct lab_ext_workspace *workspace); - -#endif /* LABWC_PROTOCOLS_EXT_WORKSPACES_H */ diff --git a/include/protocols/transaction-addon.h b/include/protocols/transaction-addon.h deleted file mode 100644 index 2c40b3dd..00000000 --- a/include/protocols/transaction-addon.h +++ /dev/null @@ -1,84 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef LABWC_PROTOCOLS_TRANSACTION_ADDON_H -#define LABWC_PROTOCOLS_TRANSACTION_ADDON_H - -#include - -struct lab_transaction_op { - uint32_t change; - void *src; - void *data; - - struct { - struct wl_signal destroy; - } events; - - // Private - struct wl_list link; -}; - -struct lab_transaction_session_context { - int ref_count; - struct wl_list transaction_ops; -}; - -struct lab_wl_resource_addon { - struct lab_transaction_session_context *ctx; - void *data; -}; - -/* - * Creates a new addon which can be attached to a wl_resource via - * wl_resource_set_user_data() and retrieved via wl_resource_get_user_data(). - * - * Usually the ctx argument should be addon->ctx of the parent wl_resource. - * If it is NULL it will be created automatically which can be used for top - * level wl_resources (when a client binds a wl_global from the registry). - * - * The context refcount is increased by one after this call. - */ -struct lab_wl_resource_addon *lab_resource_addon_create( - struct lab_transaction_session_context *ctx); - -/* - * A generic transaction operation attached to - * a session context transaction operation list. - * - * All arguments other than the context are user defined. - * Use of an enum for pending_change is suggested. - * - * The client is responsible for eventually freeing the data - * passed in the void *src and *data arguments by listening - * to the events.destroy signal. The transaction operations can be - * looped through by using lab_transaction_for_each(trans_op, ctx). - */ -struct lab_transaction_op *lab_transaction_op_add( - struct lab_transaction_session_context *ctx, - uint32_t pending_change, void *src, void *data); - -/* - * Removes the transaction operation from the ctx list and frees it. - * - * Does *not* free any passed in src or data arguments. - * Use the events.destroy signal for that if necessary. - */ -void lab_transaction_op_destroy(struct lab_transaction_op *transaction_op); - -/* - * Destroys the addon. - * - * The context refcount is decreased by one. If it reaches - * zero the context will be free'd alongside the addon itself. - * If the context is destroyed all pending transaction operations - * are destroyed as well. - */ -void lab_resource_addon_destroy(struct lab_wl_resource_addon *addon); - -/* Convenience wrappers for looping through the pending transaction ops of a ctx */ -#define lab_transaction_for_each(transaction_op, ctx) \ - wl_list_for_each(transaction_op, &(ctx)->transaction_ops, link) - -#define lab_transaction_for_each_safe(trans_op, trans_op_tmp, ctx) \ - wl_list_for_each_safe(trans_op, trans_op_tmp, &(ctx)->transaction_ops, link) - -#endif /* LABWC_PROTOCOLS_TRANSACTIONS_ADDON_H */ diff --git a/include/workspaces.h b/include/workspaces.h index 5c0f4e7a..3a5c6d06 100644 --- a/include/workspaces.h +++ b/include/workspaces.h @@ -17,20 +17,7 @@ struct workspace { struct wlr_scene_tree *tree; struct wlr_scene_tree *view_trees[3]; - struct lab_cosmic_workspace *cosmic_workspace; - struct { - struct wl_listener activate; - struct wl_listener deactivate; - struct wl_listener remove; - } on_cosmic; - - struct lab_ext_workspace *ext_workspace; - struct { - struct wl_listener activate; - struct wl_listener deactivate; - struct wl_listener assign; - struct wl_listener remove; - } on_ext; + struct wlr_ext_workspace_handle_v1 *ext_workspace; }; void workspaces_init(void); diff --git a/protocols/cosmic-workspace-unstable-v1.xml b/protocols/cosmic-workspace-unstable-v1.xml deleted file mode 100644 index 76adedd9..00000000 --- a/protocols/cosmic-workspace-unstable-v1.xml +++ /dev/null @@ -1,364 +0,0 @@ - - - - Copyright © 2019 Christopher Billington - Copyright © 2020 Ilia Bozhinov - Copyright © 2022 Victoria Brekenfeld - - Permission to use, copy, modify, distribute, and sell this - software and its documentation for any purpose is hereby granted - without fee, provided that the above copyright notice appear in - all copies and that both that copyright notice and this permission - notice appear in supporting documentation, and that the name of - the copyright holders not be used in advertising or publicity - pertaining to distribution of the software without specific, - written prior permission. The copyright holders make no - representations about the suitability of this software for any - purpose. It is provided "as is" without express or implied - warranty. - - THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY - SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, - ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF - THIS SOFTWARE. - - - - - Workspaces, also called virtual desktops, are groups of surfaces. A - compositor with a concept of workspaces may only show some such groups of - surfaces (those of 'active' workspaces) at a time. 'Activating' a - workspace is a request for the compositor to display that workspace's - surfaces as normal, whereas the compositor may hide or otherwise - de-emphasise surfaces that are associated only with 'inactive' workspaces. - Workspaces are grouped by which sets of outputs they correspond to, and - may contain surfaces only from those outputs. In this way, it is possible - for each output to have its own set of workspaces, or for all outputs (or - any other arbitrary grouping) to share workspaces. Compositors may - optionally conceptually arrange each group of workspaces in an - N-dimensional grid. - - The purpose of this protocol is to enable the creation of taskbars and - docks by providing them with a list of workspaces and their properties, - and allowing them to activate and deactivate workspaces. - - After a client binds the zcosmic_workspace_manager_v1, each workspace will be - sent via the workspace event. - - - - - This event is emitted whenever a new workspace group has been created. - - All initial details of the workspace group (workspaces, outputs) will be - sent immediately after this event via the corresponding events in - zcosmic_workspace_group_handle_v1. - - - - - - - The client must send this request after it has finished sending other - requests. The compositor must process a series of requests preceding a - commit request atomically. - - This allows changes to the workspace properties to be seen as atomic, - even if they happen via multiple events, and even if they involve - multiple zcosmic_workspace_handle_v1 objects, for example, deactivating one - workspace and activating another. - - - - - - This event is sent after all changes in all workspace groups have been - sent. - - This allows changes to one or more zcosmic_workspace_group_handle_v1 - properties and zcosmic_workspace_handle_v1 properties to be seen as atomic, - even if they happen via multiple events. - In particular, an output moving from one workspace group to - another sends an output_enter event and an output_leave event to the two - zcosmic_workspace_group_handle_v1 objects in question. The compositor sends - the done event only after updating the output information in both - workspace groups. - - - - - - This event indicates that the compositor is done sending events to the - zcosmic_workspace_manager_v1. The server will destroy the object - immediately after sending this request, so it will become invalid and - the client should free any resources associated with it. - - - - - - Indicates the client no longer wishes to receive events for new - workspace groups. However the compositor may emit further workspace - events, until the finished event is emitted. - - The client must not send any more requests after this one. - - - - - - - A zcosmic_workspace_group_handle_v1 object represents a a workspace group - that is assigned a set of outputs and contains a number of workspaces. - - The set of outputs assigned to the workspace group is conveyed to the client via - output_enter and output_leave events, and its workspaces are conveyed with - workspace events. - - For example, a compositor which has a set of workspaces for each output may - advertise a workspace group (and its workspaces) per output, whereas a compositor - where a workspace spans all outputs may advertise a single workspace group for all - outputs. - - - - - - - - - This event advertises the capabilities supported by the compositor. If - a capability isn't supported, clients should hide or disable the UI - elements that expose this functionality. For instance, if the - compositor doesn't advertise support for creating workspaces, a button - triggering the create_workspace request should not be displayed. - - The compositor will ignore requests it doesn't support. For instance, - a compositor which doesn't advertise support for creating workspaces will ignore - create_workspace requests. - - Compositors must send this event once after creation of an - zcosmic_workspace_group_handle_v1 . When the capabilities change, compositors - must send this event again. - - The capabilities are sent as an array of 32-bit unsigned integers in - native endianness. - - - - - - - This event is emitted whenever an output is assigned to the workspace - group. - - - - - - - This event is emitted whenever an output is removed from the workspace - group. - - - - - - - This event is emitted whenever a new workspace has been created. - A workspace can only be a member of a single workspace group and cannot - be re-assigned. - - All initial details of the workspace (name, coordinates, state) will - be sent immediately after this event via the corresponding events in - zcosmic_workspace_handle_v1. - - - - - - - This event means the zcosmic_workspace_group_handle_v1 has been destroyed. - It is guaranteed there won't be any more events for this - zcosmic_workspace_group_handle_v1. The zext_workspace_group_handle_v1 becomes - inert so any requests will be ignored except the destroy request. - - The compositor must remove all workspaces belonging to a workspace group - before removing the workspace group. - - - - - - Request that the compositor create a new workspace with the given name. - - There is no guarantee that the compositor will create a new workspace, - or that the created workspace will have the provided name. - - - - - - - Destroys the zcosmic_workspace_group_handle_v1 object. - - This request should be called either when the client does not want to - use the workspace object any more or after the remove event to finalize - the destruction of the object. - - - - - - - A zcosmic_workspace_handle_v1 object represents a a workspace that handles a - group of surfaces. - - Each workspace has a name, conveyed to the client with the name event; a - list of states, conveyed to the client with the state event; and - optionally a set of coordinates, conveyed to the client with the - coordinates event. The client may request that the compositor activate or - deactivate the workspace. - - Each workspace can belong to only a single workspace group. - Depepending on the compositor policy, there might be workspaces with - the same name in different workspace groups, but these workspaces are still - separate (e.g. one of them might be active while the other is not). - - - - - This event is emitted immediately after the zcosmic_workspace_handle_v1 is - created and whenever the name of the workspace changes. - - - - - - - This event is used to organize workspaces into an N-dimensional grid - within a workspace group, and if supported, is emitted immediately after - the zcosmic_workspace_handle_v1 is created and whenever the coordinates of - the workspace change. Compositors may not send this event if they do not - conceptually arrange workspaces in this way. If compositors simply - number workspaces, without any geometric interpretation, they may send - 1D coordinates, which clients should not interpret as implying any - geometry. Sending an empty array means that the compositor no longer - orders the workspace geometrically. - - Coordinates have an arbitrary number of dimensions N with an uint32 - position along each dimension. By convention if N > 1, the first - dimension is X, the second Y, the third Z, and so on. The compositor may - chose to utilize these events for a more novel workspace layout - convention, however. No guarantee is made about the grid being filled or - bounded; there may be a workspace at coordinate 1 and another at - coordinate 1000 and none in between. Within a workspace group, however, - workspaces must have unique coordinates of equal dimensionality. - - - - - - - This event is emitted immediately after the zcosmic_workspace_handle_v1 is - created and each time the workspace state changes, either because of a - compositor action or because of a request in this protocol. - - - - - - - The different states that a workspace can have. - - - - - - - The workspace is not visible in its workspace group, and clients - attempting to visualize the compositor workspace state should not - display such workspaces. - - - - - - - - - - - - - This event advertises the capabilities supported by the compositor. If - a capability isn't supported, clients should hide or disable the UI - elements that expose this functionality. For instance, if the - compositor doesn't advertise support for removing workspaces, a button - triggering the remove request should not be displayed. - - The compositor will ignore requests it doesn't support. For instance, - a compositor which doesn't advertise support for remove will ignore - remove requests. - - Compositors must send this event once after creation of an - zcosmic_workspace_handle_v1 . When the capabilities change, compositors - must send this event again. - - The capabilities are sent as an array of 32-bit unsigned integers in - native endianness. - - - - - - - This event means the zcosmic_workspace_handle_v1 has been destroyed. It is - guaranteed there won't be any more events for this - zcosmic_workspace_handle_v1. The zext_workspace_handle_v1 becomes inert so - any requests will be ignored except the destroy request. - - - - - - Destroys the zcosmic_workspace_handle_v1 object. - - This request should be called either when the client does not want to - use the workspace object any more or after the remove event to finalize - the destruction of the object. - - - - - - Request that this workspace be activated. - - There is no guarantee the workspace will be actually activated, and - behaviour may be compositor-dependent. For example, activating a - workspace may or may not deactivate all other workspaces in the same - group. - - - - - - Request that this workspace be deactivated. - - There is no guarantee the workspace will be actually deactivated. - - - - - - Request that this workspace be removed. - - There is no guarantee the workspace will be actually removed. - - - - diff --git a/protocols/meson.build b/protocols/meson.build index 67c0d3d2..f360210e 100644 --- a/protocols/meson.build +++ b/protocols/meson.build @@ -25,7 +25,6 @@ server_protocols = [ wl_protocol_dir / 'staging/ext-workspace/ext-workspace-v1.xml', wl_protocol_dir / 'staging/ext-image-capture-source/ext-image-capture-source-v1.xml', wl_protocol_dir / 'staging/ext-image-copy-capture/ext-image-copy-capture-v1.xml', - 'cosmic-workspace-unstable-v1.xml', 'wlr-layer-shell-unstable-v1.xml', 'wlr-output-power-management-unstable-v1.xml', ] diff --git a/src/meson.build b/src/meson.build index a9afdc4f..40ec3170 100644 --- a/src/meson.build +++ b/src/meson.build @@ -55,6 +55,5 @@ subdir('foreign-toplevel') subdir('img') subdir('input') subdir('menu') -subdir('protocols') subdir('scaled-buffer') subdir('ssd') diff --git a/src/output.c b/src/output.c index 1fd0a03d..49544baa 100644 --- a/src/output.c +++ b/src/output.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -32,8 +33,6 @@ #include "node.h" #include "output-state.h" #include "output-virtual.h" -#include "protocols/cosmic-workspaces.h" -#include "protocols/ext-workspace.h" #include "regions.h" #include "session-lock.h" #include "view.h" @@ -285,9 +284,7 @@ add_output_to_layout(struct output *output) layout_output, output->scene_output); } - lab_cosmic_workspace_group_output_enter( - server.workspaces.cosmic_group, output->wlr_output); - lab_ext_workspace_group_output_enter( + wlr_ext_workspace_group_handle_v1_output_enter( server.workspaces.ext_group, output->wlr_output); /* (Re-)create regions from config */ @@ -729,9 +726,7 @@ output_config_apply(struct wlr_output_configuration_v1 *config) } else if (was_in_layout) { regions_evacuate_output(output); - lab_cosmic_workspace_group_output_leave( - server.workspaces.cosmic_group, output->wlr_output); - lab_ext_workspace_group_output_leave( + wlr_ext_workspace_group_handle_v1_output_leave( server.workspaces.ext_group, output->wlr_output); /* diff --git a/src/protocols/cosmic_workspaces/cosmic-workspaces.c b/src/protocols/cosmic_workspaces/cosmic-workspaces.c deleted file mode 100644 index d12611cb..00000000 --- a/src/protocols/cosmic_workspaces/cosmic-workspaces.c +++ /dev/null @@ -1,717 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -#include -#include -#include "common/array.h" -#include "common/mem.h" -#include "common/list.h" -#include "cosmic-workspace-unstable-v1-protocol.h" -#include "protocols/cosmic-workspaces.h" -#include "protocols/cosmic-workspaces-internal.h" -#include "protocols/transaction-addon.h" - -/* - * .--------------------. - * | TODO | - * |--------------------| - * | - prevent empty | - * | done events | - * | - go through xml | - * | and verify impl | - * | - assert pub API | - * `--------------------´ - * - */ - -/* Only used within an assert() */ -#ifndef NDEBUG - #define COSMIC_WORKSPACE_V1_VERSION 1 -#endif - -/* These are just *waaay* too long */ -#define ZCOSMIC_CAP_WS_CREATE \ - ZCOSMIC_WORKSPACE_GROUP_HANDLE_V1_ZCOSMIC_WORKSPACE_GROUP_CAPABILITIES_V1_CREATE_WORKSPACE -#define ZCOSMIC_CAP_WS_ACTIVATE \ - ZCOSMIC_WORKSPACE_HANDLE_V1_ZCOSMIC_WORKSPACE_CAPABILITIES_V1_ACTIVATE -#define ZCOSMIC_CAP_WS_DEACTIVATE \ - ZCOSMIC_WORKSPACE_HANDLE_V1_ZCOSMIC_WORKSPACE_CAPABILITIES_V1_DEACTIVATE -#define ZCOSMIC_CAP_WS_REMOVE \ - ZCOSMIC_WORKSPACE_HANDLE_V1_ZCOSMIC_WORKSPACE_CAPABILITIES_V1_REMOVE - -enum workspace_state { - CW_WS_STATE_ACTIVE = 1 << 0, - CW_WS_STATE_URGENT = 1 << 1, - CW_WS_STATE_HIDDEN = 1 << 2, - - /* - * Set when creating a new workspace so we - * don't end up having to send the state twice. - */ - CW_WS_STATE_INVALID = 1 << 31, -}; - -struct ws_create_workspace_event { - char *name; - struct { - struct wl_listener transaction_op_destroy; - } on; -}; - -static void -add_caps(struct wl_array *caps_arr, uint32_t caps) -{ - if (caps == CW_CAP_NONE) { - return; - } - if (caps & CW_CAP_GRP_WS_CREATE) { - array_add(caps_arr, ZCOSMIC_CAP_WS_CREATE); - } - if (caps & CW_CAP_WS_ACTIVATE) { - array_add(caps_arr, ZCOSMIC_CAP_WS_ACTIVATE); - } - if (caps & CW_CAP_WS_DEACTIVATE) { - array_add(caps_arr, ZCOSMIC_CAP_WS_DEACTIVATE); - } - if (caps & CW_CAP_WS_REMOVE) { - array_add(caps_arr, ZCOSMIC_CAP_WS_REMOVE); - } -} - -/* Workspace */ -static void -workspace_handle_destroy(struct wl_client *client, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static void -workspace_handle_activate(struct wl_client *client, struct wl_resource *resource) -{ - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - if (!addon) { - /* workspace was destroyed from the compositor side */ - return; - } - struct lab_cosmic_workspace *workspace = addon->data; - lab_transaction_op_add(addon->ctx, CW_PENDING_WS_ACTIVATE, - workspace, /*data*/ NULL); -} - -static void -workspace_handle_deactivate(struct wl_client *client, struct wl_resource *resource) -{ - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - if (!addon) { - /* Workspace was destroyed from the compositor side */ - return; - } - struct lab_cosmic_workspace *workspace = addon->data; - lab_transaction_op_add(addon->ctx, CW_PENDING_WS_DEACTIVATE, - workspace, /*data*/ NULL); -} - -static void -workspace_handle_remove(struct wl_client *client, struct wl_resource *resource) -{ - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - if (!addon) { - /* workspace was destroyed from the compositor side */ - return; - } - struct lab_cosmic_workspace *workspace = addon->data; - lab_transaction_op_add(addon->ctx, CW_PENDING_WS_REMOVE, - workspace, /*data*/ NULL); -} - -static const struct zcosmic_workspace_handle_v1_interface workspace_impl = { - .destroy = workspace_handle_destroy, - .activate = workspace_handle_activate, - .deactivate = workspace_handle_deactivate, - .remove = workspace_handle_remove, -}; - -static void -workspace_instance_resource_destroy(struct wl_resource *resource) -{ - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - if (addon) { - lab_resource_addon_destroy(addon); - wl_resource_set_user_data(resource, NULL); - } - - wl_list_remove(wl_resource_get_link(resource)); -} - -static struct wl_resource * -workspace_resource_create(struct lab_cosmic_workspace *workspace, - struct wl_resource *group_resource, struct lab_transaction_session_context *ctx) -{ - struct wl_client *client = wl_resource_get_client(group_resource); - struct wl_resource *resource = wl_resource_create(client, - &zcosmic_workspace_handle_v1_interface, - wl_resource_get_version(group_resource), 0); - if (!resource) { - wl_client_post_no_memory(client); - return NULL; - } - - struct lab_wl_resource_addon *addon = lab_resource_addon_create(ctx); - addon->data = workspace; - - wl_resource_set_implementation(resource, &workspace_impl, addon, - workspace_instance_resource_destroy); - - wl_list_insert(&workspace->resources, wl_resource_get_link(resource)); - return resource; -} - -/* Workspace internal helpers */ -static void -workspace_send_state(struct lab_cosmic_workspace *workspace, struct wl_resource *target) -{ - struct wl_array state; - wl_array_init(&state); - - if (workspace->state & CW_WS_STATE_ACTIVE) { - array_add(&state, ZCOSMIC_WORKSPACE_HANDLE_V1_STATE_ACTIVE); - } - if (workspace->state & CW_WS_STATE_URGENT) { - array_add(&state, ZCOSMIC_WORKSPACE_HANDLE_V1_STATE_URGENT); - } - if (workspace->state & CW_WS_STATE_HIDDEN) { - array_add(&state, ZCOSMIC_WORKSPACE_HANDLE_V1_STATE_HIDDEN); - } - - if (target) { - zcosmic_workspace_handle_v1_send_state(target, &state); - } else { - struct wl_resource *resource; - wl_resource_for_each(resource, &workspace->resources) { - zcosmic_workspace_handle_v1_send_state(resource, &state); - } - } - - wl_array_release(&state); -} - -static void -workspace_send_initial_state(struct lab_cosmic_workspace *workspace, struct wl_resource *resource) -{ - zcosmic_workspace_handle_v1_send_capabilities(resource, &workspace->capabilities); - if (workspace->coordinates.size > 0) { - zcosmic_workspace_handle_v1_send_coordinates(resource, &workspace->coordinates); - } - if (workspace->name) { - zcosmic_workspace_handle_v1_send_name(resource, workspace->name); - } -} - -static void -workspace_set_state(struct lab_cosmic_workspace *workspace, - enum workspace_state state, bool enabled) -{ - if (!!(workspace->state_pending & state) == enabled) { - return; - } - - if (enabled) { - workspace->state_pending |= state; - } else { - workspace->state_pending &= ~state; - } - cosmic_manager_schedule_done_event(workspace->group->manager); -} - -/* Group */ -static void -ws_create_workspace_handle_transaction_op_destroy(struct wl_listener *listener, void *data) -{ - struct ws_create_workspace_event *ev = - wl_container_of(listener, ev, on.transaction_op_destroy); - wl_list_remove(&ev->on.transaction_op_destroy.link); - free(ev->name); - free(ev); -} - -static void -group_handle_create_workspace(struct wl_client *client, - struct wl_resource *resource, const char *name) -{ - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - if (!addon) { - return; - } - - struct lab_cosmic_workspace_group *group = addon->data; - struct ws_create_workspace_event *ev = znew(*ev); - ev->name = xstrdup(name); - - struct lab_transaction_op *transaction_op = lab_transaction_op_add( - addon->ctx, CW_PENDING_WS_CREATE, group, ev); - - ev->on.transaction_op_destroy.notify = - ws_create_workspace_handle_transaction_op_destroy; - wl_signal_add(&transaction_op->events.destroy, &ev->on.transaction_op_destroy); -} - -static void -group_handle_destroy(struct wl_client *client, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static const struct zcosmic_workspace_group_handle_v1_interface group_impl = { - .create_workspace = group_handle_create_workspace, - .destroy = group_handle_destroy, -}; - -static void -group_instance_resource_destroy(struct wl_resource *resource) -{ - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - if (addon) { - lab_resource_addon_destroy(addon); - wl_resource_set_user_data(resource, NULL); - } - wl_list_remove(wl_resource_get_link(resource)); -} - -static struct wl_resource * -group_resource_create(struct lab_cosmic_workspace_group *group, - struct wl_resource *manager_resource, struct lab_transaction_session_context *ctx) -{ - struct wl_client *client = wl_resource_get_client(manager_resource); - struct wl_resource *resource = wl_resource_create(client, - &zcosmic_workspace_group_handle_v1_interface, - wl_resource_get_version(manager_resource), 0); - if (!resource) { - wl_client_post_no_memory(client); - return NULL; - } - - struct lab_wl_resource_addon *addon = lab_resource_addon_create(ctx); - addon->data = group; - - wl_resource_set_implementation(resource, &group_impl, addon, - group_instance_resource_destroy); - - wl_list_insert(&group->resources, wl_resource_get_link(resource)); - return resource; -} - -/* Group internal helpers */ -static void -group_send_state(struct lab_cosmic_workspace_group *group, struct wl_resource *resource) -{ - zcosmic_workspace_group_handle_v1_send_capabilities( - resource, &group->capabilities); - - cosmic_group_output_send_initial_state(group, resource); -} - -/* Manager itself */ -static void -manager_handle_commit(struct wl_client *client, struct wl_resource *resource) -{ - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - if (!addon) { - return; - } - - struct lab_cosmic_workspace *workspace; - struct lab_cosmic_workspace_group *group; - struct lab_transaction_op *trans_op, *trans_op_tmp; - lab_transaction_for_each_safe(trans_op, trans_op_tmp, addon->ctx) { - switch (trans_op->change) { - case CW_PENDING_WS_CREATE: { - group = trans_op->src; - struct ws_create_workspace_event *ev = trans_op->data; - wl_signal_emit_mutable(&group->events.create_workspace, ev->name); - break; - } - case CW_PENDING_WS_ACTIVATE: - workspace = trans_op->src; - wl_signal_emit_mutable(&workspace->events.activate, NULL); - break; - case CW_PENDING_WS_DEACTIVATE: - workspace = trans_op->src; - wl_signal_emit_mutable(&workspace->events.deactivate, NULL); - break; - case CW_PENDING_WS_REMOVE: - workspace = trans_op->src; - wl_signal_emit_mutable(&workspace->events.remove, NULL); - break; - default: - wlr_log(WLR_ERROR, "Invalid transaction state: %u", trans_op->change); - } - - lab_transaction_op_destroy(trans_op); - } -} - -static void -manager_handle_stop(struct wl_client *client, struct wl_resource *resource) -{ - zcosmic_workspace_manager_v1_send_finished(resource); - wl_resource_destroy(resource); -} - -static const struct zcosmic_workspace_manager_v1_interface manager_impl = { - .commit = manager_handle_commit, - .stop = manager_handle_stop, -}; - -static void -manager_instance_resource_destroy(struct wl_resource *resource) -{ - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - if (addon) { - lab_resource_addon_destroy(addon); - wl_resource_set_user_data(resource, NULL); - } - - wl_list_remove(wl_resource_get_link(resource)); -} - -static void -manager_handle_bind(struct wl_client *client, void *data, - uint32_t version, uint32_t id) -{ - struct lab_cosmic_workspace_manager *manager = data; - struct wl_resource *resource = wl_resource_create(client, - &zcosmic_workspace_manager_v1_interface, - version, id); - if (!resource) { - wl_client_post_no_memory(client); - return; - } - - struct lab_wl_resource_addon *addon = - lab_resource_addon_create(/* session context*/ NULL); - addon->data = manager; - - wl_resource_set_implementation(resource, &manager_impl, - addon, manager_instance_resource_destroy); - - wl_list_insert(&manager->resources, wl_resource_get_link(resource)); - - struct lab_cosmic_workspace *workspace; - struct lab_cosmic_workspace_group *group; - wl_list_for_each(group, &manager->groups, link) { - /* Create group resource */ - struct wl_resource *group_resource = - group_resource_create(group, resource, addon->ctx); - zcosmic_workspace_manager_v1_send_workspace_group(resource, group_resource); - group_send_state(group, group_resource); - - /* Create workspace resource */ - wl_list_for_each(workspace, &group->workspaces, link) { - struct wl_resource *workspace_resource = - workspace_resource_create(workspace, group_resource, addon->ctx); - zcosmic_workspace_group_handle_v1_send_workspace( - group_resource, workspace_resource); - workspace_send_initial_state(workspace, workspace_resource); - /* Send the current workspace state manually */ - workspace_send_state(workspace, workspace_resource); - } - } - zcosmic_workspace_manager_v1_send_done(resource); -} - -static void -manager_handle_display_destroy(struct wl_listener *listener, void *data) -{ - struct lab_cosmic_workspace_manager *manager = - wl_container_of(listener, manager, on.display_destroy); - - struct lab_cosmic_workspace_group *group, *tmp; - wl_list_for_each_safe(group, tmp, &manager->groups, link) { - lab_cosmic_workspace_group_destroy(group); - } - - if (manager->idle_source) { - wl_event_source_remove(manager->idle_source); - } - - wl_list_remove(&manager->on.display_destroy.link); - wl_global_destroy(manager->global); - free(manager); -} - -/* Manager internal helpers */ -static void -manager_idle_send_done(void *data) -{ - struct lab_cosmic_workspace_manager *manager = data; - - struct lab_cosmic_workspace *workspace; - struct lab_cosmic_workspace_group *group; - wl_list_for_each(group, &manager->groups, link) { - wl_list_for_each(workspace, &group->workspaces, link) { - if (workspace->state != workspace->state_pending) { - workspace->state = workspace->state_pending; - workspace_send_state(workspace, /*target*/ NULL); - } - } - } - - struct wl_resource *resource; - wl_resource_for_each(resource, &manager->resources) { - zcosmic_workspace_manager_v1_send_done(resource); - } - manager->idle_source = NULL; -} - -/* Internal API */ -void -cosmic_manager_schedule_done_event(struct lab_cosmic_workspace_manager *manager) -{ - if (manager->idle_source) { - return; - } - if (!manager->event_loop) { - return; - } - manager->idle_source = wl_event_loop_add_idle( - manager->event_loop, manager_idle_send_done, manager); -} - -/* Public API */ -struct lab_cosmic_workspace_manager * -lab_cosmic_workspace_manager_create(struct wl_display *display, uint32_t caps, uint32_t version) -{ - assert(version <= COSMIC_WORKSPACE_V1_VERSION); - - struct lab_cosmic_workspace_manager *manager = znew(*manager); - manager->global = wl_global_create(display, - &zcosmic_workspace_manager_v1_interface, - version, manager, manager_handle_bind); - - if (!manager->global) { - free(manager); - return NULL; - } - - manager->caps = caps; - manager->event_loop = wl_display_get_event_loop(display); - - manager->on.display_destroy.notify = manager_handle_display_destroy; - wl_display_add_destroy_listener(display, &manager->on.display_destroy); - - wl_list_init(&manager->groups); - wl_list_init(&manager->resources); - return manager; -} - -struct lab_cosmic_workspace_group * -lab_cosmic_workspace_group_create(struct lab_cosmic_workspace_manager *manager) -{ - assert(manager); - - struct lab_cosmic_workspace_group *group = znew(*group); - group->manager = manager; - - wl_array_init(&group->capabilities); - add_caps(&group->capabilities, manager->caps & CW_CAP_GRP_ALL); - - wl_list_init(&group->outputs); - wl_list_init(&group->resources); - wl_list_init(&group->workspaces); - wl_signal_init(&group->events.create_workspace); - wl_signal_init(&group->events.destroy); - - wl_list_append(&manager->groups, &group->link); - - struct wl_resource *resource, *tmp; - wl_resource_for_each_safe(resource, tmp, &manager->resources) { - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - assert(addon && addon->ctx); - struct wl_resource *group_resource = - group_resource_create(group, resource, addon->ctx); - zcosmic_workspace_manager_v1_send_workspace_group(resource, group_resource); - group_send_state(group, group_resource); - } - cosmic_manager_schedule_done_event(manager); - - return group; -} - -void -lab_cosmic_workspace_group_destroy(struct lab_cosmic_workspace_group *group) -{ - if (!group) { - return; - } - wl_signal_emit_mutable(&group->events.destroy, NULL); - - struct lab_cosmic_workspace *ws, *ws_tmp; - wl_list_for_each_safe(ws, ws_tmp, &group->workspaces, link) { - lab_cosmic_workspace_destroy(ws); - } - - struct wl_resource *resource, *res_tmp; - wl_resource_for_each_safe(resource, res_tmp, &group->resources) { - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - if (addon) { - lab_resource_addon_destroy(addon); - wl_resource_set_user_data(resource, NULL); - } - zcosmic_workspace_group_handle_v1_send_remove(resource); - wl_list_remove(wl_resource_get_link(resource)); - wl_list_init(wl_resource_get_link(resource)); - } - - /* Cancel pending transaction operations involving this group */ - struct lab_transaction_op *trans_op, *trans_op_tmp; - wl_resource_for_each(resource, &group->manager->resources) { - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - if (!addon) { - continue; - } - lab_transaction_for_each_safe(trans_op, trans_op_tmp, addon->ctx) { - if (trans_op->src == group) { - lab_transaction_op_destroy(trans_op); - } - } - } - - wl_list_remove(&group->link); - wl_array_release(&group->capabilities); - free(group); -} - -struct lab_cosmic_workspace * -lab_cosmic_workspace_create(struct lab_cosmic_workspace_group *group) -{ - assert(group); - - struct lab_cosmic_workspace *workspace = znew(*workspace); - workspace->group = group; - /* - * Ensures we are sending workspace->state_pending on the done event, - * regardless if the compositor has changed any state in between here - * and the scheduled done event or not. - * - * Without this we might have to send the state twice, first here and - * then again in the scheduled done event when there were any changes. - */ - workspace->state = CW_WS_STATE_INVALID; - - wl_array_init(&workspace->capabilities); - add_caps(&workspace->capabilities, group->manager->caps & CW_CAP_WS_ALL); - - wl_list_init(&workspace->resources); - wl_array_init(&workspace->coordinates); - wl_signal_init(&workspace->events.activate); - wl_signal_init(&workspace->events.deactivate); - wl_signal_init(&workspace->events.remove); - wl_signal_init(&workspace->events.destroy); - - wl_list_append(&group->workspaces, &workspace->link); - - /* Notify clients */ - struct wl_resource *group_resource; - wl_resource_for_each(group_resource, &group->resources) { - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(group_resource); - assert(addon && addon->ctx); - struct wl_resource *workspace_resource = - workspace_resource_create(workspace, group_resource, addon->ctx); - zcosmic_workspace_group_handle_v1_send_workspace( - group_resource, workspace_resource); - workspace_send_initial_state(workspace, workspace_resource); - } - cosmic_manager_schedule_done_event(group->manager); - - return workspace; -} - -void -lab_cosmic_workspace_set_name(struct lab_cosmic_workspace *workspace, const char *name) -{ - assert(workspace); - assert(name); - - if (!workspace->name || strcmp(workspace->name, name)) { - free(workspace->name); - workspace->name = xstrdup(name); - struct wl_resource *resource; - wl_resource_for_each(resource, &workspace->resources) { - zcosmic_workspace_handle_v1_send_name(resource, workspace->name); - } - } - cosmic_manager_schedule_done_event(workspace->group->manager); -} - -void -lab_cosmic_workspace_set_active(struct lab_cosmic_workspace *workspace, bool enabled) -{ - workspace_set_state(workspace, CW_WS_STATE_ACTIVE, enabled); -} - -void -lab_cosmic_workspace_set_urgent(struct lab_cosmic_workspace *workspace, bool enabled) -{ - workspace_set_state(workspace, CW_WS_STATE_URGENT, enabled); -} - -void -lab_cosmic_workspace_set_hidden(struct lab_cosmic_workspace *workspace, bool enabled) -{ - workspace_set_state(workspace, CW_WS_STATE_HIDDEN, enabled); -} - -void -lab_cosmic_workspace_set_coordinates(struct lab_cosmic_workspace *workspace, - struct wl_array *coordinates) -{ - wl_array_release(&workspace->coordinates); - wl_array_init(&workspace->coordinates); - wl_array_copy(&workspace->coordinates, coordinates); - - struct wl_resource *resource; - wl_resource_for_each(resource, &workspace->resources) { - zcosmic_workspace_handle_v1_send_coordinates(resource, &workspace->coordinates); - } - cosmic_manager_schedule_done_event(workspace->group->manager); -} - -void -lab_cosmic_workspace_destroy(struct lab_cosmic_workspace *workspace) -{ - if (!workspace) { - return; - } - wl_signal_emit_mutable(&workspace->events.destroy, NULL); - - struct wl_resource *resource, *tmp; - wl_resource_for_each_safe(resource, tmp, &workspace->resources) { - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - if (addon) { - lab_resource_addon_destroy(addon); - wl_resource_set_user_data(resource, NULL); - } - zcosmic_workspace_handle_v1_send_remove(resource); - wl_list_remove(wl_resource_get_link(resource)); - wl_list_init(wl_resource_get_link(resource)); - } - cosmic_manager_schedule_done_event(workspace->group->manager); - - /* Cancel pending transaction operations involving this workspace */ - struct lab_transaction_op *trans_op, *trans_op_tmp; - wl_resource_for_each(resource, &workspace->group->manager->resources) { - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - if (!addon) { - continue; - } - lab_transaction_for_each_safe(trans_op, trans_op_tmp, addon->ctx) { - if (trans_op->src == workspace) { - lab_transaction_op_destroy(trans_op); - } - } - } - - wl_list_remove(&workspace->link); - wl_array_release(&workspace->coordinates); - wl_array_release(&workspace->capabilities); - zfree(workspace->name); - free(workspace); -} diff --git a/src/protocols/cosmic_workspaces/meson.build b/src/protocols/cosmic_workspaces/meson.build deleted file mode 100644 index 31ce18b8..00000000 --- a/src/protocols/cosmic_workspaces/meson.build +++ /dev/null @@ -1,4 +0,0 @@ -labwc_sources += files( - 'cosmic-workspaces.c', - 'output.c', -) diff --git a/src/protocols/cosmic_workspaces/output.c b/src/protocols/cosmic_workspaces/output.c deleted file mode 100644 index 1e170e85..00000000 --- a/src/protocols/cosmic_workspaces/output.c +++ /dev/null @@ -1,174 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -#include -#include -#include -#include "common/mem.h" -#include "cosmic-workspace-unstable-v1-protocol.h" -#include "protocols/cosmic-workspaces.h" -#include "protocols/cosmic-workspaces-internal.h" - -struct group_output { - struct wlr_output *wlr_output; - struct lab_cosmic_workspace_group *group; - struct { - struct wl_listener group_destroy; - struct wl_listener output_bind; - struct wl_listener output_destroy; - } on; - - struct wl_list link; -}; - -/* Internal helpers */ -static void -group_output_send_event(struct wl_list *group_resources, struct wl_list *output_resources, - void (*notifier)(struct wl_resource *group, struct wl_resource *output)) -{ - struct wl_client *client; - struct wl_resource *group_resource, *output_resource; - wl_resource_for_each(group_resource, group_resources) { - client = wl_resource_get_client(group_resource); - wl_resource_for_each(output_resource, output_resources) { - if (wl_resource_get_client(output_resource) == client) { - notifier(group_resource, output_resource); - } - } - } -} - -static void -group_output_destroy(struct group_output *group_output) -{ - group_output_send_event( - &group_output->group->resources, - &group_output->wlr_output->resources, - zcosmic_workspace_group_handle_v1_send_output_leave); - - cosmic_manager_schedule_done_event(group_output->group->manager); - - wl_list_remove(&group_output->link); - wl_list_remove(&group_output->on.group_destroy.link); - wl_list_remove(&group_output->on.output_bind.link); - wl_list_remove(&group_output->on.output_destroy.link); - free(group_output); -} - -/* Event handlers */ -static void -handle_output_bind(struct wl_listener *listener, void *data) -{ - struct group_output *group_output = - wl_container_of(listener, group_output, on.output_bind); - - struct wlr_output_event_bind *event = data; - struct wl_client *client = wl_resource_get_client(event->resource); - - bool sent = false; - struct wl_resource *group_resource; - wl_resource_for_each(group_resource, &group_output->group->resources) { - if (wl_resource_get_client(group_resource) == client) { - zcosmic_workspace_group_handle_v1_send_output_enter( - group_resource, event->resource); - sent = true; - } - } - if (!sent) { - return; - } - - struct wl_resource *manager_resource; - struct wl_list *manager_resources = &group_output->group->manager->resources; - wl_resource_for_each(manager_resource, manager_resources) { - if (wl_resource_get_client(manager_resource) == client) { - zcosmic_workspace_manager_v1_send_done(manager_resource); - } - } -} - -static void -handle_output_destroy(struct wl_listener *listener, void *data) -{ - struct group_output *group_output = - wl_container_of(listener, group_output, on.output_destroy); - group_output_destroy(group_output); -} - -static void -handle_group_destroy(struct wl_listener *listener, void *data) -{ - struct group_output *group_output = - wl_container_of(listener, group_output, on.group_destroy); - group_output_destroy(group_output); -} - -/* Internal API*/ -void -cosmic_group_output_send_initial_state(struct lab_cosmic_workspace_group *group, - struct wl_resource *group_resource) -{ - struct group_output *group_output; - struct wl_resource *output_resource; - struct wl_client *client = wl_resource_get_client(group_resource); - wl_list_for_each(group_output, &group->outputs, link) { - wl_resource_for_each(output_resource, &group_output->wlr_output->resources) { - if (wl_resource_get_client(output_resource) == client) { - zcosmic_workspace_group_handle_v1_send_output_enter( - group_resource, output_resource); - } - } - } -} - -/* Public API */ -void -lab_cosmic_workspace_group_output_enter(struct lab_cosmic_workspace_group *group, - struct wlr_output *wlr_output) -{ - struct group_output *group_output; - wl_list_for_each(group_output, &group->outputs, link) { - if (group_output->wlr_output == wlr_output) { - return; - } - } - group_output = znew(*group_output); - group_output->wlr_output = wlr_output; - group_output->group = group; - - group_output->on.group_destroy.notify = handle_group_destroy; - wl_signal_add(&group->events.destroy, &group_output->on.group_destroy); - - group_output->on.output_bind.notify = handle_output_bind; - wl_signal_add(&wlr_output->events.bind, &group_output->on.output_bind); - - group_output->on.output_destroy.notify = handle_output_destroy; - wl_signal_add(&wlr_output->events.destroy, &group_output->on.output_destroy); - - wl_list_insert(&group->outputs, &group_output->link); - - group_output_send_event( - &group_output->group->resources, - &group_output->wlr_output->resources, - zcosmic_workspace_group_handle_v1_send_output_enter); - - cosmic_manager_schedule_done_event(group->manager); -} - -void -lab_cosmic_workspace_group_output_leave(struct lab_cosmic_workspace_group *group, - struct wlr_output *wlr_output) -{ - struct group_output *tmp; - struct group_output *group_output = NULL; - wl_list_for_each(tmp, &group->outputs, link) { - if (tmp->wlr_output == wlr_output) { - group_output = tmp; - break; - } - } - if (!group_output) { - wlr_log(WLR_ERROR, "output %s was never entered", wlr_output->name); - return; - } - - group_output_destroy(group_output); -} diff --git a/src/protocols/ext-workspace/ext-workspace.c b/src/protocols/ext-workspace/ext-workspace.c deleted file mode 100644 index 30875811..00000000 --- a/src/protocols/ext-workspace/ext-workspace.c +++ /dev/null @@ -1,762 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -#include -#include -#include "common/mem.h" -#include "common/list.h" -#include "ext-workspace-v1-protocol.h" -#include "protocols/ext-workspace.h" -#include "protocols/ext-workspace-internal.h" -#include "protocols/transaction-addon.h" - -/* - * .--------------------. - * | TODO | - * |--------------------| - * | - go through xml | - * | and verify impl | - * | - assert pub API | - * `--------------------´ - * - */ - -/* Only used within an assert() */ -#ifndef NDEBUG - #define EXT_WORKSPACE_V1_VERSION 1 -#endif - -/* - * Set when creating a new workspace state so we - * don't end up having to send the state twice. - */ -#define WS_STATE_INVALID 0xffffffff - -struct ws_create_workspace_event { - char *name; - struct { - struct wl_listener transaction_op_destroy; - } on; -}; - -/* Workspace */ -static void -workspace_handle_destroy(struct wl_client *client, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static void -workspace_handle_activate(struct wl_client *client, struct wl_resource *resource) -{ - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - if (!addon) { - /* Workspace was destroyed from the compositor side */ - return; - } - struct lab_ext_workspace *workspace = addon->data; - lab_transaction_op_add(addon->ctx, WS_PENDING_WS_ACTIVATE, - workspace, /*data*/ NULL); -} - -static void -workspace_handle_deactivate(struct wl_client *client, struct wl_resource *resource) -{ - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - if (!addon) { - /* Workspace was destroyed from the compositor side */ - return; - } - struct lab_ext_workspace *workspace = addon->data; - lab_transaction_op_add(addon->ctx, WS_PENDING_WS_DEACTIVATE, - workspace, /*data*/ NULL); -} - -static void -workspace_handle_assign(struct wl_client *client, struct wl_resource *resource, - struct wl_resource *new_group_resource) -{ - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - if (!addon) { - /* Workspace was destroyed from the compositor side */ - return; - } - struct lab_ext_workspace *workspace = addon->data; - struct lab_wl_resource_addon *grp_addon = - wl_resource_get_user_data(new_group_resource); - if (!grp_addon) { - /* Group was destroyed from the compositor side */ - return; - } - struct lab_ext_workspace_group *new_grp = grp_addon->data; - lab_transaction_op_add(addon->ctx, WS_PENDING_WS_ASSIGN, workspace, new_grp); -} - -static void -workspace_handle_remove(struct wl_client *client, struct wl_resource *resource) -{ - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - if (!addon) { - /* Workspace was destroyed from the compositor side */ - return; - } - struct lab_ext_workspace *workspace = addon->data; - lab_transaction_op_add(addon->ctx, WS_PENDING_WS_REMOVE, - workspace, /*data*/ NULL); -} - -static const struct ext_workspace_handle_v1_interface workspace_impl = { - .destroy = workspace_handle_destroy, - .activate = workspace_handle_activate, - .deactivate = workspace_handle_deactivate, - .assign = workspace_handle_assign, - .remove = workspace_handle_remove, -}; - -static void -workspace_instance_resource_destroy(struct wl_resource *resource) -{ - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - if (addon) { - lab_resource_addon_destroy(addon); - wl_resource_set_user_data(resource, NULL); - } - - wl_list_remove(wl_resource_get_link(resource)); -} - -static struct wl_resource * -workspace_resource_create(struct lab_ext_workspace *workspace, - struct wl_resource *manager_resource, - struct lab_transaction_session_context *ctx) -{ - struct wl_client *client = wl_resource_get_client(manager_resource); - struct wl_resource *resource = wl_resource_create(client, - &ext_workspace_handle_v1_interface, - wl_resource_get_version(manager_resource), 0); - if (!resource) { - wl_client_post_no_memory(client); - return NULL; - } - - struct lab_wl_resource_addon *addon = lab_resource_addon_create(ctx); - addon->data = workspace; - - wl_resource_set_implementation(resource, &workspace_impl, addon, - workspace_instance_resource_destroy); - - wl_list_insert(&workspace->resources, wl_resource_get_link(resource)); - return resource; -} - -/* Workspace internal helpers */ -static void -workspace_send_state(struct lab_ext_workspace *workspace, struct wl_resource *target) -{ - if (target) { - ext_workspace_handle_v1_send_state(target, workspace->state); - } else { - struct wl_resource *resource; - wl_resource_for_each(resource, &workspace->resources) { - ext_workspace_handle_v1_send_state(resource, workspace->state); - } - } -} - -static void -workspace_send_initial_state(struct lab_ext_workspace *workspace, struct wl_resource *resource) -{ - ext_workspace_handle_v1_send_capabilities(resource, workspace->capabilities); - if (workspace->coordinates.size > 0) { - ext_workspace_handle_v1_send_coordinates(resource, &workspace->coordinates); - } - if (workspace->name) { - ext_workspace_handle_v1_send_name(resource, workspace->name); - } - if (workspace->id) { - ext_workspace_handle_v1_send_id(resource, workspace->id); - } -} - -static void -workspace_set_state(struct lab_ext_workspace *workspace, - enum ext_workspace_handle_v1_state state, bool enabled) -{ - if (!!(workspace->state_pending & state) == enabled) { - return; - } - - if (enabled) { - workspace->state_pending |= state; - } else { - workspace->state_pending &= ~state; - } - ext_manager_schedule_done_event(workspace->manager); -} - -/* Group */ -static void -ws_create_workspace_handle_transaction_op_destroy(struct wl_listener *listener, void *data) -{ - struct ws_create_workspace_event *ev = - wl_container_of(listener, ev, on.transaction_op_destroy); - wl_list_remove(&ev->on.transaction_op_destroy.link); - free(ev->name); - free(ev); -} - -static void -group_handle_create_workspace(struct wl_client *client, - struct wl_resource *resource, const char *name) -{ - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - if (!addon) { - return; - } - - struct lab_ext_workspace_group *group = addon->data; - struct ws_create_workspace_event *ev = znew(*ev); - ev->name = xstrdup(name); - - struct lab_transaction_op *transaction_op = lab_transaction_op_add( - addon->ctx, WS_PENDING_WS_CREATE, group, ev); - - ev->on.transaction_op_destroy.notify = - ws_create_workspace_handle_transaction_op_destroy; - wl_signal_add(&transaction_op->events.destroy, &ev->on.transaction_op_destroy); -} - -static void -group_handle_destroy(struct wl_client *client, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static const struct ext_workspace_group_handle_v1_interface group_impl = { - .create_workspace = group_handle_create_workspace, - .destroy = group_handle_destroy, -}; - -static void -group_instance_resource_destroy(struct wl_resource *resource) -{ - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - if (addon) { - lab_resource_addon_destroy(addon); - wl_resource_set_user_data(resource, NULL); - } - wl_list_remove(wl_resource_get_link(resource)); -} - -static struct wl_resource * -group_resource_create(struct lab_ext_workspace_group *group, - struct wl_resource *manager_resource, struct lab_transaction_session_context *ctx) -{ - struct wl_client *client = wl_resource_get_client(manager_resource); - struct wl_resource *resource = wl_resource_create(client, - &ext_workspace_group_handle_v1_interface, - wl_resource_get_version(manager_resource), 0); - if (!resource) { - wl_client_post_no_memory(client); - return NULL; - } - - struct lab_wl_resource_addon *addon = lab_resource_addon_create(ctx); - addon->data = group; - - wl_resource_set_implementation(resource, &group_impl, addon, - group_instance_resource_destroy); - - wl_list_insert(&group->resources, wl_resource_get_link(resource)); - return resource; -} - -/* Group internal helpers */ -static void -group_send_state(struct lab_ext_workspace_group *group, struct wl_resource *resource) -{ - ext_workspace_group_handle_v1_send_capabilities( - resource, group->capabilities); - - ext_group_output_send_initial_state(group, resource); -} - -/* Manager itself */ -static void -manager_handle_commit(struct wl_client *client, struct wl_resource *resource) -{ - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - if (!addon) { - return; - } - - struct lab_ext_workspace *workspace; - struct lab_ext_workspace_group *group; - struct lab_transaction_op *trans_op, *trans_op_tmp; - lab_transaction_for_each_safe(trans_op, trans_op_tmp, addon->ctx) { - switch (trans_op->change) { - case WS_PENDING_WS_CREATE: { - group = trans_op->src; - struct ws_create_workspace_event *ev = trans_op->data; - wl_signal_emit_mutable(&group->events.create_workspace, ev->name); - break; - } - case WS_PENDING_WS_ACTIVATE: - workspace = trans_op->src; - wl_signal_emit_mutable(&workspace->events.activate, NULL); - break; - case WS_PENDING_WS_DEACTIVATE: - workspace = trans_op->src; - wl_signal_emit_mutable(&workspace->events.deactivate, NULL); - break; - case WS_PENDING_WS_REMOVE: - workspace = trans_op->src; - wl_signal_emit_mutable(&workspace->events.remove, NULL); - break; - case WS_PENDING_WS_ASSIGN: - workspace = trans_op->src; - wl_signal_emit_mutable(&workspace->events.assign, trans_op->data); - break; - default: - wlr_log(WLR_ERROR, "Invalid transaction state: %u", trans_op->change); - } - - lab_transaction_op_destroy(trans_op); - } -} - -static void -manager_handle_stop(struct wl_client *client, struct wl_resource *resource) -{ - ext_workspace_manager_v1_send_finished(resource); - wl_resource_destroy(resource); -} - -static const struct ext_workspace_manager_v1_interface manager_impl = { - .commit = manager_handle_commit, - .stop = manager_handle_stop, -}; - -static void -manager_instance_resource_destroy(struct wl_resource *resource) -{ - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - if (addon) { - lab_resource_addon_destroy(addon); - wl_resource_set_user_data(resource, NULL); - } - wl_list_remove(wl_resource_get_link(resource)); -} - -static void -manager_handle_bind(struct wl_client *client, void *data, - uint32_t version, uint32_t id) -{ - struct lab_ext_workspace_manager *manager = data; - struct wl_resource *manager_resource = wl_resource_create(client, - &ext_workspace_manager_v1_interface, - version, id); - if (!manager_resource) { - wl_client_post_no_memory(client); - return; - } - - struct lab_wl_resource_addon *addon = - lab_resource_addon_create(/* session context*/ NULL); - addon->data = manager; - - wl_resource_set_implementation(manager_resource, &manager_impl, - addon, manager_instance_resource_destroy); - - wl_list_insert(&manager->resources, wl_resource_get_link(manager_resource)); - - struct lab_ext_workspace *workspace; - struct lab_ext_workspace_group *group; - wl_list_for_each(group, &manager->groups, link) { - /* Create group resource */ - struct wl_resource *group_resource = - group_resource_create(group, manager_resource, addon->ctx); - ext_workspace_manager_v1_send_workspace_group(manager_resource, group_resource); - group_send_state(group, group_resource); - wl_list_for_each(workspace, &manager->workspaces, link) { - if (workspace->group != group) { - continue; - } - /* Create workspace resource for the current group */ - struct wl_resource *workspace_resource = workspace_resource_create( - workspace, manager_resource, addon->ctx); - ext_workspace_manager_v1_send_workspace( - manager_resource, workspace_resource); - workspace_send_initial_state(workspace, workspace_resource); - workspace_send_state(workspace, workspace_resource); - ext_workspace_group_handle_v1_send_workspace_enter( - group_resource, workspace_resource); - } - } - - /* Create workspace resource for workspaces not belonging to any group */ - wl_list_for_each(workspace, &manager->workspaces, link) { - if (workspace->group) { - continue; - } - struct wl_resource *workspace_resource = - workspace_resource_create(workspace, manager_resource, addon->ctx); - ext_workspace_manager_v1_send_workspace(manager_resource, workspace_resource); - workspace_send_initial_state(workspace, workspace_resource); - workspace_send_state(workspace, workspace_resource); - } - ext_workspace_manager_v1_send_done(manager_resource); -} - -static void -manager_handle_display_destroy(struct wl_listener *listener, void *data) -{ - struct lab_ext_workspace_manager *manager = - wl_container_of(listener, manager, on.display_destroy); - - struct lab_ext_workspace_group *group, *tmp; - wl_list_for_each_safe(group, tmp, &manager->groups, link) { - lab_ext_workspace_group_destroy(group); - } - - struct lab_ext_workspace *ws, *ws_tmp; - wl_list_for_each_safe(ws, ws_tmp, &manager->workspaces, link) { - lab_ext_workspace_destroy(ws); - } - - if (manager->idle_source) { - wl_event_source_remove(manager->idle_source); - } - - wl_list_remove(&manager->on.display_destroy.link); - wl_global_destroy(manager->global); - free(manager); -} - -/* Manager internal helpers */ -static void -manager_idle_send_done(void *data) -{ - struct lab_ext_workspace_manager *manager = data; - - struct lab_ext_workspace *workspace; - wl_list_for_each(workspace, &manager->workspaces, link) { - if (workspace->state != workspace->state_pending) { - workspace->state = workspace->state_pending; - workspace_send_state(workspace, /*target*/ NULL); - } - } - - struct wl_resource *resource; - wl_resource_for_each(resource, &manager->resources) { - ext_workspace_manager_v1_send_done(resource); - } - manager->idle_source = NULL; -} - -/* Internal API */ -void -ext_manager_schedule_done_event(struct lab_ext_workspace_manager *manager) -{ - if (manager->idle_source) { - return; - } - if (!manager->event_loop) { - return; - } - manager->idle_source = wl_event_loop_add_idle( - manager->event_loop, manager_idle_send_done, manager); -} - -static void -send_group_workspace_event(struct lab_ext_workspace_group *group, - struct lab_ext_workspace *workspace, - void (*fn)(struct wl_resource *grp_res, struct wl_resource *ws_res)) -{ - struct lab_wl_resource_addon *workspace_addon, *group_addon; - struct wl_resource *workspace_resource, *group_resource; - wl_resource_for_each(workspace_resource, &workspace->resources) { - workspace_addon = wl_resource_get_user_data(workspace_resource); - wl_resource_for_each(group_resource, &group->resources) { - group_addon = wl_resource_get_user_data(group_resource); - if (group_addon->ctx != workspace_addon->ctx) { - continue; - } - fn(group_resource, workspace_resource); - break; - } - } -} - -/* Public API */ -struct lab_ext_workspace_manager * -lab_ext_workspace_manager_create(struct wl_display *display, uint32_t caps, uint32_t version) -{ - assert(display); - assert(version <= EXT_WORKSPACE_V1_VERSION); - - struct lab_ext_workspace_manager *manager = znew(*manager); - manager->global = wl_global_create(display, - &ext_workspace_manager_v1_interface, - version, manager, manager_handle_bind); - - if (!manager->global) { - free(manager); - return NULL; - } - - manager->caps = caps; - manager->event_loop = wl_display_get_event_loop(display); - - manager->on.display_destroy.notify = manager_handle_display_destroy; - wl_display_add_destroy_listener(display, &manager->on.display_destroy); - - wl_list_init(&manager->groups); - wl_list_init(&manager->workspaces); - wl_list_init(&manager->resources); - return manager; -} - -struct lab_ext_workspace_group * -lab_ext_workspace_group_create(struct lab_ext_workspace_manager *manager) -{ - assert(manager); - - struct lab_ext_workspace_group *group = znew(*group); - group->manager = manager; - group->capabilities = manager->caps & WS_CAP_GRP_ALL; - - wl_list_init(&group->outputs); - wl_list_init(&group->resources); - wl_signal_init(&group->events.create_workspace); - wl_signal_init(&group->events.destroy); - - wl_list_append(&manager->groups, &group->link); - - struct wl_resource *resource, *tmp; - wl_resource_for_each_safe(resource, tmp, &manager->resources) { - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - assert(addon && addon->ctx); - struct wl_resource *group_resource = - group_resource_create(group, resource, addon->ctx); - ext_workspace_manager_v1_send_workspace_group(resource, group_resource); - group_send_state(group, group_resource); - } - ext_manager_schedule_done_event(manager); - - return group; -} - -void -lab_ext_workspace_group_destroy(struct lab_ext_workspace_group *group) -{ - assert(group); - wl_signal_emit_mutable(&group->events.destroy, NULL); - - struct lab_ext_workspace *workspace; - wl_list_for_each(workspace, &group->manager->workspaces, link) { - if (workspace->group == group) { - send_group_workspace_event(group, workspace, - ext_workspace_group_handle_v1_send_workspace_leave); - workspace->group = NULL; - } - } - - struct wl_resource *resource, *res_tmp; - wl_resource_for_each_safe(resource, res_tmp, &group->resources) { - ext_workspace_group_handle_v1_send_removed(resource); - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - lab_resource_addon_destroy(addon); - wl_resource_set_user_data(resource, NULL); - wl_list_remove(wl_resource_get_link(resource)); - wl_list_init(wl_resource_get_link(resource)); - } - - /* Cancel pending transaction ops involving this group */ - struct lab_transaction_op *trans_op, *trans_op_tmp; - wl_resource_for_each(resource, &group->manager->resources) { - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - lab_transaction_for_each_safe(trans_op, trans_op_tmp, addon->ctx) { - if (trans_op->src == group || trans_op->data == group) { - lab_transaction_op_destroy(trans_op); - } - } - } - - ext_manager_schedule_done_event(group->manager); - - wl_list_remove(&group->link); - free(group); -} - -struct lab_ext_workspace * -lab_ext_workspace_create(struct lab_ext_workspace_manager *manager, const char *id) -{ - assert(manager); - - struct lab_ext_workspace *workspace = znew(*workspace); - /* - * Ensures we are sending workspace->state_pending on the done event, - * regardless if the compositor has changed any state in between here - * and the scheduled done event or not. - * - * Without this we might have to send the state twice, first here and - * then again in the scheduled done event when there were any changes. - */ - workspace->state = WS_STATE_INVALID; - workspace->capabilities = (manager->caps & WS_CAP_WS_ALL) >> 16; - workspace->manager = manager; - if (id) { - workspace->id = xstrdup(id); - } - - wl_list_init(&workspace->resources); - wl_array_init(&workspace->coordinates); - wl_signal_init(&workspace->events.activate); - wl_signal_init(&workspace->events.deactivate); - wl_signal_init(&workspace->events.remove); - wl_signal_init(&workspace->events.assign); - wl_signal_init(&workspace->events.destroy); - - wl_list_append(&manager->workspaces, &workspace->link); - - /* Notify clients */ - struct lab_wl_resource_addon *manager_addon; - struct wl_resource *manager_resource, *workspace_resource; - wl_resource_for_each(manager_resource, &manager->resources) { - manager_addon = wl_resource_get_user_data(manager_resource); - workspace_resource = workspace_resource_create( - workspace, manager_resource, manager_addon->ctx); - ext_workspace_manager_v1_send_workspace( - manager_resource, workspace_resource); - workspace_send_initial_state(workspace, workspace_resource); - } - - ext_manager_schedule_done_event(manager); - - return workspace; -} - -void -lab_ext_workspace_assign_to_group(struct lab_ext_workspace *workspace, - struct lab_ext_workspace_group *group) -{ - assert(workspace); - - if (workspace->group == group) { - return; - } - - if (workspace->group) { - /* Send leave event for the old group */ - send_group_workspace_event(workspace->group, workspace, - ext_workspace_group_handle_v1_send_workspace_leave); - ext_manager_schedule_done_event(workspace->manager); - } - workspace->group = group; - - if (!group) { - return; - } - - /* Send enter event for the new group */ - send_group_workspace_event(group, workspace, - ext_workspace_group_handle_v1_send_workspace_enter); - ext_manager_schedule_done_event(workspace->manager); -} - -void -lab_ext_workspace_set_name(struct lab_ext_workspace *workspace, const char *name) -{ - assert(workspace); - assert(name); - - if (!workspace->name || strcmp(workspace->name, name)) { - free(workspace->name); - workspace->name = xstrdup(name); - struct wl_resource *resource; - wl_resource_for_each(resource, &workspace->resources) { - ext_workspace_handle_v1_send_name(resource, workspace->name); - } - } - ext_manager_schedule_done_event(workspace->manager); -} - -void -lab_ext_workspace_set_active(struct lab_ext_workspace *workspace, bool enabled) -{ - assert(workspace); - workspace_set_state(workspace, EXT_WORKSPACE_HANDLE_V1_STATE_ACTIVE, enabled); -} - -void -lab_ext_workspace_set_urgent(struct lab_ext_workspace *workspace, bool enabled) -{ - assert(workspace); - workspace_set_state(workspace, EXT_WORKSPACE_HANDLE_V1_STATE_URGENT, enabled); -} - -void -lab_ext_workspace_set_hidden(struct lab_ext_workspace *workspace, bool enabled) -{ - assert(workspace); - workspace_set_state(workspace, EXT_WORKSPACE_HANDLE_V1_STATE_HIDDEN, enabled); -} - -void -lab_ext_workspace_set_coordinates(struct lab_ext_workspace *workspace, - struct wl_array *coordinates) -{ - assert(workspace); - assert(coordinates); - - wl_array_release(&workspace->coordinates); - wl_array_init(&workspace->coordinates); - wl_array_copy(&workspace->coordinates, coordinates); - - struct wl_resource *resource; - wl_resource_for_each(resource, &workspace->resources) { - ext_workspace_handle_v1_send_coordinates(resource, &workspace->coordinates); - } - ext_manager_schedule_done_event(workspace->manager); -} - -void -lab_ext_workspace_destroy(struct lab_ext_workspace *workspace) -{ - assert(workspace); - - wl_signal_emit_mutable(&workspace->events.destroy, NULL); - - if (workspace->group) { - send_group_workspace_event(workspace->group, workspace, - ext_workspace_group_handle_v1_send_workspace_leave); - } - - struct wl_resource *ws_res, *ws_tmp; - wl_resource_for_each_safe(ws_res, ws_tmp, &workspace->resources) { - ext_workspace_handle_v1_send_removed(ws_res); - struct lab_wl_resource_addon *ws_addon = wl_resource_get_user_data(ws_res); - lab_resource_addon_destroy(ws_addon); - wl_resource_set_user_data(ws_res, NULL); - wl_list_remove(wl_resource_get_link(ws_res)); - wl_list_init(wl_resource_get_link(ws_res)); - } - ext_manager_schedule_done_event(workspace->manager); - - /* Cancel pending transaction ops involving this workspace */ - struct wl_resource *resource; - struct lab_transaction_op *trans_op, *trans_op_tmp; - wl_resource_for_each(resource, &workspace->manager->resources) { - struct lab_wl_resource_addon *addon = wl_resource_get_user_data(resource); - lab_transaction_for_each_safe(trans_op, trans_op_tmp, addon->ctx) { - if (trans_op->src == workspace) { - lab_transaction_op_destroy(trans_op); - } - } - } - - wl_list_remove(&workspace->link); - wl_array_release(&workspace->coordinates); - zfree(workspace->id); - zfree(workspace->name); - free(workspace); -} diff --git a/src/protocols/ext-workspace/meson.build b/src/protocols/ext-workspace/meson.build deleted file mode 100644 index e781d13a..00000000 --- a/src/protocols/ext-workspace/meson.build +++ /dev/null @@ -1,4 +0,0 @@ -labwc_sources += files( - 'ext-workspace.c', - 'output.c', -) diff --git a/src/protocols/ext-workspace/output.c b/src/protocols/ext-workspace/output.c deleted file mode 100644 index 0d6a2a44..00000000 --- a/src/protocols/ext-workspace/output.c +++ /dev/null @@ -1,174 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -#include -#include -#include -#include "common/mem.h" -#include "ext-workspace-v1-protocol.h" -#include "protocols/ext-workspace.h" -#include "protocols/ext-workspace-internal.h" - -struct group_output { - struct wlr_output *wlr_output; - struct lab_ext_workspace_group *group; - struct { - struct wl_listener group_destroy; - struct wl_listener output_bind; - struct wl_listener output_destroy; - } on; - - struct wl_list link; -}; - -/* Internal helpers */ -static void -group_output_send_event(struct wl_list *group_resources, struct wl_list *output_resources, - void (*notifier)(struct wl_resource *group, struct wl_resource *output)) -{ - struct wl_client *client; - struct wl_resource *group_resource, *output_resource; - wl_resource_for_each(group_resource, group_resources) { - client = wl_resource_get_client(group_resource); - wl_resource_for_each(output_resource, output_resources) { - if (wl_resource_get_client(output_resource) == client) { - notifier(group_resource, output_resource); - } - } - } -} - -static void -group_output_destroy(struct group_output *group_output) -{ - group_output_send_event( - &group_output->group->resources, - &group_output->wlr_output->resources, - ext_workspace_group_handle_v1_send_output_leave); - - ext_manager_schedule_done_event(group_output->group->manager); - - wl_list_remove(&group_output->link); - wl_list_remove(&group_output->on.group_destroy.link); - wl_list_remove(&group_output->on.output_bind.link); - wl_list_remove(&group_output->on.output_destroy.link); - free(group_output); -} - -/* Event handlers */ -static void -handle_output_bind(struct wl_listener *listener, void *data) -{ - struct group_output *group_output = - wl_container_of(listener, group_output, on.output_bind); - - struct wlr_output_event_bind *event = data; - struct wl_client *client = wl_resource_get_client(event->resource); - - bool sent = false; - struct wl_resource *group_resource; - wl_resource_for_each(group_resource, &group_output->group->resources) { - if (wl_resource_get_client(group_resource) == client) { - ext_workspace_group_handle_v1_send_output_enter( - group_resource, event->resource); - sent = true; - } - } - if (!sent) { - return; - } - - struct wl_resource *manager_resource; - struct wl_list *manager_resources = &group_output->group->manager->resources; - wl_resource_for_each(manager_resource, manager_resources) { - if (wl_resource_get_client(manager_resource) == client) { - ext_workspace_manager_v1_send_done(manager_resource); - } - } -} - -static void -handle_output_destroy(struct wl_listener *listener, void *data) -{ - struct group_output *group_output = - wl_container_of(listener, group_output, on.output_destroy); - group_output_destroy(group_output); -} - -static void -handle_group_destroy(struct wl_listener *listener, void *data) -{ - struct group_output *group_output = - wl_container_of(listener, group_output, on.group_destroy); - group_output_destroy(group_output); -} - -/* Internal API*/ -void -ext_group_output_send_initial_state(struct lab_ext_workspace_group *group, - struct wl_resource *group_resource) -{ - struct group_output *group_output; - struct wl_resource *output_resource; - struct wl_client *client = wl_resource_get_client(group_resource); - wl_list_for_each(group_output, &group->outputs, link) { - wl_resource_for_each(output_resource, &group_output->wlr_output->resources) { - if (wl_resource_get_client(output_resource) == client) { - ext_workspace_group_handle_v1_send_output_enter( - group_resource, output_resource); - } - } - } -} - -/* Public API */ -void -lab_ext_workspace_group_output_enter(struct lab_ext_workspace_group *group, - struct wlr_output *wlr_output) -{ - struct group_output *group_output; - wl_list_for_each(group_output, &group->outputs, link) { - if (group_output->wlr_output == wlr_output) { - return; - } - } - group_output = znew(*group_output); - group_output->wlr_output = wlr_output; - group_output->group = group; - - group_output->on.group_destroy.notify = handle_group_destroy; - wl_signal_add(&group->events.destroy, &group_output->on.group_destroy); - - group_output->on.output_bind.notify = handle_output_bind; - wl_signal_add(&wlr_output->events.bind, &group_output->on.output_bind); - - group_output->on.output_destroy.notify = handle_output_destroy; - wl_signal_add(&wlr_output->events.destroy, &group_output->on.output_destroy); - - wl_list_insert(&group->outputs, &group_output->link); - - group_output_send_event( - &group_output->group->resources, - &group_output->wlr_output->resources, - ext_workspace_group_handle_v1_send_output_enter); - - ext_manager_schedule_done_event(group->manager); -} - -void -lab_ext_workspace_group_output_leave(struct lab_ext_workspace_group *group, - struct wlr_output *wlr_output) -{ - struct group_output *tmp; - struct group_output *group_output = NULL; - wl_list_for_each(tmp, &group->outputs, link) { - if (tmp->wlr_output == wlr_output) { - group_output = tmp; - break; - } - } - if (!group_output) { - wlr_log(WLR_ERROR, "output %s was never entered", wlr_output->name); - return; - } - - group_output_destroy(group_output); -} diff --git a/src/protocols/meson.build b/src/protocols/meson.build deleted file mode 100644 index d9d17bf5..00000000 --- a/src/protocols/meson.build +++ /dev/null @@ -1,6 +0,0 @@ -labwc_sources += files( - 'transaction-addon.c', -) - -subdir('cosmic_workspaces') -subdir('ext-workspace') diff --git a/src/protocols/transaction-addon.c b/src/protocols/transaction-addon.c deleted file mode 100644 index 808a2096..00000000 --- a/src/protocols/transaction-addon.c +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -#include "protocols/transaction-addon.h" -#include -#include -#include "common/list.h" -#include "common/mem.h" - -void -lab_transaction_op_destroy(struct lab_transaction_op *trans_op) -{ - wl_signal_emit_mutable(&trans_op->events.destroy, trans_op); - wl_list_remove(&trans_op->link); - free(trans_op); -} - -static void -transaction_destroy(struct wl_list *list) -{ - struct lab_transaction_op *trans_op, *trans_op_tmp; - wl_list_for_each_safe(trans_op, trans_op_tmp, list, link) { - lab_transaction_op_destroy(trans_op); - } -} - -void -lab_resource_addon_destroy(struct lab_wl_resource_addon *addon) -{ - assert(addon); - assert(addon->ctx); - - addon->ctx->ref_count--; - assert(addon->ctx->ref_count >= 0); - - if (!addon->ctx->ref_count) { - transaction_destroy(&addon->ctx->transaction_ops); - free(addon->ctx); - } - - free(addon); -} - -struct lab_wl_resource_addon * -lab_resource_addon_create(struct lab_transaction_session_context *ctx) -{ - struct lab_wl_resource_addon *addon = znew(*addon); - if (!ctx) { - ctx = znew(*ctx); - wl_list_init(&ctx->transaction_ops); - } - addon->ctx = ctx; - addon->ctx->ref_count++; - return addon; -} - -struct lab_transaction_op * -lab_transaction_op_add(struct lab_transaction_session_context *ctx, - uint32_t pending_change, void *src, void *data) -{ - assert(ctx); - - struct lab_transaction_op *trans_op = znew(*trans_op); - trans_op->change = pending_change; - trans_op->src = src; - trans_op->data = data; - - wl_signal_init(&trans_op->events.destroy); - wl_list_append(&ctx->transaction_ops, &trans_op->link); - - return trans_op; -} diff --git a/src/server.c b/src/server.c index 727a8f08..653caf59 100644 --- a/src/server.c +++ b/src/server.c @@ -222,7 +222,6 @@ protocol_is_privileged(const struct wl_interface *iface) "zwlr_data_control_manager_v1", "wp_security_context_manager_v1", "ext_idle_notifier_v1", - "zcosmic_workspace_manager_v1", "zwlr_foreign_toplevel_manager_v1", "ext_foreign_toplevel_list_v1", "ext_session_lock_manager_v1", diff --git a/src/workspaces.c b/src/workspaces.c index 9b4ed664..7ff471a5 100644 --- a/src/workspaces.c +++ b/src/workspaces.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include "buffer.h" @@ -20,12 +21,9 @@ #include "input/keyboard.h" #include "labwc.h" #include "output.h" -#include "protocols/cosmic-workspaces.h" -#include "protocols/ext-workspace.h" #include "theme.h" #include "view.h" -#define COSMIC_WORKSPACES_VERSION 1 #define EXT_WORKSPACES_VERSION 1 /* Internal helpers */ @@ -210,22 +208,19 @@ workspace_find_by_name(const char *name) return NULL; } -/* cosmic workspace handlers */ static void -handle_cosmic_workspace_activate(struct wl_listener *listener, void *data) +handle_ext_workspace_commit(struct wl_listener *listener, void *data) { - struct workspace *workspace = wl_container_of(listener, workspace, on_cosmic.activate); - workspaces_switch_to(workspace, /* update_focus */ true); - wlr_log(WLR_INFO, "cosmic activating workspace %s", workspace->name); -} + struct wlr_ext_workspace_v1_commit_event *event = data; -/* ext workspace handlers */ -static void -handle_ext_workspace_activate(struct wl_listener *listener, void *data) -{ - struct workspace *workspace = wl_container_of(listener, workspace, on_ext.activate); - workspaces_switch_to(workspace, /* update_focus */ true); - wlr_log(WLR_INFO, "ext activating workspace %s", workspace->name); + struct wlr_ext_workspace_v1_request *req; + wl_list_for_each(req, event->requests, link) { + if (req->type == WLR_EXT_WORKSPACE_V1_REQUEST_ACTIVATE) { + struct workspace *workspace = req->activate.workspace->data; + workspaces_switch_to(workspace, /* update_focus */ true); + wlr_log(WLR_INFO, "activating workspace %s", workspace->name); + } + } } /* Internal API */ @@ -244,23 +239,13 @@ add_workspace(const char *name) wl_list_append(&server.workspaces.all, &workspace->link); wlr_scene_node_set_enabled(&workspace->tree->node, false); - /* cosmic */ - workspace->cosmic_workspace = lab_cosmic_workspace_create(server.workspaces.cosmic_group); - lab_cosmic_workspace_set_name(workspace->cosmic_workspace, name); - - workspace->on_cosmic.activate.notify = handle_cosmic_workspace_activate; - wl_signal_add(&workspace->cosmic_workspace->events.activate, - &workspace->on_cosmic.activate); - - /* ext */ - workspace->ext_workspace = lab_ext_workspace_create( - server.workspaces.ext_manager, /*id*/ NULL); - lab_ext_workspace_assign_to_group(workspace->ext_workspace, server.workspaces.ext_group); - lab_ext_workspace_set_name(workspace->ext_workspace, name); - - workspace->on_ext.activate.notify = handle_ext_workspace_activate; - wl_signal_add(&workspace->ext_workspace->events.activate, - &workspace->on_ext.activate); + workspace->ext_workspace = wlr_ext_workspace_handle_v1_create( + server.workspaces.ext_manager, /*id*/ NULL, + EXT_WORKSPACE_HANDLE_V1_WORKSPACE_CAPABILITIES_ACTIVATE); + workspace->ext_workspace->data = workspace; + wlr_ext_workspace_handle_v1_set_group( + workspace->ext_workspace, server.workspaces.ext_group); + wlr_ext_workspace_handle_v1_set_name(workspace->ext_workspace, name); } static struct workspace * @@ -402,19 +387,15 @@ _osd_show(void) void workspaces_init(void) { - server.workspaces.cosmic_manager = lab_cosmic_workspace_manager_create( - server.wl_display, /* capabilities */ CW_CAP_WS_ACTIVATE, - COSMIC_WORKSPACES_VERSION); + server.workspaces.ext_manager = wlr_ext_workspace_manager_v1_create( + server.wl_display, EXT_WORKSPACES_VERSION); - server.workspaces.ext_manager = lab_ext_workspace_manager_create( - server.wl_display, /* capabilities */ WS_CAP_WS_ACTIVATE, - EXT_WORKSPACES_VERSION); + server.workspaces.ext_group = wlr_ext_workspace_group_handle_v1_create( + server.workspaces.ext_manager, /*caps*/ 0); - server.workspaces.cosmic_group = lab_cosmic_workspace_group_create( - server.workspaces.cosmic_manager); - - server.workspaces.ext_group = lab_ext_workspace_group_create( - server.workspaces.ext_manager); + server.workspaces.on_ext_manager.commit.notify = handle_ext_workspace_commit; + wl_signal_add(&server.workspaces.ext_manager->events.commit, + &server.workspaces.on_ext_manager.commit); wl_list_init(&server.workspaces.all); @@ -441,8 +422,7 @@ workspaces_init(void) server.workspaces.current = initial; wlr_scene_node_set_enabled(&initial->tree->node, true); - lab_cosmic_workspace_set_active(initial->cosmic_workspace, true); - lab_ext_workspace_set_active(initial->ext_workspace, true); + wlr_ext_workspace_handle_v1_set_active(initial->ext_workspace, true); } /* @@ -462,9 +442,7 @@ workspaces_switch_to(struct workspace *target, bool update_focus) wlr_scene_node_set_enabled( &server.workspaces.current->tree->node, false); - lab_cosmic_workspace_set_active( - server.workspaces.current->cosmic_workspace, false); - lab_ext_workspace_set_active( + wlr_ext_workspace_handle_v1_set_active( server.workspaces.current->ext_workspace, false); /* @@ -516,8 +494,7 @@ workspaces_switch_to(struct workspace *target, bool update_focus) /* Ensure that only currently visible fullscreen windows hide the top layer */ desktop_update_top_layer_visibility(); - lab_cosmic_workspace_set_active(target->cosmic_workspace, true); - lab_ext_workspace_set_active(target->ext_workspace, true); + wlr_ext_workspace_handle_v1_set_active(target->ext_workspace, true); } void @@ -569,11 +546,8 @@ destroy_workspace(struct workspace *workspace) wlr_scene_node_destroy(&workspace->tree->node); zfree(workspace->name); wl_list_remove(&workspace->link); - wl_list_remove(&workspace->on_cosmic.activate.link); - wl_list_remove(&workspace->on_ext.activate.link); - lab_cosmic_workspace_destroy(workspace->cosmic_workspace); - lab_ext_workspace_destroy(workspace->ext_workspace); + wlr_ext_workspace_handle_v1_destroy(workspace->ext_workspace); free(workspace); } @@ -606,9 +580,7 @@ workspaces_reconfigure(void) wlr_log(WLR_DEBUG, "Renaming workspace \"%s\" to \"%s\"", workspace->name, conf->name); xstrdup_replace(workspace->name, conf->name); - lab_cosmic_workspace_set_name( - workspace->cosmic_workspace, workspace->name); - lab_ext_workspace_set_name( + wlr_ext_workspace_handle_v1_set_name( workspace->ext_workspace, workspace->name); } workspace_link = workspace_link->next; @@ -658,4 +630,5 @@ workspaces_destroy(void) destroy_workspace(workspace); } assert(wl_list_empty(&server.workspaces.all)); + wl_list_remove(&server.workspaces.on_ext_manager.commit.link); } From cee571287752cbc2e798194a0293fad683299ba2 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Mon, 30 Mar 2026 00:02:47 -0700 Subject: [PATCH 050/146] chase wlroots: wlr_scene_set_gamma_control_manager_v1 Ref: 515275ee7214bf91f8a758b660093eb4b932195a (wlr_scene: Introduce wlr_scene_set_gamma_control_manager_v1) This wlroots change eliminates the need for separate event tracking for gamma control application. v2: Fix code style v3: Rebase now that 0.20 is merged --- include/labwc.h | 1 - include/output.h | 2 -- src/output.c | 68 +++++------------------------------------------- 3 files changed, 6 insertions(+), 65 deletions(-) diff --git a/include/labwc.h b/include/labwc.h index c579b06e..511fdd65 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -274,7 +274,6 @@ struct server { struct wl_listener renderer_lost; struct wlr_gamma_control_manager_v1 *gamma_control_manager_v1; - struct wl_listener gamma_control_set_gamma; struct session_lock_manager *session_lock_manager; diff --git a/include/output.h b/include/output.h index 4d5d63ae..89d8be04 100644 --- a/include/output.h +++ b/include/output.h @@ -38,8 +38,6 @@ struct output { * disconnected and connected again. */ uint64_t id_bit; - - bool gamma_lut_changed; }; #undef LAB_NR_LAYERS diff --git a/src/output.c b/src/output.c index 49544baa..f4f1da01 100644 --- a/src/output.c +++ b/src/output.c @@ -81,35 +81,6 @@ output_get_tearing_allowance(struct output *output) return view->force_tearing == LAB_STATE_ENABLED; } -static void -output_apply_gamma(struct output *output) -{ - assert(output); - assert(output->gamma_lut_changed); - - struct wlr_scene_output *scene_output = output->scene_output; - - struct wlr_output_state pending; - wlr_output_state_init(&pending); - - output->gamma_lut_changed = false; - struct wlr_gamma_control_v1 *gamma_control = - wlr_gamma_control_manager_v1_get_control( - server.gamma_control_manager_v1, - output->wlr_output); - - if (!wlr_gamma_control_v1_apply(gamma_control, &pending)) { - wlr_output_state_finish(&pending); - return; - } - - if (!lab_wlr_scene_output_commit(scene_output, &pending)) { - wlr_gamma_control_v1_send_failed_and_destroy(gamma_control); - } - - wlr_output_state_finish(&pending); -} - static void handle_output_frame(struct wl_listener *listener, void *data) { @@ -129,23 +100,12 @@ handle_output_frame(struct wl_listener *listener, void *data) return; } - if (output->gamma_lut_changed) { - /* - * We are not mixing the gamma state with - * other pending output changes to make it - * easier to handle a failed output commit - * due to gamma without impacting other - * unrelated output changes. - */ - output_apply_gamma(output); - } else { - struct wlr_scene_output *scene_output = output->scene_output; - struct wlr_output_state *pending = &output->pending; + struct wlr_scene_output *scene_output = output->scene_output; + struct wlr_output_state *pending = &output->pending; - pending->tearing_page_flip = output_get_tearing_allowance(output); + pending->tearing_page_flip = output_get_tearing_allowance(output); - lab_wlr_scene_output_commit(scene_output, pending); - } + lab_wlr_scene_output_commit(scene_output, pending); struct timespec now = { 0 }; clock_gettime(CLOCK_MONOTONIC, &now); @@ -598,6 +558,8 @@ output_init(void) { server.gamma_control_manager_v1 = wlr_gamma_control_manager_v1_create(server.wl_display); + wlr_scene_set_gamma_control_manager_v1(server.scene, + server.gamma_control_manager_v1); server.new_output.notify = handle_new_output; wl_signal_add(&server.backend->events.new_output, &server.new_output); @@ -907,19 +869,6 @@ handle_output_layout_change(struct wl_listener *listener, void *data) do_output_layout_change(); } -static void -handle_gamma_control_set_gamma(struct wl_listener *listener, void *data) -{ - const struct wlr_gamma_control_manager_v1_set_gamma_event *event = data; - - struct output *output = event->output->data; - if (!output_is_usable(output)) { - return; - } - output->gamma_lut_changed = true; - wlr_output_schedule_frame(output->wlr_output); -} - static void output_manager_init(void) { @@ -936,10 +885,6 @@ output_manager_init(void) server.output_manager_test.notify = handle_output_manager_test; wl_signal_add(&server.output_manager->events.test, &server.output_manager_test); - - server.gamma_control_set_gamma.notify = handle_gamma_control_set_gamma; - wl_signal_add(&server.gamma_control_manager_v1->events.set_gamma, - &server.gamma_control_set_gamma); } static void @@ -948,7 +893,6 @@ output_manager_finish(void) wl_list_remove(&server.output_layout_change.link); wl_list_remove(&server.output_manager_apply.link); wl_list_remove(&server.output_manager_test.link); - wl_list_remove(&server.gamma_control_set_gamma.link); } struct output * From cdee4ba5f1bcaa7440f38832d417f7dc5e0e05ff Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Mon, 30 Mar 2026 18:32:30 +0900 Subject: [PATCH 051/146] xwayland: use wlr_xwayland_surface_fetch_icon() --- include/xwayland.h | 1 + src/xwayland.c | 44 +++++++++++--------------------------------- 2 files changed, 12 insertions(+), 33 deletions(-) diff --git a/include/xwayland.h b/include/xwayland.h index 2be7d934..379a2e8a 100644 --- a/include/xwayland.h +++ b/include/xwayland.h @@ -53,6 +53,7 @@ struct xwayland_view { struct wl_listener set_override_redirect; struct wl_listener set_strut_partial; struct wl_listener set_window_type; + struct wl_listener set_icon; struct wl_listener focus_in; /* Not (yet) implemented */ diff --git a/src/xwayland.c b/src/xwayland.c index 263833ff..90eec6b3 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -26,13 +26,11 @@ #include "workspaces.h" enum atoms { - ATOM_NET_WM_ICON = 0, ATOM_COUNT, }; static const char * const atom_names[] = { - [ATOM_NET_WM_ICON] = "_NET_WM_ICON", }; static_assert(ARRAY_SIZE(atom_names) == ATOM_COUNT, "atom names out of sync"); @@ -448,6 +446,7 @@ handle_destroy(struct wl_listener *listener, void *data) wl_list_remove(&xwayland_view->set_override_redirect.link); wl_list_remove(&xwayland_view->set_strut_partial.link); wl_list_remove(&xwayland_view->set_window_type.link); + wl_list_remove(&xwayland_view->set_icon.link); wl_list_remove(&xwayland_view->focus_in.link); wl_list_remove(&xwayland_view->on_view.always_on_top.link); @@ -670,29 +669,20 @@ handle_set_strut_partial(struct wl_listener *listener, void *data) } static void -update_icon(struct xwayland_view *xwayland_view) +handle_set_icon(struct wl_listener *listener, void *data) { - if (!xwayland_view->xwayland_surface) { - return; - } + struct xwayland_view *xwayland_view = + wl_container_of(listener, xwayland_view, set_icon); - xcb_window_t window_id = xwayland_view->xwayland_surface->window_id; - - xcb_connection_t *xcb_conn = wlr_xwayland_get_xwm_connection(server.xwayland); - xcb_get_property_cookie_t cookie = xcb_get_property(xcb_conn, 0, - window_id, atoms[ATOM_NET_WM_ICON], XCB_ATOM_CARDINAL, 0, 0x10000); - xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_conn, cookie, NULL); - if (!reply) { - return; - } - xcb_ewmh_get_wm_icon_reply_t icon; - if (!xcb_ewmh_get_wm_icon_from_reply(&icon, reply)) { + xcb_ewmh_get_wm_icon_reply_t icon_reply = {0}; + if (!wlr_xwayland_surface_fetch_icon(xwayland_view->xwayland_surface, + &icon_reply)) { wlr_log(WLR_INFO, "Invalid x11 icon"); view_set_icon(&xwayland_view->base, NULL, NULL); goto out; } - xcb_ewmh_wm_icon_iterator_t iter = xcb_ewmh_get_wm_icon_iterator(&icon); + xcb_ewmh_wm_icon_iterator_t iter = xcb_ewmh_get_wm_icon_iterator(&icon_reply); struct wl_array buffers; wl_array_init(&buffers); for (; iter.rem; xcb_ewmh_get_wm_icon_next(&iter)) { @@ -722,7 +712,7 @@ update_icon(struct xwayland_view *xwayland_view) wl_array_release(&buffers); out: - free(reply); + xcb_ewmh_get_wm_icon_reply_wipe(&icon_reply); } static void @@ -1051,6 +1041,7 @@ xwayland_view_create(struct wlr_xwayland_surface *xsurface, bool mapped) CONNECT_SIGNAL(xsurface, xwayland_view, set_override_redirect); CONNECT_SIGNAL(xsurface, xwayland_view, set_strut_partial); CONNECT_SIGNAL(xsurface, xwayland_view, set_window_type); + CONNECT_SIGNAL(xsurface, xwayland_view, set_icon); CONNECT_SIGNAL(xsurface, xwayland_view, focus_in); /* Events from the view itself */ @@ -1064,13 +1055,10 @@ xwayland_view_create(struct wlr_xwayland_surface *xsurface, bool mapped) /* * If a surface is already associated, then we've * missed the various initial set_* events as well. - * - * TODO: update_icon() -> handle_set_icon() after - * https://github.com/labwc/labwc/pull/2760 */ handle_set_title(&view->set_title, NULL); handle_set_class(&xwayland_view->set_class, NULL); - update_icon(xwayland_view); + handle_set_icon(&xwayland_view->set_icon, NULL); } if (mapped) { handle_map(&xwayland_view->base.mappable.map, NULL); @@ -1117,16 +1105,6 @@ handle_x11_event(struct wlr_xwayland *wlr_xwayland, xcb_generic_event_t *event) switch (event->response_type & XCB_EVENT_RESPONSE_TYPE_MASK) { case XCB_PROPERTY_NOTIFY: { xcb_property_notify_event_t *ev = (void *)event; - if (ev->atom == atoms[ATOM_NET_WM_ICON]) { - struct xwayland_view *xwayland_view = - xwayland_view_from_window_id(ev->window); - if (xwayland_view) { - update_icon(xwayland_view); - } else { - wlr_log(WLR_DEBUG, "icon property changed for unknown window"); - } - return true; - } break; } default: From 3128f50a250edd5cc6902173e8220479aec8a26e Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Mon, 30 Mar 2026 18:33:58 +0900 Subject: [PATCH 052/146] xwayland: remove atom synchronization It was used to get window icon via _NET_WM_ICON, which is now implemented by wlroots 0.20. Anyone who needs another atom can revert this commit and add atoms in the `atoms` array. --- src/xwayland.c | 84 -------------------------------------------------- 1 file changed, 84 deletions(-) diff --git a/src/xwayland.c b/src/xwayland.c index 90eec6b3..967364c5 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -25,18 +25,6 @@ #include "window-rules.h" #include "workspaces.h" -enum atoms { - - ATOM_COUNT, -}; - -static const char * const atom_names[] = { -}; - -static_assert(ARRAY_SIZE(atom_names) == ATOM_COUNT, "atom names out of sync"); - -static xcb_atom_t atoms[ATOM_COUNT] = {0}; - static void set_surface(struct view *view, struct wlr_surface *surface); static void handle_map(struct wl_listener *listener, void *data); static void handle_unmap(struct wl_listener *listener, void *data); @@ -1081,81 +1069,11 @@ handle_new_surface(struct wl_listener *listener, void *data) } } -static struct xwayland_view * -xwayland_view_from_window_id(xcb_window_t id) -{ - struct view *view; - wl_list_for_each(view, &server.views, link) { - if (view->type != LAB_XWAYLAND_VIEW) { - continue; - } - struct xwayland_view *xwayland_view = xwayland_view_from_view(view); - if (xwayland_view->xwayland_surface - && xwayland_view->xwayland_surface->window_id == id) { - return xwayland_view; - } - } - return NULL; -} - -#define XCB_EVENT_RESPONSE_TYPE_MASK 0x7f -static bool -handle_x11_event(struct wlr_xwayland *wlr_xwayland, xcb_generic_event_t *event) -{ - switch (event->response_type & XCB_EVENT_RESPONSE_TYPE_MASK) { - case XCB_PROPERTY_NOTIFY: { - xcb_property_notify_event_t *ev = (void *)event; - break; - } - default: - break; - } - - return false; -} - -static void -sync_atoms(void) -{ - xcb_connection_t *xcb_conn = - wlr_xwayland_get_xwm_connection(server.xwayland); - assert(xcb_conn); - - wlr_log(WLR_DEBUG, "Syncing X11 atoms"); - xcb_intern_atom_cookie_t cookies[ATOM_COUNT]; - - /* First request everything and then loop over the results to reduce latency */ - for (size_t i = 0; i < ATOM_COUNT; i++) { - cookies[i] = xcb_intern_atom(xcb_conn, 0, - strlen(atom_names[i]), atom_names[i]); - } - - for (size_t i = 0; i < ATOM_COUNT; i++) { - xcb_generic_error_t *err = NULL; - xcb_intern_atom_reply_t *reply = - xcb_intern_atom_reply(xcb_conn, cookies[i], &err); - if (reply) { - atoms[i] = reply->atom; - wlr_log(WLR_DEBUG, "Got X11 atom for %s: %u", - atom_names[i], reply->atom); - } - if (err) { - atoms[i] = XCB_ATOM_NONE; - wlr_log(WLR_INFO, "Failed to get X11 atom for %s", - atom_names[i]); - } - free(reply); - free(err); - } -} - static void handle_server_ready(struct wl_listener *listener, void *data) { /* Fire an Xwayland startup script if one (or many) can be found */ session_run_script("xinitrc"); - - sync_atoms(); } static void @@ -1188,8 +1106,6 @@ xwayland_server_init(struct wlr_compositor *compositor) wl_signal_add(&server.xwayland->events.ready, &server.xwayland_xwm_ready); - server.xwayland->user_event_handler = handle_x11_event; - if (setenv("DISPLAY", server.xwayland->display_name, true) < 0) { wlr_log_errno(WLR_ERROR, "unable to set DISPLAY for xwayland"); } else { From 862d230ff94137c0d0cbb4ddee8e61b6fbabe260 Mon Sep 17 00:00:00 2001 From: GlassOnTin Date: Mon, 30 Mar 2026 11:55:49 +0100 Subject: [PATCH 053/146] Make labnag a meson feature flag Add a 'labnag' meson option (default: auto) to allow disabling the labnag notification daemon at build time. This is useful for embedded/headless deployments (e.g. Android) where labnag is not needed, and avoids building its wayland-client dependencies. Disable with: meson setup build -Dlabnag=disabled --- clients/meson.build | 106 ++++++++++++++++++++++---------------------- meson_options.txt | 1 + 2 files changed, 55 insertions(+), 52 deletions(-) diff --git a/clients/meson.build b/clients/meson.build index 467bc035..55a4c0e5 100644 --- a/clients/meson.build +++ b/clients/meson.build @@ -1,59 +1,61 @@ -wayland_client = dependency('wayland-client') -wayland_cursor = dependency('wayland-cursor') +if get_option('labnag').allowed() + wayland_client = dependency('wayland-client') + wayland_cursor = dependency('wayland-cursor') -nag_sources = files( - 'labnag.c', - 'pool-buffer.c', -) - -wl_protocol_dir = wayland_protos.get_variable('pkgdatadir') - -protocols = [ - wl_protocol_dir / 'stable/tablet/tablet-v2.xml', - wl_protocol_dir / 'stable/xdg-shell/xdg-shell.xml', - wl_protocol_dir / 'staging/cursor-shape/cursor-shape-v1.xml', - '../protocols/wlr-layer-shell-unstable-v1.xml', -] - -foreach xml : protocols - nag_sources += custom_target( - xml.underscorify() + '_c', - input: xml, - output: '@BASENAME@-protocol.c', - command: [wayland_scanner, 'private-code', '@INPUT@', '@OUTPUT@'], + nag_sources = files( + 'labnag.c', + 'pool-buffer.c', ) - nag_sources += custom_target( - xml.underscorify() + '_client_h', - input: xml, - output: '@BASENAME@-client-protocol.h', - command: [wayland_scanner, 'client-header', '@INPUT@', '@OUTPUT@'], - ) -endforeach -if host_machine.system() in ['freebsd', 'openbsd'] - # For signalfd() - epoll_dep = dependency('epoll-shim') -else - epoll_dep = [] + wl_protocol_dir = wayland_protos.get_variable('pkgdatadir') + + protocols = [ + wl_protocol_dir / 'stable/tablet/tablet-v2.xml', + wl_protocol_dir / 'stable/xdg-shell/xdg-shell.xml', + wl_protocol_dir / 'staging/cursor-shape/cursor-shape-v1.xml', + '../protocols/wlr-layer-shell-unstable-v1.xml', + ] + + foreach xml : protocols + nag_sources += custom_target( + xml.underscorify() + '_c', + input: xml, + output: '@BASENAME@-protocol.c', + command: [wayland_scanner, 'private-code', '@INPUT@', '@OUTPUT@'], + ) + nag_sources += custom_target( + xml.underscorify() + '_client_h', + input: xml, + output: '@BASENAME@-client-protocol.h', + command: [wayland_scanner, 'client-header', '@INPUT@', '@OUTPUT@'], + ) + endforeach + + if host_machine.system() in ['freebsd', 'openbsd'] + # For signalfd() + epoll_dep = dependency('epoll-shim') + else + epoll_dep = [] + endif + + executable( + 'labnag', + nag_sources, + dependencies: [ + cairo, + pangocairo, + glib, + wayland_client, + wayland_cursor, + wlroots, + server_protos, + epoll_dep, + xkbcommon, + ], + include_directories: [labwc_inc], + install: true, + ) endif -executable( - 'labnag', - nag_sources, - dependencies: [ - cairo, - pangocairo, - glib, - wayland_client, - wayland_cursor, - wlroots, - server_protos, - epoll_dep, - xkbcommon, - ], - include_directories: [labwc_inc], - install: true, -) - clients = files('lab-sensible-terminal') install_data(clients, install_dir: get_option('bindir')) diff --git a/meson_options.txt b/meson_options.txt index a3da65a8..a47efa86 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -2,6 +2,7 @@ option('man-pages', type: 'feature', value: 'auto', description: 'Generate and i option('xwayland', type: 'feature', value: 'auto', description: 'Enable support for X11 applications') option('svg', type: 'feature', value: 'enabled', description: 'Enable svg window buttons') option('icon', type: 'feature', value: 'enabled', description: 'Enable window icons') +option('labnag', type: 'feature', value: 'auto', description: 'Build labnag notification daemon') option('nls', type: 'feature', value: 'auto', description: 'Enable native language support') option('static_analyzer', type: 'feature', value: 'disabled', description: 'Run gcc static analyzer') option('test', type: 'feature', value: 'disabled', description: 'Run tests') From 9a8154836c04765e209f77bd1e3810e2a4818324 Mon Sep 17 00:00:00 2001 From: GlassOnTin Date: Mon, 30 Mar 2026 11:56:31 +0100 Subject: [PATCH 054/146] keyboard: use XKB_CONTEXT_NO_SECURE_GETENV on Android Android's bionic libc implements secure_getenv() as a function that always returns NULL because app processes don't have AT_SECURE set. This prevents xkbcommon from reading XKB_DEFAULT_LAYOUT and other environment variables when resolving keyboard layouts. Use XKB_CONTEXT_NO_SECURE_GETENV on Android so xkbcommon falls back to regular getenv(), which works correctly in the Android app environment. --- src/input/keyboard.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/input/keyboard.c b/src/input/keyboard.c index 8e5c1f78..5a5c7595 100644 --- a/src/input/keyboard.c +++ b/src/input/keyboard.c @@ -745,7 +745,18 @@ set_layout(struct wlr_keyboard *kb) static bool fallback_mode; struct xkb_rule_names rules = { 0 }; - struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + enum xkb_context_flags ctx_flags = XKB_CONTEXT_NO_FLAGS; +#ifdef __ANDROID__ + /* + * Android's bionic libc implements secure_getenv() as a function + * that always returns NULL (the app process has no AT_SECURE). + * This prevents xkbcommon from reading XKB_DEFAULT_LAYOUT and + * friends via secure_getenv(). Use the flag to fall back to + * regular getenv() which works fine on Android. + */ + ctx_flags |= XKB_CONTEXT_NO_SECURE_GETENV; +#endif + struct xkb_context *context = xkb_context_new(ctx_flags); struct xkb_keymap *keymap = xkb_map_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); From 46d687ab5414f2bd2d55db49be14601054d2fe75 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Mon, 30 Mar 2026 22:04:01 +0100 Subject: [PATCH 055/146] clients/labnag.c: return zero on get_text_size() error Ref: https://github.com/swaywm/sway/pull/9070 --- clients/labnag.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/clients/labnag.c b/clients/labnag.c index 237ee958..82b6e8cd 100644 --- a/clients/labnag.c +++ b/clients/labnag.c @@ -206,6 +206,16 @@ static void get_text_size(cairo_t *cairo, const PangoFontDescription *desc, int *width, int *height, int *baseline, double scale, bool markup, const char *fmt, ...) { + if (width) { + *width = 0; + } + if (height) { + *height = 0; + } + if (baseline) { + *baseline = 0; + } + va_list args; va_start(args, fmt); gchar *buf = g_strdup_vprintf(fmt, args); From 9209f611d552adbb36e59cef05aaca5d1e834efe Mon Sep 17 00:00:00 2001 From: Jens Peters Date: Tue, 31 Mar 2026 19:17:33 +0200 Subject: [PATCH 056/146] build: require libinput 1.26 Bump the requirement for having support for tablet tool pressure range configuration. --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 4b622b5e..de73e8ea 100644 --- a/meson.build +++ b/meson.build @@ -71,7 +71,7 @@ xml2 = dependency('libxml-2.0') glib = dependency('glib-2.0') cairo = dependency('cairo') pangocairo = dependency('pangocairo') -input = dependency('libinput', version: '>=1.14') +input = dependency('libinput', version: '>=1.26') pixman = dependency('pixman-1') math = cc.find_library('m') png = dependency('libpng') From 0d049552bc98a59db7c0cc62f673a83c0de67b0c Mon Sep 17 00:00:00 2001 From: Jens Peters Date: Sun, 13 Jul 2025 21:38:00 +0200 Subject: [PATCH 057/146] input: support tablet tool pressure range configuration Needs wlroots 0.20.0. --- include/config/rcxml.h | 2 ++ src/config/rcxml.c | 8 ++++++++ src/input/tablet.c | 23 +++++++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/include/config/rcxml.h b/include/config/rcxml.h index aa950234..517cd907 100644 --- a/include/config/rcxml.h +++ b/include/config/rcxml.h @@ -144,6 +144,8 @@ struct rcxml { struct tablet_tool_config { enum lab_motion motion; double relative_motion_sensitivity; + double min_pressure; + double max_pressure; } tablet_tool; /* libinput */ diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 45093781..a3eeed63 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -1355,6 +1355,12 @@ entry(xmlNode *node, char *nodename, char *content) } else if (!strcasecmp(nodename, "relativeMotionSensitivity.tabletTool")) { rc.tablet_tool.relative_motion_sensitivity = tablet_get_dbl_if_positive(content, "relativeMotionSensitivity"); + } else if (!strcasecmp(nodename, "minPressure.tabletTool")) { + rc.tablet_tool.min_pressure = + tablet_get_dbl_if_positive(content, "minPressure"); + } else if (!strcasecmp(nodename, "maxPressure.tabletTool")) { + rc.tablet_tool.max_pressure = + tablet_get_dbl_if_positive(content, "maxPressure"); } else if (!strcasecmp(nodename, "ignoreButtonReleasePeriod.menu")) { rc.menu_ignore_button_release_period = atoi(content); } else if (!strcasecmp(nodename, "showIcons.menu")) { @@ -1475,6 +1481,8 @@ rcxml_init(void) tablet_load_default_button_mappings(); rc.tablet_tool.motion = LAB_MOTION_ABSOLUTE; rc.tablet_tool.relative_motion_sensitivity = 1.0; + rc.tablet_tool.min_pressure = 0.0; + rc.tablet_tool.max_pressure = 1.0; rc.repeat_rate = 25; rc.repeat_delay = 600; diff --git a/src/input/tablet.c b/src/input/tablet.c index ed596e15..a4ca0fab 100644 --- a/src/input/tablet.c +++ b/src/input/tablet.c @@ -2,11 +2,13 @@ #include "input/tablet.h" #include #include +#include "wlr/backend/libinput.h" #include #include #include #include #include +#include #include "common/macros.h" #include "common/mem.h" #include "common/scene-helpers.h" @@ -336,6 +338,27 @@ handle_tablet_tool_proximity(struct wl_listener *listener, void *data) tool = tablet_tool_create(tablet->seat, ev->tool); } + struct libinput_tablet_tool *libinput_tool = + wlr_libinput_get_tablet_tool_handle(tool->tool_v2->wlr_tool); + + /* + * Configure tool pressure range using libinput. Note that a runtime change + * needs two proximity-in events. First one is for applying the pressure range + * here and second one until it is effectively applied, probably because of + * how lininput applies pressure range changes internally. + */ + if (libinput_tablet_tool_config_pressure_range_is_available(libinput_tool) > 0 + && rc.tablet_tool.min_pressure >= 0.0 + && rc.tablet_tool.max_pressure <= 1.0) { + double min = libinput_tablet_tool_config_pressure_range_get_minimum(libinput_tool); + double max = libinput_tablet_tool_config_pressure_range_get_maximum(libinput_tool); + if (min != rc.tablet_tool.min_pressure || max != rc.tablet_tool.max_pressure) { + wlr_log(WLR_INFO, "tablet tool pressure range configured"); + libinput_tablet_tool_config_pressure_range_set(libinput_tool, + rc.tablet_tool.min_pressure, rc.tablet_tool.max_pressure); + } + } + /* * Enforce mouse emulation when the current tool is a tablet mouse. * Client support for tablet mouses in tablet mode is often incomplete From 674238caa9d56a623c3a0182a1aca75065f97cdd Mon Sep 17 00:00:00 2001 From: Jens Peters Date: Mon, 14 Jul 2025 21:50:32 +0200 Subject: [PATCH 058/146] docs: document tablet tool pressure range --- docs/labwc-config.5.scd | 13 ++++++++++++- docs/rc.xml.all | 5 ++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index 03d5fc24..09f7b3eb 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -1090,7 +1090,8 @@ Note: To rotate touch events with output rotation, use the libinput ## TABLET TOOL ``` - + ``` ** [absolute|relative] @@ -1105,6 +1106,16 @@ Note: To rotate touch events with output rotation, use the libinput speed, using a value greater than 1.0 increases the speed of the cursor. The default is "1.0". +** +** + The pressure range of a tablet tool can be controlled by adjusting + *minPressure* and *maxPressure*. Setting the minimum pressure to + a value greater than zero requires more pressure for the tip + threshold, setting the maximum pressure to a value less than 1.0 + requires less pressure for the user before the maximum is reached. + The default is 0 for the minimum pressure and 1.0 for the maximum + pressure. + ## LIBINPUT ``` diff --git a/docs/rc.xml.all b/docs/rc.xml.all index bc9566fe..bbec9d0b 100644 --- a/docs/rc.xml.all +++ b/docs/rc.xml.all @@ -573,8 +573,11 @@ *relativeMotionSensitivity* controls the speed of the cursor. Using a value lower than 1.0 decreases the speed, using a value greater than 1.0 increases the speed of the cursor. + The pressure range of a tablet tool can be controlled by adjusting + *minPressure* and *maxPressure*. --> - + diff --git a/include/config/default-bindings.h b/include/config/default-bindings.h index 9d42d237..f2042c28 100644 --- a/include/config/default-bindings.h +++ b/include/config/default-bindings.h @@ -84,35 +84,35 @@ static struct key_combos { .value = "no", }, }, { - .binding = "XF86_AudioLowerVolume", + .binding = "XF86AudioLowerVolume", .action = "Execute", .attributes[0] = { .name = "command", .value = "amixer sset Master 5%-", }, }, { - .binding = "XF86_AudioRaiseVolume", + .binding = "XF86AudioRaiseVolume", .action = "Execute", .attributes[0] = { .name = "command", .value = "amixer sset Master 5%+", }, }, { - .binding = "XF86_AudioMute", + .binding = "XF86AudioMute", .action = "Execute", .attributes[0] = { .name = "command", .value = "amixer sset Master toggle", }, }, { - .binding = "XF86_MonBrightnessUp", + .binding = "XF86MonBrightnessUp", .action = "Execute", .attributes[0] = { .name = "command", .value = "brightnessctl set +10%", }, }, { - .binding = "XF86_MonBrightnessDown", + .binding = "XF86MonBrightnessDown", .action = "Execute", .attributes[0] = { .name = "command", From 3ec20044b5d435a801c4c79b5b7b09619a64cd9e Mon Sep 17 00:00:00 2001 From: Manuel Barrio Linares Date: Tue, 2 Dec 2025 17:44:54 -0300 Subject: [PATCH 071/146] server: add support for color-management-v1 and color-representation-manager-v1 --- src/server.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/server.c b/src/server.c index fd48efed..78aa26a7 100644 --- a/src/server.c +++ b/src/server.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include #include #include @@ -285,6 +287,8 @@ allow_for_sandbox(const struct wlr_security_context_v1_state *security_state, "xdg_wm_dialog_v1", /* plus */ "wp_alpha_modifier_v1", + "wp_color_manager_v1", + "wp_color_representation_manager_v1", "wp_linux_drm_syncobj_manager_v1", "zxdg_exporter_v1", "zxdg_exporter_v2", @@ -592,6 +596,47 @@ server_init(void) * | output->layer_tree[0] | background layer surfaces (e.g. swaybg) */ + if (server.renderer->features.input_color_transform) { + const enum wp_color_manager_v1_render_intent render_intents[] = { + WP_COLOR_MANAGER_V1_RENDER_INTENT_PERCEPTUAL, + }; + size_t transfer_functions_len = 0; + enum wp_color_manager_v1_transfer_function *transfer_functions = + wlr_color_manager_v1_transfer_function_list_from_renderer( + server.renderer, &transfer_functions_len); + + size_t primaries_len = 0; + enum wp_color_manager_v1_primaries *primaries = + wlr_color_manager_v1_primaries_list_from_renderer( + server.renderer, &primaries_len); + + struct wlr_color_manager_v1 *cm = wlr_color_manager_v1_create( + server.wl_display, 2, &(struct wlr_color_manager_v1_options){ + .features = { + .parametric = true, + .set_mastering_display_primaries = true, + }, + .render_intents = render_intents, + .render_intents_len = ARRAY_SIZE(render_intents), + .transfer_functions = transfer_functions, + .transfer_functions_len = transfer_functions_len, + .primaries = primaries, + .primaries_len = primaries_len, + }); + + free(transfer_functions); + free(primaries); + + if (cm) { + wlr_scene_set_color_manager_v1(server.scene, cm); + } else { + wlr_log(WLR_ERROR, "unable to create color manager"); + } + } + + wlr_color_representation_manager_v1_create_with_renderer( + server.wl_display, 1, server.renderer); + server.workspace_tree = lab_wlr_scene_tree_create(&server.scene->tree); server.xdg_popup_tree = lab_wlr_scene_tree_create(&server.scene->tree); #if HAVE_XWAYLAND From c4fd916fd3aa13cb21d8de08a7da8f1bbde5246e Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 31 Mar 2026 10:01:21 +0200 Subject: [PATCH 072/146] Translation updates from weblate Co-authored-by: ButterflyOfFire Co-authored-by: Weblate Translate-URL: https://translate.lxqt-project.org/projects/labwc/labwc/kab/ Translation: Labwc/labwc --- po/LINGUAS | 2 +- po/kab.po | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 po/kab.po diff --git a/po/LINGUAS b/po/LINGUAS index 33f036c9..70114b72 100644 --- a/po/LINGUAS +++ b/po/LINGUAS @@ -1 +1 @@ -ar ca cs da de el es et eu fa fi fr gl he hr hu id it ja ka kk ko lt ms nl pa pl pt pt_BR ru sk sv tr uk vi zh_CN zh_TW +ar ca cs da de el es et eu fa fi fr gl he hr hu id it ja ka kab kk ko lt ms nl pa pl pt pt_BR ru sk sv tr uk vi zh_CN zh_TW diff --git a/po/kab.po b/po/kab.po new file mode 100644 index 00000000..44961f47 --- /dev/null +++ b/po/kab.po @@ -0,0 +1,80 @@ +# Labwc pot file +# Copyright (C) 2024 +# This file is distributed under the same license as the labwc package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: labwc\n" +"Report-Msgid-Bugs-To: https://github.com/labwc/labwc/issues\n" +"POT-Creation-Date: 2024-09-19 21:09+1000\n" +"PO-Revision-Date: 2026-03-31 08:01+0000\n" +"Last-Translator: ButterflyOfFire \n" +"Language-Team: Kabyle \n" +"Language: kab\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 4.2.1\n" + +#: src/menu/menu.c:1016 +msgid "Go there..." +msgstr "" + +#: src/menu/menu.c:1034 +msgid "Terminal" +msgstr "Ixf" + +#: src/menu/menu.c:1040 +msgid "Reconfigure" +msgstr "" + +#: src/menu/menu.c:1042 +msgid "Exit" +msgstr "Ffeɣ" + +#: src/menu/menu.c:1056 +msgid "Minimize" +msgstr "" + +#: src/menu/menu.c:1058 +msgid "Maximize" +msgstr "" + +#: src/menu/menu.c:1060 +msgid "Fullscreen" +msgstr "Agdil aččuran" + +#: src/menu/menu.c:1062 +msgid "Roll Up/Down" +msgstr "" + +#: src/menu/menu.c:1064 +msgid "Decorations" +msgstr "" + +#: src/menu/menu.c:1066 +msgid "Always on Top" +msgstr "" + +#: src/menu/menu.c:1071 +msgid "Move Left" +msgstr "" + +#: src/menu/menu.c:1078 +msgid "Move Right" +msgstr "" + +#: src/menu/menu.c:1083 +msgid "Always on Visible Workspace" +msgstr "" + +#: src/menu/menu.c:1086 +msgid "Workspace" +msgstr "" + +#: src/menu/menu.c:1089 +msgid "Close" +msgstr "Mdel" From c8bb3381a4fdd5d303e3a173d4216eaa283fdce8 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Mon, 6 Apr 2026 21:57:24 +0100 Subject: [PATCH 073/146] Add key state OSD for debugging Add action `DebugToggleKeyStateIndicator` to show in the top-left corner the pressed, bound, pressed-sent keys as well as modifiers. This should help fault find issues like #2771 and #3238 Based-on: #3262 Co-authored-by: @tokyo4j --- docs/labwc-actions.5.scd | 4 + include/input/key-state.h | 5 ++ src/action.c | 7 +- src/input/key-state.c | 161 ++++++++++++++++++++++++++++++++++++++ src/input/keyboard.c | 5 ++ 5 files changed, 181 insertions(+), 1 deletion(-) diff --git a/docs/labwc-actions.5.scd b/docs/labwc-actions.5.scd index fe468cd1..a70c0086 100644 --- a/docs/labwc-actions.5.scd +++ b/docs/labwc-actions.5.scd @@ -436,6 +436,10 @@ Actions are used in menus and keyboard/mouse bindings. If used as the only action for a binding: clear an earlier defined binding. +** + Toggle visibility of key-state on-screen display (OSD). Note: This is for + debugging purposes only. + # CONDITIONAL ACTIONS Actions that execute other actions. Used in keyboard/mouse bindings. diff --git a/include/input/key-state.h b/include/input/key-state.h index d9971b74..81374b6c 100644 --- a/include/input/key-state.h +++ b/include/input/key-state.h @@ -5,12 +5,17 @@ #include #include +struct seat; + /* * All keycodes in these functions are (Linux) libinput evdev scancodes which is * what 'wlr_keyboard' uses (e.g. 'seat->keyboard_group->keyboard->keycodes'). * Note: These keycodes are different to XKB scancodes by a value of 8. */ +void key_state_indicator_update(struct seat *seat); +void key_state_indicator_toggle(void); + /** * key_state_pressed_sent_keycodes - generate array of pressed+sent keys * Note: The array is generated by subtracting any bound keys from _all_ pressed diff --git a/src/action.c b/src/action.c index 66fa9b20..2cfa6be6 100644 --- a/src/action.c +++ b/src/action.c @@ -21,6 +21,7 @@ #include "cycle.h" #include "debug.h" #include "input/keyboard.h" +#include "input/key-state.h" #include "labwc.h" #include "magnifier.h" #include "menu/menu.h" @@ -133,7 +134,8 @@ struct action_arg_list { X(ZOOM_IN, "ZoomIn") \ X(ZOOM_OUT, "ZoomOut") \ X(WARP_CURSOR, "WarpCursor") \ - X(HIDE_CURSOR, "HideCursor") + X(HIDE_CURSOR, "HideCursor") \ + X(DEBUG_TOGGLE_KEY_STATE_INDICATOR, "DebugToggleKeyStateIndicator") /* * Will expand to: @@ -1570,6 +1572,9 @@ run_action(struct view *view, struct action *action, case ACTION_TYPE_HIDE_CURSOR: cursor_set_visible(&server.seat, false); break; + case ACTION_TYPE_DEBUG_TOGGLE_KEY_STATE_INDICATOR: + key_state_indicator_toggle(); + break; case ACTION_TYPE_INVALID: wlr_log(WLR_ERROR, "Not executing unknown action"); break; diff --git a/src/input/key-state.c b/src/input/key-state.c index 492f7b0f..6d089891 100644 --- a/src/input/key-state.c +++ b/src/input/key-state.c @@ -4,10 +4,171 @@ #include #include #include +#include +#include +#include +#include "config/rcxml.h" +#include "common/buf.h" #include "common/set.h" +#include "input/keyboard.h" +#include "labwc.h" +#include "scaled-buffer/scaled-font-buffer.h" static struct lab_set pressed, bound, pressed_sent; +static bool show_debug_indicator; +static struct indicator_state { + struct wlr_scene_tree *tree; + struct scaled_font_buffer *sfb_pressed; + struct scaled_font_buffer *sfb_bound; + struct scaled_font_buffer *sfb_pressed_sent; + struct scaled_font_buffer *sfb_modifiers; + struct xkb_keymap *keymap; +} indicator_state; + +static const char * +keycode_to_keyname(struct xkb_keymap *keymap, uint32_t keycode) +{ + const xkb_keysym_t *syms; + int syms_len = xkb_keymap_key_get_syms_by_level(keymap, keycode + 8, 0, 0, &syms); + if (!syms_len) { + return NULL; + } + + static char buf[256]; + if (!xkb_keysym_get_name(syms[0], buf, sizeof(buf))) { + return NULL; + } + + return buf; +} + +static const char * +modifier_to_name(uint32_t modifier) +{ + switch (modifier) { + case WLR_MODIFIER_SHIFT: + return "S"; + case WLR_MODIFIER_CAPS: + return "caps"; + case WLR_MODIFIER_CTRL: + return "C"; + case WLR_MODIFIER_ALT: + return "A"; + case WLR_MODIFIER_MOD2: + return "numlock"; + case WLR_MODIFIER_MOD3: + return "H"; + case WLR_MODIFIER_LOGO: + return "W"; + case WLR_MODIFIER_MOD5: + return "M"; + default: + return "?"; + } +} + +static void +init_indicator(struct indicator_state *state) +{ + state->tree = wlr_scene_tree_create(&server.scene->tree); + wlr_scene_node_set_enabled(&state->tree->node, false); + + state->sfb_pressed = scaled_font_buffer_create(state->tree); + wlr_scene_node_set_position(&state->sfb_pressed->scene_buffer->node, 0, 0); + state->sfb_bound = scaled_font_buffer_create(state->tree); + wlr_scene_node_set_position(&state->sfb_bound->scene_buffer->node, 0, 20); + state->sfb_pressed_sent = scaled_font_buffer_create(state->tree); + wlr_scene_node_set_position(&state->sfb_pressed_sent->scene_buffer->node, 0, 40); + state->sfb_modifiers = scaled_font_buffer_create(state->tree); + wlr_scene_node_set_position(&state->sfb_modifiers->scene_buffer->node, 0, 60); + + struct xkb_rule_names rules = { 0 }; + struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + state->keymap = xkb_map_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); +} + +static void +update_key_indicator_callback(void *data) +{ + struct seat *seat = data; + uint32_t all_modifiers = keyboard_get_all_modifiers(seat); + float black[4] = {0, 0, 0, 1}; + float white[4] = {1, 1, 1, 1}; + + if (!indicator_state.tree) { + init_indicator(&indicator_state); + } + + if (show_debug_indicator) { + wlr_scene_node_set_enabled(&indicator_state.tree->node, true); + } else { + wlr_scene_node_set_enabled(&indicator_state.tree->node, false); + return; + } + + struct buf buf = BUF_INIT; + + buf_add(&buf, "pressed="); + for (int i = 0; i < pressed.size; i++) { + const char *keyname = keycode_to_keyname(indicator_state.keymap, + pressed.values[i]); + buf_add_fmt(&buf, "%s (%d), ", keyname, pressed.values[i]); + } + scaled_font_buffer_update(indicator_state.sfb_pressed, buf.data, + -1, &rc.font_osd, black, white); + + buf_clear(&buf); + buf_add(&buf, "bound="); + for (int i = 0; i < bound.size; i++) { + const char *keyname = keycode_to_keyname(indicator_state.keymap, + bound.values[i]); + buf_add_fmt(&buf, "%s (%d), ", keyname, bound.values[i]); + } + scaled_font_buffer_update(indicator_state.sfb_bound, buf.data, + -1, &rc.font_osd, black, white); + + buf_clear(&buf); + buf_add(&buf, "pressed_sent="); + for (int i = 0; i < pressed_sent.size; i++) { + const char *keyname = keycode_to_keyname(indicator_state.keymap, + pressed_sent.values[i]); + buf_add_fmt(&buf, "%s (%d), ", keyname, pressed_sent.values[i]); + } + scaled_font_buffer_update(indicator_state.sfb_pressed_sent, buf.data, -1, + &rc.font_osd, black, white); + + buf_clear(&buf); + buf_add(&buf, "modifiers="); + for (int i = 0; i <= 7; i++) { + uint32_t mod = 1 << i; + if (all_modifiers & mod) { + buf_add_fmt(&buf, "%s, ", modifier_to_name(mod)); + } + } + buf_add_fmt(&buf, "(%d)", all_modifiers); + scaled_font_buffer_update(indicator_state.sfb_modifiers, buf.data, -1, + &rc.font_osd, black, white); + + buf_reset(&buf); +} + +void +key_state_indicator_update(struct seat *seat) +{ + if (!show_debug_indicator) { + return; + } + wl_event_loop_add_idle(server.wl_event_loop, + update_key_indicator_callback, seat); +} + +void +key_state_indicator_toggle(void) +{ + show_debug_indicator = !show_debug_indicator; +} + static void report(struct lab_set *key_set, const char *msg) { diff --git a/src/input/keyboard.c b/src/input/keyboard.c index 2d4bde6e..9d8e840d 100644 --- a/src/input/keyboard.c +++ b/src/input/keyboard.c @@ -139,6 +139,8 @@ handle_modifiers(struct wl_listener *listener, void *data) struct seat *seat = keyboard->base.seat; struct wlr_keyboard *wlr_keyboard = keyboard->wlr_keyboard; + key_state_indicator_update(seat); + if (server.input_mode == LAB_INPUT_STATE_MOVE) { /* Any change to the modifier state re-enable region snap */ seat->region_prevent_snap = false; @@ -622,6 +624,9 @@ handle_key(struct wl_listener *listener, void *data) struct seat *seat = keyboard->base.seat; struct wlr_keyboard_key_event *event = data; struct wlr_seat *wlr_seat = seat->wlr_seat; + + key_state_indicator_update(seat); + idle_manager_notify_activity(seat->wlr_seat); /* any new press/release cancels current keybind repeat */ From 8b32422b93d0389bb2cad42376890b4270fddad6 Mon Sep 17 00:00:00 2001 From: Tobias Bengfort Date: Fri, 3 Apr 2026 20:38:21 +0200 Subject: [PATCH 074/146] rcxml: allow to restrict privileged interfaces --- docs/labwc-config.5.scd | 46 +++++++++++++++++++++++++++++++++++++++ include/config/rcxml.h | 3 +++ src/config/rcxml.c | 48 +++++++++++++++++++++++++++++++++++++++++ src/server.c | 42 ++++++------------------------------ 4 files changed, 104 insertions(+), 35 deletions(-) diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index 09f7b3eb..061e57ad 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -1445,6 +1445,52 @@ situation. Whether to apply a bilinear filter to the magnified image, or just to use nearest-neighbour. Default is true - bilinear filtered. +## PRIVILEGED INTERFACES + +Labwc supports a small set of privileged wayland interfaces. All of these +interfaces are enabled by default for applications unless they are running +via a sandbox environment supporting the security-context-v1 protocol. + +Security conscious users are suggested to use a sandbox framework to run +potentially untrusted applications as it additionally limits access to the +filesystem (including labwc configuration) and other services like dbus. + +In addition to that, privileged protocols can be restricted for non-sandboxed +clients by defining a `` block: + +``` + + zwlr_layer_shell_v1 + zwlr_virtual_pointer_manager_v1 + +``` + +** + Name of the interface that should be allowed. + +This is the full list of interfaces that can be controlled with this mechanism: + +- `wp_drm_lease_device_v1` +- `zwlr_gamma_control_manager_v1` +- `zwlr_output_manager_v1` +- `zwlr_output_power_manager_v1` +- `zwp_input_method_manager_v2` +- `zwlr_virtual_pointer_manager_v1` +- `zwp_virtual_keyboard_manager_v1` +- `zwlr_export_dmabuf_manager_v1` +- `zwlr_screencopy_manager_v1` +- `ext_data_control_manager_v1` +- `zwlr_data_control_manager_v1` +- `wp_security_context_manager_v1` +- `ext_idle_notifier_v1` +- `zwlr_foreign_toplevel_manager_v1` +- `ext_foreign_toplevel_list_v1` +- `ext_session_lock_manager_v1` +- `zwlr_layer_shell_v1` +- `ext_workspace_manager_v1` +- `ext_image_copy_capture_manager_v1` +- `ext_output_image_capture_source_manager_v1` + ## ENVIRONMENT VARIABLES *XCURSOR_PATH* diff --git a/include/config/rcxml.h b/include/config/rcxml.h index 517cd907..8a2c606c 100644 --- a/include/config/rcxml.h +++ b/include/config/rcxml.h @@ -76,6 +76,7 @@ struct rcxml { enum tearing_mode allow_tearing; bool auto_enable_outputs; bool reuse_output_mode; + uint32_t allowed_interfaces; bool xwayland_persistence; bool primary_selection; char *prompt_command; @@ -225,4 +226,6 @@ void rcxml_finish(void); */ void append_parsed_actions(xmlNode *node, struct wl_list *list); +uint32_t parse_privileged_interface(const char *name); + #endif /* LABWC_RCXML_H */ diff --git a/src/config/rcxml.c b/src/config/rcxml.c index a3eeed63..9884d15e 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -94,6 +94,43 @@ parse_window_type(const char *type) } } +uint32_t +parse_privileged_interface(const char *name) +{ + static const char * const ifaces[] = { + "wp_drm_lease_device_v1", + "zwlr_gamma_control_manager_v1", + "zwlr_output_manager_v1", + "zwlr_output_power_manager_v1", + "zwp_input_method_manager_v2", + "zwlr_virtual_pointer_manager_v1", + "zwp_virtual_keyboard_manager_v1", + "zwlr_export_dmabuf_manager_v1", + "zwlr_screencopy_manager_v1", + "ext_data_control_manager_v1", + "zwlr_data_control_manager_v1", + "wp_security_context_manager_v1", + "ext_idle_notifier_v1", + "zwlr_foreign_toplevel_manager_v1", + "ext_foreign_toplevel_list_v1", + "ext_session_lock_manager_v1", + "zwlr_layer_shell_v1", + "ext_workspace_manager_v1", + "ext_image_copy_capture_manager_v1", + "ext_output_image_capture_source_manager_v1", + }; + + static_assert(ARRAY_SIZE(ifaces) <= 32, + "return type too small for amount of privileged protocols"); + + for (size_t i = 0; i < ARRAY_SIZE(ifaces); i++) { + if (!strcmp(name, ifaces[i])) { + return 1 << i; + } + } + return 0; +} + /* * Openbox/labwc comparison * @@ -1377,6 +1414,16 @@ entry(xmlNode *node, char *nodename, char *content) rc.mag_increment = MAX(0, rc.mag_increment); } else if (!strcasecmp(nodename, "useFilter.magnifier")) { set_bool(content, &rc.mag_filter); + } else if (!strcasecmp(nodename, "privilegedInterfaces")) { + rc.allowed_interfaces = 0; + } else if (!strcasecmp(nodename, "allow.privilegedInterfaces")) { + uint32_t iface_id = parse_privileged_interface(content); + if (iface_id) { + rc.allowed_interfaces |= iface_id; + } else { + wlr_log(WLR_ERROR, "invalid value for " + ""); + } } return false; @@ -1459,6 +1506,7 @@ rcxml_init(void) rc.allow_tearing = LAB_TEARING_DISABLED; rc.auto_enable_outputs = true; rc.reuse_output_mode = false; + rc.allowed_interfaces = UINT32_MAX; rc.xwayland_persistence = false; rc.primary_selection = true; diff --git a/src/server.c b/src/server.c index 78aa26a7..e4b27026 100644 --- a/src/server.c +++ b/src/server.c @@ -212,39 +212,6 @@ handle_drm_lease_request(struct wl_listener *listener, void *data) } #endif -static bool -protocol_is_privileged(const struct wl_interface *iface) -{ - static const char * const rejected[] = { - "wp_drm_lease_device_v1", - "zwlr_gamma_control_manager_v1", - "zwlr_output_manager_v1", - "zwlr_output_power_manager_v1", - "zwp_input_method_manager_v2", - "zwlr_virtual_pointer_manager_v1", - "zwp_virtual_keyboard_manager_v1", - "zwlr_export_dmabuf_manager_v1", - "zwlr_screencopy_manager_v1", - "ext_data_control_manager_v1", - "zwlr_data_control_manager_v1", - "wp_security_context_manager_v1", - "ext_idle_notifier_v1", - "zwlr_foreign_toplevel_manager_v1", - "ext_foreign_toplevel_list_v1", - "ext_session_lock_manager_v1", - "zwlr_layer_shell_v1", - "ext_workspace_manager_v1", - "ext_image_copy_capture_manager_v1", - "ext_output_image_capture_source_manager_v1", - }; - for (size_t i = 0; i < ARRAY_SIZE(rejected); i++) { - if (!strcmp(iface->name, rejected[i])) { - return true; - } - } - return false; -} - static bool allow_for_sandbox(const struct wlr_security_context_v1_state *security_state, const struct wl_interface *iface) @@ -327,6 +294,11 @@ server_global_filter(const struct wl_client *client, const struct wl_global *glo } #endif + uint32_t iface_id = parse_privileged_interface(iface->name); + if (iface_id && !(iface_id & rc.allowed_interfaces)) { + return false; + } + /* Do not allow security_context_manager_v1 to clients with a security context attached */ const struct wlr_security_context_v1_state *security_context = wlr_security_context_manager_v1_lookup_client( @@ -342,11 +314,11 @@ server_global_filter(const struct wl_client *client, const struct wl_global *glo /* * TODO: The following call is basically useless right now * and should be replaced with - * assert(allow || protocol_is_privileged(iface)); + * assert(allow || iface_id); * This ensures that our lists are in sync with what * protocols labwc supports. */ - if (!allow && !protocol_is_privileged(iface)) { + if (!allow && !iface_id) { wlr_log(WLR_ERROR, "Blocking unknown protocol %s", iface->name); } else if (!allow) { wlr_log(WLR_DEBUG, "Blocking %s for security context %s->%s->%s", From da37e97a450d5e094a58dcd34c729c937ba01b30 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Mon, 6 Apr 2026 22:05:37 +0100 Subject: [PATCH 075/146] Add action `ToggleShowDesktop` --- docs/labwc-actions.5.scd | 7 ++++ include/show-desktop.h | 8 +++++ include/view.h | 1 + src/action.c | 5 +++ src/desktop.c | 3 ++ src/meson.build | 1 + src/show-desktop.c | 78 ++++++++++++++++++++++++++++++++++++++++ src/workspaces.c | 3 ++ 8 files changed, 106 insertions(+) create mode 100644 include/show-desktop.h create mode 100644 src/show-desktop.c diff --git a/docs/labwc-actions.5.scd b/docs/labwc-actions.5.scd index a70c0086..de1dc00d 100644 --- a/docs/labwc-actions.5.scd +++ b/docs/labwc-actions.5.scd @@ -424,6 +424,13 @@ Actions are used in menus and keyboard/mouse bindings. Toggle the screen magnifier on or off at the last magnification level used. +** + Minimize all windows in the current workspace so that the desktop becomes + visible. On calling the action again the hidden windows are unminimized, + provided that - since the initial `ShowDesktop` - (a) no windows have been + unminimized; (b) workspaces have not been switched; and (c) no new + applications have been started. + **++ ** Increase or decrease the magnification level for the screen magnifier. diff --git a/include/show-desktop.h b/include/show-desktop.h new file mode 100644 index 00000000..cc86bcb4 --- /dev/null +++ b/include/show-desktop.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef LABWC_SHOW_DESKTOP_H +#define LABWC_SHOW_DESKTOP_H + +void show_desktop_toggle(void); +void show_desktop_reset(void); + +#endif /* LABWC_SHOW_DESKTOP_H */ diff --git a/include/view.h b/include/view.h index c2764f94..da7aef02 100644 --- a/include/view.h +++ b/include/view.h @@ -184,6 +184,7 @@ struct view { enum ssd_preference ssd_preference; bool shaded; bool minimized; + bool was_minimized_by_show_desktop_action; enum view_axis maximized; bool fullscreen; bool tearing_hint; diff --git a/src/action.c b/src/action.c index 2cfa6be6..34435e02 100644 --- a/src/action.c +++ b/src/action.c @@ -28,6 +28,7 @@ #include "output.h" #include "output-virtual.h" #include "regions.h" +#include "show-desktop.h" #include "ssd.h" #include "theme.h" #include "translate.h" @@ -133,6 +134,7 @@ struct action_arg_list { X(TOGGLE_MAGNIFY, "ToggleMagnify") \ X(ZOOM_IN, "ZoomIn") \ X(ZOOM_OUT, "ZoomOut") \ + X(TOGGLE_SHOW_DESKTOP, "ToggleShowDesktop") \ X(WARP_CURSOR, "WarpCursor") \ X(HIDE_CURSOR, "HideCursor") \ X(DEBUG_TOGGLE_KEY_STATE_INDICATOR, "DebugToggleKeyStateIndicator") @@ -1562,6 +1564,9 @@ run_action(struct view *view, struct action *action, case ACTION_TYPE_ZOOM_OUT: magnifier_set_scale(MAGNIFY_DECREASE); break; + case ACTION_TYPE_TOGGLE_SHOW_DESKTOP: + show_desktop_toggle(); + break; case ACTION_TYPE_WARP_CURSOR: { const char *to = action_get_str(action, "to", "output"); const char *x = action_get_str(action, "x", "center"); diff --git a/src/desktop.c b/src/desktop.c index 28bf4464..4c7870f1 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -14,6 +14,7 @@ #include "layers.h" #include "node.h" #include "output.h" +#include "show-desktop.h" #include "ssd.h" #include "view.h" #include "workspaces.h" @@ -113,6 +114,8 @@ desktop_focus_view(struct view *view, bool raise) */ struct view *dialog = view_get_modal_dialog(view); set_or_offer_focus(dialog ? dialog : view); + + show_desktop_reset(); } /* TODO: focus layer-shell surfaces also? */ diff --git a/src/meson.build b/src/meson.build index 40ec3170..05163cfa 100644 --- a/src/meson.build +++ b/src/meson.build @@ -22,6 +22,7 @@ labwc_sources = files( 'seat.c', 'server.c', 'session-lock.c', + 'show-desktop.c', 'snap-constraints.c', 'snap.c', 'tearing.c', diff --git a/src/show-desktop.c b/src/show-desktop.c new file mode 100644 index 00000000..efddf2de --- /dev/null +++ b/src/show-desktop.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include "show-desktop.h" +#include +#include "common/array.h" +#include "config/types.h" +#include "labwc.h" +#include "view.h" + +static bool is_showing_desktop; + +static void +minimize_views(struct wl_array *views, bool minimize) +{ + struct view **view; + wl_array_for_each_reverse(view, views) { + view_minimize(*view, minimize); + } +} + +static void +show(void) +{ + static struct wl_array views; + wl_array_init(&views); + + /* Build array first as minimize changes server.views */ + struct view *view; + for_each_view(view, &server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { + if (view->minimized) { + continue; + } + view->was_minimized_by_show_desktop_action = true; + array_add(&views, view); + } + minimize_views(&views, true); + is_showing_desktop = true; + + wl_array_release(&views); +} + +static void +restore(void) +{ + static struct wl_array views; + wl_array_init(&views); + + struct view *view; + for_each_view(view, &server.views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) { + if (view->was_minimized_by_show_desktop_action) { + array_add(&views, view); + } + } + minimize_views(&views, false); + show_desktop_reset(); + + wl_array_release(&views); +} + +void +show_desktop_toggle(void) +{ + if (is_showing_desktop) { + restore(); + } else { + show(); + } +} + +void +show_desktop_reset(void) +{ + is_showing_desktop = false; + + struct view *view; + for_each_view(view, &server.views, LAB_VIEW_CRITERIA_NONE) { + view->was_minimized_by_show_desktop_action = false; + } +} diff --git a/src/workspaces.c b/src/workspaces.c index 7ff471a5..a1ed9112 100644 --- a/src/workspaces.c +++ b/src/workspaces.c @@ -21,6 +21,7 @@ #include "input/keyboard.h" #include "labwc.h" #include "output.h" +#include "show-desktop.h" #include "theme.h" #include "view.h" @@ -495,6 +496,8 @@ workspaces_switch_to(struct workspace *target, bool update_focus) desktop_update_top_layer_visibility(); wlr_ext_workspace_handle_v1_set_active(target->ext_workspace, true); + + show_desktop_reset(); } void From 4c7a9960a400bd9bd5052483e008b776eee35cfc Mon Sep 17 00:00:00 2001 From: yuiiio Date: Tue, 14 Apr 2026 12:02:20 +0900 Subject: [PATCH 076/146] osd-thumbnail: fix failed to get client texture Use wlr_client_buffer->texture directly instead of wlr_texture_from_buffer. All buffers in content_tree are wlr_client_buffer. wlr_texture_from_buffer calls client_buffer_begin_data_ptr_access which fails when client_buffer->source == NULL (client released buffer early, e.g. wl_shm foot-terminal). --- src/cycle/osd-thumbnail.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/cycle/osd-thumbnail.c b/src/cycle/osd-thumbnail.c index 623708a0..defedf09 100644 --- a/src/cycle/osd-thumbnail.c +++ b/src/cycle/osd-thumbnail.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include "config/rcxml.h" @@ -46,8 +47,12 @@ render_node(struct wlr_render_pass *pass, if (!scene_buffer->buffer) { break; } - struct wlr_texture *texture = wlr_texture_from_buffer( - server.renderer, scene_buffer->buffer); + struct wlr_texture *texture = NULL; + struct wlr_client_buffer *client_buffer = + wlr_client_buffer_get(scene_buffer->buffer); + if (client_buffer) { + texture = client_buffer->texture; + } if (!texture) { break; } @@ -62,7 +67,6 @@ render_node(struct wlr_render_pass *pass, }, .transform = scene_buffer->transform, }); - wlr_texture_destroy(texture); break; } case WLR_SCENE_NODE_RECT: From c5ea41e87698a868e7280a52af0bd7da2968e2b1 Mon Sep 17 00:00:00 2001 From: Yannis Drougas Date: Wed, 9 Apr 2025 08:26:59 +0100 Subject: [PATCH 077/146] Add overrideInhibition to keyboard.keybind --- docs/labwc-config.5.scd | 8 +++++++- include/config/keybind.h | 1 + src/config/rcxml.c | 3 +++ src/input/keyboard.c | 6 ++++-- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index 061e57ad..ac94d54c 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -760,7 +760,8 @@ References: Stores the keyboard layout either globally or per window and restores it when switching back to the window. Default is global. -** +** Define a *key* binding in the format *modifier-key*, where supported modifiers are: - S (shift) @@ -808,6 +809,11 @@ References: *allowWhenLocked* [yes|no] Make this keybind work even if the screen is locked. Default is no. + *overrideInhibition* [yes|no] + Make this keybind work even if the view inhibits keybinds. Default is no. + This can be used to prevent W-Tab and similar keybinds from being + delivered to Virtual Machines, VNC clients or nested compositors. + *onRelease* [yes|no] When yes, fires the keybind action when the key or key combination is released, rather than first pressed. This is useful to diff --git a/include/config/keybind.h b/include/config/keybind.h index e3c9e21b..d02de387 100644 --- a/include/config/keybind.h +++ b/include/config/keybind.h @@ -23,6 +23,7 @@ struct keybind { struct wl_list actions; /* struct action.link */ struct wl_list link; /* struct rcxml.keybinds */ bool on_release; + bool override_inhibition; }; /** diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 9884d15e..20c236b4 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -602,6 +602,7 @@ fill_keybind(xmlNode *node) lab_xml_get_bool(node, "onRelease", &keybind->on_release); lab_xml_get_bool(node, "layoutDependent", &keybind->use_syms_only); lab_xml_get_bool(node, "allowWhenLocked", &keybind->allow_when_locked); + lab_xml_get_bool(node, "overrideInhibition", &keybind->override_inhibition); append_parsed_actions(node, &keybind->actions); } @@ -1706,6 +1707,8 @@ deduplicate_key_bindings(void) wl_list_remove(¤t->link); keybind_destroy(current); cleared++; + } else if (actions_contain_toggle_keybinds(¤t->actions)) { + current->override_inhibition = true; } } if (replaced) { diff --git a/src/input/keyboard.c b/src/input/keyboard.c index 9d8e840d..98be5d11 100644 --- a/src/input/keyboard.c +++ b/src/input/keyboard.c @@ -203,8 +203,10 @@ match_keybinding_for_sym(uint32_t modifiers, if (modifiers ^ keybind->modifiers) { continue; } - if (view_inhibits_actions(server.active_view, &keybind->actions)) { - continue; + if (!(keybind->override_inhibition)) { + if (view_inhibits_actions(server.active_view, &keybind->actions)) { + continue; + } } if (sym == XKB_KEY_NoSymbol) { /* Use keycodes */ From 6df6a092bad7ec76a86ecda3810425412bd571cc Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Tue, 14 Apr 2026 21:55:16 +0100 Subject: [PATCH 078/146] NEWS.md: update notes for 0.9.7 --- NEWS.md | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/NEWS.md b/NEWS.md index d721ed3b..ac001850 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,7 +9,8 @@ The format is based on [Keep a Changelog] | Date | All Changes | wlroots version | lines-of-code | |------------|---------------|-----------------|---------------| -| 2026-03-31 | [unreleased] | 0.20.0 | 27402 | +| 2026-04-17 | [unreleased] | 0.20.0 | 27753 | +| 2026-04-17 | [0.9.7] | 0.19.2 | 29277 | | 2026-03-15 | [0.9.6] | 0.19.2 | 29271 | | 2026-03-04 | [0.9.5] | 0.19.2 | 29251 | | 2026-02-27 | [0.9.4] | 0.19.2 | 29225 | @@ -44,6 +45,7 @@ The format is based on [Keep a Changelog] | 2021-03-05 | [0.1.0] | 0.12.0 | 4627 | [unreleased]: NEWS.md#unreleased +[0.9.7]: NEWS.md#097---2026-04-17 [0.9.6]: NEWS.md#096---2026-03-15 [0.9.5]: NEWS.md#095---2026-03-04 [0.9.4]: NEWS.md#094---2026-02-27 @@ -117,8 +119,20 @@ There are some regression warnings worth noting for the switch to wlroots 0.19: The codebase has been ported to wlroots 0.20 [#2956] @Consolatis +Note to maintainers: +- libinput >=1.26 is required in support of tablet tool pressure range + configuration. + ### Added +- Add `overrideInhibition` option to `` [#3507] @drougas +- Add action `ToggleShowDesktop` to hide/unhide windows [#3500] @johanmalm +- Add `` config option so that privileged protocols can be + restricted [#3493] @xi +- Add action `DebugToggleKeyStateIndicator` to show a key-state on-screen + display (OSD) for debugging. [#3499] @johanmalm @tokyo4j +- Add support for `color-management-v1` and `color-representation-manager-v1` + protocols [#3469] @ManuLinares - Add configuration option `` to enable tablet tool pressure range libinput settings [#2916] @jp7677 - Add `wl_fixes` interface [#2956] @kode54 @@ -144,19 +158,41 @@ The codebase has been ported to wlroots 0.20 [#2956] @Consolatis compositor and, unlike DRM outputs, these cannot be reconnected after being destroyed. [#3440] @marler8997 - Allow policy-based placement to apply when an initially-maximized/fullscreen - view is restored to floating geometry. [#3387] @jlindgren90 + view is restored to floating geometry. [#3387] [#3502] @jlindgren90 ### Changed - Drop cosmic-workspace protocol [#3031] @tokyo4j +## 0.9.7 - 2026-04-17 + +[0.9.7-commits] + +This is a small bug fix release. + +``` + 0.9.6--------0.9.7 <--- v0.9 branch with bug-fixes only + / + / +0.9.4--------0.9.5-------- <-- master (built with wlroots-0.20) +``` + +## Fixed + +- Fix intermittent failed-to-get-texture issue with some clients (e.g. foot) + when using the window-switcher in the thumbnail mode. [#3511] @yuiiio +- Fix tablet tool tilt motion. [#3494] @jp7677 +- Handle window-switcher buffer allocation failure when in 'thumbnail' mode. + This is believed to be very unlikely to happen, but has been reported by one + user and is believed to be GPU driver related. [#3490] @Consolatis + ## 0.9.6 - 2026-03-15 [0.9.6-commits] This is an earlier-than-usual release containing bug fixes only. It has been -done on a separate branch (0.9.5-maintenance) to avoid the inclusion of -refactoring and new features. +done on a separate branch (v0.9) to avoid the inclusion of refactoring and new +features. ``` 0.9.6 <--- bug-fixes only @@ -2682,6 +2718,7 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 [Keep a Changelog]: https://keepachangelog.com/en/1.0.0/ [unreleased-commits]: https://github.com/labwc/labwc/compare/0.9.5...HEAD +[0.9.7-commits]: https://github.com/labwc/labwc/compare/0.9.6...0.9.7 [0.9.6-commits]: https://github.com/labwc/labwc/compare/0.9.5...0.9.6 [0.9.5-commits]: https://github.com/labwc/labwc/compare/0.9.4...0.9.5 [0.9.4-commits]: https://github.com/labwc/labwc/compare/0.9.3...0.9.4 @@ -3232,3 +3269,12 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 [#3445]: https://github.com/labwc/labwc/pull/3445 [#3446]: https://github.com/labwc/labwc/pull/3446 [#3450]: https://github.com/labwc/labwc/pull/3450 +[#3469]: https://github.com/labwc/labwc/pull/3469 +[#3490]: https://github.com/labwc/labwc/pull/3490 +[#3493]: https://github.com/labwc/labwc/pull/3493 +[#3494]: https://github.com/labwc/labwc/pull/3494 +[#3499]: https://github.com/labwc/labwc/pull/3499 +[#3500]: https://github.com/labwc/labwc/pull/3500 +[#3502]: https://github.com/labwc/labwc/pull/3502 +[#3507]: https://github.com/labwc/labwc/pull/3507 +[#3511]: https://github.com/labwc/labwc/pull/3511 From 5c582bda09de01f1bd172f83b1f5620923ec8c8b Mon Sep 17 00:00:00 2001 From: daniel <193309918+danielfrrrr@users.noreply.github.com> Date: Wed, 1 Apr 2026 06:49:47 -0300 Subject: [PATCH 079/146] config: migrate from amixer to pactl --- README.md | 6 +++--- docs/labwc-config.5.scd | 2 +- docs/rc.xml.all | 6 +++--- include/config/default-bindings.h | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index ec00083d..9cc81e88 100644 --- a/README.md +++ b/README.md @@ -217,9 +217,9 @@ If you have not created an rc.xml config file, default bindings will be: | `super`-`mouse-right` | resize window | `super`-`arrow` | resize window to fill half the output | `alt`-`space` | show the window menu -| `XF86AudioLowerVolume` | amixer sset Master 5%- -| `XF86AudioRaiseVolume` | amixer sset Master 5%+ -| `XF86AudioMute` | amixer sset Master toggle +| `XF86AudioLowerVolume` | pactl set-sink-volume @DEFAULT_SINK@ -5% +| `XF86AudioRaiseVolume` | pactl set-sink-volume @DEFAULT_SINK@ +5% +| `XF86AudioMute` | pactl set-sink-mute @DEFAULT_SINK@ toggle | `XF86MonBrightnessUp` | brightnessctl set +10% | `XF86MonBrightnessDown` | brightnessctl set 10%- diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index ac94d54c..32943eb7 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -851,7 +851,7 @@ overrideInhibition="">* A-Space - show window menu ``` - Audio and MonBrightness keys are also bound to amixer and + Audio and MonBrightness keys are also bound to pactl and brightnessctl, respectively. ** diff --git a/docs/rc.xml.all b/docs/rc.xml.all index 6d543b46..9ddd69a8 100644 --- a/docs/rc.xml.all +++ b/docs/rc.xml.all @@ -292,13 +292,13 @@ - + - + - + diff --git a/include/config/default-bindings.h b/include/config/default-bindings.h index f2042c28..a49f60f4 100644 --- a/include/config/default-bindings.h +++ b/include/config/default-bindings.h @@ -88,21 +88,21 @@ static struct key_combos { .action = "Execute", .attributes[0] = { .name = "command", - .value = "amixer sset Master 5%-", + .value = "pactl set-sink-volume @DEFAULT_SINK@ -5%", }, }, { .binding = "XF86AudioRaiseVolume", .action = "Execute", .attributes[0] = { .name = "command", - .value = "amixer sset Master 5%+", + .value = "pactl set-sink-volume @DEFAULT_SINK@ +5%", }, }, { .binding = "XF86AudioMute", .action = "Execute", .attributes[0] = { .name = "command", - .value = "amixer sset Master toggle", + .value = "pactl set-sink-mute @DEFAULT_SINK@ toggle", }, }, { .binding = "XF86MonBrightnessUp", From 5f668a82eedfda31482d7e7eb6c717d014333900 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Fri, 17 Apr 2026 18:52:01 +0200 Subject: [PATCH 080/146] interactive: allow resize on fully maximized views Modifier+right-drag resize was silently ignored on fully maximized views because of an early-return guard in interactive_begin(). The axis-specific un-maximization logic introduced in #3043 already handles partial maximization correctly; extend that to the VIEW_AXIS_BOTH case so both axes are cleared while keeping the current geometry as the starting point of the resize. Move already permits dragging maximized views, so this also removes an asymmetry between the move and resize paths. Fixes: #3524 --- src/interactive.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/interactive.c b/src/interactive.c index f4d8eea1..9214ba30 100644 --- a/src/interactive.c +++ b/src/interactive.c @@ -123,11 +123,12 @@ interactive_begin(struct view *view, enum input_mode mode, enum lab_edge edges) cursor_shape = LAB_CURSOR_GRAB; break; case LAB_INPUT_STATE_RESIZE: { - if (view->shaded || view->fullscreen || - view->maximized == VIEW_AXIS_BOTH) { + if (view->shaded || view->fullscreen) { /* - * We don't allow resizing while shaded, - * fullscreen or maximized in both directions. + * We don't allow resizing while shaded or fullscreen. + * Maximized views are handled below by un-maximizing + * the axes being resized while keeping the current + * geometry as the starting point. */ return; } @@ -141,9 +142,9 @@ interactive_begin(struct view *view, enum input_mode mode, enum lab_edge edges) } /* - * If tiled or maximized in only one direction, reset - * tiled state and un-maximize the relevant axes, but - * keep the same geometry as the starting point. + * If tiled or maximized, reset tiled state and un-maximize + * the axes that are being resized, but keep the same + * geometry as the starting point. */ enum view_axis maximized = view->maximized; if (server.resize_edges & LAB_EDGES_LEFT_RIGHT) { From 20540d76f9976988ccf2dc1ecfeb5e2fb65fe18b Mon Sep 17 00:00:00 2001 From: elviosak <33790211+elviosak@users.noreply.github.com> Date: Fri, 24 Apr 2026 16:04:43 -0300 Subject: [PATCH 081/146] fix docs typo --- docs/labwc-actions.5.scd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/labwc-actions.5.scd b/docs/labwc-actions.5.scd index de1dc00d..fb616340 100644 --- a/docs/labwc-actions.5.scd +++ b/docs/labwc-actions.5.scd @@ -514,7 +514,7 @@ Actions that execute other actions. Used in keyboard/mouse bindings. "right-occupied" directions will not wrap. *tiled* [up|right|down|left|up-left|up-right|down-left|down-right|center|any] - Whether the client is tiled (snapped) along the the + Whether the client is tiled (snapped) along the indicated screen edge. *tiled_region* From 7d264c907fd23f4fa6ba2a190a4e250590d58a59 Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Sun, 26 Apr 2026 18:56:03 +0900 Subject: [PATCH 082/146] src/cycle/cycle.c: fix typo --- src/cycle/cycle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cycle/cycle.c b/src/cycle/cycle.c index 77195176..2649f1e5 100644 --- a/src/cycle/cycle.c +++ b/src/cycle/cycle.c @@ -167,7 +167,7 @@ cycle_begin(enum lab_cycle_dir direction, struct view *active_view = server.active_view; if (active_view && active_view->cycle_link.next) { - /* Select the active view it's in the cycle list */ + /* Select the active view if it's in the cycle list */ server.cycle.selected_view = active_view; } else { /* Otherwise, select the first view in the cycle list */ From 5c7bfe3c67d27934f345d50239bc7084a03193d3 Mon Sep 17 00:00:00 2001 From: diniamo Date: Sat, 25 Apr 2026 20:44:02 +0200 Subject: [PATCH 083/146] Add onbutton scrollMethod, scrollButton --- docs/labwc-config.5.scd | 12 +++++++++--- docs/rc.xml.all | 3 ++- include/config/libinput.h | 1 + src/config/libinput.c | 1 + src/config/rcxml.c | 10 ++++++++++ src/seat.c | 10 ++++++++++ 6 files changed, 33 insertions(+), 4 deletions(-) diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index 32943eb7..6f198532 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -1140,6 +1140,7 @@ Note: To rotate touch events with output rotation, use the libinput + 1.0 @@ -1244,19 +1245,24 @@ Note: To rotate touch events with output rotation, use the libinput The default method depends on the touchpad hardware. -** [none|twofinger|edge] - Configure the method by which physical movements on a touchpad are - mapped to scroll events. +** [none|twofinger|edge|onbutton] + Configure the method by which physical movements are mapped to scroll events. The scroll methods available are: - *twofinger* - Scroll by two fingers being placed on the surface of the touchpad, then moving those fingers vertically or horizontally. - *edge* - Scroll by moving a single finger along the right edge (vertical scroll) or bottom edge (horizontal scroll). + - *onbutton* - Scroll by pressing a button. - *none* - No scroll events will be produced. The default method depends on the touchpad hardware. +** [button] + Set the button used for the *onbutton* scroll method. + + *button* is the decimal form of a value from `linux/input-event-codes.h`. + ** [yes|no|disabledOnExternalMouse] Optionally enable or disable sending any device events. diff --git a/docs/rc.xml.all b/docs/rc.xml.all index 9ddd69a8..61ea121a 100644 --- a/docs/rc.xml.all +++ b/docs/rc.xml.all @@ -592,7 +592,7 @@ - accelProfile [flat|adaptive] - tapButtonMap [lrm|lmr] - clickMethod [none|buttonAreas|clickfinger] - - scrollMethod [twoFinger|edge|none] + - scrollMethod [twoFinger|edge|onbutton|none] - sendEventsMode [yes|no|disabledOnExternalMouse] - calibrationMatrix [six float values split by space] - scrollFactor [float] @@ -618,6 +618,7 @@ + 1.0 diff --git a/include/config/libinput.h b/include/config/libinput.h index 80b3fc10..077bc011 100644 --- a/include/config/libinput.h +++ b/include/config/libinput.h @@ -31,6 +31,7 @@ struct libinput_category { int dwt; /* -1 or libinput_config_dwt_state */ int click_method; /* -1 or libinput_config_click_method */ int scroll_method; /* -1 or libinput_config_scroll_method */ + int scroll_button; /* -1 or a button from linux/input_event_codes.h */ int send_events_mode; /* -1 or libinput_config_send_events_mode */ bool have_calibration_matrix; double scroll_factor; diff --git a/src/config/libinput.c b/src/config/libinput.c index 1209d267..59bf469e 100644 --- a/src/config/libinput.c +++ b/src/config/libinput.c @@ -25,6 +25,7 @@ libinput_category_init(struct libinput_category *l) l->dwt = -1; l->click_method = -1; l->scroll_method = -1; + l->scroll_button = -1; l->send_events_mode = -1; l->have_calibration_matrix = false; l->scroll_factor = 1.0; diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 20c236b4..e3187af2 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -891,9 +891,19 @@ fill_libinput_category(xmlNode *node) } else if (!strcasecmp(content, "twofinger")) { category->scroll_method = LIBINPUT_CONFIG_SCROLL_2FG; + } else if (!strcasecmp(content, "onbutton")) { + category->scroll_method = + LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN; } else { wlr_log(WLR_ERROR, "invalid scrollMethod"); } + } else if (!strcasecmp(key, "scrollButton")) { + int button = atoi(content); + if (button != 0) { + category->scroll_button = button; + } else { + wlr_log(WLR_ERROR, "invalid scrollButton"); + } } else if (!strcasecmp(key, "sendEventsMode")) { category->send_events_mode = get_send_events_mode(content); diff --git a/src/seat.c b/src/seat.c index 93d108be..fe85dc26 100644 --- a/src/seat.c +++ b/src/seat.c @@ -328,6 +328,16 @@ configure_libinput(struct wlr_input_device *wlr_input_device) libinput_device_config_scroll_set_method(libinput_dev, dc->scroll_method); } + libinput_device_config_scroll_set_button(libinput_dev, + libinput_device_config_scroll_get_default_button(libinput_dev)); + if (dc->scroll_button < 0) { + wlr_log(WLR_INFO, "scroll button not configured"); + } else { + wlr_log(WLR_INFO, "scroll button configured (%d)", + dc->scroll_button); + libinput_device_config_scroll_set_button(libinput_dev, dc->scroll_button); + } + libinput_device_config_send_events_set_mode(libinput_dev, libinput_device_config_send_events_get_default_mode(libinput_dev)); if ((dc->send_events_mode != LIBINPUT_CONFIG_SEND_EVENTS_ENABLED From d8119cb3546db179d289ebd1dd26e0eb596740ad Mon Sep 17 00:00:00 2001 From: Jos Dehaes Date: Mon, 20 Apr 2026 15:53:34 +0200 Subject: [PATCH 084/146] build: ship labwc-session.target systemd user unit Add a small systemd user target modelled on miracle-wm-session.target. It binds to graphical-session.target and orders after graphical-session-pre.target, so systemd user services declaring WantedBy=graphical-session.target (panels, portals, notification daemons, ...) start and stop in sync with a labwc session. Installed into $systemduserunitdir when the systemd dependency is available at configure time; on systems without systemd the install is skipped and labwc's runtime activation of the target fails gracefully. --- data/labwc-session.target | 6 ++++++ meson.build | 9 +++++++++ 2 files changed, 15 insertions(+) create mode 100644 data/labwc-session.target diff --git a/data/labwc-session.target b/data/labwc-session.target new file mode 100644 index 00000000..e71f20e5 --- /dev/null +++ b/data/labwc-session.target @@ -0,0 +1,6 @@ +[Unit] +Description=labwc session +Documentation=man:labwc(1) man:systemd.special(7) +BindsTo=graphical-session.target +Wants=graphical-session-pre.target +After=graphical-session-pre.target diff --git a/meson.build b/meson.build index 2c2d8e57..e2d2f585 100644 --- a/meson.build +++ b/meson.build @@ -211,6 +211,15 @@ install_data('data/labwc.desktop', install_dir: get_option('datadir') / 'wayland install_data('data/labwc-portals.conf', install_dir: get_option('datadir') / 'xdg-desktop-portal') +# Install labwc-session.target so that systemd user services with +# WantedBy=graphical-session.target start under labwc. Labwc activates +# this target itself in src/config/session.c on autostart. +systemd = dependency('systemd', required: false) +if systemd.found() + install_data('data/labwc-session.target', + install_dir: systemd.get_variable('systemduserunitdir')) +endif + icons = ['labwc-symbolic.svg', 'labwc.svg'] foreach icon : icons icon_path = join_paths('data', icon) From af277b09ed465691fff2915663b6f1dad7de62a9 Mon Sep 17 00:00:00 2001 From: Jos Dehaes Date: Tue, 21 Apr 2026 16:31:30 +0200 Subject: [PATCH 085/146] docs: document labwc-session.target integration Describe the shipped labwc-session.target in labwc(1) SESSION MANAGEMENT and add commented-out systemctl start/stop lines to the example autostart and shutdown files. Users on systemd-based distros can uncomment these to pull in graphical-session.target when labwc starts and tear it down cleanly on exit, without labwc itself mandating any specific init system. --- docs/autostart | 8 ++++++++ docs/labwc.1.scd | 19 +++++++++++++++++++ docs/shutdown | 8 ++++++++ 3 files changed, 35 insertions(+) diff --git a/docs/autostart b/docs/autostart index b045ed82..17fcc270 100644 --- a/docs/autostart +++ b/docs/autostart @@ -1,5 +1,13 @@ # Example autostart file +# When running under systemd, uncomment the systemctl line below to pull in +# graphical-session.target via labwc-session.target. This lets systemd user +# services declaring WantedBy=graphical-session.target (panels, portals, +# notification daemons, etc.) start in sync with the labwc session. Enable +# individual services with: systemctl --user enable +# +# systemctl --user --no-block start labwc-session.target + # Set background color. swaybg -c '#113344' >/dev/null 2>&1 & diff --git a/docs/labwc.1.scd b/docs/labwc.1.scd index 2dab30a5..31f28c19 100644 --- a/docs/labwc.1.scd +++ b/docs/labwc.1.scd @@ -118,6 +118,25 @@ this is accomplished by setting the session variables to empty strings. For systemd, the command `systemctl --user unset-environment` will be invoked to actually remove the variables from the activation environment. +A systemd user unit named `labwc-session.target` is also shipped alongside +the compositor for users who want to integrate labwc with systemd. It binds +to the standard `graphical-session.target`, so systemd user services can +start and stop in sync with the labwc session when they declare a WantedBy +or PartOf relationship to that target. Labwc does not activate the target +itself; users opt in by adding lines like the following to their +*autostart* and *shutdown* files: + +``` +systemctl --user --no-block start labwc-session.target +systemctl --user stop graphical-session.target +``` + +The example *autostart* and *shutdown* files shipped with labwc include +these commented out. To have a user service automatically started with +the session, enable it so the corresponding symlink under the +graphical-session.target.wants directory exists, for example by running +"systemctl --user enable dms.service". + # ENVIRONMENT VARIABLES Set the environment variables listed below to enable specific debug options. diff --git a/docs/shutdown b/docs/shutdown index feed6508..a036ff53 100644 --- a/docs/shutdown +++ b/docs/shutdown @@ -3,3 +3,11 @@ # This file is executed as a shell script when labwc is preparing to terminate # itself. # For further details see labwc-config(5). + +# When running under systemd, uncomment the systemctl line below to tear down +# graphical-session.target (which cascades to labwc-session.target via +# BindsTo, and to any service declaring PartOf=graphical-session.target). +# Running synchronously here ensures those services are stopped before the +# Wayland socket goes away, avoiding "Broken pipe" failures on teardown. +# +# systemctl --user stop graphical-session.target From 70e3173f9993ef002ec8a4e8e809a7a8be612629 Mon Sep 17 00:00:00 2001 From: Jos Dehaes Date: Fri, 24 Apr 2026 10:27:55 +0200 Subject: [PATCH 086/146] build: add systemd-session feature option Let distributors opt out of installing labwc-session.target at configure time. Default is 'auto' (install if the systemd pkg-config file is present), 'enabled' forces it on, 'disabled' skips it entirely. --- meson.build | 8 +++++--- meson_options.txt | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/meson.build b/meson.build index e2d2f585..7e345ba6 100644 --- a/meson.build +++ b/meson.build @@ -212,9 +212,11 @@ install_data('data/labwc.desktop', install_dir: get_option('datadir') / 'wayland install_data('data/labwc-portals.conf', install_dir: get_option('datadir') / 'xdg-desktop-portal') # Install labwc-session.target so that systemd user services with -# WantedBy=graphical-session.target start under labwc. Labwc activates -# this target itself in src/config/session.c on autostart. -systemd = dependency('systemd', required: false) +# WantedBy=graphical-session.target can be started and stopped in sync +# with a labwc session (see labwc(1) SESSION MANAGEMENT for the opt-in +# autostart/shutdown snippet). +systemd_feat = get_option('systemd-session') +systemd = dependency('systemd', required: systemd_feat) if systemd.found() install_data('data/labwc-session.target', install_dir: systemd.get_variable('systemduserunitdir')) diff --git a/meson_options.txt b/meson_options.txt index a47efa86..e059220d 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -4,6 +4,7 @@ option('svg', type: 'feature', value: 'enabled', description: 'Enable svg window option('icon', type: 'feature', value: 'enabled', description: 'Enable window icons') option('labnag', type: 'feature', value: 'auto', description: 'Build labnag notification daemon') option('nls', type: 'feature', value: 'auto', description: 'Enable native language support') +option('systemd-session', type: 'feature', value: 'auto', description: 'Install labwc-session.target systemd user unit') option('static_analyzer', type: 'feature', value: 'disabled', description: 'Run gcc static analyzer') option('test', type: 'feature', value: 'disabled', description: 'Run tests') option('sections', type: 'feature', value: 'disabled', description: 'Show unused functions') From 7b3f37725fac33affe6d013c69f9b59bb140d5c8 Mon Sep 17 00:00:00 2001 From: Jos Dehaes Date: Wed, 15 Apr 2026 14:34:37 +0200 Subject: [PATCH 087/146] rcxml: add raiseOnFocusDelay option Add a new element accepting an integer in milliseconds. The default of 0 preserves the current behavior (raise immediately when raiseOnFocus is enabled). The new field is carried as uint32_t raise_on_focus_delay_ms on struct rcxml. This commit only adds the parser and default; the actual delay logic follows in a subsequent commit. --- include/config/rcxml.h | 1 + src/config/rcxml.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/include/config/rcxml.h b/include/config/rcxml.h index 8a2c606c..3ef7bd67 100644 --- a/include/config/rcxml.h +++ b/include/config/rcxml.h @@ -90,6 +90,7 @@ struct rcxml { bool focus_follow_mouse; bool focus_follow_mouse_requires_movement; bool raise_on_focus; + uint32_t raise_on_focus_delay_ms; /* theme */ char *theme_name; diff --git a/src/config/rcxml.c b/src/config/rcxml.c index e3187af2..d0bb76db 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -1195,6 +1195,9 @@ entry(xmlNode *node, char *nodename, char *content) set_bool(content, &rc.focus_follow_mouse_requires_movement); } else if (!strcasecmp(nodename, "raiseOnFocus.focus")) { set_bool(content, &rc.raise_on_focus); + } else if (!strcasecmp(nodename, "raiseOnFocusDelay.focus")) { + long val = strtol(content, NULL, 10); + rc.raise_on_focus_delay_ms = val > 0 ? (uint32_t)val : 0; } else if (!strcasecmp(nodename, "doubleClickTime.mouse")) { long doubleclick_time_parsed = strtol(content, NULL, 10); if (doubleclick_time_parsed > 0) { @@ -1530,6 +1533,7 @@ rcxml_init(void) rc.focus_follow_mouse = false; rc.focus_follow_mouse_requires_movement = true; rc.raise_on_focus = false; + rc.raise_on_focus_delay_ms = 0; rc.doubleclick_time = 500; From fe6ea66b8221ac77edba84e9efe30ef417553804 Mon Sep 17 00:00:00 2001 From: Jos Dehaes Date: Wed, 15 Apr 2026 14:35:27 +0200 Subject: [PATCH 088/146] server: add pending auto-raise state + decl Add two fields to struct server: struct view *pending_auto_raise_view; struct wl_event_source *pending_auto_raise_timer; and forward-declare desktop_cancel_pending_auto_raise() in labwc.h. The state is a single 'slot' (at most one view/timer pending) since a new focus change supersedes any previous pending raise. This commit just reserves the state and the public API; the behaviour is implemented in the following commit. --- include/labwc.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/labwc.h b/include/labwc.h index 511fdd65..dc4c1311 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -150,6 +150,11 @@ struct seat { struct server { struct wl_display *wl_display; struct wl_event_loop *wl_event_loop; /* Can be used for timer events */ + + /* Pending auto-raise timer (used when rc.raise_on_focus_delay_ms > 0) */ + struct view *pending_auto_raise_view; + struct wl_event_source *pending_auto_raise_timer; + struct wlr_renderer *renderer; struct wlr_allocator *allocator; struct wlr_backend *backend; @@ -343,6 +348,13 @@ void xdg_shell_finish(void); */ void desktop_focus_view(struct view *view, bool raise); +/** + * desktop_cancel_pending_auto_raise() - cancel any pending delayed auto-raise + * (from raiseOnFocusDelay). Called when a view is being destroyed, on config + * reload, or when a new focus change with raise=false supersedes the pending. + */ +void desktop_cancel_pending_auto_raise(void); + /** * desktop_focus_view_or_surface() - like desktop_focus_view() but can * also focus other (e.g. xwayland-unmanaged) surfaces From 28908adfbecb5415aa99b21c4edf00f225e67feb Mon Sep 17 00:00:00 2001 From: Jos Dehaes Date: Wed, 15 Apr 2026 14:36:14 +0200 Subject: [PATCH 089/146] desktop: implement delayed auto-raise timer logic When raiseOnFocus is enabled and raiseOnFocusDelay is > 0, defer view_move_to_front() until a wl_event_loop timer elapses instead of raising immediately. The pending view/timer pair lives on struct server so that at most one raise can be pending per compositor. Semantics: delay_ms == 0 : immediate raise (preserves prior behavior) delay_ms > 0, hover A : schedule raise of A after delay_ms another hover before : timer is reset and the new view becomes expiry the pending one (brief flyby hovers do not stack up raises) focus change, raise=false: pending raise is cancelled This is most useful with followMouse to avoid brief passes of the cursor stacking up z-order changes. --- src/desktop.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/src/desktop.c b/src/desktop.c index 4c7870f1..966bdaab 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -9,6 +9,7 @@ #include #include #include "common/scene-helpers.h" +#include "config/rcxml.h" #include "dnd.h" #include "labwc.h" #include "layers.h" @@ -65,6 +66,49 @@ set_or_offer_focus(struct view *view) } } +static int +handle_auto_raise_timer(void *data) +{ + (void)data; + struct view *view = server.pending_auto_raise_view; + server.pending_auto_raise_view = NULL; + + if (view && view->mapped) { + view_move_to_front(view); + } + return 0; /* ignored per wl_event_loop docs */ +} + +void +desktop_cancel_pending_auto_raise(void) +{ + server.pending_auto_raise_view = NULL; + if (server.pending_auto_raise_timer) { + /* Disarm by setting to 0 ms */ + wl_event_source_timer_update(server.pending_auto_raise_timer, 0); + } +} + +static void +schedule_auto_raise(struct view *view) +{ + if (rc.raise_on_focus_delay_ms == 0) { + /* Immediate raise — preserves original behavior */ + desktop_cancel_pending_auto_raise(); + view_move_to_front(view); + return; + } + + server.pending_auto_raise_view = view; + if (!server.pending_auto_raise_timer) { + server.pending_auto_raise_timer = + wl_event_loop_add_timer(server.wl_event_loop, + handle_auto_raise_timer, NULL); + } + wl_event_source_timer_update(server.pending_auto_raise_timer, + rc.raise_on_focus_delay_ms); +} + void desktop_focus_view(struct view *view, bool raise) { @@ -104,7 +148,13 @@ desktop_focus_view(struct view *view, bool raise) } if (raise) { - view_move_to_front(view); + schedule_auto_raise(view); + } else { + /* + * A new focus change without a raise supersedes any + * pending auto-raise from a previous focus event. + */ + desktop_cancel_pending_auto_raise(); } /* From ecc55656868a4f7e9350d7487ef91b33c259a125 Mon Sep 17 00:00:00 2001 From: Jos Dehaes Date: Wed, 15 Apr 2026 14:36:33 +0200 Subject: [PATCH 090/146] view: cancel pending auto-raise on view destroy The pending_auto_raise_view pointer would become dangling if the view it references is destroyed before the timer fires. Clear it in view_destroy() alongside the existing active_view cleanup. --- src/view.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/view.c b/src/view.c index 1d43fcfa..9b6604ad 100644 --- a/src/view.c +++ b/src/view.c @@ -2521,6 +2521,10 @@ view_destroy(struct view *view) server.active_view = NULL; } + if (server.pending_auto_raise_view == view) { + desktop_cancel_pending_auto_raise(); + } + if (server.session_lock_manager->last_active_view == view) { server.session_lock_manager->last_active_view = NULL; } From 9661ed4285e7f7298851a45c0770cd2b9c9839b9 Mon Sep 17 00:00:00 2001 From: Jos Dehaes Date: Wed, 15 Apr 2026 14:36:56 +0200 Subject: [PATCH 091/146] server: cancel pending auto-raise on config reload If the user disables raiseOnFocus or lowers raiseOnFocusDelay while a raise is queued, the queued raise should not fire against the new config. Cancel it in reload_config_and_theme() before rereading the rc.xml. --- src/server.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/server.c b/src/server.c index e4b27026..c792d8b4 100644 --- a/src/server.c +++ b/src/server.c @@ -89,6 +89,12 @@ reload_config_and_theme(void) /* Avoid UAF when dialog client is used during reconfigure */ action_prompts_destroy(); + /* + * Cancel any pending auto-raise before reloading config in case the + * raiseOnFocusDelay option was disabled or changed. + */ + desktop_cancel_pending_auto_raise(); + scaled_buffer_invalidate_sharing(); rcxml_finish(); rcxml_read(rc.config_file); From 6237e26a1d44ca88e27b09c41619df51de6aae81 Mon Sep 17 00:00:00 2001 From: Jos Dehaes Date: Wed, 15 Apr 2026 14:37:29 +0200 Subject: [PATCH 092/146] docs: document raiseOnFocusDelay Add the new option to labwc-config(5) and the example rc.xml.all. --- docs/labwc-config.5.scd | 7 +++++++ docs/rc.xml.all | 2 ++ 2 files changed, 9 insertions(+) diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index 6f198532..8ea88d8f 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -493,6 +493,13 @@ this is for compatibility with Openbox. ** [yes|no] Raise window to top when focused. Default is no. +** [milliseconds] + When raiseOnFocus is enabled, delay the actual raise by this many + milliseconds. Default is 0 (raise immediately). A subsequent focus + change before the timer elapses restarts or cancels the pending raise. + Useful together with followMouse to avoid brief passes of the cursor + stacking up z-order changes. + ## WINDOW SNAPPING Windows may be "snapped" to an edge or user-defined region of an output when diff --git a/docs/rc.xml.all b/docs/rc.xml.all index 61ea121a..9755530b 100644 --- a/docs/rc.xml.all +++ b/docs/rc.xml.all @@ -158,6 +158,8 @@ no yes no + + 0 From e61d58e54dd7b4c751f312ab86d305e0a7b77488 Mon Sep 17 00:00:00 2001 From: Jos Dehaes Date: Sat, 18 Apr 2026 20:54:28 +0200 Subject: [PATCH 093/146] desktop: only apply raise-on-focus delay to sloppy-focus The raise_on_focus_delay is meant to dampen z-order churn from focus-follows-mouse cursor passes. Applying it to every focus change meant explicit actions (alt-tab cycle finish, Focus action, xdg/xwayland activation, view map, etc.) also waited for the delay before raising, which felt laggy. Route all non-sloppy-focus callers through an immediate raise and keep the timer-based raise only for desktop_focus_view_or_surface(), which is the sloppy-focus entry point. --- src/desktop.c | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/desktop.c b/src/desktop.c index 966bdaab..57ef9e3c 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -90,15 +90,8 @@ desktop_cancel_pending_auto_raise(void) } static void -schedule_auto_raise(struct view *view) +schedule_delayed_auto_raise(struct view *view) { - if (rc.raise_on_focus_delay_ms == 0) { - /* Immediate raise — preserves original behavior */ - desktop_cancel_pending_auto_raise(); - view_move_to_front(view); - return; - } - server.pending_auto_raise_view = view; if (!server.pending_auto_raise_timer) { server.pending_auto_raise_timer = @@ -109,8 +102,15 @@ schedule_auto_raise(struct view *view) rc.raise_on_focus_delay_ms); } -void -desktop_focus_view(struct view *view, bool raise) +/* + * The raise_on_focus_delay is only meant to dampen z-order churn from + * focus-follows-mouse cursor passes. Explicit focus changes (alt-tab, + * Focus action, xdg/xwayland activation, etc.) should raise immediately. + * allow_delay is therefore only set when the caller is the sloppy-focus + * path in desktop_focus_view_or_surface(). + */ +static void +desktop_focus_view_internal(struct view *view, bool raise, bool allow_delay) { assert(view); /* @@ -147,14 +147,17 @@ desktop_focus_view(struct view *view, bool raise) workspaces_switch_to(view->workspace, /*update_focus*/ false); } + /* + * A new focus change supersedes any pending auto-raise from a + * previous focus event, regardless of whether we raise now. + */ + desktop_cancel_pending_auto_raise(); if (raise) { - schedule_auto_raise(view); - } else { - /* - * A new focus change without a raise supersedes any - * pending auto-raise from a previous focus event. - */ - desktop_cancel_pending_auto_raise(); + if (allow_delay && rc.raise_on_focus_delay_ms > 0) { + schedule_delayed_auto_raise(view); + } else { + view_move_to_front(view); + } } /* @@ -168,6 +171,12 @@ desktop_focus_view(struct view *view, bool raise) show_desktop_reset(); } +void +desktop_focus_view(struct view *view, bool raise) +{ + desktop_focus_view_internal(view, raise, /*allow_delay*/ false); +} + /* TODO: focus layer-shell surfaces also? */ void desktop_focus_view_or_surface(struct seat *seat, struct view *view, @@ -175,7 +184,7 @@ desktop_focus_view_or_surface(struct seat *seat, struct view *view, { assert(view || surface); if (view) { - desktop_focus_view(view, raise); + desktop_focus_view_internal(view, raise, /*allow_delay*/ true); #if HAVE_XWAYLAND } else { struct wlr_xwayland_surface *xsurface = From de3870246a06ed083db71d9069cd1bbcc6fa3aa3 Mon Sep 17 00:00:00 2001 From: stormshadow <190884359+st0rm-shad0w@users.noreply.github.com> Date: Fri, 24 Apr 2026 05:42:11 +0530 Subject: [PATCH 094/146] labnag: remove +1 offset from button Y-position calculation It essentially removes an awkward top margin from the button on the main labnag bar. --- clients/labnag.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/labnag.c b/clients/labnag.c index 82b6e8cd..5abd989e 100644 --- a/clients/labnag.c +++ b/clients/labnag.c @@ -447,7 +447,7 @@ render_button(cairo_t *cairo, struct nag *nag, struct button *button, } button->x = *x - border - text_width - padding * 2 + 1; - button->y = (int)(ideal_height - text_height) / 2 - padding + 1; + button->y = (int)(ideal_height - text_height) / 2 - padding; button->width = text_width + padding * 2; button->height = text_height + padding * 2; From 91d89f71ce8bd46e7a6b149a1e1006cce29350b8 Mon Sep 17 00:00:00 2001 From: stormshadow <190884359+st0rm-shad0w@users.noreply.github.com> Date: Fri, 24 Apr 2026 06:16:23 +0530 Subject: [PATCH 095/146] labnag: add details border color and margin options Adds --details-border-color and --details-margin command line options to configure the border color and margin of the details pane. --- clients/labnag.c | 37 ++++++++++++++++++++++++++++++++----- docs/labnag.1.scd | 6 ++++++ 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/clients/labnag.c b/clients/labnag.c index 5abd989e..5fe5164f 100644 --- a/clients/labnag.c +++ b/clients/labnag.c @@ -46,6 +46,7 @@ struct conf { uint32_t button_text; uint32_t button_background; uint32_t details_background; + uint32_t details_border_color; uint32_t background; uint32_t text; uint32_t button_border; @@ -60,6 +61,7 @@ struct conf { ssize_t button_gap_close; ssize_t button_margin_right; ssize_t button_padding; + ssize_t details_margin; }; struct pointer { @@ -343,8 +345,9 @@ render_detailed(cairo_t *cairo, struct nag *nag, uint32_t y) uint32_t width = nag->width; int border = nag->conf->details_border_thickness; + int margin = nag->conf->details_margin; int padding = nag->conf->message_padding; - int decor = padding + border; + int decor = margin + border; nag->details.x = decor; nag->details.y = y + decor; @@ -401,6 +404,8 @@ render_detailed(cairo_t *cairo, struct nag *nag, uint32_t y) nag->details.visible_lines = pango_layout_get_line_count(layout); + int border_rect_height = nag->details.height + 2 * border; + if (show_buttons) { nag->details.button_up.x = nag->details.x + nag->details.width; nag->details.button_up.y = nag->details.y; @@ -416,6 +421,11 @@ render_detailed(cairo_t *cairo, struct nag *nag, uint32_t y) render_details_scroll_button(cairo, nag, &nag->details.button_down); } + cairo_set_source_u32(cairo, nag->conf->details_border_color); + cairo_rectangle(cairo, margin, nag->details.y - border, + nag->details.width + 2 * border, border_rect_height); + cairo_fill(cairo); + cairo_set_source_u32(cairo, nag->conf->details_background); cairo_rectangle(cairo, nag->details.x, nag->details.y, nag->details.width, nag->details.height); @@ -1464,14 +1474,16 @@ conf_init(struct conf *conf) conf->keyboard_focus = ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE; conf->bar_border_thickness = 2; conf->message_padding = 8; - conf->details_border_thickness = 3; conf->button_border_thickness = 3; conf->button_gap = 20; conf->button_gap_close = 15; conf->button_margin_right = 2; conf->button_padding = 3; conf->button_background = 0x680A0AFF; + conf->details_margin = 11; + conf->details_border_thickness = 3; conf->details_background = 0x680A0AFF; + conf->details_border_color = 0x680A0AFF; conf->background = 0x900000FF; conf->text = 0xFFFFFFFF; conf->button_text = 0xFFFFFFFF; @@ -1551,16 +1563,18 @@ nag_parse_options(int argc, char **argv, struct nag *nag, TO_COLOR_BORDER_BOTTOM, TO_COLOR_BUTTON_BG, TO_COLOR_DETAILS, + TO_COLOR_DETAILS_BORDER, TO_COLOR_TEXT, TO_COLOR_BUTTON_TEXT, TO_THICK_BAR_BORDER, TO_PADDING_MESSAGE, - TO_THICK_DET_BORDER, + TO_THICK_DETAILS_BORDER, TO_THICK_BTN_BORDER, TO_GAP_BTN, TO_GAP_BTN_DISMISS, TO_MARGIN_BTN_RIGHT, TO_PADDING_BTN, + TO_MARGIN_DETAILS, }; static const struct option opts[] = { @@ -1587,8 +1601,10 @@ nag_parse_options(int argc, char **argv, struct nag *nag, {"button-text-color", required_argument, NULL, TO_COLOR_BUTTON_TEXT}, {"border-bottom-size", required_argument, NULL, TO_THICK_BAR_BORDER}, {"message-padding", required_argument, NULL, TO_PADDING_MESSAGE}, - {"details-border-size", required_argument, NULL, TO_THICK_DET_BORDER}, + {"details-border-size", required_argument, NULL, TO_THICK_DETAILS_BORDER}, {"details-background-color", required_argument, NULL, TO_COLOR_DETAILS}, + {"details-border-color", required_argument, NULL, TO_COLOR_DETAILS_BORDER}, + {"details-margin", required_argument, NULL, TO_MARGIN_DETAILS}, {"button-border-size", required_argument, NULL, TO_THICK_BTN_BORDER}, {"button-gap", required_argument, NULL, TO_GAP_BTN}, {"button-dismiss-gap", required_argument, NULL, TO_GAP_BTN_DISMISS}, @@ -1633,6 +1649,9 @@ nag_parse_options(int argc, char **argv, struct nag *nag, " --details-border-size size Thickness for the details border.\n" " --details-background-color RRGGBB[AA]\n" " Details background color.\n" + " --details-border-color RRGGBB[AA]\n" + " Details border color.\n" + " --details-margin margin Margin for the details.\n" " --button-border-size size Thickness for the button border.\n" " --button-gap gap Size of the gap between buttons\n" " --button-dismiss-gap gap Size of the gap for dismiss button.\n" @@ -1769,6 +1788,11 @@ nag_parse_options(int argc, char **argv, struct nag *nag, fprintf(stderr, "Invalid details background color: %s\n", optarg); } break; + case TO_COLOR_DETAILS_BORDER: + if (!parse_color(optarg, &conf->details_border_color)) { + fprintf(stderr, "Invalid details border color: %s\n", optarg); + } + break; case TO_COLOR_TEXT: /* Text color */ if (!parse_color(optarg, &conf->text)) { fprintf(stderr, "Invalid text color: %s\n", optarg); @@ -1785,7 +1809,7 @@ nag_parse_options(int argc, char **argv, struct nag *nag, case TO_PADDING_MESSAGE: /* Message padding */ conf->message_padding = strtol(optarg, NULL, 0); break; - case TO_THICK_DET_BORDER: /* Details border thickness */ + case TO_THICK_DETAILS_BORDER: /* Details border thickness */ conf->details_border_thickness = strtol(optarg, NULL, 0); break; case TO_THICK_BTN_BORDER: /* Button border thickness */ @@ -1803,6 +1827,9 @@ nag_parse_options(int argc, char **argv, struct nag *nag, case TO_PADDING_BTN: /* Padding for the button text */ conf->button_padding = strtol(optarg, NULL, 0); break; + case TO_MARGIN_DETAILS: + conf->details_margin = strtol(optarg, NULL, 0); + break; default: /* Help or unknown flag */ fprintf(c == 'h' ? stdout : stderr, "%s", usage); return LAB_EXIT_FAILURE; diff --git a/docs/labnag.1.scd b/docs/labnag.1.scd index 6d4b959f..bf237d00 100644 --- a/docs/labnag.1.scd +++ b/docs/labnag.1.scd @@ -95,6 +95,12 @@ _labnag_ [options...] *--details-border-size* Set the thickness for the details border. +*--details-border-color* + Set the color of the details border. + +*--details-margin* + Set the margin for the details. + *--button-border-size* Set the thickness for the button border. From e209de3eb19c560cf5e0eb16ba7523941b12b67a Mon Sep 17 00:00:00 2001 From: stormshadow <190884359+st0rm-shad0w@users.noreply.github.com> Date: Fri, 24 Apr 2026 07:40:01 +0530 Subject: [PATCH 096/146] labnag: separate details scroll button styling from regular buttons Use details-specific border thickness and color config options instead of regular button options. Adjust padding for a more compact look on details scroll buttons. --- clients/labnag.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/clients/labnag.c b/clients/labnag.c index 5fe5164f..99c44d59 100644 --- a/clients/labnag.c +++ b/clients/labnag.c @@ -302,10 +302,10 @@ render_details_scroll_button(cairo_t *cairo, struct nag *nag, get_text_size(cairo, nag->conf->font_description, &text_width, &text_height, NULL, 1, true, "%s", button->text); - int border = nag->conf->button_border_thickness; - int padding = nag->conf->button_padding; + int border = nag->conf->details_border_thickness; + int padding = (nag->conf->button_padding / 3) + 2; - cairo_set_source_u32(cairo, nag->conf->details_background); + cairo_set_source_u32(cairo, nag->conf->details_border_color); cairo_rectangle(cairo, button->x, button->y, button->width, button->height); cairo_fill(cairo); @@ -333,8 +333,8 @@ get_detailed_scroll_button_width(cairo_t *cairo, struct nag *nag) NULL, 1, true, "%s", nag->details.button_down.text); int text_width = up_width > down_width ? up_width : down_width; - int border = nag->conf->button_border_thickness; - int padding = nag->conf->button_padding; + int border = nag->conf->details_border_thickness; + int padding = (nag->conf->button_padding / 3) + 2; return text_width + border * 2 + padding * 2; } From ccdef5e854dd59d9bc67e7f983f21d79d1729504 Mon Sep 17 00:00:00 2001 From: stormshadow <190884359+st0rm-shad0w@users.noreply.github.com> Date: Fri, 24 Apr 2026 08:58:06 +0530 Subject: [PATCH 097/146] labnag: fix details scroll button group height calculation Previously the scroll button group height was shorter than intended as it was calculated using details.height instead of the border dimensions. Calculate button heights using border_rect_height to properly fill the bordered region. --- clients/labnag.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/clients/labnag.c b/clients/labnag.c index 99c44d59..a3a526c5 100644 --- a/clients/labnag.c +++ b/clients/labnag.c @@ -375,7 +375,7 @@ render_detailed(cairo_t *cairo, struct nag *nag, uint32_t y) bool show_buttons = nag->details.offset > 0; int button_width = get_detailed_scroll_button_width(cairo, nag); if (show_buttons) { - nag->details.width -= button_width; + nag->details.width += border - button_width; pango_layout_set_width(layout, (nag->details.width - padding * 2) * PANGO_SCALE); } @@ -388,7 +388,7 @@ render_detailed(cairo_t *cairo, struct nag *nag, uint32_t y) if (!show_buttons) { show_buttons = true; - nag->details.width -= button_width; + nag->details.width += border - button_width; pango_layout_set_width(layout, (nag->details.width - padding * 2) * PANGO_SCALE); } @@ -408,16 +408,17 @@ render_detailed(cairo_t *cairo, struct nag *nag, uint32_t y) if (show_buttons) { nag->details.button_up.x = nag->details.x + nag->details.width; - nag->details.button_up.y = nag->details.y; + nag->details.button_up.y = nag->details.y - border; nag->details.button_up.width = button_width; - nag->details.button_up.height = nag->details.height / 2; + nag->details.button_up.height = (border_rect_height + border) / 2; render_details_scroll_button(cairo, nag, &nag->details.button_up); nag->details.button_down.x = nag->details.x + nag->details.width; nag->details.button_down.y = nag->details.button_up.y + nag->details.button_up.height; nag->details.button_down.width = button_width; - nag->details.button_down.height = nag->details.height / 2; + nag->details.button_down.height = + border_rect_height - nag->details.button_up.height; render_details_scroll_button(cairo, nag, &nag->details.button_down); } From 7ec7a322d24f488515e307c4babe6b0536c493c8 Mon Sep 17 00:00:00 2001 From: stormshadow <190884359+st0rm-shad0w@users.noreply.github.com> Date: Tue, 28 Apr 2026 02:09:44 +0530 Subject: [PATCH 098/146] labnag: remove doubled border between scroll buttons and adjust text position Each scroll button draws its own full border, so placing the up and down buttons flush produced a divider twice the intended thickness. Shift button_down up by one border width and extend its height accordingly so its top border overlaps button_up's bottom border. Also drop a stray \`+ border\` offset from the scroll button text Y-position that was pushing the label below the button's center. --- clients/labnag.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/labnag.c b/clients/labnag.c index a3a526c5..8d47ee29 100644 --- a/clients/labnag.c +++ b/clients/labnag.c @@ -318,7 +318,7 @@ render_details_scroll_button(cairo_t *cairo, struct nag *nag, cairo_set_source_u32(cairo, nag->conf->button_text); cairo_move_to(cairo, button->x + border + padding, - button->y + border + (button->height - text_height) / 2); + button->y + (button->height - text_height) / 2); render_text(cairo, nag->conf->font_description, 1, true, "%s", button->text); } @@ -415,10 +415,10 @@ render_detailed(cairo_t *cairo, struct nag *nag, uint32_t y) nag->details.button_down.x = nag->details.x + nag->details.width; nag->details.button_down.y = - nag->details.button_up.y + nag->details.button_up.height; + nag->details.button_up.y + nag->details.button_up.height - border; nag->details.button_down.width = button_width; nag->details.button_down.height = - border_rect_height - nag->details.button_up.height; + border_rect_height - nag->details.button_up.height + border; render_details_scroll_button(cairo, nag, &nag->details.button_down); } From 998fd807373ee7e28cc88717f5f20dd3f4a0c342 Mon Sep 17 00:00:00 2001 From: Jos Dehaes Date: Wed, 29 Apr 2026 11:14:21 +0200 Subject: [PATCH 099/146] session: run activation env update synchronously dbus-update-activation-environment and systemctl --user import-environment were fired asynchronously via spawn_async_no_shell, racing with the autostart script. Any systemd user service started from autostart (e.g. via labwc-session.target) could start before the import completed, leaving WAYLAND_DISPLAY and related variables absent from its environment and those of any apps it launches. Run both commands synchronously via a new spawn_sync_no_shell helper so the import is guaranteed to complete before the autostart script executes. --- include/common/spawn.h | 6 ++++++ src/common/spawn.c | 32 ++++++++++++++++++++++++++++++++ src/config/session.c | 4 ++-- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/include/common/spawn.h b/include/common/spawn.h index 43123269..4df5ed0b 100644 --- a/include/common/spawn.h +++ b/include/common/spawn.h @@ -16,6 +16,12 @@ pid_t spawn_primary_client(const char *command); */ void spawn_async_no_shell(char const *command); +/** + * spawn_sync_no_shell - execute synchronously + * @command: command to be executed + */ +void spawn_sync_no_shell(char const *command); + /** * spawn_piped - execute asynchronously * @command: command to be executed diff --git a/src/common/spawn.c b/src/common/spawn.c index 898c4800..a703bee5 100644 --- a/src/common/spawn.c +++ b/src/common/spawn.c @@ -89,6 +89,38 @@ out: g_strfreev(argv); } +void +spawn_sync_no_shell(char const *command) +{ + GError *err = NULL; + gchar **argv = NULL; + + assert(command); + + g_shell_parse_argv((gchar *)command, NULL, &argv, &err); + if (err) { + g_message("%s", err->message); + g_error_free(err); + return; + } + + pid_t child = fork(); + switch (child) { + case -1: + wlr_log(WLR_ERROR, "unable to fork()"); + goto out; + case 0: + reset_signals_and_limits(); + execvp(argv[0], argv); + _exit(1); + default: + waitpid(child, NULL, 0); + break; + } +out: + g_strfreev(argv); +} + pid_t spawn_primary_client(const char *command) { diff --git a/src/config/session.c b/src/config/session.c index 7df6236c..61ce156f 100644 --- a/src/config/session.c +++ b/src/config/session.c @@ -219,12 +219,12 @@ execute_update(const char *env_keys, const char *env_unset_keys, bool initialize char *cmd = strdup_printf("dbus-update-activation-environment %s", initialize ? env_keys : env_unset_keys); - spawn_async_no_shell(cmd); + spawn_sync_no_shell(cmd); free(cmd); cmd = strdup_printf("systemctl --user %s %s", initialize ? "import-environment" : "unset-environment", env_keys); - spawn_async_no_shell(cmd); + spawn_sync_no_shell(cmd); free(cmd); } From def6ff22d32c00c1291d0ee4e24b8fa9c78f67ff Mon Sep 17 00:00:00 2001 From: Jos Dehaes Date: Wed, 29 Apr 2026 14:38:05 +0200 Subject: [PATCH 100/146] session: drop goto label from spawn_sync_no_shell Replace goto out with break since g_strfreev follows the switch directly. Co-Authored-By: Claude Sonnet 4.6 --- src/common/spawn.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/common/spawn.c b/src/common/spawn.c index a703bee5..6073d6ae 100644 --- a/src/common/spawn.c +++ b/src/common/spawn.c @@ -108,7 +108,7 @@ spawn_sync_no_shell(char const *command) switch (child) { case -1: wlr_log(WLR_ERROR, "unable to fork()"); - goto out; + break; case 0: reset_signals_and_limits(); execvp(argv[0], argv); @@ -117,7 +117,6 @@ spawn_sync_no_shell(char const *command) waitpid(child, NULL, 0); break; } -out: g_strfreev(argv); } From df9537c809c859adf264dc4e4c171f4f14006454 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Wed, 29 Apr 2026 20:04:23 +0100 Subject: [PATCH 101/146] NEWS.md: interim update --- NEWS.md | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index ac001850..997f4068 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,7 +9,7 @@ The format is based on [Keep a Changelog] | Date | All Changes | wlroots version | lines-of-code | |------------|---------------|-----------------|---------------| -| 2026-04-17 | [unreleased] | 0.20.0 | 27753 | +| 2026-04-29 | [unreleased] | 0.20.0 | 27849 | | 2026-04-17 | [0.9.7] | 0.19.2 | 29277 | | 2026-03-15 | [0.9.6] | 0.19.2 | 29271 | | 2026-03-04 | [0.9.5] | 0.19.2 | 29251 | @@ -125,6 +125,14 @@ Note to maintainers: ### Added +- Add labnag options `--details-border-color` and `--details-margin` + @st0rm-shad0w [#3527] +- Add config option `` to defer raise-on-focus by a + small amount when `raiseOnFocus` is enabled @joske [#3513] +- Install `labwc-session.target` systemd user unit when the systemd dependency + is available @joske [#3534] +- Add `onbutton` to config option ``. Also add + associated option ``. @diniamo [#3540] - Add `overrideInhibition` option to `` [#3507] @drougas - Add action `ToggleShowDesktop` to hide/unhide windows [#3500] @johanmalm - Add `` config option so that privileged protocols can be @@ -139,6 +147,11 @@ Note to maintainers: ### Fixed +- Run session activation environment update synchronously to avoid a race + condition with the autostart script [#3543] @joske +- Allow interactive resize on fully maximized windows so that a resize + initiated by modifier plus right-mouse-button-drag is not ignored [#3525] + @bjorn - Gracefully handle missing XWayland packages, so that a labwc compositor which has been built with XWayland support (which is optional) can be run even if XWayland is not installed. [#3401] @quite @@ -162,6 +175,8 @@ Note to maintainers: ### Changed +- Change the default keybinds for XF86Audio{LowerVolume,RaiseVolume,Mute} to use + pactl instead of amixer [#3484] @danielrrrr - Drop cosmic-workspace protocol [#3031] @tokyo4j ## 0.9.7 - 2026-04-17 @@ -3270,6 +3285,7 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 [#3446]: https://github.com/labwc/labwc/pull/3446 [#3450]: https://github.com/labwc/labwc/pull/3450 [#3469]: https://github.com/labwc/labwc/pull/3469 +[#3484]: https://github.com/labwc/labwc/pull/3484 [#3490]: https://github.com/labwc/labwc/pull/3490 [#3493]: https://github.com/labwc/labwc/pull/3493 [#3494]: https://github.com/labwc/labwc/pull/3494 @@ -3278,3 +3294,9 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 [#3502]: https://github.com/labwc/labwc/pull/3502 [#3507]: https://github.com/labwc/labwc/pull/3507 [#3511]: https://github.com/labwc/labwc/pull/3511 +[#3513]: https://github.com/labwc/labwc/pull/3513 +[#3525]: https://github.com/labwc/labwc/pull/3525 +[#3527]: https://github.com/labwc/labwc/pull/3527 +[#3534]: https://github.com/labwc/labwc/pull/3534 +[#3540]: https://github.com/labwc/labwc/pull/3540 +[#3543]: https://github.com/labwc/labwc/pull/3543 From bc7498dc6ffd634a2fb3888fc79addc2373890d5 Mon Sep 17 00:00:00 2001 From: elviosak <33790211+elviosak@users.noreply.github.com> Date: Fri, 1 May 2026 08:52:17 -0300 Subject: [PATCH 102/146] fix chromium popup on maximized window --- src/xdg-popup.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/xdg-popup.c b/src/xdg-popup.c index 04f82f9e..8e6870af 100644 --- a/src/xdg-popup.c +++ b/src/xdg-popup.c @@ -43,10 +43,13 @@ popup_unconstrain(struct xdg_popup *popup) * than zero, typically with Qt apps. We therefore clamp it to avoid for * example the 'File' menu of a maximized window to end up on an another * output. + * Also some apps open the menu exactly at the right border when maximized, + * causing popup_box->x (or y?) to be in the next output. We subtract one + * inside MAX to avoid the problem mentioned above. */ struct wlr_box *popup_box = &popup->wlr_popup->scheduled.geometry; - struct output *output = output_nearest_to(parent_lx + MAX(popup_box->x, 0), - parent_ly + MAX(popup_box->y, 0)); + struct output *output = output_nearest_to(parent_lx + MAX(popup_box->x - 1, 0), + parent_ly + MAX(popup_box->y - 1, 0)); struct wlr_box usable = output_usable_area_in_layout_coords(output); /* Get offset of toplevel window from its surface */ From 6ce25978e7328ee7263ad7642e942f68c792914f Mon Sep 17 00:00:00 2001 From: elviosak <33790211+elviosak@users.noreply.github.com> Date: Tue, 28 Apr 2026 22:42:39 -0300 Subject: [PATCH 103/146] Add Next/PreviousWindowImmediate to switch windows without OSD Co-authored-by: @johanmalm --- docs/labwc-actions.5.scd | 7 ++++- include/cycle.h | 4 +++ include/view.h | 2 ++ src/action.c | 19 ++++++++++++++ src/cycle/cycle.c | 55 ++++++++++++++++++++++++++++++++++++++++ src/view.c | 10 ++++---- src/window-rules.c | 6 ++--- 7 files changed, 94 insertions(+), 9 deletions(-) diff --git a/docs/labwc-actions.5.scd b/docs/labwc-actions.5.scd index fb616340..47ee1801 100644 --- a/docs/labwc-actions.5.scd +++ b/docs/labwc-actions.5.scd @@ -126,13 +126,18 @@ Actions are used in menus and keyboard/mouse bindings. position if it had been maximized or tiled to a direction or region. **++ -** +**++ +**++ +**++ Cycle focus to next/previous window, respectively. Default keybinds for NextWindow and PreviousWindow are Alt-Tab and Shift-Alt-Tab. While cycling through windows, the arrow keys move the selected window forwards/backwards and the escape key halts the cycling. + NextWindowImmediate and PreviousWindowImmediate skip the Window Switcher + and OSD, useful for binding to keys without modifiers. + *workspace* [all|current] This determines whether to cycle through windows on all workspaces or the current workspace. Default is "current". diff --git a/include/cycle.h b/include/cycle.h index 9bb4cb69..440b938f 100644 --- a/include/cycle.h +++ b/include/cycle.h @@ -103,6 +103,10 @@ void cycle_finish(bool switch_focus); /* Re-initialize the window switcher */ void cycle_reinitialize(void); +/* Immediately cycle to next/previous window */ +void cycle_immediate(enum lab_cycle_dir direction, + struct cycle_filter filter); + /* Focus the clicked window and close OSD */ void cycle_on_cursor_release(struct wlr_scene_node *node); diff --git a/include/view.h b/include/view.h index da7aef02..a179338e 100644 --- a/include/view.h +++ b/include/view.h @@ -630,4 +630,6 @@ enum lab_placement_policy view_placement_parse(const char *policy); /* xdg.c */ struct wlr_xdg_surface *xdg_surface_from_view(struct view *view); +bool view_matches_criteria(struct view *view, enum lab_view_criteria criteria); + #endif /* LABWC_VIEW_H */ diff --git a/src/action.c b/src/action.c index 34435e02..daf8fb30 100644 --- a/src/action.c +++ b/src/action.c @@ -84,6 +84,8 @@ struct action_arg_list { X(SHRINK_TO_EDGE, "ShrinkToEdge") \ X(NEXT_WINDOW, "NextWindow") \ X(PREVIOUS_WINDOW, "PreviousWindow") \ + X(NEXT_WINDOW_IMMEDIATE, "NextWindowImmediate") \ + X(PREVIOUS_WINDOW_IMMEDIATE, "PreviousWindowImmediate") \ X(RECONFIGURE, "Reconfigure") \ X(SHOW_MENU, "ShowMenu") \ X(TOGGLE_MAXIMIZE, "ToggleMaximize") \ @@ -337,6 +339,8 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char break; case ACTION_TYPE_NEXT_WINDOW: case ACTION_TYPE_PREVIOUS_WINDOW: + case ACTION_TYPE_NEXT_WINDOW_IMMEDIATE: + case ACTION_TYPE_PREVIOUS_WINDOW_IMMEDIATE: if (!strcasecmp(argument, "workspace")) { if (!strcasecmp(content, "all")) { action_arg_add_int(action, argument, CYCLE_WORKSPACE_ALL); @@ -1146,6 +1150,21 @@ run_action(struct view *view, struct action *action, } break; } + case ACTION_TYPE_NEXT_WINDOW_IMMEDIATE: + case ACTION_TYPE_PREVIOUS_WINDOW_IMMEDIATE: { + enum lab_cycle_dir dir = (action->type == ACTION_TYPE_NEXT_WINDOW_IMMEDIATE) ? + LAB_CYCLE_DIR_FORWARD : LAB_CYCLE_DIR_BACKWARD; + struct cycle_filter filter = { + .workspace = action_get_int(action, "workspace", + rc.window_switcher.workspace_filter), + .output = action_get_int(action, "output", + CYCLE_OUTPUT_ALL), + .app_id = action_get_int(action, "identifier", + CYCLE_APP_ID_ALL), + }; + cycle_immediate(dir, filter); + break; + } case ACTION_TYPE_RECONFIGURE: kill(getpid(), SIGHUP); break; diff --git a/src/cycle/cycle.c b/src/cycle/cycle.c index 2649f1e5..14682c9f 100644 --- a/src/cycle/cycle.c +++ b/src/cycle/cycle.c @@ -322,6 +322,61 @@ handle_osd_tree_destroy(struct wl_listener *listener, void *data) free(osd_output); } +static struct wl_list *prev(struct wl_list *elm) { return elm->prev; } +static struct wl_list *next(struct wl_list *elm) { return elm->next; } + +void +cycle_immediate(enum lab_cycle_dir direction, struct cycle_filter filter) +{ + if (wl_list_empty(&server.views)) { + return; + } + enum lab_view_criteria criteria = + LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER + | LAB_VIEW_CRITERIA_NO_DIALOG; + if (filter.workspace == CYCLE_WORKSPACE_CURRENT) { + criteria |= LAB_VIEW_CRITERIA_CURRENT_WORKSPACE; + } + uint64_t cycle_outputs = get_outputs_by_filter(filter.output); + const char *cycle_app_id = NULL; + if (filter.app_id == CYCLE_APP_ID_CURRENT && server.active_view) { + cycle_app_id = server.active_view->app_id; + } + + struct wl_list *head = &server.views; + struct wl_list *(*iter)(struct wl_list *list); + iter = direction == LAB_CYCLE_DIR_FORWARD ? next : prev; + + struct wl_list *from = (direction == LAB_CYCLE_DIR_FORWARD) && server.active_view + ? &server.active_view->link : head; + + for (struct wl_list *elm = iter(from); elm != head; elm = iter(elm)) { + struct view *view = wl_container_of(elm, view, link); + if (!view_matches_criteria(view, criteria)) { + continue; + } + if (filter.output != CYCLE_OUTPUT_ALL) { + if (!view->output || !(cycle_outputs & view->output->id_bit)) { + continue; + } + } + if (cycle_app_id && strcmp(view->app_id, cycle_app_id) != 0) { + continue; + } + if (server.active_view && direction == LAB_CYCLE_DIR_FORWARD) { + /* + * When cycling forward, the current active view needs to be + * sent to back to keep the same sequence and avoid getting + * stuck in the 2 topmost views. + */ + view_move_to_back(server.active_view); + } + desktop_focus_view(view, true); + break; + } + cursor_update_focus(); +} + /* Return false on failure */ static bool init_cycle(struct cycle_filter filter) diff --git a/src/view.c b/src/view.c index 9b6604ad..bcbd366e 100644 --- a/src/view.c +++ b/src/view.c @@ -80,7 +80,7 @@ struct view_query * view_query_create(void) { struct view_query *query = znew(*query); - /* Must be synced with view_matches_criteria() in window-rules.c */ + /* Must be synced with view_matches_rule() in window-rules.c */ query->window_type = LAB_WINDOW_TYPE_INVALID; query->maximized = VIEW_AXIS_INVALID; query->decoration = LAB_SSD_MODE_INVALID; @@ -263,8 +263,8 @@ view_get_root(struct view *view) return view; } -static bool -matches_criteria(struct view *view, enum lab_view_criteria criteria) +bool +view_matches_criteria(struct view *view, enum lab_view_criteria criteria) { if (!view_is_focusable(view)) { return false; @@ -316,7 +316,7 @@ view_next(struct wl_list *head, struct view *view, enum lab_view_criteria criter for (elm = elm->next; elm != head; elm = elm->next) { view = wl_container_of(elm, view, link); - if (matches_criteria(view, criteria)) { + if (view_matches_criteria(view, criteria)) { return view; } } @@ -332,7 +332,7 @@ view_prev(struct wl_list *head, struct view *view, enum lab_view_criteria criter for (elm = elm->prev; elm != head; elm = elm->prev) { view = wl_container_of(elm, view, link); - if (matches_criteria(view, criteria)) { + if (view_matches_criteria(view, criteria)) { return view; } } diff --git a/src/window-rules.c b/src/window-rules.c index 3911be7d..f43b92f4 100644 --- a/src/window-rules.c +++ b/src/window-rules.c @@ -24,7 +24,7 @@ other_instances_exist(struct view *self, struct view_query *query) } static bool -view_matches_criteria(struct window_rule *rule, struct view *view) +view_matches_rule(struct window_rule *rule, struct view *view) { struct view_query query = { .identifier = rule->identifier, @@ -52,7 +52,7 @@ window_rules_apply(struct view *view, enum window_rule_event event) if (rule->event != event) { continue; } - if (view_matches_criteria(rule, view)) { + if (view_matches_rule(rule, view)) { actions_run(view, &rule->actions, NULL); } } @@ -81,7 +81,7 @@ window_rules_get_property(struct view *view, const char *property) * attribute would still return here if that property was asked * for. */ - if (view_matches_criteria(rule, view)) { + if (view_matches_rule(rule, view)) { if (rule->server_decoration && !strcasecmp(property, "serverDecoration")) { return rule->server_decoration; From 0ff9af4ae05b80bc09f4bf290ab7666930debf16 Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Mon, 4 May 2026 13:56:27 +0900 Subject: [PATCH 104/146] src/img/img-xpm.c: fix unused variable warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a warning in gcc16 below: ../src/img/img-xpm.c: In function ‘xpm_load_to_surface’: ../src/img/img-xpm.c:354:33: warning: variable ‘xcnt’ set but not used [-Wunused-but-set-variable=] 354 | for (int n = 0, xcnt = 0; n < wbytes; n += cpp, xcnt++) { | ^~~~ --- src/img/img-xpm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/img/img-xpm.c b/src/img/img-xpm.c index 0d251b49..3bc7a9bb 100644 --- a/src/img/img-xpm.c +++ b/src/img/img-xpm.c @@ -351,7 +351,7 @@ xpm_load_to_surface(struct file_handle *handle) goto out; } - for (int n = 0, xcnt = 0; n < wbytes; n += cpp, xcnt++) { + for (int n = 0; n < wbytes; n += cpp) { g_strlcpy(pixel_str, &buffer[n], cpp + 1); struct xpm_color *color = From 0caefa6a9e42628549fc81b8af154bedcfc51163 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 5 May 2026 10:28:52 +0200 Subject: [PATCH 105/146] Translation updates from weblate Co-authored-by: Tobias Si Co-authored-by: Weblate Translate-URL: https://translate.lxqt-project.org/projects/labwc/labwc/sr_Latn/ Translation: Labwc/labwc --- po/LINGUAS | 2 +- po/sr_Latn.po | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 po/sr_Latn.po diff --git a/po/LINGUAS b/po/LINGUAS index 70114b72..50e5157a 100644 --- a/po/LINGUAS +++ b/po/LINGUAS @@ -1 +1 @@ -ar ca cs da de el es et eu fa fi fr gl he hr hu id it ja ka kab kk ko lt ms nl pa pl pt pt_BR ru sk sv tr uk vi zh_CN zh_TW +ar ca cs da de el es et eu fa fi fr gl he hr hu id it ja ka kab kk ko lt ms nl pa pl pt pt_BR ru sk sr_Latn sv tr uk vi zh_CN zh_TW diff --git a/po/sr_Latn.po b/po/sr_Latn.po new file mode 100644 index 00000000..ef41f62e --- /dev/null +++ b/po/sr_Latn.po @@ -0,0 +1,81 @@ +# Labwc pot file +# Copyright (C) 2024 +# This file is distributed under the same license as the labwc package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: labwc\n" +"Report-Msgid-Bugs-To: https://github.com/labwc/labwc/issues\n" +"POT-Creation-Date: 2024-09-19 21:09+1000\n" +"PO-Revision-Date: 2026-05-05 08:28+0000\n" +"Last-Translator: Tobias Si \n" +"Language-Team: Serbian (latin) \n" +"Language: sr_Latn\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 4.2.1\n" + +#: src/menu/menu.c:1016 +msgid "Go there..." +msgstr "Idi tamo..." + +#: src/menu/menu.c:1034 +msgid "Terminal" +msgstr "Terminal" + +#: src/menu/menu.c:1040 +msgid "Reconfigure" +msgstr "Podesi" + +#: src/menu/menu.c:1042 +msgid "Exit" +msgstr "Izlaz" + +#: src/menu/menu.c:1056 +msgid "Minimize" +msgstr "Minimiziraj" + +#: src/menu/menu.c:1058 +msgid "Maximize" +msgstr "Maksimiziraj" + +#: src/menu/menu.c:1060 +msgid "Fullscreen" +msgstr "Prikaz preko celog ekrana" + +#: src/menu/menu.c:1062 +msgid "Roll Up/Down" +msgstr "Prevuci Gore/Dole" + +#: src/menu/menu.c:1064 +msgid "Decorations" +msgstr "Dekoracije" + +#: src/menu/menu.c:1066 +msgid "Always on Top" +msgstr "Uvek na vrhu" + +#: src/menu/menu.c:1071 +msgid "Move Left" +msgstr "Pomeri levo" + +#: src/menu/menu.c:1078 +msgid "Move Right" +msgstr "Pomeri desno" + +#: src/menu/menu.c:1083 +msgid "Always on Visible Workspace" +msgstr "Uvek na vidljivom radnom prostoru" + +#: src/menu/menu.c:1086 +msgid "Workspace" +msgstr "Radni prostor" + +#: src/menu/menu.c:1089 +msgid "Close" +msgstr "Zatvori" From 07a0a4e59b02b7a0679c938080d6bb35b9ad3183 Mon Sep 17 00:00:00 2001 From: Alex Chernika Date: Sun, 26 Apr 2026 12:33:54 +0200 Subject: [PATCH 106/146] scaled-buffer: introduce `scaled_font_buffer_update_markup()` This function behaves identically to `scaled_font_buffer_update()` but allows setting the text as pango markup, supporting further customization like underscores. --- include/common/font.h | 4 +++- include/scaled-buffer/scaled-font-buffer.h | 15 +++++++++++-- src/common/font.c | 10 +++++++-- src/scaled-buffer/scaled-font-buffer.c | 26 ++++++++++++++++++---- 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/include/common/font.h b/include/common/font.h index a7a5ba55..22be2ae8 100644 --- a/include/common/font.h +++ b/include/common/font.h @@ -4,6 +4,7 @@ #include #include +#include struct lab_data_buffer; @@ -43,10 +44,11 @@ void font_get_buffer_size(int max_width, const char *text, struct font *font, * @font: font description * @color: foreground color in rgba format * @bg_pattern: background pattern + * @use_markup: flag to render pango markup */ void font_buffer_create(struct lab_data_buffer **buffer, int max_width, int height, const char *text, struct font *font, const float *color, - cairo_pattern_t *bg_pattern, double scale); + cairo_pattern_t *bg_pattern, double scale, bool use_markup); /** * font_finish - free some font related resources diff --git a/include/scaled-buffer/scaled-font-buffer.h b/include/scaled-buffer/scaled-font-buffer.h index a5e95087..2f0fe422 100644 --- a/include/scaled-buffer/scaled-font-buffer.h +++ b/include/scaled-buffer/scaled-font-buffer.h @@ -15,6 +15,7 @@ struct scaled_font_buffer { /* Private */ char *text; + bool use_markup; int max_width; float color[4]; float bg_color[4]; @@ -69,8 +70,18 @@ scaled_font_buffer_create_for_titlebar(struct wlr_scene_tree *parent, * bg_color is ignored for font buffers created with * scaled_font_buffer_create_for_titlebar(). */ -void scaled_font_buffer_update(struct scaled_font_buffer *self, const char *text, - int max_width, struct font *font, const float *color, +void scaled_font_buffer_update(struct scaled_font_buffer *self, + const char *text, int max_width, struct font *font, const float *color, const float *bg_color); +/** + * Update an existing auto scaling font buffer allowing the use of pango markup. + * + * Behaves identically to scaled_font_buffer_update(), but allows customization + * of the `use_markup` field of the @self struct via @use_markup. + */ +void scaled_font_buffer_update_markup(struct scaled_font_buffer *self, + const char *text, int max_width, struct font *font, const float *color, + const float *bg_color, bool use_markup); + #endif /* LABWC_SCALED_FONT_BUFFER_H */ diff --git a/src/common/font.c b/src/common/font.c index b307729c..5162d284 100644 --- a/src/common/font.c +++ b/src/common/font.c @@ -79,7 +79,7 @@ font_get_buffer_size(int max_width, const char *text, struct font *font, void font_buffer_create(struct lab_data_buffer **buffer, int max_width, int height, const char *text, struct font *font, const float *color, - cairo_pattern_t *bg_pattern, double scale) + cairo_pattern_t *bg_pattern, double scale, bool use_markup) { if (string_null_or_empty(text)) { return; @@ -123,7 +123,13 @@ font_buffer_create(struct lab_data_buffer **buffer, int max_width, PangoLayout *layout = pango_cairo_create_layout(cairo); pango_context_set_round_glyph_positions(pango_layout_get_context(layout), false); pango_layout_set_width(layout, width * PANGO_SCALE); - pango_layout_set_text(layout, text, -1); + + if (use_markup) { + pango_layout_set_markup(layout, text, -1); + } else { + pango_layout_set_text(layout, text, -1); + } + pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); if (!opaque_bg) { diff --git a/src/scaled-buffer/scaled-font-buffer.c b/src/scaled-buffer/scaled-font-buffer.c index bb93fc67..c748c00c 100644 --- a/src/scaled-buffer/scaled-font-buffer.c +++ b/src/scaled-buffer/scaled-font-buffer.c @@ -26,7 +26,7 @@ _create_buffer(struct scaled_buffer *scaled_buffer, double scale) /* Buffer gets free'd automatically along the backing wlr_buffer */ font_buffer_create(&buffer, self->max_width, self->height, self->text, - &self->font, self->color, bg_pattern, scale); + &self->font, self->color, bg_pattern, scale, self->use_markup); if (!buffer) { wlr_log(WLR_ERROR, "font_buffer_create() failed"); @@ -56,6 +56,7 @@ _equal(struct scaled_buffer *scaled_buffer_a, struct scaled_font_buffer *b = scaled_buffer_b->data; return str_equal(a->text, b->text) + && a->use_markup == b->use_markup && a->max_width == b->max_width && str_equal(a->font.name, b->font.name) && a->font.size == b->font.size @@ -104,10 +105,10 @@ scaled_font_buffer_create_for_titlebar(struct wlr_scene_tree *parent, return self; } -void -scaled_font_buffer_update(struct scaled_font_buffer *self, const char *text, +static void +_scaled_font_buffer_update(struct scaled_font_buffer *self, const char *text, int max_width, struct font *font, const float *color, - const float *bg_color) + const float *bg_color, bool use_markup) { assert(self); assert(text); @@ -120,6 +121,7 @@ scaled_font_buffer_update(struct scaled_font_buffer *self, const char *text, /* Update internal state */ self->text = xstrdup(text); + self->use_markup = use_markup; self->max_width = max_width; if (font->name) { self->font.name = xstrdup(font->name); @@ -139,3 +141,19 @@ scaled_font_buffer_update(struct scaled_font_buffer *self, const char *text, scaled_buffer_request_update(self->scaled_buffer, self->width, self->height); } + +void +scaled_font_buffer_update(struct scaled_font_buffer *self, const char *text, + int max_width, struct font *font, const float *color, + const float *bg_color) +{ + _scaled_font_buffer_update(self, text, max_width, font, color, bg_color, false); +} + +void +scaled_font_buffer_update_markup(struct scaled_font_buffer *self, const char *text, + int max_width, struct font *font, const float *color, + const float *bg_color, bool use_markup) +{ + _scaled_font_buffer_update(self, text, max_width, font, color, bg_color, use_markup); +} From 3632c6703a3fcd4545632ed62a1d635a92a60077 Mon Sep 17 00:00:00 2001 From: Alex Chernika Date: Fri, 10 Apr 2026 14:52:24 +0200 Subject: [PATCH 107/146] menu: implement menu accelerators Menu accelerators are one-letter mnemonics to quickly select/exec items from the current menu. For each menu item, the accelerator is defined as the first character of the item label, converted to lowercase. A different accelerator can be explicitly defined in menu.xml with the special '_' character before the target letter. - Add a field `accelerator` to the `menuitem` struct - Implement `menu_item_select_by_accelerator()` Example: The accelerator for an item with the label "e_macs" is 'm'. --- docs/labwc-menu.5.scd | 15 +++++ include/menu/menu.h | 17 ++++- src/input/keyboard.c | 17 +++-- src/menu/menu.c | 149 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 190 insertions(+), 8 deletions(-) diff --git a/docs/labwc-menu.5.scd b/docs/labwc-menu.5.scd index cf7ccbc7..df04ccf9 100644 --- a/docs/labwc-menu.5.scd +++ b/docs/labwc-menu.5.scd @@ -148,6 +148,21 @@ obmenu-generator with the menu generator of your choice): ``` +# ACCELERATORS / MNEMONICS + +Menu accelerators are one-letter mnemonics to quickly select/exec items from +the current menu. For each menu item, the accelerator is defined as the first +character of the item label, converted to lowercase. A different accelerator +can be explicitly defined in menu.xml with the special '\_' character before the +target letter. Accelerators can be any unicode character and are not limited to +ASCII. A usual underscore can be shown by duplicating it. + +If the menu only contains a single instance of the pressed accelerator the item +will be executed directly. Otherwise, all matching items are cycled through. + +Example: +The accelerator for an item with the label "e_Macs" is 'm'. + # LOCALISATION Available localisation for the default "client-menu" is only shown if no diff --git a/include/menu/menu.h b/include/menu/menu.h index 46bbca12..3d546efa 100644 --- a/include/menu/menu.h +++ b/include/menu/menu.h @@ -23,9 +23,11 @@ struct menuitem { char *text; char *icon_name; const char *arrow; + uint32_t accelerator; struct menu *parent; struct menu *submenu; bool selectable; + bool use_markup; enum menuitem_type type; int native_width; struct wlr_scene_tree *tree; @@ -66,6 +68,19 @@ struct menu { /* For keyboard support */ void menu_item_select_next(void); void menu_item_select_previous(void); + +/** + * menu_item_select_by_accelerator - selects the next menu item with + * a matching accelerator, starting after the current selection + * + * @accelerator a shortcut to quickly select/open an item, defined in menu.xml + * with an underscore in the item label before the target letter. + * + * Return: a boolean value that represents whether the newly selected item + * needs to be executed. + */ +bool menu_item_select_by_accelerator(uint32_t accelerator); + void menu_submenu_enter(void); void menu_submenu_leave(void); bool menu_call_selected_actions(void); @@ -100,7 +115,7 @@ void menu_open_root(struct menu *menu, int x, int y); void menu_process_cursor_motion(struct wlr_scene_node *node); /** - * menu_close_root- close root menu + * menu_close_root - close root menu * * This function will close server.menu_current and set it to NULL. * Asserts that server.input_mode is set to LAB_INPUT_STATE_MENU. diff --git a/src/input/keyboard.c b/src/input/keyboard.c index 98be5d11..36884144 100644 --- a/src/input/keyboard.c +++ b/src/input/keyboard.c @@ -444,15 +444,24 @@ handle_menu_keys(struct keysyms *syms) break; case XKB_KEY_Return: case XKB_KEY_KP_Enter: - menu_call_selected_actions(); + if (!menu_call_selected_actions()) { + menu_submenu_enter(); + }; break; case XKB_KEY_Escape: menu_close_root(); cursor_update_focus(); break; - default: - continue; - } + default: { + uint32_t accelerator = xkb_keysym_to_utf32(syms->syms[i]); + if (accelerator == 0) { + continue; + } + if (menu_item_select_by_accelerator(accelerator)) { + menu_call_selected_actions(); + } + break; + }} break; } } diff --git a/src/menu/menu.c b/src/menu/menu.c index 251f9a30..7b132806 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -2,12 +2,16 @@ #define _POSIX_C_SOURCE 200809L #include "menu/menu.h" #include +#include #include +#include #include #include #include #include +#include #include +#include #include #include #include @@ -129,6 +133,91 @@ validate(void) } } +static uint32_t +get_unicode_char(const char *first_byte, size_t *out_bytes) +{ + if (!first_byte || first_byte[0] == '\0') { + *out_bytes = 0; + return 0; + } + + /* Temporarily set locale to UTF-8 */ + locale_t utf8_locale = newlocale(LC_CTYPE_MASK, "C.UTF-8", (locale_t)0); + locale_t old_locale = (locale_t)0; + if (utf8_locale != (locale_t)0) { + old_locale = uselocale(utf8_locale); + } + + uint32_t result = 0; + char32_t codepoint = 0; + mbstate_t state = {0}; + size_t bytes = mbrtoc32(&codepoint, first_byte, 4, &state); + if (bytes > 0 && bytes <= 4) { + *out_bytes = bytes; + result = (uint32_t)towlower((wint_t)codepoint); + } else { + *out_bytes = 1; + result = (uint32_t)(unsigned char)first_byte[0]; + } + + /* Restore previous locale */ + if (utf8_locale != (locale_t)0) { + uselocale(old_locale); + freelocale(utf8_locale); + } + + return result; +} + +static void +item_parse_accelerator(struct menuitem *item, const char *text) +{ + const char *accel_ptr = NULL; + char *underscore = strchr(text, '_'); + while (underscore) { + if (underscore[1] == '_') { + /* Ignore escaped underscores */ + underscore = strchr(underscore + 2, '_'); + } else if (underscore[1] != '\0') { + /* Found a valid accelerator */ + accel_ptr = underscore + 1; + break; + } else { + /* Ignore empty accelertor */ + break; + } + } + + size_t bytes = 0; + if (!accel_ptr) { + item->text = xstrdup(text); + item->accelerator = get_unicode_char(text, &bytes); + } else { + item->use_markup = true; + item->accelerator = get_unicode_char(accel_ptr, &bytes); + item->text = strdup_printf("%.*s%.*s%s", + /* Prefix length + prefix */ + (int)(accel_ptr - 1 - text), text, + /* Accelerator (utf-8 byte) length + accelerator */ + (int)bytes, accel_ptr, + /* Remainder */ + accel_ptr + bytes); + } + + /* Remove undescores used for escaping */ + char *src = item->text; + char *dst = item->text; + while (*src) { + if (*src == '_' && *(src + 1) == '_') { + *dst++ = '_'; + src += 2; + } else { + *dst++ = *src++; + } + } + *dst = '\0'; +} + static struct menuitem * item_create(struct menu *menu, const char *text, const char *icon_name, bool show_arrow) { @@ -140,8 +229,8 @@ item_create(struct menu *menu, const char *text, const char *icon_name, bool sho menuitem->parent = menu; menuitem->selectable = true; menuitem->type = LAB_MENU_ITEM; - menuitem->text = xstrdup(text); menuitem->arrow = show_arrow ? "›" : NULL; + item_parse_accelerator(menuitem, text); #if HAVE_LIBSFDO if (rc.menu_show_icons && !string_null_or_empty(icon_name)) { @@ -212,8 +301,8 @@ item_create_scene_for_state(struct menuitem *item, float *text_color, /* Create label */ struct scaled_font_buffer *label_buffer = scaled_font_buffer_create(tree); assert(label_buffer); - scaled_font_buffer_update(label_buffer, item->text, label_max_width, - &rc.font_menuitem, text_color, bg_color); + scaled_font_buffer_update_markup(label_buffer, item->text, label_max_width, + &rc.font_menuitem, text_color, bg_color, item->use_markup); /* Vertically center and left-align label */ int x = theme->menu_items_padding_x + icon_width; int y = (theme->menu_item_height - label_buffer->height) / 2; @@ -1460,6 +1549,60 @@ menu_item_select_previous(void) menu_item_select(/* forward */ false); } +bool +menu_item_select_by_accelerator(uint32_t accelerator) +{ + struct menu *menu = get_selection_leaf(); + if (!menu || wl_list_empty(&menu->menuitems)) { + return false; + } + + bool needs_exec = false; + bool matched = false; + + struct menuitem *selection = menu->selection.item; + struct wl_list *start = selection ? &selection->link : &menu->menuitems; + struct wl_list *current = start; + struct menuitem *item = NULL; + struct menuitem *next_selection = NULL; + do { + current = current->next; + if (current == &menu->menuitems) { + /* Allow wrap around */ + continue; + } + item = wl_container_of(current, item, link); + if (item->accelerator == accelerator) { + if (!matched) { + /* Found first match */ + next_selection = item; + needs_exec = true; + matched = true; + } else { + /* + * Found another match, + * cycle selection instead of executing + */ + needs_exec = false; + break; + } + } + } while (current != start); + + if (!next_selection) { + return false; + } + + menu_process_item_selection(next_selection); + if (needs_exec && next_selection->submenu) { + /* Since we can't execute a submenu, enter it. */ + needs_exec = false; + menu_submenu_enter(); + } + + return needs_exec; +} + bool menu_call_selected_actions(void) { From f42e1895d41187cfca00e9cd61aeaeabbb830fbf Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Tue, 5 May 2026 19:11:34 +0100 Subject: [PATCH 108/146] buf.c: fix -fanalyze warning ../src/common/buf.c:61:28: error: write to string literal [-Werror=analyzer-write-to-string-literal] 61 | *p = '\0'; | ~~~^~~~~~ --- src/common/buf.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/common/buf.c b/src/common/buf.c index c141b62e..2a68b734 100644 --- a/src/common/buf.c +++ b/src/common/buf.c @@ -53,15 +53,14 @@ buf_expand_shell_variables(struct buf *s) if (s->data[i] == '$' && isvalid(s->data[i+1])) { /* expand environment variable */ buf_clear(&environment_variable); - buf_add(&environment_variable, s->data + i + 1); - char *p = environment_variable.data; - while (isvalid(*p)) { - ++p; + int len = 0; + while (isvalid(s->data[i + 1 + len])) { + buf_add_char(&environment_variable, s->data[i + 1 + len]); + ++len; } - *p = '\0'; - i += strlen(environment_variable.data); + i += len; strip_curly_braces(environment_variable.data); - p = getenv(environment_variable.data); + char *p = getenv(environment_variable.data); if (p) { buf_add(&tmp, p); } From ff2f243eb1b410e6f4792bdd1d1fceaeba01e612 Mon Sep 17 00:00:00 2001 From: Tomi Ollila Date: Mon, 4 May 2026 22:49:57 +0300 Subject: [PATCH 109/146] NEWS.md: typo and style fixes with help of perl(1) and codespell(1) $ perl -pi.bak -e 's,\S\K/>, />,' NEWS.md $ codespell [-i3] -L DoubleClick,inter-operability NEWS.md --- NEWS.md | 74 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/NEWS.md b/NEWS.md index 997f4068..2e0a6109 100644 --- a/NEWS.md +++ b/NEWS.md @@ -264,9 +264,9 @@ Note to package maintainers: This release requires wayland version >=1.22.90 - Add theme option window.button.hover.bg.color [#3365] @johanmalm - Implement scrollable window-switcher OSD [#3291] @tokyo4j - Support the `NextWindow` options listed below [#3271] @tokyo4j - - `` - - `` - - `` + - `` + - `` + - `` - Add config option `*` for setting the active workspace on startup. [#3265] @5trixs0f @@ -314,7 +314,7 @@ Note to package maintainers: This release requires wayland version >=1.22.90 and get keyboard focus so that they can be operated with the keyboard. An example use-case is the xfce4-panel applications-menu being opened by the command xfce4-popup-applicationsmenu. [#3165] @johanmalm - - On popup destory, return focus to whoever had it before the popop [#3165] + - On popup destroy, return focus to whoever had it before the popop [#3165] @johanmalm @tokyo4j - Unshade window if selected from client-list-combined-menu [#3345] @Amodio - Show non-dialog child windows in window-switcher [#3339] @tokyo4j @@ -348,7 +348,7 @@ A big thank you to all involved in this release. ### Added -- Add `` to optionally order windows by age +- Add `` to optionally order windows by age rather than most recent focus. @mbroemme [#3229] - Replace `` with `` to provide more granular control when configuring the size of snapping areas @@ -379,7 +379,7 @@ A big thank you to all involved in this release. [#3134] - labnag: add --keyboard-focus option @tokyo4j [#3120] - Allow window switcher to temporarily unshade windows using config option - `` @Amodio @Consolatis [#3124] + `` @Amodio @Consolatis [#3124] - For the 'classic' style window-switcher, add the following theme options: - `osd.window-switcher.style-classic.item.active.border.color` - `osd.window-switcher.style-classic.item.active.bg.color` @@ -409,7 +409,7 @@ A big thank you to all involved in this release. client surface. Fixes a regression in 885919f. @tokyo4j [#3211] - Set all foreign-toplevel initial states correctly. This is not believed to fix any particular user-issue, but just feels safer. @jlindgren90 [#3217] -- Update layer-shell client top layer visiblity on unmap instead of destroy +- Update layer-shell client top layer visibility on unmap instead of destroy because it is possible for fullscreen xwayland windows to be unmapped without being destroyed, and in this case the top layer visibility needs to be updated to unhide other layer-shell clients like panels. @jlindgren90 [#3199] @@ -421,7 +421,7 @@ A big thank you to all involved in this release. @elviosak [#3146] [#3168] - Work around client-side rounding issues at right/bottom pixel. This fixes an issue with some clients (notably Qt ones) where cursor coordinates in the - rightmost or bottom fixel are incorrectly rounded up putting them outside the + rightmost or bottom pixel are incorrectly rounded up putting them outside the surface bounds. The issue has been particularly noticeable with layer-shell clients like lxqt-panel. @jlindgren90 [#3157] [#2379] [#3099] Note: This also avoids a similar server-side rounding issue with some @@ -469,7 +469,7 @@ A big thank you to all involved in this release. when a window is using fullscreen mode. @johanmalm [#3158] - Call labnag with on-demand keyboard interactivity by default @tokyo4j [#3120] - Temporarily unshade windows when switching windows. Restore old behaviour with - `` @Amodio @Consolatis [#3124] + `` @Amodio @Consolatis [#3124] - In the classic style window-switcher, the default color of the selected window item has been changed to inherit the border color but with 15% opacity @tokyo4j [#3118] @@ -488,7 +488,7 @@ A big thank you to all involved in this release. ``. @tokyo4j [#2981] - Add `toggle` option to `GoToDesktop` action. This has the effect of going back to the last desktop if already on the target. @RainerKuemmerle [#3024] -- Add `` to allow hiding titlebar +- Add `` to allow hiding titlebar when window is maximized. @CosmicFusion @tokyo4j [#3015] - Use client-send-to-menu as 'Workspace' submenu in built-in client-menu @johanmalm [#2995] @@ -539,7 +539,7 @@ A big thank you to all involved in this release. - Change default keybind `W-` to combine cardinal directions to support resizing of windows to fill a quarter of an output. This only affects users who do not use an `rc.xml` (thereby using default keybinds) or use the - `` option. Previous behavior can be restored by setting + `` option. Previous behavior can be restored by setting `combine="no"` as shown below. [#3081] @tokyo4j ``` @@ -638,7 +638,7 @@ window.*.title.bg.colorTo.splitTo: window rule to enable this. @Consolatis @tokyo4j [#2840] - Add config option ``. This enables autoscroll (middle-click to scroll up/down) in Chromium and electron based clients - without inadvertantly pasting the primary clipboard. @johanmalm [#2832] + without inadvertently pasting the primary clipboard. @johanmalm [#2832] - Bump `xdg_shell` version from 3 to 6 @tokyo4j [#2814] - Bump `wl_compositor` version from 5 to 6 @tokyo4j [#2812] - Support tablet tool mouse buttons @jp7677 [#2778] @@ -715,7 +715,7 @@ window.*.title.bg.colorTo.splitTo: agnostic on choice of launcher. - `A-` for `MoveToEdge` because `Alt-` keybinds should be for clients to use and this one results in frequent user complaints because it prevents - some common usage patterns like alt-left/right in web browers. + some common usage patterns like alt-left/right in web browsers. - Change default titlebar menu button from a dot to an arrow @johanmalm [#2844] - When `dragLock` is set to `yes`, the drag no longer expires after a short delay (known as `Sticky` mode) as recommended by libinput [#2803]. The timeout @@ -750,7 +750,7 @@ release. - Localize desktop-entry application names used by the window switcher via `desktop_entry_name` or the `%n` specifier @tokyo4j [#2653] - Add `HideCursor` action @jp7677 [#2633] -- Support application icons in window-switcher using `` +- Support application icons in window-switcher using `` and use this by default. @tokyo4j [#2621] - Support application icons in client-list-combined-menu @tokyo4j [#2617] - Support the use of the keypad-enter key when using menu. @zeusgoose [#2610] @@ -887,7 +887,7 @@ Notes to package maintainers: closing a popup did not move the pointer focus to the main toplevel until the cursor was moved. [#2443] - Improve algorithm for menu placement with xdg-positioner [#2408] -- Do not forward IME key-release without correspinding key-press to avoid stuck +- Do not forward IME key-release without corresponding key-press to avoid stuck keys [#2437] ### Changed @@ -949,7 +949,7 @@ Notes to package maintainers: ```xml - + ``` @@ -966,8 +966,8 @@ menu.border.color: #aaaaaa ```xml - - + + ``` @@ -1097,7 +1097,7 @@ Notes to package maintainers: - Support the openbox style menus listed below. Written-by: @droc12345 1. `client-list-combined-menu` shows windows across all workspaces. This can be used with a mouse/key bind using: - `` [#2101] + `` [#2101] 2. `client-send-to` shows all workspaces that the current window can be sent to. This can additional be used within a client menu using: `` [#2152] @@ -1256,14 +1256,14 @@ have been attributed with a 'Written-by' against each relevant log entry. ```xml cascade - + ``` - Support relative tablet motion. Written-by: @jp7677 [#1962] ```xml - + ``` ### Fixed @@ -1347,7 +1347,7 @@ joint effort by @spl237 and @Consolatis. - Respect `menu.overlap.x` when using pipemenus. [#1940] - Do not try to restore windows to very small width/height on unmaximize. This fixes a bug with Thonny (Python IDE made with Tk). [#1938] -- Conditially set squared server-side decoration (SSD) corners when a view is +- Conditionally set squared server-side decoration (SSD) corners when a view is tiled. Written-by: @jp7677 [#1926] - Remember initial direction when starting window-cycling with `PreviousView`. Also make the toggling of direction when shift is pressed relative to the @@ -1371,7 +1371,7 @@ joint effort by @spl237 and @Consolatis. Chromium and Steam. [#1861] - Session-lock: fix flashing & update cursor shape. [#1858] - Remove tearing-controller listeners on destroy. [#1853] -- Handle invalid `ForEach` and `If` action cofigs. [#1838] +- Handle invalid `ForEach` and `If` action configs. [#1838] - Delay startup of applications until event loop is ready. This avoids race conditions when using autostart scripts that trigger a labwc SIGHUP. [#1588] - With `SendToDesktop` action follow=no option, ensure the topmost window is @@ -1388,7 +1388,7 @@ joint effort by @spl237 and @Consolatis. - Remove subprojects/seatd.wrap as no longer needed - Action `MoveToCursor` is deprecated in favour of: - ``. + ``. ## 0.7.2 - 2024-05-10 @@ -1405,7 +1405,7 @@ contributions from others as noted in the log. ### Added - Add `` to prevent clicks with small movements - from inadvertantly closing a menu or selecting a menu item. This is the + from inadvertently closing a menu or selecting a menu item. This is the equivalent of `` on Openbox. [#1760] - Support drop-shadows (disabled by default) for windows using server-side decorations. Written-by: @cillian64 @@ -1433,7 +1433,7 @@ window.inactive.shadow.color: #00000040 ```xml - + @@ -1475,7 +1475,7 @@ osd.window-switcher.width: 75% yes|no - + ``` @@ -1638,7 +1638,7 @@ osd.window-switcher.preview.border.color: #ffffff,#00a2ff,#ffffff ```xml - + ``` @@ -1646,7 +1646,7 @@ osd.window-switcher.preview.border.color: #ffffff,#00a2ff,#ffffff is already used by the action itself). [#1589] ```xml - + ``` - Do not deactivate window when giving keyboard focus to a non-view @@ -1711,8 +1711,8 @@ osd.window-switcher.preview.border.color: #ffffff,#00a2ff,#ffffff Written-by: @jp7677 ```xml - - + + ``` - Add tablet support including: @@ -1925,7 +1925,7 @@ relating to surface focus and keyboard issues, amongst others. - Allow referencing the current workspace in actions, for example: ```xml - + ``` ### Fixed @@ -2081,7 +2081,7 @@ relating to surface focus and keyboard issues, amongst others. ```xml - + ``` @@ -2148,9 +2148,9 @@ relating to surface focus and keyboard issues, amongst others. ```xml - + - + ``` @@ -2235,7 +2235,7 @@ Unless otherwise stated all contributions are by the core-devs ```xml - + @@ -2499,7 +2499,7 @@ reported, tested and fixed issues. Particular mentions go to @bi4k8, actions to be de-coupled from buttons. As a result, "Drag" and "DoubleClick" actions previously defined against "TitleBar" should now come under the "Title" context, for example: - `` + `` - Remove default alt-escape keybind for Exit because too many people have exited the compositor by mistake trying to get out of alt-tab cycling or similar. From 949e9ffe42e8e3721481239a1595c0d925246480 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Wed, 6 May 2026 21:17:02 +0100 Subject: [PATCH 110/146] cycle.c: put common code in get_view_criteria() --- src/cycle/cycle.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/cycle/cycle.c b/src/cycle/cycle.c index 14682c9f..d72a48ae 100644 --- a/src/cycle/cycle.c +++ b/src/cycle/cycle.c @@ -9,6 +9,7 @@ #include "common/mem.h" #include "common/scene-helpers.h" #include "config/rcxml.h" +#include "config/types.h" #include "labwc.h" #include "node.h" #include "output.h" @@ -322,6 +323,18 @@ handle_osd_tree_destroy(struct wl_listener *listener, void *data) free(osd_output); } +static enum lab_view_criteria +get_view_criteria(struct cycle_filter *filter) +{ + enum lab_view_criteria criteria = + LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER + | LAB_VIEW_CRITERIA_NO_DIALOG; + if (filter->workspace == CYCLE_WORKSPACE_CURRENT) { + criteria |= LAB_VIEW_CRITERIA_CURRENT_WORKSPACE; + } + return criteria; +} + static struct wl_list *prev(struct wl_list *elm) { return elm->prev; } static struct wl_list *next(struct wl_list *elm) { return elm->next; } @@ -331,13 +344,10 @@ cycle_immediate(enum lab_cycle_dir direction, struct cycle_filter filter) if (wl_list_empty(&server.views)) { return; } - enum lab_view_criteria criteria = - LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER - | LAB_VIEW_CRITERIA_NO_DIALOG; - if (filter.workspace == CYCLE_WORKSPACE_CURRENT) { - criteria |= LAB_VIEW_CRITERIA_CURRENT_WORKSPACE; - } + + enum lab_view_criteria criteria = get_view_criteria(&filter); uint64_t cycle_outputs = get_outputs_by_filter(filter.output); + const char *cycle_app_id = NULL; if (filter.app_id == CYCLE_APP_ID_CURRENT && server.active_view) { cycle_app_id = server.active_view->app_id; @@ -381,15 +391,8 @@ cycle_immediate(enum lab_cycle_dir direction, struct cycle_filter filter) static bool init_cycle(struct cycle_filter filter) { - enum lab_view_criteria criteria = - LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER - | LAB_VIEW_CRITERIA_NO_DIALOG; - if (filter.workspace == CYCLE_WORKSPACE_CURRENT) { - criteria |= LAB_VIEW_CRITERIA_CURRENT_WORKSPACE; - } - - uint64_t cycle_outputs = - get_outputs_by_filter(filter.output); + enum lab_view_criteria criteria = get_view_criteria(&filter); + uint64_t cycle_outputs = get_outputs_by_filter(filter.output); const char *cycle_app_id = NULL; if (filter.app_id == CYCLE_APP_ID_CURRENT && server.active_view) { From 0f5e4f8dd0e179b4e91fd8173bc96d5d9c3fba77 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Wed, 6 May 2026 21:17:35 +0100 Subject: [PATCH 111/146] cycle.c: put common code in get_cycle_app_id --- src/cycle/cycle.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/cycle/cycle.c b/src/cycle/cycle.c index d72a48ae..0f183ddc 100644 --- a/src/cycle/cycle.c +++ b/src/cycle/cycle.c @@ -335,6 +335,15 @@ get_view_criteria(struct cycle_filter *filter) return criteria; } +static const char * +get_cycle_app_id(struct cycle_filter *filter) +{ + if (filter->app_id == CYCLE_APP_ID_CURRENT && server.active_view) { + return server.active_view->app_id; + } + return NULL; +} + static struct wl_list *prev(struct wl_list *elm) { return elm->prev; } static struct wl_list *next(struct wl_list *elm) { return elm->next; } @@ -347,11 +356,7 @@ cycle_immediate(enum lab_cycle_dir direction, struct cycle_filter filter) enum lab_view_criteria criteria = get_view_criteria(&filter); uint64_t cycle_outputs = get_outputs_by_filter(filter.output); - - const char *cycle_app_id = NULL; - if (filter.app_id == CYCLE_APP_ID_CURRENT && server.active_view) { - cycle_app_id = server.active_view->app_id; - } + const char *cycle_app_id = get_cycle_app_id(&filter); struct wl_list *head = &server.views; struct wl_list *(*iter)(struct wl_list *list); @@ -393,11 +398,7 @@ init_cycle(struct cycle_filter filter) { enum lab_view_criteria criteria = get_view_criteria(&filter); uint64_t cycle_outputs = get_outputs_by_filter(filter.output); - - const char *cycle_app_id = NULL; - if (filter.app_id == CYCLE_APP_ID_CURRENT && server.active_view) { - cycle_app_id = server.active_view->app_id; - } + const char *cycle_app_id = get_cycle_app_id(&filter); struct view *view; for_each_view(view, &server.views, criteria) { From 2480a23b1949c77006a705acd88bf72a3a5ee17a Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Sat, 4 Apr 2026 16:58:05 +0200 Subject: [PATCH 112/146] common/macros: change WLR_VERSION macro to runtime evaluation --- include/common/macros.h | 8 ++++++-- include/labwc.h | 2 ++ src/main.c | 7 +++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/include/common/macros.h b/include/common/macros.h index 25226261..f3ceee82 100644 --- a/include/common/macros.h +++ b/include/common/macros.h @@ -62,7 +62,11 @@ #define BOUNDED_INT(a) ((a) < INT_MAX && (a) > INT_MIN) #endif -#define LAB_WLR_VERSION_AT_LEAST(major, minor, micro) \ - (WLR_VERSION_NUM >= (((major) << 16) | ((minor) << 8) | (micro))) +#define _LAB_CALC_WLR_VERSION_NUM(major, minor, micro) (((major) << 16) | ((minor) << 8) | (micro)) + +#define LAB_WLR_VERSION_AT_LEAST(major, minor, micro) ( \ + server.wlr_version >= _LAB_CALC_WLR_VERSION_NUM(major, minor, micro)) + +#define LAB_WLR_VERSION_LOWER(major, minor, micro) (!LAB_WLR_VERSION_AT_LEAST(major, minor, micro)) #endif /* LABWC_MACROS_H */ diff --git a/include/labwc.h b/include/labwc.h index dc4c1311..edde2771 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -148,6 +148,8 @@ struct seat { }; struct server { + uint32_t wlr_version; + struct wl_display *wl_display; struct wl_event_loop *wl_event_loop; /* Can be used for timer events */ diff --git a/src/main.c b/src/main.c index 373f4480..f36be071 100644 --- a/src/main.c +++ b/src/main.c @@ -6,6 +6,7 @@ #include #include "common/fd-util.h" #include "common/font.h" +#include "common/macros.h" #include "common/spawn.h" #include "config/rcxml.h" #include "config/session.h" @@ -164,6 +165,12 @@ main(int argc, char *argv[]) char *primary_client = NULL; enum wlr_log_importance verbosity = WLR_ERROR; + server.wlr_version = _LAB_CALC_WLR_VERSION_NUM( + wlr_version_get_major(), + wlr_version_get_minor(), + wlr_version_get_micro() + ); + int c; while (1) { int index = 0; From 2189b2be1e9449e9f9922fcd1808926df7ea4c51 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Thu, 7 May 2026 02:13:42 +0200 Subject: [PATCH 113/146] main: include wlroots version in --version string --- src/main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index f36be071..53f85623 100644 --- a/src/main.c +++ b/src/main.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "common/fd-util.h" #include "common/font.h" #include "common/macros.h" @@ -66,12 +67,15 @@ static void print_version(void) { #define FEATURE_ENABLED(feature) (HAVE_##feature ? "+" : "-") - printf("labwc %s (%sxwayland %snls %srsvg %slibsfdo)\n", + printf("labwc %s (%sxwayland %snls %srsvg %slibsfdo) running on wlroots %d.%d.%d\n", LABWC_VERSION, FEATURE_ENABLED(XWAYLAND), FEATURE_ENABLED(NLS), FEATURE_ENABLED(RSVG), - FEATURE_ENABLED(LIBSFDO) + FEATURE_ENABLED(LIBSFDO), + wlr_version_get_major(), + wlr_version_get_minor(), + wlr_version_get_micro() ); #undef FEATURE_ENABLED } From c1b11c782158bc6afdf4d6c456bfe85f94db4ec6 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Sun, 29 Mar 2026 23:52:38 -0700 Subject: [PATCH 114/146] chase wlroots: Add support for HDR10 output v2: Switch XRGB to XBGR v3: Rewrite HDR mode checking and setting v4: Restructure HDR support detection v5: Fix code style v6: Fix old style function declaration v7: This function should be declared static v8: This helper function can accept a const struct on input v9: Rebase now that 0.20 is merged v10: Rewrite with multiple color format attempts v11: Add in the parts that accidentally got left in my original color-management-v1 patch v12: Add missing function prototype v13: Apply suggested changes v14: Changed HDR application setup in new output v15: Rewrite configure_new_output to use lab_wlr_scene_output_commit v16: Fixed application of HDR on external mode or output config change v17: Fixed it for real this time instead of crashing v18: Moved the effective resolution collection, plus one style change. --- include/config/rcxml.h | 7 ++ include/output.h | 3 + src/config/rcxml.c | 13 +++ src/output-state.c | 1 + src/output.c | 208 ++++++++++++++++++++++++++++++++++++++++- 5 files changed, 228 insertions(+), 4 deletions(-) diff --git a/include/config/rcxml.h b/include/config/rcxml.h index 3ef7bd67..9c2183a8 100644 --- a/include/config/rcxml.h +++ b/include/config/rcxml.h @@ -36,6 +36,12 @@ enum tearing_mode { LAB_TEARING_FULLSCREEN_FORCED, }; +enum render_bit_depth { + LAB_RENDER_BIT_DEPTH_DEFAULT = 0, + LAB_RENDER_BIT_DEPTH_8, + LAB_RENDER_BIT_DEPTH_10, +}; + enum tiling_events_mode { LAB_TILING_EVENTS_NEVER = 0, LAB_TILING_EVENTS_REGION = 1 << 0, @@ -74,6 +80,7 @@ struct rcxml { int gap; enum adaptive_sync_mode adaptive_sync; enum tearing_mode allow_tearing; + enum render_bit_depth target_render_depth; bool auto_enable_outputs; bool reuse_output_mode; uint32_t allowed_interfaces; diff --git a/include/output.h b/include/output.h index 89d8be04..c17defa4 100644 --- a/include/output.h +++ b/include/output.h @@ -71,6 +71,9 @@ struct wlr_box output_usable_area_in_layout_coords(struct output *output); void handle_output_power_manager_set_mode(struct wl_listener *listener, void *data); void output_enable_adaptive_sync(struct output *output, bool enabled); +void output_enable_hdr(struct output *output, struct wlr_output_state *os, + bool enabled, bool silent); +void output_state_setup_hdr(struct output *output, bool silent); /** * Notifies whether a fullscreen view is displayed on the given output. diff --git a/src/config/rcxml.c b/src/config/rcxml.c index d0bb76db..0514b6c7 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -1080,6 +1080,16 @@ set_tearing_mode(const char *str, enum tearing_mode *variable) } } +static void +set_hdr_mode(const char *str, enum render_bit_depth *variable) +{ + if (parse_bool(str, -1) == 1) { + *variable = LAB_RENDER_BIT_DEPTH_10; + } else { + *variable = LAB_RENDER_BIT_DEPTH_8; + } +} + /* Returns true if the node's children should also be traversed */ static bool entry(xmlNode *node, char *nodename, char *content) @@ -1144,6 +1154,8 @@ entry(xmlNode *node, char *nodename, char *content) set_adaptive_sync_mode(content, &rc.adaptive_sync); } else if (!strcasecmp(nodename, "allowTearing.core")) { set_tearing_mode(content, &rc.allow_tearing); + } else if (!strcasecmp(nodename, "Hdr.core")) { + set_hdr_mode(content, &rc.target_render_depth); } else if (!strcasecmp(nodename, "autoEnableOutputs.core")) { set_bool(content, &rc.auto_enable_outputs); } else if (!strcasecmp(nodename, "reuseOutputMode.core")) { @@ -1518,6 +1530,7 @@ rcxml_init(void) rc.gap = 0; rc.adaptive_sync = LAB_ADAPTIVE_SYNC_DISABLED; rc.allow_tearing = LAB_TEARING_DISABLED; + rc.target_render_depth = LAB_RENDER_BIT_DEPTH_DEFAULT; rc.auto_enable_outputs = true; rc.reuse_output_mode = false; rc.allowed_interfaces = UINT32_MAX; diff --git a/src/output-state.c b/src/output-state.c index 7da1108b..37ebde8a 100644 --- a/src/output-state.c +++ b/src/output-state.c @@ -24,6 +24,7 @@ output_state_init(struct output *output) backup_config, output->wlr_output); wlr_output_head_v1_state_apply(&backup_head->state, &output->pending); + wlr_output_configuration_v1_destroy(backup_config); } diff --git a/src/output.c b/src/output.c index aea35062..29a2d5a0 100644 --- a/src/output.c +++ b/src/output.c @@ -9,6 +9,7 @@ #define _POSIX_C_SOURCE 200809L #include "output.h" #include +#include #include #include #include @@ -51,6 +52,150 @@ #include #endif +static uint32_t output_formats_8bit[] = { + /* 32 bpp RGB with 8 bit component width */ + DRM_FORMAT_XRGB8888, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_RGBX8888, + DRM_FORMAT_BGRX8888, + + DRM_FORMAT_ARGB8888, + DRM_FORMAT_ABGR8888, + DRM_FORMAT_RGBA8888, + DRM_FORMAT_BGRA8888, + + /* 24 bpp RGB */ + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, +}; + +uint32_t output_formats_10bit[] = { + /* 32 bpp RGB with 10 bit component width */ + DRM_FORMAT_XRGB2101010, + DRM_FORMAT_XBGR2101010, + DRM_FORMAT_RGBX1010102, + DRM_FORMAT_BGRX1010102, + + DRM_FORMAT_ARGB2101010, + DRM_FORMAT_ABGR2101010, + DRM_FORMAT_RGBA1010102, + DRM_FORMAT_BGRA1010102, +}; + +static bool +output_set_render_format(struct output *output, uint32_t candidates[], size_t count) +{ + for (size_t i = 0; i < count; i++) { + wlr_output_state_set_render_format(&output->pending, candidates[i]); + if (wlr_output_test_state(output->wlr_output, &output->pending)) { + return true; + } + } + return false; +} + +static bool +output_format_in_candidates(uint32_t render_format, uint32_t candidates[], size_t count) +{ + for (size_t i = 0; i < count; i++) { + if (candidates[i] == render_format) { + return true; + } + } + return false; +} + +static enum render_bit_depth +bit_depth_from_format(uint32_t render_format) +{ + if (output_format_in_candidates(render_format, output_formats_10bit, + ARRAY_SIZE(output_formats_10bit))) { + return LAB_RENDER_BIT_DEPTH_10; + } else if (output_format_in_candidates(render_format, output_formats_8bit, + ARRAY_SIZE(output_formats_8bit))) { + return LAB_RENDER_BIT_DEPTH_8; + } + return LAB_RENDER_BIT_DEPTH_DEFAULT; +} + +static enum render_bit_depth +get_config_render_bit_depth(void) +{ + return rc.target_render_depth; +} + +static bool +output_supports_hdr(const struct wlr_output *output, const char **unsupported_reason_ptr) +{ + const char *unsupported_reason = NULL; + if (!(output->supported_primaries & WLR_COLOR_NAMED_PRIMARIES_BT2020)) { + unsupported_reason = "BT2020 primaries not supported by output"; + } else if (!(output->supported_transfer_functions & + WLR_COLOR_TRANSFER_FUNCTION_ST2084_PQ)) { + unsupported_reason = "PQ transfer function not supported by output"; + } else if (!server.renderer->features.output_color_transform) { + unsupported_reason = "renderer doesn't support output color transforms"; + } + if (unsupported_reason_ptr) { + *unsupported_reason_ptr = unsupported_reason; + } + return !unsupported_reason; +} + +void +output_state_setup_hdr(struct output *output, bool silent) +{ + uint32_t render_format = output->wlr_output->render_format; + const char *unsupported_reason = NULL; + bool hdr_supported = output_supports_hdr(output->wlr_output, + &unsupported_reason); + bool hdr_succeeded = false; + + enum render_bit_depth render_bit_depth = get_config_render_bit_depth(); + if (render_bit_depth == LAB_RENDER_BIT_DEPTH_DEFAULT) { + render_bit_depth = bit_depth_from_format(render_format); + } + + if (!hdr_supported && render_bit_depth == LAB_RENDER_BIT_DEPTH_10) { + if (!silent) { + wlr_log(WLR_INFO, "Cannot enable HDR on output %s: %s", + output->wlr_output->name, unsupported_reason); + } + render_bit_depth = LAB_RENDER_BIT_DEPTH_8; + } + + if (render_bit_depth == LAB_RENDER_BIT_DEPTH_10 && + bit_depth_from_format(render_format) == render_bit_depth) { + /* 10-bit was set successfully before, try to save some + * tests by reusing the format + */ + hdr_succeeded = true; + } else if (render_bit_depth == LAB_RENDER_BIT_DEPTH_10) { + hdr_succeeded = output_set_render_format(output, output_formats_10bit, + ARRAY_SIZE(output_formats_10bit)); + if (!hdr_succeeded) { + if (!silent) { + wlr_log(WLR_INFO, "No 10 bit color formats" + " supported, HDR disabled."); + } + if (!output_set_render_format(output, output_formats_8bit, + ARRAY_SIZE(output_formats_8bit))) { + if (!silent) { + wlr_log(WLR_ERROR, "No 8 bit color formats" + " supported either!"); + } + } + } + } else { + if (!output_set_render_format(output, output_formats_8bit, + ARRAY_SIZE(output_formats_8bit)) && !silent) { + wlr_log(WLR_ERROR, "No 8 bit color formats supported!"); + } + } + + output_enable_hdr(output, &output->pending, hdr_succeeded, silent); +} + bool output_get_tearing_allowance(struct output *output) { @@ -371,10 +516,7 @@ configure_new_output(struct output *output) output_enable_adaptive_sync(output, true); } - output_state_commit(output); - - wlr_output_effective_resolution(wlr_output, - &output->usable_area.width, &output->usable_area.height); + output_state_setup_hdr(output, false); /* * Wait until wlr_output_layout_add_auto() returns before @@ -384,6 +526,19 @@ configure_new_output(struct output *output) server.pending_output_layout_change++; add_output_to_layout(output); server.pending_output_layout_change--; + + /* + * Commit the output this way instead, HDR needs a buffer, and + * this commit must be called after the output is added to the + * layout above. + */ + lab_wlr_scene_output_commit(output->scene_output, &output->pending); + + /* + * Collect the effective resolution after the final commit. + */ + wlr_output_effective_resolution(wlr_output, + &output->usable_area.width, &output->usable_area.height); } static uint64_t @@ -653,6 +808,7 @@ output_config_apply(struct wlr_output_configuration_v1 *config) wlr_output_state_set_transform(os, head->state.transform); output_enable_adaptive_sync(output, head->state.adaptive_sync_enabled); + output_state_setup_hdr(output, false); } if (!output_state_commit(output)) { /* @@ -666,6 +822,19 @@ output_config_apply(struct wlr_output_configuration_v1 *config) break; } + if (output_enabled) { + /* + * The above commit was likely made without an image + * buffer attached. This will break applying HDR color + * transformation, since image descriptions must be + * committed with a buffer attached. Queue the HDR mode + * again if output is enabled, but make it silent, + * since it would have emitted messages already when + * called above. + */ + output_state_setup_hdr(output, true); + } + /* * Add or remove output from layout only if the commit went * through. Note that at startup, the output may have already @@ -1136,3 +1305,34 @@ output_set_has_fullscreen_view(struct output *output, bool has_fullscreen_view) output_enable_adaptive_sync(output, has_fullscreen_view); output_state_commit(output); } + +void +output_enable_hdr(struct output *output, struct wlr_output_state *os, + bool enabled, bool silent) +{ + if (enabled && !output_supports_hdr(output->wlr_output, NULL)) { + enabled = false; + } + + if (!enabled) { + if (output->wlr_output->supported_primaries != 0 || + output->wlr_output->supported_transfer_functions != 0) { + if (!silent) { + wlr_log(WLR_DEBUG, "Disabling HDR on output %s", + output->wlr_output->name); + } + wlr_output_state_set_image_description(os, NULL); + } + return; + } + + if (!silent) { + wlr_log(WLR_DEBUG, "Enabling HDR on output %s", + output->wlr_output->name); + } + const struct wlr_output_image_description image_desc = { + .primaries = WLR_COLOR_NAMED_PRIMARIES_BT2020, + .transfer_function = WLR_COLOR_TRANSFER_FUNCTION_ST2084_PQ, + }; + wlr_output_state_set_image_description(os, &image_desc); +} From 38f80d716717da6f788a0b663b9078dbd77a9376 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Thu, 31 Jul 2025 22:13:02 -0700 Subject: [PATCH 115/146] Document the new HDR option v2: Remove note which is no longer applicable. --- docs/labwc-config.5.scd | 6 ++++++ docs/rc.xml.all | 1 + 2 files changed, 7 insertions(+) diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index 8ea88d8f..240f7043 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -175,6 +175,7 @@ this is for compatibility with Openbox. no no yes + no no no yes @@ -240,6 +241,11 @@ this is for compatibility with Openbox. 'pkill kanshi ; wlopm --off \*' resume 'kanshi & wlopm --on \*' ``` +** [yes|no] + Automatically enable HDR support on outputs when configuring them, + where supported by the particular output device and display. Default + is no. + ** [yes|no] Try to re-use the existing output mode (resolution / refresh rate). This may prevent unnecessary screenblank delays when starting labwc diff --git a/docs/rc.xml.all b/docs/rc.xml.all index 9755530b..54c9e300 100644 --- a/docs/rc.xml.all +++ b/docs/rc.xml.all @@ -13,6 +13,7 @@ no no yes + no no no yes From d86b2cfd0d2edd645bcb2e45c921daa73cf68026 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Fri, 8 May 2026 16:21:47 +0200 Subject: [PATCH 116/146] docs: mention Vulkan requirement for HDR config --- docs/labwc-config.5.scd | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index 240f7043..dec027dc 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -244,7 +244,8 @@ this is for compatibility with Openbox. ** [yes|no] Automatically enable HDR support on outputs when configuring them, where supported by the particular output device and display. Default - is no. + is no. Additionally requires the Vulkan backend. Can be set via + `WLR_RENDERER=vulkan` in `~/.config/labwc/enviornment`. ** [yes|no] Try to re-use the existing output mode (resolution / refresh rate). From e2f3c0328792195dfdc5e55bf1f6a668df87bcfd Mon Sep 17 00:00:00 2001 From: Alex Chernika Date: Fri, 8 May 2026 20:35:40 +0200 Subject: [PATCH 117/146] src/menu: slight clean up of menu accelerators Slight clean up of the accelerator implementation, including use of glib for utf8-parsing --- src/menu/menu.c | 76 ++++++++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/src/menu/menu.c b/src/menu/menu.c index 7b132806..2505317d 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -4,14 +4,12 @@ #include #include #include -#include #include +#include #include #include #include -#include #include -#include #include #include #include @@ -133,42 +131,33 @@ validate(void) } } +/* Read a single Unicode codepoint and convert it to lowercase */ static uint32_t -get_unicode_char(const char *first_byte, size_t *out_bytes) +read_unicode_char_lowercase(const char *first_byte, size_t *bytes_read) { - if (!first_byte || first_byte[0] == '\0') { - *out_bytes = 0; + assert(bytes_read); + + if (string_null_or_empty(first_byte)) { + *bytes_read = 0; return 0; } - /* Temporarily set locale to UTF-8 */ - locale_t utf8_locale = newlocale(LC_CTYPE_MASK, "C.UTF-8", (locale_t)0); - locale_t old_locale = (locale_t)0; - if (utf8_locale != (locale_t)0) { - old_locale = uselocale(utf8_locale); + gunichar codepoint = g_utf8_get_char_validated(first_byte, -1); + + bool partial_read = (codepoint == (gunichar)-2); + bool failed_read = (codepoint == (gunichar)-1); + if (partial_read || failed_read) { + /* Read only the first byte */ + *bytes_read = 1; + return (uint32_t)(unsigned char)first_byte[0]; } - uint32_t result = 0; - char32_t codepoint = 0; - mbstate_t state = {0}; - size_t bytes = mbrtoc32(&codepoint, first_byte, 4, &state); - if (bytes > 0 && bytes <= 4) { - *out_bytes = bytes; - result = (uint32_t)towlower((wint_t)codepoint); - } else { - *out_bytes = 1; - result = (uint32_t)(unsigned char)first_byte[0]; - } + *bytes_read = (size_t)(g_utf8_next_char(first_byte) - first_byte); - /* Restore previous locale */ - if (utf8_locale != (locale_t)0) { - uselocale(old_locale); - freelocale(utf8_locale); - } - - return result; + return (uint32_t)g_unichar_tolower(codepoint); } +/* Retrieve the accelerator from an item label */ static void item_parse_accelerator(struct menuitem *item, const char *text) { @@ -188,25 +177,35 @@ item_parse_accelerator(struct menuitem *item, const char *text) } } - size_t bytes = 0; + size_t bytes_read = 0; if (!accel_ptr) { + /* Default to the first char */ item->text = xstrdup(text); - item->accelerator = get_unicode_char(text, &bytes); + item->accelerator = read_unicode_char_lowercase(text, &bytes_read); } else { + /* Set the accelerator and remove the preceding underscore */ item->use_markup = true; - item->accelerator = get_unicode_char(accel_ptr, &bytes); + item->accelerator = read_unicode_char_lowercase(accel_ptr, &bytes_read); item->text = strdup_printf("%.*s%.*s%s", /* Prefix length + prefix */ (int)(accel_ptr - 1 - text), text, /* Accelerator (utf-8 byte) length + accelerator */ - (int)bytes, accel_ptr, + (int)bytes_read, accel_ptr, /* Remainder */ - accel_ptr + bytes); + accel_ptr + bytes_read); + } +} + +/* Remove underscores used for escaping other underscores from a string */ +static void +unescape_underscores(char *text) +{ + if (!text) { + return; } - /* Remove undescores used for escaping */ - char *src = item->text; - char *dst = item->text; + char *src = text; + char *dst = text; while (*src) { if (*src == '_' && *(src + 1) == '_') { *dst++ = '_'; @@ -231,6 +230,7 @@ item_create(struct menu *menu, const char *text, const char *icon_name, bool sho menuitem->type = LAB_MENU_ITEM; menuitem->arrow = show_arrow ? "›" : NULL; item_parse_accelerator(menuitem, text); + unescape_underscores(menuitem->text); #if HAVE_LIBSFDO if (rc.menu_show_icons && !string_null_or_empty(icon_name)) { @@ -1595,7 +1595,7 @@ menu_item_select_by_accelerator(uint32_t accelerator) menu_process_item_selection(next_selection); if (needs_exec && next_selection->submenu) { - /* Since we can't execute a submenu, enter it. */ + /* Since we can't execute a submenu, enter it */ needs_exec = false; menu_submenu_enter(); } From 90b87cb8823a18ad2995fd67e3a00152325af4e5 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Fri, 8 May 2026 20:53:46 +0200 Subject: [PATCH 118/146] docs/labwc-config: fix HDR comment syntax error Fixes 'Expected ``` and a newline to begin literal block' --- docs/labwc-config.5.scd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index dec027dc..70450e3c 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -244,8 +244,8 @@ this is for compatibility with Openbox. ** [yes|no] Automatically enable HDR support on outputs when configuring them, where supported by the particular output device and display. Default - is no. Additionally requires the Vulkan backend. Can be set via - `WLR_RENDERER=vulkan` in `~/.config/labwc/enviornment`. + is no. Additionally requires the Vulkan backend. Can be set + via `WLR_RENDERER=vulkan` in `~/.config/labwc/enviornment`. ** [yes|no] Try to re-use the existing output mode (resolution / refresh rate). From e1fdbb06118da63d3a0c103600d980885022cf94 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Fri, 8 May 2026 20:55:14 +0200 Subject: [PATCH 119/146] CI: also run CI on docs changes --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6130686b..caa54a33 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,6 +20,7 @@ on: - 'clients/**' - 't/**' - 'scripts/**' + - 'docs/**' - '.github/workflows/**' jobs: From 477b3b1ddbd46a68f0de475f622ac33e47533c42 Mon Sep 17 00:00:00 2001 From: Standreas Date: Sat, 9 May 2026 14:08:33 +0200 Subject: [PATCH 120/146] Fix typo in labwc-config.5.scd --- docs/labwc-config.5.scd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index 70450e3c..56097bca 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -245,7 +245,7 @@ this is for compatibility with Openbox. Automatically enable HDR support on outputs when configuring them, where supported by the particular output device and display. Default is no. Additionally requires the Vulkan backend. Can be set - via `WLR_RENDERER=vulkan` in `~/.config/labwc/enviornment`. + via `WLR_RENDERER=vulkan` in `~/.config/labwc/environment`. ** [yes|no] Try to re-use the existing output mode (resolution / refresh rate). From bc287686ea919579abb303570a78c00c87dd615e Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Thu, 7 May 2026 20:52:20 +0100 Subject: [PATCH 121/146] NEWS.md: interim update --- NEWS.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 2e0a6109..9a770ecc 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,7 +9,7 @@ The format is based on [Keep a Changelog] | Date | All Changes | wlroots version | lines-of-code | |------------|---------------|-----------------|---------------| -| 2026-04-29 | [unreleased] | 0.20.0 | 27849 | +| 2026-05-07 | [unreleased] | 0.20.0 | 28236 | | 2026-04-17 | [0.9.7] | 0.19.2 | 29277 | | 2026-03-15 | [0.9.6] | 0.19.2 | 29271 | | 2026-03-04 | [0.9.5] | 0.19.2 | 29251 | @@ -125,6 +125,11 @@ Note to maintainers: ### Added +- Add support for HDR10 output @kode54 @Consolatis [#3424] +- Include wlroots version in --version string @Consolatis [#3567] +- Implement menu accelerators (one-letter mnemonics to quickly select/exec + items from the current menu) @ch3rn1ka [#3505] +- Add Next/PreviousWindowImmediate actions @elviosak @johanmalm [#3547] - Add labnag options `--details-border-color` and `--details-margin` @st0rm-shad0w [#3527] - Add config option `` to defer raise-on-focus by a @@ -147,6 +152,8 @@ Note to maintainers: ### Fixed +- Position chromium popup correctly when a window is maximized on a multi- + output setup @elviosak [#3547] - Run session activation environment update synchronously to avoid a race condition with the autostart script [#3543] @joske - Allow interactive resize on fully maximized windows so that a resize @@ -3272,6 +3279,7 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 [#3410]: https://github.com/labwc/labwc/pull/3410 [#3411]: https://github.com/labwc/labwc/pull/3411 [#3412]: https://github.com/labwc/labwc/pull/3412 +[#3424]: https://github.com/labwc/labwc/pull/3424 [#3425]: https://github.com/labwc/labwc/pull/3425 [#3426]: https://github.com/labwc/labwc/pull/3426 [#3428]: https://github.com/labwc/labwc/pull/3428 @@ -3292,6 +3300,7 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 [#3499]: https://github.com/labwc/labwc/pull/3499 [#3500]: https://github.com/labwc/labwc/pull/3500 [#3502]: https://github.com/labwc/labwc/pull/3502 +[#3505]: https://github.com/labwc/labwc/pull/3505 [#3507]: https://github.com/labwc/labwc/pull/3507 [#3511]: https://github.com/labwc/labwc/pull/3511 [#3513]: https://github.com/labwc/labwc/pull/3513 @@ -3300,3 +3309,5 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 [#3534]: https://github.com/labwc/labwc/pull/3534 [#3540]: https://github.com/labwc/labwc/pull/3540 [#3543]: https://github.com/labwc/labwc/pull/3543 +[#3547]: https://github.com/labwc/labwc/pull/3547 +[#3567]: https://github.com/labwc/labwc/pull/3567 From 4b61a8a87925c4628d715bcbd471ecb4c33b3e3c Mon Sep 17 00:00:00 2001 From: stormshadow <190884359+st0rm-shad0w@users.noreply.github.com> Date: Mon, 11 May 2026 00:15:39 +0530 Subject: [PATCH 122/146] fix(labnag): add missing --exclusive-zone to getopt options --- clients/labnag.c | 1 + 1 file changed, 1 insertion(+) diff --git a/clients/labnag.c b/clients/labnag.c index 8d47ee29..60a5abb3 100644 --- a/clients/labnag.c +++ b/clients/labnag.c @@ -1592,6 +1592,7 @@ nag_parse_options(int argc, char **argv, struct nag *nag, {"message", required_argument, NULL, 'm'}, {"output", required_argument, NULL, 'o'}, {"timeout", required_argument, NULL, 't'}, + {"exclusive-zone", no_argument, NULL, 'x'}, {"version", no_argument, NULL, 'v'}, {"background-color", required_argument, NULL, TO_COLOR_BACKGROUND}, From 8473ea4b722b7f255590078ac9868538d853f5dd Mon Sep 17 00:00:00 2001 From: Tomi Ollila Date: Tue, 12 May 2026 21:23:22 +0300 Subject: [PATCH 123/146] main: update --version string --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 53f85623..501c2b7a 100644 --- a/src/main.c +++ b/src/main.c @@ -67,7 +67,7 @@ static void print_version(void) { #define FEATURE_ENABLED(feature) (HAVE_##feature ? "+" : "-") - printf("labwc %s (%sxwayland %snls %srsvg %slibsfdo) running on wlroots %d.%d.%d\n", + printf("labwc %s (%sxwayland %snls %srsvg %slibsfdo) wlroots-%d.%d.%d\n", LABWC_VERSION, FEATURE_ENABLED(XWAYLAND), FEATURE_ENABLED(NLS), From 7a53f294a8ec4e9ff49dc99ed2bb4bd04f39f3cc Mon Sep 17 00:00:00 2001 From: massi Date: Sun, 10 May 2026 17:40:53 -0700 Subject: [PATCH 124/146] output.c: use env var LABWC_TITLE to set nested labwc window title Introduces an environment variable LABWC_TITLE, which, when set, will be used to set the title of a nested instance of labwc. --- src/output.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/output.c b/src/output.c index 29a2d5a0..1139aca2 100644 --- a/src/output.c +++ b/src/output.c @@ -606,7 +606,11 @@ handle_new_output(struct wl_listener *listener, void *data) if (wlr_output_is_wl(wlr_output)) { char title[64]; - snprintf(title, sizeof(title), "%s - %s", "labwc", wlr_output->name); + if (getenv("LABWC_TITLE")) { + snprintf(title, sizeof(title), "%s", getenv("LABWC_TITLE")); + } else { + snprintf(title, sizeof(title), "%s - %s", "labwc", wlr_output->name); + } wlr_wl_output_set_title(wlr_output, title); wlr_wl_output_set_app_id(wlr_output, "labwc"); } From df6dde131f0ed5d77ec4ce5eeb64e02a32225e50 Mon Sep 17 00:00:00 2001 From: massi Date: Mon, 11 May 2026 16:39:22 -0700 Subject: [PATCH 125/146] window-title: implement window-title command line argument When -t or --window-title is supplied, its required argument is treated as a format string where `%o` is replaced by the `wlr-output`'s `name` when we set the window title. This uses glib to split and join the format string because our own `string-helpers` library only has `str_join`. Otherwise using `string-helpers` would have been preferred. --- include/labwc.h | 2 ++ src/main.c | 11 ++++++++++- src/output.c | 14 +++++++------- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/include/labwc.h b/include/labwc.h index edde2771..bbee63cf 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -315,6 +315,8 @@ struct server { struct sfdo *sfdo; pid_t primary_client_pid; + + char *window_title_fmt; }; /* defined in main.c */ diff --git a/src/main.c b/src/main.c index 501c2b7a..93351b22 100644 --- a/src/main.c +++ b/src/main.c @@ -9,6 +9,7 @@ #include "common/font.h" #include "common/macros.h" #include "common/spawn.h" +#include "common/string-helpers.h" #include "config/rcxml.h" #include "config/session.h" #include "labwc.h" @@ -37,6 +38,7 @@ static const struct option long_options[] = { {"reconfigure", no_argument, NULL, 'r'}, {"startup", required_argument, NULL, 's'}, {"session", required_argument, NULL, 'S'}, + {"window-title", required_argument, NULL, 't'}, {"version", no_argument, NULL, 'v'}, {"verbose", no_argument, NULL, 'V'}, {0, 0, 0, 0} @@ -178,7 +180,7 @@ main(int argc, char *argv[]) int c; while (1) { int index = 0; - c = getopt_long(argc, argv, "c:C:dehmrs:S:vV", long_options, &index); + c = getopt_long(argc, argv, "c:C:dehmrs:S:t:vV", long_options, &index); if (c == -1) { break; } @@ -207,6 +209,9 @@ main(int argc, char *argv[]) case 'S': primary_client = optarg; break; + case 't': + server.window_title_fmt = optarg; + break; case 'v': print_version(); exit(0); @@ -265,6 +270,10 @@ main(int argc, char *argv[]) increase_nofile_limit(); + if (string_null_or_empty(server.window_title_fmt)) { + server.window_title_fmt = "labwc - %o"; + } + server_init(); server_start(); diff --git a/src/output.c b/src/output.c index 1139aca2..33154e58 100644 --- a/src/output.c +++ b/src/output.c @@ -10,6 +10,7 @@ #include "output.h" #include #include +#include #include #include #include @@ -26,6 +27,7 @@ #include "common/macros.h" #include "common/mem.h" #include "common/scene-helpers.h" +#include "common/string-helpers.h" #include "config/rcxml.h" #include "labwc.h" #include "layers.h" @@ -605,13 +607,11 @@ handle_new_output(struct wl_listener *listener, void *data) } if (wlr_output_is_wl(wlr_output)) { - char title[64]; - if (getenv("LABWC_TITLE")) { - snprintf(title, sizeof(title), "%s", getenv("LABWC_TITLE")); - } else { - snprintf(title, sizeof(title), "%s - %s", "labwc", wlr_output->name); - } - wlr_wl_output_set_title(wlr_output, title); + gchar** parts = g_strsplit(server.window_title_fmt, "%o", -1); + gchar* formatted_title = g_strjoinv(wlr_output->name, parts); + g_strfreev(parts); + wlr_wl_output_set_title(wlr_output, formatted_title); + g_free(formatted_title); wlr_wl_output_set_app_id(wlr_output, "labwc"); } From 0a9bd41df0cf15e4242e9b637c29c172d572c508 Mon Sep 17 00:00:00 2001 From: massi Date: Mon, 11 May 2026 14:59:29 -0700 Subject: [PATCH 126/146] window-title: add documentation --- docs/labwc.1.scd | 8 ++++++++ src/main.c | 23 ++++++++++++----------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/docs/labwc.1.scd b/docs/labwc.1.scd index 31f28c19..30abf3f6 100644 --- a/docs/labwc.1.scd +++ b/docs/labwc.1.scd @@ -70,6 +70,14 @@ the `--exit` and `--reconfigure` options use. session clients support both X11 and Wayland, this command line option avoids re-writes and fragmentation. +*-t, --window-title* + Set the window title for labwc to use when nested in a compositor. + is a format string to be used as the window title, replacing + `%o` with the name of the output region. This is useful when simulating + multiple screens, such as with running labwc with the enviornment + variable `WLR_WL_OUTPUTS=2`. In this case, `%o` will be unique per + simulated screen. + *-v, --version* Show the version number and quit diff --git a/src/main.c b/src/main.c index 93351b22..98c1f1bf 100644 --- a/src/main.c +++ b/src/main.c @@ -46,17 +46,18 @@ static const struct option long_options[] = { static const char labwc_usage[] = "Usage: labwc [options...]\n" -" -c, --config Specify config file (with path)\n" -" -C, --config-dir Specify config directory\n" -" -d, --debug Enable full logging, including debug information\n" -" -e, --exit Exit the compositor\n" -" -h, --help Show help message and quit\n" -" -m, --merge-config Merge user config files/theme in all XDG Base Dirs\n" -" -r, --reconfigure Reload the compositor configuration\n" -" -s, --startup Run command on startup\n" -" -S, --session Run command on startup and terminate on exit\n" -" -v, --version Show version number and quit\n" -" -V, --verbose Enable more verbose logging\n"; +" -c, --config Specify config file (with path)\n" +" -C, --config-dir Specify config directory\n" +" -d, --debug Enable full logging, including debug information\n" +" -e, --exit Exit the compositor\n" +" -h, --help Show help message and quit\n" +" -m, --merge-config Merge user config files/theme in all XDG Base Dirs\n" +" -r, --reconfigure Reload the compositor configuration\n" +" -s, --startup Run command on startup\n" +" -S, --session Run command on startup and terminate on exit\n" +" -t, --window-title Specify title to use when the compositor is nested\n" +" -v, --version Show version number and quit\n" +" -V, --verbose Enable more verbose logging\n"; static void usage(void) From cd7be59d5fea887b41abb6a0edcedcc233795c36 Mon Sep 17 00:00:00 2001 From: massi Date: Tue, 12 May 2026 17:06:18 -0700 Subject: [PATCH 127/146] window-title: rewording, renaming, lint fixes --- docs/labwc.1.scd | 14 +++++++------- include/labwc.h | 2 +- src/main.c | 32 ++++++++++++++++---------------- src/output.c | 4 ++-- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/docs/labwc.1.scd b/docs/labwc.1.scd index 30abf3f6..3be47743 100644 --- a/docs/labwc.1.scd +++ b/docs/labwc.1.scd @@ -70,13 +70,13 @@ the `--exit` and `--reconfigure` options use. session clients support both X11 and Wayland, this command line option avoids re-writes and fragmentation. -*-t, --window-title* - Set the window title for labwc to use when nested in a compositor. - is a format string to be used as the window title, replacing - `%o` with the name of the output region. This is useful when simulating - multiple screens, such as with running labwc with the enviornment - variable `WLR_WL_OUTPUTS=2`. In this case, `%o` will be unique per - simulated screen. +*-t, --title* + Set the window title for labwc to use when it is running in a window + (i.e. nested in a compositor). is a format string to be used as + the window title, replacing `%o` with the name of the output + region. This is useful when simulating multiple screens, such as with + running labwc with the enviornment variable `WLR_WL_OUTPUTS=2`. In this + case, `%o` will be unique per simulated screen. *-v, --version* Show the version number and quit diff --git a/include/labwc.h b/include/labwc.h index bbee63cf..a6d69317 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -316,7 +316,7 @@ struct server { pid_t primary_client_pid; - char *window_title_fmt; + char *title_fmt; }; /* defined in main.c */ diff --git a/src/main.c b/src/main.c index 98c1f1bf..081bd62a 100644 --- a/src/main.c +++ b/src/main.c @@ -38,7 +38,7 @@ static const struct option long_options[] = { {"reconfigure", no_argument, NULL, 'r'}, {"startup", required_argument, NULL, 's'}, {"session", required_argument, NULL, 'S'}, - {"window-title", required_argument, NULL, 't'}, + {"title", required_argument, NULL, 't'}, {"version", no_argument, NULL, 'v'}, {"verbose", no_argument, NULL, 'V'}, {0, 0, 0, 0} @@ -46,18 +46,18 @@ static const struct option long_options[] = { static const char labwc_usage[] = "Usage: labwc [options...]\n" -" -c, --config Specify config file (with path)\n" -" -C, --config-dir Specify config directory\n" -" -d, --debug Enable full logging, including debug information\n" -" -e, --exit Exit the compositor\n" -" -h, --help Show help message and quit\n" -" -m, --merge-config Merge user config files/theme in all XDG Base Dirs\n" -" -r, --reconfigure Reload the compositor configuration\n" -" -s, --startup Run command on startup\n" -" -S, --session Run command on startup and terminate on exit\n" -" -t, --window-title Specify title to use when the compositor is nested\n" -" -v, --version Show version number and quit\n" -" -V, --verbose Enable more verbose logging\n"; +" -c, --config Specify config file (with path)\n" +" -C, --config-dir Specify config directory\n" +" -d, --debug Enable full logging, including debug information\n" +" -e, --exit Exit the compositor\n" +" -h, --help Show help message and quit\n" +" -m, --merge-config Merge user config files/theme in all XDG Base Dirs\n" +" -r, --reconfigure Reload the compositor configuration\n" +" -s, --startup Run command on startup\n" +" -S, --session Run command on startup and terminate on exit\n" +" -t, --title Specify title to use when running in a window\n" +" -v, --version Show version number and quit\n" +" -V, --verbose Enable more verbose logging\n"; static void usage(void) @@ -211,7 +211,7 @@ main(int argc, char *argv[]) primary_client = optarg; break; case 't': - server.window_title_fmt = optarg; + server.title_fmt = optarg; break; case 'v': print_version(); @@ -271,8 +271,8 @@ main(int argc, char *argv[]) increase_nofile_limit(); - if (string_null_or_empty(server.window_title_fmt)) { - server.window_title_fmt = "labwc - %o"; + if (string_null_or_empty(server.title_fmt)) { + server.title_fmt = "labwc - %o"; } server_init(); diff --git a/src/output.c b/src/output.c index 33154e58..6811b783 100644 --- a/src/output.c +++ b/src/output.c @@ -607,8 +607,8 @@ handle_new_output(struct wl_listener *listener, void *data) } if (wlr_output_is_wl(wlr_output)) { - gchar** parts = g_strsplit(server.window_title_fmt, "%o", -1); - gchar* formatted_title = g_strjoinv(wlr_output->name, parts); + gchar **parts = g_strsplit(server.title_fmt, "%o", -1); + gchar *formatted_title = g_strjoinv(wlr_output->name, parts); g_strfreev(parts); wlr_wl_output_set_title(wlr_output, formatted_title); g_free(formatted_title); From 4af693a7fdf61d0f0bf8c5225335c4d6eadbd543 Mon Sep 17 00:00:00 2001 From: massi Date: Fri, 15 May 2026 18:01:47 -0700 Subject: [PATCH 128/146] window-title: cleaner string replace --- src/output.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/output.c b/src/output.c index 6811b783..2eab8ec3 100644 --- a/src/output.c +++ b/src/output.c @@ -607,11 +607,10 @@ handle_new_output(struct wl_listener *listener, void *data) } if (wlr_output_is_wl(wlr_output)) { - gchar **parts = g_strsplit(server.title_fmt, "%o", -1); - gchar *formatted_title = g_strjoinv(wlr_output->name, parts); - g_strfreev(parts); - wlr_wl_output_set_title(wlr_output, formatted_title); - g_free(formatted_title); + GString *title = g_string_new(server.title_fmt); + g_string_replace(title, "%o", wlr_output->name, 0); + wlr_wl_output_set_title(wlr_output, title->str); + g_string_free(title, TRUE); wlr_wl_output_set_app_id(wlr_output, "labwc"); } From 80ff89c640007a3fa6428d5dd79db3044adfa336 Mon Sep 17 00:00:00 2001 From: Tomi Ollila Date: Sun, 17 May 2026 22:04:52 +0300 Subject: [PATCH 129/146] Typo/style fixes in docs and code comments Codespell(1)-pointed typos in files listed by `git ls-files` (sans checkpatch.pl and possibly some others). Removed some extra spaces. Added a few missing trailing periods. `Default is ...`. Added spaces in ' />' where missing (sans e.g. wayland protocol and t/* files). Fit some lines in docs/*.scd to 80 colums. Used git grep commands (to find similar cases): $ git grep -n '\S/>' $ git grep -nF '. ' $ git grep -n '[^\t*'\'',{#]\t' $ git grep -ni 'default ' No functional change. No change in *.[ch] line numbers. --- docs/autostart | 2 +- docs/labwc-actions.5.scd | 62 +++++++++++++-------------- docs/labwc-config.5.scd | 38 ++++++++-------- docs/labwc-menu.5.scd | 8 ++-- docs/labwc-theme.5.scd | 6 +-- docs/labwc.1.scd | 4 +- docs/menu.xml | 6 +-- docs/rc.xml.all | 14 +++--- include/config/default-bindings.h | 8 ++-- include/scaled-buffer/scaled-buffer.h | 2 +- src/action.c | 4 +- src/config/rcxml.c | 6 +-- src/img/img-xbm.c | 2 +- src/menu/menu.c | 4 +- src/theme.c | 2 +- src/window-rules.c | 4 +- 16 files changed, 88 insertions(+), 84 deletions(-) diff --git a/docs/autostart b/docs/autostart index 17fcc270..18adb23b 100644 --- a/docs/autostart +++ b/docs/autostart @@ -12,7 +12,7 @@ swaybg -c '#113344' >/dev/null 2>&1 & # Configure output directives such as mode, position, scale and transform. -# Use wlr-randr to get your output names +# Use wlr-randr to get your output names. # Example ~/.config/kanshi/config below: # profile { # output HDMI-A-1 position 1366,0 diff --git a/docs/labwc-actions.5.scd b/docs/labwc-actions.5.scd index 47ee1801..2677e348 100644 --- a/docs/labwc-actions.5.scd +++ b/docs/labwc-actions.5.scd @@ -16,7 +16,7 @@ Actions are used in menus and keyboard/mouse bindings. SIGTERM signal. ** - Execute command. Note that in the interest of backward compatibility, + Execute command. Note that in the interest of backward compatibility, labwc supports as an alternative to even though openbox documentation states that it is deprecated. Note: Tilde (~) is expanded in the command before passing to execvp(). @@ -139,22 +139,21 @@ Actions are used in menus and keyboard/mouse bindings. and OSD, useful for binding to keys without modifiers. *workspace* [all|current] - This determines whether to cycle through windows on all workspaces or the - current workspace. Default is "current". + This determines whether to cycle through windows on all workspaces or + the current workspace. Default is "current". *output* [all|focused|cursor] - This determines whether to cycle through windows on all outputs, the focused - output, or the output under the cursor. Default is "all". + This determines whether to cycle through windows on all outputs, the + focused output, or the output under the cursor. Default is "all". *identifier* [all|current] - This determines whether to cycle through all windows or only windows of the - same application as the currently focused window. Default is "all". + This determines whether to cycle through all windows or only windows of + the same application as the currently focused window. Default is "all". ** Re-load configuration and theme files. -** - +** Show a menu. ``` @@ -300,7 +299,7 @@ Actions are used in menus and keyboard/mouse bindings. (if one exists). *wrap* [yes|no] When using the direction attribute, wrap around from - right-to-left or top-to-bottom, and vice versa. Default no. + right-to-left or top-to-bottom, and vice versa. Default is no. ** Resizes active window size to width and height of the output when the @@ -314,10 +313,10 @@ Actions are used in menus and keyboard/mouse bindings. workspace or its index (starting at 1) as configured in rc.xml. *wrap* [yes|no] Wrap around from last desktop to first, and vice - versa. Default yes. + versa. Default is yes. *toggle* [yes|no] Toggle to “last” if already on the workspace that - would be the actual destination. Default no. + would be the actual destination. Default is no. ** Send active window to workspace. @@ -325,10 +324,11 @@ Actions are used in menus and keyboard/mouse bindings. *to* The workspace to send the window to. Supported values are the same as for GoToDesktop. - *follow* [yes|no] Also switch to the specified workspace. Default yes. + *follow* [yes|no] Also switch to the specified workspace. + Default is yes. *wrap* [yes|no] Wrap around from last desktop to first, and vice - versa. Default yes. + versa. Default is yes. ** Add virtual output (headless backend). @@ -346,11 +346,11 @@ Actions are used in menus and keyboard/mouse bindings. ``` - - + + - + ``` @@ -371,7 +371,7 @@ Actions are used in menus and keyboard/mouse bindings. *output_name* The name of virtual output. If not supplied, will remove the last virtual output added. -** +** Reposition the window according to the desired placement policy. *policy* [automatic|cursor|center|cascade] Use the specified policy, @@ -430,11 +430,11 @@ Actions are used in menus and keyboard/mouse bindings. used. ** - Minimize all windows in the current workspace so that the desktop becomes - visible. On calling the action again the hidden windows are unminimized, - provided that - since the initial `ShowDesktop` - (a) no windows have been - unminimized; (b) workspaces have not been switched; and (c) no new - applications have been started. + Minimize all windows in the current workspace so that the desktop + becomes visible. On calling the action again the hidden windows are + unminimized, provided that - since the initial `ShowDesktop` - (a) no + windows have been unminimized; (b) workspaces have not been switched; + and (c) no new applications have been started. **++ ** @@ -449,8 +449,8 @@ Actions are used in menus and keyboard/mouse bindings. binding. ** - Toggle visibility of key-state on-screen display (OSD). Note: This is for - debugging purposes only. + Toggle visibility of key-state on-screen display (OSD). Note: This is + for debugging purposes only. # CONDITIONAL ACTIONS @@ -464,10 +464,10 @@ Actions that execute other actions. Used in keyboard/mouse bindings. ``` - - - - + + + + ``` @@ -549,9 +549,9 @@ Actions that execute other actions. Used in keyboard/mouse bindings. ``` - + - + diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index 56097bca..5691a4e1 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -25,7 +25,7 @@ The XDG Base Directory Specification does not specify whether or not programs should (a) allow the first-identified configuration file to supersede any others, or (b) define rules for merging the information from more than one file. -By default, labwc uses option (a), reading only the first file identified. With +By default, labwc uses option (a), reading only the first file identified. With the --merge-config option, the search order is reversed, but every configuration file encountered is processed in turn. Thus, user-specific files will augment system-wide configurations, with conflicts favoring the user-specific @@ -526,7 +526,8 @@ extending outward from the snapped edge. ** and **, and 50 for **. ** [yes|no] - Show an overlay when snapping a window to an output edge. Default is yes. + Show an overlay when snapping a window to an output edge. + Default is yes. **++ ** @@ -595,7 +596,7 @@ extending outward from the snapped edge. A setting of 0 disables the OSD. Default is 1000 ms. ** - Set the prefix to use when using "number" above. Default is "Workspace" + Set the prefix to use when using "number" above. Default is "Workspace". ## THEME @@ -749,7 +750,7 @@ generate gesture events, like swipe and pinch. There are some related settings (e.g. *threeFingerDrag* and *twoFingerScroll*) in the ** section. In the Wayland Compositor domain, events associated with touchscreens are -sometimes simply referred to as *touch* events. Touchscreens can be configured +sometimes simply referred to as *touch* events. Touchscreens can be configured in both the ** and ** sections. Note that touchscreen gestures are not interpreted by libinput, nor labwc. Any touch point is passed to the client (application) for any interpretation of gestures. @@ -824,9 +825,10 @@ overrideInhibition="">* Make this keybind work even if the screen is locked. Default is no. *overrideInhibition* [yes|no] - Make this keybind work even if the view inhibits keybinds. Default is no. + Make this keybind work even if the view inhibits keybinds. This can be used to prevent W-Tab and similar keybinds from being delivered to Virtual Machines, VNC clients or nested compositors. + Default is no. *onRelease* [yes|no] When yes, fires the keybind action when the key or key @@ -840,7 +842,7 @@ overrideInhibition="">* ``` - + ``` @@ -900,7 +902,7 @@ input-devices by the Wayland protocol. - Shade: A button that, by default, toggles window shading. - AllDesktops: A button that, by default, toggles omnipresence of a window. - - Close: A button that, by default, closses a window. + - Close: A button that, by default, closes a window. - Border: The window's border including Top...BRCorner below. - Top: The top edge of the window's border. - Bottom: The bottom edge of the window's border. @@ -974,10 +976,10 @@ input-devices by the Wayland protocol. ``` - + - - + + ``` @@ -985,7 +987,7 @@ input-devices by the Wayland protocol. ** Load default mousebinds. This is an addition to the openbox specification and provides a way to keep config files simpler whilst - allowing user specific binds. Note that if no rc.xml is found, or if no + allowing user specific binds. Note that if no rc.xml is found, or if no entries exist, the same default mousebinds will be loaded even if the element is not provided. @@ -997,7 +999,7 @@ Note: To rotate touch events with output rotation, use the libinput *calibrationMatrix* setting. ``` - + ``` ** @@ -1260,7 +1262,8 @@ Note: To rotate touch events with output rotation, use the libinput The default method depends on the touchpad hardware. ** [none|twofinger|edge|onbutton] - Configure the method by which physical movements are mapped to scroll events. + Configure the method by which physical movements are mapped to scroll + events. The scroll methods available are: - *twofinger* - Scroll by two fingers being placed on the surface of the @@ -1275,7 +1278,8 @@ Note: To rotate touch events with output rotation, use the libinput ** [button] Set the button used for the *onbutton* scroll method. - *button* is the decimal form of a value from `linux/input-event-codes.h`. + *button* is the decimal form of a value + from `linux/input-event-codes.h`. ** [yes|no|disabledOnExternalMouse] Optionally enable or disable sending any device events. @@ -1324,7 +1328,7 @@ defined as shown below. - + @@ -1521,7 +1525,7 @@ This is the full list of interfaces that can be controlled with this mechanism: *XCURSOR_PATH* Specify a colon-separated list of paths to look for mouse cursors in. - Default + Default is ~/.local/share/icons: ~/.icons: /usr/share/icons: @@ -1532,7 +1536,7 @@ This is the full list of interfaces that can be controlled with this mechanism: *XCURSOR_SIZE* Specify an alternative mouse cursor size in pixels. Requires - XCURSOR_THEME to be set also. Default 24. + XCURSOR_THEME to be set also. Default is 24. *XCURSOR_THEME* Specify a mouse cursor theme within XCURSOR_PATH. diff --git a/docs/labwc-menu.5.scd b/docs/labwc-menu.5.scd index df04ccf9..e2c40d84 100644 --- a/docs/labwc-menu.5.scd +++ b/docs/labwc-menu.5.scd @@ -12,7 +12,7 @@ Static menus are built based on the menu.xml file located at # SYNTAX The menu file must be entirely enclosed within and - tags. Inside these tags, menus are specified as follows: + tags. Inside these tags, menus are specified as follows: ``` @@ -111,7 +111,7 @@ Pipe menus are menus generated dynamically based on output of scripts or binaries. They are so-called because the output of the executable is piped to the labwc menu. -For any ** entry in menu.xml, the +For any ** entry in menu.xml, the COMMAND will be executed the first time the item is selected (for example by cursor or keyboard input). The XML output of the command will be parsed and shown as a submenu. The content of pipemenus is cached until the whole menu @@ -124,7 +124,7 @@ menus, for example: ``` - + ``` @@ -144,7 +144,7 @@ obmenu-generator with the menu generator of your choice): ``` - + ``` diff --git a/docs/labwc-theme.5.scd b/docs/labwc-theme.5.scd index 5f99cae7..dce48bdf 100644 --- a/docs/labwc-theme.5.scd +++ b/docs/labwc-theme.5.scd @@ -135,7 +135,7 @@ window.*.title.bg.colorTo.splitTo: #557485 *window.active.title.bg* Texture for the focused window's titlebar. See texture section above. - Default is *Solid* + Default is *Solid*. *window.active.title.bg.color* Background color for the focused window's titlebar. See texture section @@ -144,7 +144,7 @@ window.*.title.bg.colorTo.splitTo: #557485 *window.inactive.title.bg* Texture for non-focused windows' titlebars. See texture section above. - Default is *Solid* + Default is *Solid*. *window.inactive.title.bg.color* Background color for non-focused windows' titlebars. See texture section @@ -470,7 +470,7 @@ all are supported. Width of magnifier window border in pixels. Default is 1. *magnifier.border.color* - Color of the magnfier window border. Default is #ff0000 (red). + Color of the magnifier window border. Default is #ff0000 (red). # BUTTONS diff --git a/docs/labwc.1.scd b/docs/labwc.1.scd index 3be47743..56dfe775 100644 --- a/docs/labwc.1.scd +++ b/docs/labwc.1.scd @@ -66,7 +66,7 @@ the `--exit` and `--reconfigure` options use. Manager, or the Window Manager can be launched independently first. On Wayland, the Compositor is both Display Server and Window Manager, so the described session management mechanisms do not work because the - Compositor needs to be running before the session can function. As some + Compositor needs to be running before the session can function. As some session clients support both X11 and Wayland, this command line option avoids re-writes and fragmentation. @@ -75,7 +75,7 @@ the `--exit` and `--reconfigure` options use. (i.e. nested in a compositor). is a format string to be used as the window title, replacing `%o` with the name of the output region. This is useful when simulating multiple screens, such as with - running labwc with the enviornment variable `WLR_WL_OUTPUTS=2`. In this + running labwc with the environment variable `WLR_WL_OUTPUTS=2`. In this case, `%o` will be unique per simulated screen. *-v, --version* diff --git a/docs/menu.xml b/docs/menu.xml index 4b4d5dda..3344161a 100644 --- a/docs/menu.xml +++ b/docs/menu.xml @@ -23,7 +23,7 @@ Any menu with the id "workspaces" will be hidden if there is only a single workspace available. --> - + diff --git a/include/config/default-bindings.h b/include/config/default-bindings.h index a49f60f4..788e8d2e 100644 --- a/include/config/default-bindings.h +++ b/include/config/default-bindings.h @@ -141,14 +141,14 @@ static struct key_combos { * * * - * - * - * + * + * + * * * * * - * + * * * * diff --git a/include/scaled-buffer/scaled-buffer.h b/include/scaled-buffer/scaled-buffer.h index c2af6054..017e29fb 100644 --- a/include/scaled-buffer/scaled-buffer.h +++ b/include/scaled-buffer/scaled-buffer.h @@ -130,7 +130,7 @@ void scaled_buffer_request_update(struct scaled_buffer *self, /** * scaled_buffer_invalidate_sharing - clear the list of entire cached - * scaled_buffers used to share visually dupliated buffers. This should + * scaled_buffers used to share visually duplicated buffers. This should * be called on Reconfigure to force updates of newly created * scaled_buffers rather than reusing ones created before Reconfigure. */ diff --git a/src/action.c b/src/action.c index daf8fb30..265ff6e7 100644 --- a/src/action.c +++ b/src/action.c @@ -145,7 +145,7 @@ struct action_arg_list { * Will expand to: * * enum action_type { - * ACTION_TYPE_INVALID, + * ACTION_TYPE_INVALID = 0, * ACTION_TYPE_NONE, * ACTION_TYPE_CLOSE, * ACTION_TYPE_KILL, @@ -1312,7 +1312,7 @@ run_action(struct view *view, struct action *action, /* * To support only setting one of width/height - * in + * in * we fall back to current dimension when unset. */ struct wlr_box box = { diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 0514b6c7..ab0639d1 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -613,9 +613,9 @@ fill_mousebind(xmlNode *node, const char *context) /* * Example of what we are parsing: * - * - * - * + * + * + * * */ diff --git a/src/img/img-xbm.c b/src/img/img-xbm.c index 91269f64..3771444a 100644 --- a/src/img/img-xbm.c +++ b/src/img/img-xbm.c @@ -226,7 +226,7 @@ out: /* * Openbox built-in icons are not bigger than 8x8, so have only written this - * function to cope wit that max size + * function to cope with that max size */ #define LABWC_BUILTIN_ICON_MAX_SIZE (8) diff --git a/src/menu/menu.c b/src/menu/menu.c index 2505317d..c0e93c59 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -172,7 +172,7 @@ item_parse_accelerator(struct menuitem *item, const char *text) accel_ptr = underscore + 1; break; } else { - /* Ignore empty accelertor */ + /* Ignore empty accelerator */ break; } } @@ -627,7 +627,7 @@ fill_menu(struct menu *parent, xmlNode *n) * * * - * + * * */ } else { diff --git a/src/theme.c b/src/theme.c index 93ac1c5e..71e577ce 100644 --- a/src/theme.c +++ b/src/theme.c @@ -788,7 +788,7 @@ entry(struct theme *theme, const char *key, const char *value) value, "window.button.spacing"); } - /* botton hover overlay */ + /* button hover overlay */ if (match_glob(key, "window.button.hover.bg.color")) { parse_color(value, theme->window_button_hover_bg_color); } diff --git a/src/window-rules.c b/src/window-rules.c index f43b92f4..4118ae32 100644 --- a/src/window-rules.c +++ b/src/window-rules.c @@ -69,8 +69,8 @@ window_rules_get_property(struct view *view, const char *property) * for foot's "serverDecoration" property to be "default". * * - * - * + * + * * */ struct window_rule *rule; From d5eb227c773c90528b0e99d10f1e4a0267c5e6ea Mon Sep 17 00:00:00 2001 From: Weblate Date: Mon, 18 May 2026 20:28:57 +0200 Subject: [PATCH 130/146] Translation updates from weblate Co-authored-by: Demian Translate-URL: https://translate.lxqt-project.org/projects/labwc/labwc/de/ Translation: Labwc/labwc --- po/de.po | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/po/de.po b/po/de.po index 5841f3f6..d83ef64a 100644 --- a/po/de.po +++ b/po/de.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: labwc\n" "Report-Msgid-Bugs-To: https://github.com/labwc/labwc/issues\n" "POT-Creation-Date: 2024-09-19 21:09+1000\n" -"PO-Revision-Date: 2025-08-15 20:01+0000\n" -"Last-Translator: Ettore Atalan \n" +"PO-Revision-Date: 2026-05-18 18:28+0000\n" +"Last-Translator: Demian \n" "Language-Team: German \n" "Language: de\n" @@ -21,7 +21,7 @@ msgstr "" #: src/menu/menu.c:1016 msgid "Go there..." -msgstr "Dorthin gehen..." +msgstr "Dorthin wechseln ..." #: src/menu/menu.c:1034 msgid "Terminal" @@ -61,11 +61,11 @@ msgstr "Immer im Vordergrund" #: src/menu/menu.c:1071 msgid "Move Left" -msgstr "nach links" +msgstr "Nach links" #: src/menu/menu.c:1078 msgid "Move Right" -msgstr "nach rechts" +msgstr "Nach rechts" #: src/menu/menu.c:1083 msgid "Always on Visible Workspace" From bce14a5ad7981e9ab99dc5b75a922438930ff39b Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Sun, 6 Jul 2025 01:04:55 +0200 Subject: [PATCH 131/146] toplevel-capture: partial initial implementation Missing: - xwayland child windows - xwayland unmanaged windows, e.g. popups / menus / ... - xdg child window positioning - xdg subsurfaces (test-case: mate-terminal settings listboxes) - xdg popup positioning --- include/labwc.h | 7 +++++ include/view.h | 7 +++++ meson.build | 2 +- src/foreign-toplevel/ext-foreign.c | 3 ++ src/server.c | 49 ++++++++++++++++++++++++++++++ src/view.c | 7 +++++ src/xdg-popup.c | 2 ++ src/xdg.c | 24 +++++++++++++++ src/xwayland.c | 1 + 9 files changed, 101 insertions(+), 1 deletion(-) diff --git a/include/labwc.h b/include/labwc.h index a6d69317..87a42198 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -194,6 +194,13 @@ struct server { struct wlr_xdg_toplevel_icon_manager_v1 *xdg_toplevel_icon_manager; struct wl_listener xdg_toplevel_icon_set_icon; + struct { + struct wlr_ext_foreign_toplevel_image_capture_source_manager_v1 *manager; + struct { + struct wl_listener new_request; + } on; + } toplevel_capture; + /* front to back order */ struct wl_list views; uint64_t next_view_creation_id; diff --git a/include/view.h b/include/view.h index a179338e..46943ab2 100644 --- a/include/view.h +++ b/include/view.h @@ -177,6 +177,12 @@ struct view { char *title; char *app_id; /* WM_CLASS for xwayland windows */ + struct { + struct wlr_scene *scene; + struct wlr_ext_image_capture_source_v1 *source; + struct wl_listener on_capture_source_destroy; + } capture; + bool mapped; bool been_mapped; uint64_t creation_id; @@ -319,6 +325,7 @@ struct xdg_toplevel_view { /* Events unique to xdg-toplevel views */ struct wl_listener set_app_id; struct wl_listener request_show_window_menu; + struct wl_listener set_parent; struct wl_listener new_popup; }; diff --git a/meson.build b/meson.build index 7e345ba6..22dc5bdc 100644 --- a/meson.build +++ b/meson.build @@ -53,7 +53,7 @@ add_project_arguments('-DLABWC_VERSION=@0@'.format(version), language: 'c') wlroots = dependency( 'wlroots-0.20', default_options: ['default_library=static', 'examples=false'], - version: ['>=0.20.0', '<0.21.0'], + version: ['>=0.20.1', '<0.21.0'], ) wlroots_has_xwayland = wlroots.get_variable('have_xwayland') == 'true' diff --git a/src/foreign-toplevel/ext-foreign.c b/src/foreign-toplevel/ext-foreign.c index 78774433..1dfa1d96 100644 --- a/src/foreign-toplevel/ext-foreign.c +++ b/src/foreign-toplevel/ext-foreign.c @@ -75,6 +75,9 @@ ext_foreign_toplevel_init(struct ext_foreign_toplevel *ext_toplevel, return; } + /* In support for ext-toplevel-capture */ + ext_toplevel->handle->data = view; + /* Client side requests */ ext_toplevel->on.handle_destroy.notify = handle_handle_destroy; wl_signal_add(&ext_toplevel->handle->events.destroy, &ext_toplevel->on.handle_destroy); diff --git a/src/server.c b/src/server.c index c792d8b4..d0c8c04c 100644 --- a/src/server.c +++ b/src/server.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only #define _POSIX_C_SOURCE 200809L #include "config.h" +#include #include #include #include @@ -410,6 +411,39 @@ handle_renderer_lost(struct wl_listener *listener, void *data) wlr_renderer_destroy(old_renderer); } +static void +handle_toplevel_capture_source_destroy(struct wl_listener *listener, void *data) +{ + struct view *view = wl_container_of(listener, view, capture.on_capture_source_destroy); + assert(view->capture.source); + view->capture.source = NULL; + wl_list_remove(&listener->link); + wl_list_init(&listener->link); +} + +static void +handle_toplevel_capture_request(struct wl_listener *listener, void *data) +{ + struct wlr_ext_foreign_toplevel_image_capture_source_manager_v1_request *request = data; + struct view *view = request->toplevel_handle->data; + assert(view); + wlr_log(WLR_INFO, "Capturing toplevel %s", view->app_id); + + if (!view->capture.source) { + view->capture.source = wlr_ext_image_capture_source_v1_create_with_scene_node( + &view->capture.scene->tree.node, server.wl_event_loop, + server.allocator, server.renderer); + assert(view->capture.source); + + view->capture.on_capture_source_destroy.notify = + handle_toplevel_capture_source_destroy; + wl_signal_add(&view->capture.source->events.destroy, + &view->capture.on_capture_source_destroy); + } + wlr_ext_foreign_toplevel_image_capture_source_manager_v1_request_accept( + request, view->capture.source); +} + void server_init(void) { @@ -689,6 +723,19 @@ server_init(void) wlr_screencopy_manager_v1_create(server.wl_display); wlr_ext_image_copy_capture_manager_v1_create(server.wl_display, 1); wlr_ext_output_image_capture_source_manager_v1_create(server.wl_display, 1); + + server.toplevel_capture.manager = + wlr_ext_foreign_toplevel_image_capture_source_manager_v1_create( + server.wl_display, 1); + if (server.toplevel_capture.manager) { + server.toplevel_capture.on.new_request.notify = handle_toplevel_capture_request; + wl_signal_add(&server.toplevel_capture.manager->events.new_request, + &server.toplevel_capture.on.new_request); + } else { + /* Allow safe removal on shutdown */ + wl_list_init(&server.toplevel_capture.on.new_request.link); + } + wlr_data_control_manager_v1_create(server.wl_display); wlr_ext_data_control_manager_v1_create(server.wl_display, LAB_EXT_DATA_CONTROL_VERSION); @@ -823,6 +870,8 @@ server_finish(void) server.drm_lease_request.notify = NULL; } + wl_list_remove(&server.toplevel_capture.on.new_request.link); + wlr_backend_destroy(server.backend); wlr_allocator_destroy(server.allocator); diff --git a/src/view.c b/src/view.c index bcbd366e..21005f20 100644 --- a/src/view.c +++ b/src/view.c @@ -2482,6 +2482,10 @@ view_init(struct view *view) view->title = xstrdup(""); view->app_id = xstrdup(""); + + view->capture.scene = wlr_scene_create(); + view->capture.scene->restack_xwayland_surfaces = false; + wl_list_init(&view->capture.on_capture_source_destroy.link); } void @@ -2503,6 +2507,9 @@ view_destroy(struct view *view) wl_list_remove(&view->request_fullscreen.link); wl_list_remove(&view->set_title.link); wl_list_remove(&view->destroy.link); + wl_list_remove(&view->capture.on_capture_source_destroy.link); + + wlr_scene_node_destroy(&view->capture.scene->tree.node); if (view->foreign_toplevel) { foreign_toplevel_destroy(view->foreign_toplevel); diff --git a/src/xdg-popup.c b/src/xdg-popup.c index 8e6870af..7ca9ab01 100644 --- a/src/xdg-popup.c +++ b/src/xdg-popup.c @@ -169,4 +169,6 @@ xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup) node_descriptor_create(wlr_popup->base->surface->data, LAB_NODE_XDG_POPUP, view, /*data*/ NULL); + + wlr_scene_xdg_surface_create(&view->capture.scene->tree, wlr_popup->base); } diff --git a/src/xdg.c b/src/xdg.c index 211a340d..03035d63 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -30,6 +30,8 @@ #define LAB_XDG_SHELL_VERSION 6 #define CONFIGURE_TIMEOUT_MS 100 +static struct view *xdg_toplevel_view_get_root(struct view *view); + static struct xdg_toplevel_view * xdg_toplevel_view_from_view(struct view *view) { @@ -462,6 +464,7 @@ handle_destroy(struct wl_listener *listener, void *data) /* Remove xdg-shell view specific listeners */ wl_list_remove(&xdg_toplevel_view->set_app_id.link); wl_list_remove(&xdg_toplevel_view->request_show_window_menu.link); + wl_list_remove(&xdg_toplevel_view->set_parent.link); wl_list_remove(&xdg_toplevel_view->new_popup.link); wl_list_remove(&view->commit.link); @@ -565,6 +568,23 @@ handle_request_show_window_menu(struct wl_listener *listener, void *data) menu_open_root(menu, cursor->x, cursor->y); } +static void +handle_set_parent(struct wl_listener *listener, void *data) +{ + struct xdg_toplevel_view *xdg_toplevel_view = wl_container_of( + listener, xdg_toplevel_view, set_parent); + struct view *view = &xdg_toplevel_view->base; + struct view *view_root = xdg_toplevel_view_get_root(view); + if (view_root == view) { + return; + } + struct wlr_scene_node *node, *tmp; + wl_list_for_each_safe(node, tmp, &view->capture.scene->tree.children, link) { + wlr_log(WLR_DEBUG, "moving capture scene node to view_root"); + wlr_scene_node_reparent(node, &view_root->capture.scene->tree); + } +} + static void handle_set_title(struct wl_listener *listener, void *data) { @@ -1046,6 +1066,9 @@ handle_new_xdg_toplevel(struct wl_listener *listener, void *data) mappable_connect(&view->mappable, xdg_surface->surface, handle_map, handle_unmap); + struct view *root_view = xdg_toplevel_view_get_root(view); + wlr_scene_xdg_surface_create(&root_view->capture.scene->tree, xdg_surface); + struct wlr_xdg_toplevel *toplevel = xdg_surface->toplevel; CONNECT_SIGNAL(toplevel, view, destroy); CONNECT_SIGNAL(toplevel, view, request_move); @@ -1059,6 +1082,7 @@ handle_new_xdg_toplevel(struct wl_listener *listener, void *data) /* Events specific to XDG toplevel views */ CONNECT_SIGNAL(toplevel, xdg_toplevel_view, set_app_id); CONNECT_SIGNAL(toplevel, xdg_toplevel_view, request_show_window_menu); + CONNECT_SIGNAL(toplevel, xdg_toplevel_view, set_parent); CONNECT_SIGNAL(xdg_surface, xdg_toplevel_view, new_popup); wl_list_insert(&server.views, &view->link); diff --git a/src/xwayland.c b/src/xwayland.c index 967364c5..5838d412 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -783,6 +783,7 @@ handle_map(struct wl_listener *listener, void *data) view->content_tree = wlr_scene_subsurface_tree_create( view->scene_tree, view->surface); die_if_null(view->content_tree); + wlr_scene_subsurface_tree_create(&view->capture.scene->tree, view->surface); } wlr_scene_node_set_enabled(&view->content_tree->node, !view->shaded); From 151acae28a9a07de2e2fc489a7743b5f89f80150 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Mon, 25 May 2026 14:26:53 +0100 Subject: [PATCH 132/146] Add default keybind super-d for ToggleShowDesktop --- README.md | 1 + docs/labwc-config.5.scd | 1 + docs/rc.xml.all | 3 +++ include/config/default-bindings.h | 3 +++ 4 files changed, 8 insertions(+) diff --git a/README.md b/README.md index 9cc81e88..80796af7 100644 --- a/README.md +++ b/README.md @@ -213,6 +213,7 @@ If you have not created an rc.xml config file, default bindings will be: | `super`-`return` | lab-sensible-terminal | `alt`-`F4` | close window | `super`-`a` | toggle maximize +| `super`-`d` | toggle show-desktop | `super`-`mouse-left` | move window | `super`-`mouse-right` | resize window | `super`-`arrow` | resize window to fill half the output diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index 5691a4e1..6a16b89c 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -863,6 +863,7 @@ overrideInhibition="">* W-Return - lab-sensible-terminal A-F4 - close window W-a - toggle maximize + W-d - toggle show-desktop W- - resize window to fill half or quarter of the output A-Space - show window menu ``` diff --git a/docs/rc.xml.all b/docs/rc.xml.all index 2d787cfa..350d2ea0 100644 --- a/docs/rc.xml.all +++ b/docs/rc.xml.all @@ -279,6 +279,9 @@ + + + diff --git a/include/config/default-bindings.h b/include/config/default-bindings.h index 788e8d2e..d1a96562 100644 --- a/include/config/default-bindings.h +++ b/include/config/default-bindings.h @@ -28,6 +28,9 @@ static struct key_combos { }, { .binding = "W-a", .action = "ToggleMaximize", + }, { + .binding = "W-d", + .action = "ToggleShowDesktop", }, { .binding = "W-Left", .action = "SnapToEdge", From 7e74b82874b9052360e7938080ca859b42bde24d Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Fri, 22 May 2026 19:30:06 +0100 Subject: [PATCH 133/146] NEWS.md: move wlroots-0.19 notes ...to the 0.9.x section --- NEWS.md | 68 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/NEWS.md b/NEWS.md index 9a770ecc..cec808db 100644 --- a/NEWS.md +++ b/NEWS.md @@ -79,40 +79,6 @@ The format is based on [Keep a Changelog] [0.2.0]: NEWS.md#020---2021-04-15 [0.1.0]: NEWS.md#010---2021-03-05 -## Notes on wlroots-0.19 - -There are some regression warnings worth noting for the switch to wlroots 0.19: - -- The DRM backend now destroys/recreates outputs on VT switch and in some cases - on suspend/resume too. The reason for this change was that (i) the KMS state - is undefined when a VT is switched away; and (ii) the previous outputs had - issues with restoration, particularly when the output configuration had - changed whilst switched away. This change causes two issues for users: - - Some layer-shell clients do not re-appear on output re-connection, or may - appear on a different output. Whilst this has always been the case, it will - now also happen in said situations. We recommend layer-shell clients to - handle the new-output and surface-destroy signals to achieve desired - behaviours. - - Some Gtk clients issue critical warnings as they assume that at least one - output is always available. This will be fixed in `Gtk-3.24.50`. It is - believed to be a harmless warning, but it can be avoided by running labwc - with the environment variable `LABWC_FALLBACK_OUTPUT=NOOP-fallback` to - temporarily create a fallback-output when the last physical display - disconnects. [#2914] [#2939] [wlroots-4878] [gtk-8792] -- Menu item can no longer be activated in any Gtk applications with a single - press-drag-release mouse action. For context: This is due to ambiguity in the - specifications and contrary implementations. For example, Gtk applications are - broken under KWin in this regard, while vice versa Qt clients are broken under - other compositors like Weston, Mutter and labwc. It has been decided not to - block the release due to this regression as it is an eco-system wide issue - that has existed for a long time. [#2787] -- It is strongly recommended to use at least wlroots 0.19.1 [#2943] - [wlroots-5098] [#2887] - -[wlroots-4878]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4878 -[wlroots-5098]:https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/5098 -[gtk-8792]: https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/8792 - ## unreleased [unreleased-commits] @@ -186,6 +152,40 @@ Note to maintainers: pactl instead of amixer [#3484] @danielrrrr - Drop cosmic-workspace protocol [#3031] @tokyo4j +## Notes on wlroots-0.19 + +There are some regression warnings worth noting for the switch to wlroots 0.19: + +- The DRM backend now destroys/recreates outputs on VT switch and in some cases + on suspend/resume too. The reason for this change was that (i) the KMS state + is undefined when a VT is switched away; and (ii) the previous outputs had + issues with restoration, particularly when the output configuration had + changed whilst switched away. This change causes two issues for users: + - Some layer-shell clients do not re-appear on output re-connection, or may + appear on a different output. Whilst this has always been the case, it will + now also happen in said situations. We recommend layer-shell clients to + handle the new-output and surface-destroy signals to achieve desired + behaviours. + - Some Gtk clients issue critical warnings as they assume that at least one + output is always available. This will be fixed in `Gtk-3.24.50`. It is + believed to be a harmless warning, but it can be avoided by running labwc + with the environment variable `LABWC_FALLBACK_OUTPUT=NOOP-fallback` to + temporarily create a fallback-output when the last physical display + disconnects. [#2914] [#2939] [wlroots-4878] [gtk-8792] +- Menu item can no longer be activated in any Gtk applications with a single + press-drag-release mouse action. For context: This is due to ambiguity in the + specifications and contrary implementations. For example, Gtk applications are + broken under KWin in this regard, while vice versa Qt clients are broken under + other compositors like Weston, Mutter and labwc. It has been decided not to + block the release due to this regression as it is an eco-system wide issue + that has existed for a long time. [#2787] +- It is strongly recommended to use at least wlroots 0.19.1 [#2943] + [wlroots-5098] [#2887] + +[wlroots-4878]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4878 +[wlroots-5098]:https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/5098 +[gtk-8792]: https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/8792 + ## 0.9.7 - 2026-04-17 [0.9.7-commits] From 52487547caaa9f17ecd719f5dc7c0857c04f820d Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Fri, 22 May 2026 19:31:16 +0100 Subject: [PATCH 134/146] NEWS.md: update notes for 0.20.0 --- NEWS.md | 43 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/NEWS.md b/NEWS.md index cec808db..f5731099 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,7 +9,7 @@ The format is based on [Keep a Changelog] | Date | All Changes | wlroots version | lines-of-code | |------------|---------------|-----------------|---------------| -| 2026-05-07 | [unreleased] | 0.20.0 | 28236 | +| 2026-05-25 | [0.20.0] | 0.20.1 | 28313 | | 2026-04-17 | [0.9.7] | 0.19.2 | 29277 | | 2026-03-15 | [0.9.6] | 0.19.2 | 29271 | | 2026-03-04 | [0.9.5] | 0.19.2 | 29251 | @@ -45,6 +45,7 @@ The format is based on [Keep a Changelog] | 2021-03-05 | [0.1.0] | 0.12.0 | 4627 | [unreleased]: NEWS.md#unreleased +[0.20.0]: NEWS.md#0200---2026-05-25 [0.9.7]: NEWS.md#097---2026-04-17 [0.9.6]: NEWS.md#096---2026-03-15 [0.9.5]: NEWS.md#095---2026-03-04 @@ -83,16 +84,44 @@ The format is based on [Keep a Changelog] [unreleased-commits] -The codebase has been ported to wlroots 0.20 [#2956] @Consolatis +## 0.20.0 - 2026-05-25 + +[0.20.0-commits] + +This is the first release using wlroots-0.20 and therefore has an increased risk +of teething issues. Many thanks to @Consolatis for leading the effort to port +across [#2956]. + +In terms of new features, the most noteworthy ones include: (i) the frequently +requested show-desktop action; (ii) initial toplevel capture support to +screenshot specific windows; (iii) menu accelerators/shortcuts; and (iv) HDR10 +support when running with the Vulkan renderer option. + +The eagle-eyed amongst you will have noticed the sudden jump from labwc `0.9.7` +to `0.20.0`. The reason for this is to align the minor number to that of the +wlroots version against which the compositor is linked. + +The 0.9.x series has turned into a maintenance branch named v0.9 with bug fixes +only, for anyone preferring to build with wlroots-0.19. Note to maintainers: + - libinput >=1.26 is required in support of tablet tool pressure range configuration. +- labwc >=0.20.1 is required to avoid some bugs that we do not want labwc to + ship with. For details, see: + https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/5325 ### Added +- Partially support toplevel-capture. Note that the following are not yet + implemented: (i) XWayland child windows; (ii) XWayland unmanaged windows + (e.g. popups); (iii) xdg child window positioning; (iv) xdg subsurfaces; + and (v) xdg popup positioning. [#2968] @Consolatis +- Add command line option -t|--title to set the labwc window title when running + nested [#3577] @mdsib - Add support for HDR10 output @kode54 @Consolatis [#3424] -- Include wlroots version in --version string @Consolatis [#3567] +- Include wlroots version in --version string @Consolatis [#3567] [#3581] - Implement menu accelerators (one-letter mnemonics to quickly select/exec items from the current menu) @ch3rn1ka [#3505] - Add Next/PreviousWindowImmediate actions @elviosak @johanmalm [#3547] @@ -105,7 +134,8 @@ Note to maintainers: - Add `onbutton` to config option ``. Also add associated option ``. @diniamo [#3540] - Add `overrideInhibition` option to `` [#3507] @drougas -- Add action `ToggleShowDesktop` to hide/unhide windows [#3500] @johanmalm +- Add action `ToggleShowDesktop` to hide/unhide windows, and default keybind + `Super-d` to trigger this action [#3500] [#3595] @johanmalm - Add `` config option so that privileged protocols can be restricted [#3493] @xi - Add action `DebugToggleKeyStateIndicator` to show a key-state on-screen @@ -118,6 +148,7 @@ Note to maintainers: ### Fixed +- Enable labnag long option --exclusive-zone [#3576] @st0rm-shad0w - Position chromium popup correctly when a window is maximized on a multi- output setup @elviosak [#3547] - Run session activation environment update synchronously to avoid a race @@ -2739,7 +2770,8 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 ShowMenu [Keep a Changelog]: https://keepachangelog.com/en/1.0.0/ -[unreleased-commits]: https://github.com/labwc/labwc/compare/0.9.5...HEAD +[unreleased-commits]: https://github.com/labwc/labwc/compare/0.20.0...HEAD +[0.20.0-commits]: https://github.com/labwc/labwc/compare/0.9.5..0.20.0 [0.9.7-commits]: https://github.com/labwc/labwc/compare/0.9.6...0.9.7 [0.9.6-commits]: https://github.com/labwc/labwc/compare/0.9.5...0.9.6 [0.9.5-commits]: https://github.com/labwc/labwc/compare/0.9.4...0.9.5 @@ -3311,3 +3343,4 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 [#3543]: https://github.com/labwc/labwc/pull/3543 [#3547]: https://github.com/labwc/labwc/pull/3547 [#3567]: https://github.com/labwc/labwc/pull/3567 +[#3595]: https://github.com/labwc/labwc/pull/3595 From 37434e3ea54ea5e3ee7d9cc121cb792f8044250d Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Mon, 25 May 2026 20:14:27 +0100 Subject: [PATCH 135/146] NEWS.md: minor fix s/labwc/wlroots/ --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index f5731099..ad71a1df 100644 --- a/NEWS.md +++ b/NEWS.md @@ -108,7 +108,7 @@ Note to maintainers: - libinput >=1.26 is required in support of tablet tool pressure range configuration. -- labwc >=0.20.1 is required to avoid some bugs that we do not want labwc to +- wlroots >=0.20.1 is required to avoid some bugs that we do not want labwc to ship with. For details, see: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/5325 From d5b5b765c7907a21a61081da6e3e1f38dbe17ff8 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Mon, 25 May 2026 20:20:18 +0100 Subject: [PATCH 136/146] build: bump version to 0.20.0 --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 22dc5bdc..8684732f 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project( 'labwc', 'c', - version: '0.9.5', + version: '0.20.0', license: 'GPL-2.0-only', meson_version: '>=0.59.0', default_options: [ From 579e532908f9dc105e6f115148fa87c29f34f2fc Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Wed, 3 Jun 2026 21:20:21 +0100 Subject: [PATCH 137/146] xdg-shell: protect against SIGABRT when TTY switching Ensure we have got sensible toplevel width/height before trying to set size on configure. This protects against an edge case experienced when TTY switching between labwc and Xfce running on XOrg on another TTY. It is not yet clear what causes this, but hitting wlroots assert() is not great, so let's protect against it. Written-by: @Tamaranch Fixes: #3608 --- src/xdg.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/xdg.c b/src/xdg.c index 03035d63..ccba0de1 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -621,7 +621,24 @@ xdg_toplevel_view_configure(struct view *view, struct wlr_box geo) if (geo.width != view->pending.width || geo.height != view->pending.height) { if (toplevel->base->initialized) { - serial = wlr_xdg_toplevel_set_size(toplevel, geo.width, geo.height); + /* + * geo.{width,height} are checked here to guard against + * an odd edge-case reported in #3608 which involves TTY + * switching between labwc and Xfce running on X.Org on + * another TTY. It is not yet clear what causes this, + * but hitting wlroots assert() is not great, so let's + * protect against it. + * + * Ref: + * - https://github.com/labwc/labwc/issues/3608 + */ + if (geo.width > 0 && geo.height > 0) { + serial = wlr_xdg_toplevel_set_size(toplevel, + geo.width, geo.height); + } else { + wlr_log(WLR_ERROR, "cannot set size %dx%d", + geo.width, geo.height); + } } else { /* * This may happen, for example, when a panel resizes because a From 78227f172464c58b078e5e312d503fbdd3c41e85 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Mon, 8 Jun 2026 19:49:14 +0200 Subject: [PATCH 138/146] CI: Debian Testing temporary labwc removal due to wlroots transition --- .github/workflows/build.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index caa54a33..d42c0d36 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -93,10 +93,15 @@ jobs: sed -i '/^Types/ s/deb/& deb-src/' /etc/apt/sources.list.d/debian.sources apt-get update apt-get upgrade -y - apt-get install -y git gcc clang gdb xwayland - apt-get build-dep -y labwc - apt-get build-dep -y libwlroots-0.19-dev - apt-get build-dep -y libxkbcommon-dev + apt-get install -y git gcc clang gdb xwayland meson pkgconf + apt-get build-dep -y libwlroots-0.20-dev + # Debian Testing temporarily removed labwc due to wlroots 0.20 transition + #apt-get build-dep -y labwc + # Install the deps manually + apt-get install -y libxml2-dev liblzma-dev libglib2.0-dev \ + libcairo2-dev libpango1.0-dev libinput-dev libpng-dev \ + librsvg2-dev wayland-protocols libxkbcommon-dev libdrm-dev \ + scdoc gettext libwlroots-0.20-dev libsfdo-dev - name: Install FreeBSD dependencies if: matrix.name == 'FreeBSD' From f4b9bdab65ddbc8ddca98ecc99e1886a36b2ff36 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Mon, 8 Jun 2026 20:19:41 +0100 Subject: [PATCH 139/146] NEWS.md: add notes on wlroots-0.20 --- NEWS.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/NEWS.md b/NEWS.md index ad71a1df..0b51e520 100644 --- a/NEWS.md +++ b/NEWS.md @@ -84,6 +84,19 @@ The format is based on [Keep a Changelog] [unreleased-commits] +## Notes on wlroots-0.20 + +There are some regression warnings worth noting for the switch to wlroots 0.20: + +- lxqt-panel auto-hiding does not work with a panel size greater than 40 [#3600] + [wlroots-5392] +- Some Wine game windows disappear after alt-tab. It is not yet clear where the + bug is, but the issue manifests itself when running wlroots-0.20 [#3615] + [wlroots-4103] + +[wlroots-5392]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/5392 +[wlroots-4103]: https://gitlab.freedesktop.org/wlroots/wlroots/-/work_items/4103 + ## 0.20.0 - 2026-05-25 [0.20.0-commits] @@ -3223,6 +3236,7 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 [#2956]: https://github.com/labwc/labwc/pull/2956 [#2965]: https://github.com/labwc/labwc/pull/2965 [#2967]: https://github.com/labwc/labwc/pull/2967 +[#2968]: https://github.com/labwc/labwc/pull/2968 [#2970]: https://github.com/labwc/labwc/pull/2970 [#2971]: https://github.com/labwc/labwc/pull/2971 [#2972]: https://github.com/labwc/labwc/pull/2972 @@ -3343,4 +3357,9 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 [#3543]: https://github.com/labwc/labwc/pull/3543 [#3547]: https://github.com/labwc/labwc/pull/3547 [#3567]: https://github.com/labwc/labwc/pull/3567 +[#3576]: https://github.com/labwc/labwc/pull/3576 +[#3577]: https://github.com/labwc/labwc/pull/3577 +[#3581]: https://github.com/labwc/labwc/pull/3581 [#3595]: https://github.com/labwc/labwc/pull/3595 +[#3600]: https://github.com/labwc/labwc/pull/3600 +[#3615]: https://github.com/labwc/labwc/pull/3615 From 28d03b0893609dadaa7c2c9b9c5b2dda0e4636ce Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Thu, 11 Jun 2026 18:01:11 +0200 Subject: [PATCH 140/146] src/buffer.c: prevent creating invalid buffers Testcase: set title of foot to an invisible string (here LTR) First one works and correctly sets the title, 2nd one crashes - printf "\x1b]0;\xe2\x80\x8e%s\x07" "some title" - printf "\x1b]0;\xe2\x80\x8e%s\x07" "" Reported-by: Domo via IRC --- src/buffer.c | 12 ++++++++++++ src/common/font.c | 8 ++++++++ src/scaled-buffer/scaled-font-buffer.c | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/buffer.c b/src/buffer.c index 04ca4328..a9fa717e 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -95,6 +95,7 @@ buffer_adopt_cairo_surface(cairo_surface_t *surface) buffer->surface = surface; buffer->data = cairo_image_surface_get_data(buffer->surface); + assert(buffer->data); buffer->format = DRM_FORMAT_ARGB8888; buffer->stride = cairo_image_surface_get_stride(buffer->surface); buffer->logical_width = width; @@ -107,6 +108,12 @@ buffer_adopt_cairo_surface(cairo_surface_t *surface) struct lab_data_buffer * buffer_create_cairo(uint32_t logical_width, uint32_t logical_height, float scale) { + if (!logical_width || !logical_height) { + wlr_log(WLR_ERROR, "Failed to create cairo buffer of %ux%u: dimensions must be > 0", + logical_width, logical_height); + return NULL; + } + /* Create an image surface with the scaled size */ cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, @@ -142,6 +149,7 @@ buffer_create_from_data(void *pixel_data, uint32_t width, uint32_t height, buffer->logical_width = width; buffer->logical_height = height; buffer->data = pixel_data; + assert(buffer->data); buffer->format = DRM_FORMAT_ARGB8888; buffer->stride = stride; buffer->surface = cairo_image_surface_create_for_data( @@ -188,6 +196,10 @@ buffer_resize(struct lab_data_buffer *src_buffer, int width, int height, struct lab_data_buffer *buffer = buffer_create_cairo(width, height, scale); + if (!buffer) { + wlr_log(WLR_INFO, "Failed to resize buffer to %dx%d", width, height); + return NULL; + } cairo_t *cairo = cairo_create(buffer->surface); struct wlr_box container = { diff --git a/src/common/font.c b/src/common/font.c index 5162d284..642f864d 100644 --- a/src/common/font.c +++ b/src/common/font.c @@ -82,6 +82,7 @@ font_buffer_create(struct lab_data_buffer **buffer, int max_width, cairo_pattern_t *bg_pattern, double scale, bool use_markup) { if (string_null_or_empty(text)) { + *buffer = NULL; return; } @@ -91,6 +92,13 @@ font_buffer_create(struct lab_data_buffer **buffer, int max_width, height = computed_height; } + if (height <= 0 || width <= 0) { + wlr_log(WLR_INFO, "Refusing to create invisible font buffer of %dx%d", + width, height); + *buffer = NULL; + return; + } + *buffer = buffer_create_cairo(width, height, scale); if (!*buffer) { wlr_log(WLR_ERROR, "Failed to create font buffer"); diff --git a/src/scaled-buffer/scaled-font-buffer.c b/src/scaled-buffer/scaled-font-buffer.c index c748c00c..b85a79ff 100644 --- a/src/scaled-buffer/scaled-font-buffer.c +++ b/src/scaled-buffer/scaled-font-buffer.c @@ -29,7 +29,7 @@ _create_buffer(struct scaled_buffer *scaled_buffer, double scale) &self->font, self->color, bg_pattern, scale, self->use_markup); if (!buffer) { - wlr_log(WLR_ERROR, "font_buffer_create() failed"); + wlr_log(WLR_INFO, "font_buffer_create() failed"); } zfree_pattern(solid_bg_pattern); From a814dd1e38c5919e98b74bf1e08171248671b6c8 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Wed, 10 Jun 2026 21:01:19 +0100 Subject: [PATCH 141/146] NEWS.md: add notes for 0.9.8 --- NEWS.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/NEWS.md b/NEWS.md index 0b51e520..27a5abd8 100644 --- a/NEWS.md +++ b/NEWS.md @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog] | Date | All Changes | wlroots version | lines-of-code | |------------|---------------|-----------------|---------------| | 2026-05-25 | [0.20.0] | 0.20.1 | 28313 | +| 2026-06-11 | [0.9.8] | 0.19.3 | 29284 | | 2026-04-17 | [0.9.7] | 0.19.2 | 29277 | | 2026-03-15 | [0.9.6] | 0.19.2 | 29271 | | 2026-03-04 | [0.9.5] | 0.19.2 | 29251 | @@ -46,6 +47,7 @@ The format is based on [Keep a Changelog] [unreleased]: NEWS.md#unreleased [0.20.0]: NEWS.md#0200---2026-05-25 +[0.9.8]: NEWS.md#098---2026-06-11 [0.9.7]: NEWS.md#097---2026-04-17 [0.9.6]: NEWS.md#096---2026-03-15 [0.9.5]: NEWS.md#095---2026-03-04 @@ -230,6 +232,16 @@ There are some regression warnings worth noting for the switch to wlroots 0.19: [wlroots-5098]:https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/5098 [gtk-8792]: https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/8792 +## 0.9.8 - 2026-06-11 + +[0.9.8-commits] + +### Fixed + +- Handle titles with no visible characters @Consolatis [#3631] +- Save window position on initial placement to fix Raspberry Pi pygame SDL + XWayland window starting off-screen. @tokyo4j [#3433] [#3625] [#3616] + ## 0.9.7 - 2026-04-17 [0.9.7-commits] @@ -2785,6 +2797,7 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 [Keep a Changelog]: https://keepachangelog.com/en/1.0.0/ [unreleased-commits]: https://github.com/labwc/labwc/compare/0.20.0...HEAD [0.20.0-commits]: https://github.com/labwc/labwc/compare/0.9.5..0.20.0 +[0.9.8-commits]: https://github.com/labwc/labwc/compare/0.9.7...0.9.8 [0.9.7-commits]: https://github.com/labwc/labwc/compare/0.9.6...0.9.7 [0.9.6-commits]: https://github.com/labwc/labwc/compare/0.9.5...0.9.6 [0.9.5-commits]: https://github.com/labwc/labwc/compare/0.9.4...0.9.5 @@ -3331,6 +3344,7 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 [#3428]: https://github.com/labwc/labwc/pull/3428 [#3429]: https://github.com/labwc/labwc/pull/3429 [#3430]: https://github.com/labwc/labwc/pull/3430 +[#3433]: https://github.com/labwc/labwc/pull/3433 [#3439]: https://github.com/labwc/labwc/pull/3439 [#3440]: https://github.com/labwc/labwc/pull/3440 [#3441]: https://github.com/labwc/labwc/pull/3441 @@ -3363,3 +3377,6 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 [#3595]: https://github.com/labwc/labwc/pull/3595 [#3600]: https://github.com/labwc/labwc/pull/3600 [#3615]: https://github.com/labwc/labwc/pull/3615 +[#3616]: https://github.com/labwc/labwc/pull/3616 +[#3625]: https://github.com/labwc/labwc/pull/3625 +[#3631]: https://github.com/labwc/labwc/pull/3631 From bbfa6bbddb9d0e08a2b6cf8606dba4fb67fc01ac Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Wed, 10 Jun 2026 21:04:59 +0100 Subject: [PATCH 142/146] CONTRIBUTING.md: add section on LLM/AI Tools --- CONTRIBUTING.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1a2251ad..eac0a9af 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,7 +19,8 @@ - [6. Unit Tests](#unit-tests) - [7. Submitting Patches](#submitting-patches) - [8. Native Language Support](#native-language-support) -- [9. Upversion](#upversion) +- [9. Tools](#tools) +- [10. Upversion](#upversion) # How to Contribute @@ -472,6 +473,29 @@ This generates a new pot file at `po/labwc.pot` 3. Copy the header from the original `labwc.pot` to the new one, keeping the newly generated dates, check for sanity and commit. +# Tools + +We permit LLM and AI-assisted tooling, but only on the basis that humans remain +fully accountable. Contributors must use an `Assisted-by:` tag in the commit +logs if AI tools generated or significantly assisted with any part of the code +or documentation. Humans retain full legal and technical responsibility for the +resulting work, including any defects. + +We have received Pull Requests where the submitter clearly did not understand +the code, could not reason about it, and would be unable to maintain it. This +is not acceptable. + +Any AI-generated code contribution must be compatible with the GPL-2.0-only +license. + +While LLMs can be useful for triage, review, clean-up, API refactoring and +similar tasks, we strongly discourage AI slop. Code review effort is usually the +project's primary bottleneck, and submitting unreviewed, AI-generated garbage +wastes reviewer time, slows development, and harms the overall health of the +project. Likewise, AI-generated commit messages and AI-written text in issues +and discussions are strongly discourage and may be treated as sabotage on this +basis. + # Upversion It is generally only the lead-maintainer who will upversion, but in order From 2135fb0d3512a99ffe514e742a17a977d9df4a99 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Thu, 11 Jun 2026 22:04:07 +0100 Subject: [PATCH 143/146] [fixup] minor typos --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eac0a9af..c1c70b47 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -482,7 +482,7 @@ or documentation. Humans retain full legal and technical responsibility for the resulting work, including any defects. We have received Pull Requests where the submitter clearly did not understand -the code, could not reason about it, and would be unable to maintain it. This +the code, could not reason about it, and would be unable to maintain it. This is not acceptable. Any AI-generated code contribution must be compatible with the GPL-2.0-only @@ -493,7 +493,7 @@ similar tasks, we strongly discourage AI slop. Code review effort is usually the project's primary bottleneck, and submitting unreviewed, AI-generated garbage wastes reviewer time, slows development, and harms the overall health of the project. Likewise, AI-generated commit messages and AI-written text in issues -and discussions are strongly discourage and may be treated as sabotage on this +and discussions are strongly discouraged and may be treated as sabotage on this basis. # Upversion From 07e1053a8d3c1170f266a69f79fee7c43c522fb1 Mon Sep 17 00:00:00 2001 From: Nikolas Nyby Date: Fri, 12 Jun 2026 23:06:53 -0400 Subject: [PATCH 144/146] readme: Use `meson setup` in example to fix meson warning Using meson without an explicit command emits a warning. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 80796af7..4fa5c0e4 100644 --- a/README.md +++ b/README.md @@ -153,7 +153,7 @@ Build dependencies include: - meson, ninja, gcc/clang - wayland-protocols -Disable xwayland with `meson -Dxwayland=disabled build/` +Disable xwayland with `meson setup -Dxwayland=disabled build/` For OS/distribution specific details see [wiki]. From 4dab6994dc24f73017f4dcac0a45e03709a2e5cf Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Thu, 11 Jun 2026 21:55:31 +0100 Subject: [PATCH 145/146] NEWS.md: add notes for 0.20.1 --- NEWS.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 27a5abd8..845451a1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog] | Date | All Changes | wlroots version | lines-of-code | |------------|---------------|-----------------|---------------| +| 2026-06-15 | [0.20.1] | 0.20.1 | 28337 | | 2026-05-25 | [0.20.0] | 0.20.1 | 28313 | | 2026-06-11 | [0.9.8] | 0.19.3 | 29284 | | 2026-04-17 | [0.9.7] | 0.19.2 | 29277 | @@ -46,6 +47,7 @@ The format is based on [Keep a Changelog] | 2021-03-05 | [0.1.0] | 0.12.0 | 4627 | [unreleased]: NEWS.md#unreleased +[0.20.1]: NEWS.md#0201---2026-06-15 [0.20.0]: NEWS.md#0200---2026-05-25 [0.9.8]: NEWS.md#098---2026-06-11 [0.9.7]: NEWS.md#097---2026-04-17 @@ -99,6 +101,22 @@ There are some regression warnings worth noting for the switch to wlroots 0.20: [wlroots-5392]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/5392 [wlroots-4103]: https://gitlab.freedesktop.org/wlroots/wlroots/-/work_items/4103 +## 0.20.1 - 2026-06-15 + +[0.20.1-commits] + +This is a small bug fix release. + +### Fixed + +- Handle titles with no visible characters, for example the left-to-right mark + (‎) @Consolatis [#3630] +- Protect against SIGABRT when TTY switching in unusual circumstances by + ensuring that xdg-shell windows have sensible width and height before trying + to set size on configure. This protects against an edge case experienced when + switching between labwc on one TTY and Xfce on XOrg on another TTY. + @johanmalm @Tamaranch [#3617] + ## 0.20.0 - 2026-05-25 [0.20.0-commits] @@ -2795,7 +2813,8 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 ShowMenu [Keep a Changelog]: https://keepachangelog.com/en/1.0.0/ -[unreleased-commits]: https://github.com/labwc/labwc/compare/0.20.0...HEAD +[unreleased-commits]: https://github.com/labwc/labwc/compare/0.20.1...HEAD +[0.20.1-commits]: https://github.com/labwc/labwc/compare/0.20.0..0.20.1 [0.20.0-commits]: https://github.com/labwc/labwc/compare/0.9.5..0.20.0 [0.9.8-commits]: https://github.com/labwc/labwc/compare/0.9.7...0.9.8 [0.9.7-commits]: https://github.com/labwc/labwc/compare/0.9.6...0.9.7 @@ -3378,5 +3397,7 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16 [#3600]: https://github.com/labwc/labwc/pull/3600 [#3615]: https://github.com/labwc/labwc/pull/3615 [#3616]: https://github.com/labwc/labwc/pull/3616 +[#3617]: https://github.com/labwc/labwc/pull/3617 [#3625]: https://github.com/labwc/labwc/pull/3625 +[#3630]: https://github.com/labwc/labwc/pull/3630 [#3631]: https://github.com/labwc/labwc/pull/3631 From 529fc382da8f9b6bc4dcea720fd3561e605abd91 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Mon, 15 Jun 2026 19:36:54 +0100 Subject: [PATCH 146/146] build: bump version to 0.20.1 --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 8684732f..d85823c9 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project( 'labwc', 'c', - version: '0.20.0', + version: '0.20.1', license: 'GPL-2.0-only', meson_version: '>=0.59.0', default_options: [