listitem: Change focus handling

Focus in the listitem now works like this:
1. If any child can take focus, do not ever attempt
   to take focus.
2. Otherwise, if this item is selectable or activatable,
   allow focusing this widget.

This makes sure every item in a list is focusable for
activation and selection handling, but no useless widgets
get focused and moving focus is as fast as possible.
This commit is contained in:
Benjamin Otte
2019-10-15 04:18:10 +02:00
committed by Matthias Clasen
parent 0e325c3208
commit 772d7e41f2

View File

@@ -86,6 +86,51 @@ G_DEFINE_TYPE (GtkListItem, gtk_list_item, GTK_TYPE_WIDGET)
static GParamSpec *properties[N_PROPS] = { NULL, };
static gboolean
gtk_list_item_focus (GtkWidget *widget,
GtkDirectionType direction)
{
GtkListItem *self = GTK_LIST_ITEM (widget);
/* The idea of this function is the following:
* 1. If any child can take focus, do not ever attempt
* to take focus.
* 2. Otherwise, if this item is selectable or activatable,
* allow focusing this widget.
*
* This makes sure every item in a list is focusable for
* activation and selection handling, but no useless widgets
* get focused and moving focus is as fast as possible.
*/
if (self->child)
{
if (gtk_widget_get_focus_child (widget))
return FALSE;
if (gtk_widget_child_focus (self->child, direction))
return TRUE;
}
if (gtk_widget_is_focus (widget))
return FALSE;
if (!gtk_widget_get_can_focus (widget) ||
!self->selectable)
return FALSE;
return gtk_widget_grab_focus (widget);
}
static gboolean
gtk_list_item_grab_focus (GtkWidget *widget)
{
GtkListItem *self = GTK_LIST_ITEM (widget);
if (self->child && gtk_widget_grab_focus (self->child))
return TRUE;
return GTK_WIDGET_CLASS (gtk_list_item_parent_class)->grab_focus (widget);
}
static void
gtk_list_item_dispose (GObject *object)
{
@@ -163,6 +208,9 @@ gtk_list_item_class_init (GtkListItemClass *klass)
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
widget_class->focus = gtk_list_item_focus;
widget_class->grab_focus = gtk_list_item_grab_focus;
gobject_class->dispose = gtk_list_item_dispose;
gobject_class->get_property = gtk_list_item_get_property;
gobject_class->set_property = gtk_list_item_set_property;
@@ -542,7 +590,5 @@ gtk_list_item_set_selectable (GtkListItem *self,
self->selectable = selectable;
gtk_widget_set_can_focus (GTK_WIDGET (self), self->selectable);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTABLE]);
}