diff --git a/src/Widgets/WindowClone.vala b/src/Widgets/WindowClone.vala index 989b280c4..8cbb0d675 100644 --- a/src/Widgets/WindowClone.vala +++ b/src/Widgets/WindowClone.vala @@ -80,6 +80,7 @@ public class Gala.WindowClone : Clutter.Actor { } } + private WindowActorFetcher? window_actor_fetcher = null; private DragDropAction? drag_action = null; private Clutter.Clone? clone = null; private ShadowEffect? shadow_effect = null; @@ -143,7 +144,12 @@ public class Gala.WindowClone : Clutter.Actor { reallocate (); - load_clone (); + if (window.get_compositor_private () != null) { + load_clone (); + } else { + window_actor_fetcher = new WindowActorFetcher (window); + window_actor_fetcher.window_actor_ready.connect (load_clone); + } window.notify["title"].connect (() => window_title.set_text (window.get_title () ?? "")); window_title.set_text (window.get_title () ?? ""); @@ -176,24 +182,14 @@ public class Gala.WindowClone : Clutter.Actor { } /** - * Waits for the texture of a new Meta.WindowActor to be available - * and makes a close of it. If it was already was assigned a slot + * Makes a clone of the window. If the window was already was assigned a slot * at this point it will animate to it. Otherwise it will just place * itself at the location of the original window. Also adds the shadow * effect and makes sure the shadow is updated on size changes. */ - private void load_clone () { - var actor = (Meta.WindowActor) window.get_compositor_private (); - if (actor == null) { - Idle.add (() => { - if (window.get_compositor_private () != null) { - load_clone (); - } - return Source.REMOVE; - }); - - return; - } + private void load_clone () requires (window.get_compositor_private () != null) { + window_actor_fetcher = null; + unowned var actor = (Meta.WindowActor) window.get_compositor_private (); if (overview_mode) { actor.hide (); diff --git a/src/WindowActorFetcher.vala b/src/WindowActorFetcher.vala new file mode 100644 index 000000000..a645fcc6c --- /dev/null +++ b/src/WindowActorFetcher.vala @@ -0,0 +1,46 @@ +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-FileCopyrightText: 2024 elementary, Inc. (https://elementary.io) + */ + +/* + * Sends a signal when a window actor is ready. + * Useful when you need to use window actor when the window was created. + */ +public class Gala.WindowActorFetcher : GLib.Object { + public signal void window_actor_ready (); + + public Meta.Window window { get; construct; } + + private uint idle_id = 0; + + public WindowActorFetcher (Meta.Window window) { + Object (window: window); + } + + ~WindowActorFetcher () { + if (idle_id > 0) { + Source.remove (idle_id); + } + } + + construct { + idle_id = Idle.add (() => { + if (window == null) { + idle_id = 0; + return Source.REMOVE; + } + + unowned var window_actor = (Meta.WindowActor) window.get_compositor_private (); + + if (window_actor != null) { + window_actor_ready (); + idle_id = 0; + + return Source.REMOVE; + } + + return Source.CONTINUE; + }); + } +} diff --git a/src/meson.build b/src/meson.build index 70d9d7b97..f45a19275 100644 --- a/src/meson.build +++ b/src/meson.build @@ -14,6 +14,7 @@ gala_bin_sources = files( 'ScreenSaverManager.vala', 'ScreenshotManager.vala', 'SessionManager.vala', + 'WindowActorFetcher.vala', 'WindowAttentionTracker.vala', 'WindowGrabTracker.vala', 'WindowListener.vala',