Compare commits

...

13 Commits

Author SHA1 Message Date
Matthias Clasen
fef69881a7 4.12.0 2023-08-05 00:01:26 -04:00
Matthias Clasen
be0eaa64ed Merge branch 'matthiasc/for-main' into 'main'
build: Rename docs build options

See merge request GNOME/gtk!6239
2023-08-05 03:37:05 +00:00
Matthias Clasen
62087b1ab5 README: Some updates 2023-08-04 22:30:13 -04:00
Matthias Clasen
6af55a31d7 build: Rename docs build options
Rename gtk_doc to documentation and update_screenshots
to screenshots. The old names are still accepted.
2023-08-04 22:30:13 -04:00
Matthias Clasen
8e57818a52 Merge branch 'wip/otte/scroll-to' into 'main'
a scroll_to() for list widgets

See merge request GNOME/gtk!6227
2023-08-05 02:20:38 +00:00
Benjamin Otte
a447c439f4 inspector: Use scroll_to() in the object tree search 2023-08-05 03:51:55 +02:00
Benjamin Otte
2120ef38d9 columnview: Implement gtk_column_view_scroll_to()
It's basically the listview version, but with an (optional) column to do
cell-based scrolling/focusing.
2023-08-05 03:51:54 +02:00
Matthias Clasen
6077ea4f48 Add gtk_grid_view_scroll_to
This does the same as gtk_list_view_scroll_to, just
for a grid view.
2023-08-05 03:51:53 +02:00
Benjamin Otte
c278c78378 gtk-demo: Make arrowing in suggestionentry scroll the dropdown 2023-08-05 03:51:53 +02:00
Benjamin Otte
b64dc75e3a listview: Implement gtk_list_view_scroll_to()
This adds a flags enum so we can also do select/focus at the same time.

It's implemented in GtkListBase, so adding support forgridview should be
easy.
2023-08-05 03:51:53 +02:00
Benjamin Otte
447c07bf5e viewport: Use gtk_viewport_scroll_to() for focus scrolling 2023-08-05 03:51:51 +02:00
Benjamin Otte
2a5f1dc6c7 viewport: Add gtk_viewport_scroll_to()
First implementation of GtkScrollInfo
2023-08-05 03:51:50 +02:00
Benjamin Otte
105be5a457 gtk: Add GtkScrollInfo
This struct carries information about scrolling a scrollable, so that
individual scrollables can share this struct for their scrolling APIs.

For now, there's not much information here, we're still trying to cook
up an API that works well.
2023-08-05 03:51:50 +02:00
33 changed files with 847 additions and 119 deletions

View File

@@ -418,10 +418,11 @@ reference:
--buildtype=release
--force-fallback-for=gdk-pixbuf,pango
-Dintrospection=enabled
-Ddocumentation=true
-Dgtk_doc=true
-Dgdk-pixbuf:gtk_doc=true
-Dpango:gtk_doc=true
-Ddemos=false
-Dbuild-demos=false
-Dbuild-examples=false
-Dbuild-tests=false
-Dbuild-testsuite=false

131
NEWS
View File

@@ -1,6 +1,135 @@
Overview of Changes in 4.11.5, xx-xx-xxxx
Overview of Changes in 4.12.0, 05-08-2023
=========================================
* List widgets:
- Add scroll_to APIs
* GtkFileLauncher:
- Add an always-ask property
* GtkTextView:
- Make backspace behavior match GtkEntry
* gsk:
- Fix handling of luminance in mask nodes
* Text rendering:
- Automate the setting of gtk-hint-font-metrics from the
scale factor. This improves font rendering in flatpaks
* Wayland:
- Fix behavior of stylus buttons
- Support suspended window state
* Vulkan:
- Many improvements
* Tools:
- Add gtk4-rendernode-tool
* Debugging:
- Drop the GTK_DEBUG_TOUCHSCREEN flag
* Build:
- Some build options have been renamed:
gtk_doc -> documentation
update_screenshots -> screenshots
The old names still work
* Translation updates:
Georgian
Greek
Hebrew
Persian
Vietnamese
* Contributors:
Aleksandr Melman
Alexander Mikhaylenko
Alexander Shopov
Alexandre Franke
Alice Mikhaylenko
António Fernandes
Arjan Molenaar
Asier Sarasua Garmendia
Balázs Meskó
Balázs Úr
Barnabás Pőcze
Bart Jacobs
Benjamin Otte
Bilal Elmoussaoui
Boyuan Yang
Bruce Cowan
Calvin Walton
Cam Cook
Chris Mayo
Christian Hergert
Christopher Davis
Chun-wei Fan
Corey Berla
Danial Behzadi
Daniel Boles
Daniel Rusek
Efstathios Iosifidis
Ekaterine Papava
Emin Tufan Çetin
Emmanuele Bassi
Erik Schilling
Fabio Tomat
FeRD (Frank Dana)
Fina Wilke
FineFindus
Fran Dieguez
G.Willems
Georges Basile Stavracas Neto
Guillaume Bernard
Hugo Carvalho
Ivan Molodetskikh
Jason Francis
Jonas Ådahl
Jordan Petridis
Jordi Mas
José Expósito
José Roberto de Souza
Khalid Abu Shawarib
Kévin Commaille
Leônidas Araújo
Luca Bacci
Ludovico de Nittis
Lukáš Tyrychtr
Marc-André Lureau
Marco Trevisan (Treviño)
Matt Turner
Matthias Clasen
Maximiliano Sandoval R
Michael Catanzaro
Michel Dänzer
Mohammed Sadiq
Nathan Follens
Nelson Benítez León
Ngọc Quân Trần
Niels De Graef
Olivier Crête
Patrick Griffis
Piotr Drąg
Sabri Ünal
Sebastian Keller
Sophie Herold
Sébastien Le Roux
Takao Fujiwara
Thomas Lange
Yiğit Burak
Yosef Or Boczko
Yuri Chornoivan
Zander Brown
al_SeveR
dgsasha
sumibi-yakitori
tszymanski
velsinki
Алексей Шилин
Арсений Засыпкин
Overview of Changes in 4.11.4, 03-07-2023
=========================================

