import mutter-3.32.2-4.el8

This commit is contained in:
CentOS Sources 2019-08-01 11:09:59 -04:00 committed by Stepan Oksanichenko
commit 1e5a152a7b
30 changed files with 5734 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
SOURCES/mutter-3.32.2.tar.xz

1
.mutter.metadata Normal file
View File

@ -0,0 +1 @@
5068f43514a6212e4b5b5f7f856b7713cbc3d420 SOURCES/mutter-3.32.2.tar.xz

View File

@ -0,0 +1,909 @@
From 2b45c3e37da7a590227e965d8a18e89337b791ba 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 | 86 ++++++++++-
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, 483 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 ea8daa03d..9665ce2b6 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -102,8 +102,10 @@ struct _MetaShapedTexture
ClutterActor parent;
MetaTextureTower *paint_tower;
+ MetaTextureTower *paint_tower_right;
CoglTexture *texture;
+ CoglTexture *texture_right;
CoglTexture *mask_texture;
CoglSnippet *snippet;
@@ -193,6 +195,9 @@ meta_shaped_texture_init (MetaShapedTexture *stex)
stex->paint_tower = meta_texture_tower_new ();
+ stex->paint_tower = meta_texture_tower_new ();
+ stex->paint_tower_right = NULL; /* demand create */
+
stex->texture = NULL;
stex->mask_texture = NULL;
stex->create_mipmaps = TRUE;
@@ -335,6 +340,9 @@ 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->opaque_region, cairo_region_destroy);
@@ -611,8 +619,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;
@@ -620,10 +629,13 @@ set_cogl_texture (MetaShapedTexture *stex,
if (stex->texture)
cogl_object_unref (stex->texture);
+ if (stex->texture_right)
+ cogl_object_unref (stex->texture_right);
g_clear_pointer (&stex->saved_base_surface, cairo_surface_destroy);
stex->texture = cogl_tex;
+ stex->texture_right = cogl_tex_right;
if (cogl_tex != NULL)
{
@@ -637,6 +649,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)
{
@@ -650,8 +665,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
@@ -927,7 +957,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;
@@ -989,7 +1021,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
@@ -1063,6 +1120,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);
+ }
}
}
@@ -1256,6 +1319,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 ();
@@ -1302,17 +1371,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.21.0

View File

