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:
parent
b0df2d0f7d
commit
11a4d56185
5 changed files with 65 additions and 9 deletions
|
@ -254,6 +254,9 @@ void meta_display_overlay_key_activate (MetaDisplay *display);
|
|||
void meta_display_accelerator_activate (MetaDisplay *display,
|
||||
guint action,
|
||||
const ClutterKeyEvent *event);
|
||||
void meta_display_accelerator_deactivate (MetaDisplay *display,
|
||||
guint action,
|
||||
const ClutterKeyEvent *event);
|
||||
gboolean meta_display_modifiers_accelerator_activate (MetaDisplay *display);
|
||||
|
||||
void meta_display_update_focus_window (MetaDisplay *display,
|
||||
|
|
|
@ -156,6 +156,7 @@ enum
|
|||
X11_DISPLAY_CLOSING,
|
||||
OVERLAY_KEY,
|
||||
ACCELERATOR_ACTIVATED,
|
||||
ACCELERATOR_DEACTIVATED,
|
||||
MODIFIERS_ACCELERATOR_ACTIVATED,
|
||||
FOCUS_WINDOW,
|
||||
WINDOW_CREATED,
|
||||
|
@ -330,6 +331,14 @@ meta_display_class_init (MetaDisplayClass *klass)
|
|||
NULL, NULL, NULL,
|
||||
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:
|
||||
* @display: the #MetaDisplay instance
|
||||
|
@ -2528,6 +2537,17 @@ meta_display_accelerator_activate (MetaDisplay *display,
|
|||
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
|
||||
meta_display_modifiers_accelerator_activate (MetaDisplay *display)
|
||||
{
|
||||
|
|
|
@ -71,6 +71,8 @@ struct _MetaKeyBinding
|
|||
MetaKeyCombo combo;
|
||||
MetaResolvedKeyCombo resolved_combo;
|
||||
gint flags;
|
||||
/* The binding should respond to release, and was just pressed */
|
||||
gboolean release_pending;
|
||||
MetaKeyHandler *handler;
|
||||
};
|
||||
|
||||
|
|
|
@ -1698,7 +1698,10 @@ handle_external_grab (MetaDisplay *display,
|
|||
{
|
||||
MetaKeyBindingManager *keys = &display->key_binding_manager;
|
||||
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;
|
||||
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);
|
||||
resolved_combo.mask = mask_from_event_params (keys, modifiers);
|
||||
|
||||
|
@ -1904,11 +1903,40 @@ process_event (MetaDisplay *display,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"Running handler for %s",
|
||||
binding->name);
|
||||
if (clutter_event_type ((ClutterEvent *) event) == CLUTTER_KEY_RELEASE)
|
||||
{
|
||||
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;
|
||||
|
||||
|
@ -3260,6 +3288,7 @@ meta_display_init_keys (MetaDisplay *display)
|
|||
|
||||
handler = g_new0 (MetaKeyHandler, 1);
|
||||
handler->name = g_strdup ("external-grab");
|
||||
handler->flags = META_KEY_BINDING_TRIGGER_RELEASE;
|
||||
handler->func = handle_external_grab;
|
||||
handler->default_func = handle_external_grab;
|
||||
g_ref_count_init (&handler->ref_count);
|
||||
|
|
|
@ -430,6 +430,7 @@ typedef enum _MetaKeyBindingAction
|
|||
* @META_KEY_BINDING_IGNORE_AUTOREPEAT: ignore autorepeat
|
||||
* @META_KEY_BINDING_NO_AUTO_GRAB: not grabbed automatically
|
||||
* @META_KEY_BINDING_CUSTOM_TRIGGER: uses a custom keybinding action
|
||||
* @META_KEY_BINDING_TRIGGER_RELEASE: notifies on release in addition to press
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
|
@ -441,6 +442,7 @@ typedef enum
|
|||
META_KEY_BINDING_IGNORE_AUTOREPEAT = 1 << 4,
|
||||
META_KEY_BINDING_NO_AUTO_GRAB = 1 << 5,
|
||||
META_KEY_BINDING_CUSTOM_TRIGGER = 1 << 6,
|
||||
META_KEY_BINDING_TRIGGER_RELEASE = 1 << 7,
|
||||
} MetaKeyBindingFlags;
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue