forked from AuroraMiddleware/gtk
Compare commits
178 Commits
frame-cloc
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
12858114a2 | ||
|
4f6133e00a | ||
|
9ca3a52bf0 | ||
|
40d99839d6 | ||
|
111e8d2808 | ||
|
9b0b3029a6 | ||
|
f743b95161 | ||
|
bdd35c1695 | ||
|
2f273ba76a | ||
|
a2d14632de | ||
|
7a3e130efd | ||
|
c8d356a250 | ||
|
ffb7177c2e | ||
|
8b2202cd56 | ||
|
14a5c78d80 | ||
|
5fd2a6c8f3 | ||
|
6cb6f4a50f | ||
|
7b909fb310 | ||
|
d12bea03d2 | ||
|
deacc63d54 | ||
|
ead121a3c1 | ||
|
de4725dbd5 | ||
|
7f5504523f | ||
|
40b154bf28 | ||
|
f0e4293b83 | ||
|
87f820287a | ||
|
30586d75ac | ||
|
7a1573a381 | ||
|
bc42955a13 | ||
|
cdc008763b | ||
|
7fff188557 | ||
|
69238c1197 | ||
|
574380c744 | ||
|
d1fc1adae7 | ||
|
64697ea95b | ||
|
aaeec84d75 | ||
|
5822ba76d0 | ||
|
a6ad8ebe0c | ||
|
55faea1046 | ||
|
21ee81823e | ||
|
9efd8ef201 | ||
|
432e8664e1 | ||
|
6d2c5e51e0 | ||
|
b669295fd8 | ||
|
96e6332d28 | ||
|
59549d0665 | ||
|
3e3158ce12 | ||
|
cfc2de4e3d | ||
|
343852af7b | ||
|
51902bbce8 | ||
|
9b3fb66bd4 | ||
|
3ccf63b3c0 | ||
|
4655226907 | ||
|
4500fa633b | ||
|
be11202538 | ||
|
0fa1e71ef0 | ||
|
987b9cec3f | ||
|
a77beb39a1 | ||
|
ac8e053ab6 | ||
|
986275239f | ||
|
2ee1273244 | ||
|
248027a366 | ||
|
c823432eef | ||
|
98ac2de649 | ||
|
1cee54009a | ||
|
80b7c60150 | ||
|
e8c5a771e5 | ||
|
882dcda53b | ||
|
b488fae893 | ||
|
b962defc11 | ||
|
9ee0696923 | ||
|
f3c53ae69d | ||
|
8aea6fc1b5 | ||
|
d949afb80e | ||
|
08c583b1b3 | ||
|
1c663cb340 | ||
|
776910d03d | ||
|
c82b2d86c0 | ||
|
3ca4acdc1a | ||
|
c705dba2ee | ||
|
55ad241f43 | ||
|
d3efd80b90 | ||
|
a899c0af6e | ||
|
f8fb30b555 | ||
|
47aa0dcc7f | ||
|
32f0723bf0 | ||
|
90a3584c1d | ||
|
891b6dc4a9 | ||
|
c6ff7400a8 | ||
|
6620b7de92 | ||
|
d58071b4c1 | ||
|
f38df62e2b | ||
|
0581e38b09 | ||
|
74a00319dd | ||
|
611788fb53 | ||
|
500128d186 | ||
|
32cf104167 | ||
|
9b98426e71 | ||
|
9820d25cf9 | ||
|
8bbf220fdf | ||
|
3a0152b65f | ||
|
22ba6b1f33 | ||
|
718b5d5fe7 | ||
|
88dd64551c | ||
|
98eac8ac83 | ||
|
dbb2cb22ca | ||
|
71dbb5090e | ||
|
4b46097748 | ||
|
eb0f33d76b | ||
|
828f686fc9 | ||
|
681f8bed19 | ||
|
5fe32a46a0 | ||
|
e3548bb9ad | ||
|
61506648bf | ||
|
621b3b51ea | ||
|
784ba8bf12 | ||
|
d968659b43 | ||
|
48d3db8daa | ||
|
ca702b4596 | ||
|
c91ba630a7 | ||
|
bc99ab38ce | ||
|
fe8c262351 | ||
|
1b000b5586 | ||
|
1b4f240883 | ||
|
496f68376b | ||
|
f019ff5287 | ||
|
c08e739996 | ||
|
8eb3c55709 | ||
|
40d4441fd8 | ||
|
471ebabd77 | ||
|
d8b7c909ea | ||
|
158165f769 | ||
|
2d90031dab | ||
|
2a862c05a1 | ||
|
93b6c7863b | ||
|
090f45a589 | ||
|
ca737b1411 | ||
|
b2af4006ba | ||
|
5d3942e5fa | ||
|
2bcc3cfb33 | ||
|
a7a498e803 | ||
|
75a417e337 | ||
|
dbaaa59758 | ||
|
73ba043b02 | ||
|
61e4eadbce | ||
|
0db2d0bc07 | ||
|
cd10e5dd1a | ||
|
c57d6c5575 | ||
|
73057b267e | ||
|
9d4bb77263 | ||
|
0d6cee9763 | ||
|
b33bfe26fe | ||
|
0cacaa08f5 | ||
|
cbf4a546b4 | ||
|
03732c1d48 | ||
|
568cf21486 | ||
|
f11d647aa4 | ||
|
49feaf465d | ||
|
9b0afd8bff | ||
|
495ca72232 | ||
|
e6f4464a3d | ||
|
cb0e4ee2be | ||
|
6f7b6ad61a | ||
|
1e599c9141 | ||
|
4cf42eb19c | ||
|
b0fc2f99ba | ||
|
2b4dd182c1 | ||
|
c141d0a70a | ||
|
6fa8033c7c | ||
|
de80f503e4 | ||
|
41b67c4722 | ||
|
1eae87621d | ||
|
5f502601c8 | ||
|
04d23c5cb9 | ||
|
d9b6f814ad | ||
|
871c46591a | ||
|
d906b456a8 | ||
|
32bc7ce987 |
@ -20,6 +20,7 @@ flatpak build ${builddir} meson \
|
||||
-Dx11-backend=true \
|
||||
-Dwayland-backend=true \
|
||||
-Dbuild-tests=false \
|
||||
-Dbuild-testsuite=false \
|
||||
-Dbuild-examples=false \
|
||||
-Dintrospection=disabled \
|
||||
-Ddemos=true \
|
||||
|
61
NEWS
61
NEWS
@ -1,5 +1,62 @@
|
||||
Overview of Changes in 4.9.5, xx-xx-xxxx
|
||||
========================================
|
||||
Overview of Changes in 4.10.1, xx-xx-xxxx
|
||||
=========================================
|
||||
|
||||
Overview of Changes in 4.10.0, 04-03-2023
|
||||
=========================================
|
||||
|
||||
* GtkTextView
|
||||
- Document hanging indentation
|
||||
|
||||
* GtkListView
|
||||
- Fix a size allocation problem
|
||||
|
||||
* GtkFileChooser
|
||||
- Fix paned behavior
|
||||
- Fix a crash
|
||||
|
||||
* GtkText
|
||||
- Fix various problems with undo
|
||||
|
||||
* Accessibility
|
||||
- Make some getters transfer-full
|
||||
- Allow setting accessible parents and siblings
|
||||
- Add a role for toggle buttons
|
||||
- Miscellaneous property fixes and improvements
|
||||
|
||||
* gtk
|
||||
- Improve the handling resize-during-size-allocate
|
||||
|
||||
* gdk
|
||||
- Introduce GdkTextureDownloader and use it
|
||||
- Make gdk_texture_get_format public
|
||||
|
||||
* gsk
|
||||
- Make mask nodes more versatile
|
||||
- Improve the GL implementation for texture scale nodes
|
||||
|
||||
* X11
|
||||
- Fix key handling during DND
|
||||
|
||||
* Tools
|
||||
- gtk-builder-tool: Try harder to handle templates
|
||||
- gtk-builder-tool: Prefer properties over <child>
|
||||
|
||||
* Translation updates
|
||||
Basque
|
||||
Belarusian
|
||||
Bulgarian
|
||||
Indonesian
|
||||
Galician
|
||||
Georgian
|
||||
German
|
||||
Hebrew
|
||||
Lithuanian
|
||||
Portuguese
|
||||
Spanish
|
||||
Swedish
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.9.4, 12-02-2023
|
||||
========================================
|
||||
|
@ -9,7 +9,7 @@ constraint_editor_sources = [
|
||||
|
||||
constraint_editor_resources = gnome.compile_resources('constraint_editor_resources',
|
||||
'constraint-editor.gresource.xml',
|
||||
source_dir: '.',
|
||||
source_dir: meson.current_source_dir(),
|
||||
)
|
||||
|
||||
executable('gtk4-constraint-editor',
|
||||
|
@ -225,7 +225,7 @@ if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_
|
||||
else
|
||||
gtkdemo_resources = gnome.compile_resources('gtkdemo_resources',
|
||||
'demo.gresource.xml',
|
||||
source_dir: '.',
|
||||
source_dir: meson.current_source_dir()
|
||||
)
|
||||
endif
|
||||
|
||||
|
@ -13,20 +13,13 @@
|
||||
static GtkWidget *app_picker;
|
||||
|
||||
static void
|
||||
file_opened (GObject *source,
|
||||
GAsyncResult *result,
|
||||
void *data)
|
||||
set_file (GFile *file,
|
||||
gpointer data)
|
||||
{
|
||||
GFile *file;
|
||||
GError *error = NULL;
|
||||
char *name;
|
||||
|
||||
file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG (source), result, &error);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
g_print ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
gtk_widget_set_sensitive (app_picker, FALSE);
|
||||
g_object_set_data (G_OBJECT (app_picker), "file", NULL);
|
||||
return;
|
||||
@ -40,6 +33,25 @@ file_opened (GObject *source,
|
||||
g_object_set_data_full (G_OBJECT (app_picker), "file", g_object_ref (file), g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
file_opened (GObject *source,
|
||||
GAsyncResult *result,
|
||||
void *data)
|
||||
{
|
||||
GFile *file;
|
||||
GError *error = NULL;
|
||||
|
||||
file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG (source), result, &error);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
g_print ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
set_file (file, data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
abort_mission (gpointer data)
|
||||
{
|
||||
@ -130,11 +142,28 @@ launch_uri (GtkButton *picker)
|
||||
g_object_unref (launcher);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_drop (GtkDropTarget *target,
|
||||
const GValue *value,
|
||||
double x,
|
||||
double y,
|
||||
gpointer data)
|
||||
{
|
||||
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
|
||||
{
|
||||
set_file (g_value_get_object (value), data);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_pickers (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
GtkWidget *table, *label, *picker, *button;
|
||||
GtkDropTarget *drop_target;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
@ -179,7 +208,13 @@ do_pickers (GtkWidget *do_widget)
|
||||
|
||||
picker = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
|
||||
button = gtk_button_new_from_icon_name ("document-open-symbolic");
|
||||
|
||||
label = gtk_label_new ("None");
|
||||
|
||||
drop_target = gtk_drop_target_new (G_TYPE_FILE, GDK_ACTION_COPY);
|
||||
g_signal_connect (drop_target, "drop", G_CALLBACK (on_drop), label);
|
||||
gtk_widget_add_controller (button, GTK_EVENT_CONTROLLER (drop_target));
|
||||
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.);
|
||||
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE);
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
|
@ -22,6 +22,7 @@ show_shortcuts (GtkWidget *window,
|
||||
gtk_window_set_transient_for (GTK_WINDOW (overlay), GTK_WINDOW (window));
|
||||
g_object_set (overlay, "view-name", view, NULL);
|
||||
g_object_unref (builder);
|
||||
gtk_window_present (GTK_WINDOW (overlay));
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT void
|
||||
|
@ -8,7 +8,7 @@ iconbrowser_sources = [
|
||||
|
||||
iconbrowser_resources = gnome.compile_resources('iconbrowser_resources',
|
||||
'iconbrowser.gresource.xml',
|
||||
source_dir: '.',
|
||||
source_dir: meson.current_source_dir(),
|
||||
)
|
||||
|
||||
executable('gtk4-icon-browser',
|
||||
|
@ -7,7 +7,7 @@ node_editor_sources = [
|
||||
|
||||
node_editor_resources = gnome.compile_resources('node_editor_resources',
|
||||
'node-editor.gresource.xml',
|
||||
source_dir: '.',
|
||||
source_dir: meson.current_source_dir(),
|
||||
)
|
||||
|
||||
executable('gtk4-node-editor',
|
||||
|
@ -69,7 +69,7 @@ if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_
|
||||
else
|
||||
widgetfactory_resources = gnome.compile_resources('widgetfactory_resources',
|
||||
'widget-factory.gresource.xml',
|
||||
source_dir: '.',
|
||||
source_dir: meson.current_source_dir(),
|
||||
)
|
||||
endif
|
||||
|
||||
|
@ -66,6 +66,10 @@ You can compile the program above with GCC using:
|
||||
gcc $( pkg-config --cflags gtk4 ) -o example-0 example-0.c $( pkg-config --libs gtk4 )
|
||||
```
|
||||
|
||||
**Note**: If the above compilation does not work due to an error regarding `G_APPLICATION_DEFAULT_FLAGS`
|
||||
this could be due to your OS providing an older version of GLib. For GLib versions older than 2.74 you
|
||||
will need to replace `G_APPLICATION_DEFAULT_FLAGS` with `G_APPLICATION_FLAGS_NONE` in this example, and
|
||||
others in this documentation.
|
||||
For more information on how to compile a GTK application, please
|
||||
refer to the [Compiling GTK Applications](compiling.html)
|
||||
section in this reference.
|
||||
|
@ -1,6 +1,6 @@
|
||||
app2_resources = gnome.compile_resources('exampleapp2_resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: '.')
|
||||
source_dir: meson.current_source_dir())
|
||||
|
||||
executable('exampleapp2',
|
||||
'exampleapp.c', 'exampleappwin.c', 'main.c', app2_resources,
|
||||
|
@ -1,6 +1,6 @@
|
||||
app3_resources = gnome.compile_resources('exampleapp3_resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: '.')
|
||||
source_dir: meson.current_source_dir())
|
||||
|
||||
executable('exampleapp3',
|
||||
'exampleapp.c', 'exampleappwin.c', 'main.c', app3_resources,
|
||||
|
@ -1,6 +1,6 @@
|
||||
app4_resources = gnome.compile_resources('exampleapp4_resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: '.')
|
||||
source_dir: meson.current_source_dir())
|
||||
|
||||
executable('exampleapp4',
|
||||
'exampleapp.c', 'exampleappwin.c', 'main.c', app4_resources,
|
||||
|
@ -1,6 +1,6 @@
|
||||
app5_resources = gnome.compile_resources('exampleapp5_resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: '.')
|
||||
source_dir: meson.current_source_dir())
|
||||
|
||||
app5_schemas = gnome.compile_schemas()
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
app6_resources = gnome.compile_resources('exampleapp6_resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: '.')
|
||||
source_dir: meson.current_source_dir())
|
||||
|
||||
app6_schemas = gnome.compile_schemas()
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
app7_resources = gnome.compile_resources('exampleapp7_resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: '.')
|
||||
source_dir: meson.current_source_dir())
|
||||
|
||||
app7_schemas = gnome.compile_schemas()
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
app8_resources = gnome.compile_resources('exampleapp8 resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: '.')
|
||||
source_dir: meson.current_source_dir())
|
||||
|
||||
app8_schemas = gnome.compile_schemas()
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
app9_resources = gnome.compile_resources('exampleapp9_resources',
|
||||
'exampleapp.gresource.xml',
|
||||
source_dir: '.')
|
||||
source_dir: meson.current_source_dir())
|
||||
|
||||
app9_schemas = gnome.compile_schemas()
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
bp_resources = gnome.compile_resources('bloatpad_resources',
|
||||
'bloatpad.gresources.xml',
|
||||
source_dir: '.')
|
||||
source_dir: meson.current_source_dir())
|
||||
|
||||
executable('bloatpad', 'bloatpad.c', bp_resources, dependencies: libgtk_dep, c_args: common_cflags)
|
||||
|
@ -178,10 +178,10 @@ gdk_memory_texture_new_subtexture (GdkMemoryTexture *source,
|
||||
GBytes *bytes;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MEMORY_TEXTURE (source), NULL);
|
||||
g_return_val_if_fail (x >= 0 || x < GDK_TEXTURE (source)->width, NULL);
|
||||
g_return_val_if_fail (y >= 0 || y < GDK_TEXTURE (source)->height, NULL);
|
||||
g_return_val_if_fail (width > 0 || x + width <= GDK_TEXTURE (source)->width, NULL);
|
||||
g_return_val_if_fail (height > 0 || y + height <= GDK_TEXTURE (source)->height, NULL);
|
||||
g_return_val_if_fail (x >= 0 && x < GDK_TEXTURE (source)->width, NULL);
|
||||
g_return_val_if_fail (y >= 0 && y < GDK_TEXTURE (source)->height, NULL);
|
||||
g_return_val_if_fail (width > 0 && x + width <= GDK_TEXTURE (source)->width, NULL);
|
||||
g_return_val_if_fail (height > 0 && y + height <= GDK_TEXTURE (source)->height, NULL);
|
||||
|
||||
texture = GDK_TEXTURE (source);
|
||||
bpp = gdk_memory_format_bytes_per_pixel (texture->format);
|
||||
|
@ -131,7 +131,7 @@ gdk_gresource_xml = configure_file(output: 'gdk.gresource.xml',
|
||||
|
||||
gdkresources = gnome.compile_resources('gdkresources',
|
||||
gdk_gresource_xml,
|
||||
source_dir: '.',
|
||||
source_dir: meson.current_source_dir(),
|
||||
c_name: '_gdk',
|
||||
extra_args: '--manual-register',
|
||||
)
|
||||
|
@ -561,8 +561,14 @@ gdk_wayland_surface_attach_image (GdkSurface *surface,
|
||||
/* Attach this new buffer to the surface */
|
||||
wl_surface_attach (impl->display_server.wl_surface,
|
||||
_gdk_wayland_shm_surface_get_wl_buffer (cairo_surface),
|
||||
impl->pending_buffer_offset_x,
|
||||
impl->pending_buffer_offset_y);
|
||||
0, 0);
|
||||
|
||||
if ((impl->pending_buffer_offset_x || impl->pending_buffer_offset_y) &&
|
||||
wl_surface_get_version (impl->display_server.wl_surface) >=
|
||||
WL_SURFACE_OFFSET_SINCE_VERSION)
|
||||
wl_surface_offset (impl->display_server.wl_surface,
|
||||
impl->pending_buffer_offset_x,
|
||||
impl->pending_buffer_offset_y);
|
||||
impl->pending_buffer_offset_x = 0;
|
||||
impl->pending_buffer_offset_y = 0;
|
||||
|
||||
@ -971,6 +977,15 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
|
||||
impl->display_server.egl_window = NULL;
|
||||
}
|
||||
|
||||
impl->awaiting_frame = FALSE;
|
||||
if (impl->awaiting_frame_frozen)
|
||||
{
|
||||
impl->awaiting_frame_frozen = FALSE;
|
||||
gdk_surface_thaw_updates (surface);
|
||||
}
|
||||
|
||||
GDK_WAYLAND_SURFACE_GET_CLASS (impl)->hide_surface (impl);
|
||||
|
||||
if (impl->display_server.xdg_surface)
|
||||
{
|
||||
xdg_surface_destroy (impl->display_server.xdg_surface);
|
||||
@ -989,15 +1004,6 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
|
||||
impl->initial_configure_received = FALSE;
|
||||
}
|
||||
|
||||
impl->awaiting_frame = FALSE;
|
||||
if (impl->awaiting_frame_frozen)
|
||||
{
|
||||
impl->awaiting_frame_frozen = FALSE;
|
||||
gdk_surface_thaw_updates (surface);
|
||||
}
|
||||
|
||||
GDK_WAYLAND_SURFACE_GET_CLASS (impl)->hide_surface (impl);
|
||||
|
||||
g_clear_pointer (&impl->display_server.wl_surface, wl_surface_destroy);
|
||||
|
||||
g_slist_free (impl->display_server.outputs);
|
||||
|
@ -872,6 +872,21 @@ gsk_gl_render_job_transform_bounds (GskGLRenderJob *job,
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_gl_render_job_untransform_bounds (GskGLRenderJob *job,
|
||||
const graphene_rect_t *rect,
|
||||
graphene_rect_t *out_rect)
|
||||
{
|
||||
GskTransform *transform;
|
||||
|
||||
transform = gsk_transform_invert (gsk_transform_ref (job->current_modelview->transform));
|
||||
|
||||
gsk_transform_transform_bounds (transform, rect, out_rect);
|
||||
|
||||
out_rect->origin.x -= job->offset_x;
|
||||
out_rect->origin.y -= job->offset_y;
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_gl_render_job_transform_rounded_rect (GskGLRenderJob *job,
|
||||
const GskRoundedRect *rect,
|
||||
@ -3615,127 +3630,98 @@ gsk_gl_render_job_visit_texture_scale_node (GskGLRenderJob *job,
|
||||
int min_filter = min_filters[scaling_filter];
|
||||
int mag_filter = mag_filters[scaling_filter];
|
||||
int max_texture_size = job->command_queue->max_texture_size;
|
||||
graphene_rect_t clip_rect;
|
||||
GskGLRenderTarget *render_target;
|
||||
GskGLRenderOffscreen offscreen = {0};
|
||||
graphene_rect_t viewport;
|
||||
graphene_rect_t prev_viewport;
|
||||
graphene_matrix_t prev_projection;
|
||||
float prev_alpha;
|
||||
guint prev_fbo;
|
||||
guint texture_id;
|
||||
float u0, u1, v0, v1;
|
||||
|
||||
if (scaling_filter == GSK_SCALING_FILTER_LINEAR)
|
||||
gsk_gl_render_job_untransform_bounds (job, &job->current_clip->rect.bounds, &clip_rect);
|
||||
if (!graphene_rect_intersection (bounds, &clip_rect, &clip_rect))
|
||||
return;
|
||||
|
||||
if G_UNLIKELY (clip_rect.size.width > max_texture_size ||
|
||||
clip_rect.size.height > max_texture_size)
|
||||
{
|
||||
gsk_gl_render_job_visit_texture (job, texture, bounds);
|
||||
return;
|
||||
}
|
||||
|
||||
if G_LIKELY (texture->width <= max_texture_size &&
|
||||
texture->height <= max_texture_size)
|
||||
viewport = GRAPHENE_RECT_INIT (0, 0,
|
||||
clip_rect.size.width,
|
||||
clip_rect.size.height);
|
||||
|
||||
if (!gsk_gl_driver_create_render_target (job->driver,
|
||||
(int) ceilf (clip_rect.size.width),
|
||||
(int) ceilf (clip_rect.size.height),
|
||||
get_target_format (job, node),
|
||||
GL_LINEAR, GL_LINEAR,
|
||||
&render_target))
|
||||
{
|
||||
GskGLRenderTarget *render_target;
|
||||
GskGLRenderOffscreen offscreen = {0};
|
||||
graphene_rect_t viewport;
|
||||
graphene_rect_t prev_viewport;
|
||||
graphene_matrix_t prev_projection;
|
||||
float prev_alpha;
|
||||
guint prev_fbo;
|
||||
guint texture_id;
|
||||
|
||||
viewport = GRAPHENE_RECT_INIT (0, 0,
|
||||
bounds->size.width,
|
||||
bounds->size.height);
|
||||
|
||||
if (!gsk_gl_driver_create_render_target (job->driver,
|
||||
(int) ceilf (viewport.size.width),
|
||||
(int) ceilf (viewport.size.height),
|
||||
get_target_format (job, node),
|
||||
GL_LINEAR, GL_LINEAR,
|
||||
&render_target))
|
||||
{
|
||||
/* viewport is too big, slice the texture and try again */
|
||||
goto slice;
|
||||
}
|
||||
|
||||
gsk_gl_render_job_upload_texture (job, texture, min_filter, mag_filter, &offscreen);
|
||||
|
||||
g_assert (offscreen.texture_id);
|
||||
g_assert (offscreen.was_offscreen == FALSE);
|
||||
|
||||
gsk_gl_render_job_set_viewport (job, &viewport, &prev_viewport);
|
||||
gsk_gl_render_job_set_projection_from_rect (job, &viewport, &prev_projection);
|
||||
gsk_gl_render_job_set_modelview (job, NULL);
|
||||
prev_alpha = gsk_gl_render_job_set_alpha (job, 1.0f);
|
||||
gsk_gl_render_job_push_clip (job, &GSK_ROUNDED_RECT_INIT_FROM_RECT (viewport));
|
||||
|
||||
prev_fbo = gsk_gl_command_queue_bind_framebuffer (job->command_queue, render_target->framebuffer_id);
|
||||
gsk_gl_command_queue_clear (job->command_queue, 0, &viewport);
|
||||
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
|
||||
gsk_gl_program_set_uniform_texture (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE0,
|
||||
offscreen.texture_id);
|
||||
gsk_gl_render_job_draw_offscreen (job, &viewport, &offscreen);
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
|
||||
gsk_gl_render_job_pop_clip (job);
|
||||
gsk_gl_render_job_pop_modelview (job);
|
||||
gsk_gl_render_job_set_viewport (job, &prev_viewport, NULL);
|
||||
gsk_gl_render_job_set_projection (job, &prev_projection);
|
||||
gsk_gl_render_job_set_alpha (job, prev_alpha);
|
||||
gsk_gl_command_queue_bind_framebuffer (job->command_queue, prev_fbo);
|
||||
|
||||
texture_id = gsk_gl_driver_release_render_target (job->driver, render_target, FALSE);
|
||||
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
|
||||
gsk_gl_program_set_uniform_texture (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE0,
|
||||
texture_id);
|
||||
gsk_gl_render_job_draw_offscreen_rect (job, bounds);
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
gsk_gl_render_job_visit_texture (job, texture, bounds);
|
||||
return;
|
||||
}
|
||||
else
|
||||
slice:
|
||||
{
|
||||
float min_x = bounds->origin.x;
|
||||
float min_y = bounds->origin.y;
|
||||
float max_x = min_x + bounds->size.width;
|
||||
float max_y = min_y + bounds->size.height;
|
||||
float scale_x = (max_x - min_x) / texture->width;
|
||||
float scale_y = (max_y - min_y) / texture->height;
|
||||
GskGLTextureSlice *slices = NULL;
|
||||
guint n_slices = 0;
|
||||
GdkGLContext *context = gsk_gl_driver_get_context (job->driver);
|
||||
guint rows, cols;
|
||||
|
||||
/* Slice enough that neither the original texture nor the scaled texture
|
||||
* exceed the texture size limit
|
||||
*/
|
||||
cols = (int)(MAX (bounds->size.width, texture->width) / (max_texture_size / 4)) + 1;
|
||||
rows = (int)(MAX (bounds->size.height, texture->height) / (max_texture_size / 4)) + 1;
|
||||
gsk_gl_render_job_upload_texture (job, texture, min_filter, mag_filter, &offscreen);
|
||||
|
||||
gsk_gl_driver_slice_texture (job->driver, texture, GL_NEAREST, GL_NEAREST, cols, rows, &slices, &n_slices);
|
||||
g_assert (offscreen.texture_id);
|
||||
g_assert (offscreen.was_offscreen == FALSE);
|
||||
|
||||
g_assert (slices != NULL);
|
||||
g_assert (n_slices > 0);
|
||||
u0 = (clip_rect.origin.x - bounds->origin.x) / bounds->size.width;
|
||||
v0 = (clip_rect.origin.y - bounds->origin.y) / bounds->size.height;
|
||||
u1 = (clip_rect.origin.x + clip_rect.size.width - bounds->origin.x) / bounds->size.width;
|
||||
v1 = (clip_rect.origin.y + clip_rect.size.height - bounds->origin.y) / bounds->size.height;
|
||||
|
||||
for (guint i = 0; i < n_slices; i ++)
|
||||
{
|
||||
const GskGLTextureSlice *slice = &slices[i];
|
||||
float x1, x2, y1, y2;
|
||||
GdkTexture *sub_texture;
|
||||
GskRenderNode *sub_node;
|
||||
gsk_gl_render_job_set_viewport (job, &viewport, &prev_viewport);
|
||||
gsk_gl_render_job_set_projection_from_rect (job, &viewport, &prev_projection);
|
||||
gsk_gl_render_job_set_modelview (job, NULL);
|
||||
prev_alpha = gsk_gl_render_job_set_alpha (job, 1.0f);
|
||||
gsk_gl_render_job_push_clip (job, &GSK_ROUNDED_RECT_INIT_FROM_RECT (viewport));
|
||||
|
||||
x1 = min_x + (scale_x * slice->rect.x);
|
||||
x2 = x1 + (slice->rect.width * scale_x);
|
||||
y1 = min_y + (scale_y * slice->rect.y);
|
||||
y2 = y1 + (slice->rect.height * scale_y);
|
||||
prev_fbo = gsk_gl_command_queue_bind_framebuffer (job->command_queue, render_target->framebuffer_id);
|
||||
gsk_gl_command_queue_clear (job->command_queue, 0, &viewport);
|
||||
|
||||
sub_texture = gdk_gl_texture_new (context, slice->texture_id, slice->rect.width, slice->rect.height, NULL, NULL);
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
|
||||
gsk_gl_program_set_uniform_texture (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE0,
|
||||
offscreen.texture_id);
|
||||
gsk_gl_render_job_draw_coords (job,
|
||||
0, 0, clip_rect.size.width, clip_rect.size.height,
|
||||
u0, v0, u1, v1,
|
||||
(guint16[]) { FP16_ZERO, FP16_ZERO, FP16_ZERO, FP16_ZERO });
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
|
||||
sub_node = gsk_texture_scale_node_new (sub_texture, &GRAPHENE_RECT_INIT (x1, y1, x2 - x1, y2 - y1), scaling_filter);
|
||||
gsk_gl_render_job_pop_clip (job);
|
||||
gsk_gl_render_job_pop_modelview (job);
|
||||
gsk_gl_render_job_set_viewport (job, &prev_viewport, NULL);
|
||||
gsk_gl_render_job_set_projection (job, &prev_projection);
|
||||
gsk_gl_render_job_set_alpha (job, prev_alpha);
|
||||
gsk_gl_command_queue_bind_framebuffer (job->command_queue, prev_fbo);
|
||||
|
||||
gsk_gl_render_job_visit_node (job, sub_node);
|
||||
gsk_render_node_unref (sub_node);
|
||||
g_object_unref (sub_texture);
|
||||
}
|
||||
}
|
||||
texture_id = gsk_gl_driver_release_render_target (job->driver, render_target, FALSE);
|
||||
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
|
||||
gsk_gl_program_set_uniform_texture (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE0,
|
||||
texture_id);
|
||||
gsk_gl_render_job_draw_coords (job,
|
||||
job->offset_x + clip_rect.origin.x,
|
||||
job->offset_y + clip_rect.origin.y,
|
||||
job->offset_x + clip_rect.origin.x + clip_rect.size.width,
|
||||
job->offset_y + clip_rect.origin.y + clip_rect.size.height,
|
||||
0, clip_rect.size.width / ceilf (clip_rect.size.width),
|
||||
clip_rect.size.height / ceilf (clip_rect.size.height), 0,
|
||||
(guint16[]){ FP16_ZERO, FP16_ZERO, FP16_ZERO, FP16_ZERO } );
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -58,6 +58,16 @@ rectangle_init_from_graphene (cairo_rectangle_int_t *cairo,
|
||||
cairo->height = ceilf (graphene->origin.y + graphene->size.height) - cairo->y;
|
||||
}
|
||||
|
||||
static void
|
||||
_graphene_rect_init_from_clip_extents (graphene_rect_t *rect,
|
||||
cairo_t *cr)
|
||||
{
|
||||
double x1c, y1c, x2c, y2c;
|
||||
|
||||
cairo_clip_extents (cr, &x1c, &y1c, &x2c, &y2c);
|
||||
graphene_rect_init (rect, x1c, y1c, x2c - x1c, y2c - y1c);
|
||||
}
|
||||
|
||||
/* {{{ GSK_COLOR_NODE */
|
||||
|
||||
/**
|
||||
@ -1625,15 +1635,21 @@ gsk_texture_scale_node_draw (GskRenderNode *node,
|
||||
};
|
||||
cairo_t *cr2;
|
||||
cairo_surface_t *surface2;
|
||||
graphene_rect_t clip_rect;
|
||||
|
||||
/* Make sure we draw the minimum region by using the clip */
|
||||
gsk_cairo_rectangle (cr, &node->bounds);
|
||||
cairo_clip (cr);
|
||||
_graphene_rect_init_from_clip_extents (&clip_rect, cr);
|
||||
if (clip_rect.size.width <= 0 || clip_rect.size.height <= 0)
|
||||
return;
|
||||
|
||||
surface2 = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
(int) ceilf (node->bounds.size.width),
|
||||
(int) ceilf (node->bounds.size.height));
|
||||
(int) ceilf (clip_rect.size.width),
|
||||
(int) ceilf (clip_rect.size.height));
|
||||
cairo_surface_set_device_offset (surface2, -clip_rect.origin.x, -clip_rect.origin.y);
|
||||
cr2 = cairo_create (surface2);
|
||||
|
||||
cairo_set_source_rgba (cr2, 0, 0, 0, 0);
|
||||
cairo_paint (cr2);
|
||||
|
||||
surface = gdk_texture_download_surface (self->texture);
|
||||
pattern = cairo_pattern_create_for_surface (surface);
|
||||
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
|
||||
@ -2072,15 +2088,15 @@ gsk_inset_shadow_node_draw (GskRenderNode *node,
|
||||
GskInsetShadowNode *self = (GskInsetShadowNode *) node;
|
||||
GskRoundedRect box, clip_box;
|
||||
int clip_radius;
|
||||
double x1c, y1c, x2c, y2c;
|
||||
graphene_rect_t clip_rect;
|
||||
double blur_radius;
|
||||
|
||||
/* We don't need to draw invisible shadows */
|
||||
if (gdk_rgba_is_clear (&self->color))
|
||||
return;
|
||||
|
||||
cairo_clip_extents (cr, &x1c, &y1c, &x2c, &y2c);
|
||||
if (!gsk_rounded_rect_intersects_rect (&self->outline, &GRAPHENE_RECT_INIT (x1c, y1c, x2c - x1c, y2c - y1c)))
|
||||
_graphene_rect_init_from_clip_extents (&clip_rect, cr);
|
||||
if (!gsk_rounded_rect_intersects_rect (&self->outline, &clip_rect))
|
||||
return;
|
||||
|
||||
blur_radius = self->blur_radius / 2;
|
||||
@ -2368,7 +2384,7 @@ gsk_outset_shadow_node_draw (GskRenderNode *node,
|
||||
GskOutsetShadowNode *self = (GskOutsetShadowNode *) node;
|
||||
GskRoundedRect box, clip_box;
|
||||
int clip_radius;
|
||||
double x1c, y1c, x2c, y2c;
|
||||
graphene_rect_t clip_rect;
|
||||
float top, right, bottom, left;
|
||||
double blur_radius;
|
||||
|
||||
@ -2376,8 +2392,8 @@ gsk_outset_shadow_node_draw (GskRenderNode *node,
|
||||
if (gdk_rgba_is_clear (&self->color))
|
||||
return;
|
||||
|
||||
cairo_clip_extents (cr, &x1c, &y1c, &x2c, &y2c);
|
||||
if (gsk_rounded_rect_contains_rect (&self->outline, &GRAPHENE_RECT_INIT (x1c, y1c, x2c - x1c, y2c - y1c)))
|
||||
_graphene_rect_init_from_clip_extents (&clip_rect, cr);
|
||||
if (!gsk_rounded_rect_intersects_rect (&self->outline, &clip_rect))
|
||||
return;
|
||||
|
||||
blur_radius = self->blur_radius / 2;
|
||||
|
@ -164,7 +164,7 @@ gskenum_h = gsk_enums[1]
|
||||
gskresources = gnome.compile_resources('gskresources',
|
||||
gsk_resources_xml,
|
||||
dependencies: gsk_private_vulkan_compiled_shaders_deps,
|
||||
source_dir: '.',
|
||||
source_dir: meson.current_source_dir(),
|
||||
c_name: '_gsk',
|
||||
extra_args: [ '--manual-register', ],
|
||||
)
|
||||
|
@ -158,9 +158,12 @@ component_handle_method (GDBusConnection *connection,
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkAtSpiContext *ctx = GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (child)));
|
||||
GtkATContext *context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child));
|
||||
GtkAtSpiContext *ctx = GTK_AT_SPI_CONTEXT (context);
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (ctx)));
|
||||
|
||||
g_object_unref (context);
|
||||
}
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetExtents") == 0)
|
||||
|
@ -203,6 +203,7 @@ collect_states (GtkAtSpiContext *self,
|
||||
|
||||
if (gtk_at_context_has_accessible_state (ctx, GTK_ACCESSIBLE_STATE_CHECKED))
|
||||
{
|
||||
set_atspi_state (&states, ATSPI_STATE_CHECKABLE);
|
||||
value = gtk_at_context_get_accessible_state (ctx, GTK_ACCESSIBLE_STATE_CHECKED);
|
||||
switch (gtk_tristate_accessible_value_get (value))
|
||||
{
|
||||
@ -246,7 +247,7 @@ collect_states (GtkAtSpiContext *self,
|
||||
case GTK_ACCESSIBLE_INVALID_TRUE:
|
||||
case GTK_ACCESSIBLE_INVALID_GRAMMAR:
|
||||
case GTK_ACCESSIBLE_INVALID_SPELLING:
|
||||
set_atspi_state (&states, ATSPI_STATE_INVALID);
|
||||
set_atspi_state (&states, ATSPI_STATE_INVALID_ENTRY);
|
||||
break;
|
||||
case GTK_ACCESSIBLE_INVALID_FALSE:
|
||||
default:
|
||||
@ -282,6 +283,34 @@ collect_states (GtkAtSpiContext *self,
|
||||
}
|
||||
}
|
||||
|
||||
if (gtk_at_context_has_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_REQUIRED))
|
||||
{
|
||||
value = gtk_at_context_get_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_REQUIRED);
|
||||
if (gtk_boolean_accessible_value_get (value))
|
||||
set_atspi_state (&states, ATSPI_STATE_REQUIRED);
|
||||
}
|
||||
|
||||
if (gtk_at_context_has_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_MULTI_SELECTABLE))
|
||||
{
|
||||
value = gtk_at_context_get_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_MULTI_SELECTABLE);
|
||||
if (gtk_boolean_accessible_value_get (value))
|
||||
set_atspi_state (&states, ATSPI_STATE_MULTISELECTABLE);
|
||||
}
|
||||
|
||||
if (gtk_at_context_has_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_HAS_POPUP))
|
||||
{
|
||||
value = gtk_at_context_get_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_HAS_POPUP);
|
||||
if (gtk_boolean_accessible_value_get (value))
|
||||
set_atspi_state (&states, ATSPI_STATE_HAS_POPUP);
|
||||
}
|
||||
|
||||
if (gtk_at_context_has_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_AUTOCOMPLETE))
|
||||
{
|
||||
value = gtk_at_context_get_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_AUTOCOMPLETE);
|
||||
if (gtk_autocomplete_accessible_value_get (value) != GTK_ACCESSIBLE_AUTOCOMPLETE_NONE)
|
||||
set_atspi_state (&states, ATSPI_STATE_SUPPORTS_AUTOCOMPLETION);
|
||||
}
|
||||
|
||||
g_variant_builder_add (builder, "u", (guint32) (states & 0xffffffff));
|
||||
g_variant_builder_add (builder, "u", (guint32) (states >> 32));
|
||||
}
|
||||
@ -299,11 +328,12 @@ collect_relations (GtkAtSpiContext *self,
|
||||
{ GTK_ACCESSIBLE_RELATION_LABELLED_BY, ATSPI_RELATION_LABELLED_BY },
|
||||
{ GTK_ACCESSIBLE_RELATION_CONTROLS, ATSPI_RELATION_CONTROLLER_FOR },
|
||||
{ GTK_ACCESSIBLE_RELATION_DESCRIBED_BY, ATSPI_RELATION_DESCRIBED_BY },
|
||||
{ GTK_ACCESSIBLE_RELATION_DETAILS, ATSPI_RELATION_DETAILS },
|
||||
{ GTK_ACCESSIBLE_RELATION_ERROR_MESSAGE, ATSPI_RELATION_ERROR_MESSAGE},
|
||||
{ GTK_ACCESSIBLE_RELATION_FLOW_TO, ATSPI_RELATION_FLOWS_TO},
|
||||
};
|
||||
GtkAccessibleValue *value;
|
||||
GList *list, *l;
|
||||
GtkATContext *target_ctx;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (map); i++)
|
||||
@ -318,13 +348,16 @@ collect_relations (GtkAtSpiContext *self,
|
||||
|
||||
for (l = list; l; l = l->next)
|
||||
{
|
||||
target_ctx = gtk_accessible_get_at_context (GTK_ACCESSIBLE (l->data));
|
||||
GtkATContext *target_ctx =
|
||||
gtk_accessible_get_at_context (GTK_ACCESSIBLE (l->data));
|
||||
|
||||
/* Realize the ATContext of the target, so we can ask for its ref */
|
||||
gtk_at_context_realize (target_ctx);
|
||||
|
||||
g_variant_builder_add (&b, "@(so)",
|
||||
gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (target_ctx)));
|
||||
|
||||
g_object_unref (target_ctx);
|
||||
}
|
||||
|
||||
g_variant_builder_add (builder, "(ua(so))", map[i].s, &b);
|
||||
@ -336,17 +369,17 @@ static int
|
||||
get_index_in (GtkAccessible *parent,
|
||||
GtkAccessible *child)
|
||||
{
|
||||
GtkAccessible *candidate;
|
||||
guint res;
|
||||
|
||||
if (parent == NULL)
|
||||
return -1;
|
||||
|
||||
res = 0;
|
||||
guint res = 0;
|
||||
GtkAccessible *candidate;
|
||||
for (candidate = gtk_accessible_get_first_accessible_child (parent);
|
||||
candidate != NULL;
|
||||
candidate = gtk_accessible_get_next_accessible_sibling (candidate))
|
||||
{
|
||||
g_object_unref (candidate);
|
||||
|
||||
if (candidate == child)
|
||||
return res;
|
||||
|
||||
@ -365,7 +398,13 @@ get_index_in_parent (GtkAccessible *accessible)
|
||||
GtkAccessible *parent = gtk_accessible_get_accessible_parent (accessible);
|
||||
|
||||
if (parent != NULL)
|
||||
return get_index_in (parent, accessible);
|
||||
{
|
||||
int res = get_index_in (parent, accessible);
|
||||
|
||||
g_object_unref (parent);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
@ -401,7 +440,6 @@ static GVariant *
|
||||
get_parent_context_ref (GtkAccessible *accessible)
|
||||
{
|
||||
GVariant *res = NULL;
|
||||
|
||||
GtkAccessible *parent = gtk_accessible_get_accessible_parent (accessible);
|
||||
|
||||
if (parent == NULL)
|
||||
@ -410,13 +448,19 @@ get_parent_context_ref (GtkAccessible *accessible)
|
||||
GtkAtSpiContext *self = GTK_AT_SPI_CONTEXT (context);
|
||||
|
||||
res = gtk_at_spi_root_to_ref (self->root);
|
||||
|
||||
g_object_unref (context);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkATContext *parent_context = gtk_accessible_get_at_context (parent);
|
||||
|
||||
gtk_at_context_realize (parent_context);
|
||||
|
||||
res = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (parent_context));
|
||||
|
||||
g_object_unref (parent_context);
|
||||
g_object_unref (parent);
|
||||
}
|
||||
|
||||
if (res == NULL)
|
||||
@ -497,31 +541,32 @@ handle_accessible_method (GDBusConnection *connection,
|
||||
{
|
||||
GtkATContext *context = NULL;
|
||||
GtkAccessible *accessible;
|
||||
GtkAccessible *child = NULL;
|
||||
int idx, presentable_idx;
|
||||
|
||||
g_variant_get (parameters, "(i)", &idx);
|
||||
|
||||
accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self));
|
||||
|
||||
GtkAccessible *child;
|
||||
|
||||
presentable_idx = 0;
|
||||
|
||||
for (child = gtk_accessible_get_first_accessible_child (accessible);
|
||||
child != NULL;
|
||||
child = gtk_accessible_get_next_accessible_sibling (child))
|
||||
{
|
||||
g_object_unref (child);
|
||||
|
||||
if (!gtk_accessible_should_present (child))
|
||||
continue;
|
||||
continue;
|
||||
|
||||
if (presentable_idx == idx)
|
||||
break;
|
||||
presentable_idx++;
|
||||
|
||||
presentable_idx += 1;
|
||||
}
|
||||
if (child)
|
||||
{
|
||||
context = gtk_accessible_get_at_context (child);
|
||||
}
|
||||
|
||||
if (child != NULL)
|
||||
context = gtk_accessible_get_at_context (child);
|
||||
|
||||
if (context == NULL)
|
||||
{
|
||||
@ -536,20 +581,23 @@ handle_accessible_method (GDBusConnection *connection,
|
||||
gtk_at_context_realize (context);
|
||||
|
||||
GVariant *ref = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (context));
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@(so))", ref));
|
||||
|
||||
g_object_unref (context);
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetChildren") == 0)
|
||||
{
|
||||
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a(so)"));
|
||||
|
||||
GtkAccessible *accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self));
|
||||
GtkAccessible *child = NULL;
|
||||
|
||||
GtkAccessible *child;
|
||||
for (child = gtk_accessible_get_first_accessible_child (accessible);
|
||||
child != NULL;
|
||||
child = gtk_accessible_get_next_accessible_sibling (child))
|
||||
{
|
||||
{
|
||||
g_object_unref (child);
|
||||
|
||||
if (!gtk_accessible_should_present (child))
|
||||
continue;
|
||||
|
||||
@ -562,6 +610,8 @@ handle_accessible_method (GDBusConnection *connection,
|
||||
|
||||
if (ref != NULL)
|
||||
g_variant_builder_add (&builder, "@(so)", ref);
|
||||
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a(so))", &builder));
|
||||
@ -741,8 +791,13 @@ emit_property_changed (GtkAtSpiContext *self,
|
||||
const char *name,
|
||||
GVariant *value)
|
||||
{
|
||||
GVariant *value_owned = g_variant_ref_sink (value);
|
||||
|
||||
if (self->connection == NULL)
|
||||
return;
|
||||
{
|
||||
g_variant_unref (value_owned);
|
||||
return;
|
||||
}
|
||||
|
||||
g_dbus_connection_emit_signal (self->connection,
|
||||
NULL,
|
||||
@ -750,8 +805,9 @@ emit_property_changed (GtkAtSpiContext *self,
|
||||
"org.a11y.atspi.Event.Object",
|
||||
"PropertyChange",
|
||||
g_variant_new ("(siiva{sv})",
|
||||
name, 0, 0, value, NULL),
|
||||
name, 0, 0, value_owned, NULL),
|
||||
NULL);
|
||||
g_variant_unref (value_owned);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -850,8 +906,6 @@ gtk_at_spi_context_state_change (GtkATContext *ctx,
|
||||
|
||||
if (changed_states & GTK_ACCESSIBLE_STATE_CHANGE_HIDDEN)
|
||||
{
|
||||
GtkAccessible *parent;
|
||||
GtkATContext *context;
|
||||
GtkAccessibleChildChange change;
|
||||
|
||||
value = gtk_accessible_attribute_set_get_value (states, GTK_ACCESSIBLE_STATE_HIDDEN);
|
||||
@ -867,10 +921,15 @@ gtk_at_spi_context_state_change (GtkATContext *ctx,
|
||||
}
|
||||
else
|
||||
{
|
||||
parent = gtk_accessible_get_accessible_parent (accessible);
|
||||
GtkAccessible *parent =
|
||||
gtk_accessible_get_accessible_parent (accessible);
|
||||
GtkATContext *context =
|
||||
gtk_accessible_get_at_context (parent);
|
||||
|
||||
context = gtk_accessible_get_at_context (parent);
|
||||
gtk_at_context_child_changed (context, change, accessible);
|
||||
|
||||
g_object_unref (context);
|
||||
g_object_unref (parent);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1119,9 +1178,18 @@ gtk_at_spi_context_child_change (GtkATContext *ctx,
|
||||
int idx = 0;
|
||||
|
||||
if (parent == NULL)
|
||||
idx = -1;
|
||||
{
|
||||
idx = -1;
|
||||
}
|
||||
else if (parent == accessible)
|
||||
idx = get_index_in (accessible, child);
|
||||
{
|
||||
idx = get_index_in (accessible, child);
|
||||
g_object_unref (parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_object_unref (parent);
|
||||
}
|
||||
|
||||
if (change & GTK_ACCESSIBLE_CHILD_CHANGE_ADDED)
|
||||
emit_children_changed (self,
|
||||
@ -1133,6 +1201,8 @@ gtk_at_spi_context_child_change (GtkATContext *ctx,
|
||||
GTK_AT_SPI_CONTEXT (child_context),
|
||||
idx,
|
||||
GTK_ACCESSIBLE_CHILD_STATE_REMOVED);
|
||||
|
||||
g_object_unref (child_context);
|
||||
}
|
||||
/* }}} */
|
||||
/* {{{ D-Bus Registration */
|
||||
@ -1701,15 +1771,16 @@ gtk_at_spi_context_get_child_count (GtkAtSpiContext *self)
|
||||
int n_children = 0;
|
||||
|
||||
GtkAccessible *child = NULL;
|
||||
|
||||
for (child = gtk_accessible_get_first_accessible_child (accessible);
|
||||
child != NULL;
|
||||
child = gtk_accessible_get_next_accessible_sibling (child))
|
||||
{
|
||||
g_object_unref (child);
|
||||
|
||||
if (!gtk_accessible_should_present (child))
|
||||
continue;
|
||||
|
||||
n_children++;
|
||||
n_children += 1;
|
||||
}
|
||||
|
||||
return n_children;
|
||||
|
@ -225,6 +225,10 @@ typedef enum {
|
||||
ATSPI_RELATION_PARENT_WINDOW_OF,
|
||||
ATSPI_RELATION_DESCRIPTION_FOR,
|
||||
ATSPI_RELATION_DESCRIBED_BY,
|
||||
ATSPI_RELATION_DETAILS,
|
||||
ATSPI_RELATION_DETAILS_FOR,
|
||||
ATSPI_RELATION_ERROR_MESSAGE,
|
||||
ATSPI_RELATION_ERROR_FOR,
|
||||
ATSPI_RELATION_LAST_DEFINED,
|
||||
} AtspiRelationType;
|
||||
|
||||
|
@ -314,6 +314,8 @@ handle_accessible_method (GDBusConnection *connection,
|
||||
const char *path = gtk_at_spi_context_get_context_path (GTK_AT_SPI_CONTEXT (context));
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("((so))", name, path));
|
||||
|
||||
g_object_unref (context);
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetChildren") == 0)
|
||||
{
|
||||
@ -334,6 +336,8 @@ handle_accessible_method (GDBusConnection *connection,
|
||||
const char *path = gtk_at_spi_context_get_context_path (GTK_AT_SPI_CONTEXT (context));
|
||||
|
||||
g_variant_builder_add (&builder, "(so)", name, path);
|
||||
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a(so))", &builder));
|
||||
@ -453,6 +457,8 @@ gtk_at_spi_root_child_changed (GtkAtSpiRoot *self,
|
||||
GtkATContext *context = gtk_accessible_get_at_context (child);
|
||||
|
||||
window_ref = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (context));
|
||||
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
switch (change)
|
||||
|
@ -94,7 +94,9 @@ listbox_handle_method (GDBusConnection *connection,
|
||||
else
|
||||
{
|
||||
GtkATContext *ctx = gtk_accessible_get_at_context (GTK_ACCESSIBLE (counter.child));
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (ctx))));
|
||||
g_dbus_method_invocation_return_value (invocation,
|
||||
g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (ctx))));
|
||||
g_object_unref (ctx);
|
||||
}
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "SelectChild") == 0)
|
||||
@ -271,7 +273,8 @@ listview_handle_method (GDBusConnection *connection,
|
||||
{
|
||||
GtkATContext *ctx = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child));
|
||||
g_dbus_method_invocation_return_value (invocation,
|
||||
g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (ctx))));
|
||||
g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (ctx))));
|
||||
g_object_unref (ctx);
|
||||
}
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "SelectChild") == 0)
|
||||
@ -495,7 +498,9 @@ flowbox_handle_method (GDBusConnection *connection,
|
||||
else
|
||||
{
|
||||
GtkATContext *ctx = gtk_accessible_get_at_context (GTK_ACCESSIBLE (counter.child));
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (ctx))));
|
||||
g_dbus_method_invocation_return_value (invocation,
|
||||
g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (ctx))));
|
||||
g_object_unref (ctx);
|
||||
}
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "SelectChild") == 0)
|
||||
@ -761,7 +766,8 @@ stackswitcher_handle_method (GDBusConnection *connection,
|
||||
{
|
||||
GtkATContext *ctx = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child));
|
||||
g_dbus_method_invocation_return_value (invocation,
|
||||
g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (ctx))));
|
||||
g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (ctx))));
|
||||
g_object_unref (ctx);
|
||||
}
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "SelectChild") == 0)
|
||||
@ -891,7 +897,8 @@ notebook_handle_method (GDBusConnection *connection,
|
||||
{
|
||||
GtkATContext *ctx = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child));
|
||||
g_dbus_method_invocation_return_value (invocation,
|
||||
g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (ctx))));
|
||||
g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (ctx))));
|
||||
g_object_unref (ctx);
|
||||
}
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "SelectChild") == 0)
|
||||
|
@ -109,7 +109,7 @@ gtk_accessible_role_to_atspi_role (GtkAccessibleRole role)
|
||||
return ATSPI_ROLE_LABEL;
|
||||
|
||||
case GTK_ACCESSIBLE_ROLE_LANDMARK:
|
||||
break;
|
||||
return ATSPI_ROLE_LANDMARK;
|
||||
|
||||
case GTK_ACCESSIBLE_ROLE_LEGEND:
|
||||
return ATSPI_ROLE_LABEL;
|
||||
@ -169,7 +169,7 @@ gtk_accessible_role_to_atspi_role (GtkAccessibleRole role)
|
||||
return ATSPI_ROLE_OPTION_PANE;
|
||||
|
||||
case GTK_ACCESSIBLE_ROLE_PRESENTATION:
|
||||
return ATSPI_ROLE_SECTION;
|
||||
return ATSPI_ROLE_FILLER;
|
||||
|
||||
case GTK_ACCESSIBLE_ROLE_PROGRESS_BAR:
|
||||
return ATSPI_ROLE_PROGRESS_BAR;
|
||||
@ -205,7 +205,7 @@ gtk_accessible_role_to_atspi_role (GtkAccessibleRole role)
|
||||
return ATSPI_ROLE_ENTRY;
|
||||
|
||||
case GTK_ACCESSIBLE_ROLE_SECTION:
|
||||
return ATSPI_ROLE_FILLER;
|
||||
return ATSPI_ROLE_SECTION;
|
||||
|
||||
case GTK_ACCESSIBLE_ROLE_SECTION_HEAD:
|
||||
return ATSPI_ROLE_FILLER;
|
||||
@ -273,6 +273,8 @@ gtk_accessible_role_to_atspi_role (GtkAccessibleRole role)
|
||||
case GTK_ACCESSIBLE_ROLE_WINDOW:
|
||||
return ATSPI_ROLE_FRAME;
|
||||
|
||||
case GTK_ACCESSIBLE_ROLE_TOGGLE_BUTTON:
|
||||
return ATSPI_ROLE_TOGGLE_BUTTON;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -995,10 +995,11 @@ gtk_cell_area_box_focus_changed (GtkCellArea *area,
|
||||
GParamSpec *pspec,
|
||||
GtkCellAreaBox *box)
|
||||
{
|
||||
GtkCellAreaBoxPrivate *priv = gtk_cell_area_box_get_instance_private (box);
|
||||
GtkCellAreaBoxPrivate *priv = gtk_cell_area_box_get_instance_private (box);
|
||||
GtkCellRenderer *focus_cell = gtk_cell_area_get_focus_cell (area);
|
||||
|
||||
if (gtk_cell_area_get_focus_cell (area))
|
||||
priv->last_focus_cell = gtk_cell_area_get_focus_cell (area);
|
||||
if (focus_cell)
|
||||
priv->last_focus_cell = focus_cell;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
|
@ -366,7 +366,6 @@ gtk_combo_box_size_allocate (GtkWidget *widget,
|
||||
{
|
||||
GtkComboBox *combo_box = GTK_COMBO_BOX (widget);
|
||||
GtkComboBoxPrivate *priv = gtk_combo_box_get_instance_private (combo_box);
|
||||
int menu_width;
|
||||
|
||||
gtk_widget_size_allocate (priv->box,
|
||||
&(GtkAllocation) {
|
||||
@ -374,17 +373,8 @@ gtk_combo_box_size_allocate (GtkWidget *widget,
|
||||
width, height
|
||||
}, baseline);
|
||||
|
||||
gtk_widget_set_size_request (priv->popup_widget, -1, -1);
|
||||
|
||||
if (priv->popup_fixed_width)
|
||||
gtk_widget_measure (priv->popup_widget, GTK_ORIENTATION_HORIZONTAL, -1,
|
||||
&menu_width, NULL, NULL, NULL);
|
||||
else
|
||||
gtk_widget_measure (priv->popup_widget, GTK_ORIENTATION_HORIZONTAL, -1,
|
||||
NULL, &menu_width, NULL, NULL);
|
||||
|
||||
gtk_widget_set_size_request (priv->popup_widget,
|
||||
MAX (width, menu_width), -1);
|
||||
gtk_widget_set_size_request (priv->popup_widget, width, -1);
|
||||
gtk_widget_queue_resize (priv->popup_widget);
|
||||
|
||||
gtk_popover_present (GTK_POPOVER (priv->popup_widget));
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ for f in funcs:
|
||||
file_output += ['#ifdef GDK_WINDOWING_WIN32']
|
||||
file_output += ['*tp++ = {0}();'.format(f)]
|
||||
file_output += ['#endif']
|
||||
elif f.startswith('gdk_quartz'):
|
||||
elif f.startswith('gdk_macos'):
|
||||
file_output += ['#ifdef GDK_WINDOWING_MACOS']
|
||||
file_output += ['*tp++ = {0}();'.format(f)]
|
||||
file_output += ['#endif']
|
||||
|
@ -91,9 +91,9 @@ gtk_accessible_default_init (GtkAccessibleInterface *iface)
|
||||
* gtk_accessible_get_at_context:
|
||||
* @self: a `GtkAccessible`
|
||||
*
|
||||
* Retrieves the `GtkATContext` for the given `GtkAccessible`.
|
||||
* Retrieves the accessible implementation for the given `GtkAccessible`.
|
||||
*
|
||||
* Returns: (transfer none): the `GtkATContext`
|
||||
* Returns: (transfer full): the accessible implementation object
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
@ -109,11 +109,11 @@ gtk_accessible_get_at_context (GtkAccessible *self)
|
||||
* gtk_accessible_get_accessible_parent:
|
||||
* @self: a `GtkAccessible`
|
||||
*
|
||||
* Retrieves the accessible accessible for an accessible object
|
||||
* Retrieves the accessible parent for an accessible object.
|
||||
*
|
||||
* This function returns `NULL` for top level widgets
|
||||
* This function returns `NULL` for top level widgets.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the accessible parent
|
||||
* Returns: (transfer full) (nullable): the accessible parent
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
@ -127,10 +127,13 @@ gtk_accessible_get_accessible_parent (GtkAccessible *self)
|
||||
|
||||
context = gtk_accessible_get_at_context (self);
|
||||
if (context != NULL)
|
||||
parent = gtk_at_context_get_accessible_parent (context);
|
||||
|
||||
{
|
||||
parent = gtk_at_context_get_accessible_parent (context);
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
if (parent != NULL)
|
||||
return parent;
|
||||
return g_object_ref (parent);
|
||||
else
|
||||
return GTK_ACCESSIBLE_GET_IFACE (self)->get_accessible_parent (self);
|
||||
}
|
||||
@ -161,6 +164,7 @@ gtk_accessible_set_accessible_parent (GtkAccessible *self,
|
||||
g_return_if_fail (GTK_IS_ACCESSIBLE (self));
|
||||
g_return_if_fail (parent == NULL || GTK_IS_ACCESSIBLE (parent));
|
||||
g_return_if_fail (next_sibling == NULL || GTK_IS_ACCESSIBLE (parent));
|
||||
|
||||
GtkATContext *context;
|
||||
|
||||
context = gtk_accessible_get_at_context (self);
|
||||
@ -168,6 +172,7 @@ gtk_accessible_set_accessible_parent (GtkAccessible *self,
|
||||
{
|
||||
gtk_at_context_set_accessible_parent (context, parent);
|
||||
gtk_at_context_set_next_accessible_sibling (context, next_sibling);
|
||||
g_object_unref (context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,6 +182,7 @@ gtk_accessible_set_accessible_parent (GtkAccessible *self,
|
||||
* @new_sibling: (nullable): the new next accessible sibling to set
|
||||
*
|
||||
* Updates the next accessible sibling of @self.
|
||||
*
|
||||
* That might be useful when a new child of a custom `GtkAccessible`
|
||||
* is created, and it needs to be linked to a previous child.
|
||||
*
|
||||
@ -187,20 +193,26 @@ gtk_accessible_update_next_accessible_sibling (GtkAccessible *self,
|
||||
GtkAccessible *new_sibling)
|
||||
{
|
||||
GtkATContext *context;
|
||||
GtkAccessible *parent;
|
||||
|
||||
g_return_if_fail (GTK_IS_ACCESSIBLE (self));
|
||||
|
||||
context = gtk_accessible_get_at_context (self);
|
||||
if (!context)
|
||||
if (context == NULL)
|
||||
return;
|
||||
|
||||
if (gtk_at_context_get_accessible_parent (context) == NULL)
|
||||
{
|
||||
g_critical ("Failed to update next accessible sibling: no parent accessible set for this accessible");
|
||||
return;
|
||||
}
|
||||
|
||||
parent = gtk_at_context_get_accessible_parent (context);
|
||||
if (parent == NULL)
|
||||
{
|
||||
g_object_unref (context);
|
||||
g_critical ("Failed to update next accessible sibling: no parent accessible set for this accessible");
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_at_context_set_next_accessible_sibling (context, new_sibling);
|
||||
|
||||
g_object_unref (parent);
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -209,7 +221,7 @@ gtk_accessible_update_next_accessible_sibling (GtkAccessible *self,
|
||||
*
|
||||
* Retrieves the first accessible child of an accessible object.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the first accessible child
|
||||
* Returns: (transfer full) (nullable): the first accessible child
|
||||
*
|
||||
* since: 4.10
|
||||
*/
|
||||
@ -227,7 +239,7 @@ gtk_accessible_get_first_accessible_child (GtkAccessible *self)
|
||||
*
|
||||
* Retrieves the next accessible sibling of an accessible object
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the next accessible sibling
|
||||
* Returns: (transfer full) (nullable): the next accessible sibling
|
||||
*
|
||||
* since: 4.10
|
||||
*/
|
||||
@ -239,8 +251,21 @@ gtk_accessible_get_next_accessible_sibling (GtkAccessible *self)
|
||||
GtkATContext *context;
|
||||
|
||||
context = gtk_accessible_get_at_context (self);
|
||||
if (context != NULL && gtk_at_context_get_accessible_parent (context) != NULL)
|
||||
return gtk_at_context_get_next_accessible_sibling (context);
|
||||
if (context != NULL)
|
||||
{
|
||||
GtkAccessible *sibling = NULL;
|
||||
|
||||
if (gtk_at_context_get_accessible_parent (context) != NULL)
|
||||
{
|
||||
sibling = gtk_at_context_get_next_accessible_sibling (context);
|
||||
if (sibling != NULL)
|
||||
sibling = g_object_ref (sibling);
|
||||
}
|
||||
|
||||
g_object_unref (context);
|
||||
|
||||
return sibling;
|
||||
}
|
||||
else
|
||||
return GTK_ACCESSIBLE_GET_IFACE (self)->get_next_accessible_sibling (self);
|
||||
}
|
||||
@ -256,13 +281,21 @@ gtk_accessible_get_next_accessible_sibling (GtkAccessible *self)
|
||||
GtkAccessibleRole
|
||||
gtk_accessible_get_accessible_role (GtkAccessible *self)
|
||||
{
|
||||
GtkAccessibleRole role;
|
||||
GtkAccessibleRole role = GTK_ACCESSIBLE_ROLE_NONE;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_ACCESSIBLE (self), GTK_ACCESSIBLE_ROLE_NONE);
|
||||
|
||||
GtkATContext *context = gtk_accessible_get_at_context (self);
|
||||
if (context != NULL && gtk_at_context_is_realized (context))
|
||||
return gtk_at_context_get_accessible_role (context);
|
||||
if (context != NULL)
|
||||
{
|
||||
if (gtk_at_context_is_realized (context))
|
||||
role = gtk_at_context_get_accessible_role (context);
|
||||
|
||||
g_object_unref (context);
|
||||
|
||||
if (role != GTK_ACCESSIBLE_ROLE_NONE)
|
||||
return role;
|
||||
}
|
||||
|
||||
g_object_get (G_OBJECT (self), "accessible-role", &role, NULL);
|
||||
|
||||
@ -336,6 +369,8 @@ gtk_accessible_update_state (GtkAccessible *self,
|
||||
|
||||
out:
|
||||
va_end (args);
|
||||
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -389,6 +424,7 @@ gtk_accessible_update_state_value (GtkAccessible *self,
|
||||
}
|
||||
|
||||
gtk_at_context_update (context);
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -412,6 +448,7 @@ gtk_accessible_reset_state (GtkAccessible *self,
|
||||
|
||||
gtk_at_context_set_accessible_state (context, state, NULL);
|
||||
gtk_at_context_update (context);
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -483,6 +520,8 @@ gtk_accessible_update_property (GtkAccessible *self,
|
||||
|
||||
out:
|
||||
va_end (args);
|
||||
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -536,6 +575,7 @@ gtk_accessible_update_property_value (GtkAccessible *self,
|
||||
}
|
||||
|
||||
gtk_at_context_update (context);
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -559,6 +599,7 @@ gtk_accessible_reset_property (GtkAccessible *self,
|
||||
|
||||
gtk_at_context_set_accessible_property (context, property, NULL);
|
||||
gtk_at_context_update (context);
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -630,6 +671,8 @@ gtk_accessible_update_relation (GtkAccessible *self,
|
||||
|
||||
out:
|
||||
va_end (args);
|
||||
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -658,6 +701,8 @@ gtk_accessible_update_relation_value (GtkAccessible *self,
|
||||
g_return_if_fail (n_relations > 0);
|
||||
|
||||
context = gtk_accessible_get_at_context (self);
|
||||
if (context == NULL)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < n_relations; i++)
|
||||
{
|
||||
@ -676,15 +721,14 @@ gtk_accessible_update_relation_value (GtkAccessible *self,
|
||||
break;
|
||||
}
|
||||
|
||||
if (context)
|
||||
gtk_at_context_set_accessible_relation (context, relation, real_value);
|
||||
gtk_at_context_set_accessible_relation (context, relation, real_value);
|
||||
|
||||
if (real_value != NULL)
|
||||
gtk_accessible_value_unref (real_value);
|
||||
}
|
||||
|
||||
if (context)
|
||||
gtk_at_context_update (context);
|
||||
gtk_at_context_update (context);
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -708,6 +752,7 @@ gtk_accessible_reset_relation (GtkAccessible *self,
|
||||
|
||||
gtk_at_context_set_accessible_relation (context, relation, NULL);
|
||||
gtk_at_context_update (context);
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
static const char *role_names[] = {
|
||||
@ -868,13 +913,22 @@ gtk_accessible_platform_changed (GtkAccessible *self,
|
||||
|
||||
/* propagate changes up from ignored widgets */
|
||||
if (gtk_accessible_get_accessible_role (self) == GTK_ACCESSIBLE_ROLE_NONE)
|
||||
context = gtk_accessible_get_at_context (gtk_accessible_get_accessible_parent (self));
|
||||
{
|
||||
GtkAccessible *parent = gtk_accessible_get_accessible_parent (self);
|
||||
|
||||
if (parent != NULL)
|
||||
{
|
||||
context = gtk_accessible_get_at_context (parent);
|
||||
g_object_unref (parent);
|
||||
}
|
||||
}
|
||||
|
||||
if (context == NULL)
|
||||
return;
|
||||
|
||||
gtk_at_context_platform_changed (context, change);
|
||||
gtk_at_context_update (context);
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -928,6 +982,7 @@ gtk_accessible_bounds_changed (GtkAccessible *self)
|
||||
return;
|
||||
|
||||
gtk_at_context_bounds_changed (context);
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -980,6 +1035,7 @@ gtk_accessible_should_present (GtkAccessible *self)
|
||||
{
|
||||
GtkAccessibleRole role;
|
||||
GtkATContext *context;
|
||||
gboolean res = TRUE;
|
||||
|
||||
if (GTK_IS_WIDGET (self) &&
|
||||
!gtk_widget_get_visible (GTK_WIDGET (self)))
|
||||
@ -1000,10 +1056,12 @@ gtk_accessible_should_present (GtkAccessible *self)
|
||||
|
||||
value = gtk_at_context_get_accessible_state (context, GTK_ACCESSIBLE_STATE_HIDDEN);
|
||||
if (gtk_boolean_accessible_value_get (value))
|
||||
return FALSE;
|
||||
res = FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
g_object_unref (context);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1017,15 +1075,24 @@ gtk_accessible_update_children (GtkAccessible *self,
|
||||
gtk_widget_get_root (GTK_WIDGET (self)) == NULL)
|
||||
return;
|
||||
|
||||
context = gtk_accessible_get_at_context (self);
|
||||
|
||||
/* propagate changes up from ignored widgets */
|
||||
if (gtk_accessible_get_accessible_role (self) == GTK_ACCESSIBLE_ROLE_NONE)
|
||||
context = gtk_accessible_get_at_context (gtk_accessible_get_accessible_parent (self));
|
||||
{
|
||||
GtkAccessible *parent = gtk_accessible_get_accessible_parent (self);
|
||||
|
||||
context = gtk_accessible_get_at_context (parent);
|
||||
|
||||
g_object_unref (parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
context = gtk_accessible_get_at_context (self);
|
||||
}
|
||||
|
||||
if (context == NULL)
|
||||
return;
|
||||
|
||||
gtk_at_context_child_changed (context, 1 << state, child);
|
||||
gtk_at_context_update (context);
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ struct _GtkAccessibleInterface
|
||||
* Retrieves the platform-specific accessibility context for the
|
||||
* accessible implementation.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the accessibility context
|
||||
* Returns: (transfer full) (nullable): the accessibility context
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
@ -101,7 +101,7 @@ struct _GtkAccessibleInterface
|
||||
*
|
||||
* This virtual function should return `NULL` for top level objects.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the accessible parent
|
||||
* Returns: (nullable) (transfer full): the accessible parent
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
@ -113,7 +113,7 @@ struct _GtkAccessibleInterface
|
||||
*
|
||||
* Retrieves the first accessible child of an accessible object.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): an accessible object
|
||||
* Returns: (transfer full) (nullable): an accessible object
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
@ -125,7 +125,7 @@ struct _GtkAccessibleInterface
|
||||
*
|
||||
* Retrieves the next accessible sibling of an accessible object.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): an accessible object
|
||||
* Returns: (transfer full) (nullable): an accessible object
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
|
@ -85,6 +85,20 @@ gtk_at_context_dispose (GObject *gobject)
|
||||
|
||||
gtk_at_context_unrealize (self);
|
||||
|
||||
if (self->accessible_parent != NULL)
|
||||
{
|
||||
g_object_remove_weak_pointer (G_OBJECT (self->accessible_parent),
|
||||
(gpointer *) &self->accessible_parent);
|
||||
self->accessible_parent = NULL;
|
||||
}
|
||||
|
||||
if (self->next_accessible_sibling != NULL)
|
||||
{
|
||||
g_object_remove_weak_pointer (G_OBJECT (self->next_accessible_sibling),
|
||||
(gpointer *) &self->next_accessible_sibling);
|
||||
self->next_accessible_sibling = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gtk_at_context_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
@ -459,14 +473,14 @@ GtkAccessible *
|
||||
gtk_at_context_get_accessible_parent (GtkATContext *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_AT_CONTEXT (self), NULL);
|
||||
|
||||
|
||||
return self->accessible_parent;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gtk_at_context_set_accessible_parent:
|
||||
* @self: a `GtkAtContext`
|
||||
* @parent: the parent `GtkAccessible` to set
|
||||
* @parent: (nullable): the parent `GtkAccessible` to set
|
||||
*
|
||||
* Sets the parent accessible object of the given `GtkAtContext`.
|
||||
*/
|
||||
@ -475,8 +489,18 @@ gtk_at_context_set_accessible_parent (GtkATContext *self,
|
||||
GtkAccessible *parent)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_AT_CONTEXT (self));
|
||||
|
||||
g_set_object (&self->accessible_parent, parent);
|
||||
|
||||
if (self->accessible_parent != parent)
|
||||
{
|
||||
if (self->accessible_parent != NULL)
|
||||
g_object_remove_weak_pointer (G_OBJECT (self->accessible_parent),
|
||||
(gpointer *) &self->accessible_parent);
|
||||
|
||||
self->accessible_parent = parent;
|
||||
if (self->accessible_parent != NULL)
|
||||
g_object_add_weak_pointer (G_OBJECT (self->accessible_parent),
|
||||
(gpointer *) &self->accessible_parent);
|
||||
}
|
||||
}
|
||||
|
||||
/*< private >
|
||||
@ -491,7 +515,7 @@ GtkAccessible *
|
||||
gtk_at_context_get_next_accessible_sibling (GtkATContext *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_AT_CONTEXT (self), NULL);
|
||||
|
||||
|
||||
return self->next_accessible_sibling;
|
||||
}
|
||||
|
||||
@ -507,8 +531,19 @@ gtk_at_context_set_next_accessible_sibling (GtkATContext *self,
|
||||
GtkAccessible *sibling)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_AT_CONTEXT (self));
|
||||
|
||||
g_set_object (&self->next_accessible_sibling, sibling);
|
||||
|
||||
if (self->next_accessible_sibling != sibling)
|
||||
{
|
||||
if (self->next_accessible_sibling != NULL)
|
||||
g_object_remove_weak_pointer (G_OBJECT (self->next_accessible_sibling),
|
||||
(gpointer *) &self->next_accessible_sibling);
|
||||
|
||||
self->next_accessible_sibling = sibling;
|
||||
|
||||
if (self->next_accessible_sibling != NULL)
|
||||
g_object_add_weak_pointer (G_OBJECT (self->next_accessible_sibling),
|
||||
(gpointer *) &self->next_accessible_sibling);
|
||||
}
|
||||
}
|
||||
|
||||
/*< private >
|
||||
@ -993,6 +1028,8 @@ gtk_at_context_get_name_accumulate (GtkATContext *self,
|
||||
GtkATContext *rel_context = gtk_accessible_get_at_context (rel);
|
||||
|
||||
gtk_at_context_get_name_accumulate (rel_context, names, FALSE);
|
||||
|
||||
g_object_unref (rel_context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1065,6 +1102,8 @@ gtk_at_context_get_description_accumulate (GtkATContext *self,
|
||||
GtkATContext *rel_context = gtk_accessible_get_at_context (rel);
|
||||
|
||||
gtk_at_context_get_description_accumulate (rel_context, labels, FALSE);
|
||||
|
||||
g_object_unref (rel_context);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1608,6 +1608,7 @@ create_subparser (GObject *object,
|
||||
subparser->object = object;
|
||||
subparser->child = child;
|
||||
subparser->tagname = g_strdup (element_name);
|
||||
subparser->level = 1;
|
||||
subparser->start = element_name;
|
||||
subparser->parser = g_memdup2 (parser, sizeof (GtkBuildableParser));
|
||||
subparser->data = user_data;
|
||||
@ -1638,6 +1639,8 @@ subparser_start (GtkBuildableParseContext *context,
|
||||
|
||||
if (subparser->start)
|
||||
{
|
||||
subparser->level++;
|
||||
|
||||
if (subparser->parser->start_element)
|
||||
subparser->parser->start_element (context,
|
||||
element_name, names, values,
|
||||
@ -1653,6 +1656,8 @@ subparser_end (GtkBuildableParseContext *context,
|
||||
ParserData *data,
|
||||
GError **error)
|
||||
{
|
||||
data->subparser->level--;
|
||||
|
||||
if (data->subparser->parser->end_element)
|
||||
data->subparser->parser->end_element (context, element_name,
|
||||
data->subparser->data, error);
|
||||
@ -1660,9 +1665,11 @@ subparser_end (GtkBuildableParseContext *context,
|
||||
if (*error)
|
||||
return;
|
||||
|
||||
if (strcmp (data->subparser->start, element_name) != 0)
|
||||
if (data->subparser->level > 0)
|
||||
return;
|
||||
|
||||
g_assert (strcmp (data->subparser->start, element_name) == 0);
|
||||
|
||||
gtk_buildable_custom_tag_end (GTK_BUILDABLE (data->subparser->object),
|
||||
data->builder,
|
||||
data->subparser->child,
|
||||
|
@ -165,6 +165,7 @@ struct _GtkBuildableParseContext {
|
||||
typedef struct {
|
||||
GtkBuildableParser *parser;
|
||||
char *tagname;
|
||||
int level;
|
||||
const char *start;
|
||||
gpointer data;
|
||||
GObject *object;
|
||||
|
@ -19,7 +19,7 @@
|
||||
* Modified by the GTK+ Team and others 1997-2001. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -63,7 +63,6 @@
|
||||
|
||||
#include "gtkactionhelperprivate.h"
|
||||
#include "gtkbuildable.h"
|
||||
#include "gtkcheckbutton.h"
|
||||
#include "gtkgestureclick.h"
|
||||
#include "gtkeventcontrollerkey.h"
|
||||
#include "gtkbinlayout.h"
|
||||
@ -829,8 +828,6 @@ gtk_button_set_label (GtkButton *button,
|
||||
gtk_label_set_use_underline (GTK_LABEL (child), priv->use_underline);
|
||||
gtk_label_set_mnemonic_widget (GTK_LABEL (child), GTK_WIDGET (button));
|
||||
}
|
||||
if (GTK_IS_CHECK_BUTTON (button))
|
||||
gtk_label_set_xalign (GTK_LABEL (child), 0.0);
|
||||
|
||||
gtk_button_set_child (button, child);
|
||||
}
|
||||
|
@ -477,6 +477,8 @@ gtk_column_view_dispose (GObject *object)
|
||||
{
|
||||
GtkColumnView *self = GTK_COLUMN_VIEW (object);
|
||||
|
||||
gtk_column_view_sorter_clear (GTK_COLUMN_VIEW_SORTER (self->sorter));
|
||||
|
||||
while (g_list_model_get_n_items (G_LIST_MODEL (self->columns)) > 0)
|
||||
{
|
||||
GtkColumnViewColumn *column = g_list_model_get_item (G_LIST_MODEL (self->columns), 0);
|
||||
|
@ -507,9 +507,6 @@ gtk_css_node_real_node_removed (GtkCssNode *parent,
|
||||
node->previous_sibling = NULL;
|
||||
node->next_sibling = NULL;
|
||||
node->parent = NULL;
|
||||
|
||||
if (parent->children_observer)
|
||||
gtk_list_list_model_item_removed (parent->children_observer, previous);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -715,6 +712,8 @@ gtk_css_node_reposition (GtkCssNode *node,
|
||||
if (old_parent != NULL)
|
||||
{
|
||||
GTK_CSS_NODE_GET_CLASS (old_parent)->node_removed (old_parent, node, node->previous_sibling);
|
||||
if (old_parent->children_observer && old_parent != new_parent)
|
||||
gtk_list_list_model_item_removed (old_parent->children_observer, previous);
|
||||
if (old_parent->first_child && node->visible)
|
||||
gtk_css_node_invalidate (old_parent->first_child, GTK_CSS_CHANGE_NTH_LAST_CHILD);
|
||||
}
|
||||
@ -784,7 +783,7 @@ gtk_css_node_reposition (GtkCssNode *node,
|
||||
|
||||
if (new_parent && new_parent->children_observer)
|
||||
{
|
||||
if (old_previous)
|
||||
if (old_previous && old_parent == new_parent)
|
||||
gtk_list_list_model_item_moved (new_parent->children_observer, node, old_previous);
|
||||
else
|
||||
gtk_list_list_model_item_added (new_parent->children_observer, node);
|
||||
|
@ -1306,6 +1306,9 @@ typedef enum {
|
||||
* @GTK_ACCESSIBLE_ROLE_WIDGET: An interactive component of a graphical user
|
||||
* interface. This is the role that GTK uses by default for widgets.
|
||||
* @GTK_ACCESSIBLE_ROLE_WINDOW: An application window.
|
||||
* @GTK_ACCESSIBLE_ROLE_TOGGLE_BUTTON: A type of push button
|
||||
* which stays pressed until depressed by a second activation.
|
||||
* Since: 4.10
|
||||
*
|
||||
* The accessible role for a [iface@Accessible] implementation.
|
||||
*
|
||||
@ -1390,7 +1393,8 @@ typedef enum {
|
||||
GTK_ACCESSIBLE_ROLE_TREE_GRID,
|
||||
GTK_ACCESSIBLE_ROLE_TREE_ITEM,
|
||||
GTK_ACCESSIBLE_ROLE_WIDGET,
|
||||
GTK_ACCESSIBLE_ROLE_WINDOW
|
||||
GTK_ACCESSIBLE_ROLE_WINDOW,
|
||||
GTK_ACCESSIBLE_ROLE_TOGGLE_BUTTON
|
||||
} GtkAccessibleRole;
|
||||
|
||||
/**
|
||||
|
@ -328,7 +328,6 @@ struct _GtkFileChooserWidget
|
||||
guint show_type_column : 1;
|
||||
guint create_folders : 1;
|
||||
guint auto_selecting_first_row : 1;
|
||||
guint starting_search : 1;
|
||||
guint browse_files_interaction_frozen : 1;
|
||||
};
|
||||
|
||||
@ -638,25 +637,36 @@ _gtk_file_chooser_extract_recent_folders (GList *infos)
|
||||
for (l = infos; l; l = l->next)
|
||||
{
|
||||
GtkRecentInfo *info = l->data;
|
||||
const char *uri;
|
||||
GFile *parent;
|
||||
const char *uri, *mime_type;
|
||||
GFile *dir;
|
||||
GFile *file;
|
||||
|
||||
if (!gtk_recent_info_is_local (info))
|
||||
continue;
|
||||
|
||||
uri = gtk_recent_info_get_uri (info);
|
||||
|
||||
file = g_file_new_for_uri (uri);
|
||||
parent = g_file_get_parent (file);
|
||||
g_object_unref (file);
|
||||
|
||||
if (parent)
|
||||
mime_type = gtk_recent_info_get_mime_type (info);
|
||||
if (strcmp (mime_type, "inode/directory") != 0)
|
||||
{
|
||||
if (!g_hash_table_lookup (folders, parent))
|
||||
dir = g_file_get_parent (file);
|
||||
g_object_unref (file);
|
||||
}
|
||||
else
|
||||
{
|
||||
dir = file;
|
||||
}
|
||||
|
||||
if (dir)
|
||||
{
|
||||
if (!g_hash_table_lookup (folders, dir))
|
||||
{
|
||||
g_hash_table_insert (folders, parent, (gpointer) 1);
|
||||
result = g_list_prepend (result, g_object_ref (parent));
|
||||
g_hash_table_insert (folders, dir, (gpointer) 1);
|
||||
result = g_list_prepend (result, g_object_ref (dir));
|
||||
}
|
||||
|
||||
g_object_unref (parent);
|
||||
g_object_unref (dir);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2061,6 +2071,9 @@ file_chooser_get_location (GtkFileChooserWidget *impl,
|
||||
else
|
||||
location = g_file_get_path (dir_location);
|
||||
|
||||
if (!location)
|
||||
location = g_strdup ("");
|
||||
|
||||
g_clear_object (&dir_location);
|
||||
g_clear_object (&home_location);
|
||||
|
||||
@ -2660,6 +2673,16 @@ location_bar_update (GtkFileChooserWidget *impl)
|
||||
gtk_widget_set_visible (impl->browse_new_folder_button, create_folder_visible);
|
||||
}
|
||||
|
||||
static void
|
||||
search_clear_engine (GtkFileChooserWidget *impl)
|
||||
{
|
||||
if (impl->search_engine)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_data (impl->search_engine, impl);
|
||||
g_clear_object (&impl->search_engine);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
operation_mode_stop (GtkFileChooserWidget *impl,
|
||||
OperationMode mode)
|
||||
@ -2670,6 +2693,7 @@ operation_mode_stop (GtkFileChooserWidget *impl,
|
||||
search_stop_searching (impl, TRUE);
|
||||
search_clear_model (impl, TRUE);
|
||||
gtk_widget_set_visible (impl->remote_warning_bar, FALSE);
|
||||
search_clear_engine (impl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3073,6 +3097,7 @@ cancel_all_operations (GtkFileChooserWidget *impl)
|
||||
g_clear_object (&impl->file_exists_get_info_cancellable);
|
||||
|
||||
search_stop_searching (impl, TRUE);
|
||||
search_clear_engine (impl);
|
||||
}
|
||||
|
||||
static void sorter_changed (GtkSorter *main_sorter,
|
||||
@ -3549,9 +3574,12 @@ show_and_select_files (GtkFileChooserWidget *impl,
|
||||
|
||||
if (!g_file_info_get_attribute_boolean (info, "filechooser::visible"))
|
||||
{
|
||||
gboolean has_is_hidden = g_file_info_has_attribute (info, "standard::is-hidden");
|
||||
gboolean has_is_backup = g_file_info_has_attribute (info, "standard::is-backup");
|
||||
|
||||
if (!enabled_hidden &&
|
||||
(g_file_info_get_is_hidden (info) ||
|
||||
g_file_info_get_is_backup (info)))
|
||||
((has_is_hidden && g_file_info_get_is_hidden (info)) ||
|
||||
(has_is_backup && g_file_info_get_is_backup (info))))
|
||||
{
|
||||
set_show_hidden (impl, TRUE);
|
||||
enabled_hidden = TRUE;
|
||||
@ -5768,8 +5796,6 @@ search_stop_searching (GtkFileChooserWidget *impl,
|
||||
if (impl->search_engine)
|
||||
{
|
||||
_gtk_search_engine_stop (impl->search_engine);
|
||||
g_signal_handlers_disconnect_by_data (impl->search_engine, impl);
|
||||
g_clear_object (&impl->search_engine);
|
||||
|
||||
set_busy_cursor (impl, FALSE);
|
||||
gtk_widget_set_visible (impl->search_spinner, FALSE);
|
||||
@ -5894,11 +5920,12 @@ static void
|
||||
search_entry_stop_cb (GtkFileChooserWidget *impl)
|
||||
{
|
||||
if (impl->search_engine)
|
||||
search_stop_searching (impl, FALSE);
|
||||
{
|
||||
search_stop_searching (impl, FALSE);
|
||||
search_clear_engine (impl);
|
||||
}
|
||||
else
|
||||
g_object_set (impl, "search-mode", FALSE, NULL);
|
||||
|
||||
impl->starting_search = FALSE;
|
||||
}
|
||||
|
||||
/* Hides the path bar and creates the search entry */
|
||||
@ -5977,6 +6004,9 @@ recent_start_loading (GtkFileChooserWidget *impl)
|
||||
GtkRecentInfo *info = l->data;
|
||||
GFile *file;
|
||||
|
||||
if (!gtk_recent_info_is_local (info))
|
||||
continue;
|
||||
|
||||
if (gtk_recent_info_get_private_hint (info) &&
|
||||
!gtk_recent_info_has_application (info, app_name))
|
||||
continue;
|
||||
@ -6983,15 +7013,20 @@ location_sort_func (gconstpointer a,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkFileChooserWidget *impl = user_data;
|
||||
char *location_a, *location_b;
|
||||
char *key_a, *key_b;
|
||||
GtkOrdering result;
|
||||
|
||||
/* FIXME: use sortkeys for these */
|
||||
key_a = g_utf8_collate_key_for_filename (file_chooser_get_location (impl, (GFileInfo *)a), -1);
|
||||
key_b = g_utf8_collate_key_for_filename (file_chooser_get_location (impl, (GFileInfo *)b), -1);
|
||||
location_a = file_chooser_get_location (impl, (GFileInfo *)a);
|
||||
location_b = file_chooser_get_location (impl, (GFileInfo *)b);
|
||||
key_a = g_utf8_collate_key_for_filename (location_a, -1);
|
||||
key_b = g_utf8_collate_key_for_filename (location_b, -1);
|
||||
|
||||
result = g_strcmp0 (key_a, key_b);
|
||||
|
||||
g_free (location_a);
|
||||
g_free (location_b);
|
||||
g_free (key_a);
|
||||
g_free (key_b);
|
||||
|
||||
|
@ -209,13 +209,18 @@ node_should_be_visible (GtkFileSystemModel *model,
|
||||
gboolean filtered_out)
|
||||
{
|
||||
FileModelNode *node = get_node (model, id);
|
||||
gboolean has_is_hidden;
|
||||
gboolean has_is_backup;
|
||||
gboolean result;
|
||||
|
||||
if (node->info == NULL)
|
||||
return FALSE;
|
||||
|
||||
has_is_hidden = g_file_info_has_attribute (node->info, "standard::is-hidden");
|
||||
has_is_backup = g_file_info_has_attribute (node->info, "standard::is-backup");
|
||||
if (!model->show_hidden &&
|
||||
(g_file_info_get_is_hidden (node->info) || g_file_info_get_is_backup (node->info)))
|
||||
((has_is_hidden && g_file_info_get_is_hidden (node->info)) ||
|
||||
(has_is_backup && g_file_info_get_is_backup (node->info))))
|
||||
return FALSE;
|
||||
|
||||
if (_gtk_file_info_consider_as_directory (node->info))
|
||||
@ -459,7 +464,7 @@ remove_file (GtkFileSystemModel *model,
|
||||
g_return_if_fail (G_IS_FILE (file));
|
||||
|
||||
id = node_get_for_file (model, file);
|
||||
if (id == 0)
|
||||
if (id == GTK_INVALID_LIST_POSITION)
|
||||
return;
|
||||
|
||||
node = get_node (model, id);
|
||||
@ -941,7 +946,7 @@ _gtk_file_system_model_set_filter_folders (GtkFileSystemModel *model,
|
||||
* @model: the model
|
||||
*
|
||||
* Gets the cancellable used by the @model. This is the cancellable used
|
||||
* internally by the @model that will be cancelled when @model is
|
||||
* internally by the @model that will be cancelled when @model is
|
||||
* disposed. So you can use it for operations that should be cancelled
|
||||
* when the model goes away.
|
||||
*
|
||||
@ -1005,7 +1010,7 @@ _gtk_file_system_model_update_files (GtkFileSystemModel *model,
|
||||
* _gtk_file_system_model_set_filter:
|
||||
* @mode: a `GtkFileSystemModel`
|
||||
* @filter: (nullable): %NULL or filter to use
|
||||
*
|
||||
*
|
||||
* Sets a filter to be used for deciding if a row should be visible or not.
|
||||
* Whether this filter applies to directories can be toggled with
|
||||
* _gtk_file_system_model_set_filter_folders().
|
||||
@ -1028,7 +1033,7 @@ _gtk_file_system_model_set_filter (GtkFileSystemModel *model,
|
||||
* @file: the file to add
|
||||
* @attributes: attributes to query before adding the file
|
||||
*
|
||||
* This is a convenience function that calls g_file_query_info_async() on
|
||||
* This is a convenience function that calls g_file_query_info_async() on
|
||||
* the given file, and when successful, adds it to the model.
|
||||
* Upon failure, the @file is discarded.
|
||||
**/
|
||||
|
@ -78,7 +78,10 @@ update_image (GtkFileThumbnail *self)
|
||||
int scale;
|
||||
|
||||
if (!g_file_info_has_attribute (self->info, G_FILE_ATTRIBUTE_STANDARD_ICON))
|
||||
return FALSE;
|
||||
{
|
||||
gtk_image_clear (GTK_IMAGE (self->image));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
scale = gtk_widget_get_scale_factor (GTK_WIDGET (self));
|
||||
icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (self)));
|
||||
@ -91,7 +94,6 @@ update_image (GtkFileThumbnail *self)
|
||||
g_object_unref (icon);
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@ -102,10 +104,19 @@ thumbnail_queried_cb (GObject *object,
|
||||
GtkFileThumbnail *self = user_data; /* might be unreffed if operation was cancelled */
|
||||
GFile *file = G_FILE (object);
|
||||
GFileInfo *queried;
|
||||
GError *error = NULL;
|
||||
|
||||
queried = g_file_query_info_finish (file, result, NULL);
|
||||
if (queried == NULL)
|
||||
return;
|
||||
queried = g_file_query_info_finish (file, result, &error);
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_file_info_set_attribute_boolean (self->info, "filechooser::queried", TRUE);
|
||||
g_clear_error (&error);
|
||||
return;
|
||||
}
|
||||
|
||||
g_file_info_set_attribute_boolean (self->info, "filechooser::queried", TRUE);
|
||||
|
||||
copy_attribute (self->info, queried, G_FILE_ATTRIBUTE_THUMBNAIL_PATH);
|
||||
copy_attribute (self->info, queried, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED);
|
||||
@ -129,7 +140,10 @@ static void
|
||||
get_thumbnail (GtkFileThumbnail *self)
|
||||
{
|
||||
if (!self->info)
|
||||
return;
|
||||
{
|
||||
gtk_image_clear (GTK_IMAGE (self->image));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!update_image (self))
|
||||
{
|
||||
@ -142,7 +156,6 @@ get_thumbnail (GtkFileThumbnail *self)
|
||||
self->cancellable = g_cancellable_new ();
|
||||
|
||||
file = _gtk_file_info_get_file (self->info);
|
||||
g_file_info_set_attribute_boolean (self->info, "filechooser::queried", TRUE);
|
||||
g_file_query_info_async (file,
|
||||
G_FILE_ATTRIBUTE_THUMBNAIL_PATH ","
|
||||
G_FILE_ATTRIBUTE_THUMBNAILING_FAILED ","
|
||||
|
@ -82,9 +82,6 @@
|
||||
* use the %GTK_ACCESSIBLE_ROLE_GRID_CELL role.
|
||||
*/
|
||||
|
||||
typedef struct _Cell Cell;
|
||||
typedef struct _CellAugment CellAugment;
|
||||
|
||||
struct _GtkGridView
|
||||
{
|
||||
GtkListBase parent_instance;
|
||||
@ -94,7 +91,6 @@ struct _GtkGridView
|
||||
guint max_columns;
|
||||
/* set in size_allocate */
|
||||
guint n_columns;
|
||||
int unknown_row_height;
|
||||
double column_width;
|
||||
};
|
||||
|
||||
@ -103,18 +99,6 @@ struct _GtkGridViewClass
|
||||
GtkListBaseClass parent_class;
|
||||
};
|
||||
|
||||
struct _Cell
|
||||
{
|
||||
GtkListItemManagerItem parent;
|
||||
guint size; /* total, only counting cells in first column */
|
||||
};
|
||||
|
||||
struct _CellAugment
|
||||
{
|
||||
GtkListItemManagerItemAugment parent;
|
||||
guint size; /* total, only counting first column */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
@ -141,333 +125,216 @@ static guint signals[LAST_SIGNAL] = { 0 };
|
||||
static void G_GNUC_UNUSED
|
||||
dump (GtkGridView *self)
|
||||
{
|
||||
Cell *cell;
|
||||
GtkListTile *tile;
|
||||
guint n_widgets, n_list_rows, n_items;
|
||||
|
||||
n_widgets = 0;
|
||||
n_list_rows = 0;
|
||||
n_items = 0;
|
||||
//g_print ("ANCHOR: %u - %u\n", self->anchor_start, self->anchor_end);
|
||||
for (cell = gtk_list_item_manager_get_first (self->item_manager);
|
||||
cell;
|
||||
cell = gtk_rb_tree_node_get_next (cell))
|
||||
for (tile = gtk_list_item_manager_get_first (self->item_manager);
|
||||
tile;
|
||||
tile = gtk_rb_tree_node_get_next (tile))
|
||||
{
|
||||
if (cell->parent.widget)
|
||||
if (tile->widget)
|
||||
n_widgets++;
|
||||
n_list_rows++;
|
||||
n_items += cell->parent.n_items;
|
||||
g_print ("%6u%6u %5ux%3u %s (%upx)\n",
|
||||
cell->parent.n_items, n_items,
|
||||
n_items += tile->n_items;
|
||||
g_print ("%6u%6u %5ux%3u %s (%d,%d,%d,%d)\n",
|
||||
tile->n_items, n_items,
|
||||
n_items / (self->n_columns ? self->n_columns : self->min_columns),
|
||||
n_items % (self->n_columns ? self->n_columns : self->min_columns),
|
||||
cell->parent.widget ? " (widget)" : "", cell->size);
|
||||
tile->widget ? " (widget)" : "",
|
||||
tile->area.x, tile->area.y, tile->area.width, tile->area.height);
|
||||
}
|
||||
|
||||
g_print (" => %u widgets in %u list rows\n", n_widgets, n_list_rows);
|
||||
}
|
||||
|
||||
static void
|
||||
cell_augment (GtkRbTree *tree,
|
||||
gpointer node_augment,
|
||||
gpointer node,
|
||||
gpointer left,
|
||||
gpointer right)
|
||||
static GtkListTile *
|
||||
gtk_grid_view_split (GtkListBase *base,
|
||||
GtkListTile *tile,
|
||||
guint n_items)
|
||||
{
|
||||
Cell *cell = node;
|
||||
CellAugment *aug = node_augment;
|
||||
GtkGridView *self = GTK_GRID_VIEW (base);
|
||||
GtkListTile *split;
|
||||
guint col, row_height;
|
||||
|
||||
gtk_list_item_manager_augment_node (tree, node_augment, node, left, right);
|
||||
row_height = tile->area.height / MAX (tile->n_items / self->n_columns, 1);
|
||||
|
||||
aug->size = cell->size;
|
||||
|
||||
if (left)
|
||||
/* split off the multirow at the top */
|
||||
if (n_items >= self->n_columns)
|
||||
{
|
||||
CellAugment *left_aug = gtk_rb_tree_get_augment (tree, left);
|
||||
guint top_rows = n_items / self->n_columns;
|
||||
guint top_items = top_rows * self->n_columns;
|
||||
|
||||
aug->size += left_aug->size;
|
||||
split = tile;
|
||||
tile = gtk_list_tile_split (self->item_manager, tile, top_items);
|
||||
gtk_list_tile_set_area (self->item_manager,
|
||||
tile,
|
||||
&(GdkRectangle) {
|
||||
split->area.x,
|
||||
split->area.y + row_height * top_rows,
|
||||
split->area.width,
|
||||
split->area.height - row_height * top_rows,
|
||||
});
|
||||
gtk_list_tile_set_area_size (self->item_manager,
|
||||
split,
|
||||
split->area.width,
|
||||
row_height * top_rows);
|
||||
n_items -= top_items;
|
||||
if (n_items == 0)
|
||||
return tile;
|
||||
}
|
||||
|
||||
if (right)
|
||||
/* split off the multirow at the bottom */
|
||||
if (tile->n_items > self->n_columns)
|
||||
{
|
||||
CellAugment *right_aug = gtk_rb_tree_get_augment (tree, right);
|
||||
|
||||
aug->size += right_aug->size;
|
||||
}
|
||||
}
|
||||
|
||||
/*<private>
|
||||
* gtk_grid_view_get_cell_at_y:
|
||||
* @self: a `GtkGridView`
|
||||
* @y: an offset in direction of @self's orientation
|
||||
* @position: (out caller-allocates) (optional): stores the position
|
||||
* index of the returned row
|
||||
* @offset: (out caller-allocates) (optional): stores the offset
|
||||
* in pixels between y and top of cell.
|
||||
* @size: (out caller-allocates) (optional): stores the height
|
||||
* of the cell
|
||||
*
|
||||
* Gets the Cell that occupies the leftmost position in the row at offset
|
||||
* @y into the primary direction.
|
||||
*
|
||||
* If y is larger than the height of all cells, %NULL will be returned.
|
||||
* In particular that means that for an empty grid, %NULL is returned
|
||||
* for any value.
|
||||
*
|
||||
* Returns: (nullable): The first cell at offset y
|
||||
**/
|
||||
static Cell *
|
||||
gtk_grid_view_get_cell_at_y (GtkGridView *self,
|
||||
int y,
|
||||
guint *position,
|
||||
int *offset,
|
||||
int *size)
|
||||
{
|
||||
Cell *cell, *tmp;
|
||||
guint pos;
|
||||
|
||||
cell = gtk_list_item_manager_get_root (self->item_manager);
|
||||
pos = 0;
|
||||
|
||||
while (cell)
|
||||
{
|
||||
tmp = gtk_rb_tree_node_get_left (cell);
|
||||
if (tmp)
|
||||
{
|
||||
CellAugment *aug = gtk_list_item_manager_get_item_augment (self->item_manager, tmp);
|
||||
if (y < aug->size)
|
||||
{
|
||||
cell = tmp;
|
||||
continue;
|
||||
}
|
||||
y -= aug->size;
|
||||
pos += aug->parent.n_items;
|
||||
}
|
||||
|
||||
if (y < cell->size)
|
||||
break;
|
||||
y -= cell->size;
|
||||
pos += cell->parent.n_items;
|
||||
|
||||
cell = gtk_rb_tree_node_get_right (cell);
|
||||
split = gtk_list_tile_split (self->item_manager, tile, self->n_columns);
|
||||
gtk_list_tile_set_area (self->item_manager,
|
||||
split,
|
||||
&(GdkRectangle) {
|
||||
tile->area.x,
|
||||
tile->area.y + row_height,
|
||||
tile->area.width,
|
||||
tile->area.height - row_height,
|
||||
});
|
||||
gtk_list_tile_set_area_size (self->item_manager,
|
||||
tile,
|
||||
tile->area.width,
|
||||
row_height);
|
||||
}
|
||||
|
||||
if (cell == NULL)
|
||||
{
|
||||
if (position)
|
||||
*position = 0;
|
||||
if (offset)
|
||||
*offset = 0;
|
||||
if (size)
|
||||
*size = 0;
|
||||
return NULL;
|
||||
}
|
||||
g_assert (n_items < tile->n_items);
|
||||
g_assert (tile->n_items <= self->n_columns);
|
||||
|
||||
/* We know have the (range of) cell(s) that contains this offset.
|
||||
* Now for the hard part of computing which index this actually is.
|
||||
*/
|
||||
if (offset || position || size)
|
||||
{
|
||||
guint n_items = cell->parent.n_items;
|
||||
guint no_widget_rows, skip;
|
||||
|
||||
/* skip remaining items at end of row */
|
||||
if (pos % self->n_columns)
|
||||
{
|
||||
skip = self->n_columns - pos % self->n_columns;
|
||||
if (n_items <= skip)
|
||||
{
|
||||
g_warning ("ran out of items");
|
||||
if (position)
|
||||
*position = 0;
|
||||
if (offset)
|
||||
*offset = 0;
|
||||
if (size)
|
||||
*size = 0;
|
||||
return NULL;
|
||||
}
|
||||
n_items -= skip;
|
||||
pos += skip;
|
||||
}
|
||||
|
||||
/* Skip all the rows this index doesn't go into */
|
||||
no_widget_rows = (n_items - 1) / self->n_columns;
|
||||
skip = MIN (y / self->unknown_row_height, no_widget_rows);
|
||||
y -= skip * self->unknown_row_height;
|
||||
pos += self->n_columns * skip;
|
||||
|
||||
if (position)
|
||||
*position = pos;
|
||||
if (offset)
|
||||
*offset = y;
|
||||
if (size)
|
||||
{
|
||||
if (skip < no_widget_rows)
|
||||
*size = self->unknown_row_height;
|
||||
else
|
||||
*size = cell->size - no_widget_rows * self->unknown_row_height;
|
||||
}
|
||||
}
|
||||
|
||||
return cell;
|
||||
/* now it's a single row, do a split at the column boundary */
|
||||
col = tile->area.x / self->column_width;
|
||||
split = gtk_list_tile_split (self->item_manager, tile, n_items);
|
||||
gtk_list_tile_set_area (self->item_manager,
|
||||
split,
|
||||
&(GdkRectangle) {
|
||||
ceil ((col + n_items) * self->column_width),
|
||||
tile->area.y,
|
||||
ceil ((col + n_items + split->n_items) * self->column_width),
|
||||
tile->area.height,
|
||||
});
|
||||
gtk_list_tile_set_area_size (self->item_manager,
|
||||
tile,
|
||||
ceil ((col + n_items) * self->column_width) - tile->area.x,
|
||||
tile->area.height);
|
||||
|
||||
return split;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_grid_view_get_allocation_along (GtkListBase *base,
|
||||
guint pos,
|
||||
int *offset,
|
||||
int *size)
|
||||
gtk_grid_view_get_allocation (GtkListBase *base,
|
||||
guint pos,
|
||||
GdkRectangle *area)
|
||||
{
|
||||
GtkGridView *self = GTK_GRID_VIEW (base);
|
||||
Cell *cell, *tmp;
|
||||
int y;
|
||||
GtkListTile *tile;
|
||||
guint offset;
|
||||
|
||||
cell = gtk_list_item_manager_get_root (self->item_manager);
|
||||
y = 0;
|
||||
pos -= pos % self->n_columns;
|
||||
tile = gtk_list_item_manager_get_nth (self->item_manager, pos, &offset);
|
||||
if (tile == NULL || tile->area.width <= 0 || tile->area.height <= 0)
|
||||
return FALSE;
|
||||
|
||||
while (cell)
|
||||
*area = tile->area;
|
||||
|
||||
if (tile->n_items > self->n_columns)
|
||||
{
|
||||
tmp = gtk_rb_tree_node_get_left (cell);
|
||||
if (tmp)
|
||||
{
|
||||
CellAugment *aug = gtk_list_item_manager_get_item_augment (self->item_manager, tmp);
|
||||
if (pos < aug->parent.n_items)
|
||||
{
|
||||
cell = tmp;
|
||||
continue;
|
||||
}
|
||||
pos -= aug->parent.n_items;
|
||||
y += aug->size;
|
||||
}
|
||||
|
||||
if (pos < cell->parent.n_items)
|
||||
break;
|
||||
y += cell->size;
|
||||
pos -= cell->parent.n_items;
|
||||
|
||||
cell = gtk_rb_tree_node_get_right (cell);
|
||||
area->height /= (tile->n_items / self->n_columns);
|
||||
area->y += (offset / self->n_columns) * area->height;
|
||||
offset %= self->n_columns;
|
||||
}
|
||||
|
||||
if (cell == NULL)
|
||||
if (tile->n_items > 1)
|
||||
{
|
||||
if (offset)
|
||||
*offset = 0;
|
||||
if (size)
|
||||
*size = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* We know have the (range of) cell(s) that contains this offset.
|
||||
* Now for the hard part of computing which index this actually is.
|
||||
*/
|
||||
if (offset || size)
|
||||
{
|
||||
guint n_items = cell->parent.n_items;
|
||||
guint skip;
|
||||
|
||||
/* skip remaining items at end of row */
|
||||
if (pos % self->n_columns)
|
||||
{
|
||||
skip = pos % self->n_columns;
|
||||
n_items -= skip;
|
||||
pos -= skip;
|
||||
}
|
||||
|
||||
/* Skip all the rows this index doesn't go into */
|
||||
skip = pos / self->n_columns;
|
||||
n_items -= skip * self->n_columns;
|
||||
y += skip * self->unknown_row_height;
|
||||
|
||||
if (offset)
|
||||
*offset = y;
|
||||
if (size)
|
||||
{
|
||||
if (n_items > self->n_columns)
|
||||
*size = self->unknown_row_height;
|
||||
else
|
||||
*size = cell->size - skip * self->unknown_row_height;
|
||||
}
|
||||
guint col = area->x / self->column_width;
|
||||
area->x = ceil ((col + offset) * self->column_width);
|
||||
area->width = ceil ((col + offset + 1) * self->column_width) - area->x;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_grid_view_get_allocation_across (GtkListBase *base,
|
||||
guint pos,
|
||||
int *offset,
|
||||
int *size)
|
||||
{
|
||||
GtkGridView *self = GTK_GRID_VIEW (base);
|
||||
guint start;
|
||||
|
||||
pos %= self->n_columns;
|
||||
start = ceil (self->column_width * pos);
|
||||
|
||||
if (offset)
|
||||
*offset = start;
|
||||
if (size)
|
||||
*size = ceil (self->column_width * (pos + 1)) - start;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int
|
||||
gtk_grid_view_compute_total_height (GtkGridView *self)
|
||||
{
|
||||
Cell *cell;
|
||||
CellAugment *aug;
|
||||
|
||||
cell = gtk_list_item_manager_get_root (self->item_manager);
|
||||
if (cell == NULL)
|
||||
return 0;
|
||||
aug = gtk_list_item_manager_get_item_augment (self->item_manager, cell);
|
||||
return aug->size;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_grid_view_get_position_from_allocation (GtkListBase *base,
|
||||
int across,
|
||||
int along,
|
||||
int x,
|
||||
int y,
|
||||
guint *position,
|
||||
cairo_rectangle_int_t *area)
|
||||
{
|
||||
GtkGridView *self = GTK_GRID_VIEW (base);
|
||||
int offset, size;
|
||||
guint pos, n_items;
|
||||
GtkListTile *tile;
|
||||
guint pos;
|
||||
GdkRectangle bounds;
|
||||
|
||||
if (across >= self->column_width * self->n_columns)
|
||||
gtk_list_item_manager_get_tile_bounds (self->item_manager, &bounds);
|
||||
if (bounds.width <= 0 || bounds.height <= 0)
|
||||
return FALSE;
|
||||
x = CLAMP (x, bounds.x, bounds.x + bounds.width - 1);
|
||||
y = CLAMP (y, bounds.y, bounds.y + bounds.height - 1);
|
||||
|
||||
tile = gtk_list_item_manager_get_tile_at (self->item_manager, x, y);
|
||||
if (tile == NULL)
|
||||
return FALSE;
|
||||
|
||||
n_items = gtk_list_base_get_n_items (base);
|
||||
along = CLAMP (along, 0, gtk_grid_view_compute_total_height (self) - 1);
|
||||
across = across < 0 ? 0 : across;
|
||||
|
||||
if (!gtk_grid_view_get_cell_at_y (self,
|
||||
along,
|
||||
&pos,
|
||||
&offset,
|
||||
&size))
|
||||
return FALSE;
|
||||
|
||||
pos += floor (across / self->column_width);
|
||||
|
||||
if (pos >= n_items)
|
||||
while (tile && tile->n_items == 0)
|
||||
tile = gtk_rb_tree_node_get_previous (tile);
|
||||
if (tile == NULL)
|
||||
{
|
||||
/* Ugh, we're in the last row and don't have enough items
|
||||
* to fill the row.
|
||||
* Do it the hard way then... */
|
||||
pos = n_items - 1;
|
||||
tile = gtk_list_item_manager_get_first (self->item_manager);
|
||||
while (tile && tile->n_items == 0)
|
||||
tile = gtk_rb_tree_node_get_next (tile);
|
||||
if (tile == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pos = gtk_list_tile_get_position (self->item_manager, tile);
|
||||
if (tile->n_items > 1)
|
||||
{
|
||||
/* offset in x direction */
|
||||
pos += (x - tile->area.x) / self->column_width;
|
||||
if (area)
|
||||
{
|
||||
guint col = MIN (x / self->column_width, self->n_columns - 1);
|
||||
area->x = ceil (col * self->column_width);
|
||||
area->width = ceil ((col + 1) * self->column_width) - area->x;
|
||||
}
|
||||
|
||||
/* offset in y direction */
|
||||
if (tile->n_items > self->n_columns)
|
||||
{
|
||||
guint rows_in_tile = tile->n_items / self->n_columns;
|
||||
guint row_height = tile->area.height / rows_in_tile;
|
||||
guint row_index = (y - tile->area.y) / row_height;
|
||||
pos += self->n_columns * row_index;
|
||||
|
||||
if (area)
|
||||
{
|
||||
area->y = tile->area.y + row_index * row_height;
|
||||
area->height = row_height;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (area)
|
||||
{
|
||||
area->y = tile->area.y;
|
||||
area->height = tile->area.height;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (area)
|
||||
*area = tile->area;
|
||||
}
|
||||
|
||||
*position = pos;
|
||||
if (area)
|
||||
{
|
||||
area->x = ceil (self->column_width * (pos % self->n_columns));
|
||||
area->width = ceil (self->column_width * (1 + pos % self->n_columns)) - area->x;
|
||||
area->y = along - offset;
|
||||
area->height = size;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -477,24 +344,24 @@ gtk_grid_view_get_items_in_rect (GtkListBase *base,
|
||||
const GdkRectangle *rect)
|
||||
{
|
||||
GtkGridView *self = GTK_GRID_VIEW (base);
|
||||
guint first_row, last_row, first_column, last_column, n_items;
|
||||
guint first_row, last_row, first_column, last_column;
|
||||
GdkRectangle bounds;
|
||||
GtkBitset *result;
|
||||
|
||||
result = gtk_bitset_new_empty ();
|
||||
|
||||
if (rect->y >= gtk_grid_view_compute_total_height (self))
|
||||
/* limit rect to the region that actually overlaps items */
|
||||
gtk_list_item_manager_get_tile_bounds (self->item_manager, &bounds);
|
||||
if (!gdk_rectangle_intersect (&bounds, rect, &bounds))
|
||||
return result;
|
||||
|
||||
n_items = gtk_list_base_get_n_items (base);
|
||||
if (n_items == 0)
|
||||
return result;
|
||||
|
||||
first_column = fmax (floor (rect->x / self->column_width), 0);
|
||||
last_column = fmin (floor ((rect->x + rect->width) / self->column_width), self->n_columns - 1);
|
||||
if (!gtk_grid_view_get_cell_at_y (self, rect->y, &first_row, NULL, NULL))
|
||||
first_row = rect->y < 0 ? 0 : n_items - 1;
|
||||
if (!gtk_grid_view_get_cell_at_y (self, rect->y + rect->height, &last_row, NULL, NULL))
|
||||
last_row = rect->y + rect->height < 0 ? 0 : n_items - 1;
|
||||
first_column = fmax (floor (bounds.x / self->column_width), 0);
|
||||
last_column = fmin (floor ((bounds.x + bounds.width) / self->column_width), self->n_columns - 1);
|
||||
/* match y = 0 here because we care about the rows, not the cells */
|
||||
if (!gtk_grid_view_get_position_from_allocation (base, 0, bounds.y, &first_row, NULL))
|
||||
g_return_val_if_reached (result);
|
||||
if (!gtk_grid_view_get_position_from_allocation (base, 0, bounds.y + bounds.height - 1, &last_row, NULL))
|
||||
g_return_val_if_reached (result);
|
||||
|
||||
gtk_bitset_add_rectangle (result,
|
||||
first_row + first_column,
|
||||
@ -570,22 +437,21 @@ gtk_grid_view_measure_column_size (GtkGridView *self,
|
||||
int *natural)
|
||||
{
|
||||
GtkOrientation opposite;
|
||||
Cell *cell;
|
||||
GtkListTile *tile;
|
||||
int min, nat, child_min, child_nat;
|
||||
|
||||
min = 0;
|
||||
nat = 0;
|
||||
opposite = gtk_list_base_get_opposite_orientation (GTK_LIST_BASE (self));
|
||||
|
||||
for (cell = gtk_list_item_manager_get_first (self->item_manager);
|
||||
cell != NULL;
|
||||
cell = gtk_rb_tree_node_get_next (cell))
|
||||
for (tile = gtk_list_item_manager_get_first (self->item_manager);
|
||||
tile != NULL;
|
||||
tile = gtk_rb_tree_node_get_next (tile))
|
||||
{
|
||||
/* ignore unavailable cells */
|
||||
if (cell->parent.widget == NULL)
|
||||
if (tile->widget == NULL)
|
||||
continue;
|
||||
|
||||
gtk_widget_measure (cell->parent.widget,
|
||||
gtk_widget_measure (tile->widget,
|
||||
opposite, -1,
|
||||
&child_min, &child_nat, NULL, NULL);
|
||||
min = MAX (min, child_min);
|
||||
@ -640,7 +506,7 @@ gtk_grid_view_measure_list (GtkWidget *widget,
|
||||
{
|
||||
GtkGridView *self = GTK_GRID_VIEW (widget);
|
||||
GtkScrollablePolicy scroll_policy;
|
||||
Cell *cell;
|
||||
GtkListTile *tile;
|
||||
int height, row_height, child_min, child_nat, column_size, col_min, col_nat;
|
||||
gboolean measured;
|
||||
GArray *heights;
|
||||
@ -660,13 +526,13 @@ gtk_grid_view_measure_list (GtkWidget *widget,
|
||||
i = 0;
|
||||
row_height = 0;
|
||||
measured = FALSE;
|
||||
for (cell = gtk_list_item_manager_get_first (self->item_manager);
|
||||
cell != NULL;
|
||||
cell = gtk_rb_tree_node_get_next (cell))
|
||||
for (tile = gtk_list_item_manager_get_first (self->item_manager);
|
||||
tile != NULL;
|
||||
tile = gtk_rb_tree_node_get_next (tile))
|
||||
{
|
||||
if (cell->parent.widget)
|
||||
if (tile->widget)
|
||||
{
|
||||
gtk_widget_measure (cell->parent.widget,
|
||||
gtk_widget_measure (tile->widget,
|
||||
gtk_list_base_get_orientation (GTK_LIST_BASE (self)),
|
||||
column_size,
|
||||
&child_min, &child_nat, NULL, NULL);
|
||||
@ -677,7 +543,7 @@ gtk_grid_view_measure_list (GtkWidget *widget,
|
||||
measured = TRUE;
|
||||
}
|
||||
|
||||
i += cell->parent.n_items;
|
||||
i += tile->n_items;
|
||||
|
||||
if (i >= n_columns)
|
||||
{
|
||||
@ -731,17 +597,6 @@ gtk_grid_view_measure (GtkWidget *widget,
|
||||
gtk_grid_view_measure_across (widget, for_size, minimum, natural);
|
||||
}
|
||||
|
||||
static void
|
||||
cell_set_size (Cell *cell,
|
||||
guint size)
|
||||
{
|
||||
if (cell->size == size)
|
||||
return;
|
||||
|
||||
cell->size = size;
|
||||
gtk_rb_tree_node_mark_dirty (cell);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_grid_view_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
@ -749,24 +604,23 @@ gtk_grid_view_size_allocate (GtkWidget *widget,
|
||||
int baseline)
|
||||
{
|
||||
GtkGridView *self = GTK_GRID_VIEW (widget);
|
||||
Cell *cell, *start;
|
||||
GtkListTile *tile, *start;
|
||||
GArray *heights;
|
||||
int min_row_height, row_height, col_min, col_nat;
|
||||
GtkOrientation orientation, opposite_orientation;
|
||||
int min_row_height, unknown_row_height, row_height, col_min, col_nat;
|
||||
GtkOrientation orientation;
|
||||
GtkScrollablePolicy scroll_policy;
|
||||
gboolean known;
|
||||
int x, y;
|
||||
int y;
|
||||
guint i;
|
||||
|
||||
orientation = gtk_list_base_get_orientation (GTK_LIST_BASE (self));
|
||||
scroll_policy = gtk_list_base_get_scroll_policy (GTK_LIST_BASE (self), orientation);
|
||||
opposite_orientation = OPPOSITE_ORIENTATION (orientation);
|
||||
min_row_height = ceil ((double) height / GTK_GRID_VIEW_MAX_VISIBLE_ROWS);
|
||||
|
||||
/* step 0: exit early if list is empty */
|
||||
if (gtk_list_item_manager_get_root (self->item_manager) == NULL)
|
||||
tile = gtk_list_tile_gc (self->item_manager, gtk_list_item_manager_get_first (self->item_manager));
|
||||
if (tile == NULL)
|
||||
{
|
||||
gtk_list_base_update_adjustments (GTK_LIST_BASE (self), 0, 0, 0, 0, &x, &y);
|
||||
gtk_list_base_allocate (GTK_LIST_BASE (self));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -781,149 +635,126 @@ gtk_grid_view_size_allocate (GtkWidget *widget,
|
||||
/* step 2: determine height of known rows */
|
||||
heights = g_array_new (FALSE, FALSE, sizeof (int));
|
||||
|
||||
i = 0;
|
||||
row_height = 0;
|
||||
start = NULL;
|
||||
for (cell = gtk_list_item_manager_get_first (self->item_manager);
|
||||
cell != NULL;
|
||||
cell = gtk_rb_tree_node_get_next (cell))
|
||||
for (;
|
||||
tile != NULL;
|
||||
tile = gtk_list_tile_gc (self->item_manager, tile))
|
||||
{
|
||||
if (i == 0)
|
||||
start = cell;
|
||||
|
||||
if (cell->parent.widget)
|
||||
/* if it's a multirow tile, handle it here */
|
||||
if (tile->n_items > 1 && tile->n_items >= self->n_columns)
|
||||
{
|
||||
int min, nat, size;
|
||||
gtk_widget_measure (cell->parent.widget,
|
||||
gtk_list_base_get_orientation (GTK_LIST_BASE (self)),
|
||||
self->column_width,
|
||||
&min, &nat, NULL, NULL);
|
||||
if (scroll_policy == GTK_SCROLL_MINIMUM)
|
||||
size = min;
|
||||
else
|
||||
size = nat;
|
||||
size = MAX (size, min_row_height);
|
||||
g_array_append_val (heights, size);
|
||||
row_height = MAX (row_height, size);
|
||||
if (tile->n_items % self->n_columns)
|
||||
gtk_list_tile_split (self->item_manager, tile, tile->n_items / self->n_columns * self->n_columns);
|
||||
tile = gtk_rb_tree_node_get_next (tile);
|
||||
continue;
|
||||
}
|
||||
cell_set_size (cell, 0);
|
||||
i += cell->parent.n_items;
|
||||
|
||||
if (i >= self->n_columns)
|
||||
/* Not a multirow tile */
|
||||
i = 0;
|
||||
row_height = 0;
|
||||
|
||||
for (i = 0, start = tile;
|
||||
i < self->n_columns && tile != NULL;
|
||||
tile = gtk_list_tile_gc (self->item_manager, gtk_rb_tree_node_get_next (tile)))
|
||||
{
|
||||
i %= self->n_columns;
|
||||
|
||||
cell_set_size (start, start->size + row_height);
|
||||
start = cell;
|
||||
row_height = 0;
|
||||
if (tile->widget)
|
||||
{
|
||||
int min, nat, size;
|
||||
gtk_widget_measure (tile->widget,
|
||||
gtk_list_base_get_orientation (GTK_LIST_BASE (self)),
|
||||
self->column_width,
|
||||
&min, &nat, NULL, NULL);
|
||||
if (scroll_policy == GTK_SCROLL_MINIMUM)
|
||||
size = min;
|
||||
else
|
||||
size = nat;
|
||||
size = MAX (size, min_row_height);
|
||||
g_array_append_val (heights, size);
|
||||
row_height = MAX (row_height, size);
|
||||
}
|
||||
if (tile->n_items > self->n_columns - i)
|
||||
gtk_list_tile_split (self->item_manager, tile, self->n_columns - i);
|
||||
i += tile->n_items;
|
||||
}
|
||||
if (row_height > 0)
|
||||
{
|
||||
for (i = 0;
|
||||
start != tile;
|
||||
start = gtk_rb_tree_node_get_next (start))
|
||||
{
|
||||
gtk_list_tile_set_area_size (self->item_manager,
|
||||
start,
|
||||
ceil (self->column_width * (i + start->n_items)) - ceil (self->column_width * i),
|
||||
row_height);
|
||||
i += start->n_items;
|
||||
}
|
||||
g_assert (i <= self->n_columns);
|
||||
}
|
||||
}
|
||||
if (i > 0)
|
||||
cell_set_size (start, start->size + row_height);
|
||||
|
||||
/* step 3: determine height of rows with only unknown items */
|
||||
self->unknown_row_height = gtk_grid_view_get_unknown_row_size (self, heights);
|
||||
unknown_row_height = gtk_grid_view_get_unknown_row_size (self, heights);
|
||||
g_array_free (heights, TRUE);
|
||||
|
||||
/* step 4: determine height for remaining rows and set each row's position */
|
||||
y = 0;
|
||||
i = 0;
|
||||
known = FALSE;
|
||||
for (start = cell = gtk_list_item_manager_get_first (self->item_manager);
|
||||
cell != NULL;
|
||||
cell = gtk_rb_tree_node_get_next (cell))
|
||||
for (tile = gtk_list_item_manager_get_first (self->item_manager);
|
||||
tile != NULL;
|
||||
tile = gtk_rb_tree_node_get_next (tile))
|
||||
{
|
||||
if (i == 0)
|
||||
start = cell;
|
||||
|
||||
if (cell->parent.widget)
|
||||
known = TRUE;
|
||||
|
||||
i += cell->parent.n_items;
|
||||
if (i >= self->n_columns)
|
||||
gtk_list_tile_set_area_position (self->item_manager,
|
||||
tile,
|
||||
ceil (self->column_width * i),
|
||||
y);
|
||||
if (tile->n_items >= self->n_columns && tile->widget == NULL)
|
||||
{
|
||||
if (!known)
|
||||
cell_set_size (start, start->size + self->unknown_row_height);
|
||||
|
||||
i -= self->n_columns;
|
||||
known = FALSE;
|
||||
|
||||
if (i >= self->n_columns)
|
||||
{
|
||||
cell_set_size (cell, cell->size + self->unknown_row_height * (i / self->n_columns));
|
||||
i %= self->n_columns;
|
||||
}
|
||||
start = cell;
|
||||
}
|
||||
}
|
||||
if (i > 0 && !known)
|
||||
cell_set_size (start, start->size + self->unknown_row_height);
|
||||
|
||||
/* step 4: update the adjustments */
|
||||
gtk_list_base_update_adjustments (GTK_LIST_BASE (self),
|
||||
self->column_width * self->n_columns,
|
||||
gtk_grid_view_compute_total_height (self),
|
||||
gtk_widget_get_size (widget, opposite_orientation),
|
||||
gtk_widget_get_size (widget, orientation),
|
||||
&x, &y);
|
||||
|
||||
/* step 5: run the size_allocate loop */
|
||||
x = -x;
|
||||
y = -y;
|
||||
i = 0;
|
||||
row_height = 0;
|
||||
|
||||
g_assert (self->n_columns > 0);
|
||||
|
||||
for (cell = gtk_list_item_manager_get_first (self->item_manager);
|
||||
cell != NULL;
|
||||
cell = gtk_rb_tree_node_get_next (cell))
|
||||
{
|
||||
if (cell->parent.widget)
|
||||
{
|
||||
row_height += cell->size;
|
||||
|
||||
gtk_list_base_size_allocate_child (GTK_LIST_BASE (self),
|
||||
cell->parent.widget,
|
||||
x + ceil (self->column_width * i),
|
||||
y,
|
||||
ceil (self->column_width * (i + 1)) - ceil (self->column_width * i),
|
||||
row_height);
|
||||
i++;
|
||||
if (i >= self->n_columns)
|
||||
{
|
||||
y += row_height;
|
||||
i -= self->n_columns;
|
||||
row_height = 0;
|
||||
}
|
||||
g_assert (i == 0);
|
||||
g_assert (tile->n_items % self->n_columns == 0);
|
||||
gtk_list_tile_set_area_size (self->item_manager,
|
||||
tile,
|
||||
ceil (self->column_width * self->n_columns),
|
||||
unknown_row_height * (tile->n_items / self->n_columns));
|
||||
y += tile->area.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
i += cell->parent.n_items;
|
||||
/* skip remaining row if we didn't start one */
|
||||
if (i > cell->parent.n_items && i >= self->n_columns)
|
||||
if (tile->area.height == 0)
|
||||
{
|
||||
i -= self->n_columns;
|
||||
y += row_height;
|
||||
row_height = 0;
|
||||
/* this case is for the last row - it may not be a full row so it won't
|
||||
* be a multirow tile but it may have no widgets either */
|
||||
gtk_list_tile_set_area_size (self->item_manager,
|
||||
tile,
|
||||
ceil (self->column_width * (i + tile->n_items)) - ceil (self->column_width * i),
|
||||
unknown_row_height);
|
||||
}
|
||||
i += tile->n_items;
|
||||
}
|
||||
|
||||
row_height += cell->size;
|
||||
|
||||
/* skip rows that are completely contained by this cell */
|
||||
if (i >= self->n_columns)
|
||||
{
|
||||
guint unknown_rows, unknown_height;
|
||||
|
||||
unknown_rows = i / self->n_columns;
|
||||
unknown_height = unknown_rows * self->unknown_row_height;
|
||||
row_height -= unknown_height;
|
||||
y += unknown_height;
|
||||
i %= self->n_columns;
|
||||
g_assert (row_height >= 0);
|
||||
}
|
||||
if (i >= self->n_columns)
|
||||
{
|
||||
g_assert (i == self->n_columns);
|
||||
y += tile->area.height;
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
/* Add a filler tile for empty space in the bottom right */
|
||||
if (i < self->n_columns)
|
||||
{
|
||||
GtkListTile *filler;
|
||||
tile = gtk_list_item_manager_get_last (self->item_manager);
|
||||
filler = gtk_list_tile_split (self->item_manager, tile, tile->n_items);
|
||||
gtk_list_tile_set_area_position (self->item_manager,
|
||||
filler,
|
||||
ceil (self->column_width * i),
|
||||
y);
|
||||
gtk_list_tile_set_area_size (self->item_manager,
|
||||
filler,
|
||||
ceil (self->column_width * self->n_columns) - filler->area.x,
|
||||
tile->area.height);
|
||||
}
|
||||
|
||||
gtk_list_base_allocate_rubberband (GTK_LIST_BASE (widget));
|
||||
/* step 4: allocate the rest */
|
||||
gtk_list_base_allocate (GTK_LIST_BASE (self));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1043,11 +874,8 @@ gtk_grid_view_class_init (GtkGridViewClass *klass)
|
||||
|
||||
list_base_class->list_item_name = "child";
|
||||
list_base_class->list_item_role = GTK_ACCESSIBLE_ROLE_GRID_CELL;
|
||||
list_base_class->list_item_size = sizeof (Cell);
|
||||
list_base_class->list_item_augment_size = sizeof (CellAugment);
|
||||
list_base_class->list_item_augment_func = cell_augment;
|
||||
list_base_class->get_allocation_along = gtk_grid_view_get_allocation_along;
|
||||
list_base_class->get_allocation_across = gtk_grid_view_get_allocation_across;
|
||||
list_base_class->split = gtk_grid_view_split;
|
||||
list_base_class->get_allocation = gtk_grid_view_get_allocation;
|
||||
list_base_class->get_items_in_rect = gtk_grid_view_get_items_in_rect;
|
||||
list_base_class->get_position_from_allocation = gtk_grid_view_get_position_from_allocation;
|
||||
list_base_class->move_focus_along = gtk_grid_view_move_focus_along;
|
||||
|
@ -351,6 +351,8 @@ init_compose_table_thread_cb (GTask *task,
|
||||
|
||||
gtk_im_context_simple_init_compose_table ();
|
||||
|
||||
g_task_return_boolean (task, TRUE);
|
||||
|
||||
gdk_profiler_end_mark (before, "im compose table load (thread)", NULL);
|
||||
}
|
||||
|
||||
|
@ -327,49 +327,22 @@ gtk_list_base_move_focus (GtkListBase *self,
|
||||
}
|
||||
|
||||
/*
|
||||
* gtk_list_base_get_allocation_along:
|
||||
* gtk_list_base_get_allocation:
|
||||
* @self: a `GtkListBase`
|
||||
* @pos: item to get the size of
|
||||
* @offset: (out caller-allocates) (optional): set to the offset
|
||||
* of the top/left of the item
|
||||
* @size: (out caller-allocates) (optional): set to the size of
|
||||
* the item in the direction
|
||||
* @pos: item to get the area of
|
||||
* @area: (out caller-allocates): set to the area
|
||||
* occupied by the item
|
||||
*
|
||||
* Computes the allocation of the item in the direction along the sizing
|
||||
* axis.
|
||||
* Computes the allocation of the item in the given position
|
||||
*
|
||||
* Returns: %TRUE if the item exists and has an allocation, %FALSE otherwise
|
||||
**/
|
||||
static gboolean
|
||||
gtk_list_base_get_allocation_along (GtkListBase *self,
|
||||
guint pos,
|
||||
int *offset,
|
||||
int *size)
|
||||
gtk_list_base_get_allocation (GtkListBase *self,
|
||||
guint pos,
|
||||
GdkRectangle *area)
|
||||
{
|
||||
return GTK_LIST_BASE_GET_CLASS (self)->get_allocation_along (self, pos, offset, size);
|
||||
}
|
||||
|
||||
/*
|
||||
* gtk_list_base_get_allocation_across:
|
||||
* @self: a `GtkListBase`
|
||||
* @pos: item to get the size of
|
||||
* @offset: (out caller-allocates) (optional): set to the offset
|
||||
* of the top/left of the item
|
||||
* @size: (out caller-allocates) (optional): set to the size of
|
||||
* the item in the direction
|
||||
*
|
||||
* Computes the allocation of the item in the direction across to the sizing
|
||||
* axis.
|
||||
*
|
||||
* Returns: %TRUE if the item exists and has an allocation, %FALSE otherwise
|
||||
**/
|
||||
static gboolean
|
||||
gtk_list_base_get_allocation_across (GtkListBase *self,
|
||||
guint pos,
|
||||
int *offset,
|
||||
int *size)
|
||||
{
|
||||
return GTK_LIST_BASE_GET_CLASS (self)->get_allocation_across (self, pos, offset, size);
|
||||
return GTK_LIST_BASE_GET_CLASS (self)->get_allocation (self, pos, area);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -492,7 +465,7 @@ gtk_list_base_focus (GtkWidget *widget,
|
||||
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
|
||||
guint old, pos, n_items;
|
||||
GtkWidget *focus_child;
|
||||
GtkListItemManagerItem *item;
|
||||
GtkListTile *tile;
|
||||
|
||||
focus_child = gtk_widget_get_focus_child (widget);
|
||||
/* focus is moving around fine inside the focus child, don't disturb it */
|
||||
@ -558,15 +531,15 @@ gtk_list_base_focus (GtkWidget *widget,
|
||||
if (old == pos)
|
||||
return TRUE;
|
||||
|
||||
item = gtk_list_item_manager_get_nth (priv->item_manager, pos, NULL);
|
||||
if (item == NULL)
|
||||
tile = gtk_list_item_manager_get_nth (priv->item_manager, pos, NULL);
|
||||
if (tile == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* This shouldn't really happen, but if it does, oh well */
|
||||
if (item->widget == NULL)
|
||||
if (tile->widget == NULL)
|
||||
return gtk_list_base_grab_focus_on_item (GTK_LIST_BASE (self), pos, TRUE, FALSE, FALSE);
|
||||
|
||||
return gtk_widget_child_focus (item->widget, direction);
|
||||
return gtk_widget_child_focus (tile->widget, direction);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -807,29 +780,22 @@ gtk_list_base_scroll_to_item (GtkListBase *self,
|
||||
guint pos)
|
||||
{
|
||||
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
|
||||
int start, end;
|
||||
double align_along, align_across;
|
||||
GtkPackType side_along, side_across;
|
||||
GdkRectangle area;
|
||||
|
||||
/* figure out primary orientation and if position is valid */
|
||||
if (!gtk_list_base_get_allocation_along (GTK_LIST_BASE (self), pos, &start, &end))
|
||||
if (!gtk_list_base_get_allocation (GTK_LIST_BASE (self), pos, &area))
|
||||
return;
|
||||
|
||||
end += start;
|
||||
gtk_list_base_compute_scroll_align (self,
|
||||
gtk_list_base_get_orientation (GTK_LIST_BASE (self)),
|
||||
start, end,
|
||||
area.y, area.y + area.height,
|
||||
priv->anchor_align_along, priv->anchor_side_along,
|
||||
&align_along, &side_along);
|
||||
|
||||
/* now do the same thing with the other orientation */
|
||||
if (!gtk_list_base_get_allocation_across (GTK_LIST_BASE (self), pos, &start, &end))
|
||||
return;
|
||||
|
||||
end += start;
|
||||
gtk_list_base_compute_scroll_align (self,
|
||||
gtk_list_base_get_opposite_orientation (GTK_LIST_BASE (self)),
|
||||
start, end,
|
||||
area.x, area.x + area.width,
|
||||
priv->anchor_align_across, priv->anchor_side_across,
|
||||
&align_across, &side_across);
|
||||
|
||||
@ -959,8 +925,7 @@ gtk_list_base_move_cursor_page_up (GtkWidget *widget,
|
||||
|
||||
pos = gtk_list_base_get_focus_position (self);
|
||||
page_size = gtk_adjustment_get_page_size (priv->adjustment[priv->orientation]);
|
||||
if (!gtk_list_base_get_allocation_along (self, pos, &area.y, &area.height) ||
|
||||
!gtk_list_base_get_allocation_across (self, pos, &area.x, &area.width))
|
||||
if (!gtk_list_base_get_allocation (self, pos, &area))
|
||||
return TRUE;
|
||||
if (!gtk_list_base_get_position_from_allocation (self,
|
||||
area.x + area.width / 2,
|
||||
@ -1005,8 +970,7 @@ gtk_list_base_move_cursor_page_down (GtkWidget *widget,
|
||||
if (end == 0)
|
||||
return TRUE;
|
||||
|
||||
if (!gtk_list_base_get_allocation_along (self, pos, &area.y, &area.height) ||
|
||||
!gtk_list_base_get_allocation_across (self, pos, &area.x, &area.width))
|
||||
if (!gtk_list_base_get_allocation (self, pos, &area))
|
||||
return TRUE;
|
||||
|
||||
if (!gtk_list_base_get_position_from_allocation (self,
|
||||
@ -1355,7 +1319,7 @@ update_autoscroll (GtkListBase *self,
|
||||
remove_autoscroll (self);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* gtk_list_base_size_allocate_child:
|
||||
* @self: The listbase
|
||||
* @child: The child
|
||||
@ -1368,7 +1332,7 @@ update_autoscroll (GtkListBase *self,
|
||||
* but with the coordinates already offset by the scroll
|
||||
* offset.
|
||||
**/
|
||||
void
|
||||
static void
|
||||
gtk_list_base_size_allocate_child (GtkListBase *self,
|
||||
GtkWidget *child,
|
||||
int x,
|
||||
@ -1432,6 +1396,32 @@ gtk_list_base_size_allocate_child (GtkListBase *self,
|
||||
gtk_widget_size_allocate (child, &child_allocation, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_base_allocate_children (GtkListBase *self)
|
||||
{
|
||||
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
|
||||
GtkListTile *tile;
|
||||
int dx, dy;
|
||||
|
||||
gtk_list_base_get_adjustment_values (self, OPPOSITE_ORIENTATION (priv->orientation), &dx, NULL, NULL);
|
||||
gtk_list_base_get_adjustment_values (self, priv->orientation, &dy, NULL, NULL);
|
||||
|
||||
for (tile = gtk_list_item_manager_get_first (priv->item_manager);
|
||||
tile != NULL;
|
||||
tile = gtk_rb_tree_node_get_next (tile))
|
||||
{
|
||||
if (tile->widget)
|
||||
{
|
||||
gtk_list_base_size_allocate_child (GTK_LIST_BASE (self),
|
||||
tile->widget,
|
||||
tile->area.x - dx,
|
||||
tile->area.y - dy,
|
||||
tile->area.width,
|
||||
tile->area.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_base_widget_to_list (GtkListBase *self,
|
||||
double x_widget,
|
||||
@ -1484,13 +1474,13 @@ gtk_list_base_get_rubberband_coords (GtkListBase *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
GdkRectangle area;
|
||||
guint pos = gtk_list_item_tracker_get_position (priv->item_manager, priv->rubberband->start_tracker);
|
||||
|
||||
if (gtk_list_base_get_allocation_along (self, pos, &y1, &y2) &&
|
||||
gtk_list_base_get_allocation_across (self, pos, &x1, &x2))
|
||||
if (gtk_list_base_get_allocation (self, pos, &area))
|
||||
{
|
||||
x1 += x2 * priv->rubberband->start_align_across;
|
||||
y1 += y2 * priv->rubberband->start_align_along;
|
||||
x1 = area.x + area.width * priv->rubberband->start_align_across;
|
||||
y1 = area.y + area.height * priv->rubberband->start_align_along;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1511,7 +1501,7 @@ gtk_list_base_get_rubberband_coords (GtkListBase *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
gtk_list_base_allocate_rubberband (GtkListBase *self)
|
||||
{
|
||||
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
|
||||
@ -1648,17 +1638,17 @@ static void
|
||||
gtk_list_base_stop_rubberband (GtkListBase *self)
|
||||
{
|
||||
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
|
||||
GtkListItemManagerItem *item;
|
||||
GtkListTile *tile;
|
||||
|
||||
if (!priv->rubberband)
|
||||
return;
|
||||
|
||||
for (item = gtk_list_item_manager_get_first (priv->item_manager);
|
||||
item != NULL;
|
||||
item = gtk_rb_tree_node_get_next (item))
|
||||
for (tile = gtk_list_item_manager_get_first (priv->item_manager);
|
||||
tile != NULL;
|
||||
tile = gtk_rb_tree_node_get_next (tile))
|
||||
{
|
||||
if (item->widget)
|
||||
gtk_widget_unset_state_flags (item->widget, GTK_STATE_FLAG_ACTIVE);
|
||||
if (tile->widget)
|
||||
gtk_widget_unset_state_flags (tile->widget, GTK_STATE_FLAG_ACTIVE);
|
||||
}
|
||||
|
||||
gtk_list_item_tracker_free (priv->item_manager, priv->rubberband->start_tracker);
|
||||
@ -1673,7 +1663,7 @@ static void
|
||||
gtk_list_base_update_rubberband_selection (GtkListBase *self)
|
||||
{
|
||||
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
|
||||
GtkListItemManagerItem *item;
|
||||
GtkListTile *tile;
|
||||
GdkRectangle rect;
|
||||
guint pos;
|
||||
GtkBitset *rubberband_selection;
|
||||
@ -1684,19 +1674,19 @@ gtk_list_base_update_rubberband_selection (GtkListBase *self)
|
||||
rubberband_selection = gtk_list_base_get_items_in_rect (self, &rect);
|
||||
|
||||
pos = 0;
|
||||
for (item = gtk_list_item_manager_get_first (priv->item_manager);
|
||||
item != NULL;
|
||||
item = gtk_rb_tree_node_get_next (item))
|
||||
for (tile = gtk_list_item_manager_get_first (priv->item_manager);
|
||||
tile != NULL;
|
||||
tile = gtk_rb_tree_node_get_next (tile))
|
||||
{
|
||||
if (item->widget)
|
||||
if (tile->widget)
|
||||
{
|
||||
if (gtk_bitset_contains (rubberband_selection, pos))
|
||||
gtk_widget_set_state_flags (item->widget, GTK_STATE_FLAG_ACTIVE, FALSE);
|
||||
gtk_widget_set_state_flags (tile->widget, GTK_STATE_FLAG_ACTIVE, FALSE);
|
||||
else
|
||||
gtk_widget_unset_state_flags (item->widget, GTK_STATE_FLAG_ACTIVE);
|
||||
gtk_widget_unset_state_flags (tile->widget, GTK_STATE_FLAG_ACTIVE);
|
||||
}
|
||||
|
||||
pos += item->n_items;
|
||||
pos += tile->n_items;
|
||||
}
|
||||
|
||||
gtk_bitset_unref (rubberband_selection);
|
||||
@ -1844,6 +1834,14 @@ gtk_list_base_drag_leave (GtkDropControllerMotion *motion,
|
||||
remove_autoscroll (GTK_LIST_BASE (widget));
|
||||
}
|
||||
|
||||
static GtkListTile *
|
||||
gtk_list_base_split_func (gpointer data,
|
||||
GtkListTile *tile,
|
||||
guint n_items)
|
||||
{
|
||||
return GTK_LIST_BASE_GET_CLASS (data)->split (data, tile, n_items);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_base_init_real (GtkListBase *self,
|
||||
GtkListBaseClass *g_class)
|
||||
@ -1851,12 +1849,11 @@ gtk_list_base_init_real (GtkListBase *self,
|
||||
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
|
||||
GtkEventController *controller;
|
||||
|
||||
priv->item_manager = gtk_list_item_manager_new_for_size (GTK_WIDGET (self),
|
||||
g_class->list_item_name,
|
||||
g_class->list_item_role,
|
||||
g_class->list_item_size,
|
||||
g_class->list_item_augment_size,
|
||||
g_class->list_item_augment_func);
|
||||
priv->item_manager = gtk_list_item_manager_new (GTK_WIDGET (self),
|
||||
g_class->list_item_name,
|
||||
g_class->list_item_role,
|
||||
gtk_list_base_split_func,
|
||||
self);
|
||||
priv->anchor = gtk_list_item_tracker_new (priv->item_manager);
|
||||
priv->anchor_side_along = GTK_PACK_START;
|
||||
priv->anchor_side_across = GTK_PACK_START;
|
||||
@ -1879,7 +1876,7 @@ gtk_list_base_init_real (GtkListBase *self,
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
gtk_list_base_set_adjustment_values (GtkListBase *self,
|
||||
GtkOrientation orientation,
|
||||
int value,
|
||||
@ -1907,23 +1904,24 @@ gtk_list_base_set_adjustment_values (GtkListBase *self,
|
||||
g_signal_handlers_unblock_by_func (priv->adjustment[orientation],
|
||||
gtk_list_base_adjustment_value_changed_cb,
|
||||
self);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_list_base_update_adjustments (GtkListBase *self,
|
||||
int total_across,
|
||||
int total_along,
|
||||
int page_across,
|
||||
int page_along,
|
||||
int *across,
|
||||
int *along)
|
||||
static void
|
||||
gtk_list_base_update_adjustments (GtkListBase *self)
|
||||
{
|
||||
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
|
||||
int value_along, value_across, size;
|
||||
GdkRectangle bounds;
|
||||
int value_along, value_across;
|
||||
int page_along, page_across;
|
||||
guint pos;
|
||||
|
||||
gtk_list_item_manager_get_tile_bounds (priv->item_manager, &bounds);
|
||||
g_assert (bounds.x == 0);
|
||||
g_assert (bounds.y == 0);
|
||||
|
||||
page_across = gtk_widget_get_size (GTK_WIDGET (self), OPPOSITE_ORIENTATION (priv->orientation));
|
||||
page_along = gtk_widget_get_size (GTK_WIDGET (self), priv->orientation);
|
||||
|
||||
pos = gtk_list_item_tracker_get_position (priv->item_manager, priv->anchor);
|
||||
if (pos == GTK_INVALID_LIST_POSITION)
|
||||
{
|
||||
@ -1932,38 +1930,45 @@ gtk_list_base_update_adjustments (GtkListBase *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gtk_list_base_get_allocation_across (self, pos, &value_across, &size))
|
||||
GdkRectangle area;
|
||||
|
||||
if (gtk_list_base_get_allocation (self, pos, &area))
|
||||
{
|
||||
value_across = area.x;
|
||||
value_along = area.y;
|
||||
if (priv->anchor_side_across == GTK_PACK_END)
|
||||
value_across += size;
|
||||
value_across -= priv->anchor_align_across * page_across;
|
||||
}
|
||||
else
|
||||
{
|
||||
value_along = 0;
|
||||
}
|
||||
if (gtk_list_base_get_allocation_along (self, pos, &value_along, &size))
|
||||
{
|
||||
value_across += area.width;
|
||||
if (priv->anchor_side_along == GTK_PACK_END)
|
||||
value_along += size;
|
||||
value_along += area.height;
|
||||
value_across -= priv->anchor_align_across * page_across;
|
||||
value_along -= priv->anchor_align_along * page_along;
|
||||
}
|
||||
else
|
||||
{
|
||||
value_across = 0;
|
||||
value_along = 0;
|
||||
}
|
||||
}
|
||||
|
||||
*across = gtk_list_base_set_adjustment_values (self,
|
||||
OPPOSITE_ORIENTATION (priv->orientation),
|
||||
value_across,
|
||||
total_across,
|
||||
page_across);
|
||||
*along = gtk_list_base_set_adjustment_values (self,
|
||||
priv->orientation,
|
||||
value_along,
|
||||
total_along,
|
||||
page_along);
|
||||
gtk_list_base_set_adjustment_values (self,
|
||||
OPPOSITE_ORIENTATION (priv->orientation),
|
||||
value_across,
|
||||
bounds.width,
|
||||
page_across);
|
||||
gtk_list_base_set_adjustment_values (self,
|
||||
priv->orientation,
|
||||
value_along,
|
||||
bounds.height,
|
||||
page_along);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_list_base_allocate (GtkListBase *self)
|
||||
{
|
||||
gtk_list_base_update_adjustments (self);
|
||||
|
||||
gtk_list_base_allocate_children (self);
|
||||
gtk_list_base_allocate_rubberband (self);
|
||||
}
|
||||
|
||||
GtkScrollablePolicy
|
||||
@ -2124,14 +2129,14 @@ gtk_list_base_grab_focus_on_item (GtkListBase *self,
|
||||
gboolean extend)
|
||||
{
|
||||
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
|
||||
GtkListItemManagerItem *item;
|
||||
GtkListTile *tile;
|
||||
gboolean success;
|
||||
|
||||
item = gtk_list_item_manager_get_nth (priv->item_manager, pos, NULL);
|
||||
if (item == NULL)
|
||||
tile = gtk_list_item_manager_get_nth (priv->item_manager, pos, NULL);
|
||||
if (tile == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!item->widget)
|
||||
if (!tile->widget)
|
||||
{
|
||||
GtkListItemTracker *tracker = gtk_list_item_tracker_new (priv->item_manager);
|
||||
|
||||
@ -2141,16 +2146,16 @@ gtk_list_base_grab_focus_on_item (GtkListBase *self,
|
||||
* so we create a temporary one. */
|
||||
gtk_list_item_tracker_set_position (priv->item_manager, tracker, pos, 0, 0);
|
||||
|
||||
item = gtk_list_item_manager_get_nth (priv->item_manager, pos, NULL);
|
||||
g_assert (item->widget);
|
||||
tile = gtk_list_item_manager_get_nth (priv->item_manager, pos, NULL);
|
||||
g_assert (tile->widget);
|
||||
|
||||
success = gtk_widget_grab_focus (item->widget);
|
||||
success = gtk_widget_grab_focus (tile->widget);
|
||||
|
||||
gtk_list_item_tracker_free (priv->item_manager, tracker);
|
||||
}
|
||||
else
|
||||
{
|
||||
success = gtk_widget_grab_focus (item->widget);
|
||||
success = gtk_widget_grab_focus (tile->widget);
|
||||
}
|
||||
|
||||
if (!success)
|
||||
|
@ -36,20 +36,14 @@ struct _GtkListBaseClass
|
||||
|
||||
const char * list_item_name;
|
||||
GtkAccessibleRole list_item_role;
|
||||
gsize list_item_size;
|
||||
gsize list_item_augment_size;
|
||||
GtkRbTreeAugmentFunc list_item_augment_func;
|
||||
|
||||
void (* adjustment_value_changed) (GtkListBase *self,
|
||||
GtkOrientation orientation);
|
||||
gboolean (* get_allocation_along) (GtkListBase *self,
|
||||
GtkListTile * (* split) (GtkListBase *self,
|
||||
GtkListTile *tile,
|
||||
guint n_items);
|
||||
|
||||
gboolean (* get_allocation) (GtkListBase *self,
|
||||
guint pos,
|
||||
int *offset,
|
||||
int *size);
|
||||
gboolean (* get_allocation_across) (GtkListBase *self,
|
||||
guint pos,
|
||||
int *offset,
|
||||
int *size);
|
||||
GdkRectangle *area);
|
||||
gboolean (* get_position_from_allocation) (GtkListBase *self,
|
||||
int across,
|
||||
int along,
|
||||
@ -75,13 +69,6 @@ guint gtk_list_base_get_n_items (GtkListBase
|
||||
GtkSelectionModel * gtk_list_base_get_model (GtkListBase *self);
|
||||
gboolean gtk_list_base_set_model (GtkListBase *self,
|
||||
GtkSelectionModel *model);
|
||||
void gtk_list_base_update_adjustments (GtkListBase *self,
|
||||
int total_across,
|
||||
int total_along,
|
||||
int page_across,
|
||||
int page_along,
|
||||
int *across,
|
||||
int *along);
|
||||
|
||||
guint gtk_list_base_get_anchor (GtkListBase *self);
|
||||
void gtk_list_base_set_anchor (GtkListBase *self,
|
||||
@ -106,13 +93,7 @@ gboolean gtk_list_base_grab_focus_on_item (GtkListBase
|
||||
void gtk_list_base_set_enable_rubberband (GtkListBase *self,
|
||||
gboolean enable);
|
||||
gboolean gtk_list_base_get_enable_rubberband (GtkListBase *self);
|
||||
void gtk_list_base_allocate_rubberband (GtkListBase *self);
|
||||
|
||||
void gtk_list_base_size_allocate_child (GtkListBase *self,
|
||||
GtkWidget *child,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
void gtk_list_base_allocate (GtkListBase *self);
|
||||
|
||||
#endif /* __GTK_LIST_BASE_PRIVATE_H__ */
|
||||
|
@ -39,6 +39,9 @@ struct _GtkListItemManager
|
||||
|
||||
GtkRbTree *items;
|
||||
GSList *trackers;
|
||||
|
||||
GtkListTile * (* split_func) (gpointer, GtkListTile *, guint);
|
||||
gpointer user_data;
|
||||
};
|
||||
|
||||
struct _GtkListItemManagerClass
|
||||
@ -74,54 +77,70 @@ static void gtk_list_item_manager_release_list_item (GtkListItemMana
|
||||
GtkWidget *widget);
|
||||
G_DEFINE_TYPE (GtkListItemManager, gtk_list_item_manager, G_TYPE_OBJECT)
|
||||
|
||||
void
|
||||
static void
|
||||
potentially_empty_rectangle_union (cairo_rectangle_int_t *self,
|
||||
const cairo_rectangle_int_t *area)
|
||||
{
|
||||
if (area->width <= 0 || area->height <= 0)
|
||||
return;
|
||||
|
||||
if (self->width <= 0 || self->height <= 0)
|
||||
{
|
||||
*self = *area;
|
||||
return;
|
||||
}
|
||||
|
||||
gdk_rectangle_union (self, area, self);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_manager_augment_node (GtkRbTree *tree,
|
||||
gpointer node_augment,
|
||||
gpointer node,
|
||||
gpointer left,
|
||||
gpointer right)
|
||||
{
|
||||
GtkListItemManagerItem *item = node;
|
||||
GtkListItemManagerItemAugment *aug = node_augment;
|
||||
GtkListTile *tile = node;
|
||||
GtkListTileAugment *aug = node_augment;
|
||||
|
||||
aug->n_items = item->n_items;
|
||||
aug->n_items = tile->n_items;
|
||||
aug->area = tile->area;
|
||||
|
||||
if (left)
|
||||
{
|
||||
GtkListItemManagerItemAugment *left_aug = gtk_rb_tree_get_augment (tree, left);
|
||||
GtkListTileAugment *left_aug = gtk_rb_tree_get_augment (tree, left);
|
||||
|
||||
aug->n_items += left_aug->n_items;
|
||||
potentially_empty_rectangle_union (&aug->area, &left_aug->area);
|
||||
}
|
||||
|
||||
if (right)
|
||||
{
|
||||
GtkListItemManagerItemAugment *right_aug = gtk_rb_tree_get_augment (tree, right);
|
||||
GtkListTileAugment *right_aug = gtk_rb_tree_get_augment (tree, right);
|
||||
|
||||
aug->n_items += right_aug->n_items;
|
||||
potentially_empty_rectangle_union (&aug->area, &right_aug->area);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_manager_clear_node (gpointer _item)
|
||||
gtk_list_item_manager_clear_node (gpointer _tile)
|
||||
{
|
||||
GtkListItemManagerItem *item G_GNUC_UNUSED = _item;
|
||||
GtkListTile *tile G_GNUC_UNUSED = _tile;
|
||||
|
||||
g_assert (item->widget == NULL);
|
||||
g_assert (tile->widget == NULL);
|
||||
}
|
||||
|
||||
GtkListItemManager *
|
||||
gtk_list_item_manager_new_for_size (GtkWidget *widget,
|
||||
const char *item_css_name,
|
||||
GtkAccessibleRole item_role,
|
||||
gsize element_size,
|
||||
gsize augment_size,
|
||||
GtkRbTreeAugmentFunc augment_func)
|
||||
gtk_list_item_manager_new (GtkWidget *widget,
|
||||
const char *item_css_name,
|
||||
GtkAccessibleRole item_role,
|
||||
GtkListTile * (* split_func) (gpointer, GtkListTile *, guint),
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkListItemManager *self;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
|
||||
g_return_val_if_fail (element_size >= sizeof (GtkListItemManagerItem), NULL);
|
||||
g_return_val_if_fail (augment_size >= sizeof (GtkListItemManagerItemAugment), NULL);
|
||||
|
||||
self = g_object_new (GTK_TYPE_LIST_ITEM_MANAGER, NULL);
|
||||
|
||||
@ -129,22 +148,48 @@ gtk_list_item_manager_new_for_size (GtkWidget *widget,
|
||||
self->widget = widget;
|
||||
self->item_css_name = g_intern_string (item_css_name);
|
||||
self->item_role = item_role;
|
||||
self->split_func = split_func;
|
||||
self->user_data = user_data;
|
||||
|
||||
self->items = gtk_rb_tree_new_for_size (element_size,
|
||||
augment_size,
|
||||
augment_func,
|
||||
self->items = gtk_rb_tree_new_for_size (sizeof (GtkListTile),
|
||||
sizeof (GtkListTileAugment),
|
||||
gtk_list_item_manager_augment_node,
|
||||
gtk_list_item_manager_clear_node,
|
||||
NULL);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_list_item_manager_get_tile_bounds (GtkListItemManager *self,
|
||||
GdkRectangle *out_bounds)
|
||||
{
|
||||
GtkListTile *tile;
|
||||
GtkListTileAugment *aug;
|
||||
|
||||
tile = gtk_rb_tree_get_root (self->items);
|
||||
if (tile == NULL)
|
||||
{
|
||||
*out_bounds = (GdkRectangle) { 0, 0, 0, 0 };
|
||||
return;
|
||||
}
|
||||
|
||||
aug = gtk_rb_tree_get_augment (self->items, tile);
|
||||
*out_bounds = aug->area;
|
||||
}
|
||||
|
||||
gpointer
|
||||
gtk_list_item_manager_get_first (GtkListItemManager *self)
|
||||
{
|
||||
return gtk_rb_tree_get_first (self->items);
|
||||
}
|
||||
|
||||
gpointer
|
||||
gtk_list_item_manager_get_last (GtkListItemManager *self)
|
||||
{
|
||||
return gtk_rb_tree_get_last (self->items);
|
||||
}
|
||||
|
||||
gpointer
|
||||
gtk_list_item_manager_get_root (GtkListItemManager *self)
|
||||
{
|
||||
@ -155,15 +200,15 @@ gtk_list_item_manager_get_root (GtkListItemManager *self)
|
||||
* gtk_list_item_manager_get_nth:
|
||||
* @self: a `GtkListItemManager`
|
||||
* @position: position of the item
|
||||
* @offset: (out): offset into the returned item
|
||||
* @offset: (out): offset into the returned tile
|
||||
*
|
||||
* Looks up the GtkListItemManagerItem that represents @position.
|
||||
* Looks up the GtkListTile that represents @position.
|
||||
*
|
||||
* If a the returned item represents multiple rows, the @offset into
|
||||
* the returned item for @position will be set. If the returned item
|
||||
* If a the returned tile represents multiple rows, the @offset into
|
||||
* the returned tile for @position will be set. If the returned tile
|
||||
* represents a row with an existing widget, @offset will always be 0.
|
||||
*
|
||||
* Returns: (type GtkListItemManagerItem): the item for @position or
|
||||
* Returns: (type GtkListTile): the tile for @position or
|
||||
* %NULL if position is out of range
|
||||
**/
|
||||
gpointer
|
||||
@ -171,48 +216,103 @@ gtk_list_item_manager_get_nth (GtkListItemManager *self,
|
||||
guint position,
|
||||
guint *offset)
|
||||
{
|
||||
GtkListItemManagerItem *item, *tmp;
|
||||
GtkListTile *tile, *tmp;
|
||||
|
||||
item = gtk_rb_tree_get_root (self->items);
|
||||
tile = gtk_rb_tree_get_root (self->items);
|
||||
|
||||
while (item)
|
||||
while (tile)
|
||||
{
|
||||
tmp = gtk_rb_tree_node_get_left (item);
|
||||
tmp = gtk_rb_tree_node_get_left (tile);
|
||||
if (tmp)
|
||||
{
|
||||
GtkListItemManagerItemAugment *aug = gtk_rb_tree_get_augment (self->items, tmp);
|
||||
GtkListTileAugment *aug = gtk_rb_tree_get_augment (self->items, tmp);
|
||||
if (position < aug->n_items)
|
||||
{
|
||||
item = tmp;
|
||||
tile = tmp;
|
||||
continue;
|
||||
}
|
||||
position -= aug->n_items;
|
||||
}
|
||||
|
||||
if (position < item->n_items)
|
||||
if (position < tile->n_items)
|
||||
break;
|
||||
position -= item->n_items;
|
||||
position -= tile->n_items;
|
||||
|
||||
item = gtk_rb_tree_node_get_right (item);
|
||||
tile = gtk_rb_tree_node_get_right (tile);
|
||||
}
|
||||
|
||||
if (offset)
|
||||
*offset = item ? position : 0;
|
||||
*offset = tile ? position : 0;
|
||||
|
||||
return item;
|
||||
return tile;
|
||||
}
|
||||
|
||||
static GtkListTile *
|
||||
gtk_list_tile_get_tile_at (GtkListItemManager *self,
|
||||
GtkListTile *tile,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
GtkListTileAugment *aug;
|
||||
GtkListTile *subtile;
|
||||
|
||||
aug = gtk_list_tile_get_augment (self, tile);
|
||||
if (!gdk_rectangle_contains_point (&aug->area, x, y))
|
||||
return NULL;
|
||||
|
||||
subtile = gtk_rb_tree_node_get_left (tile);
|
||||
if (subtile)
|
||||
{
|
||||
subtile = gtk_list_tile_get_tile_at (self, subtile, x, y);
|
||||
if (subtile)
|
||||
return subtile;
|
||||
}
|
||||
|
||||
if (gdk_rectangle_contains_point (&tile->area, x, y))
|
||||
return tile;
|
||||
|
||||
subtile = gtk_rb_tree_node_get_right (tile);
|
||||
if (subtile)
|
||||
{
|
||||
subtile = gtk_list_tile_get_tile_at (self, subtile, x, y);
|
||||
if (subtile)
|
||||
return subtile;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* gtk_list_item_manager_get_tile_at:
|
||||
* @self: a GtkListItemManager
|
||||
* @x: x coordinate of tile
|
||||
* @y: y coordinate of tile
|
||||
*
|
||||
* Finds the tile occupying the coordinates at (x, y). If no
|
||||
* tile occupies the coordinates (for example, if the tile is out of bounds),
|
||||
* NULL is returned.
|
||||
*
|
||||
* Returns: (nullable): The tile at (x, y) or NULL
|
||||
**/
|
||||
GtkListTile *
|
||||
gtk_list_item_manager_get_tile_at (GtkListItemManager *self,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
return gtk_list_tile_get_tile_at (self, gtk_list_item_manager_get_root (self), x, y);
|
||||
}
|
||||
|
||||
guint
|
||||
gtk_list_item_manager_get_item_position (GtkListItemManager *self,
|
||||
gpointer item)
|
||||
gtk_list_tile_get_position (GtkListItemManager *self,
|
||||
GtkListTile *tile)
|
||||
{
|
||||
GtkListItemManagerItem *parent, *left;
|
||||
GtkListTile *parent, *left;
|
||||
int pos;
|
||||
|
||||
left = gtk_rb_tree_node_get_left (item);
|
||||
left = gtk_rb_tree_node_get_left (tile);
|
||||
if (left)
|
||||
{
|
||||
GtkListItemManagerItemAugment *aug = gtk_rb_tree_get_augment (self->items, left);
|
||||
GtkListTileAugment *aug = gtk_rb_tree_get_augment (self->items, left);
|
||||
pos = aug->n_items;
|
||||
}
|
||||
else
|
||||
@ -220,33 +320,93 @@ gtk_list_item_manager_get_item_position (GtkListItemManager *self,
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
for (parent = gtk_rb_tree_node_get_parent (item);
|
||||
for (parent = gtk_rb_tree_node_get_parent (tile);
|
||||
parent != NULL;
|
||||
parent = gtk_rb_tree_node_get_parent (item))
|
||||
parent = gtk_rb_tree_node_get_parent (tile))
|
||||
{
|
||||
left = gtk_rb_tree_node_get_left (parent);
|
||||
|
||||
if (left != item)
|
||||
if (left != tile)
|
||||
{
|
||||
if (left)
|
||||
{
|
||||
GtkListItemManagerItemAugment *aug = gtk_rb_tree_get_augment (self->items, left);
|
||||
GtkListTileAugment *aug = gtk_rb_tree_get_augment (self->items, left);
|
||||
pos += aug->n_items;
|
||||
}
|
||||
pos += parent->n_items;
|
||||
}
|
||||
|
||||
item = parent;
|
||||
tile = parent;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
gpointer
|
||||
gtk_list_item_manager_get_item_augment (GtkListItemManager *self,
|
||||
gpointer item)
|
||||
gtk_list_tile_get_augment (GtkListItemManager *self,
|
||||
GtkListTile *tile)
|
||||
{
|
||||
return gtk_rb_tree_get_augment (self->items, item);
|
||||
return gtk_rb_tree_get_augment (self->items, tile);
|
||||
}
|
||||
|
||||
/*
|
||||
* gtk_list_tile_set_area:
|
||||
* @self: the list item manager
|
||||
* @tile: tile to set area for
|
||||
* @area: (nullable): area to set or NULL to clear
|
||||
* the area
|
||||
*
|
||||
* Updates the area of the tile.
|
||||
*
|
||||
* The area is given in the internal coordinate system,
|
||||
* so the x/y flip due to orientation and the left/right
|
||||
* flip for RTL languages will happen later.
|
||||
*
|
||||
* This function should only be called from inside size_allocate().
|
||||
**/
|
||||
void
|
||||
gtk_list_tile_set_area (GtkListItemManager *self,
|
||||
GtkListTile *tile,
|
||||
const cairo_rectangle_int_t *area)
|
||||
{
|
||||
cairo_rectangle_int_t empty_area = { 0, 0, 0, 0 };
|
||||
|
||||
if (!area)
|
||||
area = &empty_area;
|
||||
|
||||
if (gdk_rectangle_equal (&tile->area, area))
|
||||
return;
|
||||
|
||||
tile->area = *area;
|
||||
gtk_rb_tree_node_mark_dirty (tile);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_list_tile_set_area_position (GtkListItemManager *self,
|
||||
GtkListTile *tile,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
if (tile->area.x == x && tile->area.y == y)
|
||||
return;
|
||||
|
||||
tile->area.x = x;
|
||||
tile->area.y = y;
|
||||
gtk_rb_tree_node_mark_dirty (tile);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_list_tile_set_area_size (GtkListItemManager *self,
|
||||
GtkListTile *tile,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
if (tile->area.width == width && tile->area.height == height)
|
||||
return;
|
||||
|
||||
tile->area.width = width;
|
||||
tile->area.height = height;
|
||||
gtk_rb_tree_node_mark_dirty (tile);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -347,37 +507,47 @@ restart:
|
||||
}
|
||||
}
|
||||
|
||||
static GtkListTile *
|
||||
gtk_list_item_manager_ensure_split (GtkListItemManager *self,
|
||||
GtkListTile *tile,
|
||||
guint n_items)
|
||||
{
|
||||
return self->split_func (self->user_data, tile, n_items);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_manager_remove_items (GtkListItemManager *self,
|
||||
GHashTable *change,
|
||||
guint position,
|
||||
guint n_items)
|
||||
{
|
||||
GtkListItemManagerItem *item;
|
||||
GtkListTile *tile, *next;
|
||||
guint offset;
|
||||
|
||||
if (n_items == 0)
|
||||
return;
|
||||
|
||||
item = gtk_list_item_manager_get_nth (self, position, NULL);
|
||||
tile = gtk_list_item_manager_get_nth (self, position, &offset);
|
||||
if (offset)
|
||||
tile = gtk_list_item_manager_ensure_split (self, tile, offset);
|
||||
|
||||
while (n_items > 0)
|
||||
{
|
||||
if (item->n_items > n_items)
|
||||
if (tile->n_items > n_items)
|
||||
{
|
||||
item->n_items -= n_items;
|
||||
gtk_rb_tree_node_mark_dirty (item);
|
||||
n_items = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkListItemManagerItem *next = gtk_rb_tree_node_get_next (item);
|
||||
if (item->widget)
|
||||
gtk_list_item_manager_release_list_item (self, change, item->widget);
|
||||
item->widget = NULL;
|
||||
n_items -= item->n_items;
|
||||
gtk_rb_tree_remove (self->items, item);
|
||||
item = next;
|
||||
gtk_list_item_manager_ensure_split (self, tile, n_items);
|
||||
g_assert (tile->n_items <= n_items);
|
||||
}
|
||||
|
||||
next = gtk_rb_tree_node_get_next (tile);
|
||||
if (tile->widget)
|
||||
gtk_list_item_manager_release_list_item (self, change, tile->widget);
|
||||
tile->widget = NULL;
|
||||
n_items -= tile->n_items;
|
||||
tile->n_items = 0;
|
||||
gtk_rb_tree_node_mark_dirty (tile);
|
||||
|
||||
tile = next;
|
||||
}
|
||||
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self->widget));
|
||||
@ -388,26 +558,27 @@ gtk_list_item_manager_add_items (GtkListItemManager *self,
|
||||
guint position,
|
||||
guint n_items)
|
||||
{
|
||||
GtkListItemManagerItem *item;
|
||||
GtkListTile *tile;
|
||||
guint offset;
|
||||
|
||||
if (n_items == 0)
|
||||
return;
|
||||
|
||||
item = gtk_list_item_manager_get_nth (self, position, &offset);
|
||||
tile = gtk_list_item_manager_get_nth (self, position, &offset);
|
||||
if (offset)
|
||||
tile = gtk_list_item_manager_ensure_split (self, tile, offset);
|
||||
|
||||
if (item == NULL || item->widget)
|
||||
item = gtk_rb_tree_insert_before (self->items, item);
|
||||
item->n_items += n_items;
|
||||
gtk_rb_tree_node_mark_dirty (item);
|
||||
tile = gtk_rb_tree_insert_before (self->items, tile);
|
||||
tile->n_items = n_items;
|
||||
gtk_rb_tree_node_mark_dirty (tile);
|
||||
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self->widget));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_list_item_manager_merge_list_items (GtkListItemManager *self,
|
||||
GtkListItemManagerItem *first,
|
||||
GtkListItemManagerItem *second)
|
||||
gtk_list_item_manager_merge_list_items (GtkListItemManager *self,
|
||||
GtkListTile *first,
|
||||
GtkListTile *second)
|
||||
{
|
||||
if (first->widget || second->widget)
|
||||
return FALSE;
|
||||
@ -419,11 +590,86 @@ gtk_list_item_manager_merge_list_items (GtkListItemManager *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* gtk_list_tile_split:
|
||||
* @self: the listitemmanager
|
||||
* @tile: a tile to split into two
|
||||
* @n_items: nuber of items to keep in tile
|
||||
*
|
||||
* Splits the given tile into two tiles. The original
|
||||
* tile will remain with @n_items items, the remaining
|
||||
* items will be given to the new tile, which will be
|
||||
* nserted after the tile.
|
||||
*
|
||||
* It is valid for either tile to have 0 items after
|
||||
* the split.
|
||||
*
|
||||
* Returns: The new tile
|
||||
**/
|
||||
GtkListTile *
|
||||
gtk_list_tile_split (GtkListItemManager *self,
|
||||
GtkListTile *tile,
|
||||
guint n_items)
|
||||
{
|
||||
GtkListTile *result;
|
||||
|
||||
g_assert (n_items <= tile->n_items);
|
||||
|
||||
result = gtk_rb_tree_insert_after (self->items, tile);
|
||||
result->n_items = tile->n_items - n_items;
|
||||
tile->n_items = n_items;
|
||||
gtk_rb_tree_node_mark_dirty (tile);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* gtk_list_tile_gc:
|
||||
* @self: the listitemmanager
|
||||
* @tile: a tile
|
||||
*
|
||||
* Tries to get rid of tiles when they aren't needed anymore,
|
||||
* either because their referenced listitems were deleted or
|
||||
* because they can be merged with the next item(s).
|
||||
*
|
||||
* Note that this only looks forward, but never backward.
|
||||
*
|
||||
* Returns: The next tile
|
||||
**/
|
||||
GtkListTile *
|
||||
gtk_list_tile_gc (GtkListItemManager *self,
|
||||
GtkListTile *tile)
|
||||
{
|
||||
GtkListTile *next;
|
||||
|
||||
while (tile)
|
||||
{
|
||||
next = gtk_rb_tree_node_get_next (tile);
|
||||
|
||||
if (tile->n_items == 0)
|
||||
{
|
||||
gtk_rb_tree_remove (self->items, tile);
|
||||
tile = next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (next == NULL)
|
||||
break;
|
||||
|
||||
if (gtk_list_item_manager_merge_list_items (self, tile, next))
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return tile;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_manager_release_items (GtkListItemManager *self,
|
||||
GQueue *released)
|
||||
{
|
||||
GtkListItemManagerItem *item, *prev, *next;
|
||||
GtkListTile *tile;
|
||||
guint position, i, n_items, query_n_items;
|
||||
gboolean tracked;
|
||||
|
||||
@ -439,37 +685,18 @@ gtk_list_item_manager_release_items (GtkListItemManager *self,
|
||||
continue;
|
||||
}
|
||||
|
||||
item = gtk_list_item_manager_get_nth (self, position, &i);
|
||||
tile = gtk_list_item_manager_get_nth (self, position, &i);
|
||||
i = position - i;
|
||||
while (i < position + query_n_items)
|
||||
{
|
||||
g_assert (item != NULL);
|
||||
if (item->widget)
|
||||
g_assert (tile != NULL);
|
||||
if (tile->widget)
|
||||
{
|
||||
g_queue_push_tail (released, item->widget);
|
||||
item->widget = NULL;
|
||||
i++;
|
||||
prev = gtk_rb_tree_node_get_previous (item);
|
||||
if (prev && gtk_list_item_manager_merge_list_items (self, prev, item))
|
||||
item = prev;
|
||||
next = gtk_rb_tree_node_get_next (item);
|
||||
if (next && next->widget == NULL)
|
||||
{
|
||||
i += next->n_items;
|
||||
if (!gtk_list_item_manager_merge_list_items (self, next, item))
|
||||
g_assert_not_reached ();
|
||||
item = gtk_rb_tree_node_get_next (next);
|
||||
}
|
||||
else
|
||||
{
|
||||
item = next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
i += item->n_items;
|
||||
item = gtk_rb_tree_node_get_next (item);
|
||||
g_queue_push_tail (released, tile->widget);
|
||||
tile->widget = NULL;
|
||||
}
|
||||
i += tile->n_items;
|
||||
tile = gtk_rb_tree_node_get_next (tile);
|
||||
}
|
||||
position += query_n_items;
|
||||
}
|
||||
@ -480,7 +707,7 @@ gtk_list_item_manager_ensure_items (GtkListItemManager *self,
|
||||
GHashTable *change,
|
||||
guint update_start)
|
||||
{
|
||||
GtkListItemManagerItem *item, *new_item;
|
||||
GtkListTile *tile, *other_tile;
|
||||
GtkWidget *widget, *insert_after;
|
||||
guint position, i, n_items, query_n_items, offset;
|
||||
GQueue released = G_QUEUE_INIT;
|
||||
@ -503,70 +730,61 @@ gtk_list_item_manager_ensure_items (GtkListItemManager *self,
|
||||
continue;
|
||||
}
|
||||
|
||||
item = gtk_list_item_manager_get_nth (self, position, &offset);
|
||||
for (new_item = item;
|
||||
new_item && new_item->widget == NULL;
|
||||
new_item = gtk_rb_tree_node_get_previous (new_item))
|
||||
tile = gtk_list_item_manager_get_nth (self, position, &offset);
|
||||
for (other_tile = tile;
|
||||
other_tile && other_tile->widget == NULL;
|
||||
other_tile = gtk_rb_tree_node_get_previous (other_tile))
|
||||
{ /* do nothing */ }
|
||||
insert_after = new_item ? new_item->widget : NULL;
|
||||
insert_after = other_tile ? other_tile->widget : NULL;
|
||||
|
||||
if (offset > 0)
|
||||
{
|
||||
g_assert (item != NULL);
|
||||
new_item = gtk_rb_tree_insert_before (self->items, item);
|
||||
new_item->n_items = offset;
|
||||
item->n_items -= offset;
|
||||
gtk_rb_tree_node_mark_dirty (item);
|
||||
}
|
||||
tile = gtk_list_item_manager_ensure_split (self, tile, offset);
|
||||
|
||||
for (i = 0; i < query_n_items; i++)
|
||||
{
|
||||
g_assert (item != NULL);
|
||||
if (item->n_items > 1)
|
||||
{
|
||||
new_item = gtk_rb_tree_insert_before (self->items, item);
|
||||
new_item->n_items = 1;
|
||||
item->n_items--;
|
||||
gtk_rb_tree_node_mark_dirty (item);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_item = item;
|
||||
item = gtk_rb_tree_node_get_next (item);
|
||||
}
|
||||
if (new_item->widget == NULL)
|
||||
g_assert (tile != NULL);
|
||||
|
||||
while (tile->n_items == 0)
|
||||
tile = gtk_rb_tree_node_get_next (tile);
|
||||
|
||||
if (tile->n_items > 1)
|
||||
gtk_list_item_manager_ensure_split (self, tile, 1);
|
||||
|
||||
if (tile->widget == NULL)
|
||||
{
|
||||
if (change)
|
||||
{
|
||||
new_item->widget = gtk_list_item_manager_try_reacquire_list_item (self,
|
||||
change,
|
||||
position + i,
|
||||
insert_after);
|
||||
tile->widget = gtk_list_item_manager_try_reacquire_list_item (self,
|
||||
change,
|
||||
position + i,
|
||||
insert_after);
|
||||
}
|
||||
if (new_item->widget == NULL)
|
||||
if (tile->widget == NULL)
|
||||
{
|
||||
new_item->widget = g_queue_pop_head (&released);
|
||||
if (new_item->widget)
|
||||
tile->widget = g_queue_pop_head (&released);
|
||||
if (tile->widget)
|
||||
{
|
||||
gtk_list_item_manager_move_list_item (self,
|
||||
new_item->widget,
|
||||
tile->widget,
|
||||
position + i,
|
||||
insert_after);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_item->widget = gtk_list_item_manager_acquire_list_item (self,
|
||||
position + i,
|
||||
insert_after);
|
||||
tile->widget = gtk_list_item_manager_acquire_list_item (self,
|
||||
position + i,
|
||||
insert_after);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (update_start <= position + i)
|
||||
gtk_list_item_manager_update_list_item (self, new_item->widget, position + i);
|
||||
gtk_list_item_manager_update_list_item (self, tile->widget, position + i);
|
||||
}
|
||||
insert_after = new_item->widget;
|
||||
insert_after = tile->widget;
|
||||
|
||||
tile = gtk_rb_tree_node_get_next (tile);
|
||||
}
|
||||
position += query_n_items;
|
||||
}
|
||||
@ -608,17 +826,17 @@ gtk_list_item_manager_model_items_changed_cb (GListModel *model,
|
||||
* trying to find where it moved */
|
||||
if (l)
|
||||
{
|
||||
GtkListItemManagerItem *item, *new_item;
|
||||
GtkListTile *tile, *new_tile;
|
||||
GtkWidget *insert_after;
|
||||
guint i, offset;
|
||||
|
||||
item = gtk_list_item_manager_get_nth (self, position, &offset);
|
||||
for (new_item = item ? gtk_rb_tree_node_get_previous (item) : gtk_rb_tree_get_last (self->items);
|
||||
new_item && new_item->widget == NULL;
|
||||
new_item = gtk_rb_tree_node_get_previous (new_item))
|
||||
tile = gtk_list_item_manager_get_nth (self, position, &offset);
|
||||
for (new_tile = tile ? gtk_rb_tree_node_get_previous (tile) : gtk_rb_tree_get_last (self->items);
|
||||
new_tile && new_tile->widget == NULL;
|
||||
new_tile = gtk_rb_tree_node_get_previous (new_tile))
|
||||
{ }
|
||||
if (new_item)
|
||||
insert_after = new_item->widget;
|
||||
if (new_tile)
|
||||
insert_after = new_tile->widget;
|
||||
else
|
||||
insert_after = NULL; /* we're at the start */
|
||||
|
||||
@ -636,29 +854,24 @@ gtk_list_item_manager_model_items_changed_cb (GListModel *model,
|
||||
continue;
|
||||
}
|
||||
|
||||
while (offset >= tile->n_items)
|
||||
{
|
||||
offset -= tile->n_items;
|
||||
tile = gtk_rb_tree_node_get_next (tile);
|
||||
}
|
||||
if (offset > 0)
|
||||
{
|
||||
new_item = gtk_rb_tree_insert_before (self->items, item);
|
||||
new_item->n_items = offset;
|
||||
item->n_items -= offset;
|
||||
tile = gtk_list_item_manager_ensure_split (self, tile, offset);
|
||||
offset = 0;
|
||||
gtk_rb_tree_node_mark_dirty (item);
|
||||
}
|
||||
|
||||
if (item->n_items == 1)
|
||||
{
|
||||
new_item = item;
|
||||
item = gtk_rb_tree_node_get_next (item);
|
||||
}
|
||||
new_tile = tile;
|
||||
if (tile->n_items == 1)
|
||||
tile = gtk_rb_tree_node_get_next (tile);
|
||||
else
|
||||
{
|
||||
new_item = gtk_rb_tree_insert_before (self->items, item);
|
||||
new_item->n_items = 1;
|
||||
item->n_items--;
|
||||
gtk_rb_tree_node_mark_dirty (item);
|
||||
}
|
||||
tile = gtk_list_item_manager_ensure_split (self, tile, 1);
|
||||
|
||||
new_item->widget = widget;
|
||||
new_tile->widget = widget;
|
||||
insert_after = widget;
|
||||
}
|
||||
}
|
||||
@ -719,16 +932,16 @@ gtk_list_item_manager_model_items_changed_cb (GListModel *model,
|
||||
for (l = self->trackers; l; l = l->next)
|
||||
{
|
||||
GtkListItemTracker *tracker = l->data;
|
||||
GtkListItemManagerItem *item;
|
||||
GtkListTile *tile;
|
||||
|
||||
if (tracker->widget != NULL ||
|
||||
tracker->position == GTK_INVALID_LIST_POSITION)
|
||||
continue;
|
||||
|
||||
item = gtk_list_item_manager_get_nth (self, tracker->position, NULL);
|
||||
g_assert (item != NULL);
|
||||
g_assert (item->widget);
|
||||
tracker->widget = GTK_LIST_ITEM_WIDGET (item->widget);
|
||||
tile = gtk_list_item_manager_get_nth (self, tracker->position, NULL);
|
||||
g_assert (tile != NULL);
|
||||
g_assert (tile->widget);
|
||||
tracker->widget = GTK_LIST_ITEM_WIDGET (tile->widget);
|
||||
}
|
||||
|
||||
g_hash_table_unref (change);
|
||||
@ -742,28 +955,28 @@ gtk_list_item_manager_model_selection_changed_cb (GListModel *model,
|
||||
guint n_items,
|
||||
GtkListItemManager *self)
|
||||
{
|
||||
GtkListItemManagerItem *item;
|
||||
GtkListTile *tile;
|
||||
guint offset;
|
||||
|
||||
item = gtk_list_item_manager_get_nth (self, position, &offset);
|
||||
tile = gtk_list_item_manager_get_nth (self, position, &offset);
|
||||
|
||||
if (offset)
|
||||
{
|
||||
position += item->n_items - offset;
|
||||
if (item->n_items - offset > n_items)
|
||||
position += tile->n_items - offset;
|
||||
if (tile->n_items - offset > n_items)
|
||||
n_items = 0;
|
||||
else
|
||||
n_items -= item->n_items - offset;
|
||||
item = gtk_rb_tree_node_get_next (item);
|
||||
n_items -= tile->n_items - offset;
|
||||
tile = gtk_rb_tree_node_get_next (tile);
|
||||
}
|
||||
|
||||
while (n_items > 0)
|
||||
{
|
||||
if (item->widget)
|
||||
gtk_list_item_manager_update_list_item (self, item->widget, position);
|
||||
position += item->n_items;
|
||||
n_items -= MIN (n_items, item->n_items);
|
||||
item = gtk_rb_tree_node_get_next (item);
|
||||
if (tile->widget)
|
||||
gtk_list_item_manager_update_list_item (self, tile->widget, position);
|
||||
position += tile->n_items;
|
||||
n_items -= MIN (n_items, tile->n_items);
|
||||
tile = gtk_rb_tree_node_get_next (tile);
|
||||
}
|
||||
}
|
||||
|
||||
@ -842,14 +1055,14 @@ gtk_list_item_manager_set_factory (GtkListItemManager *self,
|
||||
for (l = self->trackers; l; l = l->next)
|
||||
{
|
||||
GtkListItemTracker *tracker = l->data;
|
||||
GtkListItemManagerItem *item;
|
||||
GtkListTile *tile;
|
||||
|
||||
if (tracker->widget == NULL)
|
||||
continue;
|
||||
|
||||
item = gtk_list_item_manager_get_nth (self, tracker->position, NULL);
|
||||
g_assert (item);
|
||||
tracker->widget = GTK_LIST_ITEM_WIDGET (item->widget);
|
||||
tile = gtk_list_item_manager_get_nth (self, tracker->position, NULL);
|
||||
g_assert (tile);
|
||||
tracker->widget = GTK_LIST_ITEM_WIDGET (tile->widget);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1087,18 +1300,18 @@ void
|
||||
gtk_list_item_manager_set_single_click_activate (GtkListItemManager *self,
|
||||
gboolean single_click_activate)
|
||||
{
|
||||
GtkListItemManagerItem *item;
|
||||
GtkListTile *tile;
|
||||
|
||||
g_return_if_fail (GTK_IS_LIST_ITEM_MANAGER (self));
|
||||
|
||||
self->single_click_activate = single_click_activate;
|
||||
|
||||
for (item = gtk_rb_tree_get_first (self->items);
|
||||
item != NULL;
|
||||
item = gtk_rb_tree_node_get_next (item))
|
||||
for (tile = gtk_rb_tree_get_first (self->items);
|
||||
tile != NULL;
|
||||
tile = gtk_rb_tree_node_get_next (tile))
|
||||
{
|
||||
if (item->widget)
|
||||
gtk_list_item_widget_set_single_click_activate (GTK_LIST_ITEM_WIDGET (item->widget), single_click_activate);
|
||||
if (tile->widget)
|
||||
gtk_list_item_widget_set_single_click_activate (GTK_LIST_ITEM_WIDGET (tile->widget), single_click_activate);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1148,7 +1361,7 @@ gtk_list_item_tracker_set_position (GtkListItemManager *self,
|
||||
guint n_before,
|
||||
guint n_after)
|
||||
{
|
||||
GtkListItemManagerItem *item;
|
||||
GtkListTile *tile;
|
||||
guint n_items;
|
||||
|
||||
gtk_list_item_tracker_unset_position (self, tracker);
|
||||
@ -1166,9 +1379,9 @@ gtk_list_item_tracker_set_position (GtkListItemManager *self,
|
||||
|
||||
gtk_list_item_manager_ensure_items (self, NULL, G_MAXUINT);
|
||||
|
||||
item = gtk_list_item_manager_get_nth (self, position, NULL);
|
||||
if (item)
|
||||
tracker->widget = GTK_LIST_ITEM_WIDGET (item->widget);
|
||||
tile = gtk_list_item_manager_get_nth (self, position, NULL);
|
||||
if (tile)
|
||||
tracker->widget = GTK_LIST_ITEM_WIDGET (tile->widget);
|
||||
|
||||
gtk_widget_queue_resize (self->widget);
|
||||
}
|
||||
|
@ -39,47 +39,67 @@ G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GtkListItemManager GtkListItemManager;
|
||||
typedef struct _GtkListItemManagerClass GtkListItemManagerClass;
|
||||
typedef struct _GtkListItemManagerItem GtkListItemManagerItem; /* sorry */
|
||||
typedef struct _GtkListItemManagerItemAugment GtkListItemManagerItemAugment;
|
||||
typedef struct _GtkListTile GtkListTile;
|
||||
typedef struct _GtkListTileAugment GtkListTileAugment;
|
||||
typedef struct _GtkListItemTracker GtkListItemTracker;
|
||||
|
||||
struct _GtkListItemManagerItem
|
||||
struct _GtkListTile
|
||||
{
|
||||
GtkWidget *widget;
|
||||
guint n_items;
|
||||
/* area occupied by tile. May be empty if tile has no allcoation */
|
||||
cairo_rectangle_int_t area;
|
||||
};
|
||||
|
||||
struct _GtkListItemManagerItemAugment
|
||||
struct _GtkListTileAugment
|
||||
{
|
||||
guint n_items;
|
||||
/* union of all areas of tile and children */
|
||||
cairo_rectangle_int_t area;
|
||||
};
|
||||
|
||||
|
||||
GType gtk_list_item_manager_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkListItemManager * gtk_list_item_manager_new_for_size (GtkWidget *widget,
|
||||
GtkListItemManager * gtk_list_item_manager_new (GtkWidget *widget,
|
||||
const char *item_css_name,
|
||||
GtkAccessibleRole item_role,
|
||||
gsize element_size,
|
||||
gsize augment_size,
|
||||
GtkRbTreeAugmentFunc augment_func);
|
||||
#define gtk_list_item_manager_new(widget, item_css_name, type, augment_type, augment_func) \
|
||||
gtk_list_item_manager_new_for_size (widget, item_css_name, sizeof (type), sizeof (augment_type), (augment_func))
|
||||
GtkListTile * (* split_func) (gpointer, GtkListTile *, guint),
|
||||
gpointer user_data);
|
||||
|
||||
void gtk_list_item_manager_augment_node (GtkRbTree *tree,
|
||||
gpointer node_augment,
|
||||
gpointer node,
|
||||
gpointer left,
|
||||
gpointer right);
|
||||
void gtk_list_item_manager_get_tile_bounds (GtkListItemManager *self,
|
||||
GdkRectangle *out_bounds);
|
||||
gpointer gtk_list_item_manager_get_root (GtkListItemManager *self);
|
||||
gpointer gtk_list_item_manager_get_first (GtkListItemManager *self);
|
||||
gpointer gtk_list_item_manager_get_last (GtkListItemManager *self);
|
||||
gpointer gtk_list_item_manager_get_nth (GtkListItemManager *self,
|
||||
guint position,
|
||||
guint *offset);
|
||||
guint gtk_list_item_manager_get_item_position (GtkListItemManager *self,
|
||||
gpointer item);
|
||||
gpointer gtk_list_item_manager_get_item_augment (GtkListItemManager *self,
|
||||
gpointer item);
|
||||
GtkListTile * gtk_list_item_manager_get_tile_at (GtkListItemManager *self,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
guint gtk_list_tile_get_position (GtkListItemManager *self,
|
||||
GtkListTile *tile);
|
||||
gpointer gtk_list_tile_get_augment (GtkListItemManager *self,
|
||||
GtkListTile *tile);
|
||||
void gtk_list_tile_set_area (GtkListItemManager *self,
|
||||
GtkListTile *tile,
|
||||
const cairo_rectangle_int_t *area);
|
||||
void gtk_list_tile_set_area_position (GtkListItemManager *self,
|
||||
GtkListTile *tile,
|
||||
int x,
|
||||
int y);
|
||||
void gtk_list_tile_set_area_size (GtkListItemManager *self,
|
||||
GtkListTile *tile,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
GtkListTile * gtk_list_tile_split (GtkListItemManager *self,
|
||||
GtkListTile *tile,
|
||||
guint n_items);
|
||||
GtkListTile * gtk_list_tile_gc (GtkListItemManager *self,
|
||||
GtkListTile *tile);
|
||||
|
||||
void gtk_list_item_manager_set_factory (GtkListItemManager *self,
|
||||
GtkListItemFactory *factory);
|
||||
|
@ -141,21 +141,6 @@
|
||||
* items use the %GTK_ACCESSIBLE_ROLE_LIST_ITEM role.
|
||||
*/
|
||||
|
||||
typedef struct _ListRow ListRow;
|
||||
typedef struct _ListRowAugment ListRowAugment;
|
||||
|
||||
struct _ListRow
|
||||
{
|
||||
GtkListItemManagerItem parent;
|
||||
guint height; /* per row */
|
||||
};
|
||||
|
||||
struct _ListRowAugment
|
||||
{
|
||||
GtkListItemManagerItemAugment parent;
|
||||
guint height; /* total */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
@ -181,188 +166,88 @@ static guint signals[LAST_SIGNAL] = { 0 };
|
||||
static void G_GNUC_UNUSED
|
||||
dump (GtkListView *self)
|
||||
{
|
||||
ListRow *row;
|
||||
GtkListTile *tile;
|
||||
guint n_widgets, n_list_rows;
|
||||
|
||||
n_widgets = 0;
|
||||
n_list_rows = 0;
|
||||
//g_print ("ANCHOR: %u - %u\n", self->anchor_start, self->anchor_end);
|
||||
for (row = gtk_list_item_manager_get_first (self->item_manager);
|
||||
row;
|
||||
row = gtk_rb_tree_node_get_next (row))
|
||||
for (tile = gtk_list_item_manager_get_first (self->item_manager);
|
||||
tile;
|
||||
tile = gtk_rb_tree_node_get_next (tile))
|
||||
{
|
||||
if (row->parent.widget)
|
||||
if (tile->widget)
|
||||
n_widgets++;
|
||||
n_list_rows++;
|
||||
g_print (" %4u%s (%upx)\n", row->parent.n_items, row->parent.widget ? " (widget)" : "", row->height);
|
||||
g_print (" %4u%s %d,%d,%d,%d\n", tile->n_items, tile->widget ? " (widget)" : "",
|
||||
tile->area.x, tile->area.y, tile->area.width, tile->area.height);
|
||||
}
|
||||
|
||||
g_print (" => %u widgets in %u list rows\n", n_widgets, n_list_rows);
|
||||
}
|
||||
|
||||
static void
|
||||
list_row_augment (GtkRbTree *tree,
|
||||
gpointer node_augment,
|
||||
gpointer node,
|
||||
gpointer left,
|
||||
gpointer right)
|
||||
{
|
||||
ListRow *row = node;
|
||||
ListRowAugment *aug = node_augment;
|
||||
|
||||
gtk_list_item_manager_augment_node (tree, node_augment, node, left, right);
|
||||
|
||||
aug->height = row->height * row->parent.n_items;
|
||||
|
||||
if (left)
|
||||
{
|
||||
ListRowAugment *left_aug = gtk_rb_tree_get_augment (tree, left);
|
||||
|
||||
aug->height += left_aug->height;
|
||||
}
|
||||
|
||||
if (right)
|
||||
{
|
||||
ListRowAugment *right_aug = gtk_rb_tree_get_augment (tree, right);
|
||||
|
||||
aug->height += right_aug->height;
|
||||
}
|
||||
}
|
||||
|
||||
static ListRow *
|
||||
gtk_list_view_get_row_at_y (GtkListView *self,
|
||||
int y,
|
||||
int *offset)
|
||||
{
|
||||
ListRow *row, *tmp;
|
||||
|
||||
row = gtk_list_item_manager_get_root (self->item_manager);
|
||||
|
||||
while (row)
|
||||
{
|
||||
tmp = gtk_rb_tree_node_get_left (row);
|
||||
if (tmp)
|
||||
{
|
||||
ListRowAugment *aug = gtk_list_item_manager_get_item_augment (self->item_manager, tmp);
|
||||
if (y < aug->height)
|
||||
{
|
||||
row = tmp;
|
||||
continue;
|
||||
}
|
||||
y -= aug->height;
|
||||
}
|
||||
|
||||
if (y < row->height * row->parent.n_items)
|
||||
break;
|
||||
y -= row->height * row->parent.n_items;
|
||||
|
||||
row = gtk_rb_tree_node_get_right (row);
|
||||
}
|
||||
|
||||
if (offset)
|
||||
*offset = row ? y : 0;
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
static int
|
||||
list_row_get_y (GtkListView *self,
|
||||
ListRow *row)
|
||||
{
|
||||
ListRow *parent, *left;
|
||||
int y;
|
||||
|
||||
left = gtk_rb_tree_node_get_left (row);
|
||||
if (left)
|
||||
{
|
||||
ListRowAugment *aug = gtk_list_item_manager_get_item_augment (self->item_manager, left);
|
||||
y = aug->height;
|
||||
}
|
||||
else
|
||||
y = 0;
|
||||
|
||||
for (parent = gtk_rb_tree_node_get_parent (row);
|
||||
parent != NULL;
|
||||
parent = gtk_rb_tree_node_get_parent (row))
|
||||
{
|
||||
left = gtk_rb_tree_node_get_left (parent);
|
||||
|
||||
if (left != row)
|
||||
{
|
||||
if (left)
|
||||
{
|
||||
ListRowAugment *aug = gtk_list_item_manager_get_item_augment (self->item_manager, left);
|
||||
y += aug->height;
|
||||
}
|
||||
y += parent->height * parent->parent.n_items;
|
||||
}
|
||||
|
||||
row = parent;
|
||||
}
|
||||
|
||||
return y ;
|
||||
}
|
||||
|
||||
static int
|
||||
gtk_list_view_get_list_height (GtkListView *self)
|
||||
{
|
||||
ListRow *row;
|
||||
ListRowAugment *aug;
|
||||
GtkListTile *tile;
|
||||
GtkListTileAugment *aug;
|
||||
|
||||
row = gtk_list_item_manager_get_root (self->item_manager);
|
||||
if (row == NULL)
|
||||
tile = gtk_list_item_manager_get_root (self->item_manager);
|
||||
if (tile == NULL)
|
||||
return 0;
|
||||
|
||||
aug = gtk_list_item_manager_get_item_augment (self->item_manager, row);
|
||||
return aug->height;
|
||||
aug = gtk_list_tile_get_augment (self->item_manager, tile);
|
||||
return aug->area.height;
|
||||
}
|
||||
|
||||
static GtkListTile *
|
||||
gtk_list_view_split (GtkListBase *base,
|
||||
GtkListTile *tile,
|
||||
guint n_items)
|
||||
{
|
||||
GtkListView *self = GTK_LIST_VIEW (base);
|
||||
GtkListTile *new_tile;
|
||||
guint row_height;
|
||||
|
||||
row_height = tile->area.height / tile->n_items;
|
||||
|
||||
new_tile = gtk_list_tile_split (self->item_manager, tile, n_items);
|
||||
gtk_list_tile_set_area_size (self->item_manager,
|
||||
tile,
|
||||
tile->area.width,
|
||||
row_height * tile->n_items);
|
||||
gtk_list_tile_set_area (self->item_manager,
|
||||
new_tile,
|
||||
&(GdkRectangle) {
|
||||
tile->area.x,
|
||||
tile->area.y + tile->area.height,
|
||||
tile->area.width,
|
||||
row_height * new_tile->n_items
|
||||
});
|
||||
|
||||
return new_tile;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_list_view_get_allocation_along (GtkListBase *base,
|
||||
guint pos,
|
||||
int *offset,
|
||||
int *size)
|
||||
gtk_list_view_get_allocation (GtkListBase *base,
|
||||
guint pos,
|
||||
GdkRectangle *area)
|
||||
{
|
||||
GtkListView *self = GTK_LIST_VIEW (base);
|
||||
ListRow *row;
|
||||
guint skip;
|
||||
int y;
|
||||
GtkListTile *tile;
|
||||
guint offset;
|
||||
|
||||
row = gtk_list_item_manager_get_nth (self->item_manager, pos, &skip);
|
||||
if (row == NULL)
|
||||
{
|
||||
if (offset)
|
||||
*offset = 0;
|
||||
if (size)
|
||||
*size = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
y = list_row_get_y (self, row);
|
||||
y += skip * row->height;
|
||||
tile = gtk_list_item_manager_get_nth (self->item_manager, pos, &offset);
|
||||
if (tile == NULL)
|
||||
return FALSE;
|
||||
|
||||
*area = tile->area;
|
||||
if (tile->n_items)
|
||||
area->height /= tile->n_items;
|
||||
if (offset)
|
||||
*offset = y;
|
||||
if (size)
|
||||
*size = row->height;
|
||||
area->y += offset * area->height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_list_view_get_allocation_across (GtkListBase *base,
|
||||
guint pos,
|
||||
int *offset,
|
||||
int *size)
|
||||
{
|
||||
GtkListView *self = GTK_LIST_VIEW (base);
|
||||
|
||||
if (offset)
|
||||
*offset = 0;
|
||||
if (size)
|
||||
*size = self->list_width;
|
||||
|
||||
return TRUE;
|
||||
return area->width > 0 && area->height > 0;
|
||||
}
|
||||
|
||||
static GtkBitset *
|
||||
@ -372,7 +257,7 @@ gtk_list_view_get_items_in_rect (GtkListBase *base,
|
||||
GtkListView *self = GTK_LIST_VIEW (base);
|
||||
guint first, last, n_items;
|
||||
GtkBitset *result;
|
||||
ListRow *row;
|
||||
GtkListTile *tile;
|
||||
|
||||
result = gtk_bitset_new_empty ();
|
||||
|
||||
@ -383,14 +268,14 @@ gtk_list_view_get_items_in_rect (GtkListBase *base,
|
||||
if (n_items == 0)
|
||||
return result;
|
||||
|
||||
row = gtk_list_view_get_row_at_y (self, rect->y, NULL);
|
||||
if (row)
|
||||
first = gtk_list_item_manager_get_item_position (self->item_manager, row);
|
||||
tile = gtk_list_item_manager_get_tile_at (self->item_manager, 0, rect->y);
|
||||
if (tile)
|
||||
first = gtk_list_tile_get_position (self->item_manager, tile);
|
||||
else
|
||||
first = rect->y < 0 ? 0 : n_items - 1;
|
||||
row = gtk_list_view_get_row_at_y (self, rect->y + rect->height, NULL);
|
||||
if (row)
|
||||
last = gtk_list_item_manager_get_item_position (self->item_manager, row);
|
||||
tile = gtk_list_item_manager_get_tile_at (self->item_manager, 0, rect->y + rect->height);
|
||||
if (tile)
|
||||
last = gtk_list_tile_get_position (self->item_manager, tile);
|
||||
else
|
||||
last = rect->y + rect->height < 0 ? 0 : n_items - 1;
|
||||
|
||||
@ -415,34 +300,42 @@ gtk_list_view_move_focus_along (GtkListBase *base,
|
||||
|
||||
static gboolean
|
||||
gtk_list_view_get_position_from_allocation (GtkListBase *base,
|
||||
int across,
|
||||
int along,
|
||||
int x,
|
||||
int y,
|
||||
guint *pos,
|
||||
cairo_rectangle_int_t *area)
|
||||
{
|
||||
GtkListView *self = GTK_LIST_VIEW (base);
|
||||
ListRow *row;
|
||||
int remaining;
|
||||
GtkListTile *tile;
|
||||
int row_height, tile_pos;
|
||||
|
||||
if (across >= self->list_width)
|
||||
tile = gtk_list_item_manager_get_tile_at (self->item_manager, x, y);
|
||||
if (tile == NULL)
|
||||
return FALSE;
|
||||
|
||||
along = CLAMP (along, 0, gtk_list_view_get_list_height (self) - 1);
|
||||
while (tile && tile->n_items == 0)
|
||||
tile = gtk_rb_tree_node_get_previous (tile);
|
||||
if (tile == NULL)
|
||||
{
|
||||
tile = gtk_list_item_manager_get_first (self->item_manager);
|
||||
while (tile && tile->n_items == 0)
|
||||
tile = gtk_rb_tree_node_get_next (tile);
|
||||
if (tile == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
row = gtk_list_view_get_row_at_y (self, along, &remaining);
|
||||
if (row == NULL)
|
||||
return FALSE;
|
||||
*pos = gtk_list_tile_get_position (self->item_manager, tile);
|
||||
row_height = (tile->area.height / tile->n_items);
|
||||
tile_pos = (y - tile->area.y) / row_height;
|
||||
|
||||
*pos = gtk_list_item_manager_get_item_position (self->item_manager, row);
|
||||
g_assert (remaining < row->height * row->parent.n_items);
|
||||
*pos += remaining / row->height;
|
||||
*pos += tile_pos;
|
||||
|
||||
if (area)
|
||||
{
|
||||
area->x = 0;
|
||||
area->width = self->list_width;
|
||||
area->y = along - remaining % row->height;
|
||||
area->height = row->height;
|
||||
area->x = tile->area.x;
|
||||
area->width = tile->area.width;
|
||||
area->y = tile->area.y + tile_pos * row_height;
|
||||
area->height = row_height;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -483,7 +376,7 @@ gtk_list_view_measure_across (GtkWidget *widget,
|
||||
int *natural)
|
||||
{
|
||||
GtkListView *self = GTK_LIST_VIEW (widget);
|
||||
ListRow *row;
|
||||
GtkListTile *tile;
|
||||
int min, nat, child_min, child_nat;
|
||||
/* XXX: Figure out how to split a given height into per-row heights.
|
||||
* Good luck! */
|
||||
@ -492,15 +385,15 @@ gtk_list_view_measure_across (GtkWidget *widget,
|
||||
min = 0;
|
||||
nat = 0;
|
||||
|
||||
for (row = gtk_list_item_manager_get_first (self->item_manager);
|
||||
row != NULL;
|
||||
row = gtk_rb_tree_node_get_next (row))
|
||||
for (tile = gtk_list_item_manager_get_first (self->item_manager);
|
||||
tile != NULL;
|
||||
tile = gtk_rb_tree_node_get_next (tile))
|
||||
{
|
||||
/* ignore unavailable rows */
|
||||
if (row->parent.widget == NULL)
|
||||
if (tile->widget == NULL)
|
||||
continue;
|
||||
|
||||
gtk_widget_measure (row->parent.widget,
|
||||
gtk_widget_measure (tile->widget,
|
||||
orientation, for_size,
|
||||
&child_min, &child_nat, NULL, NULL);
|
||||
min = MAX (min, child_min);
|
||||
@ -519,7 +412,7 @@ gtk_list_view_measure_list (GtkWidget *widget,
|
||||
int *natural)
|
||||
{
|
||||
GtkListView *self = GTK_LIST_VIEW (widget);
|
||||
ListRow *row;
|
||||
GtkListTile *tile;
|
||||
int min, nat, child_min, child_nat;
|
||||
GArray *min_heights, *nat_heights;
|
||||
guint n_unknown;
|
||||
@ -530,13 +423,13 @@ gtk_list_view_measure_list (GtkWidget *widget,
|
||||
min = 0;
|
||||
nat = 0;
|
||||
|
||||
for (row = gtk_list_item_manager_get_first (self->item_manager);
|
||||
row != NULL;
|
||||
row = gtk_rb_tree_node_get_next (row))
|
||||
for (tile = gtk_list_item_manager_get_first (self->item_manager);
|
||||
tile != NULL;
|
||||
tile = gtk_rb_tree_node_get_next (tile))
|
||||
{
|
||||
if (row->parent.widget)
|
||||
if (tile->widget)
|
||||
{
|
||||
gtk_widget_measure (row->parent.widget,
|
||||
gtk_widget_measure (tile->widget,
|
||||
orientation, for_size,
|
||||
&child_min, &child_nat, NULL, NULL);
|
||||
g_array_append_val (min_heights, child_min);
|
||||
@ -546,7 +439,7 @@ gtk_list_view_measure_list (GtkWidget *widget,
|
||||
}
|
||||
else
|
||||
{
|
||||
n_unknown += row->parent.n_items;
|
||||
n_unknown += tile->n_items;
|
||||
}
|
||||
}
|
||||
|
||||
@ -586,10 +479,9 @@ gtk_list_view_size_allocate (GtkWidget *widget,
|
||||
int baseline)
|
||||
{
|
||||
GtkListView *self = GTK_LIST_VIEW (widget);
|
||||
ListRow *row;
|
||||
GtkListTile *tile;
|
||||
GArray *heights;
|
||||
int min, nat, row_height;
|
||||
int x, y;
|
||||
int min, nat, row_height, y, list_width;
|
||||
GtkOrientation orientation, opposite_orientation;
|
||||
GtkScrollablePolicy scroll_policy, opposite_scroll_policy;
|
||||
|
||||
@ -599,9 +491,10 @@ gtk_list_view_size_allocate (GtkWidget *widget,
|
||||
opposite_scroll_policy = gtk_list_base_get_scroll_policy (GTK_LIST_BASE (self), opposite_orientation);
|
||||
|
||||
/* step 0: exit early if list is empty */
|
||||
if (gtk_list_item_manager_get_root (self->item_manager) == NULL)
|
||||
tile = gtk_list_tile_gc (self->item_manager, gtk_list_item_manager_get_first (self->item_manager));
|
||||
if (tile == NULL)
|
||||
{
|
||||
gtk_list_base_update_adjustments (GTK_LIST_BASE (self), 0, 0, 0, 0, &x, &y);
|
||||
gtk_list_base_allocate (GTK_LIST_BASE (self));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -609,85 +502,51 @@ gtk_list_view_size_allocate (GtkWidget *widget,
|
||||
gtk_list_view_measure_across (widget, opposite_orientation,
|
||||
-1,
|
||||
&min, &nat);
|
||||
self->list_width = orientation == GTK_ORIENTATION_VERTICAL ? width : height;
|
||||
list_width = orientation == GTK_ORIENTATION_VERTICAL ? width : height;
|
||||
if (opposite_scroll_policy == GTK_SCROLL_MINIMUM)
|
||||
self->list_width = MAX (min, self->list_width);
|
||||
list_width = MAX (min, list_width);
|
||||
else
|
||||
self->list_width = MAX (nat, self->list_width);
|
||||
list_width = MAX (nat, list_width);
|
||||
|
||||
/* step 2: determine height of known list items */
|
||||
/* step 2: determine height of known list items and gc the list */
|
||||
heights = g_array_new (FALSE, FALSE, sizeof (int));
|
||||
|
||||
for (row = gtk_list_item_manager_get_first (self->item_manager);
|
||||
row != NULL;
|
||||
row = gtk_rb_tree_node_get_next (row))
|
||||
for (;
|
||||
tile != NULL;
|
||||
tile = gtk_list_tile_gc (self->item_manager, gtk_rb_tree_node_get_next (tile)))
|
||||
{
|
||||
if (row->parent.widget == NULL)
|
||||
if (tile->widget == NULL)
|
||||
continue;
|
||||
|
||||
gtk_widget_measure (row->parent.widget, orientation,
|
||||
self->list_width,
|
||||
gtk_widget_measure (tile->widget, orientation,
|
||||
list_width,
|
||||
&min, &nat, NULL, NULL);
|
||||
if (scroll_policy == GTK_SCROLL_MINIMUM)
|
||||
row_height = min;
|
||||
else
|
||||
row_height = nat;
|
||||
if (row->height != row_height)
|
||||
{
|
||||
row->height = row_height;
|
||||
gtk_rb_tree_node_mark_dirty (row);
|
||||
}
|
||||
gtk_list_tile_set_area_size (self->item_manager, tile, list_width, row_height);
|
||||
g_array_append_val (heights, row_height);
|
||||
}
|
||||
|
||||
/* step 3: determine height of unknown items */
|
||||
/* step 3: determine height of unknown items and set the positions */
|
||||
row_height = gtk_list_view_get_unknown_row_height (self, heights);
|
||||
g_array_free (heights, TRUE);
|
||||
|
||||
for (row = gtk_list_item_manager_get_first (self->item_manager);
|
||||
row != NULL;
|
||||
row = gtk_rb_tree_node_get_next (row))
|
||||
y = 0;
|
||||
for (tile = gtk_list_item_manager_get_first (self->item_manager);
|
||||
tile != NULL;
|
||||
tile = gtk_rb_tree_node_get_next (tile))
|
||||
{
|
||||
if (row->parent.widget)
|
||||
continue;
|
||||
gtk_list_tile_set_area_position (self->item_manager, tile, 0, y);
|
||||
if (tile->widget == NULL)
|
||||
gtk_list_tile_set_area_size (self->item_manager, tile, list_width, row_height * tile->n_items);
|
||||
|
||||
if (row->height != row_height)
|
||||
{
|
||||
row->height = row_height;
|
||||
gtk_rb_tree_node_mark_dirty (row);
|
||||
}
|
||||
y += tile->area.height;
|
||||
}
|
||||
|
||||
/* step 3: update the adjustments */
|
||||
gtk_list_base_update_adjustments (GTK_LIST_BASE (self),
|
||||
self->list_width,
|
||||
gtk_list_view_get_list_height (self),
|
||||
gtk_widget_get_size (widget, opposite_orientation),
|
||||
gtk_widget_get_size (widget, orientation),
|
||||
&x, &y);
|
||||
x = -x;
|
||||
y = -y;
|
||||
|
||||
/* step 4: actually allocate the widgets */
|
||||
|
||||
for (row = gtk_list_item_manager_get_first (self->item_manager);
|
||||
row != NULL;
|
||||
row = gtk_rb_tree_node_get_next (row))
|
||||
{
|
||||
if (row->parent.widget)
|
||||
{
|
||||
gtk_list_base_size_allocate_child (GTK_LIST_BASE (self),
|
||||
row->parent.widget,
|
||||
x,
|
||||
y,
|
||||
self->list_width,
|
||||
row->height);
|
||||
}
|
||||
|
||||
y += row->height * row->parent.n_items;
|
||||
}
|
||||
|
||||
gtk_list_base_allocate_rubberband (GTK_LIST_BASE (self));
|
||||
/* step 4: allocate the rest */
|
||||
gtk_list_base_allocate (GTK_LIST_BASE (self));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -799,11 +658,8 @@ gtk_list_view_class_init (GtkListViewClass *klass)
|
||||
|
||||
list_base_class->list_item_name = "row";
|
||||
list_base_class->list_item_role = GTK_ACCESSIBLE_ROLE_LIST_ITEM;
|
||||
list_base_class->list_item_size = sizeof (ListRow);
|
||||
list_base_class->list_item_augment_size = sizeof (ListRowAugment);
|
||||
list_base_class->list_item_augment_func = list_row_augment;
|
||||
list_base_class->get_allocation_along = gtk_list_view_get_allocation_along;
|
||||
list_base_class->get_allocation_across = gtk_list_view_get_allocation_across;
|
||||
list_base_class->split = gtk_list_view_split;
|
||||
list_base_class->get_allocation = gtk_list_view_get_allocation;
|
||||
list_base_class->get_items_in_rect = gtk_list_view_get_items_in_rect;
|
||||
list_base_class->get_position_from_allocation = gtk_list_view_get_position_from_allocation;
|
||||
list_base_class->move_focus_along = gtk_list_view_move_focus_along;
|
||||
|
@ -31,8 +31,6 @@ struct _GtkListView
|
||||
|
||||
GtkListItemManager *item_manager;
|
||||
gboolean show_separators;
|
||||
|
||||
int list_width;
|
||||
};
|
||||
|
||||
struct _GtkListViewClass
|
||||
|
@ -329,6 +329,8 @@ update_at_context (GtkModelButton *button)
|
||||
|
||||
if (was_realized)
|
||||
gtk_at_context_realize (context);
|
||||
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1199,7 +1201,7 @@ gtk_model_button_class_init (GtkModelButtonClass *class)
|
||||
* A GIcon that will be used if iconic appearance for the button is
|
||||
* desired.
|
||||
*/
|
||||
properties[PROP_ICON] =
|
||||
properties[PROP_ICON] =
|
||||
g_param_spec_object ("icon", NULL, NULL,
|
||||
G_TYPE_ICON,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
@ -4033,9 +4033,6 @@ gtk_notebook_insert_notebook_page (GtkNotebook *notebook,
|
||||
g_signal_connect (controller, "enter", G_CALLBACK (gtk_notebook_tab_drop_enter), page);
|
||||
g_signal_connect (controller, "leave", G_CALLBACK (gtk_notebook_tab_drop_leave), page);
|
||||
gtk_widget_add_controller (page->tab_widget, controller);
|
||||
gtk_accessible_update_property (GTK_ACCESSIBLE (page->tab_widget),
|
||||
GTK_ACCESSIBLE_PROPERTY_LABEL, _("Tab"),
|
||||
-1);
|
||||
|
||||
page->expand = FALSE;
|
||||
page->fill = TRUE;
|
||||
@ -4335,6 +4332,11 @@ gtk_notebook_update_labels (GtkNotebook *notebook)
|
||||
text = page->tab_text;
|
||||
else
|
||||
text = string;
|
||||
|
||||
gtk_accessible_update_property (GTK_ACCESSIBLE (page->tab_widget),
|
||||
GTK_ACCESSIBLE_PROPERTY_LABEL, text,
|
||||
-1);
|
||||
|
||||
if (notebook->show_tabs)
|
||||
{
|
||||
if (page->default_tab)
|
||||
|
@ -218,7 +218,7 @@ gtk_path_bar_init (GtkPathBar *path_bar)
|
||||
desktop = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
|
||||
if (desktop != NULL)
|
||||
path_bar->desktop_file = g_file_new_for_path (desktop);
|
||||
else
|
||||
else
|
||||
path_bar->desktop_file = NULL;
|
||||
}
|
||||
else
|
||||
@ -306,7 +306,7 @@ update_visibility_up_to_next_root (GtkPathBar *path_bar,
|
||||
{
|
||||
gboolean fake_root_found = FALSE;
|
||||
GList *l;
|
||||
|
||||
|
||||
for (l = start_from_button; l; l = l->next)
|
||||
{
|
||||
GtkWidget *button = BUTTON_DATA (l->data)->button;
|
||||
@ -776,6 +776,7 @@ gtk_path_bar_get_info_callback (GObject *source,
|
||||
GFileInfo *info;
|
||||
ButtonData *button_data;
|
||||
const char *display_name;
|
||||
gboolean has_is_hidden, has_is_backup;
|
||||
gboolean is_hidden;
|
||||
|
||||
info = g_file_query_info_finish (file, result, NULL);
|
||||
@ -794,7 +795,10 @@ gtk_path_bar_get_info_callback (GObject *source,
|
||||
file_info->cancellable = NULL;
|
||||
|
||||
display_name = g_file_info_get_display_name (info);
|
||||
is_hidden = g_file_info_get_is_hidden (info) || g_file_info_get_is_backup (info);
|
||||
has_is_hidden = g_file_info_has_attribute (info, "standard::is-hidden");
|
||||
has_is_backup = g_file_info_has_attribute (info, "standard::is-backup");
|
||||
is_hidden = (has_is_hidden && g_file_info_get_is_hidden (info)) ||
|
||||
(has_is_backup && g_file_info_get_is_backup (info));
|
||||
|
||||
button_data = make_directory_button (file_info->path_bar, display_name,
|
||||
file_info->file,
|
||||
@ -879,7 +883,7 @@ _gtk_path_bar_set_file (GtkPathBar *path_bar,
|
||||
/**
|
||||
* _gtk_path_bar_up:
|
||||
* @path_bar: a `GtkPathBar`
|
||||
*
|
||||
*
|
||||
* If the selected button in the pathbar is not the furthest button “up” (in the
|
||||
* root direction), act as if the user clicked on the next button up.
|
||||
**/
|
||||
@ -906,7 +910,7 @@ _gtk_path_bar_up (GtkPathBar *path_bar)
|
||||
/**
|
||||
* _gtk_path_bar_down:
|
||||
* @path_bar: a `GtkPathBar`
|
||||
*
|
||||
*
|
||||
* If the selected button in the pathbar is not the furthest button “down” (in the
|
||||
* leaf direction), act as if the user clicked on the next button down.
|
||||
**/
|
||||
|
@ -45,7 +45,8 @@ gtk_render_node_paintable_paintable_snapshot (GdkPaintable *paintable,
|
||||
GtkRenderNodePaintable *self = GTK_RENDER_NODE_PAINTABLE (paintable);
|
||||
|
||||
if (self->bounds.size.width <= 0 ||
|
||||
self->bounds.size.height <= 0)
|
||||
self->bounds.size.height <= 0 ||
|
||||
self->node == NULL)
|
||||
return;
|
||||
|
||||
gtk_snapshot_save (snapshot);
|
||||
@ -141,12 +142,12 @@ gtk_render_node_paintable_new (GskRenderNode *node,
|
||||
{
|
||||
GtkRenderNodePaintable *self;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL);
|
||||
g_return_val_if_fail (node == NULL || GSK_IS_RENDER_NODE (node), NULL);
|
||||
g_return_val_if_fail (bounds != NULL, NULL);
|
||||
|
||||
self = g_object_new (GTK_TYPE_RENDER_NODE_PAINTABLE, NULL);
|
||||
|
||||
self->node = gsk_render_node_ref (node);
|
||||
self->node = node ? gsk_render_node_ref (node) : NULL;
|
||||
self->bounds = *bounds;
|
||||
|
||||
return GDK_PAINTABLE (self);
|
||||
|
@ -34,12 +34,14 @@
|
||||
|
||||
#include "gtksearchenginetracker3private.h"
|
||||
|
||||
#define N_RESULT_BATCH_ITEMS 50
|
||||
|
||||
#define MINER_FS_BUS_NAME "org.freedesktop.Tracker3.Miner.Files"
|
||||
|
||||
#define SEARCH_QUERY_BASE(__PATTERN__) \
|
||||
"SELECT ?url " \
|
||||
" nfo:fileName(?urn) " \
|
||||
" nie:mimeType(?urn)" \
|
||||
" nie:mimeType(?ie)" \
|
||||
" nfo:fileSize(?urn)" \
|
||||
" nfo:fileLastModified(?urn)" \
|
||||
"FROM tracker:FileSystem " \
|
||||
@ -47,13 +49,13 @@
|
||||
" ?urn a nfo:FileDataObject ;" \
|
||||
" nie:url ?url ; " \
|
||||
" fts:match ~match . " \
|
||||
" OPTIONAL { ?urn nie:interpretedAs ?ie } ." \
|
||||
__PATTERN__ \
|
||||
"} " \
|
||||
"ORDER BY DESC(fts:rank(?urn)) DESC(?url)"
|
||||
"ORDER BY ASC(?url)"
|
||||
|
||||
#define SEARCH_QUERY SEARCH_QUERY_BASE("")
|
||||
#define SEARCH_RECURSIVE_QUERY SEARCH_QUERY_BASE("?urn (nfo:belongsToContainer/nie:isStoredAs)+/nie:url ~location")
|
||||
#define SEARCH_LOCATION_QUERY SEARCH_QUERY_BASE("?urn nfo:belongsToContainer/nie:isStoredAs/nie:url ~location")
|
||||
#define SEARCH_RECURSIVE_QUERY SEARCH_QUERY_BASE("FILTER (STRSTARTS (?url, CONCAT (~location, '/')))")
|
||||
|
||||
struct _GtkSearchEngineTracker3
|
||||
{
|
||||
@ -61,8 +63,8 @@ struct _GtkSearchEngineTracker3
|
||||
TrackerSparqlConnection *sparql_conn;
|
||||
TrackerSparqlStatement *search_query;
|
||||
TrackerSparqlStatement *search_recursive_query;
|
||||
TrackerSparqlStatement *search_location_query;
|
||||
GCancellable *cancellable;
|
||||
guint idle_id;
|
||||
GtkQuery *query;
|
||||
gboolean query_pending;
|
||||
};
|
||||
@ -72,6 +74,13 @@ struct _GtkSearchEngineTracker3Class
|
||||
GtkSearchEngineClass parent_class;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
TrackerSparqlCursor *cursor;
|
||||
GtkSearchEngineTracker3 *engine;
|
||||
gboolean got_results;
|
||||
} CursorData;
|
||||
|
||||
static void gtk_search_engine_tracker3_initable_iface_init (GInitableIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkSearchEngineTracker3,
|
||||
@ -95,8 +104,11 @@ finalize (GObject *object)
|
||||
g_object_unref (engine->cancellable);
|
||||
}
|
||||
|
||||
g_clear_handle_id (&engine->idle_id, g_source_remove);
|
||||
|
||||
g_clear_object (&engine->search_query);
|
||||
g_clear_object (&engine->search_location_query);
|
||||
g_clear_object (&engine->search_recursive_query);
|
||||
|
||||
if (engine->sparql_conn != NULL)
|
||||
{
|
||||
tracker_sparql_connection_close (engine->sparql_conn);
|
||||
@ -131,7 +143,18 @@ create_file_info (GFile *file,
|
||||
|
||||
str = tracker_sparql_cursor_get_string (cursor, 2, NULL);
|
||||
if (str)
|
||||
g_file_info_set_content_type (info, str);
|
||||
{
|
||||
g_file_info_set_content_type (info, str);
|
||||
g_file_info_set_attribute_uint32 (info, "standard::type",
|
||||
strcmp (str, "inode/directory") == 0 ?
|
||||
G_FILE_TYPE_DIRECTORY :
|
||||
G_FILE_TYPE_REGULAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_file_info_set_content_type (info, "application/text");
|
||||
g_file_info_set_attribute_uint32 (info, "standard::type", G_FILE_TYPE_UNKNOWN);
|
||||
}
|
||||
|
||||
g_file_info_set_size (info,
|
||||
tracker_sparql_cursor_get_integer (cursor, 3));
|
||||
@ -151,6 +174,59 @@ create_file_info (GFile *file,
|
||||
return info;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_cursor_idle_cb (gpointer user_data)
|
||||
{
|
||||
CursorData *data = user_data;
|
||||
GtkSearchEngineTracker3 *engine = data->engine;
|
||||
TrackerSparqlCursor *cursor = data->cursor;
|
||||
gboolean has_next;
|
||||
GList *hits = NULL;
|
||||
GtkSearchHit *hit;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < N_RESULT_BATCH_ITEMS; i++)
|
||||
{
|
||||
const gchar *url;
|
||||
|
||||
has_next = tracker_sparql_cursor_next (cursor, NULL, NULL);
|
||||
if (!has_next)
|
||||
break;
|
||||
|
||||
url = tracker_sparql_cursor_get_string (cursor, 0, NULL);
|
||||
hit = g_slice_new0 (GtkSearchHit);
|
||||
hit->file = g_file_new_for_uri (url);
|
||||
hit->info = create_file_info (hit->file, cursor);
|
||||
hits = g_list_prepend (hits, hit);
|
||||
data->got_results = TRUE;
|
||||
}
|
||||
|
||||
_gtk_search_engine_hits_added (GTK_SEARCH_ENGINE (engine), hits);
|
||||
|
||||
g_list_free_full (hits, free_hit);
|
||||
|
||||
if (has_next)
|
||||
return G_SOURCE_CONTINUE;
|
||||
else
|
||||
{
|
||||
engine->idle_id = 0;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cursor_data_free (gpointer user_data)
|
||||
{
|
||||
CursorData *data = user_data;
|
||||
|
||||
tracker_sparql_cursor_close (data->cursor);
|
||||
_gtk_search_engine_finished (GTK_SEARCH_ENGINE (data->engine),
|
||||
data->got_results);
|
||||
g_object_unref (data->cursor);
|
||||
g_object_unref (data->engine);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
query_callback (TrackerSparqlStatement *statement,
|
||||
GAsyncResult *res,
|
||||
@ -158,9 +234,8 @@ query_callback (TrackerSparqlStatement *statement,
|
||||
{
|
||||
GtkSearchEngineTracker3 *engine;
|
||||
TrackerSparqlCursor *cursor;
|
||||
GList *hits = NULL;
|
||||
GError *error = NULL;
|
||||
GtkSearchHit *hit;
|
||||
CursorData *data;
|
||||
|
||||
engine = GTK_SEARCH_ENGINE_TRACKER3 (user_data);
|
||||
|
||||
@ -176,25 +251,14 @@ query_callback (TrackerSparqlStatement *statement,
|
||||
return;
|
||||
}
|
||||
|
||||
while (tracker_sparql_cursor_next (cursor, NULL, NULL))
|
||||
{
|
||||
const char *url;
|
||||
data = g_new0 (CursorData, 1);
|
||||
data->cursor = cursor;
|
||||
data->engine = engine;
|
||||
|
||||
url = tracker_sparql_cursor_get_string (cursor, 0, NULL);
|
||||
hit = g_slice_new0 (GtkSearchHit);
|
||||
hit->file = g_file_new_for_uri (url);
|
||||
hit->info = create_file_info (hit->file, cursor);
|
||||
hits = g_list_prepend (hits, hit);
|
||||
}
|
||||
|
||||
tracker_sparql_cursor_close (cursor);
|
||||
|
||||
_gtk_search_engine_hits_added (GTK_SEARCH_ENGINE (engine), hits);
|
||||
_gtk_search_engine_finished (GTK_SEARCH_ENGINE (engine), hits != NULL);
|
||||
|
||||
g_list_free_full (hits, free_hit);
|
||||
g_object_unref (engine);
|
||||
g_object_unref (cursor);
|
||||
engine->idle_id =
|
||||
g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
|
||||
handle_cursor_idle_cb,
|
||||
data, cursor_data_free);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -205,7 +269,6 @@ gtk_search_engine_tracker3_start (GtkSearchEngine *engine)
|
||||
const char *search_text;
|
||||
char *match;
|
||||
GFile *location;
|
||||
gboolean recursive;
|
||||
|
||||
tracker = GTK_SEARCH_ENGINE_TRACKER3 (engine);
|
||||
|
||||
@ -221,25 +284,20 @@ gtk_search_engine_tracker3_start (GtkSearchEngine *engine)
|
||||
return;
|
||||
}
|
||||
|
||||
tracker->query_pending = TRUE;
|
||||
search_text = gtk_query_get_text (tracker->query);
|
||||
location = gtk_query_get_location (tracker->query);
|
||||
recursive = TRUE;
|
||||
|
||||
if (strlen (search_text) <= 1)
|
||||
return;
|
||||
|
||||
tracker->query_pending = TRUE;
|
||||
|
||||
if (location)
|
||||
{
|
||||
char *location_uri = g_file_get_uri (location);
|
||||
|
||||
if (recursive)
|
||||
{
|
||||
g_debug ("Recursive search query in location: %s", location_uri);
|
||||
statement = tracker->search_recursive_query;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_debug ("Search query in location: %s", location_uri);
|
||||
statement = tracker->search_location_query;
|
||||
}
|
||||
g_debug ("Recursive search query in location: %s", location_uri);
|
||||
statement = tracker->search_recursive_query;
|
||||
|
||||
tracker_sparql_statement_bind_string (statement,
|
||||
"location",
|
||||
@ -273,6 +331,8 @@ gtk_search_engine_tracker3_stop (GtkSearchEngine *engine)
|
||||
g_cancellable_cancel (tracker->cancellable);
|
||||
tracker->query_pending = FALSE;
|
||||
}
|
||||
|
||||
g_clear_handle_id (&tracker->idle_id, g_source_remove);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -343,14 +403,6 @@ gtk_search_engine_tracker3_initable_init (GInitable *initable,
|
||||
if (!engine->search_recursive_query)
|
||||
return FALSE;
|
||||
|
||||
engine->search_location_query =
|
||||
tracker_sparql_connection_query_statement (engine->sparql_conn,
|
||||
SEARCH_LOCATION_QUERY,
|
||||
cancellable,
|
||||
error);
|
||||
if (!engine->search_location_query)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1623,17 +1623,22 @@ gtk_snapshot_to_paintable (GtkSnapshot *snapshot,
|
||||
{
|
||||
graphene_size_init_from_size (&bounds.size, size);
|
||||
}
|
||||
else
|
||||
else if (node)
|
||||
{
|
||||
gsk_render_node_get_bounds (node, &bounds);
|
||||
bounds.size.width += bounds.origin.x;
|
||||
bounds.size.height += bounds.origin.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
bounds.size.width = 0;
|
||||
bounds.size.height = 0;
|
||||
}
|
||||
bounds.origin.x = 0;
|
||||
bounds.origin.y = 0;
|
||||
|
||||
paintable = gtk_render_node_paintable_new (node, &bounds);
|
||||
gsk_render_node_unref (node);
|
||||
g_clear_pointer (&node, gsk_render_node_unref);
|
||||
|
||||
return paintable;
|
||||
}
|
||||
|
@ -219,6 +219,7 @@ struct _GtkStackPage
|
||||
guint needs_attention : 1;
|
||||
guint visible : 1;
|
||||
guint use_underline : 1;
|
||||
guint in_destruction : 1;
|
||||
};
|
||||
|
||||
typedef struct _GtkStackPageClass GtkStackPageClass;
|
||||
@ -235,6 +236,14 @@ gtk_stack_page_accessible_get_at_context (GtkAccessible *accessible)
|
||||
{
|
||||
GtkStackPage *page = GTK_STACK_PAGE (accessible);
|
||||
|
||||
if (page->in_destruction)
|
||||
{
|
||||
GTK_DEBUG (A11Y, "ATContext for “%s” [%p] accessed during destruction",
|
||||
G_OBJECT_TYPE_NAME (accessible),
|
||||
accessible);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (page->at_context == NULL)
|
||||
{
|
||||
GtkAccessibleRole role = GTK_ACCESSIBLE_ROLE_TAB_PANEL;
|
||||
@ -246,9 +255,11 @@ gtk_stack_page_accessible_get_at_context (GtkAccessible *accessible)
|
||||
display = gdk_display_get_default ();
|
||||
|
||||
page->at_context = gtk_at_context_create (role, accessible, display);
|
||||
if (page->at_context == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return page->at_context;
|
||||
return g_object_ref (page->at_context);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -262,30 +273,36 @@ static GtkAccessible *
|
||||
gtk_stack_page_accessible_get_accessible_parent (GtkAccessible *accessible)
|
||||
{
|
||||
GtkStackPage *page = GTK_STACK_PAGE (accessible);
|
||||
GtkWidget *parent;
|
||||
|
||||
if (page->widget == NULL)
|
||||
return NULL;
|
||||
else
|
||||
return GTK_ACCESSIBLE (gtk_widget_get_parent (page->widget));
|
||||
|
||||
parent = _gtk_widget_get_parent (page->widget);
|
||||
|
||||
return GTK_ACCESSIBLE (g_object_ref (parent));
|
||||
}
|
||||
|
||||
static GtkAccessible *
|
||||
gtk_stack_page_accessible_get_first_accessible_child(GtkAccessible *accessible)
|
||||
gtk_stack_page_accessible_get_first_accessible_child (GtkAccessible *accessible)
|
||||
{
|
||||
GtkStackPage *page = GTK_STACK_PAGE (accessible);
|
||||
|
||||
if (page->widget != NULL)
|
||||
return GTK_ACCESSIBLE (page->widget);
|
||||
else
|
||||
if (page->widget == NULL)
|
||||
return NULL;
|
||||
|
||||
return GTK_ACCESSIBLE (g_object_ref (page->widget));
|
||||
}
|
||||
|
||||
static GtkAccessible *
|
||||
gtk_stack_page_accessible_get_next_accessible_sibling(GtkAccessible *accessible)
|
||||
gtk_stack_page_accessible_get_next_accessible_sibling (GtkAccessible *accessible)
|
||||
{
|
||||
GtkStackPage *page = GTK_STACK_PAGE (accessible);
|
||||
|
||||
return GTK_ACCESSIBLE (page->next_page);
|
||||
if (page->next_page == NULL)
|
||||
return NULL;
|
||||
|
||||
return GTK_ACCESSIBLE (g_object_ref (page->next_page));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -345,6 +362,8 @@ gtk_stack_page_dispose (GObject *object)
|
||||
{
|
||||
GtkStackPage *page = GTK_STACK_PAGE (object);
|
||||
|
||||
page->in_destruction = TRUE;
|
||||
|
||||
g_clear_object (&page->at_context);
|
||||
|
||||
G_OBJECT_CLASS (gtk_stack_page_parent_class)->dispose (object);
|
||||
@ -791,7 +810,8 @@ gtk_stack_accessible_get_first_accessible_child (GtkAccessible *accessible)
|
||||
GtkStack *stack = GTK_STACK (accessible);
|
||||
GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
|
||||
GtkStackPage *page = g_ptr_array_index (priv->children, 0);
|
||||
return GTK_ACCESSIBLE (page);
|
||||
|
||||
return GTK_ACCESSIBLE (g_object_ref (page));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -172,6 +172,7 @@ gtk_test_accessible_has_property (GtkAccessible *accessible,
|
||||
GtkAccessibleProperty property)
|
||||
{
|
||||
GtkATContext *context;
|
||||
gboolean res;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_ACCESSIBLE (accessible), FALSE);
|
||||
|
||||
@ -179,7 +180,11 @@ gtk_test_accessible_has_property (GtkAccessible *accessible,
|
||||
if (context == NULL)
|
||||
return FALSE;
|
||||
|
||||
return gtk_at_context_has_accessible_property (context, property);
|
||||
res = gtk_at_context_has_accessible_property (context, property);
|
||||
|
||||
g_object_unref (context);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -230,6 +235,7 @@ gtk_test_accessible_check_property (GtkAccessible *accessible,
|
||||
|
||||
out:
|
||||
gtk_accessible_value_unref (check_value);
|
||||
g_object_unref (context);
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -248,6 +254,7 @@ gtk_test_accessible_has_state (GtkAccessible *accessible,
|
||||
GtkAccessibleState state)
|
||||
{
|
||||
GtkATContext *context;
|
||||
gboolean res;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_ACCESSIBLE (accessible), FALSE);
|
||||
|
||||
@ -255,7 +262,11 @@ gtk_test_accessible_has_state (GtkAccessible *accessible,
|
||||
if (context == NULL)
|
||||
return FALSE;
|
||||
|
||||
return gtk_at_context_has_accessible_state (context, state);
|
||||
res = gtk_at_context_has_accessible_state (context, state);
|
||||
|
||||
g_object_unref (context);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -306,6 +317,7 @@ gtk_test_accessible_check_state (GtkAccessible *accessible,
|
||||
|
||||
out:
|
||||
gtk_accessible_value_unref (check_value);
|
||||
g_object_unref (context);
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -324,6 +336,7 @@ gtk_test_accessible_has_relation (GtkAccessible *accessible,
|
||||
GtkAccessibleRelation relation)
|
||||
{
|
||||
GtkATContext *context;
|
||||
gboolean res;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_ACCESSIBLE (accessible), FALSE);
|
||||
|
||||
@ -331,7 +344,11 @@ gtk_test_accessible_has_relation (GtkAccessible *accessible,
|
||||
if (context == NULL)
|
||||
return FALSE;
|
||||
|
||||
return gtk_at_context_has_accessible_relation (context, relation);
|
||||
res = gtk_at_context_has_accessible_relation (context, relation);
|
||||
|
||||
g_object_unref (context);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -382,6 +399,7 @@ gtk_test_accessible_check_relation (GtkAccessible *accessible,
|
||||
|
||||
out:
|
||||
gtk_accessible_value_unref (check_value);
|
||||
g_object_unref (context);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -247,6 +247,7 @@ struct _GtkTextPrivate
|
||||
guint populate_all : 1;
|
||||
guint propagate_text_width : 1;
|
||||
guint text_handles_enabled : 1;
|
||||
guint enable_undo : 1;
|
||||
};
|
||||
|
||||
struct _GtkTextPasswordHint
|
||||
@ -397,6 +398,9 @@ static void gtk_text_set_max_width_chars (GtkText *self,
|
||||
static void gtk_text_set_alignment (GtkText *self,
|
||||
float xalign);
|
||||
|
||||
static void gtk_text_set_enable_undo (GtkText *self,
|
||||
gboolean enable_undo);
|
||||
|
||||
/* Default signal handlers
|
||||
*/
|
||||
static GMenuModel *gtk_text_get_menu_model (GtkText *self);
|
||||
@ -561,6 +565,7 @@ static void begin_change (GtkText *self);
|
||||
static void end_change (GtkText *self);
|
||||
static void emit_changed (GtkText *self);
|
||||
|
||||
static void gtk_text_update_history (GtkText *self);
|
||||
static void gtk_text_update_clipboard_actions (GtkText *self);
|
||||
static void gtk_text_update_emoji_action (GtkText *self);
|
||||
static void gtk_text_update_handles (GtkText *self);
|
||||
@ -1602,11 +1607,7 @@ gtk_text_set_property (GObject *object,
|
||||
break;
|
||||
|
||||
case NUM_PROPERTIES + GTK_EDITABLE_PROP_ENABLE_UNDO:
|
||||
if (g_value_get_boolean (value) != gtk_text_history_get_enabled (priv->history))
|
||||
{
|
||||
gtk_text_history_set_enabled (priv->history, g_value_get_boolean (value));
|
||||
g_object_notify_by_pspec (object, pspec);
|
||||
}
|
||||
gtk_text_set_enable_undo (self, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
/* GtkText properties */
|
||||
@ -1732,7 +1733,7 @@ gtk_text_get_property (GObject *object,
|
||||
break;
|
||||
|
||||
case NUM_PROPERTIES + GTK_EDITABLE_PROP_ENABLE_UNDO:
|
||||
g_value_set_boolean (value, gtk_text_history_get_enabled (priv->history));
|
||||
g_value_set_boolean (value, priv->enable_undo);
|
||||
break;
|
||||
|
||||
/* GtkText properties */
|
||||
@ -1858,6 +1859,7 @@ gtk_text_init (GtkText *self)
|
||||
priv->cursor_alpha = 1.0;
|
||||
priv->invisible_char = 0;
|
||||
priv->history = gtk_text_history_new (&history_funcs, self);
|
||||
priv->enable_undo = TRUE;
|
||||
|
||||
gtk_text_history_set_max_undo_levels (priv->history, DEFAULT_MAX_UNDO);
|
||||
|
||||
@ -3400,11 +3402,15 @@ gtk_text_insert_text (GtkText *self,
|
||||
* The incoming text may a password or other secret. We make sure
|
||||
* not to copy it into temporary buffers.
|
||||
*/
|
||||
if (priv->change_count == 0)
|
||||
gtk_text_history_begin_irreversible_action (priv->history);
|
||||
begin_change (self);
|
||||
|
||||
n_inserted = gtk_entry_buffer_insert_text (get_buffer (self), *position, text, n_chars);
|
||||
|
||||
end_change (self);
|
||||
if (priv->change_count == 0)
|
||||
gtk_text_history_end_irreversible_action (priv->history);
|
||||
|
||||
if (n_inserted != n_chars)
|
||||
gtk_widget_error_bell (GTK_WIDGET (self));
|
||||
@ -3426,11 +3432,16 @@ gtk_text_delete_text (GtkText *self,
|
||||
if (start_pos == end_pos)
|
||||
return;
|
||||
|
||||
if (priv->change_count == 0)
|
||||
gtk_text_history_begin_irreversible_action (priv->history);
|
||||
begin_change (self);
|
||||
|
||||
gtk_entry_buffer_delete_text (get_buffer (self), start_pos, end_pos - start_pos);
|
||||
|
||||
end_change (self);
|
||||
if (priv->change_count == 0)
|
||||
gtk_text_history_end_irreversible_action (priv->history);
|
||||
|
||||
update_placeholder_visibility (self);
|
||||
if (priv->propagate_text_width)
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
@ -5525,6 +5536,7 @@ gtk_text_set_editable (GtkText *self,
|
||||
gtk_event_controller_key_set_im_context (GTK_EVENT_CONTROLLER_KEY (priv->key_controller),
|
||||
is_editable ? priv->im_context : NULL);
|
||||
|
||||
gtk_text_update_history (self);
|
||||
gtk_text_update_clipboard_actions (self);
|
||||
gtk_text_update_emoji_action (self);
|
||||
|
||||
@ -5605,7 +5617,7 @@ gtk_text_set_visibility (GtkText *self,
|
||||
gtk_text_recompute (self);
|
||||
|
||||
/* disable undo when invisible text is used */
|
||||
gtk_text_history_set_enabled (priv->history, visible);
|
||||
gtk_text_update_history (self);
|
||||
|
||||
gtk_text_update_clipboard_actions (self);
|
||||
}
|
||||
@ -6342,6 +6354,9 @@ gtk_text_drag_drop (GtkDropTarget *dest,
|
||||
drop_position = gtk_text_find_position (self, x + priv->scroll_offset);
|
||||
|
||||
str = g_value_get_string (value);
|
||||
if (str == NULL)
|
||||
str = "";
|
||||
|
||||
if (priv->truncate_multiline)
|
||||
length = truncate_multiline (str);
|
||||
else
|
||||
@ -7284,3 +7299,28 @@ gtk_text_history_select_cb (gpointer funcs_data,
|
||||
selection_insert,
|
||||
selection_bound);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_set_enable_undo (GtkText *self,
|
||||
gboolean enable_undo)
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
|
||||
if (priv->enable_undo == enable_undo)
|
||||
return;
|
||||
|
||||
priv->enable_undo = enable_undo;
|
||||
gtk_text_update_history (self);
|
||||
g_object_notify (G_OBJECT (self), "enable-undo");
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_update_history (GtkText *self)
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
|
||||
gtk_text_history_set_enabled (priv->history,
|
||||
priv->enable_undo &&
|
||||
priv->visible &&
|
||||
priv->editable);
|
||||
}
|
||||
|
@ -5336,7 +5336,7 @@ gtk_text_buffer_get_run_attributes (GtkTextBuffer *buffer,
|
||||
GdkRGBA *rgba;
|
||||
char *value;
|
||||
|
||||
g_object_get (tag, "foreground", &rgba, NULL);
|
||||
g_object_get (tag, "foreground-rgba", &rgba, NULL);
|
||||
value = g_strdup_printf ("%u,%u,%u",
|
||||
(guint) rgba->red * 65535,
|
||||
(guint) rgba->green * 65535,
|
||||
|
@ -511,7 +511,7 @@ gtk_text_line_display_cache_invalidate_range (GtkTextLineDisplayCache *cache,
|
||||
/* gtk_text_iter_order() preserving const */
|
||||
if (gtk_text_iter_compare (begin, end) > 0)
|
||||
{
|
||||
const GtkTextIter *tmp = begin;
|
||||
const GtkTextIter *tmp = end;
|
||||
end = begin;
|
||||
begin = tmp;
|
||||
}
|
||||
|
@ -67,6 +67,10 @@
|
||||
* `GtkToggleButton` has a single CSS node with name button. To differentiate
|
||||
* it from a plain `GtkButton`, it gets the `.toggle` style class.
|
||||
*
|
||||
* ## Accessibility
|
||||
*
|
||||
* `GtkToggleButton` uses the %GTK_ACCESSIBLE_ROLE_TOGGLE_BUTTON role.
|
||||
*
|
||||
* ## Creating two `GtkToggleButton` widgets.
|
||||
*
|
||||
* ```c
|
||||
@ -311,6 +315,8 @@ gtk_toggle_button_class_init (GtkToggleButtonClass *class)
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, I_("button"));
|
||||
|
||||
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_TOGGLE_BUTTON);
|
||||
}
|
||||
|
||||
static void
|
||||
|
205
gtk/gtkwidget.c
205
gtk/gtkwidget.c
@ -633,6 +633,7 @@ static void remove_parent_surface_transform_changed_listener (GtkWidget *wid
|
||||
static void add_parent_surface_transform_changed_listener (GtkWidget *widget);
|
||||
static void gtk_widget_queue_compute_expand (GtkWidget *widget);
|
||||
|
||||
static GtkATContext *create_at_context (GtkWidget *self);
|
||||
|
||||
|
||||
static int GtkWidget_private_offset = 0;
|
||||
@ -904,8 +905,18 @@ gtk_widget_get_accessible_role (GtkWidget *self)
|
||||
GtkATContext *context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (self));
|
||||
GtkWidgetClassPrivate *class_priv;
|
||||
|
||||
if (context != NULL && gtk_at_context_is_realized (context))
|
||||
return gtk_at_context_get_accessible_role (context);
|
||||
if (context != NULL)
|
||||
{
|
||||
GtkAccessibleRole role = GTK_ACCESSIBLE_ROLE_NONE;
|
||||
|
||||
if (gtk_at_context_is_realized (context))
|
||||
role = gtk_at_context_get_accessible_role (context);
|
||||
|
||||
g_object_unref (context);
|
||||
|
||||
if (role != GTK_ACCESSIBLE_ROLE_NONE)
|
||||
return role;
|
||||
}
|
||||
|
||||
if (priv->accessible_role != GTK_ACCESSIBLE_ROLE_WIDGET)
|
||||
return priv->accessible_role;
|
||||
@ -2361,7 +2372,7 @@ gtk_widget_init (GTypeInstance *instance, gpointer g_class)
|
||||
gtk_widget_add_controller (widget, controller);
|
||||
}
|
||||
|
||||
priv->at_context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (widget));
|
||||
priv->at_context = create_at_context (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3860,6 +3871,29 @@ gtk_widget_adjust_size_allocation (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_widget_ensure_allocate_on_children (GtkWidget *widget)
|
||||
{
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
||||
GtkWidget *child;
|
||||
|
||||
g_assert (!priv->resize_needed);
|
||||
g_assert (!priv->alloc_needed);
|
||||
|
||||
if (!priv->alloc_needed_on_child)
|
||||
return;
|
||||
|
||||
priv->alloc_needed_on_child = FALSE;
|
||||
|
||||
for (child = _gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = _gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
if (gtk_widget_should_layout (child))
|
||||
gtk_widget_ensure_allocate (child);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_allocate:
|
||||
* @widget: A `GtkWidget`
|
||||
@ -4026,56 +4060,58 @@ gtk_widget_allocate (GtkWidget *widget,
|
||||
size_changed = (priv->width != adjusted.width) || (priv->height != adjusted.height);
|
||||
|
||||
if (!alloc_needed && !size_changed && !baseline_changed)
|
||||
goto skip_allocate;
|
||||
|
||||
priv->width = adjusted.width;
|
||||
priv->height = adjusted.height;
|
||||
priv->baseline = baseline;
|
||||
|
||||
if (priv->layout_manager != NULL)
|
||||
{
|
||||
gtk_layout_manager_allocate (priv->layout_manager, widget,
|
||||
priv->width,
|
||||
priv->height,
|
||||
baseline);
|
||||
gtk_widget_ensure_allocate_on_children (widget);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
GTK_WIDGET_GET_CLASS (widget)->size_allocate (widget,
|
||||
priv->width,
|
||||
priv->height,
|
||||
baseline);
|
||||
}
|
||||
priv->width = adjusted.width;
|
||||
priv->height = adjusted.height;
|
||||
priv->baseline = baseline;
|
||||
|
||||
/* Size allocation is god... after consulting god, no further requests or allocations are needed */
|
||||
priv->alloc_needed_on_child = FALSE;
|
||||
|
||||
if (priv->layout_manager != NULL)
|
||||
{
|
||||
gtk_layout_manager_allocate (priv->layout_manager, widget,
|
||||
priv->width,
|
||||
priv->height,
|
||||
baseline);
|
||||
}
|
||||
else
|
||||
{
|
||||
GTK_WIDGET_GET_CLASS (widget)->size_allocate (widget,
|
||||
priv->width,
|
||||
priv->height,
|
||||
baseline);
|
||||
}
|
||||
|
||||
/* Size allocation is god... after consulting god, no further requests or allocations are needed */
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GTK_DISPLAY_DEBUG_CHECK (_gtk_widget_get_display (widget), GEOMETRY) &&
|
||||
gtk_widget_get_resize_needed (widget))
|
||||
{
|
||||
g_warning ("%s %p or a child called gtk_widget_queue_resize() during size_allocate().",
|
||||
gtk_widget_get_name (widget), widget);
|
||||
}
|
||||
if (GTK_DISPLAY_DEBUG_CHECK (_gtk_widget_get_display (widget), GEOMETRY) &&
|
||||
gtk_widget_get_resize_needed (widget))
|
||||
{
|
||||
g_warning ("%s %p or a child called gtk_widget_queue_resize() during size_allocate().",
|
||||
gtk_widget_get_name (widget), widget);
|
||||
}
|
||||
#endif
|
||||
|
||||
gtk_widget_ensure_resize (widget);
|
||||
priv->alloc_needed = FALSE;
|
||||
priv->alloc_needed_on_child = FALSE;
|
||||
gtk_widget_ensure_resize (widget);
|
||||
priv->alloc_needed = FALSE;
|
||||
|
||||
gtk_widget_update_paintables (widget);
|
||||
gtk_widget_update_paintables (widget);
|
||||
|
||||
if (size_changed)
|
||||
gtk_accessible_bounds_changed (GTK_ACCESSIBLE (widget));
|
||||
if (size_changed)
|
||||
gtk_accessible_bounds_changed (GTK_ACCESSIBLE (widget));
|
||||
|
||||
skip_allocate:
|
||||
if (size_changed || baseline_changed)
|
||||
gtk_widget_queue_draw (widget);
|
||||
else if (transform_changed && priv->parent)
|
||||
if (size_changed || baseline_changed)
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
if (transform_changed && priv->parent)
|
||||
gtk_widget_queue_draw (priv->parent);
|
||||
|
||||
out:
|
||||
if (priv->alloc_needed_on_child)
|
||||
gtk_widget_ensure_allocate (widget);
|
||||
|
||||
gtk_widget_pop_verify_invariants (widget);
|
||||
}
|
||||
|
||||
@ -7352,7 +7388,6 @@ gtk_widget_dispose (GObject *object)
|
||||
GtkWidget *widget = GTK_WIDGET (object);
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
||||
GSList *sizegroups;
|
||||
GtkATContext *at_context;
|
||||
|
||||
if (priv->muxer != NULL)
|
||||
g_object_run_dispose (G_OBJECT (priv->muxer));
|
||||
@ -7402,9 +7437,11 @@ gtk_widget_dispose (GObject *object)
|
||||
gtk_size_group_remove_widget (size_group, widget);
|
||||
}
|
||||
|
||||
at_context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (widget));
|
||||
if (at_context != NULL)
|
||||
gtk_at_context_unrealize (at_context);
|
||||
if (priv->at_context != NULL)
|
||||
{
|
||||
gtk_at_context_unrealize (priv->at_context);
|
||||
g_clear_object (&priv->at_context);
|
||||
}
|
||||
|
||||
g_clear_object (&priv->muxer);
|
||||
|
||||
@ -8427,9 +8464,8 @@ gtk_widget_set_vexpand_set (GtkWidget *widget,
|
||||
*/
|
||||
|
||||
static GtkATContext *
|
||||
gtk_widget_accessible_get_at_context (GtkAccessible *accessible)
|
||||
create_at_context (GtkWidget *self)
|
||||
{
|
||||
GtkWidget *self = GTK_WIDGET (accessible);
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (self);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_GET_CLASS (self);
|
||||
GtkWidgetClassPrivate *class_priv = widget_class->priv;
|
||||
@ -8443,9 +8479,6 @@ gtk_widget_accessible_get_at_context (GtkAccessible *accessible)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (priv->at_context != NULL)
|
||||
return priv->at_context;
|
||||
|
||||
/* Widgets have two options to set the accessible role: either they
|
||||
* define it in their class_init() function, and the role applies to
|
||||
* all instances; or an instance is created with the :accessible-role
|
||||
@ -8460,9 +8493,35 @@ gtk_widget_accessible_get_at_context (GtkAccessible *accessible)
|
||||
role = class_priv->accessible_role;
|
||||
|
||||
priv->accessible_role = role;
|
||||
priv->at_context = gtk_at_context_create (role, accessible, gdk_display_get_default ());
|
||||
priv->at_context = gtk_at_context_create (role, GTK_ACCESSIBLE (self), gdk_display_get_default ());
|
||||
if (priv->at_context != NULL)
|
||||
return g_object_ref (priv->at_context);
|
||||
|
||||
return priv->at_context;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GtkATContext *
|
||||
gtk_widget_accessible_get_at_context (GtkAccessible *accessible)
|
||||
{
|
||||
GtkWidget *self = GTK_WIDGET (accessible);
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (self);
|
||||
|
||||
if (priv->in_destruction)
|
||||
{
|
||||
GTK_DEBUG (A11Y, "ATContext for widget “%s” [%p] accessed during destruction",
|
||||
G_OBJECT_TYPE_NAME (self),
|
||||
self);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (priv->at_context != NULL)
|
||||
return g_object_ref (priv->at_context);
|
||||
|
||||
priv->at_context = create_at_context (self);
|
||||
if (priv->at_context != NULL)
|
||||
return g_object_ref (priv->at_context);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -8485,19 +8544,34 @@ gtk_widget_accessible_get_platform_state (GtkAccessible *self,
|
||||
static GtkAccessible *
|
||||
gtk_widget_accessible_get_accessible_parent (GtkAccessible *self)
|
||||
{
|
||||
return GTK_ACCESSIBLE (gtk_widget_get_parent (GTK_WIDGET (self)));
|
||||
GtkWidget *parent = _gtk_widget_get_parent (GTK_WIDGET (self));
|
||||
|
||||
if (parent == NULL)
|
||||
return NULL;
|
||||
|
||||
return GTK_ACCESSIBLE (g_object_ref (parent));
|
||||
}
|
||||
|
||||
static GtkAccessible *
|
||||
gtk_widget_accessible_get_next_accessible_sibling (GtkAccessible *self)
|
||||
{
|
||||
return GTK_ACCESSIBLE (gtk_widget_get_next_sibling (GTK_WIDGET (self)));
|
||||
GtkWidget *sibling = _gtk_widget_get_next_sibling (GTK_WIDGET (self));
|
||||
|
||||
if (sibling == NULL)
|
||||
return NULL;
|
||||
|
||||
return GTK_ACCESSIBLE (g_object_ref (sibling));
|
||||
}
|
||||
|
||||
static GtkAccessible *
|
||||
gtk_widget_accessible_get_first_accessible_child (GtkAccessible *self)
|
||||
{
|
||||
return GTK_ACCESSIBLE (gtk_widget_get_first_child (GTK_WIDGET (self)));
|
||||
GtkWidget *child = _gtk_widget_get_first_child (GTK_WIDGET (self));
|
||||
|
||||
if (child == NULL)
|
||||
return NULL;
|
||||
|
||||
return GTK_ACCESSIBLE (g_object_ref (child));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -9284,6 +9358,8 @@ gtk_widget_buildable_finish_accessibility_properties (GtkWidget *widget,
|
||||
}
|
||||
|
||||
g_slist_free_full (attributes, accessibility_attribute_info_free);
|
||||
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -10585,7 +10661,10 @@ gtk_widget_set_alloc_needed (GtkWidget *widget)
|
||||
break;
|
||||
|
||||
if (GTK_IS_NATIVE (widget))
|
||||
gtk_native_queue_relayout (GTK_NATIVE (widget));
|
||||
{
|
||||
gtk_native_queue_relayout (GTK_NATIVE (widget));
|
||||
return;
|
||||
}
|
||||
|
||||
widget = priv->parent;
|
||||
if (widget == NULL)
|
||||
@ -10633,18 +10712,9 @@ gtk_widget_ensure_allocate (GtkWidget *widget)
|
||||
priv->allocated_size_baseline,
|
||||
gsk_transform_ref (priv->allocated_transform));
|
||||
}
|
||||
else if (priv->alloc_needed_on_child)
|
||||
else
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
priv->alloc_needed_on_child = FALSE;
|
||||
|
||||
for (child = _gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = _gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
gtk_widget_ensure_allocate (child);
|
||||
}
|
||||
gtk_widget_ensure_allocate_on_children (widget);
|
||||
}
|
||||
}
|
||||
|
||||
@ -11128,7 +11198,8 @@ gtk_widget_dispose_template (GtkWidget *widget,
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (g_type_name (widget_type) != NULL);
|
||||
|
||||
GtkWidgetTemplate *template = GTK_WIDGET_GET_CLASS (widget)->priv->template;
|
||||
GObjectClass *object_class = g_type_class_peek (widget_type);
|
||||
GtkWidgetTemplate *template = GTK_WIDGET_CLASS (object_class)->priv->template;
|
||||
g_return_if_fail (template != NULL);
|
||||
|
||||
/* Tear down the automatic child data */
|
||||
|
@ -3595,9 +3595,20 @@ gtk_window_set_default_size_internal (GtkWindow *window,
|
||||
*
|
||||
* Sets the default size of a window.
|
||||
*
|
||||
* If the window’s “natural” size (its size request) is larger than
|
||||
* The default size of a window is the size that will be used if no other constraints apply.
|
||||
*
|
||||
* The default size will be updated whenever the window is resized
|
||||
* to reflect the new size, unless the window is forced to a size,
|
||||
* like when it is maximized or fullscreened.
|
||||
*
|
||||
* If the window’s minimum size request is larger than
|
||||
* the default, the default will be ignored.
|
||||
*
|
||||
* Setting the default size to a value <= 0 will cause it to be
|
||||
* ignored and the natural size request will be used instead. It
|
||||
* is possible to do this while the window is showing to "reset"
|
||||
* it to its initial size.
|
||||
*
|
||||
* Unlike [method@Gtk.Widget.set_size_request], which sets a size
|
||||
* request for a widget and thus would keep users from shrinking
|
||||
* the window, this function only sets the initial size, just as
|
||||
@ -3606,13 +3617,6 @@ gtk_window_set_default_size_internal (GtkWindow *window,
|
||||
* size of -1 means to use the “natural” default size (the size request
|
||||
* of the window).
|
||||
*
|
||||
* The default size of a window only affects the first time a window is
|
||||
* shown; if a window is hidden and re-shown, it will remember the size
|
||||
* it had prior to hiding, rather than using the default size.
|
||||
*
|
||||
* Windows can’t actually be 0x0 in size, they must be at least 1x1, but
|
||||
* passing 0 for @width and @height is OK, resulting in a 1x1 default size.
|
||||
*
|
||||
* If you use this function to reestablish a previously saved window size,
|
||||
* note that the appropriate size to save is the one returned by
|
||||
* [method@Gtk.Window.get_default_size]. Using the window allocation
|
||||
@ -3643,6 +3647,9 @@ gtk_window_set_default_size (GtkWindow *window,
|
||||
* A value of 0 for the width or height indicates that a default
|
||||
* size has not been explicitly set for that dimension, so the
|
||||
* “natural” size of the window will be used.
|
||||
*
|
||||
* This function is the recommended way for [saving window state
|
||||
* across restarts of applications](https://developer.gnome.org/documentation/tutorials/save-state.html).
|
||||
*/
|
||||
void
|
||||
gtk_window_get_default_size (GtkWindow *window,
|
||||
@ -4430,6 +4437,7 @@ gtk_window_unrealize (GtkWidget *widget)
|
||||
g_signal_handlers_disconnect_by_func (surface, surface_state_changed, widget);
|
||||
g_signal_handlers_disconnect_by_func (surface, surface_render, widget);
|
||||
g_signal_handlers_disconnect_by_func (surface, surface_event, widget);
|
||||
g_signal_handlers_disconnect_by_func (surface, toplevel_compute_size, widget);
|
||||
|
||||
frame_clock = gdk_surface_get_frame_clock (surface);
|
||||
|
||||
|
@ -244,6 +244,8 @@ update_path (GtkInspectorA11y *sl)
|
||||
}
|
||||
else
|
||||
path = "not on bus";
|
||||
|
||||
g_clear_object (&context);
|
||||
#endif
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (sl->path), path);
|
||||
@ -270,7 +272,7 @@ update_attributes (GtkInspectorA11y *sl)
|
||||
gboolean has_value;
|
||||
|
||||
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (sl->object));
|
||||
if (!context)
|
||||
if (context == NULL)
|
||||
return;
|
||||
|
||||
store = g_list_store_new (G_TYPE_OBJECT);
|
||||
@ -347,6 +349,8 @@ update_attributes (GtkInspectorA11y *sl)
|
||||
g_object_unref (selection);
|
||||
|
||||
gtk_widget_set_visible (sl->attributes, g_list_model_get_n_items (G_LIST_MODEL (filter_model)) > 0);
|
||||
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -420,8 +424,11 @@ gtk_inspector_a11y_set_object (GtkInspectorA11y *sl,
|
||||
if (sl->object && GTK_IS_ACCESSIBLE (sl->object))
|
||||
{
|
||||
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (sl->object));
|
||||
if (context)
|
||||
g_signal_handlers_disconnect_by_func (context, refresh_all, sl);
|
||||
if (context != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (context, refresh_all, sl);
|
||||
g_object_unref (context);
|
||||
}
|
||||
}
|
||||
|
||||
g_set_object (&sl->object, object);
|
||||
@ -432,8 +439,12 @@ gtk_inspector_a11y_set_object (GtkInspectorA11y *sl,
|
||||
if (GTK_IS_ACCESSIBLE (sl->object))
|
||||
{
|
||||
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (sl->object));
|
||||
if (context)
|
||||
g_signal_connect_swapped (context, "state-change", G_CALLBACK (refresh_all), sl);
|
||||
if (context != NULL)
|
||||
{
|
||||
g_signal_connect_swapped (context, "state-change", G_CALLBACK (refresh_all), sl);
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
gtk_stack_page_set_visible (page, TRUE);
|
||||
update_role (sl);
|
||||
update_path (sl);
|
||||
@ -461,7 +472,11 @@ dispose (GObject *o)
|
||||
GtkATContext *context;
|
||||
|
||||
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (sl->object));
|
||||
g_signal_handlers_disconnect_by_func (context, refresh_all, sl);
|
||||
if (context != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (context, refresh_all, sl);
|
||||
g_object_unref (context);
|
||||
}
|
||||
}
|
||||
|
||||
g_clear_object (&sl->object);
|
||||
|
@ -185,7 +185,7 @@ action_state_changed_cb (GActionGroup *group,
|
||||
static void
|
||||
update_widgets (GtkInspectorActionEditor *r)
|
||||
{
|
||||
GVariant *state;
|
||||
GVariant *state = NULL;
|
||||
|
||||
if (G_IS_ACTION_GROUP (r->owner))
|
||||
g_action_group_query_action (G_ACTION_GROUP (r->owner), r->name,
|
||||
|
@ -1131,11 +1131,19 @@ toplevel_filter_func (gpointer item,
|
||||
gpointer data)
|
||||
{
|
||||
GdkDisplay *display = data;
|
||||
gpointer iw;
|
||||
|
||||
if (!GTK_IS_WINDOW (item))
|
||||
return FALSE;
|
||||
|
||||
return gtk_widget_get_display (item) == display;
|
||||
if (gtk_widget_get_display (item) != display)
|
||||
return FALSE;
|
||||
|
||||
iw = g_object_get_data (G_OBJECT (display), "-gtk-inspector");
|
||||
if (iw == item)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GListModel *
|
||||
|
@ -658,6 +658,7 @@ init_icons (GtkInspectorVisual *vis)
|
||||
GList *list, *l;
|
||||
int i;
|
||||
GtkStringList *names;
|
||||
const char * const *dirs;
|
||||
|
||||
t = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||
|
||||
@ -669,6 +670,14 @@ init_icons (GtkInspectorVisual *vis)
|
||||
fill_icons (path, t);
|
||||
g_free (path);
|
||||
|
||||
dirs = g_get_system_data_dirs ();
|
||||
for (i = 0; dirs[i]; i++)
|
||||
{
|
||||
path = g_build_filename (dirs[i], "icons", NULL);
|
||||
fill_icons (path, t);
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
list = NULL;
|
||||
g_hash_table_iter_init (&iter, t);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)&theme, NULL))
|
||||
@ -723,6 +732,7 @@ init_cursors (GtkInspectorVisual *vis)
|
||||
GList *list, *l;
|
||||
GtkStringList *names;
|
||||
int i;
|
||||
const char * const *dirs;
|
||||
|
||||
t = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||
|
||||
@ -734,6 +744,14 @@ init_cursors (GtkInspectorVisual *vis)
|
||||
fill_cursors (path, t);
|
||||
g_free (path);
|
||||
|
||||
dirs = g_get_system_data_dirs ();
|
||||
for (i = 0; dirs[i]; i++)
|
||||
{
|
||||
path = g_build_filename (dirs[i], "icons", NULL);
|
||||
fill_cursors (path, t);
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
list = NULL;
|
||||
g_hash_table_iter_init (&iter, t);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)&theme, NULL))
|
||||
|
@ -913,7 +913,7 @@ foreach lang : [
|
||||
|
||||
gnome.compile_resources(lang,
|
||||
resxml,
|
||||
source_dir: 'emoji',
|
||||
source_dir: meson.current_source_dir() / 'emoji',
|
||||
gresource_bundle: true,
|
||||
install: true,
|
||||
install_dir: gtk_datadir / 'gtk-4.0/emoji',
|
||||
|
17
meson.build
17
meson.build
@ -1,5 +1,5 @@
|
||||
project('gtk', 'c',
|
||||
version: '4.9.5',
|
||||
version: '4.10.1',
|
||||
default_options: [
|
||||
'buildtype=debugoptimized',
|
||||
'warning_level=1',
|
||||
@ -370,6 +370,13 @@ glib_dep = dependency('glib-2.0', version: glib_req)
|
||||
gobject_dep = dependency('gobject-2.0', version: glib_req)
|
||||
if os_win32
|
||||
giowin32_dep = dependency('gio-windows-2.0', version: glib_req, required: win32_enabled)
|
||||
if giowin32_dep.version().version_compare('<2.75.0')
|
||||
if cc.get_id() == 'msvc' and get_option('default_library') != 'static'
|
||||
# Override _GLIB_EXTERN on Visual Studio for media modules for glib <= 2.74.x, so that we
|
||||
# avoid error C2375 (redefinition; different linkage) when building the g_io_module_*() bits
|
||||
cdata.set('MODULES_OVERRIDE_GLIB_EXTERN', true)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
if os_unix
|
||||
giounix_dep = dependency('gio-unix-2.0', version: glib_req, required: false)
|
||||
@ -728,8 +735,13 @@ endif
|
||||
|
||||
# Introspection
|
||||
gir = find_program('g-ir-scanner', required : get_option('introspection'))
|
||||
build_gir = gir.found() and get_option('introspection').enabled()
|
||||
|
||||
if not gir.found() and get_option('introspection').enabled()
|
||||
error('Introspection enabled, but g-ir-scanner not found.')
|
||||
endif
|
||||
|
||||
build_gir = gir.found() and (get_option('introspection').enabled() or
|
||||
(get_option('introspection').allowed() and get_option('gtk_doc')))
|
||||
|
||||
project_build_root = meson.current_build_dir()
|
||||
|
||||
@ -888,6 +900,7 @@ summary('Optimization', get_option('optimization'), section: 'Build')
|
||||
summary('Introspection', build_gir, section: 'Build')
|
||||
summary('Documentation', get_option('gtk_doc'), 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')
|
||||
summary('Demos', get_option('demos'), section: 'Build')
|
||||
summary('Examples', get_option('build-examples'), section: 'Build')
|
||||
|
@ -19,6 +19,15 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/*
|
||||
* Sadly, we need this to build on Visual Studio against glib-2.74.x or earlier,
|
||||
* otherwise the build will fail when building the g_io_module_*() bits with error C2375
|
||||
* (redefinition; different linkage). This must be before including the Gio headers.
|
||||
*/
|
||||
#if defined (_MSC_VER) && defined (MODULES_OVERRIDE_GLIB_EXTERN)
|
||||
# define _GLIB_EXTERN __declspec(dllexport) extern
|
||||
#endif
|
||||
|
||||
#include "gtkffmediafileprivate.h"
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
@ -19,6 +19,15 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/*
|
||||
* Sadly, we need this to build on Visual Studio against glib-2.74.x or earlier,
|
||||
* otherwise the build will fail when building the g_io_module_*() bits with error C2375
|
||||
* (redefinition; different linkage). This must be before including the Gio headers.
|
||||
*/
|
||||
#if defined (_MSC_VER) && defined (MODULES_OVERRIDE_GLIB_EXTERN)
|
||||
# define _GLIB_EXTERN __declspec(dllexport) extern
|
||||
#endif
|
||||
|
||||
#include "gtkgstmediafileprivate.h"
|
||||
#include "gtkgstpaintableprivate.h"
|
||||
|
||||
|
@ -33,7 +33,7 @@ test_object_accessible_get_at_context (GtkAccessible *accessible)
|
||||
accessible,
|
||||
gdk_display_get_default ());
|
||||
|
||||
return self->at_context;
|
||||
return g_object_ref (self->at_context);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -10,7 +10,7 @@ styletest_env.set('G_ENABLE_DIAGNOSTIC', '0')
|
||||
cssresources = gnome.compile_resources(
|
||||
'cssresources',
|
||||
'test-css-style.gresource.xml',
|
||||
source_dir: '.',
|
||||
source_dir: meson.current_source_dir(),
|
||||
)
|
||||
|
||||
test_style = executable('test-css-style',
|
||||
|
8
testsuite/gsk/compare/texture-scale-magnify-10000x.node
Normal file
8
testsuite/gsk/compare/texture-scale-magnify-10000x.node
Normal file
@ -0,0 +1,8 @@
|
||||
clip {
|
||||
clip: 24995 24995 10 10;
|
||||
child: texture-scale {
|
||||
texture: url("data:;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAKElEQVQYlWNkYGD4z4AG/v/HEGJgwhDBAQZQIQs2hzMyMtLBauorBACQUgcSISWLRgAAAABJRU5ErkJggg==");
|
||||
bounds: 0 0 50000 50000;
|
||||
filter: nearest;
|
||||
}
|
||||
}
|
BIN
testsuite/gsk/compare/texture-scale-magnify-10000x.png
Normal file
BIN
testsuite/gsk/compare/texture-scale-magnify-10000x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 97 B |
8
testsuite/gsk/compare/texture-scale-stripes.node
Normal file
8
testsuite/gsk/compare/texture-scale-stripes.node
Normal file
@ -0,0 +1,8 @@
|
||||
clip {
|
||||
clip: 3950 3950 100 100;
|
||||
child: texture-scale {
|
||||
bounds: 0 0 19991 19991;
|
||||
filter: nearest;
|
||||
texture: url('data:,<svg><rect width="10" height="10" style="fill:red" /></svg>');
|
||||
}
|
||||
}
|
BIN
testsuite/gsk/compare/texture-scale-stripes.png
Normal file
BIN
testsuite/gsk/compare/texture-scale-stripes.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 313 B |
@ -66,19 +66,21 @@ compare_render_tests = [
|
||||
'outset_shadow_offset_y',
|
||||
'outset_shadow_rounded_top',
|
||||
'outset_shadow_simple',
|
||||
'scaled-cairo',
|
||||
'scale-textures-negative-ngl',
|
||||
'scale-up-down',
|
||||
'shadow-in-opacity',
|
||||
'texture-url',
|
||||
'repeat',
|
||||
'repeat-no-repeat',
|
||||
'repeat-negative-coords',
|
||||
'repeat-texture',
|
||||
'rounded-clip-in-clip-3d', # not really 3d, but cairo fails it
|
||||
'scale-textures-negative-ngl',
|
||||
'scale-up-down',
|
||||
'scaled-cairo',
|
||||
'scaled-texture',
|
||||
'shadow-in-opacity',
|
||||
'texture-scale-magnify-10000x',
|
||||
'texture-scale-stripes',
|
||||
'texture-url',
|
||||
'transform-in-transform',
|
||||
'transform-in-transform-in-transform',
|
||||
'rounded-clip-in-clip-3d', # not really 3d, but cairo fails it
|
||||
'scaled-texture',
|
||||
]
|
||||
|
||||
# these are too sensitive to differences in the renderers
|
||||
@ -140,6 +142,9 @@ endforeach
|
||||
|
||||
node_parser_tests = [
|
||||
'blend.node',
|
||||
'blend-unknown-mode.errors',
|
||||
'blend-unknown-mode.node',
|
||||
'blend-unknown-mode.ref.node',
|
||||
'border.node',
|
||||
'color.node',
|
||||
'conic-gradient.node',
|
||||
@ -199,6 +204,8 @@ node_parser_tests = [
|
||||
'empty-text.ref.node',
|
||||
'empty-texture.node',
|
||||
'empty-texture.ref.node',
|
||||
'empty-texture-scale.node',
|
||||
'empty-texture-scale.ref.node',
|
||||
'empty-transform.node',
|
||||
'empty-transform.ref.node',
|
||||
'glshader.node',
|
||||
@ -227,6 +234,9 @@ node_parser_tests = [
|
||||
'texture-fail.node',
|
||||
'texture-fail.ref.node',
|
||||
'texture-fail.ref.errors',
|
||||
'texture-scale-unknown-filter.errors',
|
||||
'texture-scale-unknown-filter.node',
|
||||
'texture-scale-unknown-filter.ref.node',
|
||||
'transform-fail.node',
|
||||
'transform-fail.ref.node',
|
||||
'transform-fail.errors',
|
||||
|
1
testsuite/gsk/nodeparser/blend-unknown-mode.errors
Normal file
1
testsuite/gsk/nodeparser/blend-unknown-mode.errors
Normal file
@ -0,0 +1 @@
|
||||
<data>:2:9-13: error: GTK_CSS_PARSER_ERROR_SYNTAX
|
3
testsuite/gsk/nodeparser/blend-unknown-mode.node
Normal file
3
testsuite/gsk/nodeparser/blend-unknown-mode.node
Normal file
@ -0,0 +1,3 @@
|
||||
blend {
|
||||
mode: diff;
|
||||
}
|
10
testsuite/gsk/nodeparser/blend-unknown-mode.ref.node
Normal file
10
testsuite/gsk/nodeparser/blend-unknown-mode.ref.node
Normal file
@ -0,0 +1,10 @@
|
||||
blend {
|
||||
bottom: color {
|
||||
bounds: 0 0 50 50;
|
||||
color: rgb(170,255,0);
|
||||
}
|
||||
top: color {
|
||||
bounds: 0 0 50 50;
|
||||
color: rgb(255,0,204);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user