View File

@@ -67,6 +67,13 @@ building for:
- [Graphene](https://github.com/ebassi/graphene)
- [Xkb-common](https://github.com/xkbcommon/libxkbcommon)
If you are building the Wayland backend, you will also need:
- Wayland-client
- Wayland-protocols
- Wayland-cursor
- Wayland-EGL
If you are building the X11 backend, you will also need:
- Xlib, and the following X extensions:
@@ -79,32 +86,24 @@ If you are building the X11 backend, you will also need:
- xdamage
- xcomposite
If you are building the Wayland backend, you will also need:
- Wayland-client
- Wayland-protocols
- Wayland-cursor
- Wayland-EGL
Once you have all the necessary dependencies, you can build GTK by using
Meson:
```sh
$ meson _build .
$ cd _build
$ ninja
$ meson setup _build
$ meson compile -C_build
```
You can run the test suite using:
```sh
$ meson test
$ meson test -C_build
```
And, finally, you can install GTK using:
```
$ sudo ninja install
$ sudo meson install -C_build
```
Complete information about installing GTK and related libraries

View File

@@ -801,7 +801,7 @@ suggestion_entry_key_pressed (GtkEventControllerKey *controller,
selected = matches - 1;
}
gtk_single_selection_set_selected (self->selection, selected);
gtk_list_view_scroll_to (GTK_LIST_VIEW (self->list), selected, GTK_LIST_SCROLL_SELECT, NULL);
return TRUE;
}

View File

@@ -1,7 +1,7 @@
expand_content_md_files = [
]
if get_option('gtk_doc')
if get_option('documentation')
gdk4_toml = configure_file(
input: 'gdk4.toml.in',
output: 'gdk4.toml',

View File

@@ -1,4 +1,4 @@
if get_option('gtk_doc')
if get_option('documentation')
gsk4_toml = configure_file(
input: 'gsk4.toml.in',
output: 'gsk4.toml',

View File

@@ -268,7 +268,7 @@ support in the file chooser.
This option controls whether GTK should use colord for color
calibration support in the cups print backend.
### `gtk_doc`, `man-pages` and `update_screenshots`
### `documentation`, `man-pages` and `screenshots`
The *gi-docgen* package is used to generate the reference documentation
included with GTK. By default support for *gi-docgen* is disabled

View File

@@ -78,7 +78,7 @@ ui_files = [
gtk_builder_tool = find_program('gtk4-builder-tool')
if get_option('update_screenshots')
if get_option('screenshots')
foreach ui_file: ui_files
png_file = ui_file.replace('.ui', '.png')
gtk_images += custom_target('@0@ from @1@'.format(png_file, ui_file),

View File

@@ -32,7 +32,7 @@ gtk_images = []
subdir('images')
if get_option('gtk_doc')
if get_option('documentation')
gtk4_toml = configure_file(
input: 'gtk4.toml.in',
output: 'gtk4.toml',

View File

@@ -1,7 +1,7 @@
toml_conf = configuration_data()
toml_conf.set('version', meson.project_version())
gidocgen = find_program('gi-docgen', required: get_option('gtk_doc'), native: true)
gidocgen = find_program('gi-docgen', required: get_option('documentation'), native: true)
gidocgen_common_args = [
'--quiet',
@@ -14,7 +14,7 @@ endif
docs_dir = gtk_datadir / 'doc'
if get_option('gtk_doc') and not build_gir
if get_option('documentation') and not build_gir
error('API reference requires introspection.')
endif

View File

@@ -223,6 +223,7 @@
#include <gtk/gtkscalebutton.h>
#include <gtk/gtkscrollable.h>
#include <gtk/gtkscrollbar.h>
#include <gtk/gtkscrollinfo.h>
#include <gtk/gtkscrolledwindow.h>
#include <gtk/gtksearchbar.h>
#include <gtk/gtksearchentry.h>

View File

@@ -35,6 +35,7 @@
#include "gtkgesturedrag.h"
#include "gtklistviewprivate.h"
#include "gtkscrollable.h"
#include "gtkscrollinfoprivate.h"
#include "gtksizerequest.h"
#include "gtktypebuiltins.h"
#include "gtkwidgetprivate.h"
@@ -1722,7 +1723,7 @@ gtk_column_view_remove_column (GtkColumnView *self,
else
item = NULL;
gtk_column_view_set_focus_column (self, item);
gtk_column_view_set_focus_column (self, item, TRUE);
}
}
@@ -1782,23 +1783,27 @@ gtk_column_view_insert_column (GtkColumnView *self,
static void
gtk_column_view_scroll_to_column (GtkColumnView *self,
GtkColumnViewColumn *column)
GtkColumnViewColumn *column,
GtkScrollInfo *scroll_info)
{
int col_x, col_width, adj_x, adj_width;
int col_x, col_width, new_value;
gtk_column_view_column_get_header_allocation (column, &col_x, &col_width);
adj_x = gtk_adjustment_get_value (self->hadjustment);
adj_width = gtk_adjustment_get_page_size (self->hadjustment);
if (col_x < adj_x)
gtk_adjustment_set_value (self->hadjustment, col_x);
else if (col_x + col_width > adj_x + adj_width)
gtk_adjustment_set_value (self->hadjustment, adj_x + adj_width - col_width);
new_value = gtk_scroll_info_compute_for_orientation (scroll_info,
GTK_ORIENTATION_HORIZONTAL,
col_x,
col_width,
gtk_adjustment_get_value (self->hadjustment),
gtk_adjustment_get_page_size (self->hadjustment));
gtk_adjustment_set_value (self->hadjustment, new_value);
}
void
gtk_column_view_set_focus_column (GtkColumnView *self,
GtkColumnViewColumn *column)
GtkColumnViewColumn *column,
gboolean scroll)
{
g_assert (column == NULL || gtk_column_view_column_get_column_view (column) == self);
@@ -1807,8 +1812,8 @@ gtk_column_view_set_focus_column (GtkColumnView *self,
self->focus_column = column;
if (column)
gtk_column_view_scroll_to_column (self, column);
if (column && scroll)
gtk_column_view_scroll_to_column (self, column, NULL);
}
GtkColumnViewColumn *
@@ -2174,3 +2179,44 @@ gtk_column_view_set_header_factory (GtkColumnView *self,
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_HEADER_FACTORY]);
}
/**
* gtk_column_view_scroll_to:
* @self: The columnview to scroll in
* @pos: position of the item
* @column: (nullable) (transfer none): The column to scroll to
* or %NULL to not scroll columns.
* @flags: actions to perform
* @scroll: (nullable) (transfer full): details of how to perform
* the scroll operation or %NULL to scroll into view
*
* Scroll to the row at the given position - or cell if a column is
* given - and performs the actions specified in @flags.
*
* This function works no matter if the listview is shown or focused.
* If it isn't, then the changes will take effect once that happens.
*
* Since: 4.12
*/
void
gtk_column_view_scroll_to (GtkColumnView *self,
guint pos,
GtkColumnViewColumn *column,
GtkListScrollFlags flags,
GtkScrollInfo *scroll)
{
g_return_if_fail (GTK_IS_COLUMN_VIEW (self));
g_return_if_fail (column == NULL || GTK_IS_COLUMN_VIEW_COLUMN (column));
if (column)
{
g_return_if_fail (gtk_column_view_column_get_column_view (column) == self);
}
if (column && (flags & GTK_LIST_SCROLL_FOCUS))
gtk_column_view_set_focus_column (self, column, FALSE);
gtk_list_view_scroll_to (self->listview, pos, flags, scroll);
if (column)
gtk_column_view_scroll_to_column (self, column, scroll);
}

View File

@@ -122,7 +122,6 @@ GDK_AVAILABLE_IN_4_12
GtkListItemFactory *
gtk_column_view_get_row_factory (GtkColumnView *self);
GDK_AVAILABLE_IN_4_12
void gtk_column_view_set_header_factory (GtkColumnView *self,
GtkListItemFactory *factory);
@@ -130,5 +129,12 @@ GDK_AVAILABLE_IN_4_12
GtkListItemFactory *
gtk_column_view_get_header_factory (GtkColumnView *self);
GDK_AVAILABLE_IN_4_12
void gtk_column_view_scroll_to (GtkColumnView *self,
guint pos,
GtkColumnViewColumn *column,
GtkListScrollFlags flags,
GtkScrollInfo *scroll);
G_END_DECLS

View File

@@ -40,6 +40,7 @@ void gtk_column_view_distribute_width (GtkColumnView
GtkRequestedSize *sizes);
void gtk_column_view_set_focus_column (GtkColumnView *self,
GtkColumnViewColumn *focus_column);
GtkColumnViewColumn *focus_column,
gboolean scroll);
GtkColumnViewColumn * gtk_column_view_get_focus_column (GtkColumnView *self);

View File

@@ -288,7 +288,7 @@ gtk_column_view_row_widget_focus (GtkWidget *widget,
{
if (gtk_widget_grab_focus_self (widget))
{
gtk_column_view_set_focus_column (view, NULL);
gtk_column_view_set_focus_column (view, NULL, FALSE);
return TRUE;
}
}
@@ -323,7 +323,7 @@ gtk_column_view_row_widget_grab_focus (GtkWidget *widget)
if (gtk_widget_grab_focus_self (widget))
{
gtk_column_view_set_focus_column (view, NULL);
gtk_column_view_set_focus_column (view, NULL, FALSE);
return TRUE;
}
@@ -354,7 +354,8 @@ gtk_column_view_row_widget_set_focus_child (GtkWidget *widget,
if (child)
{
gtk_column_view_set_focus_column (gtk_column_view_row_widget_get_column_view (self),
gtk_column_view_row_child_get_column (child));
gtk_column_view_row_child_get_column (child),
TRUE);
}
}

View File

@@ -295,6 +295,24 @@ typedef enum
GTK_LIST_TAB_CELL
} GtkListTabBehavior;
/**
* GtkListScrollFlags:
* @GTK_LIST_SCROLL_NONE: Don't do anything extra
* @GTK_LIST_SCROLL_FOCUS: Focus the target item
* @GTK_LIST_SCROLL_SELECT: Select the target item and
* unselect all other items.
*
* List of actions to perform when scrolling to items in
* a list widget.
*
* Since: 4.12
*/
typedef enum {
GTK_LIST_SCROLL_NONE = 0,
GTK_LIST_SCROLL_FOCUS = 1 << 0,
GTK_LIST_SCROLL_SELECT = 1 << 1
} GtkListScrollFlags;
/**
* GtkMessageType:
* @GTK_MESSAGE_INFO: Informational message

View File

@@ -1564,3 +1564,29 @@ gtk_grid_view_get_tab_behavior (GtkGridView *self)
return gtk_list_base_get_tab_behavior (GTK_LIST_BASE (self));
}
/**
* gtk_grid_view_scroll_to:
* @self: The gridview to scroll in
* @pos: position of the item
* @flags: actions to perform
* @scroll: (nullable) (transfer full): details of how to perform
* the scroll operation or %NULL to scroll into view
*
* Scrolls to the item at the given position and performs the actions
* specified in @flags.
*
* This function works no matter if the gridview is shown or focused.
* If it isn't, then the changes will take effect once that happens.
*
* Since: 4.12
*/
void
gtk_grid_view_scroll_to (GtkGridView *self,
guint pos,
GtkListScrollFlags flags,
GtkScrollInfo *scroll)
{
g_return_if_fail (GTK_IS_GRID_VIEW (self));
gtk_list_base_scroll_to (GTK_LIST_BASE (self), pos, flags, scroll);
}

View File

@@ -85,6 +85,13 @@ void gtk_grid_view_set_single_click_activate (GtkGridView
GDK_AVAILABLE_IN_ALL
gboolean gtk_grid_view_get_single_click_activate (GtkGridView *self);
GDK_AVAILABLE_IN_4_12
void gtk_grid_view_scroll_to (GtkGridView *self,
guint pos,
GtkListScrollFlags flags,
GtkScrollInfo *scroll);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkGridView, g_object_unref)
G_END_DECLS

View File

@@ -34,6 +34,7 @@
#include "gtkmultiselection.h"
#include "gtkorientable.h"
#include "gtkscrollable.h"
#include "gtkscrollinfoprivate.h"
#include "gtksingleselection.h"
#include "gtksnapshot.h"
#include "gtktypebuiltins.h"
@@ -528,7 +529,7 @@ gtk_list_base_get_n_items (GtkListBase *self)
return g_list_model_get_n_items (G_LIST_MODEL (priv->model));
}
guint
static guint
gtk_list_base_get_focus_position (GtkListBase *self)
{
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
@@ -818,23 +819,19 @@ gtk_list_base_set_property (GObject *object,
}
static void
gtk_list_base_compute_scroll_align (GtkListBase *self,
GtkOrientation orientation,
int cell_start,
int cell_end,
gtk_list_base_compute_scroll_align (int cell_start,
int cell_size,
int visible_start,
int visible_size,
double current_align,
GtkPackType current_side,
double *new_align,
GtkPackType *new_side)
{
int visible_start, visible_size, visible_end;
int cell_size;
int cell_end, visible_end;
gtk_list_base_get_adjustment_values (GTK_LIST_BASE (self),
orientation,
&visible_start, NULL, &visible_size);
visible_end = visible_start + visible_size;
cell_size = cell_end - cell_start;
cell_end = cell_start + cell_size;
if (cell_size <= visible_size)
{
@@ -878,26 +875,38 @@ gtk_list_base_compute_scroll_align (GtkListBase *self,
}
static void
gtk_list_base_scroll_to_item (GtkListBase *self,
guint pos)
gtk_list_base_scroll_to_item (GtkListBase *self,
guint pos,
GtkScrollInfo *scroll)
{
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
double align_along, align_across;
GtkPackType side_along, side_across;
GdkRectangle area;
GdkRectangle area, viewport;
int x, y;
if (!gtk_list_base_get_allocation (GTK_LIST_BASE (self), pos, &area))
return;
{
g_clear_pointer (&scroll, gtk_scroll_info_unref);
return;
}
gtk_list_base_compute_scroll_align (self,
gtk_list_base_get_orientation (GTK_LIST_BASE (self)),
area.y, area.y + area.height,
gtk_list_base_get_adjustment_values (GTK_LIST_BASE (self),
gtk_list_base_get_orientation (GTK_LIST_BASE (self)),
&viewport.y, NULL, &viewport.height);
gtk_list_base_get_adjustment_values (GTK_LIST_BASE (self),
gtk_list_base_get_opposite_orientation (GTK_LIST_BASE (self)),
&viewport.x, NULL, &viewport.width);
gtk_scroll_info_compute_scroll (scroll, &area, &viewport, &x, &y);
gtk_list_base_compute_scroll_align (area.y, area.height,
y, viewport.height,
priv->anchor_align_along, priv->anchor_side_along,
&align_along, &side_along);
gtk_list_base_compute_scroll_align (self,
gtk_list_base_get_opposite_orientation (GTK_LIST_BASE (self)),
area.x, area.x + area.width,
gtk_list_base_compute_scroll_align (area.x, area.width,
x, viewport.width,
priv->anchor_align_across, priv->anchor_side_across,
&align_across, &side_across);
@@ -905,6 +914,8 @@ gtk_list_base_scroll_to_item (GtkListBase *self,
pos,
align_across, side_across,
align_along, side_along);
g_clear_pointer (&scroll, gtk_scroll_info_unref);
}
static void
@@ -920,7 +931,7 @@ gtk_list_base_scroll_to_item_action (GtkWidget *widget,
g_variant_get (parameter, "u", &pos);
gtk_list_base_scroll_to_item (self, pos);
gtk_list_base_scroll_to_item (self, pos, NULL);
}
static void
@@ -940,7 +951,7 @@ gtk_list_base_set_focus_child (GtkWidget *widget,
if (pos != gtk_list_item_tracker_get_position (priv->item_manager, priv->focus))
{
gtk_list_base_scroll_to_item (self, pos);
gtk_list_base_scroll_to_item (self, pos, NULL);
gtk_list_item_tracker_set_position (priv->item_manager,
priv->focus,
pos,
@@ -2320,3 +2331,42 @@ gtk_list_base_get_tab_behavior (GtkListBase *self)
return priv->tab_behavior;
}
void
gtk_list_base_scroll_to (GtkListBase *self,
guint pos,
GtkListScrollFlags flags,
GtkScrollInfo *scroll)
{
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
if (flags & GTK_LIST_SCROLL_FOCUS)
{
GtkListItemTracker *old_focus;
/* We need a tracker here to keep the focus widget around,
* because we need to update the focus tracker before grabbing
* focus, because otherwise gtk_list_base_set_focus_child() will
* scroll to the item, and we want to avoid that.
*/
old_focus = gtk_list_item_tracker_new (priv->item_manager);
gtk_list_item_tracker_set_position (priv->item_manager, old_focus, gtk_list_base_get_focus_position (self), 0, 0);
gtk_list_item_tracker_set_position (priv->item_manager, priv->focus, pos, 0, 0);
/* XXX: Is this the proper check? */
if (gtk_widget_get_state_flags (GTK_WIDGET (self)) & GTK_STATE_FLAG_FOCUS_WITHIN)
{
GtkListTile *tile = gtk_list_item_manager_get_nth (priv->item_manager, pos, NULL);
gtk_widget_grab_focus (tile->widget);
}
gtk_list_item_tracker_free (priv->item_manager, old_focus);
}
if (flags & GTK_LIST_SCROLL_SELECT)
gtk_list_base_select_item (self, pos, FALSE, FALSE);
gtk_list_base_scroll_to_item (self, pos, scroll);
}

View File

@@ -62,7 +62,6 @@ struct _GtkListBaseClass
GtkOrientation gtk_list_base_get_orientation (GtkListBase *self);
#define gtk_list_base_get_opposite_orientation(self) OPPOSITE_ORIENTATION(gtk_list_base_get_orientation(self))
guint gtk_list_base_get_focus_position (GtkListBase *self);
void gtk_list_base_get_border_spacing (GtkListBase *self,
int *xspacing,
int *yspacing);
@@ -95,3 +94,7 @@ GtkListTabBehavior gtk_list_base_get_tab_behavior (GtkListBase
void gtk_list_base_allocate (GtkListBase *self);
void gtk_list_base_scroll_to (GtkListBase *self,
guint pos,
GtkListScrollFlags flags,
GtkScrollInfo *scroll);

View File

@@ -1349,3 +1349,30 @@ gtk_list_view_get_tab_behavior (GtkListView *self)
return gtk_list_base_get_tab_behavior (GTK_LIST_BASE (self));
}
/**
* gtk_list_view_scroll_to:
* @self: The listview to scroll in
* @pos: position of the item
* @flags: actions to perform
* @scroll: (nullable) (transfer full): details of how to perform
* the scroll operation or %NULL to scroll into view
*
* Scrolls to the item at the given position and performs the actions
* specified in @flags.
*
* This function works no matter if the listview is shown or focused.
* If it isn't, then the changes will take effect once that happens.
*
* Since: 4.12
*/
void
gtk_list_view_scroll_to (GtkListView *self,
guint pos,
GtkListScrollFlags flags,
GtkScrollInfo *scroll)
{
g_return_if_fail (GTK_IS_LIST_VIEW (self));
gtk_list_base_scroll_to (GTK_LIST_BASE (self), pos, flags, scroll);
}

View File

@@ -89,6 +89,11 @@ GDK_AVAILABLE_IN_4_12
GtkListTabBehavior
gtk_list_view_get_tab_behavior (GtkListView *self);
GDK_AVAILABLE_IN_4_12
void gtk_list_view_scroll_to (GtkListView *self,
guint pos,
GtkListScrollFlags flags,
GtkScrollInfo *scroll);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkListView, g_object_unref)

249
gtk/gtkscrollinfo.c Normal file
View File

@@ -0,0 +1,249 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2023 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* GtkScrollInfo:
*
* The `GtkScrollInfo` can be used to provide more accurate data on how a scroll
* operation should be performed.
*
* Scrolling functions usually allow passing a %NULL scroll info which will cause
* the default values to be used and just scroll the element into view.
*
* Since: 4.12
*/
#include "config.h"
#include "gtkscrollinfoprivate.h"
#include <math.h>
struct _GtkScrollInfo
{
guint ref_count;
gboolean enabled[2]; /* directions */
};
static GtkScrollInfo default_scroll_info = {
1,
{ TRUE, TRUE }
};
G_DEFINE_BOXED_TYPE (GtkScrollInfo, gtk_scroll_info,
gtk_scroll_info_ref,
gtk_scroll_info_unref)
/**
* gtk_scroll_info_new:
*
* Creates a new scroll info for scrolling an element into view.
*
* Returns: A new scroll info
*
* Since: 4.12
**/
GtkScrollInfo *
gtk_scroll_info_new (void)
{
GtkScrollInfo *self;
self = g_new0 (GtkScrollInfo, 1);
self->ref_count = 1;
self->enabled[GTK_ORIENTATION_HORIZONTAL] = TRUE;
self->enabled[GTK_ORIENTATION_VERTICAL] = TRUE;
return self;
}
/**
* gtk_scroll_info_ref:
* @self: a `GtkScrollInfo`
*
* Increases the reference count of a `GtkScrollInfo` by one.
*
* Returns: the passed in `GtkScrollInfo`.
*
* Since: 4.12
*/
GtkScrollInfo *
gtk_scroll_info_ref (GtkScrollInfo *self)
{
g_return_val_if_fail (self != NULL, NULL);
self->ref_count++;
return self;
}
/**
* gtk_scroll_info_unref:
* @self: a `GtkScrollInfo`
*
* Decreases the reference count of a `GtkScrollInfo` by one.
*
* If the resulting reference count is zero, frees the self.
*
* Since: 4.12
*/
void
gtk_scroll_info_unref (GtkScrollInfo *self)
{
g_return_if_fail (self != NULL);
g_return_if_fail (self->ref_count > 0);
self->ref_count--;
if (self->ref_count > 0)
return;
g_free (self);
}
/**
* gtk_scroll_info_set_enable_horizontal:
* @self: a `GtkScrollInfo`
* @horizontal: if scrolling in the horizontal direction
* should happen
*
* Turns horizontal scrolling on or off.
*
* Since: 4.12
**/
void
gtk_scroll_info_set_enable_horizontal (GtkScrollInfo *self,
gboolean horizontal)
{
g_return_if_fail (self != NULL);
self->enabled[GTK_ORIENTATION_HORIZONTAL] = horizontal;
}
/**
* gtk_scroll_info_get_enable_horizontal:
* @self: a `GtkScrollInfo`
*
* Checks if horizontal scrolling is enabled.
*
* Returns: %TRUE if horizontal scrolling is enabled.
*
* Since: 4.12
**/
gboolean
gtk_scroll_info_get_enable_horizontal (GtkScrollInfo *self)
{
g_return_val_if_fail (self != NULL, FALSE);
return self->enabled[GTK_ORIENTATION_HORIZONTAL];
}
/**
* gtk_scroll_info_set_enable_vertical:
* @self: a `GtkScrollInfo`
* @vertical: if scrolling in the vertical direction
* should happen
*
* Turns vertical scrolling on or off.
*
* Since: 4.12
**/
void
gtk_scroll_info_set_enable_vertical (GtkScrollInfo *self,
gboolean vertical)
{
g_return_if_fail (self != NULL);
self->enabled[GTK_ORIENTATION_VERTICAL] = vertical;
}
/**
* gtk_scroll_info_get_enable_vertical:
* @self: a `GtkScrollInfo`
*
* Checks if vertical scrolling is enabled.
*
* Returns: %TRUE if vertical scrolling is enabled.
*
* Since: 4.12
**/
gboolean
gtk_scroll_info_get_enable_vertical (GtkScrollInfo *self)
{
g_return_val_if_fail (self != NULL, FALSE);
return self->enabled[GTK_ORIENTATION_VERTICAL];
}
int
gtk_scroll_info_compute_for_orientation (GtkScrollInfo *self,
GtkOrientation orientation,
int area_origin,
int area_size,
int viewport_origin,
int viewport_size)
{
float origin, size;
int delta;
if (self == NULL)
self = &default_scroll_info;
if (!self->enabled[orientation])
return viewport_origin;
origin = viewport_origin;
size = viewport_size;
if (area_origin <= origin)
delta = area_origin - ceil (origin);
else if (area_origin + area_size > origin + size)
delta = area_origin + area_size - floor (origin + size);
else
delta = 0;
return viewport_origin + delta;
}
/*<private>
* gtk_scroll_info_compute_scroll:
* @self: a `GtkScrollInfo`
* @area: area to scroll
* @viewport: viewport area to scroll into
* @out_x: (out): x coordinate to scroll viewport to
* @out_y: (out): y coordinate to scroll viewport to
*
* Computes The new x/y coordinate to move the viewport to
* according to this scroll info.
**/
void
gtk_scroll_info_compute_scroll (GtkScrollInfo *self,
const cairo_rectangle_int_t *area,
const cairo_rectangle_int_t *viewport,
int *out_x,
int *out_y)
{
*out_x = gtk_scroll_info_compute_for_orientation (self,
GTK_ORIENTATION_HORIZONTAL,
area->x, area->width,
viewport->x, viewport->width);
*out_y = gtk_scroll_info_compute_for_orientation (self,
GTK_ORIENTATION_VERTICAL,
area->y, area->height,
viewport->y, viewport->height);
}

61
gtk/gtkscrollinfo.h Normal file
View File

@@ -0,0 +1,61 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2023 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gdk/gdk.h>
#include <gtk/gtkenums.h>
#include <gtk/gtktypes.h>
#include <graphene.h>
G_BEGIN_DECLS
#define GTK_TYPE_SCROLL_INFO (gtk_scroll_info_get_type ())
GDK_AVAILABLE_IN_4_12
GType gtk_scroll_info_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_4_12
GtkScrollInfo * gtk_scroll_info_new (void);
GDK_AVAILABLE_IN_4_12
GtkScrollInfo * gtk_scroll_info_ref (GtkScrollInfo *self);
GDK_AVAILABLE_IN_4_12
void gtk_scroll_info_unref (GtkScrollInfo *self);
GDK_AVAILABLE_IN_4_12
void gtk_scroll_info_set_enable_horizontal (GtkScrollInfo *self,
gboolean horizontal);
GDK_AVAILABLE_IN_4_12
gboolean gtk_scroll_info_get_enable_horizontal (GtkScrollInfo *self);
GDK_AVAILABLE_IN_4_12
void gtk_scroll_info_set_enable_vertical (GtkScrollInfo *self,
gboolean vertical);
GDK_AVAILABLE_IN_4_12
gboolean gtk_scroll_info_get_enable_vertical (GtkScrollInfo *self);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkScrollInfo, gtk_scroll_info_unref)
G_END_DECLS

View File

@@ -0,0 +1,42 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2023 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtkscrollinfo.h>
G_BEGIN_DECLS
void gtk_scroll_info_compute_scroll (GtkScrollInfo *self,
const cairo_rectangle_int_t *area,
const cairo_rectangle_int_t *viewport,
int *out_x,
int *out_y);
int gtk_scroll_info_compute_for_orientation (GtkScrollInfo *self,
GtkOrientation orientation,
int area_origin,
int area_size,
int viewport_origin,
int viewport_size);
G_END_DECLS

View File

@@ -46,6 +46,7 @@ typedef struct _GtkListItemFactory GtkListItemFactory;
typedef struct _GtkNative GtkNative;
typedef struct _GtkRequisition GtkRequisition;
typedef struct _GtkRoot GtkRoot;
typedef struct _GtkScrollInfo GtkScrollInfo;
typedef struct _GtkSettings GtkSettings;
typedef struct _GtkShortcut GtkShortcut;
typedef struct _GtkShortcutAction GtkShortcutAction;

View File

@@ -30,11 +30,13 @@
#include "gtkmarshalers.h"
#include "gtkprivate.h"
#include "gtkscrollable.h"
#include "gtkscrollinfoprivate.h"
#include "gtktypebuiltins.h"
#include "gtkwidgetprivate.h"
#include "gtkbuildable.h"
#include "gtktext.h"
#include <math.h>
/**
* GtkViewport:
@@ -602,30 +604,12 @@ gtk_viewport_set_scroll_to_focus (GtkViewport *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);
GtkRoot *root;
GtkWidget *focus_widget;
graphene_rect_t rect;
graphene_point_t p;
if ((gtk_widget_get_state_flags (widget) & GTK_STATE_FLAG_FOCUS_WITHIN) == 0)
return;
@@ -639,16 +623,7 @@ focus_change_handler (GtkWidget *widget)
if (GTK_IS_TEXT (focus_widget))
focus_widget = gtk_widget_get_parent (focus_widget);
if (!gtk_widget_compute_bounds (focus_widget, viewport->child, &rect))
return;
if (!gtk_widget_compute_point (viewport->child, widget,
&GRAPHENE_POINT_INIT (rect.origin.x, rect.origin.y),
&p))
return;
scroll_to_view (viewport->adjustment[GTK_ORIENTATION_HORIZONTAL], p.x, rect.size.width);
scroll_to_view (viewport->adjustment[GTK_ORIENTATION_VERTICAL], p.y, rect.size.height);
gtk_viewport_scroll_to (viewport, focus_widget, NULL);
}
static void
@@ -720,3 +695,54 @@ gtk_viewport_get_child (GtkViewport *viewport)
return viewport->child;
}
/**
* gtk_viewport_scroll_to:
* @viewport: a `GtkViewport`
* @descendant: a descendant widget of the viewport
* @scroll: (nullable) (transfer full): details of how to perform
* the scroll operation or NULL to scroll into view
*
* Scrolls a descendant of the viewport into view.
*
* The viewport and the descendant must be visible and mapped for
* this function to work, otherwise no scrolling will be performed.
*
* Since: 4.12
**/
void
gtk_viewport_scroll_to (GtkViewport *viewport,
GtkWidget *descendant,
GtkScrollInfo *scroll)
{
graphene_rect_t bounds;
int x, y;
double adj_x, adj_y;
g_return_if_fail (GTK_IS_VIEWPORT (viewport));
g_return_if_fail (GTK_IS_WIDGET (descendant));
if (!gtk_widget_compute_bounds (descendant, GTK_WIDGET (viewport), &bounds))
return;
adj_x = gtk_adjustment_get_value (viewport->adjustment[GTK_ORIENTATION_HORIZONTAL]);
adj_y = gtk_adjustment_get_value (viewport->adjustment[GTK_ORIENTATION_VERTICAL]);
gtk_scroll_info_compute_scroll (scroll,
&(GdkRectangle) {
floor (bounds.origin.x + adj_x),
floor (bounds.origin.y + adj_y),
ceil (bounds.origin.x + bounds.size.width) - floor (bounds.origin.x),
ceil (bounds.origin.y + bounds.size.height) - floor (bounds.origin.y)
},
&(GdkRectangle) {
adj_x,
adj_y,
gtk_widget_get_width (GTK_WIDGET (viewport)),
gtk_widget_get_height (GTK_WIDGET (viewport))
},
&x, &y);
gtk_adjustment_animate_to_value (viewport->adjustment[GTK_ORIENTATION_HORIZONTAL], x);
gtk_adjustment_animate_to_value (viewport->adjustment[GTK_ORIENTATION_VERTICAL], y);
}

View File

@@ -61,6 +61,11 @@ void gtk_viewport_set_child (GtkViewport *viewport,
GDK_AVAILABLE_IN_ALL
GtkWidget * gtk_viewport_get_child (GtkViewport *viewport);
GDK_AVAILABLE_IN_4_12
void gtk_viewport_scroll_to (GtkViewport *viewport,
GtkWidget *descendant,
GtkScrollInfo *scroll);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkViewport, g_object_unref)
G_END_DECLS

View File

@@ -910,7 +910,11 @@ search (GtkInspectorObjectTree *wt,
{
if (match_object (child, text))
{
gtk_single_selection_set_selected (priv->selection, row);
gtk_column_view_scroll_to (GTK_COLUMN_VIEW (wt->priv->list),
row,
NULL,
GTK_LIST_SCROLL_SELECT | GTK_LIST_SCROLL_FOCUS,
NULL);
g_object_unref (child);
g_object_unref (row_item);
return TRUE;
@@ -1302,8 +1306,12 @@ gtk_inspector_object_tree_select_object (GtkInspectorObjectTree *wt,
if (row_item == NULL)
return;
gtk_single_selection_set_selected (wt->priv->selection,
gtk_tree_list_row_get_position (row_item));
gtk_column_view_scroll_to (GTK_COLUMN_VIEW (wt->priv->list),
gtk_tree_list_row_get_position (row_item),
NULL,
GTK_LIST_SCROLL_SELECT | GTK_LIST_SCROLL_FOCUS,
NULL);
g_signal_emit (wt, signals[OBJECT_SELECTED], 0, object); // FIXME
g_object_unref (row_item);
}

View File

@@ -327,6 +327,7 @@ gtk_public_sources = files([
'gtkscalebutton.c',
'gtkscrollable.c',
'gtkscrollbar.c',
'gtkscrollinfo.c',
'gtkscrolledwindow.c',
'gtksearchbar.c',
'gtksearchentry.c',
@@ -557,6 +558,7 @@ gtk_public_headers = files([
'gtkscalebutton.h',
'gtkscrollable.h',
'gtkscrollbar.h',
'gtkscrollinfo.h',
'gtkscrolledwindow.h',
'gtksearchbar.h',
'gtksearchentry.h',

View File

@@ -1,5 +1,5 @@
project('gtk', 'c',
version: '4.11.5',
version: '4.12.0',
default_options: [
'buildtype=debugoptimized',
'warning_level=1',
@@ -742,7 +742,7 @@ if not gir.found() and get_option('introspection').enabled()
endif
build_gir = gir.found() and (get_option('introspection').enabled() or
(get_option('introspection').allowed() and get_option('gtk_doc')))
(get_option('introspection').allowed() and get_option('documentation')))
# Resource building
glib_compile_resources = find_program('glib-compile-resources')
@@ -920,7 +920,7 @@ summary('Linker', cc.get_linker_id(), section: 'Toolchain')
summary('Debugging', get_option('debug'), section: 'Build')
summary('Optimization', get_option('optimization'), section: 'Build')
summary('Introspection', build_gir, section: 'Build')
summary('Documentation', get_option('gtk_doc'), section: 'Build')
summary('Documentation', get_option('documentation'), section: 'Build')
summary('Man pages', get_option('man-pages'), section: 'Build')
summary('Testsuite', get_option('build-testsuite'), section: 'Build')
summary('Tests', get_option('build-tests'), section: 'Build')

View File

@@ -83,22 +83,7 @@ option('f16c',
value: 'enabled',
description: 'Enable F16C fast paths (requires F16C)')
# Documentation and introspection
option('gtk_doc',
type: 'boolean',
value: false,
description : 'Build API reference and tools documentation')
option('update_screenshots',
type: 'boolean',
value: false,
description : 'Regenerate screenshots for the documentation')
option('man-pages',
type: 'boolean',
value: false,
description : 'Build man pages for installed tools')
# Introspection
option('introspection',
type: 'feature',
@@ -106,6 +91,35 @@ option('introspection',
yield: true,
description : 'Build introspection data (requires gobject-introspection)')
# Documentation
option('documentation',
type: 'boolean',
value: false,
description : 'Build API reference and tools documentation')
option('gtk_doc',
type: 'boolean',
value: false,
description : 'Build API reference and tools documentation',
deprecated: 'documentation')
option('screenshots',
type: 'boolean',
value: false,
description : 'Regenerate screenshots for the documentation')
option('update_screenshots',
type: 'boolean',
value: false,
description : 'Regenerate screenshots for the documentation',
deprecated: 'screenshots')
option('man-pages',
type: 'boolean',
value: false,
description : 'Build man pages for installed tools')
# Demos, examples and tests
option('demo-profile',
@@ -114,17 +128,17 @@ option('demo-profile',
value: 'default',
description : 'Profile to use for demos')
option('build-demos',
type: 'boolean',
value: true,
description : 'Build demo programs')
option('profile',
type: 'combo',
choices: [ 'default', 'devel' ],
value: 'default',
deprecated: 'demo-profile')
option('build-demos',
type: 'boolean',
value: true,
description : 'Build demo programs')
option('demos',
type: 'boolean',
value: true,

View File

@@ -1 +1 @@
invalid5.ui:3:1 Required GTK version 5.10, current version is 4.11
invalid5.ui:3:1 Required GTK version 5.10, current version is 4.12