Jens Peters [Fri, 22 Dec 2023 10:20:42 +0000 (11:20 +0100)]
xwayland: Prevents usage of invalid data pointer
There are situations where the data pointer of a parent is NULL.
Checking for NULL first fixes e.g. a segmentation fault in CLion
when opening the settings window from a popup menu.
See also https://github.com/labwc/labwc/issues/1351#issuecomment-1867475324
John Lindgren [Tue, 28 Nov 2023 05:38:18 +0000 (00:38 -0500)]
xwayland: fix issue with panel getting stuck offscreen
For unknown reasons, XWayland surfaces that are completely offscreen
seem not to generate commit events. In rare cases, this can prevent an
offscreen window from moving onscreen (since we wait for a commit event
that never occurs). As a workaround, move offscreen surfaces
immediately.
This fixes an issue that I can reproduce by having qmpanel displayed on
a (larger) external monitor, then undocking the laptop so that qmpanel
requests a simultaneous move+resize to the (smaller) laptop display.
John Lindgren [Sat, 16 Dec 2023 14:56:45 +0000 (09:56 -0500)]
theme: use non-hover button variants as fallback
Some themes don't have hover variants for button pixmaps.
It looks better visually to use the non-hover variants as fallbacks
rather than the built-in 6x6 pixmaps.
Johan Malm [Tue, 19 Dec 2023 17:45:43 +0000 (17:45 +0000)]
seat: do not update active_view on layer-shell keyboard focus
...because layer-shell clients are not views and we want to be able to
use foreign-toplevel protocol on the active view even if a client such as
a panel has taken keyboard focus.
fix: fall-through to default cursor in cursor_get_from_edge()
When assertions are disabled, providing an unexpected input to
cursor_get_from_edge will cause the non-void function to terminate
without a return value. This may be effectively unreachable in practice.
However, returning a default cursor as a fall-through case will both
silence a compiler warning and prevent catastrophy should the function
ever be called with a permitted value.
Johan Malm [Sat, 9 Dec 2023 19:37:35 +0000 (19:37 +0000)]
theme: use max_toggled_hover.xbm
...and treat max_hover_toggled.xbm as an alternative name supported for
compatibility reasons.
Use the following button filename schema: "BUTTON [TOGGLED] [STATE]"
with the words separted by underscore and with the following meaning:
- BUTTON can be one of 'max', 'iconify', 'close', 'menu'
- TOGGLED is either 'toggled' or nothing
- STATE is 'hover' or nothing.
This is consistent with the openbox.org wiki and it is believed that this
is how the vast majority of extant openbox themes out there are written.
But please be aware that it is actually different to vanilla Openbox which
uses: "BUTTON [STATE] [TOGGLED]" following a commit in 2014 which broke
themes and led to some distros patching Openbox:
https://github.com/danakj/openbox/commit/35e92e4c2a45b28d5c2c9b44b64aeb4222098c94
Arch Linux and Debian patch Openbox to keep the old syntax (the one that
this commit aligns us with).
https://gitlab.archlinux.org/archlinux/packaging/packages/openbox/-/blob/main/debian-887908.patch?ref_type=heads
Consolatis [Sat, 2 Dec 2023 14:05:26 +0000 (15:05 +0100)]
src/output.c: ensure we don't carry around a stale output pointer
Prevent carrying around the wlr_output->data pointer when
destroying an output. The set_gamma handler may be called
during the destruction of a wlr_output after our own
destroy handler has already been called. This patch resets
the wlr_output->data pointer in our destroy handler and
adds a check in the set_gamma handler to verify the output
is actually valid.
Jens Peters [Thu, 30 Nov 2023 22:25:13 +0000 (23:25 +0100)]
keyboard: allow back by arrow-up or arrow-left in cycle view OSD
All non-modifier keys cycle forward which makes sense for
e.g. tab but is not very intuitive for arrow-up or arrow-left.
Handle those keys separately to provide a feel of navigation
by arrow keys in the cycle view OSD.
John Lindgren [Wed, 15 Nov 2023 16:33:55 +0000 (11:33 -0500)]
keyboard: break up handle_compositor_keybindings()
This function has grown quite large over time. Breaking out various
smaller functions makes the logic easier to follow.
No functional change intended, but there is a minor logical change:
- Due to factoring out match_keybinding(), each keypress can only
match a single keybinding now. Previously, it was theoretically
possible for a single keypress to map to multiple keysyms which could
each match a different keybinding.
John Lindgren [Tue, 22 Nov 2022 10:11:50 +0000 (05:11 -0500)]
output,xwayland: Add support for _NET_WM_STRUT_PARTIAL
Account for space taken up by XWayland panels (as indicated by the
_NET_WM_STRUT_PARTIAL property) in the usable_area calculation.
This makes it possible to use labwc in a "transitional" setup, where it
replaces the X11 window manager and compositor, but most other parts of
a existing X11 desktop environment can still be used via XWayland.
(Some remaining drawbacks of such a setup would be the lack of desktop
icons, and native Wayland clients not showing up in X11-based taskbars.)
John Lindgren [Tue, 24 Oct 2023 17:49:15 +0000 (13:49 -0400)]
xwayland: set _NET_WORKAREA property based on usable area
XWayland clients use the _NET_WORKAREA root window property to determine
how much of the screen is not covered by panels/docks. The property is
used for example by Qt to determine areas of the screen that popup menus
should not overlap (see QScreen::availableVirtualGeometry).
Depends on wlroots MR:
https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4406
v2: prevent calling wlr_xwayland_set_workareas() too early
v3: fix segfault at exit (server->xwayland == NULL)
We now delay requested resolution changes by the backend until
the next frame event which causes us to render the new content
on the already enlarged buffer. Before this change, an empty
(black) buffer would have been shown instead before the next
frame event caused a new render of the actual contents.
Keep commiting the new state and then scheduling a frame event
would not help as due to the commit call it would still show an
empty buffer in the meantime.
Just modifying wlr_output->pending wouldn't work either because
wlr_scene_output_commit() *completely* ignores it (and it will
be removed in future wlroots commits). For this reason we move
to wlr_scene_output_build_state() directly because it allows us
to supply the current wlr_output->pending state and thus apply
any resolution change in lockstep with new rendering. Result:
No more flickering in the wayland backend and resizing is again
smooth as butter.
This prevents constant flicker while resizing
when running nested via the wayland backend.
For the X11 backend (can be tested via `WLR_BACKENDS=x11 labwc`),
it is still rather janky but at least doesn't cause endless self-
resizing anymore.
Need to handle new unified mapping, where mapping is attached to the
wlr_surface objects instead of their parents. Also, most of them require
a new associate event for xsurface objects, their surface member will be
NULL before this event is received.
Johan Malm [Sat, 25 Nov 2023 17:40:44 +0000 (17:40 +0000)]
xwayland: assign view->surface earlier in map handler
...as it needs to be set before honouring xwayland_surface->fullscreen
because that calls desktop_update_top_layer_visiblity() which relies on
view->surface being set in view_is_focusable() since 13d0b14.
Fix bug introduced by PR #1237 which fails to hide the xfce4-panel (or
any other layer-shell client in the top layer) whilst gaming in
fullscreen. The bug can be observed with the following games:
- Alan Wake 2 (wine)
- Starfield (steam+proton)
- Cyberpunk (steam+proton)
- Quake 1 Remaster (steam-native)
Fixes: #661 (the last bit of it) Reported-by: @ScarecrowDM Helped-by: @Consolatis
Consolatis [Tue, 21 Nov 2023 02:09:22 +0000 (03:09 +0100)]
Keep xwayland stacking order in sync when switching workspaces
Until we expose the workspaces to xwayland we need a way to
ensure that xwayland views on the current workspace are always
stacked above xwayland views on other workspaces.
If we fail to do so, issues arise in scenarios where we change
the mouse focus but do not change the (xwayland) stacking order.
Reproducer:
- If followMouse is enabled, raiseOnFocus must be disabled
- Open at least two xwayland windows which allow scrolling
(some X11 terminal with 'man man' for example)
- Switch to another workspace, open another xwayland window
which allows scrolling and maximize it
- Switch back to the previous workspace with the two windows
- Move the mouse to the xwayland window that does *not* have
focus
- Start scrolling
- All scroll events should end up on the maximized window on
the other workspace
This patch fixes the issue by simply raising all windows from
the current workspace again in their original stacking order
when switching workspaces.
Store the key-state in `handle_keybind()` before any call to
`action_run()` as this may lead to `seat_focus()` which passes
'pressed-sent' keys to the new surface.
This partially reverts 7571c4b, which as a standalone commit was fine, but
when 'pressed_mods' were then included in 'bound' in 98bf316,
`key_state_store_pressed_keys_as_bound()` was again required in
`handle_keybind()` to ensure modifers are not passed as non-modifiers in
`wlr_seat_keyboard_notify_enter()` in `seat_focus()`
John Lindgren [Sat, 11 Nov 2023 04:43:46 +0000 (23:43 -0500)]
keyboard: include pressed modifiers in bound set
This prevents applications from seeing and handling the release event
for a modifier key that was part of a keybinding (e.g. Firefox displays
its menu bar for a lone Alt press + release).
John Lindgren [Sat, 11 Nov 2023 03:53:17 +0000 (22:53 -0500)]
keyboard: remove exceptions from storing pressed keys
These exceptions were added to prevent certain keys (modifiers and
synthetic layout switch key-events) from disabling keybindings (due to
the "nr_pressed_keys > 1" check). That check no longer exists, so the
exceptions should no longer be necessary.
John Lindgren [Sat, 11 Nov 2023 03:00:04 +0000 (22:00 -0500)]
keyboard: remove nr_pressed_keys == 1 restriction for keybindings
This restriction should be unnecessary now (see the previous commit for
details) and caused issues with keybindings not working on some systems
where irregular keypress events are received (e.g. XF86XK_WakeUp)
without an accompanying release event.
Kept separate from the previous commit for the sake of potential future
bisects.
John Lindgren [Sat, 4 Nov 2023 05:23:43 +0000 (01:23 -0400)]
keyboard: avoid stuck keys due to keybindings (alternate approach)
Before commit e77330bc3fe7, there were issues with keys becoming "stuck"
if other keys were pressed at the time a keybinding was matched, because
those other keys were included in the "bound" set and the release events
were incorrectly eaten by labwc.
Commit e77330bc3fe7 solved that issue with the "big hammer" approach of
preventing keybindings from working at all if other keys were pressed:
if (key_state_nr_pressed_keys() > 1) {
return false;
}
This is an alternate approach to solving the original problem, by (1)
not including those other keys in the "bound" set and (2) making sure we
always forward release events for un-bound keys to clients (even if a
menu or OSD is displayed).
Details:
- Since we only ever want to store the single matched keycode as bound,
key_state_store_pressed_keys_as_bound() doesn't really make sense in
the plural, so rename it to key_state_store_pressed_key_as_bound() and
pass in the keycode.
- The calls to key_state_store_pressed_keys_as_bound() within
handle_keybinding() appear to be redundant since it is also called
from the parent function (handle_compositor_keybindings()). So remove
these calls.
- Finally, rework the logic for handling key-release events so that we
always forward release events for keys not in the "bound" set.
This PR does not remove the "key_state_nr_pressed_keys() > 1" check, and
because of that should not result in any functional change. It should
however make it possible to relax or remove that check in future.
Johan Malm [Thu, 9 Nov 2023 21:44:51 +0000 (21:44 +0000)]
window-rules: add fixedPosition property
...to address regression introduced by 57075ce and enables panel/desktop
clients which rely on window rules to remain in the same position when
the usable-area changes (normally because an exclusive layer-shell
clients is started/finished).
Also disallows interactive move/resize, for example by alt +
mouse-press.
tokyo4j [Tue, 7 Nov 2023 05:43:53 +0000 (14:43 +0900)]
interactive: Make window snapping with mouse more intuitive
1. Prevent window snapping triggered by mouse from moving the window
into the adjacent output.
2. Make the coordinates used to check whether window snapping is
triggered relative to the output the cursor is at, not the output the
view is belonging to. This allows users to grab a tiled window and move
it into another output or tile it again in another output in a single
drag.
John Lindgren [Sat, 21 Oct 2023 23:49:38 +0000 (19:49 -0400)]
xdg: try to handle missing set_window_geometry with Qt apps
Qt applications occasionally fail to call set_window_geometry after a
configure request, but do correctly update the actual surface extent.
This results in a mismatch between the window decorations (which follow
the logical geometry) and the visual size of the client area. As a
workaround, try to detect this case and ignore the out-of-date window
geometry.
John Lindgren [Fri, 3 Nov 2023 16:38:07 +0000 (12:38 -0400)]
view: ensure that floating views don't overlap top panels
The top_left_edge_boundary_check() function in xwayland.c ensures that
views trying to position themselves at 0,0 don't end up with a titlebar
offscreen. However, it doesn't take into account the usable area and
thus these views can still end up overlapping a top panel.
Also, there is no good reason for top_left_edge_boundary_check() to be
xwayland-specific. This logic should really be part of
view_adjust_for_layout_change().
To fix all this, add a new view_adjust_floating_geometry() function,
which replaces the existing similar (and duplicated) logic in
view_apply_natural_geometry() and view_adjust_for_layout_change().
view_adjust_for_layout_change() is already being called from xwayland's
set_initial_position(), so top_left_edge_boundary_check() is now
redundant and can just be deleted.
Lightly tested with waybar and feh --geometry 640x480+0+0. The feh
window is now correctly positioned below waybar, even if started before
waybar (in that case, the feh window is moved when waybar starts).