From d6425c527a0b0af26e763f2a1201df7c7e24cbc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Poisot?= Date: Thu, 26 Feb 2026 20:40:04 +0000 Subject: [PATCH 1/3] sway/config/output: fix hdr+color_profile conflict detection Fixes: 26eb393d6dd7631dc5b7edd0df95342d606e907c `color_profile --device-primaries gamma22` was not inhibiting HDR like all other non-default color_profile values --- sway/config/output.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sway/config/output.c b/sway/config/output.c index 3d25b46c7..6d6afdc25 100644 --- a/sway/config/output.c +++ b/sway/config/output.c @@ -555,8 +555,10 @@ static void queue_output_config(struct output_config *oc, } bool hdr = oc && oc->hdr == 1; - if (hdr && oc->color_transform != NULL) { - sway_log(SWAY_ERROR, "Cannot HDR on output %s: output has an ICC profile set", wlr_output->name); + bool color_profile = oc && (oc->color_transform != NULL + || oc->color_profile == COLOR_PROFILE_TRANSFORM_WITH_DEVICE_PRIMARIES); + if (hdr && color_profile) { + sway_log(SWAY_ERROR, "Cannot use HDR on output %s: output has a color profile set", wlr_output->name); hdr = false; } set_hdr(wlr_output, pending, hdr); From 0356a020c1c14b4f9e9c3583d6a87dd7764714a2 Mon Sep 17 00:00:00 2001 From: "Lars-Ragnar A. Haugen" Date: Thu, 26 Feb 2026 16:34:37 +0100 Subject: [PATCH 2/3] layer-shell: handle popup reposition for unconstraining Layer shell popups were missing a handler for the xdg_popup reposition event. When a client (e.g. GTK4) creates a popup and then sends a reposition request, wlroots resets the scheduled geometry back to the positioner's original value. Without a reposition handler, the unconstrained geometry computed on the initial commit was lost, causing popups such as tooltips to render outside the screen viewport. This was most visible with GTK4 layer shell apps (e.g. taskbars) where tooltips would appear below the bottom edge of the screen instead of being flipped/slid into the visible area. Also switch the destroy listener from wlr_popup->base->events.destroy to wlr_popup->events.destroy so that cleanup runs before wlroots asserts that all popup signal listeners have been removed. Fixes #8518 --- include/sway/layers.h | 1 + sway/desktop/layer_shell.c | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/sway/layers.h b/include/sway/layers.h index 27b5dde1b..e257da0bd 100644 --- a/include/sway/layers.h +++ b/include/sway/layers.h @@ -33,6 +33,7 @@ struct sway_layer_popup { struct wl_listener destroy; struct wl_listener new_popup; struct wl_listener commit; + struct wl_listener reposition; }; struct sway_output; diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c index 8c54d71aa..c8f485971 100644 --- a/sway/desktop/layer_shell.c +++ b/sway/desktop/layer_shell.c @@ -321,6 +321,7 @@ static void popup_handle_destroy(struct wl_listener *listener, void *data) { wl_list_remove(&popup->destroy.link); wl_list_remove(&popup->new_popup.link); wl_list_remove(&popup->commit.link); + wl_list_remove(&popup->reposition.link); free(popup); } @@ -356,6 +357,11 @@ static void popup_handle_commit(struct wl_listener *listener, void *data) { } } +static void popup_handle_reposition(struct wl_listener *listener, void *data) { + struct sway_layer_popup *popup = wl_container_of(listener, popup, reposition); + popup_unconstrain(popup); +} + static void popup_handle_new_popup(struct wl_listener *listener, void *data); static struct sway_layer_popup *create_popup(struct wlr_xdg_popup *wlr_popup, @@ -376,11 +382,13 @@ static struct sway_layer_popup *create_popup(struct wlr_xdg_popup *wlr_popup, } popup->destroy.notify = popup_handle_destroy; - wl_signal_add(&wlr_popup->base->events.destroy, &popup->destroy); + wl_signal_add(&wlr_popup->events.destroy, &popup->destroy); popup->new_popup.notify = popup_handle_new_popup; wl_signal_add(&wlr_popup->base->events.new_popup, &popup->new_popup); popup->commit.notify = popup_handle_commit; wl_signal_add(&wlr_popup->base->surface->events.commit, &popup->commit); + popup->reposition.notify = popup_handle_reposition; + wl_signal_add(&wlr_popup->events.reposition, &popup->reposition); return popup; } From c57daaf0d1640b45579d75ce9775b8c0d03299b7 Mon Sep 17 00:00:00 2001 From: Willow Barraco Date: Wed, 25 Feb 2026 07:42:24 +0100 Subject: [PATCH 3/3] Skip checking if criteria is matching the view when not mapped Multiple checks in this method use view->container, but it can be NULL at some points. Bail early to avoid crash. --- sway/criteria.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sway/criteria.c b/sway/criteria.c index 230f47a18..6be6e7042 100644 --- a/sway/criteria.c +++ b/sway/criteria.c @@ -196,6 +196,10 @@ static bool criteria_matches_view(struct criteria *criteria, struct sway_container *focus = seat_get_focused_container(seat); struct sway_view *focused = focus ? focus->view : NULL; + if (!view->container) { + return false; + } + if (criteria->title) { const char *title = view_get_title(view); if (!title) {