update_keycodes_iter() currently has 4(!) levels of nested loops, which
makes the logic (especially the break/continue statements) difficult to
understand. The logic also appears to continue looping uselessly after
a given keycode has already been added to a keybind.
Refactor by adding some small utility functions:
- keybind_contains_keycode()
- keybind_contains_keysym()
- keybind_contains_any_keysym()
No functional change intended.
This is a common practice in C projects, which simply enforces that
each header must compile cleanly without implicit dependencies on
other headers (see also the previous commit).
And make mousebind handlers use that one.
Also remove keyboard_any_modifiers_pressed() and replace its usage
with the new function.
Without this patch we would only request the modifier state of the
keyboard group which makes mousebinds involving keyboard modifiers
break for virtual keyboards like when using wayvnc. Same story for
hiding the workspace overlay or snapping to regions.
Fixes: #2511
Before this commit, keystrokes were interpreted based on following
hard-coded rules while the window switcher is active:
1. Up/Left arrow keys cycle the window forward.
2. Down/Right arrow keys cycle the window backward.
3. Other keystrokes cycle the window in the initial direction specified
by NextWindow/PreviousWindow actions. But while Shift key is pressed,
the direction is inverted.
...and keybind actions were never executed.
However, this lead to a counter-intuitive behavior for new, especially
pre-Openbox users. For example, in the following keybinds, after the user
activates the window switcher with Super+n, Super+p cycles the window
_forward_:
<keybind key="W-n">
<action name="NextWindow" />
</keybind>
<keybind key="W-p">
<action name="PreviousWindow" />
</keybind>
This is because the key 'n' is recognized just as a normal key in the
third hard-coded rule.
So this commit changes the rules to be more Openbox-like:
1. Up/Left arrow keys cycles the window forward.
2. Down/Right arrow keys cycles the window backward.
3. Other keystrokes are matched against keybinds and execute their
actions. If they include NextWindow/PreviousWindow action, it cycles
the selected window forward/backward even while the window switcher
is active.
Currently we may end up in an endless loop of Reconfigure requests
if the Reconfigure action was called by a keybind. If the reconfigure
takes too long (which may happen on slow systems with libsfdo full
debug logging for example) the reconfigure might be triggered again
and again.
To prevent that, simply cancel all keybind_repeat timers on reconfigure.
The previous revert fixed the problem of stuck modifier keys with
keybinds in Blender, but made Firefox show its menu bar with Alt-*
keybinds. This is fundamentally inevitable due to the limitation of
wayland protocol, but at least for the default Alt-Tab keybind for
window switcher, we can mitigate this problem by clearing the keyboard
focus when the window switcher is activated. This is what KWin does, and
we decided to follow that.
So in this commit, keyboard and pointer focus are temporarily cleared
while Move/Resize, window switcher and menu interactions and restored
after them. We slightly deviate from KWin as KWin doesn't clear the
keyboard focus while Move/Resize, but it solves our existing problem
that Firefox shows its menu bar after dragging it with default Alt-Drag
mousebind, and this is what Mutter does.
We considered other solutions, but they don't work well:
1. Send wl_keyboard.{leave,enter} every time keybinds/mousebinds are
triggered. This solves the Firefox's menu bar problem, but that
sounds like a workaround and sending unnecessary events every time is
not desirable.
2. Send release events for both modifiers and keys even when they are
bound to keybinds. This is what Mutter is doing, but it looks like an
implementation issue and violates wayland protocol.
...of modifiers which are part of keybinds. This supports clients (for
example blender) that want to see modifier-release-events even if they are
part of a keybinds.
Most clients (including those using Qt and GTK) are setup to not see these
modifier release events and actually misbehave if they do. For example
Firefox shows the menu bar if alt is pressed and then released, whereas if
only pressed (because the release is absorbed) nothing happens. So, if
Firefox saw bound modifier-release-events it would show the menu bar every
time the window-switcher is used with alt-tab.
<windowRules>
<windowRule identifier="blender" wantAbsorbedModifierReleaseEvents="yes"/>
</windowRules>
Issue #1507
...to all clients rather than just the one with keyboard focus on keyboard
enter/create, modifer press/release and wlr_seat_set_keyboard().
This enables:
- Clients such as panels to display the current keyboard layout without
introducing new wayland protocols or other IPC.
- Unfocused xdg-shell clients to understand button press with keyboard
modifiers for example Ctrl+click.
The keymap is forwarded to all clients in wlr_seat_set_keyboard(). When a
keymap contains multiple layouts, the selection is made via modifiers,
which previously were only sent to the client with keyboard focus.
Tested with: https://github.com/johanmalm/keyboard-layout
Ref: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4496Fixes: #2271
Before this commit, we assumed `ShowMenu` action is not bound to any
buttons other than window menu button and always place the client-menu
under the window-menu button when atCursor="no". Also, it was going to be
difficult to distinguish whether the action is executed from the window
menu button or the window icon, which will be added soon.
This commit fixes it to open the menu under the actually-clicked button by
passing `cursor_context` to `actions_run()`, with some refactoring:
- `seat->pressed.resize_edges` is removed and it's calculated from the
cursor position and `seat->pressed.type` just before running Resize
action. This slightly changes the existing logic to determine the
resizing edges with Alt-Right + Drag mousebinding, but
`seat->pressed.type` is still stored on button press so it doesn't bring
back the issue #543.
- `seat->pressed.toplevel` is removed and `get_toplevel()` in
`update_pressed_surface()` may be called more often, but its overhead
will be negligible.
...when cycling windows. Also make the toggling of direction when shift
is pressed relative to the initial direction. For example if W-j is
bound to PreviousWindow, subsequent key presses will continue to
cycle backwards unless shift if pressed.
Add documentation for using shift/arrow keys in Next/Previous
...to make keybind actions fire on the release event rather then when the
key is first pressed. This is useful for binding actions to modifier keys
only. The most likely use-case for this is the binding of a Super key to a
menu, for example:
<keybind key="Super_L" onRelease="yes">
<action name="Execute" command="rofi -show drun"/>
</keybind>
If another keybind is issued between the press and release, the on-release
keybind is cancelled.
Co-authored-by: @johanmalm
- Replaced `session_lock` with `session_lock_manager` which is
persistent throughout the session.
- Replaced `session_lock->abandoned` with `session_lock_manager->locked`.
Old `session_lock->abandoned` is equal to
`!session_lock_manager->lock && session_lock_manager->locked`.
- Eliminated the use of global variables in `session-lock.c`.
- Changed some function names.
There were some missing headers like <stddef.h> for `NULL`, <wayland-util.h>
for `wl_link` and <stdbool.h> for `true`/`false`.
Also this commit fixes that `labwc.h` and `ime.h` included each other.
Add custom field with subset of printf style formatting
to replace the original field formats.
Example:
<windowSwitcher preview="no" outlines="no" allWorkspaces="yes">
<fields>
<field content="custom" format="foobar %b %3s %-10o %-20W %-10i%t" width="100%" />
</fields>
</windowSwitcher>
Mono space font recommended. May need OSD width adjusted
Co-authored-by: @Consolatis (based on work done by them)
...and unify region overlay and snap-to-edge overlay into overlay.c.
Snap-to-edge overlay is delayed for 500ms to prevent flickering when
the view is dragged from an output to another (demo in discussion labwc#1613).
This also fixes a bug that region overlay is not shown when a modifier
key is re-pressed.
...if keymap cannot be created for the provided XKB_DEFAULT_LAYOUT.
If keymap still cannot be created, exit with a helpful message to avoid
crash that is hard to understand.
Fixes: https://github.com/stefonarch/lxqt-labwc-session/issues/7
If keyboard-layout-per-toplevel-window is used, reset the group (index)
for each window on --reconfigure whenever the keymap has changed.
Refactor to use a common configure function for reconfigure and
keyboard-group creation.
Co-authored-by: @johanmalm
Fixes#1407
...(calling `wlr_session_change_vt()`) because when the session is
switched, the access to the keyboard is lost and therefore the RELEASE
event will not be passed to the compositor.
Fixes bug whereby compositor crashes on VT change on FreeBSD.
Fixes#1424
...and call actions after closing menus so that virtual keyboard input
caused by actions are sent to the surface with keyboard-focus rather
than being consumed by the open menu.
Fixes: #1366
Do no process virtual keyboard keycodes (just the keysyms).
Reproduce bug by issuing `wlrctl keyboard type xyz` and observe only 'x'
when 'xyz' was expected.
The 'y' and 'z' were matched in match_keybinding() in the keycode section and
returned keybinds for `XF86_AudioLowerVolume` and `XF86_AudioRaiseVolume`
respectively.
Fixes: #1367