[gtk/wip/matthiasc/can-focus: 20/27] gizmo: Allow passing changing focus behavior



commit 3acdc1ff503e361e7797f28aa5f848cd26fc7e94
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Apr 8 07:34:38 2020 -0400

    gizmo: Allow passing changing focus behavior
    
    We need this in popovers. Maybe it could be done better
    by defining one-off custom widgets.

 gtk/gtkgizmo.c        | 39 ++++++++++++++++++++++++++++++++++-----
 gtk/gtkgizmoprivate.h | 25 ++++++++++++++++---------
 gtk/gtklevelbar.c     |  5 +++--
 gtk/gtknotebook.c     | 16 +++++++++-------
 gtk/gtkpaned.c        |  2 +-
 gtk/gtkpopover.c      |  4 +++-
 gtk/gtkprogressbar.c  |  5 +++--
 gtk/gtkrange.c        |  9 +++++----
 gtk/gtkscale.c        | 10 ++++++----
 gtk/gtkswitch.c       |  2 +-
 gtk/gtktreepopover.c  |  2 +-
 11 files changed, 82 insertions(+), 37 deletions(-)
---
diff --git a/gtk/gtkgizmo.c b/gtk/gtkgizmo.c
index e885020e89..a929248a5c 100644
--- a/gtk/gtkgizmo.c
+++ b/gtk/gtkgizmo.c
@@ -59,6 +59,29 @@ gtk_gizmo_contains (GtkWidget *widget,
     return GTK_WIDGET_CLASS (gtk_gizmo_parent_class)->contains (widget, x, y);
 }
 
+static gboolean
+gtk_gizmo_focus (GtkWidget        *widget,
+                 GtkDirectionType  direction)
+{
+  GtkGizmo *self = GTK_GIZMO (widget);
+
+  if (self->focus_func)
+    return self->focus_func (self, direction);
+
+  return FALSE;
+}
+
+static gboolean
+gtk_gizmo_grab_focus (GtkWidget *widget)
+{
+  GtkGizmo *self = GTK_GIZMO (widget);
+
+  if (self->grab_focus_func)
+    return self->grab_focus_func (self);
+
+  return FALSE;
+}
+
 static void
 gtk_gizmo_finalize (GObject *object)
 {
@@ -90,6 +113,8 @@ gtk_gizmo_class_init (GtkGizmoClass *klass)
   widget_class->size_allocate = gtk_gizmo_size_allocate;
   widget_class->snapshot = gtk_gizmo_snapshot;
   widget_class->contains = gtk_gizmo_contains;
+  widget_class->grab_focus = gtk_gizmo_grab_focus;
+  widget_class->focus = gtk_gizmo_focus;
 }
 
 static void
@@ -98,11 +123,13 @@ gtk_gizmo_init (GtkGizmo *self)
 }
 
 GtkWidget *
