diff --git a/package/contents/ui/config.ui b/package/contents/ui/config.ui index 8adb2d0..6ac6e65 100644 --- a/package/contents/ui/config.ui +++ b/package/contents/ui/config.ui @@ -101,6 +101,34 @@ + + + + Touchpad scrolling (Wayland only) + + + + + + Enable scrolling with touchpad gestures + + + Scroll with a three-finger horizontal swipe gesture + + + + + + + + Invert scroll direction (Natural scrolling) + + + + + + + @@ -343,6 +371,36 @@ + + + Touchpad gesture scrolling speed: + + + The amount to scroll per edge-to-edge gesture + + + + + + + px + + + 10000 + + + 100 + + + 100 + + + 1920 + + + + + Preset widths: @@ -352,7 +410,7 @@ - + Comma-separated list of widths. Supported units: "px" and "%". @@ -360,14 +418,14 @@ - + Obscured window opacity: - + % @@ -380,6 +438,7 @@ + diff --git a/package/contents/ui/main.qml b/package/contents/ui/main.qml index f59bb93..d4cd1a2 100644 --- a/package/contents/ui/main.qml +++ b/package/contents/ui/main.qml @@ -35,4 +35,20 @@ Item { flags: Notification.Persistent urgency: Notification.HighUrgency } + + SwipeGestureHandler { + direction: SwipeGestureHandler.Direction.Left + fingerCount: 3 + onActivated: qmlBase.karouselInstance.gestureScrollFinish() + onCancelled: qmlBase.karouselInstance.gestureScrollFinish() + onProgressChanged: qmlBase.karouselInstance.gestureScroll(-progress) + } + + SwipeGestureHandler { + direction: SwipeGestureHandler.Direction.Right + fingerCount: 3 + onActivated: qmlBase.karouselInstance.gestureScrollFinish() + onCancelled: qmlBase.karouselInstance.gestureScrollFinish() + onProgressChanged: qmlBase.karouselInstance.gestureScroll(progress) + } } diff --git a/src/lib/config/config.ts b/src/lib/config/config.ts index c2dde3d..f6a63e0 100644 --- a/src/lib/config/config.ts +++ b/src/lib/config/config.ts @@ -18,6 +18,9 @@ type Config = { scrollingLazy: boolean; scrollingCentered: boolean; scrollingGrouped: boolean; + gestureScroll: boolean; + gestureScrollInvert: boolean; + gestureScrollStep: number; tiledKeepBelow: boolean; floatingKeepAbove: boolean; windowRules: string; diff --git a/src/lib/config/definition.ts b/src/lib/config/definition.ts index b089665..15c2a8a 100644 --- a/src/lib/config/definition.ts +++ b/src/lib/config/definition.ts @@ -149,6 +149,21 @@ const configDef = [ type: "Bool", default: false, }, + { + name: "gestureScroll", + type: "Bool", + default: false, + }, + { + name: "gestureScrollInvert", + type: "Bool", + default: false, + }, + { + name: "gestureScrollStep", + type: "UInt", + default: 1920, + }, { name: "tiledKeepBelow", type: "Bool", diff --git a/src/lib/layout/Desktop.ts b/src/lib/layout/Desktop.ts index 5fc1188..54eccf9 100644 --- a/src/lib/layout/Desktop.ts +++ b/src/lib/layout/Desktop.ts @@ -1,6 +1,7 @@ class Desktop { public readonly grid: Grid; private scrollX: number; + private gestureScrollXInitial: number | null; private dirty: boolean; private dirtyScroll: boolean; private dirtyPins: boolean; @@ -15,6 +16,7 @@ class Desktop { layoutConfig: LayoutConfig, ) { this.scrollX = 0; + this.gestureScrollXInitial = null; this.dirty = true; this.dirtyScroll = true; this.dirtyPins = true; @@ -124,6 +126,24 @@ class Desktop { this.setScroll(this.scrollX + dx, force); } + public gestureScroll(amount: number) { + if (!this.config.gestureScroll) { + return + } + if (this.gestureScrollXInitial === null) { + this.gestureScrollXInitial = this.scrollX; + } + + if (this.config.gestureScrollInvert) { + amount = -amount; + } + this.setScroll(this.gestureScrollXInitial + this.config.gestureScrollStep * amount, false); + } + + public gestureScrollFinish() { + this.gestureScrollXInitial = null; + } + public arrange() { // TODO (optimization): only arrange visible windows this.updateArea(); @@ -160,6 +180,9 @@ namespace Desktop { marginBottom: number; marginLeft: number; marginRight: number; + gestureScroll: boolean; + gestureScrollInvert: boolean; + gestureScrollStep: number; scroller: Desktop.Scroller; clamper: Desktop.Clamper; }; diff --git a/src/lib/world/World.ts b/src/lib/world/World.ts index ddd90c0..2db41cf 100644 --- a/src/lib/world/World.ts +++ b/src/lib/world/World.ts @@ -61,6 +61,9 @@ class World { marginRight: config.gapsOuterRight, scroller: World.createScroller(config), clamper: config.scrollingLazy ? new EdgeClamper() : new CenterClamper(), + gestureScroll: config.gestureScroll, + gestureScrollInvert: config.gestureScrollInvert, + gestureScrollStep: config.gestureScrollStep, }, layoutConfig, Workspace.currentActivity, @@ -124,6 +127,14 @@ class World { this.doIfTiled(Workspace.activeWindow, f); } + public gestureScroll(amount: number) { + this.do((clientManager, desktopManager) => desktopManager.getCurrentDesktop().gestureScroll(amount)); + } + + public gestureScrollFinish() { + this.do((clientManager, desktopManager) => desktopManager.getCurrentDesktop().gestureScrollFinish()); + } + public destroy() { this.workspaceSignalManager.destroy(); for (const shortcutAction of this.shortcutActions) {