Compare commits

..

3 Commits

Author SHA1 Message Date
Matthias Clasen fcf504905a Add an simd implementation
This is strongly based on graphenes simd plumbing.
All three types get represented as graphene_simf4d_t,
scale as {x,y,0,0}, point as {x,y,0,0} and box as
{x0,y0,x1,y1}.
2024-01-24 22:01:28 -05:00
Matthias Clasen b84150a580 wip: Use the new types
This is just converting the glyph node handling, for starters.
2024-01-24 21:58:07 -05:00
Matthias Clasen 415539b02f Add private Scale, Point, Box types
This is the most straightforward, plain C implementation one could
come up with, to start with something obviously correct.
2024-01-24 21:58:07 -05:00
145 changed files with 3547 additions and 4188 deletions
+1 -2
View File
@@ -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 -121
View File
@@ -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
=========================================
+46 -59
View File
@@ -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"))
{
-1
View File
@@ -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>
-2
View File
@@ -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"
-2
View File
@@ -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"
-2
View File
@@ -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",
-2
View File
@@ -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",
+1 -1
View File
@@ -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
-2
View File
@@ -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",
+4 -11
View File
@@ -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

-12
View File
@@ -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

+1 -1
View File
@@ -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" },
+1 -1
View File
@@ -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
View File
@@ -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,
-2
View File
@@ -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);
-2
View File
@@ -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
View File
@@ -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;
}
-38
View File
@@ -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;
}
-4
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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);
}
/*********************************************
+9 -9
View File
@@ -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
View File
@@ -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
View File
@@ -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 youre 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
-2
View File
@@ -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
+1 -5
View File
@@ -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
View File
@@ -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);
}
+1 -4
View File
@@ -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;
+2 -6
View File
@@ -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);
-3
View File
@@ -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
View File
@@ -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;
+7 -15
View File
@@ -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];
}
-6
View File
@@ -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;
-1
View File
@@ -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 *
+1 -8
View File
@@ -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);
}
-6
View File
@@ -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;
+33 -47
View File
@@ -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))
+2 -1
View File
@@ -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);
+5 -4
View File
@@ -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;
-1
View File
@@ -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
+16 -2
View File
@@ -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);
+10 -25
View File
@@ -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,
-6
View File
@@ -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;
}
-1
View File
@@ -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
-6
View File
@@ -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
-7
View File
@@ -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;
}
-6
View File
@@ -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
-5
View File
@@ -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;
+1 -4
View File
@@ -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]);
}
+479
View File
@@ -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
+1 -8
View File
@@ -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;
}
+1 -9
View File
@@ -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);
}
-1
View File
@@ -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);
-6
View File
@@ -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;
-1
View File
@@ -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);
+39
View File
@@ -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;
}
+9 -1
View File
@@ -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
View File
@@ -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,
+4 -5
View File
@@ -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);
+1 -1
View File
@@ -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);
+2 -2
View File
@@ -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
View File
@@ -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))
{
+8 -17
View File
@@ -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);
+1 -4
View File
@@ -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,
+1 -2
View File
@@ -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 {
-1
View File
@@ -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));
+1 -20
View File
@@ -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
+3 -3
View File
@@ -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,
+3 -34
View File
@@ -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
View File
@@ -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));
-27
View File
@@ -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;
}
/**
+6 -7
View File
@@ -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);
}
+22
View File
@@ -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;
+252
View File
@@ -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
+183
View File
@@ -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
View File
@@ -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;
}
+9 -70
View File
@@ -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;
-5
View File
@@ -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;
+1 -1
View File
@@ -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
-480
View File
@@ -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;
}
-48
View File
@@ -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
-34
View File
@@ -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
+2 -4
View File
@@ -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;
-10
View File
@@ -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
-1
View File
@@ -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>
-125
View File
@@ -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`
-29
View File
@@ -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
+1 -12
View File
@@ -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
View File
@@ -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);
}
-8
View File
@@ -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
-16
View File
@@ -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__ */
-23
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+3 -18
View File
@@ -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, &section->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, &section->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
View File
@@ -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
View File
@@ -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