-gtk_gizmo_new (const char              *css_name,
-               GtkGizmoMeasureFunc  measure_func,
-               GtkGizmoAllocateFunc allocate_func,
-               GtkGizmoSnapshotFunc snapshot_func,
-               GtkGizmoContainsFunc contains_func)
+gtk_gizmo_new (const char            *css_name,
+               GtkGizmoMeasureFunc    measure_func,
+               GtkGizmoAllocateFunc   allocate_func,
+               GtkGizmoSnapshotFunc   snapshot_func,
+               GtkGizmoContainsFunc   contains_func,
+               GtkGizmoFocusFunc      focus_func,
+               GtkGizmoGrabFocusFunc  grab_focus_func)
 {
   GtkGizmo *gizmo = GTK_GIZMO (g_object_new (GTK_TYPE_GIZMO,
                                              "css-name", css_name,
@@ -112,6 +139,8 @@ gtk_gizmo_new (const char              *css_name,
   gizmo->allocate_func = allocate_func;
   gizmo->snapshot_func = snapshot_func;
   gizmo->contains_func = contains_func;
+  gizmo->focus_func = focus_func;
+  gizmo->grab_focus_func = grab_focus_func;
 
   return GTK_WIDGET (gizmo);
 }
diff --git a/gtk/gtkgizmoprivate.h b/gtk/gtkgizmoprivate.h
index 4f4f0127c6..478af19971 100644
--- a/gtk/gtkgizmoprivate.h
+++ b/gtk/gtkgizmoprivate.h
@@ -30,15 +30,20 @@ typedef void    (* GtkGizmoSnapshotFunc)  (GtkGizmo    *gizmo,
 typedef gboolean (* GtkGizmoContainsFunc) (GtkGizmo  *gizmo,
                                            double     x,
                                            double     y);
+typedef gboolean (* GtkGizmoFocusFunc)    (GtkGizmo         *gizmo,
+                                           GtkDirectionType  direction);
+typedef gboolean (* GtkGizmoGrabFocusFunc)(GtkGizmo         *gizmo);
 
 struct _GtkGizmo
 {
   GtkWidget parent_instance;
 
-  GtkGizmoMeasureFunc  measure_func;
-  GtkGizmoAllocateFunc allocate_func;
-  GtkGizmoSnapshotFunc snapshot_func;
-  GtkGizmoContainsFunc contains_func;
+  GtkGizmoMeasureFunc   measure_func;
+  GtkGizmoAllocateFunc  allocate_func;
+  GtkGizmoSnapshotFunc  snapshot_func;
+  GtkGizmoContainsFunc  contains_func;
+  GtkGizmoFocusFunc     focus_func;
+  GtkGizmoGrabFocusFunc grab_focus_func;
 };
 
 struct _GtkGizmoClass
@@ -48,11 +53,13 @@ struct _GtkGizmoClass
 
 GType      gtk_gizmo_get_type (void) G_GNUC_CONST;
 
-GtkWidget *gtk_gizmo_new (const char          *css_name,
-                          GtkGizmoMeasureFunc  measure_func,
-                          GtkGizmoAllocateFunc allocate_func,
-                          GtkGizmoSnapshotFunc snapshot_func,
-                          GtkGizmoContainsFunc contains_func);
+GtkWidget *gtk_gizmo_new (const char            *css_name,
+                          GtkGizmoMeasureFunc    measure_func,
+                          GtkGizmoAllocateFunc   allocate_func,
+                          GtkGizmoSnapshotFunc   snapshot_func,
+                          GtkGizmoContainsFunc   contains_func,
+                          GtkGizmoFocusFunc      focus_func,
+                          GtkGizmoGrabFocusFunc  grab_focus_func);
 
 
 #endif
diff --git a/gtk/gtklevelbar.c b/gtk/gtklevelbar.c
index c34fcc5364..d00a03f1f3 100644
--- a/gtk/gtklevelbar.c
+++ b/gtk/gtklevelbar.c
@@ -545,7 +545,7 @@ update_block_nodes (GtkLevelBar *self)
       self->block_widget = g_renew (GtkWidget*, self->block_widget, n_blocks);
       for (i = self->n_blocks; i < n_blocks; i++)
         {
-          self->block_widget[i] = gtk_gizmo_new ("block", NULL, NULL, NULL, NULL);
+          self->block_widget[i] = gtk_gizmo_new ("block", NULL, NULL, NULL, NULL, NULL, NULL);
           gtk_widget_insert_before (self->block_widget[i], GTK_WIDGET (self->trough_widget), NULL);
         }
       self->n_blocks = n_blocks;
@@ -1022,7 +1022,8 @@ gtk_level_bar_init (GtkLevelBar *self)
                                        gtk_level_bar_measure_trough,
                                        gtk_level_bar_allocate_trough,
                                        gtk_level_bar_render_trough,
-                                       NULL);
+                                       NULL,
+                                       NULL, NULL);
   gtk_widget_set_parent (self->trough_widget, GTK_WIDGET (self));
 
   gtk_level_bar_ensure_offset (self, GTK_LEVEL_BAR_OFFSET_LOW, 0.25);
diff --git a/gtk/gtknotebook.c b/gtk/gtknotebook.c
index d74e2defd3..9b78beffa8 100644
--- a/gtk/gtknotebook.c
+++ b/gtk/gtknotebook.c
@@ -1412,17 +1412,19 @@ gtk_notebook_init (GtkNotebook *notebook)
   notebook->has_scrolled = FALSE;
 
   notebook->header_widget = g_object_new (GTK_TYPE_BOX,
-                                      "css-name", "header",
-                                      NULL);
+                                          "css-name", "header",
+                                          NULL);
   gtk_widget_add_css_class (notebook->header_widget, GTK_STYLE_CLASS_TOP);
   gtk_widget_hide (notebook->header_widget);
   gtk_widget_set_parent (notebook->header_widget, GTK_WIDGET (notebook));
 
   notebook->tabs_widget = gtk_gizmo_new ("tabs",
-                                     gtk_notebook_measure_tabs,
-                                     gtk_notebook_allocate_tabs,
-                                     gtk_notebook_snapshot_tabs,
-                                     NULL);
+                                         gtk_notebook_measure_tabs,
+                                         gtk_notebook_allocate_tabs,
+                                         gtk_notebook_snapshot_tabs,
+                                         NULL,
+                                         (GtkGizmoFocusFunc)gtk_widget_focus_self,
+                                         (GtkGizmoGrabFocusFunc)gtk_widget_grab_focus_self);
   gtk_widget_set_hexpand (notebook->tabs_widget, TRUE);
   gtk_container_add (GTK_CONTAINER (notebook->header_widget), notebook->tabs_widget);
 
