summaryrefslogtreecommitdiff
path: root/gdk
diff options
context:
space:
mode:
authorMichael Natterer <mitch@lanedo.com>2011-09-27 09:50:34 +0200
committerMichael Natterer <mitch@gimp.org>2011-09-27 09:56:25 +0200
commit4a7a67339a3c8a7c523b32b36a7fc2ea5abfb8f8 (patch)
tree954b9cee7be7c1d578d524b3d4bac05f7d921411 /gdk
parent04009aa3329486cc60634865b597195babbec774 (diff)
downloadgtk+-4a7a67339a3c8a7c523b32b36a7fc2ea5abfb8f8.tar.gz
Bug 659602 - Provide an abstraction for the platform's use of modifier keys
Add enum GdkModifierIntent which identifies use cases for modifier masks and GdkKeyMap::get_modifier_mask(). Add a default implementation which returns what is currently hardcoded all over GTK+, and an implementation in the quartz backend. Also add gtk_widget_get_modifier_mask() which simplifies things by doing widget->display->keymap->get_modifier_mask().
Diffstat (limited to 'gdk')
-rw-r--r--gdk/gdkkeys.c62
-rw-r--r--gdk/gdkkeys.h3
-rw-r--r--gdk/gdkkeysprivate.h2
-rw-r--r--gdk/gdktypes.h35
-rw-r--r--gdk/quartz/gdkkeys-quartz.c27
5 files changed, 129 insertions, 0 deletions
diff --git a/gdk/gdkkeys.c b/gdk/gdkkeys.c
index f52de39e04..d2b7b61f6e 100644
--- a/gdk/gdkkeys.c
+++ b/gdk/gdkkeys.c
@@ -108,6 +108,11 @@ enum {
LAST_SIGNAL
};
+
+static GdkModifierType gdk_keymap_real_get_modifier_mask (GdkKeymap *keymap,
+ GdkModifierIntent intent);
+
+
static guint signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (GdkKeymap, gdk_keymap, G_TYPE_OBJECT)
@@ -117,6 +122,8 @@ gdk_keymap_class_init (GdkKeymapClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ klass->get_modifier_mask = gdk_keymap_real_get_modifier_mask;
+
/**
* GdkKeymap::direction-changed:
* @keymap: the object on which the signal is emitted
@@ -605,6 +612,61 @@ gdk_keymap_map_virtual_modifiers (GdkKeymap *keymap,
return GDK_KEYMAP_GET_CLASS(keymap)->map_virtual_modifiers (keymap, state);
}
+static GdkModifierType
+gdk_keymap_real_get_modifier_mask (GdkKeymap *keymap,
+ GdkModifierIntent intent)
+{
+ switch (intent)
+ {
+ case GDK_MODIFIER_INTENT_PRIMARY_ACCELERATOR:
+ return GDK_CONTROL_MASK;
+
+ case GDK_MODIFIER_INTENT_CONTEXT_MENU:
+ return 0;
+
+ case GDK_MODIFIER_INTENT_EXTEND_SELECTION:
+ return GDK_SHIFT_MASK;
+
+ case GDK_MODIFIER_INTENT_MODIFY_SELECTION:
+ return GDK_CONTROL_MASK;
+
+ case GDK_MODIFIER_INTENT_NO_TEXT_INPUT:
+ return GDK_MOD1_MASK | GDK_CONTROL_MASK;
+
+ default:
+ g_return_val_if_reached (0);
+ }
+}
+
+/**
+ * gdk_keymap_get_modifier_mask:
+ * @keymap: a #GdkKeymap
+ * @intent: the use case for the modifier mask
+ *
+ * Returns the modifier mask the @keymap's windowing system backend
+ * uses for a particular purpose.
+ *
+ * Note that this function always returns real hardware modifiers, not
+ * virtual ones (e.g. it will return #GDK_MOD1_MASK rather than
+ * #GDK_META_MASK if the backend maps MOD1 to META), so there are use
+ * cases where the return value of this function has to be transformed
+ * by gdk_keymap_add_virtual_modifiers() in order to contain the
+ * expected result.
+ *
+ * Returns: the modifier mask used for @intent.
+ *
+ * Since: 3.4
+ **/
+GdkModifierType
+gdk_keymap_get_modifier_mask (GdkKeymap *keymap,
+ GdkModifierIntent intent)
+{
+ g_return_val_if_fail (GDK_IS_KEYMAP (keymap), 0);
+
+ return GDK_KEYMAP_GET_CLASS (keymap)->get_modifier_mask (keymap, intent);
+}
+
+
/**
* gdk_keyval_name:
* @keyval: a key value
diff --git a/gdk/gdkkeys.h b/gdk/gdkkeys.h
index 96e360f1ea..b085d246ca 100644
--- a/gdk/gdkkeys.h
+++ b/gdk/gdkkeys.h
@@ -114,6 +114,9 @@ void gdk_keymap_add_virtual_modifiers (GdkKeymap *keymap,
GdkModifierType *state);
gboolean gdk_keymap_map_virtual_modifiers (GdkKeymap *keymap,
GdkModifierType *state);
+GdkModifierType gdk_keymap_get_modifier_mask (GdkKeymap *keymap,
+ GdkModifierIntent intent);
+
/* Key values
*/
diff --git a/gdk/gdkkeysprivate.h b/gdk/gdkkeysprivate.h
index c0f1f0eaa9..be1be41d03 100644
--- a/gdk/gdkkeysprivate.h
+++ b/gdk/gdkkeysprivate.h
@@ -61,6 +61,8 @@ struct _GdkKeymapClass
GdkModifierType *state);
gboolean (* map_virtual_modifiers) (GdkKeymap *keymap,
GdkModifierType *state);
+ GdkModifierType (*get_modifier_mask) (GdkKeymap *keymap,
+ GdkModifierIntent intent);
/* Signals */
diff --git a/gdk/gdktypes.h b/gdk/gdktypes.h
index 87ac3b2491..a0ea89368d 100644
--- a/gdk/gdktypes.h
+++ b/gdk/gdktypes.h
@@ -242,6 +242,41 @@ typedef enum
GDK_MODIFIER_MASK = 0x5c001fff
} GdkModifierType;
+/**
+ * GdkModifierIntent:
+ * @GDK_MODIFIER_INTENT_PRIMARY_ACCELERATOR: the primary modifier used to invoke
+ * menu accelerators.
+ * @GDK_MODIFIER_INTENT_CONTEXT_MENU: the modifier used to invoke context menus.
+ * Note that mouse button 3 always triggers context menus. When this modifier
+ * is not 0, it <strong>additionally</strong> triggers context menus when used
+ * with mouse button 1.
+ * @GDK_MODIFIER_INTENT_EXTEND_SELECTION: the modifier used to extend selections
+ * using &lt;modifier&gt;-click or &lt;modifier&gt;-cursor-key
+ * @GDK_MODIFIER_INTENT_MODIFY_SELECTION: the modifier used to modify selections,
+ * which in most cases means toggling the clicked item into or out of the selection.
+ * @GDK_MODIFIER_INTENT_NO_TEXT_INPUT: when any of these modifiers is pressed, the
+ * key event cannot produce a symbol directly. This is meant to be used for
+ * input methods, and for use cases like typeahead search.
+ *
+ * This enum is used with gdk_keymap_get_modifier_mask() and
+ * gdk_get_modifier_mask() in order to determine what modifiers the
+ * currently used windowing system backend uses for particular
+ * purposes. For example, on X11/Windows, the Control key is used for
+ * invoking menu shortcuts (accelerators), whereas on Apple computers
+ * it's the Command key (which correspond to %GDK_CONTROL_MASK and
+ * %GDK_MOD2_MASK, respectively).
+ *
+ * Since: 3.4
+ **/
+typedef enum
+{
+ GDK_MODIFIER_INTENT_PRIMARY_ACCELERATOR,
+ GDK_MODIFIER_INTENT_CONTEXT_MENU,
+ GDK_MODIFIER_INTENT_EXTEND_SELECTION,
+ GDK_MODIFIER_INTENT_MODIFY_SELECTION,
+ GDK_MODIFIER_INTENT_NO_TEXT_INPUT
+} GdkModifierIntent;
+
typedef enum
{
GDK_OK = 0,
diff --git a/gdk/quartz/gdkkeys-quartz.c b/gdk/quartz/gdkkeys-quartz.c
index 9c925ae14c..2b9307f868 100644
--- a/gdk/quartz/gdkkeys-quartz.c
+++ b/gdk/quartz/gdkkeys-quartz.c
@@ -746,6 +746,32 @@ gdk_quartz_keymap_map_virtual_modifiers (GdkKeymap *keymap,
return TRUE;
}
+static GdkModifierType
+gdk_quartz_keymap_get_modifier_mask (GdkKeymap *keymap,
+ GdkModifierIntent intent)
+{
+ switch (intent)
+ {
+ case GDK_MODIFIER_INTENT_PRIMARY_ACCELERATOR:
+ return GDK_MOD2_MASK;
+
+ case GDK_MODIFIER_INTENT_CONTEXT_MENU:
+ return GDK_CONTROL_MASK;
+
+ case GDK_MODIFIER_INTENT_EXTEND_SELECTION:
+ return GDK_SHIFT_MASK;
+
+ case GDK_MODIFIER_INTENT_MODIFY_SELECTION:
+ return GDK_MOD2_MASK;
+
+ case GDK_MODIFIER_INTENT_NO_TEXT_INPUT:
+ return GDK_MOD2_MASK | GDK_CONTROL_MASK;
+
+ default:
+ g_return_val_if_reached (0);
+ }
+}
+
/* What sort of key event is this? Returns one of
* GDK_KEY_PRESS, GDK_KEY_RELEASE, GDK_NOTHING (should be ignored)
*/
@@ -835,4 +861,5 @@ gdk_quartz_keymap_class_init (GdkQuartzKeymapClass *klass)
keymap_class->translate_keyboard_state = gdk_quartz_keymap_translate_keyboard_state;
keymap_class->add_virtual_modifiers = gdk_quartz_keymap_add_virtual_modifiers;
keymap_class->map_virtual_modifiers = gdk_quartz_keymap_map_virtual_modifiers;
+ keymap_class->get_modifier_mask = gdk_quartz_keymap_get_modifier_mask;
}