Skip to content

Commit

Permalink
feat: support touch events
Browse files Browse the repository at this point in the history
  • Loading branch information
Christopher Lübbemeier committed Apr 6, 2024
1 parent b94a0cf commit 6b30aa5
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## v25

- Chore: Migrate to GNOME 46
- Feature: Support touch input
- Fix: Delay when opening the overview

## v24
Expand Down
39 changes: 37 additions & 2 deletions src/ui/WorkspacesBar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Settings } from '../services/Settings';
import { Styles } from '../services/Styles';
import { WorkspaceState, Workspaces } from '../services/Workspaces';
import { Subject } from '../utils/Subject';
import { Timeout } from '../utils/Timeout';
import { WorkspacesBarMenu } from './WorkspacesBarMenu';

interface DragEvent {
Expand Down Expand Up @@ -43,6 +44,10 @@ interface WsBoxPosition {
* Maximum number of milliseconds between button press and button release to be recognized as click.
*/
const MAX_CLICK_TIME_DELTA = 300;
/**
* Time in milliseconds until a touch event is recognized as long press.
*/
const LONG_PRESS_DURATION = 500;

export class WorkspacesBar {
private readonly _name = `${this._extension.metadata.name}`;
Expand All @@ -57,6 +62,7 @@ export class WorkspacesBar {
/** The child of `_button` when `indicator-style` is `workspaces-bar`. */
private _wsBar?: St.BoxLayout;
private readonly _dragHandler = new WorkspacesBarDragHandler(() => this._updateWorkspaces());
private readonly _touchTimeout = new Timeout();

constructor(private _extension: any) {}

Expand All @@ -77,6 +83,7 @@ export class WorkspacesBar {
this._menu.destroy();
this._dragHandler.destroy();
this._buttonSubject.complete();
this._touchTimeout.destroy();
}

observeWidget(): Subject<any> {
Expand Down Expand Up @@ -218,7 +225,34 @@ export class WorkspacesBar {
}
return Clutter.EVENT_PROPAGATE;
});
this._dragHandler.setupDnd(wsBox, workspace);
let lastTouchBeginEvent: Clutter.Event | null;
wsBox.connect('touch-event', (actor, event: Clutter.Event) => {
switch (event.type()) {
case Clutter.EventType.TOUCH_BEGIN:
lastTouchBeginEvent = event;
this._touchTimeout
.once(LONG_PRESS_DURATION)
.then(() => this._button.menu.toggle());
break;
case Clutter.EventType.TOUCH_END:
if (lastTouchBeginEvent) {
const timeDelta = event.get_time() - lastTouchBeginEvent.get_time();
if (timeDelta <= MAX_CLICK_TIME_DELTA) {
this._ws.activate(workspace.index);
}
lastTouchBeginEvent = null;
}
this._touchTimeout.clearTimeout();
break;
case Clutter.EventType.TOUCH_CANCEL:
this._touchTimeout.clearTimeout();
break;
}
return Clutter.EVENT_PROPAGATE;
});
this._dragHandler.setupDnd(wsBox, workspace, {
onDragStart: () => this._touchTimeout.clearTimeout(),
});
return wsBox;
}

Expand Down Expand Up @@ -276,10 +310,11 @@ class WorkspacesBarDragHandler {
this._setDragMonitor(false);
}

setupDnd(wsBox: St.Bin, workspace: WorkspaceState): void {
setupDnd(wsBox: St.Bin, workspace: WorkspaceState, hooks: { onDragStart: () => void }): void {
const draggable = DND.makeDraggable(wsBox, {});
draggable.connect('drag-begin', () => {
this._onDragStart(wsBox, workspace);
hooks.onDragStart();
});
draggable.connect('drag-cancelled', () => {
this._updateDragPlaceholder(this._initialDropPosition!);
Expand Down
17 changes: 14 additions & 3 deletions src/utils/Timeout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ export class Timeout {
private _timeoutId: number | null = null;

destroy(): void {
this._clearTimeout();
this.clearTimeout();
}

tick() {
return new Promise<void>((resolve) => {
this._clearTimeout();
this.clearTimeout();
this._timeoutId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 0, () => {
this._timeoutId = null;
resolve();
Expand All @@ -18,7 +18,18 @@ export class Timeout {
});
}

private _clearTimeout() {
once(milliseconds: number) {
return new Promise<void>((resolve) => {
this.clearTimeout();
this._timeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, milliseconds, () => {
this._timeoutId = null;
resolve();
return GLib.SOURCE_REMOVE;
});
});
}

clearTimeout() {
if (this._timeoutId) {
GLib.Source.remove(this._timeoutId);
this._timeoutId = null;
Expand Down

0 comments on commit 6b30aa5

Please sign in to comment.