Author: renodr Date: Mon Jul 1 21:38:25 2019 New Revision: 3951 Log: Add Mutter upstream fixes patch
Added: trunk/mutter/ trunk/mutter/mutter-3.32.2-upstream_fixes-1.patch Added: trunk/mutter/mutter-3.32.2-upstream_fixes-1.patch ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/mutter/mutter-3.32.2-upstream_fixes-1.patch Mon Jul 1 21:38:25 2019 (r3951) @@ -0,0 +1,1316 @@ +Submitted By: Douglas R. Reno <renodr at linuxfromscratch dot org> +Date: 2019-07-01 +Initial Package Version: 3.32.2 +Upstream Status: Applied +Origin: Upstream +Description: Fixes several bugs in mutter-3.32.2, including some + bugs that have to do with cogl problems and an issue + that causes a crash anytime a monitor is unplugged. + +diff -Naurp mutter-3.32.2.orig/clutter/clutter/clutter-text.c mutter-3.32.2/clutter/clutter/clutter-text.c +--- mutter-3.32.2.orig/clutter/clutter/clutter-text.c 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/clutter/clutter/clutter-text.c 2019-07-01 21:53:47.219980200 -0500 +@@ -1975,6 +1975,7 @@ selection_paint (ClutterText *self, + else + { + /* Paint selection background first */ ++ CoglPipeline *color_pipeline = cogl_pipeline_copy (default_color_pipeline); + PangoLayout *layout = clutter_text_get_layout (self); + CoglPath *selection_path = cogl_path_new (); + CoglColor cogl_color = { 0, }; +@@ -1987,11 +1988,19 @@ selection_paint (ClutterText *self, + else + color = &priv->text_color; + ++ cogl_color_init_from_4ub (&cogl_color, ++ color->red, ++ color->green, ++ color->blue, ++ paint_opacity * color->alpha / 255); ++ cogl_color_premultiply (&cogl_color); ++ cogl_pipeline_set_color (color_pipeline, &cogl_color); ++ + clutter_text_foreach_selection_rectangle_prescaled (self, + add_selection_rectangle_to_path, + selection_path); + +- cogl_path_fill (selection_path); ++ cogl_framebuffer_fill_path (fb, color_pipeline, selection_path); + + /* Paint selected text */ + cogl_framebuffer_push_path_clip (fb, selection_path); +diff -Naurp mutter-3.32.2.orig/cogl/cogl/cogl-pipeline.c mutter-3.32.2/cogl/cogl/cogl-pipeline.c +--- mutter-3.32.2.orig/cogl/cogl/cogl-pipeline.c 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/cogl/cogl/cogl-pipeline.c 2019-07-01 15:34:38.353701635 -0500 +@@ -455,9 +455,6 @@ _cogl_pipeline_free (CoglPipeline *pipel + _cogl_bitmask_destroy (&uniforms_state->changed_mask); + } + +- if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE) +- g_slice_free (CoglPipelineBigState, pipeline->big_state); +- + if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS) + { + g_list_foreach (pipeline->layer_differences, +@@ -471,6 +468,9 @@ _cogl_pipeline_free (CoglPipeline *pipel + if (pipeline->differences & COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS) + _cogl_pipeline_snippet_list_free (&pipeline->big_state->fragment_snippets); + ++ if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE) ++ g_slice_free (CoglPipelineBigState, pipeline->big_state); ++ + g_list_free (pipeline->deprecated_get_layers_list); + + recursively_free_layer_caches (pipeline); +diff -Naurp mutter-3.32.2.orig/cogl/cogl-path/cogl-path.c mutter-3.32.2/cogl/cogl-path/cogl-path.c +--- mutter-3.32.2.orig/cogl/cogl-path/cogl-path.c 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/cogl/cogl-path/cogl-path.c 2019-07-01 19:25:55.294692907 -0500 +@@ -1504,7 +1504,6 @@ cogl_framebuffer_push_path_clip (CoglFra + COGL_FRAMEBUFFER_STATE_CLIP; + } + +-/* XXX: deprecated */ + void + cogl_clip_push_from_path (CoglPath *path) + { +@@ -1575,7 +1574,6 @@ _cogl_path_build_stroke_attribute_buffer + data->stroke_n_attributes = n_attributes; + } + +-/* XXX: deprecated */ + void + cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer, + CoglPipeline *pipeline, +@@ -1588,7 +1586,6 @@ cogl_framebuffer_fill_path (CoglFramebuf + _cogl_path_fill_nodes (path, framebuffer, pipeline, 0 /* flags */); + } + +-/* XXX: deprecated */ + void + cogl_framebuffer_stroke_path (CoglFramebuffer *framebuffer, + CoglPipeline *pipeline, +diff -Naurp mutter-3.32.2.orig/cogl/cogl-path/cogl-path-functions.h mutter-3.32.2/cogl/cogl-path/cogl-path-functions.h +--- mutter-3.32.2.orig/cogl/cogl-path/cogl-path-functions.h 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/cogl/cogl-path/cogl-path-functions.h 2019-07-01 19:24:56.709323461 -0500 +@@ -460,9 +460,7 @@ cogl_path_fill (CoglPath *path); + * use while filling a path.</note> + * + * Stability: unstable +- * Deprecated: 1.16: Use cogl_path_fill() instead + */ +-COGL_DEPRECATED_FOR (cogl_path_fill) + void + cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer, + CoglPipeline *pipeline, +@@ -492,9 +490,7 @@ cogl_path_stroke (CoglPath *path); + * regardless of the current transformation matrix. + * + * Stability: unstable +- * Deprecated: 1.16: Use cogl_path_stroke() instead + */ +-COGL_DEPRECATED_FOR (cogl_path_stroke) + void + cogl_framebuffer_stroke_path (CoglFramebuffer *framebuffer, + CoglPipeline *pipeline, +@@ -529,9 +525,7 @@ cogl_framebuffer_push_path_clip (CoglFra + * + * Since: 1.8 + * Stability: Unstable +- * Deprecated: 1.16: Use cogl_framebuffer_push_path_clip() instead + */ +-COGL_DEPRECATED_FOR (cogl_framebuffer_push_path_clip) + void + cogl_clip_push_from_path (CoglPath *path); + +diff -Naurp mutter-3.32.2.orig/src/backends/meta-renderer.c mutter-3.32.2/src/backends/meta-renderer.c +--- mutter-3.32.2.orig/src/backends/meta-renderer.c 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/src/backends/meta-renderer.c 2019-07-01 21:29:17.909560150 -0500 +@@ -91,6 +91,12 @@ meta_renderer_create_view (MetaRenderer + void + meta_renderer_rebuild_views (MetaRenderer *renderer) + { ++ return META_RENDERER_GET_CLASS (renderer)->rebuild_views (renderer); ++} ++ ++static void ++meta_renderer_real_rebuild_views (MetaRenderer *renderer) ++{ + MetaRendererPrivate *priv = meta_renderer_get_instance_private (renderer); + MetaBackend *backend = meta_get_backend (); + MetaMonitorManager *monitor_manager = +@@ -181,4 +187,6 @@ meta_renderer_class_init (MetaRendererCl + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_renderer_finalize; ++ ++ klass->rebuild_views = meta_renderer_real_rebuild_views; + } +diff -Naurp mutter-3.32.2.orig/src/backends/meta-renderer.h mutter-3.32.2/src/backends/meta-renderer.h +--- mutter-3.32.2.orig/src/backends/meta-renderer.h 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/src/backends/meta-renderer.h 2019-07-01 21:30:06.639038031 -0500 +@@ -43,6 +43,7 @@ struct _MetaRendererClass + CoglRenderer * (* create_cogl_renderer) (MetaRenderer *renderer); + MetaRendererView * (* create_view) (MetaRenderer *renderer, + MetaLogicalMonitor *logical_monitor); ++ void (* rebuild_views) (MetaRenderer *renderer); + }; + + CoglRenderer * meta_renderer_create_cogl_renderer (MetaRenderer *renderer); +diff -Naurp mutter-3.32.2.orig/src/backends/native/meta-cursor-renderer-native.c mutter-3.32.2/src/backends/native/meta-cursor-renderer-native.c +--- mutter-3.32.2.orig/src/backends/native/meta-cursor-renderer-native.c 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/src/backends/native/meta-cursor-renderer-native.c 2019-07-01 15:32:14.572326991 -0500 +@@ -823,6 +823,7 @@ static void + cursor_priv_free (MetaCursorNativePrivate *cursor_priv) + { + g_hash_table_destroy (cursor_priv->gpu_states); ++ g_free (cursor_priv); + } + + static MetaCursorNativePrivate * +diff -Naurp mutter-3.32.2.orig/src/backends/native/meta-renderer-native.c mutter-3.32.2/src/backends/native/meta-renderer-native.c +--- mutter-3.32.2.orig/src/backends/native/meta-renderer-native.c 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/src/backends/native/meta-renderer-native.c 2019-07-01 22:16:57.469120864 -0500 +@@ -258,6 +258,9 @@ cogl_pixel_format_from_drm_format (uint3 + CoglPixelFormat *out_format, + CoglTextureComponents *out_components); + ++static void ++meta_renderer_native_queue_modes_reset (MetaRendererNative *renderer_native); ++ + static MetaBackend * + backend_from_renderer_native (MetaRendererNative *renderer_native) + { +@@ -1277,7 +1280,7 @@ meta_renderer_native_egl_context_created + cogl_display_egl->dummy_surface, + cogl_display_egl->egl_context)) + { +- _cogl_set_error (error, COGL_WINSYS_ERROR, ++ g_set_error (error, COGL_WINSYS_ERROR, + COGL_WINSYS_ERROR_CREATE_CONTEXT, + "Failed to make context current"); + return FALSE; +@@ -3036,10 +3039,52 @@ meta_onscreen_native_allocate (CoglOnscr + } + + static void ++destroy_egl_surface (CoglOnscreen *onscreen) ++{ ++ CoglOnscreenEGL *onscreen_egl = onscreen->winsys; ++ ++ if (onscreen_egl->egl_surface != EGL_NO_SURFACE) ++ { ++ MetaOnscreenNative *onscreen_native = onscreen_egl->platform; ++ MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native); ++ CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); ++ CoglContext *cogl_context = framebuffer->context; ++ CoglRenderer *cogl_renderer = cogl_context->display->renderer; ++ CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; ++ ++ meta_egl_destroy_surface (egl, ++ cogl_renderer_egl->edpy, ++ onscreen_egl->egl_surface, ++ NULL); ++ onscreen_egl->egl_surface = EGL_NO_SURFACE; ++ } ++} ++ ++static void ++discard_onscreen_page_flip_retries (MetaOnscreenNative *onscreen_native) ++{ ++ g_list_free_full (onscreen_native->pending_page_flip_retries, ++ (GDestroyNotify) retry_page_flip_data_free); ++ onscreen_native->pending_page_flip_retries = NULL; ++ ++ if (onscreen_native->retry_page_flips_source) ++ { ++ MetaBackend *backend = ++ backend_from_renderer_native (onscreen_native->renderer_native); ++ ++ meta_backend_thaw_updates (backend); ++ g_clear_pointer (&onscreen_native->retry_page_flips_source, ++ g_source_destroy); ++ } ++} ++ ++static void + meta_renderer_native_release_onscreen (CoglOnscreen *onscreen) + { + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + CoglContext *cogl_context = framebuffer->context; ++ CoglDisplay *cogl_display = cogl_context_get_display (cogl_context); ++ CoglDisplayEGL *cogl_display_egl = cogl_display->winsys; + CoglRenderer *cogl_renderer = cogl_context->display->renderer; + CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; +@@ -3052,28 +3097,18 @@ meta_renderer_native_release_onscreen (C + + onscreen_native = onscreen_egl->platform; + +- g_list_free_full (onscreen_native->pending_page_flip_retries, +- (GDestroyNotify) retry_page_flip_data_free); +- if (onscreen_native->retry_page_flips_source) +- { +- MetaBackend *backend = +- backend_from_renderer_native (onscreen_native->renderer_native); +- +- meta_backend_thaw_updates (backend); +- g_clear_pointer (&onscreen_native->retry_page_flips_source, +- g_source_destroy); +- } +- +- if (onscreen_egl->egl_surface != EGL_NO_SURFACE) +- { +- MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native); ++ if (onscreen_egl->egl_surface != EGL_NO_SURFACE && ++ (cogl_display_egl->current_draw_surface == onscreen_egl->egl_surface || ++ cogl_display_egl->current_read_surface == onscreen_egl->egl_surface)) ++ { ++ if (!_cogl_winsys_egl_make_current (cogl_display, ++ cogl_display_egl->dummy_surface, ++ cogl_display_egl->dummy_surface, ++ cogl_display_egl->egl_context)) ++ g_warning ("Failed to clear current context"); ++ } + +- meta_egl_destroy_surface (egl, +- cogl_renderer_egl->edpy, +- onscreen_egl->egl_surface, +- NULL); +- onscreen_egl->egl_surface = EGL_NO_SURFACE; +- } ++ discard_onscreen_page_flip_retries (onscreen_native); + + renderer_gpu_data = + meta_renderer_native_get_gpu_data (onscreen_native->renderer_native, +@@ -3087,6 +3122,8 @@ meta_renderer_native_release_onscreen (C + + free_current_bo (onscreen); + ++ destroy_egl_surface (onscreen); ++ + if (onscreen_native->gbm.surface) + { + gbm_surface_destroy (onscreen_native->gbm.surface); +@@ -3097,6 +3134,9 @@ meta_renderer_native_release_onscreen (C + case META_RENDERER_NATIVE_MODE_EGL_DEVICE: + release_dumb_fb (&onscreen_native->egl.dumb_fb, + onscreen_native->render_gpu); ++ ++ destroy_egl_surface (onscreen); ++ + if (onscreen_native->egl.stream != EGL_NO_STREAM_KHR) + { + MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native); +@@ -3157,7 +3197,7 @@ meta_renderer_native_supports_mirroring + return TRUE; + } + +-void ++static void + meta_renderer_native_queue_modes_reset (MetaRendererNative *renderer_native) + { + MetaRenderer *renderer = META_RENDERER (renderer_native); +@@ -3523,6 +3563,37 @@ meta_renderer_native_create_view (MetaRe + return view; + } + ++static void ++discard_page_flip_retries (MetaRenderer *renderer) ++{ ++ GList *l; ++ ++ for (l = meta_renderer_get_views (renderer); l; l = l->next) ++ { ++ ClutterStageView *stage_view = l->data; ++ CoglFramebuffer *framebuffer = ++ clutter_stage_view_get_onscreen (stage_view); ++ CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); ++ CoglOnscreenEGL *onscreen_egl = onscreen->winsys; ++ MetaOnscreenNative *onscreen_native = onscreen_egl->platform; ++ ++ discard_onscreen_page_flip_retries (onscreen_native); ++ } ++} ++ ++static void ++meta_renderer_native_rebuild_views (MetaRenderer *renderer) ++{ ++ MetaRendererClass *parent_renderer_class = ++ META_RENDERER_CLASS (meta_renderer_native_parent_class); ++ ++ discard_page_flip_retries (renderer); ++ ++ parent_renderer_class->rebuild_views (renderer); ++ ++ meta_renderer_native_queue_modes_reset (META_RENDERER_NATIVE (renderer)); ++} ++ + void + meta_renderer_native_finish_frame (MetaRendererNative *renderer_native) + { +@@ -4038,6 +4109,7 @@ create_renderer_gpu_data_egl_device (Met + G_IO_ERROR_FAILED, + "Missing EGL extensions required for EGLDevice renderer: %s", + missing_extensions_str); ++ meta_egl_terminate (egl, egl_display, NULL); + g_free (missing_extensions_str); + g_free (missing_extensions); + return NULL; +@@ -4320,6 +4392,7 @@ meta_renderer_native_class_init (MetaRen + + renderer_class->create_cogl_renderer = meta_renderer_native_create_cogl_renderer; + renderer_class->create_view = meta_renderer_native_create_view; ++ renderer_class->rebuild_views = meta_renderer_native_rebuild_views; + + obj_props[PROP_MONITOR_MANAGER] = + g_param_spec_object ("monitor-manager", +diff -Naurp mutter-3.32.2.orig/src/backends/native/meta-renderer-native.h mutter-3.32.2/src/backends/native/meta-renderer-native.h +--- mutter-3.32.2.orig/src/backends/native/meta-renderer-native.h 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/src/backends/native/meta-renderer-native.h 2019-07-01 21:32:29.002358942 -0500 +@@ -53,20 +53,6 @@ struct gbm_device * meta_gbm_device_from + + gboolean meta_renderer_native_supports_mirroring (MetaRendererNative *renderer_native); + +-void meta_renderer_native_queue_modes_reset (MetaRendererNative *renderer_native); +- +-gboolean meta_renderer_native_set_legacy_view_size (MetaRendererNative *renderer_native, +- MetaRendererView *view, +- int width, +- int height, +- GError **error); +- +-void meta_renderer_native_set_ignore_crtc (MetaRendererNative *renderer_native, +- uint32_t id, +- gboolean ignore); +- +-MetaRendererView * meta_renderer_native_create_legacy_view (MetaRendererNative *renderer_native); +- + void meta_renderer_native_finish_frame (MetaRendererNative *renderer_native); + + int64_t meta_renderer_native_get_frame_counter (MetaRendererNative *renderer_native); +diff -Naurp mutter-3.32.2.orig/src/backends/native/meta-stage-native.c mutter-3.32.2/src/backends/native/meta-stage-native.c +--- mutter-3.32.2.orig/src/backends/native/meta-stage-native.c 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/src/backends/native/meta-stage-native.c 2019-07-01 21:32:42.082756164 -0500 +@@ -140,7 +140,6 @@ meta_stage_native_rebuild_views (MetaSta + ClutterActor *stage = meta_backend_get_stage (backend); + + meta_renderer_rebuild_views (renderer); +- meta_renderer_native_queue_modes_reset (META_RENDERER_NATIVE (renderer)); + clutter_stage_update_resource_scales (CLUTTER_STAGE (stage)); + ensure_frame_callbacks (stage_native); + } +diff -Naurp mutter-3.32.2.orig/src/compositor/meta-surface-actor-x11.c mutter-3.32.2/src/compositor/meta-surface-actor-x11.c +--- mutter-3.32.2.orig/src/compositor/meta-surface-actor-x11.c 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/src/compositor/meta-surface-actor-x11.c 2019-07-01 21:56:24.326747542 -0500 +@@ -32,6 +32,7 @@ + #include "cogl/winsys/cogl-texture-pixmap-x11.h" + #include "compositor/meta-cullable.h" + #include "compositor/meta-shaped-texture-private.h" ++#include "compositor/meta-window-actor-private.h" + #include "core/window-private.h" + #include "meta/meta-x11-errors.h" + #include "x11/meta-x11-display-private.h" +@@ -71,11 +72,13 @@ static void + free_damage (MetaSurfaceActorX11 *self) + { + MetaDisplay *display = self->display; +- Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display); ++ Display *xdisplay; + + if (self->damage == None) + return; + ++ xdisplay = meta_x11_display_get_xdisplay (display->x11_display); ++ + meta_x11_error_trap_push (display->x11_display); + XDamageDestroy (xdisplay, self->damage); + self->damage = None; +@@ -86,12 +89,14 @@ static void + detach_pixmap (MetaSurfaceActorX11 *self) + { + MetaDisplay *display = self->display; +- Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display); + MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); ++ Display *xdisplay; + + if (self->pixmap == None) + return; + ++ xdisplay = meta_x11_display_get_xdisplay (display->x11_display); ++ + /* Get rid of all references to the pixmap before freeing it; it's unclear whether + * you are supposed to be able to free a GLXPixmap after freeing the underlying + * pixmap, but it certainly doesn't work with current DRI/Mesa +@@ -344,12 +349,18 @@ meta_surface_actor_x11_is_unredirected ( + } + + static void ++release_x11_resources (MetaSurfaceActorX11 *self) ++{ ++ detach_pixmap (self); ++ free_damage (self); ++} ++ ++static void + meta_surface_actor_x11_dispose (GObject *object) + { + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (object); + +- detach_pixmap (self); +- free_damage (self); ++ release_x11_resources (self); + + G_OBJECT_CLASS (meta_surface_actor_x11_parent_class)->dispose (object); + } +@@ -403,8 +414,7 @@ window_decorated_notify (MetaWindow *win + { + MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (user_data); + +- detach_pixmap (self); +- free_damage (self); ++ release_x11_resources (self); + create_damage (self); + } + +@@ -441,6 +451,10 @@ meta_surface_actor_x11_new (MetaWindow * + g_signal_connect_object (self->window, "notify::decorated", + G_CALLBACK (window_decorated_notify), self, 0); + ++ g_signal_connect_object (meta_window_actor_from_window (window), "destroy", ++ G_CALLBACK (release_x11_resources), self, ++ G_CONNECT_SWAPPED); ++ + self->unredirected = FALSE; + sync_unredirected (self); + +diff -Naurp mutter-3.32.2.orig/src/compositor/meta-window-actor.c mutter-3.32.2/src/compositor/meta-window-actor.c +--- mutter-3.32.2.orig/src/compositor/meta-window-actor.c 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/src/compositor/meta-window-actor.c 2019-07-01 21:45:27.896855286 -0500 +@@ -417,7 +417,7 @@ meta_window_actor_update_surface (MetaWi + else + surface_actor = NULL; + +- set_surface (self, surface_actor); ++ META_WINDOW_ACTOR_GET_CLASS (self)->set_surface_actor (self, surface_actor); + } + + static void +@@ -430,6 +430,9 @@ meta_window_actor_constructed (GObject * + + priv->compositor = window->display->compositor; + ++ /* Hang out compositor window state off the MetaWindow for fast retrieval */ ++ meta_window_set_compositor_private (window, object); ++ + meta_window_actor_update_surface (self); + + meta_window_actor_update_opacity (self); +@@ -446,9 +449,6 @@ meta_window_actor_constructed (GObject * + priv->first_frame_state = DRAWING_FIRST_FRAME; + + meta_window_actor_sync_actor_geometry (self, priv->window->placed); +- +- /* Hang our compositor window state off the MetaWindow for fast retrieval */ +- meta_window_set_compositor_private (window, object); + } + + static void +@@ -476,7 +476,7 @@ meta_window_actor_dispose (GObject *obje + + g_clear_object (&priv->window); + +- set_surface (self, NULL); ++ META_WINDOW_ACTOR_GET_CLASS (self)->set_surface_actor (self, NULL); + + G_OBJECT_CLASS (meta_window_actor_parent_class)->dispose (object); + } +diff -Naurp mutter-3.32.2.orig/src/core/display.c mutter-3.32.2/src/core/display.c +--- mutter-3.32.2.orig/src/core/display.c 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/src/core/display.c 2019-07-01 19:45:08.198338254 -0500 +@@ -920,10 +920,6 @@ meta_display_close (MetaDisplay *display + + g_clear_object (&display->gesture_tracker); + +- g_clear_pointer (&display->stack, meta_stack_free); +- g_clear_pointer (&display->stack_tracker, +- meta_stack_tracker_free); +- + if (display->focus_timeout_id) + g_source_remove (display->focus_timeout_id); + display->focus_timeout_id = 0; +@@ -940,12 +936,6 @@ meta_display_close (MetaDisplay *display + /* Stop caring about events */ + meta_display_free_events (display); + +- /* Must be after all calls to meta_window_unmanage() since they +- * unregister windows +- */ +- g_hash_table_destroy (display->wayland_windows); +- g_hash_table_destroy (display->stamps); +- + if (display->compositor) + meta_compositor_destroy (display->compositor); + +@@ -956,6 +946,16 @@ meta_display_close (MetaDisplay *display + g_clear_object (&display->x11_display); + } + ++ /* Must be after all calls to meta_window_unmanage() since they ++ * unregister windows. ++ */ ++ g_hash_table_destroy (display->wayland_windows); ++ g_hash_table_destroy (display->stamps); ++ ++ g_clear_pointer (&display->stack, meta_stack_free); ++ g_clear_pointer (&display->stack_tracker, ++ meta_stack_tracker_free); ++ + meta_display_shutdown_keys (display); + + g_clear_object (&display->bell); +diff -Naurp mutter-3.32.2.orig/src/core/window.c mutter-3.32.2/src/core/window.c +--- mutter-3.32.2.orig/src/core/window.c 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/src/core/window.c 2019-07-01 21:26:50.469092870 -0500 +@@ -3683,6 +3683,12 @@ meta_window_activate_full (MetaWindow + { + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + gboolean allow_workspace_switch; ++ ++ if (window->unmanaging) ++ { ++ g_warning ("Trying to activate unmanaged window '%s'", window->desc); ++ return; ++ } + meta_topic (META_DEBUG_FOCUS, + "_NET_ACTIVE_WINDOW message sent for %s at time %u " + "by client type %u.\n", +@@ -8562,6 +8568,8 @@ meta_window_shortcuts_inhibited (MetaWin + gboolean + meta_window_is_focusable (MetaWindow *window) + { ++ g_return_val_if_fail (!window->unmanaging, FALSE); ++ + return META_WINDOW_GET_CLASS (window)->is_focusable (window); + } + +diff -Naurp mutter-3.32.2.orig/src/core/workspace.c mutter-3.32.2/src/core/workspace.c +--- mutter-3.32.2.orig/src/core/workspace.c 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/src/core/workspace.c 2019-07-01 20:10:06.621801394 -0500 +@@ -85,6 +85,12 @@ typedef struct _MetaWorkspaceLogicalMoni + MetaRectangle logical_monitor_work_area; + } MetaWorkspaceLogicalMonitorData; + ++typedef struct _MetaWorkspaceFocusableAncestorData ++{ ++ MetaWorkspace *workspace; ++ MetaWindow *out_window; ++} MetaWorkspaceFocusableAncestorData; ++ + static MetaWorkspaceLogicalMonitorData * + meta_workspace_get_logical_monitor_data (MetaWorkspace *workspace, + MetaLogicalMonitor *logical_monitor) +@@ -1322,13 +1328,20 @@ meta_workspace_focus_default_window (Met + } + + static gboolean +-record_ancestor (MetaWindow *window, +- void *data) ++find_focusable_ancestor (MetaWindow *window, ++ gpointer user_data) + { +- MetaWindow **result = data; ++ MetaWorkspaceFocusableAncestorData *data = user_data; ++ ++ if (!window->unmanaging && meta_window_is_focusable (window) && ++ meta_window_located_on_workspace (window, data->workspace) && ++ meta_window_showing_on_its_workspace (window)) ++ { ++ data->out_window = window; ++ return FALSE; ++ } + +- *result = window; +- return FALSE; /* quit with the first ancestor we find */ ++ return TRUE; + } + + /* Focus ancestor of not_this_one if there is one */ +@@ -1350,11 +1363,15 @@ focus_ancestor_or_top_window (MetaWorksp + if (not_this_one) + { + MetaWindow *ancestor; +- ancestor = NULL; +- meta_window_foreach_ancestor (not_this_one, record_ancestor, &ancestor); +- if (ancestor != NULL && +- meta_window_located_on_workspace (ancestor, workspace) && +- meta_window_showing_on_its_workspace (ancestor)) ++ MetaWorkspaceFocusableAncestorData data; ++ ++ data = (MetaWorkspaceFocusableAncestorData) { ++ .workspace = workspace, ++ }; ++ meta_window_foreach_ancestor (not_this_one, find_focusable_ancestor, &data); ++ ancestor = data.out_window; ++ ++ if (ancestor) + { + meta_topic (META_DEBUG_FOCUS, + "Focusing %s, ancestor of %s\n", +diff -Naurp mutter-3.32.2.orig/src/tests/headless-start-test.c mutter-3.32.2/src/tests/headless-start-test.c +--- mutter-3.32.2.orig/src/tests/headless-start-test.c 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/src/tests/headless-start-test.c 2019-07-01 22:22:11.322620952 -0500 +@@ -32,6 +32,7 @@ + #include "wayland/meta-wayland.h" + + #define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1) ++#define FRAME_WARNING "Frame has assigned frame counter but no frame drawn time" + + static gboolean + run_tests (gpointer data) +@@ -40,6 +41,8 @@ run_tests (gpointer data) + MetaSettings *settings = meta_backend_get_settings (backend); + gboolean ret; + ++ g_test_log_set_fatal_handler (NULL, NULL); ++ + meta_settings_override_experimental_features (settings); + + meta_settings_enable_experimental_feature ( +@@ -53,6 +56,20 @@ run_tests (gpointer data) + return FALSE; + } + ++static gboolean ++ignore_frame_counter_warning (const gchar *log_domain, ++ GLogLevelFlags log_level, ++ const gchar *message, ++ gpointer user_data) ++{ ++ if ((log_level & G_LOG_LEVEL_WARNING) && ++ g_strcmp0 (log_domain, "mutter") == 0 && ++ g_str_has_suffix (message, FRAME_WARNING)) ++ return FALSE; ++ ++ return TRUE; ++} ++ + static void + meta_test_headless_start (void) + { +@@ -193,6 +210,8 @@ main (int argc, char *argv[]) + meta_init (); + meta_register_with_session (); + ++ g_test_log_set_fatal_handler (ignore_frame_counter_warning, NULL); ++ + g_idle_add (run_tests, NULL); + + return meta_run (); +diff -Naurp mutter-3.32.2.orig/src/tests/meson.build mutter-3.32.2/src/tests/meson.build +--- mutter-3.32.2.orig/src/tests/meson.build 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/src/tests/meson.build 2019-07-01 21:10:58.824632410 -0500 +@@ -38,6 +38,7 @@ test_client = executable('mutter-test-cl + dependencies: [ + gtk3_dep, + gio_unix_dep, ++ x11_dep, + xext_dep, + ], + install: have_installed_tests, +@@ -104,6 +105,10 @@ headless_start_test = executable('mutter + stacking_tests = files([ + 'stacking/basic-x11.metatest', + 'stacking/basic-wayland.metatest', ++ 'stacking/closed-transient-no-input-no-take-focus-parent.metatest', ++ 'stacking/closed-transient-no-input-no-take-focus-parents.metatest', ++ 'stacking/closed-transient-no-input-parent.metatest', ++ 'stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest', + 'stacking/minimized.metatest', + 'stacking/mixed-windows.metatest', + 'stacking/set-parent.metatest', +diff -Naurp mutter-3.32.2.orig/src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest mutter-3.32.2/src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest +--- mutter-3.32.2.orig/src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest 1969-12-31 18:00:00.000000000 -0600 ++++ mutter-3.32.2/src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest 2019-07-01 21:02:07.799603150 -0500 +@@ -0,0 +1,23 @@ ++new_client 1 x11 ++create 1/1 ++show 1/1 ++ ++create 1/2 csd ++set_parent 1/2 1 ++can_take_focus 1/2 false ++accept_focus 1/2 false ++show 1/2 ++ ++create 1/3 csd ++set_parent 1/3 2 ++show 1/3 ++ ++wait ++assert_focused 1/3 ++assert_stacking 1/1 1/2 1/3 ++ ++destroy 1/3 ++ ++wait ++assert_focused 1/1 ++assert_stacking 1/1 1/2 +diff -Naurp mutter-3.32.2.orig/src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest mutter-3.32.2/src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest +--- mutter-3.32.2.orig/src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest 1969-12-31 18:00:00.000000000 -0600 ++++ mutter-3.32.2/src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest 2019-07-01 21:03:13.105379567 -0500 +@@ -0,0 +1,30 @@ ++new_client 2 x11 ++create 2/1 ++show 2/1 ++wait ++ ++new_client 1 x11 ++create 1/1 ++accept_focus 1/1 false ++can_take_focus 1/1 false ++show 1/1 ++ ++create 1/2 csd ++set_parent 1/2 1 ++can_take_focus 1/2 false ++accept_focus 1/2 false ++show 1/2 ++ ++create 1/3 csd ++set_parent 1/3 2 ++show 1/3 ++ ++wait ++assert_focused 1/3 ++assert_stacking 2/1 1/1 1/2 1/3 ++ ++destroy 1/3 ++ ++wait ++assert_stacking 1/1 1/2 2/1 ++assert_focused 2/1 +diff -Naurp mutter-3.32.2.orig/src/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest mutter-3.32.2/src/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest +--- mutter-3.32.2.orig/src/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest 1969-12-31 18:00:00.000000000 -0600 ++++ mutter-3.32.2/src/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest 2019-07-01 21:13:19.449765239 -0500 +@@ -0,0 +1,36 @@ ++new_client 2 x11 ++create 2/1 ++show 2/1 ++ ++new_client 1 x11 ++create 1/1 ++show 1/1 ++ ++create 1/2 csd ++set_parent 1/2 1 ++accept_focus 1/2 false ++show 1/2 ++ ++create 1/3 csd ++set_parent 1/3 2 ++show 1/3 ++ ++wait ++assert_focused 1/3 ++assert_stacking 2/1 1/1 1/2 1/3 ++ ++destroy 1/3 ++sleep 10 ++ ++assert_focused none ++assert_stacking 2/1 1/1 1/2 ++ ++activate 2/1 ++wait ++ ++assert_focused 2/1 ++assert_stacking 1/1 1/2 2/1 ++ ++sleep 250 ++assert_focused 2/1 ++assert_stacking 1/1 1/2 2/1 +diff -Naurp mutter-3.32.2.orig/src/tests/stacking/closed-transient-no-input-parent.metatest mutter-3.32.2/src/tests/stacking/closed-transient-no-input-parent.metatest +--- mutter-3.32.2.orig/src/tests/stacking/closed-transient-no-input-parent.metatest 1969-12-31 18:00:00.000000000 -0600 ++++ mutter-3.32.2/src/tests/stacking/closed-transient-no-input-parent.metatest 2019-07-01 21:14:55.447607995 -0500 +@@ -0,0 +1,30 @@ ++new_client 2 x11 ++create 2/1 ++show 2/1 ++ ++new_client 1 x11 ++create 1/1 ++show 1/1 ++ ++create 1/2 csd ++set_parent 1/2 1 ++accept_focus 1/2 false ++show 1/2 ++ ++create 1/3 csd ++set_parent 1/3 2 ++show 1/3 ++ ++wait ++assert_focused 1/3 ++assert_stacking 2/1 1/1 1/2 1/3 ++ ++destroy 1/3 ++dispatch ++ ++assert_focused none ++assert_stacking 2/1 1/1 1/2 ++ ++sleep 250 ++assert_focused 1/1 ++assert_stacking 2/1 1/1 1/2 +diff -Naurp mutter-3.32.2.orig/src/tests/test-client.c mutter-3.32.2/src/tests/test-client.c +--- mutter-3.32.2.orig/src/tests/test-client.c 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/src/tests/test-client.c 2019-07-01 20:30:52.597491726 -0500 +@@ -196,6 +196,74 @@ process_line (const char *line) + NULL)) + g_print ("Fail to export handle for window id %s", argv[2]); + } ++ else if (strcmp (argv[0], "accept_focus") == 0) ++ { ++ if (argc != 3) ++ { ++ g_print ("usage: %s <window-id> [true|false", argv[0]); ++ goto out; ++ } ++ ++ GtkWidget *window = lookup_window (argv[1]); ++ if (!window) ++ { ++ g_print ("unknown window %s", argv[1]); ++ goto out; ++ } ++ ++ gboolean enabled = g_ascii_strcasecmp (argv[2], "true") == 0; ++ gtk_window_set_accept_focus (GTK_WINDOW (window), enabled); ++ } ++ else if (strcmp (argv[0], "can_take_focus") == 0) ++ { ++ if (argc != 3) ++ { ++ g_print ("usage: %s <window-id> [true|false]", argv[0]); ++ goto out; ++ } ++ ++ GtkWidget *window = lookup_window (argv[1]); ++ if (!window) ++ { ++ g_print ("unknown window %s", argv[1]); ++ goto out; ++ } ++ ++ if (wayland) ++ { ++ g_print ("%s is not supported under wayland", argv[0]); ++ goto out; ++ } ++ ++ GdkDisplay *display = gdk_display_get_default (); ++ GdkWindow *gdkwindow = gtk_widget_get_window (window); ++ Display *xdisplay = gdk_x11_display_get_xdisplay (display); ++ Window xwindow = GDK_WINDOW_XID (gdkwindow); ++ Atom wm_take_focus = gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS"); ++ gboolean add = g_ascii_strcasecmp(argv[2], "true") == 0; ++ Atom *protocols = NULL; ++ Atom *new_protocols; ++ int n_protocols = 0; ++ int i, n = 0; ++ ++ gdk_display_sync (display); ++ XGetWMProtocols (xdisplay, xwindow, &protocols, &n_protocols); ++ new_protocols = g_new0 (Atom, n_protocols + (add ? 1 : 0)); ++ ++ for (i = 0; i < n_protocols; ++i) ++ { ++ if (protocols[i] != wm_take_focus) ++ new_protocols[n++] = protocols[i]; ++ } ++ ++ if (add) ++ new_protocols[n++] = wm_take_focus; ++ ++ XSetWMProtocols (xdisplay, xwindow, new_protocols, n); ++ ++ XFree (new_protocols); ++ XFree (protocols); ++ } + else if (strcmp (argv[0], "show") == 0) + { + if (argc != 2) +diff -Naurp mutter-3.32.2.orig/src/tests/test-runner.c mutter-3.32.2/src/tests/test-runner.c +--- mutter-3.32.2.orig/src/tests/test-runner.c 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/src/tests/test-runner.c 2019-07-01 21:10:08.129153559 -0500 +@@ -77,7 +77,7 @@ test_case_new (void) + } + + static gboolean +-test_case_before_redraw (gpointer data) ++test_case_loop_quit (gpointer data) + { + TestCase *test = data; + +@@ -87,6 +87,23 @@ test_case_before_redraw (gpointer data) + } + + static gboolean ++test_case_dispatch (TestCase *test, ++ GError **error) ++{ ++ /* Wait until we've done any outstanding queued up work. ++ * Although we add this as BEFORE_REDRAW, the iteration that runs the ++ * BEFORE_REDRAW idles will proceed on and do the redraw, so we're ++ * waiting until after *ALL* frame processing is completed. ++ */ ++ meta_later_add (META_LATER_BEFORE_REDRAW, ++ test_case_loop_quit, ++ test, ++ NULL); ++ g_main_loop_run (test->loop); ++ ++ return TRUE; ++} ++static gboolean + test_case_wait (TestCase *test, + GError **error) + { +@@ -102,16 +119,8 @@ test_case_wait (TestCase *test, + if (!test_client_wait (value, error)) + return FALSE; + +- /* Then wait until we've done any outstanding queued up work. +- * Though we add this as BEFORE_REDRAW, the iteration that runs the +- * BEFORE_REDRAW idles will proceed on and do the redraw, so we're +- * waiting until after *all* frame processing. +- */ +- meta_later_add (META_LATER_BEFORE_REDRAW, +- test_case_before_redraw, +- test, +- NULL); +- g_main_loop_run (test->loop); ++ /* Now, we need to wait until we've done any outstanding work.*/ ++ test_case_dispatch (test, error); + + /* Then set an XSync counter ourselves and and wait until + * we receive the resulting event - this makes sure that we've +@@ -121,6 +130,16 @@ test_case_wait (TestCase *test, + return TRUE; + } + ++static gboolean ++test_case_sleep (TestCase *test, ++ guint32 interval, ++ GError **error) ++{ ++ g_timeout_add_full (G_PRIORITY_LOW, interval, test_case_loop_quit, test, NULL); ++ g_main_loop_run (test->loop); ++ ++ return TRUE; ++} + #define BAD_COMMAND(...) \ + G_STMT_START { \ + g_set_error (error, \ +@@ -238,6 +257,37 @@ test_case_assert_stacking (TestCase *tes + } + + static gboolean ++test_case_assert_focused (TestCase *test, ++ const char *expected_window, ++ GError **error) ++{ ++ MetaDisplay *display = meta_get_display (); ++ ++ if (!display -> focus_window) ++ { ++ if (g_strcmp0 (expected_window, "none") != 0) ++ { ++ g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_ASSERTION_FAILED, ++ "focus: expected='%s', actual='none'", expected_window); ++ } ++ } ++ else ++ { ++ const char *focused = display->focus_window->title; ++ ++ if (g_str_has_prefix (focused, "test/")) ++ focused += 5; ++ ++ if (g_strcmp0 (focused, "test/")) ++ g_set_error(error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_ASSERTION_FAILED, ++ "focus: expected='%s', actual='%s'", ++ expected_window, focused); ++ } ++ ++ return *error == NULL; ++} ++ ++static gboolean + test_case_check_xserver_stacking (TestCase *test, + GError **error) + { +@@ -385,6 +435,9 @@ test_case_do (TestCase *test, + argc == 3 ? argv[2] : NULL, + NULL)) + return FALSE; ++ ++ if (!test_client_wait (client, error)) ++ return FALSE; + } + else if (strcmp (argv[0], "set_parent") == 0 || + strcmp (argv[0], "set_parent_exported") == 0) +@@ -404,6 +457,44 @@ test_case_do (TestCase *test, + NULL)) + return FALSE; + } ++ else if (strcmp (argv[0], "accept_focus") == 0) ++ { ++ if (argc != 3 || ++ (g_ascii_strcasecmp (argv[2], "true") != 0 && ++ g_ascii_strcasecmp (argv[2], "false") != 0)) ++ BAD_COMMAND("usage: %s <client-id>/<window-id> [true|false]", ++ argv[0]); ++ ++ TestClient *client; ++ const char *window_id; ++ if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error)) ++ return FALSE; ++ ++ if (!test_client_do (client, error, ++ argv[0], window_id, ++ argv[2], ++ NULL)) ++ return FALSE; ++ } ++ else if (strcmp (argv[0], "can_take_focus") == 0) ++ { ++ if (argc != 3 || ++ (g_ascii_strcasecmp (argv[2], "true") != 0 && ++ g_ascii_strcasecmp (argv[2], "false") != 0)) ++ BAD_COMMAND("usage: %s <client-id>/<window-id> [true|false]", ++ argv[0]); ++ ++ TestClient *client; ++ const char *window_id; ++ if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error)) ++ return FALSE; ++ ++ if (!test_client_do (client, error, ++ argv[0], window_id, ++ argv[2], ++ NULL)) ++ return FALSE; ++ } + else if (strcmp (argv[0], "show") == 0) + { + if (argc != 2) +@@ -477,6 +568,28 @@ test_case_do (TestCase *test, + if (!test_case_wait (test, error)) + return FALSE; + } ++ else if (strcmp (argv[0], "dispatch") == 0) ++ { ++ if (argc != 1) ++ BAD_COMMAND("usage: %s", argv[0]); ++ ++ if (!test_case_dispatch (test,error)) ++ return FALSE; ++ } ++ else if (strcmp (argv[0], "sleep") == 0) ++ { ++ guint64 interval; ++ ++ if (argc != 2) ++ BAD_COMMAND("usage: %s <milliseconds>", argv[0]); ++ ++ if (!g_ascii_string_to_unsigned (argv[1], 10, 0, G_MAXUINT32, ++ &interval, error)) ++ return FALSE; ++ ++ if (!test_case_sleep (test, (guint32) interval, error)) ++ return FALSE; ++ } + else if (strcmp (argv[0], "assert_stacking") == 0) + { + if (!test_case_assert_stacking (test, argv + 1, argc - 1, error)) +@@ -485,6 +598,11 @@ test_case_do (TestCase *test, + if (!test_case_check_xserver_stacking (test, error)) + return FALSE; + } ++ else if (strcmp (argv[0], "assert_focused") == 0) ++ { ++ if (!test_case_assert_focused (test, argv[1], error)) ++ return FALSE; ++ } + else + { + BAD_COMMAND("Unknown command %s", argv[0]); +diff -Naurp mutter-3.32.2.orig/src/wayland/meta-wayland-cursor-surface.c mutter-3.32.2/src/wayland/meta-wayland-cursor-surface.c +--- mutter-3.32.2.orig/src/wayland/meta-wayland-cursor-surface.c 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/src/wayland/meta-wayland-cursor-surface.c 2019-07-01 19:36:41.018322852 -0500 +@@ -170,8 +170,9 @@ meta_wayland_cursor_surface_commit (Meta + wl_list_init (&pending->frame_callback_list); + + if (pending->newly_attached && +- (!cairo_region_is_empty (pending->surface_damage) || +- !cairo_region_is_empty (pending->buffer_damage))) ++ ((!cairo_region_is_empty (pending->surface_damage) || ++ !cairo_region_is_empty (pending->buffer_damage)) || ++ !priv->buffer)) + update_cursor_sprite_texture (META_WAYLAND_CURSOR_SURFACE (surface_role)); + } + +diff -Naurp mutter-3.32.2.orig/src/wayland/meta-wayland-seat.c mutter-3.32.2/src/wayland/meta-wayland-seat.c +--- mutter-3.32.2.orig/src/wayland/meta-wayland-seat.c 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/src/wayland/meta-wayland-seat.c 2019-07-01 15:33:03.077805423 -0500 +@@ -266,7 +266,7 @@ meta_wayland_seat_free (MetaWaylandSeat + meta_wayland_gtk_text_input_destroy (seat->gtk_text_input); + meta_wayland_text_input_destroy (seat->text_input); + +- g_slice_free (MetaWaylandSeat, seat); ++ g_free (seat); + } + + static gboolean +diff -Naurp mutter-3.32.2.orig/src/wayland/meta-wayland-surface.c mutter-3.32.2/src/wayland/meta-wayland-surface.c +--- mutter-3.32.2.orig/src/wayland/meta-wayland-surface.c 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/src/wayland/meta-wayland-surface.c 2019-07-01 19:34:56.417500382 -0500 +@@ -738,6 +738,10 @@ meta_wayland_surface_apply_pending_state + } + } + ++ else ++ { ++ cogl_clear_object (&surface->texture); ++ } + /* If the newly attached buffer is going to be accessed directly without + * making a copy, such as an EGL buffer, mark it as in-use don't release + * it until is replaced by a subsequent wl_surface.commit or when the +diff -Naurp mutter-3.32.2.orig/src/x11/window-x11.c mutter-3.32.2/src/x11/window-x11.c +--- mutter-3.32.2.orig/src/x11/window-x11.c 2019-05-14 12:57:10.000000000 -0500 ++++ mutter-3.32.2/src/x11/window-x11.c 2019-07-01 21:59:53.764106326 -0500 +@@ -50,6 +50,8 @@ + #include "x11/window-props.h" + #include "x11/xprops.h" + ++#define TAKE_FOCUS_FALLBACK_DELAY_MS 250 ++ + enum _MetaGtkEdgeConstraints + { + META_GTK_EDGE_CONSTRAINT_TOP_TILED = 1 << 0, +@@ -776,6 +778,64 @@ request_take_focus (MetaWindow *window, + send_icccm_message (window, display->x11_display->atom_WM_TAKE_FOCUS, timestamp); + } + ++typedef struct ++{ ++ MetaWindow *window; ++ guint32 timestamp; ++ guint timeout_id; ++ gulong unmanaged_id; ++ gulong focused_changed_id; ++} MetaWindowX11DelayedFocusData; ++ ++static void ++meta_window_x11_delayed_focus_data_free (MetaWindowX11DelayedFocusData *data) ++{ ++ g_signal_handler_disconnect (data->window, data->unmanaged_id); ++ g_signal_handler_disconnect (data->window->display, data->focused_changed_id); ++ ++ g_clear_handle_id (&data->timeout_id, g_source_remove); ++ g_free (data); ++} ++ ++static gboolean ++focus_window_delayed_timeout (gpointer user_data) ++{ ++ MetaWindowX11DelayedFocusData *data = user_data; ++ MetaWindow *window = data->window; ++ guint32 timestamp = data->timestamp; ++ ++ data->timeout_id = 0; ++ meta_window_x11_delayed_focus_data_free (data); ++ ++ meta_window_focus (window, timestamp); ++ ++ return G_SOURCE_REMOVE; ++} ++ ++static void ++meta_window_x11_maybe_focus_delayed (MetaWindow *window, ++ guint32 timestamp) ++{ ++ MetaWindowX11DelayedFocusData *data; ++ ++ data = g_new0 (MetaWindowX11DelayedFocusData, 1); ++ data->window = window; ++ data->timestamp = timestamp; ++ ++ data->unmanaged_id = ++ g_signal_connect_swapped (window, "unmanaged", ++ G_CALLBACK (meta_window_x11_delayed_focus_data_free), ++ data); ++ ++ data->focused_changed_id = ++ g_signal_connect_swapped (window->display, "notify::focus-window", ++ G_CALLBACK (meta_window_x11_delayed_focus_data_free), ++ data); ++ ++ data->timeout_id = g_timeout_add (TAKE_FOCUS_FALLBACK_DELAY_MS, ++ focus_window_delayed_timeout, data); ++} ++ + static void + meta_window_x11_focus (MetaWindow *window, + guint32 timestamp) +@@ -827,13 +887,44 @@ meta_window_x11_focus (MetaWindow *windo + * Normally, we want to just leave the focus undisturbed until + * the window responds to WM_TAKE_FOCUS, but if we're unmanaging + * the current focus window we *need* to move the focus away, so +- * we focus the no_focus_window now (and set +- * display->focus_window to that) before sending WM_TAKE_FOCUS. ++ * we focus the no_focus_window before sending WM_TAKE_FOCUS, ++ * and eventually the default focus window excluding this one, ++ * if meanwhile we don't get any focus request. + */ + if (window->display->focus_window != NULL && + window->display->focus_window->unmanaging) +- meta_x11_display_focus_the_no_focus_window (window->display->x11_display, +- timestamp); ++ { ++ MetaWindow *focus_window = window; ++ MetaX11Display *x11_display = window->display->x11_display; ++ MetaWorkspace *workspace = window->workspace; ++ MetaStack *stack = workspace->display->stack; ++ ++ while (TRUE) ++ { ++ focus_window = meta_stack_get_default_focus_window (stack, ++ workspace, ++ focus_window); ++ ++ if (!focus_window) ++ break; ++ ++ if (focus_window->unmanaging) ++ continue; ++ ++ if (focus_window->input) ++ break; ++ ++ if (focus_window->shaded && focus_window->frame) ++ break; ++ } ++ ++ meta_x11_display_focus_the_no_focus_window (x11_display, ++ timestamp); ++ ++ if (focus_window) ++ meta_window_x11_maybe_focus_delayed (focus_window, ++ timestamp); ++ } + } + + request_take_focus (window, timestamp); -- http://lists.linuxfromscratch.org/listinfo/patches FAQ: http://www.linuxfromscratch.org/blfs/faq.html Unsubscribe: See the above information page