[gtk/wip/matthiasc/focus3: 32/40] key controller: Add focus properties
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/matthiasc/focus3: 32/40] key controller: Add focus properties
- Date: Sun, 17 Mar 2019 01:52:44 +0000 (UTC)
commit 4f5a8207bca2c1b968c27ffd25cb76c770b7cf75
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Mar 8 09:55:27 2019 -0500
key controller: Add focus properties
Add boolean properties, is-focus and contains-focus, that
track whether the focus is in the widget itself or in
one of its descendants.
gtk/gtkeventcontrollerkey.c | 131 ++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 126 insertions(+), 5 deletions(-)
---
diff --git a/gtk/gtkeventcontrollerkey.c b/gtk/gtkeventcontrollerkey.c
index 9f32cc9023..390ec4e2f4 100644
--- a/gtk/gtkeventcontrollerkey.c
+++ b/gtk/gtkeventcontrollerkey.c
@@ -46,6 +46,9 @@ struct _GtkEventControllerKey
GHashTable *pressed_keys;
const GdkEvent *current_event;
+
+ guint is_focus : 1;
+ guint contains_focus : 1;
};
struct _GtkEventControllerKeyClass
@@ -65,6 +68,14 @@ enum {
static guint signals[N_SIGNALS] = { 0 };
+enum {
+ PROP_IS_FOCUS = 1,
+ PROP_CONTAINS_FOCUS,
+ NUM_PROPERTIES
+};
+
+static GParamSpec *props[NUM_PROPERTIES] = { NULL, };
+
G_DEFINE_TYPE (GtkEventControllerKey, gtk_event_controller_key,
GTK_TYPE_EVENT_CONTROLLER)
@@ -79,6 +90,50 @@ gtk_event_controller_key_finalize (GObject *object)
G_OBJECT_CLASS (gtk_event_controller_key_parent_class)->finalize (object);
}
+static void
+update_focus (GtkEventControllerKey *key,
+ gboolean focus_in,
+ GdkNotifyType detail)
+{
+ gboolean is_focus;
+ gboolean contains_focus;
+
+ switch (detail)
+ {
+ case GDK_NOTIFY_VIRTUAL:
+ case GDK_NOTIFY_NONLINEAR_VIRTUAL:
+ is_focus = FALSE;
+ contains_focus = focus_in;
+ break;
+ case GDK_NOTIFY_ANCESTOR:
+ case GDK_NOTIFY_NONLINEAR:
+ is_focus = focus_in;
+ contains_focus = FALSE;
+ break;
+ case GDK_NOTIFY_INFERIOR:
+ is_focus = focus_in;
+ contains_focus = !focus_in;
+ break;
+ case GDK_NOTIFY_UNKNOWN:
+ default:
+ g_warning ("Unknown focus change detail");
+ return;
+ }
+
+ g_object_freeze_notify (G_OBJECT (key));
+ if (key->is_focus != is_focus)
+ {
+ key->is_focus = is_focus;
+ g_object_notify (G_OBJECT (key), "is-focus");
+ }
+ if (key->contains_focus != contains_focus)
+ {
+ key->contains_focus = contains_focus;
+ g_object_notify (G_OBJECT (key), "contains-focus");
+ }
+ g_object_thaw_notify (G_OBJECT (key));
+}
+
static gboolean
gtk_event_controller_key_handle_event (GtkEventController *controller,
const GdkEvent *event)
@@ -96,10 +151,13 @@ gtk_event_controller_key_handle_event (GtkEventController *controller,
GdkCrossingMode mode;
GdkNotifyType detail;
+ gdk_event_get_focus_in (event, &focus_in);
gdk_event_get_crossing_mode (event, &mode);
gdk_event_get_crossing_detail (event, &detail);
- if (gdk_event_get_focus_in (event, &focus_in) && focus_in)
+ update_focus (key, focus_in, detail);
+
+ if (focus_in)
g_signal_emit (controller, signals[FOCUS_IN], 0, mode, detail);
else
g_signal_emit (controller, signals[FOCUS_OUT], 0, mode, detail);
@@ -163,6 +221,29 @@ gtk_event_controller_key_handle_event (GtkEventController *controller,
return handled;
}
+static void
+gtk_event_controller_key_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkEventControllerKey *controller = GTK_EVENT_CONTROLLER_KEY (object);
+
+ switch (prop_id)
+ {
+ case PROP_IS_FOCUS:
+ g_value_set_boolean (value, controller->is_focus);
+ break;
+
+ case PROP_CONTAINS_FOCUS:
+ g_value_set_boolean (value, controller->contains_focus);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
static void
gtk_event_controller_key_class_init (GtkEventControllerKeyClass *klass)
{
@@ -170,8 +251,46 @@ gtk_event_controller_key_class_init (GtkEventControllerKeyClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gtk_event_controller_key_finalize;
+ object_class->get_property = gtk_event_controller_key_get_property;
controller_class->handle_event = gtk_event_controller_key_handle_event;
+ /**
+ * GtkEventControllerKey:is-focus:
+ *
+ * Whether focus is in the controllers widget itself,
+ * as opposed to in a descendent widget. See
+ * #GtkEventControllerKey:contains-focus.
+ *
+ * When handling focus events, this property is updated
+ * before #GtkEventControllerKey::focus-in or
+ * #GtkEventControllerKey::focus-out are emitted.
+ */
+ props[PROP_IS_FOCUS] =
+ g_param_spec_boolean ("is-focus",
+ P_("Is Focus"),
+ P_("Whether the focus is in the controllers widget"),
+ FALSE,
+ G_PARAM_READABLE);
+
+ /**
+ * GtkEventControllerKey:contains-focus:
+ *
+ * Whether focus is in a descendant of the controllers widget.
+ * See #GtkEventControllerKey:is-focus.
+ *
+ * When handling focus events, this property is updated
+ * before #GtkEventControllerKey::focus-in or
+ * #GtkEventControllerKey::focus-out are emitted.
+ */
+ props[PROP_CONTAINS_FOCUS] =
+ g_param_spec_boolean ("contains-focus",
+ P_("Contains Focus"),
+ P_("Whether the focus is in a descendant of the controllers widget"),
+ FALSE,
+ G_PARAM_READABLE);
+
+ g_object_class_install_properties (object_class, NUM_PROPERTIES, props);
+
/**
* GtkEventControllerKey::key-pressed:
* @controller: the object which received the signal.
@@ -247,8 +366,9 @@ gtk_event_controller_key_class_init (GtkEventControllerKeyClass *klass)
* @mode: crossing mode indicating what caused this change
* @detail: detail indication where the focus is coming from
*
- * This signal is emitted whenever the #GtkEventController:widget controlled
- * by the @controller is given the keyboard focus.
+ * This signal is emitted whenever the widget controlled
+ * by the @controller or one of its descendants) is given
+ * the keyboard focus.
*/
signals[FOCUS_IN] =
g_signal_new (I_("focus-in"),
@@ -267,8 +387,9 @@ gtk_event_controller_key_class_init (GtkEventControllerKeyClass *klass)
* @mode: crossing mode indicating what caused this change
* @detail: detail indication where the focus is going
*
- * This signal is emitted whenever the #GtkEventController:widget controlled
- * by the @controller loses the keyboard focus.
+ * This signal is emitted whenever the widget controlled
+ * by the @controller (or one of its descendants) loses
+ * the keyboard focus.
*/
signals[FOCUS_OUT] =
g_signal_new (I_("focus-out"),
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]