@@ -3981,7 +3983,7 @@ gtk_notebook_insert_notebook_page (GtkNotebook *notebook,
   else
   sibling = notebook->arrow_widget[ARROW_RIGHT_AFTER];
 
-  page->tab_widget = gtk_gizmo_new ("tab", measure_tab, allocate_tab, NULL, NULL);
+  page->tab_widget = gtk_gizmo_new ("tab", measure_tab, allocate_tab, NULL, NULL, NULL, NULL);
   g_object_set_data (G_OBJECT (page->tab_widget), "notebook", notebook);
   gtk_widget_insert_before (page->tab_widget, notebook->tabs_widget, sibling);
   controller = gtk_drop_controller_motion_new ();
diff --git a/gtk/gtkpaned.c b/gtk/gtkpaned.c
index 96c937ca13..59db55efd7 100644
--- a/gtk/gtkpaned.c
+++ b/gtk/gtkpaned.c
@@ -1390,7 +1390,7 @@ gtk_paned_init (GtkPaned *paned)
   gtk_widget_add_controller (GTK_WIDGET (paned), GTK_EVENT_CONTROLLER (gesture));
   priv->drag_gesture = gesture;
 
-  priv->handle_widget = gtk_gizmo_new ("separator", NULL, NULL, gtk_paned_render_handle, 
gtk_paned_handle_contains);
+  priv->handle_widget = gtk_gizmo_new ("separator", NULL, NULL, gtk_paned_render_handle, 
gtk_paned_handle_contains, NULL, NULL);
   gtk_widget_set_parent (priv->handle_widget, GTK_WIDGET (paned));
   gtk_widget_set_cursor_from_name (priv->handle_widget, "col-resize");
 }
diff --git a/gtk/gtkpopover.c b/gtk/gtkpopover.c
index 3ef845c41f..11dd3f273b 100644
--- a/gtk/gtkpopover.c
+++ b/gtk/gtkpopover.c
@@ -847,7 +847,9 @@ gtk_popover_init (GtkPopover *popover)
                            G_CALLBACK (node_style_changed_cb), popover, 0);
   g_object_unref (priv->arrow_node);
 
-  priv->contents_widget = gtk_gizmo_new ("contents", NULL, NULL, NULL, NULL);
+  priv->contents_widget = gtk_gizmo_new ("contents", NULL, NULL, NULL, NULL,
+                                         (GtkGizmoFocusFunc)gtk_widget_focus_child,
+                                         (GtkGizmoGrabFocusFunc)gtk_widget_grab_focus_child);
   gtk_widget_set_layout_manager (priv->contents_widget, gtk_bin_layout_new ());
   gtk_widget_set_parent (priv->contents_widget, GTK_WIDGET (popover));
 
diff --git a/gtk/gtkprogressbar.c b/gtk/gtkprogressbar.c
index 42d53dd74b..c293046838 100644
--- a/gtk/gtkprogressbar.c
+++ b/gtk/gtkprogressbar.c
@@ -459,10 +459,11 @@ gtk_progress_bar_init (GtkProgressBar *pbar)
                                        NULL,
                                        allocate_trough,
                                        NULL,
-                                       NULL);
+                                       NULL,
+                                       NULL, NULL);
   gtk_widget_set_parent (priv->trough_widget, GTK_WIDGET (pbar));
 
-  priv->progress_widget = gtk_gizmo_new ("progress", NULL, NULL, NULL, NULL);
+  priv->progress_widget = gtk_gizmo_new ("progress", NULL, NULL, NULL, NULL, NULL, NULL);
   gtk_widget_set_parent (priv->progress_widget, priv->trough_widget);
 
   /* horizontal is default */
diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c
index b204596650..d6995fce4c 100644
--- a/gtk/gtkrange.c
+++ b/gtk/gtkrange.c
@@ -548,11 +548,12 @@ gtk_range_init (GtkRange *range)
                                        gtk_range_measure_trough,
                                        gtk_range_allocate_trough,
                                        gtk_range_render_trough,
-                                       NULL);
+                                       NULL,
+                                       NULL, NULL);
 
   gtk_widget_set_parent (priv->trough_widget, GTK_WIDGET (range));
 
