You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
243 lines
10 KiB
243 lines
10 KiB
From a796215ddce14ebe80774b99e29d0d28109c818b Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
|
Date: Wed, 6 Mar 2024 20:14:14 +0100
|
|
Subject: [PATCH] desktop-icons: Handle touch events
|
|
|
|
File icons currently only deal with button events. Split up the
|
|
current handlers and use them to handle touch events as well.
|
|
---
|
|
extensions/desktop-icons/fileItem.js | 181 +++++++++++++++++++--------
|
|
1 file changed, 128 insertions(+), 53 deletions(-)
|
|
|
|
diff --git a/extensions/desktop-icons/fileItem.js b/extensions/desktop-icons/fileItem.js
|
|
index 37ee54db..26afddb2 100644
|
|
--- a/extensions/desktop-icons/fileItem.js
|
|
+++ b/extensions/desktop-icons/fileItem.js
|
|
@@ -140,6 +140,7 @@ var FileItem = GObject.registerClass({
|
|
this._container.connect('leave-event', (actor, event) => this._onLeave(actor, event));
|
|
this._container.connect('enter-event', (actor, event) => this._onEnter(actor, event));
|
|
this._container.connect('button-release-event', (actor, event) => this._onReleaseButton(actor, event));
|
|
+ this._container.connect('touch-event', (actor, event) => this._onTouchEvent(actor, event));
|
|
|
|
/* Set the metadata and update relevant UI */
|
|
this._updateMetadataFromFileInfo(fileInfo);
|
|
@@ -229,6 +230,10 @@ var FileItem = GObject.registerClass({
|
|
if (this._iconAllocationIdleId)
|
|
GLib.source_remove(this._iconAllocationIdleId);
|
|
|
|
+ if (this._longPressTimeoutId)
|
|
+ GLib.source_remove(this._longPressTimeoutId);
|
|
+ delete this._longPressTimeoutId;
|
|
+
|
|
/* Menu */
|
|
this._removeMenu();
|
|
}
|
|
@@ -731,58 +736,141 @@ var FileItem = GObject.registerClass({
|
|
}
|
|
|
|
_updateClickState(event) {
|
|
+ const eventType = event.type();
|
|
+ const isButton =
|
|
+ eventType === Clutter.EventType.BUTTON_PRESS ||
|
|
+ eventType === Clutter.EventType.BUTTON_RELEASE;
|
|
+ const button = isButton ? event.get_button() : 0;
|
|
+ const time = event.get_time();
|
|
+
|
|
let settings = Clutter.Settings.get_default();
|
|
- if ((event.get_button() == this._lastClickButton) &&
|
|
- ((event.get_time() - this._lastClickTime) < settings.double_click_time))
|
|
+ if (button === this._lastClickButton &&
|
|
+ (time - this._lastClickTime) < settings.double_click_time)
|
|
this._clickCount++;
|
|
else
|
|
this._clickCount = 1;
|
|
|
|
- this._lastClickTime = event.get_time();
|
|
- this._lastClickButton = event.get_button();
|
|
+ this._lastClickTime = time;
|
|
+ this._lastClickButton = button;
|
|
}
|
|
|
|
_getClickCount() {
|
|
return this._clickCount;
|
|
}
|
|
|
|
+ _handlePressEvent(event) {
|
|
+ const pressSequence = event.get_event_sequence();
|
|
+ if (this._pressSequence &&
|
|
+ pressSequence?.get_slot() !== this._pressSequence.get_slot())
|
|
+ return Clutter.EVENT_PROPAGATE;
|
|
+
|
|
+ this._primaryButtonPressed = true;
|
|
+ this._pressSequence = pressSequence;
|
|
+ this._pressDevice = event.get_device();
|
|
+
|
|
+ if (this._getClickCount() !== 1)
|
|
+ return Clutter.EVENT_STOP;
|
|
+
|
|
+ const [x, y] = event.get_coords();
|
|
+ this._buttonPressInitialX = x;
|
|
+ this._buttonPressInitialY = y;
|
|
+
|
|
+ const shiftPressed = !!(event.get_state() & Clutter.ModifierType.SHIFT_MASK);
|
|
+ const controlPressed = !!(event.get_state() & Clutter.ModifierType.CONTROL_MASK);
|
|
+ if (controlPressed || shiftPressed)
|
|
+ this.emit('selected', true, false, !this._isSelected);
|
|
+ else if (!this._isSelected)
|
|
+ this.emit('selected', false, false, true);
|
|
+
|
|
+ return Clutter.EVENT_STOP;
|
|
+ }
|
|
+
|
|
+ _handleSecondaryPress() {
|
|
+ if (!this.isSelected)
|
|
+ this.emit('selected', false, false, true);
|
|
+ this._ensureMenu().toggle();
|
|
+ if (this._actionOpenWith) {
|
|
+ let allowOpenWith = Extension.desktopManager.getNumberOfSelectedItems() === 1;
|
|
+ this._actionOpenWith.setSensitive(allowOpenWith);
|
|
+ }
|
|
+ const specialFilesSelected =
|
|
+ Extension.desktopManager.checkIfSpecialFilesAreSelected();
|
|
+ if (this._actionCut)
|
|
+ this._actionCut.setSensitive(!specialFilesSelected);
|
|
+ if (this._actionCopy)
|
|
+ this._actionCopy.setSensitive(!specialFilesSelected);
|
|
+ if (this._actionTrash)
|
|
+ this._actionTrash.setSensitive(!specialFilesSelected);
|
|
+ return Clutter.EVENT_STOP;
|
|
+ }
|
|
+
|
|
+ _handleReleaseEvent(event) {
|
|
+ if (this._longPressTimeoutId)
|
|
+ GLib.source_remove(this._longPressTimeoutId);
|
|
+ delete this._longPressTimeoutId;
|
|
+
|
|
+ if (!this._primaryButtonPressed || this._pressDevice !== event.get_device())
|
|
+ return Clutter.EVENT_PROPAGATE;
|
|
+
|
|
+ const pressSequence = event.get_event_sequence();
|
|
+ if (this._pressSequence &&
|
|
+ pressSequence?.get_slot() !== this._pressSequence.get_slot())
|
|
+ return Clutter.EVENT_PROPAGATE;
|
|
+
|
|
+ // primaryButtonPressed is TRUE only if the user has pressed the button
|
|
+ // over an icon, and if (s)he has not started a drag&drop operation
|
|
+ this._primaryButtonPressed = false;
|
|
+ delete this._pressDevice;
|
|
+ delete this._pressSequence;
|
|
+
|
|
+ let shiftPressed = !!(event.get_state() & Clutter.ModifierType.SHIFT_MASK);
|
|
+ let controlPressed = !!(event.get_state() & Clutter.ModifierType.CONTROL_MASK);
|
|
+ if (!controlPressed && !shiftPressed)
|
|
+ this.emit('selected', false, false, true);
|
|
+ if (this._getClickCount() === 1 && Prefs.CLICK_POLICY_SINGLE && !shiftPressed && !controlPressed)
|
|
+ this.doOpen();
|
|
+ if (this._getClickCount() === 2 && !Prefs.CLICK_POLICY_SINGLE)
|
|
+ this.doOpen();
|
|
+ return Clutter.EVENT_STOP;
|
|
+ }
|
|
+
|
|
+ _onTouchEvent(actor, event) {
|
|
+ // on X11, let pointer emulation deal with touch
|
|
+ if (!Meta.is_wayland_compositor())
|
|
+ return Clutter.EVENT_PROPAGATE;
|
|
+
|
|
+ const type = event.type();
|
|
+ if (type === Clutter.EventType.TOUCH_BEGIN) {
|
|
+ Extension.desktopManager.endRubberBand();
|
|
+ this._updateClickState(event);
|
|
+
|
|
+ if (!this._handlePressEvent(event))
|
|
+ return Clutter.EVENT_PROPAGATE;
|
|
+
|
|
+ const { longPressDuration } = Clutter.Settings.get_default();
|
|
+ this._longPressTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
|
|
+ longPressDuration,
|
|
+ () => {
|
|
+ this._handleSecondaryPress();
|
|
+ delete this._longPressTimeoutId;
|
|
+ return GLib.SOURCE_REMOVE;
|
|
+ });
|
|
+
|
|
+ return Clutter.EVENT_STOP;
|
|
+ } else if (type === Clutter.EventType.TOUCH_END) {
|
|
+ return this._handleReleaseEvent(event);
|
|
+ }
|
|
+ return Clutter.EVENT_PROPAGATE;
|
|
+ }
|
|
+
|
|
_onPressButton(actor, event) {
|
|
Extension.desktopManager.endRubberBand();
|
|
this._updateClickState(event);
|
|
let button = event.get_button();
|
|
- if (button == 3) {
|
|
- if (!this.isSelected)
|
|
- this.emit('selected', false, false, true);
|
|
- this._ensureMenu().toggle();
|
|
- if (this._actionOpenWith) {
|
|
- let allowOpenWith = (Extension.desktopManager.getNumberOfSelectedItems() == 1);
|
|
- this._actionOpenWith.setSensitive(allowOpenWith);
|
|
- }
|
|
- let specialFilesSelected = Extension.desktopManager.checkIfSpecialFilesAreSelected();
|
|
- if (this._actionCut)
|
|
- this._actionCut.setSensitive(!specialFilesSelected);
|
|
- if (this._actionCopy)
|
|
- this._actionCopy.setSensitive(!specialFilesSelected);
|
|
- if (this._actionTrash)
|
|
- this._actionTrash.setSensitive(!specialFilesSelected);
|
|
- return Clutter.EVENT_STOP;
|
|
- } else if (button == 1) {
|
|
- if (this._getClickCount() == 1) {
|
|
- let [x, y] = event.get_coords();
|
|
- this._primaryButtonPressed = true;
|
|
- this._buttonPressInitialX = x;
|
|
- this._buttonPressInitialY = y;
|
|
- let shiftPressed = !!(event.get_state() & Clutter.ModifierType.SHIFT_MASK);
|
|
- let controlPressed = !!(event.get_state() & Clutter.ModifierType.CONTROL_MASK);
|
|
- if (controlPressed || shiftPressed) {
|
|
- this.emit('selected', true, false, !this._isSelected);
|
|
- } else {
|
|
- if (!this._isSelected)
|
|
- this.emit('selected', false, false, true);
|
|
- }
|
|
- }
|
|
- return Clutter.EVENT_STOP;
|
|
- }
|
|
+ if (button == 3)
|
|
+ return this._handleSecondaryPress();
|
|
+ if (button == 1)
|
|
+ return this._handlePressEvent(event);
|
|
|
|
return Clutter.EVENT_PROPAGATE;
|
|
}
|
|
@@ -821,22 +909,9 @@ var FileItem = GObject.registerClass({
|
|
|
|
_onReleaseButton(actor, event) {
|
|
let button = event.get_button();
|
|
- if (button == 1) {
|
|
- // primaryButtonPressed is TRUE only if the user has pressed the button
|
|
- // over an icon, and if (s)he has not started a drag&drop operation
|
|
- if (this._primaryButtonPressed) {
|
|
- this._primaryButtonPressed = false;
|
|
- let shiftPressed = !!(event.get_state() & Clutter.ModifierType.SHIFT_MASK);
|
|
- let controlPressed = !!(event.get_state() & Clutter.ModifierType.CONTROL_MASK);
|
|
- if (!controlPressed && !shiftPressed)
|
|
- this.emit('selected', false, false, true);
|
|
- if ((this._getClickCount() == 1) && Prefs.CLICK_POLICY_SINGLE && !shiftPressed && !controlPressed)
|
|
- this.doOpen();
|
|
- return Clutter.EVENT_STOP;
|
|
- }
|
|
- if ((this._getClickCount() == 2) && (!Prefs.CLICK_POLICY_SINGLE))
|
|
- this.doOpen();
|
|
- }
|
|
+ if (button == 1)
|
|
+ return this._handleReleaseEvent(event);
|
|
+
|
|
return Clutter.EVENT_PROPAGATE;
|
|
}
|
|
|
|
--
|
|
2.44.0
|
|
|