[gtk+] GtkStack: Improve focus handling
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] GtkStack: Improve focus handling
- Date: Thu, 11 Dec 2014 03:48:22 +0000 (UTC)
commit 123c6dc5586dd19d04055cc329e6507d602c869a
Author: Matthias Clasen <mclasen redhat com>
Date: Wed Dec 10 22:32:45 2014 -0500
GtkStack: Improve focus handling
Add notebook-like focus handling: Keep track of the last focused
descendent of each page, and focus it again when switching back
to the page. If there is no last focused child, we move the focus
into the page as if the user had hit Tab.
gtk/gtkstack.c | 41 ++++++++++++++++++++++++++++++++++++++++-
1 files changed, 40 insertions(+), 1 deletions(-)
---
diff --git a/gtk/gtkstack.c b/gtk/gtkstack.c
index 9726bed..b880c64 100644
--- a/gtk/gtkstack.c
+++ b/gtk/gtkstack.c
@@ -112,6 +112,7 @@ struct _GtkStackChildInfo {
gchar *title;
gchar *icon_name;
gboolean needs_attention;
+ GtkWidget *last_focus;
};
typedef struct {
@@ -996,6 +997,9 @@ set_visible_child (GtkStack *stack,
GtkStackChildInfo *info;
GtkWidget *widget = GTK_WIDGET (stack);
GList *l;
+ GtkWidget *toplevel;
+ GtkWidget *focus;
+ gboolean contains_focus = FALSE;
/* If none, pick first visible */
if (child_info == NULL)
@@ -1014,6 +1018,25 @@ set_visible_child (GtkStack *stack,
if (child_info == priv->visible_child)
return;
+ toplevel = gtk_widget_get_toplevel (widget);
+ if (GTK_IS_WINDOW (toplevel))
+ {
+ focus = gtk_window_get_focus (GTK_WINDOW (toplevel));
+ if (focus &&
+ priv->visible_child &&
+ gtk_widget_is_ancestor (focus, priv->visible_child->widget))
+ {
+ contains_focus = TRUE;
+
+ if (priv->visible_child->last_focus)
+ g_object_remove_weak_pointer (G_OBJECT (priv->visible_child->last_focus),
+ (gpointer *)&priv->visible_child->last_focus);
+ priv->visible_child->last_focus = focus;
+ g_object_add_weak_pointer (G_OBJECT (priv->visible_child->last_focus),
+ (gpointer *)&priv->visible_child->last_focus);
+ }
+ }
+
if (priv->last_visible_child)
gtk_widget_set_child_visible (priv->last_visible_child->widget, FALSE);
priv->last_visible_child = NULL;
@@ -1033,7 +1056,17 @@ set_visible_child (GtkStack *stack,
priv->visible_child = child_info;
if (child_info)
- gtk_widget_set_child_visible (child_info->widget, TRUE);
+ {
+ gtk_widget_set_child_visible (child_info->widget, TRUE);
+
+ if (contains_focus)
+ {
+ if (child_info->last_focus)
+ gtk_widget_grab_focus (child_info->last_focus);
+ else
+ gtk_widget_child_focus (child_info->widget, GTK_DIR_TAB_FORWARD);
+ }
+ }
if ((child_info == NULL || priv->last_visible_child == NULL) &&
is_direction_dependent_transition (transition_type))
@@ -1164,6 +1197,7 @@ gtk_stack_add (GtkContainer *container,
child_info->title = NULL;
child_info->icon_name = NULL;
child_info->needs_attention = FALSE;
+ child_info->last_focus = NULL;
priv->children = g_list_append (priv->children, child_info);
@@ -1224,6 +1258,11 @@ gtk_stack_remove (GtkContainer *container,
g_free (child_info->name);
g_free (child_info->title);
g_free (child_info->icon_name);
+
+ if (child_info->last_focus)
+ g_object_remove_weak_pointer (G_OBJECT (child_info->last_focus),
+ (gpointer *)&child_info->last_focus);
+
g_slice_free (GtkStackChildInfo, child_info);
if ((priv->hhomogeneous || priv->vhomogeneous) && was_visible)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]