From 38ea9dabfa72f7c00960861cbd8d377d5d2f9535 Mon Sep 17 00:00:00 2001 From: TheSola10 Date: Mon, 29 Jan 2024 23:38:04 +0100 Subject: [PATCH 1/4] WIP: Implemented global coords broker with touch events --- grab.js | 20 ++++++++------------ utils.js | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/grab.js b/grab.js index 5aee3ec45..e808a9b2b 100644 --- a/grab.js +++ b/grab.js @@ -63,7 +63,7 @@ export class MoveGrab { this.initialY = clone.targetY; Easer.removeEase(clone); - let [gx, gy, $] = global.get_pointer(); + let [gx, gy, $] = Utils.getPointerCoords(); let px = (gx - actor.x) / actor.width; let py = (gy - actor.y) / actor.height; @@ -86,7 +86,8 @@ export class MoveGrab { this.signals.connect(this.actor, "button-release-event", this.end.bind(this)); this.signals.connect(this.actor, "touch-event", (act, evt) => { - if (evt.type() === Clutter.EventType.TOUCH_END) { + if (evt.type() === Clutter.EventType.TOUCH_END + || evt.type() === Clutter.EventType.TOUCH_CANCEL) { this.end(); } else { @@ -121,7 +122,7 @@ export class MoveGrab { let clone = metaWindow.clone; let space = this.initialSpace; - let [gx, gy, $] = global.get_pointer(); + let [gx, gy, $] = Utils.getPointerCoords(); let point = {}; if (center) { point = space.cloneContainer.apply_relative_transform_to_point( @@ -177,7 +178,7 @@ export class MoveGrab { } spaceMotion(space, background, event) { - let [gx, gy, $] = global.get_pointer(); + let [gx, gy, $] = Utils.getPointerCoords(); let [sx, sy] = space.globalToScroll(gx, gy, { useTarget: true }); this.selectDndZone(space, sx, sy); } @@ -308,12 +309,7 @@ export class MoveGrab { motion(actor, event) { let metaWindow = this.window; // let [gx, gy] = event.get_coords(); - let [gx, gy, $] = global.get_pointer(); - if (event.type() === Clutter.EventType.TOUCH_UPDATE) { - [gx, gy] = event.get_coords(); - // We update global pointer to match touch event - Utils.warpPointer(gx, gy, false); - } + let [gx, gy, $] = Utils.getPointerCoords(); let [dx, dy] = this.pointerOffset; let clone = metaWindow.clone; @@ -370,7 +366,7 @@ export class MoveGrab { let metaWindow = this.window; let actor = metaWindow.get_compositor_private(); let clone = metaWindow.clone; - let [gx, gy, $] = global.get_pointer(); + let [gx, gy, $] = Utils.getPointerCoords(); this.zoneActors.forEach(actor => actor.destroy()); let params = { @@ -498,7 +494,7 @@ export class MoveGrab { Utils.later_add(Meta.LaterType.IDLE, () => { if (!global.display.end_grab_op && this.wasTiled) { // move to current cursor position - let [x, y, _mods] = global.get_pointer(); + let [x, y, _mods] = Utils.getPointerCoords(); getVirtualPointer().notify_absolute_motion( Clutter.get_current_event_time(), x, y); diff --git a/utils.js b/utils.js index a8d1429d7..5b39d32a9 100644 --- a/utils.js +++ b/utils.js @@ -16,15 +16,37 @@ const Display = global.display; export let version = Config.PACKAGE_VERSION.split('.').map(Number); let warpRipple; + +let touchSignal = null; +let inTouch = false; +let touchCoords = null; + export function enable() { warpRipple = new Ripples.Ripples(0.5, 0.5, 'ripple-pointer-location'); warpRipple.addTo(Main.uiGroup); + + touchSignal = global.stage.connect("captured-event", (actor, event) => { + switch (event.type()) { + case Clutter.EventType.TOUCH_BEGIN: + case Clutter.EventType.TOUCH_UPDATE: + inTouch = true; + break; + case Clutter.EventType.TOUCH_END: + case Clutter.EventType.TOUCH_CANCEL: + inTouch = false; + break; + } + touchCoords = event.get_coords(); + return Clutter.EVENT_PROPAGATE; + }); } export function disable() { warpRipple?.destroy(); warpRipple = null; markNewClonesSignalId = null; + + global.stage.disconnect(touchSignal); } export function assert(condition, message, ...dump) { @@ -161,6 +183,16 @@ export function isInRect(x, y, r) { r.y <= y && y < r.y + r.height; } +/** + * Retrieves global pointer coordinates taking into account touch screen events. + */ +export function getPointerCoords() { + if (inTouch) + return touchCoords; + else + return global.get_pointer(); +} + /** * Returns monitor a pointer co-ordinates. */ @@ -176,7 +208,7 @@ export function monitorAtPoint(gx, gy) { * Returns the monitor current pointer coordinates. */ export function monitorAtCurrentPoint() { - let [gx, gy, $] = global.get_pointer(); + let [gx, gy, $] = getPointerCoords(); return monitorAtPoint(gx, gy); } From 592fea25c56eaced0ef5a32ec2c2b2f2228760fd Mon Sep 17 00:00:00 2001 From: TheSola10 Date: Fri, 8 Mar 2024 11:03:43 +0100 Subject: [PATCH 2/4] Added fast escape-hatch --- utils.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/utils.js b/utils.js index 5b39d32a9..71e9b49a4 100644 --- a/utils.js +++ b/utils.js @@ -35,7 +35,11 @@ export function enable() { case Clutter.EventType.TOUCH_CANCEL: inTouch = false; break; + default: + return Clutter.EVENT_PROPAGATE; } + + // was one of our touch events touchCoords = event.get_coords(); return Clutter.EVENT_PROPAGATE; }); From fbca41f78e3ad58c5979995bf6877b3ad8a0679c Mon Sep 17 00:00:00 2001 From: TheSola10 Date: Fri, 2 Feb 2024 19:07:11 +0100 Subject: [PATCH 3/4] Implemented proposal from #766 This approach calls Utils.getPointerCoords() (the unified touch broker) when the event starts ONLY. Since the touch tracker fails to update once the event is "adopted" by a widget, we still need to update the global cursor's coordinates. This superficially fixes #764, but REVERT this commit before working on cleaning up touch handling! --- grab.js | 18 +++++++++++------- utils.js | 5 +++-- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/grab.js b/grab.js index e808a9b2b..9956e812d 100644 --- a/grab.js +++ b/grab.js @@ -86,8 +86,7 @@ export class MoveGrab { this.signals.connect(this.actor, "button-release-event", this.end.bind(this)); this.signals.connect(this.actor, "touch-event", (act, evt) => { - if (evt.type() === Clutter.EventType.TOUCH_END - || evt.type() === Clutter.EventType.TOUCH_CANCEL) { + if (evt.type() === Clutter.EventType.TOUCH_END) { this.end(); } else { @@ -122,7 +121,7 @@ export class MoveGrab { let clone = metaWindow.clone; let space = this.initialSpace; - let [gx, gy, $] = Utils.getPointerCoords(); + let [gx, gy, $] = global.get_pointer(); let point = {}; if (center) { point = space.cloneContainer.apply_relative_transform_to_point( @@ -178,7 +177,7 @@ export class MoveGrab { } spaceMotion(space, background, event) { - let [gx, gy, $] = Utils.getPointerCoords(); + let [gx, gy, $] = global.get_pointer(); let [sx, sy] = space.globalToScroll(gx, gy, { useTarget: true }); this.selectDndZone(space, sx, sy); } @@ -309,7 +308,12 @@ export class MoveGrab { motion(actor, event) { let metaWindow = this.window; // let [gx, gy] = event.get_coords(); - let [gx, gy, $] = Utils.getPointerCoords(); + let [gx, gy, $] = global.get_pointer(); + if (event.type() === Clutter.EventType.TOUCH_UPDATE) { + [gx, gy] = event.get_coords(); + // We update global pointer to match touch event + Utils.warpPointer(gx, gy, false); + } let [dx, dy] = this.pointerOffset; let clone = metaWindow.clone; @@ -366,7 +370,7 @@ export class MoveGrab { let metaWindow = this.window; let actor = metaWindow.get_compositor_private(); let clone = metaWindow.clone; - let [gx, gy, $] = Utils.getPointerCoords(); + let [gx, gy, $] = global.get_pointer(); this.zoneActors.forEach(actor => actor.destroy()); let params = { @@ -494,7 +498,7 @@ export class MoveGrab { Utils.later_add(Meta.LaterType.IDLE, () => { if (!global.display.end_grab_op && this.wasTiled) { // move to current cursor position - let [x, y, _mods] = Utils.getPointerCoords(); + let [x, y, _mods] = global.get_pointer(); getVirtualPointer().notify_absolute_motion( Clutter.get_current_event_time(), x, y); diff --git a/utils.js b/utils.js index 71e9b49a4..18383bd2c 100644 --- a/utils.js +++ b/utils.js @@ -191,10 +191,11 @@ export function isInRect(x, y, r) { * Retrieves global pointer coordinates taking into account touch screen events. */ export function getPointerCoords() { - if (inTouch) + if (inTouch) { return touchCoords; - else + } else { return global.get_pointer(); + } } /** From e05a16a853b3dbfc863787781c7fb852731283d7 Mon Sep 17 00:00:00 2001 From: Jay Ta'ala Date: Sat, 9 Mar 2024 20:51:23 +1100 Subject: [PATCH 4/4] Switch to PaperWM signals class. --- utils.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/utils.js b/utils.js index 18383bd2c..5bb8eb5a8 100644 --- a/utils.js +++ b/utils.js @@ -17,15 +17,15 @@ export let version = Config.PACKAGE_VERSION.split('.').map(Number); let warpRipple; -let touchSignal = null; +let signals, touchCoords; let inTouch = false; -let touchCoords = null; export function enable() { warpRipple = new Ripples.Ripples(0.5, 0.5, 'ripple-pointer-location'); warpRipple.addTo(Main.uiGroup); - touchSignal = global.stage.connect("captured-event", (actor, event) => { + signals = new Signals(); + signals.connect(global.stage, "captured-event", (actor, event) => { switch (event.type()) { case Clutter.EventType.TOUCH_BEGIN: case Clutter.EventType.TOUCH_UPDATE: @@ -50,7 +50,8 @@ export function disable() { warpRipple = null; markNewClonesSignalId = null; - global.stage.disconnect(touchSignal); + signals.destroy(); + signals = null; } export function assert(condition, message, ...dump) { @@ -189,6 +190,7 @@ export function isInRect(x, y, r) { /** * Retrieves global pointer coordinates taking into account touch screen events. + * May not work for continuous tracking, see #766. */ export function getPointerCoords() { if (inTouch) {