Compare commits

..

No commits in common. 'i8-beta' and 'c9' have entirely different histories.
i8-beta ... c9

2
.gitignore vendored

@ -1 +1 @@
SOURCES/mutter-3.32.2.tar.xz SOURCES/mutter-40.9.tar.xz

@ -1 +1 @@
5068f43514a6212e4b5b5f7f856b7713cbc3d420 SOURCES/mutter-3.32.2.tar.xz f9b20f8330ecdb76fc887c4a99c03b406e26fd66 SOURCES/mutter-40.9.tar.xz

@ -1,907 +0,0 @@
From fd67e75df470b50510b68ccf0f52b0b98d05c63f Mon Sep 17 00:00:00 2001
From: "Owen W. Taylor" <otaylor@fishsoup.net>
Date: Thu, 8 May 2014 18:44:15 -0400
Subject: [PATCH] Add support for quad-buffer stereo
Track the stereo status of windows using the new EXT_stereo_tree
GLX extension.
When stereo is enabled or disabled, a restart is triggered via
meta_restart() after a timeout, setting a _META_ENABLE_STEREO
property on the root window to indicate whether we should
turn on a stereo stage for clutter. The property avoids a loop,
since we need to enable stereo *before* initializing Clutter and GL,
but we need GL to figure out whether we have stereo windows.
Stereo windows are drawn to the stage using new functionality
in Cogl to setup a stereo context, select which buffer to draw
to, and draw either the left or right buffer of a stereo
texture_from_pixmap.
---
src/compositor/compositor-private.h | 9 ++
src/compositor/compositor.c | 125 +++++++++++++++
src/compositor/meta-shaped-texture-private.h | 5 +-
src/compositor/meta-shaped-texture.c | 85 +++++++++-
src/compositor/meta-surface-actor-wayland.c | 2 +-
src/compositor/meta-surface-actor-x11.c | 54 ++++++-
src/compositor/meta-surface-actor-x11.h | 5 +
src/compositor/meta-window-actor-private.h | 5 +
src/compositor/meta-window-actor.c | 22 +++
src/core/main.c | 4 +
src/core/stereo.c | 154 +++++++++++++++++++
src/core/stereo.h | 28 ++++
src/meson.build | 2 +
src/wayland/meta-wayland-surface.c | 2 +-
14 files changed, 482 insertions(+), 20 deletions(-)
create mode 100644 src/core/stereo.c
create mode 100644 src/core/stereo.h
diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h
index 6ab33416c..f70087512 100644
--- a/src/compositor/compositor-private.h
+++ b/src/compositor/compositor-private.h
@@ -24,6 +24,10 @@ struct _MetaCompositor
gint64 server_time_query_time;
gint64 server_time_offset;
+ int glx_opcode;
+ guint stereo_tree_ext : 1;
+ guint have_stereo_windows : 1;
+
guint server_time_is_monotonic_time : 1;
ClutterActor *stage, *window_group, *top_window_group, *feedback_group;
@@ -63,6 +67,11 @@ void meta_end_modal_for_plugin (MetaCompositor *compositor,
gint64 meta_compositor_monotonic_time_to_server_time (MetaDisplay *display,
gint64 monotonic_time);
+gboolean meta_compositor_window_is_stereo (MetaDisplay *display,
+ Window xwindow);
+void meta_compositor_select_stereo_notify (MetaDisplay *display,
+ Window xwindow);
+
void meta_compositor_flash_window (MetaCompositor *compositor,
MetaWindow *window);
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index 2a2c8fb3b..6c08c8fe4 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -69,6 +69,8 @@
#include "core/core.h"
#include "core/display-private.h"
#include "core/frame.h"
+#include "core/stack-tracker.h"
+#include "core/stereo.h"
#include "core/util-private.h"
#include "core/window-private.h"
#include "meta/compositor-mutter.h"
@@ -514,6 +516,94 @@ redirect_windows (MetaX11Display *x11_display)
}
}
+#define GLX_STEREO_TREE_EXT 0x20F5
+#define GLX_STEREO_NOTIFY_MASK_EXT 0x00000001
+#define GLX_STEREO_NOTIFY_EXT 0x00000000
+
+typedef struct {
+ int type;
+ unsigned long serial;
+ Bool send_event;
+ Display *display;
+ int extension;
+ int evtype;
+ Drawable window;
+ Bool stereo_tree;
+} StereoNotifyEvent;
+
+static gboolean
+display_has_stereo_tree_ext (MetaX11Display *x11_display)
+{
+ Display *xdisplay = x11_display->xdisplay;
+ const char *extensions_string;
+
+ static const char * (*query_extensions_string) (Display *display,
+ int screen);
+
+ if (query_extensions_string == NULL)
+ query_extensions_string =
+ (const char * (*) (Display *, int))
+ cogl_get_proc_address ("glXQueryExtensionsString");
+
+ extensions_string = query_extensions_string (xdisplay,
+ meta_x11_display_get_screen_number (x11_display));
+
+ return extensions_string && strstr (extensions_string, "EXT_stereo_tree") != 0;
+}
+
+#include <GL/gl.h>
+
+gboolean
+meta_compositor_window_is_stereo (MetaDisplay *display,
+ Window xwindow)
+{
+ MetaCompositor *compositor = get_compositor_for_display (display);
+ Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
+
+ static int (*query_drawable) (Display *dpy,
+ Drawable draw,
+ int attribute,
+ unsigned int *value);
+
+ if (compositor->stereo_tree_ext)
+ {
+ unsigned int stereo_tree = 0;
+
+ if (query_drawable == NULL)
+ query_drawable =
+ (int (*) (Display *, Drawable, int, unsigned int *))
+ cogl_get_proc_address ("glXQueryDrawable");
+
+ query_drawable (xdisplay, xwindow, GLX_STEREO_TREE_EXT, &stereo_tree);
+
+ return stereo_tree != 0;
+ }
+ else
+ return FALSE;
+}
+
+void
+meta_compositor_select_stereo_notify (MetaDisplay *display,
+ Window xwindow)
+{
+ MetaCompositor *compositor = get_compositor_for_display (display);
+ Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
+
+ static void (*select_event) (Display *dpy,
+ Drawable draw,
+ unsigned long event_mask);
+
+ if (compositor->stereo_tree_ext)
+ {
+ if (select_event == NULL)
+ select_event =
+ (void (*) (Display *, Drawable, unsigned long))
+ cogl_get_proc_address ("glXSelectEvent");
+
+ select_event (xdisplay, xwindow, GLX_STEREO_NOTIFY_MASK_EXT);
+ }
+}
+
void
meta_compositor_manage (MetaCompositor *compositor)
{
@@ -525,6 +615,8 @@ meta_compositor_manage (MetaCompositor *compositor)
{
xdisplay = display->x11_display->xdisplay;
meta_x11_display_set_cm_selection (display->x11_display);
+
+ compositor->stereo_tree_ext = display_has_stereo_tree_ext (display->x11_display);
}
compositor->stage = meta_backend_get_stage (backend);
@@ -822,6 +914,23 @@ meta_compositor_process_event (MetaCompositor *compositor,
if (window)
process_damage (compositor, (XDamageNotifyEvent *) event, window);
}
+ else if (!meta_is_wayland_compositor () &&
+ event->type == GenericEvent &&
+ event->xcookie.extension == compositor->glx_opcode)
+ {
+ if (event->xcookie.evtype == GLX_STEREO_NOTIFY_EXT)
+ {
+ StereoNotifyEvent *stereo_event = (StereoNotifyEvent *)(event->xcookie.data);
+ window = meta_x11_display_lookup_x_window (x11_display, stereo_event->window);
+
+ if (window != NULL)
+ {
+ MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
+ meta_window_actor_stereo_notify (window_actor, stereo_event->stereo_tree);
+ meta_stack_tracker_queue_sync_stack (window->display->stack_tracker);
+ }
+ }
+ }
if (compositor->have_x11_sync_object)
meta_sync_ring_handle_event (event);
@@ -1038,6 +1147,7 @@ meta_compositor_sync_stack (MetaCompositor *compositor,
GList *stack)
{
GList *old_stack;
+ int stereo_window_count = 0;
/* This is painful because hidden windows that we are in the process
* of animating out of existence. They'll be at the bottom of the
@@ -1113,6 +1223,8 @@ meta_compositor_sync_stack (MetaCompositor *compositor,
* near the front of the other.)
*/
compositor->windows = g_list_prepend (compositor->windows, actor);
+ if (meta_window_actor_is_stereo (actor))
+ stereo_window_count++;
stack = g_list_remove (stack, window);
old_stack = g_list_remove (old_stack, actor);
@@ -1120,6 +1232,8 @@ meta_compositor_sync_stack (MetaCompositor *compositor,
sync_actor_stacking (compositor);
+ meta_stereo_set_have_stereo_windows (stereo_window_count > 0);
+
if (compositor->top_window_actor)
g_signal_handlers_disconnect_by_func (compositor->top_window_actor,
on_top_window_actor_destroyed,
@@ -1325,6 +1439,17 @@ meta_compositor_new (MetaDisplay *display)
meta_post_paint_func,
compositor,
NULL);
+ if (!meta_is_wayland_compositor ())
+ {
+ Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
+ int glx_major_opcode, glx_first_event, glx_first_error;
+
+ if (XQueryExtension (xdisplay,
+ "GLX",
+ &glx_major_opcode, &glx_first_event, &glx_first_error))
+ compositor->glx_opcode = glx_major_opcode;
+ }
+
return compositor;
}
diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h
index a86a2bff0..d0efdd4dc 100644
--- a/src/compositor/meta-shaped-texture-private.h
+++ b/src/compositor/meta-shaped-texture-private.h
@@ -31,8 +31,9 @@
#include "meta/meta-shaped-texture.h"
ClutterActor *meta_shaped_texture_new (void);
-void meta_shaped_texture_set_texture (MetaShapedTexture *stex,
- CoglTexture *texture);
+void meta_shaped_texture_set_textures (MetaShapedTexture *stex,
+ CoglTexture *texture,
+ CoglTexture *texture_right);
void meta_shaped_texture_set_is_y_inverted (MetaShapedTexture *stex,
gboolean is_y_inverted);
void meta_shaped_texture_set_snippet (MetaShapedTexture *stex,
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index d64e214e5..332b4c814 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -88,8 +88,10 @@ struct _MetaShapedTexture
ClutterActor parent;
MetaTextureTower *paint_tower;
+ MetaTextureTower *paint_tower_right;
CoglTexture *texture;
+ CoglTexture *texture_right;
CoglTexture *mask_texture;
CoglSnippet *snippet;
@@ -160,6 +162,7 @@ static void
meta_shaped_texture_init (MetaShapedTexture *stex)
{
stex->paint_tower = meta_texture_tower_new ();
+ stex->paint_tower_right = NULL; /* demand create */
stex->texture = NULL;
stex->mask_texture = NULL;
@@ -297,7 +300,11 @@ meta_shaped_texture_dispose (GObject *object)
meta_texture_tower_free (stex->paint_tower);
stex->paint_tower = NULL;
+ g_clear_pointer (&stex->paint_tower, meta_texture_tower_free);
+ g_clear_pointer (&stex->paint_tower_right, meta_texture_tower_free);
+
g_clear_pointer (&stex->texture, cogl_object_unref);
+ g_clear_pointer (&stex->texture_right, cogl_object_unref);
g_clear_pointer (&stex->opaque_region, cairo_region_destroy);
meta_shaped_texture_set_mask_texture (stex, NULL);
@@ -507,8 +514,9 @@ paint_clipped_rectangle (MetaShapedTexture *stex,
}
static void
-set_cogl_texture (MetaShapedTexture *stex,
- CoglTexture *cogl_tex)
+set_cogl_textures (MetaShapedTexture *stex,
+ CoglTexture *cogl_tex,
+ CoglTexture *cogl_tex_right)
{
int width, height;
@@ -516,8 +524,11 @@ set_cogl_texture (MetaShapedTexture *stex,
if (stex->texture)
cogl_object_unref (stex->texture);
+ if (stex->texture_right)
+ cogl_object_unref (stex->texture_right);
stex->texture = cogl_tex;
+ stex->texture_right = cogl_tex_right;
if (cogl_tex != NULL)
{
@@ -531,6 +542,9 @@ set_cogl_texture (MetaShapedTexture *stex,
height = 0;
}
+ if (cogl_tex_right != NULL)
+ cogl_object_ref (cogl_tex_right);
+
if (stex->tex_width != width ||
stex->tex_height != height)
{
@@ -544,8 +558,23 @@ set_cogl_texture (MetaShapedTexture *stex,
* previous buffer. We only queue a redraw in response to surface
* damage. */
+ if (cogl_tex_right != NULL)
+ {
+ if (stex->paint_tower_right == NULL)
+ stex->paint_tower_right = meta_texture_tower_new ();
+ }
+ else
+ {
+ g_clear_pointer (&stex->paint_tower_right, meta_texture_tower_free);
+ }
+
if (stex->create_mipmaps)
- meta_texture_tower_set_base_texture (stex->paint_tower, cogl_tex);
+ {
+ meta_texture_tower_set_base_texture (stex->paint_tower, cogl_tex);
+
+ if (stex->paint_tower_right)
+ meta_texture_tower_set_base_texture (stex->paint_tower_right, cogl_tex_right);
+ }
}
static gboolean
@@ -779,7 +808,9 @@ meta_shaped_texture_paint (ClutterActor *actor)
{
MetaShapedTexture *stex = META_SHAPED_TEXTURE (actor);
CoglTexture *paint_tex;
+ CoglTexture *paint_tex_right = NULL;
CoglFramebuffer *fb;
+ gboolean stereo;
if (!stex->texture)
return;
@@ -841,7 +872,32 @@ meta_shaped_texture_paint (ClutterActor *actor)
return;
fb = cogl_get_draw_framebuffer ();
- do_paint (META_SHAPED_TEXTURE (actor), fb, paint_tex, stex->clip_region);
+
+ stereo = stex->texture_right && cogl_framebuffer_get_is_stereo (fb);
+
+ if (stereo)
+ {
+ if (stex->create_mipmaps)
+ paint_tex_right = meta_texture_tower_get_paint_texture (stex->paint_tower_right);
+
+ if (!paint_tex_right)
+ paint_tex_right = COGL_TEXTURE (stex->texture_right);
+ }
+ else
+ paint_tex_right = NULL;
+
+ if (stereo)
+ cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_LEFT);
+ do_paint (stex, fb, paint_tex, stex->clip_region);
+ if (stereo)
+ cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_BOTH);
+
+ if (paint_tex_right != NULL)
+ {
+ cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_RIGHT);
+ do_paint (stex, fb, paint_tex_right, stex->clip_region);
+ cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_BOTH);
+ }
}
static void
@@ -915,6 +971,12 @@ meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
stex->create_mipmaps = create_mipmaps;
base_texture = create_mipmaps ? stex->texture : NULL;
meta_texture_tower_set_base_texture (stex->paint_tower, base_texture);
+
+ if (stex->paint_tower_right)
+ {
+ base_texture = create_mipmaps ? stex->texture_right : NULL;
+ meta_texture_tower_set_base_texture (stex->paint_tower_right, base_texture);
+ }
}
}
@@ -1046,6 +1108,12 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
clip.y,
clip.width,
clip.height);
+ if (stex->paint_tower_right)
+ meta_texture_tower_update_area (stex->paint_tower_right,
+ clip.x,
+ clip.y,
+ clip.width,
+ clip.height);
stex->prev_invalidation = stex->last_invalidation;
stex->last_invalidation = g_get_monotonic_time ();
@@ -1092,17 +1160,18 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
}
/**
- * meta_shaped_texture_set_texture:
+ * meta_shaped_texture_set_textures:
* @stex: The #MetaShapedTexture
* @pixmap: The #CoglTexture to display
*/
void
-meta_shaped_texture_set_texture (MetaShapedTexture *stex,
- CoglTexture *texture)
+meta_shaped_texture_set_textures (MetaShapedTexture *stex,
+ CoglTexture *texture,
+ CoglTexture *texture_right)
{
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
- set_cogl_texture (stex, texture);
+ set_cogl_textures (stex, texture, texture_right);
}
/**
diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c
index f8d6c32b7..a75c4dd09 100644
--- a/src/compositor/meta-surface-actor-wayland.c
+++ b/src/compositor/meta-surface-actor-wayland.c
@@ -182,7 +182,7 @@ meta_surface_actor_wayland_dispose (GObject *object)
MetaShapedTexture *stex =
meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
- meta_shaped_texture_set_texture (stex, NULL);
+ meta_shaped_texture_set_textures (stex, NULL, NULL);
if (self->surface)
{
g_object_remove_weak_pointer (G_OBJECT (self->surface),
diff --git a/src/compositor/meta-surface-actor-x11.c b/src/compositor/meta-surface-actor-x11.c
index 244b1e885..3cd164d77 100644
--- a/src/compositor/meta-surface-actor-x11.c
+++ b/src/compositor/meta-surface-actor-x11.c
@@ -32,6 +32,7 @@
#include "cogl/winsys/cogl-texture-pixmap-x11.h"
#include "compositor/meta-cullable.h"
#include "compositor/meta-shaped-texture-private.h"
+#include "compositor-private.h"
#include "core/window-private.h"
#include "meta/meta-x11-errors.h"
#include "x11/meta-x11-display-private.h"
@@ -46,6 +47,7 @@ struct _MetaSurfaceActorX11
MetaDisplay *display;
CoglTexture *texture;
+ CoglTexture *texture_right;
Pixmap pixmap;
Damage damage;
@@ -61,6 +63,8 @@ struct _MetaSurfaceActorX11
guint size_changed : 1;
guint unredirected : 1;
+
+ guint stereo : 1;
};
G_DEFINE_TYPE (MetaSurfaceActorX11,
@@ -96,7 +100,7 @@ detach_pixmap (MetaSurfaceActorX11 *self)
* you are supposed to be able to free a GLXPixmap after freeing the underlying
* pixmap, but it certainly doesn't work with current DRI/Mesa
*/
- meta_shaped_texture_set_texture (stex, NULL);
+ meta_shaped_texture_set_textures (stex, NULL, NULL);
cogl_flush ();
meta_x11_error_trap_push (display->x11_display);
@@ -105,6 +109,7 @@ detach_pixmap (MetaSurfaceActorX11 *self)
meta_x11_error_trap_pop (display->x11_display);
g_clear_pointer (&self->texture, cogl_object_unref);
+ g_clear_pointer (&self->texture_right, cogl_object_unref);
}
static void
@@ -114,23 +119,37 @@ set_pixmap (MetaSurfaceActorX11 *self,
CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
CoglError *error = NULL;
- CoglTexture *texture;
+ CoglTexturePixmapX11 *texture;
+ CoglTexturePixmapX11 *texture_right;
g_assert (self->pixmap == None);
self->pixmap = pixmap;
- texture = COGL_TEXTURE (cogl_texture_pixmap_x11_new (ctx, self->pixmap, FALSE, &error));
+ if (self->stereo)
+ texture = cogl_texture_pixmap_x11_new_left (ctx, pixmap, FALSE, &error);
+ else
+ texture = cogl_texture_pixmap_x11_new (ctx, pixmap, FALSE, &error);
+
+ if (self->stereo)
+ texture_right = cogl_texture_pixmap_x11_new_right (texture);
+ else
+ texture_right = NULL;
if (error != NULL)
{
g_warning ("Failed to allocate stex texture: %s", error->message);
cogl_error_free (error);
}
- else if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (COGL_TEXTURE_PIXMAP_X11 (texture))))
+ else if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (texture)))
g_warning ("NOTE: Not using GLX TFP!\n");
- self->texture = texture;
- meta_shaped_texture_set_texture (stex, texture);
+ self->texture = COGL_TEXTURE (texture);
+ if (self->stereo)
+ self->texture_right = COGL_TEXTURE (texture_right);
+
+ meta_shaped_texture_set_textures (stex,
+ COGL_TEXTURE (texture),
+ COGL_TEXTURE (texture_right));;
}
static void
@@ -419,8 +438,8 @@ reset_texture (MetaSurfaceActorX11 *self)
/* Setting the texture to NULL will cause all the FBO's cached by the
* shaped texture's MetaTextureTower to be discarded and recreated.
*/
- meta_shaped_texture_set_texture (stex, NULL);
- meta_shaped_texture_set_texture (stex, self->texture);
+ meta_shaped_texture_set_textures (stex, NULL, NULL);
+ meta_shaped_texture_set_textures (stex, self->texture, self->texture_right);
}
MetaSurfaceActor *
@@ -428,12 +447,17 @@ meta_surface_actor_x11_new (MetaWindow *window)
{
MetaSurfaceActorX11 *self = g_object_new (META_TYPE_SURFACE_ACTOR_X11, NULL);
MetaDisplay *display = meta_window_get_display (window);
+ Window xwindow;
g_assert (!meta_is_wayland_compositor ());
self->window = window;
self->display = display;
+ xwindow = meta_window_x11_get_toplevel_xwindow (window);
+ self->stereo = meta_compositor_window_is_stereo (display, xwindow);
+ meta_compositor_select_stereo_notify (display, xwindow);
+
g_signal_connect_object (self->display, "gl-video-memory-purged",
G_CALLBACK (reset_texture), self, G_CONNECT_SWAPPED);
@@ -463,3 +487,17 @@ meta_surface_actor_x11_set_size (MetaSurfaceActorX11 *self,
self->last_height = height;
meta_shaped_texture_set_fallback_size (stex, width, height);
}
+
+void
+meta_surface_actor_x11_stereo_notify (MetaSurfaceActorX11 *self,
+ gboolean stereo_tree)
+{
+ self->stereo = stereo_tree != FALSE;
+ detach_pixmap (self);
+}
+
+gboolean
+meta_surface_actor_x11_is_stereo (MetaSurfaceActorX11 *self)
+{
+ return self->stereo;
+}
diff --git a/src/compositor/meta-surface-actor-x11.h b/src/compositor/meta-surface-actor-x11.h
index 2c4ed4dd6..3bdd5fdb0 100644
--- a/src/compositor/meta-surface-actor-x11.h
+++ b/src/compositor/meta-surface-actor-x11.h
@@ -47,6 +47,11 @@ MetaSurfaceActor * meta_surface_actor_x11_new (MetaWindow *window);
void meta_surface_actor_x11_set_size (MetaSurfaceActorX11 *self,
int width, int height);
+void meta_surface_actor_x11_stereo_notify (MetaSurfaceActorX11 *self,
+ gboolean stereo_tree);
+
+gboolean meta_surface_actor_x11_is_stereo (MetaSurfaceActorX11 *self);
+
G_END_DECLS
#endif /* __META_SURFACE_ACTOR_X11_H__ */
diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h
index 6333f43db..9c1c12d09 100644
--- a/src/compositor/meta-window-actor-private.h
+++ b/src/compositor/meta-window-actor-private.h
@@ -76,4 +76,9 @@ MetaSurfaceActor *meta_window_actor_get_surface (MetaWindowActor *self);
void meta_window_actor_update_surface (MetaWindowActor *self);
MetaWindowActor *meta_window_actor_from_window (MetaWindow *window);
+void meta_window_actor_stereo_notify (MetaWindowActor *actor,
+ gboolean stereo_tree);
+
+gboolean meta_window_actor_is_stereo (MetaWindowActor *actor);
+
#endif /* META_WINDOW_ACTOR_PRIVATE_H */
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index 1c8dc8fe5..11686d00b 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -2031,3 +2031,25 @@ screen_cast_window_iface_init (MetaScreenCastWindowInterface *iface)
iface->capture_into = meta_window_actor_capture_into;
iface->has_damage = meta_window_actor_has_damage;
}
+
+void
+meta_window_actor_stereo_notify (MetaWindowActor *self,
+ gboolean stereo_tree)
+{
+ MetaWindowActorPrivate *priv = meta_window_actor_get_instance_private (self);
+
+ if (META_IS_SURFACE_ACTOR_X11 (priv->surface))
+ meta_surface_actor_x11_stereo_notify (META_SURFACE_ACTOR_X11 (priv->surface),
+ stereo_tree);
+}
+
+gboolean
+meta_window_actor_is_stereo (MetaWindowActor *self)
+{
+ MetaWindowActorPrivate *priv = meta_window_actor_get_instance_private (self);
+
+ if (META_IS_SURFACE_ACTOR_X11 (priv->surface))
+ return meta_surface_actor_x11_is_stereo (META_SURFACE_ACTOR_X11 (priv->surface));
+ else
+ return FALSE;
+}
diff --git a/src/core/main.c b/src/core/main.c
index e8464720f..629f8e94e 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -81,6 +81,7 @@
#include "meta/meta-backend.h"
#include "meta/meta-x11-errors.h"
#include "meta/prefs.h"
+#include "stereo.h"
#include "ui/ui.h"
#include "x11/session.h"
@@ -589,6 +590,9 @@ meta_init (void)
meta_init_backend (backend_gtype);
+ if (!meta_is_wayland_compositor ())
+ meta_stereo_init ();
+
meta_clutter_init ();
#ifdef HAVE_WAYLAND
diff --git a/src/core/stereo.c b/src/core/stereo.c
new file mode 100644
index 000000000..817056527
--- /dev/null
+++ b/src/core/stereo.c
@@ -0,0 +1,154 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * SECTION:stereo
+ * @short_description: Keep track of whether we are a stereo compositor
+ *
+ * With GLX, we need to use a different GL context for stereo and
+ * non-stereo support. Support for multiple GL contexts is unfinished
+ * in Cogl and entirely lacking in Clutter, so it's by far easier
+ * to just restart Mutter when we detect a stereo window.
+ *
+ * A property _MUTTER_ENABLE_STEREO is maintained on the root window
+ * to know whether we should initialize clutter for stereo or not.
+ * When the presence or absence of stereo windows mismatches the
+ * stereo-enabled state for a sufficiently long period of time,
+ * we restart Mutter.
+ */
+
+#include <config.h>
+
+#include <clutter/x11/clutter-x11.h>
+#include <gio/gunixinputstream.h>
+#include <X11/Xatom.h>
+
+#include "display-private.h"
+#include <meta/main.h>
+#include <meta/meta-x11-display.h>
+#include <meta/util.h>
+#include "stereo.h"
+#include "ui/ui.h"
+#include "util-private.h"
+
+static guint stereo_switch_id = 0;
+static gboolean stereo_enabled = FALSE;
+/* -1 so the first time meta_stereo_set_have_stereo_windows() is called
+ * we avoid the short-circuit and set up a timeout to restart
+ * if necessary */
+static gboolean stereo_have_windows = (gboolean)-1;
+static gboolean stereo_restart = FALSE;
+
+#define STEREO_ENABLE_WAIT 1000
+#define STEREO_DISABLE_WAIT 5000
+
+void
+meta_stereo_init (void)
+{
+ Display *xdisplay;
+ Window root;
+ Atom atom_enable_stereo;
+ Atom type;
+ int format;
+ unsigned long n_items, bytes_after;
+ guchar *data;
+
+ xdisplay = XOpenDisplay (NULL);
+ if (xdisplay == NULL)
+ meta_fatal ("Unable to open X display %s\n", XDisplayName (NULL));
+
+ root = DefaultRootWindow (xdisplay);
+ atom_enable_stereo = XInternAtom (xdisplay, "_MUTTER_ENABLE_STEREO", False);
+
+ XGetWindowProperty (xdisplay, root, atom_enable_stereo,
+ 0, 1, False, XA_INTEGER,
+ &type, &format, &n_items, &bytes_after, &data);
+ if (type == XA_INTEGER)
+ {
+ if (format == 32 && n_items == 1 && bytes_after == 0)
+ {
+ stereo_enabled = *(long *)data;
+ }
+ else
+ {
+ meta_warning ("Bad value for _MUTTER_ENABLE_STEREO property\n");
+ }
+
+ XFree (data);
+ }
+ else if (type != None)
+ {
+ meta_warning ("Bad type for _MUTTER_ENABLE_STEREO property\n");
+ }
+
+ meta_verbose ("On startup, _MUTTER_ENABLE_STEREO=%s",
+ stereo_enabled ? "yes" : "no");
+ clutter_x11_set_use_stereo_stage (stereo_enabled);
+ XCloseDisplay (xdisplay);
+}
+
+static gboolean
+meta_stereo_switch (gpointer data)
+{
+ stereo_switch_id = 0;
+ stereo_restart = TRUE;
+
+ meta_restart (stereo_have_windows ?
+ _("Enabling stereo...") :
+ _("Disabling stereo..."));
+
+ return FALSE;
+}
+
+void
+meta_stereo_set_have_stereo_windows (gboolean have_windows)
+{
+ have_windows = have_windows != FALSE;
+
+ if (!stereo_restart && have_windows != stereo_have_windows)
+ {
+ MetaDisplay *display = meta_get_display ();
+ Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
+ Window root = DefaultRootWindow (xdisplay);
+ Atom atom_enable_stereo = XInternAtom (xdisplay, "_MUTTER_ENABLE_STEREO", False);
+ long value;
+
+ stereo_have_windows = have_windows;
+
+ if (stereo_have_windows)
+ meta_verbose ("Detected stereo windows\n");
+ else
+ meta_verbose ("No stereo windows detected\n");
+
+ value = stereo_have_windows;
+ XChangeProperty (xdisplay, root,
+ atom_enable_stereo, XA_INTEGER, 32,
+ PropModeReplace, (guchar *)&value, 1);
+
+ if (stereo_switch_id != 0)
+ {
+ g_source_remove (stereo_switch_id);
+ stereo_switch_id = 0;
+ }
+
+ if (stereo_have_windows != stereo_enabled)
+ stereo_switch_id = g_timeout_add (stereo_have_windows ? STEREO_ENABLE_WAIT : STEREO_DISABLE_WAIT,
+ meta_stereo_switch, NULL);
+ }
+}
diff --git a/src/core/stereo.h b/src/core/stereo.h
new file mode 100644
index 000000000..ccd1d702a
--- /dev/null
+++ b/src/core/stereo.h
@@ -0,0 +1,28 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef META_STEREO_H
+#define META_STEREO_H
+
+void meta_stereo_init (void);
+void meta_stereo_set_have_stereo_windows (gboolean have_windows);
+gboolean meta_stereo_is_restart (void);
+void meta_stereo_finish_restart (void);
+
+#endif
diff --git a/src/meson.build b/src/meson.build
index 9919b5cfb..7cced8f53 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -353,6 +353,8 @@ mutter_sources = [
'core/stack.h',
'core/stack-tracker.c',
'core/stack-tracker.h',
+ 'core/stereo.c',
+ 'core/stereo.h',
'core/startup-notification.c',
'core/startup-notification-private.h',
'core/util.c',
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index da0acfcbb..ddad1a45c 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -731,7 +731,7 @@ meta_wayland_surface_apply_pending_state (MetaWaylandSurface *surface,
snippet = meta_wayland_buffer_create_snippet (pending->buffer);
is_y_inverted = meta_wayland_buffer_is_y_inverted (pending->buffer);
- meta_shaped_texture_set_texture (stex, texture);
+ meta_shaped_texture_set_textures (stex, texture, NULL);
meta_shaped_texture_set_snippet (stex, snippet);
meta_shaped_texture_set_is_y_inverted (stex, is_y_inverted);
g_clear_pointer (&snippet, cogl_object_unref);
--
2.28.0

@ -1,55 +0,0 @@
From 38d88d4e4286c3ada041561426873e44fdba3c40 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Fri, 17 Jan 2020 14:45:00 +0100
Subject: [PATCH] Create explicit WacomDevices for tablet "touchpad" devices
---
src/backends/meta-input-settings.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c
index 28dc387ef9..820a3b201e 100644
--- a/src/backends/meta-input-settings.c
+++ b/src/backends/meta-input-settings.c
@@ -521,27 +521,34 @@ static gboolean
device_is_tablet_touchpad (MetaInputSettings *input_settings,
ClutterInputDevice *device)
{
+ gboolean is_tablet = FALSE;
#ifdef HAVE_LIBWACOM
+ MetaInputSettingsPrivate *priv;
WacomIntegrationFlags flags = 0;
WacomDevice *wacom_device;
+ priv = meta_input_settings_get_instance_private (input_settings);
+
if (clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
return FALSE;
wacom_device =
- meta_input_settings_get_tablet_wacom_device (input_settings,
- device);
+ libwacom_new_from_path (priv->wacom_db,
+ clutter_input_device_get_device_node (device),
+ WFALLBACK_NONE, NULL);
if (wacom_device)
{
flags = libwacom_get_integration_flags (wacom_device);
if ((flags & (WACOM_DEVICE_INTEGRATED_SYSTEM |
WACOM_DEVICE_INTEGRATED_DISPLAY)) == 0)
- return TRUE;
+ is_tablet = TRUE;
+
+ libwacom_destroy (wacom_device);
}
#endif
- return FALSE;
+ return is_tablet;
}
static void
--
2.25.0.rc2

@ -1,68 +0,0 @@
From abfc64268d4135663fb46c5f3529cd5f082a5c20 Mon Sep 17 00:00:00 2001
From: "Jan Alexander Steffens (heftig)" <jan.steffens@gmail.com>
Date: Sun, 20 Oct 2019 12:04:31 +0200
Subject: [PATCH] EGL: Include EGL/eglmesaext.h
The eglext.h shipped by libglvnd does not include the Mesa extensions,
unlike the header shipped in Mesa.
Fixes https://gitlab.gnome.org/GNOME/mutter/issues/876
---
cogl/cogl/meson.build | 2 +-
src/backends/meta-egl-ext.h | 1 +
src/backends/meta-egl.c | 1 +
src/backends/meta-egl.h | 1 +
4 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build
index cb940420a..8032669e4 100644
--- a/cogl/cogl/meson.build
+++ b/cogl/cogl/meson.build
@@ -48,7 +48,7 @@ cogl_gl_header_h = configure_file(
built_headers += [cogl_gl_header_h]
if have_egl
- cogl_egl_includes_string = '#include <EGL/egl.h>\n#include <EGL/eglext.h>'
+ cogl_egl_includes_string = '#include <EGL/egl.h>\n#include <EGL/eglext.h>\n#include <EGL/eglmesaext.h>'
else
cogl_egl_includes_string = ''
endif
diff --git a/src/backends/meta-egl-ext.h b/src/backends/meta-egl-ext.h
index 8705e7d5b..db0b74f76 100644
--- a/src/backends/meta-egl-ext.h
+++ b/src/backends/meta-egl-ext.h
@@ -29,6 +29,7 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
+#include <EGL/eglmesaext.h>
/*
* This is a little different to the tests shipped with EGL implementations,
diff --git a/src/backends/meta-egl.c b/src/backends/meta-egl.c
index 8b953449a..a28eef4ca 100644
--- a/src/backends/meta-egl.c
+++ b/src/backends/meta-egl.c
@@ -26,6 +26,7 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
+#include <EGL/eglmesaext.h>
#include <gio/gio.h>
#include <glib.h>
#include <glib-object.h>
diff --git a/src/backends/meta-egl.h b/src/backends/meta-egl.h
index ff37f124f..81b53b32d 100644
--- a/src/backends/meta-egl.h
+++ b/src/backends/meta-egl.h
@@ -27,6 +27,7 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
+#include <EGL/eglmesaext.h>
#include <glib-object.h>
#define META_EGL_ERROR meta_egl_error_quark ()
--
2.23.0

@ -1,28 +0,0 @@
From d9d355bfd8ecfb7dcf65a3810ec30e12f12673ab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Mon, 24 Feb 2020 16:09:59 +0100
Subject: [PATCH] Revert "MetaMonitorManager: ignore hotplug_mode_update at
startup"
This reverts commit 183f4b0c13f3dc9565bf5f693f2e5d61ca0199c9.
---
src/backends/meta-monitor-manager.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 076dca8cb..0adf2100d 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -527,8 +527,7 @@ meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager)
static gboolean
should_use_stored_config (MetaMonitorManager *manager)
{
- return (manager->in_init ||
- !meta_monitor_manager_has_hotplug_mode_update (manager));
+ return !meta_monitor_manager_has_hotplug_mode_update (manager);
}
static gboolean
--
2.24.1

@ -0,0 +1,26 @@
From 3899a01cd6cb00ca686946d3065d58f59f5c2099 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Tue, 17 Nov 2020 14:00:02 +0100
Subject: [PATCH] Revert "build: Do not provide built sources as libmutter_dep
sources"
This reverts commit 4e9a2e479969973bf3063c740ceff149036b3af4.
---
src/meson.build | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/meson.build b/src/meson.build
index e7c99caee..8fe484ec2 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -955,6 +955,7 @@ libmutter = shared_library(libmutter_name,
libmutter_dep = declare_dependency(
link_with: libmutter,
include_directories: mutter_includes,
+ sources: mutter_built_sources,
dependencies: [
libmutter_cogl_dep,
libmutter_clutter_dep,
--
2.28.0

@ -1,94 +0,0 @@
From dafc9cb414fd47112b972d34c205e73797a3c1c1 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Fri, 21 Feb 2020 16:45:35 +0100
Subject: [PATCH] Skip wacom touchpads when updating setting
---
src/backends/meta-input-settings.c | 46 +++++++++++++++++++++++-------
1 file changed, 36 insertions(+), 10 deletions(-)
diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c
index cdff7b346..7d866594a 100644
--- a/src/backends/meta-input-settings.c
+++ b/src/backends/meta-input-settings.c
@@ -569,20 +569,33 @@ update_touchpad_tap_enabled (MetaInputSettings *input_settings,
priv = meta_input_settings_get_instance_private (input_settings);
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
- enabled = device_is_tablet_touchpad (input_settings, device) ||
- g_settings_get_boolean (priv->touchpad_settings, "tap-to-click");
if (device)
{
+ enabled = device_is_tablet_touchpad (input_settings, device) ||
+ g_settings_get_boolean (priv->touchpad_settings, "tap-to-click");
settings_device_set_bool_setting (input_settings, device,
input_settings_class->set_tap_enabled,
enabled);
}
else
{
- settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
- input_settings_class->set_tap_enabled,
- enabled);
+ const GSList *devices, *l;
+
+ devices = clutter_device_manager_peek_devices (priv->device_manager);
+ for (l = devices; l; l = l->next)
+ {
+ device = l->data;
+
+ if (clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
+ continue;
+
+ enabled = device_is_tablet_touchpad (input_settings, device) ||
+ g_settings_get_boolean (priv->touchpad_settings, "tap-to-click");
+ settings_device_set_bool_setting (input_settings, device,
+ input_settings_class->set_tap_enabled,
+ enabled);
+ }
}
}
@@ -600,20 +613,33 @@ update_touchpad_tap_and_drag_enabled (MetaInputSettings *input_settings,
priv = meta_input_settings_get_instance_private (input_settings);
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
- enabled = device_is_tablet_touchpad (input_settings, device) ||
- g_settings_get_boolean (priv->touchpad_settings, "tap-and-drag");
if (device)
{
+ enabled = device_is_tablet_touchpad (input_settings, device) ||
+ g_settings_get_boolean (priv->touchpad_settings, "tap-and-drag");
settings_device_set_bool_setting (input_settings, device,
input_settings_class->set_tap_and_drag_enabled,
enabled);
}
else
{
- settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
- input_settings_class->set_tap_and_drag_enabled,
- enabled);
+ const GSList *devices, *l;
+
+ devices = clutter_device_manager_peek_devices (priv->device_manager);
+ for (l = devices; l; l = l->next)
+ {
+ device = l->data;
+
+ if (clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
+ continue;
+
+ enabled = device_is_tablet_touchpad (input_settings, device) ||
+ g_settings_get_boolean (priv->touchpad_settings, "tap-and-drag");
+ settings_device_set_bool_setting (input_settings, device,
+ input_settings_class->set_tap_and_drag_enabled,
+ enabled);
+ }
}
}
--
2.24.1

@ -0,0 +1,35 @@
From 9d0ded3178777cd6afcdd5fff7b6f0f39a0d5236 Mon Sep 17 00:00:00 2001
From: Adam Williamson <awilliam@redhat.com>
Date: Tue, 9 Mar 2021 17:21:59 -0800
Subject: [PATCH] Test: deny atomic KMS for "tegra" (RHBZ #1936991)
Signed-off-by: Adam Williamson <awilliam@redhat.com>
---
data/61-mutter.rules | 1 +
src/backends/native/meta-kms-device.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/data/61-mutter.rules b/data/61-mutter.rules
index edc03e6c1..d8e3c5f00 100644
--- a/data/61-mutter.rules
+++ b/data/61-mutter.rules
@@ -3,3 +3,4 @@ DRIVERS=="nouveau", SUBSYSTEM=="drm", TAG+="mutter-device-disable-kms-modifiers"
DRIVERS=="amdgpu", SUBSYSTEM=="drm", TAG+="mutter-device-disable-kms-modifiers"
DRIVERS=="radeon", SUBSYSTEM=="drm", TAG+="mutter-device-disable-kms-modifiers"
ENV{ID_PATH}=="platform-vkms", TAG+="mutter-device-ignore"
+DRIVER=="tegra", SUBSYSTEM=="platform", TAG+="mutter-device-disable-atomic-kms"
diff --git a/src/backends/native/meta-kms-device.c b/src/backends/native/meta-kms-device.c
index 85aded9a6..e749ab6b9 100644
--- a/src/backends/native/meta-kms-device.c
+++ b/src/backends/native/meta-kms-device.c
@@ -253,6 +253,7 @@ is_atomic_allowed (const char *driver_name)
"vboxvideo",
"nvidia-drm",
"virtio_gpu",
+ "tegra",
NULL,
};
--
2.32.0

@ -1,27 +0,0 @@
From 42f5bb4c67b86eab8b248b90ce30ffb162c62dbe Mon Sep 17 00:00:00 2001
From: Sergey Cherevko <s.cherevko@msvsphere-os.ru>
Date: Tue, 9 Jan 2024 11:31:17 +0300
Subject: [PATCH] Updated Russian translation
---
po/ru.po | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/po/ru.po b/po/ru.po
index 0f136c8..a334218 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -28,6 +28,10 @@ msgstr ""
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Poedit 1.8.7.1\n"
+#: data/50-mutter-wayland.xml:8
+msgid "Restore the keyboard shortcuts"
+msgstr "Восстановить сочетания клавиш"
+
#: data/50-mutter-navigation.xml:6
msgid "Navigation"
msgstr "Перемещение"
--
2.39.3

@ -1,49 +0,0 @@
From 967d8236d81c8689f2fe60621ec7e66d88b43dea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Wed, 17 Jun 2020 17:46:25 +0200
Subject: [PATCH 1/4] backend: Add getter for MetaScreenCast
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1318
---
src/backends/meta-backend-private.h | 2 ++
src/backends/meta-backend.c | 11 +++++++++++
2 files changed, 13 insertions(+)
diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h
index 81ec81e5f1..77f4da77c4 100644
--- a/src/backends/meta-backend-private.h
+++ b/src/backends/meta-backend-private.h
@@ -138,6 +138,8 @@ MetaEgl * meta_backend_get_egl (MetaBackend *backend);
#ifdef HAVE_REMOTE_DESKTOP
MetaRemoteDesktop * meta_backend_get_remote_desktop (MetaBackend *backend);
+
+MetaScreenCast * meta_backend_get_screen_cast (MetaBackend *backend);
#endif
gboolean meta_backend_grab_device (MetaBackend *backend,
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
index 750a9248a8..b498b7aa44 100644
--- a/src/backends/meta-backend.c
+++ b/src/backends/meta-backend.c
@@ -965,6 +965,17 @@ meta_backend_get_remote_desktop (MetaBackend *backend)
return priv->remote_desktop;
}
+
+/**
+ * meta_backend_get_screen_cast: (skip)
+ */
+MetaScreenCast *
+meta_backend_get_screen_cast (MetaBackend *backend)
+{
+ MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
+
+ return priv->screen_cast;
+}
#endif /* HAVE_REMOTE_DESKTOP */
/**
--
2.26.2

@ -0,0 +1,92 @@
From ff4dc8cc8274dc5f6ed11515e05a341e4e2cec28 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 12 Aug 2021 14:13:23 -0400
Subject: [PATCH] backend: Clean up renderer after clutter backendm
commit c4a73e795020722eda3e2bec0c16d96f9f37333b added
code to cleanup the renderer when the meta backend is
disposed. Unfortunately, this introduced a crash when
the window manager is replaced.
This is because cleaning up the renderer involves talking
to the X server over a display connection that's closed
two lines higher as part of the clutter_backend_destroy
call.
This commit fixes the crash by swapping their order.
---
src/backends/meta-backend.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
index ff84bfe6a..7e8b4ee95 100644
--- a/src/backends/meta-backend.c
+++ b/src/backends/meta-backend.c
@@ -216,63 +216,63 @@ meta_backend_dispose (GObject *object)
if (priv->sleep_signal_id)
{
g_dbus_connection_signal_unsubscribe (priv->system_bus, priv->sleep_signal_id);
priv->sleep_signal_id = 0;
}
if (priv->upower_watch_id)
{
g_bus_unwatch_name (priv->upower_watch_id);
priv->upower_watch_id = 0;
}
g_cancellable_cancel (priv->cancellable);
g_clear_object (&priv->cancellable);
g_clear_object (&priv->system_bus);
g_clear_object (&priv->upower_proxy);
g_clear_handle_id (&priv->device_update_idle_id, g_source_remove);
g_clear_pointer (&priv->device_monitors, g_hash_table_destroy);
g_clear_object (&priv->settings);
#ifdef HAVE_PROFILER
g_clear_object (&priv->profiler);
#endif
g_clear_pointer (&priv->default_seat, clutter_seat_destroy);
g_clear_pointer (&priv->stage, clutter_actor_destroy);
- g_clear_pointer (&priv->clutter_backend, clutter_backend_destroy);
g_clear_object (&priv->renderer);
g_clear_list (&priv->gpus, g_object_unref);
+ g_clear_pointer (&priv->clutter_backend, clutter_backend_destroy);
G_OBJECT_CLASS (meta_backend_parent_class)->dispose (object);
}
static void
meta_backend_destroy (MetaBackend *backend)
{
g_object_run_dispose (G_OBJECT (backend));
g_object_unref (backend);
}
static void
meta_backend_sync_screen_size (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
int width, height;
meta_monitor_manager_get_screen_size (priv->monitor_manager, &width, &height);
META_BACKEND_GET_CLASS (backend)->update_screen_size (backend, width, height);
}
static void
reset_pointer_position (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
MetaMonitorManager *monitor_manager = priv->monitor_manager;
ClutterSeat *seat = clutter_backend_get_default_seat (priv->clutter_backend);
MetaLogicalMonitor *primary;
--
2.31.1

@ -1,80 +0,0 @@
From eeff82f534f81b086d10d53124362d9e316e2cf9 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Thu, 12 Dec 2019 18:05:08 +0100
Subject: [PATCH] backends: Always enable tap-to-click/drag on opaque Wacom
tablets
Touch-wise, those are essentially giant touchpads, but have no buttons
associated to the "touchpad" device (There may be pad buttons, but
those are not mouse buttons).
Without tap-to-click/drag, touch in those devices is somewhat useless
out of the box. Have them always enable these features, despite the
setting.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/968
---
src/backends/meta-input-settings.c | 33 ++++++++++++++++++++++++++++--
1 file changed, 31 insertions(+), 2 deletions(-)
diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c
index 2e6672d9c..28dc387ef 100644
--- a/src/backends/meta-input-settings.c
+++ b/src/backends/meta-input-settings.c
@@ -517,6 +517,33 @@ update_touchpad_disable_while_typing (MetaInputSettings *input_settings,
}
}
+static gboolean
+device_is_tablet_touchpad (MetaInputSettings *input_settings,
+ ClutterInputDevice *device)
+{
+#ifdef HAVE_LIBWACOM
+ WacomIntegrationFlags flags = 0;
+ WacomDevice *wacom_device;
+
+ if (clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
+ return FALSE;
+
+ wacom_device =
+ meta_input_settings_get_tablet_wacom_device (input_settings,
+ device);
+ if (wacom_device)
+ {
+ flags = libwacom_get_integration_flags (wacom_device);
+
+ if ((flags & (WACOM_DEVICE_INTEGRATED_SYSTEM |
+ WACOM_DEVICE_INTEGRATED_DISPLAY)) == 0)
+ return TRUE;
+ }
+#endif
+
+ return FALSE;
+}
+
static void
update_touchpad_tap_enabled (MetaInputSettings *input_settings,
ClutterInputDevice *device)
@@ -531,7 +558,8 @@ update_touchpad_tap_enabled (MetaInputSettings *input_settings,
priv = meta_input_settings_get_instance_private (input_settings);
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
- enabled = g_settings_get_boolean (priv->touchpad_settings, "tap-to-click");
+ enabled = device_is_tablet_touchpad (input_settings, device) ||
+ g_settings_get_boolean (priv->touchpad_settings, "tap-to-click");
if (device)
{
@@ -561,7 +589,8 @@ update_touchpad_tap_and_drag_enabled (MetaInputSettings *input_settings,
priv = meta_input_settings_get_instance_private (input_settings);
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
- enabled = g_settings_get_boolean (priv->touchpad_settings, "tap-and-drag");
+ enabled = device_is_tablet_touchpad (input_settings, device) ||
+ g_settings_get_boolean (priv->touchpad_settings, "tap-and-drag");
if (device)
{
--
2.23.0

@ -1,205 +0,0 @@
From 20fcc3e045287c1ca591f3e795b19e120479a89a Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Wed, 12 Feb 2020 20:26:56 +0100
Subject: [PATCH 1/2] backends/x11: Implement is_grouped for X11
If the devices have a wacom description, compare those. Otherwise,
look up the devices' VID:PID, if they match they should also be
grouped.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/971
---
.../clutter/x11/clutter-input-device-xi2.c | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/clutter/clutter/x11/clutter-input-device-xi2.c b/clutter/clutter/x11/clutter-input-device-xi2.c
index ae2fa27..9eca34d 100644
--- a/clutter/clutter/x11/clutter-input-device-xi2.c
+++ b/clutter/clutter/x11/clutter-input-device-xi2.c
@@ -98,6 +98,31 @@ static gboolean
clutter_input_device_xi2_is_grouped (ClutterInputDevice *device,
ClutterInputDevice *other_device)
{
+#ifdef HAVE_LIBWACOM
+ ClutterInputDeviceXI2 *device_x11 = CLUTTER_INPUT_DEVICE_XI2 (device);
+ ClutterInputDeviceXI2 *other_device_x11 = CLUTTER_INPUT_DEVICE_XI2 (other_device);
+
+ if (device_x11->wacom_device &&
+ other_device_x11->wacom_device &&
+ libwacom_compare (device_x11->wacom_device,
+ other_device_x11->wacom_device,
+ WCOMPARE_NORMAL) == 0)
+ return TRUE;
+#endif
+
+ /* Devices with the same VID:PID get grouped together */
+ if (clutter_input_device_get_vendor_id (device) &&
+ clutter_input_device_get_product_id (device) &&
+ clutter_input_device_get_vendor_id (other_device) &&
+ clutter_input_device_get_product_id (other_device))
+ {
+ if (strcmp (clutter_input_device_get_vendor_id (device),
+ clutter_input_device_get_vendor_id (other_device)) == 0 &&
+ strcmp (clutter_input_device_get_product_id (device),
+ clutter_input_device_get_product_id (other_device)) == 0)
+ return TRUE;
+ }
+
return FALSE;
}
--
2.24.1
From 5914ab9ac79ce42da054036c4a8f118a3a868cc0 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Fri, 13 Dec 2019 15:26:05 +0100
Subject: [PATCH 2/2] backends: Check both input settings and mapper for tablet
monitors
The upper layers (OSDs basically) want to know the monitor that a
tablet is currently assigned to, not the monitor just as configured
through settings.
This broke proper OSD positioning for display-attached tablets since
commit 87858a4e01d9, as the MetaInputMapper kicks in precisely when
there is no configured monitor for the given device.
Consulting both about the assigned output will make OSDs pop up
again in the right place.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/971
---
src/backends/meta-input-mapper-private.h | 3 ++
src/backends/meta-input-mapper.c | 26 ++++++++++++
src/backends/meta-input-settings.c | 54 +++++++++++++++++++++++-
3 files changed, 81 insertions(+), 2 deletions(-)
diff --git a/src/backends/meta-input-mapper-private.h b/src/backends/meta-input-mapper-private.h
index 3431457..cdfdccd 100644
--- a/src/backends/meta-input-mapper-private.h
+++ b/src/backends/meta-input-mapper-private.h
@@ -42,5 +42,8 @@ ClutterInputDevice *
meta_input_mapper_get_logical_monitor_device (MetaInputMapper *mapper,
MetaLogicalMonitor *logical_monitor,
ClutterInputDeviceType device_type);
+MetaLogicalMonitor *
+meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper,
+ ClutterInputDevice *device);
#endif /* META_INPUT_MAPPER_H */
diff --git a/src/backends/meta-input-mapper.c b/src/backends/meta-input-mapper.c
index fc4f3bd..fe02ab8 100644
--- a/src/backends/meta-input-mapper.c
+++ b/src/backends/meta-input-mapper.c
@@ -675,3 +675,29 @@ meta_input_mapper_get_logical_monitor_device (MetaInputMapper *mapper,
return NULL;
}
+
+MetaLogicalMonitor *
+meta_input_mapper_get_device_logical_monitor (MetaInputMapper *mapper,
+ ClutterInputDevice *device)
+{
+ MetaMapperOutputInfo *output;
+ MetaLogicalMonitor *logical_monitor;
+ GHashTableIter iter;
+ GList *l;
+
+ g_hash_table_iter_init (&iter, mapper->output_devices);
+
+ while (g_hash_table_iter_next (&iter, (gpointer *) &logical_monitor,
+ (gpointer *) &output))
+ {
+ for (l = output->input_devices; l; l = l->next)
+ {
+ MetaMapperInputInfo *input = l->data;
+
+ if (input->device == device)
+ return logical_monitor;
+ }
+ }
+
+ return NULL;
+}
diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c
index b84595e..ab80bee 100644
--- a/src/backends/meta-input-settings.c
+++ b/src/backends/meta-input-settings.c
@@ -1937,6 +1937,42 @@ meta_input_settings_get_tablet_settings (MetaInputSettings *settings,
return info ? g_object_ref (info->settings) : NULL;
}
+static ClutterInputDevice *
+find_grouped_pen (MetaInputSettings *settings,
+ ClutterInputDevice *device)
+{
+ MetaInputSettingsPrivate *priv;
+ GSList *l, *devices;
+ ClutterInputDeviceType device_type;
+ ClutterInputDevice *pen = NULL;
+
+ device_type = clutter_input_device_get_device_type (device);
+
+ if (device_type == CLUTTER_TABLET_DEVICE ||
+ device_type == CLUTTER_PEN_DEVICE)
+ return device;
+
+ priv = meta_input_settings_get_instance_private (settings);
+ devices = clutter_device_manager_peek_devices (priv->device_manager);
+
+ for (l = devices; l; l = l->next)
+ {
+ ClutterInputDevice *device = l->data;
+
+ device_type = clutter_input_device_get_device_type (l->data);
+
+ if ((device_type == CLUTTER_TABLET_DEVICE ||
+ device_type == CLUTTER_PEN_DEVICE) &&
+ clutter_input_device_is_grouped (device, l->data))
+ {
+ pen = l->data;
+ break;
+ }
+ }
+
+ return pen;
+}
+
MetaLogicalMonitor *
meta_input_settings_get_tablet_logical_monitor (MetaInputSettings *settings,
ClutterInputDevice *device)
@@ -1948,13 +1984,27 @@ meta_input_settings_get_tablet_logical_monitor (MetaInputSettings *settings,
g_return_val_if_fail (META_IS_INPUT_SETTINGS (settings), NULL);
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL);
+ if (clutter_input_device_get_device_type (device) == CLUTTER_PAD_DEVICE)
+ {
+ device = find_grouped_pen (settings, device);
+ if (!device)
+ return NULL;
+ }
+
priv = meta_input_settings_get_instance_private (settings);
info = g_hash_table_lookup (priv->mappable_devices, device);
if (!info)
return NULL;
- meta_input_settings_find_monitor (settings, info->settings, device,
- NULL, &logical_monitor);
+ logical_monitor =
+ meta_input_mapper_get_device_logical_monitor (priv->input_mapper, device);
+
+ if (!logical_monitor)
+ {
+ meta_input_settings_find_monitor (settings, info->settings, device,
+ NULL, &logical_monitor);
+ }
+
return logical_monitor;
}
--
2.24.1

@ -1,30 +0,0 @@
From e512c397a640994807f239c570333e9942717ef5 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Fri, 13 Dec 2019 17:01:44 +0100
Subject: [PATCH] backends: Consider pen/eraser devices when looking for
matching WacomDevice
Those device types are still in use through the X11 backend, breaking some
checks around on that backend...
https://gitlab.gnome.org/GNOME/mutter/merge_requests/972
---
src/backends/meta-input-settings.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/backends/meta-input-settings.c b/src/backends/meta-input-settings.c
index 2e6672d9c..18ae52dd7 100644
--- a/src/backends/meta-input-settings.c
+++ b/src/backends/meta-input-settings.c
@@ -1589,6 +1589,8 @@ check_add_mappable_device (MetaInputSettings *input_settings,
#ifdef HAVE_LIBWACOM
if (device_type == CLUTTER_TABLET_DEVICE ||
+ device_type == CLUTTER_PEN_DEVICE ||
+ device_type == CLUTTER_ERASER_DEVICE ||
device_type == CLUTTER_PAD_DEVICE)
{
WacomError *error = libwacom_error_new ();
--
2.23.0

@ -0,0 +1,106 @@
From 8d340beb368b3b59637c91e2e6e4adbc81ce7caf Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Wed, 7 Feb 2024 21:27:32 +0100
Subject: [PATCH] backends: Disambiguate output mapped to tablet with connector
name
In some circumstances, we may end up with outputs with the same
vendor/product/serial, in which case we have a hard time finding the
right one to map tablets to, since configuration only has these 3
pieces of data.
Add the handling of a 4th argument containing the output name
based on the connector (e.g. HDMI-1), so that it can be used to
disambiguate the output if necessary.
This only kicks in if there actually are multiple outputs with the
same EDID data. A goal of the configuration as it was stored was to
remain useful if the user changed how the device is physically
connected to the computer, this remains true for the vast majority
of users having a single thing of each.
---
src/backends/meta-input-mapper.c | 43 +++++++++++++++++++++++++++++---
1 file changed, 39 insertions(+), 4 deletions(-)
diff --git a/src/backends/meta-input-mapper.c b/src/backends/meta-input-mapper.c
index ae4cd05..a0a4b8a 100644
--- a/src/backends/meta-input-mapper.c
+++ b/src/backends/meta-input-mapper.c
@@ -395,9 +395,33 @@ match_builtin (MetaInputMapper *mapper,
return monitor == meta_monitor_manager_get_laptop_panel (mapper->monitor_manager);
}
+static gboolean
+monitor_has_twin (MetaMonitor *monitor,
+ GList *monitors)
+{
+ GList *l;
+
+ for (l = monitors; l; l = l->next)
+ {
+ if (l->data == monitor)
+ continue;
+
+ if (g_strcmp0 (meta_monitor_get_vendor (monitor),
+ meta_monitor_get_vendor (l->data)) == 0 &&
+ g_strcmp0 (meta_monitor_get_product (monitor),
+ meta_monitor_get_product (l->data)) == 0 &&
+ g_strcmp0 (meta_monitor_get_serial (monitor),
+ meta_monitor_get_serial (l->data)) == 0)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static gboolean
match_config (MetaMapperInputInfo *info,
- MetaMonitor *monitor)
+ MetaMonitor *monitor,
+ GList *monitors)
{
gboolean match = FALSE;
char **edid;
@@ -406,10 +430,10 @@ match_config (MetaMapperInputInfo *info,
edid = g_settings_get_strv (info->settings, "output");
n_values = g_strv_length (edid);
- if (n_values != 3)
+ if (n_values < 3)
{
g_warning ("EDID configuration for device '%s' "
- "is incorrect, must have 3 values",
+ "is incorrect, must have at least 3 values",
clutter_input_device_get_device_name (info->device));
goto out;
}
@@ -421,6 +445,17 @@ match_config (MetaMapperInputInfo *info,
g_strcmp0 (meta_monitor_get_product (monitor), edid[1]) == 0 &&
g_strcmp0 (meta_monitor_get_serial (monitor), edid[2]) == 0);
+ if (match && n_values >= 4 && monitor_has_twin (monitor, monitors))
+ {
+ /* The 4th value if set contains the ID (e.g. HDMI-1), use it
+ * for disambiguation if multiple monitors with the same
+ * EDID data are found.
+ */
+ MetaOutput *output;
+ output = meta_monitor_get_main_output (monitor);
+ match = g_strcmp0 (meta_output_get_name (output), edid[3]) == 0;
+ }
+
out:
g_strfreev (edid);
@@ -481,7 +516,7 @@ guess_candidates (MetaInputMapper *mapper,
if (builtin && match_builtin (mapper, l->data))
match.score |= 1 << META_MATCH_IS_BUILTIN;
- if (match_config (input, l->data))
+ if (match_config (input, l->data, monitors))
match.score |= 1 << META_MATCH_CONFIG;
if (match.score > 0)
--
2.43.0

@ -0,0 +1,144 @@
From 651f5e0c6a33d9ac32c2a16735a026153a2ddf38 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Tue, 14 Jun 2022 16:31:43 +0200
Subject: [PATCH] backends: Move MetaKeyboardA11yFlags to a public header
The MetaKeyboardA11yFlags are used by gnome-shell to show a dialog
whenever a keyboard accessibility feature is switched using the
keyboard.
Unfortunately, commit c3acaeb25 renamed the Clutter flag to Meta and
moved them to a private header. As a result, gnome-shell do not show any
dialog anymore when a keyboard accessibility feature is activated.
Move the MetaKeyboardA11yFlags definition to a public header so that
gnome-shell can use it.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2306
Fixes: c3acaeb25 - backends: Move keyboard a11y into backends
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2463>
---
src/backends/meta-input-settings-private.h | 19 +------
src/meta/meson.build | 1 +
src/meta/meta-enums.h | 62 ++++++++++++++++++++++
3 files changed, 64 insertions(+), 18 deletions(-)
create mode 100644 src/meta/meta-enums.h
diff --git a/src/backends/meta-input-settings-private.h b/src/backends/meta-input-settings-private.h
index 42ee0e0e6..5ef54ee84 100644
--- a/src/backends/meta-input-settings-private.h
+++ b/src/backends/meta-input-settings-private.h
@@ -31,29 +31,12 @@
#include "backends/meta-backend-types.h"
#include "clutter/clutter.h"
#include "meta/display.h"
+#include "meta/meta-enums.h"
#define META_TYPE_INPUT_SETTINGS (meta_input_settings_get_type ())
G_DECLARE_DERIVABLE_TYPE (MetaInputSettings, meta_input_settings,
META, INPUT_SETTINGS, GObject)
-typedef enum
-{
- META_A11Y_KEYBOARD_ENABLED = 1 << 0,
- META_A11Y_TIMEOUT_ENABLED = 1 << 1,
- META_A11Y_MOUSE_KEYS_ENABLED = 1 << 2,
- META_A11Y_SLOW_KEYS_ENABLED = 1 << 3,
- META_A11Y_SLOW_KEYS_BEEP_PRESS = 1 << 4,
- META_A11Y_SLOW_KEYS_BEEP_ACCEPT = 1 << 5,
- META_A11Y_SLOW_KEYS_BEEP_REJECT = 1 << 6,
- META_A11Y_BOUNCE_KEYS_ENABLED = 1 << 7,
- META_A11Y_BOUNCE_KEYS_BEEP_REJECT = 1 << 8,
- META_A11Y_TOGGLE_KEYS_ENABLED = 1 << 9,
- META_A11Y_STICKY_KEYS_ENABLED = 1 << 10,
- META_A11Y_STICKY_KEYS_TWO_KEY_OFF = 1 << 11,
- META_A11Y_STICKY_KEYS_BEEP = 1 << 12,
- META_A11Y_FEATURE_STATE_CHANGE_BEEP = 1 << 13,
-} MetaKeyboardA11yFlags;
-
/**
* MetaKbdA11ySettings:
*
diff --git a/src/meta/meson.build b/src/meta/meson.build
index a096ee4dd..4a67abb25 100644
--- a/src/meta/meson.build
+++ b/src/meta/meson.build
@@ -17,6 +17,7 @@ mutter_public_headers = [
'meta-close-dialog.h',
'meta-cursor-tracker.h',
'meta-dnd.h',
+ 'meta-enums.h',
'meta-idle-monitor.h',
'meta-inhibit-shortcuts-dialog.h',
'meta-launch-context.h',
diff --git a/src/meta/meta-enums.h b/src/meta/meta-enums.h
new file mode 100644
index 000000000..e59ebaf72
--- /dev/null
+++ b/src/meta/meta-enums.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016-2021 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ */
+
+#ifndef META_ENUMS_H
+#define META_ENUMS_H
+
+/**
+ * MetaKeyboardA11yFlags:
+ * @META_A11Y_KEYBOARD_ENABLED:
+ * @META_A11Y_TIMEOUT_ENABLED:
+ * @META_A11Y_MOUSE_KEYS_ENABLED:
+ * @META_A11Y_SLOW_KEYS_ENABLED:
+ * @META_A11Y_SLOW_KEYS_BEEP_PRESS:
+ * @META_A11Y_SLOW_KEYS_BEEP_ACCEPT:
+ * @META_A11Y_SLOW_KEYS_BEEP_REJECT:
+ * @META_A11Y_BOUNCE_KEYS_ENABLED:
+ * @META_A11Y_BOUNCE_KEYS_BEEP_REJECT:
+ * @META_A11Y_TOGGLE_KEYS_ENABLED:
+ * @META_A11Y_STICKY_KEYS_ENABLED:
+ * @META_A11Y_STICKY_KEYS_TWO_KEY_OFF:
+ * @META_A11Y_STICKY_KEYS_BEEP:
+ * @META_A11Y_FEATURE_STATE_CHANGE_BEEP:
+ *
+ * Keyboard accessibility features.
+ *
+ */
+typedef enum
+{
+ META_A11Y_KEYBOARD_ENABLED = 1 << 0,
+ META_A11Y_TIMEOUT_ENABLED = 1 << 1,
+ META_A11Y_MOUSE_KEYS_ENABLED = 1 << 2,
+ META_A11Y_SLOW_KEYS_ENABLED = 1 << 3,
+ META_A11Y_SLOW_KEYS_BEEP_PRESS = 1 << 4,
+ META_A11Y_SLOW_KEYS_BEEP_ACCEPT = 1 << 5,
+ META_A11Y_SLOW_KEYS_BEEP_REJECT = 1 << 6,
+ META_A11Y_BOUNCE_KEYS_ENABLED = 1 << 7,
+ META_A11Y_BOUNCE_KEYS_BEEP_REJECT = 1 << 8,
+ META_A11Y_TOGGLE_KEYS_ENABLED = 1 << 9,
+ META_A11Y_STICKY_KEYS_ENABLED = 1 << 10,
+ META_A11Y_STICKY_KEYS_TWO_KEY_OFF = 1 << 11,
+ META_A11Y_STICKY_KEYS_BEEP = 1 << 12,
+ META_A11Y_FEATURE_STATE_CHANGE_BEEP = 1 << 13,
+} MetaKeyboardA11yFlags;
+
+#endif /* META_ENUMS_H */
--
2.36.1

@ -0,0 +1,34 @@
From ba25271408a32a2a73a82acc6e094a611001c9f0 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Fri, 16 Dec 2022 23:06:33 +0100
Subject: [PATCH] backends: Only apply EDID-based tablet mapping heuristic on
integrated devices
These are the ones attached to a display, thus they are the ones that may need
help from this heuristic. Non-integrated tablets (e.g. Intuos) will default to
the span of all monitors.
Fixes mapping of opaque tablets if a display-integrated tablet of the same
brand is also plugged in.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2767>
---
src/backends/meta-input-mapper.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/backends/meta-input-mapper.c b/src/backends/meta-input-mapper.c
index cc75f14e8..71d193e5f 100644
--- a/src/backends/meta-input-mapper.c
+++ b/src/backends/meta-input-mapper.c
@@ -455,7 +455,7 @@ guess_candidates (MetaInputMapper *mapper,
g_assert (META_IS_MONITOR (l->data));
- if (match_edid (input, l->data, &edid_match))
+ if (integrated && match_edid (input, l->data, &edid_match))
match.score |= 1 << edid_match;
if (integrated && match_size (input, l->data))
--
2.38.1

@ -0,0 +1,260 @@
From a1f33bdac95ba4fd0599f164ef893c05d8be123b Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Wed, 6 Oct 2021 15:31:30 -0400
Subject: [PATCH] backends/x11: Fix key repeat of on-screen keyboard for second
level keysyms
Certains keys (such as ~ and |) are in the keyboard map behind the
second shift level. This means in order for them to be input, the
shift key needs to be held down by the user.
The GNOME Shell on-screen keyboard presents these keys separately on
a page of keys that has no shift key. Instead, it relies on mutter
to set a shift latch before the key event is emitted. A shift latch
is a virtual press of the shift key that automatically gets released
after the next key press (in our case the ~ or | key).
The problem is using a shift latch doesn't work very well in the face
of key repeat. The latch is automatically released after the first
press, and subsequent repeats of that press no longer have shift
latched to them.
This commit fixes the problem by using a shift lock instead of a shift
latch. A shift lock is never implicitly released, so it remains
in place for the duration of key repeat.
---
src/backends/x11/meta-keymap-x11.c | 12 ++++++------
src/backends/x11/meta-keymap-x11.h | 6 +++---
src/backends/x11/meta-virtual-input-device-x11.c | 4 ++--
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/src/backends/x11/meta-keymap-x11.c b/src/backends/x11/meta-keymap-x11.c
index da5d064e7..1192cc387 100644
--- a/src/backends/x11/meta-keymap-x11.c
+++ b/src/backends/x11/meta-keymap-x11.c
@@ -829,85 +829,85 @@ meta_keymap_x11_reserve_keycode (MetaKeymapX11 *keymap_x11,
g_warning ("Cannot reserve a keycode for keyval %d: no available keycode", keyval);
return FALSE;
}
if (!meta_keymap_x11_replace_keycode (keymap_x11, *keycode_out, keyval))
{
g_warning ("Failed to remap keycode %d to keyval %d", *keycode_out, keyval);
return FALSE;
}
g_hash_table_insert (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (*keycode_out), GUINT_TO_POINTER (keyval));
g_queue_remove (keymap_x11->available_keycodes, GUINT_TO_POINTER (*keycode_out));
return TRUE;
}
void
meta_keymap_x11_release_keycode_if_needed (MetaKeymapX11 *keymap_x11,
uint32_t keycode)
{
g_return_if_fail (META_IS_KEYMAP_X11 (keymap_x11));
if (!g_hash_table_contains (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (keycode)) ||
g_queue_index (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode)) != -1)
return;
g_queue_push_tail (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode));
}
void
-meta_keymap_x11_latch_modifiers (MetaKeymapX11 *keymap_x11,
- uint32_t level,
- gboolean enable)
+meta_keymap_x11_lock_modifiers (MetaKeymapX11 *keymap_x11,
+ uint32_t level,
+ gboolean enable)
{
uint32_t modifiers[] = {
0,
ShiftMask,
keymap_x11->level3_shift_mask,
keymap_x11->level3_shift_mask | ShiftMask,
};
uint32_t value = 0;
if (!keymap_x11->use_xkb)
return;
level = CLAMP (level, 0, G_N_ELEMENTS (modifiers) - 1);
if (enable)
value = modifiers[level];
else
value = 0;
- XkbLatchModifiers (clutter_x11_get_default_display (),
- XkbUseCoreKbd, modifiers[level],
- value);
+ XkbLockModifiers (clutter_x11_get_default_display (),
+ XkbUseCoreKbd, modifiers[level],
+ value);
}
static uint32_t
meta_keymap_x11_get_current_group (MetaKeymapX11 *keymap_x11)
{
XkbStateRec state_rec;
if (keymap_x11->current_group >= 0)
return keymap_x11->current_group;
XkbGetState (clutter_x11_get_default_display (),
XkbUseCoreKbd, &state_rec);
return XkbStateGroup (&state_rec);
}
gboolean
meta_keymap_x11_keycode_for_keyval (MetaKeymapX11 *keymap_x11,
uint32_t keyval,
uint32_t *keycode_out,
uint32_t *level_out)
{
ClutterKeymapKey *keys;
int i, n_keys, group;
gboolean found = FALSE;
g_return_val_if_fail (keycode_out != NULL, FALSE);
g_return_val_if_fail (level_out != NULL, FALSE);
group = meta_keymap_x11_get_current_group (keymap_x11);
diff --git a/src/backends/x11/meta-keymap-x11.h b/src/backends/x11/meta-keymap-x11.h
index 67a5f8eb9..2f93acdbc 100644
--- a/src/backends/x11/meta-keymap-x11.h
+++ b/src/backends/x11/meta-keymap-x11.h
@@ -17,45 +17,45 @@
* Author: Emmanuele Bassi <ebassi@linux.intel.com>
*/
#ifndef META_KEYMAP_X11_H
#define META_KEYMAP_X11_H
#include <glib-object.h>
#include <pango/pango.h>
#include "clutter/clutter.h"
G_BEGIN_DECLS
#define META_TYPE_KEYMAP_X11 (meta_keymap_x11_get_type ())
G_DECLARE_FINAL_TYPE (MetaKeymapX11, meta_keymap_x11,
META, KEYMAP_X11, ClutterKeymap)
int meta_keymap_x11_get_key_group (MetaKeymapX11 *keymap,
ClutterModifierType state);
int meta_keymap_x11_translate_key_state (MetaKeymapX11 *keymap,
guint hardware_keycode,
ClutterModifierType *modifier_state_p,
ClutterModifierType *mods_p);
gboolean meta_keymap_x11_get_is_modifier (MetaKeymapX11 *keymap,
int keycode);
gboolean meta_keymap_x11_keycode_for_keyval (MetaKeymapX11 *keymap_x11,
guint keyval,
guint *keycode_out,
guint *level_out);
-void meta_keymap_x11_latch_modifiers (MetaKeymapX11 *keymap_x11,
- uint32_t level,
- gboolean enable);
+void meta_keymap_x11_lock_modifiers (MetaKeymapX11 *keymap_x11,
+ uint32_t level,
+ gboolean enable);
gboolean meta_keymap_x11_reserve_keycode (MetaKeymapX11 *keymap_x11,
guint keyval,
guint *keycode_out);
void meta_keymap_x11_release_keycode_if_needed (MetaKeymapX11 *keymap_x11,
guint keycode);
gboolean meta_keymap_x11_handle_event (MetaKeymapX11 *keymap_x11,
XEvent *xevent);
G_END_DECLS
#endif /* META_KEYMAP_X11_H */
diff --git a/src/backends/x11/meta-virtual-input-device-x11.c b/src/backends/x11/meta-virtual-input-device-x11.c
index fe6040859..1a5cdfc2e 100644
--- a/src/backends/x11/meta-virtual-input-device-x11.c
+++ b/src/backends/x11/meta-virtual-input-device-x11.c
@@ -159,71 +159,71 @@ meta_virtual_input_device_x11_notify_key (ClutterVirtualInputDevice *virtual_dev
ClutterKeyState key_state)
{
XTestFakeKeyEvent (clutter_x11_get_default_display (),
key + 8, key_state == CLUTTER_KEY_STATE_PRESSED, 0);
}
static void
meta_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtual_device,
uint64_t time_us,
uint32_t keyval,
ClutterKeyState key_state)
{
ClutterBackend *backend = clutter_get_default_backend ();
ClutterSeat *seat = clutter_backend_get_default_seat (backend);
MetaKeymapX11 *keymap = META_KEYMAP_X11 (clutter_seat_get_keymap (seat));
uint32_t keycode, level;
if (!meta_keymap_x11_keycode_for_keyval (keymap, keyval, &keycode, &level))
{
level = 0;
if (!meta_keymap_x11_reserve_keycode (keymap, keyval, &keycode))
{
g_warning ("No keycode found for keyval %x in current group", keyval);
return;
}
}
if (!meta_keymap_x11_get_is_modifier (keymap, keycode) &&
key_state == CLUTTER_KEY_STATE_PRESSED)
- meta_keymap_x11_latch_modifiers (keymap, level, TRUE);
+ meta_keymap_x11_lock_modifiers (keymap, level, TRUE);
XTestFakeKeyEvent (clutter_x11_get_default_display (),
(KeyCode) keycode,
key_state == CLUTTER_KEY_STATE_PRESSED, 0);
if (key_state == CLUTTER_KEY_STATE_RELEASED)
{
if (!meta_keymap_x11_get_is_modifier (keymap, keycode))
- meta_keymap_x11_latch_modifiers (keymap, level, FALSE);
+ meta_keymap_x11_lock_modifiers (keymap, level, FALSE);
meta_keymap_x11_release_keycode_if_needed (keymap, keycode);
}
}
static void
meta_virtual_input_device_x11_notify_touch_down (ClutterVirtualInputDevice *virtual_device,
uint64_t time_us,
int device_slot,
double x,
double y)
{
g_warning ("Virtual touch motion not implemented under X11");
}
static void
meta_virtual_input_device_x11_notify_touch_motion (ClutterVirtualInputDevice *virtual_device,
uint64_t time_us,
int device_slot,
double x,
double y)
{
g_warning ("Virtual touch motion not implemented under X11");
}
static void
meta_virtual_input_device_x11_notify_touch_up (ClutterVirtualInputDevice *virtual_device,
uint64_t time_us,
int device_slot)
{
g_warning ("Virtual touch motion not implemented under X11");
--
2.33.1

@ -1,118 +0,0 @@
From a8f12e7afdb35ebda581cee6a32b295cb6e643ec Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Fri, 13 Dec 2019 14:22:12 +0100
Subject: [PATCH] backends/x11: Observe multiple pad mode switch buttons in a
group
Some tablets like the Cintiq 24HDT have several mode switch buttons
per group. Those are meant to jump straight to a given mode, however
we just handle cycling across modes (as most other tablets have a
single mode switch button per group).
So spice up the mode switch handling so we handle multiple mode
switch buttons, assigning each of them a mode. If the device only
has one mode switch button, we do the old-fashioned cycling.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/970
---
.../clutter/x11/clutter-input-device-xi2.c | 71 ++++++++++++++++---
1 file changed, 60 insertions(+), 11 deletions(-)
diff --git a/clutter/clutter/x11/clutter-input-device-xi2.c b/clutter/clutter/x11/clutter-input-device-xi2.c
index 1254aca3a..c33adffc2 100644
--- a/clutter/clutter/x11/clutter-input-device-xi2.c
+++ b/clutter/clutter/x11/clutter-input-device-xi2.c
@@ -318,6 +318,57 @@ clutter_input_device_xi2_get_pad_group_mode (ClutterInputDevice *device,
return g_array_index (device_xi2->group_modes, guint, group);
}
+static gboolean
+pad_switch_mode (ClutterInputDevice *device,
+ uint32_t button,
+ uint32_t group,
+ uint32_t *mode)
+{
+ ClutterInputDeviceXI2 *device_x11 = CLUTTER_INPUT_DEVICE_XI2 (device);
+ uint32_t n_buttons, n_modes, button_group, next_mode, i;
+ GList *switch_buttons = NULL;
+
+ n_buttons = libwacom_get_num_buttons (device_x11->wacom_device);
+
+ for (i = 0; i < n_buttons; i++)
+ {
+ button_group = clutter_input_device_xi2_get_button_group (device, i);
+ if (button_group == group)
+ switch_buttons = g_list_prepend (switch_buttons, GINT_TO_POINTER (i));
+ }
+
+ switch_buttons = g_list_reverse (switch_buttons);
+ n_modes = clutter_input_device_get_group_n_modes (device, group);
+
+ if (g_list_length (switch_buttons) > 1)
+ {
+ /* If there's multiple switch buttons, we don't toggle but assign a mode
+ * to each of those buttons.
+ */
+ next_mode = g_list_index (switch_buttons, GINT_TO_POINTER (button));
+ }
+ else if (switch_buttons)
+ {
+ uint32_t cur_mode;
+
+ /* If there is a single button, have it toggle across modes */
+ cur_mode = g_array_index (device_x11->group_modes, uint32_t, group);
+ next_mode = (cur_mode + 1) % n_modes;
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ g_list_free (switch_buttons);
+
+ if (next_mode < 0 || next_mode > n_modes)
+ return FALSE;
+
+ *mode = next_mode;
+ return TRUE;
+}
+
void
clutter_input_device_xi2_update_pad_state (ClutterInputDevice *device,
guint button,
@@ -330,23 +381,21 @@ clutter_input_device_xi2_update_pad_state (ClutterInputDevice *device,
gboolean is_mode_switch = FALSE;
button_group = clutter_input_device_xi2_get_button_group (device, button);
- is_mode_switch = button_group >= 0;
- /* Assign all non-mode-switch buttons to group 0 so far */
- button_group = MAX (0, button_group);
-
- if (button_group >= device_xi2->group_modes->len)
- return;
+ if (button_group < 0 || button_group >= device_xi2->group_modes->len)
+ {
+ *group = *mode = 0;
+ return;
+ }
group_mode = &g_array_index (device_xi2->group_modes, guint, button_group);
- if (is_mode_switch && state)
+ if (state)
{
- guint next, n_modes;
+ uint32_t next_mode;
- n_modes = clutter_input_device_get_group_n_modes (device, button_group);
- next = (*group_mode + 1) % n_modes;
- *group_mode = next;
+ if (pad_switch_mode (device, button, button_group, &next_mode))
+ *group_mode = next_mode;
}
if (group)
--
2.23.0

@ -1,348 +0,0 @@
From 01803de944153694501cb64bb4250ba76ed945f5 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Thu, 19 Jan 2017 15:03:41 +0100
Subject: [PATCH] backends/x11: Support synaptics configuration
The code is taken mostly as-is from g-s-d, so we can drag the
dead horse a bit longer.
---
src/backends/x11/meta-input-settings-x11.c | 267 +++++++++++++++++++++
1 file changed, 267 insertions(+)
diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c
index 89f07ee1f..b2f5ca060 100644
--- a/src/backends/x11/meta-input-settings-x11.c
+++ b/src/backends/x11/meta-input-settings-x11.c
@@ -26,6 +26,7 @@
#include "backends/x11/meta-input-settings-x11.h"
#include <gdk/gdkx.h>
+#include <stdlib.h>
#include <string.h>
#include <X11/Xatom.h>
#include <X11/extensions/XInput2.h>
@@ -162,6 +163,179 @@ change_property (ClutterInputDevice *device,
meta_XFree (data_ret);
}
+static gboolean
+is_device_synaptics (ClutterInputDevice *device)
+{
+ guchar *has_setting;
+
+ /* We just need looking for a synaptics-specific property */
+ has_setting = get_property (device, "Synaptics Off", XA_INTEGER, 8, 1);
+ if (!has_setting)
+ return FALSE;
+
+ meta_XFree (has_setting);
+ return TRUE;
+}
+
+static void
+change_synaptics_tap_left_handed (ClutterInputDevice *device,
+ gboolean tap_enabled,
+ gboolean left_handed)
+{
+ MetaDisplay *display = meta_get_display ();
+ MetaBackend *backend = meta_get_backend ();
+ Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
+ XDevice *xdevice;
+ guchar *tap_action, *buttons;
+ guint buttons_capacity = 16, n_buttons;
+
+ xdevice = XOpenDevice(xdisplay, clutter_input_device_get_device_id (device));
+ if (!xdevice)
+ return;
+
+ tap_action = get_property (device, "Synaptics Tap Action",
+ XA_INTEGER, 8, 7);
+ if (!tap_action)
+ goto out;
+
+ tap_action[4] = tap_enabled ? (left_handed ? 3 : 1) : 0;
+ tap_action[5] = tap_enabled ? (left_handed ? 1 : 3) : 0;
+ tap_action[6] = tap_enabled ? 2 : 0;
+
+ change_property (device, "Synaptics Tap Action",
+ XA_INTEGER, 8, tap_action, 7);
+ meta_XFree (tap_action);
+
+ clutter_x11_trap_x_errors();
+ buttons = g_new (guchar, buttons_capacity);
+ n_buttons = XGetDeviceButtonMapping (xdisplay, xdevice,
+ buttons, buttons_capacity);
+
+ while (n_buttons > buttons_capacity)
+ {
+ buttons_capacity = n_buttons;
+ buttons = (guchar *) g_realloc (buttons,
+ buttons_capacity * sizeof (guchar));
+
+ n_buttons = XGetDeviceButtonMapping (xdisplay, xdevice,
+ buttons, buttons_capacity);
+ }
+
+ buttons[0] = left_handed ? 3 : 1;
+ buttons[2] = left_handed ? 1 : 3;
+ XSetDeviceButtonMapping (xdisplay, xdevice, buttons, n_buttons);
+ g_free (buttons);
+
+ if (clutter_x11_untrap_x_errors())
+ {
+ g_warning ("Could not set synaptics touchpad left-handed for %s",
+ clutter_input_device_get_device_name (device));
+ }
+
+ out:
+ XCloseDevice (xdisplay, xdevice);
+}
+
+static void
+change_synaptics_speed (ClutterInputDevice *device,
+ gdouble speed)
+{
+ MetaDisplay *display = meta_get_display ();
+ MetaBackend *backend = meta_get_backend ();
+ Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
+ XDevice *xdevice;
+ XPtrFeedbackControl feedback;
+ XFeedbackState *states, *state;
+ int i, num_feedbacks, motion_threshold, numerator, denominator;
+ gfloat motion_acceleration;
+
+ xdevice = XOpenDevice(xdisplay, clutter_input_device_get_device_id (device));
+ if (!xdevice)
+ return;
+ /* Get the list of feedbacks for the device */
+ clutter_x11_trap_x_errors();
+ states = XGetFeedbackControl (xdisplay, xdevice, &num_feedbacks);
+ if (clutter_x11_untrap_x_errors())
+ return;
+ if (!states)
+ return;
+
+ /* Calculate acceleration and threshold */
+ motion_acceleration = (speed + 1) * 5; /* speed is [-1..1], map to [0..10] */
+ motion_threshold = CLAMP (10 - floor (motion_acceleration), 1, 10);
+
+ if (motion_acceleration >= 1.0)
+ {
+ /* we want to get the acceleration, with a resolution of 0.5
+ */
+ if ((motion_acceleration - floor (motion_acceleration)) < 0.25)
+ {
+ numerator = floor (motion_acceleration);
+ denominator = 1;
+ }
+ else if ((motion_acceleration - floor (motion_acceleration)) < 0.5)
+ {
+ numerator = ceil (2.0 * motion_acceleration);
+ denominator = 2;
+ }
+ else if ((motion_acceleration - floor (motion_acceleration)) < 0.75)
+ {
+ numerator = floor (2.0 *motion_acceleration);
+ denominator = 2;
+ }
+ else
+ {
+ numerator = ceil (motion_acceleration);
+ denominator = 1;
+ }
+ }
+ else if (motion_acceleration < 1.0 && motion_acceleration > 0)
+ {
+ /* This we do to 1/10ths */
+ numerator = floor (motion_acceleration * 10) + 1;
+ denominator= 10;
+ }
+ else
+ {
+ numerator = -1;
+ denominator = -1;
+ }
+
+ clutter_x11_trap_x_errors();
+
+ state = (XFeedbackState *) states;
+
+ for (i = 0; i < num_feedbacks; i++)
+ {
+ if (state->class == PtrFeedbackClass)
+ {
+ /* And tell the device */
+ feedback.class = PtrFeedbackClass;
+ feedback.length = sizeof (XPtrFeedbackControl);
+ feedback.id = state->id;
+ feedback.threshold = motion_threshold;
+ feedback.accelNum = numerator;
+ feedback.accelDenom = denominator;
+
+ XChangeFeedbackControl (xdisplay, xdevice,
+ DvAccelNum | DvAccelDenom | DvThreshold,
+ (XFeedbackControl *) &feedback);
+ break;
+ }
+
+ state = (XFeedbackState *) ((char *) state + state->length);
+ }
+
+ if (clutter_x11_untrap_x_errors())
+ {
+ g_warning ("Could not set synaptics touchpad acceleration for %s",
+ clutter_input_device_get_device_name (device));
+ }
+
+ XFreeFeedbackList (states);
+ XCloseDevice (xdisplay, xdevice);
+}
+
static void
meta_input_settings_x11_set_send_events (MetaInputSettings *settings,
ClutterInputDevice *device,
@@ -170,6 +344,13 @@ meta_input_settings_x11_set_send_events (MetaInputSettings *settings,
guchar values[2] = { 0 }; /* disabled, disabled-on-external-mouse */
guchar *available;
+ if (is_device_synaptics (device))
+ {
+ values[0] = mode != G_DESKTOP_DEVICE_SEND_EVENTS_ENABLED;
+ change_property (device, "Synaptics Off", XA_INTEGER, 8, &values, 1);
+ return;
+ }
+
available = get_property (device, "libinput Send Events Modes Available",
XA_INTEGER, 8, 2);
if (!available)
@@ -222,6 +403,12 @@ meta_input_settings_x11_set_speed (MetaInputSettings *settings,
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
gfloat value = speed;
+ if (is_device_synaptics (device))
+ {
+ change_synaptics_speed (device, speed);
+ return;
+ }
+
change_property (device, "libinput Accel Speed",
XInternAtom (xdisplay, "FLOAT", False),
32, &value, 1);
@@ -248,6 +435,19 @@ meta_input_settings_x11_set_left_handed (MetaInputSettings *settings,
else
{
value = enabled ? 1 : 0;
+
+ if (is_device_synaptics (device))
+ {
+ GSettings *settings;
+
+ settings = g_settings_new ("org.gnome.desktop.peripherals.touchpad");
+ change_synaptics_tap_left_handed (device,
+ g_settings_get_boolean (settings, "tap-to-click"),
+ enabled);
+ g_object_unref (settings);
+ return;
+ }
+
change_property (device, "libinput Left Handed Enabled",
XA_INTEGER, 8, &value, 1);
}
@@ -271,6 +471,20 @@ meta_input_settings_x11_set_tap_enabled (MetaInputSettings *settings,
{
guchar value = (enabled) ? 1 : 0;
+ if (is_device_synaptics (device))
+ {
+ GDesktopTouchpadHandedness handedness;
+ GSettings *settings;
+
+ settings = g_settings_new ("org.gnome.desktop.peripherals.touchpad");
+ handedness = g_settings_get_enum (settings, "left-handed");
+ g_object_unref (settings);
+
+ change_synaptics_tap_left_handed (device, enabled,
+ handedness == G_DESKTOP_TOUCHPAD_HANDEDNESS_LEFT);
+ return;
+ }
+
change_property (device, "libinput Tapping Enabled",
XA_INTEGER, 8, &value, 1);
}
@@ -293,6 +507,27 @@ meta_input_settings_x11_set_invert_scroll (MetaInputSettings *settings,
{
guchar value = (inverted) ? 1 : 0;
+ if (is_device_synaptics (device))
+ {
+ gint32 *scrolling_distance;
+
+ scrolling_distance = get_property (device, "Synaptics Scrolling Distance",
+ XA_INTEGER, 32, 2);
+ if (scrolling_distance)
+ {
+ scrolling_distance[0] = inverted ?
+ -abs (scrolling_distance[0]) : abs (scrolling_distance[0]);
+ scrolling_distance[1] = inverted ?
+ -abs (scrolling_distance[1]) : abs (scrolling_distance[1]);
+
+ change_property (device, "Synaptics Scrolling Distance",
+ XA_INTEGER, 32, scrolling_distance, 2);
+ meta_XFree (scrolling_distance);
+ }
+
+ return;
+ }
+
change_property (device, "libinput Natural Scrolling Enabled",
XA_INTEGER, 8, &value, 1);
}
@@ -306,6 +541,22 @@ meta_input_settings_x11_set_edge_scroll (MetaInputSettings *settings,
guchar *current = NULL;
guchar *available = NULL;
+ if (is_device_synaptics (device))
+ {
+ current = get_property (device, "Synaptics Edge Scrolling",
+ XA_INTEGER, 8, 3);
+ if (current)
+ {
+ current[0] = !!edge_scroll_enabled;
+ current[1] = !!edge_scroll_enabled;
+ change_property (device, "Synaptics Edge Scrolling",
+ XA_INTEGER, 8, current, 3);
+ meta_XFree (current);
+ }
+
+ return;
+ }
+
available = get_property (device, "libinput Scroll Methods Available",
XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS);
if (!available || !available[SCROLL_METHOD_FIELD_EDGE])
@@ -335,6 +586,22 @@ meta_input_settings_x11_set_two_finger_scroll (MetaInputSettings *set
guchar *current = NULL;
guchar *available = NULL;
+ if (is_device_synaptics (device))
+ {
+ current = get_property (device, "Synaptics Two-Finger Scrolling",
+ XA_INTEGER, 8, 2);
+ if (current)
+ {
+ current[0] = !!two_finger_scroll_enabled;
+ current[1] = !!two_finger_scroll_enabled;
+ change_property (device, "Synaptics Two-Finger Scrolling",
+ XA_INTEGER, 8, current, 2);
+ meta_XFree (current);
+ }
+
+ return;
+ }
+
available = get_property (device, "libinput Scroll Methods Available",
XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS);
if (!available || !available[SCROLL_METHOD_FIELD_2FG])
--
2.36.1

@ -1,118 +0,0 @@
From 5a486f5b6bf5f838db5dc2bfc5819a0cba5d2d19 Mon Sep 17 00:00:00 2001
From: Daniel van Vugt <daniel.van.vugt@canonical.com>
Date: Thu, 23 May 2019 18:15:28 +0800
Subject: [PATCH] background: Reload when GPU memory is invalidated
Fixes corrupt background wallpaper when resuming from suspend on the
Nvidia driver.
https://gitlab.gnome.org/GNOME/gnome-shell/issues/1084
(cherry picked from commit a5265365dd268e15a461a58000a10b122d0bccba)
https://gitlab.gnome.org/GNOME/mutter/merge_requests/777
---
src/compositor/meta-background.c | 46 +++++++++++++++++++++++++-------
1 file changed, 36 insertions(+), 10 deletions(-)
diff --git a/src/compositor/meta-background.c b/src/compositor/meta-background.c
index c033395fe..387ce5dd3 100644
--- a/src/compositor/meta-background.c
+++ b/src/compositor/meta-background.c
@@ -252,12 +252,11 @@ static void
set_file (MetaBackground *self,
GFile **filep,
MetaBackgroundImage **imagep,
- GFile *file)
+ GFile *file,
+ gboolean force_reload)
{
- if (!file_equal0 (*filep, file))
+ if (force_reload || !file_equal0 (*filep, file))
{
- g_clear_object (filep);
-
if (*imagep)
{
g_signal_handlers_disconnect_by_func (*imagep,
@@ -267,11 +266,12 @@ set_file (MetaBackground *self,
*imagep = NULL;
}
+ g_set_object (filep, file);
+
if (file)
{
MetaBackgroundImageCache *cache = meta_background_image_cache_get_default ();
- *filep = g_object_ref (file);
*imagep = meta_background_image_cache_load (cache, file);
g_signal_connect (*imagep, "loaded",
G_CALLBACK (on_background_loaded), self);
@@ -279,6 +279,32 @@ set_file (MetaBackground *self,
}
}
+static void
+on_gl_video_memory_purged (MetaBackground *self)
+{
+ MetaBackgroundImageCache *cache = meta_background_image_cache_get_default ();
+
+ /* The GPU memory that just got invalidated is the texture inside
+ * self->background_image1,2 and/or its mipmaps. However, to save memory the
+ * original pixbuf isn't kept in RAM so we can't do a simple re-upload. The
+ * only copy of the image was the one in texture memory that got invalidated.
+ * So we need to do a full reload from disk.
+ */
+ if (self->file1)
+ {
+ meta_background_image_cache_purge (cache, self->file1);
+ set_file (self, &self->file1, &self->background_image1, self->file1, TRUE);
+ }
+
+ if (self->file2)
+ {
+ meta_background_image_cache_purge (cache, self->file2);
+ set_file (self, &self->file2, &self->background_image2, self->file2, TRUE);
+ }
+
+ mark_changed (self);
+}
+
static void
meta_background_dispose (GObject *object)
{
@@ -287,8 +313,8 @@ meta_background_dispose (GObject *object)
free_color_texture (self);
free_wallpaper_texture (self);
- set_file (self, &self->file1, &self->background_image1, NULL);
- set_file (self, &self->file2, &self->background_image2, NULL);
+ set_file (self, &self->file1, &self->background_image1, NULL, FALSE);
+ set_file (self, &self->file2, &self->background_image2, NULL, FALSE);
set_display (self, NULL);
@@ -312,7 +338,7 @@ meta_background_constructed (GObject *object)
G_OBJECT_CLASS (meta_background_parent_class)->constructed (object);
g_signal_connect_object (self->display, "gl-video-memory-purged",
- G_CALLBACK (mark_changed), object, G_CONNECT_SWAPPED);
+ G_CALLBACK (on_gl_video_memory_purged), object, G_CONNECT_SWAPPED);
g_signal_connect_object (monitor_manager, "monitors-changed",
G_CALLBACK (on_monitors_changed), self,
@@ -937,8 +963,8 @@ meta_background_set_blend (MetaBackground *self,
g_return_if_fail (META_IS_BACKGROUND (self));
g_return_if_fail (blend_factor >= 0.0 && blend_factor <= 1.0);
- set_file (self, &self->file1, &self->background_image1, file1);
- set_file (self, &self->file2, &self->background_image2, file2);
+ set_file (self, &self->file1, &self->background_image1, file1, FALSE);
+ set_file (self, &self->file2, &self->background_image2, file2, FALSE);
self->blend_factor = blend_factor;
self->style = style;
--
2.26.2

@ -1,357 +0,0 @@
From 2a2e870c139e2130b00d582546616269bca27458 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Fri, 4 Sep 2020 17:11:36 +0200
Subject: [PATCH] clutter: Backport of ::touch-mode
In upstream/master this is a ClutterSeat readonly property. Add it to
ClutterDeviceManager here, the mechanism and triggering is the same
though.
---
clutter/clutter/clutter-device-manager.c | 24 +++
clutter/clutter/clutter-device-manager.h | 2 +
.../evdev/clutter-device-manager-evdev.c | 179 ++++++++++++++++++
3 files changed, 205 insertions(+)
diff --git a/clutter/clutter/clutter-device-manager.c b/clutter/clutter/clutter-device-manager.c
index c676384..e1cc455 100644
--- a/clutter/clutter/clutter-device-manager.c
+++ b/clutter/clutter/clutter-device-manager.c
@@ -62,6 +62,7 @@ enum
PROP_0,
PROP_BACKEND,
+ PROP_TOUCH_MODE,
PROP_LAST
};
@@ -108,6 +109,7 @@ clutter_device_manager_set_property (GObject *gobject,
priv->backend = g_value_get_object (value);
break;
+ case PROP_TOUCH_MODE:
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
}
@@ -127,6 +129,10 @@ clutter_device_manager_get_property (GObject *gobject,
g_value_set_object (value, priv->backend);
break;
+ case PROP_TOUCH_MODE:
+ g_value_set_boolean (value, FALSE);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
}
@@ -143,6 +149,12 @@ clutter_device_manager_class_init (ClutterDeviceManagerClass *klass)
P_("The ClutterBackend of the device manager"),
CLUTTER_TYPE_BACKEND,
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+ obj_props[PROP_TOUCH_MODE] =
+ g_param_spec_boolean ("touch-mode",
+ P_("Touch mode"),
+ P_("Touch mode"),
+ FALSE,
+ CLUTTER_PARAM_READABLE);
gobject_class->set_property = clutter_device_manager_set_property;
gobject_class->get_property = clutter_device_manager_get_property;
@@ -579,3 +591,15 @@ clutter_device_manager_get_kbd_a11y_settings (ClutterDeviceManager *device_man
*settings = device_manager->priv->kbd_a11y_settings;
}
+
+gboolean
+clutter_device_manager_get_touch_mode (ClutterDeviceManager *device_manager)
+{
+ gboolean touch_mode;
+
+ g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager), FALSE);
+
+ g_object_get (G_OBJECT (device_manager), "touch-mode", &touch_mode, NULL);
+
+ return touch_mode;
+}
diff --git a/clutter/clutter/clutter-device-manager.h b/clutter/clutter/clutter-device-manager.h
index 1cbf030..a4a6271 100644
--- a/clutter/clutter/clutter-device-manager.h
+++ b/clutter/clutter/clutter-device-manager.h
@@ -155,6 +155,8 @@ void clutter_device_manager_set_kbd_a11y_settings (ClutterDeviceManager *devic
CLUTTER_EXPORT
void clutter_device_manager_get_kbd_a11y_settings (ClutterDeviceManager *device_manager,
ClutterKbdA11ySettings *settings);
+CLUTTER_EXPORT
+gboolean clutter_device_manager_get_touch_mode (ClutterDeviceManager *device_manager);
G_END_DECLS
diff --git a/clutter/clutter/evdev/clutter-device-manager-evdev.c b/clutter/clutter/evdev/clutter-device-manager-evdev.c
index 84b0aad..78b5b64 100644
--- a/clutter/clutter/evdev/clutter-device-manager-evdev.c
+++ b/clutter/clutter/evdev/clutter-device-manager-evdev.c
@@ -108,6 +108,19 @@ struct _ClutterDeviceManagerEvdevPrivate
gint device_id_next;
GList *free_device_ids;
+
+ guint tablet_mode_switch_state : 1;
+ guint has_touchscreen : 1;
+ guint has_tablet_switch : 1;
+ guint has_pointer : 1;
+ guint touch_mode : 1;
+};
+
+enum
+{
+ PROP_0,
+ PROP_TOUCH_MODE,
+ N_PROPS
};
static void clutter_device_manager_evdev_event_extender_init (ClutterEventExtenderInterface *iface);
@@ -765,6 +778,34 @@ clutter_event_source_free (ClutterEventSource *source)
g_source_unref (g_source);
}
+static void
+update_touch_mode (ClutterDeviceManagerEvdev *manager_evdev)
+{
+ ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv;
+ gboolean touch_mode;
+
+ /* No touch mode if we don't have a touchscreen, easy */
+ if (!priv->has_touchscreen)
+ touch_mode = FALSE;
+ /* If we have a tablet mode switch, honor it being unset */
+ else if (priv->has_tablet_switch && !priv->tablet_mode_switch_state)
+ touch_mode = FALSE;
+ /* If tablet mode is enabled, go for it */
+ else if (priv->has_tablet_switch && priv->tablet_mode_switch_state)
+ touch_mode = TRUE;
+ /* If there is no tablet mode switch (eg. kiosk machines),
+ * assume touch-mode is mutually exclusive with pointers.
+ */
+ else
+ touch_mode = !priv->has_pointer;
+
+ if (priv->touch_mode != touch_mode)
+ {
+ priv->touch_mode = touch_mode;
+ g_object_notify (G_OBJECT (manager_evdev), "touch-mode");
+ }
+}
+
static void
evdev_add_device (ClutterDeviceManagerEvdev *manager_evdev,
struct libinput_device *libinput_device)
@@ -942,19 +983,81 @@ flush_event_queue (void)
}
}
+static gboolean
+has_touchscreen (ClutterDeviceManagerEvdev *manager_evdev)
+{
+ ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv;
+ GSList *l;
+
+ for (l = priv->devices; l; l = l->next)
+ {
+ ClutterInputDeviceType device_type;
+
+ device_type = clutter_input_device_get_device_type (l->data);
+
+ if (device_type == CLUTTER_TOUCHSCREEN_DEVICE)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+device_type_is_pointer (ClutterInputDeviceType device_type)
+{
+ return (device_type == CLUTTER_POINTER_DEVICE ||
+ device_type == CLUTTER_TOUCHPAD_DEVICE);
+}
+
+static gboolean
+has_pointer (ClutterDeviceManagerEvdev *manager_evdev)
+{
+ ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv;
+ GSList *l;
+
+ for (l = priv->devices; l; l = l->next)
+ {
+ ClutterInputDeviceType device_type;
+
+ device_type = clutter_input_device_get_device_type (l->data);
+
+ if (device_type_is_pointer (device_type))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static gboolean
process_base_event (ClutterDeviceManagerEvdev *manager_evdev,
struct libinput_event *event)
{
+ ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv;
ClutterInputDevice *device;
struct libinput_device *libinput_device;
gboolean handled = TRUE;
+ gboolean check_touch_mode;
switch (libinput_event_get_type (event))
{
case LIBINPUT_EVENT_DEVICE_ADDED:
libinput_device = libinput_event_get_device (event);
+ priv->has_touchscreen |=
+ libinput_device_has_capability (libinput_device, LIBINPUT_DEVICE_CAP_TOUCH);
+ priv->has_pointer |=
+ libinput_device_has_capability (libinput_device, LIBINPUT_DEVICE_CAP_POINTER);
+ check_touch_mode = priv->has_touchscreen | priv->has_pointer;
+
+ if (libinput_device_has_capability (libinput_device,
+ LIBINPUT_DEVICE_CAP_SWITCH) &&
+ libinput_device_switch_has_switch (libinput_device,
+ LIBINPUT_SWITCH_TABLET_MODE))
+ {
+ priv->has_tablet_switch = TRUE;
+ check_touch_mode = TRUE;
+ }
+
evdev_add_device (manager_evdev, libinput_device);
break;
@@ -966,7 +1069,17 @@ process_base_event (ClutterDeviceManagerEvdev *manager_evdev,
libinput_device = libinput_event_get_device (event);
+ check_touch_mode =
+ libinput_device_has_capability (libinput_device, LIBINPUT_DEVICE_CAP_TOUCH);
device = libinput_device_get_user_data (libinput_device);
+ if (check_touch_mode)
+ priv->has_touchscreen = has_touchscreen (manager_evdev);
+ if (device_type_is_pointer (clutter_input_device_get_device_type (device)))
+ {
+ priv->has_pointer = has_pointer (manager_evdev);
+ check_touch_mode = TRUE;
+ }
+
evdev_remove_device (manager_evdev,
CLUTTER_INPUT_DEVICE_EVDEV (device));
break;
@@ -975,6 +1088,9 @@ process_base_event (ClutterDeviceManagerEvdev *manager_evdev,
handled = FALSE;
}
+ if (check_touch_mode)
+ update_touch_mode (manager_evdev);
+
return handled;
}
@@ -1752,6 +1868,23 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
notify_pad_ring (device, time, number, source, group, mode, angle);
break;
}
+ case LIBINPUT_EVENT_SWITCH_TOGGLE:
+ {
+ ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv;
+ struct libinput_event_switch *switch_event =
+ libinput_event_get_switch_event (event);
+ enum libinput_switch sw =
+ libinput_event_switch_get_switch (switch_event);
+ enum libinput_switch_state state =
+ libinput_event_switch_get_switch_state (switch_event);
+
+ if (sw == LIBINPUT_SWITCH_TABLET_MODE)
+ {
+ priv->tablet_mode_switch_state = (state == LIBINPUT_SWITCH_STATE_ON);
+ update_touch_mode (manager_evdev);
+ }
+ break;
+ }
default:
handled = FALSE;
}
@@ -1967,6 +2100,10 @@ clutter_device_manager_evdev_constructed (GObject *gobject)
source = clutter_event_source_new (manager_evdev);
priv->event_source = source;
+
+ priv->has_touchscreen = has_touchscreen (manager_evdev);
+ priv->has_pointer = has_pointer (manager_evdev);
+ update_touch_mode (manager_evdev);
}
static void
@@ -2001,6 +2138,43 @@ clutter_device_manager_evdev_dispose (GObject *object)
G_OBJECT_CLASS (clutter_device_manager_evdev_parent_class)->dispose (object);
}
+static void
+clutter_device_manager_evdev_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id)
+ {
+ case PROP_TOUCH_MODE:
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+clutter_device_manager_evdev_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ ClutterDeviceManagerEvdev *manager_evdev;
+ ClutterDeviceManagerEvdevPrivate *priv;
+
+ manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (object);
+ priv = manager_evdev->priv;
+
+ switch (prop_id)
+ {
+ case PROP_TOUCH_MODE:
+ g_value_set_boolean (value, priv->touch_mode);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+
static void
clutter_device_manager_evdev_finalize (GObject *object)
{
@@ -2036,6 +2210,8 @@ clutter_device_manager_evdev_class_init (ClutterDeviceManagerEvdevClass *klass)
gobject_class->constructed = clutter_device_manager_evdev_constructed;
gobject_class->finalize = clutter_device_manager_evdev_finalize;
gobject_class->dispose = clutter_device_manager_evdev_dispose;
+ gobject_class->set_property = clutter_device_manager_evdev_set_property;
+ gobject_class->get_property = clutter_device_manager_evdev_get_property;
manager_class = CLUTTER_DEVICE_MANAGER_CLASS (klass);
manager_class->add_device = clutter_device_manager_evdev_add_device;
@@ -2047,6 +2223,9 @@ clutter_device_manager_evdev_class_init (ClutterDeviceManagerEvdevClass *klass)
manager_class->get_supported_virtual_device_types = clutter_device_manager_evdev_get_supported_virtual_device_types;
manager_class->compress_motion = clutter_device_manager_evdev_compress_motion;
manager_class->apply_kbd_a11y_settings = clutter_device_manager_evdev_apply_kbd_a11y_settings;
+
+ g_object_class_override_property (gobject_class, PROP_TOUCH_MODE,
+ "touch-mode");
}
static void
--
2.29.2

@ -1,61 +0,0 @@
From 368fdebe8f4f4e0c0e41f5be9961a748f328cb57 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Tue, 13 Feb 2018 11:44:40 +0100
Subject: [PATCH] clutter: Extend touchpad device property check for Synaptics
So we reliably get CLUTTER_TOUCHPAD_DEVICE for those. The other heuristics
to get the device type may fall short.
---
.../clutter/x11/clutter-device-manager-xi2.c | 22 ++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/clutter/clutter/x11/clutter-device-manager-xi2.c b/clutter/clutter/x11/clutter-device-manager-xi2.c
index 87da4b050..297d3acfe 100644
--- a/clutter/clutter/x11/clutter-device-manager-xi2.c
+++ b/clutter/clutter/x11/clutter-device-manager-xi2.c
@@ -282,8 +282,9 @@ is_touch_device (XIAnyClassInfo **classes,
}
static gboolean
-is_touchpad_device (ClutterBackendX11 *backend_x11,
- XIDeviceInfo *info)
+query_exists_device_property (ClutterBackendX11 *backend_x11,
+ XIDeviceInfo *info,
+ const gchar *property)
{
gulong nitems, bytes_after;
guint32 *data = NULL;
@@ -291,7 +292,7 @@ is_touchpad_device (ClutterBackendX11 *backend_x11,
Atom type;
Atom prop;
- prop = XInternAtom (backend_x11->xdpy, "libinput Tapping Enabled", True);
+ prop = XInternAtom (backend_x11->xdpy, property, True);
if (prop == None)
return FALSE;
@@ -312,6 +313,21 @@ is_touchpad_device (ClutterBackendX11 *backend_x11,
return TRUE;
}
+static gboolean
+is_touchpad_device (ClutterBackendX11 *backend_x11,
+ XIDeviceInfo *info)
+{
+ if (query_exists_device_property (backend_x11, info,
+ "libinput Tapping Enabled"))
+ return TRUE;
+
+ if (query_exists_device_property (backend_x11, info,
+ "Synaptics Off"))
+ return TRUE;
+
+ return FALSE;
+}
+
static gboolean
get_device_ids (ClutterBackendX11 *backend_x11,
XIDeviceInfo *info,
--
2.21.0

@ -0,0 +1,38 @@
From 28030178d7682ce5be03cb7273365ab628065871 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Mon, 27 Sep 2021 20:37:30 +0200
Subject: [PATCH] clutter: Make ClutterClickAction independent of click count
This will trigger for every button press/release that is obtained,
regardless of the click count.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2024>
---
clutter/clutter/clutter-click-action.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/clutter/clutter/clutter-click-action.c b/clutter/clutter/clutter-click-action.c
index 45d87e809..266b6da92 100644
--- a/clutter/clutter/clutter-click-action.c
+++ b/clutter/clutter/clutter-click-action.c
@@ -306,9 +306,6 @@ on_event (ClutterActor *actor,
case CLUTTER_TOUCH_BEGIN:
has_button = FALSE;
case CLUTTER_BUTTON_PRESS:
- if (has_button && clutter_event_get_click_count (event) != 1)
- return CLUTTER_EVENT_PROPAGATE;
-
if (priv->is_held)
return CLUTTER_EVENT_STOP;
@@ -386,7 +383,6 @@ on_captured_event (ClutterActor *stage,
return CLUTTER_EVENT_STOP;
if ((has_button && clutter_event_get_button (event) != priv->press_button) ||
- (has_button && clutter_event_get_click_count (event) != 1) ||
clutter_event_get_device (event) != priv->press_device ||
clutter_event_get_event_sequence (event) != priv->press_sequence)
return CLUTTER_EVENT_PROPAGATE;
--
2.35.1

@ -1,27 +0,0 @@
From 2259241e4e6f03bea4e9d746582a9e6a82b3c755 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Wed, 13 Jun 2018 13:48:24 +0200
Subject: [PATCH] clutter: Only reset scroll axes on slave devices
As a plus, unknown source device IDs will just warn instead of crash.
---
clutter/clutter/x11/clutter-device-manager-xi2.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/clutter/clutter/x11/clutter-device-manager-xi2.c b/clutter/clutter/x11/clutter-device-manager-xi2.c
index 297d3acfe..76ef420ed 100644
--- a/clutter/clutter/x11/clutter-device-manager-xi2.c
+++ b/clutter/clutter/x11/clutter-device-manager-xi2.c
@@ -1899,7 +1899,8 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
_clutter_input_device_set_stage (device, NULL);
}
- _clutter_input_device_reset_scroll_info (source_device);
+ if (clutter_input_device_get_device_mode (source_device) == CLUTTER_INPUT_MODE_SLAVE)
+ _clutter_input_device_reset_scroll_info (source_device);
clutter_event_set_device (event, device);
clutter_event_set_source_device (event, source_device);
--
2.21.0

@ -1,53 +0,0 @@
From 4c1c3541efa37acf3a03822289a8ab8705cbbc4e Mon Sep 17 00:00:00 2001
From: Christian Hergert <chergert@redhat.com>
Date: Sun, 23 Feb 2020 17:27:08 -0800
Subject: [PATCH 1/3] clutter: avoid redundant _clutter_paint_node_init_types()
This only needs to be initialized once but is in the hot path of creating
new paint nodes (for which we create many). Instead, do this as part of
the clutter_init() workflow to keep it out of the hot path.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1087
---
clutter/clutter/clutter-main.c | 4 ++++
clutter/clutter/clutter-paint-node.c | 2 --
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c
index 71ec0d80c..645c8bceb 100644
--- a/clutter/clutter/clutter-main.c
+++ b/clutter/clutter/clutter-main.c
@@ -61,6 +61,7 @@
#include "clutter-main.h"
#include "clutter-master-clock.h"
#include "clutter-mutter.h"
+#include "clutter-paint-node-private.h"
#include "clutter-private.h"
#include "clutter-settings-private.h"
#include "clutter-stage-manager.h"
@@ -1366,6 +1367,9 @@ clutter_init_real (GError **error)
if (clutter_enable_accessibility)
cally_accessibility_init ();
+ /* Initialize types required for paint nodes */
+ _clutter_paint_node_init_types ();
+
return CLUTTER_INIT_SUCCESS;
}
diff --git a/clutter/clutter/clutter-paint-node.c b/clutter/clutter/clutter-paint-node.c
index e731ca60a..73765a4e9 100644
--- a/clutter/clutter/clutter-paint-node.c
+++ b/clutter/clutter/clutter-paint-node.c
@@ -1177,8 +1177,6 @@ _clutter_paint_node_create (GType gtype)
{
g_return_val_if_fail (g_type_is_a (gtype, CLUTTER_TYPE_PAINT_NODE), NULL);
- _clutter_paint_node_init_types ();
-
return (gpointer) g_type_create_instance (gtype);
}
--
2.26.0

@ -1,46 +0,0 @@
From 7bcc274dbc6cb75814cce3e5c2e7f45cf25b0538 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Tue, 9 Feb 2021 17:59:08 +0100
Subject: [PATCH 1/2] clutter/stage-view: Hide double buffered shadowfb behind
envvar
It still results in worse performance than a single FBO based shadowfb,
so don't use it. It will need a new EGL extension for zero copy CPU
memory based FBO to be feasable.
---
clutter/clutter/clutter-stage-view.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c
index 5e5966d06..ec18db7b8 100644
--- a/clutter/clutter/clutter-stage-view.c
+++ b/clutter/clutter/clutter-stage-view.c
@@ -282,6 +282,14 @@ init_dma_buf_shadowfbs (ClutterStageView *view,
CoglRenderer *cogl_renderer = cogl_context_get_renderer (cogl_context);
CoglFramebuffer *initial_shadowfb;
+ if (g_strcmp0 (g_getenv ("MUTTER_DEBUG_ENABLE_DOUBLE_BUFFER_SHADOWFB"),
+ "1") != 0)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Double buffered shadowfb not enabled");
+ return FALSE;
+ }
+
if (!cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
@@ -390,8 +398,8 @@ init_shadowfb (ClutterStageView *view)
return;
}
- g_warning ("Failed to initialize double buffered shadow fb for %s: %s",
- priv->name, error->message);
+ g_debug ("Failed to initialize double buffered shadow fb for %s: %s",
+ priv->name, error->message);
g_clear_error (&error);
if (!init_fallback_shadowfb (view, cogl_context, width, height, &error))
--
2.29.2

@ -0,0 +1,52 @@
From 5cd66485cdd99068dab0f57d7f64d3ef294b0037 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Wed, 4 Aug 2021 19:30:10 +0200
Subject: [PATCH] clutter/text: Don't query preferred size without allocation
The size request functions query the resource scale, which hits
an assert if headless. The returned sizes are already only used
when clutter_actor_has_allocation() is true, so this doesn't
change the condition for calling either redraw or relayout.
https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4522
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1956>
---
clutter/clutter/clutter-text.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/clutter/clutter/clutter-text.c b/clutter/clutter/clutter-text.c
index 45c7eac56b..80e53ea32f 100644
--- a/clutter/clutter/clutter-text.c
+++ b/clutter/clutter/clutter-text.c
@@ -4797,16 +4797,21 @@ static void
clutter_text_queue_redraw_or_relayout (ClutterText *self)
{
ClutterActor *actor = CLUTTER_ACTOR (self);
- gfloat preferred_width;
- gfloat preferred_height;
+ float preferred_width = -1.;
+ float preferred_height = -1.;
clutter_text_dirty_cache (self);
- /* we're using our private implementations here to avoid the caching done by ClutterActor */
- clutter_text_get_preferred_width (actor, -1, NULL, &preferred_width);
- clutter_text_get_preferred_height (actor, preferred_width, NULL, &preferred_height);
+ if (clutter_actor_has_allocation (actor))
+ {
+ /* we're using our private implementations here to avoid the caching done by ClutterActor */
+ clutter_text_get_preferred_width (actor, -1, NULL, &preferred_width);
+ clutter_text_get_preferred_height (actor, preferred_width, NULL,
+ &preferred_height);
+ }
- if (clutter_actor_has_allocation (actor) &&
+ if (preferred_width > 0 &&
+ preferred_height > 0 &&
fabsf (preferred_width - clutter_actor_get_width (actor)) <= 0.001 &&
fabsf (preferred_height - clutter_actor_get_height (actor)) <= 0.001)
clutter_text_queue_redraw (actor);
--
2.31.1

@ -1,37 +0,0 @@
From 251ef4ff4bacefac211e21873e10da7fa067dd68 Mon Sep 17 00:00:00 2001
From: Pekka Paalanen <pekka.paalanen@collabora.com>
Date: Fri, 26 Apr 2019 12:23:18 +0300
Subject: [PATCH 01/12] cogl: Remove unused OFFSCREEN_BLIT feature flag
This named constant is never used anywhere.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/615
(cherry picked from commit c08a24bb40ad7aa7746e86251c9dbe6c264b4d7c)
---
cogl/cogl/cogl-types.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/cogl/cogl/cogl-types.h b/cogl/cogl/cogl-types.h
index 690daa16a..69d304cf0 100644
--- a/cogl/cogl/cogl-types.h
+++ b/cogl/cogl/cogl-types.h
@@ -325,7 +325,6 @@ typedef enum /*< prefix=COGL_PIXEL_FORMAT >*/
* @COGL_FEATURE_SHADERS_GLSL: GLSL support
* @COGL_FEATURE_OFFSCREEN: FBO support
* @COGL_FEATURE_OFFSCREEN_MULTISAMPLE: Multisample support on FBOs
- * @COGL_FEATURE_OFFSCREEN_BLIT: Blit support on FBOs
* @COGL_FEATURE_FOUR_CLIP_PLANES: At least 4 clip planes available
* @COGL_FEATURE_STENCIL_BUFFER: Stencil buffer support
* @COGL_FEATURE_VBOS: VBO support
@@ -368,7 +367,6 @@ typedef enum
COGL_FEATURE_SHADERS_GLSL = (1 << 5),
COGL_FEATURE_OFFSCREEN = (1 << 6),
COGL_FEATURE_OFFSCREEN_MULTISAMPLE = (1 << 7),
- COGL_FEATURE_OFFSCREEN_BLIT = (1 << 8),
COGL_FEATURE_FOUR_CLIP_PLANES = (1 << 9),
COGL_FEATURE_STENCIL_BUFFER = (1 << 10),
COGL_FEATURE_VBOS = (1 << 11),
--
2.21.0

@ -1,265 +0,0 @@
From b0f3604cdb653ef133f9684adffeb6b93f6906f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Wed, 26 Jan 2022 10:51:07 +0100
Subject: [PATCH] compositor: Make sure _NET_WM_FRAME_DRAWN timestamp has the
right scope
The timestamp sent with _NET_WM_FRAME_DRAWN should be in "high
resolution X server timestamps", meaning they should have the same scope
as the built in X11 32 bit unsigned integer timestamps, i.e. overflow at
the same time.
This was not done correctly when mutter had determined the X server used
the monotonic clock, where it'd just forward the monotonic clock,
confusing any client using _NET_WM_FRAME_DRAWN and friends.
Fix this by 1) splitting the timestamp conversiot into an X11 case and a
display server case, where the display server case simply clamps the
monotonic clock, as it is assumed Xwayland is always usign the monotonic
clock, and 2) if we're a X11 compositing manager, if the X server is
using the monotonic clock, apply the same semantics as the display
server case and always just clamp, or if not, calculate the offset every
10 seconds, and offset the monotonic clock timestamp with the calculated
X server timestamp offset.
This fixes an issue that would occur if mutter (or rather GNOME Shell)
would have been started before a X11 timestamp overflow, after the
overflow happened. In this case, GTK3 clients would get unclamped
timestamps, and get very confused, resulting in frames queued several
weeks into the future.
---
src/compositor/compositor-private.h | 9 +-
src/compositor/compositor.c | 117 +++++++++++++++++++------
src/compositor/meta-window-actor-x11.c | 12 +--
3 files changed, 104 insertions(+), 34 deletions(-)
diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h
index f7008751215d..4588a8af7f2f 100644
--- a/src/compositor/compositor-private.h
+++ b/src/compositor/compositor-private.h
@@ -49,6 +49,10 @@ struct _MetaCompositor
gboolean frame_has_updated_xsurfaces;
gboolean have_x11_sync_object;
+
+ gboolean xserver_uses_monotonic_clock;
+ int64_t xserver_time_query_time_us;
+ int64_t xserver_time_offset_us;
};
/* Wait 2ms after vblank before starting to draw next frame */
@@ -64,8 +68,9 @@ void meta_end_modal_for_plugin (MetaCompositor *compositor,
MetaPlugin *plugin,
guint32 timestamp);
-gint64 meta_compositor_monotonic_time_to_server_time (MetaDisplay *display,
- gint64 monotonic_time);
+int64_t
+meta_compositor_monotonic_to_high_res_xserver_time (MetaDisplay *display,
+ int64_t monotonic_time_us);
gboolean meta_compositor_window_is_stereo (MetaDisplay *display,
Window xwindow);
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index ce2c1b8a3bc1..a3fbe5d888f9 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -88,6 +88,40 @@
#include "wayland/meta-wayland-private.h"
#endif
+static inline int64_t
+us (int64_t us)
+{
+ return us;
+}
+
+static inline int64_t
+ms2us (int64_t ms)
+{
+ return us (ms * 1000);
+}
+
+static inline int64_t
+s2us (int64_t s)
+{
+ return ms2us(s * 1000);
+}
+
+/*
+ * This function takes a 64 bit time stamp from the monotonic clock, and clamps
+ * it to the scope of the X server clock, without losing the granularity.
+ */
+static inline int64_t
+meta_translate_to_high_res_xserver_time (int64_t time_us)
+{
+ int64_t us;
+ int64_t ms;
+
+ us = time_us % 1000;
+ ms = time_us / 1000;
+
+ return ms2us (ms & 0xffffffff) + us;
+}
+
static void
on_presented (ClutterStage *stage,
CoglFrameEvent event,
@@ -612,6 +646,37 @@ meta_compositor_select_stereo_notify (MetaDisplay *display,
}
}
+static void
+determine_server_clock_source (MetaCompositor *compositor)
+{
+ MetaDisplay *display = compositor->display;
+ MetaX11Display *x11_display = display->x11_display;
+ uint32_t server_time_ms;
+ int64_t server_time_us;
+ int64_t translated_monotonic_now_us;
+
+ if (meta_is_wayland_compositor ())
+ {
+ compositor->xserver_uses_monotonic_clock = TRUE;
+ return;
+ }
+
+ server_time_ms = meta_x11_display_get_current_time_roundtrip (x11_display);
+ server_time_us = ms2us (server_time_ms);
+ translated_monotonic_now_us =
+ meta_translate_to_high_res_xserver_time (g_get_monotonic_time ());
+
+ /* If the server time offset is within a second of the monotonic time, we
+ * assume that they are identical. This seems like a big margin, but we want
+ * to be as robust as possible even if the system is under load and our
+ * processing of the server response is delayed.
+ */
+ if (ABS (server_time_us - translated_monotonic_now_us) < s2us (1))
+ compositor->xserver_uses_monotonic_clock = TRUE;
+ else
+ compositor->xserver_uses_monotonic_clock = FALSE;
+}
+
void
meta_compositor_manage (MetaCompositor *compositor)
{
@@ -622,6 +687,9 @@ meta_compositor_manage (MetaCompositor *compositor)
if (display->x11_display)
{
xdisplay = display->x11_display->xdisplay;
+
+ determine_server_clock_source (compositor);
+
meta_x11_display_set_cm_selection (display->x11_display);
compositor->stereo_tree_ext = display_has_stereo_tree_ext (display->x11_display);
@@ -1593,7 +1661,7 @@ meta_compositor_flash_window (MetaCompositor *compositor,
}
/**
- * meta_compositor_monotonic_time_to_server_time:
+ * meta_compositor_monotonic_to_high_res_xserver_time:
* @display: a #MetaDisplay
* @monotonic_time: time in the units of g_get_monotonic_time()
*
@@ -1606,38 +1674,35 @@ meta_compositor_flash_window (MetaCompositor *compositor,
* a time representation with high accuracy. If there is not a common
* time source, then the time synchronization will be less accurate.
*/
-gint64
-meta_compositor_monotonic_time_to_server_time (MetaDisplay *display,
- gint64 monotonic_time)
+int64_t
+meta_compositor_monotonic_to_high_res_xserver_time (MetaDisplay *display,
+ int64_t monotonic_time_us)
{
MetaCompositor *compositor = display->compositor;
+ int64_t now_us;
+
+ if (compositor->xserver_uses_monotonic_clock)
+ return meta_translate_to_high_res_xserver_time (monotonic_time_us);
- if (compositor->server_time_query_time == 0 ||
- (!compositor->server_time_is_monotonic_time &&
- monotonic_time > compositor->server_time_query_time + 10*1000*1000)) /* 10 seconds */
+ now_us = g_get_monotonic_time ();
+
+ if (compositor->xserver_time_query_time_us == 0 ||
+ now_us > (compositor->xserver_time_query_time_us + s2us (10)))
{
- guint32 server_time = meta_display_get_current_time_roundtrip (display);
- gint64 server_time_usec = (gint64)server_time * 1000;
- gint64 current_monotonic_time = g_get_monotonic_time ();
- compositor->server_time_query_time = current_monotonic_time;
-
- /* If the server time is within a second of the monotonic time,
- * we assume that they are identical. This seems like a big margin,
- * but we want to be as robust as possible even if the system
- * is under load and our processing of the server response is
- * delayed.
- */
- if (server_time_usec > current_monotonic_time - 1000*1000 &&
- server_time_usec < current_monotonic_time + 1000*1000)
- compositor->server_time_is_monotonic_time = TRUE;
+ MetaDisplay *display = compositor->display;
+ MetaX11Display *x11_display = display->x11_display;
+ uint32_t xserver_time_ms;
+ int64_t xserver_time_us;
- compositor->server_time_offset = server_time_usec - current_monotonic_time;
+ compositor->xserver_time_query_time_us = now_us;
+
+ xserver_time_ms =
+ meta_x11_display_get_current_time_roundtrip (x11_display);
+ xserver_time_us = ms2us (xserver_time_ms);
+ compositor->xserver_time_offset_us = xserver_time_us - now_us;
}
- if (compositor->server_time_is_monotonic_time)
- return monotonic_time;
- else
- return monotonic_time + compositor->server_time_offset;
+ return monotonic_time_us + compositor->xserver_time_offset_us;
}
void
diff --git a/src/compositor/meta-window-actor-x11.c b/src/compositor/meta-window-actor-x11.c
index a364323fe057..2b9c25510dc9 100644
--- a/src/compositor/meta-window-actor-x11.c
+++ b/src/compositor/meta-window-actor-x11.c
@@ -105,8 +105,8 @@ do_send_frame_drawn (MetaWindowActorX11 *actor_x11,
XClientMessageEvent ev = { 0, };
frame->frame_drawn_time =
- meta_compositor_monotonic_time_to_server_time (display,
- g_get_monotonic_time ());
+ meta_compositor_monotonic_to_high_res_xserver_time (display,
+ g_get_monotonic_time ());
actor_x11->frame_drawn_time = frame->frame_drawn_time;
ev.type = ClientMessage;
@@ -147,8 +147,8 @@ do_send_frame_timings (MetaWindowActorX11 *actor_x11,
if (presentation_time != 0)
{
int64_t presentation_time_server =
- meta_compositor_monotonic_time_to_server_time (display,
- presentation_time);
+ meta_compositor_monotonic_to_high_res_xserver_time (display,
+ presentation_time);
int64_t presentation_time_offset = presentation_time_server - frame->frame_drawn_time;
if (presentation_time_offset == 0)
presentation_time_offset = 1;
@@ -246,8 +246,8 @@ queue_send_frame_messages_timeout (MetaWindowActorX11 *actor_x11)
}
current_time =
- meta_compositor_monotonic_time_to_server_time (display,
- g_get_monotonic_time ());
+ meta_compositor_monotonic_to_high_res_xserver_time (display,
+ g_get_monotonic_time ());
interval = (int) (1000000 / refresh_rate) * 6;
offset = MAX (0, actor_x11->frame_drawn_time + interval - current_time) / 1000;
--
2.33.1

@ -1,4 +1,4 @@
From 575490895047e0709bc84826fe6d6a73028d7bbc Mon Sep 17 00:00:00 2001 From 1ab51efc968d7d3c6244d9b7efcdf4bae4fc0a9d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org> From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Wed, 12 Mar 2014 02:04:13 +0100 Date: Wed, 12 Mar 2014 02:04:13 +0100
Subject: [PATCH] constraints: Enforce X11 size limits Subject: [PATCH] constraints: Enforce X11 size limits
@ -10,7 +10,7 @@ to keep insanely huge windows from crashing the WM.
1 file changed, 42 insertions(+) 1 file changed, 42 insertions(+)
diff --git a/src/core/constraints.c b/src/core/constraints.c diff --git a/src/core/constraints.c b/src/core/constraints.c
index 117131b15..379372245 100644 index 4b1d95338a..eee16dc48f 100644
--- a/src/core/constraints.c --- a/src/core/constraints.c
+++ b/src/core/constraints.c +++ b/src/core/constraints.c
@@ -109,6 +109,7 @@ typedef enum @@ -109,6 +109,7 @@ typedef enum
@ -21,7 +21,7 @@ index 117131b15..379372245 100644
PRIORITY_MAXIMUM = 4 /* Dummy value used for loop end = max(all priorities) */ PRIORITY_MAXIMUM = 4 /* Dummy value used for loop end = max(all priorities) */
} ConstraintPriority; } ConstraintPriority;
@@ -201,6 +202,10 @@ static gboolean constrain_partially_onscreen (MetaWindow *window, @@ -204,6 +205,10 @@ static gboolean constrain_partially_onscreen (MetaWindow *window,
ConstraintInfo *info, ConstraintInfo *info,
ConstraintPriority priority, ConstraintPriority priority,
gboolean check_only); gboolean check_only);
@ -32,7 +32,7 @@ index 117131b15..379372245 100644
static void setup_constraint_info (ConstraintInfo *info, static void setup_constraint_info (ConstraintInfo *info,
MetaWindow *window, MetaWindow *window,
@@ -236,6 +241,7 @@ static const Constraint all_constraints[] = { @@ -239,6 +244,7 @@ static const Constraint all_constraints[] = {
{constrain_fully_onscreen, "constrain_fully_onscreen"}, {constrain_fully_onscreen, "constrain_fully_onscreen"},
{constrain_titlebar_visible, "constrain_titlebar_visible"}, {constrain_titlebar_visible, "constrain_titlebar_visible"},
{constrain_partially_onscreen, "constrain_partially_onscreen"}, {constrain_partially_onscreen, "constrain_partially_onscreen"},
@ -40,7 +40,7 @@ index 117131b15..379372245 100644
{NULL, NULL} {NULL, NULL}
}; };
@@ -1780,3 +1786,39 @@ constrain_partially_onscreen (MetaWindow *window, @@ -1876,3 +1882,39 @@ constrain_partially_onscreen (MetaWindow *window,
return retval; return retval;
} }
@ -81,5 +81,5 @@ index 117131b15..379372245 100644
+ return TRUE; + return TRUE;
+} +}
-- --
2.21.0 2.31.1

@ -1,4 +1,4 @@
From bfd49687aa862a7e69d0d7fe76f803ae180d40c2 Mon Sep 17 00:00:00 2001 From 88b50f5a9e4b1b87e766e929a77aafdc27e335cf Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org> From: Carlos Garnacho <carlosg@gnome.org>
Date: Wed, 7 Jun 2023 11:04:15 +0200 Date: Wed, 7 Jun 2023 11:04:15 +0200
Subject: [PATCH] core: Change MetaWaylandTextInput event forwarding to IMs Subject: [PATCH] core: Change MetaWaylandTextInput event forwarding to IMs
@ -27,14 +27,14 @@ Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5890
src/wayland/meta-wayland-seat.c | 30 ++++++++++++++++++++++------- src/wayland/meta-wayland-seat.c | 30 ++++++++++++++++++++++-------
src/wayland/meta-wayland-seat.h | 3 +++ src/wayland/meta-wayland-seat.h | 3 +++
src/wayland/meta-wayland.c | 7 +++++++ src/wayland/meta-wayland.c | 7 +++++++
src/wayland/meta-wayland.h | 4 ++++ src/wayland/meta-wayland.h | 3 +++
6 files changed, 45 insertions(+), 15 deletions(-) 6 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/core/events.c b/src/core/events.c diff --git a/src/core/events.c b/src/core/events.c
index 5b8e49fc79..19d701779b 100644 index 6bb4e90..7751042 100644
--- a/src/core/events.c --- a/src/core/events.c
+++ b/src/core/events.c +++ b/src/core/events.c
@@ -207,6 +207,14 @@ meta_display_handle_event (MetaDisplay *display, @@ -234,6 +234,14 @@ meta_display_handle_event (MetaDisplay *display,
if (meta_is_wayland_compositor ()) if (meta_is_wayland_compositor ())
{ {
compositor = meta_wayland_compositor_get_default (); compositor = meta_wayland_compositor_get_default ();
@ -50,10 +50,10 @@ index 5b8e49fc79..19d701779b 100644
} }
#endif #endif
diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c
index 8b23d76ce7..84f46bcf8e 100644 index 836939c..460d9e9 100644
--- a/src/wayland/meta-wayland-keyboard.c --- a/src/wayland/meta-wayland-keyboard.c
+++ b/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c
@@ -753,14 +753,6 @@ meta_wayland_keyboard_update (MetaWaylandKeyboard *keyboard, @@ -564,14 +564,6 @@ meta_wayland_keyboard_update (MetaWaylandKeyboard *keyboard,
{ {
gboolean is_press = event->type == CLUTTER_KEY_PRESS; gboolean is_press = event->type == CLUTTER_KEY_PRESS;
@ -69,10 +69,10 @@ index 8b23d76ce7..84f46bcf8e 100644
* changes from a previous event that didn't get cleared, we need to * changes from a previous event that didn't get cleared, we need to
* send that state right away so that the new key event can be * send that state right away so that the new key event can be
diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c
index 91fe376ffe..dcf420201f 100644 index 25d5074..27d8fe3 100644
--- a/src/wayland/meta-wayland-seat.c --- a/src/wayland/meta-wayland-seat.c
+++ b/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c
@@ -362,6 +362,29 @@ meta_wayland_seat_update (MetaWaylandSeat *seat, @@ -376,6 +376,29 @@ meta_wayland_seat_update (MetaWaylandSeat *seat,
} }
} }
@ -102,7 +102,7 @@ index 91fe376ffe..dcf420201f 100644
gboolean gboolean
meta_wayland_seat_handle_event (MetaWaylandSeat *seat, meta_wayland_seat_handle_event (MetaWaylandSeat *seat,
const ClutterEvent *event) const ClutterEvent *event)
@@ -384,13 +407,6 @@ meta_wayland_seat_handle_event (MetaWaylandSeat *seat, @@ -398,13 +421,6 @@ meta_wayland_seat_handle_event (MetaWaylandSeat *seat,
break; break;
case CLUTTER_KEY_PRESS: case CLUTTER_KEY_PRESS:
case CLUTTER_KEY_RELEASE: case CLUTTER_KEY_RELEASE:
@ -117,10 +117,10 @@ index 91fe376ffe..dcf420201f 100644
return meta_wayland_keyboard_handle_event (seat->keyboard, return meta_wayland_keyboard_handle_event (seat->keyboard,
(const ClutterKeyEvent *) event); (const ClutterKeyEvent *) event);
diff --git a/src/wayland/meta-wayland-seat.h b/src/wayland/meta-wayland-seat.h diff --git a/src/wayland/meta-wayland-seat.h b/src/wayland/meta-wayland-seat.h
index 3a744d0580..da20e69d8d 100644 index ae4e107..ab90106 100644
--- a/src/wayland/meta-wayland-seat.h --- a/src/wayland/meta-wayland-seat.h
+++ b/src/wayland/meta-wayland-seat.h +++ b/src/wayland/meta-wayland-seat.h
@@ -82,4 +82,7 @@ gboolean meta_wayland_seat_has_pointer (MetaWaylandSeat *seat); @@ -84,4 +84,7 @@ gboolean meta_wayland_seat_has_pointer (MetaWaylandSeat *seat);
gboolean meta_wayland_seat_has_touch (MetaWaylandSeat *seat); gboolean meta_wayland_seat_has_touch (MetaWaylandSeat *seat);
@ -129,10 +129,10 @@ index 3a744d0580..da20e69d8d 100644
+ +
#endif /* META_WAYLAND_SEAT_H */ #endif /* META_WAYLAND_SEAT_H */
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index a593f0a7b7..24a68f1e06 100644 index a3f0984..b548aa1 100644
--- a/src/wayland/meta-wayland.c --- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c
@@ -565,3 +565,10 @@ meta_wayland_compositor_notify_surface_id (MetaWaylandCompositor *compositor, @@ -721,3 +721,10 @@ meta_wayland_compositor_notify_surface_id (MetaWaylandCompositor *compositor,
meta_wayland_compositor_remove_surface_association (compositor, id); meta_wayland_compositor_remove_surface_association (compositor, id);
} }
} }
@ -144,20 +144,19 @@ index a593f0a7b7..24a68f1e06 100644
+ return meta_wayland_seat_handle_text_input_event (compositor->seat, event); + return meta_wayland_seat_handle_text_input_event (compositor->seat, event);
+} +}
diff --git a/src/wayland/meta-wayland.h b/src/wayland/meta-wayland.h diff --git a/src/wayland/meta-wayland.h b/src/wayland/meta-wayland.h
index 2a0aa11400..b5281d2014 100644 index 6c655e4..ad82d52 100644
--- a/src/wayland/meta-wayland.h --- a/src/wayland/meta-wayland.h
+++ b/src/wayland/meta-wayland.h +++ b/src/wayland/meta-wayland.h
@@ -87,6 +87,10 @@ META_EXPORT_TEST @@ -92,6 +92,9 @@ void meta_wayland_compositor_schedule_surface_association (Me
void meta_wayland_compositor_schedule_surface_association (MetaWaylandCompositor *compositor,
int id, int id,
MetaWindow *window); MetaWindow *window);
+
+gboolean meta_wayland_compositor_handle_text_input_event (MetaWaylandCompositor *compositor, +gboolean meta_wayland_compositor_handle_text_input_event (MetaWaylandCompositor *compositor,
+ const ClutterEvent *event); + const ClutterEvent *event);
+ +
META_EXPORT_TEST
void meta_wayland_compositor_notify_surface_id (MetaWaylandCompositor *compositor, void meta_wayland_compositor_notify_surface_id (MetaWaylandCompositor *compositor,
int id, int id,
MetaWaylandSurface *surface);
-- --
2.40.1 2.40.1

@ -1,64 +0,0 @@
From 5cab6bac4d4fb06e60d3198dc654a5d70fa6240e Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Mon, 16 Dec 2019 13:53:26 +0100
Subject: [PATCH] core: Let pad mode switch events always go through
MetaInputSettings
We used to inhibit all pad actions while the OSD is shown, but one we
would actually want to handle are mode switches while the OSD is open.
So it has an opportunity to catch up to the mode switch.
This lets MetaInputSettings reflect the mode switch (eg. when querying
action labels), so the OSD has an opportunity to update the current
actions.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/975
---
src/core/events.c | 30 ++++++++++++++++++++++++------
1 file changed, 24 insertions(+), 6 deletions(-)
diff --git a/src/core/events.c b/src/core/events.c
index d383778629..44f28d0b97 100644
--- a/src/core/events.c
+++ b/src/core/events.c
@@ -256,13 +256,31 @@ meta_display_handle_event (MetaDisplay *display,
}
#endif
- if (!display->current_pad_osd &&
- (event->type == CLUTTER_PAD_BUTTON_PRESS ||
- event->type == CLUTTER_PAD_BUTTON_RELEASE ||
- event->type == CLUTTER_PAD_RING ||
- event->type == CLUTTER_PAD_STRIP))
+ if (event->type == CLUTTER_PAD_BUTTON_PRESS ||
+ event->type == CLUTTER_PAD_BUTTON_RELEASE ||
+ event->type == CLUTTER_PAD_RING ||
+ event->type == CLUTTER_PAD_STRIP)
{
- if (meta_input_settings_handle_pad_event (meta_backend_get_input_settings (backend),
+ gboolean handle_pad_event = TRUE;
+ gboolean is_mode_switch = FALSE;
+
+ if (event->type == CLUTTER_PAD_BUTTON_PRESS ||
+ event->type == CLUTTER_PAD_BUTTON_RELEASE)
+ {
+ ClutterInputDevice *pad;
+ uint32_t button;
+
+ pad = clutter_event_get_source_device (event);
+ button = clutter_event_get_button (event);
+
+ is_mode_switch =
+ clutter_input_device_get_mode_switch_button_group (pad, button) >= 0;
+ }
+
+ handle_pad_event = !display->current_pad_osd || is_mode_switch;
+
+ if (handle_pad_event &&
+ meta_input_settings_handle_pad_event (meta_backend_get_input_settings (backend),
event))
{
bypass_wayland = bypass_clutter = TRUE;
--
2.24.0

@ -1,73 +0,0 @@
From bac090f571e6f413ba2a362ed2d70146b7701d16 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Mon, 24 Feb 2020 17:37:34 +0100
Subject: [PATCH] crtc-xrandr: Respect configured RANDR panning
A user may have configured an output to be panning, e.g. using xrandr
--output <output> --mode <mode> --panning <size>. Respect this by making
the logical monitor use the panning size, instead of the mode. This
makes e.g. makes the background cover the whole panning size, and panels
etc will cover the whole top of the panned area, instead of just the top
left part covering the monitor if having panned to (0, 0).
No support is added to configuring panning, i.e. a panned monitor
configuration cannot be stored in monitors.xml.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1085
---
src/backends/x11/meta-crtc-xrandr.c | 31 +++++++++++++++++++++++++----
1 file changed, 27 insertions(+), 4 deletions(-)
diff --git a/src/backends/x11/meta-crtc-xrandr.c b/src/backends/x11/meta-crtc-xrandr.c
index d201b8581..dc3f931e3 100644
--- a/src/backends/x11/meta-crtc-xrandr.c
+++ b/src/backends/x11/meta-crtc-xrandr.c
@@ -177,7 +177,14 @@ meta_create_xrandr_crtc (MetaGpuXrandr *gpu_xrandr,
RRCrtc crtc_id,
XRRScreenResources *resources)
{
+ MetaGpu *gpu = META_GPU (gpu_xrandr);
+ MetaMonitorManager *monitor_manager = meta_gpu_get_monitor_manager (gpu);
+ MetaMonitorManagerXrandr *monitor_manager_xrandr =
+ META_MONITOR_MANAGER_XRANDR (monitor_manager);
+ Display *xdisplay =
+ meta_monitor_manager_xrandr_get_xdisplay (monitor_manager_xrandr);
MetaCrtc *crtc;
+ XRRPanning *panning;
unsigned int i;
GList *modes;
@@ -185,10 +192,26 @@ meta_create_xrandr_crtc (MetaGpuXrandr *gpu_xrandr,
crtc->gpu = META_GPU (gpu_xrandr);
crtc->crtc_id = crtc_id;
- crtc->rect.x = xrandr_crtc->x;
- crtc->rect.y = xrandr_crtc->y;
- crtc->rect.width = xrandr_crtc->width;
- crtc->rect.height = xrandr_crtc->height;
+
+ panning = XRRGetPanning (xdisplay, resources, crtc_id);
+ if (panning && panning->width > 0 && panning->height > 0)
+ {
+ crtc->rect = (MetaRectangle) {
+ .x = panning->left,
+ .y = panning->top,
+ .width = panning->width,
+ .height = panning->height,
+ };
+ }
+ else
+ {
+ crtc->rect = (MetaRectangle) {
+ .x = xrandr_crtc->x,
+ .y = xrandr_crtc->y,
+ .width = xrandr_crtc->width,
+ .height = xrandr_crtc->height,
+ };
+ }
crtc->is_dirty = FALSE;
crtc->transform =
meta_monitor_transform_from_xrandr (xrandr_crtc->rotation);
--
2.24.1

@ -0,0 +1,69 @@
From 4618af58cc9046142f348d16ab1150bfde8f49c4 Mon Sep 17 00:00:00 2001
From: Daniel van Vugt <daniel.van.vugt@canonical.com>
Date: Wed, 20 Jul 2022 10:10:21 +0000
Subject: [PATCH] cursor-renderer-native: Don't retry forever after GBM cursor
functions fail
This avoids flooding the log with every cursor change:
```
(gnome-shell:19923): libmutter-WARNING **: 10:15:23.404: Realizing HW cursor failed: Failed to allocate gbm_bo: Invalid argument
(gnome-shell:19923): libmutter-WARNING **: 10:15:23.450: Realizing HW cursor failed: Failed to allocate gbm_bo: Invalid argument
(gnome-shell:19923): libmutter-WARNING **: 10:15:23.451: Realizing HW cursor failed: Failed to allocate gbm_bo: Invalid argument
```
Related: https://gitlab.gnome.org/GNOME/mutter/-/issues/2354
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2520>
---
.../native/meta-cursor-renderer-native.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/src/backends/native/meta-cursor-renderer-native.c b/src/backends/native/meta-cursor-renderer-native.c
index 3c63a15d68..08c9819a12 100644
--- a/src/backends/native/meta-cursor-renderer-native.c
+++ b/src/backends/native/meta-cursor-renderer-native.c
@@ -506,12 +506,9 @@ unset_crtc_cursor (MetaCursorRendererNative *native,
}
static void
-disable_hw_cursor_for_crtc (MetaKmsCrtc *kms_crtc,
- const GError *error)
+disable_hw_cursor_for_gpu (MetaGpuKms *gpu_kms,
+ const GError *error)
{
- MetaCrtcKms *crtc_kms = meta_crtc_kms_from_kms_crtc (kms_crtc);
- MetaCrtc *crtc = META_CRTC (crtc_kms);
- MetaGpuKms *gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data =
meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms);
@@ -521,6 +518,17 @@ disable_hw_cursor_for_crtc (MetaKmsCrtc *kms_crtc,
cursor_renderer_gpu_data->hw_cursor_broken = TRUE;
}
+static void
+disable_hw_cursor_for_crtc (MetaKmsCrtc *kms_crtc,
+ const GError *error)
+{
+ MetaCrtcKms *crtc_kms = meta_crtc_kms_from_kms_crtc (kms_crtc);
+ MetaCrtc *crtc = META_CRTC (crtc_kms);
+ MetaGpuKms *gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
+
+ disable_hw_cursor_for_gpu (gpu_kms, error);
+}
+
void
meta_cursor_renderer_native_prepare_frame (MetaCursorRendererNative *cursor_renderer_native,
MetaRendererView *view)
@@ -1375,6 +1383,7 @@ load_cursor_sprite_gbm_buffer_for_gpu (MetaCursorRendererNative *native,
if (!buffer)
{
g_warning ("Realizing HW cursor failed: %s", error->message);
+ disable_hw_cursor_for_gpu (gpu_kms, error);
return;
}
--
2.44.0.501.g19981daefd.dirty

@ -0,0 +1,26 @@
From 088644fb1773b64ca45dec497589517e1774eac1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Tue, 27 Aug 2024 11:33:14 +0200
Subject: [PATCH 1/5] display: Make cgroup constructor local
This silences a warning about a missing function declaration.
---
src/core/display.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/core/display.c b/src/core/display.c
index 4c9038e627..97f591a876 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -1619,7 +1619,7 @@ extract_app_id_from_cgroup (const char *cgroup)
return g_steal_pointer (&app_id);
}
-MetaCGroup*
+static MetaCGroup*
meta_cgroup_new (const char *path)
{
MetaCGroup *cgroup;
--
2.44.0.501.g19981daefd.dirty

@ -1,248 +0,0 @@
From 7f6f326a1bb96aad0b7aea9c4d7e257bf53c026c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Fri, 21 Feb 2020 21:03:16 +0100
Subject: [PATCH] display: Make check-alive timeout configureable
The check-alive feature is there for the user to be able to terminate
frozen applications more easily. However, sometimes applications are
implemented in a way where they fail to be reply to ping requests in a
timely manner, resulting in that, to the compositor, they are
indistinguishable from clients that have frozen indefinitely.
When using an application that has these issues, the GUI showed in
response to the failure to respond to ping requests can become annoying,
as it disrupts the visual presentation of the application.
To allow users to work-around these issues, add a setting allowing them
to configure the timeout waited until an application is considered
frozen, or disabling the check completely.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1080
---
data/org.gnome.mutter.gschema.xml.in | 10 ++++
src/core/display.c | 18 ++++----
src/core/prefs.c | 68 ++++++++++++++++++++++++++++
src/meta/prefs.h | 3 ++
4 files changed, 90 insertions(+), 9 deletions(-)
diff --git a/data/org.gnome.mutter.gschema.xml.in b/data/org.gnome.mutter.gschema.xml.in
index 6cbd9c1b5..4d37b1488 100644
--- a/data/org.gnome.mutter.gschema.xml.in
+++ b/data/org.gnome.mutter.gschema.xml.in
@@ -123,6 +123,16 @@
</description>
</key>
+ <key name="check-alive-timeout" type="u">
+ <default>5000</default>
+ <summary>Timeout for check-alive ping</summary>
+ <description>
+ Number of milliseconds a client has to respond to a ping request in
+ order to not be detected as frozen. Using 0 will disable the alive check
+ completely.
+ </description>
+ </key>
+
<child name="keybindings" schema="org.gnome.mutter.keybindings"/>
</schema>
diff --git a/src/core/display.c b/src/core/display.c
index eb7dc43b6..c30a03385 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -1923,12 +1923,6 @@ meta_set_syncing (gboolean setting)
}
}
-/*
- * How long, in milliseconds, we should wait after pinging a window
- * before deciding it's not going to get back to us.
- */
-#define PING_TIMEOUT_DELAY 5000
-
/**
* meta_display_ping_timeout:
* @data: All the information about this ping. It is a #MetaPingData
@@ -1986,6 +1980,11 @@ meta_display_ping_window (MetaWindow *window,
{
MetaDisplay *display = window->display;
MetaPingData *ping_data;
+ unsigned int check_alive_timeout;
+
+ check_alive_timeout = meta_prefs_get_check_alive_timeout ();
+ if (check_alive_timeout == 0)
+ return;
if (serial == 0)
{
@@ -1999,9 +1998,10 @@ meta_display_ping_window (MetaWindow *window,
ping_data = g_new (MetaPingData, 1);
ping_data->window = window;
ping_data->serial = serial;
- ping_data->ping_timeout_id = g_timeout_add (PING_TIMEOUT_DELAY,
- meta_display_ping_timeout,
- ping_data);
+ ping_data->ping_timeout_id =
+ g_timeout_add (check_alive_timeout,
+ meta_display_ping_timeout,
+ ping_data);
g_source_set_name_by_id (ping_data->ping_timeout_id, "[mutter] meta_display_ping_timeout");
display->pending_pings = g_slist_prepend (display->pending_pings, ping_data);
diff --git a/src/core/prefs.c b/src/core/prefs.c
index 3f0db8afc..4892406ce 100644
--- a/src/core/prefs.c
+++ b/src/core/prefs.c
@@ -99,6 +99,7 @@ static gboolean bell_is_visible = FALSE;
static gboolean bell_is_audible = TRUE;
static gboolean gnome_accessibility = FALSE;
static gboolean gnome_animations = TRUE;
+static unsigned int check_alive_timeout = 5000;
static char *cursor_theme = NULL;
/* cursor_size will, when running as an X11 compositing window manager, be the
* actual cursor size, multiplied with the global window scaling factor. On
@@ -213,6 +214,12 @@ typedef struct
gint *target;
} MetaIntPreference;
+typedef struct
+{
+ MetaBasePreference base;
+ unsigned int *target;
+} MetaUintPreference;
+
/* All preferences that are not keybindings must be listed here,
* plus in the GSettings schemas and the MetaPreference enum.
@@ -491,6 +498,18 @@ static MetaIntPreference preferences_int[] =
{ { NULL, 0, 0 }, NULL },
};
+static MetaUintPreference preferences_uint[] =
+ {
+ {
+ { "check-alive-timeout",
+ SCHEMA_MUTTER,
+ META_PREF_CHECK_ALIVE_TIMEOUT,
+ },
+ &check_alive_timeout,
+ },
+ { { NULL, 0, 0 }, NULL },
+ };
+
static void
handle_preference_init_enum (void)
{
@@ -613,6 +632,21 @@ handle_preference_init_int (void)
}
}
+static void
+handle_preference_init_uint (void)
+{
+ MetaUintPreference *cursor = preferences_uint;
+
+ while (cursor->base.key != NULL)
+ {
+ if (cursor->target)
+ *cursor->target = g_settings_get_uint (SETTINGS (cursor->base.schema),
+ cursor->base.key);
+
+ ++cursor;
+ }
+}
+
static void
handle_preference_update_enum (GSettings *settings,
gchar *key)
@@ -788,6 +822,28 @@ handle_preference_update_int (GSettings *settings,
}
}
+static void
+handle_preference_update_uint (GSettings *settings,
+ char *key)
+{
+ MetaUintPreference *cursor = preferences_uint;
+ unsigned int new_value;
+
+ while (cursor->base.key && strcmp (key, cursor->base.key) != 0)
+ ++cursor;
+
+ if (!cursor->base.key || !cursor->target)
+ return;
+
+ new_value = g_settings_get_uint (SETTINGS (cursor->base.schema), key);
+
+ if (*cursor->target != new_value)
+ {
+ *cursor->target = new_value;
+ queue_changed (cursor->base.pref);
+ }
+}
+
/****************************************************************************/
/* Listeners. */
@@ -964,6 +1020,7 @@ meta_prefs_init (void)
handle_preference_init_string ();
handle_preference_init_string_array ();
handle_preference_init_int ();
+ handle_preference_init_uint ();
init_bindings ();
}
@@ -1017,6 +1074,8 @@ settings_changed (GSettings *settings,
handle_preference_update_bool (settings, key);
else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
handle_preference_update_int (settings, key);
+ else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
+ handle_preference_update_uint (settings, key);
else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING_ARRAY))
handle_preference_update_string_array (settings, key);
else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
@@ -1640,6 +1699,9 @@ meta_preference_to_string (MetaPreference pref)
case META_PREF_AUTO_MAXIMIZE:
return "AUTO_MAXIMIZE";
+
+ case META_PREF_CHECK_ALIVE_TIMEOUT:
+ return "CHECK_ALIVE_TIMEOUT";
}
return "(unknown)";
@@ -1966,6 +2028,12 @@ meta_prefs_get_overlay_binding (MetaKeyCombo *combo)
*combo = overlay_key_combo;
}
+unsigned int
+meta_prefs_get_check_alive_timeout (void)
+{
+ return check_alive_timeout;
+}
+
const char *
meta_prefs_get_iso_next_group_option (void)
{
diff --git a/src/meta/prefs.h b/src/meta/prefs.h
index 9664b5c07..f42d1c63c 100644
--- a/src/meta/prefs.h
+++ b/src/meta/prefs.h
@@ -103,6 +103,7 @@ typedef enum
META_PREF_AUTO_MAXIMIZE,
META_PREF_CENTER_NEW_WINDOWS,
META_PREF_DRAG_THRESHOLD,
+ META_PREF_CHECK_ALIVE_TIMEOUT,
} MetaPreference;
typedef void (* MetaPrefsChangedFunc) (MetaPreference pref,
@@ -475,4 +476,6 @@ gboolean meta_prefs_bell_is_audible (void);
META_EXPORT
GDesktopVisualBellType meta_prefs_get_visual_bell_type (void);
+unsigned int meta_prefs_get_check_alive_timeout (void);
+
#endif
--
2.28.0

@ -1,55 +0,0 @@
From 62387eb649b7b33d923d5382f85c9210a3bedbe8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 30 May 2019 16:32:35 +0200
Subject: [PATCH] enum-types: Use @basename@ in header comment
@filename@ may contain arch-specific bits that introduce unnecessary
multi-lib issues.
---
clutter/clutter/clutter-enum-types.h.in | 2 +-
cogl/cogl-path/cogl-path-enum-types.h.in | 2 +-
src/meta/meta-enum-types.h.in | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/clutter/clutter/clutter-enum-types.h.in b/clutter/clutter/clutter-enum-types.h.in
index 2e5b6707e..17f9ee644 100644
--- a/clutter/clutter/clutter-enum-types.h.in
+++ b/clutter/clutter/clutter-enum-types.h.in
@@ -13,7 +13,7 @@ G_BEGIN_DECLS
/*** END file-header ***/
/*** BEGIN file-production ***/
-/* enumerations from "@filename@" */
+/* enumerations from "@basename@" */
/*** END file-production ***/
/*** BEGIN value-header ***/
diff --git a/cogl/cogl-path/cogl-path-enum-types.h.in b/cogl/cogl-path/cogl-path-enum-types.h.in
index 071686acd..2b377ed18 100644
--- a/cogl/cogl-path/cogl-path-enum-types.h.in
+++ b/cogl/cogl-path/cogl-path-enum-types.h.in
@@ -9,7 +9,7 @@ G_BEGIN_DECLS
/*** END file-header ***/
/*** BEGIN file-production ***/
-/* enumerations from "@filename@" */
+/* enumerations from "@basename@" */
/*** END file-production ***/
/*** BEGIN file-tail ***/
diff --git a/src/meta/meta-enum-types.h.in b/src/meta/meta-enum-types.h.in
index 6e3b67b26..bee0196de 100644
--- a/src/meta/meta-enum-types.h.in
+++ b/src/meta/meta-enum-types.h.in
@@ -10,7 +10,7 @@ G_BEGIN_DECLS
/*** END file-header ***/
/*** BEGIN file-production ***/
-/* enumerations from "@filename@" */
+/* enumerations from "@basename@" */
/*** END file-production ***/
/*** BEGIN file-tail ***/
--
2.21.0

@ -1,4 +1,4 @@
From f735f345ad8390a7fb09ef54ca3e0e419d395d1b Mon Sep 17 00:00:00 2001 From 7ac5b7bad8f2d0e61700610f68282f6687cc9d2e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org> From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 21 Jul 2016 15:43:12 +0200 Date: Thu, 21 Jul 2016 15:43:12 +0200
Subject: [PATCH] events: Don't move (sloppy) focus while buttons are pressed Subject: [PATCH] events: Don't move (sloppy) focus while buttons are pressed
@ -9,10 +9,10 @@ Subject: [PATCH] events: Don't move (sloppy) focus while buttons are pressed
1 file changed, 11 insertions(+) 1 file changed, 11 insertions(+)
diff --git a/src/x11/events.c b/src/x11/events.c diff --git a/src/x11/events.c b/src/x11/events.c
index e363fdbb6..905b5bf9d 100644 index efa8f9856b..388eff0ac7 100644
--- a/src/x11/events.c --- a/src/x11/events.c
+++ b/src/x11/events.c +++ b/src/x11/events.c
@@ -832,6 +832,16 @@ crossing_serial_is_ignored (MetaX11Display *x11_display, @@ -839,6 +839,16 @@ crossing_serial_is_ignored (MetaX11Display *x11_display,
return FALSE; return FALSE;
} }
@ -29,7 +29,7 @@ index e363fdbb6..905b5bf9d 100644
static gboolean static gboolean
handle_input_xevent (MetaX11Display *x11_display, handle_input_xevent (MetaX11Display *x11_display,
XIEvent *input_event, XIEvent *input_event,
@@ -876,6 +886,7 @@ handle_input_xevent (MetaX11Display *x11_display, @@ -883,6 +893,7 @@ handle_input_xevent (MetaX11Display *x11_display,
* avoid races. * avoid races.
*/ */
if (window && !crossing_serial_is_ignored (x11_display, serial) && if (window && !crossing_serial_is_ignored (x11_display, serial) &&
@ -38,5 +38,5 @@ index e363fdbb6..905b5bf9d 100644
enter_event->mode != XINotifyUngrab && enter_event->mode != XINotifyUngrab &&
enter_event->detail != XINotifyInferior && enter_event->detail != XINotifyInferior &&
-- --
2.21.0 2.31.1

@ -1,122 +0,0 @@
From f108395c32351cda8722130e0e2970827b18e5a9 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Wed, 2 Oct 2019 16:49:28 +0200
Subject: [PATCH] events: Sync pending pointer events without a window
Mutter issues a synchronous grab on the pointer for unfocused client
windows to be able to catch the button events first and raise/focus
client windows accordingly.
When there is a synchronous grab in effect, all events are queued until
the grabbing client releases the event queue as it processes the events.
Mutter does release the events in its event handler function but does so
only if it is able to find the window matching the event. If the window
is a shell widget, that matching may fail and therefore Mutter will not
release the events, hence causing a freeze in pointer events delivery.
To avoid the issue, make sure we sync the pointer events in case we
can't find a matching window.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/821
---
src/core/events.c | 62 ++++++++++++++++++++++++++++++++++++++---------
1 file changed, 51 insertions(+), 11 deletions(-)
diff --git a/src/core/events.c b/src/core/events.c
index 5b8e49fc7..831cb007b 100644
--- a/src/core/events.c
+++ b/src/core/events.c
@@ -50,6 +50,12 @@
#define IS_KEY_EVENT(e) ((e)->type == CLUTTER_KEY_PRESS || \
(e)->type == CLUTTER_KEY_RELEASE)
+typedef enum
+{
+ EVENTS_UNFREEZE_SYNC,
+ EVENTS_UNFREEZE_REPLAY,
+} EventsUnfreezeMethod;
+
static gboolean
stage_has_key_focus (void)
{
@@ -167,6 +173,43 @@ sequence_is_pointer_emulated (MetaDisplay *display,
return FALSE;
}
+static void
+maybe_unfreeze_pointer_events (MetaBackend *backend,
+ const ClutterEvent *event,
+ EventsUnfreezeMethod unfreeze_method)
+{
+ Display *xdisplay;
+ int event_mode;
+ int device_id;
+
+ if (event->type != CLUTTER_BUTTON_PRESS)
+ return;
+
+ if (!META_IS_BACKEND_X11 (backend))
+ return;
+
+ device_id = clutter_event_get_device_id (event);
+ switch (unfreeze_method)
+ {
+ case EVENTS_UNFREEZE_SYNC:
+ event_mode = XISyncDevice;
+ meta_verbose ("Syncing events time %u device %i\n",
+ (unsigned int) event->button.time, device_id);
+ break;
+ case EVENTS_UNFREEZE_REPLAY:
+ event_mode = XIReplayDevice;
+ meta_verbose ("Replaying events time %u device %i\n",
+ (unsigned int) event->button.time, device_id);
+ break;
+ default:
+ g_assert_not_reached ();
+ return;
+ }
+
+ xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
+ XIAllowEvents (xdisplay, device_id, event_mode, event->button.time);
+}
+
static gboolean
meta_display_handle_event (MetaDisplay *display,
const ClutterEvent *event)
@@ -366,17 +409,7 @@ meta_display_handle_event (MetaDisplay *display,
{
/* Only replay button press events, since that's where we
* have the synchronous grab. */
- if (event->type == CLUTTER_BUTTON_PRESS)
- {
- if (META_IS_BACKEND_X11 (backend))
- {
- Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
- meta_verbose ("Allowing events time %u\n",
- (unsigned int)event->button.time);
- XIAllowEvents (xdisplay, clutter_event_get_device_id (event),
- XIReplayDevice, event->button.time);
- }
- }
+ maybe_unfreeze_pointer_events (backend, event, EVENTS_UNFREEZE_REPLAY);
/* If the focus window has an active close dialog let clutter
* events go through, so fancy clutter dialogs can get to handle
@@ -392,6 +425,13 @@ meta_display_handle_event (MetaDisplay *display,
goto out;
}
+ else
+ {
+ /* We could not match the event with a window, make sure we sync
+ * the pointer to discard the sequence and don't keep events frozen.
+ */
+ maybe_unfreeze_pointer_events (backend, event, EVENTS_UNFREEZE_SYNC);
+ }
out:
/* If the compositor has a grab, don't pass that through to Wayland */
--
2.23.0

@ -0,0 +1,45 @@
From 168a47c9ebefaeca6cc25fcbc0d41ac50c16f400 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Wed, 1 Feb 2023 10:07:53 +0100
Subject: [PATCH] gpu/kms: Report that we can have outputs if we have
connectors
As part of https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/525
(introduction of transactional KMS API), the logic determining whether a
GPU can have outputs was changed from whether any connectors existed to
whether any connected connectors existed. That effectively meant that we
wouldn't attempt to start at all if there were no monitors connected
while starting up.
This was unintentional, so lets revert back the expected behavior.
---
src/backends/native/meta-gpu-kms.c | 13 +------------
1 file changed, 1 insertion(+), 12 deletions(-)
diff --git a/src/backends/native/meta-gpu-kms.c b/src/backends/native/meta-gpu-kms.c
index e81c90a022..2756bddb26 100644
--- a/src/backends/native/meta-gpu-kms.c
+++ b/src/backends/native/meta-gpu-kms.c
@@ -399,18 +399,7 @@ meta_gpu_kms_read_current (MetaGpu *gpu,
gboolean
meta_gpu_kms_can_have_outputs (MetaGpuKms *gpu_kms)
{
- GList *l;
- int n_connected_connectors = 0;
-
- for (l = meta_kms_device_get_connectors (gpu_kms->kms_device); l; l = l->next)
- {
- MetaKmsConnector *kms_connector = l->data;
-
- if (meta_kms_connector_get_current_state (kms_connector))
- n_connected_connectors++;
- }
-
- return n_connected_connectors > 0;
+ return !!meta_kms_device_get_connectors (gpu_kms->kms_device);
}
MetaGpuKms *
--
2.39.1

@ -1,136 +0,0 @@
From 80f79e0cc7509b79b38193a006b0d98d03432044 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Mon, 5 Aug 2019 14:39:21 -0400
Subject: [PATCH] iconcache: Avoid xrender picture formats when creating cairo
surface
If an application provides its window icon via wmhints, then mutter
loads the pixmap specified by the application into a cairo xlib surface. When
creating the surface it specifies the visual, indirectly, via an XRender
picture format.
This is suboptimal, since XRender picture formats don't have a way to specify
16bpp depth, which an application may be using.
In particular, applications are likely to use 16bpp depth pixmaps for their
icons, if the video card offers a 16bpp framebuffer/root window.
This commit drops the XRender middleman, and just tells cairo a visual to use
directly.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/715
---
src/x11/iconcache.c | 31 ++++++-------------------------
1 file changed, 6 insertions(+), 25 deletions(-)
diff --git a/src/x11/iconcache.c b/src/x11/iconcache.c
index 15d72da65..521c77b8d 100644
--- a/src/x11/iconcache.c
+++ b/src/x11/iconcache.c
@@ -261,97 +261,78 @@ get_pixmap_geometry (MetaX11Display *x11_display,
Pixmap pixmap,
int *w,
int *h,
int *d)
{
Window root_ignored;
int x_ignored, y_ignored;
guint width, height;
guint border_width_ignored;
guint depth;
if (w)
*w = 1;
if (h)
*h = 1;
if (d)
*d = 1;
XGetGeometry (x11_display->xdisplay,
pixmap, &root_ignored, &x_ignored, &y_ignored,
&width, &height, &border_width_ignored, &depth);
if (w)
*w = width;
if (h)
*h = height;
if (d)
*d = depth;
}
-static int
-standard_pict_format_for_depth (int depth)
-{
- switch (depth)
- {
- case 1:
- return PictStandardA1;
- case 24:
- return PictStandardRGB24;
- case 32:
- return PictStandardARGB32;
- default:
- g_assert_not_reached ();
- }
- return 0;
-}
-
-static XRenderPictFormat *
-pict_format_for_depth (Display *xdisplay, int depth)
-{
- return XRenderFindStandardFormat (xdisplay, standard_pict_format_for_depth (depth));
-}
-
static cairo_surface_t *
surface_from_pixmap (Display *xdisplay, Pixmap xpixmap,
int width, int height)
{
Window root_return;
+ XVisualInfo visual_info;
int x_ret, y_ret;
unsigned int w_ret, h_ret, bw_ret, depth_ret;
if (!XGetGeometry (xdisplay, xpixmap, &root_return,
&x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret))
return NULL;
- return cairo_xlib_surface_create_with_xrender_format (xdisplay, xpixmap, DefaultScreenOfDisplay (xdisplay),
- pict_format_for_depth (xdisplay, depth_ret), w_ret, h_ret);
+ if (!XMatchVisualInfo (xdisplay, DefaultScreen (xdisplay),
+ depth_ret, TrueColor, &visual_info))
+ return NULL;
+
+ return cairo_xlib_surface_create (xdisplay, xpixmap, visual_info.visual, w_ret, h_ret);
}
static gboolean
try_pixmap_and_mask (MetaX11Display *x11_display,
Pixmap src_pixmap,
Pixmap src_mask,
cairo_surface_t **iconp)
{
Display *xdisplay = x11_display->xdisplay;
cairo_surface_t *icon, *mask = NULL;
int w, h, d;
if (src_pixmap == None)
return FALSE;
meta_x11_error_trap_push (x11_display);
get_pixmap_geometry (x11_display, src_pixmap, &w, &h, &d);
icon = surface_from_pixmap (xdisplay, src_pixmap, w, h);
if (icon && src_mask != None)
{
get_pixmap_geometry (x11_display, src_mask, &w, &h, &d);
if (d == 1)
mask = surface_from_pixmap (xdisplay, src_mask, w, h);
}
meta_x11_error_trap_pop (x11_display);
--
2.21.0

@ -0,0 +1,193 @@
From af0460d0cedd5a66b2110ab2a99e67c647e7b6fb Mon Sep 17 00:00:00 2001
From: Piotr Lopatka <piotr.lopatka@gmail.com>
Date: Fri, 3 Sep 2021 19:39:12 +0100
Subject: [PATCH 1/2] kms: Allow passing framebuffer damage metadata
This commit adds support to atomic KMS backend for optional plane property
prop_fb_damage_clips. Some drivers (e.g. EVDI) take advantage of this
property and process only updated regions of the screen instead of
processing the full frame. This can save system resources.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1879>
---
.../native/meta-kms-impl-device-atomic.c | 28 +++++++++++++++
src/backends/native/meta-kms-plane-private.h | 1 +
src/backends/native/meta-kms-plane.c | 5 +++
src/backends/native/meta-kms-update-private.h | 7 ++++
src/backends/native/meta-kms-update.c | 35 +++++++++++++++++++
src/backends/native/meta-kms-update.h | 4 +++
6 files changed, 80 insertions(+)
diff --git a/src/backends/native/meta-kms-impl-device-atomic.c b/src/backends/native/meta-kms-impl-device-atomic.c
index 8e41207ee14..674a24902bd 100644
--- a/src/backends/native/meta-kms-impl-device-atomic.c
+++ b/src/backends/native/meta-kms-impl-device-atomic.c
@@ -416,6 +416,8 @@ process_plane_assignment (MetaKmsImplDevice *impl_device,
MetaKmsPlaneAssignment *plane_assignment = update_entry;
MetaKmsPlane *plane = plane_assignment->plane;
MetaDrmBuffer *buffer;
+ MetaKmsFbDamage *fb_damage;
+ uint32_t prop_id;
buffer = plane_assignment->buffer;
@@ -539,6 +541,32 @@ process_plane_assignment (MetaKmsImplDevice *impl_device,
return FALSE;
}
+ fb_damage = plane_assignment->fb_damage;
+ if (fb_damage &&
+ meta_kms_plane_get_prop_id (plane,
+ META_KMS_PLANE_PROP_FB_DAMAGE_CLIPS_ID))
+ {
+ meta_topic (META_DEBUG_KMS,
+ "[atomic] Setting %d damage clips on %u",
+ fb_damage->n_rects,
+ meta_kms_plane_get_id (plane));
+
+ prop_id = store_new_blob (impl_device,
+ blob_ids,
+ fb_damage->rects,
+ fb_damage->n_rects *
+ sizeof (struct drm_mode_rect),
+ error);
+ if (!prop_id)
+ return FALSE;
+
+ if (!add_plane_property (impl_device,
+ plane, req,
+ META_KMS_PLANE_PROP_FB_DAMAGE_CLIPS_ID,
+ prop_id,
+ error))
+ return FALSE;
+ }
return TRUE;
}
diff --git a/src/backends/native/meta-kms-plane-private.h b/src/backends/native/meta-kms-plane-private.h
index 92f9cfcc9aa..f735c8da8f6 100644
--- a/src/backends/native/meta-kms-plane-private.h
+++ b/src/backends/native/meta-kms-plane-private.h
@@ -41,6 +41,7 @@ typedef enum _MetaKmsPlaneProp
META_KMS_PLANE_PROP_CRTC_H,
META_KMS_PLANE_PROP_FB_ID,
META_KMS_PLANE_PROP_CRTC_ID,
+ META_KMS_PLANE_PROP_FB_DAMAGE_CLIPS_ID,
META_KMS_PLANE_N_PROPS
} MetaKmsPlaneProp;
diff --git a/src/backends/native/meta-kms-plane.c b/src/backends/native/meta-kms-plane.c
index 73fab7d8f80..3cb58764ff3 100644
--- a/src/backends/native/meta-kms-plane.c
+++ b/src/backends/native/meta-kms-plane.c
@@ -446,6 +446,11 @@ init_properties (MetaKmsPlane *plane,
.name = "CRTC_ID",
.type = DRM_MODE_PROP_OBJECT,
},
+ [META_KMS_PLANE_PROP_FB_DAMAGE_CLIPS_ID] =
+ {
+ .name = "FB_DAMAGE_CLIPS",
+ .type = DRM_MODE_PROP_BLOB,
+ },
}
};
diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h
index 22491ece2d5..c89622d09a5 100644
--- a/src/backends/native/meta-kms-update-private.h
+++ b/src/backends/native/meta-kms-update-private.h
@@ -34,6 +34,12 @@ typedef struct _MetaKmsFeedback
GError *error;
} MetaKmsFeedback;
+typedef struct _MetaKmsFbDamage
+{
+ struct drm_mode_rect *rects;
+ int n_rects;
+} MetaKmsFbDamage;
+
typedef struct _MetaKmsPlaneAssignment
{
MetaKmsUpdate *update;
@@ -43,6 +49,7 @@ typedef struct _MetaKmsPlaneAssignment
MetaFixed16Rectangle src_rect;
MetaRectangle dst_rect;
MetaKmsAssignPlaneFlag flags;
+ MetaKmsFbDamage *fb_damage;
uint64_t rotation;
diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c
index be6eaefcc2c..71e5b423fb7 100644
--- a/src/backends/native/meta-kms-update.c
+++ b/src/backends/native/meta-kms-update.c
@@ -129,9 +129,17 @@ meta_kms_feedback_get_error (const MetaKmsFeedback *feedback)
return feedback->error;
}
+static void
+meta_kms_fb_damage_free (MetaKmsFbDamage *fb_damage)
+{
+ g_free (fb_damage->rects);
+ g_free (fb_damage);
+}
+
static void
meta_kms_plane_assignment_free (MetaKmsPlaneAssignment *plane_assignment)
{
+ g_clear_pointer (&plane_assignment->fb_damage, meta_kms_fb_damage_free);
g_free (plane_assignment);
}
@@ -456,6 +464,33 @@ meta_kms_update_set_custom_page_flip (MetaKmsUpdate *update,
update->custom_page_flip = custom_page_flip;
}
+void
+meta_kms_plane_assignment_set_fb_damage (MetaKmsPlaneAssignment *plane_assignment,
+ const int *rectangles,
+ int n_rectangles)
+{
+ MetaKmsFbDamage *fb_damage;
+ struct drm_mode_rect *mode_rects;
+ int i;
+
+ mode_rects = g_new0 (struct drm_mode_rect, n_rectangles);
+ for (i = 0; i < n_rectangles; ++i)
+ {
+ mode_rects[i].x1 = rectangles[i * 4];
+ mode_rects[i].y1 = rectangles[i * 4 + 1];
+ mode_rects[i].x2 = mode_rects[i].x1 + rectangles[i * 4 + 2];
+ mode_rects[i].y2 = mode_rects[i].y1 + rectangles[i * 4 + 3];
+ }
+
+ fb_damage = g_new0 (MetaKmsFbDamage, 1);
+ *fb_damage = (MetaKmsFbDamage) {
+ .rects = mode_rects,
+ .n_rects = n_rectangles,
+ };
+
+ plane_assignment->fb_damage = fb_damage;
+}
+
void
meta_kms_plane_assignment_set_rotation (MetaKmsPlaneAssignment *plane_assignment,
uint64_t rotation)
diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h
index 4a6a8bb4373..e63b6d8711d 100644
--- a/src/backends/native/meta-kms-update.h
+++ b/src/backends/native/meta-kms-update.h
@@ -115,6 +115,10 @@ void meta_kms_update_set_crtc_gamma (MetaKmsUpdate *update,
const uint16_t *green,
const uint16_t *blue);
+void meta_kms_plane_assignment_set_fb_damage (MetaKmsPlaneAssignment *plane_assignment,
+ const int *rectangles,
+ int n_rectangles);
+
MetaKmsPlaneAssignment * meta_kms_update_assign_plane (MetaKmsUpdate *update,
MetaKmsCrtc *crtc,
MetaKmsPlane *plane,
--
2.36.1

@ -0,0 +1,46 @@
From de3188fcc6863b8a6e3d2443a00cf3b00f6f26ff Mon Sep 17 00:00:00 2001
From: Daniel van Vugt <daniel.van.vugt@canonical.com>
Date: Tue, 12 Apr 2022 18:34:58 +0800
Subject: [PATCH 1/2] kms/crtc: Add function meta_kms_crtc_has_gamma
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2360>
---
src/backends/native/meta-kms-crtc.c | 7 +++++++
src/backends/native/meta-kms-crtc.h | 3 +++
2 files changed, 10 insertions(+)
diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c
index 51d040b44..24f5a2d74 100644
--- a/src/backends/native/meta-kms-crtc.c
+++ b/src/backends/native/meta-kms-crtc.c
@@ -92,6 +92,13 @@ meta_kms_crtc_is_active (MetaKmsCrtc *crtc)
return crtc->current_state.is_active;
}
+
+gboolean
+meta_kms_crtc_has_gamma (MetaKmsCrtc *crtc)
+{
+ return !!meta_kms_crtc_get_prop_id (crtc, META_KMS_CRTC_PROP_GAMMA_LUT);
+}
+
static void
read_gamma_state (MetaKmsCrtc *crtc,
MetaKmsImplDevice *impl_device,
diff --git a/src/backends/native/meta-kms-crtc.h b/src/backends/native/meta-kms-crtc.h
index 406ca3ac1..cbaeaa280 100644
--- a/src/backends/native/meta-kms-crtc.h
+++ b/src/backends/native/meta-kms-crtc.h
@@ -66,6 +66,9 @@ uint32_t meta_kms_crtc_get_id (MetaKmsCrtc *crtc);
int meta_kms_crtc_get_idx (MetaKmsCrtc *crtc);
+
+gboolean meta_kms_crtc_has_gamma (MetaKmsCrtc *crtc);
+
gboolean meta_kms_crtc_is_active (MetaKmsCrtc *crtc);
void meta_kms_crtc_gamma_free (MetaKmsCrtcGamma *gamma);
--
2.35.1

@ -0,0 +1,51 @@
From 11e6100226006b5371de30310357582db64c9309 Mon Sep 17 00:00:00 2001
From: Daniel van Vugt <daniel.van.vugt@canonical.com>
Date: Tue, 5 Apr 2022 17:05:17 +0800
Subject: [PATCH 1/2] kms/impl-device: Add addfb2_modifiers to
MetaKmsDeviceCaps
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2359>
---
src/backends/native/meta-kms-impl-device.c | 6 ++++++
src/backends/native/meta-kms-impl-device.h | 1 +
2 files changed, 7 insertions(+)
diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c
index 75920fe6b..d2e821338 100644
--- a/src/backends/native/meta-kms-impl-device.c
+++ b/src/backends/native/meta-kms-impl-device.c
@@ -288,6 +288,7 @@ init_caps (MetaKmsImplDevice *impl_device)
meta_kms_impl_device_get_instance_private (impl_device);
int fd = priv->fd;
uint64_t cursor_width, cursor_height;
+ uint64_t addfb2_modifiers;
if (drmGetCap (fd, DRM_CAP_CURSOR_WIDTH, &cursor_width) == 0 &&
drmGetCap (fd, DRM_CAP_CURSOR_HEIGHT, &cursor_height) == 0)
@@ -296,6 +297,11 @@ init_caps (MetaKmsImplDevice *impl_device)
priv->caps.cursor_width = cursor_width;
priv->caps.cursor_height = cursor_height;
}
+
+ if (drmGetCap (fd, DRM_CAP_ADDFB2_MODIFIERS, &addfb2_modifiers) == 0)
+ {
+ priv->caps.addfb2_modifiers = (addfb2_modifiers != 0);
+ }
}
static void
diff --git a/src/backends/native/meta-kms-impl-device.h b/src/backends/native/meta-kms-impl-device.h
index 913ba992f..a82ad4155 100644
--- a/src/backends/native/meta-kms-impl-device.h
+++ b/src/backends/native/meta-kms-impl-device.h
@@ -36,6 +36,7 @@ typedef struct _MetaKmsDeviceCaps
gboolean has_cursor_size;
uint64_t cursor_width;
uint64_t cursor_height;
+ gboolean addfb2_modifiers;
} MetaKmsDeviceCaps;
typedef struct _MetaKmsProp MetaKmsProp;
--
2.45.2

@ -1,4 +1,4 @@
From 18d4fbb1fb641e2b507b3adcd13d231145a01cd6 Mon Sep 17 00:00:00 2001 From 99c74360451a85fca9dacad531ed22adbc1b0805 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com> From: Ray Strode <rstrode@redhat.com>
Date: Tue, 13 Feb 2018 09:44:50 -0500 Date: Tue, 13 Feb 2018 09:44:50 -0500
Subject: [PATCH] main: be more aggressive in assuming X11 backend Subject: [PATCH] main: be more aggressive in assuming X11 backend
@ -12,10 +12,10 @@ to X11 if the session type isn't set to wayland explicitly.
1 file changed, 3 insertions(+), 5 deletions(-) 1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/src/core/main.c b/src/core/main.c diff --git a/src/core/main.c b/src/core/main.c
index 629f8e94e..1e1e13367 100644 index a07dda9ecc..0d241f952b 100644
--- a/src/core/main.c --- a/src/core/main.c
+++ b/src/core/main.c +++ b/src/core/main.c
@@ -333,7 +333,6 @@ find_session_type (void) @@ -407,7 +407,6 @@ find_session_type (void)
char *session_id; char *session_id;
char *session_type; char *session_type;
const char *session_type_env; const char *session_type_env;
@ -23,7 +23,7 @@ index 629f8e94e..1e1e13367 100644
int ret, i; int ret, i;
ret = sd_pid_get_session (0, &session_id); ret = sd_pid_get_session (0, &session_id);
@@ -346,8 +345,7 @@ find_session_type (void) @@ -420,8 +419,7 @@ find_session_type (void)
{ {
if (session_type_is_supported (session_type)) if (session_type_is_supported (session_type))
goto out; goto out;
@ -33,7 +33,7 @@ index 629f8e94e..1e1e13367 100644
free (session_type); free (session_type);
} }
} }
@@ -379,8 +377,8 @@ find_session_type (void) @@ -453,8 +451,8 @@ find_session_type (void)
goto out; goto out;
} }
@ -45,5 +45,5 @@ index 629f8e94e..1e1e13367 100644
session_type = strdup ("x11"); session_type = strdup ("x11");
goto out; goto out;
-- --
2.21.0 2.31.1

@ -1,211 +0,0 @@
From 19024a5b2eff02b22cdb3fc90142f522dd361996 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Fri, 27 Nov 2020 09:03:38 +0100
Subject: [PATCH] monitor-config-manager: Handle multiple builtin panels
gracefully
While multiple built-in panels isn't actually supported in any
meaningful manner, if we would ever end up with such a situation, e.g.
due to kernel bugs[0], we shouldn't crash when trying to set an
'external only' without any external monitors.
While we could handle this with more degraded functionality (e.g. don't
support the 'switch' method of monitor configuration at all), handle it
by simply not trying to switch to external-only when there are no,
according to the kernel, external monitors available. This would e.g.
still allow betwene 'mirror-all', and 'linear' switches.
The crash itself was disguised as an arbitrary X11 BadValue error, due
to mutter trying to resize the root window to 0x0, as the monitor
configuration that was applied consisted of zero logical monitors, thus
was effectively empty.
[0] https://bugzilla.redhat.com/show_bug.cgi?id=1896904
Related: https://bugzilla.redhat.com/show_bug.cgi?id=1899260
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1607>
---
src/backends/meta-monitor-config-manager.c | 3 +
src/tests/monitor-unit-tests.c | 145 +++++++++++++++++++++
2 files changed, 148 insertions(+)
diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c
index bc1a39db8..d62bad52d 100644
--- a/src/backends/meta-monitor-config-manager.c
+++ b/src/backends/meta-monitor-config-manager.c
@@ -1157,6 +1157,9 @@ create_for_switch_config_external (MetaMonitorConfigManager *config_manager)
x += logical_monitor_config->layout.width;
}
+ if (!logical_monitor_configs)
+ return NULL;
+
return meta_monitors_config_new (monitor_manager,
logical_monitor_configs,
layout_mode,
diff --git a/src/tests/monitor-unit-tests.c b/src/tests/monitor-unit-tests.c
index f47544b03..725f84173 100644
--- a/src/tests/monitor-unit-tests.c
+++ b/src/tests/monitor-unit-tests.c
@@ -3175,6 +3175,149 @@ meta_test_monitor_non_upright_panel (void)
check_monitor_configuration (&test_case);
}
+static void
+meta_test_monitor_switch_external_without_external (void)
+{
+ MonitorTestCase test_case = {
+ .setup = {
+ .modes = {
+ {
+ .width = 1024,
+ .height = 768,
+ .refresh_rate = 60.0
+ }
+ },
+ .n_modes = 1,
+ .outputs = {
+ {
+ .crtc = 0,
+ .modes = { 0 },
+ .n_modes = 1,
+ .preferred_mode = 0,
+ .possible_crtcs = { 0 },
+ .n_possible_crtcs = 1,
+ .width_mm = 222,
+ .height_mm = 125,
+ .is_laptop_panel = TRUE
+ },
+ {
+ .crtc = 1,
+ .modes = { 0 },
+ .n_modes = 1,
+ .preferred_mode = 0,
+ .possible_crtcs = { 1 },
+ .n_possible_crtcs = 1,
+ .width_mm = 222,
+ .height_mm = 125,
+ .is_laptop_panel = TRUE
+ }
+ },
+ .n_outputs = 2,
+ .crtcs = {
+ {
+ .current_mode = 0
+ },
+ {
+ .current_mode = 0
+ }
+ },
+ .n_crtcs = 2
+ },
+
+ .expect = {
+ .monitors = {
+ {
+ .outputs = { 0 },
+ .n_outputs = 1,
+ .modes = {
+ {
+ .width = 1024,
+ .height = 768,
+ .refresh_rate = 60.0,
+ .crtc_modes = {
+ {
+ .output = 0,
+ .crtc_mode = 0
+ }
+ }
+ }
+ },
+ .n_modes = 1,
+ .current_mode = 0,
+ .width_mm = 222,
+ .height_mm = 125
+ },
+ {
+ .outputs = { 1 },
+ .n_outputs = 1,
+ .modes = {
+ {
+ .width = 1024,
+ .height = 768,
+ .refresh_rate = 60.0,
+ .crtc_modes = {
+ {
+ .output = 1,
+ .crtc_mode = 0
+ }
+ }
+ }
+ },
+ .n_modes = 1,
+ .current_mode = 0,
+ .width_mm = 222,
+ .height_mm = 125
+ }
+ },
+ .n_monitors = 2,
+ .logical_monitors = {
+ {
+ .monitors = { 0 },
+ .n_monitors = 1,
+ .layout = { .x = 0, .y = 0, .width = 1024, .height = 768 },
+ .scale = 1
+ },
+ {
+ .monitors = { 1 },
+ .n_monitors = 1,
+ .layout = { .x = 1024, .y = 0, .width = 1024, .height = 768 },
+ .scale = 1
+ }
+ },
+ .n_logical_monitors = 2,
+ .primary_logical_monitor = 0,
+ .n_outputs = 2,
+ .crtcs = {
+ {
+ .current_mode = 0,
+ },
+ {
+ .current_mode = 0,
+ },
+ },
+ .n_crtcs = 2,
+ .n_tiled_monitors = 0,
+ .screen_width = 2048,
+ .screen_height = 768
+ }
+ };
+ MetaMonitorTestSetup *test_setup;
+ MetaBackend *backend = meta_get_backend ();
+ MetaMonitorManager *monitor_manager =
+ meta_backend_get_monitor_manager (backend);
+
+ test_setup = create_monitor_test_setup (&test_case.setup,
+ MONITOR_TEST_FLAG_NO_STORED);
+ emulate_hotplug (test_setup);
+ check_monitor_configuration (&test_case);
+
+ meta_monitor_manager_switch_config (monitor_manager,
+ META_MONITOR_SWITCH_CONFIG_EXTERNAL);
+ check_monitor_configuration (&test_case);
+
+ check_monitor_test_clients_state ();
+}
+
static void
meta_test_monitor_custom_vertical_config (void)
{
@@ -5969,6 +6112,8 @@ init_monitor_tests (void)
meta_test_monitor_preferred_non_first_mode);
add_monitor_test ("/backends/monitor/non-upright-panel",
meta_test_monitor_non_upright_panel);
+ add_monitor_test ("/backends/monitor/switch-external-without-external",
+ meta_test_monitor_switch_external_without_external);
add_monitor_test ("/backends/monitor/custom/vertical-config",
meta_test_monitor_custom_vertical_config);
--
2.29.2

@ -0,0 +1,218 @@
From f21c8614daeb70a021c128b97c000a92652cf6f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Thu, 24 Feb 2022 12:32:27 +0100
Subject: [PATCH] monitor-manager: Add NightLightSupported property to
DisplayConfig
This checks whether it's possible to set a CRTC GAMMA_LUT, which is what
is necessary to implement night light.
---
src/backends/meta-monitor-manager.c | 76 ++++++++++++++++---
.../native/meta-monitor-manager-native.c | 25 ++++--
.../x11/meta-monitor-manager-xrandr.c | 9 ++-
src/org.gnome.Mutter.DisplayConfig.xml | 7 ++
4 files changed, 99 insertions(+), 18 deletions(-)
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 75146950c3..0f30b3de25 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -952,6 +952,59 @@ update_panel_orientation_managed (MetaMonitorManager *manager)
handle_orientation_change (orientation_manager, manager);
}
+static void
+meta_monitor_manager_get_crtc_gamma (MetaMonitorManager *manager,
+ MetaCrtc *crtc,
+ size_t *size,
+ unsigned short **red,
+ unsigned short **green,
+ unsigned short **blue)
+{
+ MetaMonitorManagerClass *klass = META_MONITOR_MANAGER_GET_CLASS (manager);
+
+ if (klass->get_crtc_gamma)
+ {
+ klass->get_crtc_gamma (manager, crtc, size, red, green, blue);
+ }
+ else
+ {
+ if (size)
+ *size = 0;
+ if (red)
+ *red = NULL;
+ if (green)
+ *green = NULL;
+ if (blue)
+ *blue = NULL;
+ }
+}
+
+static gboolean
+is_night_light_supported (MetaMonitorManager *manager)
+{
+ GList *l;
+
+ for (l = meta_backend_get_gpus (manager->backend); l; l = l->next)
+ {
+ MetaGpu *gpu = l->data;
+ GList *l_crtc;
+
+ for (l_crtc = meta_gpu_get_crtcs (gpu); l_crtc; l_crtc = l_crtc->next)
+ {
+ MetaCrtc *crtc = l_crtc->data;
+ size_t gamma_lut_size;
+
+ meta_monitor_manager_get_crtc_gamma (manager, crtc,
+ &gamma_lut_size,
+ NULL, NULL, NULL);
+ if (gamma_lut_size > 0)
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
void
meta_monitor_manager_setup (MetaMonitorManager *manager)
{
@@ -967,7 +1020,6 @@ meta_monitor_manager_setup (MetaMonitorManager *manager)
meta_dbus_display_config_set_apply_monitors_config_allowed (manager->display_config,
policy->enable_dbus);
-
meta_monitor_manager_read_current_state (manager);
meta_monitor_manager_ensure_initial_config (manager);
@@ -2445,7 +2497,6 @@ meta_monitor_manager_handle_get_crtc_gamma (MetaDBusDisplayConfig *skeleton,
guint crtc_id,
MetaMonitorManager *manager)
{
- MetaMonitorManagerClass *klass;
GList *combined_crtcs;
MetaCrtc *crtc;
gsize size;
@@ -2476,14 +2527,8 @@ meta_monitor_manager_handle_get_crtc_gamma (MetaDBusDisplayConfig *skeleton,
crtc = g_list_nth_data (combined_crtcs, crtc_id);
g_list_free (combined_crtcs);
- klass = META_MONITOR_MANAGER_GET_CLASS (manager);
- if (klass->get_crtc_gamma)
- klass->get_crtc_gamma (manager, crtc, &size, &red, &green, &blue);
- else
- {
- size = 0;
- red = green = blue = NULL;
- }
+ meta_monitor_manager_get_crtc_gamma (manager, crtc,
+ &size, &red, &green, &blue);
red_bytes = g_bytes_new_take (red, size * sizeof (unsigned short));
green_bytes = g_bytes_new_take (green, size * sizeof (unsigned short));
@@ -3078,6 +3123,16 @@ meta_monitor_manager_is_transform_handled (MetaMonitorManager *manager,
return manager_class->is_transform_handled (manager, crtc, transform);
}
+static void
+update_night_light_supported (MetaMonitorManager *manager)
+{
+ gboolean night_light_supported;
+
+ night_light_supported = is_night_light_supported (manager);
+ meta_dbus_display_config_set_night_light_supported (manager->display_config,
+ night_light_supported);
+}
+
static void
meta_monitor_manager_real_read_current_state (MetaMonitorManager *manager)
{
@@ -3098,6 +3153,7 @@ meta_monitor_manager_real_read_current_state (MetaMonitorManager *manager)
}
rebuild_monitors (manager);
+ update_night_light_supported (manager);
}
void
diff --git a/src/backends/native/meta-monitor-manager-native.c b/src/backends/native/meta-monitor-manager-native.c
index fd5e7784ff..37a50f1d6f 100644
--- a/src/backends/native/meta-monitor-manager-native.c
+++ b/src/backends/native/meta-monitor-manager-native.c
@@ -381,15 +381,30 @@ meta_monitor_manager_native_get_crtc_gamma (MetaMonitorManager *manager,
MetaKmsCrtc *kms_crtc;
const MetaKmsCrtcState *crtc_state;
- g_return_if_fail (META_IS_CRTC_KMS (crtc));
+ if (!META_IS_CRTC_KMS (crtc))
+ {
+ if (size)
+ *size = 0;
+ if (red)
+ *red = NULL;
+ if (green)
+ *green = NULL;
+ if (blue)
+ *blue = NULL;
+ return;
+ }
kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc));
crtc_state = meta_kms_crtc_get_current_state (kms_crtc);
- *size = crtc_state->gamma.size;
- *red = g_memdup2 (crtc_state->gamma.red, *size * sizeof **red);
- *green = g_memdup2 (crtc_state->gamma.green, *size * sizeof **green);
- *blue = g_memdup2 (crtc_state->gamma.blue, *size * sizeof **blue);
+ if (size)
+ *size = crtc_state->gamma.size;
+ if (red)
+ *red = g_memdup2 (crtc_state->gamma.red, *size * sizeof **red);
+ if (green)
+ *green = g_memdup2 (crtc_state->gamma.green, *size * sizeof **green);
+ if (blue)
+ *blue = g_memdup2 (crtc_state->gamma.blue, *size * sizeof **blue);
}
static char *
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
index 98eb080b6b..865f4e5800 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
@@ -707,9 +707,12 @@ meta_monitor_manager_xrandr_get_crtc_gamma (MetaMonitorManager *manager,
(XID) meta_crtc_get_id (crtc));
*size = gamma->size;
- *red = g_memdup2 (gamma->red, sizeof (unsigned short) * gamma->size);
- *green = g_memdup2 (gamma->green, sizeof (unsigned short) * gamma->size);
- *blue = g_memdup2 (gamma->blue, sizeof (unsigned short) * gamma->size);
+ if (red)
+ *red = g_memdup2 (gamma->red, sizeof (unsigned short) * gamma->size);
+ if (green)
+ *green = g_memdup2 (gamma->green, sizeof (unsigned short) * gamma->size);
+ if (blue)
+ *blue = g_memdup2 (gamma->blue, sizeof (unsigned short) * gamma->size);
XRRFreeGamma (gamma);
}
diff --git a/src/org.gnome.Mutter.DisplayConfig.xml b/src/org.gnome.Mutter.DisplayConfig.xml
index c6859c2c09..5f85c5e271 100644
--- a/src/org.gnome.Mutter.DisplayConfig.xml
+++ b/src/org.gnome.Mutter.DisplayConfig.xml
@@ -297,6 +297,13 @@
-->
<property name="ApplyMonitorsConfigAllowed" type="b" access="read" />
+ <!--
+ NightLightSupported:
+
+ Whether night light is supported by this system.
+ -->
+ <property name="NightLightSupported" type="b" access="read" />
+
<!--
MonitorsChanged:
--
2.37.1

@ -1,152 +0,0 @@
From 4904f1a1e5b881dfd5a051c15acecb3232dc8207 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 28 Jan 2016 15:26:33 +0100
Subject: [PATCH] monitor-manager: Consider external layout before default
linear config
In case of no existing configuration, we use a default layout of
aligning attached displays horizontally. This sidesteps any layout
configuration that is done externally, for instance via xorg.conf,
which is not desirable. Instead, base the initial configuration on
the existing layout if it passes some sanity checks before falling
back to the default linear config.
---
src/backends/meta-monitor-config-manager.c | 77 ++++++++++++++++++++++
src/backends/meta-monitor-config-manager.h | 2 +
src/backends/meta-monitor-manager.c | 19 ++++++
3 files changed, 98 insertions(+)
diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c
index 9a54ce50f..d64ca1f79 100644
--- a/src/backends/meta-monitor-config-manager.c
+++ b/src/backends/meta-monitor-config-manager.c
@@ -643,6 +643,83 @@ create_preferred_logical_monitor_config (MetaMonitorManager *monitor_ma
return logical_monitor_config;
}
+static MetaLogicalMonitorConfig *
+create_logical_monitor_config_from_output (MetaMonitorManager *monitor_manager,
+ MetaMonitor *monitor,
+ MetaLogicalMonitorConfig *primary_logical_monitor_config,
+ MetaLogicalMonitorLayoutMode layout_mode)
+{
+ MetaOutput *output;
+ MetaCrtc *crtc;
+
+ output = meta_monitor_get_main_output (monitor);
+ crtc = meta_output_get_assigned_crtc (output);
+ return create_preferred_logical_monitor_config (monitor_manager,
+ monitor,
+ crtc->rect.x,
+ crtc->rect.y,
+ primary_logical_monitor_config,
+ layout_mode);
+}
+
+MetaMonitorsConfig *
+meta_monitor_config_manager_create_current (MetaMonitorConfigManager *config_manager)
+{
+ MetaMonitorManager *monitor_manager = config_manager->monitor_manager;
+ GList *logical_monitor_configs;
+ MetaMonitor *primary_monitor;
+ MetaLogicalMonitorLayoutMode layout_mode;
+ MetaLogicalMonitorConfig *primary_logical_monitor_config;
+ GList *monitors;
+ GList *l;
+
+ if (meta_monitor_config_store_get_config_count (config_manager->config_store) > 0)
+ return NULL;
+
+ primary_monitor = find_primary_monitor (monitor_manager);
+ if (!primary_monitor || !meta_monitor_is_active (primary_monitor))
+ return NULL;
+
+ layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager);
+
+ primary_logical_monitor_config =
+ create_logical_monitor_config_from_output (monitor_manager,
+ primary_monitor,
+ NULL,
+ layout_mode);
+
+ primary_logical_monitor_config->is_primary = TRUE;
+ logical_monitor_configs = g_list_append (NULL,
+ primary_logical_monitor_config);
+
+ monitors = meta_monitor_manager_get_monitors (monitor_manager);
+ for (l = monitors; l; l = l->next)
+ {
+ MetaMonitor *monitor = l->data;
+ MetaLogicalMonitorConfig *logical_monitor_config;
+
+ if (monitor == primary_monitor)
+ continue;
+
+ if (!meta_monitor_is_active (monitor))
+ continue;
+
+ logical_monitor_config =
+ create_logical_monitor_config_from_output (monitor_manager,
+ monitor,
+ primary_logical_monitor_config,
+ layout_mode);
+
+ logical_monitor_configs = g_list_append (logical_monitor_configs,
+ logical_monitor_config);
+ }
+
+ return meta_monitors_config_new (monitor_manager,
+ logical_monitor_configs,
+ layout_mode,
+ META_MONITORS_CONFIG_FLAG_NONE);
+}
+
MetaMonitorsConfig *
meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_manager)
{
diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h
index 3875e04e9..364a2b36b 100644
--- a/src/backends/meta-monitor-config-manager.h
+++ b/src/backends/meta-monitor-config-manager.h
@@ -94,6 +94,8 @@ gboolean meta_monitor_config_manager_assign (MetaMonitorManager *manager,
META_EXPORT_TEST
MetaMonitorsConfig * meta_monitor_config_manager_get_stored (MetaMonitorConfigManager *config_manager);
+META_EXPORT_TEST
+MetaMonitorsConfig * meta_monitor_config_manager_create_current (MetaMonitorConfigManager *config_manager);
META_EXPORT_TEST
MetaMonitorsConfig * meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_manager);
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 2d898c757..05b27c6be 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -614,6 +614,25 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
g_clear_object (&config);
}
+ config = meta_monitor_config_manager_create_current (manager->config_manager);
+ if (config)
+ {
+ if (!meta_monitor_manager_apply_monitors_config (manager,
+ config,
+ method,
+ &error))
+ {
+ g_clear_object (&config);
+ g_warning ("Failed to use current monitor configuration: %s",
+ error->message);
+ g_clear_error (&error);
+ }
+ else
+ {
+ goto done;
+ }
+ }
+
config = meta_monitor_config_manager_create_linear (manager->config_manager);
if (config)
{
--
2.21.0

@ -1,41 +0,0 @@
From 9f8564ce066aeb704341d6f926daec0045243b70 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Thu, 25 Jun 2020 10:06:38 +0200
Subject: [PATCH 1/2] monitor-manager-kms: Trigger hotplug processing on gpu
removal
---
src/backends/native/meta-monitor-manager-kms.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
index 9a0364441a..2819881576 100644
--- a/src/backends/native/meta-monitor-manager-kms.c
+++ b/src/backends/native/meta-monitor-manager-kms.c
@@ -470,12 +470,18 @@ on_uevent (GUdevClient *client,
if (!g_strcmp0 (seat_id, device_seat))
handle_gpu_hotplug (manager_kms, device);
- }
-
- if (!g_udev_device_get_property_as_boolean (device, "HOTPLUG"))
- return;
- handle_hotplug_event (manager);
+ handle_hotplug_event (manager);
+ }
+ else if (g_str_equal (action, "remove") &&
+ g_udev_device_get_device_file (device) != NULL)
+ {
+ handle_hotplug_event (manager);
+ }
+ else if (g_udev_device_get_property_as_boolean (device, "HOTPLUG"))
+ {
+ handle_hotplug_event (manager);
+ }
}
static void
--
2.26.2

@ -1,144 +0,0 @@
From 4ad8fd80355189ecbde6c38961335ae4be4db8b3 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Tue, 11 Sep 2018 10:19:44 -0400
Subject: [PATCH] monitor-manager: only reuse initial-config if monitor
topology matches startup
Right now we try to apply the current monitor config when a new
monitor is attached. The current config obviously doesn't include the
new monitor, so the new monitor isn't lit up.
The only reason we apply the current config at all is to handle the
startup case: We want to reuse the config set in Xorg when first
logging in.
This commit changes the code to look at the *initial config* instead
of the current config, and only if the new monitor topology matches
the start up topology.
---
src/backends/meta-monitor-config-manager.c | 20 +++++++++++++++-----
src/backends/meta-monitor-config-manager.h | 2 +-
src/backends/meta-monitor-manager.c | 16 +++++++++++++++-
3 files changed, 31 insertions(+), 7 deletions(-)
diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c
index d64ca1f79..c09edbe00 100644
--- a/src/backends/meta-monitor-config-manager.c
+++ b/src/backends/meta-monitor-config-manager.c
@@ -42,6 +42,7 @@ struct _MetaMonitorConfigManager
MetaMonitorConfigStore *config_store;
MetaMonitorsConfig *current_config;
+ MetaMonitorsConfig *initial_config;
GQueue config_history;
};
@@ -663,9 +664,10 @@ create_logical_monitor_config_from_output (MetaMonitorManager *monitor
}
MetaMonitorsConfig *
-meta_monitor_config_manager_create_current (MetaMonitorConfigManager *config_manager)
+meta_monitor_config_manager_create_initial (MetaMonitorConfigManager *config_manager)
{
MetaMonitorManager *monitor_manager = config_manager->monitor_manager;
+ MetaMonitorsConfig *initial_config;
GList *logical_monitor_configs;
MetaMonitor *primary_monitor;
MetaLogicalMonitorLayoutMode layout_mode;
@@ -673,6 +675,9 @@ meta_monitor_config_manager_create_current (MetaMonitorConfigManager *config_man
GList *monitors;
GList *l;
+ if (config_manager->initial_config != NULL)
+ return g_object_ref (config_manager->initial_config);
+
if (meta_monitor_config_store_get_config_count (config_manager->config_store) > 0)
return NULL;
@@ -714,10 +719,14 @@ meta_monitor_config_manager_create_current (MetaMonitorConfigManager *config_man
logical_monitor_config);
}
- return meta_monitors_config_new (monitor_manager,
- logical_monitor_configs,
- layout_mode,
- META_MONITORS_CONFIG_FLAG_NONE);
+ initial_config = meta_monitors_config_new (monitor_manager,
+ logical_monitor_configs,
+ layout_mode,
+ META_MONITORS_CONFIG_FLAG_NONE);
+
+ config_manager->initial_config = g_object_ref (initial_config);
+
+ return initial_config;
}
MetaMonitorsConfig *
@@ -1256,6 +1265,7 @@ meta_monitor_config_manager_dispose (GObject *object)
META_MONITOR_CONFIG_MANAGER (object);
g_clear_object (&config_manager->current_config);
+ g_clear_object (&config_manager->initial_config);
meta_monitor_config_manager_clear_history (config_manager);
G_OBJECT_CLASS (meta_monitor_config_manager_parent_class)->dispose (object);
diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h
index 364a2b36b..409611bb0 100644
--- a/src/backends/meta-monitor-config-manager.h
+++ b/src/backends/meta-monitor-config-manager.h
@@ -95,7 +95,7 @@ META_EXPORT_TEST
MetaMonitorsConfig * meta_monitor_config_manager_get_stored (MetaMonitorConfigManager *config_manager);
META_EXPORT_TEST
-MetaMonitorsConfig * meta_monitor_config_manager_create_current (MetaMonitorConfigManager *config_manager);
+MetaMonitorsConfig * meta_monitor_config_manager_create_initial (MetaMonitorConfigManager *config_manager);
META_EXPORT_TEST
MetaMonitorsConfig * meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_manager);
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 05b27c6be..bb4b44188 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -534,9 +534,11 @@ should_use_stored_config (MetaMonitorManager *manager)
MetaMonitorsConfig *
meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
{
+ g_autoptr (MetaMonitorsConfig) initial_config = NULL;
MetaMonitorsConfig *config = NULL;
GError *error = NULL;
gboolean use_stored_config;
+ MetaMonitorsConfigKey *current_state_key;
MetaMonitorsConfigMethod method;
MetaMonitorsConfigMethod fallback_method =
META_MONITORS_CONFIG_METHOD_TEMPORARY;
@@ -547,6 +549,18 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
else
method = META_MONITORS_CONFIG_METHOD_TEMPORARY;
+ initial_config = meta_monitor_config_manager_create_initial (manager->config_manager);
+
+ if (initial_config)
+ {
+ current_state_key = meta_create_monitors_config_key_for_current_state (manager);
+
+ /* don't ever reuse initial configuration, if the monitor topology changed
+ */
+ if (current_state_key && !meta_monitors_config_key_equal (current_state_key, initial_config->key))
+ g_clear_object (&initial_config);
+ }
+
if (use_stored_config)
{
config = meta_monitor_config_manager_get_stored (manager->config_manager);
@@ -614,7 +628,7 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
g_clear_object (&config);
}
- config = meta_monitor_config_manager_create_current (manager->config_manager);
+ config = g_steal_pointer (&initial_config);
if (config)
{
if (!meta_monitor_manager_apply_monitors_config (manager,
--
2.21.0

@ -1,272 +0,0 @@
From 849902beff553de41dd3940b17672ef98f687be5 Mon Sep 17 00:00:00 2001
From: Rui Matos <tiagomatos@gmail.com>
Date: Mon, 4 Jun 2018 16:35:04 -0400
Subject: [PATCH] monitor-manager-xrandr: Force an update when resuming from
suspend
The stack below us isn't as reliable as we'd like and in some cases
doesn't generate RRScreenChangeNotify events when e.g. resuming a
laptop on a dock, meaning that we'd miss newly attached outputs.
---
src/backends/meta-gpu.c | 7 ++
src/backends/meta-gpu.h | 4 +
src/backends/x11/meta-gpu-xrandr.c | 26 ++++-
.../x11/meta-monitor-manager-xrandr.c | 96 +++++++++++++++++--
4 files changed, 123 insertions(+), 10 deletions(-)
diff --git a/src/backends/meta-gpu.c b/src/backends/meta-gpu.c
index 3577391e5..946f72387 100644
--- a/src/backends/meta-gpu.c
+++ b/src/backends/meta-gpu.c
@@ -64,6 +64,13 @@ meta_gpu_has_hotplug_mode_update (MetaGpu *gpu)
return FALSE;
}
+void
+meta_gpu_poll_hardware (MetaGpu *gpu)
+{
+ if (META_GPU_GET_CLASS (gpu)->poll_hardware)
+ META_GPU_GET_CLASS (gpu)->poll_hardware (gpu);
+}
+
gboolean
meta_gpu_read_current (MetaGpu *gpu,
GError **error)
diff --git a/src/backends/meta-gpu.h b/src/backends/meta-gpu.h
index 701acdc97..a2fd061f7 100644
--- a/src/backends/meta-gpu.h
+++ b/src/backends/meta-gpu.h
@@ -36,8 +36,12 @@ struct _MetaGpuClass
gboolean (* read_current) (MetaGpu *gpu,
GError **error);
+ void (* poll_hardware) (MetaGpu *gpu);
};
+META_EXPORT_TEST
+void meta_gpu_poll_hardware (MetaGpu *gpu);
+
META_EXPORT_TEST
gboolean meta_gpu_read_current (MetaGpu *gpu,
GError **error);
diff --git a/src/backends/x11/meta-gpu-xrandr.c b/src/backends/x11/meta-gpu-xrandr.c
index 3e8a7318d..90b33d486 100644
--- a/src/backends/x11/meta-gpu-xrandr.c
+++ b/src/backends/x11/meta-gpu-xrandr.c
@@ -44,6 +44,8 @@ struct _MetaGpuXrandr
int max_screen_width;
int max_screen_height;
+
+ gboolean need_hardware_poll;
};
G_DEFINE_TYPE (MetaGpuXrandr, meta_gpu_xrandr, META_TYPE_GPU)
@@ -81,6 +83,14 @@ get_xmode_name (XRRModeInfo *xmode)
return g_strdup_printf ("%dx%d", width, height);
}
+static void
+meta_gpu_xrandr_poll_hardware (MetaGpu *gpu)
+{
+ MetaGpuXrandr *gpu_xrandr = META_GPU_XRANDR (gpu);
+
+ gpu_xrandr->need_hardware_poll = TRUE;
+}
+
static gboolean
meta_gpu_xrandr_read_current (MetaGpu *gpu,
GError **error)
@@ -116,8 +126,18 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu,
monitor_manager->screen_width = WidthOfScreen (screen);
monitor_manager->screen_height = HeightOfScreen (screen);
- resources = XRRGetScreenResourcesCurrent (xdisplay,
- DefaultRootWindow (xdisplay));
+ if (gpu_xrandr->need_hardware_poll)
+ {
+ resources = XRRGetScreenResources (xdisplay,
+ DefaultRootWindow (xdisplay));
+ gpu_xrandr->need_hardware_poll = FALSE;
+ }
+ else
+ {
+ resources = XRRGetScreenResourcesCurrent (xdisplay,
+ DefaultRootWindow (xdisplay));
+ }
+
if (!resources)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
@@ -250,6 +270,7 @@ meta_gpu_xrandr_finalize (GObject *object)
static void
meta_gpu_xrandr_init (MetaGpuXrandr *gpu_xrandr)
{
+ gpu_xrandr->need_hardware_poll = TRUE;
}
static void
@@ -261,4 +282,5 @@ meta_gpu_xrandr_class_init (MetaGpuXrandrClass *klass)
object_class->finalize = meta_gpu_xrandr_finalize;
gpu_class->read_current = meta_gpu_xrandr_read_current;
+ gpu_class->poll_hardware = meta_gpu_xrandr_poll_hardware;
}
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
index 448e51fae..d60f00325 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
@@ -71,6 +71,10 @@ struct _MetaMonitorManagerXrandr
Display *xdisplay;
int rr_event_base;
int rr_error_base;
+
+ guint logind_watch_id;
+ guint logind_signal_sub_id;
+
gboolean has_randr15;
/*
@@ -102,6 +106,8 @@ typedef struct _MetaMonitorXrandrData
GQuark quark_meta_monitor_xrandr_data;
+static void meta_monitor_manager_xrandr_update (MetaMonitorManagerXrandr *manager_xrandr);
+
Display *
meta_monitor_manager_xrandr_get_xdisplay (MetaMonitorManagerXrandr *manager_xrandr)
{
@@ -1016,6 +1022,62 @@ meta_monitor_manager_xrandr_get_default_layout_mode (MetaMonitorManager *manager
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
}
+static void
+logind_signal_handler (GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ MetaMonitorManagerXrandr *manager_xrandr = user_data;
+ gboolean suspending;
+
+ if (!g_str_equal (signal_name, "PrepareForSleep"))
+ return;
+
+ g_variant_get (parameters, "(b)", &suspending);
+ if (!suspending)
+ {
+ meta_gpu_poll_hardware (manager_xrandr->gpu);
+ meta_monitor_manager_xrandr_update (manager_xrandr);
+ }
+}
+
+static void
+logind_appeared (GDBusConnection *connection,
+ const gchar *name,
+ const gchar *name_owner,
+ gpointer user_data)
+{
+ MetaMonitorManagerXrandr *manager_xrandr = user_data;
+
+ manager_xrandr->logind_signal_sub_id = g_dbus_connection_signal_subscribe (connection,
+ "org.freedesktop.login1",
+ "org.freedesktop.login1.Manager",
+ "PrepareForSleep",
+ "/org/freedesktop/login1",
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ logind_signal_handler,
+ manager_xrandr,
+ NULL);
+}
+
+static void
+logind_vanished (GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ MetaMonitorManagerXrandr *manager_xrandr = user_data;
+
+ if (connection && manager_xrandr->logind_signal_sub_id > 0)
+ g_dbus_connection_signal_unsubscribe (connection, manager_xrandr->logind_signal_sub_id);
+
+ manager_xrandr->logind_signal_sub_id = 0;
+}
+
static void
meta_monitor_manager_xrandr_constructed (GObject *object)
{
@@ -1072,12 +1134,23 @@ meta_monitor_manager_xrandr_finalize (GObject *object)
g_hash_table_destroy (manager_xrandr->tiled_monitor_atoms);
g_free (manager_xrandr->supported_scales);
+ if (manager_xrandr->logind_watch_id > 0)
+ g_bus_unwatch_name (manager_xrandr->logind_watch_id);
+ manager_xrandr->logind_watch_id = 0;
+
G_OBJECT_CLASS (meta_monitor_manager_xrandr_parent_class)->finalize (object);
}
static void
meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
{
+ manager_xrandr->logind_watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM,
+ "org.freedesktop.login1",
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ logind_appeared,
+ logind_vanished,
+ manager_xrandr,
+ NULL);
}
static void
@@ -1123,9 +1196,8 @@ is_xvnc (MetaMonitorManager *manager)
return FALSE;
}
-gboolean
-meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr,
- XEvent *event)
+static void
+meta_monitor_manager_xrandr_update (MetaMonitorManagerXrandr *manager_xrandr)
{
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
MetaGpuXrandr *gpu_xrandr;
@@ -1134,11 +1206,6 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
gboolean is_our_configuration;
unsigned int timestamp;
- if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
- return FALSE;
-
- XRRUpdateConfiguration (event);
-
meta_monitor_manager_read_current_state (manager);
gpu_xrandr = META_GPU_XRANDR (manager_xrandr->gpu);
@@ -1173,6 +1240,19 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
meta_monitor_manager_xrandr_rebuild_derived (manager, config);
}
+}
+
+gboolean
+meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr,
+ XEvent *event)
+{
+
+ if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
+ return FALSE;
+
+ XRRUpdateConfiguration (event);
+
+ meta_monitor_manager_xrandr_update (manager_xrandr);
return TRUE;
}
--
2.21.0

@ -1,114 +0,0 @@
From 078547521dd709d41ac3791322f711030ccc50e9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Wed, 27 Nov 2019 19:03:50 +0100
Subject: [PATCH 1/2] monitor-manager-xrandr: Move dpms state and screen size
updating into helpers
To be used by no-Xrandr fallback path.
---
src/backends/x11/meta-gpu-xrandr.c | 37 +++++++++++++------
.../x11/meta-monitor-manager-xrandr.c | 18 ++++++---
2 files changed, 38 insertions(+), 17 deletions(-)
diff --git a/src/backends/x11/meta-gpu-xrandr.c b/src/backends/x11/meta-gpu-xrandr.c
index 90b33d486..1884278ca 100644
--- a/src/backends/x11/meta-gpu-xrandr.c
+++ b/src/backends/x11/meta-gpu-xrandr.c
@@ -91,6 +91,30 @@ meta_gpu_xrandr_poll_hardware (MetaGpu *gpu)
gpu_xrandr->need_hardware_poll = TRUE;
}
+static void
+update_screen_size (MetaGpuXrandr *gpu_xrandr)
+{
+ MetaGpu *gpu = META_GPU (gpu_xrandr);
+ MetaMonitorManager *monitor_manager = meta_gpu_get_monitor_manager (gpu);
+ MetaMonitorManagerXrandr *monitor_manager_xrandr =
+ META_MONITOR_MANAGER_XRANDR (monitor_manager);
+ Display *xdisplay =
+ meta_monitor_manager_xrandr_get_xdisplay (monitor_manager_xrandr);
+ int min_width, min_height;
+ Screen *screen;
+
+ XRRGetScreenSizeRange (xdisplay, DefaultRootWindow (xdisplay),
+ &min_width,
+ &min_height,
+ &gpu_xrandr->max_screen_width,
+ &gpu_xrandr->max_screen_height);
+
+ screen = ScreenOfDisplay (xdisplay, DefaultScreen (xdisplay));
+ /* This is updated because we called XRRUpdateConfiguration. */
+ monitor_manager->screen_width = WidthOfScreen (screen);
+ monitor_manager->screen_height = HeightOfScreen (screen);
+}
+
static gboolean
meta_gpu_xrandr_read_current (MetaGpu *gpu,
GError **error)
@@ -105,8 +129,6 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu,
RROutput primary_output;
unsigned int i, j;
GList *l;
- int min_width, min_height;
- Screen *screen;
GList *outputs = NULL;
GList *modes = NULL;
GList *crtcs = NULL;
@@ -115,16 +137,7 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu,
XRRFreeScreenResources (gpu_xrandr->resources);
gpu_xrandr->resources = NULL;
- XRRGetScreenSizeRange (xdisplay, DefaultRootWindow (xdisplay),
- &min_width,
- &min_height,
- &gpu_xrandr->max_screen_width,
- &gpu_xrandr->max_screen_height);
-
- screen = ScreenOfDisplay (xdisplay, DefaultScreen (xdisplay));
- /* This is updated because we called XRRUpdateConfiguration. */
- monitor_manager->screen_width = WidthOfScreen (screen);
- monitor_manager->screen_height = HeightOfScreen (screen);
+ update_screen_size (gpu_xrandr);
if (gpu_xrandr->need_hardware_poll)
{
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
index b8d6342b6..7a0b43ac4 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
@@ -146,12 +146,9 @@ x11_dpms_state_to_power_save (CARD16 dpms_state)
}
static void
-meta_monitor_manager_xrandr_read_current_state (MetaMonitorManager *manager)
+meta_monitor_manager_xrandr_update_dpms_state (MetaMonitorManagerXrandr *manager_xrandr)
{
- MetaMonitorManagerXrandr *manager_xrandr =
- META_MONITOR_MANAGER_XRANDR (manager);
- MetaMonitorManagerClass *parent_class =
- META_MONITOR_MANAGER_CLASS (meta_monitor_manager_xrandr_parent_class);
+ MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
Display *xdisplay = meta_monitor_manager_xrandr_get_xdisplay (manager_xrandr);
BOOL dpms_capable, dpms_enabled;
CARD16 dpms_state;
@@ -167,6 +164,17 @@ meta_monitor_manager_xrandr_read_current_state (MetaMonitorManager *manager)
power_save_mode = META_POWER_SAVE_UNSUPPORTED;
meta_monitor_manager_power_save_mode_changed (manager, power_save_mode);
+}
+
+static void
+meta_monitor_manager_xrandr_read_current_state (MetaMonitorManager *manager)
+{
+ MetaMonitorManagerXrandr *manager_xrandr =
+ META_MONITOR_MANAGER_XRANDR (manager);
+ MetaMonitorManagerClass *parent_class =
+ META_MONITOR_MANAGER_CLASS (meta_monitor_manager_xrandr_parent_class);
+
+ meta_monitor_manager_xrandr_update_dpms_state (manager_xrandr);
parent_class->read_current_state (manager);
}
--
2.23.0

@ -1,62 +0,0 @@
From 7e21503dc7c3b8321475eb5ccfdb23e71f86c0a0 Mon Sep 17 00:00:00 2001
From: Rui Matos <tiagomatos@gmail.com>
Date: Tue, 6 Oct 2015 21:16:18 +0200
Subject: [PATCH] monitor-manager-xrandr: Work around spurious hotplugs on Xvnc
Xvnc turns its outputs off/on on every mode set which makes us believe
there was an hotplug when there actually wasn't. Work around this by
requiring new randr configuration timestamps to be ahead of the last
set timestamp by at least 100 ms for us to consider them an actual
hotplug.
---
.../x11/meta-monitor-manager-xrandr.c | 20 ++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
index 45c81f4eb..448e51fae 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
@@ -1110,6 +1110,19 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
g_quark_from_static_string ("-meta-monitor-xrandr-data");
}
+static gboolean
+is_xvnc (MetaMonitorManager *manager)
+{
+ MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager);
+ GList *l;
+
+ for (l = meta_gpu_get_outputs (manager_xrandr->gpu); l; l = l->next)
+ if (g_str_has_prefix (((MetaOutput *)l->data)->name, "VNC-"))
+ return TRUE;
+
+ return FALSE;
+}
+
gboolean
meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr,
XEvent *event)
@@ -1119,6 +1132,7 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
XRRScreenResources *resources;
gboolean is_hotplug;
gboolean is_our_configuration;
+ unsigned int timestamp;
if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
return FALSE;
@@ -1130,7 +1144,11 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
gpu_xrandr = META_GPU_XRANDR (manager_xrandr->gpu);
resources = meta_gpu_xrandr_get_resources (gpu_xrandr);
- is_hotplug = resources->timestamp < resources->configTimestamp;
+ timestamp = resources->timestamp;
+ if (is_xvnc (manager))
+ timestamp += 100;
+
+ is_hotplug = (timestamp < resources->configTimestamp);
is_our_configuration = (resources->timestamp ==
manager_xrandr->last_xrandr_set_timestamp);
if (is_hotplug)
--
2.21.0

@ -1,7 +1,7 @@
From cf16c0d16b42215f35dcede6163235ad5ec1734b Mon Sep 17 00:00:00 2001 From 86000c32d64cea7be2e6ed911cb9ea5df1306c0e Mon Sep 17 00:00:00 2001
From: Mario Limonciello <mario.limonciello@amd.com> From: Mario Limonciello <mario.limonciello@amd.com>
Date: Thu, 18 Aug 2022 13:36:20 -0500 Date: Thu, 18 Aug 2022 13:36:20 -0500
Subject: [PATCH] output/kms: Add more heuristics to decide when to offer Subject: [PATCH 1/2] output/kms: Add more heuristics to decide when to offer
fallback modes fallback modes
If the panel is connected via eDP and supports more than one mode If the panel is connected via eDP and supports more than one mode
@ -9,30 +9,33 @@ at different resolutions don't try to add more.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2586> Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2586>
(cherry picked from commit 96aa0fb8536eca579ceb1b17d83e19cf9e3e9e81) (cherry picked from commit 96aa0fb8536eca579ceb1b17d83e19cf9e3e9e81)
(cherry picked from commit 877cc3eb7d44e2886395151f763ec09bea350444)
--- ---
src/backends/native/meta-output-kms.c | 45 ++++++++++++++++++++++----- src/backends/native/meta-output-kms.c | 56 +++++++++++++++++++++------
1 file changed, 38 insertions(+), 7 deletions(-) 1 file changed, 44 insertions(+), 12 deletions(-)
diff --git a/src/backends/native/meta-output-kms.c b/src/backends/native/meta-output-kms.c diff --git a/src/backends/native/meta-output-kms.c b/src/backends/native/meta-output-kms.c
index f3cc543c4d..44c25c5648 100644 index f35cdf04e1..9adc20bfd9 100644
--- a/src/backends/native/meta-output-kms.c --- a/src/backends/native/meta-output-kms.c
+++ b/src/backends/native/meta-output-kms.c +++ b/src/backends/native/meta-output-kms.c
@@ -505,6 +505,43 @@ compare_modes (const void *one, @@ -224,6 +224,45 @@ compare_modes (const void *one,
return g_strcmp0 (b->name, a->name); meta_crtc_mode_get_name (crtc_mode_two));
} }
+static gboolean +static gboolean
+are_all_modes_equally_sized (MetaOutput *output) +are_all_modes_equally_sized (MetaOutputInfo *output_info)
+{ +{
+ MetaCrtcMode *base = output->modes[0]; + const MetaCrtcModeInfo *base =
+ meta_crtc_mode_get_info (output_info->modes[0]);
+ int i; + int i;
+ +
+ for (i = 1; i < output->n_modes; i++) + for (i = 1; i < output_info->n_modes; i++)
+ { + {
+ MetaCrtcMode *crtc_mode = output->modes[i]; + const MetaCrtcModeInfo *mode_info =
+ meta_crtc_mode_get_info (output_info->modes[i]);
+ +
+ if (base->width != crtc_mode->width || + if (base->width != mode_info->width ||
+ base->height != crtc_mode->height) + base->height != mode_info->height)
+ return FALSE; + return FALSE;
+ } + }
+ +
@ -40,42 +43,65 @@ index f3cc543c4d..44c25c5648 100644
+} +}
+ +
+static void +static void
+maybe_add_fallback_modes (MetaOutput *output, +maybe_add_fallback_modes (const MetaKmsConnectorState *connector_state,
+ MetaGpuKms *gpu_kms) + MetaOutputInfo *output_info,
+ MetaGpuKms *gpu_kms,
+ MetaKmsConnector *kms_connector)
+{ +{
+ MetaOutputKms *output_kms = output->driver_private; + if (!connector_state->has_scaling)
+
+ if (!output_kms->has_scaling)
+ return;
+
+ if (output->n_modes == 0)
+ return; + return;
+ +
+ if (output_kms->connector->connector_type == DRM_MODE_CONNECTOR_eDP && + if (output_info->connector_type == DRM_MODE_CONNECTOR_eDP &&
+ !are_all_modes_equally_sized (output)) + !are_all_modes_equally_sized (output_info))
+ return; + return;
+ +
+ add_common_modes (output, gpu_kms); + meta_topic (META_DEBUG_KMS, "Adding common modes to connector %u on %s",
+ meta_kms_connector_get_id (kms_connector),
+ meta_gpu_kms_get_file_path (gpu_kms));
+ add_common_modes (output_info, gpu_kms);
+} +}
+ +
static gboolean static gboolean
init_output_modes (MetaOutput *output, init_output_modes (MetaOutputInfo *output_info,
MetaGpuKms *gpu_kms, MetaGpuKms *gpu_kms,
@@ -528,13 +565,7 @@ init_output_modes (MetaOutput *output, @@ -252,14 +291,7 @@ init_output_modes (MetaOutputInfo *output_info,
output->preferred_mode = output->modes[i]; output_info->preferred_mode = output_info->modes[i];
} }
- /* FIXME: MSC feature bit? */ - if (connector_state->has_scaling)
- /* Presume that if the output supports scaling, then we have - {
- * a panel fitter capable of adjusting any mode to suit. - meta_topic (META_DEBUG_KMS, "Adding common modes to connector %u on %s",
- */ - meta_kms_connector_get_id (kms_connector),
- if (output_kms->has_scaling) - meta_gpu_kms_get_file_path (gpu_kms));
- add_common_modes (output, gpu_kms); - add_common_modes (output_info, gpu_kms);
- }
- -
+ maybe_add_fallback_modes (output, gpu_kms); + maybe_add_fallback_modes (connector_state, output_info, gpu_kms, kms_connector);
if (!output->modes) if (!output_info->modes)
{ {
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
@@ -322,6 +354,10 @@ meta_output_kms_new (MetaGpuKms *gpu_kms,
output_info->height_mm = connector_state->height_mm;
}
+ drm_connector_type = meta_kms_connector_get_connector_type (kms_connector);
+ output_info->connector_type =
+ meta_kms_connector_type_from_drm (drm_connector_type);
+
if (!init_output_modes (output_info, gpu_kms, kms_connector, error))
return NULL;
@@ -349,10 +385,6 @@ meta_output_kms_new (MetaGpuKms *gpu_kms,
meta_output_info_parse_edid (output_info, connector_state->edid_data);
- drm_connector_type = meta_kms_connector_get_connector_type (kms_connector);
- output_info->connector_type =
- meta_kms_connector_type_from_drm (drm_connector_type);
-
output_info->tile_info = connector_state->tile_info;
output = g_object_new (META_TYPE_OUTPUT_KMS,
-- --
2.37.1 2.37.1

@ -1,108 +0,0 @@
From d107b52939ca0acb1f8dacf1275278edba64eebe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Tue, 1 Oct 2019 11:53:57 +0200
Subject: [PATCH] renderer: Add API to check whether renderer is hardware
accelerated
Also expose an introspected variant via the MetaBackend.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/838
---
src/backends/meta-backend.c | 15 +++++++++++++++
src/backends/meta-renderer.c | 27 +++++++++++++++++++++++++++
src/backends/meta-renderer.h | 2 ++
src/meta/meta-backend.h | 3 +++
4 files changed, 47 insertions(+)
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
index 72cfbdaf3..e61181f9a 100644
--- a/src/backends/meta-backend.c
+++ b/src/backends/meta-backend.c
@@ -985,6 +985,21 @@ meta_backend_get_remote_access_controller (MetaBackend *backend)
#endif
}
+/**
+ * meta_backend_is_rendering_hardware_accelerated:
+ * @backend: A #MetaBackend
+ *
+ * Returns: %TRUE if the rendering is hardware accelerated, otherwise
+ * %FALSE.
+ */
+gboolean
+meta_backend_is_rendering_hardware_accelerated (MetaBackend *backend)
+{
+ MetaRenderer *renderer = meta_backend_get_renderer (backend);
+
+ return meta_renderer_is_hardware_accelerated (renderer);
+}
+
/**
* meta_backend_grab_device: (skip)
*/
diff --git a/src/backends/meta-renderer.c b/src/backends/meta-renderer.c
index 87ba9f9f0..470220fc8 100644
--- a/src/backends/meta-renderer.c
+++ b/src/backends/meta-renderer.c
@@ -166,6 +166,33 @@ meta_renderer_get_view_from_logical_monitor (MetaRenderer *renderer,
return NULL;
}
+gboolean
+meta_renderer_is_hardware_accelerated (MetaRenderer *renderer)
+{
+ MetaRendererPrivate *priv = meta_renderer_get_instance_private (renderer);
+ MetaBackend *backend = meta_get_backend ();
+ ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
+ CoglContext *cogl_context =
+ clutter_backend_get_cogl_context (clutter_backend);
+ CoglGpuInfo *info = &cogl_context->gpu;
+
+ switch (info->architecture)
+ {
+ case COGL_GPU_INFO_ARCHITECTURE_UNKNOWN:
+ case COGL_GPU_INFO_ARCHITECTURE_SANDYBRIDGE:
+ case COGL_GPU_INFO_ARCHITECTURE_SGX:
+ case COGL_GPU_INFO_ARCHITECTURE_MALI:
+ return TRUE;
+ case COGL_GPU_INFO_ARCHITECTURE_LLVMPIPE:
+ case COGL_GPU_INFO_ARCHITECTURE_SOFTPIPE:
+ case COGL_GPU_INFO_ARCHITECTURE_SWRAST:
+ return FALSE;
+ }
+
+ g_assert_not_reached ();
+ return FALSE;
+}
+
static void
meta_renderer_finalize (GObject *object)
{
diff --git a/src/backends/meta-renderer.h b/src/backends/meta-renderer.h
index 478baee91..97bf36860 100644
--- a/src/backends/meta-renderer.h
+++ b/src/backends/meta-renderer.h
@@ -59,4 +59,6 @@ GList * meta_renderer_get_views (MetaRenderer *renderer);
MetaRendererView * meta_renderer_get_view_from_logical_monitor (MetaRenderer *renderer,
MetaLogicalMonitor *logical_monitor);
+gboolean meta_renderer_is_hardware_accelerated (MetaRenderer *renderer);
+
#endif /* META_RENDERER_H */
diff --git a/src/meta/meta-backend.h b/src/meta/meta-backend.h
index aaa6aae97..8edc0bf2c 100644
--- a/src/meta/meta-backend.h
+++ b/src/meta/meta-backend.h
@@ -64,6 +64,9 @@ MetaSettings *meta_backend_get_settings (MetaBackend *backend);
META_EXPORT
MetaRemoteAccessController * meta_backend_get_remote_access_controller (MetaBackend *backend);
+META_EXPORT
+gboolean meta_backend_is_rendering_hardware_accelerated (MetaBackend *backend);
+
META_EXPORT
void meta_clutter_init (void);
--
2.26.2

@ -0,0 +1,63 @@
From fa70ee1cd78e2b161545bc47a1c1083063030f77 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Mon, 11 Oct 2021 10:52:43 +0200
Subject: [PATCH 1/5] renderer/native: Log render mode per device
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2051>
(cherry picked from commit e8249a572d669c4c0a8464d6bce556b2cbaca4ef)
(cherry picked from commit fe0ea79b83256d80f1dee1e4a49c94a5d6fd18a6)
---
src/backends/native/meta-renderer-native.c | 30 ++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index 735c37202..f92f648e5 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -1808,6 +1808,24 @@ meta_renderer_native_create_renderer_gpu_data (MetaRendererNative *renderer_nat
return NULL;
}
+static const char *
+renderer_data_mode_to_string (MetaRendererNativeMode mode)
+{
+ switch (mode)
+ {
+ case META_RENDERER_NATIVE_MODE_GBM:
+ return "gbm";
+ case META_RENDERER_NATIVE_MODE_SURFACELESS:
+ return "surfaceless";
+#ifdef HAVE_EGL_DEVICE
+ case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
+ return "egldevice";
+#endif
+ }
+
+ g_assert_not_reached ();
+}
+
static gboolean
create_renderer_gpu_data (MetaRendererNative *renderer_native,
MetaGpuKms *gpu_kms,
@@ -1822,6 +1840,18 @@ create_renderer_gpu_data (MetaRendererNative *renderer_native,
if (!renderer_gpu_data)
return FALSE;
+ if (gpu_kms)
+ {
+ g_message ("Created %s renderer for '%s'",
+ renderer_data_mode_to_string (renderer_gpu_data->mode),
+ meta_gpu_kms_get_file_path (gpu_kms));
+ }
+ else
+ {
+ g_message ("Created %s renderer without GPU",
+ renderer_data_mode_to_string (renderer_gpu_data->mode));
+ }
+
g_hash_table_insert (renderer_native->gpu_datas,
gpu_kms,
renderer_gpu_data);
--
2.35.1

@ -1,172 +0,0 @@
From 66e2e438b8796351a72bfec2024ee41bbde77780 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Thu, 6 Apr 2023 18:40:41 +0200
Subject: [PATCH] renderer-native: Queue fail safe callbacks when mode set
failed
This allows to recover, e.g. Ctrl-Alt-F# and using any other monitor
that managed to turn on.
---
src/backends/native/meta-crtc-kms.c | 19 ++++++++++
src/backends/native/meta-crtc-kms.h | 5 +++
src/backends/native/meta-gpu-kms.c | 10 +++++
src/backends/native/meta-renderer-native.c | 43 ++++++++++++++++++++++
4 files changed, 77 insertions(+)
diff --git a/src/backends/native/meta-crtc-kms.c b/src/backends/native/meta-crtc-kms.c
index 8374376d5..44f271eb5 100644
--- a/src/backends/native/meta-crtc-kms.c
+++ b/src/backends/native/meta-crtc-kms.c
@@ -52,6 +52,8 @@ typedef struct _MetaCrtcKms
* value: owned GArray* (uint64_t modifier), or NULL
*/
GHashTable *formats_modifiers;
+
+ gboolean is_active;
} MetaCrtcKms;
/**
@@ -540,3 +542,20 @@ meta_create_kms_crtc (MetaGpuKms *gpu_kms,
return crtc;
}
+
+void
+meta_crtc_kms_set_active (MetaCrtc *crtc,
+ gboolean is_active)
+{
+ MetaCrtcKms *crtc_kms = crtc->driver_private;
+
+ crtc_kms->is_active = is_active;
+}
+
+gboolean
+meta_crtc_kms_is_active (MetaCrtc *crtc)
+{
+ MetaCrtcKms *crtc_kms = crtc->driver_private;
+
+ return crtc_kms->is_active;
+}
diff --git a/src/backends/native/meta-crtc-kms.h b/src/backends/native/meta-crtc-kms.h
index 456f4400a..666aebcaf 100644
--- a/src/backends/native/meta-crtc-kms.h
+++ b/src/backends/native/meta-crtc-kms.h
@@ -58,4 +58,9 @@ MetaCrtc * meta_create_kms_crtc (MetaGpuKms *gpu_kms,
drmModeCrtc *drm_crtc,
unsigned int crtc_index);
+void meta_crtc_kms_set_active (MetaCrtc *crtc,
+ gboolean is_active);
+
+gboolean meta_crtc_kms_is_active (MetaCrtc *crtc);
+
#endif /* META_CRTC_KMS_H */
diff --git a/src/backends/native/meta-gpu-kms.c b/src/backends/native/meta-gpu-kms.c
index dc93abb7b..5f7a48730 100644
--- a/src/backends/native/meta-gpu-kms.c
+++ b/src/backends/native/meta-gpu-kms.c
@@ -169,9 +169,12 @@ meta_gpu_kms_apply_crtc_mode (MetaGpuKms *gpu_kms,
else
g_warning ("Failed to disable CRTC");
g_free (connectors);
+ meta_crtc_kms_set_active (crtc, FALSE);
return FALSE;
}
+ meta_crtc_kms_set_active (crtc, !!mode);
+
g_free (connectors);
return TRUE;
@@ -278,6 +281,13 @@ meta_gpu_kms_flip_crtc (MetaGpuKms *gpu_kms,
g_assert (meta_monitor_manager_get_power_save_mode (monitor_manager) ==
META_POWER_SAVE_ON);
+ if (!meta_crtc_kms_is_active (crtc))
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
+ "CRTC is not active");
+ return FALSE;
+ }
+
get_crtc_drm_connectors (gpu, crtc, &connectors, &n_connectors);
g_assert (n_connectors > 0);
g_free (connectors);
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index 62ca4bcbd..76e311508 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -217,6 +217,9 @@ struct _MetaRendererNative
GList *power_save_page_flip_closures;
guint power_save_page_flip_source_id;
+
+ GList *fail_safe_page_flip_closures;
+ guint fail_safe_page_flip_source_id;
};
static void
@@ -2048,6 +2051,34 @@ flip_crtc (MetaLogicalMonitor *logical_monitor,
}
}
+static gboolean
+fail_safe_page_flip_cb (gpointer user_data)
+{
+ MetaRendererNative *renderer_native = user_data;
+
+ g_list_free_full (renderer_native->fail_safe_page_flip_closures,
+ (GDestroyNotify) g_closure_unref);
+ renderer_native->fail_safe_page_flip_closures = NULL;
+ renderer_native->fail_safe_page_flip_source_id = 0;
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+queue_fail_safe_page_flip (MetaRendererNative *renderer_native,
+ GClosure *flip_closure)
+{
+ if (!renderer_native->fail_safe_page_flip_source_id)
+ {
+ renderer_native->fail_safe_page_flip_source_id =
+ g_idle_add (fail_safe_page_flip_cb, renderer_native);
+ }
+
+ renderer_native->fail_safe_page_flip_closures =
+ g_list_prepend (renderer_native->fail_safe_page_flip_closures,
+ g_closure_ref (flip_closure));
+}
+
static void
meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen)
{
@@ -2093,6 +2124,11 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen)
*/
if (!data.did_flip && data.did_mode_set)
meta_onscreen_native_swap_drm_fb (onscreen);
+ else if (!data.did_flip)
+ {
+ meta_onscreen_native_swap_drm_fb (onscreen);
+ queue_fail_safe_page_flip (renderer_native, flip_closure);
+ }
}
else
{
@@ -4549,6 +4585,13 @@ meta_renderer_native_finalize (GObject *object)
g_source_remove (renderer_native->power_save_page_flip_source_id);
}
+ if (renderer_native->fail_safe_page_flip_closures)
+ {
+ g_list_free_full (renderer_native->fail_safe_page_flip_closures,
+ (GDestroyNotify) g_closure_unref);
+ g_source_remove (renderer_native->fail_safe_page_flip_source_id);
+ }
+
g_hash_table_destroy (renderer_native->gpu_datas);
g_clear_object (&renderer_native->gles3);
--
2.39.2

@ -1,40 +0,0 @@
From b32ae04c122f4f76ffad296c15ba00a13800db57 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Tue, 2 Jun 2020 16:33:05 +0000
Subject: [PATCH 1/2] screen-cast-src: Destroy hash dmabuf table after stream
The stream will clean up the buffers, so let it do that before we
destroy them under its feet. Note that it'll only do this after the
following PipeWire commit:
commit fbaa4ddedd84afdffca16f090dcc4b0db8ccfc29
Author: Wim Taymans <wtaymans@redhat.com>
Date: Mon Jun 1 15:36:09 2020 +0200
stream: allow NULL param and 0 buffers in disconnect
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1283
(cherry picked from commit 97175f8fa14171606ecb95d0bf107ef8b2d71b74)
---
src/backends/meta-screen-cast-stream-src.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
index 0500bfec5..ff4af440c 100644
--- a/src/backends/meta-screen-cast-stream-src.c
+++ b/src/backends/meta-screen-cast-stream-src.c
@@ -988,8 +988,8 @@ meta_screen_cast_stream_src_finalize (GObject *object)
if (meta_screen_cast_stream_src_is_enabled (src))
meta_screen_cast_stream_src_disable (src);
- g_clear_pointer (&priv->dmabuf_handles, g_hash_table_destroy);
g_clear_pointer (&priv->pipewire_stream, pw_stream_destroy);
+ g_clear_pointer (&priv->dmabuf_handles, g_hash_table_destroy);
g_clear_pointer (&priv->pipewire_core, pw_core_disconnect);
g_clear_pointer (&priv->pipewire_context, pw_context_destroy);
g_source_destroy (&priv->pipewire_source->base);
--
2.26.2

@ -1,101 +0,0 @@
From 639b7ba7f2729a95593c0b85d4789f76152e6099 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Thu, 18 Jun 2020 21:17:29 +0200
Subject: [PATCH] stage/x11: Check that message is WM_PROTOCOLS before assuming
so
When a touch sequence was rejected, we'd update the event timestamps of
incoming touch events to help with implementing grabs. This was done by
sending a ClientMessage with a counter, and comparing the counter to
decide whether we're seing a replayed event or not.
This had the unforseen consequence that we would potentially end up
destroying all actors including the stage, since, when mutter receives a
ClientMessage event, it would assume that it's a WM_PROTOCOLS event, and
handle it as such. The problem with this approach is that it would
ignore fact that there might be other ClientMessage types sent to it,
for example the touch synchronization one. What could happen is that the
touch count value would match up with the value of the WM_DELETE_WINDOW
atom, clutter would treat this as WM_PROTOCOLS:WM_DELETE_WINDOW, which
it'd translate to clutter_actor_destroy(stage).
Destroying the stage in such a way is not expected, and caused wierd
crashes in different places depending on what was going on.
This commit make sure we only treat WM_PROTOCOLS client messages as
WM_PROTOCOLS client messages effectively avoiding the issue.
This fixes crashes such as:
#0 meta_window_get_buffer_rect (window=0x0, rect=rect@entry=0x7ffd7fc62e40) at core/window.c:4396
#1 0x00007f1e2634837f in get_top_visible_window_actor (compositor=0x297d700, compositor=0x297d700) at compositor/compositor.c:1059
#2 meta_compositor_sync_stack (compositor=0x297d700, stack=<optimized out>, stack@entry=0x26e3140) at compositor/compositor.c:1176
#3 0x00007f1e263757ac in meta_stack_tracker_sync_stack (tracker=0x297dbc0) at core/stack-tracker.c:871
#4 0x00007f1e26375899 in stack_tracker_sync_stack_later (data=<optimized out>) at core/stack-tracker.c:881
#5 0x00007f1e26376914 in run_repaint_laters (laters_list=0x7f1e2663b7d8 <laters+24>) at core/util.c:809
#6 run_all_repaint_laters (data=<optimized out>) at core/util.c:826
#7 0x00007f1e26b18325 in _clutter_run_repaint_functions (flags=flags@entry=CLUTTER_REPAINT_FLAGS_PRE_PAINT) at clutter-main.c:3448
#8 0x00007f1e26b18fc5 in master_clock_update_stages (master_clock=0x32d6a80, stages=0x4e5a740) at clutter-master-clock-default.c:437
#9 clutter_clock_dispatch (source=<optimized out>, callback=<optimized out>, user_data=<optimized out>) at clutter-master-clock-default.c:567
#10 0x00007f1e27e48049 in g_main_dispatch (context=0x225b8d0) at gmain.c:3175
#11 g_main_context_dispatch (context=context@entry=0x225b8d0) at gmain.c:3828
#12 0x00007f1e27e483a8 in g_main_context_iterate (context=0x225b8d0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3901
#13 0x00007f1e27e4867a in g_main_loop_run (loop=0x24e29f0) at gmain.c:4097
#14 0x00007f1e2636a3dc in meta_run () at core/main.c:666
#15 0x000000000040219c in main (argc=1, argv=0x7ffd7fc63238) at ../src/main.c:534
and
#0 0x00007f93943c1f25 in raise () at /usr/lib/libc.so.6
#1 0x00007f93943ab897 in abort () at /usr/lib/libc.so.6
#2 0x00007f9393e1e062 in g_assertion_message (domain=<optimized out>, file=<optimized out>, line=<optimized out>, func=0x7f93933e6860 <__func__.116322> "meta_x11_get_stage_window",
#3 0x00007f9393e4ab1d in g_assertion_message_expr ()
#4 0x00007f939338ecd7 in meta_x11_get_stage_window (stage=<optimized out>) at ../mutter/src/backends/x11/meta-stage-x11.c:923
#5 0x00007f939339e599 in meta_backend_x11_cm_translate_device_event (x11=<optimized out>, device_event=0x55bc8bcfd6b0) at ../mutter/src/backends/x11/cm/meta-backend-x11-cm.c:381
#6 0x00007f939339f2e2 in meta_backend_x11_translate_device_event (device_event=0x55bc8bcfd6b0, x11=0x55bc89dd5220) at ../mutter/src/backends/x11/meta-backend-x11.c:179
#7 0x00007f939339f2e2 in translate_device_event (device_event=0x55bc8bcfd6b0, x11=0x55bc89dd5220) at ../mutter/src/backends/x11/meta-backend-x11.c:208
#8 0x00007f939339f2e2 in maybe_spoof_event_as_stage_event (input_event=0x55bc8bcfd6b0, x11=0x55bc89dd5220) at ../mutter/src/backends/x11/meta-backend-x11.c:284
#9 0x00007f939339f2e2 in handle_input_event (event=0x7fff62d60490, x11=0x55bc89dd5220) at ../mutter/src/backends/x11/meta-backend-x11.c:309
#10 0x00007f939339f2e2 in handle_host_xevent (event=0x7fff62d60490, backend=0x55bc89dd5220) at ../mutter/src/backends/x11/meta-backend-x11.c:413
#11 0x00007f939339f2e2 in x_event_source_dispatch (source=<optimized out>, callback=<optimized out>, user_data=<optimized out>) at ../mutter/src/backends/x11/meta-backend-x11.c:467
#12 0x00007f9393e6c39e in g_main_dispatch (context=0x55bc89dd03e0) at ../glib/glib/gmain.c:3179
#13 0x00007f9393e6c39e in g_main_context_dispatch (context=context@entry=0x55bc89dd03e0) at ../glib/glib/gmain.c:3844
#14 0x00007f9393e6e1b1 in g_main_context_iterate (context=0x55bc89dd03e0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/glib/gmain.c:3917
#15 0x00007f9393e6f0c3 in g_main_loop_run (loop=0x55bc8a042640) at ../glib/glib/gmain.c:4111
#16 0x00007f9393369a0c in meta_run () at ../mutter/src/core/main.c:676
#17 0x000055bc880f2426 in main (argc=<optimized out>, argv=<optimized out>) at ../gnome-shell/src/main.c:552
Related: https://gitlab.gnome.org/GNOME/mutter/-/issues/338
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/951
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1317
---
clutter/clutter/x11/clutter-stage-x11.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/clutter/clutter/x11/clutter-stage-x11.c b/clutter/clutter/x11/clutter-stage-x11.c
index d043bcf31d..123078fc22 100644
--- a/clutter/clutter/x11/clutter-stage-x11.c
+++ b/clutter/clutter/x11/clutter-stage-x11.c
@@ -1306,11 +1306,14 @@ clutter_stage_x11_translate_event (ClutterEventTranslator *translator,
_clutter_actor_get_debug_name (CLUTTER_ACTOR (stage)),
stage,
(unsigned int) stage_xwindow);
- if (handle_wm_protocols_event (backend_x11, stage_x11, xevent))
+ if (xevent->xclient.message_type == backend_x11->atom_WM_PROTOCOLS)
{
- event->any.type = CLUTTER_DELETE;
- event->any.stage = stage;
- res = CLUTTER_TRANSLATE_QUEUE;
+ if (handle_wm_protocols_event (backend_x11, stage_x11, xevent))
+ {
+ event->any.type = CLUTTER_DELETE;
+ event->any.stage = stage;
+ res = CLUTTER_TRANSLATE_QUEUE;
+ }
}
break;
--
2.26.2

@ -1,4 +1,4 @@
From 9dfe362f41b8811450cb563c39899fafe8ec2b63 Mon Sep 17 00:00:00 2001 From 6e2ef652cd58136aa668d0c1bd843fe83f11a0ab Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com> From: Olivier Fourdan <ofourdan@redhat.com>
Date: Fri, 26 Oct 2018 08:49:39 +0200 Date: Fri, 26 Oct 2018 08:49:39 +0200
Subject: [PATCH] wayland: Allow Xwayland grabs on selected apps Subject: [PATCH] wayland: Allow Xwayland grabs on selected apps
@ -9,19 +9,19 @@ Allow Xwayland grabs on a selected set of X11 applications.
1 file changed, 2 insertions(+), 2 deletions(-) 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/data/org.gnome.mutter.wayland.gschema.xml.in b/data/org.gnome.mutter.wayland.gschema.xml.in diff --git a/data/org.gnome.mutter.wayland.gschema.xml.in b/data/org.gnome.mutter.wayland.gschema.xml.in
index 48241296e..7a6ab9288 100644 index 8a1878e105..5527a46bc6 100644
--- a/data/org.gnome.mutter.wayland.gschema.xml.in --- a/data/org.gnome.mutter.wayland.gschema.xml.in
+++ b/data/org.gnome.mutter.wayland.gschema.xml.in +++ b/data/org.gnome.mutter.wayland.gschema.xml.in
@@ -60,7 +60,7 @@ @@ -66,7 +66,7 @@
gettext-domain="@GETTEXT_DOMAIN@"> gettext-domain="@GETTEXT_DOMAIN@">
<key name="xwayland-allow-grabs" type="b"> <key name="xwayland-allow-grabs" type="b">
- <default>false</default> - <default>false</default>
+ <default>true</default> + <default>true</default>
<summary>Allow grabs with Xwayland</summary> <summary>Allow X11 grabs to lock keyboard focus with Xwayland</summary>
<description> <description>
Allow keyboard grabs issued by X11 applications running in Xwayland Allow all keyboard events to be routed to X11 “override redirect”
@@ -73,7 +73,7 @@ @@ -86,7 +86,7 @@
</key> </key>
<key name="xwayland-grab-access-rules" type="as"> <key name="xwayland-grab-access-rules" type="as">
@ -31,5 +31,5 @@ index 48241296e..7a6ab9288 100644
<description> <description>
List the resource names or resource class of X11 windows either List the resource names or resource class of X11 windows either
-- --
2.21.0 2.31.1

@ -0,0 +1,192 @@
From 5e4a1290ce75ed94e3f0f457d35a225f2ef3878c Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Tue, 28 Nov 2017 10:54:08 +0100
Subject: [PATCH] wayland: Avoid a race in wl_seat capabilities
The way wl_seat capabilities work, by notifying clients of capabilities
changes, and clients consequently requesting the relevant interface
objects (pointer, keyboard, touch) is inherently racy.
On quick VT changes for example, capabilities on the seat will be added
and removed, and by the time the client receives the capability change
notification and requests the relevant keyboard, pointer or touch,
another VT switch might have occurred and the wl_pointer, wl_keyboard or
wl_touch already destroyed, leading to a protocol error which kills the
client.
To avoid this, create the objects when requested regardless of the
capabilities.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1797
Related: https://bugzilla.gnome.org/show_bug.cgi?id=790932
---
src/wayland/meta-wayland-pointer.c | 45 ++++++++++++++++++++++++------
src/wayland/meta-wayland-seat.c | 9 ++----
src/wayland/meta-wayland-touch.c | 8 ------
3 files changed, 40 insertions(+), 22 deletions(-)
diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c
index 3132abfd2..abd779ad7 100644
--- a/src/wayland/meta-wayland-pointer.c
+++ b/src/wayland/meta-wayland-pointer.c
@@ -109,7 +109,7 @@ meta_wayland_pointer_client_new (void)
}
static void
-meta_wayland_pointer_client_free (MetaWaylandPointerClient *pointer_client)
+meta_wayland_pointer_make_resources_inert (MetaWaylandPointerClient *pointer_client)
{
struct wl_resource *resource, *next;
@@ -141,10 +141,25 @@ meta_wayland_pointer_client_free (MetaWaylandPointerClient *pointer_client)
wl_list_init (wl_resource_get_link (resource));
wl_resource_set_user_data (resource, NULL);
}
+}
+static void
+meta_wayland_pointer_client_free (MetaWaylandPointerClient *pointer_client)
+{
+ meta_wayland_pointer_make_resources_inert (pointer_client);
g_free (pointer_client);
}
+static void
+make_resources_inert_foreach (gpointer key,
+ gpointer value,
+ gpointer data)
+{
+ MetaWaylandPointerClient *pointer_client = value;
+
+ meta_wayland_pointer_make_resources_inert (pointer_client);
+}
+
static gboolean
meta_wayland_pointer_client_is_empty (MetaWaylandPointerClient *pointer_client)
{
@@ -158,8 +173,6 @@ MetaWaylandPointerClient *
meta_wayland_pointer_get_pointer_client (MetaWaylandPointer *pointer,
struct wl_client *client)
{
- if (!pointer->pointer_clients)
- return NULL;
return g_hash_table_lookup (pointer->pointer_clients, client);
}
@@ -475,10 +488,6 @@ meta_wayland_pointer_enable (MetaWaylandPointer *pointer)
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
ClutterSeat *clutter_seat;
- pointer->pointer_clients =
- g_hash_table_new_full (NULL, NULL, NULL,
- (GDestroyNotify) meta_wayland_pointer_client_free);
-
pointer->cursor_surface = NULL;
clutter_seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
@@ -508,6 +517,10 @@ meta_wayland_pointer_disable (MetaWaylandPointer *pointer)
ClutterBackend *clutter_backend = clutter_get_default_backend ();
ClutterSeat *clutter_seat = clutter_backend_get_default_seat (clutter_backend);
+ g_hash_table_foreach (pointer->pointer_clients,
+ make_resources_inert_foreach,
+ NULL);
+
g_signal_handlers_disconnect_by_func (cursor_tracker,
(gpointer) meta_wayland_pointer_on_cursor_changed,
pointer);
@@ -531,7 +544,6 @@ meta_wayland_pointer_disable (MetaWaylandPointer *pointer)
meta_wayland_pointer_set_focus (pointer, NULL);
meta_wayland_pointer_set_current (pointer, NULL);
- g_clear_pointer (&pointer->pointer_clients, g_hash_table_unref);
pointer->cursor_surface = NULL;
}
@@ -1356,11 +1368,28 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer)
pointer->default_grab.interface = &default_pointer_grab_interface;
pointer->default_grab.pointer = pointer;
pointer->grab = &pointer->default_grab;
+ pointer->pointer_clients =
+ g_hash_table_new_full (NULL, NULL, NULL,
+ (GDestroyNotify) meta_wayland_pointer_client_free);
+}
+
+static void
+meta_wayland_pointer_finalize (GObject *object)
+{
+ MetaWaylandPointer *pointer = META_WAYLAND_POINTER (object);
+
+ g_clear_pointer (&pointer->pointer_clients, g_hash_table_unref);
+
+ G_OBJECT_CLASS (meta_wayland_pointer_parent_class)->finalize (object);
}
static void
meta_wayland_pointer_class_init (MetaWaylandPointerClass *klass)
{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = meta_wayland_pointer_finalize;
+
signals[FOCUS_SURFACE_CHANGED] = g_signal_new ("focus-surface-changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c
index c6390dde7..efce6d6d6 100644
--- a/src/wayland/meta-wayland-seat.c
+++ b/src/wayland/meta-wayland-seat.c
@@ -46,8 +46,7 @@ seat_get_pointer (struct wl_client *client,
MetaWaylandSeat *seat = wl_resource_get_user_data (resource);
MetaWaylandPointer *pointer = seat->pointer;
- if (meta_wayland_seat_has_pointer (seat))
- meta_wayland_pointer_create_new_resource (pointer, client, resource, id);
+ meta_wayland_pointer_create_new_resource (pointer, client, resource, id);
}
static void
@@ -58,8 +57,7 @@ seat_get_keyboard (struct wl_client *client,
MetaWaylandSeat *seat = wl_resource_get_user_data (resource);
MetaWaylandKeyboard *keyboard = seat->keyboard;
- if (meta_wayland_seat_has_keyboard (seat))
- meta_wayland_keyboard_create_new_resource (keyboard, client, resource, id);
+ meta_wayland_keyboard_create_new_resource (keyboard, client, resource, id);
}
static void
@@ -70,8 +68,7 @@ seat_get_touch (struct wl_client *client,
MetaWaylandSeat *seat = wl_resource_get_user_data (resource);
MetaWaylandTouch *touch = seat->touch;
- if (meta_wayland_seat_has_touch (seat))
- meta_wayland_touch_create_new_resource (touch, client, resource, id);
+ meta_wayland_touch_create_new_resource (touch, client, resource, id);
}
static void
diff --git a/src/wayland/meta-wayland-touch.c b/src/wayland/meta-wayland-touch.c
index 002ff16f7..15f0312eb 100644
--- a/src/wayland/meta-wayland-touch.c
+++ b/src/wayland/meta-wayland-touch.c
@@ -521,16 +521,8 @@ meta_wayland_touch_create_new_resource (MetaWaylandTouch *touch,
struct wl_resource *seat_resource,
uint32_t id)
{
- MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
struct wl_resource *cr;
- if (!meta_wayland_seat_has_touch (seat))
- {
- wl_resource_post_error (seat_resource, WL_DISPLAY_ERROR_INVALID_METHOD,
- "Cannot retrieve touch interface without touch capability");
- return;
- }
-
cr = wl_resource_create (client, &wl_touch_interface, wl_resource_get_version (seat_resource), id);
wl_resource_set_implementation (cr, &touch_interface, touch, unbind_resource);
wl_list_insert (&touch->resource_list, wl_resource_get_link (cr));
--
2.31.1

@ -1,109 +0,0 @@
From f2b3dd318f1165849b45a86251724939b100ef7d Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Mon, 28 Oct 2019 18:07:31 +0100
Subject: [PATCH] wayland: Check stylus serials on
meta_wayland_seat_can_popup()
This allows xdg_popup.grab() to work with styli. Without this check
we would bail out and emit xdg_popup.popup_done, leaving stylus users
unable to interact with popup menus, comboboxes, etc...
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/886
---
src/wayland/meta-wayland-seat.c | 10 +++++++++-
src/wayland/meta-wayland-tablet-seat.c | 17 +++++++++++++++++
src/wayland/meta-wayland-tablet-seat.h | 2 ++
src/wayland/meta-wayland-tablet-tool.c | 7 +++++++
src/wayland/meta-wayland-tablet-tool.h | 2 ++
5 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c
index 91fe376ff..cf41d6eb8 100644
--- a/src/wayland/meta-wayland-seat.c
+++ b/src/wayland/meta-wayland-seat.c
@@ -504,9 +504,17 @@ gboolean
meta_wayland_seat_can_popup (MetaWaylandSeat *seat,
uint32_t serial)
{
+ MetaWaylandCompositor *compositor;
+ MetaWaylandTabletSeat *tablet_seat;
+
+ compositor = meta_wayland_compositor_get_default ();
+ tablet_seat =
+ meta_wayland_tablet_manager_ensure_seat (compositor->tablet_manager, seat);
+
return (meta_wayland_pointer_can_popup (seat->pointer, serial) ||
meta_wayland_keyboard_can_popup (seat->keyboard, serial) ||
- meta_wayland_touch_can_popup (seat->touch, serial));
+ meta_wayland_touch_can_popup (seat->touch, serial) ||
+ meta_wayland_tablet_seat_can_popup (tablet_seat, serial));
}
gboolean
diff --git a/src/wayland/meta-wayland-tablet-seat.c b/src/wayland/meta-wayland-tablet-seat.c
index b4bc4aa58..b1964714a 100644
--- a/src/wayland/meta-wayland-tablet-seat.c
+++ b/src/wayland/meta-wayland-tablet-seat.c
@@ -552,3 +552,20 @@ meta_wayland_tablet_seat_set_pad_focus (MetaWaylandTabletSeat *tablet_seat,
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &pad))
meta_wayland_tablet_pad_set_focus (pad, surface);
}
+
+gboolean
+meta_wayland_tablet_seat_can_popup (MetaWaylandTabletSeat *tablet_seat,
+ uint32_t serial)
+{
+ MetaWaylandTabletTool *tool;
+ GHashTableIter iter;
+
+ g_hash_table_iter_init (&iter, tablet_seat->tools);
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &tool))
+ {
+ if (meta_wayland_tablet_tool_can_popup (tool, serial))
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/src/wayland/meta-wayland-tablet-seat.h b/src/wayland/meta-wayland-tablet-seat.h
index c083dec5f..e3be5f264 100644
--- a/src/wayland/meta-wayland-tablet-seat.h
+++ b/src/wayland/meta-wayland-tablet-seat.h
@@ -75,5 +75,7 @@ MetaWaylandTablet *meta_wayland_tablet_seat_lookup_paired_tablet (MetaWaylan
MetaWaylandTabletPad *pad);
GList *meta_wayland_tablet_seat_lookup_paired_pads (MetaWaylandTabletSeat *tablet_seat,
MetaWaylandTablet *tablet);
+gboolean meta_wayland_tablet_seat_can_popup (MetaWaylandTabletSeat *tablet_seat,
+ uint32_t serial);
#endif /* META_WAYLAND_TABLET_SEAT_H */
diff --git a/src/wayland/meta-wayland-tablet-tool.c b/src/wayland/meta-wayland-tablet-tool.c
index c02831d73..065c834bb 100644
--- a/src/wayland/meta-wayland-tablet-tool.c
+++ b/src/wayland/meta-wayland-tablet-tool.c
@@ -1018,3 +1018,10 @@ meta_wayland_tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool,
return ((tool->down_serial == serial || tool->button_serial == serial) &&
tablet_tool_can_grab_surface (tool, surface));
}
+
+gboolean
+meta_wayland_tablet_tool_can_popup (MetaWaylandTabletTool *tool,
+ uint32_t serial)
+{
+ return tool->down_serial == serial || tool->button_serial == serial;
+}
diff --git a/src/wayland/meta-wayland-tablet-tool.h b/src/wayland/meta-wayland-tablet-tool.h
index 71bc86643..315e26bde 100644
--- a/src/wayland/meta-wayland-tablet-tool.h
+++ b/src/wayland/meta-wayland-tablet-tool.h
@@ -85,5 +85,7 @@ void meta_wayland_tablet_tool_set_cursor_position (MetaWaylandTabletTool *t
gboolean meta_wayland_tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool,
MetaWaylandSurface *surface,
uint32_t serial);
+gboolean meta_wayland_tablet_tool_can_popup (MetaWaylandTabletTool *tool,
+ uint32_t serial);
#endif /* META_WAYLAND_TABLET_TOOL_H */
--
2.23.0

@ -1,150 +0,0 @@
From 9269b09028ae51c7bb74e9cc9aefafd8eaa882d6 Mon Sep 17 00:00:00 2001
From: Robert Mader <robert.mader@posteo.de>
Date: Tue, 16 Apr 2019 23:35:28 +0200
Subject: [PATCH 1/2] wayland: Move check for present window out of the
actor-surface class
All child classes of `MetaWaylandShellSurface` as well as
`MetaWaylandSurfaceRoleXWayland` should only sync their actor if
their toplevel surface has a window. Currently this check is done
in the actor-surface class, but not all surface classes have a
toplevel window, e.g. dnd-surfaces.
Move the check to the right places.
For subsurfaces this assumes that the subsurface is not the child of
a window-less surface (like, as stated above, e.g. a dnd-surface).
If we want to support subsurfaces of window-less surfaces in the future
we have to extend the check here.
But as this is not a regression, ignore this case for now.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/537
(cherry picked from commit 7e2a0ede16bed5671fe55d3d81ccc9f82eebd94b)
---
src/wayland/meta-wayland-actor-surface.c | 7 -------
src/wayland/meta-wayland-shell-surface.c | 20 ++++++++++++++++++++
src/wayland/meta-wayland-subsurface.c | 5 ++++-
src/wayland/meta-xwayland.c | 18 ++++++++++++++++++
4 files changed, 42 insertions(+), 8 deletions(-)
diff --git a/src/wayland/meta-wayland-actor-surface.c b/src/wayland/meta-wayland-actor-surface.c
index 037dd901ab..e2143e51f1 100644
--- a/src/wayland/meta-wayland-actor-surface.c
+++ b/src/wayland/meta-wayland-actor-surface.c
@@ -295,9 +295,6 @@ meta_wayland_actor_surface_commit (MetaWaylandSurfaceRole *surface_role,
META_WAYLAND_ACTOR_SURFACE (surface_role);
MetaWaylandActorSurfacePrivate *priv =
meta_wayland_actor_surface_get_instance_private (actor_surface);
- MetaWaylandSurface *surface =
- meta_wayland_surface_role_get_surface (surface_role);
- MetaWaylandSurface *toplevel_surface;
if (!wl_list_empty (&pending->frame_callback_list) &&
priv->actor &&
@@ -311,10 +308,6 @@ meta_wayland_actor_surface_commit (MetaWaylandSurfaceRole *surface_role,
meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending);
- toplevel_surface = meta_wayland_surface_get_toplevel (surface);
- if (!toplevel_surface || !toplevel_surface->window)
- return;
-
meta_wayland_actor_surface_sync_actor_state (actor_surface);
}
diff --git a/src/wayland/meta-wayland-shell-surface.c b/src/wayland/meta-wayland-shell-surface.c
index 04f2aaeea8..f8354ab7c5 100644
--- a/src/wayland/meta-wayland-shell-surface.c
+++ b/src/wayland/meta-wayland-shell-surface.c
@@ -175,6 +175,22 @@ meta_wayland_shell_surface_surface_commit (MetaWaylandSurfaceRole *surface_role
window->buffer_rect.height = cogl_texture_get_height (texture) * scale;
}
+static void
+meta_wayland_shell_surface_sync_actor_state (MetaWaylandActorSurface *actor_surface)
+{
+ MetaWaylandSurfaceRole *surface_role =
+ META_WAYLAND_SURFACE_ROLE (actor_surface);
+ MetaWaylandSurface *surface =
+ meta_wayland_surface_role_get_surface (surface_role);
+ MetaWaylandActorSurfaceClass *actor_surface_class =
+ META_WAYLAND_ACTOR_SURFACE_CLASS (meta_wayland_shell_surface_parent_class);
+ MetaWaylandSurface *toplevel_surface;
+
+ toplevel_surface = meta_wayland_surface_get_toplevel (surface);
+ if (toplevel_surface && toplevel_surface->window)
+ actor_surface_class->sync_actor_state (actor_surface);
+}
+
static void
meta_wayland_shell_surface_init (MetaWaylandShellSurface *role)
{
@@ -185,6 +201,10 @@ meta_wayland_shell_surface_class_init (MetaWaylandShellSurfaceClass *klass)
{
MetaWaylandSurfaceRoleClass *surface_role_class =
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
+ MetaWaylandActorSurfaceClass *actor_surface_class =
+ META_WAYLAND_ACTOR_SURFACE_CLASS (klass);
surface_role_class->commit = meta_wayland_shell_surface_surface_commit;
+ actor_surface_class->sync_actor_state =
+ meta_wayland_shell_surface_sync_actor_state;
}
diff --git a/src/wayland/meta-wayland-subsurface.c b/src/wayland/meta-wayland-subsurface.c
index c7059b99a2..9a7ff3ec12 100644
--- a/src/wayland/meta-wayland-subsurface.c
+++ b/src/wayland/meta-wayland-subsurface.c
@@ -199,8 +199,11 @@ meta_wayland_subsurface_sync_actor_state (MetaWaylandActorSurface *actor_surface
meta_wayland_surface_role_get_surface (surface_role);
MetaWaylandActorSurfaceClass *actor_surface_class =
META_WAYLAND_ACTOR_SURFACE_CLASS (meta_wayland_subsurface_parent_class);
+ MetaWaylandSurface *toplevel_surface;
- actor_surface_class->sync_actor_state (actor_surface);
+ toplevel_surface = meta_wayland_surface_get_toplevel (surface);
+ if (toplevel_surface && toplevel_surface->window)
+ actor_surface_class->sync_actor_state (actor_surface);
sync_actor_subsurface_state (surface);
}
diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c
index 6e4b9a8ffd..b71c638d93 100644
--- a/src/wayland/meta-xwayland.c
+++ b/src/wayland/meta-xwayland.c
@@ -794,6 +794,20 @@ xwayland_surface_get_toplevel (MetaWaylandSurfaceRole *surface_role)
return meta_wayland_surface_role_get_surface (surface_role);
}
+static void
+xwayland_surface_sync_actor_state (MetaWaylandActorSurface *actor_surface)
+{
+ MetaWaylandSurfaceRole *surface_role =
+ META_WAYLAND_SURFACE_ROLE (actor_surface);
+ MetaWaylandSurface *surface =
+ meta_wayland_surface_role_get_surface (surface_role);
+ MetaWaylandActorSurfaceClass *actor_surface_class =
+ META_WAYLAND_ACTOR_SURFACE_CLASS (meta_wayland_surface_role_xwayland_parent_class);
+
+ if (surface->window)
+ actor_surface_class->sync_actor_state (actor_surface);
+}
+
static void
meta_wayland_surface_role_xwayland_init (MetaWaylandSurfaceRoleXWayland *role)
{
@@ -804,9 +818,13 @@ meta_wayland_surface_role_xwayland_class_init (MetaWaylandSurfaceRoleXWaylandCla
{
MetaWaylandSurfaceRoleClass *surface_role_class =
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
+ MetaWaylandActorSurfaceClass *actor_surface_class =
+ META_WAYLAND_ACTOR_SURFACE_CLASS (klass);
surface_role_class->get_toplevel = xwayland_surface_get_toplevel;
+ actor_surface_class->sync_actor_state = xwayland_surface_sync_actor_state;
+
xwayland_surface_signals[XWAYLAND_SURFACE_WINDOW_ASSOCIATED] =
g_signal_new ("window-associated",
G_TYPE_FROM_CLASS (klass),
--
2.31.1

@ -0,0 +1,48 @@
From 0fe26e5b6d1e6f03a99623edf6a6f4c6caa2e142 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@redhat.com>
Date: Tue, 15 Oct 2024 14:56:33 +0200
Subject: [PATCH 1/2] wayland/wl-shell: Make sure created window has a proper
size
The wl_shell_window construction is a bit messy, and was not properly
resizing when a window was created after a buffer was attached. This,
when the window was the dummy window in wl-paste, caused a SIGFPE as the
window was incorrectly assumed to be 0x0, i.e. size being 0.
---
src/wayland/meta-wayland-wl-shell.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/wayland/meta-wayland-wl-shell.c b/src/wayland/meta-wayland-wl-shell.c
index 964c185b23..51d88cea2b 100644
--- a/src/wayland/meta-wayland-wl-shell.c
+++ b/src/wayland/meta-wayland-wl-shell.c
@@ -481,7 +481,7 @@ sync_wl_shell_parent_relationship (MetaWaylandSurface *surface,
}
}
-static void
+static MetaWindow *
create_wl_shell_surface_window (MetaWaylandSurface *surface)
{
MetaWaylandWlShellSurface *wl_shell_surface =
@@ -513,6 +513,8 @@ create_wl_shell_surface_window (MetaWaylandSurface *surface)
if (meta_wayland_surface_get_window (child))
sync_wl_shell_parent_relationship (child, surface);
}
+
+ return window;
}
static void
@@ -597,7 +599,7 @@ wl_shell_surface_role_apply_state (MetaWaylandSurfaceRole *surface_role,
* convenient for us. */
if (surface->buffer_ref->buffer && !window)
{
- create_wl_shell_surface_window (surface);
+ window = create_wl_shell_surface_window (surface);
}
else if (!surface->buffer_ref->buffer && window)
{
--
2.44.0.501.g19981daefd.dirty

@ -0,0 +1,101 @@
From f1da6553e13e3c9a9ed91370dcf435fa4a19fb2b Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 6 Jun 2024 13:01:41 -0400
Subject: [PATCH 1/6] window: Don't switch workspaces if users from forged
activation messages
---
src/core/window.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/core/window.c b/src/core/window.c
index 7d86adece..e787dbce0 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -3687,74 +3687,81 @@ meta_window_unshade (MetaWindow *window,
"Focusing window %s after unshading it",
window->desc);
meta_window_focus (window, timestamp);
set_net_wm_state (window);
}
}
static gboolean
unminimize_func (MetaWindow *window,
void *data)
{
meta_window_unminimize (window);
return TRUE;
}
static void
unminimize_window_and_all_transient_parents (MetaWindow *window)
{
meta_window_unminimize (window);
meta_window_foreach_ancestor (window, unminimize_func, NULL);
}
void
meta_window_activate_full (MetaWindow *window,
guint32 timestamp,
MetaClientType source_indication,
MetaWorkspace *workspace)
{
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
- gboolean allow_workspace_switch;
+ gboolean allow_workspace_switch = FALSE;
if (window->unmanaging)
{
g_warning ("Trying to activate unmanaged window '%s'", window->desc);
return;
}
meta_topic (META_DEBUG_FOCUS,
"_NET_ACTIVE_WINDOW message sent for %s at time %u "
"by client type %u.",
window->desc, timestamp, source_indication);
- allow_workspace_switch = (timestamp != 0);
+ if (window->display->last_user_time == timestamp)
+ {
+ /* Only allow workspace switches if this activation message uses the same
+ * timestamp as the last user interaction
+ */
+ allow_workspace_switch = TRUE;
+ }
+
if (timestamp != 0 &&
XSERVER_TIME_IS_BEFORE (timestamp, window->display->last_user_time))
{
meta_topic (META_DEBUG_FOCUS,
"last_user_time (%u) is more recent; ignoring "
" _NET_ACTIVE_WINDOW message.",
window->display->last_user_time);
meta_window_set_demands_attention(window);
return;
}
if (timestamp == 0)
timestamp = meta_display_get_current_time_roundtrip (window->display);
meta_window_set_user_time (window, timestamp);
/* disable show desktop mode unless we're a desktop component */
maybe_leave_show_desktop_mode (window);
/* Get window on current or given workspace */
if (workspace == NULL)
workspace = workspace_manager->active_workspace;
/* For non-transient windows, we just set up a pulsing indicator,
rather than move windows or workspaces.
See http://bugzilla.gnome.org/show_bug.cgi?id=482354 */
if (window->transient_for == NULL &&
!allow_workspace_switch &&
!meta_window_located_on_workspace (window, workspace))
{
--
2.44.0

@ -1,35 +0,0 @@
From 24ddf60768412fd3f5f7b432449b9ed2ea0d18b3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Tue, 18 Feb 2020 23:01:28 +0100
Subject: [PATCH] window-actor: Don't show actor until meta_window_actor_show()
By default clutter will show an actor as it is added to a parent. This
means that after we create the window actor, when it's added to the
window group, we implicitly show it. What we really want is to not show
it until the window is supposed to be shown, which happens when
meta_window_actor_show() is called, as showing prior to that, could
cause issues.
Avoid the implicit show by setting the "show-on-set-parent" property on
the window actor to `FALSE` on window actor construction.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1066
---
src/compositor/compositor.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index a6ae55abb9..ce2c1b8a3b 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -810,6 +810,7 @@ meta_compositor_add_window (MetaCompositor *compositor,
window_actor = g_object_new (window_actor_type,
"meta-window", window,
+ "show-on-set-parent", FALSE,
NULL);
if (window->layer == META_LAYER_OVERRIDE_REDIRECT)
--
2.26.2

@ -1,4 +1,4 @@
From 6bca5f001338d4647e4e21d549c8cdea4bcad669 Mon Sep 17 00:00:00 2001 From 9efcc35102b4c41265e93461b35a1193b3d5822d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org> From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Fri, 12 May 2017 13:40:31 +0200 Date: Fri, 12 May 2017 13:40:31 +0200
Subject: [PATCH] window-actor: Special-case shaped Java windows Subject: [PATCH] window-actor: Special-case shaped Java windows
@ -8,28 +8,28 @@ They got lucky until commit b975676c changed the fallback case,
but now their compliance tests are broken. Make them happy again but now their compliance tests are broken. Make them happy again
by special-casing shaped Java windows. by special-casing shaped Java windows.
--- ---
src/compositor/meta-window-actor.c | 8 ++++++++ src/compositor/meta-window-actor-x11.c | 8 ++++++++
1 file changed, 8 insertions(+) 1 file changed, 8 insertions(+)
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c diff --git a/src/compositor/meta-window-actor-x11.c b/src/compositor/meta-window-actor-x11.c
index f850cb222..1c8dc8fe5 100644 index b7032e0ba..b05d5e158 100644
--- a/src/compositor/meta-window-actor.c --- a/src/compositor/meta-window-actor-x11.c
+++ b/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor-x11.c
@@ -798,6 +798,14 @@ meta_window_actor_has_shadow (MetaWindowActor *self) @@ -528,6 +528,14 @@ has_shadow (MetaWindowActorX11 *actor_x11)
if (priv->window->has_custom_frame_extents) */
if (window->has_custom_frame_extents)
return FALSE; return FALSE;
+
+ /* + /*
+ * OpenJDK wrongly assumes that shaping a window implies no compositor + * OpenJDK wrongly assumes that shaping a window implies no compositor
+ * shadows; make its compliance tests happy to give it what it wants ... + * shadows; make its compliance tests happy to give it what it wants ...
+ */ + */
+ if (g_strcmp0 (priv->window->res_name, "sun-awt-X11-XWindowPeer") == 0 && + if (g_strcmp0 (window->res_name, "sun-awt-X11-XWindowPeer") == 0 &&
+ priv->window->shape_region != NULL) + window->shape_region != NULL)
+ return FALSE; + return FALSE;
+
/* /*
* Generate shadows for all other windows. * Generate shadows for all other windows.
*/
-- --
2.21.0 2.23.0

@ -1,33 +0,0 @@
From d33a244603d1dd63e2e25255af98f489c65645f6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Mon, 29 Aug 2022 16:01:48 +0200
Subject: [PATCH] workspace: Downgrade assert to warning when adding window
An extension can by accident cause us to end up in a state where we try
to add the same window to a workspace twice. When this happens we
shouldn't crash, but instead complain loudly.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/992
Related: https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/157
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1692>
---
src/core/workspace.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/core/workspace.c b/src/core/workspace.c
index 58fcfa78c5..ed16a83098 100644
--- a/src/core/workspace.c
+++ b/src/core/workspace.c
@@ -370,7 +370,8 @@ void
meta_workspace_add_window (MetaWorkspace *workspace,
MetaWindow *window)
{
- g_assert (g_list_find (workspace->mru_list, window) == NULL);
+ g_return_if_fail (g_list_find (workspace->mru_list, window) == NULL);
+
workspace->mru_list = g_list_prepend (workspace->mru_list, window);
workspace->windows = g_list_prepend (workspace->windows, window);
--
2.37.1

@ -1,83 +0,0 @@
From eca25ab6a12770a2a767458d9b0129d4fde3995c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Tue, 13 Nov 2018 08:31:52 +0100
Subject: [PATCH 1/2] workspace: Focus only ancestors that are focusable
When destroying a window that has a parent, we initially try to focus one of
its ancestors. However if no ancestor can be focused, then we should instead
focus the default focus window instead of trying to request focus for a window
that can't get focus anyways.
Fixes https://gitlab.gnome.org/GNOME/mutter/issues/308
(cherry picked from commit eccc791f3b3451216f957e67fec47a73b65ed2b2)
---
src/core/workspace.c | 37 +++++++++++++++++++++++++++----------
1 file changed, 27 insertions(+), 10 deletions(-)
diff --git a/src/core/workspace.c b/src/core/workspace.c
index f2b2c2c48..58fcfa78c 100644
--- a/src/core/workspace.c
+++ b/src/core/workspace.c
@@ -85,6 +85,12 @@ typedef struct _MetaWorkspaceLogicalMonitorData
MetaRectangle logical_monitor_work_area;
} MetaWorkspaceLogicalMonitorData;
+typedef struct _MetaWorkspaceFocusableAncestorData
+{
+ MetaWorkspace *workspace;
+ MetaWindow *out_window;
+} MetaWorkspaceFocusableAncestorData;
+
static MetaWorkspaceLogicalMonitorData *
meta_workspace_get_logical_monitor_data (MetaWorkspace *workspace,
MetaLogicalMonitor *logical_monitor)
@@ -1322,13 +1328,20 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace,
}
static gboolean
-record_ancestor (MetaWindow *window,
- void *data)
+find_focusable_ancestor (MetaWindow *window,
+ gpointer user_data)
{
- MetaWindow **result = data;
+ MetaWorkspaceFocusableAncestorData *data = user_data;
+
+ if (!window->unmanaging && meta_window_is_focusable (window) &&
+ meta_window_located_on_workspace (window, data->workspace) &&
+ meta_window_showing_on_its_workspace (window))
+ {
+ data->out_window = window;
+ return FALSE;
+ }
- *result = window;
- return FALSE; /* quit with the first ancestor we find */
+ return TRUE;
}
/* Focus ancestor of not_this_one if there is one */
@@ -1350,11 +1363,15 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
if (not_this_one)
{
MetaWindow *ancestor;
- ancestor = NULL;
- meta_window_foreach_ancestor (not_this_one, record_ancestor, &ancestor);
- if (ancestor != NULL &&
- meta_window_located_on_workspace (ancestor, workspace) &&
- meta_window_showing_on_its_workspace (ancestor))
+ MetaWorkspaceFocusableAncestorData data;
+
+ data = (MetaWorkspaceFocusableAncestorData) {
+ .workspace = workspace,
+ };
+ meta_window_foreach_ancestor (not_this_one, find_focusable_ancestor, &data);
+ ancestor = data.out_window;
+
+ if (ancestor)
{
meta_topic (META_DEBUG_FOCUS,
"Focusing %s, ancestor of %s\n",
--
2.21.0

@ -1,80 +0,0 @@
From 52536a44e96aa34d3ec3b9332adaa15a6399fc3e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Tue, 4 Jun 2019 21:21:37 +0200
Subject: [PATCH] workspace-manager: Expose layout properties
gnome-shell hardcodes a vertical one-column workspace layout, and
while not supporting arbitrary grids is very much by design, it
currently doesn't have a choice: We simply don't expose the workspace
layout we use.
Change that to allow gnome-shell to be a bit more flexible with the
workspace layouts it supports.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/618
---
src/core/meta-workspace-manager.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/src/core/meta-workspace-manager.c b/src/core/meta-workspace-manager.c
index 8e1f03fe8..fbae34c73 100644
--- a/src/core/meta-workspace-manager.c
+++ b/src/core/meta-workspace-manager.c
@@ -50,6 +50,9 @@ enum
{
PROP_0,
+ PROP_LAYOUT_COLUMNS,
+ PROP_LAYOUT_ROWS,
+
PROP_N_WORKSPACES
};
@@ -68,6 +71,12 @@ meta_workspace_manager_get_property (GObject *object,
switch (prop_id)
{
+ case PROP_LAYOUT_COLUMNS:
+ g_value_set_int (value, workspace_manager->columns_of_workspaces);
+ break;
+ case PROP_LAYOUT_ROWS:
+ g_value_set_int (value, workspace_manager->rows_of_workspaces);
+ break;
case PROP_N_WORKSPACES:
g_value_set_int (value, meta_workspace_manager_get_n_workspaces (workspace_manager));
break;
@@ -154,6 +163,22 @@ meta_workspace_manager_class_init (MetaWorkspaceManagerClass *klass)
0, NULL, NULL, NULL,
G_TYPE_NONE, 0);
+ g_object_class_install_property (object_class,
+ PROP_LAYOUT_COLUMNS,
+ g_param_spec_int ("layout-columns",
+ "Layout columns",
+ "Number of columns in layout",
+ -1, G_MAXINT, 1,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (object_class,
+ PROP_LAYOUT_ROWS,
+ g_param_spec_int ("layout-rows",
+ "Layout rows",
+ "Number of rows in layout",
+ -1, G_MAXINT, -1,
+ G_PARAM_READABLE));
+
g_object_class_install_property (object_class,
PROP_N_WORKSPACES,
g_param_spec_int ("n-workspaces",
@@ -474,6 +499,8 @@ meta_workspace_manager_update_workspace_layout (MetaWorkspaceManager *workspace_
workspace_manager->columns_of_workspaces,
workspace_manager->vertical_workspaces,
workspace_manager->starting_corner);
+ g_object_notify (G_OBJECT (workspace_manager), "layout-columns");
+ g_object_notify (G_OBJECT (workspace_manager), "layout-rows");
}
/**
--
2.21.0

@ -1,53 +0,0 @@
From 57b3a2ea620f754cfd38f1ed4851dd8223efbcab Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Thu, 28 Nov 2019 22:50:36 +0100
Subject: [PATCH] x11: Check wacom button flags to determine whether button is
mode switch
Checking the leds is not really accurate, since some devices have mode
switch buttons without leds. Check in the button flags whether they are
mode switch buttons for any of ring/ring2/strip/strip2, and return the
appropriate group.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/952
---
.../clutter/x11/clutter-input-device-xi2.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/clutter/clutter/x11/clutter-input-device-xi2.c b/clutter/clutter/x11/clutter-input-device-xi2.c
index 1254aca3ae..4e5e2fd12c 100644
--- a/clutter/clutter/x11/clutter-input-device-xi2.c
+++ b/clutter/clutter/x11/clutter-input-device-xi2.c
@@ -155,14 +155,25 @@ clutter_input_device_xi2_get_button_group (ClutterInputDevice *device,
if (device_xi2->wacom_device)
{
+ WacomButtonFlags flags;
+
if (button >= libwacom_get_num_buttons (device_xi2->wacom_device))
return -1;
- return libwacom_get_button_led_group (device_xi2->wacom_device,
- 'A' + button);
+ flags = libwacom_get_button_flag (device_xi2->wacom_device,
+ 'A' + button);
+
+ if (flags &
+ (WACOM_BUTTON_RING_MODESWITCH |
+ WACOM_BUTTON_TOUCHSTRIP_MODESWITCH))
+ return 0;
+ if (flags &
+ (WACOM_BUTTON_RING2_MODESWITCH |
+ WACOM_BUTTON_TOUCHSTRIP2_MODESWITCH))
+ return 1;
}
- else
- return -1;
+
+ return -1;
}
#endif
--
2.24.0

@ -1,304 +0,0 @@
From d366b2bc4e89ed5807f0221afc25e66cb3d289ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Wed, 9 Dec 2020 11:23:37 +0100
Subject: [PATCH 1/2] xwayland: Don't spew warnings when looking for X11
displays
It's not important, so only show it when doing MUTTER_DEBUG=wayland.
Instead report what display numbers were eventually found.
---
src/wayland/meta-xwayland.c | 123 +++++++++++++++++++++++++++---------
1 file changed, 92 insertions(+), 31 deletions(-)
diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c
index 15c85df69..699d5561c 100644
--- a/src/wayland/meta-xwayland.c
+++ b/src/wayland/meta-xwayland.c
@@ -146,9 +146,10 @@ meta_xwayland_is_xwayland_surface (MetaWaylandSurface *surface)
}
static gboolean
-try_display (int display,
- char **filename_out,
- int *fd_out)
+try_display (int display,
+ char **filename_out,
+ int *fd_out,
+ GError **error)
{
gboolean ret = FALSE;
char *filename;
@@ -164,11 +165,32 @@ try_display (int display,
char pid[11];
char *end;
pid_t other;
+ int read_bytes;
fd = open (filename, O_CLOEXEC, O_RDONLY);
- if (fd < 0 || read (fd, pid, 11) != 11)
+ if (fd < 0)
{
- g_warning ("can't read lock file %s: %m", filename);
+ g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
+ "Failed to open lock file %s: %s",
+ filename, g_strerror (errno));
+ goto out;
+ }
+
+ read_bytes = read (fd, pid, 11);
+ if (read_bytes != 11)
+ {
+ if (read_bytes < 0)
+ {
+ g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
+ "Failed to read lock file %s: %s",
+ filename, g_strerror (errno));
+ }
+ else
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Failed to read lock file %s",
+ filename);
+ }
goto out;
}
close (fd);
@@ -178,7 +200,8 @@ try_display (int display,
other = strtol (pid, &end, 0);
if (end != pid + 10)
{
- g_warning ("can't parse lock file %s", filename);
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
+ "Can't parse lock file %s", filename);
goto out;
}
@@ -187,18 +210,23 @@ try_display (int display,
/* Process is dead. Try unlinking the lock file and trying again. */
if (unlink (filename) < 0)
{
- g_warning ("failed to unlink stale lock file %s: %m", filename);
+ g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
+ "Failed to unlink stale lock file %s: %m", filename);
goto out;
}
goto again;
}
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Lock file %s already occupied", filename);
goto out;
}
else if (fd < 0)
{
- g_warning ("failed to create lock file %s: %m", filename);
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Failed to create lock file %s: %s",
+ filename, g_strerror (errno));
goto out;
}
@@ -223,24 +251,34 @@ try_display (int display,
}
static char *
-create_lock_file (int display, int *display_out)
+create_lock_file (int display,
+ int *display_out,
+ GError **error)
{
+ g_autoptr (GError) local_error = NULL;
char *filename;
int fd;
-
char pid[12];
int size;
int number_of_tries = 0;
- while (!try_display (display, &filename, &fd))
+ while (!try_display (display, &filename, &fd, &local_error))
{
+ meta_verbose ("Failed to open display %d: %s\n",
+ display, local_error->message);
+ g_clear_error (&local_error);
+
display++;
number_of_tries++;
/* If we can't get a display after 50 times, then something's wrong. Just
* abort in this case. */
if (number_of_tries >= 50)
- return NULL;
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Tried to bind 50 display numbers, giving up");
+ return NULL;
+ }
}
/* Subtle detail: we use the pid of the wayland compositor, not the xserver
@@ -248,11 +286,22 @@ create_lock_file (int display, int *display_out)
* it _would've_ written without either the NUL or the size clamping, hence
* the disparity in size. */
size = snprintf (pid, 12, "%10d\n", getpid ());
+ errno = 0;
if (size != 11 || write (fd, pid, 11) != 11)
{
+ if (errno != 0)
+ {
+ g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
+ "Failed to write pid to lock file: %s",
+ g_strerror (errno));
+ }
+ else
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Failed to write pid to lock file");
+ }
unlink (filename);
close (fd);
- g_warning ("failed to write pid to lock file %s", filename);
g_free (filename);
return NULL;
}
@@ -264,8 +313,8 @@ create_lock_file (int display, int *display_out)
}
static int
-bind_to_abstract_socket (int display,
- gboolean *fatal)
+bind_to_abstract_socket (int display,
+ GError **error)
{
struct sockaddr_un addr;
socklen_t size, name_size;
@@ -274,8 +323,8 @@ bind_to_abstract_socket (int display,
fd = socket (PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
if (fd < 0)
{
- *fatal = TRUE;
- g_warning ("Failed to create socket: %m");
+ g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
+ "Failed to create socket: %s", g_strerror (errno));
return -1;
}
@@ -285,17 +334,18 @@ bind_to_abstract_socket (int display,
size = offsetof (struct sockaddr_un, sun_path) + name_size;
if (bind (fd, (struct sockaddr *) &addr, size) < 0)
{
- *fatal = errno != EADDRINUSE;
- g_warning ("failed to bind to @%s: %m", addr.sun_path + 1);
+ g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
+ "Failed to bind to @%s: %s",
+ addr.sun_path + 1, g_strerror (errno));
close (fd);
return -1;
}
if (listen (fd, 1) < 0)
{
- *fatal = errno != EADDRINUSE;
- g_warning ("Failed to listen on abstract socket @%s: %m",
- addr.sun_path + 1);
+ g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
+ "Failed to listen on abstract socket @%s: %s",
+ addr.sun_path + 1, g_strerror (errno));
close (fd);
return -1;
}
@@ -304,7 +354,8 @@ bind_to_abstract_socket (int display,
}
static int
-bind_to_unix_socket (int display)
+bind_to_unix_socket (int display,
+ GError **error)
{
struct sockaddr_un addr;
socklen_t size, name_size;
@@ -321,13 +372,18 @@ bind_to_unix_socket (int display)
unlink (addr.sun_path);
if (bind (fd, (struct sockaddr *) &addr, size) < 0)
{
- g_warning ("failed to bind to %s: %m\n", addr.sun_path);
+ g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
+ "Failed to bind to %s: %s",
+ addr.sun_path, g_strerror (errno));
close (fd);
return -1;
}
if (listen (fd, 1) < 0)
{
+ g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
+ "Failed to listen on %s: %s",
+ addr.sun_path, g_strerror (errno));
unlink (addr.sun_path);
close (fd);
return -1;
@@ -385,7 +441,6 @@ choose_xdisplay (MetaXWaylandManager *manager)
{
int display = 0;
char *lock_file = NULL;
- gboolean fatal = FALSE;
if (display_number_override != -1)
display = display_number_override;
@@ -394,33 +449,37 @@ choose_xdisplay (MetaXWaylandManager *manager)
do
{
- lock_file = create_lock_file (display, &display);
+ g_autoptr (GError) error = NULL;
+
+ lock_file = create_lock_file (display, &display, &error);
if (!lock_file)
{
- g_warning ("Failed to create an X lock file");
+ g_warning ("Failed to create an X lock file: %s", error->message);
return FALSE;
}
- manager->abstract_fd = bind_to_abstract_socket (display, &fatal);
+ manager->abstract_fd = bind_to_abstract_socket (display, &error);
if (manager->abstract_fd < 0)
{
unlink (lock_file);
- if (!fatal)
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_ADDRESS_IN_USE))
{
+ meta_verbose ("Failed to bind abstract socket: %s\n", error->message);
display++;
continue;
}
else
{
- g_warning ("Failed to bind abstract socket");
+ g_warning ("Failed to bind abstract socket: %s", error->message);
return FALSE;
}
}
- manager->unix_fd = bind_to_unix_socket (display);
+ manager->unix_fd = bind_to_unix_socket (display, &error);
if (manager->unix_fd < 0)
{
+ meta_verbose ("Failed to bind unix socket: %s\n", error->message);
unlink (lock_file);
close (manager->abstract_fd);
display++;
@@ -435,6 +494,8 @@ choose_xdisplay (MetaXWaylandManager *manager)
manager->display_name = g_strdup_printf (":%d", manager->display_index);
manager->lock_file = lock_file;
+ g_message ("Using X11 display %s for Xwayland", manager->display_name);
+
return TRUE;
}
--
2.29.2

@ -1,192 +0,0 @@
From 6881aa5ca235ee0737c2a409ffab966a10e5971e Mon Sep 17 00:00:00 2001
From: Christian Hergert <christian@hergert.me>
Date: Mon, 24 Feb 2020 22:36:27 +0000
Subject: [PATCH 2/3] clutter: avoid g_signal_emit_by_name() from ClutterActor
g_signal_emit_by_name() is used to emit signals on ClutterContainer when
actors are removed or added. It happens to do various interface lookups
which are a bit unneccessary and can allocate memory.
Simply using emission wrappers makes all of that go away.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1083
---
clutter/clutter/cally/cally-actor.c | 5 +--
clutter/clutter/clutter-actor.c | 17 ++++++++--
clutter/clutter/clutter-actor.h | 5 ++-
clutter/clutter/clutter-container-private.h | 36 +++++++++++++++++++++
clutter/clutter/clutter-container.c | 21 ++++++++++++
5 files changed, 78 insertions(+), 6 deletions(-)
create mode 100644 clutter/clutter/clutter-container-private.h
diff --git a/clutter/clutter/cally/cally-actor.c b/clutter/clutter/cally/cally-actor.c
index 548615f48..517969625 100644
--- a/clutter/clutter/cally/cally-actor.c
+++ b/clutter/clutter/cally/cally-actor.c
@@ -604,10 +604,11 @@ cally_actor_real_remove_actor (ClutterActor *container,
g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), 0);
atk_parent = ATK_OBJECT (data);
- atk_child = clutter_actor_get_accessible (actor);
- if (atk_child)
+ if (clutter_actor_has_accessible (actor))
{
+ atk_child = clutter_actor_get_accessible (actor);
+
g_value_init (&values.old_value, G_TYPE_POINTER);
g_value_set_pointer (&values.old_value, atk_parent);
diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c
index 803f76aae..93d0a93ef 100644
--- a/clutter/clutter/clutter-actor.c
+++ b/clutter/clutter/clutter-actor.c
@@ -624,7 +624,7 @@
#include "clutter-color-static.h"
#include "clutter-color.h"
#include "clutter-constraint-private.h"
-#include "clutter-container.h"
+#include "clutter-container-private.h"
#include "clutter-content-private.h"
#include "clutter-debug.h"
#include "clutter-easing.h"
@@ -4372,7 +4372,7 @@ clutter_actor_remove_child_internal (ClutterActor *self,
/* we need to emit the signal before dropping the reference */
if (emit_actor_removed)
- g_signal_emit_by_name (self, "actor-removed", child);
+ _clutter_container_emit_actor_removed (CLUTTER_CONTAINER (self), child);
if (notify_first_last)
{
@@ -13060,7 +13060,7 @@ clutter_actor_add_child_internal (ClutterActor *self,
}
if (emit_actor_added)
- g_signal_emit_by_name (self, "actor-added", child);
+ _clutter_container_emit_actor_added (CLUTTER_CONTAINER (self), child);
if (notify_first_last)
{
@@ -21448,3 +21448,14 @@ clutter_actor_create_texture_paint_node (ClutterActor *self,
return node;
}
+
+gboolean
+clutter_actor_has_accessible (ClutterActor *actor)
+{
+ g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), FALSE);
+
+ if (CLUTTER_ACTOR_GET_CLASS (actor)->has_accessible)
+ return CLUTTER_ACTOR_GET_CLASS (actor)->has_accessible (actor);
+
+ return TRUE;
+}
diff --git a/clutter/clutter/clutter-actor.h b/clutter/clutter/clutter-actor.h
index 7d2168af1..d286f2843 100644
--- a/clutter/clutter/clutter-actor.h
+++ b/clutter/clutter/clutter-actor.h
@@ -296,10 +296,11 @@ struct _ClutterActorClass
gboolean (* touch_event) (ClutterActor *self,
ClutterTouchEvent *event);
+ gboolean (* has_accessible) (ClutterActor *self);
/*< private >*/
/* padding for future expansion */
- gpointer _padding_dummy[26];
+ gpointer _padding_dummy[25];
};
/**
@@ -369,6 +370,8 @@ CLUTTER_EXPORT
const gchar * clutter_actor_get_name (ClutterActor *self);
CLUTTER_EXPORT
AtkObject * clutter_actor_get_accessible (ClutterActor *self);
+CLUTTER_EXPORT
+gboolean clutter_actor_has_accessible (ClutterActor *self);
CLUTTER_EXPORT
gboolean clutter_actor_is_visible (ClutterActor *self);
diff --git a/clutter/clutter/clutter-container-private.h b/clutter/clutter/clutter-container-private.h
new file mode 100644
index 000000000..d619a6531
--- /dev/null
+++ b/clutter/clutter/clutter-container-private.h
@@ -0,0 +1,36 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Copyright 2020 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __CLUTTER_CONTAINER_PRIVATE_H__
+#define __CLUTTER_CONTAINER_PRIVATE_H__
+
+#include <clutter/clutter-container.h>
+
+G_BEGIN_DECLS
+
+void _clutter_container_emit_actor_added (ClutterContainer *container,
+ ClutterActor *actor);
+void _clutter_container_emit_actor_removed (ClutterContainer *container,
+ ClutterActor *actor);
+
+G_END_DECLS
+
+#endif /* __CLUTTER_CONTAINER_PRIVATE_H__ */
diff --git a/clutter/clutter/clutter-container.c b/clutter/clutter/clutter-container.c
index 0f611ae55..79abb5b4f 100644
--- a/clutter/clutter/clutter-container.c
+++ b/clutter/clutter/clutter-container.c
@@ -37,6 +37,7 @@
#include "clutter-actor-private.h"
#include "clutter-child-meta.h"
+#include "clutter-container-private.h"
#include "clutter-debug.h"
#include "clutter-main.h"
#include "clutter-marshal.h"
@@ -1446,3 +1447,23 @@ clutter_container_child_notify (ClutterContainer *container,
child,
pspec);
}
+
+void
+_clutter_container_emit_actor_added (ClutterContainer *container,
+ ClutterActor *actor)
+{
+ g_return_if_fail (CLUTTER_IS_CONTAINER (container));
+ g_return_if_fail (CLUTTER_IS_ACTOR (actor));
+
+ g_signal_emit (container, container_signals[ACTOR_ADDED], 0, actor);
+}
+
+void
+_clutter_container_emit_actor_removed (ClutterContainer *container,
+ ClutterActor *actor)
+{
+ g_return_if_fail (CLUTTER_IS_CONTAINER (container));
+ g_return_if_fail (CLUTTER_IS_ACTOR (actor));
+
+ g_signal_emit (container, container_signals[ACTOR_REMOVED], 0, actor);
+}
--
2.26.0

@ -1,42 +0,0 @@
From 801da0dab1d2928578e9b191ee1684bcc7154081 Mon Sep 17 00:00:00 2001
From: Pekka Paalanen <pekka.paalanen@collabora.com>
Date: Tue, 30 Apr 2019 17:01:04 +0300
Subject: [PATCH 02/12] cogl: Fix doc for _cogl_blit_framebuffer
Commit 38921701e533b7fda38a236cc45aec2ed3afef8a added explicit source and
destination parameters. Fix the documentation to match.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/615
(cherry picked from commit fc0ce11fcd997af12fc2253eeb37e03cebb5964f)
---
cogl/cogl/cogl-framebuffer-private.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h
index 296788c2b..de886b64f 100644
--- a/cogl/cogl/cogl-framebuffer-private.h
+++ b/cogl/cogl/cogl-framebuffer-private.h
@@ -4,6 +4,7 @@
* A Low Level GPU Graphics and Utilities API
*
* Copyright (C) 2007,2008,2009 Intel Corporation.
+ * Copyright (C) 2019 DisplayLink (UK) Ltd.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -377,9 +378,8 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
* @width: Width of region to copy
* @height: Height of region to copy
*
- * This blits a region of the color buffer of the current draw buffer
- * to the current read buffer. The draw and read buffers can be set up
- * using _cogl_push_framebuffers(). This function should only be
+ * This blits a region of the color buffer of the source buffer
+ * to the destination buffer. This function should only be
* called if the COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT feature is
* advertised. The two buffers must both be offscreen and have the
* same format.
--
2.21.0

@ -1,27 +0,0 @@
From 03c30b76bae4c2e3f51a6689ebb7c0c60bd7b29a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Tue, 9 Feb 2021 18:00:26 +0100
Subject: [PATCH 2/2] cogl/gpu-info: Fix software acceleration detection
The string used to match mesa changed; update to fix software rendering
detection.
---
cogl/cogl/cogl-gpu-info.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/cogl/cogl/cogl-gpu-info.c b/cogl/cogl/cogl-gpu-info.c
index f44319e96..c1817b3b0 100644
--- a/cogl/cogl/cogl-gpu-info.c
+++ b/cogl/cogl/cogl-gpu-info.c
@@ -192,6 +192,8 @@ check_mesa_vendor (const CoglGpuInfoStrings *strings)
return TRUE;
else if (strcmp (strings->vendor_string, "Mesa Project") == 0)
return TRUE;
+ else if (strcmp (strings->vendor_string, "Mesa/X.org") == 0)
+ return TRUE;
return FALSE;
}
--
2.29.2

@ -0,0 +1,133 @@
From b2cf9836373a446d674ecce251e3e42bb863dc75 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 6 Jun 2024 13:32:03 -0400
Subject: [PATCH 2/6] core/events: Count shell interactions has user
interactions too
mutter keeps track of the last time the user used the system to
decide whether or not to prevent focus stealing.
Right now, it only considers user interactions with application
windows, not interactions with the compositor chrome.
That means a user could start loading an application,
switch workspaces, and get forcefully pulled back when the
application finishes loading.
This commit fixes that problem by updating the user time on shell
interactions as well.
---
src/core/events.c | 38 ++++++++++++++++++++++++--------------
1 file changed, 24 insertions(+), 14 deletions(-)
diff --git a/src/core/events.c b/src/core/events.c
index 775104229..4d25b6dc0 100644
--- a/src/core/events.c
+++ b/src/core/events.c
@@ -288,79 +288,89 @@ meta_display_handle_event (MetaDisplay *display,
if (source)
meta_backend_update_last_device (backend, source);
}
#ifdef HAVE_WAYLAND
if (meta_is_wayland_compositor () && event->type == CLUTTER_MOTION)
{
MetaCursorRenderer *cursor_renderer;
ClutterInputDevice *device;
device = clutter_event_get_device (event);
cursor_renderer = meta_backend_get_cursor_renderer_for_device (backend,
device);
if (cursor_renderer)
meta_cursor_renderer_update_position (cursor_renderer);
if (device == clutter_seat_get_pointer (clutter_input_device_get_seat (device)))
{
MetaCursorTracker *cursor_tracker =
meta_backend_get_cursor_tracker (backend);
meta_cursor_tracker_invalidate_position (cursor_tracker);
}
}
#endif
window = get_window_for_event (display, event);
display->current_time = event->any.time;
- if (window && !window->override_redirect &&
- (event->type == CLUTTER_KEY_PRESS ||
- event->type == CLUTTER_BUTTON_PRESS ||
- event->type == CLUTTER_TOUCH_BEGIN))
+ if (event->type == CLUTTER_KEY_PRESS ||
+ event->type == CLUTTER_BUTTON_PRESS ||
+ event->type == CLUTTER_TOUCH_BEGIN)
{
- if (META_CURRENT_TIME == display->current_time)
+ if (window && !window->override_redirect)
{
- /* We can't use missing (i.e. invalid) timestamps to set user time,
- * nor do we want to use them to sanity check other timestamps.
- * See bug 313490 for more details.
- */
- meta_warning ("Event has no timestamp! You may be using a broken "
- "program such as xse. Please ask the authors of that "
- "program to fix it.");
+ if (META_CURRENT_TIME == display->current_time)
+ {
+ /* We can't use missing (i.e. invalid) timestamps to set user time,
+ * nor do we want to use them to sanity check other timestamps.
+ * See bug 313490 for more details.
+ */
+ meta_warning ("Event has no timestamp! You may be using a broken "
+ "program such as xse. Please ask the authors of that "
+ "program to fix it.");
+ }
+ else
+ {
+ meta_window_set_user_time (window, display->current_time);
+ meta_display_sanity_check_timestamps (display, display->current_time);
+ }
}
else
{
- meta_window_set_user_time (window, display->current_time);
- meta_display_sanity_check_timestamps (display, display->current_time);
+ /* Always update user time to the last time the user did an event, even
+ * if it was to shell chrome or a notification or something.
+ */
+ if (XSERVER_TIME_IS_BEFORE (display->last_user_time, display->current_time))
+ display->last_user_time = display->current_time;
}
}
gesture_tracker = meta_display_get_gesture_tracker (display);
if (meta_gesture_tracker_handle_event (gesture_tracker, event))
{
bypass_wayland = bypass_clutter = TRUE;
goto out;
}
if (display->event_route == META_EVENT_ROUTE_WINDOW_OP)
{
if (meta_window_handle_mouse_grab_op_event (window, event))
{
bypass_clutter = TRUE;
bypass_wayland = TRUE;
goto out;
}
}
/* For key events, it's important to enforce single-handling, or
* we can get into a confused state. So if a keybinding is
* handled (because it's one of our hot-keys, or because we are
* in a keyboard-grabbed mode like moving a window, we don't
* want to pass the key event to the compositor or Wayland at all.
*/
if (meta_keybindings_process_event (display, window, event))
{
bypass_clutter = TRUE;
--
2.44.0

@ -0,0 +1,43 @@
From 69c40c6d126a5c804db54ce0afe581362e4fd33b Mon Sep 17 00:00:00 2001
From: Daniel van Vugt <daniel.van.vugt@canonical.com>
Date: Tue, 12 Apr 2022 18:37:29 +0800
Subject: [PATCH 2/2] crtc/kms: Don't add gamma to the update if unsupported by
the CRTC
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2197
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2360>
---
src/backends/native/meta-crtc-kms.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/backends/native/meta-crtc-kms.c b/src/backends/native/meta-crtc-kms.c
index f1bc79146..953f023ce 100644
--- a/src/backends/native/meta-crtc-kms.c
+++ b/src/backends/native/meta-crtc-kms.c
@@ -201,10 +201,14 @@ meta_crtc_kms_maybe_set_gamma (MetaCrtcKms *crtc_kms,
MetaKms *kms = meta_kms_device_get_kms (kms_device);
MetaKmsUpdate *kms_update;
MetaKmsCrtcGamma *gamma;
+ MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
if (crtc_kms->is_gamma_valid)
return;
+ if (!meta_kms_crtc_has_gamma (kms_crtc))
+ return;
+
gamma = meta_monitor_manager_native_get_cached_crtc_gamma (monitor_manager_native,
crtc_kms);
if (!gamma)
@@ -212,7 +216,7 @@ meta_crtc_kms_maybe_set_gamma (MetaCrtcKms *crtc_kms,
kms_update = meta_kms_ensure_pending_update (kms, kms_device);
meta_kms_update_set_crtc_gamma (kms_update,
- meta_crtc_kms_get_kms_crtc (crtc_kms),
+ kms_crtc,
gamma->size,
gamma->red,
gamma->green,
--
2.35.1

@ -0,0 +1,27 @@
From 37b4b8dd63851e97b507008fe1028a259c0419c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Tue, 27 Aug 2024 11:33:22 +0200
Subject: [PATCH 2/5] display: Also set window cgroup on cgroup creation
We'd register the cgroup for a window twice, because the firs time
didn't update the MetaWindow::cgroup pointer. This meant the cgroups
were never removed.
---
src/core/display.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/core/display.c b/src/core/display.c
index 97f591a876..e99e787fbe 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -1704,6 +1704,7 @@ meta_display_register_cgroup (MetaDisplay *display,
cgroup = meta_cgroup_new (path);
g_hash_table_insert (display->cgroups, g_file_get_path (cgroup->path), cgroup);
+ window->cgroup = cgroup;
}
void
--
2.44.0.501.g19981daefd.dirty

@ -1,28 +0,0 @@
From a192b9abd77aa14ae794850e41d210472f86b9b0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Thu, 25 Jun 2020 10:09:48 +0200
Subject: [PATCH 2/2] gpu-kms: Reset CRTC, mode and output list if no resources
On device removal, the next resource retrieval will fail; handle this by
just clearing the CRTC, mode and outputs.
---
src/backends/native/meta-gpu-kms.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/backends/native/meta-gpu-kms.c b/src/backends/native/meta-gpu-kms.c
index 93e509def5..dc93abb7b1 100644
--- a/src/backends/native/meta-gpu-kms.c
+++ b/src/backends/native/meta-gpu-kms.c
@@ -871,6 +871,9 @@ meta_gpu_kms_read_current (MetaGpu *gpu,
local_error->message);
gpu_kms->resources_init_failed_before = TRUE;
}
+ meta_gpu_take_outputs (gpu, NULL);
+ meta_gpu_take_modes (gpu, NULL);
+ meta_gpu_take_crtcs (gpu, NULL);
return TRUE;
}
--
2.26.2

@ -0,0 +1,29 @@
From dd94c448e94b1033b90749d77c5dc587c3b8f9f4 Mon Sep 17 00:00:00 2001
From: Daniel van Vugt <daniel.van.vugt@canonical.com>
Date: Tue, 5 Apr 2022 17:06:21 +0800
Subject: [PATCH 2/2] kms/device: Disable modifiers when
!DRM_CAP_ADDFB2_MODIFIERS
Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2210
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2359>
---
src/backends/native/meta-kms-device.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/backends/native/meta-kms-device.c b/src/backends/native/meta-kms-device.c
index bef1e2065..7c84f14f5 100644
--- a/src/backends/native/meta-kms-device.c
+++ b/src/backends/native/meta-kms-device.c
@@ -490,6 +490,9 @@ meta_kms_device_new (MetaKms *kms,
free (device->path);
device->path = data.out_path;
+ if (!device->caps.addfb2_modifiers)
+ device->flags |= META_KMS_DEVICE_FLAG_DISABLE_MODIFIERS;
+
return device;
}
--
2.45.2

@ -1,185 +0,0 @@
From 85484d8f5d75764ab74308da7b21411c3fe4a2da Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Wed, 3 Oct 2018 10:50:47 +0200
Subject: [PATCH 2/2] monitor-manager/xrandr: Create dummy screen sized monitor
if no RANDR
When there is no RANDR support enabled in the X server, we wont get
notified of any monitors, resulting in mutter believing we're being
headless. To get at least something working, although with no way
configuration ability, lets pretend the whole screen is just a single
monitor with a single output, crtc and mode.
---
src/backends/x11/meta-gpu-xrandr.c | 60 +++++++++++++++++++
.../x11/meta-monitor-manager-xrandr.c | 22 ++++++-
.../x11/meta-monitor-manager-xrandr.h | 4 ++
3 files changed, 85 insertions(+), 1 deletion(-)
diff --git a/src/backends/x11/meta-gpu-xrandr.c b/src/backends/x11/meta-gpu-xrandr.c
index 1884278ca..22e7e70e0 100644
--- a/src/backends/x11/meta-gpu-xrandr.c
+++ b/src/backends/x11/meta-gpu-xrandr.c
@@ -115,6 +115,63 @@ update_screen_size (MetaGpuXrandr *gpu_xrandr)
monitor_manager->screen_height = HeightOfScreen (screen);
}
+static gboolean
+read_current_fallback (MetaGpuXrandr *gpu_xrandr,
+ MetaMonitorManagerXrandr *monitor_manager_xrandr)
+{
+ MetaGpu *gpu = META_GPU (gpu_xrandr);
+ MetaMonitorManager *monitor_manager =
+ META_MONITOR_MANAGER (monitor_manager_xrandr);
+ MetaCrtcMode *mode;
+ MetaCrtc *crtc;
+ MetaOutput *output;
+
+ meta_monitor_manager_xrandr_update_dpms_state (monitor_manager_xrandr);
+ update_screen_size (gpu_xrandr);
+
+ mode = g_object_new (META_TYPE_CRTC_MODE, NULL);
+ mode->mode_id = 0;
+ mode->width = monitor_manager->screen_width;
+ mode->height = monitor_manager->screen_height;
+ mode->refresh_rate = 60.0;
+ mode->name = g_strdup_printf ("%dx%d", mode->width, mode->height);
+
+ meta_gpu_take_modes (gpu, g_list_prepend (NULL, mode));
+
+ crtc = g_object_new (META_TYPE_CRTC, NULL);
+ crtc->gpu = gpu;
+ crtc->crtc_id = 0;
+ crtc->rect = (MetaRectangle) { .width = mode->width, .height = mode->height };
+ crtc->current_mode = mode;
+
+ meta_gpu_take_crtcs (gpu, g_list_prepend (NULL, crtc));
+
+ output = g_object_new (META_TYPE_OUTPUT, NULL);
+ output->gpu = gpu;
+ output->winsys_id = 0;
+ output->name = g_strdup ("X11 Screen");
+ output->vendor = g_strdup ("unknown");
+ output->product = g_strdup ("unknown");
+ output->serial = g_strdup ("unknown");
+ output->hotplug_mode_update = TRUE;
+ output->suggested_x = -1;
+ output->suggested_y = -1;
+ output->connector_type = META_CONNECTOR_TYPE_Unknown;
+ output->modes = g_new0 (MetaCrtcMode *, 1);
+ output->modes[0] = mode;
+ output->n_modes = 1;
+ output->preferred_mode = mode;
+ output->possible_crtcs = g_new0 (MetaCrtc *, 1);
+ output->possible_crtcs[0] = crtc;
+ output->n_possible_crtcs = 1;
+ meta_output_assign_crtc (output, crtc);
+ output->is_primary = TRUE;
+
+ meta_gpu_take_outputs (gpu, g_list_prepend (NULL, output));
+
+ return TRUE;
+}
+
static gboolean
meta_gpu_xrandr_read_current (MetaGpu *gpu,
GError **error)
@@ -133,6 +190,9 @@ meta_gpu_xrandr_read_current (MetaGpu *gpu,
GList *modes = NULL;
GList *crtcs = NULL;
+ if (!meta_monitor_manager_xrandr_has_randr (monitor_manager_xrandr))
+ return read_current_fallback (gpu_xrandr, monitor_manager_xrandr);
+
if (gpu_xrandr->resources)
XRRFreeScreenResources (gpu_xrandr->resources);
gpu_xrandr->resources = NULL;
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
index 7a0b43ac4..d6306faeb 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
@@ -75,6 +75,7 @@ struct _MetaMonitorManagerXrandr
guint logind_watch_id;
guint logind_signal_sub_id;
+ gboolean has_randr;
gboolean has_randr15;
/*
@@ -114,6 +115,12 @@ meta_monitor_manager_xrandr_get_xdisplay (MetaMonitorManagerXrandr *manager_xran
return manager_xrandr->xdisplay;
}
+gboolean
+meta_monitor_manager_xrandr_has_randr (MetaMonitorManagerXrandr *manager_xrandr)
+{
+ return manager_xrandr->has_randr;
+}
+
gboolean
meta_monitor_manager_xrandr_has_randr15 (MetaMonitorManagerXrandr *manager_xrandr)
{
@@ -145,7 +152,7 @@ x11_dpms_state_to_power_save (CARD16 dpms_state)
}
}
-static void
+void
meta_monitor_manager_xrandr_update_dpms_state (MetaMonitorManagerXrandr *manager_xrandr)
{
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
@@ -637,9 +644,18 @@ meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager *mana
MetaMonitorsConfigMethod method,
GError **error)
{
+ MetaMonitorManagerXrandr *manager_xrandr =
+ META_MONITOR_MANAGER_XRANDR (manager);
GPtrArray *crtc_infos;
GPtrArray *output_infos;
+ if (!manager_xrandr->has_randr)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Tried to change configuration without XRANDR support");
+ return FALSE;
+ }
+
if (!config)
{
meta_monitor_manager_xrandr_rebuild_derived (manager, NULL);
@@ -1105,11 +1121,15 @@ meta_monitor_manager_xrandr_constructed (GObject *object)
&manager_xrandr->rr_event_base,
&manager_xrandr->rr_error_base))
{
+ g_warning ("No RANDR support, monitor configuration disabled");
return;
}
else
{
int major_version, minor_version;
+
+ manager_xrandr->has_randr = TRUE;
+
/* We only use ScreenChangeNotify, but GDK uses the others,
and we don't want to step on its toes */
XRRSelectInput (manager_xrandr->xdisplay,
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.h b/src/backends/x11/meta-monitor-manager-xrandr.h
index d55b3d2b8..dc75134a5 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.h
+++ b/src/backends/x11/meta-monitor-manager-xrandr.h
@@ -33,9 +33,13 @@ G_DECLARE_FINAL_TYPE (MetaMonitorManagerXrandr, meta_monitor_manager_xrandr,
Display * meta_monitor_manager_xrandr_get_xdisplay (MetaMonitorManagerXrandr *manager_xrandr);
+gboolean meta_monitor_manager_xrandr_has_randr (MetaMonitorManagerXrandr *manager_xrandr);
+
gboolean meta_monitor_manager_xrandr_has_randr15 (MetaMonitorManagerXrandr *manager_xrandr);
gboolean meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager,
XEvent *event);
+void meta_monitor_manager_xrandr_update_dpms_state (MetaMonitorManagerXrandr *manager_xrandr);
+
#endif /* META_MONITOR_MANAGER_XRANDR_H */
--
2.23.0

@ -0,0 +1,120 @@
From b328c8cc8b0b31a4afe2bfc857c6ea5a2b837ef2 Mon Sep 17 00:00:00 2001
From: Piotr Lopatka <piotr.lopatka@gmail.com>
Date: Fri, 3 Sep 2021 20:01:59 +0100
Subject: [PATCH 2/2] onscreen/native: Pass damage rectangles when page
flipping
This commit passes damage rectangles metadata to the (KMS) primary
plane.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1879>
---
src/backends/native/meta-crtc-kms.c | 4 +++-
src/backends/native/meta-crtc-kms.h | 6 +++---
src/backends/native/meta-onscreen-native.c | 22 ++++++++++++++++++----
3 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/src/backends/native/meta-crtc-kms.c b/src/backends/native/meta-crtc-kms.c
index f1bc79146af..fde64817532 100644
--- a/src/backends/native/meta-crtc-kms.c
+++ b/src/backends/native/meta-crtc-kms.c
@@ -115,7 +115,7 @@ meta_crtc_kms_apply_transform (MetaCrtcKms *crtc_kms,
hw_transform);
}
-void
+MetaKmsPlaneAssignment *
meta_crtc_kms_assign_primary_plane (MetaCrtcKms *crtc_kms,
MetaDrmBuffer *buffer,
MetaKmsUpdate *kms_update)
@@ -161,6 +161,8 @@ meta_crtc_kms_assign_primary_plane (MetaCrtcKms *crtc_kms,
dst_rect,
flags);
meta_crtc_kms_apply_transform (crtc_kms, plane_assignment);
+
+ return plane_assignment;
}
static GList *
diff --git a/src/backends/native/meta-crtc-kms.h b/src/backends/native/meta-crtc-kms.h
index f8d241bbb51..bd80835f986 100644
--- a/src/backends/native/meta-crtc-kms.h
+++ b/src/backends/native/meta-crtc-kms.h
@@ -48,9 +48,9 @@ void meta_crtc_kms_set_cursor_renderer_private (MetaCrtcKms *crtc_kms,
void meta_crtc_kms_apply_transform (MetaCrtcKms *crtc_kms,
MetaKmsPlaneAssignment *kms_plane_assignment);
-void meta_crtc_kms_assign_primary_plane (MetaCrtcKms *crtc_kms,
- MetaDrmBuffer *buffer,
- MetaKmsUpdate *kms_update);
+MetaKmsPlaneAssignment * meta_crtc_kms_assign_primary_plane (MetaCrtcKms *crtc_kms,
+ MetaDrmBuffer *buffer,
+ MetaKmsUpdate *kms_update);
void meta_crtc_kms_set_mode (MetaCrtcKms *crtc_kms,
MetaKmsUpdate *kms_update);
diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c
index 112bd0d438b..00b2d9f89cc 100644
--- a/src/backends/native/meta-onscreen-native.c
+++ b/src/backends/native/meta-onscreen-native.c
@@ -416,7 +416,9 @@ static void
meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
MetaRendererView *view,
MetaCrtc *crtc,
- MetaKmsPageFlipListenerFlag flags)
+ MetaKmsPageFlipListenerFlag flags,
+ const int *rectangles,
+ int n_rectangles)
{
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
MetaRendererNative *renderer_native = onscreen_native->renderer_native;
@@ -430,6 +432,7 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
MetaKmsUpdate *kms_update;
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state = NULL;
MetaDrmBuffer *buffer;
+ MetaKmsPlaneAssignment *plane_assignment;
COGL_TRACE_BEGIN_SCOPED (MetaOnscreenNativeFlipCrtcs,
"Onscreen (flip CRTCs)");
@@ -456,8 +459,15 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
buffer = secondary_gpu_state->gbm.next_fb;
}
- meta_crtc_kms_assign_primary_plane (crtc_kms, buffer, kms_update);
+ plane_assignment = meta_crtc_kms_assign_primary_plane (crtc_kms,
+ buffer,
+ kms_update);
+ if (rectangles != NULL && n_rectangles != 0)
+ {
+ meta_kms_plane_assignment_set_fb_damage (plane_assignment,
+ rectangles, n_rectangles);
+ }
break;
case META_RENDERER_NATIVE_MODE_SURFACELESS:
g_assert_not_reached ();
@@ -1081,7 +1091,9 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
meta_onscreen_native_flip_crtc (onscreen,
onscreen_native->view,
onscreen_native->crtc,
- META_KMS_PAGE_FLIP_LISTENER_FLAG_NONE);
+ META_KMS_PAGE_FLIP_LISTENER_FLAG_NONE,
+ rectangles,
+ n_rectangles);
}
else
{
@@ -1299,7 +1311,9 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen,
meta_onscreen_native_flip_crtc (onscreen,
onscreen_native->view,
onscreen_native->crtc,
- META_KMS_PAGE_FLIP_LISTENER_FLAG_DROP_ON_ERROR);
+ META_KMS_PAGE_FLIP_LISTENER_FLAG_DROP_ON_ERROR,
+ NULL,
+ 0);
kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (onscreen_native->crtc));
kms_device = meta_kms_crtc_get_device (kms_crtc);
--
2.36.1

@ -0,0 +1,47 @@
From cd8b90a7a7185c3f177469d1a37654a9e8539cd1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Thu, 29 Sep 2022 14:23:55 +0200
Subject: [PATCH 2/2] output/kms: Don't attemp to add common modes on
connectors without modes
We have no way to sanely add safe modes if there are no modes we can
compare with, thus don't try.
Fixes the following crash:
#0 are_all_modes_equally_sized at ../src/backends/native/meta-output-kms.c:284
#1 maybe_add_fallback_modes at ../src/backends/native/meta-output-kms.c:310
#2 init_output_modes at ../src/backends/native/meta-output-kms.c:347
#3 meta_output_kms_new at ../src/backends/native/meta-output-kms.c:414
#4 init_outputs at ../src/backends/native/meta-gpu-kms.c:332
#5 meta_gpu_kms_read_current at ../src/backends/native/meta-gpu-kms.c:368
#6 meta_gpu_kms_new at ../src/backends/native/meta-gpu-kms.c:403
#7 create_gpu_from_udev_device at ../src/backends/native/meta-backend-native.c:461
#8 init_gpus at ../src/backends/native/meta-backend-native.c:551
#9 meta_backend_native_initable_init at ../src/backends/native/meta-backend-native.c:632
Fixes: 877cc3eb7d44e2886395151f763ec09bea350444
Related: https://bugzilla.redhat.com/show_bug.cgi?id=2127801
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2646>
(cherry picked from commit 2c8adb19660cb2cd53381372833e088962437d3b)
---
src/backends/native/meta-output-kms.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/backends/native/meta-output-kms.c b/src/backends/native/meta-output-kms.c
index 9adc20bfd9..058ab7c053 100644
--- a/src/backends/native/meta-output-kms.c
+++ b/src/backends/native/meta-output-kms.c
@@ -250,6 +250,9 @@ maybe_add_fallback_modes (const MetaKmsConnectorState *connector_state,
MetaGpuKms *gpu_kms,
MetaKmsConnector *kms_connector)
{
+ if (!connector_state->modes)
+ return;
+
if (!connector_state->has_scaling)
return;
--
2.37.1

@ -1,46 +0,0 @@
From 63455680096e015eaf023760466593b6f42f9cf5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Thu, 12 Sep 2019 11:50:34 +0200
Subject: [PATCH 2/4] renderer/native: Add API to get primary GPU
Will be used when acquiring scanouts from Wayland buffers.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/798
---
src/backends/native/meta-renderer-native.c | 6 ++++++
src/backends/native/meta-renderer-native.h | 2 ++
2 files changed, 8 insertions(+)
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index dbb88edb8e..25833b6cf6 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -317,6 +317,12 @@ meta_gbm_device_from_gpu (MetaGpuKms *gpu_kms)
return renderer_gpu_data->gbm.device;
}
+MetaGpuKms *
+meta_renderer_native_get_primary_gpu (MetaRendererNative *renderer_native)
+{
+ return renderer_native->primary_gpu_kms;
+}
+
static MetaRendererNativeGpuData *
meta_create_renderer_native_gpu_data (MetaGpuKms *gpu_kms)
{
diff --git a/src/backends/native/meta-renderer-native.h b/src/backends/native/meta-renderer-native.h
index 9eecdead1c..b59366e267 100644
--- a/src/backends/native/meta-renderer-native.h
+++ b/src/backends/native/meta-renderer-native.h
@@ -53,6 +53,8 @@ struct gbm_device * meta_gbm_device_from_gpu (MetaGpuKms *gpu_kms);
gboolean meta_renderer_native_supports_mirroring (MetaRendererNative *renderer_native);
+MetaGpuKms * meta_renderer_native_get_primary_gpu (MetaRendererNative *renderer_native);
+
void meta_renderer_native_finish_frame (MetaRendererNative *renderer_native);
int64_t meta_renderer_native_get_frame_counter (MetaRendererNative *renderer_native);
--
2.26.2

@ -1,44 +0,0 @@
From 2e4d3e22aff7cc8e41fa08d798c55a39a542476c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Tue, 2 Jun 2020 18:34:57 +0200
Subject: [PATCH 2/2] renderer-native: Don't leak DMA buffer CoglFramebuffer
When we created the DMA buffer backed CoglFramebuffer, we handed it over
to CoglDmaBufHandle which took its own reference. What we failed to do
was to release our own reference to it, effectively leaking it.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1283
(cherry picked from commit c823b5ddba18d30e1fdb74d6764cd40637dc4054)
---
src/backends/native/meta-renderer-native.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index ba98de650..dbb88edb8 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -2633,6 +2633,7 @@ meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer,
case META_RENDERER_NATIVE_MODE_GBM:
{
CoglFramebuffer *dmabuf_fb;
+ CoglDmaBufHandle *dmabuf_handle;
struct gbm_bo *new_bo;
int dmabuf_fd = -1;
@@ -2669,8 +2670,11 @@ meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer,
if (!dmabuf_fb)
return NULL;
- return cogl_dma_buf_handle_new (dmabuf_fb, dmabuf_fd, new_bo,
- (GDestroyNotify) gbm_bo_destroy);
+ dmabuf_handle =
+ cogl_dma_buf_handle_new (dmabuf_fb, dmabuf_fd, new_bo,
+ (GDestroyNotify) gbm_bo_destroy);
+ cogl_object_unref (dmabuf_fb);
+ return dmabuf_handle;
}
break;
#ifdef HAVE_EGL_DEVICE
--
2.26.2

@ -0,0 +1,94 @@
From 425710866438a62843b96272a6cbc6c22174f10c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Mon, 11 Oct 2021 10:39:43 +0200
Subject: [PATCH 2/5] renderer/native: Try the gbm renderer before the
EGLDevice renderer
This switches the order of what renderer mode is tried first, so that
the gbm renderer mode is preferred on an NVIDIA driver where it is
supported.
We fall back to still try the EGLDevice renderer mode if the created gbm
renderer is not hardware accelerated.
The last fallback is still to use the gbm renderer, even if it is not
hardware accelerated, as this is needed when hardware acceleration isn't
available at all. The original reason for the old order was due to the
fact that a gbm renderer without hardware acceleration would succeed
even on NVIDIA driver that didn't support gbm.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2051>
(cherry picked from commit 8fc1325e8e713dfa05a12c47e6e981e50d3cda61)
---
src/backends/native/meta-renderer-native.c | 44 +++++++++++-----------
1 file changed, 23 insertions(+), 21 deletions(-)
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index f92f648e5..c851619a1 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -1754,38 +1754,40 @@ meta_renderer_native_create_renderer_gpu_data (MetaRendererNative *renderer_nat
MetaGpuKms *gpu_kms,
GError **error)
{
- MetaRendererNativeGpuData *renderer_gpu_data;
+ MetaRendererNativeGpuData *gbm_renderer_gpu_data;
GError *gbm_error = NULL;
#ifdef HAVE_EGL_DEVICE
+ MetaRendererNativeGpuData *egl_stream_renderer_gpu_data;
GError *egl_device_error = NULL;
#endif
if (!gpu_kms)
return create_renderer_gpu_data_surfaceless (renderer_native, error);
-#ifdef HAVE_EGL_DEVICE
- /* Try to initialize the EGLDevice backend first. Whenever we use a
- * non-NVIDIA GPU, the EGLDevice enumeration function won't find a match, and
- * we'll fall back to GBM (which will always succeed as it has a software
- * rendering fallback)
- */
- renderer_gpu_data = create_renderer_gpu_data_egl_device (renderer_native,
- gpu_kms,
- &egl_device_error);
- if (renderer_gpu_data)
- return renderer_gpu_data;
-#endif
-
- renderer_gpu_data = create_renderer_gpu_data_gbm (renderer_native,
- gpu_kms,
- &gbm_error);
- if (renderer_gpu_data)
+ gbm_renderer_gpu_data = create_renderer_gpu_data_gbm (renderer_native,
+ gpu_kms,
+ &gbm_error);
+ if (gbm_renderer_gpu_data)
{
+ if (gbm_renderer_gpu_data->secondary.is_hardware_rendering)
+ return gbm_renderer_gpu_data;
+ }
+
#ifdef HAVE_EGL_DEVICE
- g_error_free (egl_device_error);
-#endif
- return renderer_gpu_data;
+ egl_stream_renderer_gpu_data =
+ create_renderer_gpu_data_egl_device (renderer_native,
+ gpu_kms,
+ &egl_device_error);
+ if (egl_stream_renderer_gpu_data)
+ {
+ g_clear_pointer (&gbm_renderer_gpu_data,
+ meta_renderer_native_gpu_data_free);
+ return egl_stream_renderer_gpu_data;
}
+#endif
+
+ if (gbm_renderer_gpu_data)
+ return gbm_renderer_gpu_data;
g_set_error (error, G_IO_ERROR,
G_IO_ERROR_FAILED,
--
2.35.1

@ -1,38 +0,0 @@
From f37ef55525777f742051cb988341fa1bab403666 Mon Sep 17 00:00:00 2001
From: Robert Mader <robert.mader@posteo.de>
Date: Mon, 15 Apr 2019 02:02:10 +0200
Subject: [PATCH 2/2] wayland/dnd-surface: Propagate commit to parent class
We need to call the underlying actor-surface so the actor
state is synced, otherwise surface state like the scale factor
does not get applied.
Fixes https://gitlab.gnome.org/GNOME/mutter/issues/550
https://gitlab.gnome.org/GNOME/mutter/merge_requests/537
(cherry picked from commit 01d0316fd703872a2470a351f906ffa4605a647e)
---
src/wayland/meta-wayland-dnd-surface.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/wayland/meta-wayland-dnd-surface.c b/src/wayland/meta-wayland-dnd-surface.c
index 8ddeb2a7bd..7aa7e3be2f 100644
--- a/src/wayland/meta-wayland-dnd-surface.c
+++ b/src/wayland/meta-wayland-dnd-surface.c
@@ -51,9 +51,13 @@ dnd_surface_commit (MetaWaylandSurfaceRole *surface_role,
{
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role);
+ MetaWaylandSurfaceRoleClass *surface_role_class =
+ META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_surface_role_dnd_parent_class);
meta_wayland_compositor_add_frame_callback_surface (surface->compositor,
surface);
+
+ surface_role_class->commit (surface_role, pending);
}
static void
--
2.31.1

@ -0,0 +1,24 @@
From e434615ed1d4ba506e0282ad5cdc94303310c682 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@redhat.com>
Date: Wed, 16 Oct 2024 14:26:28 +0200
Subject: [PATCH 2/2] window: Avoid SIGFPE on bogus window size
---
src/core/window.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/core/window.c b/src/core/window.c
index 512ef9312f..142aa0eca1 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -2393,6 +2393,7 @@ window_would_mostly_be_covered_by_always_above_window (MetaWindow *window)
}
window_area = window->rect.width * window->rect.height;
+ g_return_val_if_fail (window_area > 0, FALSE);
cairo_region_intersect_rectangle (region, &window->rect);
intersection_area = calculate_region_area (region);
--
2.44.0.501.g19981daefd.dirty

@ -1,42 +0,0 @@
From 9a8bb8a205656ca1089444a041c99c5591477642 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Fri, 3 May 2019 18:10:47 +0000
Subject: [PATCH 2/2] window: Emit an error and return when trying to activate
an unmanaged
If something (i.e. gnome-shell or an extension) tries to activate an unmanaged
window, we should warn about this and avoid to perform further actions as this
could lead to a crash of mutter, since the window has not valid flags (like
workspace) set anymore at this stage.
Fixes https://gitlab.gnome.org/GNOME/mutter/issues/580
https://gitlab.gnome.org/GNOME/mutter/merge_requests/564
(cherry picked from commit a6fc656e917fd48b8708b8d9f4bf9f8b15581313)
---
src/core/window.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/core/window.c b/src/core/window.c
index d2c24506b..725cca7ce 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -3683,6 +3683,13 @@ meta_window_activate_full (MetaWindow *window,
{
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
gboolean allow_workspace_switch;
+
+ if (window->unmanaging)
+ {
+ g_warning ("Trying to activate unmanaged window '%s'", window->desc);
+ return;
+ }
+
meta_topic (META_DEBUG_FOCUS,
"_NET_ACTIVE_WINDOW message sent for %s at time %u "
"by client type %u.\n",
--
2.21.0

@ -1,90 +0,0 @@
From 56c2e4efdcef14531dcf752e89117d22a21ec8ad Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Wed, 9 Dec 2020 15:18:29 +0100
Subject: [PATCH 2/2] xwayland: Make sure /tmp/.X11-unix/ exists
When we're running under a polyinstantiated SELinux environment, we'll
likely start with an isolated and empty /tmp, meannig no /tmp/.X11-unix
directory to add things to. To make it possible to still function in
this kind of setup, make sure said directory exists.
---
src/wayland/meta-xwayland.c | 30 ++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c
index 699d5561c..f3df9766e 100644
--- a/src/wayland/meta-xwayland.c
+++ b/src/wayland/meta-xwayland.c
@@ -30,6 +30,7 @@
#include <glib-unix.h>
#include <glib.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <sys/un.h>
#include "compositor/meta-surface-actor-wayland.h"
@@ -436,9 +437,27 @@ meta_xwayland_override_display_number (int number)
display_number_override = number;
}
+static gboolean
+ensure_x11_unix_dir (GError **error)
+{
+ if (mkdir ("/tmp/.X11-unix", 01777) != 0)
+ {
+ if (errno == EEXIST)
+ return TRUE;
+
+ g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
+ "Failed to create directory \"/tmp/.X11-unix\": %s",
+ g_strerror (errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
static gboolean
choose_xdisplay (MetaXWaylandManager *manager)
{
+ g_autoptr (GError) error = NULL;
int display = 0;
char *lock_file = NULL;
@@ -447,10 +466,15 @@ choose_xdisplay (MetaXWaylandManager *manager)
else if (g_getenv ("RUNNING_UNDER_GDM"))
display = 1024;
- do
+ if (!ensure_x11_unix_dir (&error))
{
- g_autoptr (GError) error = NULL;
+ g_warning ("Failed to ensure X11 socket directory: %s",
+ error->message);
+ return FALSE;
+ }
+ do
+ {
lock_file = create_lock_file (display, &display, &error);
if (!lock_file)
{
@@ -466,6 +490,7 @@ choose_xdisplay (MetaXWaylandManager *manager)
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_ADDRESS_IN_USE))
{
meta_verbose ("Failed to bind abstract socket: %s\n", error->message);
+ g_clear_error (&error);
display++;
continue;
}
@@ -480,6 +505,7 @@ choose_xdisplay (MetaXWaylandManager *manager)
if (manager->unix_fd < 0)
{
meta_verbose ("Failed to bind unix socket: %s\n", error->message);
+ g_clear_error (&error);
unlink (lock_file);
close (manager->abstract_fd);
display++;
--
2.29.2

@ -1,167 +0,0 @@
From df565fcb681a50aac5046981c5aba04073d14856 Mon Sep 17 00:00:00 2001
From: Christian Hergert <christian@hergert.me>
Date: Fri, 21 Feb 2020 22:36:31 +0000
Subject: [PATCH 3/3] clutter: fix hole in ClutterPaintNode
Fixing the missalignment takes the structure from 80 bytes down to 72.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1081
---
clutter/clutter/clutter-actor.c | 8 +++----
clutter/clutter/clutter-canvas.c | 2 +-
clutter/clutter/clutter-image.c | 2 +-
clutter/clutter/clutter-paint-node-private.h | 6 ++---
clutter/clutter/clutter-paint-node.c | 23 +++++++++++++++-----
clutter/clutter/clutter-paint-node.h | 3 +++
6 files changed, 30 insertions(+), 14 deletions(-)
diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c
index 93d0a93ef..ff5c4a69d 100644
--- a/clutter/clutter/clutter-actor.c
+++ b/clutter/clutter/clutter-actor.c
@@ -3758,7 +3758,7 @@ clutter_actor_paint_node (ClutterActor *actor,
clear_flags |= COGL_BUFFER_BIT_COLOR;
node = clutter_root_node_new (fb, &bg_color, clear_flags);
- clutter_paint_node_set_name (node, "stageClear");
+ clutter_paint_node_set_static_name (node, "stageClear");
clutter_paint_node_add_rectangle (node, &box);
clutter_paint_node_add_child (root, node);
clutter_paint_node_unref (node);
@@ -3773,7 +3773,7 @@ clutter_actor_paint_node (ClutterActor *actor,
/ 255;
node = clutter_color_node_new (&bg_color);
- clutter_paint_node_set_name (node, "backgroundColor");
+ clutter_paint_node_set_static_name (node, "backgroundColor");
clutter_paint_node_add_rectangle (node, &box);
clutter_paint_node_add_child (root, node);
clutter_paint_node_unref (node);
@@ -4069,7 +4069,7 @@ clutter_actor_continue_paint (ClutterActor *self)
* virtual function can then be called directly.
*/
dummy = _clutter_dummy_node_new (self);
- clutter_paint_node_set_name (dummy, "Root");
+ clutter_paint_node_set_static_name (dummy, "Root");
/* XXX - for 1.12, we use the return value of paint_node() to
* decide whether we should emit the ::paint signal.
@@ -21427,7 +21427,7 @@ clutter_actor_create_texture_paint_node (ClutterActor *self,
color.alpha = clutter_actor_get_paint_opacity_internal (self);
node = clutter_texture_node_new (texture, &color, priv->min_filter, priv->mag_filter);
- clutter_paint_node_set_name (node, "Texture");
+ clutter_paint_node_set_static_name (node, "Texture");
if (priv->content_repeat == CLUTTER_REPEAT_NONE)
clutter_paint_node_add_rectangle (node, &box);
diff --git a/clutter/clutter/clutter-canvas.c b/clutter/clutter/clutter-canvas.c
index b0f1f080c..89c031be2 100644
--- a/clutter/clutter/clutter-canvas.c
+++ b/clutter/clutter/clutter-canvas.c
@@ -351,7 +351,7 @@ clutter_canvas_paint_content (ClutterContent *content,
return;
node = clutter_actor_create_texture_paint_node (actor, priv->texture);
- clutter_paint_node_set_name (node, "Canvas Content");
+ clutter_paint_node_set_static_name (node, "Canvas Content");
clutter_paint_node_add_child (root, node);
clutter_paint_node_unref (node);
diff --git a/clutter/clutter/clutter-image.c b/clutter/clutter/clutter-image.c
index 266c68799..790e09521 100644
--- a/clutter/clutter/clutter-image.c
+++ b/clutter/clutter/clutter-image.c
@@ -129,7 +129,7 @@ clutter_image_paint_content (ClutterContent *content,
return;
node = clutter_actor_create_texture_paint_node (actor, priv->texture);
- clutter_paint_node_set_name (node, "Image Content");
+ clutter_paint_node_set_static_name (node, "Image Content");
clutter_paint_node_add_child (root, node);
clutter_paint_node_unref (node);
}
diff --git a/clutter/clutter/clutter-paint-node-private.h b/clutter/clutter/clutter-paint-node-private.h
index d61b89951..720df1458 100644
--- a/clutter/clutter/clutter-paint-node-private.h
+++ b/clutter/clutter/clutter-paint-node-private.h
@@ -48,11 +48,11 @@ struct _ClutterPaintNode
ClutterPaintNode *next_sibling;
ClutterPaintNode *last_child;
- guint n_children;
-
GArray *operations;
- gchar *name;
+ const gchar *name;
+
+ guint n_children;
volatile int ref_count;
};
diff --git a/clutter/clutter/clutter-paint-node.c b/clutter/clutter/clutter-paint-node.c
index 73765a4e9..1f9451a43 100644
--- a/clutter/clutter/clutter-paint-node.c
+++ b/clutter/clutter/clutter-paint-node.c
@@ -171,8 +171,6 @@ clutter_paint_node_real_finalize (ClutterPaintNode *node)
{
ClutterPaintNode *iter;
- g_free (node->name);
-
if (node->operations != NULL)
{
guint i;
@@ -294,7 +292,8 @@ clutter_paint_node_get_type (void)
*
* The @name will be used for debugging purposes.
*
- * The @node will copy the passed string.
+ * The @node will intern @name using g_intern_string(). If you have access to a
+ * static string, use clutter_paint_node_set_static_name() instead.
*
* Since: 1.10
*/
@@ -304,8 +303,22 @@ clutter_paint_node_set_name (ClutterPaintNode *node,
{
g_return_if_fail (CLUTTER_IS_PAINT_NODE (node));
- g_free (node->name);
- node->name = g_strdup (name);
+ node->name = g_intern_string (name);
+}
+
+/**
+ * clutter_paint_node_set_static_name: (skip)
+ *
+ * Like clutter_paint_node_set_name() but uses a static or interned string
+ * containing the name.
+ */
+void
+clutter_paint_node_set_static_name (ClutterPaintNode *node,
+ const char *name)
+{
+ g_return_if_fail (CLUTTER_IS_PAINT_NODE (node));
+
+ node->name = name;
}
/**
diff --git a/clutter/clutter/clutter-paint-node.h b/clutter/clutter/clutter-paint-node.h
index c42abbc3d..7d25f1681 100644
--- a/clutter/clutter/clutter-paint-node.h
+++ b/clutter/clutter/clutter-paint-node.h
@@ -55,6 +55,9 @@ void clutter_paint_node_paint (Clutter
CLUTTER_EXPORT
void clutter_paint_node_set_name (ClutterPaintNode *node,
const char *name);
+CLUTTER_EXPORT
+void clutter_paint_node_set_static_name (ClutterPaintNode *node,
+ const char *name);
CLUTTER_EXPORT
void clutter_paint_node_add_child (ClutterPaintNode *node,
--
2.26.0

@ -1,77 +0,0 @@
From 04d921c2c1da571c8c61a4ca12a380bc3b9623fe Mon Sep 17 00:00:00 2001
From: Pekka Paalanen <pekka.paalanen@collabora.com>
Date: Mon, 6 May 2019 13:40:31 +0300
Subject: [PATCH 03/12] cogl: Replace ANGLE with GLES3 and NV framebuffer_blit
ANGLE extensions are only provided by Google's Almost Native Graphics Layer
Engine (ANGLE) implementation. Therefore they do not seem too useful for
Mutter.
The reason to drop GL_ANGLE_framebuffer_blit support is that it has more
limitations compared to the glBlitFramebuffer in GL_EXT_framebuffer_blit,
GL_NV_framebuffer_bit, OpenGL 3.0 and OpenGL ES 3.0. Most importantly, the
ANGLE version cannot flip the image while copying, which limits
_cogl_blit_framebuffer to only off-screen <-> off-screen copies. Follow-up work
will need off-screen <-> on-screen copies.
Instead of adding yet more capability flags to Cogl, dropping ANGLE support
seems appropriate.
The NV extension is added to the list of glBlitFramebuffer providers because it
provides the same support as ANGLE and more.
Likewise OpenGL ES 3.0 is added to the list of glBlitFramebuffer providers
because e.g. Mesa GLES implementation usually provides it and that makes it
widely available, again surpassing the ANGLE supported features.
Follow-up patches will lift some of the Cogl assumptions of what
glBlitFramebuffer cannot do.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/615
(cherry picked from commit 3e68c9e8faa78298039fa3583898f18550740812)
---
cogl/cogl/cogl-framebuffer-private.h | 3 +--
cogl/cogl/gl-prototypes/cogl-all-functions.h | 5 +++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h
index de886b64f..3aab852c4 100644
--- a/cogl/cogl/cogl-framebuffer-private.h
+++ b/cogl/cogl/cogl-framebuffer-private.h
@@ -387,8 +387,7 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
* Note that this function differs a lot from the glBlitFramebuffer
* function provided by the GL_EXT_framebuffer_blit extension. Notably
* it doesn't support having different sizes for the source and
- * destination rectangle. This isn't supported by the corresponding
- * GL_ANGLE_framebuffer_blit extension on GLES2.0 and it doesn't seem
+ * destination rectangle. This doesn't seem
* like a particularly useful feature. If the application wanted to
* scale the results it may make more sense to draw a primitive
* instead.
diff --git a/cogl/cogl/gl-prototypes/cogl-all-functions.h b/cogl/cogl/gl-prototypes/cogl-all-functions.h
index 924ee349d..0af126059 100644
--- a/cogl/cogl/gl-prototypes/cogl-all-functions.h
+++ b/cogl/cogl/gl-prototypes/cogl-all-functions.h
@@ -4,6 +4,7 @@
* A Low Level GPU Graphics and Utilities API
*
* Copyright (C) 2009, 2011 Intel Corporation.
+ * Copyright (C) 2019 DisplayLink (UK) Ltd.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -132,8 +133,8 @@ COGL_EXT_END ()
COGL_EXT_BEGIN (offscreen_blit, 3, 0,
- 0, /* not in either GLES */
- "EXT\0ANGLE\0",
+ COGL_EXT_IN_GLES3,
+ "EXT\0NV\0",
"framebuffer_blit\0")
COGL_EXT_FUNCTION (void, glBlitFramebuffer,
(GLint srcX0,
--
2.21.0

@ -0,0 +1,816 @@
From 0c104d85654318978d10d0fadf33ceea92e29c0a Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 13 Jun 2024 12:58:21 -0400
Subject: [PATCH 3/6] core/window: Split cgroup out to separate struct
We're going to need to attach other information to the cgroup,
aside from the cgroup path, so this commit separates it out
to its own struct, shared with other windows using the same
cgroup.
---
src/core/display-private.h | 17 +++++++++
src/core/display.c | 70 ++++++++++++++++++++++++++++++++++++++
src/core/window-private.h | 2 ++
src/core/window.c | 44 ++++++++++++++++++++++++
4 files changed, 133 insertions(+)
diff --git a/src/core/display-private.h b/src/core/display-private.h
index 3d690fcb6..fb17d20a6 100644
--- a/src/core/display-private.h
+++ b/src/core/display-private.h
@@ -78,98 +78,106 @@ typedef enum
META_TILE_LEFT,
META_TILE_RIGHT,
META_TILE_MAXIMIZED
} MetaTileMode;
typedef enum
{
/* Normal interaction where you're interacting with windows.
* Events go to windows normally. */
META_EVENT_ROUTE_NORMAL,
/* In a window operation like moving or resizing. All events
* goes to MetaWindow, but not to the actual client window. */
META_EVENT_ROUTE_WINDOW_OP,
/* In a compositor grab operation. All events go to the
* compositor plugin. */
META_EVENT_ROUTE_COMPOSITOR_GRAB,
/* A Wayland application has a popup open. All events go to
* the Wayland application. */
META_EVENT_ROUTE_WAYLAND_POPUP,
/* The user is clicking on a window button. */
META_EVENT_ROUTE_FRAME_BUTTON,
} MetaEventRoute;
typedef void (* MetaDisplayWindowFunc) (MetaWindow *window,
gpointer user_data);
+typedef struct _MetaCGroup MetaCGroup;
+struct _MetaCGroup {
+ GFile *path;
+
+ grefcount ref_count;
+};
+
struct _MetaDisplay
{
GObject parent_instance;
MetaX11Display *x11_display;
int clutter_event_filter;
/* Our best guess as to the "currently" focused window (that is, the
* window that we expect will be focused at the point when the X
* server processes our next request), and the serial of the request
* or event that caused this.
*/
MetaWindow *focus_window;
/* last timestamp passed to XSetInputFocus */
guint32 last_focus_time;
/* last user interaction time in any app */
guint32 last_user_time;
/* whether we're using mousenav (only relevant for sloppy&mouse focus modes;
* !mouse_mode means "keynav mode")
*/
guint mouse_mode : 1;
/* Helper var used when focus_new_windows setting is 'strict'; only
* relevant in 'strict' mode and if the focus window is a terminal.
* In that case, we don't allow new windows to take focus away from
* a terminal, but if the user explicitly did something that should
* allow a different window to gain focus (e.g. global keybinding or
* clicking on a dock), then we will allow the transfer.
*/
guint allow_terminal_deactivation : 1;
/*< private-ish >*/
GHashTable *stamps;
GHashTable *wayland_windows;
+ GHashTable *cgroups;
/* serials of leave/unmap events that may
* correspond to an enter event we should
* ignore
*/
unsigned long ignored_crossing_serials[N_IGNORED_CROSSING_SERIALS];
guint32 current_time;
/* We maintain a sequence counter, incremented for each #MetaWindow
* created. This is exposed by meta_window_get_stable_sequence()
* but is otherwise not used inside mutter.
*
* It can be useful to plugins which want to sort windows in a
* stable fashion.
*/
guint32 window_sequence_counter;
/* Pings which we're waiting for a reply from */
GSList *pending_pings;
/* Pending focus change */
guint focus_timeout_id;
/* Pending autoraise */
guint autoraise_timeout_id;
MetaWindow* autoraise_window;
/* Event routing */
MetaEventRoute event_route;
@@ -254,60 +262,69 @@ struct _MetaDisplayClass
*
* See the docs for meta_display_xserver_time_is_before().
*/
#define XSERVER_TIME_IS_BEFORE(time1, time2) \
( (time1) == 0 || \
(XSERVER_TIME_IS_BEFORE_ASSUMING_REAL_TIMESTAMPS(time1, time2) && \
(time2) != 0) \
)
gboolean meta_display_open (void);
void meta_display_manage_all_xwindows (MetaDisplay *display);
void meta_display_unmanage_windows (MetaDisplay *display,
guint32 timestamp);
/* Utility function to compare the stacking of two windows */
int meta_display_stack_cmp (const void *a,
const void *b);
/* Each MetaWindow is uniquely identified by a 64-bit "stamp"; unlike a
* a MetaWindow *, a stamp will never be recycled
*/
MetaWindow* meta_display_lookup_stamp (MetaDisplay *display,
guint64 stamp);
void meta_display_register_stamp (MetaDisplay *display,
guint64 *stampp,
MetaWindow *window);
void meta_display_unregister_stamp (MetaDisplay *display,
guint64 stamp);
+void meta_display_register_cgroup (MetaDisplay *display,
+ MetaWindow *window,
+ const char *path);
+void meta_display_unregister_cgroup (MetaDisplay *display,
+ MetaWindow *window);
+
+MetaCGroup* meta_cgroup_ref (MetaCGroup *cgroup);
+gboolean meta_cgroup_unref (MetaCGroup *cgroup);
+
/* A "stack id" is a XID or a stamp */
#define META_STACK_ID_IS_X11(id) ((id) < G_GUINT64_CONSTANT(0x100000000))
META_EXPORT_TEST
MetaWindow* meta_display_lookup_stack_id (MetaDisplay *display,
guint64 stack_id);
/* for debug logging only; returns a human-description of the stack
* ID - a small number of buffers are recycled, so the result must
* be used immediately or copied */
const char *meta_display_describe_stack_id (MetaDisplay *display,
guint64 stack_id);
void meta_display_register_wayland_window (MetaDisplay *display,
MetaWindow *window);
void meta_display_unregister_wayland_window (MetaDisplay *display,
MetaWindow *window);
void meta_display_notify_window_created (MetaDisplay *display,
MetaWindow *window);
META_EXPORT_TEST
GSList* meta_display_list_windows (MetaDisplay *display,
MetaListWindowsFlags flags);
MetaDisplay* meta_display_for_x_display (Display *xdisplay);
META_EXPORT_TEST
MetaDisplay* meta_get_display (void);
diff --git a/src/core/display.c b/src/core/display.c
index 4b58a5d2f..937defd2c 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -833,60 +833,61 @@ meta_display_open (void)
i = 0;
while (i < N_IGNORED_CROSSING_SERIALS)
{
display->ignored_crossing_serials[i] = 0;
++i;
}
display->current_time = META_CURRENT_TIME;
display->grab_resize_timeout_id = 0;
display->grab_have_keyboard = FALSE;
display->grab_op = META_GRAB_OP_NONE;
display->grab_window = NULL;
display->grab_tile_mode = META_TILE_NONE;
display->grab_tile_monitor_number = -1;
meta_display_cleanup_edges (display);
meta_display_init_keys (display);
meta_prefs_add_listener (prefs_changed_callback, display);
/* Get events */
meta_display_init_events (display);
display->stamps = g_hash_table_new (g_int64_hash,
g_int64_equal);
display->wayland_windows = g_hash_table_new (NULL, NULL);
+ display->cgroups = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
monitor_manager = meta_backend_get_monitor_manager (backend);
g_signal_connect (monitor_manager, "monitors-changed-internal",
G_CALLBACK (on_monitors_changed_internal), display);
display->pad_action_mapper = meta_pad_action_mapper_new (monitor_manager);
settings = meta_backend_get_settings (backend);
g_signal_connect (settings, "ui-scaling-factor-changed",
G_CALLBACK (on_ui_scaling_factor_changed), display);
display->compositor = create_compositor (display);
meta_display_set_cursor (display, META_CURSOR_DEFAULT);
display->stack = meta_stack_new (display);
display->stack_tracker = meta_stack_tracker_new (display);
display->workspace_manager = meta_workspace_manager_new (display);
display->startup_notification = meta_startup_notification_new (display);
display->bell = meta_bell_new (display);
display->selection = meta_selection_new (display);
meta_clipboard_manager_init (display);
#ifdef HAVE_WAYLAND
if (meta_is_wayland_compositor ())
{
@@ -1095,60 +1096,61 @@ meta_display_close (MetaDisplay *display,
meta_prefs_remove_listener (prefs_changed_callback, display);
meta_display_remove_autoraise_callback (display);
g_clear_object (&display->gesture_tracker);
g_clear_handle_id (&display->focus_timeout_id, g_source_remove);
g_clear_handle_id (&display->tile_preview_timeout_id, g_source_remove);
if (display->work_area_later != 0)
meta_later_remove (display->work_area_later);
if (display->check_fullscreen_later != 0)
meta_later_remove (display->check_fullscreen_later);
/* Stop caring about events */
meta_display_free_events (display);
g_clear_pointer (&display->compositor, meta_compositor_destroy);
meta_display_shutdown_x11 (display);
g_clear_object (&display->stack);
g_clear_pointer (&display->stack_tracker,
meta_stack_tracker_free);
/* Must be after all calls to meta_window_unmanage() since they
* unregister windows
*/
g_hash_table_destroy (display->wayland_windows);
g_hash_table_destroy (display->stamps);
+ g_hash_table_destroy (display->cgroups);
meta_display_shutdown_keys (display);
g_clear_object (&display->bell);
g_clear_object (&display->startup_notification);
g_clear_object (&display->workspace_manager);
g_clear_object (&display->sound_player);
meta_clipboard_manager_shutdown (display);
g_clear_object (&display->selection);
g_clear_object (&display->pad_action_mapper);
g_object_unref (display);
the_display = NULL;
meta_quit (META_EXIT_SUCCESS);
}
/**
* meta_display_for_x_display:
* @xdisplay: An X display
*
* Returns the singleton MetaDisplay if @xdisplay matches the X display it's
* managing; otherwise gives a warning and returns %NULL. When we were claiming
* to be able to manage multiple displays, this was supposed to find the
* display out of the list which matched that display. Now it's merely an
* extra sanity check.
*
* Returns: The singleton X display, or %NULL if @xdisplay isn't the one
* we're managing.
@@ -1491,60 +1493,128 @@ meta_display_set_input_focus (MetaDisplay *display,
meta_display_update_focus_window (display, window);
display->last_focus_time = timestamp;
if (window == NULL || window != display->autoraise_window)
meta_display_remove_autoraise_callback (display);
}
void
meta_display_unset_input_focus (MetaDisplay *display,
guint32 timestamp)
{
meta_display_set_input_focus (display, NULL, FALSE, timestamp);
}
void
meta_display_register_wayland_window (MetaDisplay *display,
MetaWindow *window)
{
g_hash_table_add (display->wayland_windows, window);
}
void
meta_display_unregister_wayland_window (MetaDisplay *display,
MetaWindow *window)
{
g_hash_table_remove (display->wayland_windows, window);
}
+MetaCGroup*
+meta_cgroup_new (const char *path)
+{
+ MetaCGroup *cgroup;
+
+ cgroup = g_new0 (MetaCGroup, 1);
+ cgroup->path = g_file_new_for_path (path);
+ g_ref_count_init (&cgroup->ref_count);
+
+ return cgroup;
+}
+
+MetaCGroup*
+meta_cgroup_ref (MetaCGroup *cgroup)
+{
+ g_ref_count_inc (&cgroup->ref_count);
+ return cgroup;
+}
+
+gboolean
+meta_cgroup_unref (MetaCGroup *cgroup)
+{
+ if (!g_ref_count_dec (&cgroup->ref_count))
+ return FALSE;
+
+ g_clear_object (&cgroup->path);
+ g_free (cgroup);
+
+ return TRUE;
+}
+
+void
+meta_display_register_cgroup (MetaDisplay *display,
+ MetaWindow *window,
+ const char *path)
+{
+ MetaCGroup *cgroup;
+
+ cgroup = g_hash_table_lookup (display->cgroups, path);
+
+ if (cgroup)
+ {
+ window->cgroup = meta_cgroup_ref (cgroup);
+ return;
+ }
+
+ cgroup = meta_cgroup_new (path);
+ g_hash_table_insert (display->cgroups, g_file_get_path (cgroup->path), cgroup);
+}
+
+void
+meta_display_unregister_cgroup (MetaDisplay *display,
+ MetaWindow *window)
+{
+ g_autofree const char *path = NULL;
+ MetaCGroup *cgroup = g_steal_pointer (&window->cgroup);
+
+ if (!cgroup)
+ return;
+
+ path = g_file_get_path (cgroup->path);
+
+ if (!meta_cgroup_unref (cgroup))
+ return;
+
+ g_hash_table_remove (display->cgroups, path);
+}
+
MetaWindow*
meta_display_lookup_stamp (MetaDisplay *display,
guint64 stamp)
{
return g_hash_table_lookup (display->stamps, &stamp);
}
void
meta_display_register_stamp (MetaDisplay *display,
guint64 *stampp,
MetaWindow *window)
{
g_return_if_fail (g_hash_table_lookup (display->stamps, stampp) == NULL);
g_hash_table_insert (display->stamps, stampp, window);
}
void
meta_display_unregister_stamp (MetaDisplay *display,
guint64 stamp)
{
g_return_if_fail (g_hash_table_lookup (display->stamps, &stamp) != NULL);
g_hash_table_remove (display->stamps, &stamp);
}
MetaWindow*
meta_display_lookup_stack_id (MetaDisplay *display,
guint64 stack_id)
{
diff --git a/src/core/window-private.h b/src/core/window-private.h
index d1730c988..8a0aebb38 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -193,60 +193,62 @@ struct _MetaWindow
* binary data
*/
char *res_class;
char *res_name;
char *role;
char *sm_client_id;
char *wm_client_machine;
char *startup_id;
char *mutter_hints;
char *sandboxed_app_id;
char *gtk_theme_variant;
char *gtk_application_id;
char *gtk_unique_bus_name;
char *gtk_application_object_path;
char *gtk_window_object_path;
char *gtk_app_menu_object_path;
char *gtk_menubar_object_path;
Window xtransient_for;
Window xgroup_leader;
Window xclient_leader;
MetaWindow *transient_for;
/* Initial workspace property */
int initial_workspace;
/* Initial timestamp property */
guint32 initial_timestamp;
+ MetaCGroup *cgroup;
+
/* Whether this is an override redirect window or not */
guint override_redirect : 1;
/* Whether we're maximized */
guint maximized_horizontally : 1;
guint maximized_vertically : 1;
/* Whether we have to maximize/minimize after placement */
guint maximize_horizontally_after_placement : 1;
guint maximize_vertically_after_placement : 1;
guint minimize_after_placement : 1;
/* The current tile mode */
MetaTileMode tile_mode;
/* The last "full" maximized/unmaximized state. We need to keep track of
* that to toggle between normal/tiled or maximized/tiled states. */
guint saved_maximize : 1;
int tile_monitor_number;
struct {
MetaEdgeConstraint top;
MetaEdgeConstraint right;
MetaEdgeConstraint bottom;
MetaEdgeConstraint left;
} edge_constraints;
double tile_hfraction;
uint64_t preferred_output_winsys_id;
diff --git a/src/core/window.c b/src/core/window.c
index e787dbce0..f5ecd6438 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -70,60 +70,65 @@
#include "cogl/cogl.h"
#include "core/boxes-private.h"
#include "core/constraints.h"
#include "core/edge-resistance.h"
#include "core/frame.h"
#include "core/keybindings-private.h"
#include "core/meta-workspace-manager-private.h"
#include "core/place.h"
#include "core/stack.h"
#include "core/util-private.h"
#include "core/workspace-private.h"
#include "meta/compositor-mutter.h"
#include "meta/group.h"
#include "meta/meta-cursor-tracker.h"
#include "meta/meta-enum-types.h"
#include "meta/meta-x11-errors.h"
#include "meta/prefs.h"
#include "ui/ui.h"
#include "x11/meta-x11-display-private.h"
#include "x11/window-props.h"
#include "x11/window-x11.h"
#include "x11/xprops.h"
#ifdef HAVE_WAYLAND
#include "wayland/meta-wayland-private.h"
#include "wayland/meta-wayland-surface.h"
#include "wayland/meta-window-wayland.h"
#include "wayland/meta-window-xwayland.h"
#endif
+#ifdef HAVE_LIBSYSTEMD
+#include <systemd/sd-login.h>
+#endif
+
+
/* Windows that unmaximize to a size bigger than that fraction of the workarea
* will be scaled down to that size (while maintaining aspect ratio).
* Windows that cover an area greater then this size are automaximized on map.
*/
#define MAX_UNMAXIMIZED_WINDOW_AREA .8
#define SNAP_SECURITY_LABEL_PREFIX "snap."
static int destroying_windows_disallowed = 0;
/* Each window has a "stamp" which is a non-recycled 64-bit ID. They
* start after the end of the XID space so that, for stacking
* we can keep a guint64 that represents one or the other
*/
static guint64 next_window_stamp = G_GUINT64_CONSTANT(0x100000000);
static void invalidate_work_areas (MetaWindow *window);
static void set_wm_state (MetaWindow *window);
static void set_net_wm_state (MetaWindow *window);
static void meta_window_set_above (MetaWindow *window,
gboolean new_value);
static void meta_window_show (MetaWindow *window);
static void meta_window_hide (MetaWindow *window);
static void meta_window_save_rect (MetaWindow *window);
static void ensure_mru_position_after (MetaWindow *window,
MetaWindow *after_this_one);
@@ -303,60 +308,63 @@ meta_window_real_get_client_pid (MetaWindow *window)
}
static void
meta_window_finalize (GObject *object)
{
MetaWindow *window = META_WINDOW (object);
if (window->icon)
cairo_surface_destroy (window->icon);
if (window->mini_icon)
cairo_surface_destroy (window->mini_icon);
if (window->frame_bounds)
cairo_region_destroy (window->frame_bounds);
if (window->shape_region)
cairo_region_destroy (window->shape_region);
if (window->opaque_region)
cairo_region_destroy (window->opaque_region);
if (window->input_region)
cairo_region_destroy (window->input_region);
if (window->transient_for)
g_object_unref (window->transient_for);
g_free (window->sm_client_id);
g_free (window->wm_client_machine);
+
+ meta_display_unregister_cgroup (window->display, window);
+
g_free (window->startup_id);
g_free (window->role);
g_free (window->res_class);
g_free (window->res_name);
g_free (window->title);
g_free (window->desc);
g_free (window->sandboxed_app_id);
g_free (window->gtk_theme_variant);
g_free (window->gtk_application_id);
g_free (window->gtk_unique_bus_name);
g_free (window->gtk_application_object_path);
g_free (window->gtk_window_object_path);
g_free (window->gtk_app_menu_object_path);
g_free (window->gtk_menubar_object_path);
g_free (window->placement.rule);
G_OBJECT_CLASS (meta_window_parent_class)->finalize (object);
}
static void
meta_window_get_property(GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
MetaWindow *win = META_WINDOW (object);
switch (prop_id)
{
case PROP_TITLE:
@@ -1129,60 +1137,61 @@ _meta_window_shared_new (MetaDisplay *display,
window->has_minimize_func = TRUE;
window->has_maximize_func = TRUE;
window->has_move_func = TRUE;
window->has_resize_func = TRUE;
window->has_shade_func = TRUE;
window->has_fullscreen_func = TRUE;
window->always_sticky = FALSE;
window->skip_taskbar = FALSE;
window->skip_pager = FALSE;
window->skip_from_window_list = FALSE;
window->wm_state_above = FALSE;
window->wm_state_below = FALSE;
window->wm_state_demands_attention = FALSE;
window->res_class = NULL;
window->res_name = NULL;
window->role = NULL;
window->sm_client_id = NULL;
window->wm_client_machine = NULL;
window->is_remote = FALSE;
window->startup_id = NULL;
window->client_pid = 0;
window->xtransient_for = None;
window->xclient_leader = None;
+ window->cgroup = NULL;
window->type = META_WINDOW_NORMAL;
window->struts = NULL;
window->layer = META_LAYER_LAST; /* invalid value */
window->stack_position = -1;
window->initial_workspace = 0; /* not used */
window->initial_timestamp = 0; /* not used */
window->compositor_private = NULL;
window->monitor = meta_window_calculate_main_logical_monitor (window);
if (window->monitor)
window->preferred_output_winsys_id = window->monitor->winsys_id;
else
window->preferred_output_winsys_id = UINT_MAX;
window->tile_match = NULL;
/* Assign this #MetaWindow a sequence number which can be used
* for sorting.
*/
window->stable_sequence = ++display->window_sequence_counter;
window->opacity = 0xFF;
if (window->override_redirect)
{
window->decorated = FALSE;
@@ -7640,60 +7649,95 @@ meta_window_get_transient_for (MetaWindow *window)
else if (window->xtransient_for)
return meta_x11_display_lookup_x_window (window->display->x11_display,
window->xtransient_for);
else
return NULL;
}
/**
* meta_window_get_pid:
* @window: a #MetaWindow
*
* Returns the pid of the process that created this window, if available
* to the windowing system.
*
* Note that the value returned by this is vulnerable to spoofing attacks
* by the client.
*
* Return value: the pid, or 0 if not known.
*/
pid_t
meta_window_get_pid (MetaWindow *window)
{
g_return_val_if_fail (META_IS_WINDOW (window), 0);
if (window->client_pid == 0)
window->client_pid = META_WINDOW_GET_CLASS (window)->get_client_pid (window);
return window->client_pid;
}
+static void
+meta_window_read_cgroup (MetaWindow *window)
+{
+#ifdef HAVE_LIBSYSTEMD
+ g_autofree char *contents = NULL;
+ g_autofree char *complete_path = NULL;
+ g_autofree char *unit_name = NULL;
+ g_autofree char *unit_path = NULL;
+ char *unit_end;
+ pid_t pid;
+
+ if (window->cgroup)
+ return;
+
+ pid = meta_window_get_pid (window);
+ if (pid < 1)
+ return;
+
+ if (sd_pid_get_cgroup (pid, &contents) < 0)
+ return;
+ g_strstrip (contents);
+
+ complete_path = g_strdup_printf ("%s%s", "/sys/fs/cgroup", contents);
+
+ if (sd_pid_get_user_unit (pid, &unit_name) < 0)
+ return;
+ g_strstrip (unit_name);
+
+ unit_end = strstr (complete_path, unit_name) + strlen (unit_name);
+ *unit_end = '\0';
+
+ meta_display_register_cgroup (window->display, window, complete_path);
+#endif
+}
+
/**
* meta_window_get_client_machine:
* @window: a #MetaWindow
*
* Returns name of the client machine from which this windows was created,
* if known (obtained from the WM_CLIENT_MACHINE property).
*
* Return value: (transfer none): the machine name, or NULL; the string is
* owned by the window manager and should not be freed or modified by the
* caller.
*/
const char *
meta_window_get_client_machine (MetaWindow *window)
{
g_return_val_if_fail (META_IS_WINDOW (window), NULL);
return window->wm_client_machine;
}
/**
* meta_window_is_remote:
* @window: a #MetaWindow
*
* Returns: %TRUE if this window originates from a host
* different from the one running mutter.
*/
gboolean
meta_window_is_remote (MetaWindow *window)
{
return window->is_remote;
--
2.44.0

@ -0,0 +1,37 @@
From 8d6e41fc9b5194fb24523c939de54a2af46b5d07 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Fri, 27 May 2022 18:19:27 +0200
Subject: [PATCH] kms/crtc: Determine gamma support given the gamma length
The property doesn't necessarily exist when using drivers that doesn't
support atomic mode setting, and the way it worked will break night
light and other gamma related features. This makes things use the gamma
length; if it is higher than 0, it definitely supports it one way or the
other, i.e. GAMMA_LUT with the atomic backend, and drmModeCrtcSetGamma()
with the legacy/simple backend.
Fixes: 364572b95c8354ac66674064a8058aa98bc0bbef
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2287
(cherry picked from commit a2ebd10f049d888e451938e23a035ed97e0c8eff)
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2452>
---
src/backends/native/meta-kms-crtc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c
index 24f5a2d7400..0513af947c9 100644
--- a/src/backends/native/meta-kms-crtc.c
+++ b/src/backends/native/meta-kms-crtc.c
@@ -96,7 +96,7 @@ meta_kms_crtc_is_active (MetaKmsCrtc *crtc)
gboolean
meta_kms_crtc_has_gamma (MetaKmsCrtc *crtc)
{
- return !!meta_kms_crtc_get_prop_id (crtc, META_KMS_CRTC_PROP_GAMMA_LUT);
+ return crtc->current_state.gamma.size > 0;
}
static void
--
2.36.1

@ -1,108 +0,0 @@
From 914fd2bec65c2e9928b03d5bc94930bc0151f998 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Wed, 17 Jun 2020 17:48:05 +0200
Subject: [PATCH 3/4] screen-cast: Move DMA buffer allocation to MetaScreenCast
The aim with centralizing it is to be able to apply global policy to DMA
buffer allocations, e.g. disabling due to various hueristics.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1318
---
src/backends/meta-screen-cast-stream-src.c | 18 ++++++--------
src/backends/meta-screen-cast.c | 28 ++++++++++++++++++++++
src/backends/meta-screen-cast.h | 4 ++++
3 files changed, 39 insertions(+), 11 deletions(-)
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
index ff4af440c1..b77186415f 100644
--- a/src/backends/meta-screen-cast-stream-src.c
+++ b/src/backends/meta-screen-cast-stream-src.c
@@ -649,10 +649,10 @@ on_stream_add_buffer (void *data,
MetaScreenCastStreamSrc *src = data;
MetaScreenCastStreamSrcPrivate *priv =
meta_screen_cast_stream_src_get_instance_private (src);
- CoglContext *context =
- clutter_backend_get_cogl_context (clutter_get_default_backend ());
- CoglRenderer *renderer = cogl_context_get_renderer (context);
- g_autoptr (GError) error = NULL;
+ MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
+ MetaScreenCastSession *session = meta_screen_cast_stream_get_session (stream);
+ MetaScreenCast *screen_cast =
+ meta_screen_cast_session_get_screen_cast (session);
CoglDmaBufHandle *dmabuf_handle;
struct spa_buffer *spa_buffer = buffer->buffer;
struct spa_data *spa_data = spa_buffer->datas;
@@ -664,13 +664,9 @@ on_stream_add_buffer (void *data,
spa_data[0].mapoffset = 0;
spa_data[0].maxsize = stride * priv->video_format.size.height;
- dmabuf_handle = cogl_renderer_create_dma_buf (renderer,
- priv->stream_width,
- priv->stream_height,
- &error);
-
- if (error)
- g_debug ("Error exporting DMA buffer handle: %s", error->message);
+ dmabuf_handle = meta_screen_cast_create_dma_buf_handle (screen_cast,
+ priv->stream_width,
+ priv->stream_height);
if (dmabuf_handle)
{
diff --git a/src/backends/meta-screen-cast.c b/src/backends/meta-screen-cast.c
index 46bc268389..5f1ca8b5ca 100644
--- a/src/backends/meta-screen-cast.c
+++ b/src/backends/meta-screen-cast.c
@@ -94,6 +94,34 @@ meta_screen_cast_get_backend (MetaScreenCast *screen_cast)
return screen_cast->backend;
}
+CoglDmaBufHandle *
+meta_screen_cast_create_dma_buf_handle (MetaScreenCast *screen_cast,
+ int width,
+ int height)
+{
+ ClutterBackend *clutter_backend =
+ meta_backend_get_clutter_backend (screen_cast->backend);
+ CoglContext *cogl_context =
+ clutter_backend_get_cogl_context (clutter_backend);
+ CoglRenderer *cogl_renderer = cogl_context_get_renderer (cogl_context);
+ g_autoptr (GError) error = NULL;
+ CoglDmaBufHandle *dmabuf_handle;
+
+ dmabuf_handle = cogl_renderer_create_dma_buf (cogl_renderer,
+ width, height,
+ &error);
+ if (!dmabuf_handle)
+ {
+ g_warning ("Failed to allocate DMA buffer, "
+ "disabling DMA buffer based screen casting: %s",
+ error->message);
+ screen_cast->disable_dma_bufs = TRUE;
+ return NULL;
+ }
+
+ return dmabuf_handle;
+}
+
static gboolean
register_remote_desktop_screen_cast_session (MetaScreenCastSession *session,
const char *remote_desktop_session_id,
diff --git a/src/backends/meta-screen-cast.h b/src/backends/meta-screen-cast.h
index a3b650cd80..fb5a38f34f 100644
--- a/src/backends/meta-screen-cast.h
+++ b/src/backends/meta-screen-cast.h
@@ -50,6 +50,10 @@ GDBusConnection * meta_screen_cast_get_connection (MetaScreenCast *screen_cast);
MetaBackend * meta_screen_cast_get_backend (MetaScreenCast *screen_cast);
+CoglDmaBufHandle * meta_screen_cast_create_dma_buf_handle (MetaScreenCast *screen_cast,
+ int width,
+ int height);
+
MetaScreenCast * meta_screen_cast_new (MetaBackend *backend,
MetaDbusSessionWatcher *session_watcher);
--
2.26.2

@ -0,0 +1,100 @@
From 07f63ad466b66cc02b49a326789686bce9325201 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Thu, 14 Oct 2021 18:36:43 +0200
Subject: [PATCH 3/5] wayland: Only init EGLStream controller if we didn't end
up with gbm
When we use gbm together with the NVIDIA driver, we want the EGL/Vulkan
clients to do the same, instead of using the EGLStream paths. To achieve
that, make sure to only initialize the EGLStream controller when we
didn't end up using gbm as the renderer backend.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2052>
(cherry picked from commit ac907119ae0f415c099976635c3b1dff4d2d7201)
(cherry picked from commit e3931f7b8cbd44072137c5dc9de9041486daeade)
---
src/backends/native/meta-renderer-native.c | 11 +++++++++
src/backends/native/meta-renderer-native.h | 2 ++
src/wayland/meta-wayland.c | 26 ++++++++++++++++++++--
3 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index c851619a1..e7460fbf1 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -201,6 +201,17 @@ meta_renderer_native_has_pending_mode_set (MetaRendererNative *renderer_native)
return renderer_native->pending_mode_set;
}
+MetaRendererNativeMode
+meta_renderer_native_get_mode (MetaRendererNative *renderer_native)
+{
+ MetaGpuKms *primary_gpu = renderer_native->primary_gpu_kms;
+ MetaRendererNativeGpuData *primary_gpu_data;
+
+ primary_gpu_data = meta_renderer_native_get_gpu_data (renderer_native,
+ primary_gpu);
+ return primary_gpu_data->mode;
+}
+
static void
meta_renderer_native_disconnect (CoglRenderer *cogl_renderer)
{
diff --git a/src/backends/native/meta-renderer-native.h b/src/backends/native/meta-renderer-native.h
index 9475e1857..8c06c2473 100644
--- a/src/backends/native/meta-renderer-native.h
+++ b/src/backends/native/meta-renderer-native.h
@@ -66,4 +66,6 @@ void meta_renderer_native_reset_modes (MetaRendererNative *renderer_native);
gboolean meta_renderer_native_use_modifiers (MetaRendererNative *renderer_native);
+MetaRendererNativeMode meta_renderer_native_get_mode (MetaRendererNative *renderer_native);
+
#endif /* META_RENDERER_NATIVE_H */
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index 8f16aa429..a3f098410 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -50,6 +50,10 @@
#include "wayland/meta-xwayland-private.h"
#include "wayland/meta-xwayland.h"
+#ifdef HAVE_NATIVE_BACKEND
+#include "backends/native/meta-renderer-native.h"
+#endif
+
static char *_display_name_override;
G_DEFINE_TYPE (MetaWaylandCompositor, meta_wayland_compositor, G_TYPE_OBJECT)
@@ -521,8 +525,26 @@ meta_wayland_compositor_setup (MetaWaylandCompositor *compositor)
compositor);
#ifdef HAVE_WAYLAND_EGLSTREAM
- meta_wayland_eglstream_controller_init (compositor);
-#endif
+ {
+ gboolean should_enable_eglstream_controller = TRUE;
+#if defined(HAVE_EGL_DEVICE) && defined(HAVE_NATIVE_BACKEND)
+ MetaBackend *backend = meta_get_backend ();
+ MetaRenderer *renderer = meta_backend_get_renderer (backend);
+
+ if (META_IS_RENDERER_NATIVE (renderer))
+ {
+ MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
+
+ if (meta_renderer_native_get_mode (renderer_native) ==
+ META_RENDERER_NATIVE_MODE_GBM)
+ should_enable_eglstream_controller = FALSE;
+ }
+#endif /* defined(HAVE_EGL_DEVICE) && defined(HAVE_NATIVE_BACKEND) */
+
+ if (should_enable_eglstream_controller)
+ meta_wayland_eglstream_controller_init (compositor);
+ }
+#endif /* HAVE_WAYLAND_EGLSTREAM */
if (meta_get_x11_display_policy () != META_DISPLAY_POLICY_DISABLED)
{
--
2.35.1

@ -0,0 +1,36 @@
From dd887dcf4770309fca127217660c5142a463e2c1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Tue, 27 Aug 2024 11:33:23 +0200
Subject: [PATCH 3/5] window: Unregister cgroup on unmanage()
This means any potential reference held by gjs will not hold the cgroup
alive longer than necessary.
---
src/core/window.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/core/window.c b/src/core/window.c
index 142aa0eca1..272d664965 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -339,8 +339,6 @@ meta_window_finalize (GObject *object)
g_free (window->sm_client_id);
g_free (window->wm_client_machine);
- meta_display_unregister_cgroup (window->display, window);
-
g_free (window->startup_id);
g_free (window->role);
g_free (window->res_class);
@@ -1467,6 +1465,8 @@ meta_window_unmanage (MetaWindow *window,
meta_verbose ("Unmanaging %s", window->desc);
window->unmanaging = TRUE;
+ meta_display_unregister_cgroup (window->display, window);
+
g_clear_handle_id (&window->unmanage_idle_id, g_source_remove);
g_signal_emit (window, window_signals[UNMANAGING], 0);
--
2.44.0.501.g19981daefd.dirty

@ -1,100 +0,0 @@
From 6c6c6ad5412f5bb13592630d7cb3b7aed25d159b Mon Sep 17 00:00:00 2001
From: Pekka Paalanen <pekka.paalanen@collabora.com>
Date: Mon, 6 May 2019 14:09:16 +0300
Subject: [PATCH 04/12] cogl: Relax formats on glBlitFramebuffer
Depends on: "cogl: Replace ANGLE with GLES3 and NV framebuffer_blit"
As a possible ANGLE implementation is not longer limiting the pixel format
matching, lift the requirement of having the same pixel format.
We still cannot do a premult <-> non-premult conversion during a blit, so guard
against that.
This will be useful in follow-up work to copy from onscreen primary GPU
framebuffer to an offscreen secondary GPU framebuffer if the formats do not
match exactly.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/615
(cherry picked from commit 6df34eb4b7c65210f4066f7eb9bd462278b7279b)
---
cogl/cogl/cogl-blit.c | 10 ++++++----
cogl/cogl/cogl-framebuffer-private.h | 8 ++++++--
cogl/cogl/cogl-framebuffer.c | 6 ++++--
3 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/cogl/cogl/cogl-blit.c b/cogl/cogl/cogl-blit.c
index 74f404f3d..a61eb66d2 100644
--- a/cogl/cogl/cogl-blit.c
+++ b/cogl/cogl/cogl-blit.c
@@ -4,6 +4,7 @@
* A Low Level GPU Graphics and Utilities API
*
* Copyright (C) 2011 Intel Corporation.
+ * Copyright (C) 2019 DisplayLink (UK) Ltd.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -152,10 +153,11 @@ _cogl_blit_framebuffer_begin (CoglBlitData *data)
CoglFramebuffer *dst_fb, *src_fb;
CoglError *ignore_error = NULL;
- /* We can only blit between FBOs if both textures are the same
- format and the blit framebuffer extension is supported */
- if ((_cogl_texture_get_format (data->src_tex) & ~COGL_A_BIT) !=
- (_cogl_texture_get_format (data->dst_tex) & ~COGL_A_BIT) ||
+ /* We can only blit between FBOs if both textures have the same
+ premult convention and the blit framebuffer extension is
+ supported. */
+ if ((_cogl_texture_get_format (data->src_tex) & COGL_PREMULT_BIT) !=
+ (_cogl_texture_get_format (data->dst_tex) & COGL_PREMULT_BIT) ||
!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT))
return FALSE;
diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h
index 3aab852c4..b06fbaee1 100644
--- a/cogl/cogl/cogl-framebuffer-private.h
+++ b/cogl/cogl/cogl-framebuffer-private.h
@@ -381,8 +381,12 @@ _cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
* This blits a region of the color buffer of the source buffer
* to the destination buffer. This function should only be
* called if the COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT feature is
- * advertised. The two buffers must both be offscreen and have the
- * same format.
+ * advertised. The two buffers must both be offscreen.
+ *
+ * The two buffers must have the same value types (e.g. floating-point,
+ * unsigned int, signed int, or fixed-point), but color formats do not
+ * need to match. This limitation comes from OpenGL ES 3.0 definition
+ * of glBlitFramebuffer.
*
* Note that this function differs a lot from the glBlitFramebuffer
* function provided by the GL_EXT_framebuffer_blit extension. Notably
diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c
index bd8a7fa42..0bc225945 100644
--- a/cogl/cogl/cogl-framebuffer.c
+++ b/cogl/cogl/cogl-framebuffer.c
@@ -4,6 +4,7 @@
* A Low Level GPU Graphics and Utilities API
*
* Copyright (C) 2007,2008,2009,2012 Intel Corporation.
+ * Copyright (C) 2019 DisplayLink (UK) Ltd.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -1468,8 +1469,9 @@ _cogl_blit_framebuffer (CoglFramebuffer *src,
support this */
_COGL_RETURN_IF_FAIL (cogl_is_offscreen (src));
_COGL_RETURN_IF_FAIL (cogl_is_offscreen (dest));
- /* The buffers must be the same format */
- _COGL_RETURN_IF_FAIL (src->internal_format == dest->internal_format);
+ /* The buffers must use the same premult convention */
+ _COGL_RETURN_IF_FAIL ((src->internal_format & COGL_PREMULT_BIT) ==
+ (dest->internal_format & COGL_PREMULT_BIT));
/* Make sure the current framebuffers are bound. We explicitly avoid
flushing the clip state so we can bind our own empty state */
--
2.21.0

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save