diff options
author | CoprDistGit <copr-devel@lists.fedorahosted.org> | 2020-01-03 06:22:51 +0000 |
---|---|---|
committer | CoprDistGit <copr-devel@lists.fedorahosted.org> | 2020-01-03 06:22:51 +0000 |
commit | fb21330b9e239b12be7c19323c3aec9413294bf5 (patch) | |
tree | 6d0c5da93a7b17837ecd253c2ce7b5e270c14f61 | |
parent | 23df33dbf1551fd2000c337861b34e191f9f89a1 (diff) |
automatic import of mutter
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | 0001-cursor-tracker-Add-API-to-keep-the-wayland-pointer-f.patch | 149 | ||||
-rw-r--r-- | 867.patch | 515 | ||||
-rw-r--r-- | mutter-clipboard-manager-crash.patch | 254 | ||||
-rw-r--r-- | mutter-gnome-3-34-2019-11-12.patch | 4156 | ||||
-rw-r--r-- | mutter.spec | 59 | ||||
-rw-r--r-- | sources | 2 |
7 files changed, 28 insertions, 5108 deletions
@@ -1 +1,2 @@ /mutter-3.34.1.tar.xz +/mutter-3.34.2.tar.xz diff --git a/0001-cursor-tracker-Add-API-to-keep-the-wayland-pointer-f.patch b/0001-cursor-tracker-Add-API-to-keep-the-wayland-pointer-f.patch deleted file mode 100644 index 1c700d8..0000000 --- a/0001-cursor-tracker-Add-API-to-keep-the-wayland-pointer-f.patch +++ /dev/null @@ -1,149 +0,0 @@ -From bc8e1d76cd40e7797a05df39cfc524247e1d7f7a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl> -Date: Mon, 7 Oct 2019 14:32:11 +0200 -Subject: [PATCH] cursor-tracker: Add API to keep the wayland pointer focus - while hidden - -Since commit a2a8f0cda we force the focus surface of the -meta-wayland-pointer to NULL while the pointer is invisible. This -introduced an issue with the a11y magnifier of the shell, which uses -`meta_cursor_tracker_set_pointer_visible` to hide the real cursor and -show its own magnified cursor at the correct position: Because the -meta-wayland-pointer is still used to communicate with Wayland clients, -the UI of the windows will not respond to mouse movement anymore as -soon as the real cursor is hidden. - -Fix this issue for now by adding an additional method to the -cursor-tracker which allows disabling the behavior commit a2a8f0cda -introduced. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/832 ---- - src/backends/meta-cursor-tracker-private.h | 1 + - src/backends/meta-cursor-tracker.c | 39 ++++++++++++++++++++++ - src/meta/meta-cursor-tracker.h | 7 ++++ - src/wayland/meta-wayland-pointer.c | 9 +++-- - 4 files changed, 53 insertions(+), 3 deletions(-) - -diff --git a/src/backends/meta-cursor-tracker-private.h b/src/backends/meta-cursor-tracker-private.h -index 29ee94044..0923337fb 100644 ---- a/src/backends/meta-cursor-tracker-private.h -+++ b/src/backends/meta-cursor-tracker-private.h -@@ -31,6 +31,7 @@ struct _MetaCursorTracker { - GObject parent_instance; - - gboolean is_showing; -+ gboolean keep_focus_while_hidden; - - MetaCursorSprite *effective_cursor; /* May be NULL when hidden */ - MetaCursorSprite *displayed_cursor; -diff --git a/src/backends/meta-cursor-tracker.c b/src/backends/meta-cursor-tracker.c -index 45291e286..346e3faae 100644 ---- a/src/backends/meta-cursor-tracker.c -+++ b/src/backends/meta-cursor-tracker.c -@@ -136,6 +136,7 @@ static void - meta_cursor_tracker_init (MetaCursorTracker *self) - { - self->is_showing = TRUE; -+ self->keep_focus_while_hidden = FALSE; - } - - static void -@@ -457,6 +458,44 @@ meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker, - g_signal_emit (tracker, signals[VISIBILITY_CHANGED], 0); - } - -+/** -+ * meta_cursor_tracker_get_keep_focus_while_hidden: -+ * @tracker: a #MetaCursorTracker object. -+ * -+ * Returns: %FALSE if the Wayland focus surface of the pointer will -+ * be forced to NULL while the pointer is hidden, %TRUE otherwise. -+ * This function is only meant to be used by the magnifier of the shell -+ * and will be removed in a future release. -+ */ -+gboolean -+meta_cursor_tracker_get_keep_focus_while_hidden (MetaCursorTracker *tracker) -+{ -+ return tracker->keep_focus_while_hidden; -+} -+ -+/** -+ * meta_cursor_tracker_set_keep_focus_while_hidden: -+ * @tracker: a #MetaCursorTracker object. -+ * @keep_focus: whether to keep the cursor focus while hidden -+ * -+ * If this is set to %TRUE, the Wayland focus surface of the pointer will -+ * not be forced to NULL while the pointer is hidden. -+ * This function is only meant to be used by the magnifier of the shell -+ * and will be removed in a future release. -+ */ -+void -+meta_cursor_tracker_set_keep_focus_while_hidden (MetaCursorTracker *tracker, -+ gboolean keep_focus) -+{ -+ if (keep_focus == tracker->keep_focus_while_hidden) -+ return; -+ tracker->keep_focus_while_hidden = keep_focus; -+ -+ sync_cursor (tracker); -+ -+ g_signal_emit (tracker, signals[VISIBILITY_CHANGED], 0); -+} -+ - MetaCursorSprite * - meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker) - { -diff --git a/src/meta/meta-cursor-tracker.h b/src/meta/meta-cursor-tracker.h -index 2f51115e4..6aef2745d 100644 ---- a/src/meta/meta-cursor-tracker.h -+++ b/src/meta/meta-cursor-tracker.h -@@ -62,4 +62,11 @@ META_EXPORT - void meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker, - gboolean visible); - -+META_EXPORT -+gboolean meta_cursor_tracker_get_keep_focus_while_hidden (MetaCursorTracker *tracker); -+ -+META_EXPORT -+void meta_cursor_tracker_set_keep_focus_while_hidden (MetaCursorTracker *tracker, -+ gboolean keep_focus); -+ - #endif -diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c -index 751f6b9b9..b69f43ab3 100644 ---- a/src/wayland/meta-wayland-pointer.c -+++ b/src/wayland/meta-wayland-pointer.c -@@ -228,7 +228,8 @@ sync_focus_surface (MetaWaylandPointer *pointer) - MetaBackend *backend = meta_get_backend (); - MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); - -- if (!meta_cursor_tracker_get_pointer_visible (cursor_tracker)) -+ if (!meta_cursor_tracker_get_pointer_visible (cursor_tracker) && -+ !meta_cursor_tracker_get_keep_focus_while_hidden (cursor_tracker)) - { - meta_wayland_pointer_set_focus (pointer, NULL); - return; -@@ -433,7 +434,8 @@ default_grab_focus (MetaWaylandPointerGrab *grab, - if (!meta_wayland_seat_has_pointer (seat)) - return; - -- if (!meta_cursor_tracker_get_pointer_visible (cursor_tracker)) -+ if (!meta_cursor_tracker_get_pointer_visible (cursor_tracker) && -+ !meta_cursor_tracker_get_keep_focus_while_hidden (cursor_tracker)) - return; - - if (pointer->button_count > 0) -@@ -898,7 +900,8 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, - MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); - - g_return_if_fail (meta_cursor_tracker_get_pointer_visible (cursor_tracker) || -- surface == NULL); -+ meta_cursor_tracker_get_keep_focus_while_hidden (cursor_tracker) || -+ surface == NULL); - - if (pointer->focus_surface == surface) - return; --- -2.23.0 - diff --git a/867.patch b/867.patch deleted file mode 100644 index e206905..0000000 --- a/867.patch +++ /dev/null @@ -1,515 +0,0 @@ -diff --git a/clutter/clutter/clutter-stage-window.c b/clutter/clutter/clutter-stage-window.c -index c859264b3ea18ab297f347fe3179e69d654c3185..68a763d445aabd4b92dbcdb4c9f3b4695591109d 100644 ---- a/clutter/clutter/clutter-stage-window.c -+++ b/clutter/clutter/clutter-stage-window.c -@@ -249,23 +249,6 @@ _clutter_stage_window_get_redraw_clip (ClutterStageWindow *window) - return NULL; - } - --gboolean --_clutter_stage_window_get_redraw_clip_bounds (ClutterStageWindow *window, -- cairo_rectangle_int_t *stage_clip) --{ -- cairo_region_t *redraw_clip; -- -- g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), FALSE); -- -- redraw_clip = _clutter_stage_window_get_redraw_clip (window); -- if (!redraw_clip) -- return FALSE; -- -- cairo_region_get_extents (redraw_clip, stage_clip); -- cairo_region_destroy (redraw_clip); -- return TRUE; --} -- - void - _clutter_stage_window_set_accept_focus (ClutterStageWindow *window, - gboolean accept_focus) -diff --git a/clutter/clutter/clutter-stage-window.h b/clutter/clutter/clutter-stage-window.h -index a06c5190d5199244b5bc2f46f0e3b672d07e277d..c99e9594d583b53f5d45d3cfc9a609b2b56cf231 100644 ---- a/clutter/clutter/clutter-stage-window.h -+++ b/clutter/clutter/clutter-stage-window.h -@@ -98,8 +98,6 @@ void _clutter_stage_window_add_redraw_clip (ClutterStageWin - cairo_rectangle_int_t *stage_clip); - gboolean _clutter_stage_window_has_redraw_clips (ClutterStageWindow *window); - gboolean _clutter_stage_window_ignoring_redraw_clips (ClutterStageWindow *window); --gboolean _clutter_stage_window_get_redraw_clip_bounds (ClutterStageWindow *window, -- cairo_rectangle_int_t *clip); - cairo_region_t * _clutter_stage_window_get_redraw_clip (ClutterStageWindow *window); - - void _clutter_stage_window_set_accept_focus (ClutterStageWindow *window, -diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c -index 4b6f46612cb7ef44d01e29eefe455485676af4d1..02377867a8fcddbbe58231feed310b72447cb25a 100644 ---- a/clutter/clutter/clutter-stage.c -+++ b/clutter/clutter/clutter-stage.c -@@ -1394,11 +1394,10 @@ _clutter_stage_check_updated_pointers (ClutterStage *stage) - ClutterDeviceManager *device_manager; - GSList *updating = NULL; - const GSList *devices; -- cairo_rectangle_int_t clip; -+ cairo_region_t *clip; - ClutterPoint point; -- gboolean has_clip; - -- has_clip = _clutter_stage_window_get_redraw_clip_bounds (priv->impl, &clip); -+ clip = _clutter_stage_window_get_redraw_clip (priv->impl); - - device_manager = clutter_device_manager_get_default (); - devices = clutter_device_manager_peek_devices (device_manager); -@@ -1421,9 +1420,7 @@ _clutter_stage_check_updated_pointers (ClutterStage *stage) - if (!clutter_input_device_get_coords (dev, NULL, &point)) - continue; - -- if (!has_clip || -- (point.x >= clip.x && point.x < clip.x + clip.width && -- point.y >= clip.y && point.y < clip.y + clip.height)) -+ if (!clip || cairo_region_contains_point (clip, point.x, point.y)) - updating = g_slist_prepend (updating, dev); - break; - default: -@@ -1632,40 +1629,5 @@ clutter_stage_get_redraw_clip (ClutterStage *stage) - } - --/** -- * clutter_stage_get_redraw_clip_bounds: -- * @stage: A #ClutterStage -- * @clip: (out caller-allocates): Return location for the clip bounds -- * -- * Gets the bounds of the current redraw for @stage in stage pixel -- * coordinates. E.g., if only a single actor has queued a redraw then -- * Clutter may redraw the stage with a clip so that it doesn't have to -- * paint every pixel in the stage. This function would then return the -- * bounds of that clip. An application can use this information to -- * avoid some extra work if it knows that some regions of the stage -- * aren't going to be painted. This should only be called while the -- * stage is being painted. If there is no current redraw clip then -- * this function will set @clip to the full extents of the stage. -- * -- * Since: 1.8 -- */ --void --clutter_stage_get_redraw_clip_bounds (ClutterStage *stage, -- cairo_rectangle_int_t *clip) --{ -- ClutterStagePrivate *priv; -- -- g_return_if_fail (CLUTTER_IS_STAGE (stage)); -- g_return_if_fail (clip != NULL); -- -- priv = stage->priv; -- -- if (!_clutter_stage_window_get_redraw_clip_bounds (priv->impl, clip)) -- { -- /* Set clip to the full extents of the stage */ -- _clutter_stage_window_get_geometry (priv->impl, clip); -- } --} -- - static ClutterActor * - _clutter_stage_do_pick_on_view (ClutterStage *stage, - gint x, -diff --git a/clutter/clutter/clutter-stage.h b/clutter/clutter/clutter-stage.h -index 88cd96ad5ca498210b404654665ce45f24b750c5..5910e61400268791046014619a0b8c6f35549da7 100644 ---- a/clutter/clutter/clutter-stage.h -+++ b/clutter/clutter/clutter-stage.h -@@ -206,9 +206,6 @@ guchar * clutter_stage_read_pixels (ClutterStage - gint height); - - CLUTTER_EXPORT --void clutter_stage_get_redraw_clip_bounds (ClutterStage *stage, -- cairo_rectangle_int_t *clip); --CLUTTER_EXPORT - cairo_region_t * clutter_stage_get_redraw_clip (ClutterStage *stage); - CLUTTER_EXPORT - void clutter_stage_ensure_viewport (ClutterStage *stage); -diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c -index 6dfde0b6bb78eefcc7850fc037662a2a28b85c53..4304db6e1cc698858e2a3342a7f6561ffb005a83 100644 ---- a/clutter/clutter/cogl/clutter-stage-cogl.c -+++ b/clutter/clutter/cogl/clutter-stage-cogl.c -@@ -879,27 +879,34 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window, - cairo_rectangle_int_t clip_rect; - cairo_rectangle_int_t scissor_rect; - -- cairo_region_get_extents (fb_clip_region, &clip_rect); -+ stage_cogl->using_clipped_redraw = TRUE; - -- calculate_scissor_region (&clip_rect, -- subpixel_compensation, -- fb_width, fb_height, -- &scissor_rect); -+ if (cairo_region_num_rectangles (fb_clip_region) == 1) -+ { -+ cairo_region_get_extents (fb_clip_region, &clip_rect); - -- CLUTTER_NOTE (CLIPPING, -- "Stage clip pushed: x=%d, y=%d, width=%d, height=%d\n", -- scissor_rect.x, -- scissor_rect.y, -- scissor_rect.width, -- scissor_rect.height); -+ calculate_scissor_region (&clip_rect, -+ subpixel_compensation, -+ fb_width, fb_height, -+ &scissor_rect); - -- stage_cogl->using_clipped_redraw = TRUE; -+ CLUTTER_NOTE (CLIPPING, -+ "Stage clip pushed: x=%d, y=%d, width=%d, height=%d\n", -+ scissor_rect.x, -+ scissor_rect.y, -+ scissor_rect.width, -+ scissor_rect.height); - -- cogl_framebuffer_push_scissor_clip (fb, -- scissor_rect.x, -- scissor_rect.y, -- scissor_rect.width, -- scissor_rect.height); -+ cogl_framebuffer_push_scissor_clip (fb, -+ scissor_rect.x, -+ scissor_rect.y, -+ scissor_rect.width, -+ scissor_rect.height); -+ } -+ else -+ { -+ cogl_framebuffer_push_region_clip (fb, fb_clip_region); -+ } - - paint_stage (stage_cogl, view, fb_clip_region); - -diff --git a/cogl/cogl/cogl-clip-stack.c b/cogl/cogl/cogl-clip-stack.c -index 092510714e8b09319cf7197e4d39b97baa7895eb..8c2100a44e2c2a250bedd7015354992786e50b77 100644 ---- a/cogl/cogl/cogl-clip-stack.c -+++ b/cogl/cogl/cogl-clip-stack.c -@@ -295,6 +295,30 @@ _cogl_clip_stack_push_primitive (CoglClipStack *stack, - return (CoglClipStack *) entry; - } - -+CoglClipStack * -+_cogl_clip_stack_push_region (CoglClipStack *stack, -+ cairo_region_t *region) -+{ -+ CoglClipStack *entry; -+ CoglClipStackRegion *entry_region; -+ cairo_rectangle_int_t bounds; -+ -+ entry_region = _cogl_clip_stack_push_entry (stack, -+ sizeof (CoglClipStackRegion), -+ COGL_CLIP_STACK_REGION); -+ entry = (CoglClipStack *) entry_region; -+ -+ cairo_region_get_extents (region, &bounds); -+ entry->bounds_x0 = bounds.x; -+ entry->bounds_x1 = bounds.x + bounds.width; -+ entry->bounds_y0 = bounds.y; -+ entry->bounds_y1 = bounds.y + bounds.height; -+ -+ entry_region->region = cairo_region_reference (region); -+ -+ return entry; -+} -+ - CoglClipStack * - _cogl_clip_stack_ref (CoglClipStack *entry) - { -@@ -336,6 +360,13 @@ _cogl_clip_stack_unref (CoglClipStack *entry) - g_slice_free1 (sizeof (CoglClipStackPrimitive), entry); - break; - } -+ case COGL_CLIP_STACK_REGION: -+ { -+ CoglClipStackRegion *region = (CoglClipStackRegion *) entry; -+ cairo_region_destroy (region->region); -+ g_slice_free1 (sizeof (CoglClipStackRegion), entry); -+ break; -+ } - default: - g_assert_not_reached (); - } -diff --git a/cogl/cogl/cogl-clip-stack.h b/cogl/cogl/cogl-clip-stack.h -index eb2c4328217a2f85cdcd0c7962f0767af27bcba6..095cf25736ce1f91a57d27502bb41c0ab890b99a 100644 ---- a/cogl/cogl/cogl-clip-stack.h -+++ b/cogl/cogl/cogl-clip-stack.h -@@ -48,12 +48,14 @@ typedef struct _CoglClipStack CoglClipStack; - typedef struct _CoglClipStackRect CoglClipStackRect; - typedef struct _CoglClipStackWindowRect CoglClipStackWindowRect; - typedef struct _CoglClipStackPrimitive CoglClipStackPrimitive; -+typedef struct _CoglClipStackRegion CoglClipStackRegion; - - typedef enum - { - COGL_CLIP_STACK_RECT, - COGL_CLIP_STACK_WINDOW_RECT, -- COGL_CLIP_STACK_PRIMITIVE -+ COGL_CLIP_STACK_PRIMITIVE, -+ COGL_CLIP_STACK_REGION, - } CoglClipStackType; - - /* A clip stack consists a list of entries. Each entry has a reference -@@ -162,6 +164,13 @@ struct _CoglClipStackPrimitive - float bounds_y2; - }; - -+struct _CoglClipStackRegion -+{ -+ CoglClipStack _parent_data; -+ -+ cairo_region_t *region; -+}; -+ - CoglClipStack * - _cogl_clip_stack_push_window_rectangle (CoglClipStack *stack, - int x_offset, -@@ -189,6 +198,9 @@ _cogl_clip_stack_push_primitive (CoglClipStack *stack, - CoglMatrixEntry *modelview_entry, - CoglMatrixEntry *projection_entry, - const float *viewport); -+CoglClipStack * -+_cogl_clip_stack_push_region (CoglClipStack *stack, -+ cairo_region_t *region); - - CoglClipStack * - _cogl_clip_stack_pop (CoglClipStack *stack); -diff --git a/cogl/cogl/cogl-context-private.h b/cogl/cogl/cogl-context-private.h -index 04040ce8c8330ccc20aa619b9ab8872d80304188..d767abcf6db0ba439d6ce1e1ecae538700735a8a 100644 ---- a/cogl/cogl/cogl-context-private.h -+++ b/cogl/cogl/cogl-context-private.h -@@ -272,11 +272,6 @@ struct _CoglContext - same state multiple times. When the clip state is flushed this - will hold a reference */ - CoglClipStack *current_clip_stack; -- /* Whether the stencil buffer was used as part of the current clip -- state. If TRUE then any further use of the stencil buffer (such -- as for drawing paths) would need to be merged with the existing -- stencil buffer */ -- gboolean current_clip_stack_uses_stencil; - - /* This is used as a temporary buffer to fill a CoglBuffer when - cogl_buffer_map fails and we only want to map to fill it with new -diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c -index 8164e5760c222cdd9032e79a29cecdff98ab7541..9fe1b31f8be1ae4be8676e4e4352ef5b8bd7ca5a 100644 ---- a/cogl/cogl/cogl-framebuffer.c -+++ b/cogl/cogl/cogl-framebuffer.c -@@ -1762,6 +1762,19 @@ cogl_framebuffer_push_primitive_clip (CoglFramebuffer *framebuffer, - COGL_FRAMEBUFFER_STATE_CLIP; - } - -+void -+cogl_framebuffer_push_region_clip (CoglFramebuffer *framebuffer, -+ cairo_region_t *region) -+{ -+ framebuffer->clip_stack = -+ _cogl_clip_stack_push_region (framebuffer->clip_stack, -+ region); -+ -+ if (framebuffer->context->current_draw_buffer == framebuffer) -+ framebuffer->context->current_draw_buffer_changes |= -+ COGL_FRAMEBUFFER_STATE_CLIP; -+} -+ - void - cogl_framebuffer_pop_clip (CoglFramebuffer *framebuffer) - { -diff --git a/cogl/cogl/cogl-framebuffer.h b/cogl/cogl/cogl-framebuffer.h -index b582dac7172c1d1db4753cdf93ac31564aa807c7..1df6731f7d6b4287c596c18a9fb14514c08d86af 100644 ---- a/cogl/cogl/cogl-framebuffer.h -+++ b/cogl/cogl/cogl-framebuffer.h -@@ -54,3 +54,4 @@ typedef struct _CoglFramebuffer CoglFramebuffer; - #include <cogl/cogl-texture.h> - #include <glib-object.h> -+#include <cairo.h> - -@@ -624,6 +625,10 @@ cogl_framebuffer_push_primitive_clip (CoglFramebuffer *framebuffer, - float bounds_x2, - float bounds_y2); - -+void -+cogl_framebuffer_push_region_clip (CoglFramebuffer *framebuffer, -+ cairo_region_t *region); -+ - /** - * cogl_framebuffer_pop_clip: - * @framebuffer: A #CoglFramebuffer pointer -diff --git a/cogl/cogl/driver/gl/cogl-clip-stack-gl.c b/cogl/cogl/driver/gl/cogl-clip-stack-gl.c -index 34f809a867c1020bcd1a03357241392ba8ee3820..2bc754cc0637bd7865233cc63ef7d911490f3580 100644 ---- a/cogl/cogl/driver/gl/cogl-clip-stack-gl.c -+++ b/cogl/cogl/driver/gl/cogl-clip-stack-gl.c -@@ -115,6 +115,102 @@ add_stencil_clip_rectangle (CoglFramebuffer *framebuffer, - GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) ); - } - -+static void -+add_stencil_clip_region (CoglFramebuffer *framebuffer, -+ cairo_region_t *region, -+ gboolean merge) -+{ -+ CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); -+ CoglMatrix matrix; -+ int num_rectangles = cairo_region_num_rectangles (region); -+ int i; -+ -+ /* NB: This can be called while flushing the journal so we need -+ * to be very conservative with what state we change. -+ */ -+ _cogl_context_set_current_projection_entry (ctx, &ctx->identity_entry); -+ _cogl_context_set_current_modelview_entry (ctx, &ctx->identity_entry); -+ -+ /* The coordinates in the region are meant to be window coordinates, -+ * make a matrix that translates those across the viewport, and into -+ * the default [-1, -1, 1, 1] range. -+ */ -+ cogl_matrix_init_identity (&matrix); -+ cogl_matrix_translate (&matrix, -1, 1, 0); -+ cogl_matrix_scale (&matrix, -+ 2.0 / framebuffer->viewport_width, -+ - 2.0 / framebuffer->viewport_height, -+ 1); -+ cogl_matrix_translate (&matrix, -+ - framebuffer->viewport_x, -+ - framebuffer->viewport_y, -+ 0); -+ -+ GE( ctx, glEnable (GL_STENCIL_TEST) ); -+ -+ GE( ctx, glColorMask (FALSE, FALSE, FALSE, FALSE) ); -+ GE( ctx, glDepthMask (FALSE) ); -+ -+ if (merge) -+ { -+ GE( ctx, glStencilFunc (GL_ALWAYS, 0x1, 0x3) ); -+ GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_INCR) ); -+ } -+ else -+ { -+ /* Initially disallow everything */ -+ GE( ctx, glClearStencil (0) ); -+ GE( ctx, glClear (GL_STENCIL_BUFFER_BIT) ); -+ -+ /* Punch out holes to allow the rectangles */ -+ GE( ctx, glStencilFunc (GL_ALWAYS, 0x1, 0x1) ); -+ GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE) ); -+ } -+ -+ for (i = 0; i < num_rectangles; i++) -+ { -+ cairo_rectangle_int_t rect; -+ float tl[4], br[4]; -+ -+ cairo_region_get_rectangle (region, i, &rect); -+ -+ tl[0] = rect.x; -+ tl[1] = rect.y; -+ tl[2] = 0.; -+ tl[3] = 1.; -+ -+ br[0] = rect.x + rect.width; -+ br[1] = rect.y + rect.height; -+ br[2] = 0.; -+ br[3] = 1.; -+ -+ cogl_matrix_transform_point (&matrix, &tl[0], &tl[1], &tl[2], &tl[3]); -+ cogl_matrix_transform_point (&matrix, &br[0], &br[1], &br[2], &br[3]); -+ -+ _cogl_rectangle_immediate (framebuffer, -+ ctx->stencil_pipeline, -+ tl[0], tl[1], br[0], br[1]); -+ } -+ -+ if (merge) -+ { -+ /* Subtract one from all pixels in the stencil buffer so that -+ * only pixels where both the original stencil buffer and the -+ * region are set will be valid -+ */ -+ GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_DECR) ); -+ _cogl_rectangle_immediate (framebuffer, -+ ctx->stencil_pipeline, -+ -1.0, -1.0, 1.0, 1.0); -+ } -+ -+ /* Restore the stencil mode */ -+ GE (ctx, glDepthMask (TRUE)); -+ GE (ctx, glColorMask (TRUE, TRUE, TRUE, TRUE)); -+ GE( ctx, glStencilFunc (GL_EQUAL, 0x1, 0x1) ); -+ GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) ); -+} -+ - typedef void (*SilhouettePaintCallback) (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - void *user_data); -@@ -287,7 +383,6 @@ _cogl_clip_stack_gl_flush (CoglClipStack *stack, - { - COGL_NOTE (CLIPPING, "Flushed empty clip stack"); - -- ctx->current_clip_stack_uses_stencil = FALSE; - GE (ctx, glDisable (GL_SCISSOR_TEST)); - return; - } -@@ -382,6 +477,23 @@ _cogl_clip_stack_gl_flush (CoglClipStack *stack, - } - break; - } -+ case COGL_CLIP_STACK_REGION: -+ { -+ CoglClipStackRegion *region = (CoglClipStackRegion *) entry; -+ -+ /* If nrectangles <= 1, it can be fully represented with the -+ * scissor clip. -+ */ -+ if (cairo_region_num_rectangles (region->region) > 1) -+ { -+ COGL_NOTE (CLIPPING, "Adding stencil clip for region"); -+ -+ add_stencil_clip_region (framebuffer, region->region, -+ using_stencil_buffer); -+ using_stencil_buffer = TRUE; -+ } -+ break; -+ } - case COGL_CLIP_STACK_WINDOW_RECT: - break; - /* We don't need to do anything for window space rectangles because -@@ -389,3 +501,1 @@ _cogl_clip_stack_gl_flush (CoglClipStack *stack, -- -- ctx->current_clip_stack_uses_stencil = using_stencil_buffer; - } -diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build -index c2fea5e96856c0020c09bfd9f94353732c3ae5e2..e62adbd57920e7f6483e65de2acae1f24a386ec7 100644 ---- a/cogl/cogl/meson.build -+++ b/cogl/cogl/meson.build -@@ -479,7 +479,7 @@ if have_introspection - sources: cogl_introspected_headers, - nsversion: libmutter_api_version, - namespace: 'Cogl', -- includes: ['GL-1.0', 'GObject-2.0'], -+ includes: ['cairo-1.0', 'GL-1.0', 'GObject-2.0'], - dependencies: [cogl_deps], - extra_args: introspection_args + [ - '-UCOGL_COMPILATION', -diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c -index 29ec1e74223ce2b86167378a7879306e7b0dcc21..b8a33cc30fa8cea34622d49cdd1a0cfff7a3605b 100644 ---- a/src/compositor/meta-window-group.c -+++ b/src/compositor/meta-window-group.c -@@ -56,7 +56,7 @@ meta_window_group_paint (ClutterActor *actor) - { - cairo_region_t *clip_region; - cairo_region_t *unobscured_region; -- cairo_rectangle_int_t visible_rect, clip_rect; -+ cairo_rectangle_int_t visible_rect; - int paint_x_origin, paint_y_origin; - int screen_width, screen_height; - -@@ -112,10 +112,7 @@ meta_window_group_paint (ClutterActor *actor) - * sizes, we could intersect this with an accurate union of the - * monitors to avoid painting shadows that are visible only in the - * holes. */ -- clutter_stage_get_redraw_clip_bounds (CLUTTER_STAGE (stage), -- &clip_rect); -- -- clip_region = cairo_region_create_rectangle (&clip_rect); -+ clip_region = clutter_stage_get_redraw_clip (CLUTTER_STAGE (stage)); - - cairo_region_translate (clip_region, -paint_x_origin, -paint_y_origin); - diff --git a/mutter-clipboard-manager-crash.patch b/mutter-clipboard-manager-crash.patch deleted file mode 100644 index c11b5c8..0000000 --- a/mutter-clipboard-manager-crash.patch +++ /dev/null @@ -1,254 +0,0 @@ -From 46b3811e22b3b898342141b1575c888285e51caf Mon Sep 17 00:00:00 2001 -From: Carlos Garnacho <carlosg@gnome.org> -Date: Wed, 20 Nov 2019 00:27:54 +0100 -Subject: [PATCH 1/4] wayland: Drop unused wl_signal structs - -Those were used to signal clipboard ownership around, but that got -replaced by MetaSelection and friends. These signals are no longer -listened on, so can be safely removed. - -https://gitlab.gnome.org/GNOME/mutter/issues/591 ---- - src/wayland/meta-wayland-data-device.c | 11 ----------- - src/wayland/meta-wayland-data-device.h | 4 ---- - 2 files changed, 15 deletions(-) - -diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c -index 2887da62d..3a9f276aa 100644 ---- a/src/wayland/meta-wayland-data-device.c -+++ b/src/wayland/meta-wayland-data-device.c -@@ -1327,7 +1327,6 @@ selection_data_source_destroyed (gpointer data, GObject *object_was_here) - wl_data_device_send_selection (data_device_resource, NULL); - } - -- wl_signal_emit (&data_device->selection_ownership_signal, NULL); - unset_selection_source (data_device, META_SELECTION_CLIPBOARD); - } - -@@ -1599,8 +1598,6 @@ meta_wayland_data_device_set_dnd_source (MetaWaylandDataDevice *data_device, - if (source) - g_object_add_weak_pointer (G_OBJECT (data_device->dnd_data_source), - (gpointer *)&data_device->dnd_data_source); -- -- wl_signal_emit (&data_device->dnd_ownership_signal, source); - } - - void -@@ -1658,8 +1655,6 @@ meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device, - wl_data_device_send_selection (data_device_resource, offer); - } - } -- -- wl_signal_emit (&data_device->selection_ownership_signal, source); - } - - static void -@@ -1725,7 +1720,6 @@ primary_source_destroyed (gpointer data, - gtk_primary_selection_device_send_selection (data_device_resource, NULL); - } - -- wl_signal_emit (&data_device->primary_ownership_signal, NULL); - unset_selection_source (data_device, META_SELECTION_PRIMARY); - } - -@@ -1785,8 +1779,6 @@ meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device, - gtk_primary_selection_device_send_selection (data_device_resource, offer); - } - } -- -- wl_signal_emit (&data_device->primary_ownership_signal, source); - } - - static void -@@ -2009,9 +2001,6 @@ meta_wayland_data_device_init (MetaWaylandDataDevice *data_device) - { - wl_list_init (&data_device->resource_list); - wl_list_init (&data_device->primary_resource_list); -- wl_signal_init (&data_device->selection_ownership_signal); -- wl_signal_init (&data_device->primary_ownership_signal); -- wl_signal_init (&data_device->dnd_ownership_signal); - } - - static struct wl_resource * -diff --git a/src/wayland/meta-wayland-data-device.h b/src/wayland/meta-wayland-data-device.h -index efa5478bf..c61c241a5 100644 ---- a/src/wayland/meta-wayland-data-device.h -+++ b/src/wayland/meta-wayland-data-device.h -@@ -67,10 +67,6 @@ struct _MetaWaylandDataDevice - MetaWaylandDragGrab *current_grab; - struct wl_client *focus_client; - -- struct wl_signal selection_ownership_signal; -- struct wl_signal dnd_ownership_signal; -- struct wl_signal primary_ownership_signal; -- - guint selection_owner_signal_id; - - MetaSelectionSource *owners[META_N_SELECTION_TYPES]; --- -2.22.0 - - -From e7b2f9603e90d87092c9e755c176f1244a8b3e36 Mon Sep 17 00:00:00 2001 -From: Carlos Garnacho <carlosg@gnome.org> -Date: Wed, 20 Nov 2019 00:29:01 +0100 -Subject: [PATCH 2/4] wayland: Avoid redundant cancel() call - -This is unnecessary as we are unsetting the DnD selection owner, -and will result in the related data source being cancelled already. - -https://gitlab.gnome.org/GNOME/mutter/issues/591 ---- - src/wayland/meta-wayland-data-device.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c -index 3a9f276aa..5a669b5f5 100644 ---- a/src/wayland/meta-wayland-data-device.c -+++ b/src/wayland/meta-wayland-data-device.c -@@ -1068,7 +1068,6 @@ drag_grab_button (MetaWaylandPointerGrab *grab, - } - else - { -- meta_wayland_data_source_cancel (source); - meta_wayland_data_source_set_current_offer (source, NULL); - meta_wayland_data_device_set_dnd_source (&seat->data_device, NULL); - unset_selection_source (&seat->data_device, META_SELECTION_DND); --- -2.22.0 - - -From 48639ac5da35697d885bd0736dea46e34a832ca2 Mon Sep 17 00:00:00 2001 -From: Carlos Garnacho <carlosg@gnome.org> -Date: Wed, 20 Nov 2019 00:30:23 +0100 -Subject: [PATCH 3/4] wayland: Do not cancel data source on offer destruction - -This is wrong for both clipboard and DnD, as the selection source -will still be able to focus another surface, and churn another -wl_offer. - -We should just detach the data offer from the data source in this -case, and let the source live on. However, we should still check -that there is a source and an offer to finish DnD, do that when -handling the drop operation instead. - -https://gitlab.gnome.org/GNOME/mutter/issues/591 ---- - src/wayland/meta-wayland-data-device.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - -diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c -index 5a669b5f5..c83667b16 100644 ---- a/src/wayland/meta-wayland-data-device.c -+++ b/src/wayland/meta-wayland-data-device.c -@@ -582,12 +582,7 @@ destroy_data_offer (struct wl_resource *resource) - WL_DATA_OFFER_ACTION_SINCE_VERSION) - meta_wayland_data_source_notify_finish (offer->source); - else -- { -- if (seat->data_device.dnd_data_source == offer->source) -- unset_selection_source (&seat->data_device, META_SELECTION_DND); -- meta_wayland_data_source_cancel (offer->source); -- meta_wayland_data_source_set_current_offer (offer->source, NULL); -- } -+ meta_wayland_data_source_set_current_offer (offer->source, NULL); - } - - g_object_remove_weak_pointer (G_OBJECT (offer->source), -@@ -1045,6 +1040,7 @@ drag_grab_button (MetaWaylandPointerGrab *grab, - gboolean success; - - if (drag_grab->drag_focus && source && -+ meta_wayland_data_source_get_current_offer (source) && - meta_wayland_data_source_has_target (source) && - meta_wayland_data_source_get_current_action (source)) - { --- -2.22.0 - - -From e5af790acb979ae9c8a0509052a42208c67639a6 Mon Sep 17 00:00:00 2001 -From: Carlos Garnacho <carlosg@gnome.org> -Date: Wed, 20 Nov 2019 00:32:21 +0100 -Subject: [PATCH 4/4] wayland: Move "ownership" of the DnD selection source to - the data device - -On wl_data_source destruction we used to indirectly unset the DnD selection -owner via the wl_resource destructor triggering the destruction of the -MetaWaylandDataSource, which would be caught through the weak ref set by -the MetaWaylandDragGrab. - -This works as long as the grab is held, however we have a window between -the button being released and the drop site replying with -wl_data_offer.finish that the MetaWaylandDataSource is alive, but its -destruction wouldn't result in the call chain above to unsetting the DnD -source. - -In other selection sources, we let the MetaWaylandDataDevice hold the -"ownership" of the MetaWaylandDataSource, and its weak ref functions unset -the respective MetaSelection owners. Do the same here, so the -MetaWaylandDataSource destruction is listened for all its lifetime. - -Closes: https://gitlab.gnome.org/GNOME/mutter/issues/591 ---- - src/wayland/meta-wayland-data-device.c | 26 ++++++++++++++++++++------ - 1 file changed, 20 insertions(+), 6 deletions(-) - -diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c -index c83667b16..bee7fb8bc 100644 ---- a/src/wayland/meta-wayland-data-device.c -+++ b/src/wayland/meta-wayland-data-device.c -@@ -1138,8 +1138,6 @@ drag_grab_data_source_destroyed (gpointer data, GObject *where_the_object_was) - MetaWaylandDragGrab *drag_grab = data; - - drag_grab->drag_data_source = NULL; -- meta_wayland_data_device_set_dnd_source (&drag_grab->seat->data_device, NULL); -- unset_selection_source (&drag_grab->seat->data_device, META_SELECTION_DND); - data_device_end_drag_grab (drag_grab); - } - -@@ -1577,6 +1575,16 @@ meta_wayland_data_device_get_drag_dest_funcs (void) - return &meta_wayland_drag_dest_funcs; - } - -+static void -+dnd_data_source_destroyed (gpointer data, -+ GObject *object_was_here) -+{ -+ MetaWaylandDataDevice *data_device = data; -+ -+ data_device->dnd_data_source = NULL; -+ unset_selection_source (data_device, META_SELECTION_DND); -+} -+ - void - meta_wayland_data_device_set_dnd_source (MetaWaylandDataDevice *data_device, - MetaWaylandDataSource *source) -@@ -1585,14 +1593,20 @@ meta_wayland_data_device_set_dnd_source (MetaWaylandDataDevice *data_device, - return; - - if (data_device->dnd_data_source) -- g_object_remove_weak_pointer (G_OBJECT (data_device->dnd_data_source), -- (gpointer *)&data_device->dnd_data_source); -+ { -+ g_object_weak_unref (G_OBJECT (data_device->dnd_data_source), -+ dnd_data_source_destroyed, -+ data_device); -+ } - - data_device->dnd_data_source = source; - - if (source) -- g_object_add_weak_pointer (G_OBJECT (data_device->dnd_data_source), -- (gpointer *)&data_device->dnd_data_source); -+ { -+ g_object_weak_ref (G_OBJECT (source), -+ dnd_data_source_destroyed, -+ data_device); -+ } - } - - void --- -2.22.0 - diff --git a/mutter-gnome-3-34-2019-11-12.patch b/mutter-gnome-3-34-2019-11-12.patch deleted file mode 100644 index 99485ae..0000000 --- a/mutter-gnome-3-34-2019-11-12.patch +++ /dev/null @@ -1,4156 +0,0 @@ -From 81ee8886ceb64fecff74655cb971966cb88295d7 Mon Sep 17 00:00:00 2001 -From: Tim Klocke <taaem@mailbox.org> -Date: Wed, 9 Oct 2019 10:24:54 +0200 -Subject: [PATCH 01/53] backends: Update inhibited state for the monitor and - respect that state - -The inhibited state of the monitor was after the initializiation never -updated. meta_idle_monitor_reset_idletime didn't respect the inhibited -state, so it set timeouts if it shouldn't have. - -Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/573 ---- - src/backends/meta-idle-monitor.c | 15 ++++++++++++--- - 1 file changed, 12 insertions(+), 3 deletions(-) - -diff --git a/src/backends/meta-idle-monitor.c b/src/backends/meta-idle-monitor.c -index 9fa481742..2ff1602e7 100644 ---- a/src/backends/meta-idle-monitor.c -+++ b/src/backends/meta-idle-monitor.c -@@ -207,6 +207,8 @@ update_inhibited (MetaIdleMonitor *monitor, - if (inhibited == monitor->inhibited) - return; - -+ monitor->inhibited = inhibited; -+ - g_hash_table_foreach (monitor->watches, - update_inhibited_watch, - monitor); -@@ -516,9 +518,16 @@ meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor) - } - else - { -- g_source_set_ready_time (watch->timeout_source, -- monitor->last_event_time + -- watch->timeout_msec * 1000); -+ if (monitor->inhibited) -+ { -+ g_source_set_ready_time (watch->timeout_source, -1); -+ } -+ else -+ { -+ g_source_set_ready_time (watch->timeout_source, -+ monitor->last_event_time + -+ watch->timeout_msec * 1000); -+ } - } - } - --- -2.23.0 - - -From 73eaf517702a448a4b073ca666413f030ffa8fe1 Mon Sep 17 00:00:00 2001 -From: Daniel van Vugt <daniel.van.vugt@canonical.com> -Date: Thu, 10 Oct 2019 17:21:13 +0800 -Subject: [PATCH 02/53] cogl-pango/meson.build: Remove extraneous quoting - -It wasn't necessary (see other instances of -DG_LOG_DOMAIN) and somewhere -along the line it was getting turned into forward slashes becoming a syntax -error: - -``` -/usr/include/glib-2.0/gobject/gobject.h:767: syntax error, unexpected '/' in -... -g_assertion_message (/"CoglPango/", -``` - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/841 ---- - cogl/cogl-pango/meson.build | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/cogl/cogl-pango/meson.build b/cogl/cogl-pango/meson.build -index 787ec0132..06fba5195 100644 ---- a/cogl/cogl-pango/meson.build -+++ b/cogl/cogl-pango/meson.build -@@ -62,7 +62,7 @@ if have_introspection - ], - extra_args: introspection_args + [ - '-UCOGL_COMPILATION', -- '-DG_LOG_DOMAIN=\"CoglPango\"', -+ '-DG_LOG_DOMAIN="CoglPango"', - ], - install_dir_gir: pkglibdir, - install_dir_typelib: pkglibdir, --- -2.23.0 - - -From 4c15d32b5541b852bbdeaf2c63c081849f2a14b9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com> -Date: Wed, 9 Oct 2019 21:27:11 +0200 -Subject: [PATCH 03/53] wayland/surface: Some minor coding style clean up - -Some very long lines that were split up. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/839 ---- - src/wayland/meta-wayland-surface.c | 24 +++++++++++++++++++----- - 1 file changed, 19 insertions(+), 5 deletions(-) - -diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c -index 5def3c5d6..647f05338 100644 ---- a/src/wayland/meta-wayland-surface.c -+++ b/src/wayland/meta-wayland-surface.c -@@ -972,8 +972,12 @@ wl_surface_frame (struct wl_client *client, - - callback = g_slice_new0 (MetaWaylandFrameCallback); - callback->surface = surface; -- callback->resource = wl_resource_create (client, &wl_callback_interface, META_WL_CALLBACK_VERSION, callback_id); -- wl_resource_set_implementation (callback->resource, NULL, callback, destroy_frame_callback); -+ callback->resource = wl_resource_create (client, -+ &wl_callback_interface, -+ META_WL_CALLBACK_VERSION, -+ callback_id); -+ wl_resource_set_implementation (callback->resource, NULL, callback, -+ destroy_frame_callback); - - wl_list_insert (surface->pending->frame_callback_list.prev, &callback->link); - } -@@ -1370,7 +1374,9 @@ wl_surface_destructor (struct wl_resource *resource) - - meta_wayland_compositor_destroy_frame_callbacks (compositor, surface); - -- g_hash_table_foreach (surface->outputs_to_destroy_notify_id, surface_output_disconnect_signal, surface); -+ g_hash_table_foreach (surface->outputs_to_destroy_notify_id, -+ surface_output_disconnect_signal, -+ surface); - g_hash_table_unref (surface->outputs_to_destroy_notify_id); - - wl_list_for_each_safe (cb, next, &surface->pending_frame_callback_list, link) -@@ -1419,12 +1425,20 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor, - guint32 id) - { - MetaWaylandSurface *surface = g_object_new (META_TYPE_WAYLAND_SURFACE, NULL); -+ int surface_version; - - surface->compositor = compositor; - surface->scale = 1; - -- surface->resource = wl_resource_create (client, &wl_surface_interface, wl_resource_get_version (compositor_resource), id); -- wl_resource_set_implementation (surface->resource, &meta_wayland_wl_surface_interface, surface, wl_surface_destructor); -+ surface_version = wl_resource_get_version (compositor_resource); -+ surface->resource = wl_resource_create (client, -+ &wl_surface_interface, -+ surface_version, -+ id); -+ wl_resource_set_implementation (surface->resource, -+ &meta_wayland_wl_surface_interface, -+ surface, -+ wl_surface_destructor); - - wl_list_init (&surface->pending_frame_callback_list); - --- -2.23.0 - - -From d49d10b14f4e0fa80e6867979b26fab383610b39 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com> -Date: Wed, 9 Oct 2019 21:53:09 +0200 -Subject: [PATCH 04/53] wayland/actor-surface: Queue redraw for frame callback - -A frame callback without damage is still expected to be responded to. -Implement this by simply queuing damage if there are any frame callbacks -requested and there is no damage yet. If there already is damage, -we'll be queued already, but with more correct damage. Without we simply -need to make sure we flush the callbacks if any area of surface is not -occluded. - -Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/457 - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/839 ---- - src/wayland/meta-wayland-actor-surface.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/src/wayland/meta-wayland-actor-surface.c b/src/wayland/meta-wayland-actor-surface.c -index f74bfc59c..a61a80eff 100644 ---- a/src/wayland/meta-wayland-actor-surface.c -+++ b/src/wayland/meta-wayland-actor-surface.c -@@ -241,6 +241,11 @@ meta_wayland_actor_surface_commit (MetaWaylandSurfaceRole *surface_role, - if (!priv->actor) - return; - -+ if (!wl_list_empty (&pending->frame_callback_list) && -+ cairo_region_is_empty (pending->surface_damage) && -+ cairo_region_is_empty (pending->buffer_damage)) -+ clutter_actor_queue_redraw (CLUTTER_ACTOR (priv->actor)); -+ - meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending); - - meta_wayland_actor_surface_sync_actor_state (actor_surface); --- -2.23.0 - - -From 59a697f773e856776887c6e11e452fe4b2cefed0 Mon Sep 17 00:00:00 2001 -From: Carlos Garnacho <carlosg@gnome.org> -Date: Thu, 10 Oct 2019 12:16:58 +0200 -Subject: [PATCH 05/53] x11: Translate well known selection atoms to mimetypes - -Some antediluvian x11 clients only bother to set atoms like -UTF8_STRING/STRING/TEXT/... and no matching mimetypes. Cover for them -and add the well known mimetypes if they are missing. - -Reported at https://bugzilla.redhat.com/show_bug.cgi?id=1758873 - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/842 ---- - src/x11/meta-selection-source-x11.c | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - -diff --git a/src/x11/meta-selection-source-x11.c b/src/x11/meta-selection-source-x11.c -index 15a763651..1a0369ab0 100644 ---- a/src/x11/meta-selection-source-x11.c -+++ b/src/x11/meta-selection-source-x11.c -@@ -139,6 +139,8 @@ atoms_to_mimetypes (MetaX11Display *display, - const Atom *atoms; - gsize size; - guint i, n_atoms; -+ gboolean utf8_string_found = FALSE, utf8_text_plain_found = FALSE; -+ gboolean string_found = FALSE, text_plain_found = FALSE; - - atoms = g_bytes_get_data (bytes, &size); - n_atoms = size / sizeof (Atom); -@@ -149,8 +151,19 @@ atoms_to_mimetypes (MetaX11Display *display, - - mimetype = gdk_x11_get_xatom_name (atoms[i]); - mimetypes = g_list_prepend (mimetypes, g_strdup (mimetype)); -+ -+ utf8_text_plain_found |= strcmp (mimetype, "text/plain;charset=utf-8") == 0; -+ text_plain_found |= strcmp (mimetype, "text/plain") == 0; -+ utf8_string_found |= strcmp (mimetype, "UTF8_STRING") == 0; -+ string_found |= strcmp (mimetype, "STRING") == 0; - } - -+ /* Ensure non-x11 clients get well-known mimetypes */ -+ if (string_found && !text_plain_found) -+ mimetypes = g_list_prepend (mimetypes, g_strdup ("text/plain")); -+ if (utf8_string_found && !utf8_text_plain_found) -+ mimetypes = g_list_prepend (mimetypes, g_strdup ("text/plain;charset=utf-8")); -+ - return mimetypes; - } - --- -2.23.0 - - -From 9234fcb6248c41d09e46d4e5b7747f78052b2b83 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net> -Date: Sat, 31 Aug 2019 17:48:43 +0200 -Subject: [PATCH 06/53] event-x11: Use CLUTTER prefix for X11 filter docs - -As per commit ad72fa46b clutter_x11_handle_event was renamed into -meta_x11_handle_event but the return type didn't change. - -So, keep the doc-string to match the actual possible return values. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/764 ---- - src/backends/x11/meta-event-x11.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/backends/x11/meta-event-x11.c b/src/backends/x11/meta-event-x11.c -index 8b4f4fc81..19da2235b 100644 ---- a/src/backends/x11/meta-event-x11.c -+++ b/src/backends/x11/meta-event-x11.c -@@ -82,12 +82,12 @@ meta_x11_handle_event (XEvent *xevent) - gboolean allocated_event; - - /* The return values here are someone approximate; we return -- * META_X11_FILTER_REMOVE if a clutter event is -+ * CLUTTER_X11_FILTER_REMOVE if a clutter event is - * generated for the event. This mostly, but not entirely, - * corresponds to whether other event processing should be - * excluded. As long as the stage window is not shared with another - * toolkit it should be safe, and never return -- * %META_X11_FILTER_REMOVE when more processing is needed. -+ * %CLUTTER_X11_FILTER_REMOVE when more processing is needed. - */ - - result = CLUTTER_X11_FILTER_CONTINUE; --- -2.23.0 - - -From 446bd04b6c5c63b71cd90b8664e5442be43bfaaa Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net> -Date: Sat, 31 Aug 2019 17:57:32 +0200 -Subject: [PATCH 07/53] clutter-backend-x11: Don't push keymap events to - clutter - -Xkb events should be handled by clutter backend but they are not translated -into an actual clutter event. However we're now handling them and also trying -to push an empty event to clutter queue, causing a critical error. - -So in such case, just handle the native event but don't push the non-populated -clutter-event to the queue. - -Fixes https://gitlab.gnome.org/GNOME/mutter/issues/750 -https://gitlab.gnome.org/GNOME/mutter/merge_requests/764 ---- - src/backends/x11/meta-clutter-backend-x11.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/backends/x11/meta-clutter-backend-x11.c b/src/backends/x11/meta-clutter-backend-x11.c -index 8d4b64b03..b6334de8b 100644 ---- a/src/backends/x11/meta-clutter-backend-x11.c -+++ b/src/backends/x11/meta-clutter-backend-x11.c -@@ -129,7 +129,7 @@ meta_clutter_backend_x11_translate_event (ClutterBackend *backend, - return TRUE; - - if (meta_keymap_x11_handle_event (backend_x11->keymap, native)) -- return TRUE; -+ return FALSE; - - stage_x11 = META_STAGE_X11 (clutter_backend_get_stage_window (backend)); - if (meta_stage_x11_translate_event (stage_x11, native, event)) --- -2.23.0 - - -From 1cc249fe18c8c280d8087642e0ac1f0287c53a64 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com> -Date: Thu, 10 Oct 2019 10:10:38 +0200 -Subject: [PATCH 08/53] kms: Always predict state after processing update - -Not only mode sets have state that should be predicted; changing gamma -currently happens with its own update, so we missed predicting that. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/840 ---- - src/backends/native/meta-kms-update-private.h | 2 -- - src/backends/native/meta-kms-update.c | 6 ------ - src/backends/native/meta-kms.c | 3 +-- - 3 files changed, 1 insertion(+), 10 deletions(-) - -diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h -index 88e2590af..df7737c9b 100644 ---- a/src/backends/native/meta-kms-update-private.h -+++ b/src/backends/native/meta-kms-update-private.h -@@ -110,6 +110,4 @@ GList * meta_kms_update_get_connector_properties (MetaKmsUpdate *update); - - GList * meta_kms_update_get_crtc_gammas (MetaKmsUpdate *update); - --gboolean meta_kms_update_has_mode_set (MetaKmsUpdate *update); -- - #endif /* META_KMS_UPDATE_PRIVATE_H */ -diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c -index 2a4a05c3e..c946aa7a2 100644 ---- a/src/backends/native/meta-kms-update.c -+++ b/src/backends/native/meta-kms-update.c -@@ -282,12 +282,6 @@ meta_kms_update_get_crtc_gammas (MetaKmsUpdate *update) - return update->crtc_gammas; - } - --gboolean --meta_kms_update_has_mode_set (MetaKmsUpdate *update) --{ -- return !!update->mode_sets; --} -- - void - meta_kms_update_seal (MetaKmsUpdate *update) - { -diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c -index 9485bb4e8..804a1adda 100644 ---- a/src/backends/native/meta-kms.c -+++ b/src/backends/native/meta-kms.c -@@ -211,8 +211,7 @@ meta_kms_update_process_in_impl (MetaKmsImpl *impl, - - ret = meta_kms_impl_process_update (impl, update, error); - -- if (meta_kms_update_has_mode_set (update)) -- meta_kms_predict_states_in_impl (meta_kms_impl_get_kms (impl), update); -+ meta_kms_predict_states_in_impl (meta_kms_impl_get_kms (impl), update); - - return ret; - } --- -2.23.0 - - -From 1b4709794ea3602f5573fee164c880a14f049d3b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com> -Date: Thu, 10 Oct 2019 10:47:05 +0200 -Subject: [PATCH 09/53] kms/crtc: Read gamma state when prediction failed - -If we did a mode set, the gamma may have been changed by the kernel, and -if we didn't also update the gamma in the same transaction, we have no -way to predict the current gamma ramp state. In this case, read the -gamma state directly from KMS. - -This should be relatively harmless regarding the race conditions the -state prediction was meant to solve, as the worst case is we get none or -out of date gamma ramps; and since this is for when gamma ramps are not -updated at mode setting time, we'd get intermediate gamma state to begin -with, so it's not worse than what we currently do anyway. - -Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/851 - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/840 ---- - src/backends/native/meta-kms-crtc.c | 46 +++++++++++++++++++++++++++-- - 1 file changed, 43 insertions(+), 3 deletions(-) - -diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c -index 3610df903..da99a58cd 100644 ---- a/src/backends/native/meta-kms-crtc.c -+++ b/src/backends/native/meta-kms-crtc.c -@@ -143,14 +143,26 @@ meta_kms_crtc_update_state (MetaKmsCrtc *crtc) - drmModeFreeCrtc (drm_crtc); - } - -+static void -+clear_gamma_state (MetaKmsCrtc *crtc) -+{ -+ crtc->current_state.gamma.size = 0; -+ g_clear_pointer (&crtc->current_state.gamma.red, g_free); -+ g_clear_pointer (&crtc->current_state.gamma.green, g_free); -+ g_clear_pointer (&crtc->current_state.gamma.blue, g_free); -+} -+ - void - meta_kms_crtc_predict_state (MetaKmsCrtc *crtc, - MetaKmsUpdate *update) - { -+ gboolean is_gamma_valid; - GList *mode_sets; - GList *crtc_gammas; - GList *l; - -+ is_gamma_valid = TRUE; -+ - mode_sets = meta_kms_update_get_mode_sets (update); - for (l = mode_sets; l; l = l->next) - { -@@ -178,6 +190,8 @@ meta_kms_crtc_predict_state (MetaKmsCrtc *crtc, - crtc->current_state.drm_mode = (drmModeModeInfo) { 0 }; - } - -+ is_gamma_valid = FALSE; -+ - break; - } - -@@ -196,8 +210,36 @@ meta_kms_crtc_predict_state (MetaKmsCrtc *crtc, - g_memdup (gamma->green, gamma->size * sizeof (uint16_t)); - crtc->current_state.gamma.blue = - g_memdup (gamma->blue, gamma->size * sizeof (uint16_t)); -+ -+ is_gamma_valid = TRUE; - break; - } -+ -+ if (!is_gamma_valid) -+ { -+ if (crtc->current_state.is_drm_mode_valid) -+ { -+ MetaKmsImplDevice *impl_device; -+ drmModeCrtc *drm_crtc; -+ -+ impl_device = meta_kms_device_get_impl_device (crtc->device); -+ drm_crtc = drmModeGetCrtc (meta_kms_impl_device_get_fd (impl_device), -+ crtc->id); -+ if (drm_crtc) -+ { -+ read_gamma_state (crtc, impl_device, drm_crtc); -+ drmModeFreeCrtc (drm_crtc); -+ } -+ else -+ { -+ clear_gamma_state (crtc); -+ } -+ } -+ else -+ { -+ clear_gamma_state (crtc); -+ } -+ } - } - - MetaKmsCrtc * -@@ -220,9 +262,7 @@ meta_kms_crtc_finalize (GObject *object) - { - MetaKmsCrtc *crtc = META_KMS_CRTC (object); - -- g_clear_pointer (&crtc->current_state.gamma.red, g_free); -- g_clear_pointer (&crtc->current_state.gamma.green, g_free); -- g_clear_pointer (&crtc->current_state.gamma.blue, g_free); -+ clear_gamma_state (crtc); - - G_OBJECT_CLASS (meta_kms_crtc_parent_class)->finalize (object); - } --- -2.23.0 - - -From 69a0c1dc80ec733a807d61825e56794bdcf8c5ca Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com> -Date: Wed, 9 Oct 2019 10:58:43 +0200 -Subject: [PATCH 10/53] main: Warn instead of error in meta_test_init() - -Otherwise we'll get the warning - -../src/core/main.c: In function 'meta_test_init': -../src/core/main.c:755:1: error: function might be candidate for attribute 'noreturn' [-Werror=suggest-attribute=noreturn] - 755 | meta_test_init (void) - | ^~~~~~~~~~~~~~ - -when building without Wayland. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/837 ---- - src/core/main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/core/main.c b/src/core/main.c -index 7f4f666d2..3935f3523 100644 ---- a/src/core/main.c -+++ b/src/core/main.c -@@ -766,6 +766,6 @@ meta_test_init (void) - - close (fd); - #else -- g_error ("Tests require wayland support"); -+ g_warning ("Tests require wayland support"); - #endif - } --- -2.23.0 - - -From f7c3f50f61507bec04b52f342175a5be5a7ec2fb Mon Sep 17 00:00:00 2001 -From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com> -Date: Fri, 11 Oct 2019 10:45:34 -0300 -Subject: [PATCH 11/53] clutter/shader-effect: Initialize shader-type properly - -The default value of the ClutterShaderEffect:shader-type -property is CLUTTER_FRAGMENT_SHADER. However, because the -struct field is not actually initialized to it, it ends -up assuming the value 0, which is CLUTTER_VERTEX_SHADER. - -Properly initialize ClutterShaderEffect's shader_type to -CLUTTER_FRAGMENT_SHADER. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/846 ---- - clutter/clutter/clutter-shader-effect.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/clutter/clutter/clutter-shader-effect.c b/clutter/clutter/clutter-shader-effect.c -index a5ae1ee40..c659dab12 100644 ---- a/clutter/clutter/clutter-shader-effect.c -+++ b/clutter/clutter/clutter-shader-effect.c -@@ -500,6 +500,7 @@ static void - clutter_shader_effect_init (ClutterShaderEffect *effect) - { - effect->priv = clutter_shader_effect_get_instance_private (effect); -+ effect->priv->shader_type = CLUTTER_FRAGMENT_SHADER; - } - - /** --- -2.23.0 - - -From 79cae1de9e9e3a93cb5dd71c7e8aedecfde1b86b Mon Sep 17 00:00:00 2001 -From: Carlos Garnacho <carlosg@gnome.org> -Date: Fri, 11 Oct 2019 13:25:35 +0200 -Subject: [PATCH 12/53] wayland: Plug MetaSelectionSourceWayland leaks - -There was a dangling ref left on all of them, oops. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/848 ---- - src/wayland/meta-wayland-data-device.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c -index 2ca77e8ea..e063a9a0c 100644 ---- a/src/wayland/meta-wayland-data-device.c -+++ b/src/wayland/meta-wayland-data-device.c -@@ -1309,6 +1309,7 @@ data_device_start_drag (struct wl_client *client, - g_list_free_full (mimetypes, g_free); - set_selection_source (data_device, META_SELECTION_DND, - selection_source); -+ g_object_unref (selection_source); - - meta_wayland_pointer_set_focus (seat->pointer, NULL); - meta_wayland_data_device_start_drag (data_device, client, -@@ -1694,6 +1695,7 @@ meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device, - - set_selection_source (data_device, META_SELECTION_CLIPBOARD, - selection_source); -+ g_object_unref (selection_source); - } - else - { -@@ -1831,6 +1833,7 @@ meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device, - - set_selection_source (data_device, META_SELECTION_PRIMARY, - selection_source); -+ g_object_unref (selection_source); - } - else - { --- -2.23.0 - - -From d1205d3c6b442bc4534e21c9a9036f30e805ca44 Mon Sep 17 00:00:00 2001 -From: Carlos Garnacho <carlosg@gnome.org> -Date: Fri, 11 Oct 2019 16:49:24 +0200 -Subject: [PATCH 13/53] wayland: Drop field from MetaWaylandDataSourcePrimary - -This is a subclass of MetaWaylandDataSourceWayland, so there's no need -for a duplicate wl_resource field. Make sure to reuse the parent struct -one. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/848 ---- - src/wayland/meta-wayland-data-device.c | 22 ++++++++++------------ - 1 file changed, 10 insertions(+), 12 deletions(-) - -diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c -index e063a9a0c..310ad13cf 100644 ---- a/src/wayland/meta-wayland-data-device.c -+++ b/src/wayland/meta-wayland-data-device.c -@@ -84,8 +84,6 @@ typedef struct _MetaWaylandDataSourceWayland - typedef struct _MetaWaylandDataSourcePrimary - { - MetaWaylandDataSourceWayland parent; -- -- struct wl_resource *resource; - } MetaWaylandDataSourcePrimary; - - G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandDataSource, meta_wayland_data_source, -@@ -1452,10 +1450,10 @@ meta_wayland_data_source_primary_send (MetaWaylandDataSource *source, - const gchar *mime_type, - gint fd) - { -- MetaWaylandDataSourcePrimary *source_primary; -+ MetaWaylandDataSourceWayland *source_wayland; - -- source_primary = META_WAYLAND_DATA_SOURCE_PRIMARY (source); -- gtk_primary_selection_source_send_send (source_primary->resource, -+ source_wayland = META_WAYLAND_DATA_SOURCE_WAYLAND (source); -+ gtk_primary_selection_source_send_send (source_wayland->resource, - mime_type, fd); - close (fd); - } -@@ -1463,10 +1461,10 @@ meta_wayland_data_source_primary_send (MetaWaylandDataSource *source, - static void - meta_wayland_data_source_primary_cancel (MetaWaylandDataSource *source) - { -- MetaWaylandDataSourcePrimary *source_primary; -+ MetaWaylandDataSourceWayland *source_wayland; - -- source_primary = META_WAYLAND_DATA_SOURCE_PRIMARY (source); -- gtk_primary_selection_source_send_cancelled (source_primary->resource); -+ source_wayland = META_WAYLAND_DATA_SOURCE_WAYLAND (source); -+ gtk_primary_selection_source_send_cancelled (source_wayland->resource); - } - - static void -@@ -1780,7 +1778,7 @@ meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device, - { - struct wl_resource *resource; - -- resource = META_WAYLAND_DATA_SOURCE_PRIMARY (source)->resource; -+ resource = META_WAYLAND_DATA_SOURCE_WAYLAND (source)->resource; - - if (wl_resource_get_client (resource) != - meta_wayland_keyboard_get_focus_client (seat->keyboard)) -@@ -1825,7 +1823,7 @@ meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device, - data_device); - - mimetypes = copy_string_array_to_list (meta_wayland_data_source_get_mime_types (source)); -- selection_source = meta_selection_source_wayland_new (META_WAYLAND_DATA_SOURCE_PRIMARY (source)->resource, -+ selection_source = meta_selection_source_wayland_new (META_WAYLAND_DATA_SOURCE_WAYLAND (source)->resource, - mimetypes, - gtk_primary_selection_source_send_send, - gtk_primary_selection_source_send_cancelled); -@@ -1971,7 +1969,7 @@ static const struct wl_data_device_manager_interface manager_interface = { - static void - destroy_primary_source (struct wl_resource *resource) - { -- MetaWaylandDataSourcePrimary *source = wl_resource_get_user_data (resource); -+ MetaWaylandDataSourceWayland *source = wl_resource_get_user_data (resource); - - source->resource = NULL; - g_object_unref (source); -@@ -2207,7 +2205,7 @@ meta_wayland_data_source_wayland_new (struct wl_resource *resource) - static MetaWaylandDataSource * - meta_wayland_data_source_primary_new (struct wl_resource *resource) - { -- MetaWaylandDataSourcePrimary *source_primary = -+ MetaWaylandDataSourceWayland *source_primary = - g_object_new (META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY, NULL); - - source_primary->resource = resource; --- -2.23.0 - - -From 3f2ad3c5635aa388b6c4d7d8bb2fa33a2766c495 Mon Sep 17 00:00:00 2001 -From: Carlos Garnacho <carlosg@gnome.org> -Date: Fri, 11 Oct 2019 18:02:13 +0200 -Subject: [PATCH 14/53] wayland: Chain up to the right finalize on - MetaWaylandDataSourceWayland - -This function was using the wrong parent class pointer, so it was mistakenly -skipping over MetaWaylandDataSource::finalize. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/848 ---- - src/wayland/meta-wayland-data-device.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c -index 310ad13cf..7948fe912 100644 ---- a/src/wayland/meta-wayland-data-device.c -+++ b/src/wayland/meta-wayland-data-device.c -@@ -1420,7 +1420,7 @@ meta_wayland_source_drag_finished (MetaWaylandDataSource *source) - static void - meta_wayland_source_finalize (GObject *object) - { -- G_OBJECT_CLASS (meta_wayland_data_source_parent_class)->finalize (object); -+ G_OBJECT_CLASS (meta_wayland_data_source_wayland_parent_class)->finalize (object); - } - - static void --- -2.23.0 - - -From 86743a9c7c27c16f0b0a63aaf20c5cae60742bcd Mon Sep 17 00:00:00 2001 -From: Carlos Garnacho <carlosg@gnome.org> -Date: Fri, 11 Oct 2019 12:27:56 +0200 -Subject: [PATCH 15/53] wayland: Emit wl/primary offer after changing selection - -We are still poking the mimetypes from the previous selection when creating -the new offer. This may come out wrong between changes of the copied -mimetypes. - -Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/789 ---- - src/wayland/meta-wayland-data-device.c | 48 +++++++++++++------------- - 1 file changed, 24 insertions(+), 24 deletions(-) - -diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c -index 7948fe912..24e97222a 100644 ---- a/src/wayland/meta-wayland-data-device.c -+++ b/src/wayland/meta-wayland-data-device.c -@@ -1660,18 +1660,6 @@ meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device, - data_device->selection_data_source = source; - data_device->selection_serial = serial; - -- focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard); -- if (focus_client) -- { -- data_device_resource = wl_resource_find_for_client (&data_device->resource_list, focus_client); -- if (data_device_resource) -- { -- struct wl_resource *offer; -- offer = create_and_send_clipboard_offer (data_device, data_device_resource); -- wl_data_device_send_selection (data_device_resource, offer); -- } -- } -- - if (source) - { - MetaWaylandDataSourceWayland *source_wayland = -@@ -1700,6 +1688,18 @@ meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device, - unset_selection_source (data_device, META_SELECTION_CLIPBOARD); - } - -+ focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard); -+ if (focus_client) -+ { -+ data_device_resource = wl_resource_find_for_client (&data_device->resource_list, focus_client); -+ if (data_device_resource) -+ { -+ struct wl_resource *offer; -+ offer = create_and_send_clipboard_offer (data_device, data_device_resource); -+ wl_data_device_send_selection (data_device_resource, offer); -+ } -+ } -+ - wl_signal_emit (&data_device->selection_ownership_signal, source); - } - -@@ -1800,18 +1800,6 @@ meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device, - data_device->primary_data_source = source; - data_device->primary_serial = serial; - -- focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard); -- if (focus_client) -- { -- data_device_resource = wl_resource_find_for_client (&data_device->primary_resource_list, focus_client); -- if (data_device_resource) -- { -- struct wl_resource *offer; -- offer = create_and_send_primary_offer (data_device, data_device_resource); -- gtk_primary_selection_device_send_selection (data_device_resource, offer); -- } -- } -- - if (source) - { - MetaSelectionSource *selection_source; -@@ -1838,6 +1826,18 @@ meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device, - unset_selection_source (data_device, META_SELECTION_PRIMARY); - } - -+ focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard); -+ if (focus_client) -+ { -+ data_device_resource = wl_resource_find_for_client (&data_device->primary_resource_list, focus_client); -+ if (data_device_resource) -+ { -+ struct wl_resource *offer; -+ offer = create_and_send_primary_offer (data_device, data_device_resource); -+ gtk_primary_selection_device_send_selection (data_device_resource, offer); -+ } -+ } -+ - wl_signal_emit (&data_device->primary_ownership_signal, source); - } - --- -2.23.0 - - -From b3c69c3dfbe3859b4c7a7ee877f46407b9294d08 Mon Sep 17 00:00:00 2001 -From: Carlos Garnacho <carlosg@gnome.org> -Date: Fri, 11 Oct 2019 17:47:00 +0200 -Subject: [PATCH 16/53] wayland: Check resource before emitting cancelled event - -If a data source is destroyed we first unset the resource, and then try to -unref the related selection source. At this point the only event that might -be emitted by the internal selection machinery is .cancelled, so make sure -we avoid it on destroyed sources. - -Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/842 ---- - src/wayland/meta-wayland-data-device.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c -index 24e97222a..3dfedd959 100644 ---- a/src/wayland/meta-wayland-data-device.c -+++ b/src/wayland/meta-wayland-data-device.c -@@ -1369,7 +1369,8 @@ meta_wayland_source_cancel (MetaWaylandDataSource *source) - MetaWaylandDataSourceWayland *source_wayland = - META_WAYLAND_DATA_SOURCE_WAYLAND (source); - -- wl_data_source_send_cancelled (source_wayland->resource); -+ if (source_wayland->resource) -+ wl_data_source_send_cancelled (source_wayland->resource); - } - - static void -@@ -1464,7 +1465,8 @@ meta_wayland_data_source_primary_cancel (MetaWaylandDataSource *source) - MetaWaylandDataSourceWayland *source_wayland; - - source_wayland = META_WAYLAND_DATA_SOURCE_WAYLAND (source); -- gtk_primary_selection_source_send_cancelled (source_wayland->resource); -+ if (source_wayland->resource) -+ gtk_primary_selection_source_send_cancelled (source_wayland->resource); - } - - static void --- -2.23.0 - - -From 86b1a0465715b887156b7597de0553f4119c29f5 Mon Sep 17 00:00:00 2001 -From: Carlos Garnacho <carlosg@gnome.org> -Date: Fri, 11 Oct 2019 17:09:26 +0200 -Subject: [PATCH 17/53] wayland: Simplify MetaSelectionSourceWayland - -Instead of taking resource and send/cancel funcs, take a -MetaWaylandDataSource, which exposes all the vfuncs to do the same on the -internal resource. - -This has the added side effect that only MetaWaylandDataSource has a -pointer to the wl_resource, which may be unset untimely. - -Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/842 ---- - .../meta-selection-source-wayland-private.h | 12 ++---- - src/wayland/meta-selection-source-wayland.c | 36 +++++++++------- - src/wayland/meta-wayland-data-device.c | 42 ++----------------- - src/wayland/meta-wayland-data-device.h | 2 + - 4 files changed, 31 insertions(+), 61 deletions(-) - -diff --git a/src/wayland/meta-selection-source-wayland-private.h b/src/wayland/meta-selection-source-wayland-private.h -index 6affc77a8..a6ada8898 100644 ---- a/src/wayland/meta-selection-source-wayland-private.h -+++ b/src/wayland/meta-selection-source-wayland-private.h -@@ -25,6 +25,8 @@ - #include <wayland-server.h> - - #include "meta/meta-selection-source.h" -+#include "wayland/meta-wayland-data-device.h" -+#include "wayland/meta-wayland-data-device-private.h" - - #define META_TYPE_SELECTION_SOURCE_WAYLAND (meta_selection_source_wayland_get_type ()) - -@@ -33,14 +35,6 @@ G_DECLARE_FINAL_TYPE (MetaSelectionSourceWayland, - META, SELECTION_SOURCE_WAYLAND, - MetaSelectionSource) - --typedef void (* MetaWaylandSendFunc) (struct wl_resource *resource, -- const char *mimetype, -- int fd); --typedef void (* MetaWaylandCancelFunc) (struct wl_resource *resource); -- --MetaSelectionSource * meta_selection_source_wayland_new (struct wl_resource *resource, -- GList *mime_types, -- MetaWaylandSendFunc send_func, -- MetaWaylandCancelFunc cancel_func); -+MetaSelectionSource * meta_selection_source_wayland_new (MetaWaylandDataSource *source); - - #endif /* META_SELECTION_SOURCE_WAYLAND_H */ -diff --git a/src/wayland/meta-selection-source-wayland.c b/src/wayland/meta-selection-source-wayland.c -index 7031c911e..4f6f0c33c 100644 ---- a/src/wayland/meta-selection-source-wayland.c -+++ b/src/wayland/meta-selection-source-wayland.c -@@ -29,10 +29,8 @@ - struct _MetaSelectionSourceWayland - { - MetaSelectionSource parent_instance; -+ MetaWaylandDataSource *data_source; - GList *mimetypes; -- MetaWaylandSendFunc send_func; -- MetaWaylandCancelFunc cancel_func; -- struct wl_resource *resource; - }; - - G_DEFINE_TYPE (MetaSelectionSourceWayland, meta_selection_source_wayland, -@@ -85,7 +83,8 @@ meta_selection_source_wayland_read_async (MetaSelectionSource *source, - g_task_set_source_tag (task, meta_selection_source_wayland_read_async); - - stream = g_unix_input_stream_new (pipe_fds[0], TRUE); -- source_wayland->send_func (source_wayland->resource, mimetype, pipe_fds[1]); -+ meta_wayland_data_source_send (source_wayland->data_source, -+ mimetype, pipe_fds[1]); - close (pipe_fds[1]); - - g_task_return_pointer (task, stream, g_object_unref); -@@ -119,7 +118,7 @@ meta_selection_source_wayland_deactivated (MetaSelectionSource *source) - MetaSelectionSourceWayland *source_wayland = - META_SELECTION_SOURCE_WAYLAND (source); - -- source_wayland->cancel_func (source_wayland->resource); -+ meta_wayland_data_source_cancel (source_wayland->data_source); - META_SELECTION_SOURCE_CLASS (meta_selection_source_wayland_parent_class)->deactivated (source); - } - -@@ -143,20 +142,29 @@ meta_selection_source_wayland_init (MetaSelectionSourceWayland *source) - { - } - -+static GList * -+copy_string_array_to_list (struct wl_array *array) -+{ -+ GList *l = NULL; -+ char **p; -+ -+ wl_array_for_each (p, array) -+ l = g_list_prepend (l, g_strdup (*p)); -+ -+ return l; -+} -+ - MetaSelectionSource * --meta_selection_source_wayland_new (struct wl_resource *resource, -- GList *mime_types, -- MetaWaylandSendFunc send_func, -- MetaWaylandCancelFunc cancel_func) -+meta_selection_source_wayland_new (MetaWaylandDataSource *data_source) - { - MetaSelectionSourceWayland *source_wayland; -+ struct wl_array *mimetypes; - - source_wayland = g_object_new (META_TYPE_SELECTION_SOURCE_WAYLAND, NULL); -- source_wayland->mimetypes = g_list_copy_deep (mime_types, -- (GCopyFunc) g_strdup, NULL); -- source_wayland->send_func = send_func; -- source_wayland->cancel_func = cancel_func; -- source_wayland->resource = resource; -+ source_wayland->data_source = data_source; -+ -+ mimetypes = meta_wayland_data_source_get_mime_types (data_source); -+ source_wayland->mimetypes = copy_string_array_to_list (mimetypes); - - return META_SELECTION_SOURCE (source_wayland); - } -diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c -index 3dfedd959..0044a80b8 100644 ---- a/src/wayland/meta-wayland-data-device.c -+++ b/src/wayland/meta-wayland-data-device.c -@@ -250,7 +250,7 @@ meta_wayland_data_source_get_mime_types (const MetaWaylandDataSource *source) - return &priv->mime_types; - } - --static void -+void - meta_wayland_data_source_cancel (MetaWaylandDataSource *source) - { - META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->cancel (source); -@@ -1152,18 +1152,6 @@ destroy_data_device_icon (struct wl_listener *listener, void *data) - clutter_actor_remove_all_children (drag_grab->feedback_actor); - } - --static GList * --copy_string_array_to_list (struct wl_array *array) --{ -- GList *l = NULL; -- char **p; -- -- wl_array_for_each (p, array) -- l = g_list_prepend (l, g_strdup (*p)); -- -- return l; --} -- - void - meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data_device, - struct wl_client *client, -@@ -1263,7 +1251,6 @@ data_device_start_drag (struct wl_client *client, - MetaWaylandSurface *surface = NULL, *icon_surface = NULL; - MetaWaylandDataSource *drag_source = NULL; - MetaSelectionSource *selection_source; -- GList *mimetypes; - - if (origin_resource) - surface = wl_resource_get_user_data (origin_resource); -@@ -1299,12 +1286,7 @@ data_device_start_drag (struct wl_client *client, - return; - } - -- mimetypes = copy_string_array_to_list (meta_wayland_data_source_get_mime_types (drag_source)); -- selection_source = meta_selection_source_wayland_new (source_resource, -- mimetypes, -- wl_data_source_send_send, -- wl_data_source_send_cancelled); -- g_list_free_full (mimetypes, g_free); -+ selection_source = meta_selection_source_wayland_new (drag_source); - set_selection_source (data_device, META_SELECTION_DND, - selection_source); - g_object_unref (selection_source); -@@ -1664,23 +1646,14 @@ meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device, - - if (source) - { -- MetaWaylandDataSourceWayland *source_wayland = -- META_WAYLAND_DATA_SOURCE_WAYLAND (source); - MetaSelectionSource *selection_source; -- GList *mimetypes; - - meta_wayland_data_source_set_seat (source, seat); - g_object_weak_ref (G_OBJECT (source), - selection_data_source_destroyed, - data_device); - -- mimetypes = copy_string_array_to_list (meta_wayland_data_source_get_mime_types (source)); -- selection_source = meta_selection_source_wayland_new (source_wayland->resource, -- mimetypes, -- wl_data_source_send_send, -- wl_data_source_send_cancelled); -- g_list_free_full (mimetypes, g_free); -- -+ selection_source = meta_selection_source_wayland_new (source); - set_selection_source (data_device, META_SELECTION_CLIPBOARD, - selection_source); - g_object_unref (selection_source); -@@ -1805,20 +1778,13 @@ meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device, - if (source) - { - MetaSelectionSource *selection_source; -- GList *mimetypes; - - meta_wayland_data_source_set_seat (source, seat); - g_object_weak_ref (G_OBJECT (source), - primary_source_destroyed, - data_device); - -- mimetypes = copy_string_array_to_list (meta_wayland_data_source_get_mime_types (source)); -- selection_source = meta_selection_source_wayland_new (META_WAYLAND_DATA_SOURCE_WAYLAND (source)->resource, -- mimetypes, -- gtk_primary_selection_source_send_send, -- gtk_primary_selection_source_send_cancelled); -- g_list_free_full (mimetypes, g_free); -- -+ selection_source = meta_selection_source_wayland_new (source); - set_selection_source (data_device, META_SELECTION_PRIMARY, - selection_source); - g_object_unref (selection_source); -diff --git a/src/wayland/meta-wayland-data-device.h b/src/wayland/meta-wayland-data-device.h -index 729baacd9..efa5478bf 100644 ---- a/src/wayland/meta-wayland-data-device.h -+++ b/src/wayland/meta-wayland-data-device.h -@@ -111,6 +111,8 @@ gboolean meta_wayland_data_source_has_target (MetaWaylandDataSource *source) - void meta_wayland_data_source_set_has_target (MetaWaylandDataSource *source, - gboolean has_target); - -+void meta_wayland_data_source_cancel (MetaWaylandDataSource *source); -+ - void meta_wayland_data_source_send (MetaWaylandDataSource *source, - const gchar *mime_type, - gint fd); --- -2.23.0 - - -From a43aec2d3a466effd0ccc4433a58b3c0892abf66 Mon Sep 17 00:00:00 2001 -From: Carlos Garnacho <carlosg@gnome.org> -Date: Fri, 11 Oct 2019 18:43:00 +0200 -Subject: [PATCH 18/53] wayland: Set dummy selection source on - .set_selection(null) - -Requesting a selection with a NULL data source means "unset the clipboard", -but internally we use an unset clipboard as the indication that the -clipboard manager should take over. - -Moreover, this unset request may go unheard if the current owner is someone -else than the MetaWaylandDataDevice. - -Instead, set a dummy data source with no mimetypes nor data, this both -prevents the clipboard manager from taking over and ensures the selection -is replaced with it. - -The MetaSelectionSourceMemory was also added some checks to allow for this -dummy mode. - -Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/793 ---- - src/core/meta-selection-source-memory.c | 5 ++++- - src/wayland/meta-wayland-data-device.c | 25 +++++++++++++------------ - 2 files changed, 17 insertions(+), 13 deletions(-) - -diff --git a/src/core/meta-selection-source-memory.c b/src/core/meta-selection-source-memory.c -index 04b7f39a3..c8b0c83f5 100644 ---- a/src/core/meta-selection-source-memory.c -+++ b/src/core/meta-selection-source-memory.c -@@ -76,6 +76,9 @@ meta_selection_source_memory_get_mimetypes (MetaSelectionSource *source) - { - MetaSelectionSourceMemory *source_mem = META_SELECTION_SOURCE_MEMORY (source); - -+ if (!source_mem->mimetype) -+ return NULL; -+ - return g_list_prepend (NULL, g_strdup (source_mem->mimetype)); - } - -@@ -84,7 +87,7 @@ meta_selection_source_memory_finalize (GObject *object) - { - MetaSelectionSourceMemory *source_mem = META_SELECTION_SOURCE_MEMORY (object); - -- g_bytes_unref (source_mem->content); -+ g_clear_pointer (&source_mem->content, g_bytes_unref); - g_free (source_mem->mimetype); - - G_OBJECT_CLASS (meta_selection_source_memory_parent_class)->finalize (object); -diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c -index 0044a80b8..f95be0bf8 100644 ---- a/src/wayland/meta-wayland-data-device.c -+++ b/src/wayland/meta-wayland-data-device.c -@@ -36,6 +36,7 @@ - #include <unistd.h> - - #include "compositor/meta-dnd-actor-private.h" -+#include "meta/meta-selection-source-memory.h" - #include "wayland/meta-selection-source-wayland-private.h" - #include "wayland/meta-wayland-dnd-surface.h" - #include "wayland/meta-wayland-pointer.h" -@@ -1627,6 +1628,7 @@ meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device, - MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device); - struct wl_resource *data_device_resource; - struct wl_client *focus_client; -+ MetaSelectionSource *selection_source; - - if (data_device->selection_data_source && - data_device->selection_serial - serial < UINT32_MAX / 2) -@@ -1646,23 +1648,22 @@ meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device, - - if (source) - { -- MetaSelectionSource *selection_source; -- - meta_wayland_data_source_set_seat (source, seat); - g_object_weak_ref (G_OBJECT (source), - selection_data_source_destroyed, - data_device); - - selection_source = meta_selection_source_wayland_new (source); -- set_selection_source (data_device, META_SELECTION_CLIPBOARD, -- selection_source); -- g_object_unref (selection_source); - } - else - { -- unset_selection_source (data_device, META_SELECTION_CLIPBOARD); -+ selection_source = g_object_new (META_TYPE_SELECTION_SOURCE_MEMORY, NULL); - } - -+ set_selection_source (data_device, META_SELECTION_CLIPBOARD, -+ selection_source); -+ g_object_unref (selection_source); -+ - focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard); - if (focus_client) - { -@@ -1748,6 +1749,7 @@ meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device, - MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device); - struct wl_resource *data_device_resource; - struct wl_client *focus_client; -+ MetaSelectionSource *selection_source; - - if (META_IS_WAYLAND_DATA_SOURCE_PRIMARY (source)) - { -@@ -1777,23 +1779,22 @@ meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device, - - if (source) - { -- MetaSelectionSource *selection_source; -- - meta_wayland_data_source_set_seat (source, seat); - g_object_weak_ref (G_OBJECT (source), - primary_source_destroyed, - data_device); - - selection_source = meta_selection_source_wayland_new (source); -- set_selection_source (data_device, META_SELECTION_PRIMARY, -- selection_source); -- g_object_unref (selection_source); - } - else - { -- unset_selection_source (data_device, META_SELECTION_PRIMARY); -+ selection_source = g_object_new (META_TYPE_SELECTION_SOURCE_MEMORY, NULL); - } - -+ set_selection_source (data_device, META_SELECTION_PRIMARY, -+ selection_source); -+ g_object_unref (selection_source); -+ - focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard); - if (focus_client) - { --- -2.23.0 - - -From 55b4e24a2584c1e3c72b6b519816d8d70cac32cc Mon Sep 17 00:00:00 2001 -From: Carlos Garnacho <carlosg@gnome.org> -Date: Fri, 11 Oct 2019 19:32:42 +0200 -Subject: [PATCH 19/53] wayland: Figure out better the right selection source - for a wl_data_offer - -We were just looking at DnD actions which might still be unset at that -point. Instead of doing these heuristics, store the selection type on -the data offer. - -Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/845 ---- - src/wayland/meta-wayland-data-device.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c -index f95be0bf8..38aa0f317 100644 ---- a/src/wayland/meta-wayland-data-device.c -+++ b/src/wayland/meta-wayland-data-device.c -@@ -60,6 +60,7 @@ struct _MetaWaylandDataOffer - gboolean action_sent; - uint32_t dnd_actions; - enum wl_data_device_manager_dnd_action preferred_dnd_action; -+ MetaSelectionType selection_type; - }; - - typedef struct _MetaWaylandDataSourcePrivate -@@ -399,11 +400,7 @@ data_offer_receive (struct wl_client *client, struct wl_resource *resource, - GList *mime_types; - gboolean found; - -- if (offer->dnd_actions != 0) -- selection_type = META_SELECTION_DND; -- else -- selection_type = META_SELECTION_CLIPBOARD; -- -+ selection_type = offer->selection_type; - mime_types = meta_selection_get_mimetypes (meta_display_get_selection (display), - selection_type); - found = g_list_find_custom (mime_types, mime_type, (GCompareFunc) g_strcmp0) != NULL; -@@ -622,6 +619,7 @@ create_and_send_dnd_offer (MetaWaylandDataSource *source, - MetaWaylandDataOffer *offer = g_slice_new0 (MetaWaylandDataOffer); - char **p; - -+ offer->selection_type = META_SELECTION_DND; - offer->source = source; - g_object_add_weak_pointer (G_OBJECT (source), (gpointer *)&offer->source); - offer->resource = wl_resource_create (wl_resource_get_client (target), -@@ -2043,6 +2041,7 @@ create_and_send_clipboard_offer (MetaWaylandDataDevice *data_device, - return NULL; - - offer = g_slice_new0 (MetaWaylandDataOffer); -+ offer->selection_type = META_SELECTION_CLIPBOARD; - offer->resource = wl_resource_create (wl_resource_get_client (target), - &wl_data_offer_interface, - wl_resource_get_version (target), 0); -@@ -2075,6 +2074,7 @@ create_and_send_primary_offer (MetaWaylandDataDevice *data_device, - return NULL; - - offer = g_slice_new0 (MetaWaylandDataOffer); -+ offer->selection_type = META_SELECTION_PRIMARY; - offer->resource = wl_resource_create (wl_resource_get_client (target), - >k_primary_selection_offer_interface, - wl_resource_get_version (target), 0); --- -2.23.0 - - -From 18621e3e29cf98c4b37fcb5f770129b83b3538dc Mon Sep 17 00:00:00 2001 -From: Carlos Garnacho <carlosg@gnome.org> -Date: Sat, 12 Oct 2019 19:15:11 +0200 -Subject: [PATCH 20/53] x11: Map mimetypes back to selection atoms - -This may be seen as the missing half of -https://gitlab.gnome.org/GNOME/mutter/merge_requests/842. Now that we -translate some atoms to better known mimetypes, we should also translate -those mimetypes to the underlying atoms if we might have added them. - -Fixes c&p from certain X11 clients. - -Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/854 ---- - src/x11/meta-selection-source-x11.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/src/x11/meta-selection-source-x11.c b/src/x11/meta-selection-source-x11.c -index 1a0369ab0..55e500327 100644 ---- a/src/x11/meta-selection-source-x11.c -+++ b/src/x11/meta-selection-source-x11.c -@@ -82,6 +82,15 @@ meta_selection_source_x11_read_async (MetaSelectionSource *source, - task = g_task_new (source, cancellable, callback, user_data); - g_task_set_source_tag (task, meta_selection_source_x11_read_async); - -+ if (strcmp (mimetype, "text/plain") == 0 && -+ g_list_find_custom (source_x11->mimetypes, "STRING", -+ (GCompareFunc) g_strcmp0)) -+ mimetype = "STRING"; -+ else if (strcmp (mimetype, "text/plain;charset=utf-8") == 0 && -+ g_list_find_custom (source_x11->mimetypes, "UTF8_STRING", -+ (GCompareFunc) g_strcmp0)) -+ mimetype = "UTF8_STRING"; -+ - meta_x11_selection_input_stream_new_async (source_x11->x11_display, - source_x11->x11_display->selection.xwindow, - gdk_x11_get_xatom_name (source_x11->xselection), --- -2.23.0 - - -From 938d983fe9f28b03c1db67f2cf5e729255a340e1 Mon Sep 17 00:00:00 2001 -From: Niels De Graef <niels.degraef@barco.com> -Date: Fri, 11 Oct 2019 14:24:25 +0000 -Subject: [PATCH 21/53] dbus-session-watcher: Chain up to parent finalize() - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/847 - - -(cherry picked from commit 3a688988e0834c4605445425f3b35bb08c324691) ---- - src/backends/meta-dbus-session-watcher.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/backends/meta-dbus-session-watcher.c b/src/backends/meta-dbus-session-watcher.c -index 22718e6c2..a885b423b 100644 ---- a/src/backends/meta-dbus-session-watcher.c -+++ b/src/backends/meta-dbus-session-watcher.c -@@ -214,6 +214,8 @@ meta_dbus_session_watcher_finalize (GObject *object) - MetaDbusSessionWatcher *session_watcher = META_DBUS_SESSION_WATCHER (object); - - g_hash_table_destroy (session_watcher->clients); -+ -+ G_OBJECT_CLASS (meta_dbus_session_watcher_parent_class)->finalize (object); - } - - static void --- -2.23.0 - - -From da9a38689e2837956aec689cc0082731ba435c0f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net> -Date: Thu, 10 Oct 2019 16:11:20 +0000 -Subject: [PATCH 22/53] clutter/actor: Save key-focus state and unset it before - destruction - -When clutter actors with key focus are destroyed we emit ::key-focus-out on -them just after their destruction. This is against our assumption that no -signal should be emitted after "::destroy" (see GNOME/mutter!769 [1]), and -in fact could cause the shell to do actions that we won't ever stop on -destroy callback. - -To avoid this to happen, use a private function to set its key-state (so we -can avoid looking for the stage) and emit ::key-focus-in/out events and use -this value in both clutter_actor_has_key_focus(), -clutter_actor_grab_key_focus() and on unmap and destruction to unset the -stage key focus before we emit the ::destroy signal. - -As result of this, we can now avoid to unset the key focus on actor -destruction in the stage. - -[1] https://gitlab.gnome.org/GNOME/mutter/merge_requests/769 - -Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/1704 - - -(cherry picked from commit c2d03bf73e5a945296d22c4d95709eeebf2eb57c) ---- - clutter/clutter/clutter-actor-private.h | 3 ++ - clutter/clutter/clutter-actor.c | 57 +++++++++++++++++-------- - clutter/clutter/clutter-stage.c | 31 +++----------- - 3 files changed, 48 insertions(+), 43 deletions(-) - -diff --git a/clutter/clutter/clutter-actor-private.h b/clutter/clutter/clutter-actor-private.h -index 119ec4296..fa2d4c328 100644 ---- a/clutter/clutter/clutter-actor-private.h -+++ b/clutter/clutter/clutter-actor-private.h -@@ -274,6 +274,9 @@ void _clutter_actor_set_enable_paint_unmapped - void _clutter_actor_set_has_pointer (ClutterActor *self, - gboolean has_pointer); - -+void _clutter_actor_set_has_key_focus (ClutterActor *self, -+ gboolean has_key_focus); -+ - void _clutter_actor_queue_redraw_with_clip (ClutterActor *self, - ClutterRedrawFlags flags, - const ClutterPaintVolume *clip_volume); -diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c -index e763291a5..ecf9a597d 100644 ---- a/clutter/clutter/clutter-actor.c -+++ b/clutter/clutter/clutter-actor.c -@@ -835,6 +835,7 @@ struct _ClutterActorPrivate - guint enable_model_view_transform : 1; - guint enable_paint_unmapped : 1; - guint has_pointer : 1; -+ guint has_key_focus : 1; - guint propagated_one_redraw : 1; - guint paint_volume_valid : 1; - guint last_paint_volume_valid : 1; -@@ -1691,6 +1692,20 @@ clutter_actor_is_mapped (ClutterActor *self) - return CLUTTER_ACTOR_IS_MAPPED (self); - } - -+static void -+maybe_unset_key_focus (ClutterActor *self) -+{ -+ ClutterActor *stage; -+ -+ if (!self->priv->has_key_focus) -+ return; -+ -+ stage = _clutter_actor_get_stage_internal (self); -+ -+ if (stage) -+ clutter_stage_set_key_focus (CLUTTER_STAGE (stage), NULL); -+} -+ - static void - clutter_actor_real_unmap (ClutterActor *self) - { -@@ -1724,17 +1739,7 @@ clutter_actor_real_unmap (ClutterActor *self) - - /* relinquish keyboard focus if we were unmapped while owning it */ - if (!CLUTTER_ACTOR_IS_TOPLEVEL (self)) -- { -- ClutterStage *stage; -- -- stage = CLUTTER_STAGE (_clutter_actor_get_stage_internal (self)); -- -- if (stage != NULL && -- clutter_stage_get_key_focus (stage) == self) -- { -- clutter_stage_set_key_focus (stage, NULL); -- } -- } -+ maybe_unset_key_focus (self); - } - - /** -@@ -6064,6 +6069,8 @@ clutter_actor_dispose (GObject *object) - object->ref_count, - g_type_name (G_OBJECT_TYPE (self))); - -+ maybe_unset_key_focus (self); -+ - /* Stop the emission of any property change */ - g_object_freeze_notify (object); - -@@ -15979,6 +15986,9 @@ clutter_actor_grab_key_focus (ClutterActor *self) - - g_return_if_fail (CLUTTER_IS_ACTOR (self)); - -+ if (self->priv->has_key_focus) -+ return; -+ - stage = _clutter_actor_get_stage_internal (self); - if (stage != NULL) - clutter_stage_set_key_focus (CLUTTER_STAGE (stage), self); -@@ -16768,6 +16778,23 @@ _clutter_actor_set_has_pointer (ClutterActor *self, - } - } - -+void -+_clutter_actor_set_has_key_focus (ClutterActor *self, -+ gboolean has_key_focus) -+{ -+ ClutterActorPrivate *priv = self->priv; -+ -+ if (priv->has_key_focus != has_key_focus) -+ { -+ priv->has_key_focus = has_key_focus; -+ -+ if (has_key_focus) -+ g_signal_emit (self, actor_signals[KEY_FOCUS_IN], 0); -+ else -+ g_signal_emit (self, actor_signals[KEY_FOCUS_OUT], 0); -+ } -+} -+ - /** - * clutter_actor_get_text_direction: - * @self: a #ClutterActor -@@ -17616,15 +17643,9 @@ clutter_actor_clear_effects (ClutterActor *self) - gboolean - clutter_actor_has_key_focus (ClutterActor *self) - { -- ClutterActor *stage; -- - g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); - -- stage = _clutter_actor_get_stage_internal (self); -- if (stage == NULL) -- return FALSE; -- -- return clutter_stage_get_key_focus (CLUTTER_STAGE (stage)) == self; -+ return self->priv->has_key_focus; - } - - static gboolean -diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c -index 245cb8997..3a8a019d2 100644 ---- a/clutter/clutter/clutter-stage.c -+++ b/clutter/clutter/clutter-stage.c -@@ -1066,10 +1066,7 @@ clutter_stage_emit_key_focus_event (ClutterStage *stage, - if (priv->key_focused_actor == NULL) - return; - -- if (focus_in) -- g_signal_emit_by_name (priv->key_focused_actor, "key-focus-in"); -- else -- g_signal_emit_by_name (priv->key_focused_actor, "key-focus-out"); -+ _clutter_actor_set_has_key_focus (CLUTTER_ACTOR (stage), focus_in); - - g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_KEY_FOCUS]); - } -@@ -3011,14 +3008,6 @@ clutter_stage_get_title (ClutterStage *stage) - return stage->priv->title; - } - --static void --on_key_focus_destroy (ClutterActor *actor, -- ClutterStage *stage) --{ -- /* unset the key focus */ -- clutter_stage_set_key_focus (stage, NULL); --} -- - /** - * clutter_stage_set_key_focus: - * @stage: the #ClutterStage -@@ -3058,18 +3047,14 @@ clutter_stage_set_key_focus (ClutterStage *stage, - old_focused_actor = priv->key_focused_actor; - - /* set key_focused_actor to NULL before emitting the signal or someone -- * might hide the previously focused actor in the signal handler and we'd -- * get re-entrant call and get glib critical from g_object_weak_unref -+ * might hide the previously focused actor in the signal handler - */ -- g_signal_handlers_disconnect_by_func (priv->key_focused_actor, -- G_CALLBACK (on_key_focus_destroy), -- stage); - priv->key_focused_actor = NULL; - -- g_signal_emit_by_name (old_focused_actor, "key-focus-out"); -+ _clutter_actor_set_has_key_focus (old_focused_actor, FALSE); - } - else -- g_signal_emit_by_name (stage, "key-focus-out"); -+ _clutter_actor_set_has_key_focus (CLUTTER_ACTOR (stage), FALSE); - - /* Note, if someone changes key focus in focus-out signal handler we'd be - * overriding the latter call below moving the focus where it was originally -@@ -3079,14 +3064,10 @@ clutter_stage_set_key_focus (ClutterStage *stage, - if (actor != NULL) - { - priv->key_focused_actor = actor; -- -- g_signal_connect (actor, -- "destroy", G_CALLBACK (on_key_focus_destroy), -- stage); -- g_signal_emit_by_name (priv->key_focused_actor, "key-focus-in"); -+ _clutter_actor_set_has_key_focus (actor, FALSE); - } - else -- g_signal_emit_by_name (stage, "key-focus-in"); -+ _clutter_actor_set_has_key_focus (CLUTTER_ACTOR (stage), TRUE); - - g_object_notify_by_pspec (G_OBJECT (stage), obj_props[PROP_KEY_FOCUS]); - } --- -2.23.0 - - -From 46935960b14c57ae535cbace33f3ac91d7ccd7aa Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net> -Date: Tue, 15 Oct 2019 14:38:14 +0000 -Subject: [PATCH 23/53] clutter/stage: Actually set key focus to an actor on - key focus - -As per commit c2d03bf73 we're using a private method to set the actors key -focus and emit key-focus-in signal, but we're using inverted logic here. - -So flip the parameter to match the expected result. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/860 - - -(cherry picked from commit 553211dd81a849f33f0aca447c8683f031fff868) ---- - clutter/clutter/clutter-stage.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c -index 3a8a019d2..c4b88b32e 100644 ---- a/clutter/clutter/clutter-stage.c -+++ b/clutter/clutter/clutter-stage.c -@@ -3064,7 +3064,7 @@ clutter_stage_set_key_focus (ClutterStage *stage, - if (actor != NULL) - { - priv->key_focused_actor = actor; -- _clutter_actor_set_has_key_focus (actor, FALSE); -+ _clutter_actor_set_has_key_focus (actor, TRUE); - } - else - _clutter_actor_set_has_key_focus (CLUTTER_ACTOR (stage), TRUE); --- -2.23.0 - - -From cf821044d1b6fa203e620589cc0ef52aa8c6da56 Mon Sep 17 00:00:00 2001 -From: Cosimo Cecchi <cosimoc@gnome.org> -Date: Thu, 4 Jul 2019 19:52:30 +0000 -Subject: [PATCH 24/53] monitor-manager: check for underscan setting validity - upfront - -Instead of doing a roundtrip to the X server before setting it, rely on -the previous value fetched before the configuration was sent over DBus. -This matches the argument check we already do elsewhere, and will allow -us to more easily add an additional condition to determine if underscan -is supported. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/673 - - -(cherry picked from commit 8665084df15190adc0d18cc77b7fcb738d3e4fa6) ---- - src/backends/meta-monitor-manager.c | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - -diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c -index 41036ca2a..0210aee33 100644 ---- a/src/backends/meta-monitor-manager.c -+++ b/src/backends/meta-monitor-manager.c -@@ -1648,6 +1648,7 @@ create_monitor_config_from_variant (MetaMonitorManager *manager, - MetaMonitorModeSpec *monitor_mode_spec; - g_autoptr (GVariant) properties_variant = NULL; - gboolean enable_underscanning = FALSE; -+ gboolean set_underscanning = FALSE; - - g_variant_get (monitor_config_variant, "(ss@a{sv})", - &connector, -@@ -1670,7 +1671,18 @@ create_monitor_config_from_variant (MetaMonitorManager *manager, - return NULL; - } - -- g_variant_lookup (properties_variant, "underscanning", "b", &enable_underscanning); -+ set_underscanning = -+ g_variant_lookup (properties_variant, "underscanning", "b", -+ &enable_underscanning); -+ if (set_underscanning) -+ { -+ if (enable_underscanning && !meta_monitor_supports_underscanning (monitor)) -+ { -+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, -+ "Underscanning requested but unsupported"); -+ return NULL; -+ } -+ } - - monitor_spec = meta_monitor_spec_clone (meta_monitor_get_spec (monitor)); - --- -2.23.0 - - -From df336f2f6f2cc85e7718679e2c5474b8da153284 Mon Sep 17 00:00:00 2001 -From: Robert Mader <robert.mader@posteo.de> -Date: Mon, 14 Oct 2019 17:45:14 +0200 -Subject: [PATCH 25/53] window-actor: Add a missing NULL-check - -We shouldn't crash on a NULL-clip. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/856 ---- - src/compositor/meta-window-actor.c | 26 +++++++++++++++----------- - 1 file changed, 15 insertions(+), 11 deletions(-) - -diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c -index db9ccec62..fd99844e8 100644 ---- a/src/compositor/meta-window-actor.c -+++ b/src/compositor/meta-window-actor.c -@@ -2183,21 +2183,25 @@ meta_window_actor_get_image (MetaWindowActor *self, - if (clutter_actor_get_n_children (actor) == 1) - { - MetaShapedTexture *stex; -- MetaRectangle surface_clip; -- int geometry_scale; -+ MetaRectangle *surface_clip = NULL; - -- geometry_scale = -- meta_window_actor_get_geometry_scale (self); -+ if (clip) -+ { - -- surface_clip = (MetaRectangle) { -- .x = clip->x / geometry_scale, -- .y = clip->y / geometry_scale, -- .width = clip->width / geometry_scale, -- .height = clip->height / geometry_scale, -- }; -+ int geometry_scale; -+ -+ geometry_scale = -+ meta_window_actor_get_geometry_scale (self); -+ -+ surface_clip = g_alloca (sizeof (MetaRectangle)); -+ surface_clip->x = clip->x / geometry_scale, -+ surface_clip->y = clip->y / geometry_scale; -+ surface_clip->width = clip->width / geometry_scale; -+ surface_clip->height = clip->height / geometry_scale; -+ } - - stex = meta_surface_actor_get_texture (priv->surface); -- return meta_shaped_texture_get_image (stex, &surface_clip); -+ return meta_shaped_texture_get_image (stex, surface_clip); - } - - clutter_actor_get_size (actor, &width, &height); --- -2.23.0 - - -From 5b71851b3fee13a405a6f8350e8362457315749c Mon Sep 17 00:00:00 2001 -From: Robert Mader <robert.mader@posteo.de> -Date: Sun, 20 Oct 2019 19:32:29 +0000 -Subject: [PATCH 26/53] wayland/surface: Reset buffer_destroy_handler_id - -Syncronized subsurfaces that call into `merge_pending_state` might -otherwise not create new destroy handlers, ending up with a invalid -handler ids, throwing errors and leaking. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/868 - - -(cherry picked from commit 98892391d764d1cf4b32e57367e45f39b10880e4) ---- - src/wayland/meta-wayland-surface.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c -index 647f05338..163b7c515 100644 ---- a/src/wayland/meta-wayland-surface.c -+++ b/src/wayland/meta-wayland-surface.c -@@ -401,7 +401,7 @@ static void - pending_buffer_resource_destroyed (MetaWaylandBuffer *buffer, - MetaWaylandPendingState *pending) - { -- g_signal_handler_disconnect (buffer, pending->buffer_destroy_handler_id); -+ g_clear_signal_handler (&pending->buffer_destroy_handler_id, buffer); - pending->buffer = NULL; - } - --- -2.23.0 - - -From 6955b9ffeaa7fdd352e67d24b24dfb149ffcefca Mon Sep 17 00:00:00 2001 -From: Carlos Garnacho <carlosg@gnome.org> -Date: Tue, 22 Oct 2019 12:17:40 +0000 -Subject: [PATCH 27/53] x11: Update X11 focus before updating MetaDisplay focus - -In a similar vein to commit 8fd55fef853. This notably failed when setting -the focus on the stage (eg. to redirect key events to Clutter actors). -Deeper in MetaDisplay focus updating machinery, it would check -meta_stage_is_focused() which would still return FALSE at the time it's -called. - -This would not typically have side effects, but our "App does not respond" -dialogs see the focus change under their feet, so they try to bring -themselves to focus again. This results in a feedback loop. - -Changing the order results in later checks on the X11 POV of the focus -being correct, so focus is not mistakenly stolen from the close dialog, -and it actually succeeds in keeping the key focus. - -Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/1607 - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/876 - - -(cherry picked from commit 71c3f4af3196b77fb52f395238f0704e7fa4d273) ---- - src/x11/meta-x11-display.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c -index 3ae5b3d8d..1aebaa961 100644 ---- a/src/x11/meta-x11-display.c -+++ b/src/x11/meta-x11-display.c -@@ -1928,10 +1928,10 @@ meta_x11_display_set_input_focus_xwindow (MetaX11Display *x11_display, - { - gulong serial; - -- meta_display_unset_input_focus (x11_display->display, timestamp); - serial = XNextRequest (x11_display->xdisplay); - meta_x11_display_set_input_focus_internal (x11_display, window, timestamp); - meta_x11_display_update_focus_window (x11_display, window, serial, TRUE); -+ meta_display_unset_input_focus (x11_display->display, timestamp); - } - - static MetaX11DisplayLogicalMonitorData * --- -2.23.0 - - -From 3922409a6d45cb78e04331a02289c0dc6f9f230a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com> -Date: Thu, 24 Oct 2019 21:19:36 +0200 -Subject: [PATCH 28/53] display: Move finishing of touch sequence to the - backend - -We need to manipulate an X11 grab when a touch sequence ends; move that -logic to where it belongs - in the X11 backend. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/886 ---- - src/backends/meta-backend-private.h | 16 ++++++++++++ - src/backends/meta-backend.c | 14 +++++++++++ - src/backends/x11/meta-backend-x11.c | 23 +++++++++++++++++ - src/core/display.c | 33 +++++++++++-------------- - src/core/meta-gesture-tracker-private.h | 9 +------ - 5 files changed, 69 insertions(+), 26 deletions(-) - -diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h -index 397c5f382..213cad5c1 100644 ---- a/src/backends/meta-backend-private.h -+++ b/src/backends/meta-backend-private.h -@@ -49,6 +49,14 @@ - #define DEFAULT_XKB_RULES_FILE "evdev" - #define DEFAULT_XKB_MODEL "pc105+inet" - -+typedef enum -+{ -+ META_SEQUENCE_NONE, -+ META_SEQUENCE_ACCEPTED, -+ META_SEQUENCE_REJECTED, -+ META_SEQUENCE_PENDING_END -+} MetaSequenceState; -+ - struct _MetaBackendClass - { - GObjectClass parent_class; -@@ -71,6 +79,10 @@ struct _MetaBackendClass - int device_id, - uint32_t timestamp); - -+ void (* finish_touch_sequence) (MetaBackend *backend, -+ ClutterEventSequence *sequence, -+ MetaSequenceState state); -+ - void (* warp_pointer) (MetaBackend *backend, - int x, - int y); -@@ -135,6 +147,10 @@ gboolean meta_backend_ungrab_device (MetaBackend *backend, - int device_id, - uint32_t timestamp); - -+void meta_backend_finish_touch_sequence (MetaBackend *backend, -+ ClutterEventSequence *sequence, -+ MetaSequenceState state); -+ - void meta_backend_warp_pointer (MetaBackend *backend, - int x, - int y); -diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c -index 7b05d72eb..9c206f4c1 100644 ---- a/src/backends/meta-backend.c -+++ b/src/backends/meta-backend.c -@@ -1059,6 +1059,20 @@ meta_backend_ungrab_device (MetaBackend *backend, - return META_BACKEND_GET_CLASS (backend)->ungrab_device (backend, device_id, timestamp); - } - -+/** -+ * meta_backend_finish_touch_sequence: (skip) -+ */ -+void -+meta_backend_finish_touch_sequence (MetaBackend *backend, -+ ClutterEventSequence *sequence, -+ MetaSequenceState state) -+{ -+ if (META_BACKEND_GET_CLASS (backend)->finish_touch_sequence) -+ META_BACKEND_GET_CLASS (backend)->finish_touch_sequence (backend, -+ sequence, -+ state); -+} -+ - /** - * meta_backend_warp_pointer: (skip) - */ -diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c -index a0fd2f5e0..fd58a388b 100644 ---- a/src/backends/x11/meta-backend-x11.c -+++ b/src/backends/x11/meta-backend-x11.c -@@ -590,6 +590,28 @@ meta_backend_x11_ungrab_device (MetaBackend *backend, - return (ret == Success); - } - -+static void -+meta_backend_x11_finish_touch_sequence (MetaBackend *backend, -+ ClutterEventSequence *sequence, -+ MetaSequenceState state) -+{ -+ MetaBackendX11 *x11 = META_BACKEND_X11 (backend); -+ MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); -+ int event_mode; -+ -+ if (state == META_SEQUENCE_ACCEPTED) -+ event_mode = XIAcceptTouch; -+ else if (state == META_SEQUENCE_REJECTED) -+ event_mode = XIRejectTouch; -+ else -+ g_return_if_reached (); -+ -+ XIAllowTouchEvents (priv->xdisplay, -+ META_VIRTUAL_CORE_POINTER_ID, -+ meta_x11_event_sequence_get_touch_detail (sequence), -+ DefaultRootWindow (priv->xdisplay), event_mode); -+} -+ - static void - meta_backend_x11_warp_pointer (MetaBackend *backend, - int x, -@@ -781,6 +803,7 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass) - backend_class->post_init = meta_backend_x11_post_init; - backend_class->grab_device = meta_backend_x11_grab_device; - backend_class->ungrab_device = meta_backend_x11_ungrab_device; -+ backend_class->finish_touch_sequence = meta_backend_x11_finish_touch_sequence; - backend_class->warp_pointer = meta_backend_x11_warp_pointer; - backend_class->get_current_logical_monitor = meta_backend_x11_get_current_logical_monitor; - backend_class->get_keymap = meta_backend_x11_get_keymap; -diff --git a/src/core/display.c b/src/core/display.c -index 82c9cd108..05c2a64b8 100644 ---- a/src/core/display.c -+++ b/src/core/display.c -@@ -40,6 +40,7 @@ - #include <X11/extensions/Xdamage.h> - #include <X11/extensions/Xfixes.h> - -+#include "backends/meta-backend-private.h" - #include "backends/meta-cursor-sprite-xcursor.h" - #include "backends/meta-cursor-tracker-private.h" - #include "backends/meta-idle-monitor-dbus.h" -@@ -622,27 +623,23 @@ gesture_tracker_state_changed (MetaGestureTracker *tracker, - MetaSequenceState state, - MetaDisplay *display) - { -- if (meta_is_wayland_compositor ()) -+ switch (state) - { -- if (state == META_SEQUENCE_ACCEPTED) -- meta_display_cancel_touch (display); -- } -- else -- { -- MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ()); -- int event_mode; -+ case META_SEQUENCE_NONE: -+ case META_SEQUENCE_PENDING_END: -+ return; -+ case META_SEQUENCE_ACCEPTED: -+ meta_display_cancel_touch (display); - -- if (state == META_SEQUENCE_ACCEPTED) -- event_mode = XIAcceptTouch; -- else if (state == META_SEQUENCE_REJECTED) -- event_mode = XIRejectTouch; -- else -- return; -+ /* Intentional fall-through */ -+ case META_SEQUENCE_REJECTED: -+ { -+ MetaBackend *backend; - -- XIAllowTouchEvents (meta_backend_x11_get_xdisplay (backend), -- META_VIRTUAL_CORE_POINTER_ID, -- meta_x11_event_sequence_get_touch_detail (sequence), -- DefaultRootWindow (display->x11_display->xdisplay), event_mode); -+ backend = meta_get_backend (); -+ meta_backend_finish_touch_sequence (backend, sequence, state); -+ break; -+ } - } - } - -diff --git a/src/core/meta-gesture-tracker-private.h b/src/core/meta-gesture-tracker-private.h -index a9db35ebc..e7bfc5472 100644 ---- a/src/core/meta-gesture-tracker-private.h -+++ b/src/core/meta-gesture-tracker-private.h -@@ -26,6 +26,7 @@ - - #include <glib-object.h> - -+#include "backends/meta-backend-private.h" - #include "clutter/clutter.h" - #include "meta/window.h" - -@@ -39,14 +40,6 @@ - typedef struct _MetaGestureTracker MetaGestureTracker; - typedef struct _MetaGestureTrackerClass MetaGestureTrackerClass; - --typedef enum --{ -- META_SEQUENCE_NONE, -- META_SEQUENCE_ACCEPTED, -- META_SEQUENCE_REJECTED, -- META_SEQUENCE_PENDING_END --} MetaSequenceState; -- - struct _MetaGestureTracker - { - GObject parent_instance; --- -2.23.0 - - -From a7ee1635b234fedf2ea56be04a02d70c9aadab75 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com> -Date: Fri, 25 Oct 2019 10:06:55 +0200 -Subject: [PATCH 29/53] x11: Limit touch replay pointer events to when - replaying - -When a touch sequence was rejected, the emulated pointer events would be -replayed with old timestamps. This caused issues with grabs as they -would be ignored due to being too old. This was mitigated by making sure -device event timestamps never travelled back in time by tampering with -any event that had a timestamp seemingly in the past. - -This failed when the most recent timestamp that had been received were -much older than the timestamp of the new event. This could for example -happen when a session was left not interacted with for 40+ days or so; -when interacted with again, as any new timestamp would according to -XSERVER_TIME_IS_BEFORE() still be in the past compared to the "most -recent" one. The effect is that we'd always use the `latest_evtime` for -all new device events without ever updating it. - -The end result of this was that passive grabs would become active when -interacted with, but would then newer be released, as the timestamps to -XIAllowEvents() would out of date, resulting in the desktop effectively -freezing, as the Shell would have an active pointer grab. - -To avoid the situation where we get stuck with an old `latest_evtime` -timestamp, limit the tampering with device event timestamp to 1) only -pointer events, and 2) only during the replay sequence. The second part -is implemented by sending an asynchronous message via the X server after -rejecting a touch sequence, only potentially tampering with the device -event timestamps until the reply. This should avoid the stuck timestamp -as in those situations, we'll always have a relatively up to date -`latest_evtime` meaning XSERVER_TIME_IS_BEFORE() will not get confused. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/886 ---- - src/backends/x11/meta-backend-x11.c | 71 +++++++++++++++++++++++------ - 1 file changed, 58 insertions(+), 13 deletions(-) - -diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c -index fd58a388b..225d14d33 100644 ---- a/src/backends/x11/meta-backend-x11.c -+++ b/src/backends/x11/meta-backend-x11.c -@@ -67,6 +67,10 @@ struct _MetaBackendX11Private - XSyncAlarm user_active_alarm; - XSyncCounter counter; - -+ int current_touch_replay_sync_serial; -+ int pending_touch_replay_sync_serial; -+ Atom touch_replay_sync_atom; -+ - int xinput_opcode; - int xinput_event_base; - int xinput_error_base; -@@ -175,6 +179,26 @@ meta_backend_x11_translate_device_event (MetaBackendX11 *x11, - backend_x11_class->translate_device_event (x11, device_event); - } - -+static void -+maybe_translate_touch_replay_pointer_event (MetaBackendX11 *x11, -+ XIDeviceEvent *device_event) -+{ -+ MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); -+ -+ if (!device_event->send_event && -+ device_event->time != META_CURRENT_TIME && -+ priv->current_touch_replay_sync_serial != -+ priv->pending_touch_replay_sync_serial && -+ XSERVER_TIME_IS_BEFORE (device_event->time, priv->latest_evtime)) -+ { -+ /* Emulated pointer events received after XIRejectTouch is received -+ * on a passive touch grab will contain older timestamps, update those -+ * so we dont get InvalidTime at grabs. -+ */ -+ device_event->time = priv->latest_evtime; -+ } -+} -+ - static void - translate_device_event (MetaBackendX11 *x11, - XIDeviceEvent *device_event) -@@ -184,19 +208,7 @@ translate_device_event (MetaBackendX11 *x11, - meta_backend_x11_translate_device_event (x11, device_event); - - if (!device_event->send_event && device_event->time != META_CURRENT_TIME) -- { -- if (XSERVER_TIME_IS_BEFORE (device_event->time, priv->latest_evtime)) -- { -- /* Emulated pointer events received after XIRejectTouch is received -- * on a passive touch grab will contain older timestamps, update those -- * so we dont get InvalidTime at grabs. -- */ -- device_event->time = priv->latest_evtime; -- } -- -- /* Update the internal latest evtime, for any possible later use */ -- priv->latest_evtime = device_event->time; -- } -+ priv->latest_evtime = device_event->time; - } - - static void -@@ -261,6 +273,9 @@ maybe_spoof_event_as_stage_event (MetaBackendX11 *x11, - case XI_Motion: - case XI_ButtonPress: - case XI_ButtonRelease: -+ maybe_translate_touch_replay_pointer_event (x11, -+ (XIDeviceEvent *) input_event); -+ /* Intentional fall-through */ - case XI_KeyPress: - case XI_KeyRelease: - case XI_TouchBegin: -@@ -329,6 +344,17 @@ handle_host_xevent (MetaBackend *backend, - gboolean bypass_clutter = FALSE; - MetaDisplay *display; - -+ switch (event->type) -+ { -+ case ClientMessage: -+ if (event->xclient.window == meta_backend_x11_get_xwindow (x11) && -+ event->xclient.message_type == priv->touch_replay_sync_atom) -+ priv->current_touch_replay_sync_serial = event->xclient.data.l[0]; -+ break; -+ default: -+ break; -+ } -+ - XGetEventData (priv->xdisplay, &event->xcookie); - - display = meta_get_display (); -@@ -533,6 +559,10 @@ meta_backend_x11_post_init (MetaBackend *backend) - monitor_manager = meta_backend_get_monitor_manager (backend); - g_signal_connect (monitor_manager, "monitors-changed-internal", - G_CALLBACK (on_monitors_changed), backend); -+ -+ priv->touch_replay_sync_atom = XInternAtom (priv->xdisplay, -+ "_MUTTER_TOUCH_SEQUENCE_SYNC", -+ False); - } - - static ClutterBackend * -@@ -610,6 +640,21 @@ meta_backend_x11_finish_touch_sequence (MetaBackend *backend, - META_VIRTUAL_CORE_POINTER_ID, - meta_x11_event_sequence_get_touch_detail (sequence), - DefaultRootWindow (priv->xdisplay), event_mode); -+ -+ if (state == META_SEQUENCE_REJECTED) -+ { -+ XClientMessageEvent ev; -+ -+ ev = (XClientMessageEvent) { -+ .type = ClientMessage, -+ .window = meta_backend_x11_get_xwindow (x11), -+ .message_type = priv->touch_replay_sync_atom, -+ .format = 32, -+ .data.l[0] = ++priv->pending_touch_replay_sync_serial, -+ }; -+ XSendEvent (priv->xdisplay, meta_backend_x11_get_xwindow (x11), -+ False, 0, (XEvent *) &ev); -+ } - } - - static void --- -2.23.0 - - -From e3c8f81b5e268678ea72ff5468333a8290516172 Mon Sep 17 00:00:00 2001 -From: Carlos Garnacho <carlosg@gnome.org> -Date: Mon, 28 Oct 2019 18:07:31 +0100 -Subject: [PATCH 30/53] wayland: Check stylus serials on - meta_wayland_seat_can_popup() - -This allows xdg_popup.grab() to work with styli. Without this check -we would bail out and emit xdg_popup.popup_done, leaving stylus users -unable to interact with popup menus, comboboxes, etc... - -Closes: https://gitlab.gnome.org/GNOME/mutter/issues/886 ---- - src/wayland/meta-wayland-seat.c | 10 +++++++++- - src/wayland/meta-wayland-tablet-seat.c | 17 +++++++++++++++++ - src/wayland/meta-wayland-tablet-seat.h | 2 ++ - src/wayland/meta-wayland-tablet-tool.c | 7 +++++++ - src/wayland/meta-wayland-tablet-tool.h | 2 ++ - 5 files changed, 37 insertions(+), 1 deletion(-) - -diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c -index 91fe376ff..cf41d6eb8 100644 ---- a/src/wayland/meta-wayland-seat.c -+++ b/src/wayland/meta-wayland-seat.c -@@ -504,9 +504,17 @@ gboolean - meta_wayland_seat_can_popup (MetaWaylandSeat *seat, - uint32_t serial) - { -+ MetaWaylandCompositor *compositor; -+ MetaWaylandTabletSeat *tablet_seat; -+ -+ compositor = meta_wayland_compositor_get_default (); -+ tablet_seat = -+ meta_wayland_tablet_manager_ensure_seat (compositor->tablet_manager, seat); -+ - return (meta_wayland_pointer_can_popup (seat->pointer, serial) || - meta_wayland_keyboard_can_popup (seat->keyboard, serial) || -- meta_wayland_touch_can_popup (seat->touch, serial)); -+ meta_wayland_touch_can_popup (seat->touch, serial) || -+ meta_wayland_tablet_seat_can_popup (tablet_seat, serial)); - } - - gboolean -diff --git a/src/wayland/meta-wayland-tablet-seat.c b/src/wayland/meta-wayland-tablet-seat.c -index b4bc4aa58..b1964714a 100644 ---- a/src/wayland/meta-wayland-tablet-seat.c -+++ b/src/wayland/meta-wayland-tablet-seat.c -@@ -552,3 +552,20 @@ meta_wayland_tablet_seat_set_pad_focus (MetaWaylandTabletSeat *tablet_seat, - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &pad)) - meta_wayland_tablet_pad_set_focus (pad, surface); - } -+ -+gboolean -+meta_wayland_tablet_seat_can_popup (MetaWaylandTabletSeat *tablet_seat, -+ uint32_t serial) -+{ -+ MetaWaylandTabletTool *tool; -+ GHashTableIter iter; -+ -+ g_hash_table_iter_init (&iter, tablet_seat->tools); -+ while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &tool)) -+ { -+ if (meta_wayland_tablet_tool_can_popup (tool, serial)) -+ return TRUE; -+ } -+ -+ return FALSE; -+} -diff --git a/src/wayland/meta-wayland-tablet-seat.h b/src/wayland/meta-wayland-tablet-seat.h -index c083dec5f..e3be5f264 100644 ---- a/src/wayland/meta-wayland-tablet-seat.h -+++ b/src/wayland/meta-wayland-tablet-seat.h -@@ -75,5 +75,7 @@ MetaWaylandTablet *meta_wayland_tablet_seat_lookup_paired_tablet (MetaWaylan - MetaWaylandTabletPad *pad); - GList *meta_wayland_tablet_seat_lookup_paired_pads (MetaWaylandTabletSeat *tablet_seat, - MetaWaylandTablet *tablet); -+gboolean meta_wayland_tablet_seat_can_popup (MetaWaylandTabletSeat *tablet_seat, -+ uint32_t serial); - - #endif /* META_WAYLAND_TABLET_SEAT_H */ -diff --git a/src/wayland/meta-wayland-tablet-tool.c b/src/wayland/meta-wayland-tablet-tool.c -index c02831d73..065c834bb 100644 ---- a/src/wayland/meta-wayland-tablet-tool.c -+++ b/src/wayland/meta-wayland-tablet-tool.c -@@ -1018,3 +1018,10 @@ meta_wayland_tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool, - return ((tool->down_serial == serial || tool->button_serial == serial) && - tablet_tool_can_grab_surface (tool, surface)); - } -+ -+gboolean -+meta_wayland_tablet_tool_can_popup (MetaWaylandTabletTool *tool, -+ uint32_t serial) -+{ -+ return tool->down_serial == serial || tool->button_serial == serial; -+} -diff --git a/src/wayland/meta-wayland-tablet-tool.h b/src/wayland/meta-wayland-tablet-tool.h -index 71bc86643..315e26bde 100644 ---- a/src/wayland/meta-wayland-tablet-tool.h -+++ b/src/wayland/meta-wayland-tablet-tool.h -@@ -85,5 +85,7 @@ void meta_wayland_tablet_tool_set_cursor_position (MetaWaylandTabletTool *t - gboolean meta_wayland_tablet_tool_can_grab_surface (MetaWaylandTabletTool *tool, - MetaWaylandSurface *surface, - uint32_t serial); -+gboolean meta_wayland_tablet_tool_can_popup (MetaWaylandTabletTool *tool, -+ uint32_t serial); - - #endif /* META_WAYLAND_TABLET_TOOL_H */ --- -2.23.0 - - -From f133364b960b6715b67e53808ac2e47f49897a18 Mon Sep 17 00:00:00 2001 -From: Olivier Fourdan <ofourdan@redhat.com> -Date: Tue, 22 Oct 2019 17:03:03 +0200 -Subject: [PATCH 31/53] clutter/stage-view: Separate offscreen and shadowfb - -Previously, we would use a single offscreen framebuffer for both -transformations and when a shadow framebuffer should be used, but that -can be dreadfully slow when using software rendering with a discrete GPU -due to bandwidth limitations. - -Keep the offscreen framebuffer for transformations only and add another -intermediate shadow framebuffer used as a copy of the onscreen -framebuffer. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/917 - -(cherry picked from commit 2b8b450fe16c21f0f37a1779560c0e5da61a9b89) ---- - clutter/clutter/clutter-stage-view.c | 162 +++++++++++++++++----- - clutter/clutter/cogl/clutter-stage-cogl.c | 6 +- - 2 files changed, 128 insertions(+), 40 deletions(-) - -diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c -index b76bf677b..0fad6fc44 100644 ---- a/clutter/clutter/clutter-stage-view.c -+++ b/clutter/clutter/clutter-stage-view.c -@@ -30,6 +30,7 @@ enum - PROP_LAYOUT, - PROP_FRAMEBUFFER, - PROP_OFFSCREEN, -+ PROP_SHADOWFB, - PROP_SCALE, - - PROP_LAST -@@ -44,7 +45,10 @@ typedef struct _ClutterStageViewPrivate - CoglFramebuffer *framebuffer; - - CoglOffscreen *offscreen; -- CoglPipeline *pipeline; -+ CoglPipeline *offscreen_pipeline; -+ -+ CoglOffscreen *shadowfb; -+ CoglPipeline *shadowfb_pipeline; - - guint dirty_viewport : 1; - guint dirty_projection : 1; -@@ -78,6 +82,8 @@ clutter_stage_view_get_framebuffer (ClutterStageView *view) - - if (priv->offscreen) - return priv->offscreen; -+ else if (priv->shadowfb) -+ return priv->shadowfb; - else - return priv->framebuffer; - } -@@ -99,6 +105,24 @@ clutter_stage_view_get_onscreen (ClutterStageView *view) - return priv->framebuffer; - } - -+static CoglPipeline * -+clutter_stage_view_create_framebuffer_pipeline (CoglFramebuffer *framebuffer) -+{ -+ CoglPipeline *pipeline; -+ -+ pipeline = cogl_pipeline_new (cogl_framebuffer_get_context (framebuffer)); -+ -+ cogl_pipeline_set_layer_filters (pipeline, 0, -+ COGL_PIPELINE_FILTER_NEAREST, -+ COGL_PIPELINE_FILTER_NEAREST); -+ cogl_pipeline_set_layer_texture (pipeline, 0, -+ cogl_offscreen_get_texture (framebuffer)); -+ cogl_pipeline_set_layer_wrap_mode (pipeline, 0, -+ COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); -+ -+ return pipeline; -+} -+ - static void - clutter_stage_view_ensure_offscreen_blit_pipeline (ClutterStageView *view) - { -@@ -109,71 +133,122 @@ clutter_stage_view_ensure_offscreen_blit_pipeline (ClutterStageView *view) - - g_assert (priv->offscreen != NULL); - -- if (priv->pipeline) -+ if (priv->offscreen_pipeline) - return; - -- priv->pipeline = -- cogl_pipeline_new (cogl_framebuffer_get_context (priv->offscreen)); -- cogl_pipeline_set_layer_filters (priv->pipeline, 0, -- COGL_PIPELINE_FILTER_NEAREST, -- COGL_PIPELINE_FILTER_NEAREST); -- cogl_pipeline_set_layer_texture (priv->pipeline, 0, -- cogl_offscreen_get_texture (priv->offscreen)); -- cogl_pipeline_set_layer_wrap_mode (priv->pipeline, 0, -- COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); -+ priv->offscreen_pipeline = -+ clutter_stage_view_create_framebuffer_pipeline (priv->offscreen); - - if (view_class->setup_offscreen_blit_pipeline) -- view_class->setup_offscreen_blit_pipeline (view, priv->pipeline); -+ view_class->setup_offscreen_blit_pipeline (view, priv->offscreen_pipeline); - } - --void --clutter_stage_view_invalidate_offscreen_blit_pipeline (ClutterStageView *view) -+static void -+clutter_stage_view_ensure_shadowfb_blit_pipeline (ClutterStageView *view) - { - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); - -- g_clear_pointer (&priv->pipeline, cogl_object_unref); -+ if (priv->shadowfb_pipeline) -+ return; -+ -+ priv->shadowfb_pipeline = -+ clutter_stage_view_create_framebuffer_pipeline (priv->shadowfb); - } - - void --clutter_stage_view_blit_offscreen (ClutterStageView *view, -- const cairo_rectangle_int_t *rect) -+clutter_stage_view_invalidate_offscreen_blit_pipeline (ClutterStageView *view) - { - ClutterStageViewPrivate *priv = - clutter_stage_view_get_instance_private (view); -+ -+ g_clear_pointer (&priv->offscreen_pipeline, cogl_object_unref); -+} -+ -+static void -+clutter_stage_view_copy_to_framebuffer (ClutterStageView *view, -+ const cairo_rectangle_int_t *rect, -+ CoglPipeline *pipeline, -+ CoglFramebuffer *src_framebuffer, -+ CoglFramebuffer *dst_framebuffer, -+ gboolean can_blit) -+{ - CoglMatrix matrix; - -- clutter_stage_view_get_offscreen_transformation_matrix (view, &matrix); -- if (cogl_matrix_is_identity (&matrix)) -+ /* First, try with blit */ -+ if (can_blit) - { -- int fb_width = cogl_framebuffer_get_width (priv->framebuffer); -- int fb_height = cogl_framebuffer_get_height (priv->framebuffer); -- -- if (cogl_blit_framebuffer (priv->offscreen, -- priv->framebuffer, -+ if (cogl_blit_framebuffer (src_framebuffer, -+ dst_framebuffer, - 0, 0, - 0, 0, -- fb_width, fb_height, -+ cogl_framebuffer_get_width (dst_framebuffer), -+ cogl_framebuffer_get_height (dst_framebuffer), - NULL)) - return; - } - -- clutter_stage_view_ensure_offscreen_blit_pipeline (view); -- cogl_framebuffer_push_matrix (priv->framebuffer); -+ /* If blit fails, fallback to the slower painting method */ -+ cogl_framebuffer_push_matrix (dst_framebuffer); - -- /* Set transform so 0,0 is on the top left corner and 1,1 on -- * the bottom right corner. -- */ - cogl_matrix_init_identity (&matrix); - cogl_matrix_translate (&matrix, -1, 1, 0); - cogl_matrix_scale (&matrix, 2, -2, 0); -- cogl_framebuffer_set_projection_matrix (priv->framebuffer, &matrix); -+ cogl_framebuffer_set_projection_matrix (dst_framebuffer, &matrix); - -- cogl_framebuffer_draw_rectangle (priv->framebuffer, -- priv->pipeline, -+ cogl_framebuffer_draw_rectangle (dst_framebuffer, -+ pipeline, - 0, 0, 1, 1); - -- cogl_framebuffer_pop_matrix (priv->framebuffer); -+ cogl_framebuffer_pop_matrix (dst_framebuffer); -+} -+ -+void -+clutter_stage_view_blit_offscreen (ClutterStageView *view, -+ const cairo_rectangle_int_t *rect) -+{ -+ ClutterStageViewPrivate *priv = -+ clutter_stage_view_get_instance_private (view); -+ -+ if (priv->offscreen) -+ { -+ gboolean can_blit; -+ CoglMatrix matrix; -+ -+ clutter_stage_view_ensure_offscreen_blit_pipeline (view); -+ clutter_stage_view_get_offscreen_transformation_matrix (view, &matrix); -+ can_blit = cogl_matrix_is_identity (&matrix); -+ -+ if (priv->shadowfb) -+ { -+ clutter_stage_view_copy_to_framebuffer (view, -+ rect, -+ priv->offscreen_pipeline, -+ priv->offscreen, -+ priv->shadowfb, -+ can_blit); -+ } -+ else -+ { -+ clutter_stage_view_copy_to_framebuffer (view, -+ rect, -+ priv->offscreen_pipeline, -+ priv->offscreen, -+ priv->framebuffer, -+ can_blit); -+ } -+ } -+ -+ if (priv->shadowfb) -+ { -+ clutter_stage_view_ensure_shadowfb_blit_pipeline (view); -+ clutter_stage_view_copy_to_framebuffer (view, -+ rect, -+ priv->shadowfb_pipeline, -+ priv->shadowfb, -+ priv->framebuffer, -+ TRUE); -+ } - } - - float -@@ -273,6 +348,9 @@ clutter_stage_view_get_property (GObject *object, - case PROP_OFFSCREEN: - g_value_set_boxed (value, priv->offscreen); - break; -+ case PROP_SHADOWFB: -+ g_value_set_boxed (value, priv->shadowfb); -+ break; - case PROP_SCALE: - g_value_set_float (value, priv->scale); - break; -@@ -318,6 +396,9 @@ clutter_stage_view_set_property (GObject *object, - case PROP_OFFSCREEN: - priv->offscreen = g_value_dup_boxed (value); - break; -+ case PROP_SHADOWFB: -+ priv->shadowfb = g_value_dup_boxed (value); -+ break; - case PROP_SCALE: - priv->scale = g_value_get_float (value); - break; -@@ -334,8 +415,10 @@ clutter_stage_view_dispose (GObject *object) - clutter_stage_view_get_instance_private (view); - - g_clear_pointer (&priv->framebuffer, cogl_object_unref); -+ g_clear_pointer (&priv->shadowfb, cogl_object_unref); - g_clear_pointer (&priv->offscreen, cogl_object_unref); -- g_clear_pointer (&priv->pipeline, cogl_object_unref); -+ g_clear_pointer (&priv->offscreen_pipeline, cogl_object_unref); -+ g_clear_pointer (&priv->shadowfb_pipeline, cogl_object_unref); - - G_OBJECT_CLASS (clutter_stage_view_parent_class)->dispose (object); - } -@@ -390,6 +473,15 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass) - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - -+ obj_props[PROP_SHADOWFB] = -+ g_param_spec_boxed ("shadowfb", -+ "Shadow framebuffer", -+ "Framebuffer used as intermediate shadow buffer", -+ COGL_TYPE_HANDLE, -+ G_PARAM_READWRITE | -+ G_PARAM_CONSTRUCT_ONLY | -+ G_PARAM_STATIC_STRINGS); -+ - obj_props[PROP_SCALE] = - g_param_spec_float ("scale", - "View scale", -diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c -index 4810e42a4..d2b833c4d 100644 ---- a/clutter/clutter/cogl/clutter-stage-cogl.c -+++ b/clutter/clutter/cogl/clutter-stage-cogl.c -@@ -526,11 +526,7 @@ paint_stage (ClutterStageCogl *stage_cogl, - _clutter_stage_maybe_setup_viewport (stage, view); - _clutter_stage_paint_view (stage, view, clip); - -- if (clutter_stage_view_get_onscreen (view) != -- clutter_stage_view_get_framebuffer (view)) -- { -- clutter_stage_view_blit_offscreen (view, clip); -- } -+ clutter_stage_view_blit_offscreen (view, clip); - } - - static void --- -2.23.0 - - -From ad30e12971303f09f4dfe3a2b9590217ba056826 Mon Sep 17 00:00:00 2001 -From: Olivier Fourdan <ofourdan@redhat.com> -Date: Tue, 22 Oct 2019 17:05:46 +0200 -Subject: [PATCH 32/53] renderer-native: Separate offscreen and shadowfb - -Create the intermediate shadow framebuffer for use exclusively when a -shadowfb is required. - -Keep the previous offscreen framebuffer is as an intermediate -framebuffer for transformations only. - -This way, we can apply transformations between in-memory framebuffers -prior to blit the result to screen, and achieve acceptable performance -even with software rendering on discrete GPU. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/917 - -(cherry picked from commit 551641c74822ca2e3c685e49603836ebf5397df2) ---- - src/backends/native/meta-renderer-native.c | 29 ++++++++++++++++++---- - 1 file changed, 24 insertions(+), 5 deletions(-) - -diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c -index 5c01375c8..84b6a7323 100644 ---- a/src/backends/native/meta-renderer-native.c -+++ b/src/backends/native/meta-renderer-native.c -@@ -3053,7 +3053,6 @@ meta_renderer_native_create_onscreen (MetaRendererNative *renderer_native, - static CoglOffscreen * - meta_renderer_native_create_offscreen (MetaRendererNative *renderer, - CoglContext *context, -- MetaMonitorTransform transform, - gint view_width, - gint view_height, - GError **error) -@@ -3256,6 +3255,7 @@ meta_renderer_native_create_view (MetaRenderer *renderer, - MetaMonitorTransform view_transform; - CoglOnscreen *onscreen = NULL; - CoglOffscreen *offscreen = NULL; -+ CoglOffscreen *shadowfb = NULL; - float scale; - int width, height; - MetaRendererView *view; -@@ -3282,18 +3282,35 @@ meta_renderer_native_create_view (MetaRenderer *renderer, - if (!onscreen) - g_error ("Failed to allocate onscreen framebuffer: %s", error->message); - -- if (view_transform != META_MONITOR_TRANSFORM_NORMAL || -- should_force_shadow_fb (renderer_native, -- renderer_native->primary_gpu_kms)) -+ if (view_transform != META_MONITOR_TRANSFORM_NORMAL) - { - offscreen = meta_renderer_native_create_offscreen (renderer_native, - cogl_context, -- view_transform, - width, - height, - &error); - if (!offscreen) - g_error ("Failed to allocate back buffer texture: %s", error->message); -+ -+ } -+ -+ if (should_force_shadow_fb (renderer_native, -+ renderer_native->primary_gpu_kms)) -+ { -+ int shadow_width; -+ int shadow_height; -+ -+ /* The shadowfb must be the same size as the on-screen framebuffer */ -+ shadow_width = cogl_framebuffer_get_width (COGL_FRAMEBUFFER (onscreen)); -+ shadow_height = cogl_framebuffer_get_height (COGL_FRAMEBUFFER (onscreen)); -+ -+ shadowfb = meta_renderer_native_create_offscreen (renderer_native, -+ cogl_context, -+ shadow_width, -+ shadow_height, -+ &error); -+ if (!shadowfb) -+ g_error ("Failed to allocate shadow buffer texture: %s", error->message); - } - - view = g_object_new (META_TYPE_RENDERER_VIEW, -@@ -3301,10 +3318,12 @@ meta_renderer_native_create_view (MetaRenderer *renderer, - "scale", scale, - "framebuffer", onscreen, - "offscreen", offscreen, -+ "shadowfb", shadowfb, - "logical-monitor", logical_monitor, - "transform", view_transform, - NULL); - g_clear_pointer (&offscreen, cogl_object_unref); -+ g_clear_pointer (&shadowfb, cogl_object_unref); - - meta_onscreen_native_set_view (onscreen, view); - --- -2.23.0 - - -From 414962cd544b943efb747e8e7ff81620dba856ff Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com> -Date: Fri, 1 Nov 2019 13:14:39 +0100 -Subject: [PATCH 33/53] display: Add 'closing' signal - -Emitted when the MetaDisplay is closing. Meant for clean up that depends -on things that will be torn down during closing. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/912 ---- - src/core/display.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/src/core/display.c b/src/core/display.c -index 05c2a64b8..7f0b7f95e 100644 ---- a/src/core/display.c -+++ b/src/core/display.c -@@ -156,6 +156,7 @@ enum - SHOWING_DESKTOP_CHANGED, - RESTACKED, - WORKAREAS_CHANGED, -+ CLOSING, - LAST_SIGNAL - }; - -@@ -493,6 +494,12 @@ meta_display_class_init (MetaDisplayClass *klass) - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 0); -+ display_signals[CLOSING] = -+ g_signal_new ("closing", -+ G_TYPE_FROM_CLASS (klass), -+ G_SIGNAL_RUN_LAST, -+ 0, NULL, NULL, NULL, -+ G_TYPE_NONE, 0); - - g_object_class_install_property (object_class, - PROP_FOCUS_WINDOW, -@@ -971,6 +978,8 @@ meta_display_close (MetaDisplay *display, - - display->closing += 1; - -+ g_signal_emit (display, display_signals[CLOSING], 0); -+ - meta_compositor_unmanage (display->compositor); - - meta_display_unmanage_windows (display, timestamp); --- -2.23.0 - - -From a416c03c9488fbb7dcefc67cd09eff39f7262c49 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com> -Date: Fri, 1 Nov 2019 13:15:57 +0100 -Subject: [PATCH 34/53] plugin/default: Init quark before using - -Cut lines in pieces, and remove useless "optimizations" while at it - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/912 ---- - src/compositor/plugins/default.c | 13 +++++++++---- - 1 file changed, 9 insertions(+), 4 deletions(-) - -diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c -index e7203ee11..42d28ec20 100644 ---- a/src/compositor/plugins/default.c -+++ b/src/compositor/plugins/default.c -@@ -750,12 +750,17 @@ free_display_tile_preview (gpointer data) - static DisplayTilePreview * - get_display_tile_preview (MetaDisplay *display) - { -- DisplayTilePreview *preview = g_object_get_qdata (G_OBJECT (display), display_tile_preview_data_quark); -+ DisplayTilePreview *preview; - -- if (G_UNLIKELY (display_tile_preview_data_quark == 0)) -- display_tile_preview_data_quark = g_quark_from_static_string (DISPLAY_TILE_PREVIEW_DATA_KEY); -+ if (!display_tile_preview_data_quark) -+ { -+ display_tile_preview_data_quark = -+ g_quark_from_static_string (DISPLAY_TILE_PREVIEW_DATA_KEY); -+ } - -- if (G_UNLIKELY (!preview)) -+ preview = g_object_get_qdata (G_OBJECT (display), -+ display_tile_preview_data_quark); -+ if (!preview) - { - preview = g_slice_new0 (DisplayTilePreview); - --- -2.23.0 - - -From 5d70153ea8dae2631000754749ed321e4aec2558 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com> -Date: Fri, 1 Nov 2019 13:16:25 +0100 -Subject: [PATCH 35/53] plugins/default: Clean up tile preview when closing - display - -On finalize, the preview actor will have been destroyed behind our back; -avoid that by cleaning up before it's too late. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/912 ---- - src/compositor/plugins/default.c | 20 +++++++++++++++----- - 1 file changed, 15 insertions(+), 5 deletions(-) - -diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c -index 42d28ec20..378009006 100644 ---- a/src/compositor/plugins/default.c -+++ b/src/compositor/plugins/default.c -@@ -737,9 +737,8 @@ destroy (MetaPlugin *plugin, MetaWindowActor *window_actor) - * Tile preview private data accessor - */ - static void --free_display_tile_preview (gpointer data) -+free_display_tile_preview (DisplayTilePreview *preview) - { -- DisplayTilePreview *preview = data; - - if (G_LIKELY (preview != NULL)) { - clutter_actor_destroy (preview->actor); -@@ -747,6 +746,13 @@ free_display_tile_preview (gpointer data) - } - } - -+static void -+on_display_closing (MetaDisplay *display, -+ DisplayTilePreview *preview) -+{ -+ free_display_tile_preview (preview); -+} -+ - static DisplayTilePreview * - get_display_tile_preview (MetaDisplay *display) - { -@@ -769,9 +775,13 @@ get_display_tile_preview (MetaDisplay *display) - clutter_actor_set_opacity (preview->actor, 100); - - clutter_actor_add_child (meta_get_window_group_for_display (display), preview->actor); -- g_object_set_qdata_full (G_OBJECT (display), -- display_tile_preview_data_quark, preview, -- free_display_tile_preview); -+ g_signal_connect (display, -+ "closing", -+ G_CALLBACK (on_display_closing), -+ preview); -+ g_object_set_qdata (G_OBJECT (display), -+ display_tile_preview_data_quark, -+ preview); - } - - return preview; --- -2.23.0 - - -From b37ec8fd05fc8ead9f625f470f07813963fe4417 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com> -Date: Fri, 1 Nov 2019 13:18:12 +0100 -Subject: [PATCH 36/53] window: Always update tile monitor number on hot plug - -Otherwise we'll end up crashing if we had two connected monitors, -unplugged both, then replugged in a single one. - -Avoids the following error: - - #0 _g_log_abort () - #1 g_logv () - #2 g_log () - #3 meta_monitor_manager_get_logical_monitor_from_number () - #4 meta_window_get_work_area_for_monitor () - #5 meta_window_get_tile_area () - #6 constrain_maximization () - #7 do_all_constraints () - #8 meta_window_constrain () - #9 meta_window_move_resize_internal () - #10 meta_window_move_resize_frame () - #11 meta_window_move_resize_now () - #12 idle_move_resize () - #13 call_idle_later () - -https://bugzilla.redhat.com/show_bug.cgi?id=1767703 - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/912 ---- - src/core/window.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/src/core/window.c b/src/core/window.c -index e276b1e59..f72260f5d 100644 ---- a/src/core/window.c -+++ b/src/core/window.c -@@ -3923,11 +3923,16 @@ meta_window_update_for_monitors_changed (MetaWindow *window) - if (!new) - new = meta_monitor_manager_get_primary_logical_monitor (monitor_manager); - -- if (new && old) -+ if (window->tile_mode != META_TILE_NONE) - { -- if (window->tile_mode != META_TILE_NONE) -+ if (new) - window->tile_monitor_number = new->number; -+ else -+ window->tile_monitor_number = -1; -+ } - -+ if (new && old) -+ { - /* This will eventually reach meta_window_update_monitor that - * will send leave/enter-monitor events. The old != new monitor - * check will always fail (due to the new logical_monitors set) so --- -2.23.0 - - -From 8d71a01c9d25340f585635de77570f17197ffdc2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com> -Date: Fri, 1 Nov 2019 13:35:38 +0100 -Subject: [PATCH 37/53] tests/monitor-unit-tests: Move test client sanity check - into helper - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/912 ---- - src/tests/monitor-unit-tests.c | 17 ++++++++++++----- - 1 file changed, 12 insertions(+), 5 deletions(-) - -diff --git a/src/tests/monitor-unit-tests.c b/src/tests/monitor-unit-tests.c -index 83102c3a5..250bcd67d 100644 ---- a/src/tests/monitor-unit-tests.c -+++ b/src/tests/monitor-unit-tests.c -@@ -378,15 +378,22 @@ create_monitor_test_clients (void) - } - - static void --check_monitor_test_clients_state (void) -+check_test_client_state (TestClient *test_client) - { - GError *error = NULL; - -- if (!test_client_wait (wayland_monitor_test_client, &error)) -- g_error ("Failed to sync Wayland test client: %s", error->message); -+ if (!test_client_wait (test_client, &error)) -+ { -+ g_error ("Failed to sync test client '%s': %s", -+ test_client_get_id (test_client), error->message); -+ } -+} - -- if (!test_client_wait (x11_monitor_test_client, &error)) -- g_error ("Failed to sync X11 test client: %s", error->message); -+static void -+check_monitor_test_clients_state (void) -+{ -+ check_test_client_state (wayland_monitor_test_client); -+ check_test_client_state (x11_monitor_test_client); - } - - static void --- -2.23.0 - - -From 71b2eba8018d32490ba634475503e739fac7b97c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com> -Date: Fri, 1 Nov 2019 13:37:22 +0100 -Subject: [PATCH 38/53] tests/runner: Move window shown synchronization to - helper - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/912 ---- - src/tests/test-runner.c | 46 +------------------------------------ - src/tests/test-utils.c | 51 +++++++++++++++++++++++++++++++++++++++++ - src/tests/test-utils.h | 3 +++ - 3 files changed, 55 insertions(+), 45 deletions(-) - -diff --git a/src/tests/test-runner.c b/src/tests/test-runner.c -index 377b256c2..7560c957e 100644 ---- a/src/tests/test-runner.c -+++ b/src/tests/test-runner.c -@@ -342,39 +342,6 @@ test_case_check_xserver_stacking (TestCase *test, - return *error == NULL; - } - --typedef struct _WaitForShownData --{ -- GMainLoop *loop; -- MetaWindow *window; -- guint shown_handler_id; --} WaitForShownData; -- --static void --on_window_shown (MetaWindow *window, -- WaitForShownData *data) --{ -- g_main_loop_quit (data->loop); --} -- --static gboolean --test_case_wait_for_showing_before_redraw (gpointer user_data) --{ -- WaitForShownData *data = user_data; -- -- if (meta_window_is_hidden (data->window)) -- { -- data->shown_handler_id = g_signal_connect (data->window, "shown", -- G_CALLBACK (on_window_shown), -- data); -- } -- else -- { -- g_main_loop_quit (data->loop); -- } -- -- return FALSE; --} -- - static gboolean - test_case_do (TestCase *test, - int argc, -@@ -533,18 +500,7 @@ test_case_do (TestCase *test, - if (!window) - return FALSE; - -- WaitForShownData data = { -- .loop = g_main_loop_new (NULL, FALSE), -- .window = window, -- }; -- meta_later_add (META_LATER_BEFORE_REDRAW, -- test_case_wait_for_showing_before_redraw, -- &data, -- NULL); -- g_main_loop_run (data.loop); -- if (data.shown_handler_id) -- g_signal_handler_disconnect (window, data.shown_handler_id); -- g_main_loop_unref (data.loop); -+ test_client_wait_for_window_shown (client, window); - } - else if (strcmp (argv[0], "hide") == 0 || - strcmp (argv[0], "activate") == 0 || -diff --git a/src/tests/test-utils.c b/src/tests/test-utils.c -index a42005451..c16ccf8b2 100644 ---- a/src/tests/test-utils.c -+++ b/src/tests/test-utils.c -@@ -359,6 +359,57 @@ test_client_find_window (TestClient *client, - return result; - } - -+typedef struct _WaitForShownData -+{ -+ GMainLoop *loop; -+ MetaWindow *window; -+ guint shown_handler_id; -+} WaitForShownData; -+ -+static void -+on_window_shown (MetaWindow *window, -+ WaitForShownData *data) -+{ -+ g_main_loop_quit (data->loop); -+} -+ -+static gboolean -+wait_for_showing_before_redraw (gpointer user_data) -+{ -+ WaitForShownData *data = user_data; -+ -+ if (meta_window_is_hidden (data->window)) -+ { -+ data->shown_handler_id = g_signal_connect (data->window, "shown", -+ G_CALLBACK (on_window_shown), -+ data); -+ } -+ else -+ { -+ g_main_loop_quit (data->loop); -+ } -+ -+ return FALSE; -+} -+ -+void -+test_client_wait_for_window_shown (TestClient *client, -+ MetaWindow *window) -+{ -+ WaitForShownData data = { -+ .loop = g_main_loop_new (NULL, FALSE), -+ .window = window, -+ }; -+ meta_later_add (META_LATER_BEFORE_REDRAW, -+ wait_for_showing_before_redraw, -+ &data, -+ NULL); -+ g_main_loop_run (data.loop); -+ if (data.shown_handler_id) -+ g_signal_handler_disconnect (window, data.shown_handler_id); -+ g_main_loop_unref (data.loop); -+} -+ - gboolean - test_client_alarm_filter (MetaX11Display *x11_display, - XSyncAlarmNotifyEvent *event, -diff --git a/src/tests/test-utils.h b/src/tests/test-utils.h -index e11f25353..2f1a73116 100644 ---- a/src/tests/test-utils.h -+++ b/src/tests/test-utils.h -@@ -70,6 +70,9 @@ MetaWindow * test_client_find_window (TestClient *client, - const char *window_id, - GError **error); - -+void test_client_wait_for_window_shown (TestClient *client, -+ MetaWindow *window); -+ - gboolean test_client_quit (TestClient *client, - GError **error); - --- -2.23.0 - - -From a37126bb158980420bfa338245a9d4279a496565 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com> -Date: Fri, 1 Nov 2019 13:38:25 +0100 -Subject: [PATCH 39/53] tests/monitor-unit-tests: Add window tiling hot plug - test - -This test that we handle hot plugs correctly together with tiled -windows. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/912 ---- - src/core/window-private.h | 1 + - src/tests/monitor-unit-tests.c | 103 +++++++++++++++++++++++++++++++++ - 2 files changed, 104 insertions(+) - -diff --git a/src/core/window-private.h b/src/core/window-private.h -index dd89fdc90..62f97fba2 100644 ---- a/src/core/window-private.h -+++ b/src/core/window-private.h -@@ -629,6 +629,7 @@ void meta_window_unmanage (MetaWindow *window, - void meta_window_unmanage_on_idle (MetaWindow *window); - void meta_window_queue (MetaWindow *window, - guint queuebits); -+META_EXPORT_TEST - void meta_window_tile (MetaWindow *window, - MetaTileMode mode); - MetaTileMode meta_window_get_tile_mode (MetaWindow *window); -diff --git a/src/tests/monitor-unit-tests.c b/src/tests/monitor-unit-tests.c -index 250bcd67d..c03c17e8d 100644 ---- a/src/tests/monitor-unit-tests.c -+++ b/src/tests/monitor-unit-tests.c -@@ -28,6 +28,7 @@ - #include "backends/meta-monitor-config-migration.h" - #include "backends/meta-monitor-config-store.h" - #include "backends/meta-output.h" -+#include "core/window-private.h" - #include "meta-backend-test.h" - #include "tests/meta-monitor-manager-test.h" - #include "tests/monitor-test-utils.h" -@@ -5760,6 +5761,105 @@ meta_test_monitor_migrated_wiggle_discard (void) - g_error ("Failed to remove test data output file: %s", error->message); - } - -+static gboolean -+quit_main_loop (gpointer data) -+{ -+ GMainLoop *loop = data; -+ -+ g_main_loop_quit (loop); -+ -+ return G_SOURCE_REMOVE; -+} -+ -+static void -+dispatch (void) -+{ -+ GMainLoop *loop; -+ -+ loop = g_main_loop_new (NULL, FALSE); -+ meta_later_add (META_LATER_BEFORE_REDRAW, -+ quit_main_loop, -+ loop, -+ NULL); -+ g_main_loop_run (loop); -+} -+ -+static TestClient * -+create_test_window (const char *window_name) -+{ -+ TestClient *test_client; -+ static int client_count = 0; -+ g_autofree char *client_name = NULL; -+ g_autoptr (GError) error = NULL; -+ -+ client_name = g_strdup_printf ("test_client_%d", client_count++); -+ test_client = test_client_new (client_name, META_WINDOW_CLIENT_TYPE_WAYLAND, -+ &error); -+ if (!test_client) -+ g_error ("Failed to launch test client: %s", error->message); -+ -+ if (!test_client_do (test_client, &error, -+ "create", window_name, -+ NULL)) -+ g_error ("Failed to create window: %s", error->message); -+ -+ return test_client; -+} -+ -+static void -+meta_test_monitor_wm_tiling (void) -+{ -+ MonitorTestCase test_case = initial_test_case; -+ MetaMonitorTestSetup *test_setup; -+ g_autoptr (GError) error = NULL; -+ -+ test_setup = create_monitor_test_setup (&test_case, -+ MONITOR_TEST_FLAG_NO_STORED); -+ emulate_hotplug (test_setup); -+ -+ /* -+ * 1) Start with two monitors connected. -+ * 2) Tile it on the second monitor. -+ * 3) Unplug both monitors. -+ * 4) Replug in first monitor. -+ */ -+ -+ const char *test_window_name= "window1"; -+ TestClient *test_client = create_test_window (test_window_name); -+ -+ if (!test_client_do (test_client, &error, -+ "show", test_window_name, -+ NULL)) -+ g_error ("Failed to show the window: %s", error->message); -+ -+ MetaWindow *test_window = -+ test_client_find_window (test_client, -+ test_window_name, -+ &error); -+ if (!test_window) -+ g_error ("Failed to find the window: %s", error->message); -+ test_client_wait_for_window_shown (test_client, test_window); -+ -+ meta_window_tile (test_window, META_TILE_MAXIMIZED); -+ meta_window_move_to_monitor (test_window, 1); -+ check_test_client_state (test_client); -+ -+ fprintf(stderr, ":::: %s:%d %s() - UNPLUGGING\n", __FILE__, __LINE__, __func__); -+ -+ test_case.setup.n_outputs = 0; -+ test_setup = create_monitor_test_setup (&test_case, -+ MONITOR_TEST_FLAG_NO_STORED); -+ emulate_hotplug (test_setup); -+ test_case.setup.n_outputs = 1; -+ test_setup = create_monitor_test_setup (&test_case, -+ MONITOR_TEST_FLAG_NO_STORED); -+ emulate_hotplug (test_setup); -+ -+ dispatch (); -+ -+ test_client_destroy (test_client); -+} -+ - static void - meta_test_monitor_migrated_wiggle (void) - { -@@ -6015,6 +6115,9 @@ init_monitor_tests (void) - meta_test_monitor_migrated_wiggle); - add_monitor_test ("/backends/monitor/migrated/wiggle-discard", - meta_test_monitor_migrated_wiggle_discard); -+ -+ add_monitor_test ("/backends/monitor/wm/tiling", -+ meta_test_monitor_wm_tiling); - } - - void --- -2.23.0 - - -From c3b1d9fc8113595a0ace0a141fa7b91c17696ad5 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com> -Date: Fri, 1 Nov 2019 13:40:04 +0100 -Subject: [PATCH 40/53] window: Reset tile monitor number when untiling - -Otherwise we'll end up trying to access the out of date state later. - -Fixes the following test failure backtrace: - - #0 _g_log_abort () - #1 g_logv () - #2 g_log () - #3 meta_monitor_manager_get_logical_monitor_from_number () - #4 meta_window_get_work_area_for_monitor () - #5 meta_window_get_tile_area () - #6 constrain_maximization () - #7 do_all_constraints () - #8 meta_window_constrain () - #9 meta_window_move_resize_internal () - #10 meta_window_tile () - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/912 ---- - src/core/window.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/src/core/window.c b/src/core/window.c -index f72260f5d..d93e723a5 100644 ---- a/src/core/window.c -+++ b/src/core/window.c -@@ -3192,7 +3192,10 @@ meta_window_tile (MetaWindow *window, - - /* Don't do anything if no tiling is requested */ - if (window->tile_mode == META_TILE_NONE) -- return; -+ { -+ window->tile_monitor_number = -1; -+ return; -+ } - - if (window->tile_mode == META_TILE_MAXIMIZED) - directions = META_MAXIMIZE_BOTH; --- -2.23.0 - - -From 8605eb5c03c81f9f30716dd823a284a89639be56 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com> -Date: Fri, 1 Nov 2019 13:48:50 +0100 -Subject: [PATCH 41/53] tests/monitor-unit-tests: Add another tiling window hot - plug test - -Checks that we handle hot plugs of a untiled window, that was previously -tiled. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/912 ---- - src/tests/monitor-unit-tests.c | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - -diff --git a/src/tests/monitor-unit-tests.c b/src/tests/monitor-unit-tests.c -index c03c17e8d..b498d899f 100644 ---- a/src/tests/monitor-unit-tests.c -+++ b/src/tests/monitor-unit-tests.c -@@ -5857,6 +5857,29 @@ meta_test_monitor_wm_tiling (void) - - dispatch (); - -+ /* -+ * 1) Start with two monitors connected. -+ * 2) Tile a window on the second monitor. -+ * 3) Untile window. -+ * 4) Unplug monitor. -+ * 5) Tile window again. -+ */ -+ -+ test_case.setup.n_outputs = 2; -+ test_setup = create_monitor_test_setup (&test_case, -+ MONITOR_TEST_FLAG_NO_STORED); -+ emulate_hotplug (test_setup); -+ -+ meta_window_move_to_monitor (test_window, 1); -+ meta_window_tile (test_window, META_TILE_NONE); -+ -+ test_case.setup.n_outputs = 1; -+ test_setup = create_monitor_test_setup (&test_case, -+ MONITOR_TEST_FLAG_NO_STORED); -+ emulate_hotplug (test_setup); -+ -+ meta_window_tile (test_window, META_TILE_MAXIMIZED); -+ - test_client_destroy (test_client); - } - --- -2.23.0 - - -From 7c25950c30f85267ec769f168a10f7dbfc25d272 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net> -Date: Thu, 31 Oct 2019 06:36:52 +0000 -Subject: [PATCH 42/53] x11-display: Don't unset the X11 focused window after - setting one - -When using DesktopIcons extension and clicking in an icon, gnome-shell -starts an infinite loop caused by the first focus change that may trigger -on X11 a focus in/out event that leads to stage activation/deactivation -which never ends. - -This happens because as part of meta_x11_display_set_input_focus_xwindow() -to focus the X11 stage window, we unset the display focus, but this also -causes to request the X11 display to unset the focus since we convolute by -calling meta_x11_display_set_input_focus() with no window, that leads to -focusing the no_focus_window and then a focus-in / focus-out dance that the -shell amplifies in order to give back the focus to the stage. - -In order to fix this, mimic what meta_display_set_input_focus() does, but -without updating the X11 display, and so without implicitly calling -meta_x11_display_set_input_focus(), stopping the said convolution and -properly focusing the requested xwindow. -Also ensure that we're not doing this when using an older timestamp, since -this check isn't performed anymore. - -Fixes https://gitlab.gnome.org/GNOME/mutter/issues/896 -Fixes https://gitlab.gnome.org/GNOME/mutter/issues/899 - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/909 - - -(cherry picked from commit efe5bed5b4a8706fc796dfd7dc07562a866c12ed) ---- - src/x11/meta-x11-display.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c -index 1aebaa961..c05f1ab28 100644 ---- a/src/x11/meta-x11-display.c -+++ b/src/x11/meta-x11-display.c -@@ -1928,10 +1928,15 @@ meta_x11_display_set_input_focus_xwindow (MetaX11Display *x11_display, - { - gulong serial; - -+ if (meta_display_timestamp_too_old (x11_display->display, ×tamp)) -+ return; -+ - serial = XNextRequest (x11_display->xdisplay); - meta_x11_display_set_input_focus_internal (x11_display, window, timestamp); - meta_x11_display_update_focus_window (x11_display, window, serial, TRUE); -- meta_display_unset_input_focus (x11_display->display, timestamp); -+ meta_display_update_focus_window (x11_display->display, NULL); -+ meta_display_remove_autoraise_callback (x11_display->display); -+ x11_display->display->last_focus_time = timestamp; - } - - static MetaX11DisplayLogicalMonitorData * --- -2.23.0 - - -From c457a54a437d000fbdc9d4fb072659bd5d111666 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com> -Date: Mon, 28 Oct 2019 17:20:31 +0000 -Subject: [PATCH 43/53] wayland/actor-surface: Always store away frame - callbacks on commit - -We're expected by MetaWaylandSurface to always pick the frame callbacks -out from the pending state when committing (applying) so that no frame -callbacks are unaccounted for. We failed to do this if our actor for -some reason (e.g. associated window was unmanaged) was destroyed. To -handle this situation better, store away the frame callbacks until we -some later point in time need to pass them on forward. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/893 - - -(cherry picked from commit 0e5a5df5fe4d147197d85d4191d8a5c2eefb1561) ---- - src/wayland/meta-wayland-actor-surface.c | 22 ++++++++++++++++++++-- - 1 file changed, 20 insertions(+), 2 deletions(-) - -diff --git a/src/wayland/meta-wayland-actor-surface.c b/src/wayland/meta-wayland-actor-surface.c -index a61a80eff..bf93f9564 100644 ---- a/src/wayland/meta-wayland-actor-surface.c -+++ b/src/wayland/meta-wayland-actor-surface.c -@@ -38,6 +38,8 @@ struct _MetaWaylandActorSurfacePrivate - MetaSurfaceActor *actor; - - gulong actor_destroyed_handler_id; -+ -+ struct wl_list frame_callback_list; - }; - - G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaWaylandActorSurface, -@@ -78,6 +80,7 @@ meta_wayland_actor_surface_dispose (GObject *object) - MetaWaylandActorSurface *actor_surface = META_WAYLAND_ACTOR_SURFACE (object); - MetaWaylandActorSurfacePrivate *priv = - meta_wayland_actor_surface_get_instance_private (actor_surface); -+ MetaWaylandFrameCallback *cb, *next; - - if (priv->actor) - { -@@ -85,6 +88,9 @@ meta_wayland_actor_surface_dispose (GObject *object) - clear_surface_actor (actor_surface); - } - -+ wl_list_for_each_safe (cb, next, &priv->frame_callback_list, link) -+ wl_resource_destroy (cb->resource); -+ - G_OBJECT_CLASS (meta_wayland_actor_surface_parent_class)->dispose (object); - } - -@@ -113,6 +119,9 @@ meta_wayland_actor_surface_queue_frame_callbacks (MetaWaylandActorSurface *actor - if (!priv->actor) - return; - -+ meta_surface_actor_wayland_add_frame_callbacks (surface_actor_wayland, -+ &priv->frame_callback_list); -+ wl_list_init (&priv->frame_callback_list); - meta_surface_actor_wayland_add_frame_callbacks (surface_actor_wayland, - &pending->frame_callback_list); - wl_list_init (&pending->frame_callback_list); -@@ -239,7 +248,12 @@ meta_wayland_actor_surface_commit (MetaWaylandSurfaceRole *surface_role, - meta_wayland_actor_surface_get_instance_private (actor_surface); - - if (!priv->actor) -- return; -+ { -+ wl_list_insert_list (&priv->frame_callback_list, -+ &pending->frame_callback_list); -+ wl_list_init (&pending->frame_callback_list); -+ return; -+ } - - if (!wl_list_empty (&pending->frame_callback_list) && - cairo_region_is_empty (pending->surface_damage) && -@@ -292,8 +306,12 @@ meta_wayland_actor_surface_is_on_logical_monitor (MetaWaylandSurfaceRole *surfac - } - - static void --meta_wayland_actor_surface_init (MetaWaylandActorSurface *role) -+meta_wayland_actor_surface_init (MetaWaylandActorSurface *actor_surface) - { -+ MetaWaylandActorSurfacePrivate *priv = -+ meta_wayland_actor_surface_get_instance_private (actor_surface); -+ -+ wl_list_init (&priv->frame_callback_list); - } - - static void --- -2.23.0 - - -From 4d589619764a556a5464836c5353cede43bfe79b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net> -Date: Tue, 29 Oct 2019 16:48:00 +0000 -Subject: [PATCH 44/53] window: Warn if O-R window workspace state is used - -Override-redirect windows have no workspace by default, and can't be parent -of a top-level window, so we must check that the parent window is not an -O-R one when setting the workspace state. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/895 - - -(cherry picked from commit 2644e54c514377009a9d4d747874a55b387c6beb) ---- - src/core/window.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/core/window.c b/src/core/window.c -index d93e723a5..f38f0fee2 100644 ---- a/src/core/window.c -+++ b/src/core/window.c -@@ -1306,6 +1306,7 @@ _meta_window_shared_new (MetaDisplay *display, - "Putting window %s on same workspace as parent %s\n", - window->desc, window->transient_for->desc); - -+ g_warn_if_fail (!window->transient_for->override_redirect); - set_workspace_state (window, - should_be_on_all_workspaces (window->transient_for), - window->transient_for->workspace); --- -2.23.0 - - -From c94174d8e8876f12327f0f7fe56090882aa66401 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net> -Date: Tue, 29 Oct 2019 02:54:42 +0000 -Subject: [PATCH 45/53] window: Assert we only set a NULL workspace when - unmanaging - -There might be cases in which a window might be marked as both not in all -workspaces and with NULL workspace. - -So to avoid this to happen, let's just assert early instead of doing this at -later point where the context might not be clear. - -Related to https://gitlab.gnome.org/GNOME/mutter/issues/885 - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/895 - - -(cherry picked from commit 13f10e36e4ac162f0b54fa57de24120e0e5a5453) ---- - src/core/window.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/src/core/window.c b/src/core/window.c -index f38f0fee2..ac8187978 100644 ---- a/src/core/window.c -+++ b/src/core/window.c -@@ -4826,9 +4826,12 @@ set_workspace_state (MetaWindow *window, - { - MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; - -- /* If we're on all workspaces, then our new workspace must be NULL. */ -+ /* If we're on all workspaces, then our new workspace must be NULL, -+ * otherwise it must be set, unless we're unmanaging. */ - if (on_all_workspaces) -- g_assert (workspace == NULL); -+ g_assert_null (workspace); -+ else -+ g_assert_true (window->unmanaging || workspace != NULL); - - /* If this is an override-redirect window, ensure that the only - * times we're setting the workspace state is either during construction --- -2.23.0 - - -From 7438c8ef9db05a020835c29461865e7ba9441a1c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net> -Date: Tue, 29 Oct 2019 16:14:43 +0000 -Subject: [PATCH 46/53] window-props: Don't look for parent multiple times - -Once we set the transient_for, we look for parent MetaWindow, so instead -of overwriting this value for loops check, just use another function -and avoid to look for the xwindow again when setting the MetaWindow parent. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/895 - - -(cherry picked from commit c85fb107c0556283062f2bf9b8d990f1e2c0acae) ---- - src/x11/window-props.c | 33 ++++++++++++++++++++------------- - 1 file changed, 20 insertions(+), 13 deletions(-) - -diff --git a/src/x11/window-props.c b/src/x11/window-props.c -index 48454befe..2564909a9 100644 ---- a/src/x11/window-props.c -+++ b/src/x11/window-props.c -@@ -1625,6 +1625,22 @@ reload_wm_hints (MetaWindow *window, - meta_window_queue (window, META_QUEUE_UPDATE_ICON | META_QUEUE_MOVE_RESIZE); - } - -+static gboolean -+check_xtransient_for_loop (MetaWindow *window, -+ MetaWindow *parent) -+{ -+ while (parent) -+ { -+ if (parent == window) -+ return TRUE; -+ -+ parent = meta_x11_display_lookup_x_window (parent->display->x11_display, -+ parent->xtransient_for); -+ } -+ -+ return FALSE; -+} -+ - static void - reload_transient_for (MetaWindow *window, - MetaPropValue *value, -@@ -1647,18 +1663,11 @@ reload_transient_for (MetaWindow *window, - } - - /* Make sure there is not a loop */ -- while (parent) -+ if (check_xtransient_for_loop (window, parent)) - { -- if (parent == window) -- { -- meta_warning ("WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n", -- transient_for, window->desc); -- transient_for = None; -- break; -- } -- -- parent = meta_x11_display_lookup_x_window (parent->display->x11_display, -- parent->xtransient_for); -+ meta_warning ("WM_TRANSIENT_FOR window 0x%lx for %s would create a " -+ "loop.\n", transient_for, window->desc); -+ transient_for = None; - } - } - else -@@ -1679,8 +1688,6 @@ reload_transient_for (MetaWindow *window, - meta_window_set_transient_for (window, NULL); - else - { -- parent = meta_x11_display_lookup_x_window (window->display->x11_display, -- window->xtransient_for); - meta_window_set_transient_for (window, parent); - } - } --- -2.23.0 - - -From 961b3b724a04bc216bf243e688f82542e33dc964 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net> -Date: Tue, 29 Oct 2019 03:22:19 +0000 -Subject: [PATCH 47/53] window-props: Don't set override redirect windows as - top-level parent - -Java applications might use override-redirect windows as parent windows for -top-level windows, although this is not following the standard [1]. - -In such case, the first non-override-redirect child window that is created -was marked as being on_all_workspaces since the call to -should_be_on_all_workspaces() returns TRUE for its parent, and this even -though the on_all_workspaces_requested bit is unset. -When a further child of this window was added, it was set as not having a -workspace and not being on_all_workspaces, since the call to -should_be_on_all_workspaces() for its parent would return FALSE (unless if -it is in a different monitor, and the multiple-monitors workspaces are -disabled). - -Since per commit 09bab98b we don't recompute the workspace if the -on_all_workspaces bit is unset, we could end up in a case where a window can -be nor in all the workspaces or in a specific workspace. - -So let's just ignore the transient_for bit for a window if that points to an -override-redirect, using the x11 root window instead. - -Add a stacking test to verify this scenario (was failing before of this -commit). - -Fixes https://gitlab.gnome.org/GNOME/mutter/issues/885 -https://gitlab.gnome.org/GNOME/mutter/merge_requests/895 - -[1] https://standards.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472512128 - - -(cherry picked from commit bacbbbd628fd68618f14bdf07ba3f9e6ccd1c038) ---- - src/tests/meson.build | 1 + - .../set-override-redirect-parent.metatest | 24 +++++++++++++++++++ - src/x11/window-props.c | 9 +++++++ - 3 files changed, 34 insertions(+) - create mode 100644 src/tests/stacking/set-override-redirect-parent.metatest - -diff --git a/src/tests/meson.build b/src/tests/meson.build -index dafe67ff8..f5a132f6b 100644 ---- a/src/tests/meson.build -+++ b/src/tests/meson.build -@@ -131,6 +131,7 @@ stacking_tests = [ - 'mixed-windows', - 'set-parent', - 'override-redirect', -+ 'set-override-redirect-parent', - 'set-parent-exported', - ] - -diff --git a/src/tests/stacking/set-override-redirect-parent.metatest b/src/tests/stacking/set-override-redirect-parent.metatest -new file mode 100644 -index 000000000..fc99e4818 ---- /dev/null -+++ b/src/tests/stacking/set-override-redirect-parent.metatest -@@ -0,0 +1,24 @@ -+new_client 1 x11 -+create 1/1 override -+show 1/1 -+ -+create 1/2 -+set_parent 1/2 1 -+show 1/2 -+ -+create 1/3 -+set_parent 1/3 2 -+show 1/3 -+ -+ -+new_client 2 x11 -+create 2/1 -+show 2/1 -+ -+create 2/2 override -+set_parent 2/2 1 -+show 2/2 -+ -+create 2/3 -+set_parent 2/3 2 -+show 2/3 -diff --git a/src/x11/window-props.c b/src/x11/window-props.c -index 2564909a9..e1e96e0e3 100644 ---- a/src/x11/window-props.c -+++ b/src/x11/window-props.c -@@ -1661,6 +1661,15 @@ reload_transient_for (MetaWindow *window, - transient_for, window->desc); - transient_for = None; - } -+ else if (parent->override_redirect) -+ { -+ meta_warning ("WM_TRANSIENT_FOR window %s for top-level %s is an " -+ "override-redirect window and this is not correct " -+ "according to the standard, so we'll fallback to " -+ "the root window.\n", parent->desc, window->desc); -+ transient_for = parent->display->x11_display->xroot; -+ parent = NULL; -+ } - - /* Make sure there is not a loop */ - if (check_xtransient_for_loop (window, parent)) --- -2.23.0 - - -From 3f283b9be1bc19cf7a6f470e7a9fc280de97d88e Mon Sep 17 00:00:00 2001 -From: Xiang Fan <sfanxiang@gmail.com> -Date: Sat, 2 Nov 2019 15:05:57 -0400 -Subject: [PATCH 48/53] wayland/surface: Don't double scale when getting - absolute coordinates - -The actor is already in surface coordinate space, so we should not scale -with the buffer scale to transform surface coordinates to stage -coordinates. - -This bug causes input method using wayland text-input protocol to -receive wrong cursor location. Reproduced in ibus (when candidate -window is open) with scaling factor other than 1. - -This commit also fixes pointer confinement. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/915 ---- - src/wayland/meta-wayland-surface.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c -index 163b7c515..56d292517 100644 ---- a/src/wayland/meta-wayland-surface.c -+++ b/src/wayland/meta-wayland-surface.c -@@ -1647,8 +1647,8 @@ meta_wayland_surface_get_absolute_coordinates (MetaWaylandSurface *surface, - ClutterActor *actor = - CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface)); - ClutterVertex sv = { -- .x = sx * surface->scale, -- .y = sy * surface->scale, -+ .x = sx, -+ .y = sy, - }; - ClutterVertex v = { 0 }; - --- -2.23.0 - - -From 2334b971e17d786c8add7dfa5260c9a75aa1b9c6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org> -Date: Fri, 8 Nov 2019 22:41:35 +0100 -Subject: [PATCH 49/53] plugins/default: Handle skipped animations - -We currently assume that the actor_animate() helper function returns -a timeline. However Clutter may skip implicit animations and simple -set properties directly, for example when the actor is hidden. - -The returned timeline will be NULL in that case, and we abort when -using it as instance parameter to g_signal_connect(). - -Fix this by only setting up a completed handler when we are actually -animating, and complete the effect directly otherwise. - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/925 ---- - src/compositor/plugins/default.c | 43 ++++++++++++++++++++------------ - 1 file changed, 27 insertions(+), 16 deletions(-) - -diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c -index 378009006..08ecf01ac 100644 ---- a/src/compositor/plugins/default.c -+++ b/src/compositor/plugins/default.c -@@ -590,6 +590,7 @@ minimize (MetaPlugin *plugin, MetaWindowActor *window_actor) - MetaWindowType type; - MetaRectangle icon_geometry; - MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor); -+ ClutterTimeline *timeline = NULL; - ClutterActor *actor = CLUTTER_ACTOR (window_actor); - - -@@ -602,24 +603,28 @@ minimize (MetaPlugin *plugin, MetaWindowActor *window_actor) - } - - if (type == META_WINDOW_NORMAL) -+ { -+ timeline = actor_animate (actor, -+ CLUTTER_EASE_IN_SINE, -+ MINIMIZE_TIMEOUT, -+ "scale-x", 0.0, -+ "scale-y", 0.0, -+ "x", (double)icon_geometry.x, -+ "y", (double)icon_geometry.y, -+ NULL); -+ } -+ -+ if (timeline) - { - EffectCompleteData *data = g_new0 (EffectCompleteData, 1); - ActorPrivate *apriv = get_actor_private (window_actor); - -- apriv->tml_minimize = actor_animate (actor, -- CLUTTER_EASE_IN_SINE, -- MINIMIZE_TIMEOUT, -- "scale-x", 0.0, -- "scale-y", 0.0, -- "x", (double)icon_geometry.x, -- "y", (double)icon_geometry.y, -- NULL); -+ apriv->tml_minimize = timeline; - data->plugin = plugin; - data->actor = actor; - g_signal_connect (apriv->tml_minimize, "completed", - G_CALLBACK (on_minimize_effect_complete), - data); -- - } - else - meta_plugin_minimize_completed (plugin, window_actor); -@@ -708,21 +713,27 @@ destroy (MetaPlugin *plugin, MetaWindowActor *window_actor) - MetaWindowType type; - ClutterActor *actor = CLUTTER_ACTOR (window_actor); - MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor); -+ ClutterTimeline *timeline = NULL; - - type = meta_window_get_window_type (meta_window); - - if (type == META_WINDOW_NORMAL) -+ { -+ timeline = actor_animate (actor, -+ CLUTTER_EASE_OUT_QUAD, -+ DESTROY_TIMEOUT, -+ "opacity", 0, -+ "scale-x", 0.8, -+ "scale-y", 0.8, -+ NULL); -+ } -+ -+ if (timeline) - { - EffectCompleteData *data = g_new0 (EffectCompleteData, 1); - ActorPrivate *apriv = get_actor_private (window_actor); - -- apriv->tml_destroy = actor_animate (actor, -- CLUTTER_EASE_OUT_QUAD, -- DESTROY_TIMEOUT, -- "opacity", 0, -- "scale-x", 0.8, -- "scale-y", 0.8, -- NULL); -+ apriv->tml_destroy = timeline; - data->plugin = plugin; - data->actor = actor; - g_signal_connect (apriv->tml_destroy, "completed", --- -2.23.0 - - -From 35142ada8d980bb77ec4f5e86d30be58179c3952 Mon Sep 17 00:00:00 2001 -From: Robert Mader <robert.mader@posteo.de> -Date: Fri, 8 Nov 2019 17:27:28 +0000 -Subject: [PATCH 50/53] plugin-manager: Kill window effects on destroy - -We do so for all other window effects already. Why this was left out -is unknown (9b3a0d1ad8f), but we will need it for a fix in GS. - -Related: https://gitlab.gnome.org/GNOME/mutter/issues/655 - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/924 - - -(cherry picked from commit a4f51da184e8eab0a2d44d0fc535032515436e8d) ---- - src/compositor/meta-plugin-manager.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/compositor/meta-plugin-manager.c b/src/compositor/meta-plugin-manager.c -index 09bcfd333..47bf922db 100644 ---- a/src/compositor/meta-plugin-manager.c -+++ b/src/compositor/meta-plugin-manager.c -@@ -195,6 +195,8 @@ meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr, - if (klass->destroy) - { - retval = TRUE; -+ meta_plugin_manager_kill_window_effects (plugin_mgr, -+ actor); - klass->destroy (plugin, actor); - } - break; --- -2.23.0 - - -From 7c05d8273296002a53215e0588fcfaeaa1d25227 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Sun, 10 Nov 2019 17:41:37 +0100 -Subject: [PATCH 51/53] input-settings/x11: Add missing - clutter_x11_trap_x_errors around XIGetProperty - -Add missing clutter_x11_[un]trap_x_errors around the XIGetProperty call -in meta-input-settings-x11.c's get_property helper function. - -This fixes mutter crashing with the following error if the XInput device -goes away at an unconvenient time: - - X Error of failed request: XI_BadDevice (invalid Device parameter) - Major opcode of failed request: 131 (XInputExtension) - Minor opcode of failed request: 59 () - Device id in failed request: 0x200011 - Serial number of failed request: 454 - Current serial number in output stream: 454 - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/928 ---- - src/backends/x11/meta-input-settings-x11.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/src/backends/x11/meta-input-settings-x11.c b/src/backends/x11/meta-input-settings-x11.c -index 89f07ee1f..05f932420 100644 ---- a/src/backends/x11/meta-input-settings-x11.c -+++ b/src/backends/x11/meta-input-settings-x11.c -@@ -118,9 +118,12 @@ get_property (ClutterInputDevice *device, - - device_id = clutter_input_device_get_device_id (device); - -+ clutter_x11_trap_x_errors (); - rc = XIGetProperty (xdisplay, device_id, property_atom, - 0, 10, False, type, &type_ret, &format_ret, - &nitems_ret, &bytes_after_ret, &data_ret); -+ clutter_x11_untrap_x_errors (); -+ - if (rc == Success && type_ret == type && format_ret == format && nitems_ret >= nitems) - { - if (nitems_ret > nitems) --- -2.23.0 - - -From 48f22df38d59bb722f300a506e137b01b0e8aac6 Mon Sep 17 00:00:00 2001 -From: Carlos Garnacho <carlosg@gnome.org> -Date: Mon, 21 Oct 2019 18:55:12 +0200 -Subject: [PATCH 52/53] backends: Plug MetaKmsPageFlipData leak -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -If the page flip is postponed, keep a ref to it, but still unref it -on the page flip callback anyways. Fix suggested by Jonas Ådahl. - -(cherry-picked from 668be1f4bd309fedc846a0022180aef5a9e44869) - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/873 ---- - src/backends/native/meta-kms-impl-simple.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/src/backends/native/meta-kms-impl-simple.c b/src/backends/native/meta-kms-impl-simple.c -index 19c4b2b33..571dccf12 100644 ---- a/src/backends/native/meta-kms-impl-simple.c -+++ b/src/backends/native/meta-kms-impl-simple.c -@@ -772,12 +772,14 @@ meta_kms_impl_simple_handle_page_flip_callback (MetaKmsImpl *impl, - { - impl_simple->postponed_page_flip_datas = - g_list_append (impl_simple->postponed_page_flip_datas, -- page_flip_data); -+ meta_kms_page_flip_data_ref (page_flip_data)); - } - else - { - meta_kms_page_flip_data_flipped_in_impl (page_flip_data); - } -+ -+ meta_kms_page_flip_data_unref (page_flip_data); - } - - static void --- -2.23.0 - - -From 5634f22be7249c91db922aa964f83efb25204c89 Mon Sep 17 00:00:00 2001 -From: Carlos Garnacho <carlosg@gnome.org> -Date: Mon, 21 Oct 2019 18:57:10 +0200 -Subject: [PATCH 53/53] compositor: Plug cairo_region_t leak - -The MetaBackgroundActor uses a region to find out the areas that need -repainting, but forgot to free it, oops. - -(cherry-picked from 40e6aa7d94e64d80fe07f020d75d540200004ea9) - -https://gitlab.gnome.org/GNOME/mutter/merge_requests/873 ---- - src/compositor/meta-background-actor.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/compositor/meta-background-actor.c b/src/compositor/meta-background-actor.c -index 48f745b38..961f6721b 100644 ---- a/src/compositor/meta-background-actor.c -+++ b/src/compositor/meta-background-actor.c -@@ -573,6 +573,8 @@ meta_background_actor_paint (ClutterActor *actor) - paint_clipped_rectangle (fb, self->pipeline, &rect, - &self->texture_area); - } -+ -+ cairo_region_destroy (region); - } - - static void --- -2.23.0 - diff --git a/mutter.spec b/mutter.spec index 5992117..7969be3 100644 --- a/mutter.spec +++ b/mutter.spec @@ -1,4 +1,4 @@ -### Enable LTO +# Enable LTO %global optflags %{optflags} -flto %global build_ldflags %{build_ldflags} -flto @@ -11,8 +11,8 @@ %global mutter_api_version 5 Name: mutter -Version: 3.34.1 -Release: 12.3.performance%{?dist} +Version: 3.34.2 +Release: 1.1.performance%{?dist} Summary: Window and compositing manager based on Clutter License: GPLv2+ @@ -22,53 +22,39 @@ Source0: http://download.gnome.org/sources/%{name}/3.34/%{name}-%{version} # Work-around for OpenJDK's compliance test Patch0: 0001-window-actor-Special-case-shaped-Java-windows.patch -# https://gitlab.gnome.org/GNOME/mutter/merge_requests/832 -# Provides some bits necessary for a gnome-shell patch to fix -# accessibility cursor zoom bug: -# https://bugzilla.redhat.com/show_bug.cgi?id=1749433 -# https://gitlab.gnome.org/GNOME/mutter/issues/826 -Patch1: 0001-cursor-tracker-Add-API-to-keep-the-wayland-pointer-f.patch -# https://gitlab.gnome.org/GNOME/mutter/merge_requests/840 # https://gitlab.gnome.org/GNOME/mutter/merge_requests/739 # Complements the backported Xwayland randr resolution change emulation support # necessary for SDL2 apps to work correctly -Patch2: 0001-window-Add-adjust_fullscreen_monitor_rect-virtual-me.patch -Patch3: 0002-window-xwayland-Add-Xwayland-fullscreen-games-workar.patch - -# Backport of patches on the stable branch (gnome-3-34) after 3.34.1 -# rhbz#1759876, rhbz#1764311, rhbz#1770535, rhbz#1770539, rhbz#1770540 -Patch4: mutter-gnome-3-34-2019-11-12.patch +Patch1: 0001-window-Add-adjust_fullscreen_monitor_rect-virtual-me.patch +Patch2: 0002-window-xwayland-Add-Xwayland-fullscreen-games-workar.patch # Mitigate crash on tear down. (rhbz#1770089, rhbz#1770089) -Patch5: 0001-compositor-Guard-against-untimely-calls.patch - -# https://gitlab.gnome.org/GNOME/mutter/merge_requests/943 -Patch6: mutter-clipboard-manager-crash.patch +Patch3: 0001-compositor-Guard-against-untimely-calls.patch -## Sync timelines to hardware vsync +# Sync timelines to hardware vsync Patch20: https://gitlab.gnome.org/GNOME/mutter/merge_requests/724.diff#/sync-timelines-to-hardware-vsync.diff -## Fixes and performance improvements to the extension system -# Patch21: https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/96.diff +# Fixes and performance improvements to the extension system +#Patch21: https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/96.diff -### Honour `CLUTTER_ACTOR_NO_LAYOUT` more efficiently +# Honour `CLUTTER_ACTOR_NO_LAYOUT` more efficiently Patch22: https://gitlab.gnome.org/GNOME/mutter/merge_requests/575.patch -### clutter-stage-cogl: Use regions +# clutter-stage-cogl: Use regions Patch23: https://gitlab.gnome.org/GNOME/mutter/merge_requests/692.patch -### Geometric (OpenGL-less) picking -# Patch24: https://gitlab.gnome.org/GNOME/mutter/merge_requests/189.diff +# Geometric (OpenGL-less) picking +#Patch24: https://gitlab.gnome.org/GNOME/mutter/merge_requests/189.diff -### Drop CAP_SYS_* capabilities -# Patch25: https://gitlab.gnome.org/GNOME/mutter/merge_requests/923.patch +# Drop CAP_SYS_* capabilities +#Patch25: https://gitlab.gnome.org/GNOME/mutter/merge_requests/923.patch -### Intermediate shadowfb -# Patch26: https://gitlab.gnome.org/GNOME/mutter/merge_requests/877.patch +# Intermediate shadowfb +#Patch26: https://gitlab.gnome.org/GNOME/mutter/merge_requests/877.patch -### Use regions for Cogl clipping and culling -Patch27: https://gitlab.gnome.org/GNOME/mutter/merge_requests/867.patch +# Use regions for Cogl clipping and culling +#Patch27: https://gitlab.gnome.org/GNOME/mutter/merge_requests/867.patch BuildRequires: chrpath BuildRequires: pango-devel @@ -213,6 +199,13 @@ desktop-file-validate %{buildroot}/%{_datadir}/applications/%{name}.desktop %{_datadir}/mutter-%{mutter_api_version}/tests %changelog +* Fri Jan 03 2020 Artem Polishchuk <ego.cordatus@gmail.com> - 3.34.2-1.1.performance +- With performance patches + +* Wed Dec 11 2019 Florian Müllner <fmuellner@redhat.com> - 3.34.2-1 +- Update to 3.34.2 +- Drop relevant downstream patches + * Tue Dec 03 2019 Artem Polishchuk <ego.cordatus@gmail.com> - 3.34.1-12.1.performance - With performance patches @@ -1 +1 @@ -4d7b67471fa4177e5ff0357e1f1736fb mutter-3.34.1.tar.xz +4515ccdb762a243d65757f5ab073d206 mutter-3.34.2.tar.xz |