Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix warp pointer if focus window on another monitor #839

Merged
merged 9 commits into from
Apr 26, 2024
17 changes: 9 additions & 8 deletions liveAltTab.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,26 @@ import GObject from 'gi://GObject';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import * as AltTab from 'resource:///org/gnome/shell/ui/altTab.js';

import { Settings, Keybindings, Tiling, Scratch } from './imports.js';
import { Utils, Settings, Keybindings, Tiling, Scratch } from './imports.js';
import { Easer } from './utils.js';

let switcherSettings;
export function enable() {
switcherSettings = new Gio.Settings({
schema_id: 'org.gnome.shell.window-switcher',
schema_id: 'org.gnome.shell.app-switcher',
});
}

export function disable() {
switcherSettings = null;
}

export function liveAltTab(meta_window, space, { display, screen, binding }) {
export function liveAltTab(meta_window, space, { _display, _screen, binding }) {
let tabPopup = new LiveAltTab(binding.is_reversed(), false);
tabPopup.show(binding.is_reversed(), binding.get_name(), binding.get_mask());
}

export function liveAltTabScratch(meta_window, space, { display, screen, binding }) {
export function liveAltTabScratch(meta_window, space, { _display, _screen, binding }) {
let tabPopup = new LiveAltTab(binding.is_reversed(), true);
tabPopup.show(binding.is_reversed(), binding.get_name(), binding.get_mask());
}
Expand All @@ -41,18 +41,18 @@ export const LiveAltTab = GObject.registerClass(
}

_getWindowList(reverse) {
let tabList = global.display.get_tab_list(
let tabList = Utils.getGlobal().display.get_tab_list(
Meta.TabList.NORMAL_ALL,
switcherSettings.get_boolean('current-workspace-only')
? global.workspace_manager.get_active_workspace() : null)
? Utils.getGlobal().workspace_manager.get_active_workspace() : null)
.filter(w => !Scratch.isScratchWindow(w));

let scratch = Scratch.getScratchWindows();

if (this.scratchOnly) {
return reverse ? scratch.reverse() : scratch;
}
else if (Scratch.isScratchWindow(global.display.focus_window)) {
else if (Scratch.isScratchWindow(Utils.getGlobal().display.focus_window)) {
// Access scratch windows in mru order with shift-super-tab
return scratch.concat(reverse ? tabList.reverse() : tabList);
} else {
Expand All @@ -73,7 +73,7 @@ export const LiveAltTab = GObject.registerClass(
// this.space.cloneContainer.add_effect(this.blur);
this.space.setSelectionInactive();

Main.uiGroup.insert_child_above(fog, global.window_group);
Main.uiGroup.insert_child_above(fog, Utils.getGlobal().window_group);
Easer.addEase(fog, {
time: Settings.prefs.animation_time,
opacity: 100,
Expand Down Expand Up @@ -154,6 +154,7 @@ export const LiveAltTab = GObject.registerClass(
// accepted. This can cause _select to run on the item below the pointer
// ensuring the wrong window.
if (!this.was_accepted) {
// eslint-disable-next-line prefer-rest-params
super._itemEnteredHandler.apply(this, arguments);
}
}
Expand Down
6 changes: 6 additions & 0 deletions tiling.js
Original file line number Diff line number Diff line change
Expand Up @@ -4227,6 +4227,12 @@ export function focus_handler(metaWindow) {
}

let space = spaces.spaceOfWindow(metaWindow);

// if window is on another monitor then warp pointer there
if (Utils.monitorAtCurrentPoint() !== space.monitor) {
Utils.warpPointerToMonitor(space.monitor);
}

if (metaWindow.fullscreen) {
space.enableWindowPositionBar(false);
space.setSpaceTopbarElementsVisible(false);
Expand Down
56 changes: 33 additions & 23 deletions utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,30 @@ import * as Config from 'resource:///org/gnome/shell/misc/config.js';

import { Lib } from './imports.js';

const Display = global.display;
const Display = getGlobal().display;
export let version = Config.PACKAGE_VERSION.split('.').map(Number);

let warpRipple;

let signals, touchCoords;
let inTouch = false;

/**
* Convenience function to get global. Avoids linter flagging
* references to global as no-undef
* @returns global
*/
export function getGlobal() {
// eslint-disable-next-line no-undef
return global;
}

export function enable() {
warpRipple = new Ripples.Ripples(0.5, 0.5, 'ripple-pointer-location');
warpRipple.addTo(Main.uiGroup);

signals = new Signals();
signals.connect(global.stage, "captured-event", (actor, event) => {
signals.connect(getGlobal().stage, "captured-event", (actor, event) => {
switch (event.type()) {
case Clutter.EventType.TOUCH_BEGIN:
case Clutter.EventType.TOUCH_UPDATE:
Expand Down Expand Up @@ -144,7 +154,7 @@ export function toggleWindowBoxes(metaWindow) {
boxes.push(makeFrameBox(actor, "yellow"));
}

boxes.forEach(box => global.stage.add_child(box));
boxes.forEach(box => getGlobal().stage.add_child(box));

metaWindow._paperDebugBoxes = boxes;
return boxes;
Expand Down Expand Up @@ -196,7 +206,7 @@ export function getPointerCoords() {
if (inTouch) {
return touchCoords;
} else {
return global.get_pointer();
return getGlobal().get_pointer();
}
}

Expand All @@ -215,34 +225,40 @@ export function monitorAtPoint(gx, gy) {
* Returns the monitor current pointer coordinates.
*/
export function monitorAtCurrentPoint() {
let [gx, gy, $] = getPointerCoords();
let [gx, gy] = getPointerCoords();
return monitorAtPoint(gx, gy);
}

/**
* Warps pointer to the center of a monitor.
*/
export function warpPointerToMonitor(monitor, center = false) {
export function warpPointerToMonitor(monitor, params = { center: false, ripple: true }) {
const center = params?.center ?? false;
const ripple = params?.ripple ?? true;

// no need to warp if already on this monitor
let currMonitor = monitorAtCurrentPoint();
if (currMonitor === monitor) {
return;
}

let [x, y, _mods] = global.get_pointer();
let [x, y] = getGlobal().get_pointer();
if (center) {
x -= monitor.x;
y -= monitor.y;
warpPointer(monitor.x + Math.floor(monitor.width / 2),
monitor.y + Math.floor(monitor.height / 2));
warpPointer(
monitor.x + Math.floor(monitor.width / 2),
monitor.y + Math.floor(monitor.height / 2),
ripple);
return;
}

let proportionalX = (x - currMonitor.x) / currMonitor.width;
let proportionalY = (y - currMonitor.y) / currMonitor.height;
warpPointer(
monitor.x + Math.floor(proportionalX * monitor.width),
monitor.y + Math.floor(proportionalY * monitor.height)
monitor.y + Math.floor(proportionalY * monitor.height),
ripple
);
}

Expand All @@ -262,7 +278,7 @@ export function warpPointer(x, y, ripple = true) {
* Return current modifiers state (or'ed Clutter.ModifierType.*)
*/
export function getModiferState() {
let [x, y, mods] = global.get_pointer();
let [, , mods] = getGlobal().get_pointer();
return mods;
}

Expand Down Expand Up @@ -294,6 +310,7 @@ export function mkFmt({ nameOnly } = { nameOnly: false }) {
const extraStr = extra.join(" | ");
let actorId = "";
if (nameOnly) {
// eslint-disable-next-line no-nested-ternary, eqeqeq
actorId = actor.name ? actor.name : prefix.length == 0 ? "" : "#";
} else {
actorId = actor.toString();
Expand Down Expand Up @@ -379,14 +396,7 @@ export function actor_reparent(actor, newParent) {
* Backwards compatible later_add function.
*/
export function later_add(...args) {
// Gnome 44+ uses global.compositor.get_laters()
if (global.compositor?.get_laters) {
global.compositor.get_laters().add(...args);
}
// Gnome 42, 43 used Meta.later_add
else if (Meta.later_add) {
Meta.later_add(...args);
}
getGlobal().compositor.get_laters().add(...args);
}

/**
Expand Down Expand Up @@ -563,10 +573,10 @@ export class DisplayConfig {
return;
}

const [serial, monitors, logicalMonitors] = state;
const [, monitors] = state;
for (const monitor of monitors) {
const [specs, modes, props] = monitor;
const [connector, vendor, product, serial] = specs;
const [specs] = monitor;
const [connector] = specs;

// upgrade gnome monitor object to add connector
let gnomeIndex = this.monitorManager.get_monitor_for_connector(connector);
Expand All @@ -591,7 +601,7 @@ export class DisplayConfig {
}

get monitorManager() {
return global.backend.get_monitor_manager();
return getGlobal().backend.get_monitor_manager();
}

get gnomeMonitors() {
Expand Down