Compare commits
93 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d7d75f0b26 | |||
| 40ac37245d | |||
| 250414d6b3 | |||
| d69cdf6c05 | |||
| 9532657fa2 | |||
| 3cb2115212 | |||
| dd7c85adc3 | |||
| 8965d6c7f8 | |||
| d7309a009c | |||
| b6fac448d7 | |||
| 765f55dfbe | |||
| bebaad3e1f | |||
| db6a116d49 | |||
| a299656c60 | |||
| 27fd0b907d | |||
| 62951c7277 | |||
| 8e00f6e5e5 | |||
| ff141a1ed4 | |||
| 25a10f502e | |||
| 585fb497c1 | |||
| c57e5811f1 | |||
| 940a2b6923 | |||
| 3277e2ee3e | |||
| 3e8489fea5 | |||
| 1035640020 | |||
| 6cee73d100 | |||
| e4c43901c1 | |||
| c7f30ecdfd | |||
| b64f7050ba | |||
| d37b9619e2 | |||
| 4a22e681b3 | |||
| 189aced844 | |||
| d90cb02570 | |||
| 4246c7bafd | |||
| d67101d46e | |||
| 60f3cc398a | |||
| e010cd242c | |||
| 41454b63b4 | |||
| f458951745 | |||
| ef3793ec37 | |||
| 94b1a78378 | |||
| 584fd36a5f | |||
| 64a1969293 | |||
| 2baab9732c | |||
| 8134daf843 | |||
| 9c013d40c1 | |||
| d798372a53 | |||
| cfaf1b3e71 | |||
| 9763d83a9d | |||
| 5f82a496cb | |||
| 0c35015c44 | |||
| 3da0572078 | |||
| c649d8a4ec | |||
| 75bea01a86 | |||
| 5d3cec5441 | |||
| 891242920e | |||
| b375f17f09 | |||
| ec69990126 | |||
| aec5a5739e | |||
| ac9e0039b8 | |||
| 4574b21fd6 | |||
| 31c5961c4f | |||
| 8fc3f06155 | |||
| 5327203201 | |||
| 8442fce962 | |||
| d8b46c16cc | |||
| 4df7273266 | |||
| 2b8fd89fd5 | |||
| 5b9a7863cf | |||
| d625ff8106 | |||
| 5ecd8a1c10 | |||
| e9f7a9b8e6 | |||
| 93b1130c07 | |||
| db48cd6467 | |||
| ba43a126b9 | |||
| 2a70093a30 | |||
| dd407dab00 | |||
| ccae75022b | |||
| faac2f7894 | |||
| d00b78d283 | |||
| 3eee1c0724 | |||
| 5e6bc681a3 | |||
| 87e16f3ad9 | |||
| aa9e83876d | |||
| d8796b3075 | |||
| cefd720789 | |||
| e12669e230 | |||
| 7f906bef06 | |||
| 5970a14217 | |||
| 2c3f82fd01 | |||
| 5f4a6210c2 | |||
| c0fa9e80aa | |||
| 2fde4c9a5f |
+26
-8
@@ -24,6 +24,7 @@ typedef struct
|
||||
GdkRGBA draw_color;
|
||||
GtkPadController *pad_controller;
|
||||
double brush_size;
|
||||
GtkGesture *gesture;
|
||||
} DrawingArea;
|
||||
|
||||
typedef struct
|
||||
@@ -260,7 +261,7 @@ drawing_area_apply_stroke (DrawingArea *area,
|
||||
double y,
|
||||
double pressure)
|
||||
{
|
||||
if (gdk_device_tool_get_tool_type (tool) == GDK_DEVICE_TOOL_TYPE_ERASER)
|
||||
if (tool && gdk_device_tool_get_tool_type (tool) == GDK_DEVICE_TOOL_TYPE_ERASER)
|
||||
{
|
||||
cairo_set_line_width (area->cr, 10 * pressure * area->brush_size);
|
||||
cairo_set_operator (area->cr, CAIRO_OPERATOR_DEST_OUT);
|
||||
@@ -311,7 +312,9 @@ stylus_gesture_motion (GtkGestureStylus *gesture,
|
||||
drawing_area_apply_stroke (area, tool,
|
||||
backlog[i].axes[GDK_AXIS_X],
|
||||
backlog[i].axes[GDK_AXIS_Y],
|
||||
backlog[i].axes[GDK_AXIS_PRESSURE]);
|
||||
backlog[i].flags & GDK_AXIS_FLAG_PRESSURE
|
||||
? backlog[i].axes[GDK_AXIS_PRESSURE]
|
||||
: 1);
|
||||
}
|
||||
|
||||
g_free (backlog);
|
||||
@@ -341,6 +344,8 @@ drawing_area_init (DrawingArea *area)
|
||||
|
||||
area->draw_color = (GdkRGBA) { 0, 0, 0, 1 };
|
||||
area->brush_size = 1;
|
||||
|
||||
area->gesture = gesture;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
@@ -379,6 +384,12 @@ drawing_area_color_set (DrawingArea *area,
|
||||
gtk_color_dialog_button_set_rgba (button, color);
|
||||
}
|
||||
|
||||
static GtkGesture *
|
||||
drawing_area_get_gesture (DrawingArea *area)
|
||||
{
|
||||
return area->gesture;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_paint (GtkWidget *toplevel)
|
||||
{
|
||||
@@ -386,7 +397,7 @@ do_paint (GtkWidget *toplevel)
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *draw_area, *headerbar, *colorbutton;
|
||||
GtkWidget *draw_area, *headerbar, *button;
|
||||
|
||||
window = gtk_window_new ();
|
||||
|
||||
@@ -395,15 +406,22 @@ do_paint (GtkWidget *toplevel)
|
||||
|
||||
headerbar = gtk_header_bar_new ();
|
||||
|
||||
colorbutton = gtk_color_dialog_button_new (gtk_color_dialog_new ());
|
||||
g_signal_connect (colorbutton, "notify::rgba",
|
||||
button = gtk_color_dialog_button_new (gtk_color_dialog_new ());
|
||||
g_signal_connect (button, "notify::rgba",
|
||||
G_CALLBACK (color_button_color_set), draw_area);
|
||||
g_signal_connect (draw_area, "color-set",
|
||||
G_CALLBACK (drawing_area_color_set), colorbutton);
|
||||
gtk_color_dialog_button_set_rgba (GTK_COLOR_DIALOG_BUTTON (colorbutton),
|
||||
G_CALLBACK (drawing_area_color_set), button);
|
||||
gtk_color_dialog_button_set_rgba (GTK_COLOR_DIALOG_BUTTON (button),
|
||||
&(GdkRGBA) { 0, 0, 0, 1 });
|
||||
|
||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (headerbar), colorbutton);
|
||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (headerbar), button);
|
||||
|
||||
button = gtk_check_button_new_with_label ("Stylus only");
|
||||
g_object_bind_property (button, "active",
|
||||
drawing_area_get_gesture ((DrawingArea *)draw_area), "stylus-only",
|
||||
G_BINDING_SYNC_CREATE);
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (headerbar), button);
|
||||
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), headerbar);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Paint");
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
GSK render nodes can be serialized and deserialized using APIs such as `gsk_render_node_serialize()` and `gsk_render_node_deserialize()`. The intended use for this is development - primarily the development of GTK - by allowing things such as creating testsuites and benchmarks, exchanging nodes in bug reports. GTK includes the `gtk4-node-editor` application for creating such test files.
|
||||
|
||||
The format is a text format that follows the [CSS syntax rules](https://drafts.csswg.org/css-syntax-3/). In particular, this means that every array of bytes will produce a render node when parsed, as there is a defined error recovery method. For more details on error handling, please refer to the documentation of the aprsing APIs.
|
||||
The format is a text format that follows the [CSS syntax rules](https://drafts.csswg.org/css-syntax-3/). In particular, this means that every array of bytes will produce a render node when parsed, as there is a defined error recovery method. For more details on error handling, please refer to the documentation of the parsing APIs.
|
||||
|
||||
The grammar of a node text representation using [the CSS value definition syntax](https://drafts.csswg.org/css-values-3/#value-defs) looks like this:
|
||||
**document**: `<node>\*`
|
||||
@@ -23,7 +23,7 @@ Nodes can be given a name by adding a string after the `<node-type>` in their de
|
||||
|
||||
### Textures
|
||||
|
||||
Just like nodes, textures can be referenced by name. When definining the named texture, the name has to be placed in front of the URL.
|
||||
Just like nodes, textures can be referenced by name. When defining a named texture, the name has to be placed in front of the URL.
|
||||
|
||||
# Nodes
|
||||
|
||||
|
||||
@@ -291,16 +291,6 @@ _gdk_broadway_display_create_surface (GdkDisplay *display,
|
||||
return surface;
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
gdk_broadway_surface_ref_cairo_surface (GdkSurface *surface)
|
||||
{
|
||||
if (GDK_IS_BROADWAY_SURFACE (surface) &&
|
||||
GDK_SURFACE_DESTROYED (surface))
|
||||
return NULL;
|
||||
|
||||
return cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_broadway_surface_destroy (GdkSurface *surface,
|
||||
gboolean foreign_destroy)
|
||||
@@ -1254,7 +1244,6 @@ gdk_broadway_surface_class_init (GdkBroadwaySurfaceClass *klass)
|
||||
|
||||
object_class->finalize = gdk_broadway_surface_finalize;
|
||||
|
||||
impl_class->ref_cairo_surface = gdk_broadway_surface_ref_cairo_surface;
|
||||
impl_class->hide = gdk_broadway_surface_hide;
|
||||
impl_class->get_geometry = gdk_broadway_surface_get_geometry;
|
||||
impl_class->get_root_coords = gdk_broadway_surface_get_root_coords;
|
||||
|
||||
@@ -1723,8 +1723,6 @@ gdk_display_init_egl (GdkDisplay *self,
|
||||
epoxy_has_egl_extension (priv->egl_display, "EGL_KHR_no_config_context");
|
||||
self->have_egl_pixel_format_float =
|
||||
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_pixel_format_float");
|
||||
self->have_egl_win32_libangle =
|
||||
epoxy_has_egl_extension (priv->egl_display, "EGL_ANGLE_d3d_share_handle_client_buffer");
|
||||
|
||||
if (self->have_egl_no_config_context)
|
||||
priv->egl_config_high_depth = gdk_display_create_egl_config (self,
|
||||
|
||||
@@ -108,7 +108,6 @@ struct _GdkDisplay
|
||||
guint have_egl_buffer_age : 1;
|
||||
guint have_egl_no_config_context : 1;
|
||||
guint have_egl_pixel_format_float : 1;
|
||||
guint have_egl_win32_libangle : 1;
|
||||
};
|
||||
|
||||
struct _GdkDisplayClass
|
||||
|
||||
+2
-12
@@ -297,7 +297,6 @@ gdk_gl_context_create_egl_context (GdkGLContext *context,
|
||||
/* We will use the default version matching the context status
|
||||
* unless the user requested a version which makes sense */
|
||||
gdk_gl_context_get_matching_version (api, legacy,
|
||||
display->have_egl_win32_libangle,
|
||||
&min_major, &min_minor);
|
||||
gdk_gl_context_get_clipped_version (context,
|
||||
min_major, min_minor,
|
||||
@@ -989,7 +988,6 @@ gdk_gl_context_get_forward_compatible (GdkGLContext *context)
|
||||
void
|
||||
gdk_gl_context_get_matching_version (GdkGLAPI api,
|
||||
gboolean legacy,
|
||||
gboolean win32_libangle,
|
||||
int *major,
|
||||
int *minor)
|
||||
{
|
||||
@@ -1010,16 +1008,8 @@ gdk_gl_context_get_matching_version (GdkGLAPI api,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (win32_libangle)
|
||||
{
|
||||
maj = GDK_GL_MIN_GLES_WIN32_ANGLE_VERSION_MAJOR;
|
||||
min = GDK_GL_MIN_GLES_WIN32_ANGLE_VERSION_MINOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
maj = GDK_GL_MIN_GLES_VERSION_MAJOR;
|
||||
min = GDK_GL_MIN_GLES_VERSION_MINOR;
|
||||
}
|
||||
maj = GDK_GL_MIN_GLES_VERSION_MAJOR;
|
||||
min = GDK_GL_MIN_GLES_VERSION_MINOR;
|
||||
}
|
||||
|
||||
if (major != NULL)
|
||||
|
||||
@@ -36,8 +36,7 @@ G_BEGIN_DECLS
|
||||
* Backends should make sure to never create a context of a previous version.
|
||||
*
|
||||
* The macros refer to OpenGL; OpenGL with OPENGL_COMPATIBILITY_PROFILE_BIT as
|
||||
* OPENGL_PROFILE_MASK; OpenGL ES; and OpenGL ES win32 Angle implementation,
|
||||
* respectively
|
||||
* OPENGL_PROFILE_MASK; and OpenGL ES respectively
|
||||
*/
|
||||
#define GDK_GL_MIN_GL_VERSION_MAJOR (3)
|
||||
#define GDK_GL_MIN_GL_VERSION_MINOR (2)
|
||||
@@ -45,8 +44,6 @@ G_BEGIN_DECLS
|
||||
#define GDK_GL_MIN_GL_LEGACY_VERSION_MINOR (0)
|
||||
#define GDK_GL_MIN_GLES_VERSION_MAJOR (2)
|
||||
#define GDK_GL_MIN_GLES_VERSION_MINOR (0)
|
||||
#define GDK_GL_MIN_GLES_WIN32_ANGLE_VERSION_MAJOR (3)
|
||||
#define GDK_GL_MIN_GLES_WIN32_ANGLE_VERSION_MINOR (0)
|
||||
|
||||
typedef enum {
|
||||
GDK_GL_NONE = 0,
|
||||
@@ -100,7 +97,6 @@ typedef struct {
|
||||
} GdkGLContextProgram;
|
||||
|
||||
typedef struct {
|
||||
guint vertex_array_object;
|
||||
guint tmp_framebuffer;
|
||||
guint tmp_vertex_buffer;
|
||||
|
||||
@@ -140,7 +136,6 @@ void gdk_gl_context_get_clipped_version (GdkGLContext
|
||||
int *minor);
|
||||
void gdk_gl_context_get_matching_version (GdkGLAPI api,
|
||||
gboolean legacy,
|
||||
gboolean win32_libangle,
|
||||
int *major,
|
||||
int *minor);
|
||||
|
||||
|
||||
+8
-3
@@ -131,6 +131,8 @@ struct _Download
|
||||
|
||||
static gboolean
|
||||
gdk_gl_texture_find_format (gboolean use_es,
|
||||
guint gl_major,
|
||||
guint gl_minor,
|
||||
GLint gl_format,
|
||||
GLint gl_type,
|
||||
GdkMemoryFormat *out_format)
|
||||
@@ -141,7 +143,7 @@ gdk_gl_texture_find_format (gboolean use_es,
|
||||
{
|
||||
GLenum q_internal_format, q_format, q_type;
|
||||
|
||||
if (!gdk_memory_format_gl_format (format, use_es, &q_internal_format, &q_format, &q_type))
|
||||
if (!gdk_memory_format_gl_format (format, use_es, gl_major, gl_minor, &q_internal_format, &q_format, &q_type))
|
||||
continue;
|
||||
|
||||
if (q_format != gl_format || q_type != gl_type)
|
||||
@@ -163,12 +165,14 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
|
||||
gsize expected_stride;
|
||||
Download *download = download_;
|
||||
GLenum gl_internal_format, gl_format, gl_type;
|
||||
int major, minor;
|
||||
|
||||
expected_stride = texture->width * gdk_memory_format_bytes_per_pixel (download->format);
|
||||
gdk_gl_context_get_version (context, &major, &minor);
|
||||
|
||||
if (download->stride == expected_stride &&
|
||||
!gdk_gl_context_get_use_es (context) &&
|
||||
gdk_memory_format_gl_format (download->format, TRUE, &gl_internal_format, &gl_format, &gl_type))
|
||||
gdk_memory_format_gl_format (download->format, TRUE, major, minor, &gl_internal_format, &gl_format, &gl_type))
|
||||
{
|
||||
glGetTexImage (GL_TEXTURE_2D,
|
||||
0,
|
||||
@@ -187,9 +191,10 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
|
||||
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->id, 0);
|
||||
if (gdk_gl_context_check_version (context, 4, 3, 3, 1))
|
||||
{
|
||||
gdk_gl_context_get_version (context, &major, &minor);
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &gl_read_format);
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &gl_read_type);
|
||||
if (!gdk_gl_texture_find_format (gdk_gl_context_get_use_es (context), gl_read_format, gl_read_type, &actual_format))
|
||||
if (!gdk_gl_texture_find_format (gdk_gl_context_get_use_es (context), major, minor, gl_read_format, gl_read_type, &actual_format))
|
||||
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; /* pray */
|
||||
}
|
||||
else
|
||||
|
||||
+40
-21
@@ -220,7 +220,12 @@ struct _GdkMemoryFormatDescription
|
||||
gsize bytes_per_pixel;
|
||||
gsize alignment;
|
||||
gboolean prefers_high_depth;
|
||||
gboolean supports_gles;
|
||||
struct {
|
||||
guint gl_major;
|
||||
guint gl_minor;
|
||||
guint gles_major;
|
||||
guint gles_minor;
|
||||
} min_gl_version;
|
||||
struct {
|
||||
guint internal_format;
|
||||
guint format;
|
||||
@@ -245,7 +250,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
4,
|
||||
G_ALIGNOF (guchar),
|
||||
FALSE,
|
||||
FALSE,
|
||||
{ 0, 0, G_MAXUINT, G_MAXUINT },
|
||||
{ GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE },
|
||||
b8g8r8a8_premultiplied_to_float,
|
||||
b8g8r8a8_premultiplied_from_float,
|
||||
@@ -255,7 +260,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
4,
|
||||
G_ALIGNOF (guchar),
|
||||
FALSE,
|
||||
FALSE,
|
||||
{ 0, 0, G_MAXUINT, G_MAXUINT },
|
||||
{ GL_RGBA8, GL_BGRA, GDK_GL_UNSIGNED_BYTE_FLIPPED },
|
||||
a8r8g8b8_premultiplied_to_float,
|
||||
a8r8g8b8_premultiplied_from_float,
|
||||
@@ -265,7 +270,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
4,
|
||||
G_ALIGNOF (guchar),
|
||||
FALSE,
|
||||
TRUE,
|
||||
{ 0, 0, 0, 0 },
|
||||
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE },
|
||||
r8g8b8a8_premultiplied_to_float,
|
||||
r8g8b8a8_premultiplied_from_float,
|
||||
@@ -275,7 +280,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
4,
|
||||
G_ALIGNOF (guchar),
|
||||
FALSE,
|
||||
FALSE,
|
||||
{ 0, 0, G_MAXUINT, G_MAXUINT },
|
||||
{ GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE },
|
||||
b8g8r8a8_to_float,
|
||||
b8g8r8a8_from_float,
|
||||
@@ -285,7 +290,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
4,
|
||||
G_ALIGNOF (guchar),
|
||||
FALSE,
|
||||
FALSE,
|
||||
{ 0, 0, G_MAXUINT, G_MAXUINT },
|
||||
{ GL_RGBA8, GL_RGBA, GDK_GL_UNSIGNED_BYTE_FLIPPED },
|
||||
a8r8g8b8_to_float,
|
||||
a8r8g8b8_from_float,
|
||||
@@ -295,7 +300,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
4,
|
||||
G_ALIGNOF (guchar),
|
||||
FALSE,
|
||||
TRUE,
|
||||
{ 0, 0, 0, 0 },
|
||||
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE },
|
||||
r8g8b8a8_to_float,
|
||||
r8g8b8a8_from_float,
|
||||
@@ -305,7 +310,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
4,
|
||||
G_ALIGNOF (guchar),
|
||||
FALSE,
|
||||
FALSE,
|
||||
{ 0, 0, G_MAXUINT, G_MAXUINT },
|
||||
{ GL_RGBA8, GL_BGRA, GDK_GL_UNSIGNED_BYTE_FLIPPED },
|
||||
a8b8g8r8_to_float,
|
||||
a8b8g8r8_from_float,
|
||||
@@ -315,7 +320,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
3,
|
||||
G_ALIGNOF (guchar),
|
||||
FALSE,
|
||||
TRUE,
|
||||
{ 0, 0, 0, 0 },
|
||||
{ GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE },
|
||||
r8g8b8_to_float,
|
||||
r8g8b8_from_float,
|
||||
@@ -325,7 +330,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
3,
|
||||
G_ALIGNOF (guchar),
|
||||
FALSE,
|
||||
FALSE,
|
||||
{ 0, 0, G_MAXUINT, G_MAXUINT },
|
||||
{ GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE },
|
||||
b8g8r8_to_float,
|
||||
b8g8r8_from_float,
|
||||
@@ -335,7 +340,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
6,
|
||||
G_ALIGNOF (guint16),
|
||||
TRUE,
|
||||
TRUE,
|
||||
{ 0, 0, 3, 0 },
|
||||
{ GL_RGB16, GL_RGB, GL_UNSIGNED_SHORT },
|
||||
r16g16b16_to_float,
|
||||
r16g16b16_from_float,
|
||||
@@ -345,7 +350,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
8,
|
||||
G_ALIGNOF (guint16),
|
||||
TRUE,
|
||||
TRUE,
|
||||
{ 0, 0, 3, 0 },
|
||||
{ GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT },
|
||||
r16g16b16a16_to_float,
|
||||
r16g16b16a16_from_float,
|
||||
@@ -355,7 +360,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
8,
|
||||
G_ALIGNOF (guint16),
|
||||
TRUE,
|
||||
TRUE,
|
||||
{ 0, 0, 3, 0 },
|
||||
{ GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT },
|
||||
r16g16b16a16_to_float,
|
||||
r16g16b16a16_from_float,
|
||||
@@ -365,7 +370,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
6,
|
||||
G_ALIGNOF (guint16),
|
||||
TRUE,
|
||||
TRUE,
|
||||
{ 0, 0, 3, 0 },
|
||||
{ GL_RGB16F, GL_RGB, GL_HALF_FLOAT },
|
||||
r16g16b16_float_to_float,
|
||||
r16g16b16_float_from_float,
|
||||
@@ -375,7 +380,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
8,
|
||||
G_ALIGNOF (guint16),
|
||||
TRUE,
|
||||
TRUE,
|
||||
{ 0, 0, 3, 0 },
|
||||
{ GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT },
|
||||
r16g16b16a16_float_to_float,
|
||||
r16g16b16a16_float_from_float,
|
||||
@@ -385,7 +390,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
8,
|
||||
G_ALIGNOF (guint16),
|
||||
TRUE,
|
||||
TRUE,
|
||||
{ 0, 0, 3, 0 },
|
||||
{ GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT },
|
||||
r16g16b16a16_float_to_float,
|
||||
r16g16b16a16_float_from_float,
|
||||
@@ -395,7 +400,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
12,
|
||||
G_ALIGNOF (float),
|
||||
TRUE,
|
||||
TRUE,
|
||||
{ 0, 0, 3, 0 },
|
||||
{ GL_RGB32F, GL_RGB, GL_FLOAT },
|
||||
r32g32b32_float_to_float,
|
||||
r32g32b32_float_from_float,
|
||||
@@ -405,7 +410,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
16,
|
||||
G_ALIGNOF (float),
|
||||
TRUE,
|
||||
TRUE,
|
||||
{ 0, 0, 3, 0 },
|
||||
{ GL_RGBA32F, GL_RGBA, GL_FLOAT },
|
||||
r32g32b32a32_float_to_float,
|
||||
r32g32b32a32_float_from_float,
|
||||
@@ -415,7 +420,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
|
||||
16,
|
||||
G_ALIGNOF (float),
|
||||
TRUE,
|
||||
TRUE,
|
||||
{ 0, 0, 3, 0 },
|
||||
{ GL_RGBA32F, GL_RGBA, GL_FLOAT },
|
||||
r32g32b32a32_float_to_float,
|
||||
r32g32b32a32_float_from_float,
|
||||
@@ -463,6 +468,8 @@ gdk_memory_format_prefers_high_depth (GdkMemoryFormat format)
|
||||
gboolean
|
||||
gdk_memory_format_gl_format (GdkMemoryFormat format,
|
||||
gboolean gles,
|
||||
guint gl_major,
|
||||
guint gl_minor,
|
||||
guint *out_internal_format,
|
||||
guint *out_format,
|
||||
guint *out_type)
|
||||
@@ -474,8 +481,20 @@ gdk_memory_format_gl_format (GdkMemoryFormat format,
|
||||
if (memory_formats[format].alpha == GDK_MEMORY_ALPHA_STRAIGHT)
|
||||
return FALSE;
|
||||
|
||||
if (gles && !memory_formats[format].supports_gles)
|
||||
return FALSE;
|
||||
if (gles)
|
||||
{
|
||||
if (memory_formats[format].min_gl_version.gles_major > gl_major ||
|
||||
(memory_formats[format].min_gl_version.gles_major == gl_major &&
|
||||
memory_formats[format].min_gl_version.gles_minor > gl_minor))
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (memory_formats[format].min_gl_version.gl_major > gl_major ||
|
||||
(memory_formats[format].min_gl_version.gl_major == gl_major &&
|
||||
memory_formats[format].min_gl_version.gl_minor > gl_minor))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,8 @@ gsize gdk_memory_format_bytes_per_pixel (GdkMemoryFormat
|
||||
gboolean gdk_memory_format_prefers_high_depth(GdkMemoryFormat format) G_GNUC_CONST;
|
||||
gboolean gdk_memory_format_gl_format (GdkMemoryFormat format,
|
||||
gboolean gles,
|
||||
guint gl_major,
|
||||
guint gl_minor,
|
||||
guint *out_internal_format,
|
||||
guint *out_format,
|
||||
guint *out_type);
|
||||
|
||||
@@ -110,8 +110,6 @@ struct _GdkSurfaceClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
cairo_surface_t *
|
||||
(* ref_cairo_surface) (GdkSurface *surface);
|
||||
void (* hide) (GdkSurface *surface);
|
||||
void (* get_geometry) (GdkSurface *surface,
|
||||
int *x,
|
||||
|
||||
+75
-1
@@ -243,6 +243,74 @@ gdk_vulkan_strerror (VkResult result)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
static const char *
|
||||
surface_present_mode_to_string (VkPresentModeKHR present_mode)
|
||||
{
|
||||
switch (present_mode)
|
||||
{
|
||||
case VK_PRESENT_MODE_MAILBOX_KHR:
|
||||
return "VK_PRESENT_MODE_MAILBOX_KHR";
|
||||
case VK_PRESENT_MODE_IMMEDIATE_KHR:
|
||||
return "VK_PRESENT_MODE_IMMEDIATE_KHR";
|
||||
case VK_PRESENT_MODE_FIFO_KHR:
|
||||
return "VK_PRESENT_MODE_FIFO_KHR";
|
||||
case VK_PRESENT_MODE_FIFO_RELAXED_KHR:
|
||||
return "VK_PRESENT_MODE_FIFO_RELAXED_KHR";
|
||||
case VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR:
|
||||
case VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR:
|
||||
case VK_PRESENT_MODE_MAX_ENUM_KHR:
|
||||
default:
|
||||
return "(invalid)";
|
||||
}
|
||||
|
||||
return "(unknown)";
|
||||
}
|
||||
#endif
|
||||
|
||||
static const VkPresentModeKHR preferred_present_modes[] = {
|
||||
VK_PRESENT_MODE_MAILBOX_KHR,
|
||||
VK_PRESENT_MODE_IMMEDIATE_KHR,
|
||||
};
|
||||
|
||||
static VkPresentModeKHR
|
||||
find_best_surface_present_mode (GdkVulkanContext *context)
|
||||
{
|
||||
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
|
||||
VkPresentModeKHR *available_present_modes;
|
||||
uint32_t n_present_modes;
|
||||
VkResult res;
|
||||
|
||||
res = GDK_VK_CHECK (vkGetPhysicalDeviceSurfacePresentModesKHR, gdk_vulkan_context_get_physical_device (context),
|
||||
priv->surface,
|
||||
&n_present_modes,
|
||||
NULL);
|
||||
|
||||
if (res != VK_SUCCESS)
|
||||
goto fallback_present_mode;
|
||||
|
||||
available_present_modes = g_alloca (sizeof (VkPresentModeKHR) * n_present_modes);
|
||||
res = GDK_VK_CHECK (vkGetPhysicalDeviceSurfacePresentModesKHR, gdk_vulkan_context_get_physical_device (context),
|
||||
priv->surface,
|
||||
&n_present_modes,
|
||||
available_present_modes);
|
||||
|
||||
if (res != VK_SUCCESS)
|
||||
goto fallback_present_mode;
|
||||
|
||||
for (uint32_t i = 0; i < G_N_ELEMENTS (preferred_present_modes); i++)
|
||||
{
|
||||
for (uint32_t j = 0; j < n_present_modes; j++)
|
||||
{
|
||||
if (preferred_present_modes[i] == available_present_modes[j])
|
||||
return available_present_modes[j];
|
||||
}
|
||||
}
|
||||
|
||||
fallback_present_mode:
|
||||
return VK_PRESENT_MODE_FIFO_KHR;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_vulkan_context_dispose (GObject *gobject)
|
||||
{
|
||||
@@ -302,6 +370,7 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
|
||||
GdkSurface *surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (context));
|
||||
VkSurfaceCapabilitiesKHR capabilities;
|
||||
VkCompositeAlphaFlagBitsKHR composite_alpha;
|
||||
VkPresentModeKHR present_mode;
|
||||
VkSwapchainKHR new_swapchain;
|
||||
VkResult res;
|
||||
VkDevice device;
|
||||
@@ -333,6 +402,11 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
|
||||
composite_alpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||
}
|
||||
|
||||
present_mode = find_best_surface_present_mode (context);
|
||||
|
||||
GDK_DEBUG (VULKAN, "Using surface present mode %s",
|
||||
surface_present_mode_to_string (present_mode));
|
||||
|
||||
/*
|
||||
* Per https://www.khronos.org/registry/vulkan/specs/1.0-wsi_extensions/xhtml/vkspec.html#VkSurfaceCapabilitiesKHR
|
||||
* the current extent may assume a special value, meaning that the extent should assume whatever
|
||||
@@ -367,7 +441,7 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
|
||||
},
|
||||
.preTransform = capabilities.currentTransform,
|
||||
.compositeAlpha = composite_alpha,
|
||||
.presentMode = VK_PRESENT_MODE_FIFO_KHR,
|
||||
.presentMode = present_mode,
|
||||
.clipped = VK_FALSE,
|
||||
.oldSwapchain = priv->swapchain
|
||||
},
|
||||
|
||||
@@ -127,9 +127,6 @@ gdk_wayland_drag_surface_present (GdkDragSurface *drag_surface,
|
||||
GdkSurface *surface = GDK_SURFACE (drag_surface);
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (!impl->display_server.wl_surface)
|
||||
gdk_wayland_surface_create_wl_surface (surface);
|
||||
|
||||
impl->next_layout.configured_width = width;
|
||||
impl->next_layout.configured_height = height;
|
||||
impl->next_layout.surface_geometry_dirty = TRUE;
|
||||
|
||||
@@ -1289,11 +1289,6 @@ show_popup (GdkWaylandPopup *wayland_popup,
|
||||
int height,
|
||||
GdkPopupLayout *layout)
|
||||
{
|
||||
GdkWaylandSurface *wayland_surface = GDK_WAYLAND_SURFACE (wayland_popup);
|
||||
|
||||
if (!wayland_surface->display_server.wl_surface)
|
||||
gdk_wayland_surface_create_wl_surface (GDK_SURFACE (wayland_popup));
|
||||
|
||||
if (wayland_popup->thaw_upon_show)
|
||||
{
|
||||
wayland_popup->thaw_upon_show = FALSE;
|
||||
|
||||
@@ -99,7 +99,7 @@ gdk_wayland_primary_claim_remote (GdkWaylandPrimary *cb,
|
||||
|
||||
if (cb->source)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (gdk_clipboard_get_display (GDK_CLIPBOARD (cb)), CLIPBOARD, "%p: Ignoring clipboard offer for self", cb);
|
||||
GDK_DISPLAY_DEBUG (gdk_clipboard_get_display (GDK_CLIPBOARD (cb)), CLIPBOARD, "%p: Ignoring primary offer for self", cb);
|
||||
gdk_content_formats_unref (formats);
|
||||
g_clear_pointer (&offer, zwp_primary_selection_offer_v1_destroy);
|
||||
return;
|
||||
@@ -111,7 +111,7 @@ gdk_wayland_primary_claim_remote (GdkWaylandPrimary *cb,
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (gdk_clipboard_get_display (GDK_CLIPBOARD (cb)), CLIPBOARD))
|
||||
{
|
||||
char *s = gdk_content_formats_to_string (formats);
|
||||
gdk_debug_message ("%p: remote clipboard claim for %s", cb, s);
|
||||
gdk_debug_message ("%p: remote primary claim for %s", cb, s);
|
||||
g_free (s);
|
||||
}
|
||||
#endif
|
||||
@@ -119,8 +119,7 @@ gdk_wayland_primary_claim_remote (GdkWaylandPrimary *cb,
|
||||
cb->offer_formats = formats;
|
||||
cb->offer = offer;
|
||||
|
||||
gdk_clipboard_claim_remote (GDK_CLIPBOARD (cb),
|
||||
cb->offer_formats);
|
||||
gdk_clipboard_claim_remote (GDK_CLIPBOARD (cb), cb->offer_formats);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -271,6 +270,14 @@ gdk_wayland_primary_claim (GdkClipboard *clipboard,
|
||||
{
|
||||
GdkWaylandPrimary *cb = GDK_WAYLAND_PRIMARY (clipboard);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (gdk_clipboard_get_display (clipboard), CLIPBOARD))
|
||||
{
|
||||
char *s = gdk_content_formats_to_string (formats);
|
||||
gdk_debug_message ("%p: claim primary (%s) for %s", cb, local ? "local" : "remote", s);
|
||||
g_free (s);
|
||||
}
|
||||
#endif
|
||||
if (local)
|
||||
{
|
||||
GdkWaylandDisplay *wdisplay = GDK_WAYLAND_DISPLAY (gdk_clipboard_get_display (clipboard));
|
||||
|
||||
@@ -104,7 +104,6 @@ struct _GdkWaylandSurfaceClass
|
||||
|
||||
#define GDK_WAYLAND_SURFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WAYLAND_SURFACE, GdkWaylandSurfaceClass))
|
||||
|
||||
void gdk_wayland_surface_create_wl_surface (GdkSurface *surface);
|
||||
void gdk_wayland_surface_update_size (GdkSurface *surface,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
|
||||
+152
-184
@@ -198,38 +198,6 @@ gdk_wayland_surface_thaw_state (GdkSurface *surface)
|
||||
gdk_wayland_surface_configure (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_maybe_resize (GdkSurface *surface,
|
||||
int width,
|
||||
int height,
|
||||
const GdkFractionalScale *scale)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
gboolean hide_temporarily;
|
||||
|
||||
if (surface->width == width &&
|
||||
surface->height == height &&
|
||||
gdk_fractional_scale_equal (&impl->scale, scale))
|
||||
return;
|
||||
|
||||
/* For xdg_popup using an xdg_positioner, there is a race condition if
|
||||
* the application tries to change the size after it's mapped, but before
|
||||
* the initial configure is received, so hide and show the surface again
|
||||
* force the new size onto the compositor. See bug #772505.
|
||||
*/
|
||||
hide_temporarily = GDK_IS_WAYLAND_POPUP (surface) &&
|
||||
gdk_surface_get_mapped (surface) &&
|
||||
!impl->initial_configure_received;
|
||||
|
||||
if (hide_temporarily)
|
||||
gdk_surface_hide (surface);
|
||||
|
||||
gdk_wayland_surface_update_size (surface, width, height, scale);
|
||||
|
||||
if (hide_temporarily)
|
||||
gdk_wayland_surface_create_wl_surface (surface);
|
||||
}
|
||||
|
||||
static inline void
|
||||
get_egl_window_size (GdkSurface *surface,
|
||||
int *width,
|
||||
@@ -508,105 +476,9 @@ gdk_wayland_surface_update_scale (GdkSurface *surface)
|
||||
}
|
||||
|
||||
/* Notify app that scale changed */
|
||||
gdk_wayland_surface_maybe_resize (surface,
|
||||
surface->width, surface->height,
|
||||
&GDK_FRACTIONAL_SCALE_INIT_INT (scale));
|
||||
}
|
||||
|
||||
GdkSurface *
|
||||
_gdk_wayland_display_create_surface (GdkDisplay *display,
|
||||
GdkSurfaceType surface_type,
|
||||
GdkSurface *parent,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
GdkSurface *surface;
|
||||
GdkFrameClock *frame_clock;
|
||||
|
||||
if (parent)
|
||||
frame_clock = g_object_ref (gdk_surface_get_frame_clock (parent));
|
||||
else
|
||||
frame_clock = _gdk_frame_clock_idle_new ();
|
||||
|
||||
switch (surface_type)
|
||||
{
|
||||
case GDK_SURFACE_TOPLEVEL:
|
||||
g_warn_if_fail (parent == NULL);
|
||||
surface = g_object_new (GDK_TYPE_WAYLAND_TOPLEVEL,
|
||||
"display", display,
|
||||
"frame-clock", frame_clock,
|
||||
"title", get_default_title (),
|
||||
NULL);
|
||||
display_wayland->toplevels = g_list_prepend (display_wayland->toplevels, surface);
|
||||
break;
|
||||
case GDK_SURFACE_POPUP:
|
||||
g_warn_if_fail (parent != NULL);
|
||||
surface = g_object_new (GDK_TYPE_WAYLAND_POPUP,
|
||||
"parent", parent,
|
||||
"display", display,
|
||||
"frame-clock", frame_clock,
|
||||
NULL);
|
||||
break;
|
||||
case GDK_SURFACE_DRAG:
|
||||
g_warn_if_fail (parent == NULL);
|
||||
surface = g_object_new (GDK_TYPE_WAYLAND_DRAG_SURFACE,
|
||||
"display", display,
|
||||
"frame-clock", frame_clock,
|
||||
NULL);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
if (width > 65535)
|
||||
{
|
||||
g_warning ("Native Surfaces wider than 65535 pixels are not supported");
|
||||
width = 65535;
|
||||
}
|
||||
if (height > 65535)
|
||||
{
|
||||
g_warning ("Native Surfaces taller than 65535 pixels are not supported");
|
||||
height = 65535;
|
||||
}
|
||||
|
||||
surface->x = x;
|
||||
surface->y = y;
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
|
||||
g_object_ref (surface);
|
||||
|
||||
/* More likely to be right than just assuming 1 */
|
||||
if (wl_compositor_get_version (display_wayland->compositor) >= WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION)
|
||||
{
|
||||
GdkMonitor *monitor = g_list_model_get_item (gdk_display_get_monitors (display), 0);
|
||||
if (monitor)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
guint32 monitor_scale = gdk_monitor_get_scale_factor (monitor);
|
||||
|
||||
if (monitor_scale != 1)
|
||||
{
|
||||
impl->scale = GDK_FRACTIONAL_SCALE_INIT_INT (monitor_scale);
|
||||
impl->buffer_scale_dirty = TRUE;
|
||||
}
|
||||
|
||||
g_object_unref (monitor);
|
||||
}
|
||||
}
|
||||
|
||||
gdk_wayland_surface_create_wl_surface (surface);
|
||||
|
||||
g_signal_connect (frame_clock, "before-paint", G_CALLBACK (on_frame_clock_before_paint), surface);
|
||||
g_signal_connect (frame_clock, "after-paint", G_CALLBACK (on_frame_clock_after_paint), surface);
|
||||
|
||||
g_object_unref (frame_clock);
|
||||
|
||||
return surface;
|
||||
gdk_wayland_surface_update_size (surface,
|
||||
surface->width, surface->height,
|
||||
&GDK_FRACTIONAL_SCALE_INIT_INT (scale));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -684,7 +556,7 @@ gdk_wayland_surface_dispose (GObject *object)
|
||||
GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
|
||||
|
||||
display_wayland->event_queues =
|
||||
g_list_remove (display_wayland->event_queues, surface);
|
||||
g_list_remove (display_wayland->event_queues, impl->event_queue);
|
||||
g_clear_pointer (&impl->event_queue, wl_event_queue_destroy);
|
||||
}
|
||||
|
||||
@@ -858,9 +730,9 @@ gdk_wayland_surface_fractional_scale_preferred_scale_cb (void *data,
|
||||
GdkSurface *surface = GDK_SURFACE (self);
|
||||
|
||||
/* Notify app that scale changed */
|
||||
gdk_wayland_surface_maybe_resize (surface,
|
||||
surface->width, surface->height,
|
||||
&GDK_FRACTIONAL_SCALE_INIT (scale));
|
||||
gdk_wayland_surface_update_size (surface,
|
||||
surface->width, surface->height,
|
||||
&GDK_FRACTIONAL_SCALE_INIT (scale));
|
||||
}
|
||||
|
||||
static const struct wp_fractional_scale_v1_listener fractional_scale_listener = {
|
||||
@@ -915,7 +787,7 @@ static const struct wl_surface_listener surface_listener = {
|
||||
surface_leave
|
||||
};
|
||||
|
||||
void
|
||||
static void
|
||||
gdk_wayland_surface_create_wl_surface (GdkSurface *surface)
|
||||
{
|
||||
GdkWaylandSurface *self = GDK_WAYLAND_SURFACE (surface);
|
||||
@@ -942,6 +814,117 @@ gdk_wayland_surface_create_wl_surface (GdkSurface *surface)
|
||||
self->display_server.wl_surface = wl_surface;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_destroy_wl_surface (GdkWaylandSurface *self)
|
||||
{
|
||||
if (self->display_server.egl_window)
|
||||
{
|
||||
gdk_surface_set_egl_native_window (GDK_SURFACE (self), NULL);
|
||||
g_clear_pointer (&self->display_server.egl_window, wl_egl_window_destroy);
|
||||
}
|
||||
|
||||
g_clear_pointer (&self->display_server.viewport, wp_viewport_destroy);
|
||||
g_clear_pointer (&self->display_server.fractional_scale, wp_fractional_scale_v1_destroy);
|
||||
|
||||
g_clear_pointer (&self->display_server.wl_surface, wl_surface_destroy);
|
||||
|
||||
g_clear_pointer (&self->display_server.outputs, g_slist_free);
|
||||
}
|
||||
|
||||
GdkSurface *
|
||||
_gdk_wayland_display_create_surface (GdkDisplay *display,
|
||||
GdkSurfaceType surface_type,
|
||||
GdkSurface *parent,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
GdkSurface *surface;
|
||||
GdkFrameClock *frame_clock;
|
||||
|
||||
if (parent)
|
||||
frame_clock = g_object_ref (gdk_surface_get_frame_clock (parent));
|
||||
else
|
||||
frame_clock = _gdk_frame_clock_idle_new ();
|
||||
|
||||
switch (surface_type)
|
||||
{
|
||||
case GDK_SURFACE_TOPLEVEL:
|
||||
g_warn_if_fail (parent == NULL);
|
||||
surface = g_object_new (GDK_TYPE_WAYLAND_TOPLEVEL,
|
||||
"display", display,
|
||||
"frame-clock", frame_clock,
|
||||
"title", get_default_title (),
|
||||
NULL);
|
||||
display_wayland->toplevels = g_list_prepend (display_wayland->toplevels, surface);
|
||||
break;
|
||||
case GDK_SURFACE_POPUP:
|
||||
g_warn_if_fail (parent != NULL);
|
||||
surface = g_object_new (GDK_TYPE_WAYLAND_POPUP,
|
||||
"parent", parent,
|
||||
"display", display,
|
||||
"frame-clock", frame_clock,
|
||||
NULL);
|
||||
break;
|
||||
case GDK_SURFACE_DRAG:
|
||||
g_warn_if_fail (parent == NULL);
|
||||
surface = g_object_new (GDK_TYPE_WAYLAND_DRAG_SURFACE,
|
||||
"display", display,
|
||||
"frame-clock", frame_clock,
|
||||
NULL);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
if (width > 65535)
|
||||
{
|
||||
g_warning ("Native Surfaces wider than 65535 pixels are not supported");
|
||||
width = 65535;
|
||||
}
|
||||
if (height > 65535)
|
||||
{
|
||||
g_warning ("Native Surfaces taller than 65535 pixels are not supported");
|
||||
height = 65535;
|
||||
}
|
||||
|
||||
surface->x = x;
|
||||
surface->y = y;
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
|
||||
/* More likely to be right than just assuming 1 */
|
||||
if (wl_compositor_get_version (display_wayland->compositor) >= WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION)
|
||||
{
|
||||
GdkMonitor *monitor = g_list_model_get_item (gdk_display_get_monitors (display), 0);
|
||||
if (monitor)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
guint32 monitor_scale = gdk_monitor_get_scale_factor (monitor);
|
||||
|
||||
if (monitor_scale != 1)
|
||||
{
|
||||
impl->scale = GDK_FRACTIONAL_SCALE_INIT_INT (monitor_scale);
|
||||
impl->buffer_scale_dirty = TRUE;
|
||||
}
|
||||
|
||||
g_object_unref (monitor);
|
||||
}
|
||||
}
|
||||
|
||||
gdk_wayland_surface_create_wl_surface (surface);
|
||||
|
||||
g_signal_connect (frame_clock, "before-paint", G_CALLBACK (on_frame_clock_before_paint), surface);
|
||||
g_signal_connect (frame_clock, "after-paint", G_CALLBACK (on_frame_clock_after_paint), surface);
|
||||
|
||||
g_object_unref (frame_clock);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_notify_mapped (GdkSurface *surface)
|
||||
{
|
||||
@@ -1069,59 +1052,42 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (!impl->mapped)
|
||||
return;
|
||||
|
||||
unmap_popups_for_surface (surface);
|
||||
|
||||
if (impl->display_server.wl_surface)
|
||||
impl->awaiting_frame = FALSE;
|
||||
if (impl->awaiting_frame_frozen)
|
||||
{
|
||||
if (impl->display_server.egl_window)
|
||||
{
|
||||
gdk_surface_set_egl_native_window (surface, NULL);
|
||||
wl_egl_window_destroy (impl->display_server.egl_window);
|
||||
impl->display_server.egl_window = NULL;
|
||||
}
|
||||
|
||||
impl->awaiting_frame = FALSE;
|
||||
if (impl->awaiting_frame_frozen)
|
||||
{
|
||||
impl->awaiting_frame_frozen = FALSE;
|
||||
gdk_surface_thaw_updates (surface);
|
||||
}
|
||||
|
||||
GDK_WAYLAND_SURFACE_GET_CLASS (impl)->hide_surface (impl);
|
||||
|
||||
if (impl->display_server.xdg_surface)
|
||||
{
|
||||
xdg_surface_destroy (impl->display_server.xdg_surface);
|
||||
impl->display_server.xdg_surface = NULL;
|
||||
if (!impl->initial_configure_received)
|
||||
gdk_surface_thaw_updates (surface);
|
||||
else
|
||||
impl->initial_configure_received = FALSE;
|
||||
}
|
||||
if (impl->display_server.zxdg_surface_v6)
|
||||
{
|
||||
g_clear_pointer (&impl->display_server.zxdg_surface_v6, zxdg_surface_v6_destroy);
|
||||
if (!impl->initial_configure_received)
|
||||
gdk_surface_thaw_updates (surface);
|
||||
else
|
||||
impl->initial_configure_received = FALSE;
|
||||
}
|
||||
|
||||
g_clear_pointer (&impl->display_server.fractional_scale, wp_fractional_scale_v1_destroy);
|
||||
g_clear_pointer (&impl->display_server.viewport, wp_viewport_destroy);
|
||||
|
||||
g_clear_pointer (&impl->display_server.wl_surface, wl_surface_destroy);
|
||||
|
||||
g_slist_free (impl->display_server.outputs);
|
||||
impl->display_server.outputs = NULL;
|
||||
impl->awaiting_frame_frozen = FALSE;
|
||||
gdk_surface_thaw_updates (surface);
|
||||
}
|
||||
|
||||
GDK_WAYLAND_SURFACE_GET_CLASS (impl)->hide_surface (impl);
|
||||
|
||||
if (impl->display_server.xdg_surface)
|
||||
{
|
||||
xdg_surface_destroy (impl->display_server.xdg_surface);
|
||||
impl->display_server.xdg_surface = NULL;
|
||||
if (!impl->initial_configure_received)
|
||||
gdk_surface_thaw_updates (surface);
|
||||
else
|
||||
impl->initial_configure_received = FALSE;
|
||||
}
|
||||
if (impl->display_server.zxdg_surface_v6)
|
||||
{
|
||||
g_clear_pointer (&impl->display_server.zxdg_surface_v6, zxdg_surface_v6_destroy);
|
||||
if (!impl->initial_configure_received)
|
||||
gdk_surface_thaw_updates (surface);
|
||||
else
|
||||
impl->initial_configure_received = FALSE;
|
||||
}
|
||||
|
||||
wl_surface_attach (impl->display_server.wl_surface, NULL, 0, 0);
|
||||
wl_surface_commit (impl->display_server.wl_surface);
|
||||
|
||||
impl->has_uncommitted_ack_configure = FALSE;
|
||||
impl->input_region_dirty = TRUE;
|
||||
impl->opaque_region_dirty = TRUE;
|
||||
impl->viewport_dirty = TRUE;
|
||||
if (!gdk_fractional_scale_equal (&impl->scale, &GDK_FRACTIONAL_SCALE_INIT_INT (1)))
|
||||
impl->buffer_scale_dirty = TRUE;
|
||||
|
||||
impl->last_sent_window_geometry = (GdkRectangle) { 0 };
|
||||
impl->mapped = FALSE;
|
||||
@@ -1155,7 +1121,7 @@ gdk_wayland_surface_move_resize (GdkSurface *surface,
|
||||
|
||||
surface->x = x;
|
||||
surface->y = y;
|
||||
gdk_wayland_surface_maybe_resize (surface, width, height, &impl->scale);
|
||||
gdk_wayland_surface_update_size (surface, width, height, &impl->scale);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1262,6 +1228,8 @@ gdk_wayland_surface_destroy (GdkSurface *surface,
|
||||
|
||||
gdk_wayland_surface_hide_surface (surface);
|
||||
|
||||
gdk_wayland_surface_destroy_wl_surface (GDK_WAYLAND_SURFACE(surface));
|
||||
|
||||
frame_clock = gdk_surface_get_frame_clock (surface);
|
||||
g_signal_handlers_disconnect_by_func (frame_clock, on_frame_clock_before_paint, surface);
|
||||
g_signal_handlers_disconnect_by_func (frame_clock, on_frame_clock_after_paint, surface);
|
||||
|
||||
@@ -1526,9 +1526,6 @@ gdk_wayland_toplevel_show (GdkWaylandToplevel *toplevel)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel);
|
||||
|
||||
if (!impl->display_server.wl_surface)
|
||||
gdk_wayland_surface_create_wl_surface (GDK_SURFACE (impl));
|
||||
|
||||
if (impl->mapped)
|
||||
return;
|
||||
|
||||
|
||||
@@ -1207,6 +1207,7 @@ gdk_win32_display_init_gl (GdkDisplay *display,
|
||||
{
|
||||
return g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_EGL,
|
||||
"display", display,
|
||||
"allowed-apis", GDK_GL_API_GLES,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1882,11 +1882,6 @@ gdk_win32_drag_drop_done (GdkDrag *drag,
|
||||
GdkDragAnim *anim;
|
||||
GdkWin32Clipdrop *clipdrop;
|
||||
gpointer ddd;
|
||||
/*
|
||||
cairo_surface_t *win_surface;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
*/
|
||||
guint id;
|
||||
|
||||
GDK_NOTE (DND, g_print ("gdk_win32_drag_drop_done: 0x%p %s\n",
|
||||
@@ -1916,26 +1911,6 @@ gdk_win32_drag_drop_done (GdkDrag *drag,
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
win_surface = _gdk_surface_ref_cairo_surface (drag_win32->drag_surface);
|
||||
surface = gdk_surface_create_similar_surface (drag_win32->drag_surface,
|
||||
cairo_surface_get_content (win_surface),
|
||||
gdk_surface_get_width (drag_win32->drag_surface),
|
||||
gdk_surface_get_height (drag_win32->drag_surface));
|
||||
cr = cairo_create (surface);
|
||||
cairo_set_source_surface (cr, win_surface, 0, 0);
|
||||
cairo_paint (cr);
|
||||
cairo_destroy (cr);
|
||||
cairo_surface_destroy (win_surface);
|
||||
|
||||
pattern = cairo_pattern_create_for_surface (surface);
|
||||
|
||||
gdk_surface_set_background_pattern (drag_win32->drag_surface, pattern);
|
||||
|
||||
cairo_pattern_destroy (pattern);
|
||||
cairo_surface_destroy (surface);
|
||||
*/
|
||||
|
||||
anim = g_new0 (GdkDragAnim, 1);
|
||||
g_set_object (&anim->drag, drag_win32);
|
||||
anim->frame_clock = gdk_surface_get_frame_clock (drag_win32->drag_surface);
|
||||
|
||||
@@ -83,20 +83,13 @@ gdk_win32_gl_context_egl_end_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *painted)
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
|
||||
GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (context);
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
cairo_rectangle_int_t whole_window;
|
||||
EGLSurface egl_surface;
|
||||
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_egl_parent_class)->end_frame (draw_context, painted);
|
||||
|
||||
gdk_gl_context_make_current (context);
|
||||
whole_window =
|
||||
(GdkRectangle) { 0, 0,
|
||||
gdk_surface_get_width (surface),
|
||||
gdk_surface_get_height (surface)
|
||||
};
|
||||
|
||||
egl_surface = gdk_surface_get_egl_surface (surface);
|
||||
|
||||
|
||||
@@ -1843,11 +1843,6 @@ gdk_x11_drag_drop_done (GdkDrag *drag,
|
||||
{
|
||||
GdkX11Drag *x11_drag = GDK_X11_DRAG (drag);
|
||||
GdkDragAnim *anim;
|
||||
/*
|
||||
cairo_surface_t *win_surface;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
*/
|
||||
guint id;
|
||||
|
||||
gdk_x11_drag_release_selection (drag);
|
||||
@@ -1862,26 +1857,6 @@ gdk_x11_drag_drop_done (GdkDrag *drag,
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
win_surface = _gdk_surface_ref_cairo_surface (x11_drag->drag_surface);
|
||||
surface = gdk_surface_create_similar_surface (x11_drag->drag_surface,
|
||||
cairo_surface_get_content (win_surface),
|
||||
gdk_surface_get_width (x11_drag->drag_surface),
|
||||
gdk_surface_get_height (x11_drag->drag_surface));
|
||||
cr = cairo_create (surface);
|
||||
cairo_set_source_surface (cr, win_surface, 0, 0);
|
||||
cairo_paint (cr);
|
||||
cairo_destroy (cr);
|
||||
cairo_surface_destroy (win_surface);
|
||||
|
||||
pattern = cairo_pattern_create_for_surface (surface);
|
||||
|
||||
gdk_surface_set_background_pattern (x11_drag->drag_surface, pattern);
|
||||
|
||||
cairo_pattern_destroy (pattern);
|
||||
cairo_surface_destroy (surface);
|
||||
*/
|
||||
|
||||
anim = g_new0 (GdkDragAnim, 1);
|
||||
anim->drag = g_object_ref (x11_drag);
|
||||
anim->frame_clock = gdk_surface_get_frame_clock (x11_drag->drag_surface);
|
||||
|
||||
@@ -488,7 +488,7 @@ gdk_x11_context_create_glx_context (GdkGLContext *context,
|
||||
|
||||
/* We will use the default version matching the context status
|
||||
* unless the user requested a version which makes sense */
|
||||
gdk_gl_context_get_matching_version (api, legacy, 0,
|
||||
gdk_gl_context_get_matching_version (api, legacy,
|
||||
&min_major, &min_minor);
|
||||
gdk_gl_context_get_clipped_version (context, min_major, min_minor,
|
||||
&major, &minor);
|
||||
|
||||
+46
-20
@@ -1060,8 +1060,11 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
|
||||
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBlendEquation (GL_FUNC_ADD);
|
||||
|
||||
glGenVertexArrays (1, &vao_id);
|
||||
glBindVertexArray (vao_id);
|
||||
if (!gdk_gl_context_get_use_es (self->context))
|
||||
{
|
||||
glGenVertexArrays (1, &vao_id);
|
||||
glBindVertexArray (vao_id);
|
||||
}
|
||||
|
||||
vbo_id = gsk_gl_buffer_submit (&self->vertices);
|
||||
|
||||
@@ -1234,7 +1237,8 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
|
||||
}
|
||||
|
||||
glDeleteBuffers (1, &vbo_id);
|
||||
glDeleteVertexArrays (1, &vao_id);
|
||||
if (!gdk_gl_context_get_use_es (self->context))
|
||||
glDeleteVertexArrays (1, &vao_id);
|
||||
|
||||
gdk_profiler_set_int_counter (self->metrics.n_binds, n_binds);
|
||||
gdk_profiler_set_int_counter (self->metrics.n_uniforms, n_uniforms);
|
||||
@@ -1425,28 +1429,44 @@ gsk_gl_command_queue_create_framebuffer (GskGLCommandQueue *self)
|
||||
static GdkMemoryFormat
|
||||
memory_format_gl_format (GdkMemoryFormat data_format,
|
||||
gboolean use_es,
|
||||
guint major,
|
||||
guint minor,
|
||||
guint *gl_internalformat,
|
||||
guint *gl_format,
|
||||
guint *gl_type)
|
||||
{
|
||||
if (gdk_memory_format_gl_format (data_format,
|
||||
use_es,
|
||||
major,
|
||||
minor,
|
||||
gl_internalformat,
|
||||
gl_format,
|
||||
gl_type))
|
||||
return data_format;
|
||||
|
||||
if (gdk_memory_format_prefers_high_depth (data_format))
|
||||
{
|
||||
data_format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
|
||||
if (gdk_memory_format_gl_format (data_format,
|
||||
use_es,
|
||||
major,
|
||||
minor,
|
||||
gl_internalformat,
|
||||
gl_format,
|
||||
gl_type))
|
||||
return data_format;
|
||||
}
|
||||
|
||||
data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
|
||||
if (!gdk_memory_format_gl_format (data_format,
|
||||
use_es,
|
||||
major,
|
||||
minor,
|
||||
gl_internalformat,
|
||||
gl_format,
|
||||
gl_type))
|
||||
{
|
||||
if (gdk_memory_format_prefers_high_depth (data_format))
|
||||
data_format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
|
||||
else
|
||||
data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
|
||||
if (!gdk_memory_format_gl_format (data_format,
|
||||
use_es,
|
||||
gl_internalformat,
|
||||
gl_format,
|
||||
gl_type))
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return data_format;
|
||||
@@ -1458,7 +1478,6 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
GdkGLContext *context;
|
||||
const guchar *data;
|
||||
gsize stride;
|
||||
GBytes *bytes;
|
||||
@@ -1470,15 +1489,18 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
|
||||
GLenum gl_type;
|
||||
gsize bpp;
|
||||
gboolean use_es;
|
||||
int major, minor;
|
||||
|
||||
context = gdk_gl_context_get_current ();
|
||||
use_es = gdk_gl_context_get_use_es (context);
|
||||
use_es = gdk_gl_context_get_use_es (self->context);
|
||||
gdk_gl_context_get_version (self->context, &major, &minor);
|
||||
data_format = gdk_texture_get_format (texture);
|
||||
width = gdk_texture_get_width (texture);
|
||||
height = gdk_texture_get_height (texture);
|
||||
|
||||
data_format = memory_format_gl_format (data_format,
|
||||
use_es,
|
||||
major,
|
||||
minor,
|
||||
&gl_internalformat,
|
||||
&gl_format,
|
||||
&gl_type);
|
||||
@@ -1500,7 +1522,7 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0, x, y, width, height, gl_format, gl_type, data);
|
||||
}
|
||||
else if (stride % bpp == 0 &&
|
||||
(gdk_gl_context_check_version (context, 0, 0, 3, 0) || gdk_gl_context_has_unpack_subimage (context)))
|
||||
(gdk_gl_context_check_version (self->context, 0, 0, 3, 0) || gdk_gl_context_has_unpack_subimage (self->context)))
|
||||
{
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, stride / bpp);
|
||||
|
||||
@@ -1532,6 +1554,7 @@ gsk_gl_command_queue_upload_texture_chunks (GskGLCommandQueue *self,
|
||||
GLenum gl_type;
|
||||
gboolean use_es;
|
||||
int texture_id;
|
||||
int major, minor;
|
||||
|
||||
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
|
||||
|
||||
@@ -1564,10 +1587,13 @@ gsk_gl_command_queue_upload_texture_chunks (GskGLCommandQueue *self,
|
||||
glBindTexture (GL_TEXTURE_2D, texture_id);
|
||||
|
||||
/* Initialize the texture */
|
||||
use_es = gdk_gl_context_get_use_es (gdk_gl_context_get_current ());
|
||||
use_es = gdk_gl_context_get_use_es (self->context);
|
||||
gdk_gl_context_get_version (self->context, &major, &minor);
|
||||
data_format = gdk_texture_get_format (chunks[0].texture);
|
||||
memory_format_gl_format (data_format,
|
||||
use_es,
|
||||
major,
|
||||
minor,
|
||||
&gl_internalformat,
|
||||
&gl_format,
|
||||
&gl_type);
|
||||
|
||||
@@ -372,7 +372,11 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
|
||||
return texture;
|
||||
}
|
||||
|
||||
format = gsk_render_node_prefers_high_depth (root) ? GL_RGBA32F : GL_RGBA8;
|
||||
if (gsk_render_node_prefers_high_depth (root) &&
|
||||
gdk_gl_context_check_version (self->context, 3, 0, 3, 0))
|
||||
format = GL_RGBA32F;
|
||||
else
|
||||
format = GL_RGBA8;
|
||||
|
||||
gdk_gl_context_make_current (self->context);
|
||||
|
||||
|
||||
@@ -647,9 +647,12 @@ gsk_vulkan_render_draw (GskVulkanRender *self)
|
||||
GdkTexture *
|
||||
gsk_vulkan_render_download_target (GskVulkanRender *self)
|
||||
{
|
||||
GdkTexture *texture;
|
||||
|
||||
texture = gsk_vulkan_image_download (self->target, self->uploader);
|
||||
gsk_vulkan_uploader_reset (self->uploader);
|
||||
|
||||
return gsk_vulkan_image_download (self->target, self->uploader);
|
||||
return texture;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -460,6 +460,9 @@ gsk_pango_renderer_release (GskPangoRenderer *renderer)
|
||||
* Creates render nodes for rendering @layout in the given foregound @color
|
||||
* and appends them to the current node of @snapshot without changing the
|
||||
* current node.
|
||||
*
|
||||
* Note that if the layout does not produce any visible output, then nodes
|
||||
* may not be added to the @snapshot.
|
||||
**/
|
||||
void
|
||||
gtk_snapshot_append_layout (GtkSnapshot *snapshot,
|
||||
|
||||
@@ -747,6 +747,9 @@ gtk_alert_dialog_choose_finish (GtkAlertDialog *self,
|
||||
g_return_val_if_fail (g_task_is_valid (result, self), -1);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_alert_dialog_choose, -1);
|
||||
|
||||
/* Destroy the dialog window not to be bound to GTask lifecycle */
|
||||
g_task_set_task_data (G_TASK (result), NULL, NULL);
|
||||
|
||||
return (int) g_task_propagate_int (G_TASK (result), error);
|
||||
}
|
||||
|
||||
|
||||
@@ -492,6 +492,9 @@ gtk_color_dialog_choose_rgba_finish (GtkColorDialog *self,
|
||||
g_return_val_if_fail (g_task_is_valid (result, self), NULL);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_color_dialog_choose_rgba, NULL);
|
||||
|
||||
/* Destroy the dialog window not to be bound to GTask lifecycle */
|
||||
g_task_set_task_data (G_TASK (result), NULL, NULL);
|
||||
|
||||
return g_task_propagate_pointer (G_TASK (result), error);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -2098,7 +2098,7 @@ gtk_entry_get_visibility (GtkEntry *entry)
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_entry_set_invisible_char: (attributes org.gtk.Method.sets_property=invisible-char)
|
||||
* gtk_entry_set_invisible_char: (attributes org.gtk.Method.set_property=invisible-char)
|
||||
* @entry: a `GtkEntry`
|
||||
* @ch: a Unicode character
|
||||
*
|
||||
|
||||
+52
-16
@@ -23,22 +23,25 @@
|
||||
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkbinlayout.h"
|
||||
#include "gtkcolumnviewcell.h"
|
||||
#include "gtkdragsource.h"
|
||||
#include "gtkgestureclick.h"
|
||||
#include "gtkgesturelongpress.h"
|
||||
#include "gtkicontheme.h"
|
||||
#include "gtklistitem.h"
|
||||
#include "gtklabel.h"
|
||||
#include "gtkselectionmodel.h"
|
||||
#include "gtkfilechooserutils.h"
|
||||
#include "gtkfilechooserwidgetprivate.h"
|
||||
#include "gtklistitem.h"
|
||||
|
||||
struct _GtkFileChooserCell
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GFileInfo *item;
|
||||
GtkListItem *list_item;
|
||||
GtkColumnViewCell *list_item;
|
||||
|
||||
gboolean date_column;
|
||||
guint type_format;
|
||||
|
||||
gboolean show_time;
|
||||
};
|
||||
@@ -52,7 +55,8 @@ G_DEFINE_TYPE (GtkFileChooserCell, gtk_file_chooser_cell, GTK_TYPE_WIDGET)
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_POSITION = 1,
|
||||
PROP_DATE_COLUMN = 1,
|
||||
PROP_POSITION,
|
||||
PROP_ITEM,
|
||||
PROP_SHOW_TIME,
|
||||
PROP_LIST_ITEM,
|
||||
@@ -60,6 +64,12 @@ enum
|
||||
|
||||
#define ICON_SIZE 16
|
||||
|
||||
guint
|
||||
gtk_file_chooser_cell_get_type_format (GtkFileChooserCell *self)
|
||||
{
|
||||
return self->type_format;
|
||||
}
|
||||
|
||||
static void
|
||||
popup_menu (GtkFileChooserCell *self,
|
||||
double x,
|
||||
@@ -79,7 +89,7 @@ popup_menu (GtkFileChooserCell *self,
|
||||
|
||||
if (self->list_item)
|
||||
gtk_widget_activate_action (widget, "item.popup-file-list-menu",
|
||||
"(udd)", gtk_list_item_get_position (self->list_item), p.x, p.y);
|
||||
"(udd)", gtk_column_view_cell_get_position (self->list_item), p.x, p.y);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -125,7 +135,7 @@ drag_prepare_cb (GtkDragSource *source,
|
||||
impl = GTK_FILE_CHOOSER_WIDGET (gtk_widget_get_ancestor (GTK_WIDGET (self),
|
||||
GTK_TYPE_FILE_CHOOSER_WIDGET));
|
||||
|
||||
if (self->list_item && !gtk_list_item_get_selected (self->list_item))
|
||||
if (self->list_item && !gtk_column_view_cell_get_selected (self->list_item))
|
||||
{
|
||||
gtk_widget_activate_action (GTK_WIDGET (self), "listitem.select", "(bb)", FALSE, FALSE);
|
||||
}
|
||||
@@ -161,6 +171,23 @@ gtk_file_chooser_cell_realize (GtkWidget *widget)
|
||||
GTK_TYPE_FILE_CHOOSER_WIDGET));
|
||||
|
||||
g_object_bind_property (impl, "show-time", self, "show-time", G_BINDING_SYNC_CREATE);
|
||||
|
||||
if (self->date_column)
|
||||
{
|
||||
GtkWidget *box;
|
||||
GtkWidget *label;
|
||||
char *text;
|
||||
|
||||
box = gtk_widget_get_first_child (GTK_WIDGET (self));
|
||||
label = gtk_widget_get_first_child (box);
|
||||
text = gtk_file_chooser_widget_get_file_date (self->list_item, self->item);
|
||||
gtk_label_set_text (GTK_LABEL (label), text);
|
||||
g_free (text);
|
||||
label = gtk_widget_get_last_child (box);
|
||||
text = gtk_file_chooser_widget_get_file_time (self->list_item, self->item);
|
||||
gtk_label_set_text (GTK_LABEL (label), text);
|
||||
g_free (text);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -168,6 +195,11 @@ gtk_file_chooser_cell_init (GtkFileChooserCell *self)
|
||||
{
|
||||
GtkGesture *gesture;
|
||||
GtkDragSource *drag_source;
|
||||
GSettings *settings;
|
||||
|
||||
settings = _gtk_file_chooser_get_settings_for_widget (GTK_WIDGET (self));
|
||||
|
||||
self->type_format = g_settings_get_enum (settings, SETTINGS_KEY_TYPE_FORMAT);
|
||||
|
||||
gesture = gtk_gesture_click_new ();
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
|
||||
@@ -205,13 +237,6 @@ get_selectable (GtkFileChooserCell *self)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
update_list_item (GtkFileChooserCell *self)
|
||||
{
|
||||
if (self->list_item)
|
||||
gtk_list_item_set_selectable (self->list_item, get_selectable (self));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_chooser_cell_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
@@ -222,6 +247,10 @@ gtk_file_chooser_cell_set_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DATE_COLUMN:
|
||||
self->date_column = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
case PROP_ITEM:
|
||||
self->item = g_value_get_object (value);
|
||||
|
||||
@@ -230,7 +259,6 @@ gtk_file_chooser_cell_set_property (GObject *object,
|
||||
else
|
||||
gtk_widget_add_css_class (GTK_WIDGET (self), "dim-label");
|
||||
|
||||
update_list_item (self);
|
||||
break;
|
||||
|
||||
case PROP_SHOW_TIME:
|
||||
@@ -239,8 +267,6 @@ gtk_file_chooser_cell_set_property (GObject *object,
|
||||
|
||||
case PROP_LIST_ITEM:
|
||||
self->list_item = g_value_get_object (value);
|
||||
|
||||
update_list_item (self);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -259,6 +285,10 @@ gtk_file_chooser_cell_get_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DATE_COLUMN:
|
||||
g_value_set_boolean (value, self->date_column);
|
||||
break;
|
||||
|
||||
case PROP_ITEM:
|
||||
g_value_set_object (value, self->item);
|
||||
break;
|
||||
@@ -284,6 +314,12 @@ gtk_file_chooser_cell_class_init (GtkFileChooserCellClass *klass)
|
||||
object_class->set_property = gtk_file_chooser_cell_set_property;
|
||||
object_class->get_property = gtk_file_chooser_cell_get_property;
|
||||
|
||||
g_object_class_install_property (object_class, PROP_DATE_COLUMN,
|
||||
g_param_spec_boolean ("date-column", NULL, NULL,
|
||||
FALSE,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
|
||||
g_object_class_install_property (object_class, PROP_ITEM,
|
||||
g_param_spec_object ("item", NULL, NULL,
|
||||
G_TYPE_FILE_INFO,
|
||||
|
||||
@@ -31,5 +31,7 @@ G_DECLARE_FINAL_TYPE (GtkFileChooserCell, gtk_file_chooser_cell, GTK, FILE_CHOOS
|
||||
|
||||
GtkFileChooserCell * gtk_file_chooser_cell_new (void);
|
||||
|
||||
guint gtk_file_chooser_cell_get_type_format (GtkFileChooserCell *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+17
-12
@@ -193,28 +193,30 @@ match_func (GtkEntryCompletion *compl,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkFileChooserEntry *chooser_entry = user_data;
|
||||
GFileInfo *info;
|
||||
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (chooser_entry->completion_store),
|
||||
iter,
|
||||
FILE_INFO_COLUMN, &info,
|
||||
-1);
|
||||
|
||||
g_assert (info != NULL);
|
||||
g_object_unref (info);
|
||||
|
||||
if (g_file_info_get_attribute_boolean (info, "filechooser::filtered-out"))
|
||||
return FALSE;
|
||||
|
||||
/* If we arrive here, the GtkFileSystemModel's GtkFileFilter already filtered out all
|
||||
* files that don't start with the current prefix, so we manually apply the GtkFileChooser's
|
||||
* current file filter (e.g. just jpg files) here. */
|
||||
* current file filter (e.g. just jpg files) here.
|
||||
*/
|
||||
if (chooser_entry->current_filter != NULL)
|
||||
{
|
||||
GFileInfo *info;
|
||||
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (chooser_entry->completion_store),
|
||||
iter,
|
||||
FILE_INFO_COLUMN, &info,
|
||||
-1);
|
||||
|
||||
g_assert (info != NULL);
|
||||
g_object_unref (info);
|
||||
|
||||
/* We always allow navigating into subfolders, so don't ever filter directories */
|
||||
if (g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR)
|
||||
return TRUE;
|
||||
|
||||
g_assert (g_file_info_has_attribute (info, "standard::file"));
|
||||
|
||||
return gtk_filter_match (GTK_FILTER (chooser_entry->current_filter), info);
|
||||
}
|
||||
|
||||
@@ -598,6 +600,9 @@ model_items_changed_cb (GListModel *model,
|
||||
DISPLAY_NAME_COLUMN, display_name,
|
||||
-1);
|
||||
|
||||
g_free (display_name);
|
||||
g_free (full_path);
|
||||
|
||||
g_clear_object (&info);
|
||||
|
||||
position++;
|
||||
|
||||
+32
-35
@@ -27,6 +27,7 @@
|
||||
#include "gtkbutton.h"
|
||||
#include "gtkdropdown.h"
|
||||
#include "gtkcolumnview.h"
|
||||
#include "gtkcolumnviewcell.h"
|
||||
#include "gtkcolumnviewcolumn.h"
|
||||
#include "gtkcolumnviewrow.h"
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
@@ -44,7 +45,6 @@
|
||||
#include "gtkgesturelongpress.h"
|
||||
#include "gtkgrid.h"
|
||||
#include "gtklabel.h"
|
||||
#include "gtklistitem.h"
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtkalertdialog.h"
|
||||
#include "gtkmountoperation.h"
|
||||
@@ -505,8 +505,8 @@ static void set_model_filter (GtkFileChooserWidget *impl,
|
||||
static void switch_to_home_dir (GtkFileChooserWidget *impl);
|
||||
static void set_show_hidden (GtkFileChooserWidget *impl,
|
||||
gboolean show_hidden);
|
||||
static char * get_type_information (GtkFileChooserWidget *impl,
|
||||
GFileInfo *info);
|
||||
static char * get_type_information (TypeFormat type_format,
|
||||
GFileInfo *info);
|
||||
static char * my_g_format_date_for_display (GtkFileChooserWidget *impl,
|
||||
glong secs);
|
||||
static char * my_g_format_time_for_display (GtkFileChooserWidget *impl,
|
||||
@@ -1945,9 +1945,9 @@ files_list_restrict_key_presses (GtkEventControllerKey *controller,
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static char *
|
||||
column_view_get_file_date (GtkListItem *item,
|
||||
GFileInfo *info)
|
||||
char *
|
||||
gtk_file_chooser_widget_get_file_date (GtkColumnViewCell *cell,
|
||||
GFileInfo *info)
|
||||
{
|
||||
GtkFileChooserWidget *impl;
|
||||
glong time;
|
||||
@@ -1955,7 +1955,7 @@ column_view_get_file_date (GtkListItem *item,
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
impl = GTK_FILE_CHOOSER_WIDGET (gtk_widget_get_ancestor (gtk_list_item_get_child (item),
|
||||
impl = GTK_FILE_CHOOSER_WIDGET (gtk_widget_get_ancestor (gtk_column_view_cell_get_child (cell),
|
||||
GTK_TYPE_FILE_CHOOSER_WIDGET));
|
||||
if (!impl)
|
||||
return NULL;
|
||||
@@ -1972,8 +1972,8 @@ column_view_get_file_date (GtkListItem *item,
|
||||
}
|
||||
|
||||
static char *
|
||||
column_view_get_file_display_name (GtkListItem *item,
|
||||
GFileInfo *info)
|
||||
column_view_get_file_display_name (GtkColumnViewCell *cell,
|
||||
GFileInfo *info)
|
||||
{
|
||||
if (info)
|
||||
return g_strdup (g_file_info_get_display_name (info));
|
||||
@@ -1981,9 +1981,9 @@ column_view_get_file_display_name (GtkListItem *item,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *
|
||||
column_view_get_file_time (GtkListItem *item,
|
||||
GFileInfo *info)
|
||||
char *
|
||||
gtk_file_chooser_widget_get_file_time (GtkColumnViewCell *cell,
|
||||
GFileInfo *info)
|
||||
{
|
||||
GtkFileChooserWidget *impl;
|
||||
glong time;
|
||||
@@ -1991,7 +1991,7 @@ column_view_get_file_time (GtkListItem *item,
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
impl = GTK_FILE_CHOOSER_WIDGET (gtk_widget_get_ancestor (gtk_list_item_get_child (item),
|
||||
impl = GTK_FILE_CHOOSER_WIDGET (gtk_widget_get_ancestor (gtk_column_view_cell_get_child (cell),
|
||||
GTK_TYPE_FILE_CHOOSER_WIDGET));
|
||||
if (!impl)
|
||||
return NULL;
|
||||
@@ -2008,20 +2008,20 @@ column_view_get_file_time (GtkListItem *item,
|
||||
}
|
||||
|
||||
static char *
|
||||
column_view_get_file_type (GtkListItem *item,
|
||||
GFileInfo *info)
|
||||
column_view_get_file_type (GtkColumnViewCell *cell,
|
||||
GFileInfo *info)
|
||||
{
|
||||
GtkFileChooserWidget *impl;
|
||||
GtkFileChooserCell *child;
|
||||
|
||||
if (!info || _gtk_file_info_consider_as_directory (info))
|
||||
return NULL;
|
||||
|
||||
impl = GTK_FILE_CHOOSER_WIDGET (gtk_widget_get_ancestor (gtk_list_item_get_child (item),
|
||||
GTK_TYPE_FILE_CHOOSER_WIDGET));
|
||||
if (!impl)
|
||||
child = GTK_FILE_CHOOSER_CELL (gtk_column_view_cell_get_child (cell));
|
||||
|
||||
if (!child)
|
||||
return NULL;
|
||||
|
||||
return get_type_information (impl, info);
|
||||
return get_type_information (gtk_file_chooser_cell_get_type_format (child), info);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2097,12 +2097,12 @@ file_chooser_get_location (GtkFileChooserWidget *impl,
|
||||
}
|
||||
|
||||
static char *
|
||||
column_view_get_location (GtkListItem *list_item,
|
||||
GFileInfo *info)
|
||||
column_view_get_location (GtkColumnViewCell *cell,
|
||||
GFileInfo *info)
|
||||
{
|
||||
GtkFileChooserWidget *impl;
|
||||
|
||||
impl = GTK_FILE_CHOOSER_WIDGET (gtk_widget_get_ancestor (gtk_list_item_get_child (list_item),
|
||||
impl = GTK_FILE_CHOOSER_WIDGET (gtk_widget_get_ancestor (gtk_column_view_cell_get_child (cell),
|
||||
GTK_TYPE_FILE_CHOOSER_WIDGET));
|
||||
if (!impl)
|
||||
return NULL;
|
||||
@@ -2111,8 +2111,8 @@ column_view_get_location (GtkListItem *list_item,
|
||||
}
|
||||
|
||||
static char *
|
||||
column_view_get_size (GtkListItem *item,
|
||||
GFileInfo *info)
|
||||
column_view_get_size (GtkColumnViewCell *cell,
|
||||
GFileInfo *info)
|
||||
{
|
||||
if (info && !_gtk_file_info_consider_as_directory (info))
|
||||
return g_format_size (g_file_info_get_size (info));
|
||||
@@ -2121,8 +2121,8 @@ column_view_get_size (GtkListItem *item,
|
||||
}
|
||||
|
||||
static char *
|
||||
column_view_get_tooltip_text (GtkListItem *list_item,
|
||||
GFileInfo *info)
|
||||
column_view_get_tooltip_text (GtkColumnViewCell *cell,
|
||||
GFileInfo *info)
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
@@ -3284,7 +3284,6 @@ settings_save (GtkFileChooserWidget *impl)
|
||||
g_settings_set_int (settings, SETTINGS_KEY_SIDEBAR_WIDTH,
|
||||
gtk_paned_get_position (GTK_PANED (impl->browse_widgets_hpaned)));
|
||||
g_settings_set_enum (settings, SETTINGS_KEY_DATE_FORMAT, impl->show_time ? DATE_FORMAT_WITH_TIME : DATE_FORMAT_REGULAR);
|
||||
g_settings_set_enum (settings, SETTINGS_KEY_TYPE_FORMAT, impl->type_format);
|
||||
g_settings_set_enum (settings, SETTINGS_KEY_VIEW_TYPE, impl->view_type);
|
||||
|
||||
/* Now apply the settings */
|
||||
@@ -3947,8 +3946,8 @@ get_category_from_content_type (const char *content_type)
|
||||
}
|
||||
|
||||
static char *
|
||||
get_type_information (GtkFileChooserWidget *impl,
|
||||
GFileInfo *info)
|
||||
get_type_information (TypeFormat type_format,
|
||||
GFileInfo *info)
|
||||
{
|
||||
const char *content_type;
|
||||
char *mime_type;
|
||||
@@ -3960,7 +3959,7 @@ get_type_information (GtkFileChooserWidget *impl,
|
||||
if (!content_type)
|
||||
goto end;
|
||||
|
||||
switch (impl->type_format)
|
||||
switch (type_format)
|
||||
{
|
||||
case TYPE_FORMAT_MIME:
|
||||
mime_type = g_content_type_get_mime_type (content_type);
|
||||
@@ -6848,9 +6847,7 @@ gtk_file_chooser_widget_class_init (GtkFileChooserWidgetClass *class)
|
||||
gtk_widget_class_bind_template_callback (widget_class, rename_file_name_changed);
|
||||
gtk_widget_class_bind_template_callback (widget_class, rename_file_rename_clicked);
|
||||
gtk_widget_class_bind_template_callback (widget_class, rename_file_end);
|
||||
gtk_widget_class_bind_template_callback (widget_class, column_view_get_file_date);
|
||||
gtk_widget_class_bind_template_callback (widget_class, column_view_get_file_display_name);
|
||||
gtk_widget_class_bind_template_callback (widget_class, column_view_get_file_time);
|
||||
gtk_widget_class_bind_template_callback (widget_class, column_view_get_file_type);
|
||||
gtk_widget_class_bind_template_callback (widget_class, column_view_get_location);
|
||||
gtk_widget_class_bind_template_callback (widget_class, column_view_get_size);
|
||||
@@ -7085,8 +7082,8 @@ type_sort_func (gconstpointer a,
|
||||
GtkOrdering result;
|
||||
|
||||
/* FIXME: use sortkeys for these */
|
||||
key_a = get_type_information (impl, (GFileInfo *)a);
|
||||
key_b = get_type_information (impl, (GFileInfo *)b);
|
||||
key_a = get_type_information (impl->type_format, (GFileInfo *)a);
|
||||
key_b = get_type_information (impl->type_format, (GFileInfo *)b);
|
||||
|
||||
result = g_strcmp0 (key_a, key_b);
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <glib.h>
|
||||
#include "deprecated/gtkfilechooserwidget.h"
|
||||
#include "gtkcolumnviewcell.h"
|
||||
#include "gtkselectionmodel.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -36,6 +37,14 @@ gtk_file_chooser_widget_should_respond (GtkFileChooserWidget *chooser);
|
||||
void
|
||||
gtk_file_chooser_widget_initial_focus (GtkFileChooserWidget *chooser);
|
||||
|
||||
char *
|
||||
gtk_file_chooser_widget_get_file_date (GtkColumnViewCell *cell,
|
||||
GFileInfo *info);
|
||||
|
||||
char *
|
||||
gtk_file_chooser_widget_get_file_time (GtkColumnViewCell *cell,
|
||||
GFileInfo *info);
|
||||
|
||||
GSList *
|
||||
gtk_file_chooser_widget_get_selected_files (GtkFileChooserWidget *impl);
|
||||
|
||||
|
||||
@@ -976,6 +976,9 @@ gtk_file_dialog_open_finish (GtkFileDialog *self,
|
||||
g_return_val_if_fail (g_task_is_valid (result, self), NULL);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_file_dialog_open, NULL);
|
||||
|
||||
/* Destroy the dialog window not to be bound to GTask lifecycle */
|
||||
g_task_set_task_data (G_TASK (result), NULL, NULL);
|
||||
|
||||
return finish_file_op (self, G_TASK (result), error);
|
||||
}
|
||||
|
||||
@@ -1050,6 +1053,9 @@ gtk_file_dialog_select_folder_finish (GtkFileDialog *self,
|
||||
g_return_val_if_fail (g_task_is_valid (result, self), NULL);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_file_dialog_select_folder, NULL);
|
||||
|
||||
/* Destroy the dialog window not to be bound to GTask lifecycle */
|
||||
g_task_set_task_data (G_TASK (result), NULL, NULL);
|
||||
|
||||
return finish_file_op (self, G_TASK (result), error);
|
||||
}
|
||||
|
||||
@@ -1120,6 +1126,9 @@ gtk_file_dialog_save_finish (GtkFileDialog *self,
|
||||
g_return_val_if_fail (g_task_is_valid (result, self), NULL);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_file_dialog_save, NULL);
|
||||
|
||||
/* Destroy the dialog window not to be bound to GTask lifecycle */
|
||||
g_task_set_task_data (G_TASK (result), NULL, NULL);
|
||||
|
||||
return finish_file_op (self, G_TASK (result), error);
|
||||
}
|
||||
|
||||
@@ -1194,6 +1203,9 @@ gtk_file_dialog_open_multiple_finish (GtkFileDialog *self,
|
||||
g_return_val_if_fail (g_task_is_valid (result, self), NULL);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_file_dialog_open_multiple, NULL);
|
||||
|
||||
/* Destroy the dialog window not to be bound to GTask lifecycle */
|
||||
g_task_set_task_data (G_TASK (result), NULL, NULL);
|
||||
|
||||
return finish_multiple_files_op (self, G_TASK (result), error);
|
||||
}
|
||||
|
||||
@@ -1268,6 +1280,9 @@ gtk_file_dialog_select_multiple_folders_finish (GtkFileDialog *self,
|
||||
g_return_val_if_fail (g_task_is_valid (result, self), NULL);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_file_dialog_select_multiple_folders, NULL);
|
||||
|
||||
/* Destroy the dialog window not to be bound to GTask lifecycle */
|
||||
g_task_set_task_data (G_TASK (result), NULL, NULL);
|
||||
|
||||
return finish_multiple_files_op (self, G_TASK (result), error);
|
||||
}
|
||||
|
||||
|
||||
@@ -331,8 +331,6 @@ list_model_get_item (GListModel *list_model,
|
||||
GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (list_model);
|
||||
FileModelNode *node;
|
||||
|
||||
/* The first items of GtkFileSystemModel is not really a file,
|
||||
* so ignore it. */
|
||||
if (position >= model->files->len)
|
||||
return NULL;
|
||||
|
||||
@@ -502,7 +500,7 @@ remove_file (GtkFileSystemModel *model,
|
||||
|
||||
g_array_remove_index (model->files, id);
|
||||
|
||||
g_list_model_items_changed (G_LIST_MODEL (model), id - 1, 1, 0);
|
||||
g_list_model_items_changed (G_LIST_MODEL (model), id, 1, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+1
-1
@@ -538,7 +538,7 @@ gtk_flow_box_child_class_init (GtkFlowBoxChildClass *class)
|
||||
*
|
||||
* Emitted when the user activates a child widget in a `GtkFlowBox`.
|
||||
*
|
||||
* This can be happen either by clicking or double-clicking,
|
||||
* This can happen either by clicking or double-clicking,
|
||||
* or via a keybinding.
|
||||
*
|
||||
* This is a [keybinding signal](class.SignalAction.html),
|
||||
|
||||
@@ -697,6 +697,9 @@ gtk_font_dialog_choose_family_finish (GtkFontDialog *self,
|
||||
g_return_val_if_fail (g_task_is_valid (result, self), NULL);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_font_dialog_choose_family, NULL);
|
||||
|
||||
/* Destroy the dialog window not to be bound to GTask lifecycle */
|
||||
g_task_set_task_data (G_TASK (result), NULL, NULL);
|
||||
|
||||
return g_task_propagate_pointer (G_TASK (result), error);
|
||||
}
|
||||
|
||||
@@ -777,6 +780,9 @@ gtk_font_dialog_choose_face_finish (GtkFontDialog *self,
|
||||
g_return_val_if_fail (g_task_is_valid (result, self), NULL);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_font_dialog_choose_face, NULL);
|
||||
|
||||
/* Destroy the dialog window not to be bound to GTask lifecycle */
|
||||
g_task_set_task_data (G_TASK (result), NULL, NULL);
|
||||
|
||||
return g_task_propagate_pointer (G_TASK (result), error);
|
||||
}
|
||||
|
||||
@@ -855,6 +861,9 @@ gtk_font_dialog_choose_font_finish (GtkFontDialog *self,
|
||||
g_return_val_if_fail (g_task_is_valid (result, self), NULL);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_font_dialog_choose_font, NULL);
|
||||
|
||||
/* Destroy the dialog window not to be bound to GTask lifecycle */
|
||||
g_task_set_task_data (G_TASK (result), NULL, NULL);
|
||||
|
||||
return g_task_propagate_pointer (G_TASK (result), error);
|
||||
}
|
||||
|
||||
@@ -944,6 +953,8 @@ gtk_font_dialog_choose_font_and_features_finish (GtkFontDialog *self,
|
||||
g_return_val_if_fail (g_task_is_valid (result, self), FALSE);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_font_dialog_choose_font_and_features, FALSE);
|
||||
|
||||
/* Destroy the dialog window not to be bound to GTask lifecycle */
|
||||
g_task_set_task_data (G_TASK (result), NULL, NULL);
|
||||
font_result = g_task_propagate_pointer (G_TASK (result), error);
|
||||
|
||||
if (font_result)
|
||||
|
||||
@@ -150,6 +150,7 @@ _gtk_gesture_click_update_timeout (GtkGestureClick *gesture)
|
||||
|
||||
static gboolean
|
||||
_gtk_gesture_click_check_within_threshold (GtkGestureClick *gesture,
|
||||
const char *setting,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
@@ -165,9 +166,7 @@ _gtk_gesture_click_check_within_threshold (GtkGestureClick *gesture,
|
||||
|
||||
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
|
||||
settings = gtk_widget_get_settings (widget);
|
||||
g_object_get (settings,
|
||||
"gtk-double-click-distance", &double_click_distance,
|
||||
NULL);
|
||||
g_object_get (settings, setting, &double_click_distance, NULL);
|
||||
|
||||
if (ABS (priv->initial_press_x - x) < double_click_distance &&
|
||||
ABS (priv->initial_press_y - y) < double_click_distance)
|
||||
@@ -220,7 +219,8 @@ gtk_gesture_click_begin (GtkGesture *gesture,
|
||||
_gtk_gesture_click_update_timeout (click);
|
||||
gtk_gesture_get_point (gesture, current, &x, &y);
|
||||
|
||||
if (!_gtk_gesture_click_check_within_threshold (click, x, y))
|
||||
if (gdk_device_get_source (priv->current_device) == GDK_SOURCE_MOUSE &&
|
||||
!_gtk_gesture_click_check_within_threshold (click, "gtk-double-click-distance", x, y))
|
||||
_gtk_gesture_click_stop (click);
|
||||
|
||||
/* Increment later the real counter, just if the gesture is
|
||||
@@ -250,7 +250,7 @@ gtk_gesture_click_update (GtkGesture *gesture,
|
||||
current = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
|
||||
gtk_gesture_get_point (gesture, current, &x, &y);
|
||||
|
||||
if (!_gtk_gesture_click_check_within_threshold (click, x, y))
|
||||
if (!_gtk_gesture_click_check_within_threshold (click, "gtk-dnd-drag-threshold", x, y))
|
||||
_gtk_gesture_click_stop (click);
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ gtk_gesture_stylus_handle_event (GtkEventController *controller,
|
||||
priv = gtk_gesture_stylus_get_instance_private (GTK_GESTURE_STYLUS (controller));
|
||||
GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_stylus_parent_class)->handle_event (controller, event, x, y);
|
||||
|
||||
if (!(priv->stylus_only || gdk_event_get_device_tool (event)))
|
||||
if (priv->stylus_only && !gdk_event_get_device_tool (event))
|
||||
return FALSE;
|
||||
|
||||
switch ((guint) gdk_event_get_event_type (event))
|
||||
|
||||
+2
-2
@@ -889,7 +889,7 @@ gtk_gl_area_class_init (GtkGLAreaClass *klass)
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkGLArea:allowed-apis: (attributes org.gtk.Property.get=gtk_gl_area_get_allowed_apis org.gtk.Property.set=gtk_gl_area_set_allowed_apis)
|
||||
* GtkGLArea:allowed-apis: (attributes org.gtk.Property.get=gtk_gl_area_get_allowed_apis org.gtk.Property.set=gtk_gl_area_set_allowed_apis)
|
||||
*
|
||||
* The allowed APIs.
|
||||
*
|
||||
@@ -904,7 +904,7 @@ gtk_gl_area_class_init (GtkGLAreaClass *klass)
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GdkGLArea:api: (attributes org.gtk.Property.get=gtk_gl_area_get_api)
|
||||
* GtkGLArea:api: (attributes org.gtk.Property.get=gtk_gl_area_get_api)
|
||||
*
|
||||
* The API currently in use.
|
||||
*
|
||||
|
||||
+5
-5
@@ -3236,10 +3236,10 @@ gtk_label_set_attributes (GtkLabel *self,
|
||||
*
|
||||
* This is the [struct@Pango.AttrList] that was set on the label using
|
||||
* [method@Gtk.Label.set_attributes], if any. This function does not
|
||||
* reflect attributes that come from the labels markup (see
|
||||
* reflect attributes that come from the label's markup (see
|
||||
* [method@Gtk.Label.set_markup]). If you want to get the effective
|
||||
* attributes for the label, use
|
||||
* `pango_layout_get_attribute (gtk_label_get_layout (self))`.
|
||||
* `pango_layout_get_attributes (gtk_label_get_layout (self))`.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the attribute list
|
||||
*/
|
||||
@@ -3889,7 +3889,7 @@ gtk_label_get_justify (GtkLabel *self)
|
||||
* @self: a `GtkLabel`
|
||||
* @mode: a `PangoEllipsizeMode`
|
||||
*
|
||||
* Sets the mode used to ellipsizei the text.
|
||||
* Sets the mode used to ellipsize the text.
|
||||
*
|
||||
* The text will be ellipsized if there is not enough space
|
||||
* to render the entire string.
|
||||
@@ -5894,7 +5894,7 @@ gtk_label_get_xalign (GtkLabel *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_label_set_yalign: (attributes org.gtk.Method.get_property=yalign)
|
||||
* gtk_label_set_yalign: (attributes org.gtk.Method.set_property=yalign)
|
||||
* @self: a `GtkLabel`
|
||||
* @yalign: the new yalign value, between 0 and 1
|
||||
*
|
||||
@@ -5920,7 +5920,7 @@ gtk_label_set_yalign (GtkLabel *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_label_get_yalign: (attributes org.gtk.Method.set_property=yalign)
|
||||
* gtk_label_get_yalign: (attributes org.gtk.Method.get_property=yalign)
|
||||
* @self: a `GtkLabel`
|
||||
*
|
||||
* Gets the `yalign` of the label.
|
||||
|
||||
+59
-11
@@ -41,6 +41,9 @@ struct _GtkListListModel
|
||||
gpointer (* get_item) (gpointer, gpointer);
|
||||
gpointer data;
|
||||
GDestroyNotify notify;
|
||||
|
||||
guint cache_pos;
|
||||
gpointer cache_item;
|
||||
};
|
||||
|
||||
struct _GtkListListModelClass
|
||||
@@ -72,6 +75,18 @@ gtk_list_list_model_get_n_items (GListModel *list)
|
||||
return self->n_items;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_list_list_model_cache_is_valid (GtkListListModel *self)
|
||||
{
|
||||
return self->cache_item != NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_list_model_invalidate_cache (GtkListListModel *self)
|
||||
{
|
||||
self->cache_item = NULL;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
gtk_list_list_model_get_item (GListModel *list,
|
||||
guint position)
|
||||
@@ -79,31 +94,50 @@ gtk_list_list_model_get_item (GListModel *list,
|
||||
GtkListListModel *self = GTK_LIST_LIST_MODEL (list);
|
||||
gpointer result;
|
||||
guint i;
|
||||
guint start, end;
|
||||
|
||||
if (position >= self->n_items)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else if (self->get_last &&
|
||||
position >= self->n_items / 2)
|
||||
{
|
||||
result = self->get_last (self->data);
|
||||
return NULL;
|
||||
|
||||
for (i = self->n_items - 1; i > position; i--)
|
||||
start = 0;
|
||||
end = self->n_items;
|
||||
if (gtk_list_list_model_cache_is_valid (self))
|
||||
{
|
||||
if (self->cache_pos <= position)
|
||||
start = self->cache_pos;
|
||||
else
|
||||
end = self->cache_pos;
|
||||
}
|
||||
|
||||
if (self->get_last &&
|
||||
position > (start + end) / 2)
|
||||
{
|
||||
if (end == self->cache_pos && gtk_list_list_model_cache_is_valid (self))
|
||||
result = self->get_previous (self->cache_item, self->data);
|
||||
else
|
||||
result = self->get_last (self->data);
|
||||
|
||||
for (i = end - 1; i > position; i--)
|
||||
{
|
||||
result = self->get_previous (result, self->data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = self->get_first (self->data);
|
||||
if (start == self->cache_pos && gtk_list_list_model_cache_is_valid (self))
|
||||
result = self->cache_item;
|
||||
else
|
||||
result = self->get_first (self->data);
|
||||
|
||||
for (i = 0; i < position; i++)
|
||||
for (i = start; i < position; i++)
|
||||
{
|
||||
result = self->get_next (result, self->data);
|
||||
}
|
||||
}
|
||||
|
||||
self->cache_item = result;
|
||||
self->cache_pos = position;
|
||||
|
||||
return self->get_item (result, self->data);
|
||||
}
|
||||
|
||||
@@ -275,7 +309,9 @@ gtk_list_list_model_item_added_at (GtkListListModel *self,
|
||||
g_return_if_fail (GTK_IS_LIST_LIST_MODEL (self));
|
||||
g_return_if_fail (position <= self->n_items);
|
||||
|
||||
self->n_items += 1;
|
||||
self->n_items++;
|
||||
if (position <= self->cache_pos)
|
||||
self->cache_pos++;
|
||||
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), position, 0, 1);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
|
||||
@@ -327,6 +363,12 @@ gtk_list_list_model_item_moved (GtkListListModel *self,
|
||||
|
||||
min = MIN (position, previous_position);
|
||||
max = MAX (position, previous_position) + 1;
|
||||
|
||||
if (self->cache_item == item)
|
||||
self->cache_pos = position;
|
||||
else if (self->cache_pos >= min && self->cache_pos < max)
|
||||
self->cache_pos += (self->cache_pos > position ? 1 : -1);
|
||||
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), min, max - min, max - min);
|
||||
}
|
||||
|
||||
@@ -338,6 +380,10 @@ gtk_list_list_model_item_removed_at (GtkListListModel *self,
|
||||
g_return_if_fail (position < self->n_items);
|
||||
|
||||
self->n_items -= 1;
|
||||
if (position == self->cache_pos)
|
||||
gtk_list_list_model_invalidate_cache (self);
|
||||
else if (position < self->cache_pos)
|
||||
self->cache_pos--;
|
||||
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), position, 1, 0);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
|
||||
@@ -358,6 +404,8 @@ gtk_list_list_model_clear (GtkListListModel *self)
|
||||
self->n_items = 0;
|
||||
self->notify = NULL;
|
||||
|
||||
gtk_list_list_model_invalidate_cache (self);
|
||||
|
||||
if (n_items > 0)
|
||||
{
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), 0, n_items, 0);
|
||||
|
||||
@@ -67,6 +67,12 @@ init_openuri_portal (void)
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
if (gtk_xdp_open_uri_get_version (openuri) < 3)
|
||||
{
|
||||
g_warning ("Not a supported version of the OpenURI portal: %u", gtk_xdp_open_uri_get_version (openuri));
|
||||
g_clear_object (&openuri);
|
||||
}
|
||||
|
||||
g_object_unref (connection);
|
||||
}
|
||||
else
|
||||
|
||||
+47
-2
@@ -71,8 +71,14 @@
|
||||
*
|
||||
* # CSS nodes
|
||||
*
|
||||
* `GtkScaleButton` has a single CSS node with name button. To differentiate
|
||||
* it from a plain `GtkButton`, it gets the .scale style class.
|
||||
* ```
|
||||
* scalebutton.scale
|
||||
* ╰── button.toggle
|
||||
* ╰── <icon>
|
||||
* ```
|
||||
*
|
||||
* `GtkScaleButton` has a single CSS node with name scalebutton and `.scale`
|
||||
* style class, and contains a `button` node with a `.toggle` style class.
|
||||
*/
|
||||
|
||||
|
||||
@@ -810,6 +816,40 @@ gtk_scale_button_get_active (GtkScaleButton *button)
|
||||
return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->button));
|
||||
}
|
||||
|
||||
static void
|
||||
apply_orientation (GtkScaleButton *button,
|
||||
GtkOrientation orientation)
|
||||
{
|
||||
GtkScaleButtonPrivate *priv = gtk_scale_button_get_instance_private (button);
|
||||
|
||||
if (priv->applied_orientation != orientation)
|
||||
{
|
||||
priv->applied_orientation = orientation;
|
||||
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (priv->box), orientation);
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (priv->scale), orientation);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_VERTICAL)
|
||||
{
|
||||
gtk_box_reorder_child_after (GTK_BOX (priv->box), priv->scale,
|
||||
priv->plus_button);
|
||||
gtk_box_reorder_child_after (GTK_BOX (priv->box), priv->minus_button,
|
||||
priv->scale);
|
||||
gtk_widget_set_size_request (GTK_WIDGET (priv->scale), -1, SCALE_SIZE);
|
||||
gtk_range_set_inverted (GTK_RANGE (priv->scale), TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_box_reorder_child_after (GTK_BOX (priv->box), priv->scale,
|
||||
priv->minus_button);
|
||||
gtk_box_reorder_child_after (GTK_BOX (priv->box), priv->plus_button,
|
||||
priv->scale);
|
||||
gtk_widget_set_size_request (GTK_WIDGET (priv->scale), SCALE_SIZE, -1);
|
||||
gtk_range_set_inverted (GTK_RANGE (priv->scale), FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_scale_button_set_orientation_private (GtkScaleButton *button,
|
||||
GtkOrientation orientation)
|
||||
@@ -819,6 +859,9 @@ gtk_scale_button_set_orientation_private (GtkScaleButton *button,
|
||||
if (priv->orientation != orientation)
|
||||
{
|
||||
priv->orientation = orientation;
|
||||
|
||||
apply_orientation (button, priv->orientation);
|
||||
|
||||
g_object_notify (G_OBJECT (button), "orientation");
|
||||
}
|
||||
}
|
||||
@@ -855,6 +898,8 @@ gtk_scale_popup (GtkWidget *widget)
|
||||
GtkScaleButton *button = GTK_SCALE_BUTTON (widget);
|
||||
GtkScaleButtonPrivate *priv = gtk_scale_button_get_instance_private (button);
|
||||
|
||||
apply_orientation (button, priv->orientation);
|
||||
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->button), TRUE);
|
||||
}
|
||||
|
||||
|
||||
@@ -4202,9 +4202,7 @@ gtk_scrolled_window_set_child (GtkScrolledWindow *scrolled_window,
|
||||
if (priv->child)
|
||||
{
|
||||
if (priv->auto_added_viewport)
|
||||
{
|
||||
gtk_viewport_set_child (GTK_VIEWPORT (priv->child), NULL);
|
||||
}
|
||||
gtk_viewport_set_child (GTK_VIEWPORT (priv->child), NULL);
|
||||
|
||||
g_object_set (priv->child,
|
||||
"hadjustment", NULL,
|
||||
@@ -4212,6 +4210,7 @@ gtk_scrolled_window_set_child (GtkScrolledWindow *scrolled_window,
|
||||
NULL);
|
||||
|
||||
g_clear_pointer (&priv->child, gtk_widget_unparent);
|
||||
priv->auto_added_viewport = FALSE;
|
||||
}
|
||||
|
||||
if (child)
|
||||
|
||||
+8
-1
@@ -300,6 +300,8 @@ gtk_snapshot_new (void)
|
||||
* Returns the node that was constructed by @snapshot
|
||||
* and frees @snapshot.
|
||||
*
|
||||
* See also [method@Gtk.Snapshot.to_node].
|
||||
*
|
||||
* Returns: (transfer full) (nullable): a newly-created [class@Gsk.RenderNode]
|
||||
*/
|
||||
GskRenderNode *
|
||||
@@ -1569,11 +1571,16 @@ gtk_snapshot_pop_collect (GtkSnapshot *snapshot)
|
||||
* Returns the render node that was constructed
|
||||
* by @snapshot.
|
||||
*
|
||||
* Note that this function may return %NULL if nothing has been
|
||||
* added to the snapshot or if its content does not produce pixels
|
||||
* to be rendered.
|
||||
*
|
||||
* After calling this function, it is no longer possible to
|
||||
* add more nodes to @snapshot. The only function that should
|
||||
* be called after this is [method@GObject.Object.unref].
|
||||
*
|
||||
* Returns: (transfer full) (nullable): the constructed `GskRenderNode`
|
||||
* Returns: (transfer full) (nullable): the constructed `GskRenderNode` or
|
||||
* %NULL if there are no nodes to render.
|
||||
*/
|
||||
GskRenderNode *
|
||||
gtk_snapshot_to_node (GtkSnapshot *snapshot)
|
||||
|
||||
+22
-1
@@ -320,6 +320,8 @@ static void gtk_text_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gtk_text_notify (GObject *object,
|
||||
GParamSpec *pspec);
|
||||
static void gtk_text_finalize (GObject *object);
|
||||
static void gtk_text_dispose (GObject *object);
|
||||
|
||||
@@ -738,6 +740,7 @@ gtk_text_class_init (GtkTextClass *class)
|
||||
gobject_class->finalize = gtk_text_finalize;
|
||||
gobject_class->set_property = gtk_text_set_property;
|
||||
gobject_class->get_property = gtk_text_get_property;
|
||||
gobject_class->notify = gtk_text_notify;
|
||||
|
||||
widget_class->map = gtk_text_map;
|
||||
widget_class->unmap = gtk_text_unmap;
|
||||
@@ -1815,6 +1818,17 @@ gtk_text_get_property (GObject *object,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_notify (GObject *object,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
if (pspec->name == I_("has-focus"))
|
||||
gtk_text_check_cursor_blink (GTK_TEXT (object));
|
||||
|
||||
if (G_OBJECT_CLASS (gtk_text_parent_class)->notify)
|
||||
G_OBJECT_CLASS (gtk_text_parent_class)->notify (object, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_ensure_text_handles (GtkText *self)
|
||||
{
|
||||
@@ -3260,6 +3274,7 @@ gtk_text_focus_changed (GtkEventControllerFocus *controller,
|
||||
gtk_text_im_set_focus_in (self);
|
||||
gtk_text_reset_blink_time (self);
|
||||
gtk_text_check_cursor_blink (self);
|
||||
gtk_text_update_primary_selection (self);
|
||||
}
|
||||
else /* Focus out */
|
||||
{
|
||||
@@ -5364,6 +5379,9 @@ gtk_text_update_primary_selection (GtkText *self)
|
||||
if (!gtk_widget_get_realized (GTK_WIDGET (self)))
|
||||
return;
|
||||
|
||||
if (!gtk_widget_has_focus (GTK_WIDGET (self)))
|
||||
return;
|
||||
|
||||
clipboard = gtk_widget_get_primary_clipboard (GTK_WIDGET (self));
|
||||
|
||||
if (priv->selection_bound != priv->current_pos)
|
||||
@@ -6451,8 +6469,11 @@ static gboolean
|
||||
cursor_blinks (GtkText *self)
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
GtkRoot *root = gtk_widget_get_root (GTK_WIDGET (self));
|
||||
|
||||
if (gtk_event_controller_focus_is_focus (GTK_EVENT_CONTROLLER_FOCUS (priv->focus_controller)) &&
|
||||
if (gtk_widget_get_mapped (GTK_WIDGET (self)) &&
|
||||
gtk_window_is_active (GTK_WINDOW (root)) &&
|
||||
gtk_event_controller_focus_is_focus (GTK_EVENT_CONTROLLER_FOCUS (priv->focus_controller)) &&
|
||||
priv->editable &&
|
||||
priv->selection_bound == priv->current_pos)
|
||||
{
|
||||
|
||||
@@ -5640,6 +5640,26 @@ gtk_text_view_click_gesture_pressed (GtkGestureClick *gesture,
|
||||
if (state & GDK_SHIFT_MASK)
|
||||
extends = TRUE;
|
||||
|
||||
if (n_press > 1)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter cur, ins;
|
||||
|
||||
buffer = get_buffer (text_view);
|
||||
get_iter_from_gesture (text_view, GTK_GESTURE (gesture),
|
||||
&cur, NULL, NULL);
|
||||
gtk_text_buffer_get_iter_at_mark (buffer, &ins,
|
||||
gtk_text_buffer_get_insert (buffer));
|
||||
|
||||
/* Reset count if double/triple clicking on a different line */
|
||||
if (gtk_text_iter_get_line (&cur) !=
|
||||
gtk_text_iter_get_line (&ins))
|
||||
{
|
||||
gtk_event_controller_reset (GTK_EVENT_CONTROLLER (gesture));
|
||||
n_press = 1;
|
||||
}
|
||||
}
|
||||
|
||||
switch (n_press)
|
||||
{
|
||||
case 1:
|
||||
|
||||
+4
-1
@@ -2023,7 +2023,7 @@ gtk_window_root_set_focus (GtkRoot *root,
|
||||
synthesize_focus_change_events (self, old_focus, focus, GTK_CROSSING_FOCUS);
|
||||
|
||||
if (focus)
|
||||
gtk_widget_set_has_focus (focus, TRUE);
|
||||
gtk_widget_set_has_focus (focus, priv->is_active);
|
||||
|
||||
g_set_object (&priv->focus_widget, focus);
|
||||
|
||||
@@ -3828,6 +3828,9 @@ gtk_window_show (GtkWidget *widget)
|
||||
GtkWindow *window = GTK_WINDOW (widget);
|
||||
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
|
||||
|
||||
if (!g_list_store_find (toplevel_list, window, NULL))
|
||||
g_warning ("A window is shown after it has been destroyed. This will leave the window in an inconsistent state.");
|
||||
|
||||
_gtk_widget_set_visible_flag (widget, TRUE);
|
||||
|
||||
gtk_css_node_validate (gtk_widget_get_css_node (widget));
|
||||
|
||||
@@ -38,6 +38,7 @@ struct _GtkInspectorActionEditor
|
||||
gboolean enabled;
|
||||
const GVariantType *parameter_type;
|
||||
GVariantType *state_type;
|
||||
GVariant *state;
|
||||
GtkWidget *activate_button;
|
||||
GtkWidget *parameter_entry;
|
||||
GtkWidget *state_entry;
|
||||
@@ -101,6 +102,11 @@ state_changed (GtkWidget *editor,
|
||||
return;
|
||||
|
||||
g_variant_ref_sink (value);
|
||||
if (g_variant_equal (value, r->state))
|
||||
{
|
||||
g_variant_unref (value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (G_IS_ACTION_GROUP (r->owner))
|
||||
g_action_group_change_action_state (G_ACTION_GROUP (r->owner), r->name, value);
|
||||
@@ -147,35 +153,35 @@ gtk_inspector_action_editor_init (GtkInspectorActionEditor *r)
|
||||
static void
|
||||
update_widgets (GtkInspectorActionEditor *r)
|
||||
{
|
||||
GVariant *state;
|
||||
g_clear_pointer (&r->state, g_variant_unref);
|
||||
|
||||
if (G_IS_ACTION_GROUP (r->owner))
|
||||
{
|
||||
if (!g_action_group_query_action (G_ACTION_GROUP (r->owner), r->name,
|
||||
&r->enabled, &r->parameter_type, NULL, NULL,
|
||||
&state))
|
||||
&r->state))
|
||||
{
|
||||
r->enabled = FALSE;
|
||||
r->parameter_type = NULL;
|
||||
state = NULL;
|
||||
r->state = NULL;
|
||||
}
|
||||
}
|
||||
else if (GTK_IS_ACTION_MUXER (r->owner))
|
||||
{
|
||||
if (!gtk_action_muxer_query_action (GTK_ACTION_MUXER (r->owner), r->name,
|
||||
&r->enabled, &r->parameter_type, NULL, NULL,
|
||||
&state))
|
||||
&r->state))
|
||||
{
|
||||
r->enabled = FALSE;
|
||||
r->parameter_type = NULL;
|
||||
state = NULL;
|
||||
r->state = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
r->enabled = FALSE;
|
||||
r->parameter_type = NULL;
|
||||
state = NULL;
|
||||
r->state = NULL;
|
||||
}
|
||||
|
||||
gtk_widget_set_sensitive (r->activate_button, r->enabled);
|
||||
@@ -184,15 +190,13 @@ update_widgets (GtkInspectorActionEditor *r)
|
||||
if (r->parameter_type)
|
||||
gtk_inspector_variant_editor_set_type (r->parameter_entry, r->parameter_type);
|
||||
|
||||
gtk_widget_set_visible (r->state_editor, state != NULL);
|
||||
if (state)
|
||||
gtk_widget_set_visible (r->state_editor, r->state != NULL);
|
||||
if (r->state)
|
||||
{
|
||||
if (r->state_type)
|
||||
g_variant_type_free (r->state_type);
|
||||
r->state_type = g_variant_type_copy (g_variant_get_type (state));
|
||||
gtk_inspector_variant_editor_set_value (r->state_entry, state);
|
||||
|
||||
g_variant_unref (state);
|
||||
r->state_type = g_variant_type_copy (g_variant_get_type (r->state));
|
||||
gtk_inspector_variant_editor_set_value (r->state_entry, r->state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,6 +211,7 @@ dispose (GObject *object)
|
||||
|
||||
g_clear_pointer (&r->name, g_free);
|
||||
g_clear_pointer (&r->state_type, g_variant_type_free);
|
||||
g_clear_pointer (&r->state, g_variant_unref);
|
||||
|
||||
G_OBJECT_CLASS (gtk_inspector_action_editor_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@@ -330,25 +330,25 @@
|
||||
<property name="bytes"><![CDATA[
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="GtkListItem">
|
||||
<template class="GtkColumnViewCell">
|
||||
<property name="child">
|
||||
<object class="GtkFileChooserCell">
|
||||
<binding name="item">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
<lookup name="item">GtkColumnViewCell</lookup>
|
||||
</binding>
|
||||
<property name="list-item">GtkListItem</property>
|
||||
<property name="list-item">GtkColumnViewCell</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<binding name="label">
|
||||
<closure type="gchararray" function="column_view_get_file_type">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
<lookup name="item">GtkColumnViewCell</lookup>
|
||||
</closure>
|
||||
</binding>
|
||||
<binding name="tooltip-text">
|
||||
<closure type="gchararray" function="column_view_get_tooltip_text">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
<lookup name="item">GtkColumnViewCell</lookup>
|
||||
</closure>
|
||||
</binding>
|
||||
</object>
|
||||
@@ -378,6 +378,7 @@
|
||||
<lookup name="item">GtkColumnViewCell</lookup>
|
||||
</binding>
|
||||
<property name="list-item">GtkColumnViewCell</property>
|
||||
<property name="date-column">true</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="spacing">6</property>
|
||||
@@ -388,21 +389,11 @@
|
||||
</binding>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<binding name="label">
|
||||
<closure type="gchararray" function="column_view_get_file_date">
|
||||
<lookup name="item">GtkColumnViewCell</lookup>
|
||||
</closure>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible" bind-source="file_chooser_cell" bind-property="show-time" bind-flags="sync-create"/>
|
||||
<binding name="label">
|
||||
<closure type="gchararray" function="column_view_get_file_time">
|
||||
<lookup name="item">GtkColumnViewCell</lookup>
|
||||
</closure>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
@@ -19,9 +19,6 @@
|
||||
<object class="GtkBox" id="dialog-vbox1">
|
||||
<property name="orientation">1</property>
|
||||
<property name="spacing">2</property>
|
||||
<style>
|
||||
<class name="view"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkBox" id="box1">
|
||||
<property name="orientation">1</property>
|
||||
|
||||
@@ -1641,7 +1641,7 @@ test_widget (void)
|
||||
builder = builder_new_from_string (buffer, -1, NULL);
|
||||
button1 = gtk_builder_get_object (builder, "button1");
|
||||
|
||||
g_assert_true (gtk_widget_has_focus (GTK_WIDGET (button1)));
|
||||
g_assert_true (gtk_widget_is_focus (GTK_WIDGET (button1)));
|
||||
window1 = gtk_builder_get_object (builder, "window1");
|
||||
gtk_window_destroy (GTK_WINDOW (window1));
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ free_changes (gpointer data)
|
||||
}
|
||||
|
||||
static void
|
||||
test_list_list_model (void)
|
||||
test_change (void)
|
||||
{
|
||||
GtkWidget *box;
|
||||
GListModel *model;
|
||||
@@ -111,6 +111,87 @@ test_list_list_model (void)
|
||||
g_object_unref (box);
|
||||
}
|
||||
|
||||
static void
|
||||
test_exhaustive (void)
|
||||
{
|
||||
GtkBox *box;
|
||||
GListModel *model, *compare;
|
||||
guint i;
|
||||
|
||||
box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0));
|
||||
g_object_ref_sink (box);
|
||||
|
||||
model = gtk_widget_observe_children (GTK_WIDGET (box));
|
||||
compare = G_LIST_MODEL (g_list_store_new (GTK_TYPE_WIDGET));
|
||||
|
||||
for (i = 0; i < 500; i++)
|
||||
{
|
||||
switch (g_test_rand_int_range (0, 4))
|
||||
{
|
||||
case 0:
|
||||
/* compare */
|
||||
g_assert_cmpint (g_list_model_get_n_items (model), ==, g_list_model_get_n_items (compare));
|
||||
if (g_list_model_get_n_items (compare) > 0)
|
||||
{
|
||||
guint n = g_list_model_get_n_items (compare);
|
||||
guint step = n == 1 ? 1 : g_test_rand_int_range (1, n);
|
||||
guint j = 0;
|
||||
do
|
||||
{
|
||||
gpointer o1 = g_list_model_get_item (model, j);
|
||||
gpointer o2 = g_list_model_get_item (compare, j);
|
||||
g_assert_cmphex (GPOINTER_TO_SIZE (o1), ==, GPOINTER_TO_SIZE (o2));
|
||||
g_object_unref (o1);
|
||||
g_object_unref (o2);
|
||||
j = (j + step) % n;
|
||||
}
|
||||
while (j != 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* remove a widget */
|
||||
if (g_list_model_get_n_items (compare) > 0)
|
||||
{
|
||||
guint position = g_test_rand_int_range (0, g_list_model_get_n_items (compare));
|
||||
GtkWidget *child = g_list_model_get_item (compare, position);
|
||||
gtk_box_remove (box, child);
|
||||
g_list_store_remove (G_LIST_STORE (compare), position);
|
||||
g_object_unref (child);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* add a widget */
|
||||
{
|
||||
guint position = g_test_rand_int_range (0, g_list_model_get_n_items (compare) + 1);
|
||||
GtkWidget *child = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
GtkWidget *sibling;
|
||||
if (position == 0)
|
||||
sibling = NULL;
|
||||
else
|
||||
sibling = g_list_model_get_item (compare, position - 1);
|
||||
gtk_box_insert_child_after (box, child, sibling);
|
||||
g_list_store_insert (G_LIST_STORE (compare), position, child);
|
||||
g_clear_object (&sibling);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
/* move a widget (FIXME) */
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (compare);
|
||||
g_object_unref (box);
|
||||
g_object_unref (model);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@@ -120,7 +201,8 @@ main (int argc, char *argv[])
|
||||
|
||||
changes_quark = g_quark_from_static_string ("What did I see? Can I believe what I saw?");
|
||||
|
||||
g_test_add_func ("/listlistmodel/change", test_list_list_model);
|
||||
g_test_add_func ("/listlistmodel/change", test_change);
|
||||
g_test_add_func ("/listlistmodel/exhaustive", test_exhaustive);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
||||
@@ -262,6 +262,7 @@ foreach test : focus_chain_tests
|
||||
join_paths(meson.current_source_dir(), 'focus-chain', test[0] + '.ui'),
|
||||
join_paths(meson.current_source_dir(), 'focus-chain', test[0] + '.' + test[1]),
|
||||
],
|
||||
is_parallel: false,
|
||||
env: test_env,
|
||||
suite: [ 'gtk', 'focus' ],
|
||||
)
|
||||
|
||||
@@ -383,6 +383,9 @@ check_property (GObject *instance, GParamSpec *pspec)
|
||||
g_object_set (instance, pspec->name, NULL, NULL);
|
||||
assert_notifies (instance, pspec->name, data.count, 2);
|
||||
|
||||
g_object_set (instance, pspec->name, value, NULL);
|
||||
assert_notifies (instance, pspec->name, data.count, 3);
|
||||
|
||||
g_object_unref (value);
|
||||
|
||||
g_signal_handler_disconnect (instance, id);
|
||||
|
||||
@@ -360,7 +360,6 @@ test_trigger_trigger (void)
|
||||
}
|
||||
|
||||
gdk_surface_destroy (surface);
|
||||
g_object_unref (surface);
|
||||
|
||||
g_object_unref (trigger[0]);
|
||||
g_object_unref (trigger[1]);
|
||||
|
||||
@@ -208,14 +208,18 @@ load_ui_file (GFile *ui_file,
|
||||
timeout_handle_id = g_timeout_add (2000,
|
||||
quit_iteration_loop,
|
||||
&keep_running);
|
||||
while (keep_running)
|
||||
{
|
||||
if (!g_main_context_iteration (NULL, FALSE))
|
||||
break;
|
||||
}
|
||||
while (keep_running && !gtk_window_is_active (GTK_WINDOW (window)))
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
if (keep_running)
|
||||
g_source_remove (timeout_handle_id);
|
||||
|
||||
if (!gtk_window_is_active (GTK_WINDOW (window)))
|
||||
{
|
||||
g_print ("Skipping focus tests because window did not get focus. Headless display?");
|
||||
exit (77);
|
||||
}
|
||||
|
||||
if (ext)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -17,7 +17,10 @@ setups = [
|
||||
{ 'backend': 'wayland', 'if': wayland_enabled, 'is_default': true, },
|
||||
{ 'name': 'wayland_gles',
|
||||
'backend': 'wayland', 'if': wayland_enabled,
|
||||
'env': ['GDK_DEBUG=gl-gles,default-settings'], },
|
||||
'env': ['GDK_DEBUG=gl-gles,default-settings',
|
||||
'MESA_GLES_VERSION_OVERRIDE=2.0',
|
||||
'MESA_EXTENSION_OVERRIDE=-GL_OES_vertex_array_object',
|
||||
], },
|
||||
{ 'backend': 'win32', 'if': os_win32 },
|
||||
{ 'backend': 'broadway', 'if': broadway_enabled, },
|
||||
{ 'name': 'wayland_smalltexture',
|
||||
|
||||
Reference in New Issue
Block a user