From 50bbd183ba60838cb28eded055e0d7160e2e487c Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Mon, 15 May 2023 00:58:27 +0900 Subject: [PATCH] Add cursor warp --- prefs.js | 6 +++ ...g.gnome.shell.extensions.fairy.gschema.xml | 5 +++ sources/keybinds.js | 4 +- sources/renderer.js | 44 ++++++++++++++++++- sources/state.js | 28 +----------- 5 files changed, 57 insertions(+), 30 deletions(-) diff --git a/prefs.js b/prefs.js index cc9a8bd..e336ed6 100644 --- a/prefs.js +++ b/prefs.js @@ -61,6 +61,12 @@ function fillPreferencesWindow(window) { const general = new Adw.PreferencesGroup(); page.add(general); + general.add( + _createBool(settings, { + title: "Warp cursor", + key: "warp-cursor", + }) + ); general.add( _createBool(settings, { title: "Show Layout Indicator", diff --git a/schemas/org.gnome.shell.extensions.fairy.gschema.xml b/schemas/org.gnome.shell.extensions.fairy.gschema.xml index 6e4764d..e933549 100644 --- a/schemas/org.gnome.shell.extensions.fairy.gschema.xml +++ b/schemas/org.gnome.shell.extensions.fairy.gschema.xml @@ -1,6 +1,11 @@ + + true + Should the cursor warp to newly focused windows + + true diff --git a/sources/keybinds.js b/sources/keybinds.js index 32fe503..d78a268 100644 --- a/sources/keybinds.js +++ b/sources/keybinds.js @@ -54,7 +54,7 @@ var KeyboardManager = GObject.registerClass( const idx = this._state.workIndexByHandle(state.focused); const newW = this._state.workIndex(mon, state.tags, idx + 1); if (newW && newW.handle !== state.focused) { - this._state.focus(newW.handle); + this._renderer.focus(newW.handle); this._renderer.render(mon); } }); @@ -203,7 +203,7 @@ var KeyboardManager = GObject.registerClass( const idx = this._state.workIndexByHandle(state.focused); const win = this._state.workIndex(mon, state.tags, idx - 1); if (win && win.handle !== state.focused) { - this._state.focus(win.handle); + this._renderer.focus(win.handle); this._renderer.render(mon); } } diff --git a/sources/renderer.js b/sources/renderer.js index efa26f8..76e6432 100644 --- a/sources/renderer.js +++ b/sources/renderer.js @@ -1,6 +1,7 @@ "use strict"; const Meta = imports.gi.Meta; +const Gdk = imports.gi.Gdk; const GLib = imports.gi.GLib; const GObject = imports.gi.GObject; const Main = imports.ui.main; @@ -19,6 +20,7 @@ var Renderer = GObject.registerClass( size: 10, outerGaps: 20, }; + this.warpEnabled = true; log("fairy init!"); } @@ -34,6 +36,7 @@ var Renderer = GObject.registerClass( size: this._settings.get_uint("gap-size"), outerGaps: this._settings.get_uint("outer-gap-size"), }; + this.warpEnabled = this._settings.get_boolean("warp-cursor"); for (const window of global.display.list_all_windows()) this.trackWindow(window); @@ -137,7 +140,7 @@ var Renderer = GObject.registerClass( this._waitForWindow(window, () => { this.trackWindow(window); GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => { - this._state.focus(window); + this.focus(window); // Do not retrigger this idle. return false; }); @@ -183,6 +186,9 @@ var Renderer = GObject.registerClass( this.gaps.smart = this._settings.get_boolean(key); this.renderAll(); break; + case "warp-cursor": + this.warpEnabled = this._settings.get_boolean(key); + break; } }); } @@ -203,7 +209,7 @@ var Renderer = GObject.registerClass( const tags = this._state.monitors[faWindow.monitor].tags; // Since we retrieved the idx, the window as been removed so we don't need to +1. const newWindow = this._state.workIndex(faWindow.monitor, tags, idx); - if (newWindow) this._state.focus(newWindow.handle); + if (newWindow) this.focus(newWindow.handle); this.render(faWindow.monitor); }), @@ -227,6 +233,40 @@ var Renderer = GObject.registerClass( this._state.newWindow(handle); } + /** + * @param {Meta.Window} handle + */ + focus(handle) { + const mon = handle.get_monitor(); + this._state.monitors[mon].focused = handle; + // This was focused without a zoom, removing the old zoom value. + this._state.monitors[mon].beforeZoom = null; + + log("focusing window with title", handle.get_title()); + handle.raise(); + handle.focus(global.display.get_current_time()); + handle.activate(global.display.get_current_time()); + this.warpCursor(handle); + } + + /** + * @param {Meta.Window} handle + */ + warpCursor(handle) { + if (!this.warpEnabled) return; + + log("warping"); + const gdkDisplay = Gdk.DisplayManager.get().get_default_display(); + if (!gdkDisplay) return; + log("Display existing") + + const pointer = gdkDisplay.get_default_seat().get_pointer(); + const screen = gdkDisplay.get_default_screen(); + const rect = handle.get_frame_rect(); + log("Warping to x,y", rect.x, rect.y); + pointer.warp(screen, rect.x + rect.width / 2, rect.y + rect.height / 2); + } + setTags(mon, tags) { const currTags = this._state.monitors[mon].tags; this._state.monitors[mon].tags = tags; diff --git a/sources/state.js b/sources/state.js index 2b3a534..ec922ed 100644 --- a/sources/state.js +++ b/sources/state.js @@ -104,30 +104,6 @@ var StateManager = GObject.registerClass( return windows.findIndex((x) => x.handle === handle); } - /** - * @param {Meta.Window} handle - */ - focus(handle) { - const mon = handle.get_monitor(); - this.monitors[mon].focused = handle; - // This was focused without a zoom, removing the old zoom value. - this.monitors[mon].beforeZoom = null; - - log("focusing window with title", handle.get_title()); - handle.raise(); - handle.focus(global.display.get_current_time()); - handle.activate(global.display.get_current_time()); - this.warpCursor(handle); - } - - /** - * @param {Meta.Window} handle - */ - warpCursor(handle) { - // TODO: Warp the cursor - // TODO: Check if the warp-cursor setting is enabled. - } - /** * @param {number} mon * @param {number} tags @@ -208,8 +184,8 @@ var StateManager = GObject.registerClass( windows.length <= nmaster || nmaster <= 0 ? 100 : i < nmaster - ? mfact - : 100 - mfact, + ? mfact + : 100 - mfact, height: 100 / stackLength, }; });