Merge branch 'wip/otte/for-master' into 'master'

Wip/otte/for master

See merge request GNOME/gtk!2024
This commit is contained in:
Benjamin Otte 2020-06-03 17:40:26 +00:00
commit 7312284e4f
2 changed files with 53 additions and 25 deletions

View File

@ -455,7 +455,15 @@ gtk_list_base_focus (GtkWidget *widget,
GtkDirectionType direction)
{
GtkListBase *self = GTK_LIST_BASE (widget);
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
guint old, pos, n_items;
GtkWidget *focus_child;
GtkListItemManagerItem *item;
focus_child = gtk_widget_get_focus_child (widget);
/* focus is moving around fine inside the focus child, don't disturb it */
if (focus_child && gtk_widget_child_focus (focus_child, direction))
return TRUE;
pos = gtk_list_base_get_focus_position (self);
n_items = gtk_list_base_get_n_items (self);
@ -468,12 +476,12 @@ gtk_list_base_focus (GtkWidget *widget,
pos = 0;
}
else if (gtk_widget_get_focus_child (widget) == NULL)
else if (focus_child == NULL)
{
/* Focus was outside the list, just grab the old focus item
* while keeping the selection intact.
*/
return gtk_list_base_grab_focus_on_item (GTK_LIST_BASE (self), pos, FALSE, FALSE, FALSE);
old = GTK_INVALID_LIST_POSITION;
}
else
{
@ -513,14 +521,18 @@ gtk_list_base_focus (GtkWidget *widget,
}
}
if (old != pos)
{
return gtk_list_base_grab_focus_on_item (GTK_LIST_BASE (self), pos, TRUE, FALSE, FALSE);
}
else
{
return TRUE;
}
if (old == pos)
return TRUE;
item = gtk_list_item_manager_get_nth (priv->item_manager, pos, NULL);
if (item == NULL)
return FALSE;
/* This shouldn't really happen, but if it does, oh well */
if (item->widget == NULL)
return gtk_list_base_grab_focus_on_item (GTK_LIST_BASE (self), pos, TRUE, FALSE, FALSE);
return gtk_widget_child_focus (item->widget, direction);
}
static void
@ -1460,6 +1472,7 @@ gtk_list_base_grab_focus_on_item (GtkListBase *self,
{
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
GtkListItemManagerItem *item;
gboolean success;
item = gtk_list_item_manager_get_nth (priv->item_manager, pos, NULL);
if (item == NULL)
@ -1478,17 +1491,18 @@ gtk_list_base_grab_focus_on_item (GtkListBase *self,
item = gtk_list_item_manager_get_nth (priv->item_manager, pos, NULL);
g_assert (item->widget);
if (!gtk_widget_grab_focus (item->widget))
return FALSE;
success = gtk_widget_grab_focus (item->widget);
gtk_list_item_tracker_free (priv->item_manager, tracker);
}
else
{
if (!gtk_widget_grab_focus (item->widget))
return FALSE;
success = gtk_widget_grab_focus (item->widget);
}
if (!success)
return FALSE;
if (select)
gtk_list_base_select_item (self, pos, modify, extend);

View File

@ -83,8 +83,7 @@ static gboolean
gtk_list_item_widget_focus (GtkWidget *widget,
GtkDirectionType direction)
{
GtkListItemWidget *self = GTK_LIST_ITEM_WIDGET (widget);
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
GtkWidget *child, *focus_child;
/* The idea of this function is the following:
* 1. If any child can take focus, do not ever attempt
@ -96,19 +95,24 @@ gtk_list_item_widget_focus (GtkWidget *widget,
* activation and selection handling, but no useless widgets
* get focused and moving focus is as fast as possible.
*/
if (priv->list_item && priv->list_item->child)
focus_child = gtk_widget_get_focus_child (widget);
if (focus_child && gtk_widget_child_focus (focus_child, direction))
return TRUE;
for (child = focus_child ? gtk_widget_get_next_sibling (focus_child)
: gtk_widget_get_first_child (widget);
child;
child = gtk_widget_get_next_sibling (child))
{
if (gtk_widget_get_focus_child (widget))
return FALSE;
if (gtk_widget_child_focus (priv->list_item->child, direction))
if (gtk_widget_child_focus (child, direction))
return TRUE;
}
if (gtk_widget_is_focus (widget))
if (focus_child)
return FALSE;
if (!gtk_widget_get_can_focus (widget) ||
!priv->list_item->selectable)
if (gtk_widget_is_focus (widget))
return FALSE;
return gtk_widget_grab_focus (widget);
@ -119,9 +123,19 @@ gtk_list_item_widget_grab_focus (GtkWidget *widget)
{
GtkListItemWidget *self = GTK_LIST_ITEM_WIDGET (widget);
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
GtkWidget *child;
if (priv->list_item && priv->list_item->child && gtk_widget_grab_focus (priv->list_item->child))
return TRUE;
for (child = gtk_widget_get_first_child (widget);
child;
child = gtk_widget_get_next_sibling (child))
{
if (gtk_widget_grab_focus (child))
return TRUE;
}
if (priv->list_item == NULL ||
!priv->list_item->selectable)
return FALSE;
return GTK_WIDGET_CLASS (gtk_list_item_widget_parent_class)->grab_focus (widget);
}