diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d71c898 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/mutter-3.32.2.tar.xz diff --git a/.mutter.metadata b/.mutter.metadata new file mode 100644 index 0000000..9e3c1a4 --- /dev/null +++ b/.mutter.metadata @@ -0,0 +1 @@ +5068f43514a6212e4b5b5f7f856b7713cbc3d420 SOURCES/mutter-3.32.2.tar.xz diff --git a/SOURCES/0001-Add-support-for-quad-buffer-stereo.patch b/SOURCES/0001-Add-support-for-quad-buffer-stereo.patch new file mode 100644 index 0000000..8e12a79 --- /dev/null +++ b/SOURCES/0001-Add-support-for-quad-buffer-stereo.patch @@ -0,0 +1,909 @@ +From 2b45c3e37da7a590227e965d8a18e89337b791ba Mon Sep 17 00:00:00 2001 +From: "Owen W. Taylor" +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 ++ ++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 . ++ */ ++ ++/* ++ * 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 ++ ++#include ++#include ++#include ++ ++#include "display-private.h" ++#include ++#include ++#include ++#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 . ++ */ ++ ++#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 + diff --git a/SOURCES/0001-backends-x11-Support-synaptics-configuration.patch b/SOURCES/0001-backends-x11-Support-synaptics-configuration.patch new file mode 100644 index 0000000..2dd5bb9 --- /dev/null +++ b/SOURCES/0001-backends-x11-Support-synaptics-configuration.patch @@ -0,0 +1,349 @@ +From 471174ba6cf517baf8ff73e903202e1c73b6ec74 Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +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 ++#include + #include + #include + #include +@@ -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 + diff --git a/SOURCES/0001-clutter-Extend-touchpad-device-property-check-for-Sy.patch b/SOURCES/0001-clutter-Extend-touchpad-device-property-check-for-Sy.patch new file mode 100644 index 0000000..96fe26b --- /dev/null +++ b/SOURCES/0001-clutter-Extend-touchpad-device-property-check-for-Sy.patch @@ -0,0 +1,61 @@ +From 368fdebe8f4f4e0c0e41f5be9961a748f328cb57 Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +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 + diff --git a/SOURCES/0001-clutter-Only-reset-scroll-axes-on-slave-devices.patch b/SOURCES/0001-clutter-Only-reset-scroll-axes-on-slave-devices.patch new file mode 100644 index 0000000..dd9eeb5 --- /dev/null +++ b/SOURCES/0001-clutter-Only-reset-scroll-axes-on-slave-devices.patch @@ -0,0 +1,27 @@ +From 2259241e4e6f03bea4e9d746582a9e6a82b3c755 Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +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 + diff --git a/SOURCES/0001-cogl-add-new-UNSTABLE_TEXTURES-feature.patch b/SOURCES/0001-cogl-add-new-UNSTABLE_TEXTURES-feature.patch new file mode 100644 index 0000000..673608d --- /dev/null +++ b/SOURCES/0001-cogl-add-new-UNSTABLE_TEXTURES-feature.patch @@ -0,0 +1,136 @@ +From 78bb1fff1155462638b0d6037ccddf1328482842 Mon Sep 17 00:00:00 2001 +From: Ray Strode +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 + diff --git a/SOURCES/0001-enum-types-Use-basename-in-header-comment.patch b/SOURCES/0001-enum-types-Use-basename-in-header-comment.patch new file mode 100644 index 0000000..88b3a4f --- /dev/null +++ b/SOURCES/0001-enum-types-Use-basename-in-header-comment.patch @@ -0,0 +1,55 @@ +From 62387eb649b7b33d923d5382f85c9210a3bedbe8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +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 + diff --git a/SOURCES/0001-events-Don-t-move-sloppy-focus-while-buttons-are-pre.patch b/SOURCES/0001-events-Don-t-move-sloppy-focus-while-buttons-are-pre.patch new file mode 100644 index 0000000..69fc6ef --- /dev/null +++ b/SOURCES/0001-events-Don-t-move-sloppy-focus-while-buttons-are-pre.patch @@ -0,0 +1,42 @@ +From f735f345ad8390a7fb09ef54ca3e0e419d395d1b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +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 + diff --git a/SOURCES/0001-main-be-more-aggressive-in-assuming-X11-backend.patch b/SOURCES/0001-main-be-more-aggressive-in-assuming-X11-backend.patch new file mode 100644 index 0000000..495d859 --- /dev/null +++ b/SOURCES/0001-main-be-more-aggressive-in-assuming-X11-backend.patch @@ -0,0 +1,49 @@ +From 18d4fbb1fb641e2b507b3adcd13d231145a01cd6 Mon Sep 17 00:00:00 2001 +From: Ray Strode +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 + diff --git a/SOURCES/0001-monitor-manager-Consider-external-layout-before-defa.patch b/SOURCES/0001-monitor-manager-Consider-external-layout-before-defa.patch new file mode 100644 index 0000000..d204242 --- /dev/null +++ b/SOURCES/0001-monitor-manager-Consider-external-layout-before-defa.patch @@ -0,0 +1,152 @@ +From 4904f1a1e5b881dfd5a051c15acecb3232dc8207 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +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 + diff --git a/SOURCES/0001-monitor-manager-only-reuse-initial-config-if-monitor.patch b/SOURCES/0001-monitor-manager-only-reuse-initial-config-if-monitor.patch new file mode 100644 index 0000000..dc34cee --- /dev/null +++ b/SOURCES/0001-monitor-manager-only-reuse-initial-config-if-monitor.patch @@ -0,0 +1,144 @@ +From 4ad8fd80355189ecbde6c38961335ae4be4db8b3 Mon Sep 17 00:00:00 2001 +From: 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 + diff --git a/SOURCES/0001-monitor-manager-xrandr-Force-an-update-when-resuming.patch b/SOURCES/0001-monitor-manager-xrandr-Force-an-update-when-resuming.patch new file mode 100644 index 0000000..2242c67 --- /dev/null +++ b/SOURCES/0001-monitor-manager-xrandr-Force-an-update-when-resuming.patch @@ -0,0 +1,272 @@ +From 849902beff553de41dd3940b17672ef98f687be5 Mon Sep 17 00:00:00 2001 +From: Rui Matos +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 + diff --git a/SOURCES/0001-monitor-manager-xrandr-Work-around-spurious-hotplugs.patch b/SOURCES/0001-monitor-manager-xrandr-Work-around-spurious-hotplugs.patch new file mode 100644 index 0000000..c487119 --- /dev/null +++ b/SOURCES/0001-monitor-manager-xrandr-Work-around-spurious-hotplugs.patch @@ -0,0 +1,62 @@ +From 7e21503dc7c3b8321475eb5ccfdb23e71f86c0a0 Mon Sep 17 00:00:00 2001 +From: Rui Matos +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 + diff --git a/SOURCES/0001-wayland-Allow-Xwayland-grabs-on-selected-apps.patch b/SOURCES/0001-wayland-Allow-Xwayland-grabs-on-selected-apps.patch new file mode 100644 index 0000000..83f42ff --- /dev/null +++ b/SOURCES/0001-wayland-Allow-Xwayland-grabs-on-selected-apps.patch @@ -0,0 +1,35 @@ +From 9dfe362f41b8811450cb563c39899fafe8ec2b63 Mon Sep 17 00:00:00 2001 +From: Olivier Fourdan +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@"> + + +- false ++ true + Allow grabs with Xwayland + + Allow keyboard grabs issued by X11 applications running in Xwayland +@@ -73,7 +73,7 @@ + + + +- [] ++ ['@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@'] + Xwayland applications allowed to issue keyboard grabs + + List the resource names or resource class of X11 windows either +-- +2.21.0 + diff --git a/SOURCES/0001-window-actor-Special-case-shaped-Java-windows.patch b/SOURCES/0001-window-actor-Special-case-shaped-Java-windows.patch new file mode 100644 index 0000000..3cf01de --- /dev/null +++ b/SOURCES/0001-window-actor-Special-case-shaped-Java-windows.patch @@ -0,0 +1,35 @@ +From 6bca5f001338d4647e4e21d549c8cdea4bcad669 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +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 + diff --git a/SOURCES/0001-workspace-manager-Expose-layout-properties.patch b/SOURCES/0001-workspace-manager-Expose-layout-properties.patch new file mode 100644 index 0000000..908fe67 --- /dev/null +++ b/SOURCES/0001-workspace-manager-Expose-layout-properties.patch @@ -0,0 +1,80 @@ +From 52536a44e96aa34d3ec3b9332adaa15a6399fc3e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +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 + diff --git a/SOURCES/0002-backend-switch-to-using-generated-logind-proxy.patch b/SOURCES/0002-backend-switch-to-using-generated-logind-proxy.patch new file mode 100644 index 0000000..3cb0623 --- /dev/null +++ b/SOURCES/0002-backend-switch-to-using-generated-logind-proxy.patch @@ -0,0 +1,163 @@ +From 063db6c9a7504a4d7baae28f7899bd661c459c41 Mon Sep 17 00:00:00 2001 +From: Ray Strode +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 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +-- +2.21.0 + diff --git a/SOURCES/0003-backend-add-signals-for-reporting-suspend-and-resume.patch b/SOURCES/0003-backend-add-signals-for-reporting-suspend-and-resume.patch new file mode 100644 index 0000000..911ac79 --- /dev/null +++ b/SOURCES/0003-backend-add-signals-for-reporting-suspend-and-resume.patch @@ -0,0 +1,146 @@ +From 9f566208d584ec4d8da797390b6806157c7d2402 Mon Sep 17 00:00:00 2001 +From: Ray Strode +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 + diff --git a/SOURCES/0004-wayland-force-X-clients-to-redraw-on-resume.patch b/SOURCES/0004-wayland-force-X-clients-to-redraw-on-resume.patch new file mode 100644 index 0000000..d5a0e9f --- /dev/null +++ b/SOURCES/0004-wayland-force-X-clients-to-redraw-on-resume.patch @@ -0,0 +1,118 @@ +From a4a703c75e208badf78c81558994a249797dbb0a Mon Sep 17 00:00:00 2001 +From: Ray Strode +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 + diff --git a/SOURCES/0005-backends-native-emit-gl-video-memory-purged-when-bec.patch b/SOURCES/0005-backends-native-emit-gl-video-memory-purged-when-bec.patch new file mode 100644 index 0000000..0567862 --- /dev/null +++ b/SOURCES/0005-backends-native-emit-gl-video-memory-purged-when-bec.patch @@ -0,0 +1,40 @@ +From 122d7726e450712b8b2fc85db41e3c8ab7b6ad56 Mon Sep 17 00:00:00 2001 +From: Ray Strode +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 + diff --git a/SOURCES/0006-backends-native-update-glyph-cache-on-resume.patch b/SOURCES/0006-backends-native-update-glyph-cache-on-resume.patch new file mode 100644 index 0000000..3f4193b --- /dev/null +++ b/SOURCES/0006-backends-native-update-glyph-cache-on-resume.patch @@ -0,0 +1,35 @@ +From 762ffddfa6157fe50bfa394ecbe4ba707d15f368 Mon Sep 17 00:00:00 2001 +From: Ray Strode +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 + diff --git a/SOURCES/0007-backends-native-update-cursor-on-resume.patch b/SOURCES/0007-backends-native-update-cursor-on-resume.patch new file mode 100644 index 0000000..721996f --- /dev/null +++ b/SOURCES/0007-backends-native-update-cursor-on-resume.patch @@ -0,0 +1,38 @@ +From 59ba24c09e5d2a3210ca3d259789f7ba5ae6266a Mon Sep 17 00:00:00 2001 +From: Ray Strode +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 + diff --git a/SOURCES/0008-background-purge-all-background-textures-on-suspend.patch b/SOURCES/0008-background-purge-all-background-textures-on-suspend.patch new file mode 100644 index 0000000..1034111 --- /dev/null +++ b/SOURCES/0008-background-purge-all-background-textures-on-suspend.patch @@ -0,0 +1,110 @@ +From c78a614b0d45a4bc8101a93c7138c9fb6102d13c Mon Sep 17 00:00:00 2001 +From: Ray Strode +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 + diff --git a/SOURCES/0009-MetaShapedTexture-save-and-restore-textures-on-suspe.patch b/SOURCES/0009-MetaShapedTexture-save-and-restore-textures-on-suspe.patch new file mode 100644 index 0000000..4b38154 --- /dev/null +++ b/SOURCES/0009-MetaShapedTexture-save-and-restore-textures-on-suspe.patch @@ -0,0 +1,712 @@ +From d8cc418899276b45cb1a787493e0998e3b008fe5 Mon Sep 17 00:00:00 2001 +From: Ray Strode +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 + #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 + diff --git a/SOURCES/add-support-for-plain-old-x-device-configuration.patch b/SOURCES/add-support-for-plain-old-x-device-configuration.patch new file mode 100644 index 0000000..53813c1 --- /dev/null +++ b/SOURCES/add-support-for-plain-old-x-device-configuration.patch @@ -0,0 +1,378 @@ +From 3f7ba6739773f43a3ad2a5d26cb8c3365f77cc00 Mon Sep 17 00:00:00 2001 +From: Rui Matos +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 +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 + #endif ++#ifdef __linux ++#include ++#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 +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 + diff --git a/SOURCES/covscan-fixes.patch b/SOURCES/covscan-fixes.patch new file mode 100644 index 0000000..25bfe3c --- /dev/null +++ b/SOURCES/covscan-fixes.patch @@ -0,0 +1,246 @@ +From 55417eea4294210495eceebd6dd4b832f371f054 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= +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?= +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?= +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?= +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?= +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 + diff --git a/SOURCES/deal-more-gracefully-with-oversized-windows.patch b/SOURCES/deal-more-gracefully-with-oversized-windows.patch new file mode 100644 index 0000000..9a7a36d --- /dev/null +++ b/SOURCES/deal-more-gracefully-with-oversized-windows.patch @@ -0,0 +1,85 @@ +From 575490895047e0709bc84826fe6d6a73028d7bbc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +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 + diff --git a/SOURCES/fix-text-selection-drawing.patch b/SOURCES/fix-text-selection-drawing.patch new file mode 100644 index 0000000..11554aa --- /dev/null +++ b/SOURCES/fix-text-selection-drawing.patch @@ -0,0 +1,138 @@ +From 30d6e3abe2a0251b11513d66d15a59cd0705a828 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +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?= +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. + * + * 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 + diff --git a/SPECS/mutter.spec b/SPECS/mutter.spec new file mode 100644 index 0000000..4bcf864 --- /dev/null +++ b/SPECS/mutter.spec @@ -0,0 +1,1115 @@ +%global gtk3_version 3.19.8 +%global glib_version 2.53.2 +%global gsettings_desktop_schemas_version 3.21.4 +%global json_glib_version 0.12.0 +%global libinput_version 1.4 +%global pipewire_version 0.2.2 +%global mutter_api_version 4 + +Name: mutter +Version: 3.32.2 +Release: 4%{?dist} +Summary: Window and compositing manager based on Clutter + +License: GPLv2+ +#VCS: git:git://git.gnome.org/mutter +URL: http://www.gnome.org +Source0: http://download.gnome.org/sources/%{name}/3.32/%{name}-%{version}.tar.xz + +# Work-around for OpenJDK's compliance test +Patch0: 0001-window-actor-Special-case-shaped-Java-windows.patch + +# Allow Xwayland grabs by default, on a selected set of X11 apps +# https://bugzilla.redhat.com/1500399 +Patch1: 0001-wayland-Allow-Xwayland-grabs-on-selected-apps.patch + +Patch2: fix-text-selection-drawing.patch +Patch3: covscan-fixes.patch +Patch4: 0001-enum-types-Use-basename-in-header-comment.patch +Patch5: 0001-workspace-manager-Expose-layout-properties.patch + +# Fix corruption on suspend and resume with nvidia (rhbz#1663440) +Patch10001: 0001-cogl-add-new-UNSTABLE_TEXTURES-feature.patch +Patch10002: 0002-backend-switch-to-using-generated-logind-proxy.patch +Patch10003: 0003-backend-add-signals-for-reporting-suspend-and-resume.patch +Patch10004: 0004-wayland-force-X-clients-to-redraw-on-resume.patch +Patch10005: 0005-backends-native-emit-gl-video-memory-purged-when-bec.patch +Patch10006: 0006-backends-native-update-glyph-cache-on-resume.patch +Patch10007: 0007-backends-native-update-cursor-on-resume.patch +Patch10008: 0008-background-purge-all-background-textures-on-suspend.patch +Patch10009: 0009-MetaShapedTexture-save-and-restore-textures-on-suspe.patch + +# RHEL 7 downstream patches +Patch100: deal-more-gracefully-with-oversized-windows.patch +# Work-around for Xvnc resizing (rhbz#1265511) +Patch101: 0001-monitor-manager-xrandr-Work-around-spurious-hotplugs.patch +Patch102: 0001-monitor-manager-xrandr-Force-an-update-when-resuming.patch +Patch103: 0001-monitor-manager-Consider-external-layout-before-defa.patch +Patch104: 0001-events-Don-t-move-sloppy-focus-while-buttons-are-pre.patch +Patch105: 0001-backends-x11-Support-synaptics-configuration.patch +Patch107: 0001-clutter-Extend-touchpad-device-property-check-for-Sy.patch +# http://bugzilla.gnome.org/show_bug.cgi?id=733277 +Patch109: 0001-Add-support-for-quad-buffer-stereo.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1618632 +# https://bugzilla.redhat.com/show_bug.cgi?id=1497303 +Patch110: 0001-monitor-manager-only-reuse-initial-config-if-monitor.patch +Patch112: add-support-for-plain-old-x-device-configuration.patch +Patch113: 0001-main-be-more-aggressive-in-assuming-X11-backend.patch +Patch114: 0001-clutter-Only-reset-scroll-axes-on-slave-devices.patch + +BuildRequires: chrpath +BuildRequires: pango-devel +BuildRequires: startup-notification-devel +BuildRequires: gnome-desktop3-devel +BuildRequires: glib2-devel >= %{glib_version} +BuildRequires: gtk3-devel >= %{gtk3_version} +BuildRequires: pkgconfig +BuildRequires: gobject-introspection-devel >= 1.41.0 +BuildRequires: libSM-devel +BuildRequires: libwacom-devel +BuildRequires: libX11-devel +BuildRequires: libXdamage-devel +BuildRequires: libXext-devel +BuildRequires: libXfixes-devel +BuildRequires: libXi-devel +BuildRequires: libXrandr-devel +BuildRequires: libXrender-devel +BuildRequires: libXcursor-devel +BuildRequires: libXcomposite-devel +BuildRequires: libxcb-devel +BuildRequires: libxkbcommon-devel +BuildRequires: libxkbcommon-x11-devel +BuildRequires: libxkbfile-devel +BuildRequires: libXtst-devel +BuildRequires: mesa-libEGL-devel +BuildRequires: mesa-libGLES-devel +BuildRequires: mesa-libGL-devel +BuildRequires: mesa-libgbm-devel +BuildRequires: pam-devel +BuildRequires: pipewire-devel >= %{pipewire_version} +BuildRequires: systemd-devel +BuildRequires: upower-devel +BuildRequires: xorg-x11-server-Xorg +BuildRequires: xkeyboard-config-devel +BuildRequires: zenity +BuildRequires: desktop-file-utils +# Bootstrap requirements +BuildRequires: gtk-doc gnome-common gettext-devel git +BuildRequires: libcanberra-devel +BuildRequires: gsettings-desktop-schemas-devel >= %{gsettings_desktop_schemas_version} +BuildRequires: gnome-settings-daemon-devel +BuildRequires: meson +BuildRequires: pkgconfig(gudev-1.0) +BuildRequires: pkgconfig(libdrm) +BuildRequires: pkgconfig(gbm) +BuildRequires: pkgconfig(wayland-server) +BuildRequires: pkgconfig(wayland-eglstream) + +BuildRequires: json-glib-devel >= %{json_glib_version} +BuildRequires: libgudev1-devel +BuildRequires: libinput-devel >= %{libinput_version} +BuildRequires: xorg-x11-server-Xwayland + +Obsoletes: mutter-wayland < 3.13.0 +Obsoletes: mutter-wayland-devel < 3.13.0 + +# Make sure yum updates gnome-shell as well; otherwise we might end up with +# broken gnome-shell installations due to mutter ABI changes. +Conflicts: gnome-shell < 3.21.1 + +Requires: control-center-filesystem +Requires: gsettings-desktop-schemas%{?_isa} >= %{gsettings_desktop_schemas_version} +Requires: gtk3%{?_isa} >= %{gtk3_version} +Requires: pipewire%{_isa} >= %{pipewire_version} +Requires: startup-notification +Requires: dbus +Requires: zenity + +Requires: json-glib%{?_isa} >= %{json_glib_version} +Requires: libinput%{?_isa} >= %{libinput_version} + +%description +Mutter is a window and compositing manager that displays and manages +your desktop via OpenGL. Mutter combines a sophisticated display engine +using the Clutter toolkit with solid window-management logic inherited +from the Metacity window manager. + +While Mutter can be used stand-alone, it is primarily intended to be +used as the display core of a larger system such as GNOME Shell. For +this reason, Mutter is very extensible via plugins, which are used both +to add fancy visual effects and to rework the window management +behaviors to meet the needs of the environment. + +%package devel +Summary: Development package for %{name} +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description devel +Header files and libraries for developing Mutter plugins. Also includes +utilities for testing Metacity/Mutter themes. + +%package tests +Summary: Tests for the %{name} package +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description tests +The %{name}-tests package contains tests that can be used to verify +the functionality of the installed %{name} package. + +%prep +%autosetup -S git + +%build +%meson -Degl_device=true -Dwayland_eglstream=true +%meson_build + +%install +%meson_install + +%find_lang %{name} + +# Mutter contains a .desktop file so we just need to validate it +desktop-file-validate %{buildroot}/%{_datadir}/applications/%{name}.desktop + +%ldconfig_scriptlets + +%files -f %{name}.lang +%license COPYING +%doc NEWS +%{_bindir}/mutter +%{_datadir}/applications/*.desktop +%{_libdir}/lib*.so.* +%{_libdir}/mutter-%{mutter_api_version}/ +%{_libexecdir}/mutter-restart-helper +%{_datadir}/GConf/gsettings/mutter-schemas.convert +%{_datadir}/glib-2.0/schemas/org.gnome.mutter.gschema.xml +%{_datadir}/glib-2.0/schemas/org.gnome.mutter.wayland.gschema.xml +%{_datadir}/gnome-control-center/keybindings/50-mutter-*.xml +%{_mandir}/man1/mutter.1* + +%files devel +%{_includedir}/* +%{_libdir}/lib*.so +%{_libdir}/pkgconfig/* + +%files tests +%{_libexecdir}/installed-tests/mutter-%{mutter_api_version} +%{_datadir}/installed-tests/mutter-%{mutter_api_version} +%{_datadir}/mutter-%{mutter_api_version}/tests + +%changelog +* Wed Jun 12 2019 Florian Müllner - 3.32.2-4 +- Expose workspace layout as properties + Related: #1704360 + +* Thu May 30 2019 Florian Müllner - 3.32.2-3 +- Avoid arch-specific bits in header comments + Related: #1698884 +* Tue May 28 2019 Florian Müllner - 3.32.2-2 +- Fix a couple of issues pointed out by covscan + Resolves: #1698884 + +* Thu May 23 2019 Florian Müllner - 3.32.2-1 +- Update to 3.32.2 + Resolves: #1698884 + +* Tue Apr 02 2019 Carlos Garnacho - 3.28.3-19 +- Fix synaptics/evdev driver support forward port to not break tablet pads + Resolves: #1687949 + +* Thu Feb 21 2019 Jonas Ådahl - 3.28.3-18 +- Remove patch enabling monitor framebuffer scaling + Related: #1668883 + +* Mon Feb 11 2019 Ray Strode - 3.28.3-17 +- Fix bug in suspend/resume corruption patch leading to inhibit fd + not getting fetched + Related: #1663440 + +* Mon Feb 11 2019 Florian Müllner - 3.28.3-16 +- Backport forward_key() method + Related: #1668979 + +* Mon Feb 11 2019 Florian Müllner - 3.28.3-15 +- Re-add dropped downstream patches (rhbz#1668883) + +* Tue Feb 05 2019 Olivier Fourdan - 3.28.3-14 +- Restore update monitor fix (rhbz#1635123) + +* Fri Feb 01 2019 Jonas Ådahl - 3.28.3-13 +- Fix screen recording on HiDPI monitor (rhbz#1670287) + +* Thu Jan 31 2019 Ray Strode - 3.28.3-12 +- Drop "Always update monitor for non user op" patch. It's already + in tree and getting misapplied + Related: #1663440 +- Fix suspend and resume corruption on NVidia + Resolves: #1663440 + +* Tue Jan 22 2019 Olivier Fourdan - 3.28.3-11 +- Fix a new crash in recordwindow related to behavior changes in + recent backport additions (rhbz#1657661) + +* Fri Jan 11 2019 Jonas Ådahl - 3.28.3-10 +- Backport screen cast cursor side channel patches (rhbz#1658971) + +* Fri Jan 11 2019 Jonas Ådahl - 3.28.3-9 +- Avoid EGLStream backend deadlock (rhbz#1656905) + +* Fri Jan 11 2019 Jonas Ådahl - 3.28.3-8 +- Get texture pixels via offscreen for EGLStreams (rhbz#1656926) + +* Mon Jan 07 2019 Olivier Fourdan - 3.28.3-7 +- Backport the RecordWindow screencast mode (rhbz#1657661) + +* Fri Jan 04 2019 Ray Strode - 3.28.3-6 +- Add shadow framebuffer for server cards to fix blending + performance + Resolves: #1591250 + +* Fri Oct 26 2018 Olivier Fourdan - 3.28.3-5 +- Allow Xwayland grabs on a selected set of X11 applications. + (rhbz#1500399) + +* Tue Oct 23 2018 Olivier Fourdan - 3.28.3-4 +- More backport fixes from upstream "gnome-3-28" branch +- enable eglstream support (rhbz#1639782) + +* Mon Oct 15 2018 Jonas Ådahl - 3.28.3-3 +- Fix garbled window titles (rhbz#1639194) + +* Thu Oct 04 2018 Olivier Fourdan - 3.28.3-2 +- Backport fixes from upstream "gnome-3-28" branch: +- [wayland] laptop with lid closed and external monitor can't log in to + wayland session (rhbz#1635106) +- [Wayland] Crash with Xwayland grabs enabled in mutter (rhbz#1635110) +- [Wayland] Crash on monitor hotplug (rhbz#1635123) +- [wayland] mutter crashes if drmModeSetCrtc() failed (rhbz#1635155) +- mutter crashes if a modal window closes whilst being dragged (rhbz#1635159) +- gnome-shell crashed with SIGSEGV in meta_monitor_mode_get_resolution() + (rhbz#1635164) +- [wayland] crash when drmModeGetResources() fails (rhbz#1635167) +- [wayland] Can't create new back buffer on Intel i915 (rhbz#1635170) +- [wayland] keyboard: Create a separate keymap shm file per resource + (rhbz#1635235) +- Crash in gnome-shell/mutter after a window is destroyed (rhbz#1635237) +- [x11] Using a cursor theme missing cursors can crash mutter (rhbz#1635241) +- [wayland] Warning messages when starting mutter (rhbz#1635248) +- [wayland] mutter/gnome-shell crash after failed DnD in nautilus + (rhbz#1635718) + +* Thu Aug 09 2018 Kalev Lember - 3.28.3-1 +- Update to 3.28.3 +- Apply HW cursor on-demand patches +- Apply monitor transform regression patch + +* Wed Aug 08 2018 Jonas Ådahl - 3.28.1-4 +- Backport remote-access controller API patch + +* Tue Aug 07 2018 Jonas Ådahl - 3.28.1-3 +- Backport remote desktop related patches + +* Wed Aug 01 2018 Jan Grulich - 3.28.1-2 +- Support PipeWire 0.2.2+ + +* Fri Apr 13 2018 Florian Müllner - 3.28.1-1 +- Update to 3.28.1 + +* Mon Mar 12 2018 Florian Müllner - 3.28.0-1 +- Update to 3.28.0 + +* Mon Mar 05 2018 Florian Müllner - 3.27.92-1 +- Update to 3.27.92 + +* Wed Feb 28 2018 Adam Williamson - 3.27.91-2 +- Backport MR#36 to fix RHBZ #1547691 (GGO #2), mouse issues + +* Wed Feb 21 2018 Florian Müllner - 3.27.91-1 +- Update to 3.27.91 + +* Tue Feb 13 2018 Björn Esser - 3.27.1-4 +- Rebuild against newer gnome-desktop3 package +- Add patch for adjustments to pipewire 0.1.8 API + +* Thu Feb 08 2018 Fedora Release Engineering - 3.27.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Sat Jan 06 2018 Igor Gnatenko - 3.27.1-2 +- Remove obsolete scriptlets + +* Mon Oct 30 2017 Florian Müllner - 3.27.1-1 +- Include 32-bit build fixes + +* Tue Oct 17 2017 Florian Müllner - 3.27.1-1 +- Update to 3.27.1 + +* Fri Oct 06 2017 Florian Müllner - 3.26.1-2 +- Fix screencasts + +* Wed Oct 04 2017 Florian Müllner - 3.26.1-1 +- Update to 3.26.1 + +* Thu Sep 21 2017 Florian Müllner - 3.26.0-5 +- Adjust to pipewire API break + +* Wed Sep 20 2017 Florian Müllner - 3.26.0-5 +- Enable tablet support + +* Tue Sep 12 2017 Adam Williamson - 3.26.0-4 +- Also backport BGO #787570 fix from upstream + +* Tue Sep 12 2017 Adam Williamson - 3.26.0-3 +- Backport upstream fixes for crasher bug BGO #787568 + +* Tue Sep 12 2017 Florian Müllner - 3.26.0-2 +- Enable remote desktop support + +* Tue Sep 12 2017 Florian Müllner - 3.26.0-1 +- Update to 3.26.0 + +* Thu Sep 07 2017 Florian Müllner - 3.25.92-1 +- Update to 3.25.92 + +* Thu Aug 24 2017 Bastien Nocera - 3.25.91-2 ++ mutter-3.25.91-2 +- Fix inverted red and blue channels with newer Mesa + +* Tue Aug 22 2017 Florian Müllner - 3.25.91-1 +- Update to 3.25.91 + +* Thu Aug 10 2017 Florian Müllner - 3.25.90-1 +- Update to 3.25.90 + +* Thu Aug 03 2017 Fedora Release Engineering - 3.25.4-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 3.25.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Wed Jul 19 2017 Florian Müllner - 3.25.4-1 +- Update to 3.25.4 + +* Wed Jun 21 2017 Florian Müllner - 3.25.3-1 +- Update to 3.25.3 + +* Wed May 24 2017 Florian Müllner - 3.25.2-1 +- Update to 3.25.2 + +* Thu May 18 2017 Florian Müllner - 3.25.1-2 +- Fix copy+paste of UTF8 strings between X11 and wayland + +* Thu Apr 27 2017 Florian Müllner - 3.25.1-1 +- Update to 3.25.1 + +* Tue Apr 11 2017 Florian Müllner - 3.24.1-1 +- Update to 3.24.1 + +* Mon Mar 20 2017 Florian Müllner - 3.24.0-1 +- Update to 3.24.0 + +* Tue Mar 14 2017 Florian Müllner - 3.23.92-1 +- Update to 3.23.92 + +* Fri Mar 10 2017 Florian Müllner - 3.23.91-4 +- Apply startup-notification hack again + +* Tue Mar 07 2017 Adam Williamson - 3.23.91-3 +- Backport more color fixes, should really fix BGO #779234, RHBZ #1428559 + +* Thu Mar 02 2017 Adam Williamson - 3.23.91-2 +- Backport fix for a color issue in 3.23.91 (BGO #779234, RHBZ #1428559) + +* Wed Mar 01 2017 Florian Müllner - 3.23.91-1 +- Update to 3.23.91 + +* Thu Feb 16 2017 Florian Müllner - 3.23.90-1 +- Update to 3.23.90 + +* Fri Feb 10 2017 Fedora Release Engineering - 3.23.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Thu Dec 15 2016 Florian Müllner - 3.23.3-1 +- Update to 3.23.3 + +* Fri Dec 02 2016 Florian Müllner - 3.23.2-2 +- Fix build error on 32-bit platforms + +* Thu Nov 24 2016 Kevin Fenzi - 3.23.2-2 +- Some fixes to get building. Still needs patch1 rebased. + +* Wed Nov 23 2016 Florian Müllner - 3.23.2-1 +- Update to 3.23.2 + +* Tue Nov 8 2016 Matthias Clasen - 3.23.1-2 +- Fix 1376471 + +* Sun Oct 30 2016 Florian Müllner - 3.23.1-1 +- Update to 3.23.1 + +* Tue Oct 18 2016 Kalev Lember - 3.22.1-3 +- Backport a fix to make gnome-screenshot --area work + +* Tue Oct 11 2016 Adam Jackson - 3.22.1-2 +- Prefer eglGetPlatformDisplay() to eglGetDisplay() + +* Tue Oct 11 2016 Florian Müllner - 3.22.1-1 +- Update to 3.22.1 + +* Wed Sep 28 2016 Florian Müllner - 3.22.0-2 +- Include fix for crash on VT switch + +* Mon Sep 19 2016 Florian Müllner - 3.22.0-1 +- Update to 3.22.0 + +* Tue Sep 13 2016 Florian Müllner - 3.21.92-1 +- Update to 3.21.92 + +* Thu Sep 08 2016 Kalev Lember - 3.21.91-2 +- wayland/cursor-role: Increase buffer use count on construction (#1373372) + +* Tue Aug 30 2016 Florian Müllner - 3.21.91-1 +- Update to 3.21.91 + +* Mon Aug 29 2016 Kalev Lember - 3.21.90-3 +- clutter/evdev: Fix absolute pointer motion events (#1369492) + +* Sat Aug 20 2016 Kalev Lember - 3.21.90-2 +- Update minimum dep versions + +* Fri Aug 19 2016 Florian Müllner - 3.21.90-1 +- Update to 3.21.90 + +* Wed Jul 20 2016 Florian Müllner - 3.21.4-1 +- Update to 3.21.4 +- Drop downstream patch +- Fix build error on 32-bit + +* Tue Jun 21 2016 Florian Müllner - 3.21.3-1 +- Update to 3.21.3 + +* Fri May 27 2016 Florian Müllner - 3.21.2-1 +- Update to 3.21.2 + +* Fri Apr 29 2016 Florian Müllner - 3.21.1-1 +- Update to 3.21.1 + +* Wed Apr 13 2016 Florian Müllner - 3.20.1-1 +- Update to 3.20.1 + +* Tue Mar 22 2016 Florian Müllner - 3.20.0-1 +- Update to 3.20.0 + +* Wed Mar 16 2016 Florian Müllner - 3.19.92-1 +- Update to 3.19.92 + +* Thu Mar 03 2016 Florian Müllner - 3.19.91-2 +- Include fix for invalid cursor wl_buffer access + +* Thu Mar 03 2016 Florian Müllner - 3.19.91-1 +- Update to 3.19.91 + +* Fri Feb 19 2016 Florian Müllner - 3.19.90-1 +- Update to 3.19.90 + +* Thu Feb 04 2016 Fedora Release Engineering - 3.19.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Thu Jan 21 2016 Florian Müllner - 3.19.4-1 +- Update to 3.19.4 + +* Thu Dec 17 2015 Florian Müllner - 3.19.3-1 +- Update to 3.19.3 + +* Wed Nov 25 2015 Florian Müllner - 3.19.2-1 +- Update to 3.19.2 + +* Tue Nov 10 2015 Ray Strode 3.19.1-5.20151110git049f1556d +- Update to git snapshot + +* Thu Oct 29 2015 Florian Müllner - 3.19.1-1 +- Update to 3.19.1 + +* Wed Oct 21 2015 Ray Strode 3.18.1-4 +- Force the cursor visible on vt switches after setting + the crtc to workaround that qxl bug from before in a + different situation + Related: #1273247 + +* Wed Oct 21 2015 Kalev Lember - 3.18.1-3 +- Backport a fix for a common Wayland crash (#1266486) + +* Thu Oct 15 2015 Kalev Lember - 3.18.1-2 +- Bump gnome-shell conflicts version + +* Thu Oct 15 2015 Florian Müllner - 3.18.1-1 +- Update to 3.18.1 + +* Mon Sep 21 2015 Florian Müllner - 3.18.0-1 +- Update to 3.18.0 + +* Wed Sep 16 2015 Florian Müllner - 3.17.92-1 +- Update to 3.17.92 + +* Thu Sep 03 2015 Florian Müllner - 3.17.91-1 +- Update to 3.17.91 + +* Thu Sep 03 2015 Ray Strode 3.17.90-2 +- Add workaround for qxl cursor visibility wonkiness that we + did for f22 + Related: #1200901 + +* Thu Aug 20 2015 Florian Müllner - 3.17.90-1 +- Update to 3.17.90 + +* Thu Jul 23 2015 Florian Müllner - 3.17.4-1 +- Update to 3.17.4 + +* Wed Jul 22 2015 David King - 3.17.3-2 +- Bump for new gnome-desktop3 + +* Thu Jul 02 2015 Florian Müllner - 3.17.3-1 +- Update to 3.17.3 + +* Wed Jun 17 2015 Fedora Release Engineering - 3.17.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Wed May 27 2015 Florian Müllner - 3.17.2-1 +- Update to 3.17.2 + +* Thu Apr 30 2015 Florian Müllner - 3.17.1-1 +- Update to 3.17.1 + +* Thu Apr 16 2015 Kalev Lember - 3.16.1.1-2 +- Bump gnome-shell conflicts version + +* Wed Apr 15 2015 Rui Matos - 3.16.1.1-1 +- Update to 3.16.1.1 + +* Tue Apr 14 2015 Florian Müllner - 3.16.1-1 +- Update to 3.16.1 + +* Mon Mar 23 2015 Florian Müllner - 3.16.0-1 +- Update to 3.16.0 + +* Tue Mar 17 2015 Kalev Lember - 3.15.92-2 +- Update minimum dep versions +- Use license macro for the COPYING file + +* Tue Mar 17 2015 Florian Müllner - 3.15.92-1 +- Update to 3.15.92 + +* Tue Mar 10 2015 Peter Hutterer - 3.15.91-2 +- Rebuild for libinput soname bump + +* Wed Mar 04 2015 Florian Müllner - 3.15.91-1 +- Update to 3.15.91 + +* Fri Feb 20 2015 Florian Müllner - 3.15.90-1 +- Update to 3.15.90 + +* Mon Feb 02 2015 Adam Williamson - 3.15.4-2 +- backport ad90b7dd to fix BGO #743412 / RHBZ #1185811 + +* Wed Jan 21 2015 Florian Müllner - 3.15.4-1 +- Update to 3.15.4 + +* Mon Jan 19 2015 Peter Hutterer 3.15.3-3 +- Rebuild for libinput soname bump + +* Mon Jan 12 2015 Ray Strode 3.15.3-2 +- Add specific BuildRequires for wayland bits, so we don't + get wayland support by happenstance. +- Add BuildRequires for autogoo since ./autogen.sh is run as part of + the build process + +* Fri Dec 19 2014 Florian Müllner - 3.15.3-1 +- Revert unsatisfiable wayland requirement + +* Fri Dec 19 2014 Florian Müllner - 3.15.3-1 +- Update to 3.15.3 + +* Thu Nov 27 2014 Florian Müllner - 3.15.2-1 +- Update to 3.15.2 + +* Wed Nov 12 2014 Vadim Rutkovsky - 3.15.1-2 +- Build installed tests + +* Thu Oct 30 2014 Florian Müllner - 3.15.1-1 +- Update to 3.15.1 + +* Tue Oct 21 2014 Florian Müllner - 3.14.1-2 +- Fix regression in handling raise-on-click option (rhbz#1151918) + +* Tue Oct 14 2014 Florian Müllner - 3.14.1-1 +- Update to 3.14.1 + +* Fri Oct 03 2014 Adam Williamson - 3.14.0-3 +- backport fix for BGO #737233 / RHBZ #1145952 (desktop right click broken) + +* Mon Sep 22 2014 Kalev Lember - 3.14.0-2 +- Bump gnome-shell conflicts version + +* Mon Sep 22 2014 Florian Müllner - 3.14.0-1 +- Update to 3.14.0 + +* Wed Sep 17 2014 Florian Müllner - 3.13.92-1 +- Update to 3.13.92 + +* Fri Sep 12 2014 Peter Hutterer - 3.13.91-2 +- Rebuild for libinput soname bump + +* Wed Sep 03 2014 Florian Müllner - 3.31.91-1 +- Update to 3.13.91, drop downstream patches + +* Tue Aug 26 2014 Adel Gadllah - 3.13.90-4 +- Apply fix for RH #1133166 + +* Mon Aug 25 2014 Hans de Goede - 3.13.90-3 +- Add a patch from upstream fixing gnome-shell crashing non stop on + multi monitor setups (rhbz#1103221) + +* Fri Aug 22 2014 Kevin Fenzi 3.13.90-2 +- Rebuild for new wayland + +* Wed Aug 20 2014 Florian Müllner - 3.13.90-1 +- Update to 3.13.90 + +* Mon Aug 18 2014 Kalev Lember - 3.13.4-3 +- Rebuilt for upower 0.99.1 soname bump + +* Sun Aug 17 2014 Fedora Release Engineering - 3.13.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Wed Jul 23 2014 Florian Müllner - 3.13.4-1 +- Update to 3.13.4 + +* Tue Jul 22 2014 Kalev Lember - 3.13.3-2 +- Rebuilt for gobject-introspection 1.41.4 + +* Fri Jun 27 2014 Florian Müllner - 3.13.3-1 +- New gobject-introspection has been built, drop the last patch again + +* Wed Jun 25 2014 Florian Müllner - 3.13.3-1 +- Revert annotation updates until we get a new gobject-introspection build + +* Wed Jun 25 2014 Florian Müllner - 3.13.3-1 +- Update to 3.13.1 + +* Wed Jun 11 2014 Florian Müllner - 3.13.2-2 +- Backport fix for legacy fullscreen check + +* Sat Jun 07 2014 Fedora Release Engineering - 3.13.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Tue May 27 2014 Florian Müllner - 3.13.2-1 +- Update to 3.13.2, drop upstreamed patches + +* Thu May 8 2014 Matthias Clasen - 3.13.1-5 +- Fix shrinking terminals + +* Wed May 07 2014 Kalev Lember - 3.13.1-4 +- Backport an upstream fix for a Wayland session crash + +* Wed May 07 2014 Kalev Lember - 3.13.1-3 +- Install mutter-launch as setuid root + +* Thu May 01 2014 Kalev Lember - 3.13.1-2 +- Obsolete mutter-wayland + +* Wed Apr 30 2014 Florian Müllner - 3.13.1-1 +- Update to 3.13.1 + +* Tue Apr 15 2014 Florian Müllner - 3.12.1-1 +- Update to 3.12.1 + +* Sat Apr 05 2014 Kalev Lember - 3.12.0-2 +- Update dep versions + +* Tue Mar 25 2014 Florian Müllner - 3.12.0-1 +- Update to 3.12.0 + +* Wed Mar 19 2014 Florian Müllner - 3.11.92-1 +- Update to 3.11.92 + +* Thu Mar 06 2014 Florian Müllner - 3.11.91-1 +- Update to 3.11.91 + +* Thu Feb 20 2014 Kalev Lember - 3.11.90-2 +- Rebuilt for cogl soname bump + +* Wed Feb 19 2014 Florian Müllner - 3.11.90-1 +- Update to 3.11.90 + +* Wed Feb 19 2014 Richard Hughes - 3.11.5-4 +- Rebuilt for gnome-desktop soname bump + +* Mon Feb 10 2014 Peter Hutterer - 3.11.5-3 +- Rebuild for libevdev soname bump + +* Wed Feb 05 2014 Richard Hughes - 3.11.5-2 +- Rebuilt for cogl soname bump + +* Wed Feb 05 2014 Florian Müllner - 3.11.5-1 +- Update to 3.11.5 + +* Wed Jan 15 2014 Florian Müllner - 3.11.4-1 +- Update to 3.11.4 + +* Fri Dec 20 2013 Florian Müllner - 3.11.3-1 +- Update to 3.11.3 + +* Wed Nov 13 2013 Florian Müllner - 3.11.2-1 +- Update to 3.11.2 + +* Wed Oct 30 2013 Florian Müllner - 3.11.1-1 +- Update to 3.11.1 + +* Tue Oct 15 2013 Florian Müllner - 3.10.1.1-1 +- Update to 3.10.1.1 + +* Mon Oct 14 2013 Florian Müllner - 3.10.1-1 +- Update to 3.10.1 + +* Wed Sep 25 2013 Florian Müllner - 3.10.0.1-1 +- Update to 3.10.0.1 + +* Mon Sep 23 2013 Florian Müllner - 3.10.0-1 +- Update to 3.10.0 + +* Tue Sep 17 2013 Kalev Lember - 3.9.92-2 +- Update the description and URL +- Tighten -devel subpackage deps with _isa +- Use the make_install macro + +* Mon Sep 16 2013 Florian Müllner - 3.9.92-1 +- Update to 3.9.92 + +* Tue Sep 03 2013 Kalev Lember - 3.9.91-2 +- Rebuilt for libgnome-desktop soname bump + +* Tue Sep 03 2013 Florian Müllner - 3.9.91-1 +- Update to 3.9.91 + +* Thu Aug 22 2013 Florian Müllner - 3.9.90-1 +- Update to 3.9.90 + +* Fri Aug 09 2013 Kalev Lember - 3.9.5-2 +- Rebuilt for cogl 1.15.4 soname bump + +* Tue Jul 30 2013 Florian Müllner - 3.9.5-1 +- Update to 3.9.5 + +* Wed Jul 10 2013 Florian Müllner - 3.9.4-1 +- Update to 3.9.4 + +* Tue Jun 18 2013 Florian Müllner - 3.9.3-1 +- Update to 3.9.3 + +* Tue May 28 2013 Florian Müllner - 3.9.2-1 +- Update to 3.9.2 + +* Wed May 01 2013 Florian Müllner - 3.9.1-1 +- Update to 3.9.1 + +* Tue Apr 23 2013 Florian Müllner - 3.8.1-1 +- Update to 3.8.1 + +* Tue Mar 26 2013 Florian Müllner - 3.8.0-1 +- Update to 3.8.0 + +* Tue Mar 19 2013 Florian Müllner - 3.7.92-1 +- Update to 3.7.92 + +* Mon Mar 04 2013 Florian Müllner - 3.7.91-1 +- Update to 3.7.91 + +* Wed Feb 20 2013 Florian Müllner - 3.7.90-1 +- Update to 3.7.90 + +* Tue Feb 05 2013 Florian Müllner - 3.7.5-1 +- Update to 3.7.5 + +* Fri Jan 25 2013 Peter Robinson 3.7.4-2 +- Rebuild for new cogl + +* Tue Jan 15 2013 Florian Müllner - 3.7.4-1 +- Update to 3.7.4 + +* Tue Dec 18 2012 Florian Müllner - 3.7.3-1 +- Update to 3.7.3 + +* Mon Nov 19 2012 Florian Müllner - 3.7.2-1 +- Update to 3.7.2 + +* Fri Nov 09 2012 Kalev Lember - 3.7.1-1 +- Update to 3.7.1 + +* Mon Oct 15 2012 Florian Müllner - 3.6.1-1 +- Update to 3.6.1 + +* Tue Sep 25 2012 Florian Müllner - 3.6.0-1 +- Update to 3.6.0 + +* Wed Sep 19 2012 Florian Müllner - 3.5.92-1 +- Update to 3.5.92 + +* Tue Sep 04 2012 Debarshi Ray - 3.5.91-2 +- Rebuild against new cogl + +* Tue Sep 04 2012 Debarshi Ray - 3.5.91-1 +- Update to 3.5.91 + +* Tue Aug 28 2012 Matthias Clasen - 3.5.90-2 +- Rebuild against new cogl/clutter + +* Tue Aug 21 2012 Richard Hughes - 3.5.90-1 +- Update to 3.5.90 + +* Tue Aug 07 2012 Richard Hughes - 3.5.5-1 +- Update to 3.5.5 + +* Fri Jul 27 2012 Fedora Release Engineering - 3.5.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Tue Jul 17 2012 Richard Hughes - 3.5.4-1 +- Update to 3.5.4 + +* Tue Jun 26 2012 Matthias Clasen - 3.5.3-1 +- Update to 3.5.3 + +* Fri Jun 8 2012 Matthias Clasen - 3.5.2-3 +- Make resize grip area larger + +* Thu Jun 07 2012 Matthias Clasen - 3.5.2-2 +- Don't check for Xinerama anymore - it is now mandatory + +* Thu Jun 07 2012 Richard Hughes - 3.5.2-1 +- Update to 3.5.2 +- Remove upstreamed patches + +* Wed May 09 2012 Adam Jackson 3.4.1-3 +- mutter-never-slice-shape-mask.patch, mutter-use-cogl-texrect-api.patch: + Fix window texturing on hardware without ARB_texture_non_power_of_two + (#813648) + +* Wed Apr 18 2012 Kalev Lember - 3.4.1-2 +- Silence glib-compile-schemas scriplets + +* Wed Apr 18 2012 Kalev Lember - 3.4.1-1 +- Update to 3.4.1 +- Conflict with gnome-shell versions older than 3.4.1 + +* Tue Mar 27 2012 Richard Hughes - 3.4.0-1 +- Update to 3.4.0 + +* Wed Mar 21 2012 Kalev Lember - 3.3.92-1 +- Update to 3.3.92 + +* Sat Mar 10 2012 Matthias Clasen - 3.3.90-2 +- Rebuild against new cogl + +* Sat Feb 25 2012 Matthias Clasen - 3.3.90-1 +- Update to 3.3.90 + +* Tue Feb 7 2012 Matthias Clasen - 3.3.5-1 +- Update to 3.3.5 + +* Fri Jan 20 2012 Matthias Clasen - 3.3.4-1 +- Update to 3.3.4 + +* Thu Jan 19 2012 Matthias Clasen - 3.3.3-2 +- Rebuild against new cogl + +* Thu Jan 5 2012 Matthias Clasen - 3.3.3-1 +- Update to 3.3.3 + +* Wed Nov 23 2011 Matthias Clasen - 3.3.2-2 +- Rebuild against new clutter + +* Tue Nov 22 2011 Matthias Clasen - 3.3.2-1 +- Update to 3.3.2 + +* Wed Oct 26 2011 Fedora Release Engineering - 3.2.1-2 +- Rebuilt for glibc bug#747377 + +* Wed Oct 19 2011 Matthias Clasen - 3.2.1-1 +- Update to 3.2.1 + +* Mon Sep 26 2011 Owen Taylor - 3.2.0-1 +- Update to 3.2.0 + +* Tue Sep 20 2011 Matthias Clasen - 3.1.92-1 +- Update to 3.1.92 + +* Wed Sep 14 2011 Owen Taylor - 3.1.91.1-1 +- Update to 3.1.91.1 + +* Wed Aug 31 2011 Matthias Clasen - 3.1.90.1-1 +- Update to 3.1.90.1 + +* Wed Jul 27 2011 Matthias Clasen - 3.1.4-1 +- Update to 3.1.4 + +* Wed Jul 27 2011 Matthias Clasen - 3.1.3.1-3 +- Rebuild + +* Mon Jul 4 2011 Peter Robinson - 3.1.3.1-2 +- rebuild against new clutter/cogl + +* Mon Jul 04 2011 Adam Williamson - 3.1.3.1-1 +- Update to 3.1.3.1 + +* Thu Jun 30 2011 Owen Taylor - 3.1.3-1 +- Update to 3.1.3 + +* Wed May 25 2011 Owen Taylor - 3.0.2.1-1 +- Update to 3.0.2.1 + +* Fri Apr 29 2011 Matthias Clasen - 3.0.1-3 +- Actually apply the patch for #700276 + +* Thu Apr 28 2011 Matthias Clasen - 3.0.1-2 +- Make session saving of gnome-shell work + +* Mon Apr 25 2011 Owen Taylor - 3.0.1-1 +- Update to 3.0.1 + +* Mon Apr 4 2011 Owen Taylor - 3.0.0-1 +- Update to 3.0.0 + +* Mon Mar 28 2011 Matthias Clasen - 2.91.93-1 +- Update to 2.91.93 + +* Wed Mar 23 2011 Matthias Clasen - 2.91.92-1 +- Update to 2.91.92 + +* Mon Mar 7 2011 Owen Taylor - 2.91.91-1 +- Update to 2.91.91 + +* Tue Mar 1 2011 Matthias Clasen - 2.91.90-2 +- Build against libcanberra, to enable AccessX feedback features + +* Tue Feb 22 2011 Matthias Clasen - 2.91.90-1 +- Update to 2.91.90 + +* Thu Feb 10 2011 Matthias Clasen - 2.91.6-4 +- Rebuild against newer gtk + +* Tue Feb 08 2011 Fedora Release Engineering - 2.91.6-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Wed Feb 2 2011 Matthias Clasen - 2.91.6-2 +- Rebuild against newer gtk + +* Tue Feb 1 2011 Owen Taylor - 2.91.6-1 +- Update to 2.91.6 + +* Tue Jan 11 2011 Matthias Clasen - 2.91.5-1 +- Update to 2.91.5 + +* Fri Jan 7 2011 Matthias Clasen - 2.91.4-1 +- Update to 2.91.4 + +* Fri Dec 3 2010 Matthias Clasen - 2.91.3-2 +- Rebuild against new gtk +- Drop no longer needed %%clean etc + +* Mon Nov 29 2010 Owen Taylor - 2.91.3-1 +- Update to 2.91.3 + +* Tue Nov 9 2010 Owen Taylor - 2.91.2-1 +- Update to 2.91.2 + +* Tue Nov 2 2010 Matthias Clasen - 2.91.1-2 +- Rebuild against newer gtk3 + +* Fri Oct 29 2010 Owen Taylor - 2.91.1-1 +- Update to 2.91.1 + +* Mon Oct 4 2010 Owen Taylor - 2.91.0-1 +- Update to 2.91.0 + +* Wed Sep 22 2010 Matthias Clasen - 2.31.5-4 +- Rebuild against newer gobject-introspection + +* Wed Jul 14 2010 Colin Walters - 2.31.5-3 +- Rebuild for new gobject-introspection + +* Tue Jul 13 2010 Adel Gadllah - 2.31.5-2 +- Build against gtk3 + +* Mon Jul 12 2010 Colin Walters - 2.31.5-1 +- New upstream version + +* Mon Jul 12 2010 Colin Walters - 2.31.2-5 +- Rebuild against new gobject-introspection + +* Tue Jul 6 2010 Colin Walters - 2.31.2-4 +- Changes to support snapshot builds + +* Fri Jun 25 2010 Colin Walters - 2.31.2-3 +- drop gir-repository-devel dep + +* Wed May 26 2010 Adam Miller - 2.31.2-2 +- removed "--with-clutter" as configure is claiming it to be an unknown option + +* Wed May 26 2010 Adam Miller - 2.31.2-1 +- New upstream 2.31.2 release + +* Thu Mar 25 2010 Peter Robinson 2.29.1-1 +- New upstream 2.29.1 release + +* Wed Mar 17 2010 Peter Robinson 2.29.0-1 +- New upstream 2.29.0 release + +* Tue Feb 16 2010 Adam Jackson 2.28.1-0.2 +- mutter-2.28.1-add-needed.patch: Fix FTBFS from --no-add-needed + +* Thu Feb 4 2010 Peter Robinson 2.28.1-0.1 +- Move to git snapshot + +* Wed Oct 7 2009 Owen Taylor - 2.28.0-1 +- Update to 2.28.0 + +* Tue Sep 15 2009 Owen Taylor - 2.27.5-1 +- Update to 2.27.5 + +* Fri Sep 4 2009 Owen Taylor - 2.27.4-1 +- Remove workaround for #520209 +- Update to 2.27.4 + +* Sat Aug 29 2009 Owen Taylor - 2.27.3-3 +- Fix %%preun GConf script to properly be for package removal + +* Fri Aug 28 2009 Owen Taylor - 2.27.3-2 +- Add a workaround for Red Hat bug #520209 + +* Fri Aug 28 2009 Owen Taylor - 2.27.3-1 +- Update to 2.27.3, remove mutter-metawindow.patch + +* Fri Aug 21 2009 Peter Robinson 2.27.2-2 +- Add upstream patch needed by latest mutter-moblin + +* Tue Aug 11 2009 Peter Robinson 2.27.2-1 +- New upstream 2.27.2 release. Drop upstreamed patches. + +* Wed Jul 29 2009 Peter Robinson 2.27.1-5 +- Add upstream patches for clutter 1.0 + +* Wed Jul 29 2009 Peter Robinson 2.27.1-4 +- Add patch to fix mutter --replace + +* Sat Jul 25 2009 Fedora Release Engineering - 2.27.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Sat Jul 18 2009 Peter Robinson 2.27.1-2 +- Updates from review request + +* Fri Jul 17 2009 Peter Robinson 2.27.1-1 +- Update to official 2.27.1 and review updates + +* Thu Jun 18 2009 Peter Robinson 2.27.0-0.2 +- Updates from initial reviews + +* Thu Jun 18 2009 Peter Robinson 2.27.0-0.1 +- Initial packaging