[gtk/wip/matthiasc/can-focus: 83/83] wip: Make can-focus recursive
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/matthiasc/can-focus: 83/83] wip: Make can-focus recursive
- Date: Fri, 3 Apr 2020 19:26:48 +0000 (UTC)
commit 597176cbe9f9a6ec116fa6c04f693b82f6a81ede
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Apr 3 09:36:40 2020 -0400
wip: Make can-focus recursive
Make can-focus default to TRUE and prevent all focus
in a widget subtree when set to FALSE. Adapt all
widgets to have grab_focus and focus vfuncs that
do the right thing, instead of relying on can-focus.
demos/gtk-demo/fontplane.c | 2 --
gtk/gtkbuiltinicon.c | 2 ++
gtk/gtkbutton.c | 4 ++-
gtk/gtkcolorbutton.c | 4 +++
gtk/gtkcolorchooserwidget.c | 4 +++
gtk/gtkcolorplane.c | 2 --
gtk/gtkcolorswatch.c | 2 ++
gtk/gtkcombobox.c | 1 +
gtk/gtkcontainer.c | 2 ++
gtk/gtkentry.c | 1 +
gtk/gtkexpander.c | 2 --
gtk/gtkfilechooserbutton.c | 3 ++
gtk/gtkfontbutton.c | 4 +++
gtk/gtkiconview.c | 1 -
gtk/gtkimage.c | 2 ++
gtk/gtklevelbar.c | 2 ++
gtk/gtkprogressbar.c | 2 ++
gtk/gtkscale.c | 3 ++
gtk/gtkspinbutton.c | 1 +
gtk/gtkswitch.c | 3 ++
gtk/gtkwidget.c | 83 ++++++++++++++++++++++++++++++++-------------
gtk/gtkwidgetprivate.h | 12 +++++++
gtk/inspector/css-editor.ui | 1 -
23 files changed, 111 insertions(+), 32 deletions(-)
---
diff --git a/demos/gtk-demo/fontplane.c b/demos/gtk-demo/fontplane.c
index 1f7e074adb..0a7aae6339 100644
--- a/demos/gtk-demo/fontplane.c
+++ b/demos/gtk-demo/fontplane.c
@@ -189,8 +189,6 @@ gtk_font_plane_init (GtkFontPlane *plane)
{
GtkGesture *gesture;
- gtk_widget_set_can_focus (GTK_WIDGET (plane), TRUE);
-
gesture = gtk_gesture_drag_new ();
g_signal_connect (gesture, "drag-begin",
G_CALLBACK (plane_drag_gesture_begin), plane);
diff --git a/gtk/gtkbuiltinicon.c b/gtk/gtkbuiltinicon.c
index b91864db44..53b0318239 100644
--- a/gtk/gtkbuiltinicon.c
+++ b/gtk/gtkbuiltinicon.c
@@ -95,6 +95,8 @@ gtk_builtin_icon_class_init (GtkBuiltinIconClass *klass)
wclass->snapshot = gtk_builtin_icon_snapshot;
wclass->measure = gtk_builtin_icon_measure;
wclass->css_changed = gtk_builtin_icon_css_changed;
+ wclass->grab_focus = gtk_widget_grab_focus_none;
+ wclass->focus = gtk_widget_focus_none;
}
static void
diff --git a/gtk/gtkbutton.c b/gtk/gtkbutton.c
index d633c77fe6..7276d2c24d 100644
--- a/gtk/gtkbutton.c
+++ b/gtk/gtkbutton.c
@@ -68,6 +68,7 @@
#include "gtkprivate.h"
#include "gtkstylecontext.h"
#include "gtktypebuiltins.h"
+#include "gtkwidgetprivate.h"
#include "a11y/gtkbuttonaccessible.h"
@@ -204,6 +205,8 @@ gtk_button_class_init (GtkButtonClass *klass)
widget_class->state_flags_changed = gtk_button_state_flags_changed;
widget_class->grab_notify = gtk_button_grab_notify;
widget_class->unmap = gtk_button_unmap;
+ widget_class->grab_focus = gtk_widget_grab_focus_self;
+ widget_class->focus = gtk_widget_focus_self;
container_class->add = gtk_button_add;
container_class->remove = gtk_button_remove;
@@ -408,7 +411,6 @@ gtk_button_init (GtkButton *button)
GtkButtonPrivate *priv = gtk_button_get_instance_private (button);
GtkEventController *key_controller;
- gtk_widget_set_can_focus (GTK_WIDGET (button), TRUE);
gtk_widget_set_receives_default (GTK_WIDGET (button), TRUE);
priv->in_button = FALSE;
diff --git a/gtk/gtkcolorbutton.c b/gtk/gtkcolorbutton.c
index 1638cdc6ee..9b6a7015b7 100644
--- a/gtk/gtkcolorbutton.c
+++ b/gtk/gtkcolorbutton.c
@@ -44,6 +44,7 @@
#include "gtkprivate.h"
#include "gtksnapshot.h"
#include "gtkstylecontext.h"
+#include "gtkwidgetprivate.h"
/**
@@ -143,6 +144,9 @@ gtk_color_button_class_init (GtkColorButtonClass *klass)
gobject_class->set_property = gtk_color_button_set_property;
gobject_class->finalize = gtk_color_button_finalize;
+ widget_class->grab_focus = gtk_widget_grab_focus_child;
+ widget_class->focus = gtk_widget_focus_child;
+
klass->color_set = NULL;
/**
diff --git a/gtk/gtkcolorchooserwidget.c b/gtk/gtkcolorchooserwidget.c
index 0455d07457..ca25709695 100644
--- a/gtk/gtkcolorchooserwidget.c
+++ b/gtk/gtkcolorchooserwidget.c
@@ -30,6 +30,7 @@
#include "gtksizegroup.h"
#include "gtkstylecontext.h"
#include "gtkboxlayout.h"
+#include "gtkwidgetprivate.h"
#include "a11y/gtkcompositeaccessible.h"
@@ -709,6 +710,9 @@ gtk_color_chooser_widget_class_init (GtkColorChooserWidgetClass *class)
object_class->set_property = gtk_color_chooser_widget_set_property;
object_class->finalize = gtk_color_chooser_widget_finalize;
+ widget_class->grab_focus = gtk_widget_grab_focus_none;
+ widget_class->focus = gtk_widget_focus_child;
+
g_object_class_override_property (object_class, PROP_RGBA, "rgba");
g_object_class_override_property (object_class, PROP_USE_ALPHA, "use-alpha");
diff --git a/gtk/gtkcolorplane.c b/gtk/gtkcolorplane.c
index a11b0752e2..2582cca2ea 100644
--- a/gtk/gtkcolorplane.c
+++ b/gtk/gtkcolorplane.c
@@ -407,8 +407,6 @@ gtk_color_plane_init (GtkColorPlane *plane)
plane->priv = gtk_color_plane_get_instance_private (plane);
- gtk_widget_set_can_focus (GTK_WIDGET (plane), TRUE);
-
atk_obj = gtk_widget_get_accessible (GTK_WIDGET (plane));
if (GTK_IS_ACCESSIBLE (atk_obj))
{
diff --git a/gtk/gtkcolorswatch.c b/gtk/gtkcolorswatch.c
index f68003cc69..72d66192cc 100644
--- a/gtk/gtkcolorswatch.c
+++ b/gtk/gtkcolorswatch.c
@@ -481,6 +481,8 @@ gtk_color_swatch_class_init (GtkColorSwatchClass *class)
widget_class->snapshot = swatch_snapshot;
widget_class->size_allocate = swatch_size_allocate;
widget_class->state_flags_changed = swatch_state_flags_changed;
+ widget_class->grab_focus = gtk_widget_grab_focus_self;
+ widget_class->focus = gtk_widget_focus_self;
g_object_class_install_property (object_class, PROP_RGBA,
g_param_spec_boxed ("rgba", P_("RGBA Color"), P_("Color as RGBA"),
diff --git a/gtk/gtkcombobox.c b/gtk/gtkcombobox.c
index c1e97debb0..0db20726df 100644
--- a/gtk/gtkcombobox.c
+++ b/gtk/gtkcombobox.c
@@ -420,6 +420,7 @@ gtk_combo_box_class_init (GtkComboBoxClass *klass)
widget_class->size_allocate = gtk_combo_box_size_allocate;
widget_class->mnemonic_activate = gtk_combo_box_mnemonic_activate;
widget_class->grab_focus = gtk_combo_box_grab_focus;
+ widget_class->focus = gtk_widget_focus_child;
widget_class->measure = gtk_combo_box_measure;
widget_class->unmap = gtk_combo_box_unmap;
widget_class->destroy = gtk_combo_box_destroy;
diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c
index 7d74e4f069..1b8953cbbc 100644
--- a/gtk/gtkcontainer.c
+++ b/gtk/gtkcontainer.c
@@ -140,6 +140,8 @@ gtk_container_class_init (GtkContainerClass *class)
widget_class->destroy = gtk_container_destroy;
widget_class->compute_expand = gtk_container_compute_expand;
widget_class->get_request_mode = gtk_container_get_request_mode;
+ widget_class->grab_focus = gtk_widget_grab_focus_child;
+ widget_class->focus = gtk_widget_focus_child;
class->add = gtk_container_add_unimplemented;
class->remove = gtk_container_remove_unimplemented;
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index 13fd885acf..b7c987dc33 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -340,6 +340,7 @@ gtk_entry_class_init (GtkEntryClass *class)
widget_class->query_tooltip = gtk_entry_query_tooltip;
widget_class->direction_changed = gtk_entry_direction_changed;
widget_class->grab_focus = gtk_entry_grab_focus;
+ widget_class->focus = gtk_widget_focus_child;
widget_class->mnemonic_activate = gtk_entry_mnemonic_activate;
quark_entry_completion = g_quark_from_static_string ("gtk-entry-completion-key");
diff --git a/gtk/gtkexpander.c b/gtk/gtkexpander.c
index dbe31e68e0..91f73aa654 100644
--- a/gtk/gtkexpander.c
+++ b/gtk/gtkexpander.c
@@ -385,8 +385,6 @@ gtk_expander_init (GtkExpander *expander)
GtkGesture *gesture;
GtkEventController *controller;
- gtk_widget_set_can_focus (GTK_WIDGET (expander), TRUE);
-
priv->label_widget = NULL;
priv->child = NULL;
diff --git a/gtk/gtkfilechooserbutton.c b/gtk/gtkfilechooserbutton.c
index ce15326723..e0064fc9f3 100644
--- a/gtk/gtkfilechooserbutton.c
+++ b/gtk/gtkfilechooserbutton.c
@@ -61,6 +61,7 @@
#include "gtkstylecontextprivate.h"
#include "gtkbitmaskprivate.h"
#include "gtkeventcontroller.h"
+#include "gtkwidgetprivate.h"
/**
* SECTION:gtkfilechooserbutton
@@ -476,6 +477,8 @@ gtk_file_chooser_button_class_init (GtkFileChooserButtonClass * class)
widget_class->root = gtk_file_chooser_button_root;
widget_class->mnemonic_activate = gtk_file_chooser_button_mnemonic_activate;
widget_class->state_flags_changed = gtk_file_chooser_button_state_flags_changed;
+ widget_class->grab_focus = gtk_widget_grab_focus_child;
+ widget_class->focus = gtk_widget_focus_child;
/**
* GtkFileChooserButton::file-set:
diff --git a/gtk/gtkfontbutton.c b/gtk/gtkfontbutton.c
index 1e5cf9889e..1cad2f6c59 100644
--- a/gtk/gtkfontbutton.c
+++ b/gtk/gtkfontbutton.c
@@ -41,6 +41,7 @@
#include "gtkprivate.h"
#include "gtkseparator.h"
#include "gtkstylecontext.h"
+#include "gtkwidgetprivate.h"
#include <string.h>
#include <stdio.h>
@@ -483,6 +484,9 @@ gtk_font_button_class_init (GtkFontButtonClass *klass)
gobject_class->set_property = gtk_font_button_set_property;
gobject_class->get_property = gtk_font_button_get_property;
+ widget_class->grab_focus = gtk_widget_grab_focus_child;
+ widget_class->focus = gtk_widget_focus_child;
+
klass->font_set = NULL;
_gtk_font_chooser_install_properties (gobject_class);
diff --git a/gtk/gtkiconview.c b/gtk/gtkiconview.c
index f3bb6ead98..0aa89870c2 100644
--- a/gtk/gtkiconview.c
+++ b/gtk/gtkiconview.c
@@ -943,7 +943,6 @@ gtk_icon_view_init (GtkIconView *icon_view)
icon_view->priv->mouse_x = -1;
icon_view->priv->mouse_y = -1;
- gtk_widget_set_can_focus (GTK_WIDGET (icon_view), TRUE);
gtk_widget_set_overflow (GTK_WIDGET (icon_view), GTK_OVERFLOW_HIDDEN);
icon_view->priv->item_orientation = GTK_ORIENTATION_VERTICAL;
diff --git a/gtk/gtkimage.c b/gtk/gtkimage.c
index da98ccc698..c4ee1642cb 100644
--- a/gtk/gtkimage.c
+++ b/gtk/gtkimage.c
@@ -157,6 +157,8 @@ gtk_image_class_init (GtkImageClass *class)
widget_class->measure = gtk_image_measure;
widget_class->unrealize = gtk_image_unrealize;
widget_class->css_changed = gtk_image_css_changed;
+ widget_class->grab_focus = gtk_widget_grab_focus_none;
+ widget_class->focus = gtk_widget_focus_none;
image_props[PROP_PAINTABLE] =
g_param_spec_object ("paintable",
diff --git a/gtk/gtklevelbar.c b/gtk/gtklevelbar.c
index c34fcc5364..fd2e68ab4d 100644
--- a/gtk/gtklevelbar.c
+++ b/gtk/gtklevelbar.c
@@ -901,6 +901,8 @@ gtk_level_bar_class_init (GtkLevelBarClass *klass)
oclass->finalize = gtk_level_bar_finalize;
wclass->direction_changed = gtk_level_bar_direction_changed;
+ wclass->grab_focus = gtk_widget_grab_focus_none;
+ wclass->focus = gtk_widget_focus_none;
g_object_class_override_property (oclass, PROP_ORIENTATION, "orientation");
diff --git a/gtk/gtkprogressbar.c b/gtk/gtkprogressbar.c
index 42d53dd74b..4a446192bc 100644
--- a/gtk/gtkprogressbar.c
+++ b/gtk/gtkprogressbar.c
@@ -181,6 +181,8 @@ gtk_progress_bar_class_init (GtkProgressBarClass *class)
gobject_class->finalize = gtk_progress_bar_finalize;
widget_class->direction_changed = gtk_progress_bar_direction_changed;
+ widget_class->grab_focus = gtk_widget_grab_focus_none;
+ widget_class->focus = gtk_widget_focus_none;
g_object_class_override_property (gobject_class, PROP_ORIENTATION, "orientation");
diff --git a/gtk/gtkscale.c b/gtk/gtkscale.c
index 9583c3ea9c..3195d94511 100644
--- a/gtk/gtkscale.c
+++ b/gtk/gtkscale.c
@@ -41,6 +41,7 @@
#include "gtkstylecontextprivate.h"
#include "gtkstylepropertyprivate.h"
#include "gtktypebuiltins.h"
+#include "gtkwidgetprivate.h"
#include "a11y/gtkscaleaccessible.h"
@@ -663,6 +664,8 @@ gtk_scale_class_init (GtkScaleClass *class)
widget_class->snapshot = gtk_scale_snapshot;
widget_class->size_allocate = gtk_scale_size_allocate;
widget_class->measure = gtk_scale_measure;
+ widget_class->grab_focus = gtk_widget_grab_focus_self;
+ widget_class->focus = gtk_widget_focus_self;
range_class->get_range_border = gtk_scale_get_range_border;
range_class->value_changed = gtk_scale_value_changed;
diff --git a/gtk/gtkspinbutton.c b/gtk/gtkspinbutton.c
index 6d610e7ef3..c59ef30ab8 100644
--- a/gtk/gtkspinbutton.c
+++ b/gtk/gtkspinbutton.c
@@ -349,6 +349,7 @@ gtk_spin_button_class_init (GtkSpinButtonClass *class)
widget_class->grab_notify = gtk_spin_button_grab_notify;
widget_class->state_flags_changed = gtk_spin_button_state_flags_changed;
widget_class->grab_focus = gtk_spin_button_grab_focus;
+ widget_class->focus = gtk_widget_focus_child;
widget_class->mnemonic_activate = gtk_spin_button_mnemonic_activate;
class->input = NULL;
diff --git a/gtk/gtkswitch.c b/gtk/gtkswitch.c
index 148a94a418..781054b265 100644
--- a/gtk/gtkswitch.c
+++ b/gtk/gtkswitch.c
@@ -548,6 +548,9 @@ gtk_switch_class_init (GtkSwitchClass *klass)
g_object_class_install_properties (gobject_class, LAST_PROP, switch_props);
+ widget_class->grab_focus = gtk_widget_grab_focus_self;
+ widget_class->focus = gtk_widget_focus_self;
+
klass->activate = gtk_switch_activate;
klass->state_set = state_set;
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 26853d9cbb..0d2f372110 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -981,7 +981,7 @@ gtk_widget_class_init (GtkWidgetClass *klass)
g_param_spec_boolean ("can-focus",
P_("Can focus"),
P_("Whether the widget can accept the input focus"),
- FALSE,
+ TRUE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
widget_props[PROP_HAS_FOCUS] =
@@ -2297,6 +2297,7 @@ gtk_widget_init (GTypeInstance *instance, gpointer g_class)
#ifdef G_ENABLE_DEBUG
priv->highlight_resize = FALSE;
#endif
+ priv->can_focus = TRUE;
priv->can_target = TRUE;
switch (_gtk_widget_get_direction (widget))
@@ -4740,25 +4741,34 @@ gtk_widget_grab_focus (GtkWidget *widget)
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
if (!gtk_widget_is_sensitive (widget) ||
+ !gtk_widget_get_can_focus (widget) ||
widget->priv->root == NULL)
return FALSE;
return GTK_WIDGET_GET_CLASS (widget)->grab_focus (widget);
}
-static gboolean
-gtk_widget_real_grab_focus (GtkWidget *focus_widget)
+gboolean
+gtk_widget_grab_focus_none (GtkWidget *widget)
{
- GtkWidgetPrivate *priv = gtk_widget_get_instance_private (focus_widget);
- GtkWidget *child;
+ return FALSE;
+}
- if (priv->can_focus)
- {
- gtk_root_set_focus (priv->root, focus_widget);
- return TRUE;
- }
+gboolean
+gtk_widget_grab_focus_self (GtkWidget *widget)
+{
+ GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
- for (child = _gtk_widget_get_first_child (focus_widget);
+ gtk_root_set_focus (priv->root, widget);
+ return TRUE;
+}
+
+gboolean
+gtk_widget_grab_focus_child (GtkWidget *widget)
+{
+ GtkWidget *child;
+
+ for (child = _gtk_widget_get_first_child (widget);
child != NULL;
child = _gtk_widget_get_next_sibling (child))
{
@@ -4769,6 +4779,15 @@ gtk_widget_real_grab_focus (GtkWidget *focus_widget)
return FALSE;
}
+static gboolean
+gtk_widget_real_grab_focus (GtkWidget *focus_widget)
+{
+ GtkWidgetPrivate *priv = gtk_widget_get_instance_private (focus_widget);
+
+ gtk_root_set_focus (priv->root, focus_widget);
+ return TRUE;
+}
+
static gboolean
gtk_widget_real_query_tooltip (GtkWidget *widget,
gint x,
@@ -4878,20 +4897,11 @@ direction_is_forward (GtkDirectionType direction)
}
static gboolean
-gtk_widget_real_focus (GtkWidget *widget,
- GtkDirectionType direction)
+gtk_widget_real_focus (GtkWidget *widget,
+ GtkDirectionType direction)
{
GtkWidget *focus;
- /* The easy case: not focusable. Just try the children */
- if (!gtk_widget_get_can_focus (widget))
- {
- if (gtk_widget_focus_move (widget, direction))
- return TRUE;
-
- return FALSE;
- }
-
/* For focusable widgets, we want to focus the widget
* before its children. We differentiate 3 cases:
* 1) focus is currently on widget
@@ -4934,6 +4944,32 @@ gtk_widget_real_focus (GtkWidget *widget,
return TRUE;
}
+gboolean
+gtk_widget_focus_self (GtkWidget *widget,
+ GtkDirectionType direction)
+{
+ if (!gtk_widget_is_focus (widget))
+ {
+ gtk_widget_grab_focus (widget);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gboolean
+gtk_widget_focus_child (GtkWidget *widget,
+ GtkDirectionType direction)
+{
+ return gtk_widget_focus_move (widget, direction);
+}
+
+gboolean
+gtk_widget_focus_none (GtkWidget *widget,
+ GtkDirectionType direction)
+{
+ return FALSE;
+}
+
static void
gtk_widget_real_move_focus (GtkWidget *widget,
GtkDirectionType direction)
@@ -6658,7 +6694,8 @@ gtk_widget_child_focus (GtkWidget *widget,
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
if (!_gtk_widget_get_visible (widget) ||
- !gtk_widget_is_sensitive (widget))
+ !gtk_widget_is_sensitive (widget) ||
+ !gtk_widget_get_can_focus (widget))
return FALSE;
/* Emit ::focus in any case, even if can-focus is FALSE,
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index 53467aeae1..6ff2be1d74 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -360,6 +360,18 @@ guint gtk_widget_add_surface_transform_changed_callback (GtkWidget
void gtk_widget_remove_surface_transform_changed_callback (GtkWidget *widget,
guint id);
+/* focus vfuncs for non-focusable non-containers */
+gboolean gtk_widget_grab_focus_none (GtkWidget *widget);
+gboolean gtk_widget_focus_none (GtkWidget *widget,
+ GtkDirectionType direction);
+/* focus vfuncs for non-focusable containers with focusable children */
+gboolean gtk_widget_grab_focus_child (GtkWidget *widget);
+gboolean gtk_widget_focus_child (GtkWidget *widget,
+ GtkDirectionType direction);
+/* focus vfuncs for focusable widgets with children */
+gboolean gtk_widget_grab_focus_self (GtkWidget *widget);
+gboolean gtk_widget_focus_self (GtkWidget *widget,
+ GtkDirectionType direction);
/* inline getters */
diff --git a/gtk/inspector/css-editor.ui b/gtk/inspector/css-editor.ui
index 15984bc28d..50b9bee503 100644
--- a/gtk/inspector/css-editor.ui
+++ b/gtk/inspector/css-editor.ui
@@ -55,7 +55,6 @@
<property name="buffer">text</property>
<property name="wrap-mode">word</property>
<property name="monospace">1</property>
- <property name="has-focus">1</property>
<property name="left-margin">6</property>
<property name="right-margin">6</property>
<property name="has-tooltip">1</property>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]