| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- /**
- * © gnome-shell-extension-tiling-assistant
- * Source: https://git.launchpad.net/ubuntu/+source/gnome-shell-extension-tiling-assistant/tree/tiling-assistant@leleat-on-github/src/prefs/shortcutListener.js
- *
- * This code is partially reused from Ubuntu tiling assistant extension (GPL-2.0).
- *
- * enableArrowBinding and disableArrowBinding are new methods.
- * Other methods are modified for our use case.
- */
- import * as Main from 'resource:///org/gnome/shell/ui/main.js';
- import Meta from 'gi://Meta';
- import Shell from 'gi://Shell';
- import GLib from 'gi://GLib';
- import {Shortcut} from '../common.js';
- import {Direction} from '../tileWindowManager.js';
- const MAX_RESIZE_GAP = 50;
- const MIN_RESIZE_GAP = 10;
- /**
- * Class to handle the keyboard shortcuts (on the extension side) except the
- * ones related to the Layouts. For those, see layoutsManager.js.
- */
- export default class KeybindingHandler {
- _keyBindings;
- _windowManager;
- _extensionObject = null;
- _settings;
- _waitingAction;
- _enableArrow = false;
- _prevArrowTyped;
- constructor(windowManager, extension) {
- this._extensionObject = extension;
- this._settings = extension.getSettings();
- this._windowManager = windowManager;
- this._prevArrowTyped = [Direction.North, 0];
- this._keyBindings = Shortcut.getShortcuts();
- this._keyBindings.forEach(key => {
- Main.wm.addKeybinding(key, this._settings, Meta.KeyBindingFlags.IGNORE_AUTOREPEAT, Shell.ActionMode.NORMAL, this._onCustomKeybindingPressed.bind(this, key));
- });
- }
- destroy() {
- this._keyBindings.forEach(key => Main.wm.removeKeybinding(key));
- this.disableArrowBinding();
- }
- enableArrowBinding() {
- let bindings = ['arrow-up', 'arrow-down', 'arrow-left', 'arrow-right', 'key-escape'];
- bindings.forEach(key => {
- Main.wm.addKeybinding(key, this._settings, Meta.KeyBindingFlags.IGNORE_AUTOREPEAT, Shell.ActionMode.NORMAL, this._onCustomKeybindingPressed.bind(this, key));
- });
- }
- disableArrowBinding() {
- let bindings = ['arrow-up', 'arrow-down', 'arrow-left', 'arrow-right', 'key-escape'];
- bindings.forEach(key => Main.wm.removeKeybinding(key));
- }
- compute_gap(direction) {
- const t = GLib.get_real_time();
- const dir = this._prevArrowTyped[0];
- const time = Math.min(Math.max(t - this._prevArrowTyped[1], 150000), 300000) - 150000;
- this._prevArrowTyped = [direction, t];
- let gap = dir === direction
- ? MAX_RESIZE_GAP - ((time * (MAX_RESIZE_GAP - MIN_RESIZE_GAP) / 150000))
- : MIN_RESIZE_GAP;
- return gap;
- }
- /**
- * @param {string} shortcutName
- */
- _onCustomKeybindingPressed(shortcutName) {
- switch (shortcutName) {
- case 'keybinding-close':
- global.display.get_focus_window().delete(global.get_current_time());
- break;
- case 'keybinding-open-settings':
- this._extensionObject?.openPreferences();
- break;
- case 'keybinding-rotation':
- this._windowManager.rotateWindow(global.display.get_focus_window());
- break;
- case 'keybinding-maximize':
- this._windowManager.maximizeTile(global.display.get_focus_window());
- break;
- case 'keybinding-search':
- this._windowManager.createSearchBar();
- break;
- case 'keybinding-refresh':
- // Unused
- this._windowManager.refresh();
- break;
- case 'keybinding-move-left':
- this._windowManager.moveTile(Direction.West);
- break;
- case 'keybinding-move-right':
- this._windowManager.moveTile(Direction.East);
- break;
- case 'keybinding-move-top':
- this._windowManager.moveTile(Direction.North);
- break;
- case 'keybinding-move-bottom':
- this._windowManager.moveTile(Direction.South);
- break;
- case 'keybinding-move':
- this._waitingAction = shortcutName;
- this.enableArrowBinding();
- break;
- case 'keybinding-resize':
- this._waitingAction = shortcutName;
- this.enableArrowBinding();
- break;
- case 'keybinding-resize-left':
- this._windowManager.resizeFocusedWindow(Meta.GrabOp.RESIZING_W);
- break;
- case 'keybinding-resize-right':
- this._windowManager.resizeFocusedWindow(Meta.GrabOp.RESIZING_E);
- break;
- case 'keybinding-resize-top':
- this._windowManager.resizeFocusedWindow(Meta.GrabOp.RESIZING_N);
- break;
- case 'keybinding-resize-bottom':
- this._windowManager.resizeFocusedWindow(Meta.GrabOp.RESIZING_S);
- break;
- case 'keybinding-focus':
- this._waitingAction = shortcutName;
- this.enableArrowBinding();
- break;
- case 'keybinding-focus-left':
- this._windowManager.changeFocus(Direction.West);
- break;
- case 'keybinding-focus-right':
- this._windowManager.changeFocus(Direction.East);
- break;
- case 'keybinding-focus-top':
- this._windowManager.changeFocus(Direction.North);
- break;
- case 'keybinding-focus-bottom':
- this._windowManager.changeFocus(Direction.South);
- break;
- case 'keybinding-next-workspace':
- this._windowManager.moveToWorkspace(true);
- break;
- case 'keybinding-previous-workspace':
- this._windowManager.moveToWorkspace(false);
- break;
- case 'keybinding-next-monitor':
- this._windowManager.moveToNextMonitor();
- break;
- case 'arrow-up':
- if (this._waitingAction === 'keybinding-move') {
- this._windowManager.moveTile(Direction.North);
- this.disableArrowBinding();
- } else if (this._waitingAction === 'keybinding-resize') {
- this._windowManager.resizeFocusedWindow(Meta.GrabOp.RESIZING_N, this.compute_gap(Direction.North));
- } else if (this._waitingAction === 'keybinding-focus') {
- this._windowManager.changeFocus(Direction.North);
- }
- break;
- case 'arrow-down':
- if (this._waitingAction === 'keybinding-move') {
- this._windowManager.moveTile(Direction.South);
- this.disableArrowBinding();
- } else if (this._waitingAction === 'keybinding-resize') {
- this._windowManager.resizeFocusedWindow(Meta.GrabOp.RESIZING_S, this.compute_gap(Direction.South));
- } else if (this._waitingAction === 'keybinding-focus') {
- this._windowManager.changeFocus(Direction.South);
- }
- break;
- case 'arrow-left':
- if (this._waitingAction === 'keybinding-move') {
- this._windowManager.moveTile(Direction.West);
- this.disableArrowBinding();
- } else if (this._waitingAction === 'keybinding-resize') {
- this._windowManager.resizeFocusedWindow(Meta.GrabOp.RESIZING_W, this.compute_gap(Direction.West));
- } else if (this._waitingAction === 'keybinding-focus') {
- this._windowManager.changeFocus(Direction.West);
- }
- break;
- case 'arrow-right':
- if (this._waitingAction === 'keybinding-move') {
- this._windowManager.moveTile(Direction.East);
- this.disableArrowBinding();
- } else if (this._waitingAction === 'keybinding-resize') {
- this._windowManager.resizeFocusedWindow(Meta.GrabOp.RESIZING_E, this.compute_gap(Direction.East));
- } else if (this._waitingAction === 'keybinding-focus') {
- this._windowManager.changeFocus(Direction.East);
- }
- break;
- case 'key-escape':
- this.disableArrowBinding();
- break;
- default:
- break;
- }
- }
- }
|