diff --git a/data/gala.metainfo.xml.in b/data/gala.metainfo.xml.in index 1927ab866..0b56dd5e9 100644 --- a/data/gala.metainfo.xml.in +++ b/data/gala.metainfo.xml.in @@ -36,6 +36,7 @@ + Dock interacts with the mouse even with the window overlapping diff --git a/src/ShellClients/DelegateActor.vala b/src/ShellClients/DelegateActor.vala new file mode 100644 index 000000000..bd93f9128 --- /dev/null +++ b/src/ShellClients/DelegateActor.vala @@ -0,0 +1,42 @@ +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-FileCopyrightText: 2024 elementary, Inc. (https://elementary.io) + */ + +/* This class is used to workaround https://github.com/elementary/gala/issues/2101 */ +public class Gala.DelegateActor : GLib.Object { + public const int OUT_OF_BOUNDS = 1000000; + + public Meta.WindowActor actor { get; construct; } + + /* Current window actor position or position before the window was moved out of bounds */ + public float x { get; private set; default = 0.0f; } + public float y { get; private set; default = 0.0f; } + + /* Current window position or position before it was moved out of bounds */ + public int actual_x { get; private set; default = 0; } + public int actual_y { get; private set; default = 0; } + + public DelegateActor (Meta.WindowActor actor) { + Object (actor: actor); + } + + construct { + actor.meta_window.position_changed.connect ((_window) => { + var rect = _window.get_frame_rect (); + + if (rect.x != OUT_OF_BOUNDS) { + actual_x = rect.x; + Idle.add_once (() => { + x = actor.x; + }); + } + if (rect.y != OUT_OF_BOUNDS) { + actual_y = rect.y; + Idle.add_once (() => { + y = actor.y; + }); + } + }); + } +} diff --git a/src/ShellClients/PanelClone.vala b/src/ShellClients/PanelClone.vala index 13d7e7587..15fc8d23f 100644 --- a/src/ShellClients/PanelClone.vala +++ b/src/ShellClients/PanelClone.vala @@ -48,8 +48,8 @@ public class Gala.PanelClone : Object { actor = (Meta.WindowActor) panel.window.get_compositor_private (); // WindowActor position and Window position aren't necessarily the same. // The clone needs the actor position - actor.notify["x"].connect (update_clone_position); - actor.notify["y"].connect (update_clone_position); + panel.delegate_actor.notify["x"].connect (update_clone_position); + panel.delegate_actor.notify["y"].connect (update_clone_position); // Actor visibility might be changed by something else e.g. workspace switch // but we want to keep it in sync with us actor.notify["visible"].connect (update_visible); @@ -97,7 +97,7 @@ public class Gala.PanelClone : Object { switch (panel.anchor) { case TOP: case BOTTOM: - return actor.x; + return panel.delegate_actor.x; default: return 0; } @@ -106,9 +106,9 @@ public class Gala.PanelClone : Object { private float calculate_clone_y (bool hidden) { switch (panel.anchor) { case TOP: - return hidden ? actor.y - actor.height : actor.y; + return hidden ? panel.delegate_actor.y - actor.height : panel.delegate_actor.y; case BOTTOM: - return hidden ? actor.y + actor.height : actor.y; + return hidden ? panel.delegate_actor.y + actor.height : panel.delegate_actor.y; default: return 0; } @@ -127,6 +127,10 @@ public class Gala.PanelClone : Object { panel_hidden = true; + if (!Meta.Util.is_wayland_compositor ()) { + panel.window.move_frame (false, DelegateActor.OUT_OF_BOUNDS, DelegateActor.OUT_OF_BOUNDS); + } + if (panel.anchor != TOP && panel.anchor != BOTTOM) { warning ("Animated hide not supported for side yet."); return; @@ -146,6 +150,10 @@ public class Gala.PanelClone : Object { return; } + if (!Meta.Util.is_wayland_compositor ()) { + panel.window.move_frame (false, panel.delegate_actor.actual_x, panel.delegate_actor.actual_y); + } + clone.save_easing_state (); clone.set_easing_mode (Clutter.AnimationMode.EASE_OUT_QUAD); clone.set_easing_duration (get_animation_duration ()); diff --git a/src/ShellClients/PanelWindow.vala b/src/ShellClients/PanelWindow.vala index 5351cbe5a..107218e11 100644 --- a/src/ShellClients/PanelWindow.vala +++ b/src/ShellClients/PanelWindow.vala @@ -15,6 +15,7 @@ public class Gala.PanelWindow : Object { public Meta.Side anchor; + public DelegateActor delegate_actor; private PanelClone clone; private uint idle_move_id = 0; @@ -45,6 +46,7 @@ public class Gala.PanelWindow : Object { window.stick (); + delegate_actor = new DelegateActor ((Meta.WindowActor) window.get_compositor_private ()); clone = new PanelClone (wm, this); var monitor_manager = wm.get_display ().get_context ().get_backend ().get_monitor_manager (); @@ -62,6 +64,8 @@ public class Gala.PanelWindow : Object { public Meta.Rectangle get_custom_window_rect () { #endif var window_rect = window.get_frame_rect (); + window_rect.x = delegate_actor.actual_x; + window_rect.y = delegate_actor.actual_y; if (width > 0) { window_rect.width = width; diff --git a/src/meson.build b/src/meson.build index 7e6488fd1..d8fa147aa 100644 --- a/src/meson.build +++ b/src/meson.build @@ -41,6 +41,7 @@ gala_bin_sources = files( 'HotCorners/Barrier.vala', 'HotCorners/HotCorner.vala', 'HotCorners/HotCornerManager.vala', + 'ShellClients/DelegateActor.vala', 'ShellClients/HideTracker.vala', 'ShellClients/ManagedClient.vala', 'ShellClients/NotificationsClient.vala',