1
0
Fork 0

keybindings: Send trigger when a key accelerator is deactivated

This is neccessary to support the GlobalShortcuts portal which demands Deactivate events.

https://gitlab.gnome.org/GNOME/xdg-desktop-portal-gnome/-/issues/47

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3680>
This commit is contained in:
dcz 2024-03-31 14:09:56 +00:00 committed by dcz
parent b0df2d0f7d
commit 11a4d56185
5 changed files with 65 additions and 9 deletions

View file

@ -254,6 +254,9 @@ void meta_display_overlay_key_activate (MetaDisplay *display);
void meta_display_accelerator_activate (MetaDisplay *display, void meta_display_accelerator_activate (MetaDisplay *display,
guint action, guint action,
const ClutterKeyEvent *event); const ClutterKeyEvent *event);
void meta_display_accelerator_deactivate (MetaDisplay *display,
guint action,
const ClutterKeyEvent *event);
gboolean meta_display_modifiers_accelerator_activate (MetaDisplay *display); gboolean meta_display_modifiers_accelerator_activate (MetaDisplay *display);
void meta_display_update_focus_window (MetaDisplay *display, void meta_display_update_focus_window (MetaDisplay *display,

View file

@ -156,6 +156,7 @@ enum
X11_DISPLAY_CLOSING, X11_DISPLAY_CLOSING,
OVERLAY_KEY, OVERLAY_KEY,
ACCELERATOR_ACTIVATED, ACCELERATOR_ACTIVATED,
ACCELERATOR_DEACTIVATED,
MODIFIERS_ACCELERATOR_ACTIVATED, MODIFIERS_ACCELERATOR_ACTIVATED,
FOCUS_WINDOW, FOCUS_WINDOW,
WINDOW_CREATED, WINDOW_CREATED,
@ -330,6 +331,14 @@ meta_display_class_init (MetaDisplayClass *klass)
NULL, NULL, NULL, NULL, NULL, NULL,
G_TYPE_NONE, 3, G_TYPE_UINT, CLUTTER_TYPE_INPUT_DEVICE, G_TYPE_UINT); G_TYPE_NONE, 3, G_TYPE_UINT, CLUTTER_TYPE_INPUT_DEVICE, G_TYPE_UINT);
display_signals[ACCELERATOR_DEACTIVATED] =
g_signal_new ("accelerator-deactivated",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 3, G_TYPE_UINT, CLUTTER_TYPE_INPUT_DEVICE, G_TYPE_UINT);
/** /**
* MetaDisplay::modifiers-accelerator-activated: * MetaDisplay::modifiers-accelerator-activated:
* @display: the #MetaDisplay instance * @display: the #MetaDisplay instance
@ -2528,6 +2537,17 @@ meta_display_accelerator_activate (MetaDisplay *display,
clutter_event_get_time ((const ClutterEvent *) event)); clutter_event_get_time ((const ClutterEvent *) event));
} }
void
meta_display_accelerator_deactivate (MetaDisplay *display,
guint action,
const ClutterKeyEvent *event)
{
g_signal_emit (display, display_signals[ACCELERATOR_DEACTIVATED], 0,
action,
clutter_event_get_source_device ((const ClutterEvent *) event),
clutter_event_get_time ((const ClutterEvent *) event));
}
gboolean gboolean
meta_display_modifiers_accelerator_activate (MetaDisplay *display) meta_display_modifiers_accelerator_activate (MetaDisplay *display)
{ {

View file

@ -71,6 +71,8 @@ struct _MetaKeyBinding
MetaKeyCombo combo; MetaKeyCombo combo;
MetaResolvedKeyCombo resolved_combo; MetaResolvedKeyCombo resolved_combo;
gint flags; gint flags;
/* The binding should respond to release, and was just pressed */
gboolean release_pending;
MetaKeyHandler *handler; MetaKeyHandler *handler;
}; };

View file

