[gtk/wip/matthiasc/can-focus: 15/17] widget: Add common focus vfunc implementations



commit 89607448fb4088fbe83a387ed1b55b67d5cfe292
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Apr 8 07:42:27 2020 -0400

    widget: Add common focus vfunc implementations
    
    Privately export a number of implementations for the focus
    and grab_focus vfuncs that cover many common cases.

 gtk/gtkwidget.c        | 77 ++++++++++++++++++++++++++++++++------------------
 gtk/gtkwidgetprivate.h | 15 ++++++++++
 2 files changed, 65 insertions(+), 27 deletions(-)
---
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 75155458e5..38233c1359 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -586,7 +586,6 @@ static void gtk_widget_real_size_allocate    (GtkWidget         *widget,
 static void    gtk_widget_real_direction_changed(GtkWidget         *widget,
                                                   GtkTextDirection   previous_direction);
 
-static gboolean        gtk_widget_real_grab_focus       (GtkWidget         *focus_widget);
 static gboolean gtk_widget_real_query_tooltip    (GtkWidget         *widget,
                                                  gint               x,
                                                  gint               y,
@@ -595,8 +594,6 @@ static gboolean gtk_widget_real_query_tooltip    (GtkWidget         *widget,
 static void     gtk_widget_real_css_changed      (GtkWidget         *widget,
                                                   GtkCssStyleChange *change);
 
-static gboolean                gtk_widget_real_focus                   (GtkWidget        *widget,
-                                                                GtkDirectionType  direction);
 static void             gtk_widget_real_move_focus              (GtkWidget        *widget,
                                                                  GtkDirectionType  direction);
 static gboolean                gtk_widget_real_keynav_failed           (GtkWidget        *widget,
@@ -906,8 +903,8 @@ gtk_widget_class_init (GtkWidgetClass *klass)
   klass->grab_notify = gtk_widget_real_grab_notify;
   klass->snapshot = gtk_widget_real_snapshot;
   klass->mnemonic_activate = gtk_widget_real_mnemonic_activate;
-  klass->grab_focus = gtk_widget_real_grab_focus;
-  klass->focus = gtk_widget_real_focus;
+  klass->grab_focus = gtk_widget_grab_focus_self;
+  klass->focus = gtk_widget_focus_all;
   klass->move_focus = gtk_widget_real_move_focus;
   klass->keynav_failed = gtk_widget_real_keynav_failed;
   klass->query_tooltip = gtk_widget_real_query_tooltip;
@@ -4740,25 +4737,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))
     {
@@ -4877,21 +4883,12 @@ direction_is_forward (GtkDirectionType direction)
     }
 }
 
-static gboolean
-gtk_widget_real_focus (GtkWidget         *widget,
-                       GtkDirectionType   direction)
+gboolean
+gtk_widget_focus_all (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 +4931,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)
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index 53467aeae1..b2a4836ca0 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -360,6 +360,21 @@ 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 that don't receive focus */
+gboolean gtk_widget_grab_focus_self  (GtkWidget        *widget);
+gboolean gtk_widget_focus_self       (GtkWidget        *widget,
+                                      GtkDirectionType  direction);
+/* focus vfuncs for focusable widgets with children that receive focus */
+gboolean gtk_widget_focus_all        (GtkWidget        *widget,
+                                      GtkDirectionType  direction);
 
 /* inline getters */
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]