]> git.mdlowis.com Git - proto/labwc.git/commitdiff
keyboard: add window rule to send release-events (#2377)
authorJohan Malm <johanmalm@users.noreply.github.com>
Tue, 26 Nov 2024 20:02:36 +0000 (20:02 +0000)
committerGitHub <noreply@github.com>
Tue, 26 Nov 2024 20:02:36 +0000 (20:02 +0000)
...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

docs/labwc-config.5.scd
include/window-rules.h
src/config/rcxml.c
src/input/keyboard.c
src/window-rules.c

index 5925a0076e3a44bc0b247ddb0382d6d16d3f541f..878ab60b8f32781744556958255ac78ed5973887 100644 (file)
@@ -1055,6 +1055,18 @@ situation.
        can be caused by *<margin>* settings or exclusive layer-shell clients
        such as panels.
 
+*<windowRules><windowRule wantAbsorbedModifierReleaseEvents="">* [yes|no|default]
+       *wantAbsorbedModifierReleaseEvents* allows clients to receive modifier
+       release events even if they are part of keybinds. Most clients should
+       not receive these, but some (for example blender) need it in some
+       situations.
+
+```
+<windowRules>
+  <windowRule identifier="blender" wantAbsorbedModifierReleaseEvents="yes"/>
+</windowRules>
+```
+
 ## MENU
 
 ```
index b93bc367b3dadd6601b65efa06cbbbe18c0088f0..30abfddb78681855e00bd10d5cbebb5bc21f6002 100644 (file)
@@ -38,6 +38,7 @@ struct window_rule {
        enum property ignore_focus_request;
        enum property ignore_configure_request;
        enum property fixed_position;
+       enum property want_absorbed_modifier_release_events;
 
        struct wl_list link; /* struct rcxml.window_rules */
 };
index 84708664bf7cf05087401b42ec9a08e9abe6a92e..eeb9d681de25ac8c630a0e7e4caebf9ad1e00d1d 100644 (file)
@@ -354,6 +354,8 @@ fill_window_rule(char *nodename, char *content)
                set_property(content, &current_window_rule->ignore_configure_request);
        } else if (!strcasecmp(nodename, "fixedPosition")) {
                set_property(content, &current_window_rule->fixed_position);
+       } else if (!strcasecmp(nodename, "wantAbsorbedModifierReleaseEvents")) {
+               set_property(content, &current_window_rule->want_absorbed_modifier_release_events);
 
        /* Actions */
        } else if (!strcmp(nodename, "name.action")) {
index f0ceb7dae4f8f6d2bc99aa0729392d2503ca576b..cef86bbf97cafd9ea529e69b112a7baf1cd5f9e3 100644 (file)
@@ -15,6 +15,7 @@
 #include "osd.h"
 #include "regions.h"
 #include "view.h"
+#include "window-rules.h"
 #include "workspaces.h"
 
 enum lab_key_handled {
@@ -363,7 +364,8 @@ get_keyinfo(struct wlr_keyboard *wlr_keyboard, uint32_t evdev_keycode)
 }
 
 static bool
-handle_key_release(struct server *server, uint32_t evdev_keycode)
+handle_key_release(struct server *server, uint32_t evdev_keycode,
+               bool is_modifier_key)
 {
        /*
         * Release events for keys that were not bound should always be
@@ -386,11 +388,33 @@ handle_key_release(struct server *server, uint32_t evdev_keycode)
                end_cycling(server);
        }
 
+       key_state_bound_key_remove(evdev_keycode);
+
+       /*
+        * There are some clients (for example blender) that want to see the
+        * modifier-release-event even if it was part of a keybinds. This is
+        * treated as a special case and can only be achieved by configuration.
+        *
+        * 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.
+        */
+       struct view *view = server->active_view;
+       if (is_modifier_key && view) {
+               if (window_rules_get_property(view, "wantAbsorbedModifierReleaseEvents")
+                               == LAB_PROP_TRUE) {
+                       return false;
+               }
+       }
+
        /*
         * If a press event was handled by a compositor binding, then do
         * not forward the corresponding release event to clients.
         */
-       key_state_bound_key_remove(evdev_keycode);
        return true;
 }
 
@@ -525,7 +549,8 @@ handle_compositor_keybindings(struct keyboard *keyboard,
                        actions_run(NULL, server, &cur_keybind->actions, NULL);
                        return true;
                } else {
-                       return handle_key_release(server, event->keycode);
+                       return handle_key_release(server, event->keycode,
+                               keyinfo.is_modifier);
                }
        }
 
index 0f4f1952d233ffc7796e3efa2ca7c7e5924f136e..7c88865fce63abb57e440ff82e007c8da751b4ad 100644 (file)
@@ -108,6 +108,11 @@ window_rules_get_property(struct view *view, const char *property)
                                        && !strcasecmp(property, "fixedPosition")) {
                                return rule->fixed_position;
                        }
+                       if (rule->want_absorbed_modifier_release_events
+                                       && !strcasecmp(property,
+                                       "wantAbsorbedModifierReleaseEvents")) {
+                               return rule->want_absorbed_modifier_release_events;
+                       }
                }
        }
        return LAB_PROP_UNSPECIFIED;