forked from AuroraMiddleware/gtk
Merge branch 'focus-adjustment' into 'master'
Drop container focus adjustments See merge request GNOME/gtk!1716
This commit is contained in:
commit
1e7c56db19
@ -839,6 +839,7 @@ overshot (GtkScrolledWindow *sw, GtkPositionType pos, GtkWidget *widget)
|
||||
gdk_rgba_parse (&rgba, color);
|
||||
swatch = g_object_new (g_type_from_name ("GtkColorSwatch"),
|
||||
"rgba", &rgba,
|
||||
"can-focus", FALSE,
|
||||
"selectable", FALSE,
|
||||
"halign", GTK_ALIGN_END,
|
||||
"valign", GTK_ALIGN_CENTER,
|
||||
@ -957,6 +958,7 @@ populate_colors (GtkWidget *widget, GtkWidget *chooser)
|
||||
swatch = g_object_new (g_type_from_name ("GtkColorSwatch"),
|
||||
"rgba", &rgba,
|
||||
"selectable", FALSE,
|
||||
"can-focus", FALSE,
|
||||
"halign", GTK_ALIGN_END,
|
||||
"valign", GTK_ALIGN_CENTER,
|
||||
"margin-start", 6,
|
||||
|
@ -700,10 +700,6 @@ gtk_container_add
|
||||
gtk_container_remove
|
||||
gtk_container_foreach
|
||||
gtk_container_get_children
|
||||
gtk_container_get_focus_vadjustment
|
||||
gtk_container_set_focus_vadjustment
|
||||
gtk_container_get_focus_hadjustment
|
||||
gtk_container_set_focus_hadjustment
|
||||
gtk_container_child_type
|
||||
gtk_container_forall
|
||||
|
||||
|
@ -494,6 +494,12 @@
|
||||
The recommended way to influence focus behavior of custom widgets
|
||||
in GTK 4 is to override the focus() and grab_focus() vfuncs.
|
||||
</para>
|
||||
<para>
|
||||
The feature to automatically keep the focus widget scrolled into view
|
||||
with gtk_container_set_focus_vadjustment() has been removed from
|
||||
GtkContainer, and is provided by scrollables instead. In the common case
|
||||
that the scrollable is a #GtkViewport, use #GtkViewport:scroll-to-focus.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
|
@ -794,6 +794,9 @@ add_custom_color (GtkColorChooserWidget *cc,
|
||||
{
|
||||
GtkWidget *last = gtk_widget_get_last_child (cc->custom);
|
||||
|
||||
if (last == (GtkWidget *)cc->current)
|
||||
cc->current = NULL;
|
||||
|
||||
gtk_container_remove (GTK_CONTAINER (cc->custom), last);
|
||||
}
|
||||
g_list_free (children);
|
||||
|
@ -119,8 +119,6 @@ static GtkSizeRequestMode gtk_container_get_request_mode (GtkWidget *widget);
|
||||
static void gtk_container_buildable_init (GtkBuildableIface *iface);
|
||||
static GtkBuildableIface *parent_buildable_iface;
|
||||
|
||||
static GQuark vadjustment_key_id;
|
||||
static GQuark hadjustment_key_id;
|
||||
static guint container_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GtkContainer, gtk_container, GTK_TYPE_WIDGET,
|
||||
@ -134,9 +132,6 @@ gtk_container_class_init (GtkContainerClass *class)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
vadjustment_key_id = g_quark_from_static_string ("gtk-vadjustment");
|
||||
hadjustment_key_id = g_quark_from_static_string ("gtk-hadjustment");
|
||||
|
||||
widget_class->destroy = gtk_container_destroy;
|
||||
widget_class->compute_expand = gtk_container_compute_expand;
|
||||
widget_class->get_request_mode = gtk_container_get_request_mode;
|
||||
@ -611,40 +606,6 @@ static void
|
||||
gtk_container_real_set_focus_child (GtkContainer *container,
|
||||
GtkWidget *focus_child)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CONTAINER (container));
|
||||
g_return_if_fail (focus_child == NULL || GTK_IS_WIDGET (focus_child));
|
||||
|
||||
/* Check for h/v adjustments and scroll to show the focus child if possible */
|
||||
if (focus_child)
|
||||
{
|
||||
GtkAdjustment *hadj;
|
||||
GtkAdjustment *vadj;
|
||||
gint x, y;
|
||||
|
||||
hadj = g_object_get_qdata (G_OBJECT (container), hadjustment_key_id);
|
||||
vadj = g_object_get_qdata (G_OBJECT (container), vadjustment_key_id);
|
||||
if (hadj || vadj)
|
||||
{
|
||||
GtkWidget *child = focus_child;
|
||||
graphene_rect_t child_bounds;
|
||||
|
||||
while (gtk_widget_get_focus_child (child))
|
||||
child = gtk_widget_get_focus_child (child);
|
||||
|
||||
if (!gtk_widget_translate_coordinates (child, focus_child,
|
||||
0, 0, &x, &y))
|
||||
return;
|
||||
|
||||
if (!gtk_widget_compute_bounds (child, child, &child_bounds))
|
||||
return;
|
||||
|
||||
if (vadj)
|
||||
gtk_adjustment_clamp_page (vadj, y, y + child_bounds.size.height);
|
||||
|
||||
if (hadj)
|
||||
gtk_adjustment_clamp_page (hadj, x, x + child_bounds.size.width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -656,114 +617,3 @@ gtk_container_children_callback (GtkWidget *widget,
|
||||
children = (GList**) client_data;
|
||||
*children = g_list_prepend (*children, widget);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_container_set_focus_vadjustment:
|
||||
* @container: a #GtkContainer
|
||||
* @adjustment: an adjustment which should be adjusted when the focus
|
||||
* is moved among the descendents of @container
|
||||
*
|
||||
* Hooks up an adjustment to focus handling in a container, so when a
|
||||
* child of the container is focused, the adjustment is scrolled to
|
||||
* show that widget. This function sets the vertical alignment. See
|
||||
* gtk_scrolled_window_get_vadjustment() for a typical way of obtaining
|
||||
* the adjustment and gtk_container_set_focus_hadjustment() for setting
|
||||
* the horizontal adjustment.
|
||||
*
|
||||
* The adjustments have to be in pixel units and in the same coordinate
|
||||
* system as the allocation for immediate children of the container.
|
||||
*/
|
||||
void
|
||||
gtk_container_set_focus_vadjustment (GtkContainer *container,
|
||||
GtkAdjustment *adjustment)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CONTAINER (container));
|
||||
if (adjustment)
|
||||
g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
|
||||
|
||||
if (adjustment)
|
||||
g_object_ref (adjustment);
|
||||
|
||||
g_object_set_qdata_full (G_OBJECT (container),
|
||||
vadjustment_key_id,
|
||||
adjustment,
|
||||
g_object_unref);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_container_get_focus_vadjustment:
|
||||
* @container: a #GtkContainer
|
||||
*
|
||||
* Retrieves the vertical focus adjustment for the container. See
|
||||
* gtk_container_set_focus_vadjustment().
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the vertical focus adjustment, or
|
||||
* %NULL if none has been set.
|
||||
**/
|
||||
GtkAdjustment *
|
||||
gtk_container_get_focus_vadjustment (GtkContainer *container)
|
||||
{
|
||||
GtkAdjustment *vadjustment;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CONTAINER (container), NULL);
|
||||
|
||||
vadjustment = g_object_get_qdata (G_OBJECT (container), vadjustment_key_id);
|
||||
|
||||
return vadjustment;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_container_set_focus_hadjustment:
|
||||
* @container: a #GtkContainer
|
||||
* @adjustment: an adjustment which should be adjusted when the focus is
|
||||
* moved among the descendents of @container
|
||||
*
|
||||
* Hooks up an adjustment to focus handling in a container, so when a child
|
||||
* of the container is focused, the adjustment is scrolled to show that
|
||||
* widget. This function sets the horizontal alignment.
|
||||
* See gtk_scrolled_window_get_hadjustment() for a typical way of obtaining
|
||||
* the adjustment and gtk_container_set_focus_vadjustment() for setting
|
||||
* the vertical adjustment.
|
||||
*
|
||||
* The adjustments have to be in pixel units and in the same coordinate
|
||||
* system as the allocation for immediate children of the container.
|
||||
*/
|
||||
void
|
||||
gtk_container_set_focus_hadjustment (GtkContainer *container,
|
||||
GtkAdjustment *adjustment)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CONTAINER (container));
|
||||
if (adjustment)
|
||||
g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
|
||||
|
||||
if (adjustment)
|
||||
g_object_ref (adjustment);
|
||||
|
||||
g_object_set_qdata_full (G_OBJECT (container),
|
||||
hadjustment_key_id,
|
||||
adjustment,
|
||||
g_object_unref);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_container_get_focus_hadjustment:
|
||||
* @container: a #GtkContainer
|
||||
*
|
||||
* Retrieves the horizontal focus adjustment for the container. See
|
||||
* gtk_container_set_focus_hadjustment ().
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the horizontal focus adjustment, or %NULL if
|
||||
* none has been set.
|
||||
**/
|
||||
GtkAdjustment *
|
||||
gtk_container_get_focus_hadjustment (GtkContainer *container)
|
||||
{
|
||||
GtkAdjustment *hadjustment;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CONTAINER (container), NULL);
|
||||
|
||||
hadjustment = g_object_get_qdata (G_OBJECT (container), hadjustment_key_id);
|
||||
|
||||
return hadjustment;
|
||||
}
|
||||
|
||||
|
@ -108,18 +108,6 @@ void gtk_container_foreach (GtkContainer *container,
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GList* gtk_container_get_children (GtkContainer *container);
|
||||
|
||||
/* Widget-level methods */
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_container_set_focus_vadjustment (GtkContainer *container,
|
||||
GtkAdjustment *adjustment);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkAdjustment *gtk_container_get_focus_vadjustment (GtkContainer *container);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_container_set_focus_hadjustment (GtkContainer *container,
|
||||
GtkAdjustment *adjustment);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkAdjustment *gtk_container_get_focus_hadjustment (GtkContainer *container);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gtk_container_child_type (GtkContainer *container);
|
||||
|
||||
|
@ -772,15 +772,10 @@ setup_section (GtkEmojiChooser *chooser,
|
||||
const char *first,
|
||||
const char *icon)
|
||||
{
|
||||
GtkAdjustment *adj;
|
||||
|
||||
section->first = first;
|
||||
|
||||
gtk_button_set_icon_name (GTK_BUTTON (section->button), icon);
|
||||
|
||||
adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (chooser->scrolled_window));
|
||||
|
||||
gtk_container_set_focus_vadjustment (GTK_CONTAINER (section->box), adj);
|
||||
gtk_flow_box_disable_move_cursor (GTK_FLOW_BOX (section->box));
|
||||
gtk_flow_box_set_filter_func (GTK_FLOW_BOX (section->box), filter_func, section, NULL);
|
||||
g_signal_connect_swapped (section->button, "clicked", G_CALLBACK (scroll_to_section), section);
|
||||
|
@ -3963,7 +3963,6 @@ gtk_flow_box_set_hadjustment (GtkFlowBox *box,
|
||||
if (priv->hadjustment)
|
||||
g_object_unref (priv->hadjustment);
|
||||
priv->hadjustment = adjustment;
|
||||
gtk_container_set_focus_hadjustment (GTK_CONTAINER (box), adjustment);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3998,7 +3997,6 @@ gtk_flow_box_set_vadjustment (GtkFlowBox *box,
|
||||
if (priv->vadjustment)
|
||||
g_object_unref (priv->vadjustment);
|
||||
priv->vadjustment = adjustment;
|
||||
gtk_container_set_focus_vadjustment (GTK_CONTAINER (box), adjustment);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -3501,10 +3501,6 @@ gtk_scrolled_window_add (GtkContainer *container,
|
||||
else
|
||||
{
|
||||
scrollable_child = gtk_viewport_new (hadj, vadj);
|
||||
gtk_container_set_focus_hadjustment (GTK_CONTAINER (scrollable_child),
|
||||
gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
|
||||
gtk_container_set_focus_vadjustment (GTK_CONTAINER (scrollable_child),
|
||||
gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
|
||||
gtk_container_add (GTK_CONTAINER (scrollable_child), child);
|
||||
priv->auto_added_viewport = TRUE;
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
#include "gtkviewport.h"
|
||||
|
||||
#include "gtkadjustment.h"
|
||||
#include "gtkadjustmentprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtkprivate.h"
|
||||
@ -34,6 +34,7 @@
|
||||
#include "gtkstylecontext.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtktext.h"
|
||||
|
||||
|
||||
/**
|
||||
@ -80,6 +81,9 @@ struct _GtkViewportPrivate
|
||||
* driving the scrollable adjustment values */
|
||||
guint hscroll_policy : 1;
|
||||
guint vscroll_policy : 1;
|
||||
guint scroll_to_focus : 1;
|
||||
|
||||
gulong focus_handler;
|
||||
};
|
||||
|
||||
struct _GtkViewportClass
|
||||
@ -92,7 +96,8 @@ enum {
|
||||
PROP_HADJUSTMENT,
|
||||
PROP_VADJUSTMENT,
|
||||
PROP_HSCROLL_POLICY,
|
||||
PROP_VSCROLL_POLICY
|
||||
PROP_VSCROLL_POLICY,
|
||||
PROP_SCROLL_TO_FOCUS
|
||||
};
|
||||
|
||||
|
||||
@ -115,6 +120,9 @@ static void viewport_set_adjustment (GtkViewport *viewport,
|
||||
GtkOrientation orientation,
|
||||
GtkAdjustment *adjustment);
|
||||
|
||||
static void setup_focus_change_handler (GtkViewport *viewport);
|
||||
static void clear_focus_change_handler (GtkViewport *viewport);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkViewport, gtk_viewport, GTK_TYPE_BIN,
|
||||
G_ADD_PRIVATE (GtkViewport)
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL))
|
||||
@ -228,6 +236,39 @@ gtk_viewport_measure (GtkWidget *widget,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_viewport_dispose (GObject *object)
|
||||
{
|
||||
clear_focus_change_handler (GTK_VIEWPORT (object));
|
||||
|
||||
G_OBJECT_CLASS (gtk_viewport_parent_class)->dispose (object);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_viewport_root (GtkWidget *widget)
|
||||
{
|
||||
GtkViewport *viewport = GTK_VIEWPORT (widget);
|
||||
GtkViewportPrivate *priv = gtk_viewport_get_instance_private (viewport);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_viewport_parent_class)->root (widget);
|
||||
|
||||
if (priv->scroll_to_focus)
|
||||
setup_focus_change_handler (viewport);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_viewport_unroot (GtkWidget *widget)
|
||||
{
|
||||
GtkViewport *viewport = GTK_VIEWPORT (widget);
|
||||
GtkViewportPrivate *priv = gtk_viewport_get_instance_private (viewport);
|
||||
|
||||
if (priv->scroll_to_focus)
|
||||
clear_focus_change_handler (viewport);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_viewport_parent_class)->unroot (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_viewport_class_init (GtkViewportClass *class)
|
||||
{
|
||||
@ -237,12 +278,15 @@ gtk_viewport_class_init (GtkViewportClass *class)
|
||||
gobject_class = G_OBJECT_CLASS (class);
|
||||
widget_class = (GtkWidgetClass*) class;
|
||||
|
||||
gobject_class->dispose = gtk_viewport_dispose;
|
||||
gobject_class->set_property = gtk_viewport_set_property;
|
||||
gobject_class->get_property = gtk_viewport_get_property;
|
||||
|
||||
widget_class->destroy = gtk_viewport_destroy;
|
||||
widget_class->size_allocate = gtk_viewport_size_allocate;
|
||||
widget_class->measure = gtk_viewport_measure;
|
||||
widget_class->root = gtk_viewport_root;
|
||||
widget_class->unroot = gtk_viewport_unroot;
|
||||
|
||||
gtk_widget_class_set_accessible_role (widget_class, ATK_ROLE_VIEWPORT);
|
||||
|
||||
@ -252,6 +296,14 @@ gtk_viewport_class_init (GtkViewportClass *class)
|
||||
g_object_class_override_property (gobject_class, PROP_HSCROLL_POLICY, "hscroll-policy");
|
||||
g_object_class_override_property (gobject_class, PROP_VSCROLL_POLICY, "vscroll-policy");
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_SCROLL_TO_FOCUS,
|
||||
g_param_spec_boolean ("scroll-to-focus",
|
||||
P_("Scroll to focus"),
|
||||
P_("Whether to scroll when the focus changes"),
|
||||
FALSE,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, I_("viewport"));
|
||||
}
|
||||
|
||||
@ -288,6 +340,9 @@ gtk_viewport_set_property (GObject *object,
|
||||
g_object_notify_by_pspec (object, pspec);
|
||||
}
|
||||
break;
|
||||
case PROP_SCROLL_TO_FOCUS:
|
||||
gtk_viewport_set_scroll_to_focus (viewport, g_value_get_boolean (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -317,6 +372,9 @@ gtk_viewport_get_property (GObject *object,
|
||||
case PROP_VSCROLL_POLICY:
|
||||
g_value_set_enum (value, priv->vscroll_policy);
|
||||
break;
|
||||
case PROP_SCROLL_TO_FOCUS:
|
||||
g_value_set_boolean (value, priv->scroll_to_focus);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -464,3 +522,117 @@ gtk_viewport_adjustment_value_changed (GtkAdjustment *adjustment,
|
||||
{
|
||||
gtk_widget_queue_allocate (GTK_WIDGET (data));
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_viewport_get_scroll_to_focus (GtkViewport *viewport)
|
||||
{
|
||||
GtkViewportPrivate *priv = gtk_viewport_get_instance_private (viewport);
|
||||
|
||||
g_return_val_if_fail (GTK_IS_VIEWPORT (viewport), FALSE);
|
||||
|
||||
return priv->scroll_to_focus;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_viewport_set_scroll_to_focus (GtkViewport *viewport,
|
||||
gboolean scroll_to_focus)
|
||||
{
|
||||
GtkViewportPrivate *priv = gtk_viewport_get_instance_private (viewport);
|
||||
|
||||
g_return_if_fail (GTK_IS_VIEWPORT (viewport));
|
||||
|
||||
if (priv->scroll_to_focus == scroll_to_focus)
|
||||
return;
|
||||
|
||||
priv->scroll_to_focus = scroll_to_focus;
|
||||
|
||||
if (gtk_widget_get_root (GTK_WIDGET (viewport)))
|
||||
{
|
||||
if (scroll_to_focus)
|
||||
setup_focus_change_handler (viewport);
|
||||
else
|
||||
clear_focus_change_handler (viewport);
|
||||
}
|
||||
|
||||
g_object_notify (G_OBJECT (viewport), "scroll-to-focus");
|
||||
}
|
||||
|
||||
static void
|
||||
scroll_to_view (GtkAdjustment *adj,
|
||||
double pos,
|
||||
double size)
|
||||
{
|
||||
double value, page_size;
|
||||
|
||||
value = gtk_adjustment_get_value (adj);
|
||||
page_size = gtk_adjustment_get_page_size (adj);
|
||||
|
||||
if (pos < 0)
|
||||
gtk_adjustment_animate_to_value (adj, value + pos);
|
||||
else if (pos + size >= page_size)
|
||||
gtk_adjustment_animate_to_value (adj, value + pos + size - page_size);
|
||||
}
|
||||
|
||||
static void
|
||||
focus_change_handler (GtkWidget *widget)
|
||||
{
|
||||
GtkViewport *viewport = GTK_VIEWPORT (widget);
|
||||
GtkViewportPrivate *priv = gtk_viewport_get_instance_private (viewport);
|
||||
GtkRoot *root;
|
||||
GtkWidget *focus_widget;
|
||||
GtkWidget *child;
|
||||
graphene_rect_t rect;
|
||||
int x, y;
|
||||
|
||||
if ((gtk_widget_get_state_flags (widget) & GTK_STATE_FLAG_FOCUS_WITHIN) == 0)
|
||||
return;
|
||||
|
||||
root = gtk_widget_get_root (widget);
|
||||
focus_widget = gtk_root_get_focus (root);
|
||||
|
||||
if (!focus_widget)
|
||||
return;
|
||||
|
||||
if (GTK_IS_TEXT (focus_widget))
|
||||
focus_widget = gtk_widget_get_parent (focus_widget);
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (viewport));
|
||||
|
||||
if (!gtk_widget_compute_bounds (focus_widget, child, &rect))
|
||||
return;
|
||||
|
||||
gtk_widget_translate_coordinates (child, widget,
|
||||
(int)rect.origin.x,
|
||||
(int)rect.origin.y,
|
||||
&x, &y);
|
||||
|
||||
scroll_to_view (priv->hadjustment, x, rect.size.width);
|
||||
scroll_to_view (priv->vadjustment, y, rect.size.height);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_focus_change_handler (GtkViewport *viewport)
|
||||
{
|
||||
GtkViewportPrivate *priv = gtk_viewport_get_instance_private (viewport);
|
||||
GtkRoot *root;
|
||||
|
||||
root = gtk_widget_get_root (GTK_WIDGET (viewport));
|
||||
|
||||
priv->focus_handler = g_signal_connect_swapped (root, "notify::focus-widget",
|
||||
G_CALLBACK (focus_change_handler), viewport);
|
||||
}
|
||||
|
||||
static void
|
||||
clear_focus_change_handler (GtkViewport *viewport)
|
||||
{
|
||||
GtkViewportPrivate *priv = gtk_viewport_get_instance_private (viewport);
|
||||
GtkRoot *root;
|
||||
|
||||
root = gtk_widget_get_root (GTK_WIDGET (viewport));
|
||||
|
||||
if (priv->focus_handler)
|
||||
{
|
||||
g_signal_handler_disconnect (root, priv->focus_handler);
|
||||
priv->focus_handler = 0;
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,12 @@ GDK_AVAILABLE_IN_ALL
|
||||
GtkWidget* gtk_viewport_new (GtkAdjustment *hadjustment,
|
||||
GtkAdjustment *vadjustment);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_viewport_get_scroll_to_focus (GtkViewport *viewport);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_viewport_set_scroll_to_focus (GtkViewport *viewport,
|
||||
gboolean scroll_to_focus);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
|
@ -90,7 +90,6 @@ struct _GtkInspectorGeneralPrivate
|
||||
GtkWidget *display_rgba;
|
||||
GtkWidget *display_composited;
|
||||
GtkSizeGroup *labels;
|
||||
GtkAdjustment *focus_adjustment;
|
||||
|
||||
GdkDisplay *display;
|
||||
};
|
||||
@ -816,7 +815,6 @@ static gboolean
|
||||
keynav_failed (GtkWidget *widget, GtkDirectionType direction, GtkInspectorGeneral *gen)
|
||||
{
|
||||
GtkWidget *next;
|
||||
gdouble value, lower, upper, page;
|
||||
|
||||
if (direction == GTK_DIR_DOWN && widget == gen->priv->version_box)
|
||||
next = gen->priv->env_box;
|
||||
@ -847,22 +845,6 @@ keynav_failed (GtkWidget *widget, GtkDirectionType direction, GtkInspectorGenera
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
value = gtk_adjustment_get_value (gen->priv->focus_adjustment);
|
||||
lower = gtk_adjustment_get_lower (gen->priv->focus_adjustment);
|
||||
upper = gtk_adjustment_get_upper (gen->priv->focus_adjustment);
|
||||
page = gtk_adjustment_get_page_size (gen->priv->focus_adjustment);
|
||||
|
||||
if (direction == GTK_DIR_UP && value > lower)
|
||||
{
|
||||
gtk_adjustment_set_value (gen->priv->focus_adjustment, lower);
|
||||
return TRUE;
|
||||
}
|
||||
else if (direction == GTK_DIR_DOWN && value < upper - page)
|
||||
{
|
||||
gtk_adjustment_set_value (gen->priv->focus_adjustment, upper - page);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -873,10 +855,6 @@ gtk_inspector_general_constructed (GObject *object)
|
||||
|
||||
G_OBJECT_CLASS (gtk_inspector_general_parent_class)->constructed (object);
|
||||
|
||||
gen->priv->focus_adjustment = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (gen->priv->swin));
|
||||
gtk_container_set_focus_vadjustment (GTK_CONTAINER (gen->priv->box),
|
||||
gen->priv->focus_adjustment);
|
||||
|
||||
g_signal_connect (gen->priv->version_box, "keynav-failed", G_CALLBACK (keynav_failed), gen);
|
||||
g_signal_connect (gen->priv->env_box, "keynav-failed", G_CALLBACK (keynav_failed), gen);
|
||||
g_signal_connect (gen->priv->display_box, "keynav-failed", G_CALLBACK (keynav_failed), gen);
|
||||
|
@ -90,8 +90,6 @@ struct _GtkInspectorVisualPrivate
|
||||
GtkWidget *touchscreen_switch;
|
||||
GtkWidget *software_gl_switch;
|
||||
|
||||
GtkAdjustment *focus_adjustment;
|
||||
|
||||
GtkInspectorOverlay *fps_overlay;
|
||||
GtkInspectorOverlay *updates_overlay;
|
||||
GtkInspectorOverlay *layout_overlay;
|
||||
@ -912,7 +910,6 @@ static gboolean
|
||||
keynav_failed (GtkWidget *widget, GtkDirectionType direction, GtkInspectorVisual *vis)
|
||||
{
|
||||
GtkWidget *next;
|
||||
gdouble value, lower, upper, page;
|
||||
|
||||
if (direction == GTK_DIR_DOWN &&
|
||||
widget == vis->priv->visual_box)
|
||||
@ -935,22 +932,6 @@ keynav_failed (GtkWidget *widget, GtkDirectionType direction, GtkInspectorVisual
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
value = gtk_adjustment_get_value (vis->priv->focus_adjustment);
|
||||
lower = gtk_adjustment_get_lower (vis->priv->focus_adjustment);
|
||||
upper = gtk_adjustment_get_upper (vis->priv->focus_adjustment);
|
||||
page = gtk_adjustment_get_page_size (vis->priv->focus_adjustment);
|
||||
|
||||
if (direction == GTK_DIR_UP && value > lower)
|
||||
{
|
||||
gtk_adjustment_set_value (vis->priv->focus_adjustment, lower);
|
||||
return TRUE;
|
||||
}
|
||||
else if (direction == GTK_DIR_DOWN && value < upper - page)
|
||||
{
|
||||
gtk_adjustment_set_value (vis->priv->focus_adjustment, upper - page);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -1070,10 +1051,6 @@ gtk_inspector_visual_constructed (GObject *object)
|
||||
|
||||
G_OBJECT_CLASS (gtk_inspector_visual_parent_class)->constructed (object);
|
||||
|
||||
vis->priv->focus_adjustment = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (vis->priv->swin));
|
||||
gtk_container_set_focus_vadjustment (GTK_CONTAINER (vis->priv->box),
|
||||
vis->priv->focus_adjustment);
|
||||
|
||||
g_signal_connect (vis->priv->visual_box, "keynav-failed", G_CALLBACK (keynav_failed), vis);
|
||||
g_signal_connect (vis->priv->debug_box, "keynav-failed", G_CALLBACK (keynav_failed), vis);
|
||||
g_signal_connect (vis->priv->misc_box, "keynav-failed", G_CALLBACK (keynav_failed), vis);
|
||||
|
@ -28,6 +28,9 @@
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="swin">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<property name="scroll-to-focus">1</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="box">
|
||||
<property name="orientation">vertical</property>
|
||||
@ -687,6 +690,8 @@
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
<object class="GtkSizeGroup">
|
||||
<widgets>
|
||||
|
@ -94,6 +94,7 @@ gtk_tests = [
|
||||
['testvolumebutton'],
|
||||
['testscrolledwindow'],
|
||||
['testscrolledge'],
|
||||
['testscrolltofocus'],
|
||||
['testcellarea'],
|
||||
['testswitch'],
|
||||
['testnoscreen'],
|
||||
|
@ -1991,10 +1991,7 @@ create_scrolled_windows (GtkWidget *widget)
|
||||
gtk_grid_set_row_spacing (GTK_GRID (grid), 10);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (grid), 10);
|
||||
gtk_container_add (GTK_CONTAINER (scrolled_window), grid);
|
||||
gtk_container_set_focus_hadjustment (GTK_CONTAINER (grid),
|
||||
gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
|
||||
gtk_container_set_focus_vadjustment (GTK_CONTAINER (grid),
|
||||
gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
|
||||
gtk_viewport_set_scroll_to_focus (GTK_VIEWPORT (gtk_widget_get_parent (grid)), TRUE);
|
||||
gtk_widget_show (grid);
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
@ -6074,6 +6071,7 @@ create_main_window (void)
|
||||
|
||||
box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (scrolled_window), box2);
|
||||
gtk_viewport_set_scroll_to_focus (GTK_VIEWPORT (gtk_widget_get_parent (box2)), TRUE);
|
||||
gtk_widget_show (box2);
|
||||
|
||||
for (i = 0; i < nbuttons; i++)
|
||||
|
43
tests/testscrolltofocus.c
Normal file
43
tests/testscrolltofocus.c
Normal file
@ -0,0 +1,43 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
GtkWidget *window, *sw, *viewport, *grid;
|
||||
GtkWidget *entry;
|
||||
int i, j;
|
||||
char *text;
|
||||
|
||||
gtk_init ();
|
||||
|
||||
window = gtk_window_new ();
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (window), sw);
|
||||
viewport = gtk_viewport_new (gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (sw)),
|
||||
gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (sw)));
|
||||
gtk_viewport_set_scroll_to_focus (GTK_VIEWPORT (viewport), TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (sw), viewport);
|
||||
grid = gtk_grid_new ();
|
||||
gtk_widget_set_margin_start (grid, 20);
|
||||
gtk_widget_set_margin_end (grid, 20);
|
||||
gtk_widget_set_margin_top (grid, 20);
|
||||
gtk_widget_set_margin_bottom (grid, 20);
|
||||
gtk_container_add (GTK_CONTAINER (viewport), grid);
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
for (j = 0; j < 20; j++)
|
||||
{
|
||||
entry = gtk_entry_new ();
|
||||
text = g_strdup_printf ("(%d, %d)", i, j);
|
||||
gtk_editable_set_text (GTK_EDITABLE (entry), text);
|
||||
g_free (text);
|
||||
gtk_editable_set_width_chars (GTK_EDITABLE (entry), 6);
|
||||
gtk_grid_attach (GTK_GRID (grid), entry, i, j, 1, 1);
|
||||
}
|
||||
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
|
||||
while (1)
|
||||
g_main_context_iteration (NULL, FALSE);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user