@ -0,0 +1,349 @@
From 471174ba6cf517baf8ff73e903202e1c73b6ec74 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 | 268 +++++++++++++++++++++
1 file changed, 268 insertions(+)
diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c
index 89f07ee1f..051a1c605 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,180 @@ 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 ();
+ MetaX11Display *x11_display = display ? display->x11_display : NULL;
+ 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);
+
+ if (x11_display)
+ meta_x11_error_trap_push (x11_display);
+ 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 (x11_display && meta_x11_error_trap_pop_with_return (x11_display))
+ {
+ 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 ();
+ MetaX11Display *x11_display = display ? display->x11_display : NULL;
+ 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 */
+ states = XGetFeedbackControl (xdisplay, xdevice, &num_feedbacks);
+ 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;
+ }
+
+ if (x11_display)
+ meta_x11_error_trap_push (x11_display);
+
+ 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 (x11_display && meta_x11_error_trap_pop_with_return (x11_display))
+ {
+ 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 +345,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 +404,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 +436,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 +472,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 +508,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 +542,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 +587,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.21.0

View File

@ -0,0 +1,61 @@
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

View File

@ -0,0 +1,27 @@
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

View File

@ -0,0 +1,136 @@
From 78bb1fff1155462638b0d6037ccddf1328482842 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Tue, 15 Jan 2019 11:01:38 -0500
Subject: [PATCH 1/9] cogl: add new UNSTABLE_TEXTURES feature
The proprietary nvidia driver garbles texture memory on suspend.
Before we can address that, we need to be able to detect it.
This commit adds a new UNSTABLE_TEXTURES feature that gets set if
the proprietary nvidia driver is in use.
---
cogl/cogl/cogl-context.h | 1 +
cogl/cogl/cogl-types.h | 5 ++++-
cogl/cogl/winsys/cogl-winsys-egl.c | 11 +++++++++++
cogl/cogl/winsys/cogl-winsys-glx.c | 13 +++++++++++--
4 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/cogl/cogl/cogl-context.h b/cogl/cogl/cogl-context.h
index d4104625e..a20c54549 100644
--- a/cogl/cogl/cogl-context.h
+++ b/cogl/cogl/cogl-context.h
@@ -261,6 +261,7 @@ typedef enum _CoglFeatureID
COGL_FEATURE_ID_TEXTURE_RG,
COGL_FEATURE_ID_BUFFER_AGE,
COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL,
+ COGL_FEATURE_ID_UNSTABLE_TEXTURES,
/*< private >*/
_COGL_N_FEATURE_IDS /*< skip >*/
diff --git a/cogl/cogl/cogl-types.h b/cogl/cogl/cogl-types.h
index 690daa16a..5b980a43c 100644
--- a/cogl/cogl/cogl-types.h
+++ b/cogl/cogl/cogl-types.h
@@ -354,6 +354,8 @@ typedef enum /*< prefix=COGL_PIXEL_FORMAT >*/
* supported with CoglBufferAccess including write support.
* @COGL_FEATURE_DEPTH_TEXTURE: Whether #CoglFramebuffer support rendering the
* depth buffer to a texture.
+ * @COGL_FEATURE_UNSTABLE_TEXTURES: Whether textures require redrawing on
+ * resume or not.
*
* Flags for the supported features.
*
@@ -383,7 +385,8 @@ typedef enum
COGL_FEATURE_MAP_BUFFER_FOR_READ = (1 << 21),
COGL_FEATURE_MAP_BUFFER_FOR_WRITE = (1 << 22),
COGL_FEATURE_ONSCREEN_MULTIPLE = (1 << 23),
- COGL_FEATURE_DEPTH_TEXTURE = (1 << 24)
+ COGL_FEATURE_DEPTH_TEXTURE = (1 << 24),
+ COGL_FEATURE_UNSTABLE_TEXTURES = (1 << 25)
} CoglFeatureFlags;
/**
diff --git a/cogl/cogl/winsys/cogl-winsys-egl.c b/cogl/cogl/winsys/cogl-winsys-egl.c
index 903c6492d..dd450d4f3 100644
--- a/cogl/cogl/winsys/cogl-winsys-egl.c
+++ b/cogl/cogl/winsys/cogl-winsys-egl.c
@@ -499,6 +499,7 @@ _cogl_winsys_context_init (CoglContext *context, CoglError **error)
CoglRenderer *renderer = context->display->renderer;
CoglDisplayEGL *egl_display = context->display->winsys;
CoglRendererEGL *egl_renderer = renderer->winsys;
+ CoglGpuInfo *info;
context->winsys = g_new0 (CoglContextEGL, 1);
@@ -511,6 +512,16 @@ _cogl_winsys_context_init (CoglContext *context, CoglError **error)
if (!_cogl_context_update_features (context, error))
return FALSE;
+ info = &context->gpu;
+
+ if (info->vendor == COGL_GPU_INFO_VENDOR_NVIDIA)
+ {
+ context->feature_flags |= COGL_FEATURE_UNSTABLE_TEXTURES;
+ COGL_FLAGS_SET (context->features,
+ COGL_FEATURE_ID_UNSTABLE_TEXTURES,
+ TRUE);
+ }
+
if (egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_SWAP_REGION)
{
COGL_FLAGS_SET (context->winsys_features,
diff --git a/cogl/cogl/winsys/cogl-winsys-glx.c b/cogl/cogl/winsys/cogl-winsys-glx.c
index 235cfe81f..7e87dc15f 100644
--- a/cogl/cogl/winsys/cogl-winsys-glx.c
+++ b/cogl/cogl/winsys/cogl-winsys-glx.c
@@ -830,12 +830,15 @@ update_winsys_features (CoglContext *context, CoglError **error)
{
CoglGLXDisplay *glx_display = context->display->winsys;
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
+ CoglGpuInfo *info;
_COGL_RETURN_VAL_IF_FAIL (glx_display->glx_context, FALSE);
if (!_cogl_context_update_features (context, error))
return FALSE;
+ info = &context->gpu;
+
memcpy (context->winsys_features,
glx_renderer->base_winsys_features,
sizeof (context->winsys_features));
@@ -848,7 +851,6 @@ update_winsys_features (CoglContext *context, CoglError **error)
if (glx_renderer->glXCopySubBuffer || context->glBlitFramebuffer)
{
- CoglGpuInfo *info = &context->gpu;
CoglGpuInfoArchitecture arch = info->architecture;
COGL_FLAGS_SET (context->winsys_features, COGL_WINSYS_FEATURE_SWAP_REGION, TRUE);
@@ -897,7 +899,6 @@ update_winsys_features (CoglContext *context, CoglError **error)
}
else
{
- CoglGpuInfo *info = &context->gpu;
if (glx_display->have_vblank_counter &&
context->display->renderer->xlib_enable_threaded_swap_wait &&
info->vendor == COGL_GPU_INFO_VENDOR_NVIDIA)
@@ -919,6 +920,14 @@ update_winsys_features (CoglContext *context, CoglError **error)
}
}
+ if (info->vendor == COGL_GPU_INFO_VENDOR_NVIDIA)
+ {
+ context->feature_flags |= COGL_FEATURE_UNSTABLE_TEXTURES;
+ COGL_FLAGS_SET (context->features,
+ COGL_FEATURE_ID_UNSTABLE_TEXTURES,
+ TRUE);
+ }
+
/* We'll manually handle queueing dirty events in response to
* Expose events from X */
COGL_FLAGS_SET (context->private_features,
--
2.21.0

View File

@ -0,0 +1,55 @@
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

View File

@ -0,0 +1,42 @@
From f735f345ad8390a7fb09ef54ca3e0e419d395d1b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Thu, 21 Jul 2016 15:43:12 +0200
Subject: [PATCH] events: Don't move (sloppy) focus while buttons are pressed
(https://bugzilla.redhat.com/show_bug.cgi?id=1358535)
---
src/x11/events.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/src/x11/events.c b/src/x11/events.c
index e363fdbb6..905b5bf9d 100644
--- a/src/x11/events.c
+++ b/src/x11/events.c
@@ -832,6 +832,16 @@ crossing_serial_is_ignored (MetaX11Display *x11_display,
return FALSE;
}
+static gboolean
+event_has_button_mask (XIEnterEvent *enter_event)
+{
+ int i;
+ for (i = 0; i < enter_event->buttons.mask_len; i++)
+ if (enter_event->buttons.mask[i] != '\0')
+ return TRUE;
+ return FALSE;
+}
+
static gboolean
handle_input_xevent (MetaX11Display *x11_display,
XIEvent *input_event,
@@ -876,6 +886,7 @@ handle_input_xevent (MetaX11Display *x11_display,
* avoid races.
*/
if (window && !crossing_serial_is_ignored (x11_display, serial) &&
+ !event_has_button_mask (enter_event) &&
enter_event->mode != XINotifyGrab &&
enter_event->mode != XINotifyUngrab &&
enter_event->detail != XINotifyInferior &&
--
2.21.0

View File

@ -0,0 +1,49 @@
From 18d4fbb1fb641e2b507b3adcd13d231145a01cd6 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Tue, 13 Feb 2018 09:44:50 -0500
Subject: [PATCH] main: be more aggressive in assuming X11 backend
If the session is started by vncserver right now, the
XDG_SESSION_TYPE won't be X11. Ideally that would be
fixed, but for backward compatibility we should default
to X11 if the session type isn't set to wayland explicitly.
---
src/core/main.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/src/core/main.c b/src/core/main.c
index 629f8e94e..1e1e13367 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -333,7 +333,6 @@ find_session_type (void)
char *session_id;
char *session_type;
const char *session_type_env;
- gboolean is_tty = FALSE;
int ret, i;
ret = sd_pid_get_session (0, &session_id);
@@ -346,8 +345,7 @@ find_session_type (void)
{
if (session_type_is_supported (session_type))
goto out;
- else
- is_tty = g_strcmp0 (session_type, "tty") == 0;
+
free (session_type);
}
}
@@ -379,8 +377,8 @@ find_session_type (void)
goto out;
}
- /* Legacy support for starting through xinit */
- if (is_tty && (g_getenv ("MUTTER_DISPLAY") || g_getenv ("DISPLAY")))
+ /* Legacy support for starting through xinit or vncserver */
+ if (g_getenv ("MUTTER_DISPLAY") || g_getenv ("DISPLAY"))
{
session_type = strdup ("x11");
goto out;
--
2.21.0

View File

@ -0,0 +1,152 @@
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

View File

@ -0,0 +1,144 @@
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

View File

@ -0,0 +1,272 @@
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

View File

@ -0,0 +1,62 @@
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

View File

@ -0,0 +1,35 @@
From 9dfe362f41b8811450cb563c39899fafe8ec2b63 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Fri, 26 Oct 2018 08:49:39 +0200
Subject: [PATCH] wayland: Allow Xwayland grabs on selected apps
Allow Xwayland grabs on a selected set of X11 applications.
---
data/org.gnome.mutter.wayland.gschema.xml.in | 4 ++--
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
index 48241296e..7a6ab9288 100644
--- a/data/org.gnome.mutter.wayland.gschema.xml.in
+++ b/data/org.gnome.mutter.wayland.gschema.xml.in
@@ -60,7 +60,7 @@
gettext-domain="@GETTEXT_DOMAIN@">
<key name="xwayland-allow-grabs" type="b">
- <default>false</default>
+ <default>true</default>
<summary>Allow grabs with Xwayland</summary>
<description>
Allow keyboard grabs issued by X11 applications running in Xwayland
@@ -73,7 +73,7 @@
</key>
<key name="xwayland-grab-access-rules" type="as">
- <default>[]</default>
+ <default>['@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@']</default>
<summary>Xwayland applications allowed to issue keyboard grabs</summary>
<description>
List the resource names or resource class of X11 windows either
--
2.21.0

View File

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

View File

@ -0,0 +1,80 @@
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

View File

@ -0,0 +1,163 @@
From 063db6c9a7504a4d7baae28f7899bd661c459c41 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Mon, 14 Jan 2019 11:11:01 -0500
Subject: [PATCH 2/9] backend: switch to using generated logind proxy
Right now we listen to prepare-for-sleep using
raw gdbus calls.
This commit switches it over to use a generated
proxy, which will become useful in a future commit,
for adding suspending inhibitors.
---
src/backends/meta-backend.c | 60 ++++++++++++++++++++++------------
src/org.freedesktop.login1.xml | 13 ++++++++
2 files changed, 52 insertions(+), 21 deletions(-)
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
index 23ab2faec..5d71977c6 100644
--- a/src/backends/meta-backend.c
+++ b/src/backends/meta-backend.c
@@ -65,6 +65,7 @@
#include "meta/main.h"
#include "meta/meta-backend.h"
#include "meta/util.h"
+#include "meta-dbus-login1.h"
#ifdef HAVE_REMOTE_DESKTOP
#include "backends/meta-dbus-session-watcher.h"
@@ -145,10 +146,12 @@ struct _MetaBackendPrivate
GDBusProxy *upower_proxy;
gboolean lid_is_closed;
- guint sleep_signal_id;
GCancellable *cancellable;
GDBusConnection *system_bus;
+ Login1Manager *logind_proxy;
+ int inhibit_sleep_fd;
+
gboolean was_headless;
};
typedef struct _MetaBackendPrivate MetaBackendPrivate;
@@ -156,6 +159,10 @@ typedef struct _MetaBackendPrivate MetaBackendPrivate;
static void
initable_iface_init (GInitableIface *initable_iface);
+
+static void prepare_for_sleep_cb (MetaBackend *backend,
+ gboolean suspending);
+
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaBackend, meta_backend, G_TYPE_OBJECT,
G_ADD_PRIVATE (MetaBackend)
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
@@ -177,8 +184,6 @@ meta_backend_finalize (GObject *object)
g_clear_object (&priv->remote_access_controller);
#endif
- if (priv->sleep_signal_id)
- g_dbus_connection_signal_unsubscribe (priv->system_bus, priv->sleep_signal_id);
if (priv->upower_watch_id)
g_bus_unwatch_name (priv->upower_watch_id);
g_cancellable_cancel (priv->cancellable);
@@ -764,13 +769,8 @@ meta_backend_create_renderer (MetaBackend *backend,
}
static void
-prepare_for_sleep_cb (GDBusConnection *connection,
- const gchar *sender_name,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *signal_name,
- GVariant *parameters,
- gpointer user_data)
+prepare_for_sleep_cb (MetaBackend *backend,
+ gboolean suspending)
{
gboolean suspending;
@@ -780,12 +780,31 @@ prepare_for_sleep_cb (GDBusConnection *connection,
meta_idle_monitor_reset_idletime (meta_idle_monitor_get_core ());
}
+static Login1Manager *
+get_logind_proxy (GCancellable *cancellable,
+ GError **error)
+{
+ Login1Manager *proxy;
+
+ proxy =
+ login1_manager_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1",
+ cancellable, error);
+ if (!proxy)
+ g_prefix_error (error, "Could not get logind proxy: ");
+
+ return proxy;
+}
+
static void
system_bus_gotten_cb (GObject *object,
GAsyncResult *res,
gpointer user_data)
{
MetaBackendPrivate *priv;
+ g_autoptr (GError) error = NULL;
GDBusConnection *bus;
bus = g_bus_get_finish (res, NULL);
@@ -794,17 +813,16 @@ system_bus_gotten_cb (GObject *object,
priv = meta_backend_get_instance_private (user_data);
priv->system_bus = bus;
- priv->sleep_signal_id =
- g_dbus_connection_signal_subscribe (priv->system_bus,
- "org.freedesktop.login1",
- "org.freedesktop.login1.Manager",
- "PrepareForSleep",
- "/org/freedesktop/login1",
- NULL,
- G_DBUS_SIGNAL_FLAGS_NONE,
- prepare_for_sleep_cb,
- NULL,
- NULL);
+ priv->logind_proxy = get_logind_proxy (priv->cancellable, &error);
+
+ if (!priv->logind_proxy)
+ g_warning ("Failed to get logind proxy: %s", error->message);
+
+ g_signal_connect_object (priv->logind_proxy,
+ "prepare-for-sleep",
+ G_CALLBACK (prepare_for_sleep_cb),
+ user_data,
+ G_CONNECT_SWAPPED);
}
static gboolean
diff --git a/src/org.freedesktop.login1.xml b/src/org.freedesktop.login1.xml
index 765475132..1ecfd976f 100644
--- a/src/org.freedesktop.login1.xml
+++ b/src/org.freedesktop.login1.xml
@@ -43,4 +43,17 @@
<arg name="vt" type="u"/>
</method>
</interface>
+
+ <interface name="org.freedesktop.login1.Manager">
+ <method name="Inhibit">
+ <arg name="what" type="s" direction="in"/>
+ <arg name="who" type="s" direction="in"/>
+ <arg name="why" type="s" direction="in"/>
+ <arg name="mode" type="s" direction="in"/>
+ <arg name="fd" type="h" direction="out"/>
+ </method>
+ <signal name="PrepareForSleep">
+ <arg name="active" type="b"/>
+ </signal>
+ </interface>
</node>
--
2.21.0

View File

@ -0,0 +1,146 @@
From 9f566208d584ec4d8da797390b6806157c7d2402 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 10 Jan 2019 10:47:19 -0500
Subject: [PATCH 3/9] backend: add signals for reporting suspend and resume
This commit adds "suspending" and "resuming" signals
to MetaBackend.
It's preliminary work needed for tracking when to purge
and recreate all textures (needed by nvidia).
---
src/backends/meta-backend.c | 83 ++++++++++++++++++++++++++++++++-----
1 file changed, 72 insertions(+), 11 deletions(-)
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
index 5d71977c6..c980cf150 100644
--- a/src/backends/meta-backend.c
+++ b/src/backends/meta-backend.c
@@ -87,6 +87,8 @@ enum
LAST_DEVICE_CHANGED,
LID_IS_CLOSED_CHANGED,
+ SUSPENDING,
+ RESUMING,
N_SIGNALS
};
@@ -745,6 +747,20 @@ meta_backend_class_init (MetaBackendClass *klass)
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+ signals[SUSPENDING] =
+ g_signal_new ("suspending",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 0);
+ signals[RESUMING] =
+ g_signal_new ("resuming",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 0);
mutter_stage_views = g_getenv ("MUTTER_STAGE_VIEWS");
stage_views_disabled = g_strcmp0 (mutter_stage_views, "0") == 0;
@@ -768,15 +784,53 @@ meta_backend_create_renderer (MetaBackend *backend,
return META_BACKEND_GET_CLASS (backend)->create_renderer (backend, error);
}
+static void
+inhibit_sleep (MetaBackend *backend)
+{
+ MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
+ g_autoptr (GVariant) fd_variant = NULL;
+ g_autoptr (GError) error = NULL;
+
+ if (priv->inhibit_sleep_fd >= 0)
+ return;
+
+ if (!login1_manager_call_inhibit_sync (priv->logind_proxy,
+ "sleep",
+ "Display Server",
+ "Prepare for suspend",
+ "delay",
+ &fd_variant,
+ priv->cancellable,
+ &error))
+ {
+ g_warning ("Failed to inhibit sleep: %s", error->message);
+ return;
+ }
+
+ priv->inhibit_sleep_fd = g_variant_get_handle (fd_variant);
+}
+
+static void
+uninhibit_sleep (MetaBackend *backend)
+{
+ MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
+
+ close (priv->inhibit_sleep_fd);
+ priv->inhibit_sleep_fd = -1;
+}
+
static void
prepare_for_sleep_cb (MetaBackend *backend,
gboolean suspending)
{
- gboolean suspending;
-
- g_variant_get (parameters, "(b)", &suspending);
- if (suspending)
+ if (suspending) {
+ g_signal_emit (backend, signals[SUSPENDING], 0);
+ uninhibit_sleep (backend);
return;
+ }
+
+ inhibit_sleep (backend);
+ g_signal_emit (backend, signals[RESUMING], 0);
meta_idle_monitor_reset_idletime (meta_idle_monitor_get_core ());
}
@@ -803,6 +857,7 @@ system_bus_gotten_cb (GObject *object,
GAsyncResult *res,
gpointer user_data)
{
+ MetaBackend *backend = META_BACKEND (user_data);
MetaBackendPrivate *priv;
g_autoptr (GError) error = NULL;
GDBusConnection *bus;
@@ -814,15 +869,21 @@ system_bus_gotten_cb (GObject *object,
priv = meta_backend_get_instance_private (user_data);
priv->system_bus = bus;
priv->logind_proxy = get_logind_proxy (priv->cancellable, &error);
+ priv->inhibit_sleep_fd = -1;
if (!priv->logind_proxy)
- g_warning ("Failed to get logind proxy: %s", error->message);
-
- g_signal_connect_object (priv->logind_proxy,
- "prepare-for-sleep",
- G_CALLBACK (prepare_for_sleep_cb),
- user_data,
- G_CONNECT_SWAPPED);
+ {
+ g_warning ("Failed to get logind proxy: %s", error->message);
+ }
+ else
+ {
+ inhibit_sleep (backend);
+ g_signal_connect_object (priv->logind_proxy,
+ "prepare-for-sleep",
+ G_CALLBACK (prepare_for_sleep_cb),
+ user_data,
+ G_CONNECT_SWAPPED);
+ }
}
static gboolean
--
2.21.0

View File

@ -0,0 +1,118 @@
From a4a703c75e208badf78c81558994a249797dbb0a Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Sat, 12 Jan 2019 12:38:01 -0500
Subject: [PATCH 4/9] wayland: force X clients to redraw on resume
On nvidia, the textures backing Xwayland client window contents get
corrupted on suspend. Xwayland currently doesn't handle this situation
itself.
For now, in order to work around this issue, send an empty output
change event to Xwayland. This will cause it to force Expose events
to get sent to all clients and get them to redraw.
---
.../native/meta-monitor-manager-kms.c | 7 +++
src/wayland/meta-wayland-outputs.c | 47 +++++++++++++++++++
src/wayland/meta-wayland-outputs.h | 1 +
3 files changed, 55 insertions(+)
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
index 9a0364441..7bcceee97 100644
--- a/src/backends/native/meta-monitor-manager-kms.c
+++ b/src/backends/native/meta-monitor-manager-kms.c
@@ -60,6 +60,7 @@
#include "clutter/clutter.h"
#include "meta/main.h"
#include "meta/meta-x11-errors.h"
+#include "wayland/meta-wayland-outputs.h"
#define DRM_CARD_UDEV_DEVICE_TYPE "drm_minor"
@@ -505,9 +506,15 @@ void
meta_monitor_manager_kms_resume (MetaMonitorManagerKms *manager_kms)
{
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms);
+ ClutterBackend *clutter_backend = clutter_get_default_backend ();
+ CoglContext *cogl_context =
+ clutter_backend_get_cogl_context (clutter_backend);
meta_monitor_manager_kms_connect_uevent_handler (manager_kms);
handle_hotplug_event (manager);
+
+ if (cogl_has_feature (cogl_context, COGL_FEATURE_ID_UNSTABLE_TEXTURES))
+ meta_wayland_outputs_redraw (meta_wayland_compositor_get_default ());
}
static gboolean
diff --git a/src/wayland/meta-wayland-outputs.c b/src/wayland/meta-wayland-outputs.c
index 099e87ab9..bc69d699d 100644
--- a/src/wayland/meta-wayland-outputs.c
+++ b/src/wayland/meta-wayland-outputs.c
@@ -496,6 +496,53 @@ meta_wayland_compositor_update_outputs (MetaWaylandCompositor *compositor,
return new_table;
}
+void
+meta_wayland_outputs_redraw (MetaWaylandCompositor *compositor)
+{
+ MetaMonitorManager *monitor_manager;
+ GList *logical_monitors, *l;
+
+ monitor_manager = meta_monitor_manager_get ();
+
+ logical_monitors =
+ meta_monitor_manager_get_logical_monitors (monitor_manager);
+
+ for (l = logical_monitors; l; l = l->next)
+ {
+ MetaLogicalMonitor *logical_monitor = l->data;
+ MetaWaylandOutput *wayland_output;
+ GList *iter;
+
+ if (logical_monitor->winsys_id == 0)
+ continue;
+
+ wayland_output =
+ g_hash_table_lookup (compositor->outputs,
+ GSIZE_TO_POINTER (logical_monitor->winsys_id));
+
+ if (wayland_output == NULL)
+ continue;
+
+ /* Just output a "changes done" event for one of the outputs, with no actual changes.
+ * xwayland takes this as a cue to send expose events to all X clients.
+ */
+ for (iter = wayland_output->resources; iter; iter = iter->next)
+ {
+ struct wl_resource *resource = iter->data;
+ if (wl_resource_get_version (resource) >= WL_OUTPUT_DONE_SINCE_VERSION)
+ wl_output_send_done (resource);
+ }
+
+ for (iter = wayland_output->xdg_output_resources; iter; iter = iter->next)
+ {
+ struct wl_resource *xdg_output = iter->data;
+ zxdg_output_v1_send_done (xdg_output);
+ }
+
+ break;
+ }
+}
+
static void
on_monitors_changed (MetaMonitorManager *monitors,
MetaWaylandCompositor *compositor)
diff --git a/src/wayland/meta-wayland-outputs.h b/src/wayland/meta-wayland-outputs.h
index ff15a81bd..d649e0fa1 100644
--- a/src/wayland/meta-wayland-outputs.h
+++ b/src/wayland/meta-wayland-outputs.h
@@ -49,5 +49,6 @@ struct _MetaWaylandOutput
};
void meta_wayland_outputs_init (MetaWaylandCompositor *compositor);
+void meta_wayland_outputs_redraw (MetaWaylandCompositor *compositor);
#endif /* META_WAYLAND_OUTPUTS_H */
--
2.21.0

View File

@ -0,0 +1,40 @@
From 122d7726e450712b8b2fc85db41e3c8ab7b6ad56 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Tue, 15 Jan 2019 10:29:55 -0500
Subject: [PATCH 5/9] backends/native: emit gl-video-memory-purged when
becoming active
The proprietary NVIDIA driver garbles memory on suspend. In order
to work around that limitation, mutter needs to refresh all its
textures on resuem.
This commit lays the way toward doing that by emitting the
"gl-video-memory-purged" signal when the compositor becomes active
by logind (which happens on VT switch and on resume).
---
src/backends/native/meta-backend-native.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
index c473681cb..f593197e7 100644
--- a/src/backends/native/meta-backend-native.c
+++ b/src/backends/native/meta-backend-native.c
@@ -653,8 +653,15 @@ void meta_backend_native_resume (MetaBackendNative *native)
meta_backend_get_monitor_manager (backend);
MetaMonitorManagerKms *monitor_manager_kms =
META_MONITOR_MANAGER_KMS (monitor_manager);
+ MetaDisplay *display = meta_get_display ();
+ ClutterBackend *clutter_backend = clutter_get_default_backend ();
+ CoglContext *cogl_context =
+ clutter_backend_get_cogl_context (clutter_backend);
MetaIdleMonitor *idle_monitor;
+ if (cogl_has_feature (cogl_context, COGL_FEATURE_ID_UNSTABLE_TEXTURES))
+ g_signal_emit_by_name (display, "gl-video-memory-purged");
+
meta_monitor_manager_kms_resume (monitor_manager_kms);
clutter_evdev_reclaim_devices ();
--
2.21.0

View File

@ -0,0 +1,35 @@
From 762ffddfa6157fe50bfa394ecbe4ba707d15f368 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Tue, 15 Jan 2019 10:29:55 -0500
Subject: [PATCH 6/9] backends/native: update glyph cache on resume
As mentioned in a previous commit, the proprietary NVIDIA
driver garbles memory on suspend. That behavior, means that
clutter's glyph cache (which is stored in GPU memory) gets
corrupted on suspend.
This commit ensures the glyph cache is blown away when
the logind session becomes active (on VT switch and resume).
---
src/backends/native/meta-backend-native.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
index f593197e7..db9b63ac4 100644
--- a/src/backends/native/meta-backend-native.c
+++ b/src/backends/native/meta-backend-native.c
@@ -660,7 +660,10 @@ void meta_backend_native_resume (MetaBackendNative *native)
MetaIdleMonitor *idle_monitor;
if (cogl_has_feature (cogl_context, COGL_FEATURE_ID_UNSTABLE_TEXTURES))
- g_signal_emit_by_name (display, "gl-video-memory-purged");
+ {
+ clutter_clear_glyph_cache ();
+ g_signal_emit_by_name (display, "gl-video-memory-purged");
+ }
meta_monitor_manager_kms_resume (monitor_manager_kms);
--
2.21.0

View File

@ -0,0 +1,38 @@
From 59ba24c09e5d2a3210ca3d259789f7ba5ae6266a Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Tue, 15 Jan 2019 10:29:55 -0500
Subject: [PATCH 7/9] backends/native: update cursor on resume
As mentioned in a previous commit, the proprietary NVIDIA
driver garbles memory on suspend. That behavior, means that
the cursor gets corrupted on suspend.
This commit forces the cursor to redraw itself when the
logind session becomes active (on VT switch and resume).
---
src/backends/native/meta-backend-native.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
index db9b63ac4..479e9326b 100644
--- a/src/backends/native/meta-backend-native.c
+++ b/src/backends/native/meta-backend-native.c
@@ -54,6 +54,7 @@
#include "backends/native/meta-renderer-native.h"
#include "backends/native/meta-stage-native.h"
#include "clutter/evdev/clutter-evdev.h"
+#include "core/display-private.h"
#include "core/meta-border.h"
#include "meta/main.h"
@@ -662,6 +663,7 @@ void meta_backend_native_resume (MetaBackendNative *native)
if (cogl_has_feature (cogl_context, COGL_FEATURE_ID_UNSTABLE_TEXTURES))
{
clutter_clear_glyph_cache ();
+ meta_display_update_cursor (display);
g_signal_emit_by_name (display, "gl-video-memory-purged");
}
--
2.21.0

View File

@ -0,0 +1,110 @@
From c78a614b0d45a4bc8101a93c7138c9fb6102d13c Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Wed, 9 Jan 2019 16:57:05 -0500
Subject: [PATCH 8/9] background: purge all background textures on suspend
This commit makes sure all background textures get purged
on suspend, which is important for nvidia.
---
src/compositor/meta-background-image.c | 28 ++++++++++++++++++++++++++
src/compositor/meta-background.c | 17 +++++++++++++++-
src/meta/meta-background-image.h | 2 ++
3 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/src/compositor/meta-background-image.c b/src/compositor/meta-background-image.c
index 14d3baf57..98909cb53 100644
--- a/src/compositor/meta-background-image.c
+++ b/src/compositor/meta-background-image.c
@@ -283,6 +283,34 @@ meta_background_image_cache_purge (MetaBackgroundImageCache *cache,
image->in_cache = FALSE;
}
+/**
+ * meta_background_image_cache_unload_all:
+ * @cache: a #MetaBackgroundImageCache
+ *
+ * Remove all entries from the cache and unloads them; this would be used
+ * if textures in video memory have been invalidated.
+ */
+void
+meta_background_image_cache_unload_all (MetaBackgroundImageCache *cache)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_return_if_fail (META_IS_BACKGROUND_IMAGE_CACHE (cache));
+
+ g_hash_table_iter_init (&iter, cache->images);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ MetaBackgroundImage *image = value;
+
+ g_clear_pointer (&image->texture, cogl_object_unref);
+ image->in_cache = FALSE;
+ image->loaded = FALSE;
+ }
+
+ g_hash_table_remove_all (cache->images);
+}
+
G_DEFINE_TYPE (MetaBackgroundImage, meta_background_image, G_TYPE_OBJECT);
static void
diff --git a/src/compositor/meta-background.c b/src/compositor/meta-background.c
index c033395fe..abdfcc7df 100644
--- a/src/compositor/meta-background.c
+++ b/src/compositor/meta-background.c
@@ -303,6 +303,18 @@ meta_background_finalize (GObject *object)
G_OBJECT_CLASS (meta_background_parent_class)->finalize (object);
}
+static void
+free_textures (MetaBackground *self)
+{
+ 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);
+
+ mark_changed (self);
+}
+
static void
meta_background_constructed (GObject *object)
{
@@ -312,7 +324,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 (free_textures), object, G_CONNECT_SWAPPED);
g_signal_connect_object (monitor_manager, "monitors-changed",
G_CALLBACK (on_monitors_changed), self,
@@ -950,8 +962,11 @@ meta_background_set_blend (MetaBackground *self,
void
meta_background_refresh_all (void)
{
+ MetaBackgroundImageCache *cache = meta_background_image_cache_get_default ();
GSList *l;
+ meta_background_image_cache_unload_all (cache);
+
for (l = all_backgrounds; l; l = l->next)
mark_changed (l->data);
}
diff --git a/src/meta/meta-background-image.h b/src/meta/meta-background-image.h
index 137a6ff8e..87e40d251 100644
--- a/src/meta/meta-background-image.h
+++ b/src/meta/meta-background-image.h
@@ -66,4 +66,6 @@ META_EXPORT
void meta_background_image_cache_purge (MetaBackgroundImageCache *cache,
GFile *file);
+void meta_background_image_cache_unload_all (MetaBackgroundImageCache *cache);
+
#endif /* __META_BACKGROUND_IMAGE_H__ */
--
2.21.0

View File

@ -0,0 +1,712 @@
From d8cc418899276b45cb1a787493e0998e3b008fe5 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 10 Jan 2019 10:48:02 -0500
Subject: [PATCH 9/9] MetaShapedTexture: save and restore textures on suspend
The proprietary nvidia driver garbles GPU memory on suspend.
In order to workaround that limitation, this commit copies all
textures to host memory on suspend and restores them on resume.
One complication comes from external textures (such as those
given to us by Xwayland for X clients). We can't just restore
those textures, since they aren't writable.
This commit addresses that complication by keeping a local texture
around for those external textures, and using it instead for parts
of the window that haven't been redrawn since resume.
---
src/compositor/meta-shaped-texture.c | 487 +++++++++++++++++++++++++--
src/meta/meta-shaped-texture.h | 2 +
2 files changed, 468 insertions(+), 21 deletions(-)
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index d64e214e5..ea8daa03d 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -40,7 +40,9 @@
#include "compositor/meta-texture-tower.h"
#include "compositor/region-utils.h"
#include "core/boxes-private.h"
+#include <meta/meta-backend.h>
#include "meta/meta-shaped-texture.h"
+#include "meta-texture-rectangle.h"
/* MAX_MIPMAPPING_FPS needs to be as small as possible for the best GPU
* performance, but higher than the refresh rate of commonly slow updating
@@ -72,8 +74,12 @@ static void meta_shaped_texture_get_preferred_height (ClutterActor *self,
static gboolean meta_shaped_texture_get_paint_volume (ClutterActor *self, ClutterPaintVolume *volume);
+static void disable_backing_store (MetaShapedTexture *stex);
+
static void cullable_iface_init (MetaCullableInterface *iface);
+static gboolean meta_debug_show_backing_store = FALSE;
+
enum
{
SIZE_CHANGED,
@@ -83,6 +89,14 @@ enum
static guint signals[LAST_SIGNAL];
+typedef struct
+{
+ CoglTexture *texture;
+ CoglTexture *mask_texture;
+ cairo_surface_t *mask_surface;
+ cairo_region_t *region;
+} MetaTextureBackingStore;
+
struct _MetaShapedTexture
{
ClutterActor parent;
@@ -114,6 +128,16 @@ struct _MetaShapedTexture
int viewport_dst_width;
int viewport_dst_height;
+ /* textures get corrupted on suspend, so save them */
+ cairo_surface_t *saved_base_surface;
+ cairo_surface_t *saved_mask_surface;
+
+ /* We can't just restore external textures, so we need to track
+ * which parts of the external texture are freshly drawn from
+ * the client after corruption, and fill in the rest from our
+ * saved snapshot */
+ MetaTextureBackingStore *backing_store;
+
int tex_width, tex_height;
int fallback_width, fallback_height;
int dst_width, dst_height;
@@ -148,6 +172,9 @@ meta_shaped_texture_class_init (MetaShapedTextureClass *klass)
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
+
+ if (g_getenv ("MUTTER_DEBUG_BACKING_STORE"))
+ meta_debug_show_backing_store = TRUE;
}
static void
@@ -159,6 +186,11 @@ invalidate_size (MetaShapedTexture *stex)
static void
meta_shaped_texture_init (MetaShapedTexture *stex)
{
+ MetaBackend *backend = meta_get_backend ();
+ ClutterBackend *clutter_backend = clutter_get_default_backend ();
+ CoglContext *cogl_context =
+ clutter_backend_get_cogl_context (clutter_backend);
+
stex->paint_tower = meta_texture_tower_new ();
stex->texture = NULL;
@@ -171,6 +203,12 @@ meta_shaped_texture_init (MetaShapedTexture *stex)
"notify::scale-x",
G_CALLBACK (invalidate_size),
stex);
+
+ if (cogl_has_feature (cogl_context, COGL_FEATURE_ID_UNSTABLE_TEXTURES))
+ {
+ g_signal_connect_object (backend, "suspending", G_CALLBACK (meta_shaped_texture_save), stex, G_CONNECT_SWAPPED);
+ g_signal_connect_object (backend, "resuming", G_CALLBACK (meta_shaped_texture_restore), stex, G_CONNECT_SWAPPED);
+ }
}
static void
@@ -311,24 +349,72 @@ meta_shaped_texture_dispose (GObject *object)
G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object);
}
+static int
+get_layer_indices (MetaShapedTexture *stex,
+ int *main_layer_index,
+ int *backing_mask_layer_index,
+ int *backing_layer_index,
+ int *mask_layer_index)
+{
+ int next_layer_index = 0;
+
+ if (main_layer_index)
+ *main_layer_index = next_layer_index;
+
+ next_layer_index++;
+
+ if (stex->backing_store)
+ {
+ if (backing_mask_layer_index)
+ *backing_mask_layer_index = next_layer_index;
+ next_layer_index++;
+ if (backing_layer_index)
+ *backing_layer_index = next_layer_index;
+ next_layer_index++;
+ }
+ else
+ {
+ if (backing_mask_layer_index)
+ *backing_mask_layer_index = -1;
+ if (backing_layer_index)
+ *backing_layer_index = -1;
+ }
+
+ if (mask_layer_index)
+ *mask_layer_index = next_layer_index;
+
+ return next_layer_index;
+}
+
static CoglPipeline *
get_base_pipeline (MetaShapedTexture *stex,
CoglContext *ctx)
{
CoglPipeline *pipeline;
+ int main_layer_index;
+ int backing_layer_index;
+ int backing_mask_layer_index;
+ int i, number_of_layers;
if (stex->base_pipeline)
return stex->base_pipeline;
pipeline = cogl_pipeline_new (ctx);
- cogl_pipeline_set_layer_wrap_mode_s (pipeline, 0,
- COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
- cogl_pipeline_set_layer_wrap_mode_t (pipeline, 0,
- COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
- cogl_pipeline_set_layer_wrap_mode_s (pipeline, 1,
- COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
- cogl_pipeline_set_layer_wrap_mode_t (pipeline, 1,
- COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
+
+ number_of_layers = get_layer_indices (stex,
+ &main_layer_index,
+ &backing_mask_layer_index,
+ &backing_layer_index,
+ NULL);
+
+ for (i = 0; i < number_of_layers; i++)
+ {
+ cogl_pipeline_set_layer_wrap_mode_s (pipeline, i,
+ COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
+ cogl_pipeline_set_layer_wrap_mode_t (pipeline, i,
+ COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
+ }
+
if (!stex->is_y_inverted)
{
CoglMatrix matrix;
@@ -336,7 +422,22 @@ get_base_pipeline (MetaShapedTexture *stex,
cogl_matrix_init_identity (&matrix);
cogl_matrix_scale (&matrix, 1, -1, 1);
cogl_matrix_translate (&matrix, 0, -1, 0);
- cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
+ cogl_pipeline_set_layer_matrix (pipeline, main_layer_index, &matrix);
+ }
+
+ if (stex->backing_store)
+ {
+ g_autofree char *backing_description = NULL;
+ cogl_pipeline_set_layer_combine (pipeline, backing_mask_layer_index,
+ "RGBA = REPLACE(PREVIOUS)",
+ NULL);
+ backing_description = g_strdup_printf ("RGBA = INTERPOLATE(PREVIOUS, TEXTURE_%d, TEXTURE_%d[A])",
+ backing_layer_index,
+ backing_mask_layer_index);
+ cogl_pipeline_set_layer_combine (pipeline,
+ backing_layer_index,
+ backing_description,
+ NULL);
}
if (stex->transform != META_MONITOR_TRANSFORM_NORMAL)
@@ -379,7 +480,7 @@ get_base_pipeline (MetaShapedTexture *stex,
}
if (stex->snippet)
- cogl_pipeline_add_layer_snippet (pipeline, 0, stex->snippet);
+ cogl_pipeline_add_layer_snippet (pipeline, main_layer_index, stex->snippet);
stex->base_pipeline = pipeline;
@@ -398,12 +499,15 @@ get_masked_pipeline (MetaShapedTexture *stex,
CoglContext *ctx)
{
CoglPipeline *pipeline;
+ int mask_layer_index;
if (stex->masked_pipeline)
return stex->masked_pipeline;
+ get_layer_indices (stex, NULL, NULL, NULL, &mask_layer_index);
+
pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
- cogl_pipeline_set_layer_combine (pipeline, 1,
+ cogl_pipeline_set_layer_combine (pipeline, mask_layer_index,
"RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
NULL);
@@ -517,6 +621,8 @@ set_cogl_texture (MetaShapedTexture *stex,
if (stex->texture)
cogl_object_unref (stex->texture);
+ g_clear_pointer (&stex->saved_base_surface, cairo_surface_destroy);
+
stex->texture = cogl_tex;
if (cogl_tex != NULL)
@@ -579,6 +685,10 @@ do_paint (MetaShapedTexture *stex,
CoglContext *ctx;
ClutterActorBox alloc;
CoglPipelineFilter filter;
+ int main_layer_index;
+ int backing_mask_layer_index;
+ int backing_layer_index;
+ int mask_layer_index;
clutter_actor_get_scale (CLUTTER_ACTOR (stex), &tex_scale, NULL);
ensure_size_valid (stex);
@@ -665,6 +775,12 @@ do_paint (MetaShapedTexture *stex,
}
}
+ get_layer_indices (stex,
+ &main_layer_index,
+ &backing_mask_layer_index,
+ &backing_layer_index,
+ &mask_layer_index);
+
/* First, paint the unblended parts, which are part of the opaque region. */
if (use_opaque_region)
{
@@ -686,8 +802,24 @@ do_paint (MetaShapedTexture *stex,
if (!cairo_region_is_empty (region))
{
opaque_pipeline = get_unblended_pipeline (stex, ctx);
- cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
- cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
+ cogl_pipeline_set_layer_texture (opaque_pipeline, main_layer_index, paint_tex);
+ cogl_pipeline_set_layer_filters (opaque_pipeline, main_layer_index, filter, filter);
+
+ if (stex->backing_store)
+ {
+ cogl_pipeline_set_layer_texture (opaque_pipeline,
+ backing_mask_layer_index,
+ stex->backing_store->mask_texture);
+ cogl_pipeline_set_layer_filters (opaque_pipeline,
+ backing_mask_layer_index,
+ filter, filter);
+ cogl_pipeline_set_layer_texture (opaque_pipeline,
+ backing_layer_index,
+ stex->backing_store->texture);
+ cogl_pipeline_set_layer_filters (opaque_pipeline,
+ backing_layer_index,
+ filter, filter);
+ }
n_rects = cairo_region_num_rectangles (region);
for (i = 0; i < n_rects; i++)
@@ -726,12 +858,28 @@ do_paint (MetaShapedTexture *stex,
else
{
blended_pipeline = get_masked_pipeline (stex, ctx);
- cogl_pipeline_set_layer_texture (blended_pipeline, 1, stex->mask_texture);
- cogl_pipeline_set_layer_filters (blended_pipeline, 1, filter, filter);
+ cogl_pipeline_set_layer_texture (blended_pipeline, mask_layer_index, stex->mask_texture);
+ cogl_pipeline_set_layer_filters (blended_pipeline, mask_layer_index, filter, filter);
}
- cogl_pipeline_set_layer_texture (blended_pipeline, 0, paint_tex);
- cogl_pipeline_set_layer_filters (blended_pipeline, 0, filter, filter);
+ cogl_pipeline_set_layer_texture (blended_pipeline, main_layer_index, paint_tex);
+ cogl_pipeline_set_layer_filters (blended_pipeline, main_layer_index, filter, filter);
+
+ if (stex->backing_store)
+ {
+ cogl_pipeline_set_layer_texture (blended_pipeline,
+ backing_mask_layer_index,
+ stex->backing_store->mask_texture);
+ cogl_pipeline_set_layer_filters (blended_pipeline,
+ backing_mask_layer_index,
+ filter, filter);
+ cogl_pipeline_set_layer_texture (blended_pipeline,
+ backing_layer_index,
+ stex->backing_store->texture);
+ cogl_pipeline_set_layer_filters (blended_pipeline,
+ backing_layer_index,
+ filter, filter);
+ }
CoglColor color;
cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
@@ -925,6 +1073,7 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
g_clear_pointer (&stex->mask_texture, cogl_object_unref);
+ g_clear_pointer (&stex->saved_mask_surface, cairo_surface_destroy);
if (mask_texture != NULL)
{
@@ -946,6 +1095,65 @@ meta_shaped_texture_is_obscured (MetaShapedTexture *stex)
return FALSE;
}
+static void
+meta_texture_backing_store_redraw_mask (MetaTextureBackingStore *backing_store)
+{
+ CoglError *error = NULL;
+
+ if (!cogl_texture_set_data (backing_store->mask_texture, COGL_PIXEL_FORMAT_A_8,
+ cairo_image_surface_get_stride (backing_store->mask_surface),
+ cairo_image_surface_get_data (backing_store->mask_surface), 0,
+ &error))
+ {
+
+ g_warning ("Failed to update backing mask texture");
+ g_clear_pointer (&error, cogl_error_free);
+ }
+}
+
+static gboolean
+meta_texture_backing_store_shrink (MetaTextureBackingStore *backing_store,
+ const cairo_rectangle_int_t *area)
+{
+ cairo_t *cr;
+
+ cairo_region_subtract_rectangle (backing_store->region, area);
+
+ /* If the client has finally redrawn the entire surface, we can
+ * ditch our snapshot
+ */
+ if (cairo_region_is_empty (backing_store->region))
+ return FALSE;
+
+ cr = cairo_create (backing_store->mask_surface);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+ gdk_cairo_region (cr, backing_store->region);
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+ cairo_fill (cr);
+ cairo_destroy (cr);
+
+ meta_texture_backing_store_redraw_mask (backing_store);
+
+ return TRUE;
+}
+
+static void
+shrink_backing_region (MetaShapedTexture *stex,
+ const cairo_rectangle_int_t *area)
+{
+ gboolean still_backing_texture;
+
+ if (!stex->backing_store)
+ return;
+
+ still_backing_texture =
+ meta_texture_backing_store_shrink (stex->backing_store, area);
+
+ if (!still_backing_texture)
+ disable_backing_store (stex);
+}
+
/**
* meta_shaped_texture_update_area:
* @stex: #MetaShapedTexture
@@ -1041,6 +1249,8 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
&clip);
}
+ shrink_backing_region (stex, &clip);
+
meta_texture_tower_update_area (stex->paint_tower,
clip.x,
clip.y,
@@ -1268,8 +1478,9 @@ should_get_via_offscreen (MetaShapedTexture *stex)
}
static cairo_surface_t *
-get_image_via_offscreen (MetaShapedTexture *stex,
- cairo_rectangle_int_t *clip)
+get_image_via_offscreen (MetaShapedTexture *stex,
+ cairo_rectangle_int_t *clip,
+ CoglTexture **texture)
{
ClutterBackend *clutter_backend = clutter_get_default_backend ();
CoglContext *cogl_context =
@@ -1340,9 +1551,29 @@ get_image_via_offscreen (MetaShapedTexture *stex,
clip->width, clip->height,
CLUTTER_CAIRO_FORMAT_ARGB32,
cairo_image_surface_get_data (surface));
+ cairo_surface_mark_dirty (surface);
+
+ if (texture)
+ {
+ *texture = cogl_object_ref (image_texture);
+
+ if (G_UNLIKELY (meta_debug_show_backing_store))
+ {
+ cairo_t *cr;
+
+ cr = cairo_create (surface);
+ cairo_set_source_rgba (cr, 1.0, 0.0, 0.0, 0.75);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+ }
+
+ cogl_texture_set_data (*texture, CLUTTER_CAIRO_FORMAT_ARGB32,
+ cairo_image_surface_get_stride (surface),
+ cairo_image_surface_get_data (surface), 0, NULL);
+ }
+
cogl_object_unref (fb);
- cairo_surface_mark_dirty (surface);
return surface;
}
@@ -1404,7 +1635,7 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex,
}
if (should_get_via_offscreen (stex))
- return get_image_via_offscreen (stex, transformed_clip);
+ return get_image_via_offscreen (stex, transformed_clip, NULL);
if (transformed_clip)
texture = cogl_texture_new_from_sub_texture (texture,
@@ -1465,6 +1696,220 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex,
return surface;
}
+static void
+meta_texture_backing_store_free (MetaTextureBackingStore *backing_store)
+{
+ g_clear_pointer (&backing_store->texture, cogl_object_unref);
+ g_clear_pointer (&backing_store->mask_texture, cogl_object_unref);
+ g_clear_pointer (&backing_store->mask_surface, cairo_surface_destroy);
+ g_clear_pointer (&backing_store->region, cairo_region_destroy);
+
+ g_slice_free (MetaTextureBackingStore, backing_store);
+}
+
+static MetaTextureBackingStore *
+meta_texture_backing_store_new (CoglTexture *texture)
+{
+ MetaTextureBackingStore *backing_store = NULL;
+ ClutterBackend *backend = clutter_get_default_backend ();
+ CoglContext *context = clutter_backend_get_cogl_context (backend);
+ CoglTexture *mask_texture = NULL;
+ guchar *mask_data;
+ int width, height, stride;
+ cairo_surface_t *surface;
+ cairo_region_t *region;
+ cairo_rectangle_int_t backing_rectangle;
+
+ width = cogl_texture_get_width (texture);
+ height = cogl_texture_get_height (texture);
+ stride = cairo_format_stride_for_width (CAIRO_FORMAT_A8, width);
+
+ /* we start off by only letting the backing texture through, and none of the real texture */
+ backing_rectangle.x = 0;
+ backing_rectangle.y = 0;
+ backing_rectangle.width = width;
+ backing_rectangle.height = height;
+
+ region = cairo_region_create_rectangle (&backing_rectangle);
+
+ /* initialize mask to transparent, so the entire backing store shows through
+ * up front
+ */
+ mask_data = g_malloc0 (stride * height);
+ surface = cairo_image_surface_create_for_data (mask_data,
+ CAIRO_FORMAT_A8,
+ width,
+ height,
+ stride);
+
+ if (meta_texture_rectangle_check (texture))
+ {
+ mask_texture = COGL_TEXTURE (cogl_texture_rectangle_new_with_size (context,
+ width,
+ height));
+ cogl_texture_set_components (mask_texture, COGL_TEXTURE_COMPONENTS_A);
+ cogl_texture_set_region (mask_texture,
+ 0, 0,
+ 0, 0,
+ width, height,
+ width, height,
+ COGL_PIXEL_FORMAT_A_8,
+ stride, mask_data);
+ }
+ else
+ {
+ CoglError *error = NULL;
+
+ mask_texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (context, width, height,
+ COGL_PIXEL_FORMAT_A_8,
+ stride, mask_data, &error));
+
+ if (error)
+ {
+ g_warning ("Failed to allocate mask texture: %s", error->message);
+ cogl_error_free (error);
+ }
+ }
+
+ if (mask_texture)
+ {
+ backing_store = g_slice_new0 (MetaTextureBackingStore);
+ backing_store->texture = cogl_object_ref (texture);
+ backing_store->mask_texture = mask_texture;
+ backing_store->mask_surface = surface;
+ backing_store->region = region;
+ }
+
+ return backing_store;
+}
+
+static void
+enable_backing_store (MetaShapedTexture *stex,
+ CoglTexture *texture)
+{
+ g_clear_pointer (&stex->backing_store, meta_texture_backing_store_free);
+
+ stex->backing_store = meta_texture_backing_store_new (texture);
+
+ meta_shaped_texture_reset_pipelines (stex);
+}
+
+static void
+disable_backing_store (MetaShapedTexture *stex)
+{
+ g_clear_pointer (&stex->backing_store, meta_texture_backing_store_free);
+
+ meta_shaped_texture_reset_pipelines (stex);
+}
+
+void
+meta_shaped_texture_save (MetaShapedTexture *stex)
+{
+
+ CoglTexture *texture, *mask_texture;
+ cairo_surface_t *surface;
+
+ g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
+
+ texture = COGL_TEXTURE (stex->texture);
+
+ if (texture == NULL)
+ return;
+
+ g_clear_pointer (&stex->saved_base_surface, cairo_surface_destroy);
+ g_clear_pointer (&stex->saved_mask_surface, cairo_surface_destroy);
+ g_clear_pointer (&stex->backing_store, meta_texture_backing_store_free);
+
+ if (should_get_via_offscreen (stex))
+ {
+ CoglTexture *backing_texture;
+
+ meta_shaped_texture_reset_pipelines (stex);
+
+ surface = get_image_via_offscreen (stex, NULL, &backing_texture);
+
+ enable_backing_store (stex, backing_texture);
+ cogl_object_unref (backing_texture);
+ }
+ else
+ {
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ cogl_texture_get_width (texture),
+ cogl_texture_get_height (texture));
+
+ cogl_texture_get_data (texture, CLUTTER_CAIRO_FORMAT_ARGB32,
+ cairo_image_surface_get_stride (surface),
+ cairo_image_surface_get_data (surface));
+ }
+
+ stex->saved_base_surface = surface;
+
+ mask_texture = stex->mask_texture;
+ if (mask_texture != NULL)
+ {
+ cairo_surface_t *mask_surface;
+
+ mask_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ cogl_texture_get_width (mask_texture),
+ cogl_texture_get_height (mask_texture));
+
+ cogl_texture_get_data (mask_texture, CLUTTER_CAIRO_FORMAT_ARGB32,
+ cairo_image_surface_get_stride (mask_surface),
+ cairo_image_surface_get_data (mask_surface));
+
+ cairo_surface_mark_dirty (mask_surface);
+
+ stex->saved_mask_surface = mask_surface;
+ }
+}
+
+void
+meta_shaped_texture_restore (MetaShapedTexture *stex)
+{
+ CoglTexture *texture;
+ CoglError *error = NULL;
+
+ texture = meta_shaped_texture_get_texture (stex);
+
+ if (texture == NULL)
+ return;
+
+ if (stex->mask_texture)
+ {
+ if (!cogl_texture_set_data (stex->mask_texture, CLUTTER_CAIRO_FORMAT_ARGB32,
+ cairo_image_surface_get_stride (stex->saved_mask_surface),
+ cairo_image_surface_get_data (stex->saved_mask_surface), 0,
+ &error))
+ {
+ g_warning ("Failed to restore mask texture");
+ g_clear_pointer (&error, cogl_error_free);
+ }
+ g_clear_pointer (&stex->saved_mask_surface, cairo_surface_destroy);
+ }
+
+ /* if the main texture doesn't support direct writes, then
+ * write to the local backing texture instead, and blend old
+ * versus new at paint time.
+ */
+ if (stex->backing_store)
+ {
+ meta_texture_backing_store_redraw_mask (stex->backing_store);
+ texture = stex->backing_store->texture;
+ }
+
+ if (!cogl_texture_set_data (texture, CLUTTER_CAIRO_FORMAT_ARGB32,
+ cairo_image_surface_get_stride (stex->saved_base_surface),
+ cairo_image_surface_get_data (stex->saved_base_surface), 0,
+ &error))
+ {
+ g_warning ("Failed to restore texture");
+ g_clear_pointer (&error, cogl_error_free);
+ }
+ g_clear_pointer (&stex->saved_base_surface, cairo_surface_destroy);
+
+ clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
+}
+
void
meta_shaped_texture_set_fallback_size (MetaShapedTexture *stex,
int fallback_width,
diff --git a/src/meta/meta-shaped-texture.h b/src/meta/meta-shaped-texture.h
index c36b8547f..22b4fbd53 100644
--- a/src/meta/meta-shaped-texture.h
+++ b/src/meta/meta-shaped-texture.h
@@ -66,6 +66,8 @@ META_EXPORT
cairo_surface_t * meta_shaped_texture_get_image (MetaShapedTexture *stex,
cairo_rectangle_int_t *clip);
+void meta_shaped_texture_save (MetaShapedTexture *self);
+void meta_shaped_texture_restore (MetaShapedTexture *self);
G_END_DECLS
#endif /* __META_SHAPED_TEXTURE_H__ */
--
2.21.0

View File

@ -0,0 +1,378 @@
From 3f7ba6739773f43a3ad2a5d26cb8c3365f77cc00 Mon Sep 17 00:00:00 2001
From: Rui Matos <tiagomatos@gmail.com>
Date: Mon, 9 Oct 2017 18:39:52 +0200
Subject: [PATCH 1/3] backends/x11: Add a synaptics check for two finger scroll
availability
Commit "backends/x11: Support synaptics configuration" added support
for synaptics two finger scrolling but didn't add the code to check
that it is available resulting in the upper layer always assuming it
isn't.
---
src/backends/x11/meta-input-settings-x11.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c
index 051a1c605..887bc8b42 100644
--- a/src/backends/x11/meta-input-settings-x11.c
+++ b/src/backends/x11/meta-input-settings-x11.c
@@ -630,6 +630,17 @@ meta_input_settings_x11_has_two_finger_scroll (MetaInputSettings *settings,
guchar *available = NULL;
gboolean has_two_finger = TRUE;
+ if (is_device_synaptics (device))
+ {
+ available = get_property (device, "Synaptics Capabilities",
+ XA_INTEGER, 8, 4);
+ if (!available || !available[3])
+ has_two_finger = FALSE;
+
+ meta_XFree (available);
+ return has_two_finger;
+ }
+
available = get_property (device, "libinput Scroll Methods Available",
XA_INTEGER, 8, SCROLL_METHOD_NUM_FIELDS);
if (!available || !available[SCROLL_METHOD_FIELD_2FG])
--
2.21.0
From 717561b28f35e05d40fb941baba781436a0abf68 Mon Sep 17 00:00:00 2001
From: Rui Matos <tiagomatos@gmail.com>
Date: Mon, 9 Oct 2017 18:55:56 +0200
Subject: [PATCH 2/3] backends/x11: Add disable while typing support for
synaptics
This is basically a copy of the old g-s-d mouse plugin code to manage
syndaemon when the synaptics driver is being used.
---
src/backends/x11/meta-input-settings-x11.c | 112 +++++++++++++++++++++
1 file changed, 112 insertions(+)
diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c
index 887bc8b42..12a592c75 100644
--- a/src/backends/x11/meta-input-settings-x11.c
+++ b/src/backends/x11/meta-input-settings-x11.c
@@ -35,6 +35,9 @@
#ifdef HAVE_LIBGUDEV
#include <gudev/gudev.h>
#endif
+#ifdef __linux
+#include <sys/prctl.h>
+#endif
#include "backends/meta-logical-monitor.h"
#include "backends/x11/meta-backend-x11.h"
@@ -46,6 +49,8 @@ typedef struct _MetaInputSettingsX11Private
#ifdef HAVE_LIBGUDEV
GUdevClient *udev_client;
#endif
+ gboolean syndaemon_spawned;
+ GPid syndaemon_pid;
} MetaInputSettingsX11Private;
G_DEFINE_TYPE_WITH_PRIVATE (MetaInputSettingsX11, meta_input_settings_x11,
@@ -337,6 +342,107 @@ change_synaptics_speed (ClutterInputDevice *device,
XCloseDevice (xdisplay, xdevice);
}
+/* Ensure that syndaemon dies together with us, to avoid running several of
+ * them */
+static void
+setup_syndaemon (gpointer user_data)
+{
+#ifdef __linux
+ prctl (PR_SET_PDEATHSIG, SIGHUP);
+#endif
+}
+
+static gboolean
+have_program_in_path (const char *name)
+{
+ gchar *path;
+ gboolean result;
+
+ path = g_find_program_in_path (name);
+ result = (path != NULL);
+ g_free (path);
+ return result;
+}
+
+static void
+syndaemon_died (GPid pid,
+ gint status,
+ gpointer user_data)
+{
+ MetaInputSettingsX11 *settings_x11 = META_INPUT_SETTINGS_X11 (user_data);
+ MetaInputSettingsX11Private *priv =
+ meta_input_settings_x11_get_instance_private (settings_x11);
+ GError *error = NULL;
+
+ if (!g_spawn_check_exit_status (status, &error))
+ {
+ if ((WIFSIGNALED (status) && WTERMSIG (status) != SIGHUP) ||
+ error->domain == G_SPAWN_EXIT_ERROR)
+ g_warning ("Syndaemon exited unexpectedly: %s", error->message);
+ g_error_free (error);
+ }
+
+ g_spawn_close_pid (pid);
+ priv->syndaemon_spawned = FALSE;
+}
+
+static void
+set_synaptics_disable_w_typing (MetaInputSettings *settings,
+ gboolean state)
+{
+ MetaInputSettingsX11 *settings_x11 = META_INPUT_SETTINGS_X11 (settings);
+ MetaInputSettingsX11Private *priv =
+ meta_input_settings_x11_get_instance_private (settings_x11);
+
+ if (state)
+ {
+ GError *error = NULL;
+ GPtrArray *args;
+
+ if (priv->syndaemon_spawned)
+ return;
+
+ if (!have_program_in_path ("syndaemon"))
+ return;
+
+ args = g_ptr_array_new ();
+
+ g_ptr_array_add (args, (gpointer)"syndaemon");
+ g_ptr_array_add (args, (gpointer)"-i");
+ g_ptr_array_add (args, (gpointer)"1.0");
+ g_ptr_array_add (args, (gpointer)"-t");
+ g_ptr_array_add (args, (gpointer)"-K");
+ g_ptr_array_add (args, (gpointer)"-R");
+ g_ptr_array_add (args, NULL);
+
+ /* we must use G_SPAWN_DO_NOT_REAP_CHILD to avoid
+ * double-forking, otherwise syndaemon will immediately get
+ * killed again through (PR_SET_PDEATHSIG when the intermediate
+ * process dies */
+ g_spawn_async (g_get_home_dir (), (char **) args->pdata, NULL,
+ G_SPAWN_SEARCH_PATH|G_SPAWN_DO_NOT_REAP_CHILD, setup_syndaemon, NULL,
+ &priv->syndaemon_pid, &error);
+
+ priv->syndaemon_spawned = (error == NULL);
+ g_ptr_array_free (args, TRUE);
+
+ if (error)
+ {
+ g_warning ("Failed to launch syndaemon: %s", error->message);
+ g_error_free (error);
+ }
+ else
+ {
+ g_child_watch_add (priv->syndaemon_pid, syndaemon_died, settings);
+ }
+ }
+ else if (priv->syndaemon_spawned)
+ {
+ kill (priv->syndaemon_pid, SIGHUP);
+ priv->syndaemon_spawned = FALSE;
+ }
+}
+
static void
meta_input_settings_x11_set_send_events (MetaInputSettings *settings,
ClutterInputDevice *device,
@@ -461,6 +567,12 @@ meta_input_settings_x11_set_disable_while_typing (MetaInputSettings *settings,
{
guchar value = (enabled) ? 1 : 0;
+ if (is_device_synaptics (device))
+ {
+ set_synaptics_disable_w_typing (settings, enabled);
+ return;
+ }
+
change_property (device, "libinput Disable While Typing Enabled",
XA_INTEGER, 8, &value, 1);
}
--
2.21.0
From 0afa6d0940ca4f5ffafd24effd2c414963a44277 Mon Sep 17 00:00:00 2001
From: Rui Matos <tiagomatos@gmail.com>
Date: Tue, 10 Oct 2017 19:07:27 +0200
Subject: [PATCH 3/3] backends/x11: Support plain old X device configuration
We re-use part of the code added to support synaptics and add a few
bits specific for xorg-x11-drv-evdev devices.
---
src/backends/x11/meta-input-settings-x11.c | 97 +++++++++++++++++-----
1 file changed, 74 insertions(+), 23 deletions(-)
diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c
index 12a592c75..80e5ed10e 100644
--- a/src/backends/x11/meta-input-settings-x11.c
+++ b/src/backends/x11/meta-input-settings-x11.c
@@ -182,36 +182,36 @@ is_device_synaptics (ClutterInputDevice *device)
return TRUE;
}
+static gboolean
+is_device_libinput (ClutterInputDevice *device)
+{
+ guchar *has_setting;
+
+ /* We just need looking for a synaptics-specific property */
+ has_setting = get_property (device, "libinput Send Events Modes Available", XA_INTEGER, 8, 2);
+ 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)
+change_x_device_left_handed (ClutterInputDevice *device,
+ gboolean left_handed)
{
MetaDisplay *display = meta_get_display ();
MetaX11Display *x11_display = display ? display->x11_display : NULL;
MetaBackend *backend = meta_get_backend ();
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
XDevice *xdevice;
- guchar *tap_action, *buttons;
+ guchar *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);
-
if (x11_display)
meta_x11_error_trap_push (x11_display);
buttons = g_new (guchar, buttons_capacity);
@@ -235,17 +235,39 @@ change_synaptics_tap_left_handed (ClutterInputDevice *device,
if (x11_display && meta_x11_error_trap_pop_with_return (x11_display))
{
- g_warning ("Could not set synaptics touchpad left-handed for %s",
+ g_warning ("Could not set left-handed for %s",
clutter_input_device_get_device_name (device));
}
- out:
XCloseDevice (xdisplay, xdevice);
}
static void
-change_synaptics_speed (ClutterInputDevice *device,
- gdouble speed)
+change_synaptics_tap_left_handed (ClutterInputDevice *device,
+ gboolean tap_enabled,
+ gboolean left_handed)
+{
+ guchar *tap_action;
+
+ tap_action = get_property (device, "Synaptics Tap Action",
+ XA_INTEGER, 8, 7);
+ if (!tap_action)
+ return;
+
+ 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);
+
+ change_x_device_left_handed (device, left_handed);
+}
+
+static void
+change_x_device_speed (ClutterInputDevice *device,
+ gdouble speed)
{
MetaDisplay *display = meta_get_display ();
MetaX11Display *x11_display = display ? display->x11_display : NULL;
@@ -342,6 +364,23 @@ change_synaptics_speed (ClutterInputDevice *device,
XCloseDevice (xdisplay, xdevice);
}
+static void
+change_x_device_scroll_button (ClutterInputDevice *device,
+ guint button)
+{
+ guchar value;
+
+ value = button > 0 ? 1 : 0;
+ change_property (device, "Evdev Wheel Emulation",
+ XA_INTEGER, 8, &value, 1);
+ if (button > 0)
+ {
+ value = button;
+ change_property (device, "Evdev Wheel Emulation Button",
+ XA_INTEGER, 8, &value, 1);
+ }
+}
+
/* Ensure that syndaemon dies together with us, to avoid running several of
* them */
static void
@@ -510,9 +549,10 @@ 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))
+ if (is_device_synaptics (device) ||
+ !is_device_libinput (device))
{
- change_synaptics_speed (device, speed);
+ change_x_device_speed (device, speed);
return;
}
@@ -554,6 +594,11 @@ meta_input_settings_x11_set_left_handed (MetaInputSettings *settings,
g_object_unref (settings);
return;
}
+ else if (!is_device_libinput (device))
+ {
+ change_x_device_left_handed (device, enabled);
+ return;
+ }
change_property (device, "libinput Left Handed Enabled",
XA_INTEGER, 8, &value, 1);
@@ -767,6 +812,12 @@ meta_input_settings_x11_set_scroll_button (MetaInputSettings *settings,
ClutterInputDevice *device,
guint button)
{
+ if (!is_device_libinput (device))
+ {
+ change_x_device_scroll_button (device, button);
+ return;
+ }
+
change_property (device, "libinput Button Scrolling Button",
XA_INTEGER, 32, &button, 1);
}
--
2.21.0

246
SOURCES/covscan-fixes.patch Normal file
View File

@ -0,0 +1,246 @@
From 55417eea4294210495eceebd6dd4b832f371f054 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
Date: Sun, 14 Apr 2019 17:15:06 +0200
Subject: [PATCH 1/5] display: Fix a possible bug in
meta_display_sync_wayland_focus
The check for the focus xwindow is called, but not used. Fix that by
renaming the variable to reflect better what it does and actually using
the return value of the check.
This was the original intention of the author in commit
05899596d10918df5359d89baa82e6fedd0ae208 and got broken in commit
8e7e1eeef59c4f74046e6783b6334c1432255c5a.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/535
---
src/core/display.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/core/display.c b/src/core/display.c
index 0de99edb2..4c8907f40 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -1208,15 +1208,15 @@ meta_display_sync_wayland_input_focus (MetaDisplay *display)
MetaWindow *focus_window = NULL;
MetaBackend *backend = meta_get_backend ();
MetaStage *stage = META_STAGE (meta_backend_get_stage (backend));
- gboolean is_focus_xwindow = FALSE;
+ gboolean is_no_focus_xwindow = FALSE;
if (display->x11_display)
- meta_x11_display_xwindow_is_a_no_focus_window (display->x11_display,
- display->x11_display->focus_xwindow);
+ is_no_focus_xwindow = meta_x11_display_xwindow_is_a_no_focus_window (display->x11_display,
+ display->x11_display->focus_xwindow);
if (!meta_display_windows_are_interactable (display))
focus_window = NULL;
- else if (is_focus_xwindow)
+ else if (is_no_focus_xwindow)
focus_window = NULL;
else if (display->focus_window && display->focus_window->surface)
focus_window = display->focus_window;
--
2.21.0
From 17cc0a2a21c504b8631bf2ce0f508f611f9b1d3e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Mon, 27 May 2019 20:03:25 +0000
Subject: [PATCH 2/5] renderer-x11-nested: Fix copy-and-paste error
The rounding added in commit c5471e5b8b1 mixed up some variables,
whoops.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/598
---
src/backends/x11/nested/meta-renderer-x11-nested.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/backends/x11/nested/meta-renderer-x11-nested.c b/src/backends/x11/nested/meta-renderer-x11-nested.c
index 71a85a8c2..5000bf357 100644
--- a/src/backends/x11/nested/meta-renderer-x11-nested.c
+++ b/src/backends/x11/nested/meta-renderer-x11-nested.c
@@ -203,7 +203,7 @@ meta_renderer_x11_nested_create_view (MetaRenderer *renderer,
height = logical_monitor->rect.height;
}
width = roundf (width * view_scale);
- height = roundf (width * view_scale);
+ height = roundf (height * view_scale);
fake_onscreen = create_offscreen (cogl_context, width, height);
--
2.21.0
From a58fabbb0e3173359d3374b931815c21ce65032d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Mon, 27 May 2019 19:59:53 +0000
Subject: [PATCH 3/5] input-mapper: Remove unnecessary return value
Since commit ae6d9e35bd, there is a fallback to META_MATCH_IS_BUILTIN,
so the condition for returning FALSE is never met.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/598
---
src/backends/meta-input-mapper.c | 15 +++------------
1 file changed, 3 insertions(+), 12 deletions(-)
diff --git a/src/backends/meta-input-mapper.c b/src/backends/meta-input-mapper.c
index acc9b1618..fc4f3bd59 100644
--- a/src/backends/meta-input-mapper.c
+++ b/src/backends/meta-input-mapper.c
@@ -353,7 +353,7 @@ find_builtin_output (MetaInputMapper *mapper,
return panel != NULL;
}
-static gboolean
+static void
guess_candidates (MetaInputMapper *mapper,
MetaMapperInputInfo *input,
DeviceCandidates *info)
@@ -387,15 +387,7 @@ guess_candidates (MetaInputMapper *mapper,
find_builtin_output (mapper, &info->candidates[META_MATCH_IS_BUILTIN]);
}
- if (best < N_OUTPUT_MATCHES)
- {
- info->best = best;
- return TRUE;
- }
- else
- {
- return FALSE;
- }
+ info->best = best;
}
static void
@@ -408,8 +400,7 @@ mapping_helper_add (MappingHelper *helper,
info.input = input;
- if (!guess_candidates (mapper, input, &info))
- return;
+ guess_candidates (mapper, input, &info);
for (i = 0; i < helper->device_maps->len; i++)
{
--
2.21.0
From 4eb025cf36a9118cc496ae9143ee2eb510b6228c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Mon, 27 May 2019 20:22:50 +0000
Subject: [PATCH 4/5] workspace-manager: Remove unnecessary assignment
The initialization to -1 is never used, instead the variables are
re-initialized to 0 before the loop that uses them.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/598
---
src/core/meta-workspace-manager.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/core/meta-workspace-manager.c b/src/core/meta-workspace-manager.c
index af7344709..8e1f03fe8 100644
--- a/src/core/meta-workspace-manager.c
+++ b/src/core/meta-workspace-manager.c
@@ -600,8 +600,6 @@ meta_workspace_manager_calc_workspace_layout (MetaWorkspaceManager *workspace_ma
grid = g_new (int, grid_area);
- current_row = -1;
- current_col = -1;
i = 0;
switch (workspace_manager->starting_corner)
--
2.21.0
From a854a337ac8807f310ac2c474f9be290089f79f3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Mon, 27 May 2019 20:43:21 +0000
Subject: [PATCH 5/5] x11-display: Simplify bell handling
Since commit 956ab4bd made libcanberra mandatory, we never use
the system bell for handling the `audible-bell` setting. So
instead of reacting to settings changes with the exact same call
to XkbChangeEnabledControls(), just call it once when initializing.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/598
---
src/x11/meta-x11-display.c | 39 +++++++-------------------------------
1 file changed, 7 insertions(+), 32 deletions(-)
diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c
index 8ce12b994..065ffcdda 100644
--- a/src/x11/meta-x11-display.c
+++ b/src/x11/meta-x11-display.c
@@ -463,6 +463,13 @@ init_x11_bell (MetaX11Display *x11_display)
&mask);
}
}
+
+ /* We are playing sounds using libcanberra support, we handle the
+ * bell whether its an audible bell or a visible bell */
+ XkbChangeEnabledControls (x11_display->xdisplay,
+ XkbUseCoreKbd,
+ XkbAudibleBellMask,
+ 0);
}
/*
@@ -480,32 +487,6 @@ shutdown_x11_bell (MetaX11Display *x11_display)
XkbAudibleBellMask);
}
-/*
- * Turns the bell to audible or visual. This tells X what to do, but
- * not Mutter; you will need to set the "visual bell" pref for that.
- */
-static void
-set_x11_bell_is_audible (MetaX11Display *x11_display,
- gboolean is_audible)
-{
- /* When we are playing sounds using libcanberra support, we handle the
- * bell whether its an audible bell or a visible bell */
- gboolean enable_system_bell = FALSE;
-
- XkbChangeEnabledControls (x11_display->xdisplay,
- XkbUseCoreKbd,
- XkbAudibleBellMask,
- enable_system_bell ? XkbAudibleBellMask : 0);
-}
-
-static void
-on_is_audible_changed (MetaBell *bell,
- gboolean is_audible,
- MetaX11Display *x11_display)
-{
- set_x11_bell_is_audible (x11_display, is_audible);
-}
-
static void
set_desktop_geometry_hint (MetaX11Display *x11_display)
{
@@ -1320,12 +1301,6 @@ meta_x11_display_new (MetaDisplay *display, GError **error)
init_x11_bell (x11_display);
- g_signal_connect_object (display->bell, "is-audible-changed",
- G_CALLBACK (on_is_audible_changed),
- x11_display, 0);
-
- set_x11_bell_is_audible (x11_display, meta_prefs_bell_is_audible ());
-
meta_x11_startup_notification_init (x11_display);
return x11_display;
--
2.21.0

View File

@ -0,0 +1,85 @@
From 575490895047e0709bc84826fe6d6a73028d7bbc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Wed, 12 Mar 2014 02:04:13 +0100
Subject: [PATCH] constraints: Enforce X11 size limits
X11 limits windows to a maximum of 32767x32767, enforce that restriction
to keep insanely huge windows from crashing the WM.
---
src/core/constraints.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/src/core/constraints.c b/src/core/constraints.c
index 117131b15..379372245 100644
--- a/src/core/constraints.c
+++ b/src/core/constraints.c
@@ -109,6 +109,7 @@ typedef enum
PRIORITY_TITLEBAR_VISIBLE = 4,
PRIORITY_PARTIALLY_VISIBLE_ON_WORKAREA = 4,
PRIORITY_CUSTOM_RULE = 4,
+ PRIORITY_XLIMITS = 4,
PRIORITY_MAXIMUM = 4 /* Dummy value used for loop end = max(all priorities) */
} ConstraintPriority;
@@ -201,6 +202,10 @@ static gboolean constrain_partially_onscreen (MetaWindow *window,
ConstraintInfo *info,
ConstraintPriority priority,
gboolean check_only);
+static gboolean constrain_xlimits (MetaWindow *window,
+ ConstraintInfo *info,
+ ConstraintPriority priority,
+ gboolean check_only);
static void setup_constraint_info (ConstraintInfo *info,
MetaWindow *window,
@@ -236,6 +241,7 @@ static const Constraint all_constraints[] = {
{constrain_fully_onscreen, "constrain_fully_onscreen"},
{constrain_titlebar_visible, "constrain_titlebar_visible"},
{constrain_partially_onscreen, "constrain_partially_onscreen"},
+ {constrain_xlimits, "constrain_xlimits"},
{NULL, NULL}
};
@@ -1780,3 +1786,39 @@ constrain_partially_onscreen (MetaWindow *window,
return retval;
}
+
+
+#define MAX_WINDOW_SIZE 32767
+
+static gboolean
+constrain_xlimits (MetaWindow *window,
+ ConstraintInfo *info,
+ ConstraintPriority priority,
+ gboolean check_only)
+{
+ int max_w, max_h;
+ gboolean constraint_already_satisfied;
+
+ if (priority > PRIORITY_XLIMITS)
+ return TRUE;
+
+ max_w = max_h = MAX_WINDOW_SIZE;
+
+ if (window->frame)
+ {
+ MetaFrameBorders borders;
+ meta_frame_calc_borders (window->frame, &borders);
+
+ max_w -= (borders.total.left + borders.total.right);
+ max_h -= (borders.total.top + borders.total.bottom);
+ }
+
+ constraint_already_satisfied = info->current.width < max_w && info->current.height < max_h;
+ if (check_only || constraint_already_satisfied)
+ return constraint_already_satisfied;
+
+ info->current.width = MIN (info->current.width, max_w);
+ info->current.height = MIN (info->current.height, max_h);
+
+ return TRUE;
+}
--
2.21.0

View File

@ -0,0 +1,138 @@
From 30d6e3abe2a0251b11513d66d15a59cd0705a828 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Mon, 27 May 2019 17:48:41 +0000
Subject: [PATCH 1/2] clutter-text: Fix selection color drawing
Commit cabcad185 removed the call to cogl_set_source_color4ub() before
cogl_fill_path(), so instead of the previously assigned selection color,
the background is drawn with the last set source.
In order to honour the newly added framebuffer parameter and still apply
the correct color, switch from cogl_fill_path() to the (deprecated!)
cogl_framebuffer_fill_path() method.
https://gitlab.gnome.org/GNOME/mutter/issues/494
---
clutter/clutter/clutter-text.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/clutter/clutter/clutter-text.c b/clutter/clutter/clutter-text.c
index fb9d926df..000bbbbd4 100644
--- a/clutter/clutter/clutter-text.c
+++ b/clutter/clutter/clutter-text.c
@@ -1975,6 +1975,7 @@ selection_paint (ClutterText *self,
else
{
/* Paint selection background first */
+ CoglPipeline *color_pipeline = cogl_pipeline_copy (default_color_pipeline);
PangoLayout *layout = clutter_text_get_layout (self);
CoglPath *selection_path = cogl_path_new ();
CoglColor cogl_color = { 0, };
@@ -1987,11 +1988,19 @@ selection_paint (ClutterText *self,
else
color = &priv->text_color;
+ cogl_color_init_from_4ub (&cogl_color,
+ color->red,
+ color->green,
+ color->blue,
+ paint_opacity * color->alpha / 255);
+ cogl_color_premultiply (&cogl_color);
+ cogl_pipeline_set_color (color_pipeline, &cogl_color);
+
clutter_text_foreach_selection_rectangle_prescaled (self,
add_selection_rectangle_to_path,
selection_path);
- cogl_path_fill (selection_path);
+ cogl_framebuffer_fill_path (fb, color_pipeline, selection_path);
/* Paint selected text */
cogl_framebuffer_push_path_clip (fb, selection_path);
--
2.21.0
From 13a1624c1050c91cd4d8a298f7a10fafe56fe9e5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Mon, 27 May 2019 22:40:47 +0000
Subject: [PATCH 2/2] cogl-path: Undeprecate framebuffer functions
It looks like deprecating the functions with explicit framebuffer/pipeline
arguments made it to (cogl) master by mistake:
https://mail.gnome.org/archives/clutter-list/2016-April/msg00008.html
We now use one of them, so this is a good time to undeprecate the lot.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/597
---
cogl/cogl-path/cogl-path-functions.h | 6 ------
cogl/cogl-path/cogl-path.c | 3 ---
2 files changed, 9 deletions(-)
diff --git a/cogl/cogl-path/cogl-path-functions.h b/cogl/cogl-path/cogl-path-functions.h
index d4ef328d2..318fed028 100644
--- a/cogl/cogl-path/cogl-path-functions.h
+++ b/cogl/cogl-path/cogl-path-functions.h
@@ -460,9 +460,7 @@ cogl_path_fill (CoglPath *path);
* use while filling a path.</note>
*
* Stability: unstable
- * Deprecated: 1.16: Use cogl_path_fill() instead
*/
-COGL_DEPRECATED_FOR (cogl_path_fill)
void
cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
@@ -492,9 +490,7 @@ cogl_path_stroke (CoglPath *path);
* regardless of the current transformation matrix.
*
* Stability: unstable
- * Deprecated: 1.16: Use cogl_path_stroke() instead
*/
-COGL_DEPRECATED_FOR (cogl_path_stroke)
void
cogl_framebuffer_stroke_path (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
@@ -529,9 +525,7 @@ cogl_framebuffer_push_path_clip (CoglFramebuffer *framebuffer,
*
* Since: 1.8
* Stability: Unstable
- * Deprecated: 1.16: Use cogl_framebuffer_push_path_clip() instead
*/
-COGL_DEPRECATED_FOR (cogl_framebuffer_push_path_clip)
void
cogl_clip_push_from_path (CoglPath *path);
diff --git a/cogl/cogl-path/cogl-path.c b/cogl/cogl-path/cogl-path.c
index 4d86c6fb5..8774406f8 100644
--- a/cogl/cogl-path/cogl-path.c
+++ b/cogl/cogl-path/cogl-path.c
@@ -1504,7 +1504,6 @@ cogl_framebuffer_push_path_clip (CoglFramebuffer *framebuffer,
COGL_FRAMEBUFFER_STATE_CLIP;
}
-/* XXX: deprecated */
void
cogl_clip_push_from_path (CoglPath *path)
{
@@ -1575,7 +1574,6 @@ _cogl_path_build_stroke_attribute_buffer (CoglPath *path)
data->stroke_n_attributes = n_attributes;
}
-/* XXX: deprecated */
void
cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
@@ -1588,7 +1586,6 @@ cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer,
_cogl_path_fill_nodes (path, framebuffer, pipeline, 0 /* flags */);
}
-/* XXX: deprecated */
void
cogl_framebuffer_stroke_path (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
--
2.21.0

1115
SPECS/mutter.spec Normal file

File diff suppressed because it is too large Load Diff