-  priv->slider_widget = gtk_gizmo_new ("slider", NULL, NULL, NULL, NULL);
+  priv->slider_widget = gtk_gizmo_new ("slider", NULL, NULL, NULL, NULL, NULL, NULL);
   gtk_widget_set_parent (priv->slider_widget, priv->trough_widget);
 
   /* Note: Order is important here.
@@ -1115,7 +1116,7 @@ gtk_range_set_show_fill_level (GtkRange *range,
 
   if (show_fill_level)
     {
-      priv->fill_widget = gtk_gizmo_new ("fill", NULL, NULL, NULL, NULL);
+      priv->fill_widget = gtk_gizmo_new ("fill", NULL, NULL, NULL, NULL, NULL, NULL);
       gtk_widget_insert_after (priv->fill_widget, priv->trough_widget, NULL);
       update_fill_position (range);
     }
@@ -2757,7 +2758,7 @@ _gtk_range_set_has_origin (GtkRange *range,
 
   if (has_origin)
     {
-      priv->highlight_widget = gtk_gizmo_new ("highlight", NULL, NULL, NULL, NULL);
+      priv->highlight_widget = gtk_gizmo_new ("highlight", NULL, NULL, NULL, NULL, NULL, NULL);
       gtk_widget_insert_before (priv->highlight_widget, priv->trough_widget, priv->slider_widget);
 
       update_highlight_position (range);
diff --git a/gtk/gtkscale.c b/gtk/gtkscale.c
index 9583c3ea9c..c961919524 100644
--- a/gtk/gtkscale.c
+++ b/gtk/gtkscale.c
@@ -1715,7 +1715,8 @@ gtk_scale_add_mark (GtkScale        *scale,
                                                   gtk_scale_measure_marks,
                                                   gtk_scale_allocate_marks,
                                                   NULL,
-                                                  NULL);
+                                                  NULL,
+                                                  NULL, NULL);
 
           gtk_widget_insert_after (priv->top_marks_widget,
                                    GTK_WIDGET (scale),
@@ -1734,7 +1735,8 @@ gtk_scale_add_mark (GtkScale        *scale,
                                                      gtk_scale_measure_marks,
                                                      gtk_scale_allocate_marks,
                                                      NULL,
-                                                     NULL);
+                                                     NULL,
+                                                     NULL, NULL);
 
           gtk_widget_insert_before (priv->bottom_marks_widget,
                                     GTK_WIDGET (scale),
@@ -1746,10 +1748,10 @@ gtk_scale_add_mark (GtkScale        *scale,
       marks_widget = priv->bottom_marks_widget;
     }
 
-  mark->widget = gtk_gizmo_new ("mark", gtk_scale_measure_mark, gtk_scale_allocate_mark, NULL, NULL);
+  mark->widget = gtk_gizmo_new ("mark", gtk_scale_measure_mark, gtk_scale_allocate_mark, NULL, NULL, NULL, 
NULL);
   g_object_set_data (G_OBJECT (mark->widget), "mark", mark);
 
-  mark->indicator_widget = gtk_gizmo_new ("indicator", NULL, NULL, NULL, NULL);
+  mark->indicator_widget = gtk_gizmo_new ("indicator", NULL, NULL, NULL, NULL, NULL, NULL);
   gtk_widget_set_parent (mark->indicator_widget, mark->widget);
   if (mark->markup && *mark->markup)
     {
diff --git a/gtk/gtkswitch.c b/gtk/gtkswitch.c
index 148a94a418..a62a83b1e2 100644
--- a/gtk/gtkswitch.c
+++ b/gtk/gtkswitch.c
@@ -656,7 +656,7 @@ gtk_switch_init (GtkSwitch *self)
   self->off_image = gtk_image_new_from_icon_name ("switch-off-symbolic");
   gtk_widget_set_parent (self->off_image, GTK_WIDGET (self));
 
-  self->slider = gtk_gizmo_new ("slider", NULL, NULL, NULL, NULL);
+  self->slider = gtk_gizmo_new ("slider", NULL, NULL, NULL, NULL, NULL, NULL);
   gtk_widget_set_parent (self->slider, GTK_WIDGET (self));
 }
 
diff --git a/gtk/gtktreepopover.c b/gtk/gtktreepopover.c
index 207f107699..b638ec2f17 100644
--- a/gtk/gtktreepopover.c
+++ b/gtk/gtktreepopover.c
@@ -666,7 +666,7 @@ gtk_tree_popover_create_item (GtkTreePopover *popover,
       gtk_cell_view_set_displayed_row (GTK_CELL_VIEW (view), path);
       gtk_widget_set_hexpand (view, TRUE);
 
-      item = gtk_gizmo_new ("modelbutton", NULL, NULL, NULL, NULL);
+      item = gtk_gizmo_new ("modelbutton", NULL, NULL, NULL, NULL, NULL, NULL);
       gtk_widget_set_layout_manager (item, gtk_box_layout_new (GTK_ORIENTATION_HORIZONTAL));
       gtk_widget_add_css_class (item, "flat");
 


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