Merge branch 'focusable-containers' into 'master'

Focusable containers

See merge request GNOME/gtk!929
This commit is contained in:
Matthias Clasen
2019-06-11 17:36:40 +00:00
6 changed files with 109 additions and 11 deletions

View File

@@ -5522,31 +5522,79 @@ gtk_widget_real_style_updated (GtkWidget *widget)
}
}
static gboolean
direction_is_forward (GtkDirectionType direction)
{
switch (direction)
{
case GTK_DIR_TAB_FORWARD:
case GTK_DIR_RIGHT:
case GTK_DIR_DOWN:
return TRUE;
case GTK_DIR_TAB_BACKWARD:
case GTK_DIR_LEFT:
case GTK_DIR_UP:
return FALSE;
default:
g_assert_not_reached ();
}
}
static gboolean
gtk_widget_real_focus (GtkWidget *widget,
GtkDirectionType direction)
{
if (gtk_widget_get_can_focus (widget))
GtkWidget *focus;
/* The easy case: not focusable. Just try the children */
if (!gtk_widget_get_can_focus (widget))
{
if (!gtk_widget_is_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
* 2) focus is on some child
* 3) focus is outside
*/
if (gtk_widget_is_focus (widget))
{
if (direction_is_forward (direction) &&
gtk_widget_focus_move (widget, direction))
return TRUE;
return FALSE;
}
focus = gtk_window_get_focus (GTK_WINDOW (gtk_widget_get_root (widget)));
if (focus && gtk_widget_is_ancestor (focus, widget))
{
if (gtk_widget_focus_move (widget, direction))
return TRUE;
if (direction_is_forward (direction))
return FALSE;
else
{
gtk_widget_grab_focus (widget);
return TRUE;
}
}
else if (_gtk_widget_get_first_child (widget) == NULL)
if (!direction_is_forward (direction))
{
/* No children, no possibility to focus anything */
return FALSE;
}
else
{
/* Try focusing any of the child widgets, depending on the given direction */
if (gtk_widget_focus_move (widget, direction))
return TRUE;
}
return FALSE;
gtk_widget_grab_focus (widget);
return TRUE;
}
static void

View File

@@ -0,0 +1,5 @@
entry1 GtkText
box
entry2 GtkText
entry3 GtkText
WRAP

View File

@@ -0,0 +1,5 @@
entry3 GtkText
entry2 GtkText
box
entry1 GtkText
WRAP

View File

@@ -0,0 +1,29 @@
<interface>
<object class="GtkWindow" id="window">
<child>
<object class="GtkBox">
<child>
<object class="GtkEntry">
<property name="name">entry1</property>
</object>
</child>
<child>
<object class="GtkBox">
<property name="name">box</property>
<property name="can-focus">1</property>
<child>
<object class="GtkEntry">
<property name="name">entry2</property>
</object>
</child>
<child>
<object class="GtkEntry">
<property name="name">entry3</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -136,6 +136,8 @@ focus_chain_tests = [
[ 'basic', 'tab-backward' ],
[ 'basic', 'left' ],
[ 'basic', 'right' ],
[ 'focusable-container', 'tab' ],
[ 'focusable-container', 'tab-backward' ],
]
focus_chain = executable(

View File

@@ -92,9 +92,10 @@ generate_focus_chain (GtkWidget *window,
{
char *first = NULL;
char *last = NULL;
char *name;
char *name = NULL;
GString *output = g_string_new ("");
GtkWidget *focus;
int count = 0;
gtk_widget_show (window);
@@ -135,6 +136,7 @@ generate_focus_chain (GtkWidget *window,
}
g_string_append_printf (output, "%s\n", name);
count++;
if (!first)
first = g_strdup (name);
@@ -142,9 +144,16 @@ generate_focus_chain (GtkWidget *window,
g_free (last);
last = g_strdup (name);
if (count == 100)
{
g_string_append (output, "ABORT\n");
break;
}
g_free (name);
}
g_free (name);
g_free (first);
g_free (last);