@ -1698,7 +1698,10 @@ handle_external_grab (MetaDisplay *display,
{ {
MetaKeyBindingManager *keys = &display->key_binding_manager; MetaKeyBindingManager *keys = &display->key_binding_manager;
guint action = get_keybinding_action (keys, &binding->resolved_combo); guint action = get_keybinding_action (keys, &binding->resolved_combo);
meta_display_accelerator_activate (display, action, event); if (clutter_event_type ((ClutterEvent *) event) == CLUTTER_KEY_RELEASE)
meta_display_accelerator_deactivate (display, action, event);
else
meta_display_accelerator_activate (display, action, event);
} }
@ -1855,10 +1858,6 @@ process_event (MetaDisplay *display,
MetaKeyBinding *binding; MetaKeyBinding *binding;
ClutterModifierType modifiers; ClutterModifierType modifiers;
/* we used to have release-based bindings but no longer. */
if (clutter_event_type ((ClutterEvent *) event) == CLUTTER_KEY_RELEASE)
return FALSE;
modifiers = get_modifiers ((ClutterEvent *) event); modifiers = get_modifiers ((ClutterEvent *) event);
resolved_combo.mask = mask_from_event_params (keys, modifiers); resolved_combo.mask = mask_from_event_params (keys, modifiers);
@ -1904,11 +1903,40 @@ process_event (MetaDisplay *display,
return TRUE; return TRUE;
} }
meta_topic (META_DEBUG_KEYBINDINGS, if (clutter_event_type ((ClutterEvent *) event) == CLUTTER_KEY_RELEASE)
"Running handler for %s", {
binding->name); if (binding->release_pending)
{
meta_topic (META_DEBUG_KEYBINDINGS,
"Running release handler for %s",
binding->name);
invoke_handler (display, binding->handler, window, event, binding); invoke_handler (display, binding->handler, window, event, binding);
binding->release_pending = FALSE;
}
else
{
meta_topic (META_DEBUG_KEYBINDINGS,
"Ignore release for handler %s",
binding->name);
}
}
else
{
meta_topic (META_DEBUG_KEYBINDINGS,
"Running handler for %s",
binding->name);
invoke_handler (display, binding->handler, window, event, binding);
if (!binding->release_pending &&
((binding->flags & META_KEY_BINDING_TRIGGER_RELEASE) != 0))
{
meta_topic (META_DEBUG_KEYBINDINGS,
"Preparing release for handler %s",
binding->name);
binding->release_pending = TRUE;
}
}
return TRUE; return TRUE;
@ -3260,6 +3288,7 @@ meta_display_init_keys (MetaDisplay *display)
handler = g_new0 (MetaKeyHandler, 1); handler = g_new0 (MetaKeyHandler, 1);
handler->name = g_strdup ("external-grab"); handler->name = g_strdup ("external-grab");
handler->flags = META_KEY_BINDING_TRIGGER_RELEASE;
handler->func = handle_external_grab; handler->func = handle_external_grab;
handler->default_func = handle_external_grab; handler->default_func = handle_external_grab;
g_ref_count_init (&handler->ref_count); g_ref_count_init (&handler->ref_count);

View file

@ -430,6 +430,7 @@ typedef enum _MetaKeyBindingAction
* @META_KEY_BINDING_IGNORE_AUTOREPEAT: ignore autorepeat * @META_KEY_BINDING_IGNORE_AUTOREPEAT: ignore autorepeat
* @META_KEY_BINDING_NO_AUTO_GRAB: not grabbed automatically * @META_KEY_BINDING_NO_AUTO_GRAB: not grabbed automatically
* @META_KEY_BINDING_CUSTOM_TRIGGER: uses a custom keybinding action * @META_KEY_BINDING_CUSTOM_TRIGGER: uses a custom keybinding action
* @META_KEY_BINDING_TRIGGER_RELEASE: notifies on release in addition to press
*/ */
typedef enum typedef enum
{ {
@ -441,6 +442,7 @@ typedef enum
META_KEY_BINDING_IGNORE_AUTOREPEAT = 1 << 4, META_KEY_BINDING_IGNORE_AUTOREPEAT = 1 << 4,
META_KEY_BINDING_NO_AUTO_GRAB = 1 << 5, META_KEY_BINDING_NO_AUTO_GRAB = 1 << 5,
META_KEY_BINDING_CUSTOM_TRIGGER = 1 << 6, META_KEY_BINDING_CUSTOM_TRIGGER = 1 << 6,
META_KEY_BINDING_TRIGGER_RELEASE = 1 << 7,
} MetaKeyBindingFlags; } MetaKeyBindingFlags;
/** /**