Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fcf504905a | |||
| b84150a580 | |||
| 415539b02f |
+1
-2
@@ -212,9 +212,7 @@ msys2-mingw64:
|
||||
macos-x86_64:
|
||||
rules:
|
||||
# Do not run in forks as the runner is not available there.
|
||||
# (except for dehesselle who maintains the runner)
|
||||
- if: $CI_PROJECT_NAMESPACE == "GNOME"
|
||||
- if: $CI_PROJECT_NAMESPACE == "dehesselle"
|
||||
stage: build
|
||||
tags:
|
||||
- macosintel
|
||||
@@ -253,6 +251,7 @@ macos-x86_64:
|
||||
-Dpixman:tests=disabled
|
||||
-Dlibjpeg-turbo:simd=disabled
|
||||
-Dbuild-demos=false
|
||||
-Dbuild-tests=false
|
||||
-Dbuild-examples=false
|
||||
-Dbuild-testsuite=false
|
||||
_build
|
||||
|
||||
@@ -1,126 +1,6 @@
|
||||
Overview of Changes in 4.13.7, xx-xx-xxxx
|
||||
Overview of Changes in 4.13.6, xx-xx-xxxx
|
||||
=========================================
|
||||
|
||||
* GtkFileChooser:
|
||||
- Speed up opening
|
||||
|
||||
* Accessibility:
|
||||
- Add socket support for webkit accessibility
|
||||
- Implement AT-SPI text for GtkText
|
||||
- Implement AT-SPI component generically
|
||||
- Add an announce API
|
||||
|
||||
* GSK:
|
||||
- Make the ngl renderer work on macOS
|
||||
- Fix a crash in the vulkan renderer
|
||||
- Make nodeparser allow aliases for fonts again
|
||||
- Implement cache eviction for the glyph and
|
||||
texture caches
|
||||
- Fix shaders to work on GL < 4.0
|
||||
- Fix problems with scaled shadows
|
||||
- Fix problems with holes for underlaid subsurfaces
|
||||
|
||||
* media:
|
||||
- Support dmabufs in the gstreamer backend. This allows
|
||||
zero-copy video playback on Wayland when paired with
|
||||
hardware video decoding
|
||||
|
||||
* Wayland:
|
||||
- Commit empty frames if and double-buffered state
|
||||
is pending
|
||||
- Fix monitor size information when using mutter without
|
||||
the scale-monitor-framebuffer setting
|
||||
|
||||
* macOS:
|
||||
- Propagate unhandled input events back to the OS
|
||||
|
||||
* Tools:
|
||||
- Make the crash handling in gtk4-node-editor more robust
|
||||
|
||||
* Translation updates
|
||||
Galician
|
||||
Georgian
|
||||
Occitan
|
||||
|
||||
|
||||
Overview of Changes in 4.13.6, 25-01-2024
|
||||
=========================================
|
||||
|
||||
This release changes the ngl renderer to be the default renderer.
|
||||
|
||||
The intent of this change is to get wider testing and verify that
|
||||
the new renderers are production-ready. If significant problems
|
||||
show up, we will revert this change for 4.14.
|
||||
|
||||
You can still override the renderer choice using the GSK_RENDERER
|
||||
environment variable.
|
||||
|
||||
Since ngl can handle fractional scaling much better than the old gl
|
||||
renderer, we allow fractional scaling by default with gl now. If you
|
||||
are using the old gl renderer (e.g. because your system is limited to
|
||||
GLES2), you can disable fractional scaling by setting the GDK_DEBUG
|
||||
environment variable to include the gl-no-fractional key.
|
||||
|
||||
* GtkColumnView:
|
||||
- Fix infinite loops in dispose
|
||||
- Fix problems with weak ref cycles in GtkExpression
|
||||
|
||||
* GtkListView:
|
||||
- Fix some corner cases with sections during insertions and deletions
|
||||
- Don't double-recycle widgets
|
||||
|
||||
* GtkStack:
|
||||
- Add automatic cleanup for GtkStackPage
|
||||
|
||||
* GDK:
|
||||
- Use standard cursor names for drag cursors
|
||||
- Enable fractional scaling with gl by default
|
||||
|
||||
* GSK:
|
||||
- Many fixes and improvements to the unified renderers:
|
||||
- Fix text rendering with the uber shader
|
||||
- Fix rounding issues with fractional scales
|
||||
- Fix some memory leaks
|
||||
- Many text rendering fixes
|
||||
- Implement subpixel positioning for glyphs
|
||||
- Support custom fonts in node files
|
||||
- Add tests for font rendering
|
||||
- Fix drawing of repeat nodes
|
||||
- Implement subpixels positioning
|
||||
- Evict stale textures, glyphs and atlases from the cache
|
||||
- Some fixes and improvements to the GL renderer:
|
||||
- Fix problems with GLES on Nvidia
|
||||
- Avoid a crash in the mask demo
|
||||
- Respect opacity of the first child node in containers
|
||||
- Some fixes and improvements to the fallback renderer:
|
||||
- Fix drawing of repeat nodes
|
||||
- Make ngl the default renderer
|
||||
|
||||
* Wayland:
|
||||
- Fix problems with tablet cursors
|
||||
- Fix problems without seats
|
||||
|
||||
* Accessibility:
|
||||
- Respect a separate "show-status-shapes setting
|
||||
- Fix change notification for accessible names on some widgets
|
||||
|
||||
* Inspector:
|
||||
- Show the git commit in devel builds
|
||||
|
||||
* Tools:
|
||||
- Make gtk4-node-editor autosave its contents
|
||||
- Add a benchmark command to gtk4-rendernode-tool
|
||||
|
||||
* Translation updates:
|
||||
French
|
||||
Galician
|
||||
Georgian
|
||||
Occitan
|
||||
Persian
|
||||
Russian
|
||||
Vietnamese
|
||||
|
||||
|
||||
Overview of Changes in 4.13.5, 07-01-2024
|
||||
=========================================
|
||||
|
||||
|
||||
@@ -68,9 +68,8 @@ struct _NodeEditorWindow
|
||||
|
||||
GArray *errors;
|
||||
|
||||
guint update_timeout;
|
||||
gboolean auto_reload;
|
||||
gboolean mark_as_safe_pending;
|
||||
gulong after_paint_handler;
|
||||
};
|
||||
|
||||
struct _NodeEditorWindowClass
|
||||
@@ -246,41 +245,6 @@ highlight_text (NodeEditorWindow *self)
|
||||
gtk_text_buffer_apply_tag_by_name (self->text_buffer, "no-hyphens", &start, &end);
|
||||
}
|
||||
|
||||
static void
|
||||
mark_autosave_as_unsafe (void)
|
||||
{
|
||||
char *path1 = NULL;
|
||||
char *path2 = NULL;
|
||||
|
||||
path1 = get_autosave_path ("-unsafe");
|
||||
path2 = get_autosave_path (NULL);
|
||||
|
||||
g_rename (path2, path1);
|
||||
}
|
||||
|
||||
static void
|
||||
mark_autosave_as_safe (void)
|
||||
{
|
||||
char *path1 = NULL;
|
||||
char *path2 = NULL;
|
||||
|
||||
path1 = get_autosave_path ("-unsafe");
|
||||
path2 = get_autosave_path (NULL);
|
||||
|
||||
g_rename (path1, path2);
|
||||
}
|
||||
|
||||
static void
|
||||
after_paint (GdkFrameClock *clock,
|
||||
NodeEditorWindow *self)
|
||||
{
|
||||
if (self->mark_as_safe_pending)
|
||||
{
|
||||
self->mark_as_safe_pending = FALSE;
|
||||
mark_autosave_as_safe ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
reload (NodeEditorWindow *self)
|
||||
{
|
||||
@@ -289,8 +253,6 @@ reload (NodeEditorWindow *self)
|
||||
float scale;
|
||||
GskRenderNode *big_node;
|
||||
|
||||
mark_autosave_as_unsafe ();
|
||||
|
||||
text = get_current_text (self->text_buffer);
|
||||
bytes = g_bytes_new_take (text, strlen (text));
|
||||
|
||||
@@ -352,8 +314,6 @@ reload (NodeEditorWindow *self)
|
||||
}
|
||||
|
||||
g_clear_pointer (&big_node, gsk_render_node_unref);
|
||||
|
||||
self->mark_as_safe_pending = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1165,6 +1125,9 @@ node_editor_window_finalize (GObject *object)
|
||||
{
|
||||
NodeEditorWindow *self = (NodeEditorWindow *)object;
|
||||
|
||||
if (self->update_timeout)
|
||||
g_source_remove (self->update_timeout);
|
||||
|
||||
g_array_free (self->errors, TRUE);
|
||||
|
||||
g_clear_pointer (&self->node, gsk_render_node_unref);
|
||||
@@ -1209,7 +1172,6 @@ static void
|
||||
node_editor_window_realize (GtkWidget *widget)
|
||||
{
|
||||
NodeEditorWindow *self = NODE_EDITOR_WINDOW (widget);
|
||||
GdkFrameClock *frameclock;
|
||||
|
||||
GTK_WIDGET_CLASS (node_editor_window_parent_class)->realize (widget);
|
||||
|
||||
@@ -1237,24 +1199,14 @@ node_editor_window_realize (GtkWidget *widget)
|
||||
node_editor_window_add_renderer (self,
|
||||
gsk_cairo_renderer_new (),
|
||||
"Cairo");
|
||||
|
||||
frameclock = gtk_widget_get_frame_clock (widget);
|
||||
self->after_paint_handler = g_signal_connect (frameclock, "after-paint",
|
||||
G_CALLBACK (after_paint), self);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
node_editor_window_unrealize (GtkWidget *widget)
|
||||
{
|
||||
NodeEditorWindow *self = NODE_EDITOR_WINDOW (widget);
|
||||
GdkFrameClock *frameclock;
|
||||
guint i;
|
||||
|
||||
frameclock = gtk_widget_get_frame_clock (widget);
|
||||
g_signal_handler_disconnect (frameclock, self->after_paint_handler);
|
||||
self->after_paint_handler = 0;
|
||||
|
||||
for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (self->renderers)); i ++)
|
||||
{
|
||||
gpointer item = g_list_model_get_item (G_LIST_MODEL (self->renderers), i);
|
||||
@@ -1794,16 +1746,16 @@ set_initial_text (NodeEditorWindow *self)
|
||||
path = get_autosave_path (NULL);
|
||||
path1 = get_autosave_path ("-unsafe");
|
||||
|
||||
if (g_file_get_contents (path1, &initial_text, &len, NULL))
|
||||
if (g_file_get_contents (path, &initial_text, &len, NULL))
|
||||
{
|
||||
gtk_text_buffer_set_text (self->text_buffer, initial_text, len);
|
||||
g_free (initial_text);
|
||||
}
|
||||
else if (g_file_get_contents (path1, &initial_text, &len, NULL))
|
||||
{
|
||||
self->auto_reload = FALSE;
|
||||
gtk_revealer_set_reveal_child (GTK_REVEALER (self->crash_warning), TRUE);
|
||||
|
||||
gtk_text_buffer_set_text (self->text_buffer, initial_text, len);
|
||||
g_free (initial_text);
|
||||
}
|
||||
else if (g_file_get_contents (path, &initial_text, &len, NULL))
|
||||
{
|
||||
gtk_text_buffer_set_text (self->text_buffer, initial_text, len);
|
||||
g_free (initial_text);
|
||||
}
|
||||
@@ -1854,6 +1806,41 @@ autosave_contents (NodeEditorWindow *self)
|
||||
g_free (contents);
|
||||
}
|
||||
|
||||
static void
|
||||
mark_autosave_as_safe (void)
|
||||
{
|
||||
char *path1 = NULL;
|
||||
char *path2 = NULL;
|
||||
|
||||
path1 = get_autosave_path ("-unsafe");
|
||||
path2 = get_autosave_path (NULL);
|
||||
|
||||
g_rename (path1, path2);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_timeout_cb (gpointer data)
|
||||
{
|
||||
NodeEditorWindow *self = data;
|
||||
|
||||
self->update_timeout = 0;
|
||||
|
||||
mark_autosave_as_safe ();
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
initiate_autosave (NodeEditorWindow *self)
|
||||
{
|
||||
autosave_contents (self);
|
||||
|
||||
if (self->update_timeout != 0)
|
||||
g_source_remove (self->update_timeout);
|
||||
|
||||
self->update_timeout = g_timeout_add (100, update_timeout_cb, self);
|
||||
}
|
||||
|
||||
static void
|
||||
node_editor_window_init (NodeEditorWindow *self)
|
||||
{
|
||||
@@ -1918,7 +1905,7 @@ node_editor_window_init (NodeEditorWindow *self)
|
||||
|
||||
set_initial_text (self);
|
||||
|
||||
g_signal_connect_swapped (self->text_buffer, "changed", G_CALLBACK (autosave_contents), self);
|
||||
g_signal_connect_swapped (self->text_buffer, "changed", G_CALLBACK (initiate_autosave), self);
|
||||
|
||||
if (g_getenv ("GSK_RENDERER"))
|
||||
{
|
||||
|
||||
@@ -213,7 +213,6 @@
|
||||
<property name="halign">1</property>
|
||||
<property name="label" translatable="1">The application may have crashed.
|
||||
As a precaution, auto-loading has been turned off.
|
||||
You can turn it back on in the menu.
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@@ -25,8 +25,6 @@ base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/"
|
||||
|
||||
[extra]
|
||||
content_images = [
|
||||
"../images/favicon.svg",
|
||||
"../images/favicon-192x192.png",
|
||||
"images/gtk-logo.svg",
|
||||
]
|
||||
urlmap_file = "urlmap.js"
|
||||
|
||||
@@ -24,8 +24,6 @@ base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/"
|
||||
|
||||
[extra]
|
||||
content_images = [
|
||||
"../images/favicon.svg",
|
||||
"../images/favicon-192x192.png",
|
||||
"images/gtk-logo.svg",
|
||||
]
|
||||
urlmap_file = "urlmap.js"
|
||||
|
||||
@@ -67,8 +67,6 @@ content_files = [
|
||||
"macos.md",
|
||||
]
|
||||
content_images = [
|
||||
"../images/favicon.svg",
|
||||
"../images/favicon-192x192.png",
|
||||
"images/gtk-logo.svg",
|
||||
"images/rotated-text.png",
|
||||
"images/default_cursor.png",
|
||||
|
||||
@@ -36,8 +36,6 @@ content_files = [
|
||||
"paths.md",
|
||||
]
|
||||
content_images = [
|
||||
"../images/favicon.svg",
|
||||
"../images/favicon-192x192.png",
|
||||
"gtk-logo.svg",
|
||||
"images/arc-dark.png",
|
||||
"images/arc-light.png",
|
||||
|
||||
@@ -234,7 +234,7 @@ By default, GTK will try to build with support for the Vulkan graphics
|
||||
API in addition to cairo and OpenGL. This option can be used to explicitly
|
||||
control whether Vulkan should be used.
|
||||
|
||||
### `media-gstreamer`
|
||||
### `media-gstreamer` and `media-ffmpeg`
|
||||
|
||||
By default, GTK will try to build the gstreamer backend for
|
||||
media playback support. These options can be used to explicitly
|
||||
|
||||
@@ -85,8 +85,6 @@ content_files = [
|
||||
"visual_index.md",
|
||||
]
|
||||
content_images = [
|
||||
"../images/favicon.svg",
|
||||
"../images/favicon-192x192.png",
|
||||
"images/aboutdialog.png",
|
||||
"images/action-bar.png",
|
||||
"images/appchooserbutton.png",
|
||||
|
||||
@@ -126,8 +126,8 @@ available on the system.
|
||||
### `GTK_MEDIA`
|
||||
|
||||
Specifies what backend to load for [class@Gtk.MediaFile]. The possible values
|
||||
depend on what options GTK was built with, and can include 'gstreamer'
|
||||
and 'none'. If set to 'none', media playback will be unavailable.
|
||||
depend on what options GTK was built with, and can include 'gstreamer',
|
||||
'ffmpeg' and 'none'. If set to 'none', media playback will be unavailable.
|
||||
The special value 'help' can be used to obtain a list of all supported
|
||||
media backends.
|
||||
|
||||
@@ -220,8 +220,8 @@ A number of options affect behavior instead of logging:
|
||||
`gl-disable`
|
||||
: Disable OpenGL support
|
||||
|
||||
`gl-no-fractional`
|
||||
: Disable fractional scaling for OpenGL.
|
||||
`gl-fractional`
|
||||
: Enable fractional scaling for OpenGL. This is experimental
|
||||
|
||||
`gl-debug`
|
||||
: Insert debugging information in OpenGL
|
||||
@@ -460,13 +460,6 @@ disable certain optimizations of the "ngl" and "vulkan" renderer.
|
||||
The special value `all` can be used to turn on all values. The special
|
||||
value `help` can be used to obtain a list of all supported values.
|
||||
|
||||
### `GSK_CACHE_TIMEOUT`
|
||||
|
||||
Overrides the timeout for cache GC in the "ngl" and "vulkan" renderers.
|
||||
The value can be -1 to disable GC entirely, 0 to force GC to happen
|
||||
before every frame, or a positive number to do GC in a timeout every
|
||||
n seconds. The default timeout is 15 seconds.
|
||||
|
||||
### `GSK_MAX_TEXTURE_SIZE`
|
||||
|
||||
Limit texture size to the minimum of this value and the OpenGL limit
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB |
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.0" width="88.572334" height="96.050743" id="svg6843">
|
||||
<defs id="defs6845"/>
|
||||
<g transform="translate(-19.822308,-16.115941)" id="layer1">
|
||||
<path d="M 20.88413,30.82696 53.816977,55.527708 107.33282,39.060543 70.587303,17.177763 20.88413,30.82696 z" id="path6976" style="fill:#729fcf;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.12364459;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"/>
|
||||
<path d="m 22.94243,82.287118 -2.0583,-51.460158 32.932847,24.700748 0,55.577152 L 22.94243,82.287118 z" id="path6978" style="fill:#e40000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.12364459;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"/>
|
||||
<path d="m 53.816977,111.10486 49.399213,-20.58416 4.11663,-51.460157 -53.515843,16.467165 0,55.577152 z" id="path6980" style="fill:#7fe719;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.12364459;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"/>
|
||||
<path d="M 23.216626,81.319479 70.48573,67.361442 103.38422,90.444516" id="path6982" style="fill:none;stroke:#ffffff;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"/>
|
||||
<path d="m 70.434539,17.875593 0,49.109284" id="path6984" style="fill:#babdb6;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.8 KiB |
@@ -123,7 +123,7 @@ static const GdkDebugKey gdk_debug_keys[] = {
|
||||
{ "portals", GDK_DEBUG_PORTALS, "Force use of portals" },
|
||||
{ "no-portals", GDK_DEBUG_NO_PORTALS, "Disable use of portals" },
|
||||
{ "gl-disable", GDK_DEBUG_GL_DISABLE, "Disable OpenGL support" },
|
||||
{ "gl-no-fractional", GDK_DEBUG_GL_NO_FRACTIONAL, "Disable fractional scaling for OpenGL" },
|
||||
{ "gl-fractional", GDK_DEBUG_GL_FRACTIONAL, "Enable fractional scaling for OpenGL (experimental)" },
|
||||
{ "gl-debug", GDK_DEBUG_GL_DEBUG, "Insert debugging information in OpenGL" },
|
||||
{ "gl-disable-gl", GDK_DEBUG_GL_DISABLE_GL, "Only allow OpenGL GLES API" },
|
||||
{ "gl-disable-gles", GDK_DEBUG_GL_DISABLE_GLES, "Don't allow OpenGL GLES API" },
|
||||
|
||||
@@ -43,7 +43,7 @@ typedef enum {
|
||||
GDK_DEBUG_PORTALS = 1 << 14,
|
||||
GDK_DEBUG_NO_PORTALS = 1 << 15,
|
||||
GDK_DEBUG_GL_DISABLE = 1 << 16,
|
||||
GDK_DEBUG_GL_NO_FRACTIONAL= 1 << 17,
|
||||
GDK_DEBUG_GL_FRACTIONAL = 1 << 17,
|
||||
|
||||
GDK_DEBUG_GL_DISABLE_GL = 1 << 19,
|
||||
GDK_DEBUG_GL_DISABLE_GLES = 1 << 20,
|
||||
|
||||
+1
-60
@@ -77,7 +77,6 @@ enum
|
||||
PROP_0,
|
||||
PROP_COMPOSITED,
|
||||
PROP_RGBA,
|
||||
PROP_SHADOW_WIDTH,
|
||||
PROP_INPUT_SHAPES,
|
||||
PROP_DMABUF_FORMATS,
|
||||
LAST_PROP
|
||||
@@ -112,7 +111,6 @@ struct _GdkDisplayPrivate {
|
||||
|
||||
guint rgba : 1;
|
||||
guint composited : 1;
|
||||
guint shadow_width: 1;
|
||||
guint input_shapes : 1;
|
||||
|
||||
GdkDebugFlags debug_flags;
|
||||
@@ -146,10 +144,6 @@ gdk_display_get_property (GObject *object,
|
||||
g_value_set_boolean (value, gdk_display_is_rgba (display));
|
||||
break;
|
||||
|
||||
case PROP_SHADOW_WIDTH:
|
||||
g_value_set_boolean (value, gdk_display_supports_shadow_width (display));
|
||||
break;
|
||||
|
||||
case PROP_INPUT_SHAPES:
|
||||
g_value_set_boolean (value, gdk_display_supports_input_shapes (display));
|
||||
break;
|
||||
@@ -249,18 +243,6 @@ gdk_display_class_init (GdkDisplayClass *class)
|
||||
TRUE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkDisplay:shadow-width: (attributes org.gtk.Property.get=gdk_display_supports_shadow_width)
|
||||
*
|
||||
* %TRUE if the display supports extensible frames.
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
props[PROP_SHADOW_WIDTH] =
|
||||
g_param_spec_boolean ("shadow-width", NULL, NULL,
|
||||
TRUE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkDisplay:input-shapes: (attributes org.gtk.Property.get=gdk_display_supports_input_shapes)
|
||||
*
|
||||
@@ -272,7 +254,7 @@ gdk_display_class_init (GdkDisplayClass *class)
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkDisplay:dmabuf-formats: (attributes org.gtk.Property.get=gdk_display_get_dmabuf_formats)
|
||||
* GdkDisplay:dmabuf-formats:
|
||||
*
|
||||
* The dma-buf formats that are supported on this display
|
||||
*
|
||||
@@ -409,7 +391,6 @@ gdk_display_init (GdkDisplay *display)
|
||||
|
||||
priv->composited = TRUE;
|
||||
priv->rgba = TRUE;
|
||||
priv->shadow_width = TRUE;
|
||||
priv->input_shapes = TRUE;
|
||||
}
|
||||
|
||||
@@ -2141,46 +2122,6 @@ gdk_display_set_rgba (GdkDisplay *display,
|
||||
g_object_notify_by_pspec (G_OBJECT (display), props[PROP_RGBA]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_display_supports_shadow_width: (attributes org.gtk.Method.get_property=shadow-width)
|
||||
* @display: a `GdkDisplay`
|
||||
*
|
||||
* Returns whether it's possible for a surface to draw outside of the window area.
|
||||
*
|
||||
* If %TRUE is returned the application decides if it wants to draw shadows.
|
||||
* If %FALSE is returned, the compositor decides if it wants to draw shadows.
|
||||
*
|
||||
* Returns: %TRUE if surfaces can draw shadows or
|
||||
* %FALSE if the display does not support this functionality.
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
gboolean
|
||||
gdk_display_supports_shadow_width (GdkDisplay *display)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
||||
|
||||
return priv->shadow_width;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_display_set_shadow_width (GdkDisplay *display,
|
||||
gboolean shadow_width)
|
||||
{
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
|
||||
|
||||
g_return_if_fail (GDK_IS_DISPLAY (display));
|
||||
|
||||
if (priv->shadow_width == shadow_width)
|
||||
return;
|
||||
|
||||
priv->shadow_width = shadow_width;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (display), props[PROP_SHADOW_WIDTH]);
|
||||
}
|
||||
|
||||
static void
|
||||
device_removed_cb (GdkSeat *seat,
|
||||
GdkDevice *device,
|
||||
|
||||
@@ -63,8 +63,6 @@ GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_display_is_composited (GdkDisplay *display);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_display_is_rgba (GdkDisplay *display);
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
gboolean gdk_display_supports_shadow_width (GdkDisplay *display);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_display_supports_input_shapes (GdkDisplay *display);
|
||||
|
||||
|
||||
@@ -257,8 +257,6 @@ void gdk_display_set_composited (GdkDisplay *display
|
||||
gboolean composited);
|
||||
void gdk_display_set_input_shapes (GdkDisplay *display,
|
||||
gboolean input_shapes);
|
||||
void gdk_display_set_shadow_width (GdkDisplay *display,
|
||||
gboolean shadow_width);
|
||||
|
||||
void gdk_display_add_seat (GdkDisplay *display,
|
||||
GdkSeat *seat);
|
||||
|
||||
+1
-25
@@ -2329,42 +2329,18 @@ gdk_dmabuf_sanitize (GdkDmabuf *dest,
|
||||
* @dmabuf: a sanitized GdkDmabuf
|
||||
*
|
||||
* A dmabuf is considered disjoint if it uses more than
|
||||
* 1 inode.
|
||||
* Multiple file descriptors may exist when the creator
|
||||
* of the dmabuf just dup()ed once for every plane...
|
||||
* 1 file descriptor.
|
||||
*
|
||||
* Returns: %TRUE if the dmabuf is disjoint
|
||||
**/
|
||||
gboolean
|
||||
gdk_dmabuf_is_disjoint (const GdkDmabuf *dmabuf)
|
||||
{
|
||||
struct stat first_stat;
|
||||
unsigned i;
|
||||
|
||||
/* First, do a fast check */
|
||||
|
||||
for (i = 1; i < dmabuf->n_planes; i++)
|
||||
{
|
||||
if (dmabuf->planes[0].fd != dmabuf->planes[i].fd)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == dmabuf->n_planes)
|
||||
return FALSE;
|
||||
|
||||
/* We have different fds, do the fancy check instead */
|
||||
|
||||
if (fstat (dmabuf->planes[0].fd, &first_stat) != 0)
|
||||
return TRUE;
|
||||
|
||||
for (i = 1; i < dmabuf->n_planes; i++)
|
||||
{
|
||||
struct stat plane_stat;
|
||||
|
||||
if (fstat (dmabuf->planes[0].fd, &plane_stat) != 0)
|
||||
return TRUE;
|
||||
|
||||
if (first_stat.st_ino != plane_stat.st_ino)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -217,41 +217,3 @@ gdk_dmabuf_formats_peek_formats (GdkDmabufFormats *self)
|
||||
{
|
||||
return self->formats;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_dmabuf_formats_equal:
|
||||
* @formats1: (nullable): a `GdkDmabufFormats`
|
||||
* @formats2: (nullable): another `GdkDmabufFormats`
|
||||
*
|
||||
* Returns whether @formats1 and @formats2 contain the
|
||||
* same dmabuf formats, in the same order.
|
||||
*
|
||||
* Returns: `TRUE` if @formats1 and @formats2 are equal
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
gboolean
|
||||
gdk_dmabuf_formats_equal (const GdkDmabufFormats *formats1,
|
||||
const GdkDmabufFormats *formats2)
|
||||
{
|
||||
if (formats1 == formats2)
|
||||
return TRUE;
|
||||
|
||||
if (formats1 == NULL || formats2 == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (formats1->n_formats != formats2->n_formats)
|
||||
return FALSE;
|
||||
|
||||
for (gsize i = 0; i < formats1->n_formats; i++)
|
||||
{
|
||||
GdkDmabufFormat *f1 = &formats1->formats[i];
|
||||
GdkDmabufFormat *f2 = &formats2->formats[i];
|
||||
|
||||
if (f1->fourcc != f2->fourcc ||
|
||||
f1->modifier != f2->modifier)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -51,8 +51,4 @@ gboolean gdk_dmabuf_formats_contains (GdkDmabufFormats *formats
|
||||
guint32 fourcc,
|
||||
guint64 modifier) G_GNUC_PURE;
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
gboolean gdk_dmabuf_formats_equal (const GdkDmabufFormats *formats1,
|
||||
const GdkDmabufFormats *formats2);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
/**
|
||||
* GdkDmabufTexture:
|
||||
*
|
||||
* A `GdkTexture` representing a DMA buffer.
|
||||
* A `GdkTexture` representing a dma-buf object.
|
||||
*
|
||||
* To create a `GdkDmabufTexture`, use the auxiliary
|
||||
* [class@Gdk.DmabufTextureBuilder] object.
|
||||
|
||||
+4
-4
@@ -477,18 +477,18 @@ check_event_sanity (GdkEvent *event)
|
||||
}
|
||||
#endif
|
||||
|
||||
gboolean
|
||||
void
|
||||
_gdk_event_emit (GdkEvent *event)
|
||||
{
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (!check_event_sanity (event))
|
||||
return FALSE;
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (gdk_drag_handle_source_event (event))
|
||||
return TRUE;
|
||||
return;
|
||||
|
||||
return gdk_surface_handle_event (event);
|
||||
gdk_surface_handle_event (event);
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
|
||||
@@ -619,16 +619,16 @@ typedef enum
|
||||
|
||||
GdkEvent* _gdk_event_unqueue (GdkDisplay *display);
|
||||
|
||||
gboolean _gdk_event_emit (GdkEvent *event);
|
||||
GList* _gdk_event_queue_find_first (GdkDisplay *display);
|
||||
void _gdk_event_queue_remove_link (GdkDisplay *display,
|
||||
GList *node);
|
||||
GList* _gdk_event_queue_append (GdkDisplay *display,
|
||||
GdkEvent *event);
|
||||
void _gdk_event_emit (GdkEvent *event);
|
||||
GList* _gdk_event_queue_find_first (GdkDisplay *display);
|
||||
void _gdk_event_queue_remove_link (GdkDisplay *display,
|
||||
GList *node);
|
||||
GList* _gdk_event_queue_append (GdkDisplay *display,
|
||||
GdkEvent *event);
|
||||
|
||||
void _gdk_event_queue_handle_motion_compression (GdkDisplay *display);
|
||||
void gdk_event_queue_handle_scroll_compression (GdkDisplay *display);
|
||||
void _gdk_event_queue_flush (GdkDisplay *display);
|
||||
void _gdk_event_queue_handle_motion_compression (GdkDisplay *display);
|
||||
void gdk_event_queue_handle_scroll_compression (GdkDisplay *display);
|
||||
void _gdk_event_queue_flush (GdkDisplay *display);
|
||||
|
||||
double * gdk_event_dup_axes (GdkEvent *event);
|
||||
|
||||
|
||||
+1
-1
@@ -593,7 +593,7 @@ gdk_gl_context_get_scale (GdkGLContext *self)
|
||||
scale = gdk_surface_get_scale (surface);
|
||||
|
||||
display = gdk_gl_context_get_display (self);
|
||||
if (gdk_display_get_debug_flags (display) & GDK_DEBUG_GL_NO_FRACTIONAL)
|
||||
if (!(gdk_display_get_debug_flags (display) & GDK_DEBUG_GL_FRACTIONAL))
|
||||
scale = ceil (scale);
|
||||
|
||||
return scale;
|
||||
|
||||
+2
-74
@@ -26,8 +26,6 @@
|
||||
#include "gdkenumtypes.h"
|
||||
#include "gdkrectangle.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* GdkMonitor:
|
||||
*
|
||||
@@ -48,7 +46,6 @@ enum {
|
||||
PROP_MODEL,
|
||||
PROP_CONNECTOR,
|
||||
PROP_SCALE_FACTOR,
|
||||
PROP_SCALE,
|
||||
PROP_GEOMETRY,
|
||||
PROP_WIDTH_MM,
|
||||
PROP_HEIGHT_MM,
|
||||
@@ -73,8 +70,6 @@ static void
|
||||
gdk_monitor_init (GdkMonitor *monitor)
|
||||
{
|
||||
monitor->scale_factor = 1;
|
||||
monitor->scale = 1.0;
|
||||
monitor->scale_set = FALSE;
|
||||
monitor->valid = TRUE;
|
||||
}
|
||||
|
||||
@@ -112,10 +107,6 @@ gdk_monitor_get_property (GObject *object,
|
||||
g_value_set_int (value, monitor->scale_factor);
|
||||
break;
|
||||
|
||||
case PROP_SCALE:
|
||||
g_value_set_double (value, monitor->scale);
|
||||
break;
|
||||
|
||||
case PROP_GEOMETRY:
|
||||
g_value_set_boxed (value, &monitor->geometry);
|
||||
break;
|
||||
@@ -242,28 +233,13 @@ gdk_monitor_class_init (GdkMonitorClass *class)
|
||||
* GdkMonitor:scale-factor: (attributes org.gtk.Property.get=gdk_monitor_get_scale_factor)
|
||||
*
|
||||
* The scale factor.
|
||||
*
|
||||
* The scale factor is the next larger integer,
|
||||
* compared to [property@Gdk.Surface:scale].
|
||||
*/
|
||||
props[PROP_SCALE_FACTOR] =
|
||||
g_param_spec_int ("scale-factor", NULL, NULL,
|
||||
1, G_MAXINT,
|
||||
0, G_MAXINT,
|
||||
1,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkMonitor:scale: (attributes org.gtk.Property.get=gdk_monitor_get_scale)
|
||||
*
|
||||
* The scale of the monitor.
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
props[PROP_SCALE] =
|
||||
g_param_spec_double ("scale", NULL, NULL,
|
||||
1., G_MAXDOUBLE, 1.,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkMonitor:geometry: (attributes org.gtk.Property.get=gdk_monitor_get_geometry)
|
||||
*
|
||||
@@ -370,7 +346,7 @@ gdk_monitor_get_display (GdkMonitor *monitor)
|
||||
* display coordinate space.
|
||||
*
|
||||
* The returned geometry is in ”application pixels”, not in
|
||||
* ”device pixels” (see [method@Gdk.Monitor.get_scale]).
|
||||
* ”device pixels” (see [method@Gdk.Monitor.get_scale_factor]).
|
||||
*/
|
||||
void
|
||||
gdk_monitor_get_geometry (GdkMonitor *monitor,
|
||||
@@ -496,29 +472,6 @@ gdk_monitor_get_scale_factor (GdkMonitor *monitor)
|
||||
return monitor->scale_factor;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_monitor_get_scale: (attributes org.gtk.Method.get_property=scale)
|
||||
* @monitor: a `GdkMonitor`
|
||||
*
|
||||
* Gets the internal scale factor that maps from monitor coordinates
|
||||
* to device pixels.
|
||||
*
|
||||
* This can be used if you want to create pixel based data for a
|
||||
* particular monitor, but most of the time you’re drawing to a surface
|
||||
* where it is better to use [method@Gdk.Surface.get_scale] instead.
|
||||
*
|
||||
* Returns: the scale
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
double
|
||||
gdk_monitor_get_scale (GdkMonitor *monitor)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MONITOR (monitor), 1.);
|
||||
|
||||
return monitor->scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_monitor_get_refresh_rate: (attributes org.gtk.Method.get_property=refresh-rate)
|
||||
* @monitor: a `GdkMonitor`
|
||||
@@ -630,37 +583,12 @@ void
|
||||
gdk_monitor_set_scale_factor (GdkMonitor *monitor,
|
||||
int scale_factor)
|
||||
{
|
||||
g_return_if_fail (scale_factor >= 1);
|
||||
|
||||
if (monitor->scale_set)
|
||||
return;
|
||||
|
||||
if (monitor->scale_factor == scale_factor)
|
||||
return;
|
||||
|
||||
monitor->scale_factor = scale_factor;
|
||||
monitor->scale = scale_factor;
|
||||
|
||||
g_object_notify (G_OBJECT (monitor), "scale-factor");
|
||||
g_object_notify (G_OBJECT (monitor), "scale");
|
||||
}
|
||||
|
||||
void
|
||||
gdk_monitor_set_scale (GdkMonitor *monitor,
|
||||
double scale)
|
||||
{
|
||||
g_return_if_fail (scale >= 1.);
|
||||
|
||||
monitor->scale_set = TRUE;
|
||||
|
||||
if (monitor->scale == scale)
|
||||
return;
|
||||
|
||||
monitor->scale = scale;
|
||||
monitor->scale_factor = (int) ceil (scale);
|
||||
|
||||
g_object_notify (G_OBJECT (monitor), "scale");
|
||||
g_object_notify (G_OBJECT (monitor), "scale-factor");
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -77,8 +77,6 @@ GDK_AVAILABLE_IN_ALL
|
||||
const char * gdk_monitor_get_connector (GdkMonitor *monitor);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gdk_monitor_get_scale_factor (GdkMonitor *monitor);
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
double gdk_monitor_get_scale (GdkMonitor *monitor);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gdk_monitor_get_refresh_rate (GdkMonitor *monitor);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
|
||||
@@ -44,8 +44,6 @@ struct _GdkMonitor {
|
||||
int refresh_rate;
|
||||
GdkSubpixelLayout subpixel_layout;
|
||||
gboolean valid;
|
||||
double scale;
|
||||
gboolean scale_set;
|
||||
};
|
||||
|
||||
struct _GdkMonitorClass {
|
||||
@@ -66,9 +64,7 @@ void gdk_monitor_set_physical_size (GdkMonitor *monitor,
|
||||
int width_mm,
|
||||
int height_mm);
|
||||
void gdk_monitor_set_scale_factor (GdkMonitor *monitor,
|
||||
int scale_factor);
|
||||
void gdk_monitor_set_scale (GdkMonitor *monitor,
|
||||
double scale);
|
||||
int scale);
|
||||
void gdk_monitor_set_refresh_rate (GdkMonitor *monitor,
|
||||
int refresh_rate);
|
||||
void gdk_monitor_set_subpixel_layout (GdkMonitor *monitor,
|
||||
|
||||
+1
-84
@@ -55,58 +55,6 @@ gdk_subsurface_get_parent (GdkSubsurface *subsurface)
|
||||
return subsurface->parent;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_subsurface (GdkSubsurface *subsurface)
|
||||
{
|
||||
GdkSurface *parent = subsurface->parent;
|
||||
|
||||
if (parent->subsurfaces_above == subsurface)
|
||||
parent->subsurfaces_above = subsurface->sibling_above;
|
||||
if (parent->subsurfaces_below == subsurface)
|
||||
parent->subsurfaces_below = subsurface->sibling_below;
|
||||
|
||||
if (subsurface->sibling_above)
|
||||
subsurface->sibling_above->sibling_below = subsurface->sibling_below;
|
||||
if (subsurface->sibling_below)
|
||||
subsurface->sibling_below->sibling_above = subsurface->sibling_above;
|
||||
|
||||
subsurface->sibling_above = NULL;
|
||||
subsurface->sibling_below = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
insert_subsurface (GdkSubsurface *subsurface,
|
||||
gboolean above,
|
||||
GdkSubsurface *sibling)
|
||||
{
|
||||
GdkSurface *parent = subsurface->parent;
|
||||
|
||||
subsurface->above_parent = sibling->above_parent;
|
||||
|
||||
if (above)
|
||||
{
|
||||
subsurface->sibling_above = sibling->sibling_above;
|
||||
sibling->sibling_above = subsurface;
|
||||
subsurface->sibling_below = sibling;
|
||||
if (subsurface->sibling_above)
|
||||
subsurface->sibling_above->sibling_below = subsurface;
|
||||
|
||||
if (parent->subsurfaces_below == sibling)
|
||||
parent->subsurfaces_below = subsurface;
|
||||
}
|
||||
else
|
||||
{
|
||||
subsurface->sibling_below = sibling->sibling_below;
|
||||
sibling->sibling_below = subsurface;
|
||||
subsurface->sibling_above = sibling;
|
||||
if (subsurface->sibling_below)
|
||||
subsurface->sibling_below->sibling_above = subsurface;
|
||||
|
||||
if (parent->subsurfaces_above == sibling)
|
||||
parent->subsurfaces_above = subsurface;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_subsurface_attach (GdkSubsurface *subsurface,
|
||||
GdkTexture *texture,
|
||||
@@ -114,39 +62,10 @@ gdk_subsurface_attach (GdkSubsurface *subsurface,
|
||||
gboolean above,
|
||||
GdkSubsurface *sibling)
|
||||
{
|
||||
GdkSurface *parent = subsurface->parent;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), FALSE);
|
||||
g_return_val_if_fail (GDK_IS_TEXTURE (texture), FALSE);
|
||||
g_return_val_if_fail (rect != NULL, FALSE);
|
||||
g_return_val_if_fail (sibling != subsurface, FALSE);
|
||||
g_return_val_if_fail (sibling == NULL || GDK_IS_SUBSURFACE (sibling), FALSE);
|
||||
g_return_val_if_fail (sibling == NULL || sibling->parent == subsurface->parent, FALSE);
|
||||
|
||||
remove_subsurface (subsurface);
|
||||
|
||||
if (sibling)
|
||||
{
|
||||
insert_subsurface (subsurface, above, sibling);
|
||||
}
|
||||
else
|
||||
{
|
||||
sibling = above ? parent->subsurfaces_above : parent->subsurfaces_below;
|
||||
|
||||
if (sibling)
|
||||
{
|
||||
insert_subsurface (subsurface, !above, sibling);
|
||||
}
|
||||
else
|
||||
{
|
||||
subsurface->above_parent = above;
|
||||
|
||||
if (above)
|
||||
parent->subsurfaces_above = subsurface;
|
||||
else
|
||||
parent->subsurfaces_below = subsurface;
|
||||
}
|
||||
}
|
||||
|
||||
return GDK_SUBSURFACE_GET_CLASS (subsurface)->attach (subsurface, texture, rect, above, sibling);
|
||||
}
|
||||
@@ -156,8 +75,6 @@ gdk_subsurface_detach (GdkSubsurface *subsurface)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_SUBSURFACE (subsurface));
|
||||
|
||||
remove_subsurface (subsurface);
|
||||
|
||||
GDK_SUBSURFACE_GET_CLASS (subsurface)->detach (subsurface);
|
||||
}
|
||||
|
||||
@@ -184,5 +101,5 @@ gdk_subsurface_is_above_parent (GdkSubsurface *subsurface)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), TRUE);
|
||||
|
||||
return subsurface->above_parent;
|
||||
return GDK_SUBSURFACE_GET_CLASS (subsurface)->is_above_parent (subsurface);
|
||||
}
|
||||
|
||||
@@ -41,10 +41,6 @@ struct _GdkSubsurface
|
||||
GdkSurface *parent;
|
||||
|
||||
int ref_count;
|
||||
|
||||
gboolean above_parent;
|
||||
GdkSubsurface *sibling_above;
|
||||
GdkSubsurface *sibling_below;
|
||||
};
|
||||
|
||||
|
||||
@@ -61,6 +57,7 @@ struct _GdkSubsurfaceClass
|
||||
GdkTexture * (* get_texture) (GdkSubsurface *subsurface);
|
||||
void (* get_rect) (GdkSubsurface *subsurface,
|
||||
graphene_rect_t *rect);
|
||||
gboolean (* is_above_parent) (GdkSubsurface *subsurface);
|
||||
};
|
||||
|
||||
GType gdk_subsurface_get_type (void) G_GNUC_CONST;
|
||||
|
||||
@@ -99,12 +99,6 @@ struct _GdkSurface
|
||||
GdkSeat *current_shortcuts_inhibited_seat;
|
||||
|
||||
GPtrArray *subsurfaces;
|
||||
|
||||
/* We keep the subsurfaces above and below the surface in two linked
|
||||
* lists, which start here.
|
||||
*/
|
||||
GdkSubsurface *subsurfaces_above;
|
||||
GdkSubsurface *subsurfaces_below;
|
||||
};
|
||||
|
||||
struct _GdkSurfaceClass
|
||||
@@ -351,6 +345,8 @@ void gdk_surface_request_motion (GdkSurface *surface);
|
||||
gboolean gdk_surface_supports_edge_constraints (GdkSurface *surface);
|
||||
|
||||
GdkSubsurface * gdk_surface_create_subsurface (GdkSurface *surface);
|
||||
void gdk_surface_destroy_subsurface (GdkSurface *surface,
|
||||
GdkSubsurface *subsurface);
|
||||
gsize gdk_surface_get_n_subsurfaces (GdkSurface *surface);
|
||||
GdkSubsurface * gdk_surface_get_subsurface (GdkSurface *surface,
|
||||
gsize idx);
|
||||
|
||||
@@ -142,9 +142,6 @@ gdk_toplevel_size_set_min_size (GdkToplevelSize *size,
|
||||
* The shadow width corresponds to the part of the computed surface size
|
||||
* that would consist of the shadow margin surrounding the window, would
|
||||
* there be any.
|
||||
*
|
||||
* Shadow width should only be set if
|
||||
* [method@Gtk.Display.supports_shadow_width] is %TRUE.
|
||||
*/
|
||||
void
|
||||
gdk_toplevel_size_set_shadow_width (GdkToplevelSize *size,
|
||||
|
||||
+2
-23
@@ -593,8 +593,7 @@ physical_device_check_features (VkPhysicalDevice device,
|
||||
v12_features.shaderStorageBufferArrayNonUniformIndexing)
|
||||
*out_features |= GDK_VULKAN_FEATURE_NONUNIFORM_INDEXING;
|
||||
|
||||
if (ycbcr_features.samplerYcbcrConversion ||
|
||||
physical_device_supports_extension (device, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME))
|
||||
if (ycbcr_features.samplerYcbcrConversion)
|
||||
*out_features |= GDK_VULKAN_FEATURE_YCBCR;
|
||||
|
||||
if (physical_device_supports_extension (device, VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME) &&
|
||||
@@ -1467,27 +1466,13 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
||||
if (features & GDK_VULKAN_FEATURE_DESCRIPTOR_INDEXING)
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
|
||||
if (features & GDK_VULKAN_FEATURE_YCBCR)
|
||||
{
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
|
||||
}
|
||||
if (features & GDK_VULKAN_FEATURE_DMABUF)
|
||||
{
|
||||
g_assert (features & GDK_VULKAN_FEATURE_YCBCR);
|
||||
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
|
||||
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME);
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME);
|
||||
}
|
||||
if (features & (GDK_VULKAN_FEATURE_SEMAPHORE_IMPORT | GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT))
|
||||
{
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME);
|
||||
}
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME);
|
||||
if (features & GDK_VULKAN_FEATURE_INCREMENTAL_PRESENT)
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME);
|
||||
|
||||
@@ -1628,12 +1613,6 @@ gdk_display_create_vulkan_instance (GdkDisplay *display,
|
||||
g_ptr_array_add (used_extensions, (gpointer) VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
|
||||
have_debug_report = TRUE;
|
||||
}
|
||||
if (g_str_equal (extensions[i].extensionName, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME))
|
||||
g_ptr_array_add (used_extensions, (gpointer) VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
|
||||
if (g_str_equal (extensions[i].extensionName, VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME))
|
||||
g_ptr_array_add (used_extensions, (gpointer) VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME);
|
||||
if (g_str_equal (extensions[i].extensionName, VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME))
|
||||
g_ptr_array_add (used_extensions, (gpointer) VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
|
||||
}
|
||||
|
||||
uint32_t n_layers;
|
||||
|
||||
@@ -398,7 +398,8 @@ typedef NSString *CALayerContentsGravity;
|
||||
* in from a display-side change. We need to request a layout in
|
||||
* addition to the configure event.
|
||||
*/
|
||||
if (GDK_IS_MACOS_TOPLEVEL_SURFACE (gdk_surface))
|
||||
if (GDK_IS_MACOS_TOPLEVEL_SURFACE (gdk_surface) &&
|
||||
GDK_MACOS_TOPLEVEL_SURFACE (gdk_surface)->decorated)
|
||||
gdk_surface_request_layout (GDK_SURFACE (gdk_surface));
|
||||
}
|
||||
|
||||
@@ -874,21 +875,12 @@ typedef NSString *CALayerContentsGravity;
|
||||
{
|
||||
NSWindowStyleMask style_mask = [self styleMask];
|
||||
|
||||
if (decorated)
|
||||
{
|
||||
style_mask &= ~NSWindowStyleMaskFullSizeContentView;
|
||||
[self setTitleVisibility:NSWindowTitleVisible];
|
||||
}
|
||||
else
|
||||
{
|
||||
style_mask |= NSWindowStyleMaskFullSizeContentView;
|
||||
[self setTitleVisibility:NSWindowTitleHidden];
|
||||
}
|
||||
[self setHasShadow:decorated];
|
||||
|
||||
[self setTitlebarAppearsTransparent:!decorated];
|
||||
[[self standardWindowButton:NSWindowCloseButton] setHidden:!decorated];
|
||||
[[self standardWindowButton:NSWindowMiniaturizeButton] setHidden:!decorated];
|
||||
[[self standardWindowButton:NSWindowZoomButton] setHidden:!decorated];
|
||||
if (decorated)
|
||||
style_mask |= NSWindowStyleMaskTitled;
|
||||
else
|
||||
style_mask &= ~NSWindowStyleMaskTitled;
|
||||
|
||||
[self setStyleMask:style_mask];
|
||||
}
|
||||
|
||||
@@ -271,11 +271,6 @@ _gdk_macos_cairo_context_end_frame (GdkDrawContext *draw_context,
|
||||
[CATransaction commit];
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_cairo_context_empty_frame (GdkDrawContext *draw_context)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_cairo_context_surface_resized (GdkDrawContext *draw_context)
|
||||
{
|
||||
@@ -292,7 +287,6 @@ _gdk_macos_cairo_context_class_init (GdkMacosCairoContextClass *klass)
|
||||
|
||||
draw_context_class->begin_frame = _gdk_macos_cairo_context_begin_frame;
|
||||
draw_context_class->end_frame = _gdk_macos_cairo_context_end_frame;
|
||||
draw_context_class->empty_frame = _gdk_macos_cairo_context_empty_frame;
|
||||
draw_context_class->surface_resized = _gdk_macos_cairo_context_surface_resized;
|
||||
|
||||
cairo_context_class->cairo_create = _gdk_macos_cairo_context_cairo_create;
|
||||
|
||||
@@ -625,7 +625,6 @@ gdk_macos_display_init (GdkMacosDisplay *self)
|
||||
gdk_display_set_composited (GDK_DISPLAY (self), TRUE);
|
||||
gdk_display_set_input_shapes (GDK_DISPLAY (self), FALSE);
|
||||
gdk_display_set_rgba (GDK_DISPLAY (self), TRUE);
|
||||
gdk_display_set_shadow_width (GDK_DISPLAY (self), FALSE);
|
||||
}
|
||||
|
||||
GdkDisplay *
|
||||
|
||||
@@ -734,14 +734,7 @@ gdk_macos_event_source_dispatch (GSource *source,
|
||||
|
||||
if (event)
|
||||
{
|
||||
gboolean handled = _gdk_event_emit (event);
|
||||
|
||||
if (!handled)
|
||||
{
|
||||
NSEvent *nsevent = _gdk_macos_display_get_nsevent (event);
|
||||
if (nsevent != NULL)
|
||||
[NSApp sendEvent: nsevent];
|
||||
}
|
||||
_gdk_event_emit (event);
|
||||
|
||||
gdk_event_unref (event);
|
||||
}
|
||||
|
||||
@@ -545,11 +545,6 @@ gdk_macos_gl_context_end_frame (GdkDrawContext *context,
|
||||
[CATransaction commit];
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_gl_context_empty_frame (GdkDrawContext *draw_context)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_gl_context_surface_resized (GdkDrawContext *draw_context)
|
||||
{
|
||||
@@ -672,7 +667,6 @@ gdk_macos_gl_context_class_init (GdkMacosGLContextClass *klass)
|
||||
|
||||
draw_context_class->begin_frame = gdk_macos_gl_context_begin_frame;
|
||||
draw_context_class->end_frame = gdk_macos_gl_context_end_frame;
|
||||
draw_context_class->empty_frame = gdk_macos_gl_context_empty_frame;
|
||||
draw_context_class->surface_resized = gdk_macos_gl_context_surface_resized;
|
||||
|
||||
gl_class->get_damage = gdk_macos_gl_context_get_damage;
|
||||
|
||||
@@ -1795,7 +1795,7 @@ static TranslationEntry translations[] = {
|
||||
{ FALSE, "org.gnome.desktop.wm.preferences", "action-middle-click-titlebar", "gtk-titlebar-middle-click", G_TYPE_STRING, { .s = "none" } },
|
||||
{ FALSE, "org.gnome.desktop.wm.preferences", "action-right-click-titlebar", "gtk-titlebar-right-click", G_TYPE_STRING, { .s = "menu" } },
|
||||
{ FALSE, "org.gnome.desktop.a11y", "always-show-text-caret", "gtk-keynav-use-caret", G_TYPE_BOOLEAN, { .b = FALSE } },
|
||||
{ FALSE, "org.gnome.desktop.a11y.interface", "high-contrast", "high-contrast", G_TYPE_NONE, { .b = FALSE } },
|
||||
{ FALSE, "org.gnome.desktop.a11y.interface", "high-contrast", "high-contast", G_TYPE_NONE, { .b = FALSE } },
|
||||
{ FALSE, "org.gnome.desktop.a11y.interface", "show-status-shapes", "gtk-show-status-shapes", G_TYPE_BOOLEAN, { .b = FALSE } },
|
||||
/* Note, this setting doesn't exist, the portal and gsd fake it */
|
||||
{ FALSE, "org.gnome.fontconfig", "serial", "gtk-fontconfig-timestamp", G_TYPE_NONE, { .i = 0 } },
|
||||
@@ -2430,47 +2430,15 @@ apply_monitor_change (GdkWaylandMonitor *monitor)
|
||||
{
|
||||
GDK_DEBUG (MISC, "monitor %d changed position %d %d, size %d %d",
|
||||
monitor->id,
|
||||
monitor->output_geometry.x, monitor->output_geometry.y,
|
||||
monitor->output_geometry.width, monitor->output_geometry.height);
|
||||
monitor->x, monitor->y,
|
||||
monitor->width, monitor->height);
|
||||
|
||||
GdkRectangle logical_geometry;
|
||||
gboolean needs_scaling = FALSE;
|
||||
double scale;
|
||||
|
||||
if (monitor->xdg_output_done)
|
||||
{
|
||||
logical_geometry = monitor->xdg_output_geometry;
|
||||
needs_scaling =
|
||||
logical_geometry.width == monitor->output_geometry.width ||
|
||||
logical_geometry.height == monitor->output_geometry.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
logical_geometry = monitor->output_geometry;
|
||||
needs_scaling = TRUE;
|
||||
}
|
||||
|
||||
if (needs_scaling)
|
||||
{
|
||||
int scale_factor = gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
|
||||
logical_geometry.y /= scale_factor;
|
||||
logical_geometry.x /= scale_factor;
|
||||
logical_geometry.width /= scale_factor;
|
||||
logical_geometry.height /= scale_factor;
|
||||
|
||||
scale = scale_factor;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = MAX (monitor->output_geometry.width / (double) logical_geometry.width,
|
||||
monitor->output_geometry.height / (double) logical_geometry.height);
|
||||
}
|
||||
|
||||
gdk_monitor_set_geometry (GDK_MONITOR (monitor), &logical_geometry);
|
||||
gdk_monitor_set_geometry (GDK_MONITOR (monitor),
|
||||
&(GdkRectangle) {
|
||||
monitor->x, monitor->y,
|
||||
monitor->width, monitor->height });
|
||||
gdk_monitor_set_connector (GDK_MONITOR (monitor), monitor->name);
|
||||
gdk_monitor_set_description (GDK_MONITOR (monitor), monitor->description);
|
||||
gdk_monitor_set_scale (GDK_MONITOR (monitor), scale);
|
||||
|
||||
monitor->wl_output_done = FALSE;
|
||||
monitor->xdg_output_done = FALSE;
|
||||
|
||||
@@ -2488,8 +2456,8 @@ xdg_output_handle_logical_position (void *data,
|
||||
GDK_DEBUG (MISC, "handle logical position xdg-output %d, position %d %d",
|
||||
monitor->id, x, y);
|
||||
|
||||
monitor->xdg_output_geometry.x = x;
|
||||
monitor->xdg_output_geometry.y = y;
|
||||
monitor->x = x;
|
||||
monitor->y = y;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2503,8 +2471,8 @@ xdg_output_handle_logical_size (void *data,
|
||||
GDK_DEBUG (MISC, "handle logical size xdg-output %d, size %d %d",
|
||||
monitor->id, width, height);
|
||||
|
||||
monitor->xdg_output_geometry.width = width;
|
||||
monitor->xdg_output_geometry.height = height;
|
||||
monitor->width = width;
|
||||
monitor->height = height;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2590,8 +2558,8 @@ output_handle_geometry (void *data,
|
||||
make, model,
|
||||
transform_to_string (transform));
|
||||
|
||||
monitor->output_geometry.x = x;
|
||||
monitor->output_geometry.y = y;
|
||||
monitor->x = x;
|
||||
monitor->y = y;
|
||||
|
||||
switch (transform)
|
||||
{
|
||||
@@ -2635,12 +2603,28 @@ output_handle_scale (void *data,
|
||||
int32_t scale)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
|
||||
GdkRectangle previous_geometry;
|
||||
int previous_scale;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
GDK_DEBUG (MISC, "handle scale output %d, scale %d", monitor->id, scale);
|
||||
|
||||
gdk_monitor_get_geometry (GDK_MONITOR (monitor), &previous_geometry);
|
||||
previous_scale = gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
|
||||
|
||||
/* Set the scale from wl_output protocol, regardless of xdg-output support */
|
||||
gdk_monitor_set_scale_factor (GDK_MONITOR (monitor), scale);
|
||||
|
||||
if (monitor_has_xdg_output (monitor))
|
||||
return;
|
||||
|
||||
width = previous_geometry.width * previous_scale;
|
||||
height = previous_geometry.height * previous_scale;
|
||||
|
||||
monitor->width = width / scale;
|
||||
monitor->height = height / scale;
|
||||
|
||||
if (should_update_monitor (monitor))
|
||||
apply_monitor_change (monitor);
|
||||
}
|
||||
@@ -2654,6 +2638,7 @@ output_handle_mode (void *data,
|
||||
int refresh)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
|
||||
int scale;
|
||||
|
||||
GDK_DEBUG (MISC, "handle mode output %d, size %d %d, rate %d",
|
||||
monitor->id, width, height, refresh);
|
||||
@@ -2661,8 +2646,9 @@ output_handle_mode (void *data,
|
||||
if ((flags & WL_OUTPUT_MODE_CURRENT) == 0)
|
||||
return;
|
||||
|
||||
monitor->output_geometry.width = width;
|
||||
monitor->output_geometry.height = height;
|
||||
scale = gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
|
||||
monitor->width = width / scale;
|
||||
monitor->height = height / scale;
|
||||
gdk_monitor_set_refresh_rate (GDK_MONITOR (monitor), refresh);
|
||||
|
||||
if (should_update_monitor (monitor) || !monitor_has_xdg_output (monitor))
|
||||
|
||||
@@ -87,8 +87,9 @@ static void
|
||||
gdk_wayland_gl_context_empty_frame (GdkDrawContext *draw_context)
|
||||
{
|
||||
GdkSurface *surface = gdk_draw_context_get_surface (draw_context);
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (gdk_wayland_surface_needs_commit (surface))
|
||||
if (impl->has_pending_subsurface_commits)
|
||||
{
|
||||
gdk_wayland_surface_sync (surface);
|
||||
gdk_wayland_surface_request_frame (surface);
|
||||
|
||||
@@ -31,10 +31,11 @@ struct _GdkWaylandMonitor {
|
||||
gboolean added;
|
||||
|
||||
struct zxdg_output_v1 *xdg_output;
|
||||
/* Raw wl_output data */
|
||||
GdkRectangle output_geometry;
|
||||
/* Raw xdg_output data */
|
||||
GdkRectangle xdg_output_geometry;
|
||||
/* Size and position, can be either from wl_output or xdg_output */
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
char *name;
|
||||
char *description;
|
||||
gboolean wl_output_done;
|
||||
|
||||
@@ -129,7 +129,6 @@ guint _gdk_wayland_cursor_get_next_image_index (GdkWaylandDisplay *display,
|
||||
guint *next_image_delay);
|
||||
|
||||
void gdk_wayland_surface_sync (GdkSurface *surface);
|
||||
gboolean gdk_wayland_surface_needs_commit (GdkSurface *surface);
|
||||
void gdk_wayland_surface_commit (GdkSurface *surface);
|
||||
void gdk_wayland_surface_notify_committed (GdkSurface *surface);
|
||||
void gdk_wayland_surface_request_frame (GdkSurface *surface);
|
||||
|
||||
@@ -26,6 +26,8 @@ struct _GdkWaylandSubsurface
|
||||
struct wl_region *opaque_region;
|
||||
|
||||
struct wl_callback *frame_callback;
|
||||
|
||||
gboolean above_parent;
|
||||
};
|
||||
|
||||
struct _GdkWaylandSubsurfaceClass
|
||||
|
||||
@@ -166,8 +166,8 @@ gdk_wayland_subsurface_attach (GdkSubsurface *sub,
|
||||
graphene_rect_t device_rect;
|
||||
cairo_rectangle_int_t device_dest;
|
||||
|
||||
if (sibling)
|
||||
will_be_above = sibling->above_parent;
|
||||
if (sib)
|
||||
will_be_above = sib->above_parent;
|
||||
else
|
||||
will_be_above = above;
|
||||
|
||||
@@ -322,6 +322,8 @@ gdk_wayland_subsurface_attach (GdkSubsurface *sub,
|
||||
wl_subsurface_place_above (self->subsurface, sib->surface);
|
||||
else
|
||||
wl_subsurface_place_below (self->subsurface, sib->surface);
|
||||
|
||||
self->above_parent = sib->above_parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -331,6 +333,7 @@ gdk_wayland_subsurface_attach (GdkSubsurface *sub,
|
||||
else
|
||||
wl_subsurface_place_below (self->subsurface,
|
||||
GDK_WAYLAND_SURFACE (sub->parent)->display_server.wl_surface);
|
||||
self->above_parent = above;
|
||||
}
|
||||
|
||||
wl_surface_commit (self->surface);
|
||||
@@ -381,6 +384,14 @@ gdk_wayland_subsurface_get_rect (GdkSubsurface *sub,
|
||||
rect->size.height = self->dest.height;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_subsurface_is_above_parent (GdkSubsurface *sub)
|
||||
{
|
||||
GdkWaylandSubsurface *self = (GdkWaylandSubsurface *)sub;
|
||||
|
||||
return self->above_parent;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_subsurface_class_init (GdkWaylandSubsurfaceClass *class)
|
||||
{
|
||||
@@ -393,6 +404,7 @@ gdk_wayland_subsurface_class_init (GdkWaylandSubsurfaceClass *class)
|
||||
subsurface_class->detach = gdk_wayland_subsurface_detach;
|
||||
subsurface_class->get_texture = gdk_wayland_subsurface_get_texture;
|
||||
subsurface_class->get_rect = gdk_wayland_subsurface_get_rect;
|
||||
subsurface_class->is_above_parent = gdk_wayland_subsurface_is_above_parent;
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -466,6 +478,8 @@ gdk_wayland_surface_create_subsurface (GdkSurface *surface)
|
||||
wl_region_add (sub->opaque_region, 0, 0, G_MAXINT, G_MAXINT);
|
||||
wl_surface_set_opaque_region (sub->surface, sub->opaque_region);
|
||||
|
||||
sub->above_parent = TRUE;
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, OFFLOAD, "Subsurface %p of surface %p created", sub, impl);
|
||||
|
||||
return GDK_SUBSURFACE (sub);
|
||||
|
||||
@@ -199,20 +199,20 @@ get_egl_window_size (GdkSurface *surface,
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (display, GL_NO_FRACTIONAL))
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, OPENGL, "Using integer scale %d for EGL window", gdk_fractional_scale_to_int (&impl->scale));
|
||||
|
||||
*width = surface->width * gdk_fractional_scale_to_int (&impl->scale);
|
||||
*height = surface->height * gdk_fractional_scale_to_int (&impl->scale);
|
||||
}
|
||||
else
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (display, GL_FRACTIONAL))
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, OPENGL, "Using fractional scale %g for EGL window", gdk_fractional_scale_to_double (&impl->scale));
|
||||
|
||||
*width = gdk_fractional_scale_scale (&impl->scale, surface->width),
|
||||
*height = gdk_fractional_scale_scale (&impl->scale, surface->height);
|
||||
}
|
||||
else
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, OPENGL, "Using integer scale %d for EGL window", gdk_fractional_scale_to_int (&impl->scale));
|
||||
|
||||
*width = surface->width * gdk_fractional_scale_to_int (&impl->scale);
|
||||
*height = surface->height * gdk_fractional_scale_to_int (&impl->scale);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -646,12 +646,9 @@ gdk_wayland_surface_sync_opaque_region (GdkSurface *surface)
|
||||
cairo_region_t *region = cairo_region_copy (impl->opaque_region);
|
||||
for (gsize i = 0; i < gdk_surface_get_n_subsurfaces (surface); i++)
|
||||
{
|
||||
GdkSubsurface *subsurface = gdk_surface_get_subsurface (surface, i);
|
||||
GdkWaylandSubsurface *sub = (GdkWaylandSubsurface *) subsurface;
|
||||
|
||||
if (subsurface->above_parent)
|
||||
GdkWaylandSubsurface *sub = (GdkWaylandSubsurface *)gdk_surface_get_subsurface (surface, i);
|
||||
if (sub->above_parent)
|
||||
continue;
|
||||
|
||||
if (sub->texture != NULL)
|
||||
cairo_region_subtract_rectangle (region, &sub->dest);
|
||||
}
|
||||
@@ -749,18 +746,6 @@ gdk_wayland_surface_sync (GdkSurface *surface)
|
||||
gdk_wayland_surface_sync_viewport (surface);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_wayland_surface_needs_commit (GdkSurface *surface)
|
||||
{
|
||||
GdkWaylandSurface *self = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
return self->has_pending_subsurface_commits ||
|
||||
self->opaque_region_dirty ||
|
||||
self->input_region_dirty ||
|
||||
self->buffer_scale_dirty ||
|
||||
self->viewport_dirty;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_fractional_scale_preferred_scale_cb (void *data,
|
||||
struct wp_fractional_scale_v1 *fractional_scale,
|
||||
|
||||
@@ -153,11 +153,6 @@ gdk_win32_cairo_context_end_frame (GdkDrawContext *draw_context,
|
||||
g_clear_pointer (&self->window_surface, cairo_surface_destroy);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_cairo_context_empty_frame (GdkDrawContext *draw_context)
|
||||
{
|
||||
}
|
||||
|
||||
static cairo_t *
|
||||
gdk_win32_cairo_context_cairo_create (GdkCairoContext *context)
|
||||
{
|
||||
@@ -187,7 +182,6 @@ gdk_win32_cairo_context_class_init (GdkWin32CairoContextClass *klass)
|
||||
|
||||
draw_context_class->begin_frame = gdk_win32_cairo_context_begin_frame;
|
||||
draw_context_class->end_frame = gdk_win32_cairo_context_end_frame;
|
||||
draw_context_class->empty_frame = gdk_win32_cairo_context_empty_frame;
|
||||
|
||||
cairo_context_class->cairo_create = gdk_win32_cairo_context_cairo_create;
|
||||
}
|
||||
|
||||
@@ -1064,7 +1064,6 @@ gdk_win32_display_check_composited (GdkWin32Display *display)
|
||||
}
|
||||
|
||||
gdk_display_set_composited (GDK_DISPLAY (display), composited);
|
||||
gdk_display_set_shadow_width (GDK_DISPLAY (display), composited);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -117,11 +117,6 @@ gdk_win32_gl_context_egl_begin_frame (GdkDrawContext *draw_context,
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_egl_parent_class)->begin_frame (draw_context, depth, update_area);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_gl_context_egl_empty_frame (GdkDrawContext *draw_context)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_gl_context_egl_class_init (GdkWin32GLContextClass *klass)
|
||||
{
|
||||
@@ -132,7 +127,6 @@ gdk_win32_gl_context_egl_class_init (GdkWin32GLContextClass *klass)
|
||||
|
||||
draw_context_class->begin_frame = gdk_win32_gl_context_egl_begin_frame;
|
||||
draw_context_class->end_frame = gdk_win32_gl_context_egl_end_frame;
|
||||
draw_context_class->empty_frame = gdk_win32_gl_context_egl_empty_frame;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -116,11 +116,6 @@ gdk_win32_gl_context_wgl_end_frame (GdkDrawContext *draw_context,
|
||||
SwapBuffers (hdc);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_gl_context_wgl_empty_frame (GdkDrawContext *draw_context)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_gl_context_wgl_begin_frame (GdkDrawContext *draw_context,
|
||||
GdkMemoryDepth depth,
|
||||
@@ -814,8 +809,6 @@ gdk_win32_gl_context_wgl_class_init (GdkWin32GLContextWGLClass *klass)
|
||||
|
||||
draw_context_class->begin_frame = gdk_win32_gl_context_wgl_begin_frame;
|
||||
draw_context_class->end_frame = gdk_win32_gl_context_wgl_end_frame;
|
||||
draw_context_class->empty_frame = gdk_win32_gl_context_wgl_empty_frame;
|
||||
|
||||
gobject_class->dispose = gdk_win32_gl_context_wgl_dispose;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,11 +74,6 @@ gdk_win32_vulkan_context_begin_frame (GdkDrawContext *draw_context,
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_win32_vulkan_context_parent_class)->begin_frame (draw_context, depth, update_area);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_vulkan_context_empty_frame (GdkDrawContext *draw_context)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_vulkan_context_class_init (GdkWin32VulkanContextClass *klass)
|
||||
{
|
||||
@@ -87,7 +82,6 @@ gdk_win32_vulkan_context_class_init (GdkWin32VulkanContextClass *klass)
|
||||
|
||||
context_class->create_surface = gdk_win32_vulkan_context_create_surface;
|
||||
draw_context_class->begin_frame = gdk_win32_vulkan_context_begin_frame;
|
||||
draw_context_class->empty_frame = gdk_win32_vulkan_context_empty_frame;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -1429,7 +1429,6 @@ gdk_x11_display_open (const char *display_name)
|
||||
int ignore;
|
||||
int maj, min;
|
||||
char *cm_name;
|
||||
gboolean frame_extents;
|
||||
|
||||
XInitThreads ();
|
||||
|
||||
@@ -1644,10 +1643,6 @@ gdk_x11_display_open (const char *display_name)
|
||||
gdk_x11_get_xatom_by_name_for_display (display, cm_name)) != None);
|
||||
g_free (cm_name);
|
||||
|
||||
frame_extents = gdk_x11_screen_supports_net_wm_hint (gdk_x11_display_get_screen (display),
|
||||
g_intern_static_string ("_GTK_FRAME_EXTENTS"));
|
||||
gdk_display_set_shadow_width (display, frame_extents);
|
||||
|
||||
gdk_display_emit_opened (display);
|
||||
|
||||
return display;
|
||||
|
||||
@@ -316,10 +316,7 @@ gdk_x11_gl_context_glx_get_damage (GdkGLContext *context)
|
||||
for (i = 0; i < buffer_age - 1; i++)
|
||||
{
|
||||
if (context->old_updated_area[i] == NULL)
|
||||
{
|
||||
cairo_region_destroy (damage);
|
||||
return GDK_GL_CONTEXT_CLASS (gdk_x11_gl_context_glx_parent_class)->get_damage (context);
|
||||
}
|
||||
return GDK_GL_CONTEXT_CLASS (gdk_x11_gl_context_glx_parent_class)->get_damage (context);
|
||||
|
||||
cairo_region_union (damage, context->old_updated_area[i]);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,479 @@
|
||||
#pragma once
|
||||
|
||||
#include <graphene.h>
|
||||
#include <math.h>
|
||||
#include "gsktypesprivate.h"
|
||||
#include "scaleprivate.h"
|
||||
#include "pointprivate.h"
|
||||
|
||||
#ifndef USE_SIMD
|
||||
|
||||
struct _Box
|
||||
{
|
||||
float x0, y0, x1, y1;
|
||||
};
|
||||
|
||||
static inline float
|
||||
box_x0 (const Box box)
|
||||
{
|
||||
return box.x0;
|
||||
}
|
||||
|
||||
static inline float
|
||||
box_y0 (const Box box)
|
||||
{
|
||||
return box.y0;
|
||||
}
|
||||
|
||||
static inline float
|
||||
box_x1 (const Box box)
|
||||
{
|
||||
return box.x1;
|
||||
}
|
||||
|
||||
static inline float
|
||||
box_y1 (const Box box)
|
||||
{
|
||||
return box.y1;
|
||||
}
|
||||
|
||||
static inline float
|
||||
box_width (const Box box)
|
||||
{
|
||||
return box.x1 - box.x0;
|
||||
}
|
||||
|
||||
static inline float
|
||||
box_height (const Box box)
|
||||
{
|
||||
return box.y1 - box.y0;
|
||||
}
|
||||
|
||||
/* Assumes x0 <= x1 && y0 <= y1 */
|
||||
static inline Box
|
||||
box (float x0,
|
||||
float y0,
|
||||
float x1,
|
||||
float y1)
|
||||
{
|
||||
return (Box) { .x0 = x0, .y0 = y0, .x1 = x1, .y1 = y1 };
|
||||
}
|
||||
|
||||
static inline Box
|
||||
box_from_rect (float x,
|
||||
float y,
|
||||
float w,
|
||||
float h)
|
||||
{
|
||||
return box (x, y, x + w, y + h);
|
||||
}
|
||||
|
||||
static inline Box
|
||||
box_from_graphene (const graphene_rect_t *rect)
|
||||
{
|
||||
return box_from_rect (rect->origin.x,
|
||||
rect->origin.y,
|
||||
rect->size.width,
|
||||
rect->size.height);
|
||||
}
|
||||
|
||||
/* Assumes p0.x <= p1.x && p0.y <= p1.y */
|
||||
static inline Box
|
||||
box_from_points (Point p0,
|
||||
Point p1)
|
||||
{
|
||||
return box (p0.x, p0.y, p1.x, p1.y);
|
||||
}
|
||||
|
||||
static inline Point
|
||||
box_origin (const Box box)
|
||||
{
|
||||
return point (box.x0, box.y0);
|
||||
}
|
||||
|
||||
static inline Point
|
||||
box_opposite (const Box box)
|
||||
{
|
||||
return point (box.x1, box.y1);
|
||||
}
|
||||
|
||||
static inline void
|
||||
box_to_float (const Box box,
|
||||
float v[4])
|
||||
{
|
||||
v[0] = box.x0;
|
||||
v[1] = box.y0;
|
||||
v[2] = box.x1 - box.x0;
|
||||
v[3] = box.y1 - box.y0;
|
||||
}
|
||||
|
||||
static inline Box
|
||||
box_inset (const Box box,
|
||||
float dx,
|
||||
float dy)
|
||||
{
|
||||
return (Box) { .x0 = box.x0 + dx, .y0 = box.y0 + dy,
|
||||
.x1 = box.x1 - dx, .y1 = box.y1 - dy };
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
box_intersect (const Box box1,
|
||||
const Box box2,
|
||||
Box *box)
|
||||
{
|
||||
Box b;
|
||||
|
||||
b.x0 = MAX (box1.x0, box2.x0);
|
||||
b.y0 = MAX (box1.y0, box2.y0);
|
||||
b.x1 = MIN (box1.x1, box2.x1);
|
||||
b.y1 = MIN (box1.y1, box2.y1);
|
||||
|
||||
if (b.x0 <= b.x1 && b.y0 <= b.x1)
|
||||
{
|
||||
if (box)
|
||||
*box = b;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
box_equal (const Box box1,
|
||||
const Box box2)
|
||||
{
|
||||
return memcmp (&box1, &box2, sizeof (Box)) == 0;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
box_contains (const Box box1,
|
||||
const Box box2)
|
||||
{
|
||||
Box box;
|
||||
|
||||
if (box_intersect (box1, box2, &box))
|
||||
return box_equal (box, box2);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
box_empty (const Box box)
|
||||
{
|
||||
return box.x0 == box.x1 || box.y0 == box.y1;
|
||||
}
|
||||
|
||||
static inline Box
|
||||
box_add (const Box box,
|
||||
const Point offset)
|
||||
{
|
||||
return (Box) { .x0 = box.x0 + offset.x, .y0 = box.y0 + offset.y,
|
||||
.x1 = box.x1 + offset.x, .y1 = box.y1 + offset.y };
|
||||
}
|
||||
|
||||
static inline Box
|
||||
box_sub (const Box box,
|
||||
const Point offset)
|
||||
{
|
||||
return (Box) { .x0 = box.x0 - offset.x, .y0 = box.y0 - offset.y,
|
||||
.x1 = box.x1 - offset.x, .y1 = box.y1 - offset.y };
|
||||
}
|
||||
|
||||
static inline Box
|
||||
box_mul (const Box box,
|
||||
const Scale scale)
|
||||
{
|
||||
Box b = (Box) { .x0 = box.x0 * scale.x, .y0 = box.y0 * scale.y,
|
||||
.x1 = box.x1 * scale.x, .y1 = box.y1 * scale.y };
|
||||
|
||||
if (G_UNLIKELY (scale.x < 0 || scale.y < 0))
|
||||
return (Box) { .x0 = MIN (b.x0, b.x1), .y0 = MIN (b.y0, b.y1),
|
||||
.x1 = MAX (b.x0, b.x1), .y1 = MAX (b.y0, b.y1) };
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
static inline Box
|
||||
box_div (const Box box,
|
||||
const Scale scale)
|
||||
{
|
||||
return box_mul (box, scale_inv (scale));
|
||||
}
|
||||
|
||||
static inline void
|
||||
box_offset_to_float (const Box box,
|
||||
const Point offset,
|
||||
float v[4])
|
||||
{
|
||||
box_to_float (box_add (box, offset), v);
|
||||
}
|
||||
|
||||
static inline Box
|
||||
box_round_larger (const Box box)
|
||||
{
|
||||
return (Box) { .x0 = floorf (box.x0), .y0 = floorf (box.y0),
|
||||
.x1 = ceilf (box.x1), .y1 = ceilf (box.y1) };
|
||||
}
|
||||
|
||||
static inline Box
|
||||
box_round_to_pixels (const Box box,
|
||||
const Scale scale,
|
||||
const Point offset)
|
||||
{
|
||||
return box_sub (box_div (box_round_larger (box_mul (box_add (box, offset), scale)), scale), offset);
|
||||
}
|
||||
|
||||
#else /* USE_SIMD */
|
||||
|
||||
struct _Box
|
||||
{
|
||||
GRAPHENE_ALIGNED_DECL (graphene_simd4f_t v, 16);
|
||||
};
|
||||
|
||||
static inline float
|
||||
box_x0 (const Box box)
|
||||
{
|
||||
return graphene_simd4f_get_x (box.v);
|
||||
}
|
||||
|
||||
static inline float
|
||||
box_y0 (const Box box)
|
||||
{
|
||||
return graphene_simd4f_get_y (box.v);
|
||||
}
|
||||
|
||||
static inline float
|
||||
box_x1 (const Box box)
|
||||
{
|
||||
return graphene_simd4f_get_z (box.v);
|
||||
}
|
||||
|
||||
static inline float
|
||||
box_y1 (const Box box)
|
||||
{
|
||||
return graphene_simd4f_get_w (box.v);
|
||||
}
|
||||
|
||||
static inline float
|
||||
box_width (const Box box)
|
||||
{
|
||||
return box_x1 (box) - box_x0 (box);
|
||||
}
|
||||
|
||||
static inline float
|
||||
box_height (const Box box)
|
||||
{
|
||||
return box_y1 (box) - box_y0 (box);
|
||||
}
|
||||
|
||||
static inline Box
|
||||
box (float x0,
|
||||
float y0,
|
||||
float x1,
|
||||
float y1)
|
||||
{
|
||||
return (Box) { .v = graphene_simd4f_init (x0, y0, x1, y1) };
|
||||
}
|
||||
|
||||
static inline Box
|
||||
box_from_rect (float x,
|
||||
float y,
|
||||
float w,
|
||||
float h)
|
||||
{
|
||||
return box (x, y, x + w, y + h);
|
||||
}
|
||||
|
||||
static inline Box
|
||||
box_from_graphene (const graphene_rect_t *rect)
|
||||
{
|
||||
return box_from_rect (rect->origin.x,
|
||||
rect->origin.y,
|
||||
rect->size.width,
|
||||
rect->size.height);
|
||||
}
|
||||
|
||||
/* { a[0], a[1], b[0], b[1] } */
|
||||
# define graphene_simd4f_splat_xyxy(a,b) \
|
||||
(__extension__ ({ \
|
||||
(graphene_simd4f_t) _mm_shuffle_ps ((a), (b), _MM_SHUFFLE (1, 0, 1, 0)); \
|
||||
}))
|
||||
|
||||
static inline Box
|
||||
box_from_points (Point p0,
|
||||
Point p1)
|
||||
{
|
||||
return (Box) { .v = graphene_simd4f_splat_xyxy (p0.v, p1.v) };
|
||||
}
|
||||
|
||||
static inline Point
|
||||
box_origin (const Box box)
|
||||
{
|
||||
return (Point) { .v = graphene_simd4f_zero_zw (box.v) };
|
||||
}
|
||||
|
||||
static inline Point
|
||||
box_opposite (const Box box)
|
||||
{
|
||||
return (Point) { .v = graphene_simd4f_zero_zw (graphene_simd4f_shuffle_zwxy (box.v)) };
|
||||
}
|
||||
|
||||
static inline void
|
||||
box_to_float (const Box box,
|
||||
float v[4])
|
||||
{
|
||||
graphene_simd4f_dup_4f (box.v, v);
|
||||
v[2] -= v[0];
|
||||
v[3] -= v[1];
|
||||
}
|
||||
|
||||
static inline Box
|
||||
box_inset (const Box box,
|
||||
float dx,
|
||||
float dy)
|
||||
{
|
||||
return (Box) { .v = graphene_simd4f_add (box.v, graphene_simd4f_init (dx, dy, -dx, -dy)) };
|
||||
}
|
||||
|
||||
/* return a[0] < b[0] && a[1] < b[1] */
|
||||
#ifndef graphene_simd4f_cmple_xy
|
||||
# define graphene_simd4f_cmple_xy(a,b) \
|
||||
(__extension__ ({ \
|
||||
__m128i __res = (__m128i) _mm_cmple_ps ((a), (b)); \
|
||||
(bool) ((_mm_movemask_epi8 (__res) & 0xff) == 0xff); \
|
||||
}))
|
||||
#endif
|
||||
|
||||
static inline gboolean
|
||||
box_intersect (const Box box1,
|
||||
const Box box2,
|
||||
Box *box)
|
||||
{
|
||||
graphene_simd4f_t s, t, t1;
|
||||
|
||||
s = graphene_simd4f_max (box1.v, box2.v);
|
||||
t = graphene_simd4f_min (box1.v, box2.v);
|
||||
t1 = graphene_simd4f_shuffle_zwxy (t);
|
||||
|
||||
if (graphene_simd4f_cmple_xy (s, t1))
|
||||
{
|
||||
if (box)
|
||||
box->v = graphene_simd4f_splat_xyxy (s, t);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
box_equal (const Box box1,
|
||||
const Box box2)
|
||||
{
|
||||
return (gboolean) !!graphene_simd4f_cmp_eq (box1.v, box2.v);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
box_contains (const Box box1,
|
||||
const Box box2)
|
||||
{
|
||||
Box box;
|
||||
|
||||
if (box_intersect (box1, box2, &box))
|
||||
return box_equal (box, box2);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
box_empty (const Box box)
|
||||
{
|
||||
/* FIXME simd */
|
||||
return box_x0 (box) == box_x1 (box) || box_y0 (box) == box_y1 (box);
|
||||
}
|
||||
|
||||
/* a splat variation */
|
||||
#ifndef graphene_simd4f_shuffle_xyxy
|
||||
# define graphene_simd4f_shuffle_xyxy(v) \
|
||||
(__extension__ ({ \
|
||||
(graphene_simd4f_t) _mm_shuffle_ps ((v), (v), _MM_SHUFFLE (1, 0, 1, 0)); \
|
||||
}))
|
||||
#endif
|
||||
|
||||
static inline Box
|
||||
box_add (const Box box,
|
||||
const Point offset)
|
||||
{
|
||||
return (Box) { .v = graphene_simd4f_add (box.v, graphene_simd4f_shuffle_xyxy (offset.v)) };
|
||||
}
|
||||
|
||||
static inline Box
|
||||
box_sub (const Box box,
|
||||
const Point offset)
|
||||
{
|
||||
return (Box) { .v = graphene_simd4f_sub (box.v, graphene_simd4f_shuffle_xyxy (offset.v)) };
|
||||
}
|
||||
|
||||
static inline Box
|
||||
box_mul (const Box box,
|
||||
const Scale scale)
|
||||
{
|
||||
Box b = (Box) { .v = graphene_simd4f_mul (box.v, graphene_simd4f_shuffle_xyxy (scale.v)) };
|
||||
|
||||
if (G_UNLIKELY (!graphene_simd4f_cmple_xy (graphene_simd4f_init (0, 0, 0, 0), scale.v)))
|
||||
{
|
||||
graphene_simd4f_t v = graphene_simd4f_shuffle_zwxy (b.v);
|
||||
graphene_simd4f_t s = graphene_simd4f_min (b.v, v);
|
||||
graphene_simd4f_t t = graphene_simd4f_max (b.v, v);
|
||||
|
||||
return (Box) { .v = graphene_simd4f_splat_xyxy (s, t) };
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
static inline Box
|
||||
box_div (const Box box,
|
||||
const Scale scale)
|
||||
{
|
||||
return box_mul (box, scale_inv (scale));
|
||||
}
|
||||
|
||||
static inline void
|
||||
box_offset_to_float (const Box box,
|
||||
const Point offset,
|
||||
float v[4])
|
||||
{
|
||||
box_to_float (box_add (box, offset), v);
|
||||
}
|
||||
|
||||
#ifdef __SSE4_1__
|
||||
|
||||
static inline Box
|
||||
box_round_larger (const Box box)
|
||||
{
|
||||
return { (Box) .v = graphene_simd4f_splat_xyxy (graphene_simd4f_floor (b.v), graphene_simd4f_ceil (b.v)) };
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline Box
|
||||
box_round_larger (const Box b)
|
||||
{
|
||||
return box (floorf (box_x0 (b)),
|
||||
floorf (box_y0 (b)),
|
||||
ceilf (box_x1 (b)),
|
||||
ceilf (box_y1 (b)));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static inline Box
|
||||
box_round_to_pixels (const Box box,
|
||||
const Scale scale,
|
||||
const Point offset)
|
||||
{
|
||||
return box_sub (box_div (box_round_larger (box_mul (box_add (box, offset), scale)), scale), offset);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -125,12 +125,6 @@ gsk_gl_device_create_atlas_image (GskGpuDevice *device,
|
||||
height);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_device_make_current (GskGpuDevice *device)
|
||||
{
|
||||
gdk_gl_context_make_current (gdk_display_get_gl_context (gsk_gpu_device_get_display (device)));
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_device_finalize (GObject *object)
|
||||
{
|
||||
@@ -157,7 +151,6 @@ gsk_gl_device_class_init (GskGLDeviceClass *klass)
|
||||
gpu_device_class->create_atlas_image = gsk_gl_device_create_atlas_image;
|
||||
gpu_device_class->create_upload_image = gsk_gl_device_create_upload_image;
|
||||
gpu_device_class->create_download_image = gsk_gl_device_create_download_image;
|
||||
gpu_device_class->make_current = gsk_gl_device_make_current;
|
||||
|
||||
object_class->finalize = gsk_gl_device_finalize;
|
||||
}
|
||||
@@ -242,7 +235,7 @@ gsk_gl_device_get_for_display (GdkDisplay *display,
|
||||
if (!gdk_gl_context_check_version (context, "3.0", "3.0"))
|
||||
{
|
||||
g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("OpenGL ES 3.0 is not supported by this renderer."));
|
||||
_("OpenGL ES 2.0 is not supported by this renderer."));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ gsk_gl_image_finalize (GObject *object)
|
||||
{
|
||||
GskGLImage *self = GSK_GL_IMAGE (object);
|
||||
|
||||
if (self->texture_id && self->framebuffer_id)
|
||||
if (self->framebuffer_id)
|
||||
glDeleteFramebuffers (1, &self->framebuffer_id);
|
||||
|
||||
if (self->owns_texture)
|
||||
@@ -70,7 +70,6 @@ gsk_gl_image_init (GskGLImage *self)
|
||||
|
||||
GskGpuImage *
|
||||
gsk_gl_image_new_backbuffer (GskGLDevice *device,
|
||||
GdkGLContext *context,
|
||||
GdkMemoryFormat format,
|
||||
gsize width,
|
||||
gsize height)
|
||||
@@ -96,13 +95,6 @@ gsk_gl_image_new_backbuffer (GskGLDevice *device,
|
||||
|
||||
/* texture_id == 0 means backbuffer */
|
||||
|
||||
/* Check for non-standard framebuffer binding as we might not be using
|
||||
* the default framebuffer on systems like macOS where we've bound an
|
||||
* IOSurface to a GL_TEXTURE_RECTANGLE. Otherwise, no scissor clip will
|
||||
* be applied in the command queue causing overdrawing.
|
||||
*/
|
||||
self->framebuffer_id = GDK_GL_CONTEXT_GET_CLASS (context)->get_default_framebuffer (context);
|
||||
|
||||
return GSK_GPU_IMAGE (self);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ G_BEGIN_DECLS
|
||||
G_DECLARE_FINAL_TYPE (GskGLImage, gsk_gl_image, GSK, GL_IMAGE, GskGpuImage)
|
||||
|
||||
GskGpuImage * gsk_gl_image_new_backbuffer (GskGLDevice *device,
|
||||
GdkGLContext *context,
|
||||
GdkMemoryFormat format,
|
||||
gsize width,
|
||||
gsize height);
|
||||
|
||||
@@ -36,9 +36,6 @@ gsk_gpu_blend_op_print (GskGpuOp *op,
|
||||
case GSK_GPU_BLEND_ADD:
|
||||
gsk_gpu_print_string (string, "add");
|
||||
break;
|
||||
case GSK_GPU_BLEND_CLEAR:
|
||||
gsk_gpu_print_string (string, "clear");
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
@@ -75,9 +72,6 @@ gsk_gpu_blend_op_gl_command (GskGpuOp *op,
|
||||
case GSK_GPU_BLEND_ADD:
|
||||
glBlendFunc (GL_ONE, GL_ONE);
|
||||
break;
|
||||
case GSK_GPU_BLEND_CLEAR:
|
||||
glBlendFunc (GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
|
||||
@@ -31,7 +31,6 @@ gsk_gpu_blur_op_print (GskGpuOp *op,
|
||||
instance = (GskGpuBlurInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset);
|
||||
|
||||
gsk_gpu_print_op (string, indent, "blur");
|
||||
g_string_append_printf (string, "%g,%g ", instance->blur_direction[0], instance->blur_direction[1]);
|
||||
gsk_gpu_print_rect (string, instance->rect);
|
||||
gsk_gpu_print_image_descriptor (string, shader->desc, instance->tex_id);
|
||||
gsk_gpu_print_newline (string);
|
||||
|
||||
@@ -301,3 +301,42 @@ gsk_gpu_clip_get_shader_clip (const GskGpuClip *self,
|
||||
return GSK_GPU_SHADER_CLIP_ROUNDED;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_gpu_clip_contains_box (const GskGpuClip *self,
|
||||
const Point *offset,
|
||||
const Box *box)
|
||||
{
|
||||
Box b = box_add (*box, *offset);
|
||||
|
||||
switch (self->type)
|
||||
{
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
case GSK_GPU_CLIP_ALL_CLIPPED:
|
||||
return FALSE;
|
||||
|
||||
case GSK_GPU_CLIP_NONE:
|
||||
case GSK_GPU_CLIP_CONTAINED:
|
||||
case GSK_GPU_CLIP_RECT:
|
||||
return box_contains (box_from_graphene (&self->rect.bounds), b);
|
||||
|
||||
case GSK_GPU_CLIP_ROUNDED:
|
||||
return gsk_rounded_rect_contains_rect (&self->rect, &GRAPHENE_RECT_INIT (box_x0 (b), box_y0 (b), box_width (b), box_height (b)));
|
||||
}
|
||||
}
|
||||
|
||||
GskGpuShaderClip
|
||||
gsk_gpu_clip_get_shader_clip2 (const GskGpuClip *self,
|
||||
const Point *offset,
|
||||
const Box *box)
|
||||
{
|
||||
if (self->type == GSK_GPU_CLIP_NONE ||
|
||||
self->type == GSK_GPU_CLIP_CONTAINED ||
|
||||
gsk_gpu_clip_contains_box (self, offset, box))
|
||||
return GSK_GPU_SHADER_CLIP_NONE;
|
||||
else if (self->type == GSK_GPU_CLIP_RECT)
|
||||
return GSK_GPU_SHADER_CLIP_RECT;
|
||||
else
|
||||
return GSK_GPU_SHADER_CLIP_ROUNDED;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <gdk/gdk.h>
|
||||
#include <graphene.h>
|
||||
#include <gsk/gskroundedrect.h>
|
||||
#include "boxprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -65,9 +66,16 @@ gboolean gsk_gpu_clip_contains_rect (const G
|
||||
gboolean gsk_gpu_clip_may_intersect_rect (const GskGpuClip *self,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *rect) G_GNUC_WARN_UNUSED_RESULT;
|
||||
GskGpuShaderClip gsk_gpu_clip_get_shader_clip (const GskGpuClip *self,
|
||||
GskGpuShaderClip gsk_gpu_clip_get_shader_clip (const GskGpuClip *self,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *rect);
|
||||
|
||||
gboolean gsk_gpu_clip_contains_box (const GskGpuClip *self,
|
||||
const Point *offset,
|
||||
const Box *box) G_GNUC_WARN_UNUSED_RESULT;
|
||||
GskGpuShaderClip gsk_gpu_clip_get_shader_clip2 (const GskGpuClip *self,
|
||||
const Point *offset,
|
||||
const Box *box);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+59
-307
@@ -3,14 +3,10 @@
|
||||
#include "gskgpudeviceprivate.h"
|
||||
|
||||
#include "gskgpuframeprivate.h"
|
||||
#include "gskgpuimageprivate.h"
|
||||
#include "gskgpuuploadopprivate.h"
|
||||
|
||||
#include "gdk/gdkdisplayprivate.h"
|
||||
#include "gdk/gdktextureprivate.h"
|
||||
#include "gdk/gdkprofilerprivate.h"
|
||||
|
||||
#include "gsk/gskdebugprivate.h"
|
||||
|
||||
#define MAX_SLICES_PER_ATLAS 64
|
||||
|
||||
@@ -18,13 +14,6 @@
|
||||
|
||||
#define MAX_ATLAS_ITEM_SIZE 256
|
||||
|
||||
#define MAX_DEAD_PIXELS (ATLAS_SIZE * ATLAS_SIZE / 2)
|
||||
|
||||
#define CACHE_TIMEOUT 15 /* seconds */
|
||||
|
||||
G_STATIC_ASSERT (MAX_ATLAS_ITEM_SIZE < ATLAS_SIZE);
|
||||
G_STATIC_ASSERT (MAX_DEAD_PIXELS < ATLAS_SIZE * ATLAS_SIZE);
|
||||
|
||||
typedef struct _GskGpuCached GskGpuCached;
|
||||
typedef struct _GskGpuCachedClass GskGpuCachedClass;
|
||||
typedef struct _GskGpuCachedAtlas GskGpuCachedAtlas;
|
||||
@@ -40,14 +29,11 @@ struct _GskGpuDevicePrivate
|
||||
GskGpuCached *first_cached;
|
||||
GskGpuCached *last_cached;
|
||||
guint cache_gc_source;
|
||||
int cache_timeout; /* in seconds, or -1 to disable gc */
|
||||
|
||||
GHashTable *texture_cache;
|
||||
GHashTable *glyph_cache;
|
||||
|
||||
GskGpuCachedAtlas *current_atlas;
|
||||
|
||||
/* atomic */ gsize dead_texture_pixels;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GskGpuDevice, gsk_gpu_device, G_TYPE_OBJECT)
|
||||
@@ -68,34 +54,12 @@ struct _GskGpuCachedClass
|
||||
struct _GskGpuCached
|
||||
{
|
||||
const GskGpuCachedClass *class;
|
||||
|
||||
|
||||
GskGpuCachedAtlas *atlas;
|
||||
GskGpuCached *next;
|
||||
GskGpuCached *prev;
|
||||
|
||||
gint64 timestamp;
|
||||
gboolean stale;
|
||||
guint pixels; /* For glyphs and textures, pixels. For atlases, dead pixels */
|
||||
};
|
||||
|
||||
static inline void
|
||||
mark_as_stale (GskGpuCached *cached,
|
||||
gboolean stale)
|
||||
{
|
||||
if (cached->stale != stale)
|
||||
{
|
||||
cached->stale = stale;
|
||||
|
||||
if (cached->atlas)
|
||||
{
|
||||
if (stale)
|
||||
((GskGpuCached *) cached->atlas)->pixels += cached->pixels;
|
||||
else
|
||||
((GskGpuCached *) cached->atlas)->pixels -= cached->pixels;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_cached_free (GskGpuDevice *device,
|
||||
GskGpuCached *cached)
|
||||
@@ -111,8 +75,6 @@ gsk_gpu_cached_free (GskGpuDevice *device,
|
||||
else
|
||||
priv->first_cached = cached->next;
|
||||
|
||||
mark_as_stale (cached, TRUE);
|
||||
|
||||
cached->class->free (device, cached);
|
||||
}
|
||||
|
||||
@@ -152,21 +114,7 @@ gsk_gpu_cached_use (GskGpuDevice *device,
|
||||
GskGpuCached *cached,
|
||||
gint64 timestamp)
|
||||
{
|
||||
cached->timestamp = timestamp;
|
||||
mark_as_stale (cached, FALSE);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
gsk_gpu_cached_is_old (GskGpuDevice *device,
|
||||
GskGpuCached *cached,
|
||||
gint64 timestamp)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (device);
|
||||
|
||||
if (priv->cache_timeout < 0)
|
||||
return FALSE;
|
||||
else
|
||||
return timestamp - cached->timestamp > priv->cache_timeout * G_TIME_SPAN_SECOND;
|
||||
/* FIXME */
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
@@ -189,23 +137,10 @@ static void
|
||||
gsk_gpu_cached_atlas_free (GskGpuDevice *device,
|
||||
GskGpuCached *cached)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (device);
|
||||
GskGpuCachedAtlas *self = (GskGpuCachedAtlas *) cached;
|
||||
GskGpuCached *c, *next;
|
||||
|
||||
/* Free all remaining glyphs on this atlas */
|
||||
for (c = priv->first_cached; c != NULL; c = next)
|
||||
{
|
||||
next = c->next;
|
||||
if (c->atlas == self)
|
||||
gsk_gpu_cached_free (device, c);
|
||||
}
|
||||
|
||||
if (priv->current_atlas == self)
|
||||
priv->current_atlas = NULL;
|
||||
|
||||
g_object_unref (self->image);
|
||||
|
||||
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
@@ -214,7 +149,8 @@ gsk_gpu_cached_atlas_should_collect (GskGpuDevice *device,
|
||||
GskGpuCached *cached,
|
||||
gint64 timestamp)
|
||||
{
|
||||
return cached->pixels > MAX_DEAD_PIXELS;
|
||||
/* FIXME */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static const GskGpuCachedClass GSK_GPU_CACHED_ATLAS_CLASS =
|
||||
@@ -242,14 +178,7 @@ struct _GskGpuCachedTexture
|
||||
{
|
||||
GskGpuCached parent;
|
||||
|
||||
/* atomic */ int use_count; /* We count the use by the device (via the linked
|
||||
* list) and by the texture (via render data or
|
||||
* weak ref.
|
||||
*/
|
||||
|
||||
gsize *dead_pixels_counter;
|
||||
|
||||
GdkTexture *texture;
|
||||
/* atomic */ GdkTexture *texture;
|
||||
GskGpuImage *image;
|
||||
};
|
||||
|
||||
@@ -257,37 +186,14 @@ static void
|
||||
gsk_gpu_cached_texture_free (GskGpuDevice *device,
|
||||
GskGpuCached *cached)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (device);
|
||||
GskGpuCachedTexture *self = (GskGpuCachedTexture *) cached;
|
||||
gpointer key, value;
|
||||
gboolean texture_still_alive;
|
||||
|
||||
g_clear_object (&self->image);
|
||||
|
||||
if (g_hash_table_steal_extended (priv->texture_cache, self->texture, &key, &value))
|
||||
{
|
||||
/* If the texture has been reused already, we put the entry back */
|
||||
if ((GskGpuCached *) value != cached)
|
||||
g_hash_table_insert (priv->texture_cache, key, value);
|
||||
}
|
||||
|
||||
/* If the cached item itself is still in use by the texture, we leave
|
||||
* it to the weak ref or render data to free it.
|
||||
*/
|
||||
if (g_atomic_int_dec_and_test (&self->use_count))
|
||||
{
|
||||
g_free (self);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
gsk_gpu_cached_texture_is_invalid (GskGpuCachedTexture *self)
|
||||
{
|
||||
/* If the use count is less than 2, the orignal texture has died,
|
||||
* and the memory may have been reused for a new texture, so we
|
||||
* can't hand out the image that is for the original texture.
|
||||
*/
|
||||
return g_atomic_int_get (&self->use_count) < 2;
|
||||
texture_still_alive = g_atomic_pointer_exchange (&self->texture, NULL) != NULL;
|
||||
g_object_unref (self->image);
|
||||
|
||||
if (!texture_still_alive)
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -295,10 +201,8 @@ gsk_gpu_cached_texture_should_collect (GskGpuDevice *device,
|
||||
GskGpuCached *cached,
|
||||
gint64 timestamp)
|
||||
{
|
||||
GskGpuCachedTexture *self = (GskGpuCachedTexture *) cached;
|
||||
|
||||
return gsk_gpu_cached_is_old (device, cached, timestamp) ||
|
||||
gsk_gpu_cached_texture_is_invalid (self);
|
||||
/* FIXME */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static const GskGpuCachedClass GSK_GPU_CACHED_TEXTURE_CLASS =
|
||||
@@ -308,19 +212,16 @@ static const GskGpuCachedClass GSK_GPU_CACHED_TEXTURE_CLASS =
|
||||
gsk_gpu_cached_texture_should_collect
|
||||
};
|
||||
|
||||
/* Note: this function can run in an arbitrary thread, so it can
|
||||
* only access things atomically
|
||||
*/
|
||||
static void
|
||||
gsk_gpu_cached_texture_destroy_cb (gpointer data)
|
||||
{
|
||||
GskGpuCachedTexture *self = data;
|
||||
GskGpuCachedTexture *cache = data;
|
||||
gboolean cache_still_alive;
|
||||
|
||||
if (!gsk_gpu_cached_texture_is_invalid (self))
|
||||
g_atomic_pointer_add (self->dead_pixels_counter, ((GskGpuCached *) self)->pixels);
|
||||
cache_still_alive = g_atomic_pointer_exchange (&cache->texture, NULL) != NULL;
|
||||
|
||||
if (g_atomic_int_dec_and_test (&self->use_count))
|
||||
g_free (self);
|
||||
if (!cache_still_alive)
|
||||
g_free (cache);
|
||||
}
|
||||
|
||||
static GskGpuCachedTexture *
|
||||
@@ -334,19 +235,18 @@ gsk_gpu_cached_texture_new (GskGpuDevice *device,
|
||||
if (gdk_texture_get_render_data (texture, device))
|
||||
gdk_texture_clear_render_data (texture);
|
||||
else if ((self = g_hash_table_lookup (priv->texture_cache, texture)))
|
||||
g_hash_table_remove (priv->texture_cache, texture);
|
||||
{
|
||||
g_hash_table_remove (priv->texture_cache, texture);
|
||||
g_object_weak_unref (G_OBJECT (texture), (GWeakNotify) gsk_gpu_cached_texture_destroy_cb, self);
|
||||
}
|
||||
|
||||
self = gsk_gpu_cached_new (device, &GSK_GPU_CACHED_TEXTURE_CLASS, NULL);
|
||||
self->texture = texture;
|
||||
self->image = g_object_ref (image);
|
||||
((GskGpuCached *)self)->pixels = gsk_gpu_image_get_width (image) * gsk_gpu_image_get_height (image);
|
||||
self->dead_pixels_counter = &priv->dead_texture_pixels;
|
||||
self->use_count = 2;
|
||||
|
||||
if (!gdk_texture_set_render_data (texture, device, self, gsk_gpu_cached_texture_destroy_cb))
|
||||
{
|
||||
g_object_weak_ref (G_OBJECT (texture), (GWeakNotify) gsk_gpu_cached_texture_destroy_cb, self);
|
||||
|
||||
g_hash_table_insert (priv->texture_cache, texture, self);
|
||||
}
|
||||
|
||||
@@ -374,11 +274,8 @@ static void
|
||||
gsk_gpu_cached_glyph_free (GskGpuDevice *device,
|
||||
GskGpuCached *cached)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (device);
|
||||
GskGpuCachedGlyph *self = (GskGpuCachedGlyph *) cached;
|
||||
|
||||
g_hash_table_remove (priv->glyph_cache, self);
|
||||
|
||||
g_object_unref (self->font);
|
||||
g_object_unref (self->image);
|
||||
|
||||
@@ -390,15 +287,7 @@ gsk_gpu_cached_glyph_should_collect (GskGpuDevice *device,
|
||||
GskGpuCached *cached,
|
||||
gint64 timestamp)
|
||||
{
|
||||
if (gsk_gpu_cached_is_old (device, cached, timestamp))
|
||||
{
|
||||
if (cached->atlas)
|
||||
mark_as_stale (cached, TRUE);
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Glyphs are only collected when their atlas is freed */
|
||||
/* FIXME */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -436,127 +325,19 @@ static const GskGpuCachedClass GSK_GPU_CACHED_GLYPH_CLASS =
|
||||
/* }}} */
|
||||
/* {{{ GskGpuDevice */
|
||||
|
||||
static void
|
||||
print_cache_stats (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
GskGpuCached *cached;
|
||||
guint glyphs = 0;
|
||||
guint stale_glyphs = 0;
|
||||
guint textures = 0;
|
||||
guint atlases = 0;
|
||||
GString *ratios = g_string_new ("");
|
||||
|
||||
for (cached = priv->first_cached; cached != NULL; cached = cached->next)
|
||||
{
|
||||
if (cached->class == &GSK_GPU_CACHED_GLYPH_CLASS)
|
||||
{
|
||||
glyphs++;
|
||||
if (cached->stale)
|
||||
stale_glyphs++;
|
||||
}
|
||||
else if (cached->class == &GSK_GPU_CACHED_TEXTURE_CLASS)
|
||||
{
|
||||
textures++;
|
||||
}
|
||||
else if (cached->class == &GSK_GPU_CACHED_ATLAS_CLASS)
|
||||
{
|
||||
double ratio;
|
||||
|
||||
atlases++;
|
||||
|
||||
ratio = (double) cached->pixels / (double) (ATLAS_SIZE * ATLAS_SIZE);
|
||||
|
||||
if (ratios->len == 0)
|
||||
g_string_append (ratios, " (ratios ");
|
||||
else
|
||||
g_string_append (ratios, ", ");
|
||||
g_string_append_printf (ratios, "%.2f", ratio);
|
||||
}
|
||||
}
|
||||
|
||||
if (ratios->len > 0)
|
||||
g_string_append (ratios, ")");
|
||||
|
||||
gdk_debug_message ("Cached items\n"
|
||||
" glyphs: %5u (%u stale)\n"
|
||||
" textures: %5u (%u in hash)\n"
|
||||
" atlases: %5u%s",
|
||||
glyphs, stale_glyphs,
|
||||
textures, g_hash_table_size (priv->texture_cache),
|
||||
atlases, ratios->str);
|
||||
|
||||
g_string_free (ratios, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
gsk_gpu_device_gc (GskGpuDevice *self,
|
||||
gint64 timestamp)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
GskGpuCached *cached, *prev;
|
||||
gint64 before G_GNUC_UNUSED = GDK_PROFILER_CURRENT_TIME;
|
||||
GskGpuCached *cached, *next;
|
||||
|
||||
gsk_gpu_device_make_current (self);
|
||||
|
||||
/* We walk the cache from the end so we don't end up with prev
|
||||
* being a leftover glyph on the atlas we are freeing
|
||||
*/
|
||||
for (cached = priv->last_cached; cached != NULL; cached = prev)
|
||||
for (cached = priv->first_cached; cached != NULL; cached = next)
|
||||
{
|
||||
prev = cached->prev;
|
||||
next = cached->next;
|
||||
if (gsk_gpu_cached_should_collect (self, cached, timestamp))
|
||||
gsk_gpu_cached_free (self, cached);
|
||||
}
|
||||
|
||||
g_atomic_pointer_set (&priv->dead_texture_pixels, 0);
|
||||
|
||||
if (GSK_DEBUG_CHECK (GLYPH_CACHE))
|
||||
print_cache_stats (self);
|
||||
|
||||
gdk_profiler_end_mark (before, "Glyph cache GC", NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cache_gc_cb (gpointer data)
|
||||
{
|
||||
GskGpuDevice *self = data;
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
GSK_DEBUG (GLYPH_CACHE, "Periodic GC");
|
||||
|
||||
gsk_gpu_device_gc (self, g_get_monotonic_time ());
|
||||
|
||||
priv->cache_gc_source = 0;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gpu_device_maybe_gc (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
gsize dead_texture_pixels;
|
||||
|
||||
if (priv->cache_timeout < 0)
|
||||
return;
|
||||
|
||||
dead_texture_pixels = GPOINTER_TO_SIZE (g_atomic_pointer_get (&priv->dead_texture_pixels));
|
||||
|
||||
if (priv->cache_timeout == 0 || dead_texture_pixels > 1000000)
|
||||
{
|
||||
GSK_DEBUG (GLYPH_CACHE, "Pre-frame GC (%lu dead pixels)", dead_texture_pixels);
|
||||
gsk_gpu_device_gc (self, g_get_monotonic_time ());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gpu_device_queue_gc (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
if (priv->cache_timeout > 0 && !priv->cache_gc_source)
|
||||
priv->cache_gc_source = g_timeout_add_seconds (priv->cache_timeout, cache_gc_cb, self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -576,9 +357,8 @@ gsk_gpu_device_clear_cache (GskGpuDevice *self)
|
||||
g_assert (cached->next->prev == cached);
|
||||
}
|
||||
|
||||
/* We clear the cache from the end so glyphs get freed before their atlas */
|
||||
while (priv->last_cached)
|
||||
gsk_gpu_cached_free (self, priv->last_cached);
|
||||
while (priv->first_cached)
|
||||
gsk_gpu_cached_free (self, priv->first_cached);
|
||||
|
||||
g_assert (priv->last_cached == NULL);
|
||||
}
|
||||
@@ -592,7 +372,6 @@ gsk_gpu_device_dispose (GObject *object)
|
||||
gsk_gpu_device_clear_cache (self);
|
||||
g_hash_table_unref (priv->glyph_cache);
|
||||
g_hash_table_unref (priv->texture_cache);
|
||||
g_clear_handle_id (&priv->cache_gc_source, g_source_remove);
|
||||
|
||||
G_OBJECT_CLASS (gsk_gpu_device_parent_class)->dispose (object);
|
||||
}
|
||||
@@ -634,38 +413,9 @@ gsk_gpu_device_setup (GskGpuDevice *self,
|
||||
gsize max_image_size)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
const char *str;
|
||||
|
||||
priv->display = g_object_ref (display);
|
||||
priv->max_image_size = max_image_size;
|
||||
priv->cache_timeout = CACHE_TIMEOUT;
|
||||
|
||||
str = g_getenv ("GSK_CACHE_TIMEOUT");
|
||||
if (str != NULL)
|
||||
{
|
||||
gint64 value;
|
||||
GError *error = NULL;
|
||||
|
||||
if (!g_ascii_string_to_signed (str, 10, -1, G_MAXINT, &value, &error))
|
||||
{
|
||||
g_warning ("Failed to parse GSK_CACHE_TIMEOUT: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->cache_timeout = (int) value;
|
||||
}
|
||||
}
|
||||
|
||||
if (GSK_DEBUG_CHECK (GLYPH_CACHE))
|
||||
{
|
||||
if (priv->cache_timeout < 0)
|
||||
gdk_debug_message ("Cache GC disabled");
|
||||
else if (priv->cache_timeout == 0)
|
||||
gdk_debug_message ("Cache GC before every frame");
|
||||
else
|
||||
gdk_debug_message ("Cache GC timeout: %d seconds", priv->cache_timeout);
|
||||
}
|
||||
}
|
||||
|
||||
GdkDisplay *
|
||||
@@ -704,12 +454,6 @@ gsk_gpu_device_create_upload_image (GskGpuDevice *self,
|
||||
return GSK_GPU_DEVICE_GET_CLASS (self)->create_upload_image (self, with_mipmap, format, width, height);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gpu_device_make_current (GskGpuDevice *self)
|
||||
{
|
||||
GSK_GPU_DEVICE_GET_CLASS (self)->make_current (self);
|
||||
}
|
||||
|
||||
GskGpuImage *
|
||||
gsk_gpu_device_create_download_image (GskGpuDevice *self,
|
||||
GdkMemoryDepth depth,
|
||||
@@ -803,7 +547,8 @@ gsk_gpu_cached_atlas_allocate (GskGpuCachedAtlas *atlas,
|
||||
|
||||
static void
|
||||
gsk_gpu_device_ensure_atlas (GskGpuDevice *self,
|
||||
gboolean recreate)
|
||||
gboolean recreate,
|
||||
gint64 timestamp)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
@@ -818,13 +563,14 @@ gsk_gpu_device_get_atlas_image (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
gsk_gpu_device_ensure_atlas (self, FALSE);
|
||||
gsk_gpu_device_ensure_atlas (self, FALSE, g_get_monotonic_time ());
|
||||
|
||||
return priv->current_atlas->image;
|
||||
}
|
||||
|
||||
static GskGpuImage *
|
||||
gsk_gpu_device_add_atlas_image (GskGpuDevice *self,
|
||||
gint64 timestamp,
|
||||
gsize width,
|
||||
gsize height,
|
||||
gsize *out_x,
|
||||
@@ -835,15 +581,21 @@ gsk_gpu_device_add_atlas_image (GskGpuDevice *self,
|
||||
if (width > MAX_ATLAS_ITEM_SIZE || height > MAX_ATLAS_ITEM_SIZE)
|
||||
return NULL;
|
||||
|
||||
gsk_gpu_device_ensure_atlas (self, FALSE);
|
||||
gsk_gpu_device_ensure_atlas (self, FALSE, timestamp);
|
||||
|
||||
if (gsk_gpu_cached_atlas_allocate (priv->current_atlas, width, height, out_x, out_y))
|
||||
{
|
||||
gsk_gpu_cached_use (self, (GskGpuCached *) priv->current_atlas, timestamp);
|
||||
return priv->current_atlas->image;
|
||||
}
|
||||
|
||||
gsk_gpu_device_ensure_atlas (self, TRUE, timestamp);
|
||||
|
||||
if (gsk_gpu_cached_atlas_allocate (priv->current_atlas, width, height, out_x, out_y))
|
||||
return priv->current_atlas->image;
|
||||
|
||||
gsk_gpu_device_ensure_atlas (self, TRUE);
|
||||
|
||||
if (gsk_gpu_cached_atlas_allocate (priv->current_atlas, width, height, out_x, out_y))
|
||||
return priv->current_atlas->image;
|
||||
{
|
||||
gsk_gpu_cached_use (self, (GskGpuCached *) priv->current_atlas, timestamp);
|
||||
return priv->current_atlas->image;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -860,12 +612,12 @@ gsk_gpu_device_lookup_texture_image (GskGpuDevice *self,
|
||||
if (cache == NULL)
|
||||
cache = g_hash_table_lookup (priv->texture_cache, texture);
|
||||
|
||||
if (!cache || !cache->image || gsk_gpu_cached_texture_is_invalid (cache))
|
||||
return NULL;
|
||||
if (cache)
|
||||
{
|
||||
return g_object_ref (cache->image);
|
||||
}
|
||||
|
||||
gsk_gpu_cached_use (self, (GskGpuCached *) cache, timestamp);
|
||||
|
||||
return g_object_ref (cache->image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -926,6 +678,7 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
|
||||
padding = 1;
|
||||
|
||||
image = gsk_gpu_device_add_atlas_image (self,
|
||||
gsk_gpu_frame_get_timestamp (frame),
|
||||
rect.size.width + 2 * padding, rect.size.height + 2 * padding,
|
||||
&atlas_x, &atlas_y);
|
||||
if (image)
|
||||
@@ -944,15 +697,14 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
|
||||
cache = gsk_gpu_cached_new (self, &GSK_GPU_CACHED_GLYPH_CLASS, NULL);
|
||||
}
|
||||
|
||||
cache->font = g_object_ref (font);
|
||||
cache->glyph = glyph;
|
||||
cache->flags = flags;
|
||||
cache->scale = scale;
|
||||
cache->bounds = rect;
|
||||
cache->image = image;
|
||||
cache->font = g_object_ref (font),
|
||||
cache->glyph = glyph,
|
||||
cache->flags = flags,
|
||||
cache->scale = scale,
|
||||
cache->bounds = rect,
|
||||
cache->image = image,
|
||||
cache->origin = GRAPHENE_POINT_INIT (- origin.x + subpixel_x,
|
||||
- origin.y + subpixel_y);
|
||||
((GskGpuCached *) cache)->pixels = (rect.size.width + 2 * padding) * (rect.size.height + 2 * padding);
|
||||
|
||||
gsk_gpu_upload_glyph_op (frame,
|
||||
cache->image,
|
||||
|
||||
@@ -41,8 +41,6 @@ struct _GskGpuDeviceClass
|
||||
GdkMemoryDepth depth,
|
||||
gsize width,
|
||||
gsize height);
|
||||
void (* make_current) (GskGpuDevice *self);
|
||||
|
||||
};
|
||||
|
||||
GType gsk_gpu_device_get_type (void) G_GNUC_CONST;
|
||||
@@ -50,8 +48,9 @@ GType gsk_gpu_device_get_type (void) G
|
||||
void gsk_gpu_device_setup (GskGpuDevice *self,
|
||||
GdkDisplay *display,
|
||||
gsize max_image_size);
|
||||
void gsk_gpu_device_maybe_gc (GskGpuDevice *self);
|
||||
void gsk_gpu_device_queue_gc (GskGpuDevice *self);
|
||||
void gsk_gpu_device_gc (GskGpuDevice *self,
|
||||
gint64 timestamp);
|
||||
|
||||
GdkDisplay * gsk_gpu_device_get_display (GskGpuDevice *self);
|
||||
gsize gsk_gpu_device_get_max_image_size (GskGpuDevice *self);
|
||||
GskGpuImage * gsk_gpu_device_get_atlas_image (GskGpuDevice *self);
|
||||
@@ -70,7 +69,7 @@ GskGpuImage * gsk_gpu_device_create_download_image (GskGpuD
|
||||
GdkMemoryDepth depth,
|
||||
gsize width,
|
||||
gsize height);
|
||||
void gsk_gpu_device_make_current (GskGpuDevice *self);
|
||||
|
||||
GskGpuImage * gsk_gpu_device_lookup_texture_image (GskGpuDevice *self,
|
||||
GdkTexture *texture,
|
||||
gint64 timestamp);
|
||||
|
||||
@@ -220,7 +220,7 @@ gsk_gpu_frame_seal_ops (GskGpuFrame *self)
|
||||
{
|
||||
GskGpuFramePrivate *priv = gsk_gpu_frame_get_instance_private (self);
|
||||
GskGpuOp *last, *op;
|
||||
gsize i;
|
||||
guint i;
|
||||
|
||||
priv->first_op = (GskGpuOp *) gsk_gpu_ops_index (&priv->ops, 0);
|
||||
|
||||
|
||||
@@ -129,8 +129,8 @@ gsk_gpu_mipmap_op_vk_command (GskGpuOp *op,
|
||||
.z = 0,
|
||||
},
|
||||
{
|
||||
.x = MAX (1, width / 2),
|
||||
.y = MAX (1, height / 2),
|
||||
.x = width / 2,
|
||||
.y = height / 2,
|
||||
.z = 1,
|
||||
}
|
||||
},
|
||||
|
||||
+91
-116
@@ -43,6 +43,10 @@
|
||||
|
||||
#include "gdk/gdkrgbaprivate.h"
|
||||
|
||||
#include "scaleprivate.h"
|
||||
#include "pointprivate.h"
|
||||
#include "boxprivate.h"
|
||||
|
||||
/* A note about coordinate systems
|
||||
*
|
||||
* The rendering code keeps track of multiple coordinate systems to optimize rendering as
|
||||
@@ -353,10 +357,7 @@ gsk_gpu_node_processor_init_draw (GskGpuNodeProcessor *self,
|
||||
NULL,
|
||||
image,
|
||||
&area,
|
||||
&GRAPHENE_RECT_INIT (viewport->origin.x,
|
||||
viewport->origin.y,
|
||||
area.width / graphene_vec2_get_x (scale),
|
||||
area.height / graphene_vec2_get_y (scale)));
|
||||
viewport);
|
||||
|
||||
gsk_gpu_render_pass_begin_op (frame,
|
||||
image,
|
||||
@@ -501,6 +502,18 @@ gsk_gpu_pattern_writer_append_rect (GskGpuPatternWriter *self,
|
||||
gsk_gpu_pattern_writer_append (self, G_ALIGNOF (float), (guchar *) f, sizeof (f));
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_pattern_writer_append_box (GskGpuPatternWriter *self,
|
||||
const Box box,
|
||||
const Point offset)
|
||||
{
|
||||
float f[4];
|
||||
|
||||
box_offset_to_float (box, offset, f);
|
||||
|
||||
gsk_gpu_pattern_writer_append (self, G_ALIGNOF (float), (guchar *) f, sizeof (f));
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_pattern_writer_append_rgba (GskGpuPatternWriter *self,
|
||||
const GdkRGBA *rgba)
|
||||
@@ -1010,10 +1023,7 @@ gsk_gpu_node_processor_blur_op (GskGpuNodeProcessor *self,
|
||||
source_desc,
|
||||
intermediate,
|
||||
&(cairo_rectangle_int_t) { 0, 0, width, height },
|
||||
&GRAPHENE_RECT_INIT (intermediate_rect.origin.x,
|
||||
intermediate_rect.origin.y,
|
||||
width / graphene_vec2_get_x (&self->scale),
|
||||
height / graphene_vec2_get_y (&self->scale)));
|
||||
&intermediate_rect);
|
||||
|
||||
gsk_gpu_render_pass_begin_op (other.frame,
|
||||
intermediate,
|
||||
@@ -1324,8 +1334,7 @@ gsk_gpu_node_processor_add_node_clipped (GskGpuNodeProcessor *self,
|
||||
gsk_gpu_clip_init_copy (&self->clip, &old_clip);
|
||||
return;
|
||||
}
|
||||
else if (self->clip.type == GSK_GPU_CLIP_RECT &&
|
||||
gsk_rect_contains_rect (&self->clip.rect.bounds, &clip))
|
||||
else if (self->clip.type == GSK_GPU_CLIP_RECT)
|
||||
{
|
||||
self->clip.type = GSK_GPU_CLIP_NONE;
|
||||
}
|
||||
@@ -2981,9 +2990,9 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
|
||||
GskGpuDevice *device;
|
||||
const PangoGlyphInfo *glyphs;
|
||||
PangoFont *font;
|
||||
graphene_point_t offset;
|
||||
Point offset;
|
||||
Scale scale, s4, pango_scale;
|
||||
guint i, num_glyphs;
|
||||
float scale, inv_scale;
|
||||
GdkRGBA color;
|
||||
gboolean glyph_align;
|
||||
|
||||
@@ -3002,31 +3011,33 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
|
||||
num_glyphs = gsk_text_node_get_num_glyphs (node);
|
||||
glyphs = gsk_text_node_get_glyphs (node, NULL);
|
||||
font = gsk_text_node_get_font (node);
|
||||
offset = *gsk_text_node_get_offset (node);
|
||||
offset.x += self->offset.x;
|
||||
offset.y += self->offset.y;
|
||||
|
||||
scale = MAX (graphene_vec2_get_x (&self->scale), graphene_vec2_get_y (&self->scale));
|
||||
inv_scale = 1.f / scale;
|
||||
offset = point_add (point_from_graphene (gsk_text_node_get_offset (node)),
|
||||
point_from_graphene (&self->offset));
|
||||
scale = scale_max (scale_from_graphene (&self->scale));
|
||||
s4 = scale_mul (scale, scale_from_float (4));
|
||||
pango_scale = scale_from_float (PANGO_SCALE);
|
||||
|
||||
for (i = 0; i < num_glyphs; i++)
|
||||
{
|
||||
GskGpuImage *image;
|
||||
graphene_rect_t glyph_bounds, glyph_tex_rect;
|
||||
graphene_point_t glyph_offset, glyph_origin;
|
||||
graphene_rect_t glyph_bds;
|
||||
graphene_point_t glyph_ofs;
|
||||
Box glyph_bounds, glyph_tex_rect;
|
||||
Point g_ofs, glyph_origin;
|
||||
guint32 descriptor;
|
||||
GskGpuGlyphLookupFlags flags;
|
||||
|
||||
glyph_origin = GRAPHENE_POINT_INIT (offset.x + (float) glyphs[i].geometry.x_offset / PANGO_SCALE,
|
||||
offset.y + (float) glyphs[i].geometry.y_offset / PANGO_SCALE);
|
||||
glyph_origin = point_add (offset, point_div (point (glyphs[i].geometry.x_offset, glyphs[i].geometry.y_offset), pango_scale));
|
||||
|
||||
if (glyph_align)
|
||||
{
|
||||
glyph_origin.x = roundf (glyph_origin.x * scale * 4);
|
||||
glyph_origin.y = roundf (glyph_origin.y * scale * 4);
|
||||
flags = ((int) glyph_origin.x & 3) |
|
||||
(((int) glyph_origin.y & 3) << 2);
|
||||
glyph_origin.x = 0.25 * inv_scale * glyph_origin.x;
|
||||
glyph_origin.y = 0.25 * inv_scale * glyph_origin.y;
|
||||
glyph_origin = point_round (point_mul (glyph_origin, s4));
|
||||
|
||||
flags = ((int) point_x (glyph_origin) & 3) |
|
||||
(((int) point_y (glyph_origin) & 3) << 2);
|
||||
|
||||
glyph_origin = point_div (glyph_origin, s4);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3038,34 +3049,37 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
|
||||
font,
|
||||
glyphs[i].glyph,
|
||||
flags,
|
||||
scale,
|
||||
&glyph_bounds,
|
||||
&glyph_offset);
|
||||
scale_x (scale),
|
||||
&glyph_bds,
|
||||
&glyph_ofs);
|
||||
|
||||
glyph_tex_rect = box_div (box_from_rect (-glyph_bds.origin.x, -glyph_bds.origin.y, gsk_gpu_image_get_width (image), gsk_gpu_image_get_height (image)), scale);
|
||||
|
||||
glyph_bounds = box_div (box_from_rect (0, 0, glyph_bds.size.width, glyph_bds.size.height), scale);
|
||||
|
||||
g_ofs = point_from_graphene (&glyph_ofs);
|
||||
glyph_origin = point_sub (glyph_origin, point_div (g_ofs, scale));
|
||||
|
||||
gsk_rect_scale (&GRAPHENE_RECT_INIT (-glyph_bounds.origin.x, -glyph_bounds.origin.y, gsk_gpu_image_get_width (image), gsk_gpu_image_get_height (image)), inv_scale, inv_scale, &glyph_tex_rect);
|
||||
gsk_rect_scale (&GRAPHENE_RECT_INIT(0, 0, glyph_bounds.size.width, glyph_bounds.size.height), inv_scale, inv_scale, &glyph_bounds);
|
||||
glyph_origin = GRAPHENE_POINT_INIT (glyph_origin.x - glyph_offset.x * inv_scale,
|
||||
glyph_origin.y - glyph_offset.y * inv_scale);
|
||||
descriptor = gsk_gpu_node_processor_add_image (self, image, GSK_GPU_SAMPLER_DEFAULT);
|
||||
if (glyphs[i].attr.is_color)
|
||||
gsk_gpu_texture_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &glyph_offset, &glyph_bounds),
|
||||
gsk_gpu_clip_get_shader_clip2 (&self->clip, &g_ofs, &glyph_bounds),
|
||||
self->desc,
|
||||
descriptor,
|
||||
&glyph_bounds,
|
||||
&glyph_origin,
|
||||
&glyph_tex_rect);
|
||||
&GRAPHENE_RECT_INIT (box_x0 (glyph_bounds), box_y0 (glyph_bounds), box_width (glyph_bounds), box_height (glyph_bounds)),
|
||||
&GRAPHENE_POINT_INIT (point_x (glyph_origin), point_y (glyph_origin)),
|
||||
&GRAPHENE_RECT_INIT (box_x0 (glyph_tex_rect), box_y0 (glyph_tex_rect), box_width (glyph_tex_rect), box_height (glyph_tex_rect)));
|
||||
else
|
||||
gsk_gpu_colorize_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &glyph_offset, &glyph_bounds),
|
||||
gsk_gpu_clip_get_shader_clip2 (&self->clip, &g_ofs, &glyph_bounds),
|
||||
self->desc,
|
||||
descriptor,
|
||||
&glyph_bounds,
|
||||
&glyph_origin,
|
||||
&glyph_tex_rect,
|
||||
&GRAPHENE_RECT_INIT (box_x0 (glyph_bounds), box_y0 (glyph_bounds), box_width (glyph_bounds), box_height (glyph_bounds)),
|
||||
&GRAPHENE_POINT_INIT (point_x (glyph_origin), point_y (glyph_origin)),
|
||||
&GRAPHENE_RECT_INIT (box_x0 (glyph_tex_rect), box_y0 (glyph_tex_rect), box_width (glyph_tex_rect), box_height (glyph_tex_rect)),
|
||||
&color);
|
||||
|
||||
offset.x += (float) glyphs[i].geometry.width / PANGO_SCALE;
|
||||
offset = point_add (offset, point (glyphs[i].geometry.width / (float)PANGO_SCALE, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3078,10 +3092,10 @@ gsk_gpu_node_processor_create_glyph_pattern (GskGpuPatternWriter *self,
|
||||
PangoFont *font;
|
||||
guint num_glyphs;
|
||||
gsize i;
|
||||
float scale, inv_scale;
|
||||
Scale scale, pango_scale;
|
||||
guint32 tex_id;
|
||||
GskGpuImage *last_image;
|
||||
graphene_point_t offset;
|
||||
Point offset;
|
||||
|
||||
if (gsk_text_node_has_color_glyphs (node))
|
||||
return FALSE;
|
||||
@@ -3090,12 +3104,11 @@ gsk_gpu_node_processor_create_glyph_pattern (GskGpuPatternWriter *self,
|
||||
num_glyphs = gsk_text_node_get_num_glyphs (node);
|
||||
glyphs = gsk_text_node_get_glyphs (node, NULL);
|
||||
font = gsk_text_node_get_font (node);
|
||||
offset = *gsk_text_node_get_offset (node);
|
||||
offset.x += self->offset.x;
|
||||
offset.y += self->offset.y;
|
||||
|
||||
scale = MAX (graphene_vec2_get_x (&self->scale), graphene_vec2_get_y (&self->scale));
|
||||
inv_scale = 1.f / scale;
|
||||
offset = point_add (point_from_graphene (gsk_text_node_get_offset (node)),
|
||||
point_from_graphene (&self->offset));
|
||||
scale = scale_max (scale_from_graphene (&self->scale));
|
||||
pango_scale = scale_from_float (PANGO_SCALE);
|
||||
|
||||
gsk_gpu_pattern_writer_append_uint (self, GSK_GPU_PATTERN_GLYPHS);
|
||||
gsk_gpu_pattern_writer_append_rgba (self, gsk_text_node_get_color (node));
|
||||
@@ -3105,17 +3118,20 @@ gsk_gpu_node_processor_create_glyph_pattern (GskGpuPatternWriter *self,
|
||||
for (i = 0; i < num_glyphs; i++)
|
||||
{
|
||||
GskGpuImage *image;
|
||||
graphene_rect_t glyph_bounds;
|
||||
graphene_point_t glyph_offset;
|
||||
graphene_rect_t glyph_bds;
|
||||
graphene_point_t glyph_ofs;
|
||||
Point glyph_offset;
|
||||
Box glyph_bounds;
|
||||
Box glyph_tex_rect;
|
||||
|
||||
image = gsk_gpu_device_lookup_glyph_image (device,
|
||||
self->frame,
|
||||
font,
|
||||
glyphs[i].glyph,
|
||||
0,
|
||||
scale,
|
||||
&glyph_bounds,
|
||||
&glyph_offset);
|
||||
scale_x (scale),
|
||||
&glyph_bds,
|
||||
&glyph_ofs);
|
||||
|
||||
if (image != last_image)
|
||||
{
|
||||
@@ -3125,28 +3141,15 @@ gsk_gpu_node_processor_create_glyph_pattern (GskGpuPatternWriter *self,
|
||||
last_image = image;
|
||||
}
|
||||
|
||||
glyph_offset = GRAPHENE_POINT_INIT (offset.x - glyph_offset.x * inv_scale + (float) glyphs[i].geometry.x_offset / PANGO_SCALE,
|
||||
offset.y - glyph_offset.y * inv_scale + (float) glyphs[i].geometry.y_offset / PANGO_SCALE);
|
||||
glyph_offset = point_add (point_sub (offset, point_div (glyph_offset, scale)), point_div (point (glyphs[i].geometry.x_offset, glyphs[i].geometry.y_offset), pango_scale));
|
||||
|
||||
glyph_bounds = box_div (box_from_rect (0, 0, glyph_bds.size.width, glyph_bds.size.height), scale);
|
||||
glyph_tex_rect = box_div (box_from_rect (-glyph_bds.origin.x, - glyph_bds.origin.y, gsk_gpu_image_get_width (image), gsk_gpu_image_get_height (image)), scale);
|
||||
gsk_gpu_pattern_writer_append_uint (self, tex_id);
|
||||
gsk_gpu_pattern_writer_append_rect (self,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
0,
|
||||
0,
|
||||
glyph_bounds.size.width * inv_scale,
|
||||
glyph_bounds.size.height * inv_scale
|
||||
),
|
||||
&glyph_offset);
|
||||
gsk_gpu_pattern_writer_append_rect (self,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
- glyph_bounds.origin.x * inv_scale,
|
||||
- glyph_bounds.origin.y * inv_scale,
|
||||
gsk_gpu_image_get_width (image) * inv_scale,
|
||||
gsk_gpu_image_get_height (image) * inv_scale
|
||||
),
|
||||
&glyph_offset);
|
||||
gsk_gpu_pattern_writer_append_box (self, glyph_bounds, glyph_offset);
|
||||
gsk_gpu_pattern_writer_append_box (self, glyph_tex_rect, glyph_offset);
|
||||
|
||||
offset.x += (float) glyphs[i].geometry.width / PANGO_SCALE;
|
||||
offset = point_add (offset, point (glyphs[i].geometry.width / (float)PANGO_SCALE, 0));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -3680,42 +3683,22 @@ gsk_gpu_node_processor_add_subsurface_node (GskGpuNodeProcessor *self,
|
||||
|
||||
if (!gdk_subsurface_is_above_parent (subsurface))
|
||||
{
|
||||
cairo_rectangle_int_t int_clipped;
|
||||
graphene_rect_t rect, clipped;
|
||||
cairo_rectangle_int_t int_rect;
|
||||
|
||||
graphene_rect_offset_r (&node->bounds,
|
||||
self->offset.x, self->offset.y,
|
||||
&rect);
|
||||
gsk_rect_intersection (&self->clip.rect.bounds, &rect, &clipped);
|
||||
|
||||
if (gsk_gpu_frame_should_optimize (self->frame, GSK_GPU_OPTIMIZE_CLEAR) &&
|
||||
node->bounds.size.width * node->bounds.size.height > 100 * 100 && /* not worth the effort for small images */
|
||||
(self->clip.type != GSK_GPU_CLIP_ROUNDED ||
|
||||
gsk_gpu_clip_contains_rect (&self->clip, &GRAPHENE_POINT_INIT(0,0), &clipped)) &&
|
||||
gsk_gpu_node_processor_rect_is_integer (self, &clipped, &int_clipped))
|
||||
if (!gsk_gpu_node_processor_rect_is_integer (self,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
node->bounds.origin.x + self->offset.x,
|
||||
node->bounds.origin.y + self->offset.y,
|
||||
node->bounds.size.width,
|
||||
node->bounds.size.height
|
||||
),
|
||||
&int_rect))
|
||||
{
|
||||
if (gdk_rectangle_intersect (&int_clipped, &self->scissor, &int_clipped))
|
||||
{
|
||||
gsk_gpu_clear_op (self->frame,
|
||||
&int_clipped,
|
||||
&GDK_RGBA_TRANSPARENT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self->blend = GSK_GPU_BLEND_CLEAR;
|
||||
self->pending_globals |= GSK_GPU_GLOBAL_BLEND;
|
||||
gsk_gpu_node_processor_sync_globals (self, 0);
|
||||
|
||||
gsk_gpu_color_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
|
||||
&node->bounds,
|
||||
&self->offset,
|
||||
&GDK_RGBA_WHITE);
|
||||
|
||||
self->blend = GSK_GPU_BLEND_OVER;
|
||||
self->pending_globals |= GSK_GPU_GLOBAL_BLEND;
|
||||
g_warning ("FIXME: non-integer aligned subsurface?!");
|
||||
}
|
||||
gsk_gpu_clear_op (self->frame,
|
||||
&int_rect,
|
||||
&GDK_RGBA_TRANSPARENT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3960,11 +3943,9 @@ gsk_gpu_node_processor_add_node (GskGpuNodeProcessor *self,
|
||||
GskRenderNodeType node_type;
|
||||
|
||||
/* This catches the corner cases of empty nodes, so after this check
|
||||
* there's quaranteed to be at least 1 pixel that needs to be drawn
|
||||
*/
|
||||
* there's quaranteed to be at least 1 pixel that needs to be drawn */
|
||||
if (node->bounds.size.width == 0 || node->bounds.size.height == 0)
|
||||
return;
|
||||
|
||||
if (!gsk_gpu_clip_may_intersect_rect (&self->clip, &self->offset, &node->bounds))
|
||||
return;
|
||||
|
||||
@@ -4009,12 +3990,6 @@ gsk_gpu_node_processor_create_node_pattern (GskGpuPatternWriter *self,
|
||||
if (!gsk_gpu_frame_should_optimize (self->frame, GSK_GPU_OPTIMIZE_UBER))
|
||||
return FALSE;
|
||||
|
||||
/* This catches the corner cases of empty nodes, so after this check
|
||||
* there's quaranteed to be at least 1 pixel that needs to be drawn
|
||||
*/
|
||||
if (node->bounds.size.width == 0 || node->bounds.size.height == 0)
|
||||
return TRUE;
|
||||
|
||||
node_type = gsk_render_node_get_node_type (node);
|
||||
if (node_type >= G_N_ELEMENTS (nodes_vtable))
|
||||
{
|
||||
|
||||
@@ -119,7 +119,7 @@ gsk_gpu_renderer_dmabuf_downloader_download (GdkDmabufDownloader *downloader,
|
||||
frame = gsk_gpu_renderer_create_frame (self);
|
||||
|
||||
gsk_gpu_frame_download_texture (frame,
|
||||
g_get_monotonic_time (),
|
||||
g_get_monotonic_time(),
|
||||
GDK_TEXTURE (texture),
|
||||
format,
|
||||
data,
|
||||
@@ -301,7 +301,7 @@ gsk_gpu_renderer_fallback_render_texture (GskGpuRenderer *self,
|
||||
|
||||
frame = gsk_gpu_renderer_create_frame (self);
|
||||
gsk_gpu_frame_render (frame,
|
||||
g_get_monotonic_time (),
|
||||
g_get_monotonic_time(),
|
||||
image,
|
||||
NULL,
|
||||
root,
|
||||
@@ -343,8 +343,6 @@ gsk_gpu_renderer_render_texture (GskRenderer *renderer,
|
||||
GdkTexture *texture;
|
||||
graphene_rect_t rounded_viewport;
|
||||
|
||||
gsk_gpu_device_maybe_gc (priv->device);
|
||||
|
||||
gsk_gpu_renderer_make_current (self);
|
||||
|
||||
rounded_viewport = GRAPHENE_RECT_INIT (viewport->origin.x,
|
||||
@@ -355,7 +353,6 @@ gsk_gpu_renderer_render_texture (GskRenderer *renderer,
|
||||
gsk_render_node_get_preferred_depth (root),
|
||||
rounded_viewport.size.width,
|
||||
rounded_viewport.size.height);
|
||||
|
||||
if (image == NULL)
|
||||
return gsk_gpu_renderer_fallback_render_texture (self, root, &rounded_viewport);
|
||||
|
||||
@@ -363,7 +360,7 @@ gsk_gpu_renderer_render_texture (GskRenderer *renderer,
|
||||
|
||||
texture = NULL;
|
||||
gsk_gpu_frame_render (frame,
|
||||
g_get_monotonic_time (),
|
||||
g_get_monotonic_time(),
|
||||
image,
|
||||
NULL,
|
||||
root,
|
||||
@@ -373,8 +370,6 @@ gsk_gpu_renderer_render_texture (GskRenderer *renderer,
|
||||
g_object_unref (frame);
|
||||
g_object_unref (image);
|
||||
|
||||
gsk_gpu_device_queue_gc (priv->device);
|
||||
|
||||
/* check that callback setting texture was actually called, as its technically async */
|
||||
g_assert (texture);
|
||||
|
||||
@@ -391,7 +386,7 @@ gsk_gpu_renderer_render (GskRenderer *renderer,
|
||||
GskGpuFrame *frame;
|
||||
GskGpuImage *backbuffer;
|
||||
cairo_region_t *render_region;
|
||||
double scale;
|
||||
GdkSurface *surface;
|
||||
|
||||
if (cairo_region_is_empty (region))
|
||||
{
|
||||
@@ -403,30 +398,26 @@ gsk_gpu_renderer_render (GskRenderer *renderer,
|
||||
gsk_render_node_get_preferred_depth (root),
|
||||
region);
|
||||
|
||||
gsk_gpu_device_maybe_gc (priv->device);
|
||||
|
||||
gsk_gpu_renderer_make_current (self);
|
||||
|
||||
backbuffer = GSK_GPU_RENDERER_GET_CLASS (self)->get_backbuffer (self);
|
||||
|
||||
frame = gsk_gpu_renderer_get_frame (self);
|
||||
render_region = get_render_region (self);
|
||||
scale = gsk_gpu_renderer_get_scale (self);
|
||||
surface = gdk_draw_context_get_surface (priv->context);
|
||||
|
||||
gsk_gpu_frame_render (frame,
|
||||
g_get_monotonic_time (),
|
||||
g_get_monotonic_time(),
|
||||
backbuffer,
|
||||
render_region,
|
||||
root,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
0, 0,
|
||||
gsk_gpu_image_get_width (backbuffer) / scale,
|
||||
gsk_gpu_image_get_height (backbuffer) / scale
|
||||
gdk_surface_get_width (surface),
|
||||
gdk_surface_get_height (surface)
|
||||
),
|
||||
NULL);
|
||||
|
||||
gsk_gpu_device_queue_gc (priv->device);
|
||||
|
||||
gdk_draw_context_end_frame (priv->context);
|
||||
|
||||
g_clear_pointer (&render_region, cairo_region_destroy);
|
||||
|
||||
@@ -360,10 +360,7 @@ gsk_gpu_render_pass_op_offscreen (GskGpuFrame *frame,
|
||||
image,
|
||||
&(cairo_rectangle_int_t) { 0, 0, width, height },
|
||||
node,
|
||||
&GRAPHENE_RECT_INIT (viewport->origin.x,
|
||||
viewport->origin.y,
|
||||
width / graphene_vec2_get_x (scale),
|
||||
height / graphene_vec2_get_y (scale)));
|
||||
viewport);
|
||||
|
||||
gsk_gpu_render_pass_end_op (frame,
|
||||
image,
|
||||
|
||||
@@ -49,8 +49,7 @@ typedef enum {
|
||||
|
||||
typedef enum {
|
||||
GSK_GPU_BLEND_OVER,
|
||||
GSK_GPU_BLEND_ADD,
|
||||
GSK_GPU_BLEND_CLEAR
|
||||
GSK_GPU_BLEND_ADD
|
||||
} GskGpuBlend;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -99,7 +99,6 @@ gsk_ngl_renderer_get_backbuffer (GskGpuRenderer *renderer)
|
||||
{
|
||||
gsk_ngl_renderer_free_backbuffer (self);
|
||||
self->backbuffer = gsk_gl_image_new_backbuffer (GSK_GL_DEVICE (gsk_gpu_renderer_get_device (renderer)),
|
||||
GDK_GL_CONTEXT (context),
|
||||
GDK_MEMORY_DEFAULT /* FIXME */,
|
||||
ceil (gdk_surface_get_width (surface) * scale),
|
||||
ceil (gdk_surface_get_height (surface) * scale));
|
||||
|
||||
@@ -425,11 +425,6 @@ gsk_vulkan_device_create_download_image (GskGpuDevice *device,
|
||||
return image;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_vulkan_device_make_current (GskGpuDevice *device)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_vulkan_device_finalize (GObject *object)
|
||||
{
|
||||
@@ -498,7 +493,6 @@ gsk_vulkan_device_class_init (GskVulkanDeviceClass *klass)
|
||||
gpu_device_class->create_atlas_image = gsk_vulkan_device_create_atlas_image;
|
||||
gpu_device_class->create_upload_image = gsk_vulkan_device_create_upload_image;
|
||||
gpu_device_class->create_download_image = gsk_vulkan_device_create_download_image;
|
||||
gpu_device_class->make_current = gsk_vulkan_device_make_current;
|
||||
|
||||
object_class->finalize = gsk_vulkan_device_finalize;
|
||||
}
|
||||
@@ -892,7 +886,7 @@ struct _GskVulkanShaderSpecialization
|
||||
guint32 variation;
|
||||
};
|
||||
|
||||
static VkPipelineColorBlendAttachmentState blend_attachment_states[3] = {
|
||||
static VkPipelineColorBlendAttachmentState blend_attachment_states[2] = {
|
||||
[GSK_GPU_BLEND_OVER] = {
|
||||
.blendEnable = VK_TRUE,
|
||||
.colorBlendOp = VK_BLEND_OP_ADD,
|
||||
@@ -919,19 +913,6 @@ static VkPipelineColorBlendAttachmentState blend_attachment_states[3] = {
|
||||
| VK_COLOR_COMPONENT_G_BIT
|
||||
| VK_COLOR_COMPONENT_B_BIT
|
||||
},
|
||||
[GSK_GPU_BLEND_CLEAR] = {
|
||||
.blendEnable = VK_TRUE,
|
||||
.colorBlendOp = VK_BLEND_OP_ADD,
|
||||
.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO,
|
||||
.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
.alphaBlendOp = VK_BLEND_OP_ADD,
|
||||
.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
|
||||
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
.colorWriteMask = VK_COLOR_COMPONENT_A_BIT
|
||||
| VK_COLOR_COMPONENT_R_BIT
|
||||
| VK_COLOR_COMPONENT_G_BIT
|
||||
| VK_COLOR_COMPONENT_B_BIT
|
||||
},
|
||||
};
|
||||
|
||||
VkPipeline
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
precision highp float;
|
||||
|
||||
#if __VERSION__ < 420 || (defined(GSK_GLES) && __VERSION__ < 310)
|
||||
#if defined(GSK_GLES) && __VERSION__ < 310
|
||||
layout(std140)
|
||||
#else
|
||||
layout(std140, binding = 0)
|
||||
@@ -17,7 +17,7 @@ uniform PushConstants
|
||||
#define GSK_GLOBAL_CLIP_RECT push.clip[0]
|
||||
#define GSK_GLOBAL_SCALE push.scale
|
||||
|
||||
#if __VERSION__ < 420 || (defined(GSK_GLES) && __VERSION__ < 310)
|
||||
#if defined(GSK_GLES) && __VERSION__ < 310
|
||||
layout(std140)
|
||||
#else
|
||||
layout(std140, binding = 1)
|
||||
@@ -91,7 +91,7 @@ gsk_get_float (uint id)
|
||||
#define gsk_get_int(id) (floatBitsToInt(gsk_get_float(id)))
|
||||
#define gsk_get_uint(id) (floatBitsToUint(gsk_get_float(id)))
|
||||
|
||||
#if __VERSION__ < 400 || defined(GSK_GLES)
|
||||
#ifdef GSK_GLES
|
||||
|
||||
vec4
|
||||
gsk_texture (uint id,
|
||||
|
||||
@@ -18,68 +18,37 @@ vec4
|
||||
compute_color (void)
|
||||
{
|
||||
uint triangle_index = uint (GSK_VERTEX_INDEX) / 3u;
|
||||
uint index, fallback;
|
||||
uint index;
|
||||
|
||||
switch (triangle_index)
|
||||
{
|
||||
case 2u * SLICE_TOP_LEFT + 1u:
|
||||
index = TOP;
|
||||
fallback = LEFT;
|
||||
break;
|
||||
case 2u * SLICE_TOP:
|
||||
case 2u * SLICE_TOP + 1u:
|
||||
index = TOP;
|
||||
fallback = TOP;
|
||||
break;
|
||||
case 2u * SLICE_TOP_RIGHT:
|
||||
index = TOP;
|
||||
fallback = RIGHT;
|
||||
break;
|
||||
case 2u * SLICE_TOP_RIGHT + 1u:
|
||||
index = RIGHT;
|
||||
fallback = TOP;
|
||||
break;
|
||||
case 2u * SLICE_RIGHT:
|
||||
case 2u * SLICE_RIGHT + 1u:
|
||||
index = RIGHT;
|
||||
fallback = RIGHT;
|
||||
break;
|
||||
case 2u * SLICE_BOTTOM_RIGHT:
|
||||
index = RIGHT;
|
||||
fallback = BOTTOM;
|
||||
break;
|
||||
case 2u * SLICE_BOTTOM_RIGHT + 1u:
|
||||
index = BOTTOM;
|
||||
fallback = RIGHT;
|
||||
break;
|
||||
case 2u * SLICE_BOTTOM:
|
||||
case 2u * SLICE_BOTTOM + 1u:
|
||||
index = BOTTOM;
|
||||
fallback = BOTTOM;
|
||||
break;
|
||||
case 2u * SLICE_BOTTOM_LEFT:
|
||||
index = BOTTOM;
|
||||
fallback = LEFT;
|
||||
break;
|
||||
case 2u * SLICE_BOTTOM_LEFT + 1u:
|
||||
index = LEFT;
|
||||
fallback = BOTTOM;
|
||||
break;
|
||||
case 2u * SLICE_LEFT:
|
||||
case 2u * SLICE_LEFT + 1u:
|
||||
index = LEFT;
|
||||
fallback = LEFT;
|
||||
break;
|
||||
case 2u * SLICE_TOP_LEFT:
|
||||
index = LEFT;
|
||||
fallback = TOP;
|
||||
break;
|
||||
}
|
||||
|
||||
if (in_border_widths[index] > 0.0)
|
||||
return color_premultiply (in_border_colors[index]);
|
||||
else
|
||||
return color_premultiply (in_border_colors[fallback]);
|
||||
return color_premultiply (in_border_colors[index]);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -88,7 +57,7 @@ run (out vec2 pos)
|
||||
vec4 border_widths = in_border_widths * GSK_GLOBAL_SCALE.yxyx;
|
||||
RoundedRect outside = rounded_rect_from_gsk (in_outline);
|
||||
RoundedRect inside = rounded_rect_shrink (outside, border_widths);
|
||||
rounded_rect_offset (inside, in_offset * GSK_GLOBAL_SCALE);
|
||||
rounded_rect_offset (inside, in_offset);
|
||||
|
||||
pos = border_get_position (outside, inside);
|
||||
|
||||
|
||||
+50
-22
@@ -141,8 +141,16 @@ transform_bounds (GskOffload *self,
|
||||
graphene_rect_t *rect)
|
||||
{
|
||||
GskTransform *t = self->transforms ? self->transforms->data : NULL;
|
||||
float sx, sy, dx, dy;
|
||||
|
||||
gsk_transform_transform_bounds (t, bounds, rect);
|
||||
g_assert (gsk_transform_get_category (t) >= GSK_TRANSFORM_CATEGORY_2D_AFFINE);
|
||||
|
||||
gsk_transform_to_affine (t, &sx, &sy, &dx, &dy);
|
||||
|
||||
rect->origin.x = bounds->origin.x * sx + dx;
|
||||
rect->origin.y = bounds->origin.y * sy + dy;
|
||||
rect->size.width = bounds->size.width * sx;
|
||||
rect->size.height = bounds->size.height * sy;
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -252,8 +260,9 @@ interval_contains (float p1, float w1,
|
||||
|
||||
static gboolean
|
||||
update_clip (GskOffload *self,
|
||||
const graphene_rect_t *transformed_bounds)
|
||||
const graphene_rect_t *bounds)
|
||||
{
|
||||
graphene_rect_t transformed_bounds;
|
||||
gboolean no_clip = FALSE;
|
||||
gboolean rect_clip = FALSE;
|
||||
|
||||
@@ -262,7 +271,9 @@ update_clip (GskOffload *self,
|
||||
self->current_clip->is_complex)
|
||||
return FALSE;
|
||||
|
||||
if (!gsk_rect_intersects (&self->current_clip->rect.bounds, transformed_bounds))
|
||||
transform_bounds (self, bounds, &transformed_bounds);
|
||||
|
||||
if (!gsk_rect_intersects (&self->current_clip->rect.bounds, &transformed_bounds))
|
||||
{
|
||||
push_empty_clip (self);
|
||||
return TRUE;
|
||||
@@ -270,12 +281,12 @@ update_clip (GskOffload *self,
|
||||
|
||||
if (self->current_clip->is_rectilinear)
|
||||
{
|
||||
if (gsk_rect_contains_rect (&self->current_clip->rect.bounds, transformed_bounds))
|
||||
if (gsk_rect_contains_rect (&self->current_clip->rect.bounds, &transformed_bounds))
|
||||
no_clip = TRUE;
|
||||
else
|
||||
rect_clip = TRUE;
|
||||
}
|
||||
else if (gsk_rounded_rect_contains_rect (&self->current_clip->rect, transformed_bounds))
|
||||
else if (gsk_rounded_rect_contains_rect (&self->current_clip->rect, &transformed_bounds))
|
||||
{
|
||||
no_clip = TRUE;
|
||||
}
|
||||
@@ -286,9 +297,9 @@ update_clip (GskOffload *self,
|
||||
rounded_rect_get_inner (&self->current_clip->rect, &inner);
|
||||
|
||||
if (interval_contains (inner.origin.x, inner.size.width,
|
||||
transformed_bounds->origin.x, transformed_bounds->size.width) ||
|
||||
transformed_bounds.origin.x, transformed_bounds.size.width) ||
|
||||
interval_contains (inner.origin.y, inner.size.height,
|
||||
transformed_bounds->origin.y, transformed_bounds->size.height))
|
||||
transformed_bounds.origin.y, transformed_bounds.size.height))
|
||||
rect_clip = TRUE;
|
||||
}
|
||||
|
||||
@@ -307,7 +318,7 @@ update_clip (GskOffload *self,
|
||||
|
||||
/* The clip gets simpler for this node */
|
||||
|
||||
gsk_rect_intersection (&self->current_clip->rect.bounds, transformed_bounds, &rect);
|
||||
gsk_rect_intersection (&self->current_clip->rect.bounds, &transformed_bounds, &rect);
|
||||
push_rect_clip (self, &GSK_ROUNDED_RECT_INIT_FROM_RECT (rect));
|
||||
return TRUE;
|
||||
}
|
||||
@@ -334,9 +345,6 @@ visit_node (GskOffload *self,
|
||||
GskRenderNode *node)
|
||||
{
|
||||
gboolean has_clip;
|
||||
graphene_rect_t transformed_bounds;
|
||||
|
||||
transform_bounds (self, &node->bounds, &transformed_bounds);
|
||||
|
||||
for (gsize i = 0; i < self->n_subsurfaces; i++)
|
||||
{
|
||||
@@ -344,6 +352,9 @@ visit_node (GskOffload *self,
|
||||
|
||||
if (info->can_raise)
|
||||
{
|
||||
graphene_rect_t transformed_bounds;
|
||||
|
||||
transform_bounds (self, &node->bounds, &transformed_bounds);
|
||||
if (gsk_rect_intersects (&transformed_bounds, &info->rect))
|
||||
{
|
||||
GskRenderNodeType type = GSK_RENDER_NODE_TYPE (node);
|
||||
@@ -364,7 +375,7 @@ visit_node (GskOffload *self,
|
||||
}
|
||||
}
|
||||
|
||||
has_clip = update_clip (self, &transformed_bounds);
|
||||
has_clip = update_clip (self, &node->bounds);
|
||||
|
||||
switch (GSK_RENDER_NODE_TYPE (node))
|
||||
{
|
||||
@@ -472,9 +483,33 @@ complex_clip:
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_NODE:
|
||||
push_transform (self, gsk_transform_node_get_transform (node));
|
||||
visit_node (self, gsk_transform_node_get_child (node));
|
||||
pop_transform (self);
|
||||
{
|
||||
GskTransform *transform = gsk_transform_node_get_transform (node);
|
||||
const GskTransformCategory category = gsk_transform_get_category (transform);
|
||||
|
||||
switch (category)
|
||||
{
|
||||
case GSK_TRANSFORM_CATEGORY_IDENTITY:
|
||||
visit_node (self, gsk_transform_node_get_child (node));
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
|
||||
case GSK_TRANSFORM_CATEGORY_2D_AFFINE:
|
||||
push_transform (self, transform);
|
||||
visit_node (self, gsk_transform_node_get_child (node));
|
||||
pop_transform (self);
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_2D:
|
||||
case GSK_TRANSFORM_CATEGORY_3D:
|
||||
case GSK_TRANSFORM_CATEGORY_ANY:
|
||||
case GSK_TRANSFORM_CATEGORY_UNKNOWN:
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_CONTAINER_NODE:
|
||||
@@ -504,13 +539,6 @@ complex_clip:
|
||||
"Can't offload subsurface %p: clipped",
|
||||
subsurface);
|
||||
}
|
||||
else if (self->transforms &&
|
||||
gsk_transform_get_category ((GskTransform *)self->transforms->data) < GSK_TRANSFORM_CATEGORY_2D_AFFINE)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (gdk_surface_get_display (self->surface), OFFLOAD,
|
||||
"Can't offload subsurface %p: non-affine transform",
|
||||
subsurface);
|
||||
}
|
||||
else
|
||||
{
|
||||
info->texture = find_texture_to_attach (self, subsurface, gsk_subsurface_node_get_child (node));
|
||||
|
||||
@@ -4224,32 +4224,6 @@ gsk_repeat_node_draw (GskRenderNode *node,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_repeat_node_diff (GskRenderNode *node1,
|
||||
GskRenderNode *node2,
|
||||
GskDiffData *data)
|
||||
{
|
||||
GskRepeatNode *self1 = (GskRepeatNode *) node1;
|
||||
GskRepeatNode *self2 = (GskRepeatNode *) node2;
|
||||
|
||||
if (gsk_rect_equal (&node1->bounds, &node2->bounds) &&
|
||||
gsk_rect_equal (&self1->child_bounds, &self2->child_bounds))
|
||||
{
|
||||
cairo_region_t *sub;
|
||||
|
||||
sub = cairo_region_create();
|
||||
gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) {sub, data->offload });
|
||||
if (cairo_region_is_empty (sub))
|
||||
{
|
||||
cairo_region_destroy (sub);
|
||||
return;
|
||||
}
|
||||
cairo_region_destroy (sub);
|
||||
}
|
||||
|
||||
gsk_render_node_diff_impossible (node1, node2, data);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_repeat_node_class_init (gpointer g_class,
|
||||
gpointer class_data)
|
||||
@@ -4260,7 +4234,6 @@ gsk_repeat_node_class_init (gpointer g_class,
|
||||
|
||||
node_class->finalize = gsk_repeat_node_finalize;
|
||||
node_class->draw = gsk_repeat_node_draw;
|
||||
node_class->diff = gsk_repeat_node_diff;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -854,8 +854,7 @@ parse_mask_mode (GtkCssParser *parser,
|
||||
|
||||
static PangoFont *
|
||||
font_from_string (PangoFontMap *fontmap,
|
||||
const char *string,
|
||||
gboolean allow_fallback)
|
||||
const char *string)
|
||||
{
|
||||
PangoFontDescription *desc;
|
||||
PangoContext *ctx;
|
||||
@@ -866,7 +865,7 @@ font_from_string (PangoFontMap *fontmap,
|
||||
font = pango_font_map_load_font (fontmap, ctx, desc);
|
||||
g_object_unref (ctx);
|
||||
|
||||
if (font && !allow_fallback)
|
||||
if (font)
|
||||
{
|
||||
PangoFontDescription *desc2;
|
||||
const char *family, *family2;
|
||||
@@ -1082,7 +1081,7 @@ parse_font (GtkCssParser *parser,
|
||||
return FALSE;
|
||||
|
||||
if (context->fontmap)
|
||||
font = font_from_string (context->fontmap, font_name, FALSE);
|
||||
font = font_from_string (context->fontmap, font_name);
|
||||
|
||||
if (gtk_css_parser_has_url (parser))
|
||||
{
|
||||
@@ -1141,7 +1140,7 @@ parse_font (GtkCssParser *parser,
|
||||
|
||||
if (success)
|
||||
{
|
||||
font = font_from_string (context->fontmap, font_name, FALSE);
|
||||
font = font_from_string (context->fontmap, font_name);
|
||||
if (!font)
|
||||
{
|
||||
gtk_css_parser_error (parser,
|
||||
@@ -1157,7 +1156,7 @@ parse_font (GtkCssParser *parser,
|
||||
else
|
||||
{
|
||||
if (!font)
|
||||
font = font_from_string (pango_cairo_font_map_get_default (), font_name, TRUE);
|
||||
font = font_from_string (pango_cairo_font_map_get_default (), font_name);
|
||||
|
||||
if (!font)
|
||||
gtk_css_parser_error_value (parser, "The font \"%s\" does not exist", font_name);
|
||||
@@ -2237,7 +2236,7 @@ parse_text_node (GtkCssParser *parser,
|
||||
|
||||
if (font == NULL)
|
||||
{
|
||||
font = font_from_string (pango_cairo_font_map_get_default (), "Cantarell 11", TRUE);
|
||||
font = font_from_string (pango_cairo_font_map_get_default (), "Cantarell 11");
|
||||
g_assert (font);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/* GSK - The GTK Scene Kit
|
||||
* Copyright 2024 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef struct _Scale Scale;
|
||||
typedef struct _Point Point;
|
||||
typedef struct _Box Box;
|
||||
@@ -0,0 +1,252 @@
|
||||
#pragma once
|
||||
|
||||
#include "gsktypesprivate.h"
|
||||
#include <graphene.h>
|
||||
#include <math.h>
|
||||
#include <smmintrin.h>
|
||||
|
||||
#include "scaleprivate.h"
|
||||
|
||||
#ifndef USE_SIMD
|
||||
|
||||
struct _Point
|
||||
{
|
||||
float x, y;
|
||||
};
|
||||
|
||||
static inline float
|
||||
point_x (const Point p)
|
||||
{
|
||||
return p.x;
|
||||
}
|
||||
|
||||
static inline float
|
||||
point_y (const Point p)
|
||||
{
|
||||
return p.y;
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point (float x,
|
||||
float y)
|
||||
{
|
||||
return (Point) { .x = x, .y = y };
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point_from_graphene (const graphene_point_t *p)
|
||||
{
|
||||
return point (p->x, p->y);
|
||||
}
|
||||
|
||||
static inline void
|
||||
point_to_float (const Point p,
|
||||
float v[2])
|
||||
{
|
||||
v[0] = p.x;
|
||||
v[1] = p.y;
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point_zero (void)
|
||||
{
|
||||
return point (0, 0);
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point_neg (const Point p)
|
||||
{
|
||||
return (Point) { .x = -p.x, .y = -p.y };
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point_mul (const Point p,
|
||||
const Scale s)
|
||||
{
|
||||
return (Point) { .x = p.x * s.x, .y = p.y * s.y };
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point_div (const Point p,
|
||||
const Scale s)
|
||||
{
|
||||
return (Point) { .x = p.x / s.x, .y = p.y / s.y };
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point_add (const Point p1,
|
||||
const Point p2)
|
||||
{
|
||||
return (Point) { .x = p1.x + p2.x, .y = p1.y + p2.y };
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point_sub (const Point p1,
|
||||
const Point p2)
|
||||
{
|
||||
return (Point) { .x = p1.x - p2.x, .y = p1.y - p2.y };
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point_floor (const Point p)
|
||||
{
|
||||
return (Point) { .x = floorf (p.x), .y = floorf (p.y) };
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point_ceil (const Point p)
|
||||
{
|
||||
return (Point) { .x = ceilf (p.x), .y = ceilf (p.y) };
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point_round (const Point p)
|
||||
{
|
||||
return (Point) { .x = roundf (p.x), .y = roundf (p.y) };
|
||||
}
|
||||
|
||||
#else /* USE_SIMD */
|
||||
|
||||
#include <smmintrin.h>
|
||||
|
||||
struct _Point
|
||||
{
|
||||
GRAPHENE_ALIGNED_DECL (graphene_simd4f_t v, 16);
|
||||
};
|
||||
|
||||
static inline float
|
||||
point_x (const Point p)
|
||||
{
|
||||
return graphene_simd4f_get_x (p.v);
|
||||
}
|
||||
|
||||
static inline float
|
||||
point_y (const Point p)
|
||||
{
|
||||
return graphene_simd4f_get_y (p.v);
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point (float x,
|
||||
float y)
|
||||
{
|
||||
return (Point) { .v = graphene_simd4f_init (x, y, 0.f, 0.f) };
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point_from_graphene (const graphene_point_t *p)
|
||||
{
|
||||
return point (p->x, p->y);
|
||||
}
|
||||
|
||||
static inline void
|
||||
point_to_float (const Point p,
|
||||
float v[2])
|
||||
{
|
||||
graphene_simd4f_dup_2f (p.v, v);
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point_zero (void)
|
||||
{
|
||||
return point (0, 0);
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point_neg (const Point p)
|
||||
{
|
||||
return (Point) { .v = graphene_simd4f_neg (p.v) };
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point_mul (const Point p,
|
||||
const Scale s)
|
||||
{
|
||||
return (Point) { .v = graphene_simd4f_mul (p.v, s.v) };
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point_div (const Point p,
|
||||
const Scale s)
|
||||
{
|
||||
return (Point) { .v = graphene_simd4f_div (p.v, s.v) };
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point_add (const Point p1,
|
||||
const Point p2)
|
||||
{
|
||||
return (Point) { .v = graphene_simd4f_add (p1.v, p2.v) };
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point_sub (const Point p1,
|
||||
const Point p2)
|
||||
{
|
||||
return (Point) { .v = graphene_simd4f_sub (p1.v, p2.v) };
|
||||
}
|
||||
|
||||
#ifdef __SSE4_1__
|
||||
|
||||
#ifndef graphene_simd4f_floor
|
||||
# define graphene_simd4f_floor(v) \
|
||||
(__extension__ ({ \
|
||||
(graphene_simd4f_t) _mm_floor_ps ((v)); \
|
||||
}))
|
||||
#endif
|
||||
|
||||
#ifndef graphene_simd4f_ceil
|
||||
# define graphene_simd4f_ceil(v) \
|
||||
(__extension__ ({ \
|
||||
(graphene_simd4f_t) _mm_ceil_ps ((v)); \
|
||||
}))
|
||||
#endif
|
||||
|
||||
#ifndef graphene_simd4f_round
|
||||
# define graphene_simd4f_round(v) \
|
||||
(__extension__ ({ \
|
||||
(graphene_simd4f_t) _mm_round_ps ((v)); \
|
||||
}))
|
||||
#endif
|
||||
|
||||
static inline Point
|
||||
point_floor (const Point p)
|
||||
{
|
||||
return (Point) { .v = graphene_simd4f_floor (p.v) };
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point_ceil (const Point p)
|
||||
{
|
||||
return (Point) { .v = graphene_simd4f_ceil (p.v) };
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point_round (const Point p)
|
||||
{
|
||||
return (Point) { .v = graphene_simd4f_round (p.v) };
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline Point
|
||||
point_floor (const Point p)
|
||||
{
|
||||
return point (floorf (point_x (p)), floorf (point_y (p)));
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point_ceil (const Point p)
|
||||
{
|
||||
return point (ceilf (point_x (p)), ceilf (point_y (p)));
|
||||
}
|
||||
|
||||
static inline Point
|
||||
point_round (const Point p)
|
||||
{
|
||||
return point (roundf (point_x (p)), roundf (point_y (p)));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,183 @@
|
||||
#pragma once
|
||||
|
||||
#include "gsktypesprivate.h"
|
||||
#include <graphene.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifndef USE_SIMD
|
||||
|
||||
struct _Scale
|
||||
{
|
||||
float x, y;
|
||||
};
|
||||
|
||||
static inline float
|
||||
scale_x (const Scale s)
|
||||
{
|
||||
return s.x;
|
||||
}
|
||||
|
||||
static inline float
|
||||
scale_y (const Scale s)
|
||||
{
|
||||
return s.y;
|
||||
}
|
||||
|
||||
static inline Scale
|
||||
scale (float x,
|
||||
float y)
|
||||
{
|
||||
return (Scale) { .x = x, .y = y };
|
||||
}
|
||||
|
||||
static inline Scale
|
||||
scale_from_float (float s)
|
||||
{
|
||||
return scale (s, s);
|
||||
}
|
||||
|
||||
static inline Scale
|
||||
scale_from_graphene (const graphene_vec2_t *v)
|
||||
{
|
||||
return (Scale) { .x = graphene_vec2_get_x (v), .y = graphene_vec2_get_y (v) };
|
||||
}
|
||||
|
||||
static inline void
|
||||
scale_to_float (const Scale s,
|
||||
float v[2])
|
||||
{
|
||||
v[0] = s.x;
|
||||
v[1] = s.y;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
scale_equal (const Scale s1,
|
||||
const Scale s2)
|
||||
{
|
||||
return (gboolean) (s1.x == s2.x && s1.y == s2.y);
|
||||
}
|
||||
|
||||
static inline Scale
|
||||
scale_one (void)
|
||||
{
|
||||
return scale (1, 1);
|
||||
}
|
||||
|
||||
static inline Scale
|
||||
scale_inv (const Scale s)
|
||||
{
|
||||
return (Scale) { .x = 1 / s.x, .y = 1 / s.y };
|
||||
}
|
||||
|
||||
static inline Scale
|
||||
scale_mul (const Scale s1,
|
||||
const Scale s2)
|
||||
{
|
||||
return (Scale) { .x = s1.x * s2.x, .y = s1.y * s2.y };
|
||||
}
|
||||
|
||||
static inline Scale
|
||||
scale_div (const Scale s1,
|
||||
const Scale s2)
|
||||
{
|
||||
return (Scale) { .x = s1.x / s2.x, .y = s1.y / s2.y };
|
||||
}
|
||||
|
||||
static inline Scale
|
||||
scale_max (const Scale s)
|
||||
{
|
||||
return (Scale) { .x = MAX (s.x, s.y), .y = MAX (s.x, s.y) };
|
||||
}
|
||||
|
||||
#else /* USE_SIMD */
|
||||
|
||||
struct _Scale
|
||||
{
|
||||
GRAPHENE_ALIGNED_DECL (graphene_simd4f_t v, 16);
|
||||
};
|
||||
|
||||
static inline float
|
||||
scale_x (const Scale s)
|
||||
{
|
||||
return graphene_simd4f_get_x (s.v);
|
||||
}
|
||||
|
||||
static inline float
|
||||
scale_y (const Scale s)
|
||||
{
|
||||
return graphene_simd4f_get_y (s.v);
|
||||
}
|
||||
|
||||
static inline Scale
|
||||
scale (float x,
|
||||
float y)
|
||||
{
|
||||
return (Scale) { .v = graphene_simd4f_init (x, y, 0.f, 0.f) };
|
||||
}
|
||||
|
||||
static inline Scale
|
||||
scale_from_float (float s)
|
||||
{
|
||||
return scale (s, s);
|
||||
}
|
||||
|
||||
static inline Scale
|
||||
scale_from_graphene (const graphene_vec2_t *v)
|
||||
{
|
||||
return (Scale) { .v = v->__graphene_private_value };
|
||||
}
|
||||
|
||||
static inline void
|
||||
scale_to_float (const Scale s,
|
||||
float v[2])
|
||||
{
|
||||
graphene_simd4f_dup_2f (s.v, v);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
scale_equal (const Scale s1,
|
||||
const Scale s2)
|
||||
{
|
||||
return (gboolean) graphene_simd4f_cmp_eq (s1.v, s2.v);
|
||||
}
|
||||
|
||||
static inline Scale
|
||||
scale_one (void)
|
||||
{
|
||||
return scale (1, 1);
|
||||
}
|
||||
|
||||
static inline Scale
|
||||
scale_inv (const Scale s)
|
||||
{
|
||||
return (Scale) { .v = graphene_simd4f_reciprocal (s.v) };
|
||||
}
|
||||
|
||||
static inline Scale
|
||||
scale_mul (const Scale s1,
|
||||
const Scale s2)
|
||||
{
|
||||
return (Scale) { .v = graphene_simd4f_mul (s1.v, s2.v) };
|
||||
}
|
||||
|
||||
static inline Scale
|
||||
scale_div (const Scale s1,
|
||||
const Scale s2)
|
||||
{
|
||||
return (Scale) { .v = graphene_simd4f_div (s1.v, s2.v) };
|
||||
}
|
||||
|
||||
#ifndef graphene_simd4f_shuffle_yxzw
|
||||
# define graphene_simd4f_shuffle_yxzw(v) \
|
||||
(__extension__ ({ \
|
||||
(graphene_simd4f_t) _mm_shuffle_ps ((v), (v), _MM_SHUFFLE (3, 2, 0, 1)); \
|
||||
}))
|
||||
#endif
|
||||
|
||||
static inline Scale
|
||||
scale_max (const Scale s)
|
||||
{
|
||||
return (Scale) { .v = graphene_simd4f_max (graphene_simd4f_shuffle_yxzw (s.v), s.v) };
|
||||
}
|
||||
|
||||
#endif
|
||||
+76
-153
@@ -25,158 +25,89 @@
|
||||
#include "gtkatspicontextprivate.h"
|
||||
#include "gtkatspiprivate.h"
|
||||
#include "gtkatspiutilsprivate.h"
|
||||
#include "gtkatspisocket.h"
|
||||
#include "gtkaccessibleprivate.h"
|
||||
#include "gtkpopover.h"
|
||||
#include "gtkwidget.h"
|
||||
#include "gtkwindow.h"
|
||||
|
||||
#include "a11y/atspi/atspi-component.h"
|
||||
|
||||
static GtkAccessible *
|
||||
find_first_accessible_non_socket (GtkAccessible *accessible)
|
||||
{
|
||||
GtkAccessible *parent = gtk_accessible_get_accessible_parent (accessible);
|
||||
#include "gtkdebug.h"
|
||||
|
||||
while (parent != NULL)
|
||||
{
|
||||
g_object_unref (parent);
|
||||
|
||||
if (!GTK_IS_AT_SPI_SOCKET (parent))
|
||||
return parent;
|
||||
|
||||
parent = gtk_accessible_get_accessible_parent (parent);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#include <gio/gio.h>
|
||||
|
||||
static void
|
||||
translate_coordinates_to_accessible (GtkAccessible *accessible,
|
||||
AtspiCoordType coordtype,
|
||||
int xi,
|
||||
int yi,
|
||||
int *xo,
|
||||
int *yo)
|
||||
translate_coordinates_to_widget (GtkWidget *widget,
|
||||
AtspiCoordType coordtype,
|
||||
int xi,
|
||||
int yi,
|
||||
int *xo,
|
||||
int *yo)
|
||||
{
|
||||
GtkAccessible *parent;
|
||||
int x, y, width, height;
|
||||
graphene_point_t p;
|
||||
GtkWidget *source;
|
||||
|
||||
if (coordtype == ATSPI_COORD_TYPE_SCREEN)
|
||||
switch (coordtype)
|
||||
{
|
||||
case ATSPI_COORD_TYPE_SCREEN:
|
||||
*xo = 0;
|
||||
*yo = 0;
|
||||
return;
|
||||
|
||||
case ATSPI_COORD_TYPE_WINDOW:
|
||||
source = GTK_WIDGET (gtk_widget_get_root (widget));
|
||||
break;
|
||||
|
||||
case ATSPI_COORD_TYPE_PARENT:
|
||||
source = gtk_widget_get_parent (widget);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (!gtk_accessible_get_bounds (accessible, &x, &y, &width, &height))
|
||||
{
|
||||
*xo = xi;
|
||||
*yo = yi;
|
||||
return;
|
||||
}
|
||||
if (!gtk_widget_compute_point (source, widget, &GRAPHENE_POINT_INIT (xi, yi), &p))
|
||||
graphene_point_init (&p, xi, yi);
|
||||
|
||||
// Transform coords to our parent, we will need that in any case
|
||||
*xo = xi - x;
|
||||
*yo = yi - y;
|
||||
|
||||
// If that's what the caller requested, we're done
|
||||
if (coordtype == ATSPI_COORD_TYPE_PARENT)
|
||||
return;
|
||||
|
||||
if (coordtype == ATSPI_COORD_TYPE_WINDOW)
|
||||
{
|
||||
parent = gtk_accessible_get_accessible_parent (accessible);
|
||||
while (parent != NULL)
|
||||
{
|
||||
if (gtk_accessible_get_bounds (parent, &x, &y, &width, &height))
|
||||
{
|
||||
*xo = *xo - x;
|
||||
*yo = *yo - y;
|
||||
parent = gtk_accessible_get_accessible_parent (parent);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
*xo = (int)p.x;
|
||||
*yo = (int)p.y;
|
||||
}
|
||||
|
||||
static void
|
||||
translate_coordinates_from_accessible (GtkAccessible *accessible,
|
||||
AtspiCoordType coordtype,
|
||||
int xi,
|
||||
int yi,
|
||||
int *xo,
|
||||
int *yo)
|
||||
translate_coordinates_from_widget (GtkWidget *widget,
|
||||
AtspiCoordType coordtype,
|
||||
int xi,
|
||||
int yi,
|
||||
int *xo,
|
||||
int *yo)
|
||||
{
|
||||
GtkAccessible *parent;
|
||||
int x, y, width, height;
|
||||
graphene_point_t p;
|
||||
GtkWidget *target;
|
||||
|
||||
if (coordtype == ATSPI_COORD_TYPE_SCREEN)
|
||||
switch (coordtype)
|
||||
{
|
||||
case ATSPI_COORD_TYPE_SCREEN:
|
||||
*xo = 0;
|
||||
*yo = 0;
|
||||
return;
|
||||
|
||||
case ATSPI_COORD_TYPE_WINDOW:
|
||||
target = GTK_WIDGET (gtk_widget_get_root (widget));
|
||||
break;
|
||||
|
||||
case ATSPI_COORD_TYPE_PARENT:
|
||||
target = gtk_widget_get_parent (widget);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (!gtk_accessible_get_bounds (accessible, &x, &y, &width, &height))
|
||||
{
|
||||
*xo = xi;
|
||||
*yo = yi;
|
||||
return;
|
||||
}
|
||||
if (!gtk_widget_compute_point (widget, target, &GRAPHENE_POINT_INIT (xi, yi), &p))
|
||||
graphene_point_init (&p, xi, yi);
|
||||
|
||||
// Transform coords to our parent, we will need that in any case
|
||||
*xo = xi + x;
|
||||
*yo = yi + y;
|
||||
|
||||
// If that's what the caller requested, we're done
|
||||
if (coordtype == ATSPI_COORD_TYPE_PARENT)
|
||||
return;
|
||||
|
||||
if (coordtype == ATSPI_COORD_TYPE_WINDOW)
|
||||
{
|
||||
parent = gtk_accessible_get_accessible_parent (accessible);
|
||||
while (parent != NULL)
|
||||
{
|
||||
if (gtk_accessible_get_bounds (parent, &x, &y, &width, &height))
|
||||
{
|
||||
*xo = *xo + x;
|
||||
*yo = *yo + y;
|
||||
parent = gtk_accessible_get_accessible_parent (parent);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
static GtkAccessible *
|
||||
accessible_at_point (GtkAccessible *parent,
|
||||
int x,
|
||||
int y,
|
||||
bool children_only)
|
||||
{
|
||||
GtkAccessible *result = NULL;
|
||||
int px, py, width, height;
|
||||
|
||||
if (!gtk_accessible_get_bounds (parent, &px, &py, &width, &height))
|
||||
return NULL;
|
||||
|
||||
if (!children_only && x >= 0 && x <= width && y >= 0 && y <= height)
|
||||
result = parent;
|
||||
|
||||
for (GtkAccessible *child = gtk_accessible_get_first_accessible_child (parent);
|
||||
child != NULL;
|
||||
child = gtk_accessible_get_next_accessible_sibling (child))
|
||||
{
|
||||
GtkAccessible *found = accessible_at_point (child, x - px, y - py, FALSE);
|
||||
if (found)
|
||||
result = found;
|
||||
}
|
||||
|
||||
return result;
|
||||
*xo = (int)p.x;
|
||||
*yo = (int)p.y;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -191,46 +122,39 @@ component_handle_method (GDBusConnection *connection,
|
||||
{
|
||||
GtkATContext *self = user_data;
|
||||
GtkAccessible *accessible = gtk_at_context_get_accessible (self);
|
||||
|
||||
if (GTK_IS_AT_SPI_SOCKET (accessible))
|
||||
accessible = find_first_accessible_non_socket (accessible);
|
||||
GtkWidget *widget = GTK_WIDGET (accessible);
|
||||
|
||||
if (g_strcmp0 (method_name, "Contains") == 0)
|
||||
{
|
||||
int x, y;
|
||||
int bounds_x, bounds_y, width, height;
|
||||
AtspiCoordType coordtype;
|
||||
gboolean ret;
|
||||
|
||||
g_variant_get (parameters, "(iiu)", &x, &y, &coordtype);
|
||||
|
||||
translate_coordinates_to_accessible (accessible, coordtype, x, y, &x, &y);
|
||||
|
||||
if (gtk_accessible_get_bounds (accessible, &bounds_x, &bounds_y, &width, &height))
|
||||
ret = x >= 0 && x <= bounds_x && y >= 0 && y <= bounds_y;
|
||||
else
|
||||
ret = FALSE;
|
||||
translate_coordinates_to_widget (widget, coordtype, x, y, &x, &y);
|
||||
|
||||
ret = gtk_widget_contains (widget, x, y);
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", ret));
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetAccessibleAtPoint") == 0)
|
||||
{
|
||||
int x, y;
|
||||
AtspiCoordType coordtype;
|
||||
GtkAccessible *child;
|
||||
GtkWidget *child;
|
||||
|
||||
g_variant_get (parameters, "(iiu)", &x, &y, &coordtype);
|
||||
|
||||
translate_coordinates_to_accessible (accessible, coordtype, x, y, &x, &y);
|
||||
translate_coordinates_to_widget (widget, coordtype, x, y, &x, &y);
|
||||
|
||||
child = accessible_at_point (accessible, x, y, TRUE);
|
||||
child = gtk_widget_pick (widget, x, y, GTK_PICK_DEFAULT);
|
||||
if (!child)
|
||||
{
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@(so))", gtk_at_spi_null_ref ()));
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkATContext *context = gtk_accessible_get_at_context (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)));
|
||||
@@ -241,13 +165,13 @@ component_handle_method (GDBusConnection *connection,
|
||||
else if (g_strcmp0 (method_name, "GetExtents") == 0)
|
||||
{
|
||||
AtspiCoordType coordtype;
|
||||
int x, y, width, height;
|
||||
|
||||
gtk_accessible_get_bounds (accessible, &x, &y, &width, &height);
|
||||
int x, y;
|
||||
int width = gtk_widget_get_width (widget);
|
||||
int height = gtk_widget_get_height (widget);
|
||||
|
||||
g_variant_get (parameters, "(u)", &coordtype);
|
||||
|
||||
translate_coordinates_from_accessible (accessible, coordtype, 0, 0, &x, &y);
|
||||
translate_coordinates_from_widget (widget, coordtype, 0, 0, &x, &y);
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("((iiii))", x, y, width, height));
|
||||
}
|
||||
@@ -258,15 +182,14 @@ component_handle_method (GDBusConnection *connection,
|
||||
|
||||
g_variant_get (parameters, "(u)", &coordtype);
|
||||
|
||||
translate_coordinates_from_accessible (accessible, coordtype, 0, 0, &x, &y);
|
||||
translate_coordinates_from_widget (widget, coordtype, 0, 0, &x, &y);
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(ii)", x, y));
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetSize") == 0)
|
||||
{
|
||||
int x, y, width, height;
|
||||
|
||||
gtk_accessible_get_bounds (accessible, &x, &y, &width, &height);
|
||||
int width = gtk_widget_get_width (widget);
|
||||
int height = gtk_widget_get_height (widget);
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(ii)", width, height));
|
||||
}
|
||||
@@ -274,9 +197,9 @@ component_handle_method (GDBusConnection *connection,
|
||||
{
|
||||
AtspiComponentLayer layer;
|
||||
|
||||
if (self->accessible_role == GTK_ACCESSIBLE_ROLE_WINDOW)
|
||||
if (GTK_IS_WINDOW (widget))
|
||||
layer = ATSPI_COMPONENT_LAYER_WINDOW;
|
||||
else if (GTK_IS_POPOVER (accessible))
|
||||
else if (GTK_IS_POPOVER (widget))
|
||||
layer = ATSPI_COMPONENT_LAYER_POPUP;
|
||||
else
|
||||
layer = ATSPI_COMPONENT_LAYER_WIDGET;
|
||||
@@ -293,10 +216,7 @@ component_handle_method (GDBusConnection *connection,
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetAlpha") == 0)
|
||||
{
|
||||
double opacity = 1.0;
|
||||
|
||||
if (GTK_IS_WIDGET (accessible))
|
||||
opacity = gtk_widget_get_opacity (GTK_WIDGET (accessible));
|
||||
double opacity = gtk_widget_get_opacity (widget);
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(d)", opacity));
|
||||
}
|
||||
@@ -329,5 +249,8 @@ static const GDBusInterfaceVTable component_vtable = {
|
||||
const GDBusInterfaceVTable *
|
||||
gtk_atspi_get_component_vtable (GtkAccessible *accessible)
|
||||
{
|
||||
return &component_vtable;
|
||||
if (GTK_IS_WIDGET (accessible))
|
||||
return &component_vtable;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "gtkatspiprivate.h"
|
||||
#include "gtkatspirootprivate.h"
|
||||
#include "gtkatspiselectionprivate.h"
|
||||
#include "gtkatspisocketprivate.h"
|
||||
#include "gtkatspitextprivate.h"
|
||||
#include "gtkatspiutilsprivate.h"
|
||||
#include "gtkatspivalueprivate.h"
|
||||
@@ -577,15 +576,6 @@ handle_accessible_method (GDBusConnection *connection,
|
||||
|
||||
accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self));
|
||||
|
||||
if (GTK_IS_AT_SPI_SOCKET (accessible))
|
||||
{
|
||||
GtkAtSpiSocket *socket = GTK_AT_SPI_SOCKET (accessible);
|
||||
GVariant *ref = gtk_at_spi_socket_to_ref (socket);
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@(so))", ref));
|
||||
return;
|
||||
}
|
||||
|
||||
presentable_idx = 0;
|
||||
|
||||
for (child = gtk_accessible_get_first_accessible_child (accessible);
|
||||
@@ -630,13 +620,6 @@ handle_accessible_method (GDBusConnection *connection,
|
||||
GtkAccessible *accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self));
|
||||
GtkAccessible *child = NULL;
|
||||
|
||||
if (GTK_IS_AT_SPI_SOCKET (accessible))
|
||||
{
|
||||
GtkAtSpiSocket *socket = GTK_AT_SPI_SOCKET (accessible);
|
||||
GVariant *ref = gtk_at_spi_socket_to_ref (socket);
|
||||
g_variant_builder_add (&builder, "@(so)", ref);
|
||||
}
|
||||
|
||||
for (child = gtk_accessible_get_first_accessible_child (accessible);
|
||||
child != NULL;
|
||||
child = gtk_accessible_get_next_accessible_sibling (child))
|
||||
@@ -1387,18 +1370,6 @@ gtk_at_spi_context_register_object (GtkAtSpiContext *self)
|
||||
GTK_DEBUG (A11Y, "Registered %d interfaces on object path '%s'",
|
||||
self->n_registered_objects,
|
||||
self->context_path);
|
||||
|
||||
if (GTK_IS_AT_SPI_SOCKET (accessible))
|
||||
{
|
||||
GtkAtSpiSocket *socket = GTK_AT_SPI_SOCKET (accessible);
|
||||
|
||||
gtk_at_spi_socket_embed (socket, self->connection);
|
||||
|
||||
GTK_DEBUG (A11Y, "Embedded plug %s:%s in socket %s",
|
||||
gtk_at_spi_socket_get_bus_name (socket),
|
||||
gtk_at_spi_socket_get_object_path (socket),
|
||||
self->context_path);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1430,6 +1401,14 @@ gtk_at_spi_context_finalize (GObject *gobject)
|
||||
G_OBJECT_CLASS (gtk_at_spi_context_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_at_spi_context_constructed (GObject *gobject)
|
||||
{
|
||||
GtkAtSpiContext *self G_GNUC_UNUSED = GTK_AT_SPI_CONTEXT (gobject);
|
||||
|
||||
G_OBJECT_CLASS (gtk_at_spi_context_parent_class)->constructed (gobject);
|
||||
}
|
||||
|
||||
static const char *get_bus_address (GdkDisplay *display);
|
||||
|
||||
static void
|
||||
@@ -1531,48 +1510,13 @@ gtk_at_spi_context_unrealize (GtkATContext *context)
|
||||
g_clear_object (&self->root);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_at_spi_context_announce (GtkATContext *context,
|
||||
const char *message,
|
||||
GtkAccessibleAnnouncementPriority priority)
|
||||
{
|
||||
GtkAtSpiContext *self = GTK_AT_SPI_CONTEXT (context);
|
||||
AtspiLive live;
|
||||
|
||||
if (self->connection == NULL)
|
||||
return;
|
||||
|
||||
switch (priority)
|
||||
{
|
||||
case GTK_ACCESSIBLE_ANNOUNCEMENT_PRIORITY_LOW:
|
||||
case GTK_ACCESSIBLE_ANNOUNCEMENT_PRIORITY_MEDIUM:
|
||||
live = ATSPI_LIVE_POLITE;
|
||||
break;
|
||||
case GTK_ACCESSIBLE_ANNOUNCEMENT_PRIORITY_HIGH:
|
||||
live = ATSPI_LIVE_ASSERTIVE;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
g_dbus_connection_emit_signal (self->connection,
|
||||
NULL,
|
||||
self->context_path,
|
||||
"org.a11y.atspi.Event.Object",
|
||||
"Announcement",
|
||||
g_variant_new ("(siiva{sv})",
|
||||
"", live, 0,
|
||||
g_variant_new_string (message),
|
||||
NULL),
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_at_spi_context_class_init (GtkAtSpiContextClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GtkATContextClass *context_class = GTK_AT_CONTEXT_CLASS (klass);
|
||||
|
||||
gobject_class->constructed = gtk_at_spi_context_constructed;
|
||||
gobject_class->finalize = gtk_at_spi_context_finalize;
|
||||
|
||||
context_class->realize = gtk_at_spi_context_realize;
|
||||
@@ -1581,7 +1525,6 @@ gtk_at_spi_context_class_init (GtkAtSpiContextClass *klass)
|
||||
context_class->platform_change = gtk_at_spi_context_platform_change;
|
||||
context_class->bounds_change = gtk_at_spi_context_bounds_change;
|
||||
context_class->child_change = gtk_at_spi_context_child_change;
|
||||
context_class->announce = gtk_at_spi_context_announce;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1873,10 +1816,6 @@ gtk_at_spi_context_get_child_count (GtkAtSpiContext *self)
|
||||
GtkAccessible *accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self));
|
||||
int n_children = 0;
|
||||
|
||||
/* A socket always has exactly one child: the remote plug */
|
||||
if (GTK_IS_AT_SPI_SOCKET (accessible))
|
||||
return 1;
|
||||
|
||||
GtkAccessible *child = NULL;
|
||||
for (child = gtk_accessible_get_first_accessible_child (accessible);
|
||||
child != NULL;
|
||||
|
||||
@@ -277,11 +277,6 @@ typedef enum {
|
||||
ATSPI_SCROLL_ANYWHERE
|
||||
} AtspiScrollType;
|
||||
|
||||
typedef enum {
|
||||
ATSPI_LIVE_POLITE = 1,
|
||||
ATSPI_LIVE_ASSERTIVE = 2
|
||||
} AtspiLive;
|
||||
|
||||
typedef struct _GtkAtSpiRoot GtkAtSpiRoot;
|
||||
typedef struct _GtkAtSpiCache GtkAtSpiCache;
|
||||
typedef struct _GtkAtSpiContext GtkAtSpiContext;
|
||||
|
||||
@@ -96,7 +96,7 @@ gtk_at_spi_root_finalize (GObject *gobject)
|
||||
g_free (self->desktop_name);
|
||||
g_free (self->desktop_path);
|
||||
|
||||
G_OBJECT_CLASS (gtk_at_spi_root_parent_class)->finalize (gobject);
|
||||
G_OBJECT_CLASS (gtk_at_spi_root_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -1,480 +0,0 @@
|
||||
/* gtkatspisocket.c: AT-SPI socket object
|
||||
*
|
||||
* Copyright 2024 GNOME Foundation Inc.
|
||||
* 2024 Igalia S.L.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* GtkAtApiSocket:
|
||||
*
|
||||
* `GtkAtApiSocket` is an AT-SPI specific `GtkAccessible` interface for
|
||||
* integrating remote accessible objects. It makes the accessible tree
|
||||
* of the remote accessible object appear as part of the accessible tree
|
||||
* that it belongs to itself.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkatspisocketprivate.h"
|
||||
|
||||
#include "gtkatspicontextprivate.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
|
||||
struct _GtkAtSpiSocket
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
char *bus_name;
|
||||
char *object_path;
|
||||
GtkATContext *at_context;
|
||||
GtkAccessibleRole accessible_role;
|
||||
|
||||
GCancellable *cancellable;
|
||||
gboolean embedded;
|
||||
};
|
||||
|
||||
static void g_initable_interface_init (GInitableIface *iface);
|
||||
static void gtk_accessible_interface_init (GtkAccessibleInterface *iface);
|
||||
|
||||
G_DEFINE_FINAL_TYPE_WITH_CODE (GtkAtSpiSocket, gtk_at_spi_socket, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
|
||||
g_initable_interface_init)
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_ACCESSIBLE,
|
||||
gtk_accessible_interface_init))
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_BUS_NAME,
|
||||
PROP_OBJECT_PATH,
|
||||
N_PROPS,
|
||||
|
||||
/* GtkAccessible */
|
||||
PROP_ACCESSIBLE_ROLE,
|
||||
};
|
||||
|
||||
static GParamSpec *properties [N_PROPS];
|
||||
|
||||
static void
|
||||
set_accessible_role (GtkAtSpiSocket *self,
|
||||
GtkAccessibleRole role)
|
||||
{
|
||||
g_return_if_fail (!gtk_accessible_role_is_abstract (role));
|
||||
|
||||
if (self->at_context == NULL || !gtk_at_context_is_realized (self->at_context))
|
||||
{
|
||||
self->accessible_role = role;
|
||||
|
||||
if (self->at_context != NULL)
|
||||
gtk_at_context_set_accessible_role (self->at_context, role);
|
||||
|
||||
g_object_notify (G_OBJECT (self), "accessible-role");
|
||||
}
|
||||
else
|
||||
{
|
||||
char *role_str = g_enum_to_string (GTK_TYPE_ACCESSIBLE_ROLE, self->accessible_role);
|
||||
|
||||
g_critical ("%s already has an accessible role of type “%s”",
|
||||
G_OBJECT_TYPE_NAME (self),
|
||||
role_str);
|
||||
|
||||
g_free (role_str);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_at_spi_socket_initable_init (GInitable *initable,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
GtkAtSpiSocket *self = (GtkAtSpiSocket *) initable;
|
||||
|
||||
g_assert (GTK_IS_AT_SPI_SOCKET (initable));
|
||||
|
||||
if (self->bus_name == NULL || !g_dbus_is_name (self->bus_name))
|
||||
{
|
||||
g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "Invalid bus name");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (self->object_path == NULL || !g_variant_is_object_path (self->object_path))
|
||||
{
|
||||
g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "Invalid object path");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
self->at_context = gtk_at_context_create (self->accessible_role,
|
||||
GTK_ACCESSIBLE (self),
|
||||
gdk_display_get_default ());
|
||||
|
||||
/* Sockets are strictly specific to AT-SPI */
|
||||
if (self->at_context != NULL && !GTK_IS_AT_SPI_CONTEXT (self->at_context))
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
"AT-SPI sockets can only be used with the AT-SPI backend");
|
||||
g_clear_object (&self->at_context);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gtk_accessible_update_state (GTK_ACCESSIBLE (self),
|
||||
GTK_ACCESSIBLE_STATE_HIDDEN, TRUE,
|
||||
-1);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
g_initable_interface_init (GInitableIface *iface)
|
||||
{
|
||||
iface->init = gtk_at_spi_socket_initable_init;
|
||||
}
|
||||
|
||||
static GtkATContext *
|
||||
gtk_at_spi_socket_get_at_context (GtkAccessible *accessible)
|
||||
{
|
||||
GtkAtSpiSocket *self = (GtkAtSpiSocket *) accessible;
|
||||
|
||||
g_assert (GTK_IS_AT_SPI_SOCKET (accessible));
|
||||
|
||||
if (self->at_context != NULL)
|
||||
return g_object_ref (self->at_context);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_at_spi_socket_get_platform_state (GtkAccessible *self,
|
||||
GtkAccessiblePlatformState state)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GtkAccessible *
|
||||
gtk_at_spi_socket_get_first_accessible_child (GtkAccessible *accessible)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GtkAccessible *
|
||||
gtk_at_spi_socket_get_next_accessible_sibling (GtkAccessible *accessible)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_at_spi_socket_get_bounds (GtkAccessible *accessible,
|
||||
int *x,
|
||||
int *y,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
GtkAccessible *accessible_parent;
|
||||
|
||||
g_assert (GTK_IS_AT_SPI_SOCKET (accessible));
|
||||
|
||||
accessible_parent = gtk_accessible_get_accessible_parent (accessible);
|
||||
if (accessible_parent == NULL)
|
||||
return FALSE;
|
||||
|
||||
return gtk_accessible_get_bounds (accessible_parent, x, y, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_accessible_interface_init (GtkAccessibleInterface *iface)
|
||||
{
|
||||
iface->get_at_context = gtk_at_spi_socket_get_at_context;
|
||||
iface->get_platform_state = gtk_at_spi_socket_get_platform_state;
|
||||
iface->get_first_accessible_child = gtk_at_spi_socket_get_first_accessible_child;
|
||||
iface->get_next_accessible_sibling = gtk_at_spi_socket_get_next_accessible_sibling;
|
||||
iface->get_bounds = gtk_at_spi_socket_get_bounds;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_at_spi_socket_dispose (GObject *object)
|
||||
{
|
||||
GtkAtSpiSocket *self = (GtkAtSpiSocket *)object;
|
||||
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
|
||||
g_clear_pointer (&self->object_path, g_free);
|
||||
g_clear_pointer (&self->bus_name, g_free);
|
||||
g_clear_object (&self->cancellable);
|
||||
g_clear_object (&self->at_context);
|
||||
|
||||
G_OBJECT_CLASS (gtk_at_spi_socket_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_at_spi_socket_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkAtSpiSocket *self = GTK_AT_SPI_SOCKET (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ACCESSIBLE_ROLE:
|
||||
g_value_set_enum (value, self->accessible_role);
|
||||
break;
|
||||
|
||||
case PROP_BUS_NAME:
|
||||
g_value_set_string (value, self->bus_name);
|
||||
break;
|
||||
|
||||
case PROP_OBJECT_PATH:
|
||||
g_value_set_string (value, self->object_path);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_at_spi_socket_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkAtSpiSocket *self = GTK_AT_SPI_SOCKET (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ACCESSIBLE_ROLE:
|
||||
set_accessible_role (self, g_value_get_enum (value));
|
||||
break;
|
||||
|
||||
case PROP_BUS_NAME:
|
||||
self->bus_name = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_OBJECT_PATH:
|
||||
self->object_path = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_at_spi_socket_class_init (GtkAtSpiSocketClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gtk_at_spi_socket_dispose;
|
||||
object_class->get_property = gtk_at_spi_socket_get_property;
|
||||
object_class->set_property = gtk_at_spi_socket_set_property;
|
||||
|
||||
/**
|
||||
* GtkAtSpiSocket:bus-name: (attributes org.gtk.Property.get=gtk_at_spi_socket_get_bus_name)
|
||||
*
|
||||
* The bus name of the remote accessible client.
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
properties[PROP_BUS_NAME] =
|
||||
g_param_spec_string ("bus-name", NULL, NULL,
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GtkAtSpiSocket:height: (attributes org.gtk.Property.get=gtk_at_spi_socket_get_object_path)
|
||||
*
|
||||
* The object path of the remote accessible object that
|
||||
* the socket connects to.
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
properties[PROP_OBJECT_PATH] =
|
||||
g_param_spec_string ("object-path", NULL, NULL,
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
|
||||
g_object_class_override_property (object_class, PROP_ACCESSIBLE_ROLE, "accessible-role");
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_at_spi_socket_init (GtkAtSpiSocket *self)
|
||||
{
|
||||
self->accessible_role = GTK_ACCESSIBLE_ROLE_GENERIC;
|
||||
}
|
||||
|
||||
GVariant *
|
||||
gtk_at_spi_socket_to_ref (GtkAtSpiSocket *self)
|
||||
{
|
||||
return g_variant_new ("(so)", self->bus_name, self->object_path);
|
||||
}
|
||||
|
||||
static void
|
||||
update_embedded_state (GtkAtSpiSocket *self,
|
||||
gboolean embedded)
|
||||
{
|
||||
if (self->embedded == embedded)
|
||||
return;
|
||||
|
||||
gtk_accessible_update_state (GTK_ACCESSIBLE (self),
|
||||
GTK_ACCESSIBLE_STATE_HIDDEN, !embedded,
|
||||
-1);
|
||||
|
||||
self->embedded = embedded;
|
||||
|
||||
g_clear_object (&self->cancellable);
|
||||
}
|
||||
|
||||
static void
|
||||
socket_embedded_cb (GObject *source_object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkAtSpiSocket *self = (GtkAtSpiSocket *)user_data;
|
||||
GVariant *res = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
res = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
|
||||
result,
|
||||
&error);
|
||||
|
||||
g_clear_pointer (&res, g_variant_unref);
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
{
|
||||
g_warning ("Error embedding AT-SPI socket: %s", error->message);
|
||||
update_embedded_state (self, FALSE);
|
||||
}
|
||||
g_clear_error (&error);
|
||||
return;
|
||||
}
|
||||
|
||||
update_embedded_state (self, TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_at_spi_socket_embed (GtkAtSpiSocket *self,
|
||||
GDBusConnection *connection)
|
||||
{
|
||||
const char *context_path = NULL;
|
||||
|
||||
if (self->at_context == NULL)
|
||||
return;
|
||||
|
||||
if (self->embedded || self->cancellable != NULL)
|
||||
return;
|
||||
|
||||
context_path = gtk_at_spi_context_get_context_path (GTK_AT_SPI_CONTEXT (self->at_context));
|
||||
|
||||
self->cancellable = g_cancellable_new ();
|
||||
|
||||
g_dbus_connection_call (connection,
|
||||
self->bus_name,
|
||||
self->object_path,
|
||||
"org.a11y.atspi.Socket",
|
||||
"Embedded",
|
||||
g_variant_new ("(s)", context_path),
|
||||
NULL,
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
||||
-1,
|
||||
self->cancellable,
|
||||
socket_embedded_cb,
|
||||
self);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_at_spi_socket_new:
|
||||
* @bus_name: the bus name of the remote accessible object
|
||||
* @object_path: the object path of the remote accessible object
|
||||
* @error: (nullable): return location for a #GError
|
||||
*
|
||||
* Creates an AT-SPI socket object that makes the accessible tree
|
||||
* at the given @bus_name and @object_path appear as part of the
|
||||
* accessible tree that it belongs to itself.
|
||||
*
|
||||
* It is up to the app to acquire @bus_name and @object_path. That's
|
||||
* usually done through a side channel with the remote side, for
|
||||
* example using sockets, or reading the output of a subprocess.
|
||||
*
|
||||
* The remote accessible object at @object_path must be a must
|
||||
* have an `org.a11y.atspi.Socket` interface with the `Embedded()`
|
||||
* method.
|
||||
*
|
||||
* This constructor can fail, most notably if the accessibility
|
||||
* stack is not AT-SPI.
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
GtkAccessible *
|
||||
gtk_at_spi_socket_new (const char *bus_name,
|
||||
const char *object_path,
|
||||
GError **error)
|
||||
{
|
||||
return g_initable_new (GTK_TYPE_AT_SPI_SOCKET,
|
||||
NULL,
|
||||
error,
|
||||
"bus-name", bus_name,
|
||||
"object-path", object_path,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_at_spi_socket_get_bus_name:
|
||||
* @self: a #GtkAtSpiSocket
|
||||
*
|
||||
* Retrieves the bus name of the remote accessible object that the
|
||||
* socket is connected to.
|
||||
*
|
||||
* Returns: (transfer none): the bus name of the remote accessible object
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
const char *
|
||||
gtk_at_spi_socket_get_bus_name (GtkAtSpiSocket *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_AT_SPI_SOCKET (self), NULL);
|
||||
|
||||
return self->bus_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_at_spi_socket_get_object_path:
|
||||
* @self: a #GtkAtSpiSocket
|
||||
*
|
||||
* Retrieves the object path of the remove accessible object that
|
||||
* the socket is connected to.
|
||||
*
|
||||
* Returns: (transfer none): the object path of the socket remote
|
||||
* accessible object
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
const char *
|
||||
gtk_at_spi_socket_get_object_path (GtkAtSpiSocket *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_AT_SPI_SOCKET (self), NULL);
|
||||
|
||||
return self->object_path;
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/* gtkatspisocket.h: AT-SPI socket accessible object
|
||||
*
|
||||
* Copyright 2024 GNOME Foundation Inc.
|
||||
* 2024 Igalia S.L.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined (__GTKATSPI_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gtk/a11y/gtkatspi.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gtk/gtkaccessible.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_AT_SPI_SOCKET (gtk_at_spi_socket_get_type())
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
G_DECLARE_FINAL_TYPE (GtkAtSpiSocket, gtk_at_spi_socket, GTK, AT_SPI_SOCKET, GObject)
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
GtkAccessible * gtk_at_spi_socket_new (const char *bus_name,
|
||||
const char *object_path,
|
||||
GError **error);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
const char * gtk_at_spi_socket_get_bus_name (GtkAtSpiSocket *self);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
const char * gtk_at_spi_socket_get_object_path (GtkAtSpiSocket *self);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,34 +0,0 @@
|
||||
/* gtkatspisocketprivate.h: AT-SPI socket object
|
||||
*
|
||||
* Copyright 2024 GNOME Foundation Inc.
|
||||
* 2024 Igalia S.L.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include "gtkaccessible.h"
|
||||
#include "gtkatspisocket.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GVariant * gtk_at_spi_socket_to_ref (GtkAtSpiSocket *self);
|
||||
void gtk_at_spi_socket_embed (GtkAtSpiSocket *self,
|
||||
GDBusConnection *connection);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -691,9 +691,6 @@ gtk_editable_get_text_widget (GtkWidget *widget)
|
||||
|
||||
if (GTK_IS_TEXT (delegate))
|
||||
return GTK_TEXT (delegate);
|
||||
|
||||
if (GTK_IS_TEXT (widget))
|
||||
return GTK_TEXT (widget);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -1577,7 +1574,8 @@ gtk_atspi_get_text_vtable (GtkAccessible *accessible)
|
||||
return &label_vtable;
|
||||
else if (GTK_IS_INSCRIPTION (accessible))
|
||||
return &inscription_vtable;
|
||||
else if (GTK_IS_EDITABLE (accessible))
|
||||
else if (GTK_IS_EDITABLE (accessible) &&
|
||||
GTK_IS_TEXT (gtk_editable_get_delegate (GTK_EDITABLE (accessible))))
|
||||
return &editable_vtable;
|
||||
else if (GTK_IS_TEXT_VIEW (accessible))
|
||||
return &text_view_vtable;
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
gtk_a11y_src = []
|
||||
gtk_a11y_backends = []
|
||||
gtk_a11y_backend_info = {}
|
||||
|
||||
if os_unix
|
||||
gtk_a11y_backends += 'atspi'
|
||||
endif
|
||||
|
||||
if gtk_a11y_backends.contains('atspi')
|
||||
gtk_a11y_backend_info += { 'atspi': { 'description': 'GTK AT-SPI accessibility support' } }
|
||||
|
||||
subdir('atspi')
|
||||
|
||||
gtk_a11y_src += files([
|
||||
@@ -20,16 +17,9 @@ if gtk_a11y_backends.contains('atspi')
|
||||
'gtkatspipango.c',
|
||||
'gtkatspiroot.c',
|
||||
'gtkatspiselection.c',
|
||||
'gtkatspisocket.c',
|
||||
'gtkatspitextbuffer.c',
|
||||
'gtkatspitext.c',
|
||||
'gtkatspiutils.c',
|
||||
'gtkatspivalue.c',
|
||||
])
|
||||
|
||||
gtk_atspi_public_headers = files([
|
||||
'gtkatspisocket.h',
|
||||
])
|
||||
|
||||
install_headers(gtk_atspi_public_headers, 'gtkatspi.h', subdir: 'gtk-4.0/gtk/a11y/')
|
||||
endif
|
||||
|
||||
@@ -92,7 +92,6 @@
|
||||
#include <gtk/gtkcolumnviewsorter.h>
|
||||
#include <gtk/deprecated/gtkcombobox.h>
|
||||
#include <gtk/deprecated/gtkcomboboxtext.h>
|
||||
#include <gtk/gtkconfig.h>
|
||||
#include <gtk/gtkconstraintlayout.h>
|
||||
#include <gtk/gtkconstraint.h>
|
||||
#include <gtk/gtkcssprovider.h>
|
||||
|
||||
@@ -751,41 +751,6 @@ gtk_accessible_reset_relation (GtkAccessible *self,
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_accessible_announce:
|
||||
* @self: a `GtkAccessible`
|
||||
* @message: the string to announce
|
||||
* @priority: the priority of the announcement
|
||||
*
|
||||
* Requests the user's screen reader to announce the given message.
|
||||
*
|
||||
* This kind of notification is useful for messages that
|
||||
* either have only a visual representation or that are not
|
||||
* exposed visually at all, e.g. a notification about a
|
||||
* successful operation.
|
||||
*
|
||||
* Also, by using this API, you can ensure that the message
|
||||
* does not interrupts the user's current screen reader output.
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
void
|
||||
gtk_accessible_announce (GtkAccessible *self,
|
||||
const char *message,
|
||||
GtkAccessibleAnnouncementPriority priority)
|
||||
{
|
||||
GtkATContext *context;
|
||||
|
||||
g_return_if_fail (GTK_IS_ACCESSIBLE (self));
|
||||
|
||||
context = gtk_accessible_get_at_context (self);
|
||||
if (context == NULL)
|
||||
return;
|
||||
|
||||
gtk_at_context_announce (context, message, priority);
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
static const char *role_names[] = {
|
||||
[GTK_ACCESSIBLE_ROLE_ALERT] = NC_("accessibility", "alert"),
|
||||
[GTK_ACCESSIBLE_ROLE_ALERT_DIALOG] = NC_("accessibility", "alert dialog"),
|
||||
@@ -1184,96 +1149,6 @@ gtk_accessible_get_bounds (GtkAccessible *self,
|
||||
return GTK_ACCESSIBLE_GET_IFACE (self)->get_bounds (self, x, y, width, height);
|
||||
}
|
||||
|
||||
struct _GtkAccessibleList
|
||||
{
|
||||
GList *objects;
|
||||
};
|
||||
|
||||
/**
|
||||
* gtk_accessible_list_new_from_list:
|
||||
* @list: (element-type GtkAccessible): a reference to a `GList` containing a list of accessible values
|
||||
*
|
||||
* Allocates a new `GtkAccessibleList`, doing a shallow copy of the
|
||||
* passed list of `GtkAccessible` instances.
|
||||
*
|
||||
* Returns: (transfer full): the list of accessible instances
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
GtkAccessibleList *
|
||||
gtk_accessible_list_new_from_list (GList *list)
|
||||
{
|
||||
GtkAccessibleList *accessible_list = g_new (GtkAccessibleList, 1);
|
||||
|
||||
accessible_list->objects = g_list_copy (list);
|
||||
|
||||
return accessible_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_accessible_list_new_from_array:
|
||||
* @accessibles: (array length=n_accessibles): array of GtkAccessible
|
||||
* @n_accessibles: length of @accessibles array
|
||||
*
|
||||
* Allocates a new list of accessible instances.
|
||||
*
|
||||
* Returns: (transfer full): the newly created list of accessible instances
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
GtkAccessibleList *
|
||||
gtk_accessible_list_new_from_array (GtkAccessible **accessibles,
|
||||
gsize n_accessibles)
|
||||
{
|
||||
GtkAccessibleList *accessible_list;
|
||||
GList *list = NULL;
|
||||
|
||||
g_return_val_if_fail (accessibles == NULL || n_accessibles == 0, NULL);
|
||||
|
||||
accessible_list = g_new (GtkAccessibleList, 1);
|
||||
|
||||
for (gsize i = 0; i < n_accessibles; i++)
|
||||
{
|
||||
list = g_list_prepend (list, accessibles[i]);
|
||||
}
|
||||
|
||||
accessible_list->objects = g_list_reverse (list);
|
||||
|
||||
return accessible_list;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_accessible_list_free (GtkAccessibleList *accessible_list)
|
||||
{
|
||||
g_free (accessible_list->objects);
|
||||
g_free (accessible_list);
|
||||
}
|
||||
|
||||
static GtkAccessibleList *
|
||||
gtk_accessible_list_copy (GtkAccessibleList *accessible_list)
|
||||
{
|
||||
return gtk_accessible_list_new_from_list (accessible_list->objects);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_accessible_list_get_objects:
|
||||
*
|
||||
* Gets the list of objects this boxed type holds
|
||||
*
|
||||
* Returns: (transfer container) (element-type GtkAccessible): a shallow copy of the objects
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
GList *
|
||||
gtk_accessible_list_get_objects (GtkAccessibleList *accessible_list)
|
||||
{
|
||||
return g_list_copy (accessible_list->objects);
|
||||
}
|
||||
|
||||
G_DEFINE_BOXED_TYPE (GtkAccessibleList, gtk_accessible_list,
|
||||
gtk_accessible_list_copy,
|
||||
gtk_accessible_list_free)
|
||||
|
||||
/*< private >
|
||||
* gtk_accessible_should_present:
|
||||
* @self: a `GtkAccessible`
|
||||
|
||||
@@ -154,15 +154,6 @@ struct _GtkAccessibleInterface
|
||||
int *height);
|
||||
};
|
||||
|
||||
/**
|
||||
* GtkAccessibleList:
|
||||
*
|
||||
* A boxed type which wraps a list of references to GtkAccessible objects.
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
typedef struct _GtkAccessibleList GtkAccessibleList;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkATContext * gtk_accessible_get_at_context (GtkAccessible *self);
|
||||
|
||||
@@ -245,24 +236,4 @@ GDK_AVAILABLE_IN_ALL
|
||||
void gtk_accessible_relation_init_value (GtkAccessibleRelation relation,
|
||||
GValue *value);
|
||||
|
||||
#define GTK_ACCESSIBLE_LIST (gtk_accessible_list_get_type())
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
GType gtk_accessible_list_get_type (void);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
GList * gtk_accessible_list_get_objects (GtkAccessibleList *accessible_list);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
GtkAccessibleList * gtk_accessible_list_new_from_list (GList *list);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
GtkAccessibleList * gtk_accessible_list_new_from_array (GtkAccessible **accessibles,
|
||||
gsize n_accessibles);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
void gtk_accessible_announce (GtkAccessible *self,
|
||||
const char *message,
|
||||
GtkAccessibleAnnouncementPriority priority);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -1332,18 +1332,7 @@ gtk_accessible_value_collect_value (const GtkAccessibleCollect *cstate,
|
||||
GtkAccessibleValueRefListCtor ctor =
|
||||
(GtkAccessibleValueRefListCtor) cstate->ctor;
|
||||
|
||||
GList *value;
|
||||
|
||||
if (g_type_is_a (G_VALUE_TYPE(value_), GTK_ACCESSIBLE_LIST))
|
||||
{
|
||||
GtkAccessibleList *boxed = g_value_get_boxed (value_);
|
||||
|
||||
value = gtk_accessible_list_get_objects (boxed);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = g_value_get_pointer (value_);
|
||||
}
|
||||
GList *value = g_value_get_pointer (value_);
|
||||
|
||||
if (ctor == NULL)
|
||||
{
|
||||
|
||||
+13
-29
@@ -484,9 +484,6 @@ gtk_at_context_get_accessible_parent (GtkATContext *self)
|
||||
return self->accessible_parent;
|
||||
}
|
||||
|
||||
|
||||
static GtkATContext * get_parent_context (GtkATContext *self);
|
||||
|
||||
/*< private >
|
||||
* gtk_at_context_set_accessible_parent:
|
||||
* @self: a `GtkAtContext`
|
||||
@@ -508,16 +505,8 @@ gtk_at_context_set_accessible_parent (GtkATContext *self,
|
||||
|
||||
self->accessible_parent = parent;
|
||||
if (self->accessible_parent != NULL)
|
||||
{
|
||||
GtkATContext *parent_context = NULL;
|
||||
|
||||
g_object_add_weak_pointer (G_OBJECT (self->accessible_parent),
|
||||
(gpointer *) &self->accessible_parent);
|
||||
|
||||
parent_context = get_parent_context (self);
|
||||
if (parent_context && parent_context->realized)
|
||||
gtk_at_context_realize (self);
|
||||
}
|
||||
g_object_add_weak_pointer (G_OBJECT (self->accessible_parent),
|
||||
(gpointer *) &self->accessible_parent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -615,10 +604,14 @@ static const struct {
|
||||
GtkAccessible *accessible,
|
||||
GdkDisplay *display);
|
||||
} a11y_backends[] = {
|
||||
#if defined(GDK_WINDOWING_WAYLAND) || defined(GDK_WINDOWING_X11)
|
||||
{ "AT-SPI", "atspi", gtk_at_spi_create_context },
|
||||
#if defined(GDK_WINDOWING_WAYLAND)
|
||||
{ "AT-SPI (Wayland)", "atspi", gtk_at_spi_create_context },
|
||||
#endif
|
||||
#if defined(GDK_WINDOWING_X11)
|
||||
{ "AT-SPI (X11)", "atspi", gtk_at_spi_create_context },
|
||||
#endif
|
||||
{ "Test", "test", gtk_test_at_context_new },
|
||||
{ NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -641,7 +634,6 @@ gtk_at_context_create (GtkAccessibleRole accessible_role,
|
||||
GdkDisplay *display)
|
||||
{
|
||||
static const char *gtk_a11y_env;
|
||||
GtkATContext *res = NULL;
|
||||
|
||||
if (gtk_a11y_env == NULL)
|
||||
{
|
||||
@@ -669,9 +661,12 @@ gtk_at_context_create (GtkAccessibleRole accessible_role,
|
||||
if (g_ascii_strcasecmp (gtk_a11y_env, "none") == 0)
|
||||
return NULL;
|
||||
|
||||
for (size_t i = 0; i < G_N_ELEMENTS (a11y_backends); i++)
|
||||
GtkATContext *res = NULL;
|
||||
|
||||
for (guint i = 0; i < G_N_ELEMENTS (a11y_backends); i++)
|
||||
{
|
||||
g_assert (a11y_backends[i].name != NULL);
|
||||
if (a11y_backends[i].name == NULL)
|
||||
break;
|
||||
|
||||
if (a11y_backends[i].create_context != NULL &&
|
||||
(*gtk_a11y_env == '0' || g_ascii_strcasecmp (a11y_backends[i].env_name, gtk_a11y_env) == 0))
|
||||
@@ -1473,14 +1468,3 @@ gtk_at_context_child_changed (GtkATContext *self,
|
||||
|
||||
GTK_AT_CONTEXT_GET_CLASS (self)->child_change (self, change, child);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_at_context_announce (GtkATContext *self,
|
||||
const char *message,
|
||||
GtkAccessibleAnnouncementPriority priority)
|
||||
{
|
||||
if (!self->realized)
|
||||
return;
|
||||
|
||||
GTK_AT_CONTEXT_GET_CLASS (self)->announce (self, message, priority);
|
||||
}
|
||||
|
||||
@@ -127,10 +127,6 @@ struct _GtkATContextClass
|
||||
|
||||
void (* realize) (GtkATContext *self);
|
||||
void (* unrealize) (GtkATContext *self);
|
||||
|
||||
void (* announce) (GtkATContext *self,
|
||||
const char *message,
|
||||
GtkAccessibleAnnouncementPriority priority);
|
||||
};
|
||||
|
||||
GtkATContext * gtk_at_context_clone (GtkATContext *self,
|
||||
@@ -197,8 +193,4 @@ void
|
||||
gtk_at_context_set_next_accessible_sibling (GtkATContext *self,
|
||||
GtkAccessible *sibling);
|
||||
|
||||
void gtk_at_context_announce (GtkATContext *self,
|
||||
const char *message,
|
||||
GtkAccessibleAnnouncementPriority priority);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#ifndef __GTKCONFIG_H__
|
||||
#define __GTKCONFIG_H__
|
||||
|
||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#mesondefine GTK_ACCESSIBILITY_ATSPI
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTKCONFIG_H__ */
|
||||
@@ -1801,29 +1801,6 @@ typedef enum { /*< prefix=GTK_ACCESSIBLE_SORT >*/
|
||||
GTK_ACCESSIBLE_SORT_OTHER
|
||||
} GtkAccessibleSort;
|
||||
|
||||
/**
|
||||
* GTK_ANNOUNCEMENT_PRIORITY:
|
||||
* @GTK_ANNOUNCEMENT_PRIORITY_LOW: The announcement is low priority, and might be read only
|
||||
* on the user's request.
|
||||
* @GTK_ANNOUNCEMENT_PRIORITY_MEDIUM: The announcement is of medium priority, and is usually
|
||||
* spoken at the next opportunity, such as at the end of speaking the current sentence
|
||||
* or when the user pauses typing.
|
||||
* @GTK_ANNOUNCEMENT_PRIORITY_HIGH: The announcement is of high priority, and is usually
|
||||
* spoken immediately. Because an interruption might disorient users or cause them to
|
||||
* not complete their current task, authors SHOULD NOT use high priority announcements
|
||||
* unless the interruption is imperative. An example would be a notification about a
|
||||
* critical battery power level.
|
||||
*
|
||||
* The priority of an accessibility announcement.
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
typedef enum {
|
||||
GTK_ACCESSIBLE_ANNOUNCEMENT_PRIORITY_LOW,
|
||||
GTK_ACCESSIBLE_ANNOUNCEMENT_PRIORITY_MEDIUM,
|
||||
GTK_ACCESSIBLE_ANNOUNCEMENT_PRIORITY_HIGH
|
||||
} GtkAccessibleAnnouncementPriority;
|
||||
|
||||
/**
|
||||
* GtkPopoverMenuFlags:
|
||||
* @GTK_POPOVER_MENU_SLIDING: Submenus are presented as sliding submenus that
|
||||
|
||||
+20
-29
@@ -639,7 +639,6 @@ _gtk_file_chooser_extract_recent_folders (GList *infos)
|
||||
GList *l;
|
||||
GList *result;
|
||||
GHashTable *folders;
|
||||
guint counter = 0;
|
||||
|
||||
result = NULL;
|
||||
|
||||
@@ -652,9 +651,6 @@ _gtk_file_chooser_extract_recent_folders (GList *infos)
|
||||
GFile *dir;
|
||||
GFile *file;
|
||||
|
||||
if (counter >= DEFAULT_RECENT_FILES_LIMIT)
|
||||
break;
|
||||
|
||||
if (!gtk_recent_info_is_local (info))
|
||||
continue;
|
||||
|
||||
@@ -678,7 +674,6 @@ _gtk_file_chooser_extract_recent_folders (GList *infos)
|
||||
{
|
||||
g_hash_table_insert (folders, dir, (gpointer) 1);
|
||||
result = g_list_prepend (result, g_object_ref (dir));
|
||||
counter++;
|
||||
}
|
||||
|
||||
g_object_unref (dir);
|
||||
@@ -3723,25 +3718,21 @@ my_g_format_date_for_display (GtkFileChooserWidget *impl,
|
||||
{
|
||||
GDateTime *now, *time;
|
||||
GDateTime *now_date, *date;
|
||||
GTimeZone *tz;
|
||||
const char *format;
|
||||
char *date_str;
|
||||
int days_ago;
|
||||
|
||||
tz = g_time_zone_new_local ();
|
||||
time = g_date_time_new_from_unix_local (secs);
|
||||
date = g_date_time_new (tz,
|
||||
g_date_time_get_year (time),
|
||||
g_date_time_get_month (time),
|
||||
g_date_time_get_day_of_month (time),
|
||||
0, 0, 0);
|
||||
date = g_date_time_new_local (g_date_time_get_year (time),
|
||||
g_date_time_get_month (time),
|
||||
g_date_time_get_day_of_month (time),
|
||||
0, 0, 0);
|
||||
|
||||
now = g_date_time_new_now (tz);
|
||||
now_date = g_date_time_new (tz,
|
||||
g_date_time_get_year (now),
|
||||
g_date_time_get_month (now),
|
||||
g_date_time_get_day_of_month (now),
|
||||
0, 0, 0);
|
||||
now = g_date_time_new_now_local ();
|
||||
now_date = g_date_time_new_local (g_date_time_get_year (now),
|
||||
g_date_time_get_month (now),
|
||||
g_date_time_get_day_of_month (now),
|
||||
0, 0, 0);
|
||||
days_ago = g_date_time_difference (now_date, date) / G_TIME_SPAN_DAY;
|
||||
|
||||
if (days_ago < 1)
|
||||
@@ -5933,7 +5924,6 @@ recent_start_loading (GtkFileChooserWidget *impl)
|
||||
{
|
||||
const int limit = DEFAULT_RECENT_FILES_LIMIT;
|
||||
const char *app_name = g_get_application_name ();
|
||||
GList *files = NULL;
|
||||
GList *l;
|
||||
int n;
|
||||
|
||||
@@ -5951,30 +5941,31 @@ recent_start_loading (GtkFileChooserWidget *impl)
|
||||
!gtk_recent_info_has_application (info, app_name))
|
||||
continue;
|
||||
|
||||
|
||||
file = g_file_new_for_uri (gtk_recent_info_get_uri (info));
|
||||
files = g_list_prepend (files, file);
|
||||
_gtk_file_system_model_add_and_query_file (impl->recent_model,
|
||||
file,
|
||||
MODEL_ATTRIBUTES);
|
||||
g_object_unref (file);
|
||||
|
||||
n++;
|
||||
if (limit != -1 && n >= limit)
|
||||
break;
|
||||
}
|
||||
|
||||
files = g_list_reverse (files);
|
||||
_gtk_file_system_model_add_and_query_files (impl->recent_model,
|
||||
files,
|
||||
MODEL_ATTRIBUTES);
|
||||
g_list_free_full (files, g_object_unref);
|
||||
|
||||
g_set_object (&impl->model_for_search, impl->recent_model);
|
||||
}
|
||||
else
|
||||
{
|
||||
GList *folders;
|
||||
GList *l;
|
||||
|
||||
folders = _gtk_file_chooser_extract_recent_folders (items);
|
||||
_gtk_file_system_model_add_and_query_files (impl->recent_model,
|
||||
folders,
|
||||
MODEL_ATTRIBUTES);
|
||||
|
||||
for (l = folders; l; l = l->next)
|
||||
_gtk_file_system_model_add_and_query_file (impl->recent_model,
|
||||
G_FILE (l->data),
|
||||
MODEL_ATTRIBUTES);
|
||||
|
||||
g_list_free_full (folders, g_object_unref);
|
||||
}
|
||||
|
||||
+30
-11
@@ -770,21 +770,15 @@ NSArray * _gtk_file_filter_get_as_pattern_nsstrings (GtkFileFilter *filter)
|
||||
switch (rule->type)
|
||||
{
|
||||
case FILTER_RULE_MIME_TYPE:
|
||||
case FILTER_RULE_PIXBUF_FORMATS:
|
||||
{
|
||||
int i;
|
||||
|
||||
// GContentType from GIO use UTI on macOS since glib version 2.51
|
||||
for (i = 0; rule->u.content_types[i] != NULL; i++)
|
||||
NSString *uti_nsstring = [NSString stringWithUTF8String: rule->u.content_types[0]];
|
||||
if (uti_nsstring == NULL)
|
||||
{
|
||||
NSString *uti_nsstring = [NSString stringWithUTF8String: rule->u.content_types[i]];
|
||||
if (uti_nsstring == NULL)
|
||||
{
|
||||
[array release];
|
||||
return NULL;
|
||||
}
|
||||
[array addObject:uti_nsstring];
|
||||
[array release];
|
||||
return NULL;
|
||||
}
|
||||
[array addObject:uti_nsstring];
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -804,9 +798,34 @@ NSArray * _gtk_file_filter_get_as_pattern_nsstrings (GtkFileFilter *filter)
|
||||
char *pattern_c = g_string_free (pattern, FALSE);
|
||||
NSString *pattern_nsstring = [NSString stringWithUTF8String:pattern_c];
|
||||
g_free (pattern_c);
|
||||
[pattern_nsstring retain];
|
||||
[array addObject:pattern_nsstring];
|
||||
}
|
||||
break;
|
||||
|
||||
case FILTER_RULE_PIXBUF_FORMATS:
|
||||
{
|
||||
GSList *formats, *l;
|
||||
|
||||
formats = gdk_pixbuf_get_formats ();
|
||||
for (l = formats; l; l = l->next)
|
||||
{
|
||||
int i;
|
||||
char **extensions;
|
||||
|
||||
extensions = gdk_pixbuf_format_get_extensions (l->data);
|
||||
|
||||
for (i = 0; extensions[i] != NULL; i++)
|
||||
{
|
||||
NSString *extension = [NSString stringWithUTF8String: extensions[i]];
|
||||
[extension retain];
|
||||
[array addObject:extension];
|
||||
}
|
||||
g_strfreev (extensions);
|
||||
}
|
||||
g_slist_free (formats);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return array;
|
||||
|
||||
@@ -117,6 +117,7 @@ gtk_list_item_change_release (GtkListItemChange *change,
|
||||
if (!g_hash_table_replace (change->deleted_items, gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (widget)), widget))
|
||||
{
|
||||
g_warning ("Duplicate item detected in list. Picking one randomly.");
|
||||
gtk_list_item_change_recycle (change, widget);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -967,26 +968,10 @@ gtk_list_item_manager_add_items (GtkListItemManager *self,
|
||||
|
||||
if (section != NULL && section->type == GTK_LIST_TILE_HEADER)
|
||||
{
|
||||
guint start, end;
|
||||
GtkListTile *footer = gtk_list_tile_get_footer (self, section);
|
||||
GtkListTile *previous_footer = gtk_list_tile_get_previous_skip (section);
|
||||
|
||||
gtk_section_model_get_section (GTK_SECTION_MODEL (self->model), position, &start, &end);
|
||||
|
||||
if (previous_footer != NULL && previous_footer->type == GTK_LIST_TILE_FOOTER &&
|
||||
position > start && position < end)
|
||||
{
|
||||
gtk_list_item_change_clear_header (change, §ion->widget);
|
||||
gtk_list_tile_set_type (section, GTK_LIST_TILE_REMOVED);
|
||||
gtk_list_tile_set_type (previous_footer, GTK_LIST_TILE_REMOVED);
|
||||
|
||||
section = gtk_list_tile_get_header (self, previous_footer);
|
||||
}
|
||||
|
||||
gtk_list_item_change_clear_header (change, §ion->widget);
|
||||
gtk_list_tile_set_type (section,
|
||||
GTK_LIST_TILE_UNMATCHED_HEADER);
|
||||
gtk_list_tile_set_type (footer,
|
||||
gtk_list_tile_set_type (gtk_list_tile_get_footer (self, section),
|
||||
GTK_LIST_TILE_UNMATCHED_FOOTER);
|
||||
}
|
||||
}
|
||||
@@ -1625,7 +1610,7 @@ gtk_list_item_manager_model_sections_changed_cb (GListModel *model,
|
||||
gtk_list_item_change_clear_header (&change, &header->widget);
|
||||
gtk_list_tile_set_type (header, GTK_LIST_TILE_UNMATCHED_HEADER);
|
||||
|
||||
n_items += offset;
|
||||
n_items -= MIN (n_items, position - offset);
|
||||
while (n_items > 0)
|
||||
{
|
||||
switch (tile->type)
|
||||
|
||||
+6
-10
@@ -1553,7 +1553,7 @@ is_transient_for (GtkWindow *child,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
void
|
||||
gtk_main_do_event (GdkEvent *event)
|
||||
{
|
||||
GtkWidget *event_widget;
|
||||
@@ -1562,10 +1562,9 @@ gtk_main_do_event (GdkEvent *event)
|
||||
GtkWindowGroup *window_group;
|
||||
GdkEvent *rewritten_event = NULL;
|
||||
GList *tmp_list;
|
||||
gboolean handled_event = FALSE;
|
||||
|
||||
if (gtk_inspector_handle_event (event))
|
||||
return FALSE;
|
||||
return;
|
||||
|
||||
/* Find the widget which got the event. We store the widget
|
||||
* in the user_data field of GdkSurface's. Ignore the event
|
||||
@@ -1573,7 +1572,7 @@ gtk_main_do_event (GdkEvent *event)
|
||||
*/
|
||||
event_widget = gtk_get_event_widget (event);
|
||||
if (!event_widget)
|
||||
return FALSE;
|
||||
return;
|
||||
|
||||
target_widget = event_widget;
|
||||
|
||||
@@ -1651,7 +1650,6 @@ gtk_main_do_event (GdkEvent *event)
|
||||
if (GTK_IS_WINDOW (target_widget) &&
|
||||
!gtk_window_emit_close_request (GTK_WINDOW (target_widget)))
|
||||
gtk_window_destroy (GTK_WINDOW (target_widget));
|
||||
handled_event = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1659,7 +1657,7 @@ gtk_main_do_event (GdkEvent *event)
|
||||
{
|
||||
GtkWidget *root = GTK_WIDGET (gtk_widget_get_root (target_widget));
|
||||
if (!_gtk_widget_captured_event (root, event, root))
|
||||
handled_event = gtk_widget_event (root, event, root);
|
||||
gtk_widget_event (root, event, root);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1684,7 +1682,7 @@ gtk_main_do_event (GdkEvent *event)
|
||||
case GDK_PAD_STRIP:
|
||||
case GDK_PAD_GROUP_MODE:
|
||||
case GDK_GRAB_BROKEN:
|
||||
handled_event = gtk_propagate_event (grab_widget, event);
|
||||
gtk_propagate_event (grab_widget, event);
|
||||
break;
|
||||
|
||||
case GDK_ENTER_NOTIFY:
|
||||
@@ -1692,7 +1690,6 @@ gtk_main_do_event (GdkEvent *event)
|
||||
case GDK_DRAG_ENTER:
|
||||
case GDK_DRAG_LEAVE:
|
||||
/* Crossing event propagation happens during picking */
|
||||
handled_event = TRUE;
|
||||
break;
|
||||
|
||||
case GDK_DRAG_MOTION:
|
||||
@@ -1700,7 +1697,7 @@ gtk_main_do_event (GdkEvent *event)
|
||||
{
|
||||
GdkDrop *drop = gdk_dnd_event_get_drop (event);
|
||||
gtk_drop_begin_event (drop, gdk_event_get_event_type (event));
|
||||
handled_event = gtk_propagate_event (grab_widget, event);
|
||||
gtk_propagate_event (grab_widget, event);
|
||||
gtk_drop_end_event (drop);
|
||||
}
|
||||
break;
|
||||
@@ -1722,7 +1719,6 @@ gtk_main_do_event (GdkEvent *event)
|
||||
|
||||
if (rewritten_event)
|
||||
gdk_event_unref (rewritten_event);
|
||||
return handled_event;
|
||||
}
|
||||
|
||||
static GtkWindowGroup *
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@
|
||||
* GTK provides a GIO extension point for `GtkMediaFile` implementations
|
||||
* to allow for external implementations using various media frameworks.
|
||||
*
|
||||
* GTK itself includes an implementation using GStreamer.
|
||||
* GTK itself includes implementations using GStreamer and ffmpeg.
|
||||
*/
|
||||
|
||||
typedef struct _GtkMediaFilePrivate GtkMediaFilePrivate;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user