[gtk/focusable-property: 1/2] widget: Add a :focusable property
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/focusable-property: 1/2] widget: Add a :focusable property
- Date: Tue, 5 May 2020 19:08:22 +0000 (UTC)
commit 64b15b696ce069dac1b539b03b816ebe96963a31
Author: Matthias Clasen <mclasen redhat com>
Date: Tue May 5 14:57:21 2020 -0400
widget: Add a :focusable property
Add back a property that determines whether an individual
widget will accept focus or not. :can-focus prevents the
focus from ever entering the entire widget hierarchy
below a widget, and :focusable just determines if grabbing
the focus to the widget itself will succeed.
See #2686
docs/reference/gtk/gtk4-sections.txt | 2 +
gtk/gtkwidget.c | 96 ++++++++++++++++++++++++++++++++----
gtk/gtkwidget.h | 5 ++
gtk/gtkwidgetprivate.h | 1 +
4 files changed, 95 insertions(+), 9 deletions(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index 2123854971..85a6e3aa1c 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -4050,6 +4050,8 @@ GtkPickFlags
gtk_widget_pick
gtk_widget_get_can_focus
gtk_widget_set_can_focus
+gtk_widget_get_focusable
+gtk_widget_set_focusable
gtk_widget_get_focus_on_click
gtk_widget_set_focus_on_click
gtk_widget_set_focus_child
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 8ee76a263d..ee310b333e 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -518,6 +518,7 @@ enum {
PROP_HAS_FOCUS,
PROP_CAN_TARGET,
PROP_FOCUS_ON_CLICK,
+ PROP_FOCUSABLE,
PROP_HAS_DEFAULT,
PROP_RECEIVES_DEFAULT,
PROP_CURSOR,
@@ -1007,6 +1008,18 @@ gtk_widget_class_init (GtkWidgetClass *klass)
TRUE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+ /**
+ * GtkWidget:focusable:
+ *
+ * Whether this widget itself will accept the input focus.
+ */
+ widget_props[PROP_FOCUSABLE] =
+ g_param_spec_boolean ("focusable",
+ P_("Focusable"),
+ P_("Whether the widget can accept the input focus"),
+ TRUE,
+ GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+
widget_props[PROP_HAS_FOCUS] =
g_param_spec_boolean ("has-focus",
P_("Has focus"),
@@ -1707,6 +1720,9 @@ gtk_widget_set_property (GObject *object,
case PROP_CAN_FOCUS:
gtk_widget_set_can_focus (widget, g_value_get_boolean (value));
break;
+ case PROP_FOCUSABLE:
+ gtk_widget_set_focusable (widget, g_value_get_boolean (value));
+ break;
case PROP_CAN_TARGET:
gtk_widget_set_can_target (widget, g_value_get_boolean (value));
break;
@@ -1857,6 +1873,9 @@ gtk_widget_get_property (GObject *object,
case PROP_CAN_FOCUS:
g_value_set_boolean (value, gtk_widget_get_can_focus (widget));
break;
+ case PROP_FOCUSABLE:
+ g_value_set_boolean (value, gtk_widget_get_focusable (widget));
+ break;
case PROP_HAS_FOCUS:
g_value_set_boolean (value, gtk_widget_has_focus (widget));
break;
@@ -2318,6 +2337,7 @@ gtk_widget_init (GTypeInstance *instance, gpointer g_class)
priv->highlight_resize = FALSE;
#endif
priv->can_focus = TRUE;
+ priv->focusable = TRUE;
priv->can_target = TRUE;
switch (_gtk_widget_get_direction (widget))
@@ -4773,7 +4793,11 @@ gtk_widget_grab_focus_self (GtkWidget *widget)
{
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
+ if (!priv->focusable)
+ return FALSE;
+
gtk_root_set_focus (priv->root, widget);
+
return TRUE;
}
@@ -4969,6 +4993,7 @@ gtk_widget_focus_all (GtkWidget *widget,
}
gtk_widget_grab_focus (widget);
+
return TRUE;
}
@@ -5035,14 +5060,16 @@ gtk_widget_real_keynav_failed (GtkWidget *widget,
/**
* gtk_widget_set_can_focus:
* @widget: a #GtkWidget
- * @can_focus: whether or not @widget can own the input focus.
+ * @can_focus: whether or not the input focus can enter
+ * the widget tree below @widget
*
- * Specifies whether @widget can own the input focus.
+ * Specifies whether the input focus can enter the widget
+ * tree below @widget.
*
* Note that having @can_focus be %TRUE is only one of the
* necessary conditions for being focusable. A widget must
* also be sensitive and not have an ancestor that is marked
- * as not child-focusable in order to receive input focus.
+ * as not can-focus in order to receive input focus.
*
* See gtk_widget_grab_focus() for actually setting the input
* focus on a widget.
@@ -5068,21 +5095,72 @@ gtk_widget_set_can_focus (GtkWidget *widget,
* gtk_widget_get_can_focus:
* @widget: a #GtkWidget
*
- * Determines whether @widget can own the input focus. See
- * gtk_widget_set_can_focus().
+ * Determines whether the input focus can enter @widget.
+ * See gtk_widget_set_focusable().
*
- * Returns: %TRUE if @widget can own the input focus, %FALSE otherwise
+ * Returns: %TRUE if the input focus can enter @widget, %FALSE otherwise
**/
gboolean
gtk_widget_get_can_focus (GtkWidget *widget)
{
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
- g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
return priv->can_focus;
}
+/**
+ * gtk_widget_set_focusable:
+ * @widget: a #GtkWidget
+ * @focusable: whether or not @widget can own the input focus.
+ *
+ * Specifies whether @widget can own the input focus.
+ *
+ * Note that having @focusable be %TRUE is only one of the
+ * necessary conditions for being focusable. A widget must
+ * also be sensitive and not have an ancestor that is marked
+ * as not child-focusable in order to receive input focus.
+ *
+ * See gtk_widget_grab_focus() for actually setting the input
+ * focus on a widget.
+ **/
+void
+gtk_widget_set_focusable (GtkWidget *widget,
+ gboolean focusable)
+{
+ GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ if (priv->focusable == focusable)
+ return;
+
+ priv->focusable = focusable;
+
+ gtk_widget_queue_resize (widget);
+ g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_FOCUSABLE]);
+}
+
+/**
+ * gtk_widget_get_focusable:
+ * @widget: a #GtkWidget
+ *
+ * Determines whether @widget can own the input focus.
+ * See gtk_widget_set_focusable().
+ *
+ * Returns: %TRUE if @widget can own the input focus, %FALSE otherwise
+ **/
+gboolean
+gtk_widget_get_focusable (GtkWidget *widget)
+{
+ GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
+
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
+
+ return priv->focusable;
+}
+
/**
* gtk_widget_has_focus:
* @widget: a #GtkWidget
@@ -6663,7 +6741,7 @@ gtk_widget_get_display (GtkWidget *widget)
* writing an app, you’d use gtk_widget_grab_focus() to move the focus
* to a particular widget.
*
- * gtk_widget_child_focus() is called by containers as the user moves
+ * gtk_widget_child_focus() is called by widgets as the user moves
* around the window using keyboard shortcuts. @direction indicates
* what kind of motion is taking place (up, down, left, right, tab
* forward, tab backward). gtk_widget_child_focus() emits the
@@ -6690,7 +6768,7 @@ gtk_widget_child_focus (GtkWidget *widget,
!gtk_widget_get_can_focus (widget))
return FALSE;
- /* Emit ::focus in any case, even if can-focus is FALSE,
+ /* Emit ::focus in any case, even if focusable is FALSE,
* since any widget might have child widgets that will take
* focus
*/
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index 631547484f..85bee1bd19 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -409,6 +409,11 @@ void gtk_widget_set_can_focus (GtkWidget *widget,
GDK_AVAILABLE_IN_ALL
gboolean gtk_widget_get_can_focus (GtkWidget *widget);
GDK_AVAILABLE_IN_ALL
+void gtk_widget_set_focusable (GtkWidget *widget,
+ gboolean focusable);
+GDK_AVAILABLE_IN_ALL
+gboolean gtk_widget_get_focusable (GtkWidget *widget);
+GDK_AVAILABLE_IN_ALL
gboolean gtk_widget_has_focus (GtkWidget *widget);
GDK_AVAILABLE_IN_ALL
gboolean gtk_widget_is_focus (GtkWidget *widget);
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index 5085353525..1ea7a0465c 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -77,6 +77,7 @@ struct _GtkWidgetPrivate
guint visible : 1;
guint sensitive : 1;
guint can_focus : 1;
+ guint focusable : 1;
guint has_focus : 1;
guint focus_on_click : 1;
guint has_default : 1;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]