From 83e67b32b6194917a4fd47e875809b3be632dfa8 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Mon, 27 Nov 2023 17:11:29 -0500 Subject: [PATCH] xwayland: treat X11 panel views as if fixedPosition rule is set --- include/view.h | 10 ++++++++++ src/interactive.c | 4 +++- src/view.c | 12 +++++++++++- src/xwayland.c | 9 +++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/include/view.h b/include/view.h index 04460f3b..a3dd9cb0 100644 --- a/include/view.h +++ b/include/view.h @@ -112,6 +112,8 @@ struct view_impl { struct view_size_hints (*get_size_hints)(struct view *self); /* if not implemented, VIEW_WANTS_FOCUS_ALWAYS is assumed */ enum view_wants_focus (*wants_focus)(struct view *self); + /* returns true if view reserves space at screen edge */ + bool (*has_strut_partial)(struct view *self); }; struct view { @@ -431,6 +433,14 @@ void view_append_children(struct view *view, struct wl_array *children); */ bool view_is_related(struct view *view, struct wlr_surface *surface); +/** + * view_has_strut_partial() - returns true for views that reserve space + * at a screen edge (e.g. panels). These views are treated as if they + * have the fixedPosition window rule: i.e. they are not restricted to + * the usable area and cannot be moved/resized interactively. + */ +bool view_has_strut_partial(struct view *view); + const char *view_get_string_prop(struct view *view, const char *prop); void view_update_title(struct view *view); void view_update_app_id(struct view *view); diff --git a/src/interactive.c b/src/interactive.c index 31c3c076..95eb4b78 100644 --- a/src/interactive.c +++ b/src/interactive.c @@ -35,7 +35,9 @@ interactive_begin(struct view *view, enum input_mode mode, uint32_t edges) return; } - if (window_rules_get_property(view, "fixedPosition") == LAB_PROP_TRUE) { + /* Prevent moving/resizing fixed-position and panel-like views */ + if (window_rules_get_property(view, "fixedPosition") == LAB_PROP_TRUE + || view_has_strut_partial(view)) { return; } diff --git a/src/view.c b/src/view.c index f26ca4ac..7dc81205 100644 --- a/src/view.c +++ b/src/view.c @@ -593,7 +593,9 @@ view_adjust_floating_geometry(struct view *view, struct wlr_box *geometry) return false; } - if (window_rules_get_property(view, "fixedPosition") == LAB_PROP_TRUE) { + /* Avoid moving panels out of their own reserved area ("strut") */ + if (window_rules_get_property(view, "fixedPosition") == LAB_PROP_TRUE + || view_has_strut_partial(view)) { return false; } @@ -1550,6 +1552,14 @@ view_is_related(struct view *view, struct wlr_surface *surface) return false; } +bool +view_has_strut_partial(struct view *view) +{ + assert(view); + return view->impl->has_strut_partial && + view->impl->has_strut_partial(view); +} + const char * view_get_string_prop(struct view *view, const char *prop) { diff --git a/src/xwayland.c b/src/xwayland.c index ac2c7158..30277c06 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -103,6 +103,14 @@ xwayland_view_wants_focus(struct view *view) return VIEW_WANTS_FOCUS_NEVER; } +static bool +xwayland_view_has_strut_partial(struct view *view) +{ + struct wlr_xwayland_surface *xsurface = + xwayland_surface_from_view(view); + return (bool)xsurface->strut_partial; +} + static struct wlr_xwayland_surface * top_parent_of(struct view *view) { @@ -786,6 +794,7 @@ static const struct view_impl xwayland_view_impl = { .is_related = xwayland_view_is_related, .get_size_hints = xwayland_view_get_size_hints, .wants_focus = xwayland_view_wants_focus, + .has_strut_partial = xwayland_view_has_strut_partial, }; void