[gnome-shell] main: Add help function for moving window to monitor/workspace



commit 1cb01ec5b139da136cac665fc705e4ddd1d926a1
Author: Florian Müllner <fmuellner gnome org>
Date:   Thu Mar 31 16:59:49 2022 +0200

    main: Add help function for moving window to monitor/workspace
    
    MetaWindow.move_to_monitor() can no longer be assumed to have updated
    the monitor on return, as under wayland, if the move involves a size
    change, the monitor state will only be updated after the new size has
    been synced with the client.
    
    If that happens, trying to change the workspace of the moved window
    fails, as it is still considered on-all-workspaces until it leaves
    the secondary monitor.
    
    It's possible to work around this by waiting for the window to actually
    enter the requested monitor. That's finicky enough to warrant a helper
    funtion, so add one.
    
    https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/893
    
    Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2259>

 js/ui/main.js | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)
---
diff --git a/js/ui/main.js b/js/ui/main.js
index 76223b9c2a..d1a2076f66 100644
--- a/js/ui/main.js
+++ b/js/ui/main.js
@@ -5,7 +5,8 @@
             shellAccessDialogDBusService, shellAudioSelectionDBusService,
             screenSaverDBus, uiGroup, magnifier, xdndHandler, keyboard,
             kbdA11yDialog, introspectService, start, pushModal, popModal,
-            activateWindow, createLookingGlass, initializeDeferredWork,
+            activateWindow, moveWindowToMonitorAndWorkspace,
+            createLookingGlass, initializeDeferredWork,
             getThemeStylesheet, setThemeStylesheet, screenshotUI */
 
 const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
@@ -720,6 +721,33 @@ function activateWindow(window, time, workspaceNum) {
     panel.closeCalendar();
 }
 
+/**
+ * Move @window to the specified monitor and workspace.
+ *
+ * @param {Meta.Window} window - the window to move
+ * @param {number} monitorIndex - the requested monitor
+ * @param {number} workspaceIndex - the requested workspace
+ * @param {bool} append - create workspace if it doesn't exist
+ */
+function moveWindowToMonitorAndWorkspace(window, monitorIndex, workspaceIndex, append = false) {
+    // We need to move the window before changing the workspace, because
+    // the move itself could cause a workspace change if the window enters
+    // the primary monitor
+    if (window.get_monitor() !== monitorIndex) {
+        // Wait for the monitor change to take effect
+        const id = global.display.connect('window-entered-monitor',
+            (dsp, num, w) => {
+                if (w !== window)
+                    return;
+                window.change_workspace_by_index(workspaceIndex, append);
+                global.display.disconnect(id);
+            });
+        window.move_to_monitor(monitorIndex);
+    } else {
+        window.change_workspace_by_index(workspaceIndex, append);
+    }
+}
+
 // TODO - replace this timeout with some system to guess when the user might
 // be e.g. just reading the screen and not likely to interact.
 var DEFERRED_TIMEOUT_SECONDS = 20;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]