shortcuttrigger: Introduce partial matches

Allow GtkShortcutTrigger to return partial matches.
Currently, no triggers produce such results, and
GtkShortcutController treats partial matches like
exact ones.
This commit is contained in:
Matthias Clasen 2020-03-22 09:16:57 -04:00
parent cb821d5df3
commit 904835d4b1
4 changed files with 52 additions and 32 deletions

View File

@ -247,7 +247,7 @@ gtk_shortcut_controller_trigger_shortcut (GtkShortcutController *self,
{
GtkWidget *widget;
if (!gtk_shortcut_trigger_trigger (gtk_shortcut_get_trigger (shortcut), event, enable_mnemonics))
if (gtk_shortcut_trigger_trigger (gtk_shortcut_get_trigger (shortcut), event, enable_mnemonics) == GTK_SHORTCUT_TRIGGER_MATCH_NONE)
return FALSE;
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (self));

View File

@ -59,7 +59,8 @@ struct _GtkShortcutTriggerClass
const char *type_name;
void (* finalize) (GtkShortcutTrigger *trigger);
gboolean (* trigger) (GtkShortcutTrigger *trigger,
GtkShortcutTriggerMatch
(* trigger) (GtkShortcutTrigger *trigger,
GdkEvent *event,
gboolean enable_mnemonics);
guint (* hash) (GtkShortcutTrigger *trigger);
@ -166,17 +167,16 @@ gtk_shortcut_trigger_get_trigger_type (GtkShortcutTrigger *self)
* value of this property is determined by checking that the passed
* in @event is a Key event and has the right modifiers set.
*
* Checks if the given @event triggers @self. If so,
* returns %TRUE.
* Checks if the given @event triggers @self.
*
* Returns: %TRUE if this event triggered the trigger
* Returns: Whether the event triggered the shortcut
**/
gboolean
GtkShortcutTriggerMatch
gtk_shortcut_trigger_trigger (GtkShortcutTrigger *self,
GdkEvent *event,
gboolean enable_mnemonics)
{
g_return_val_if_fail (GTK_IS_SHORTCUT_TRIGGER (self), FALSE);
g_return_val_if_fail (GTK_IS_SHORTCUT_TRIGGER (self), GTK_SHORTCUT_TRIGGER_MATCH_NONE);
return self->trigger_class->trigger (self, event, enable_mnemonics);
}
@ -411,12 +411,12 @@ gtk_never_trigger_finalize (GtkShortcutTrigger *trigger)
g_assert_not_reached ();
}
static gboolean
static GtkShortcutTriggerMatch
gtk_never_trigger_trigger (GtkShortcutTrigger *trigger,
GdkEvent *event,
gboolean enable_mnemonics)
{
return FALSE;
return GTK_SHORTCUT_TRIGGER_MATCH_NONE;
}
static guint
@ -493,7 +493,7 @@ gtk_keyval_trigger_finalize (GtkShortcutTrigger *trigger)
{
}
static gboolean
static GtkShortcutTriggerMatch
gtk_keyval_trigger_trigger (GtkShortcutTrigger *trigger,
GdkEvent *event,
gboolean enable_mnemonics)
@ -503,7 +503,7 @@ gtk_keyval_trigger_trigger (GtkShortcutTrigger *trigger,
guint keyval;
if (gdk_event_get_event_type (event) != GDK_KEY_PRESS)
return FALSE;
return GTK_SHORTCUT_TRIGGER_MATCH_NONE;
/* XXX: This needs to deal with groups */
modifiers = gdk_event_get_modifier_state (event);
@ -514,7 +514,10 @@ gtk_keyval_trigger_trigger (GtkShortcutTrigger *trigger,
else
keyval = gdk_keyval_to_lower (keyval);
return keyval == self->keyval && modifiers == self->modifiers;
if (keyval != self->keyval || modifiers != self->modifiers)
return GTK_SHORTCUT_TRIGGER_MATCH_NONE;
return GTK_SHORTCUT_TRIGGER_MATCH_EXACT;
}
static guint
@ -659,7 +662,7 @@ gtk_mnemonic_trigger_finalize (GtkShortcutTrigger *trigger)
{
}
static gboolean
static GtkShortcutTriggerMatch
gtk_mnemonic_trigger_trigger (GtkShortcutTrigger *trigger,
GdkEvent *event,
gboolean enable_mnemonics)
@ -668,10 +671,10 @@ gtk_mnemonic_trigger_trigger (GtkShortcutTrigger *trigger,
guint keyval;
if (!enable_mnemonics)
return FALSE;
return GTK_SHORTCUT_TRIGGER_MATCH_NONE;
if (gdk_event_get_event_type (event) != GDK_KEY_PRESS)
return FALSE;
return GTK_SHORTCUT_TRIGGER_MATCH_NONE;
/* XXX: This needs to deal with groups */
keyval = gdk_key_event_get_keyval (event);
@ -681,7 +684,10 @@ gtk_mnemonic_trigger_trigger (GtkShortcutTrigger *trigger,
else
keyval = gdk_keyval_to_lower (keyval);
return keyval == self->keyval;
if (keyval != self->keyval)
return GTK_SHORTCUT_TRIGGER_MATCH_NONE;
return GTK_SHORTCUT_TRIGGER_MATCH_EXACT;
}
static guint
@ -814,20 +820,15 @@ gtk_alternative_trigger_finalize (GtkShortcutTrigger *trigger)
gtk_shortcut_trigger_unref (self->second);
}
static gboolean
static GtkShortcutTriggerMatch
gtk_alternative_trigger_trigger (GtkShortcutTrigger *trigger,
GdkEvent *event,
gboolean enable_mnemonics)
{
GtkAlternativeTrigger *self = (GtkAlternativeTrigger *) trigger;
if (gtk_shortcut_trigger_trigger (self->first, event, enable_mnemonics))
return TRUE;
if (gtk_shortcut_trigger_trigger (self->second, event, enable_mnemonics))
return TRUE;
return FALSE;
return MAX (gtk_shortcut_trigger_trigger (self->first, event, enable_mnemonics),
gtk_shortcut_trigger_trigger (self->second, event, enable_mnemonics));
}
static guint

View File

@ -51,6 +51,25 @@ typedef enum {
GTK_SHORTCUT_TRIGGER_ALTERNATIVE
} GtkShortcutTriggerType;
/**
* GtkShortcutTriggerMatch:
* @GTK_SHORTCUT_TRIGGER_MATCH_NONE: The key event does not
* match the trigger
* @GTK_SHORTCUT_TRIGGER_MATCH_PARTIAL: The key event matches
* the trigger if keyboard state (specifically, the currently
* active group) is ignored
* @GTK_SHORTCUT_TRIGGER_MATCH_EXACT: The key event matches
* the trigger
*
* The possible return values from gtk_shortcut_trigger_trigger()
* describe if a key event triggers a shortcut.
*/
typedef enum {
GTK_SHORTCUT_TRIGGER_MATCH_NONE,
GTK_SHORTCUT_TRIGGER_MATCH_PARTIAL,
GTK_SHORTCUT_TRIGGER_MATCH_EXACT,
} GtkShortcutTriggerMatch;
GDK_AVAILABLE_IN_ALL
GType gtk_shortcut_trigger_get_type (void) G_GNUC_CONST;
@ -88,7 +107,7 @@ gint gtk_shortcut_trigger_compare (gconstpointer
gconstpointer trigger2);
GDK_AVAILABLE_IN_ALL
gboolean gtk_shortcut_trigger_trigger (GtkShortcutTrigger *self,
GtkShortcutTriggerMatch gtk_shortcut_trigger_trigger (GtkShortcutTrigger *self,
GdkEvent *event,
gboolean enable_mnemonics);

View File

@ -195,14 +195,14 @@ test_trigger_trigger (void)
guint keyval;
GdkModifierType state;
gboolean mnemonic;
gboolean result[4];
GtkShortcutTriggerMatch result[4];
} tests[] = {
{ GDK_KEY_a, GDK_CONTROL_MASK, FALSE, { 0, 1, 0, 1 } },
{ GDK_KEY_a, GDK_CONTROL_MASK, TRUE, { 0, 1, 0, 1 } },
{ GDK_KEY_a, GDK_SHIFT_MASK, FALSE, { 0, 0, 0, 0 } },
{ GDK_KEY_a, GDK_SHIFT_MASK, TRUE, { 0, 0, 0, 0 } },
{ GDK_KEY_u, GDK_SHIFT_MASK, FALSE, { 0, 0, 0, 0 } },
{ GDK_KEY_u, GDK_SHIFT_MASK, TRUE, { 0, 0, 1, 1 } },
{ GDK_KEY_a, GDK_CONTROL_MASK, FALSE, { GTK_SHORTCUT_TRIGGER_MATCH_NONE, GTK_SHORTCUT_TRIGGER_MATCH_EXACT, GTK_SHORTCUT_TRIGGER_MATCH_NONE, GTK_SHORTCUT_TRIGGER_MATCH_EXACT } },
{ GDK_KEY_a, GDK_CONTROL_MASK, TRUE, { GTK_SHORTCUT_TRIGGER_MATCH_NONE, GTK_SHORTCUT_TRIGGER_MATCH_EXACT, GTK_SHORTCUT_TRIGGER_MATCH_NONE, GTK_SHORTCUT_TRIGGER_MATCH_EXACT } },
{ GDK_KEY_a, GDK_SHIFT_MASK, FALSE, { GTK_SHORTCUT_TRIGGER_MATCH_NONE, GTK_SHORTCUT_TRIGGER_MATCH_NONE, GTK_SHORTCUT_TRIGGER_MATCH_NONE, GTK_SHORTCUT_TRIGGER_MATCH_NONE } },
{ GDK_KEY_a, GDK_SHIFT_MASK, TRUE, { GTK_SHORTCUT_TRIGGER_MATCH_NONE, GTK_SHORTCUT_TRIGGER_MATCH_NONE, GTK_SHORTCUT_TRIGGER_MATCH_NONE, GTK_SHORTCUT_TRIGGER_MATCH_NONE } },
{ GDK_KEY_u, GDK_SHIFT_MASK, FALSE, { GTK_SHORTCUT_TRIGGER_MATCH_NONE, GTK_SHORTCUT_TRIGGER_MATCH_NONE, GTK_SHORTCUT_TRIGGER_MATCH_NONE, GTK_SHORTCUT_TRIGGER_MATCH_NONE } },
{ GDK_KEY_u, GDK_SHIFT_MASK, TRUE, { GTK_SHORTCUT_TRIGGER_MATCH_NONE, GTK_SHORTCUT_TRIGGER_MATCH_NONE, GTK_SHORTCUT_TRIGGER_MATCH_EXACT, GTK_SHORTCUT_TRIGGER_MATCH_EXACT } },
};
int i;