summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2021-03-18 19:01:50 +0100
committerCarlos Garnacho <carlosg@gnome.org>2021-03-19 12:00:27 +0100
commit6a1b8d67a32cb26e764b56b1efb92af1de490e22 (patch)
treec20c0a2a16964986d6e0f3092215b35c75ab798e
parent77ee2b2198f5441771b80a300c0a78725461f0a2 (diff)
downloadgnome-shell-wip/carlosg/app-grid-gestures.tar.gz
appDisplay: Improve app grid interaction for touch deviceswip/carlosg/app-grid-gestures
Currently, handling of touch devices in the app grid is a bit awkward, paging by dragging the view can only happen if started from the gaps between icons, trying to drag from an icon will trigger DnD, and popping up the menu takes over it all. Instead, have the app grid actions play this game of rock-paper-scissors: - Fast swipes on icons trigger scrolling, beats DnD and menu - Slower press-and-drag on icons trigger DnD, beats scrolling and menu - Long press triggers menu, beats scrolling, is beaten by DnD This allows quick swipes to handle navigation, while still allowing the fine grained operations. DnD, when triggered, dismisses the menu, if shown. This all could probably be nicer with a more stateful gesture framework, we're not there yet though. Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3849
-rw-r--r--js/ui/appDisplay.js45
1 files changed, 41 insertions, 4 deletions
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index 40122ad4b..d6eb9d7c4 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -492,6 +492,11 @@ var BaseAppView = GObject.registerClass({
if (monitor !== Main.layoutManager.primaryIndex)
return;
+ if (this._dragFocus) {
+ this._dragFocus.cancelActions();
+ this._dragFocus = null;
+ }
+
const adjustment = this._adjustment;
adjustment.remove_transition('value');
@@ -674,6 +679,8 @@ var BaseAppView = GObject.registerClass({
};
DND.addDragMonitor(this._dragMonitor);
this._slideSidePages(SidePages.PREVIOUS | SidePages.NEXT | SidePages.DND);
+ this._dragFocus = null;
+ this._swipeTracker.enabled = false;
}
_onDragMotion(dragEvent) {
@@ -710,6 +717,7 @@ var BaseAppView = GObject.registerClass({
this._resetOvershoot();
this._slideSidePages(SidePages.NONE);
delete this._dropPage;
+ this._swipeTracker.enabled = true;
}
_onDragCancelled() {
@@ -717,6 +725,7 @@ var BaseAppView = GObject.registerClass({
// will move all items to their original positions
this._redisplay();
this._slideSidePages(SidePages.NONE);
+ this._swipeTracker.enabled = true;
}
_canAccept(source) {
@@ -1318,6 +1327,10 @@ var BaseAppView = GObject.registerClass({
});
}
}
+
+ updateDragFocus(dragFocus) {
+ this._dragFocus = dragFocus;
+ }
});
var PageManager = GObject.registerClass({
@@ -1509,6 +1522,10 @@ class AppDisplay extends BaseAppView {
global.settings.is_writable('app-picker-layout');
this._placeholder = new AppIcon(app, { isDraggable });
+ this._placeholder.connect('notify::pressed', () => {
+ if (this._placeholder.pressed)
+ this.updateDragFocus(this._placeholder);
+ });
this._placeholder.scaleAndFade();
this._redisplay();
}
@@ -1584,6 +1601,10 @@ class AppDisplay extends BaseAppView {
this._redisplay();
this._savePages();
});
+ icon.connect('notify::pressed', () => {
+ if (icon.pressed)
+ this.updateDragFocus(icon);
+ });
}
// Don't try to display empty folders
@@ -1617,6 +1638,10 @@ class AppDisplay extends BaseAppView {
let app = appSys.lookup_app(appId);
icon = new AppIcon(app, { isDraggable });
+ icon.connect('notify::pressed', () => {
+ if (icon.pressed)
+ this.updateDragFocus(icon);
+ });
}
appIcons.push(icon);
@@ -1936,7 +1961,8 @@ class AppViewItem extends St.Button {
this._delegate = this;
if (isDraggable) {
- this._draggable = DND.makeDraggable(this);
+ this._draggable = DND.makeDraggable(this, { timeoutThreshold: 200 });
+
this._draggable.connect('drag-begin', this._onDragBegin.bind(this));
this._draggable.connect('drag-cancelled', this._onDragCancelled.bind(this));
this._draggable.connect('drag-end', this._onDragEnd.bind(this));
@@ -2115,6 +2141,11 @@ class AppViewItem extends St.Button {
return true;
}
+ cancelActions() {
+ this._draggable.fakeRelease();
+ this.fake_release();
+ }
+
get id() {
return this._id;
}
@@ -3112,6 +3143,8 @@ var AppIcon = GObject.registerClass({
}
_onDragBegin() {
+ if (this._menu)
+ this._menu.close(true);
this._removeMenuTimeout();
super._onDragBegin();
}
@@ -3189,9 +3222,6 @@ var AppIcon = GObject.registerClass({
this._removeMenuTimeout();
this.fake_release();
- if (this._draggable)
- this._draggable.fakeRelease();
-
if (!this._menu) {
this._menu = new AppIconMenu(this, side);
this._menu.connect('activate-window', (menu, window) => {
@@ -3346,6 +3376,13 @@ var AppIcon = GObject.registerClass({
return view.createFolder(apps);
}
+
+ cancelActions() {
+ if (this._menu)
+ this._menu.close(true);
+ this._removeMenuTimeout();
+ super.cancelActions();
+ }
});
var AppIconMenu = class AppIconMenu extends PopupMenu.PopupMenu {