Merge branch 'focus-adjustment' into 'master'

Drop container focus adjustments

See merge request GNOME/gtk!1716
This commit is contained in:
Matthias Clasen 2020-04-18 20:59:50 +00:00
commit 1e7c56db19
17 changed files with 755 additions and 741 deletions

View File

@ -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,

View File

@ -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

View File

@ -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>

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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);

View File

@ -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);

File diff suppressed because it is too large Load Diff

View File

@ -94,6 +94,7 @@ gtk_tests = [
['testvolumebutton'],
['testscrolledwindow'],
['testscrolledge'],
['testscrolltofocus'],
['testcellarea'],
['testswitch'],
['testnoscreen'],

View File

@ -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
View 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;
}