From dc36a60486d5b2c980a241eeab6b9f596a5c945e Mon Sep 17 00:00:00 2001 From: Leonhard Kargl Date: Sun, 13 Oct 2024 19:13:42 +0200 Subject: [PATCH 1/5] Introduce a WindowPositioner --- src/ShellClients/ShellClientsManager.vala | 44 +++++++++++-------- ...teredWindow.vala => WindowPositioner.vala} | 34 +++++++------- src/meson.build | 2 +- 3 files changed, 46 insertions(+), 34 deletions(-) rename src/ShellClients/{CenteredWindow.vala => WindowPositioner.vala} (59%) diff --git a/src/ShellClients/ShellClientsManager.vala b/src/ShellClients/ShellClientsManager.vala index ad15ca9e8..6e94acf26 100644 --- a/src/ShellClients/ShellClientsManager.vala +++ b/src/ShellClients/ShellClientsManager.vala @@ -25,8 +25,8 @@ public class Gala.ShellClientsManager : Object { private NotificationsClient notifications_client; private ManagedClient[] protocol_clients = {}; - private GLib.HashTable windows = new GLib.HashTable (null, null); - private GLib.HashTable centered_windows = new GLib.HashTable (null, null); + private GLib.HashTable panel_windows = new GLib.HashTable (null, null); + private GLib.HashTable positioned_windows = new GLib.HashTable (null, null); private ShellClientsManager (WindowManager wm) { Object (wm: wm); @@ -144,18 +144,18 @@ public class Gala.ShellClientsManager : Object { } public void set_anchor (Meta.Window window, Meta.Side side) { - if (window in windows) { - windows[window].update_anchor (side); + if (window in panel_windows) { + panel_windows[window].update_anchor (side); return; } make_dock (window); // TODO: Return if requested by window that's not a trusted client? - windows[window] = new PanelWindow (wm, window, side); + panel_windows[window] = new PanelWindow (wm, window, side); // connect_after so we make sure the PanelWindow can destroy its barriers and struts - window.unmanaging.connect_after (() => windows.remove (window)); + window.unmanaging.connect_after ((_window) => panel_windows.remove (_window)); } /** @@ -166,37 +166,45 @@ public class Gala.ShellClientsManager : Object { * TODO: Maybe use for strut only? */ public void set_size (Meta.Window window, int width, int height) { - if (!(window in windows)) { + if (!(window in panel_windows)) { warning ("Set anchor for window before size."); return; } - windows[window].set_size (width, height); + panel_windows[window].set_size (width, height); } public void set_hide_mode (Meta.Window window, Pantheon.Desktop.HideMode hide_mode) { - if (!(window in windows)) { + if (!(window in panel_windows)) { warning ("Set anchor for window before hide mode."); return; } - windows[window].set_hide_mode (hide_mode); + panel_windows[window].set_hide_mode (hide_mode); } - public void make_centered (Meta.Window window) { - if (window in centered_windows) { - return; - } + public void make_centered (Meta.Window window) requires (!is_itself_positioned (window)) { + positioned_windows[window] = new WindowPositioner (window, wm, (ref x, ref y) => { + unowned var display = wm.get_display (); + var monitor_geom = display.get_monitor_geometry (display.get_primary_monitor ()); + var window_rect = window.get_frame_rect (); - centered_windows[window] = new CenteredWindow (wm, window); + x = monitor_geom.x + (monitor_geom.width - window_rect.width) / 2; + y = monitor_geom.y + (monitor_geom.height - window_rect.height) / 2; + }); + + // connect_after so we make sure that any queued move is unqueued + window.unmanaging.connect_after ((_window) => positioned_windows.remove (_window)); + } - window.unmanaging.connect_after (() => centered_windows.remove (window)); + private bool is_itself_positioned (Meta.Window window) { + return (window in positioned_windows) || (window in panel_windows); } public bool is_positioned_window (Meta.Window window) { - bool positioned = (window in centered_windows) || (window in windows); + bool positioned = is_itself_positioned (window); window.foreach_ancestor ((ancestor) => { - if (ancestor in centered_windows || ancestor in windows) { + if (ancestor in positioned_windows || ancestor in panel_windows) { positioned = true; } diff --git a/src/ShellClients/CenteredWindow.vala b/src/ShellClients/WindowPositioner.vala similarity index 59% rename from src/ShellClients/CenteredWindow.vala rename to src/ShellClients/WindowPositioner.vala index 6099c68d1..3f9df883a 100644 --- a/src/ShellClients/CenteredWindow.vala +++ b/src/ShellClients/WindowPositioner.vala @@ -5,27 +5,35 @@ * Authored by: Leonhard Kargl */ -public class Gala.CenteredWindow : Object { - public WindowManager wm { get; construct; } +public class Gala.WindowPositioner : Object { + public delegate void PositionFunc (ref int x, ref int y); + public Meta.Window window { get; construct; } + public WindowManager wm { get; construct; } + + private PositionFunc position_func; private uint idle_move_id = 0; - public CenteredWindow (WindowManager wm, Meta.Window window) { - Object (wm: wm, window: window); + public WindowPositioner (Meta.Window window, WindowManager wm, owned PositionFunc position_func) { + Object (window: window, wm: wm); + + this.position_func = (owned) position_func; } construct { - window.size_changed.connect (position_window); window.stick (); + window.size_changed.connect (position_window); + window.position_changed.connect (position_window); + window.shown.connect (position_window); + var monitor_manager = wm.get_display ().get_context ().get_backend ().get_monitor_manager (); - monitor_manager.monitors_changed.connect (() => position_window ()); + monitor_manager.monitors_changed.connect (position_window); + monitor_manager.monitors_changed_internal.connect (position_window); position_window (); - window.shown.connect (() => window.focus (wm.get_display ().get_current_time ())); - window.unmanaging.connect (() => { if (idle_move_id != 0) { Source.remove (idle_move_id); @@ -34,18 +42,14 @@ public class Gala.CenteredWindow : Object { } private void position_window () { - var display = wm.get_display (); - var monitor_geom = display.get_monitor_geometry (display.get_primary_monitor ()); - var window_rect = window.get_frame_rect (); - - var x = monitor_geom.x + (monitor_geom.width - window_rect.width) / 2; - var y = monitor_geom.y + (monitor_geom.height - window_rect.height) / 2; - if (idle_move_id != 0) { Source.remove (idle_move_id); } idle_move_id = Idle.add (() => { + int x = 0, y = 0; + position_func (ref x, ref y); + window.move_frame (false, x, y); idle_move_id = 0; diff --git a/src/meson.build b/src/meson.build index e2e61807b..7e6488fd1 100644 --- a/src/meson.build +++ b/src/meson.build @@ -41,13 +41,13 @@ gala_bin_sources = files( 'HotCorners/Barrier.vala', 'HotCorners/HotCorner.vala', 'HotCorners/HotCornerManager.vala', - 'ShellClients/CenteredWindow.vala', 'ShellClients/HideTracker.vala', 'ShellClients/ManagedClient.vala', 'ShellClients/NotificationsClient.vala', 'ShellClients/PanelClone.vala', 'ShellClients/PanelWindow.vala', 'ShellClients/ShellClientsManager.vala', + 'ShellClients/WindowPositioner.vala', 'Widgets/DwellClickTimer.vala', 'Widgets/IconGroup.vala', 'Widgets/IconGroupContainer.vala', From e0d73b4c35ede5f04be6aceb26e03d3f9207b7f4 Mon Sep 17 00:00:00 2001 From: Leonhard Kargl Date: Sun, 13 Oct 2024 19:16:57 +0200 Subject: [PATCH 2/5] Cleanup --- src/ShellClients/ShellClientsManager.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ShellClients/ShellClientsManager.vala b/src/ShellClients/ShellClientsManager.vala index 6e94acf26..92fb2ee9d 100644 --- a/src/ShellClients/ShellClientsManager.vala +++ b/src/ShellClients/ShellClientsManager.vala @@ -204,7 +204,7 @@ public class Gala.ShellClientsManager : Object { public bool is_positioned_window (Meta.Window window) { bool positioned = is_itself_positioned (window); window.foreach_ancestor ((ancestor) => { - if (ancestor in positioned_windows || ancestor in panel_windows) { + if (is_itself_positioned (ancestor)) { positioned = true; } From f8bd6cfef789dce29d300d8ad2e355233109fabd Mon Sep 17 00:00:00 2001 From: Leonhard Kargl Date: Tue, 15 Oct 2024 18:17:15 +0200 Subject: [PATCH 3/5] We dont need idle --- src/ShellClients/WindowPositioner.vala | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/src/ShellClients/WindowPositioner.vala b/src/ShellClients/WindowPositioner.vala index 3f9df883a..bcbe7fa64 100644 --- a/src/ShellClients/WindowPositioner.vala +++ b/src/ShellClients/WindowPositioner.vala @@ -13,8 +13,6 @@ public class Gala.WindowPositioner : Object { private PositionFunc position_func; - private uint idle_move_id = 0; - public WindowPositioner (Meta.Window window, WindowManager wm, owned PositionFunc position_func) { Object (window: window, wm: wm); @@ -31,29 +29,12 @@ public class Gala.WindowPositioner : Object { var monitor_manager = wm.get_display ().get_context ().get_backend ().get_monitor_manager (); monitor_manager.monitors_changed.connect (position_window); monitor_manager.monitors_changed_internal.connect (position_window); - - position_window (); - - window.unmanaging.connect (() => { - if (idle_move_id != 0) { - Source.remove (idle_move_id); - } - }); } private void position_window () { - if (idle_move_id != 0) { - Source.remove (idle_move_id); - } - - idle_move_id = Idle.add (() => { - int x = 0, y = 0; - position_func (ref x, ref y); - - window.move_frame (false, x, y); + int x = 0, y = 0; + position_func (ref x, ref y); - idle_move_id = 0; - return Source.REMOVE; - }); + window.move_frame (false, x, y); } } From 6711ee3e3849f97548a95c2d639c7fec9c150d70 Mon Sep 17 00:00:00 2001 From: Leonhard Kargl Date: Fri, 18 Oct 2024 13:00:48 +0200 Subject: [PATCH 4/5] Move positioning funcs to the WindowPositioner --- src/ShellClients/ShellClientsManager.vala | 9 +----- src/ShellClients/WindowPositioner.vala | 36 ++++++++++++++++++----- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/ShellClients/ShellClientsManager.vala b/src/ShellClients/ShellClientsManager.vala index 92fb2ee9d..05a765fc3 100644 --- a/src/ShellClients/ShellClientsManager.vala +++ b/src/ShellClients/ShellClientsManager.vala @@ -184,14 +184,7 @@ public class Gala.ShellClientsManager : Object { } public void make_centered (Meta.Window window) requires (!is_itself_positioned (window)) { - positioned_windows[window] = new WindowPositioner (window, wm, (ref x, ref y) => { - unowned var display = wm.get_display (); - var monitor_geom = display.get_monitor_geometry (display.get_primary_monitor ()); - var window_rect = window.get_frame_rect (); - - x = monitor_geom.x + (monitor_geom.width - window_rect.width) / 2; - y = monitor_geom.y + (monitor_geom.height - window_rect.height) / 2; - }); + positioned_windows[window] = new WindowPositioner (wm, window, CENTER); // connect_after so we make sure that any queued move is unqueued window.unmanaging.connect_after ((_window) => positioned_windows.remove (_window)); diff --git a/src/ShellClients/WindowPositioner.vala b/src/ShellClients/WindowPositioner.vala index bcbe7fa64..6928fd0bd 100644 --- a/src/ShellClients/WindowPositioner.vala +++ b/src/ShellClients/WindowPositioner.vala @@ -6,17 +6,17 @@ */ public class Gala.WindowPositioner : Object { - public delegate void PositionFunc (ref int x, ref int y); + public enum Position { + CENTER + } public Meta.Window window { get; construct; } public WindowManager wm { get; construct; } + public Position position { get; private set; } + public Variant? position_data { get; private set; } - private PositionFunc position_func; - - public WindowPositioner (Meta.Window window, WindowManager wm, owned PositionFunc position_func) { - Object (window: window, wm: wm); - - this.position_func = (owned) position_func; + public WindowPositioner (WindowManager wm, Meta.Window window, Position position, Variant? position_data = null) { + Object (wm: wm, window: window, position: position, position_data: position_data); } construct { @@ -31,9 +31,29 @@ public class Gala.WindowPositioner : Object { monitor_manager.monitors_changed_internal.connect (position_window); } + /** + * This may only be called after the window was shown. + */ + public void update_position (Position new_position, Variant? new_position_data = null) { + position = new_position; + position_data = new_position_data; + + position_window (); + } + private void position_window () { int x = 0, y = 0; - position_func (ref x, ref y); + + switch (position) { + case CENTER: + unowned var display = wm.get_display (); + var monitor_geom = display.get_monitor_geometry (display.get_primary_monitor ()); + var window_rect = window.get_frame_rect (); + + x = monitor_geom.x + (monitor_geom.width - window_rect.width) / 2; + y = monitor_geom.y + (monitor_geom.height - window_rect.height) / 2; + break; + } window.move_frame (false, x, y); } From 7765ecca229a3085010b634f1b8f1be78b5dc67d Mon Sep 17 00:00:00 2001 From: Leo Date: Sat, 2 Nov 2024 15:13:57 +0300 Subject: [PATCH 5/5] Update src/ShellClients/WindowPositioner.vala --- src/ShellClients/WindowPositioner.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ShellClients/WindowPositioner.vala b/src/ShellClients/WindowPositioner.vala index 6928fd0bd..3966d359e 100644 --- a/src/ShellClients/WindowPositioner.vala +++ b/src/ShellClients/WindowPositioner.vala @@ -26,7 +26,7 @@ public class Gala.WindowPositioner : Object { window.position_changed.connect (position_window); window.shown.connect (position_window); - var monitor_manager = wm.get_display ().get_context ().get_backend ().get_monitor_manager (); + unowned var monitor_manager = wm.get_display ().get_context ().get_backend ().get_monitor_manager (); monitor_manager.monitors_changed.connect (position_window); monitor_manager.monitors_changed_internal.connect (position_window); }