forked from AuroraMiddleware/gtk
Merge branch 'wip/corey/listbase-focus' into 'main'
listbase: Use set_focus_child properly Closes #5433 and #5432 See merge request GNOME/gtk!5169 (cherry picked from commit1f001a8f6a
)7081bfc6
listbase: Split scroll_to_item for reuse93e591fd
listbase: Use set_focus_child properly
This commit is contained in:
parent
779f8063d3
commit
9df10fa96f
@ -803,43 +803,13 @@ gtk_list_base_compute_scroll_align (GtkListBase *self,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_base_update_focus_tracker (GtkListBase *self)
|
||||
gtk_list_base_scroll_to_item (GtkListBase *self,
|
||||
guint pos)
|
||||
{
|
||||
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
|
||||
GtkWidget *focus_child;
|
||||
guint pos;
|
||||
|
||||
focus_child = gtk_widget_get_focus_child (GTK_WIDGET (self));
|
||||
if (!GTK_IS_LIST_ITEM_WIDGET (focus_child))
|
||||
return;
|
||||
|
||||
pos = gtk_list_item_widget_get_position (GTK_LIST_ITEM_WIDGET (focus_child));
|
||||
if (pos != gtk_list_item_tracker_get_position (priv->item_manager, priv->focus))
|
||||
{
|
||||
gtk_list_item_tracker_set_position (priv->item_manager,
|
||||
priv->focus,
|
||||
pos,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_base_scroll_to_item (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkListBase *self = GTK_LIST_BASE (widget);
|
||||
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
|
||||
int start, end;
|
||||
double align_along, align_across;
|
||||
GtkPackType side_along, side_across;
|
||||
guint pos;
|
||||
|
||||
if (!g_variant_check_format_string (parameter, "u", FALSE))
|
||||
return;
|
||||
|
||||
g_variant_get (parameter, "u", &pos);
|
||||
|
||||
/* figure out primary orientation and if position is valid */
|
||||
if (!gtk_list_base_get_allocation_along (GTK_LIST_BASE (self), pos, &start, &end))
|
||||
@ -867,14 +837,48 @@ gtk_list_base_scroll_to_item (GtkWidget *widget,
|
||||
pos,
|
||||
align_across, side_across,
|
||||
align_along, side_along);
|
||||
}
|
||||
|
||||
/* HACK HACK HACK
|
||||
*
|
||||
* GTK has no way to track the focused child. But we now that when a listitem
|
||||
* gets focus, it calls this action. So we update our focus tracker from here
|
||||
* because it's the closest we can get to accurate tracking.
|
||||
*/
|
||||
gtk_list_base_update_focus_tracker (self);
|
||||
static void
|
||||
gtk_list_base_scroll_to_item_action (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkListBase *self = GTK_LIST_BASE (widget);
|
||||
guint pos;
|
||||
|
||||
if (!g_variant_check_format_string (parameter, "u", FALSE))
|
||||
return;
|
||||
|
||||
g_variant_get (parameter, "u", &pos);
|
||||
|
||||
gtk_list_base_scroll_to_item (self, pos);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_base_set_focus_child (GtkWidget *widget,
|
||||
GtkWidget *child)
|
||||
{
|
||||
GtkListBase *self = GTK_LIST_BASE (widget);
|
||||
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
|
||||
guint pos;
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_list_base_parent_class)->set_focus_child (widget, child);
|
||||
|
||||
if (!GTK_IS_LIST_ITEM_WIDGET (child))
|
||||
return;
|
||||
|
||||
pos = gtk_list_item_widget_get_position (GTK_LIST_ITEM_WIDGET (child));
|
||||
|
||||
if (pos != gtk_list_item_tracker_get_position (priv->item_manager, priv->focus))
|
||||
{
|
||||
gtk_list_base_scroll_to_item (self, pos);
|
||||
gtk_list_item_tracker_set_position (priv->item_manager,
|
||||
priv->focus,
|
||||
pos,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1135,6 +1139,7 @@ gtk_list_base_class_init (GtkListBaseClass *klass)
|
||||
|
||||
widget_class->focus = gtk_list_base_focus;
|
||||
widget_class->grab_focus = gtk_list_base_grab_focus;
|
||||
widget_class->set_focus_child = gtk_list_base_set_focus_child;
|
||||
|
||||
gobject_class->dispose = gtk_list_base_dispose;
|
||||
gobject_class->get_property = gtk_list_base_get_property;
|
||||
@ -1179,7 +1184,7 @@ gtk_list_base_class_init (GtkListBaseClass *klass)
|
||||
gtk_widget_class_install_action (widget_class,
|
||||
"list.scroll-to-item",
|
||||
"u",
|
||||
gtk_list_base_scroll_to_item);
|
||||
gtk_list_base_scroll_to_item_action);
|
||||
|
||||
/**
|
||||
* GtkListBase|list.select-item:
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "gtklistitemwidgetprivate.h"
|
||||
|
||||
#include "gtkbinlayout.h"
|
||||
#include "gtkeventcontrollerfocus.h"
|
||||
#include "gtkeventcontrollermotion.h"
|
||||
#include "gtkgestureclick.h"
|
||||
#include "gtklistitemfactoryprivate.h"
|
||||
@ -467,19 +466,6 @@ gtk_list_item_widget_click_gesture_released (GtkGestureClick *gesture,
|
||||
gtk_widget_unset_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_ACTIVE);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_widget_enter_cb (GtkEventControllerFocus *controller,
|
||||
GtkListItemWidget *self)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (self);
|
||||
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
|
||||
|
||||
gtk_widget_activate_action (widget,
|
||||
"list.scroll-to-item",
|
||||
"u",
|
||||
priv->position);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_widget_hover_cb (GtkEventControllerMotion *controller,
|
||||
double x,
|
||||
@ -531,10 +517,6 @@ gtk_list_item_widget_init (GtkListItemWidget *self)
|
||||
G_CALLBACK (gtk_list_item_widget_click_gesture_canceled), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
controller = gtk_event_controller_focus_new ();
|
||||
g_signal_connect (controller, "enter", G_CALLBACK (gtk_list_item_widget_enter_cb), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||
|
||||
controller = gtk_event_controller_motion_new ();
|
||||
g_signal_connect (controller, "enter", G_CALLBACK (gtk_list_item_widget_hover_cb), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||
|
Loading…
Reference in New Issue
Block a user