From 77cc572dc550d10b2f1819fd9a2805fdaa86cb27 Mon Sep 17 00:00:00 2001 From: Domenico Ferraro Date: Thu, 14 Nov 2024 22:36:57 +0100 Subject: [PATCH] version 15.0: auto tiling and improved keybindings --- README.md | 13 +- package.json | 2 +- resources/metadata.json | 2 +- src/components/snapassist/snapAssist.ts | 6 +- .../tilepreview/selectionTilePreview.ts | 2 +- src/components/tilepreview/tilePreview.ts | 6 +- .../tilingsystem/edgeTilingManager.ts | 7 +- src/components/tilingsystem/resizeManager.ts | 3 +- src/components/tilingsystem/tilingLayout.ts | 117 +--- src/components/tilingsystem/tilingManager.ts | 141 +++-- src/components/windowBorderManager.ts | 25 +- src/extension.ts | 27 +- src/indicator/defaultMenu.ts | 41 +- src/indicator/indicator.ts | 4 +- src/keybindings.ts | 10 +- src/prefs.ts | 96 +-- src/settings/settings.ts | 573 ++++++++++-------- src/settings/settingsExport.ts | 12 +- src/settings/settingsOverride.ts | 8 +- src/utils/globalState.ts | 31 +- tsconfig.json | 2 +- 21 files changed, 588 insertions(+), 540 deletions(-) diff --git a/README.md b/README.md index d78cf0e..1299ef6 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ # Tiling Shell # -This is a Gnome Shell extension implementing modern windows tiling system by extending GNOME's default 2 columns to any layout you want! Can be installed on Gnome Shells from **40 to 46** on X11 and Wayland: the most recent GNOME Shell is supported, and older releases will include all the features and bug fixes! +This is a Gnome Shell extension implementing modern windows tiling system by extending GNOME's default 2 columns to any layout you want! Can be installed on Gnome Shells from **40 to 47** on X11 and Wayland: the most recent GNOME Shell is supported, and older releases will include all the features and bug fixes! - 🤩 First and only extension that provides Windows 11's **snap assistant** - 🖥️🖥️ **multiple monitors support**, even with different scaling factors! @@ -32,7 +32,7 @@ Have issues, you want to suggest a new feature or contribute? Please open a new | [⬇️](#tiling-system) Tiling System | [⬇️](#snap-assistant) Snap Assistant | [⬇️](#select-a-layout) Select a layout | [⬇️](#select-multiple-tiles) Select multiple tiles | |:---|:---|:---|:---| | [⬇️](#layout-editor) **Layout editor** | [⬇️](#smart-resize) **Smart resize** | [⬇️](#tile-with-keyboard) **Tile with Keyboard** | [⬇️](#edge-tiling) **Edge Tiling** | -| [⬇️](#tiling-buttons) **Tiling Buttons** | [⬇️](#per-workspace-layout) **Per-workspace layout** +| [⬇️](#tiling-buttons) **Tiling Buttons** | [⬇️](#per-workspace-layout) **Per-workspace layout** | [⬇️](#auto-tiling) **Auto-tiling** ### Tiling System ### When grabbing and moving a window, press CTRL key to show the tiling layout (you can choose another key from the preferences). When moving on a tile, it will highlight. Ungrab the window to place that window on the highlighted tile. @@ -123,6 +123,15 @@ You can select your favorite layout for each workspace of each monitor.

Go to Usage ⬆️

+### Auto-tiling ### + +When a window is created, it is automatically moved to the best tile according to where other windows are tiled and the current layout. This is disabled by default and can be enabled in the preferences. + + +[automatic_tiling](https://github.com/user-attachments/assets/76abc53f-2c6d-47ab-bee3-bbcdd946f2a1) + +

Go to Usage ⬆️

+ ## Installation This extension is published on [extensions.gnome.org](https://extensions.gnome.org/extension/7065/tiling-shell/)! You can install from there or install manually. By installing from [extensions.gnome.org](https://extensions.gnome.org/extension/7065/tiling-shell/) you will always have the latest update. diff --git a/package.json b/package.json index fafbc5b..e412197 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tilingshell", - "version": "14.1", + "version": "15.0", "author": "Domenico Ferraro ", "private": true, "license": "GPL v2.0", diff --git a/resources/metadata.json b/resources/metadata.json index 3c17fb9..5d8e03a 100644 --- a/resources/metadata.json +++ b/resources/metadata.json @@ -11,7 +11,7 @@ "47" ], "version": 99, - "version-name": "14.1", + "version-name": "15.0", "url": "https://github.com/domferr/tilingshell", "settings-schema": "org.gnome.shell.extensions.tilingshell", "gettext-domain": "tilingshell", diff --git a/src/components/snapassist/snapAssist.ts b/src/components/snapassist/snapAssist.ts index 758352e..7a3d6aa 100644 --- a/src/components/snapassist/snapAssist.ts +++ b/src/components/snapassist/snapAssist.ts @@ -88,19 +88,19 @@ class SnapAssistContent extends St.BoxLayout { 54 * getMonitorScalingFactor(this._monitorIndex); Settings.bind( - Settings.SETTING_ENABLE_BLUR_SNAP_ASSISTANT, + Settings.KEY_ENABLE_BLUR_SNAP_ASSISTANT, this, 'blur', Gio.SettingsBindFlags.GET, ); Settings.bind( - Settings.SETTING_SNAP_ASSISTANT_THRESHOLD, + Settings.KEY_SNAP_ASSISTANT_THRESHOLD, this, 'snapAssistantThreshold', Gio.SettingsBindFlags.GET, ); Settings.bind( - Settings.SETTING_SNAP_ASSISTANT_ANIMATION_TIME, + Settings.KEY_SNAP_ASSISTANT_ANIMATION_TIME, this, 'snapAssistantAnimationTime', Gio.SettingsBindFlags.GET, diff --git a/src/components/tilepreview/selectionTilePreview.ts b/src/components/tilepreview/selectionTilePreview.ts index 1539fb9..770c085 100644 --- a/src/components/tilepreview/selectionTilePreview.ts +++ b/src/components/tilepreview/selectionTilePreview.ts @@ -27,7 +27,7 @@ export default class SelectionTilePreview extends TilePreview { this._blur = false; Settings.bind( - Settings.SETTING_ENABLE_BLUR_SELECTED_TILEPREVIEW, + Settings.KEY_ENABLE_BLUR_SELECTED_TILEPREVIEW, this, 'blur', Gio.SettingsBindFlags.GET, diff --git a/src/components/tilepreview/tilePreview.ts b/src/components/tilepreview/tilePreview.ts index 189028e..b2e7da8 100644 --- a/src/components/tilepreview/tilePreview.ts +++ b/src/components/tilepreview/tilePreview.ts @@ -128,10 +128,10 @@ export default class TilePreview extends St.Widget { position?: Mtk.Rectangle, ) { if (this.get_parent() === global.windowGroup) { - const windowActor = + /* const windowActor = window.get_compositor_private() as Clutter.Actor; - if (!windowActor) return; - global.windowGroup.set_child_above_sibling(this, windowActor); + if (!windowActor) return;*/ + global.windowGroup.set_child_above_sibling(this, null); } this.open(ease, position); diff --git a/src/components/tilingsystem/edgeTilingManager.ts b/src/components/tilingsystem/edgeTilingManager.ts index 496a4ed..71eb805 100644 --- a/src/components/tilingsystem/edgeTilingManager.ts +++ b/src/components/tilingsystem/edgeTilingManager.ts @@ -54,10 +54,9 @@ export default class EdgeTilingManager extends GObject.Object { this._rightCenter = buildRectangle(); this._activeEdgeTile = null; this.workarea = initialWorkArea; - this._quarterActivationPercentage = - Settings.get_quarter_tiling_threshold(); + this._quarterActivationPercentage = Settings.QUARTER_TILING_THRESHOLD; Settings.bind( - Settings.SETTING_QUARTER_TILING_THRESHOLD, + Settings.KEY_QUARTER_TILING_THRESHOLD, this, 'quarterActivationPercentage', ); @@ -242,7 +241,7 @@ export default class EdgeTilingManager extends GObject.Object { public needMaximize(): boolean { return ( this._activeEdgeTile !== null && - Settings.get_top_edge_maximize() && + Settings.TOP_EDGE_MAXIMIZE && this._activeEdgeTile === this._topCenter ); } diff --git a/src/components/tilingsystem/resizeManager.ts b/src/components/tilingsystem/resizeManager.ts index 6533b28..98a739a 100644 --- a/src/components/tilingsystem/resizeManager.ts +++ b/src/components/tilingsystem/resizeManager.ts @@ -26,8 +26,7 @@ export class ResizingManager { const moving = grabOp === Meta.GrabOp.KEYBOARD_MOVING || grabOp === Meta.GrabOp.MOVING; - if (moving || !Settings.get_resize_complementing_windows()) - return; + if (moving || !Settings.RESIZE_COMPLEMENTING_WINDOWS) return; this._onWindowResizingBegin(window, grabOp & ~1024); }, diff --git a/src/components/tilingsystem/tilingLayout.ts b/src/components/tilingsystem/tilingLayout.ts index 1f3a36a..5086dcb 100644 --- a/src/components/tilingsystem/tilingLayout.ts +++ b/src/components/tilingsystem/tilingLayout.ts @@ -1,5 +1,5 @@ import { registerGObjectClass } from '@/utils/gjs'; -import { Clutter, Mtk, Meta } from '@gi.ext'; +import { Clutter, Mtk, Meta, St } from '@gi.ext'; import TilePreview, { TilePreviewConstructorProperties, } from '../tilepreview/tilePreview'; @@ -116,10 +116,7 @@ export default class TilingLayout extends LayoutWidget { public openAbove(window: Meta.Window) { if (this._showing) return; - const windowActor = window.get_compositor_private() as Clutter.Actor; - if (!windowActor) return; - - global.windowGroup.set_child_above_sibling(this, windowActor); + global.windowGroup.set_child_above_sibling(this, null); this.open(); } @@ -364,52 +361,11 @@ export default class TilingLayout extends LayoutWidget { return [true, results]; } - public findNearestTile( - source: Mtk.Rectangle, - ): { rect: Mtk.Rectangle; tile: Tile } | undefined { - const sourceCoords = { - x: source.x + source.width / 2, - y: source.y + source.height / 2, - }; - - // uncomment to show debugging - /* global.windowGroup - .get_children() - .filter((c) => c.get_name() === 'debug-kb')[0] - ?.destroy(); - const debugWidget = new St.Widget({ - x: sourceCoords.x - 8, - y: sourceCoords.y - 8, - height: 16, - width: 16, - style: 'border: 2px solid red; border-radius: 8px;', - name: 'debug-kb', - }); - global.windowGroup.add_child(debugWidget);*/ - - for (let i = 0; i < this._previews.length; i++) { - const previewFound = this._previews[i]; - if (isPointInsideRect(sourceCoords, previewFound.rect)) { - return { - rect: buildRectangle({ - x: previewFound.innerX, - y: previewFound.innerY, - width: previewFound.innerWidth, - height: previewFound.innerHeight, - }), - tile: previewFound.tile, - }; - } - } - - return undefined; - } - public findNearestTileDirection( source: Mtk.Rectangle, direction: KeyBindingsDirection, ): { rect: Mtk.Rectangle; tile: Tile } | undefined { - if (direction === KeyBindingsDirection.CENTER) return undefined; + if (direction === KeyBindingsDirection.NODIRECTION) return undefined; const sourceCoords = { x: source.x + source.width / 2, @@ -417,20 +373,33 @@ export default class TilingLayout extends LayoutWidget { }; // enlarge the side of the direction and search a tile that contains that point + // clamp to ensure we do not go outside of the container area (e.g. the screen) const enlarge = 64; switch (direction) { case KeyBindingsDirection.RIGHT: - sourceCoords.x = source.x + source.width + enlarge; + sourceCoords.x = Math.min( + this._containerRect.width + this._containerRect.x, + source.x + source.width + enlarge, + ); break; case KeyBindingsDirection.LEFT: - sourceCoords.x = source.x - enlarge; + sourceCoords.x = Math.max( + this._containerRect.x, + source.x - enlarge, + ); break; case KeyBindingsDirection.DOWN: - sourceCoords.y = source.y + source.height + enlarge; + sourceCoords.y = Math.min( + this._containerRect.height + this._containerRect.y, + source.y + source.height + enlarge, + ); break; case KeyBindingsDirection.UP: - sourceCoords.y = source.y - enlarge; + sourceCoords.y = Math.max( + this._containerRect.y, + source.y - enlarge, + ); break; } @@ -466,50 +435,4 @@ export default class TilingLayout extends LayoutWidget { return undefined; } - - public getRightmostTile(): { rect: Mtk.Rectangle; tile: Tile } { - let previewFound: DynamicTilePreview = this._previews[0]; - - for (let i = 1; i < this._previews.length; i++) { - const preview = this._previews[i]; - if (preview.x + preview.width < previewFound.x + previewFound.width) - continue; - - if (preview.x + preview.width > previewFound.x + previewFound.width) - previewFound = preview; - else if (preview.y < previewFound.y) previewFound = preview; - } - - return { - rect: buildRectangle({ - x: previewFound.innerX, - y: previewFound.innerY, - width: previewFound.innerWidth, - height: previewFound.innerHeight, - }), - tile: previewFound.tile, - }; - } - - public getLeftmostTile(): { rect: Mtk.Rectangle; tile: Tile } { - let previewFound: DynamicTilePreview = this._previews[0]; - - for (let i = 1; i < this._previews.length; i++) { - const preview = this._previews[i]; - if (preview.x > previewFound.x) continue; - - if (preview.x < previewFound.x) previewFound = preview; - else if (preview.y < previewFound.y) previewFound = preview; - } - - return { - rect: buildRectangle({ - x: previewFound.innerX, - y: previewFound.innerY, - width: previewFound.innerWidth, - height: previewFound.innerHeight, - }), - tile: previewFound.tile, - }; - } } diff --git a/src/components/tilingsystem/tilingManager.ts b/src/components/tilingsystem/tilingManager.ts index cc7c7ed..85d2ceb 100644 --- a/src/components/tilingsystem/tilingManager.ts +++ b/src/components/tilingsystem/tilingManager.ts @@ -129,7 +129,7 @@ export class TilingManager { public enable() { this._signals.connect( Settings, - Settings.SETTING_SELECTED_LAYOUTS, + Settings.KEY_SETTING_SELECTED_LAYOUTS, () => { const ws = global.workspaceManager.get_active_workspace(); if (!ws) return; @@ -156,13 +156,13 @@ export class TilingManager { }, ); - this._signals.connect(Settings, Settings.SETTING_INNER_GAPS, () => { + this._signals.connect(Settings, Settings.KEY_INNER_GAPS, () => { const innerGaps = buildMargin(Settings.get_inner_gaps()); this._workspaceTilingLayout.forEach((tilingLayout) => tilingLayout.relayout({ innerGaps }), ); }); - this._signals.connect(Settings, Settings.SETTING_OUTER_GAPS, () => { + this._signals.connect(Settings, Settings.KEY_OUTER_GAPS, () => { const outerGaps = buildMargin(Settings.get_outer_gaps()); this._workspaceTilingLayout.forEach((tilingLayout) => tilingLayout.relayout({ outerGaps }), @@ -262,16 +262,14 @@ export class TilingManager { global.display, 'window-created', (_display: Meta.Display, window: Meta.Window) => { - if (Settings.get_enable_autotiling()) - this._autoTile(window, true); + if (Settings.ENABLE_AUTO_TILING) this._autoTile(window, true); }, ); this._signals.connect( TilingShellWindowManager.get(), 'unmaximized', (_, window: Meta.Window) => { - if (Settings.get_enable_autotiling()) - this._autoTile(window, false); + if (Settings.ENABLE_AUTO_TILING) this._autoTile(window, false); }, ); } @@ -282,7 +280,7 @@ export class TilingManager { this._easeWindowRect(window, destination, false, force); - (window as ExtendedWindow).originalSize = undefined; + (window as ExtendedWindow).assignedTile = undefined; } public onKeyboardMoveWindow( @@ -297,58 +295,72 @@ export class TilingManager { const currentWs = window.get_workspace(); const tilingLayout = this._workspaceTilingLayout.get(currentWs); if (!tilingLayout) return false; + const windowRectCopy = window.get_frame_rect().copy(); + const extWin = window as ExtendedWindow; if (window.get_maximized()) { switch (direction) { - case KeyBindingsDirection.CENTER: - window.unmaximize(Meta.MaximizeFlags.BOTH); + case KeyBindingsDirection.NODIRECTION: + case KeyBindingsDirection.LEFT: + case KeyBindingsDirection.RIGHT: break; case KeyBindingsDirection.DOWN: window.unmaximize(Meta.MaximizeFlags.BOTH); return true; case KeyBindingsDirection.UP: return false; - case KeyBindingsDirection.LEFT: - destination = tilingLayout.getLeftmostTile(); - break; - case KeyBindingsDirection.RIGHT: - destination = tilingLayout.getRightmostTile(); - break; } } + // maximize the window using keybindings + if ( + direction === KeyBindingsDirection.UP && + extWin.assignedTile && + extWin.assignedTile?.y === 0 + ) { + window.maximize(Meta.MaximizeFlags.BOTH); + return true; + } + // find the nearest tile - const windowRectCopy = window.get_frame_rect().copy(); - if (!destination) { - // if the window is not tiled, find the nearest tile in any direction - if (direction === KeyBindingsDirection.CENTER) { - // direction is undefined -> move to the center of the screen - const rect = buildRectangle({ - x: - this._workArea.x + - this._workArea.width / 2 - - windowRectCopy.width / 2, - y: - this._workArea.y + - this._workArea.height / 2 - - windowRectCopy.height / 2, - width: windowRectCopy.width, - height: windowRectCopy.height, - }); - destination = { - rect, - tile: TileUtils.build_tile(rect, this._workArea), - }; - } else if (!(window as ExtendedWindow).assignedTile) { - destination = tilingLayout.findNearestTile(windowRectCopy); - } else { - destination = tilingLayout.findNearestTileDirection( - windowRectCopy, - direction, - ); - } + // direction is CENTER -> move to the center of the screen + if (direction === KeyBindingsDirection.NODIRECTION) { + const rect = buildRectangle({ + x: + this._workArea.x + + this._workArea.width / 2 - + windowRectCopy.width / 2, + y: + this._workArea.y + + this._workArea.height / 2 - + windowRectCopy.height / 2, + width: windowRectCopy.width, + height: windowRectCopy.height, + }); + destination = { + rect, + tile: TileUtils.build_tile(rect, this._workArea), + }; + } else { + destination = tilingLayout.findNearestTileDirection( + windowRectCopy, + direction, + ); } + // if the window is already on the desired tile + if ( + destination && + (window as ExtendedWindow).assignedTile && + (window as ExtendedWindow).assignedTile?.x === destination.tile.x && + (window as ExtendedWindow).assignedTile?.y === destination.tile.y && + (window as ExtendedWindow).assignedTile?.width === + destination.tile.width && + (window as ExtendedWindow).assignedTile?.height === + destination.tile.height + ) + return true; + // there isn't a tile near the window if (!destination) { if (spanFlag) return false; @@ -364,7 +376,9 @@ export class TilingManager { return false; } - if (!(window as ExtendedWindow).assignedTile && !window.get_maximized()) + const isMaximized = + window.maximizedHorizontally || window.maximizedVertically; + if (!(window as ExtendedWindow).assignedTile && !isMaximized) (window as ExtendedWindow).originalSize = windowRectCopy; if (spanFlag) { @@ -375,7 +389,7 @@ export class TilingManager { ); } - if (window.get_maximized()) window.unmaximize(Meta.MaximizeFlags.BOTH); + if (isMaximized) window.unmaximize(Meta.MaximizeFlags.BOTH); this._easeWindowRect(window, destination.rect, false, force); @@ -436,16 +450,16 @@ export class TilingManager { // workaround for gnome-shell bug https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2857 if ( - Settings.get_enable_blur_snap_assistant() || - Settings.get_enable_blur_selected_tilepreview() + Settings.ENABLE_BLUR_SNAP_ASSISTANT || + Settings.ENABLE_BLUR_SELECTED_TILEPREVIEW ) { this._signals.connect(window, 'position-changed', () => { - if (Settings.get_enable_blur_selected_tilepreview()) { + if (Settings.ENABLE_BLUR_SELECTED_TILEPREVIEW) { this._selectedTilesPreview .get_effect('blur') ?.queue_repaint(); } - if (Settings.get_enable_blur_snap_assistant()) { + if (Settings.ENABLE_BLUR_SNAP_ASSISTANT) { this._snapAssist .get_first_child() ?.get_effect('blur') @@ -528,7 +542,7 @@ export class TilingManager { squaredEuclideanDistance(currPointerPos, this._grabStartPosition) > MINIMUM_DISTANCE_TO_RESTORE_ORIGINAL_SIZE ) { - if (Settings.get_restore_window_original_size()) { + if (Settings.RESTORE_WINDOW_ORIGINAL_SIZE) { const windowRect = window.get_frame_rect(); const offsetX = (x - windowRect.x) / windowRect.width; const offsetY = (y - windowRect.y) / windowRect.height; @@ -577,31 +591,31 @@ export class TilingManager { const isSpanMultiTilesActivated = this._activationKeyStatus( modifier, - Settings.get_span_multiple_tiles_activation_key(), + Settings.SPAN_MULTIPLE_TILES_ACTIVATION_KEY, ); const isTilingSystemActivated = this._activationKeyStatus( modifier, - Settings.get_tiling_system_activation_key(), + Settings.TILING_SYSTEM_ACTIVATION_KEY, ); - const deactivationKey = Settings.get_tiling_system_deactivation_key(); + const deactivationKey = Settings.TILING_SYSTEM_DEACTIVATION_KEY; const isTilingSystemDeactivated = deactivationKey === ActivationKey.NONE ? false : this._activationKeyStatus(modifier, deactivationKey); const allowSpanMultipleTiles = - Settings.get_span_multiple_tiles() && isSpanMultiTilesActivated; + Settings.SPAN_MULTIPLE_TILES && isSpanMultiTilesActivated; const showTilingSystem = - Settings.get_tiling_system_enabled() && + Settings.TILING_SYSTEM && isTilingSystemActivated && !isTilingSystemDeactivated; // ensure we handle window movement only when needed // if the snap assistant activation key status is not changed and the mouse is on the same position as before // and the tiling system activation key status is not changed, we have nothing to do const changedSpanMultipleTiles = - Settings.get_span_multiple_tiles() && + Settings.SPAN_MULTIPLE_TILES && isSpanMultiTilesActivated !== this._wasSpanMultipleTilesActivated; const changedShowTilingSystem = - Settings.get_tiling_system_enabled() && + Settings.TILING_SYSTEM && isTilingSystemActivated !== this._wasTilingSystemActivated; if ( !changedSpanMultipleTiles && @@ -624,7 +638,7 @@ export class TilingManager { } if ( - Settings.get_active_screen_edges() && + Settings.ACTIVE_SCREEN_EDGES && !this._isSnapAssisting && this._edgeTilingManager.canActivateEdgeTiling(currPointerPos) ) { @@ -639,7 +653,7 @@ export class TilingManager { this._edgeTilingManager.abortEdgeTiling(); } - if (Settings.get_snap_assist_enabled()) { + if (Settings.SNAP_ASSIST) { this._snapAssist.onMovingWindow( window, true, @@ -726,7 +740,7 @@ export class TilingManager { const isTilingSystemActivated = this._activationKeyStatus( global.get_pointer()[2], - Settings.get_tiling_system_activation_key(), + Settings.TILING_SYSTEM_ACTIVATION_KEY, ); if ( !isTilingSystemActivated && @@ -1012,7 +1026,6 @@ export class TilingManager { } private _autoTile(window: Meta.Window, windowCreated: boolean) { - /* // do not handle windows in monitors not managed by this manager if (window.get_monitor() !== this._monitor.index) return; @@ -1061,7 +1074,7 @@ export class TilingManager { }); } else { this._easeWindowRectFromTile(vacantTile, window, true); - } */ + } } private _findEmptyTile(window: Meta.Window): Tile | undefined { diff --git a/src/components/windowBorderManager.ts b/src/components/windowBorderManager.ts index 8c88102..fa5f043 100644 --- a/src/components/windowBorderManager.ts +++ b/src/components/windowBorderManager.ts @@ -3,6 +3,7 @@ import SignalHandling from '@utils/signalHandling'; import { logger } from '@utils/logger'; import { registerGObjectClass } from '@utils/gjs'; import Settings from '@settings/settings'; +import * as Main from 'resource:///org/gnome/shell/ui/main.js'; const debug = logger('WindowBorderManager'); @@ -135,7 +136,7 @@ class WindowBorder extends St.Bin { public updateStyle(): void { this.set_style( - `border-color: ${Settings.get_window_border_color()}; border-width: ${Settings.get_window_border_width()}px;`, + `border-color: ${Settings.WINDOW_BORDER_COLOR}; border-width: ${Settings.WINDOW_BORDER_WIDTH}px;`, ); } @@ -168,14 +169,14 @@ export class WindowBorderManager { } public enable(): void { - if (Settings.get_enable_window_border()) this._turnOn(); + if (Settings.ENABLE_WINDOW_BORDER) this._turnOn(); // enable/disable based on user preferences this._signals.connect( Settings, - Settings.SETTING_ENABLE_WINDOW_BORDER, + Settings.KEY_ENABLE_WINDOW_BORDER, () => { - if (Settings.get_enable_window_border()) this._turnOn(); + if (Settings.ENABLE_WINDOW_BORDER) this._turnOn(); else this._turnOff(); }, ); @@ -188,20 +189,12 @@ export class WindowBorderManager { 'notify::focus-window', this._onWindowFocused.bind(this), ); - this._signals.connect( - Settings, - Settings.SETTING_WINDOW_BORDER_COLOR, - () => { - this._border?.updateStyle(); - }, + this._signals.connect(Settings, Settings.KEY_WINDOW_BORDER_COLOR, () => + this._border?.updateStyle(), ); - this._signals.connect( - Settings, - Settings.SETTING_WINDOW_BORDER_WIDTH, - () => { - this._border?.updateStyle(); - }, + this._signals.connect(Settings, Settings.KEY_WINDOW_BORDER_WIDTH, () => + this._border?.updateStyle(), ); } diff --git a/src/extension.ts b/src/extension.ts index fc2362f..c8ff789 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -51,16 +51,15 @@ export default class TilingShellExtension extends Extension { } private _validateSettings() { - if (Settings.get_last_version_installed() === '14.0') { + if (Settings.LAST_VERSION_NAME_INSTALLED === '14.0') { debug('apply compatibility changes'); Settings.save_selected_layouts([]); } // Setting used for compatibility changes if necessary if (this.metadata['version-name']) { - Settings.set_last_version_installed( - this.metadata['version-name'] || '0', - ); + Settings.LAST_VERSION_NAME_INSTALLED = + this.metadata['version-name'] || '0'; } } @@ -82,7 +81,7 @@ export default class TilingShellExtension extends Extension { this._keybindings = new KeyBindings(this.getSettings()); // disable native edge tiling - if (Settings.get_active_screen_edges()) { + if (Settings.ACTIVE_SCREEN_EDGES) { SettingsOverride.get().override( new Gio.Settings({ schema_id: 'org.gnome.mutter' }), 'edge-tiling', @@ -117,7 +116,7 @@ export default class TilingShellExtension extends Extension { this._dbus = new DBus(); this._dbus.enable(this); - if (Settings.get_override_window_menu()) OverriddenWindowMenu.enable(); + if (Settings.OVERRIDE_WINDOW_MENU) OverriddenWindowMenu.enable(); debug('extension is enabled'); } @@ -220,7 +219,7 @@ export default class TilingShellExtension extends Extension { (kb: KeyBindings, dp: Meta.Display) => { this._onKeyboardMoveWin( dp, - KeyBindingsDirection.CENTER, + KeyBindingsDirection.NODIRECTION, false, ); }, @@ -242,12 +241,12 @@ export default class TilingShellExtension extends Extension { // then enable/disable native edge-tiling this._signals.connect( Settings, - Settings.SETTING_ACTIVE_SCREEN_EDGES, + Settings.KEY_ACTIVE_SCREEN_EDGES, () => { const gioSettings = new Gio.Settings({ schema_id: 'org.gnome.mutter', }); - if (Settings.get_active_screen_edges()) { + if (Settings.ACTIVE_SCREEN_EDGES) { debug('disable native edge tiling'); // disable native edge tiling SettingsOverride.get().override( @@ -269,9 +268,9 @@ export default class TilingShellExtension extends Extension { // enable/disable window menu from preferences this._signals.connect( Settings, - Settings.SETTING_OVERRIDE_WINDOW_MENU, + Settings.KEY_OVERRIDE_WINDOW_MENU, () => { - if (Settings.get_override_window_menu()) + if (Settings.OVERRIDE_WINDOW_MENU) OverriddenWindowMenu.enable(); else OverriddenWindowMenu.disable(); }, @@ -397,13 +396,17 @@ export default class TilingShellExtension extends Extension { this._tilingManagers[focus_window.get_monitor()]; if (!monitorTilingManager) return; + if (Settings.ENABLE_AUTO_TILING && focus_window.get_maximized()) { + focus_window.unmaximize(Meta.MaximizeFlags.BOTH); + return; + } const success = monitorTilingManager.onKeyboardMoveWindow( focus_window, direction, false, spanFlag, ); - if (success || direction === KeyBindingsDirection.CENTER) return; + if (success || direction === KeyBindingsDirection.NODIRECTION) return; let displayDirection = Meta.DisplayDirection.DOWN; switch (direction) { diff --git a/src/indicator/defaultMenu.ts b/src/indicator/defaultMenu.ts index 469cdd1..2a82fff 100644 --- a/src/indicator/defaultMenu.ts +++ b/src/indicator/defaultMenu.ts @@ -170,27 +170,34 @@ export default class DefaultMenu implements CurrentMenu { this._layoutsRows = []; this._drawLayouts(); // update the layouts shown by the indicator when they are modified - this._signals.connect(Settings, Settings.SETTING_LAYOUTS_JSON, () => { - this._drawLayouts(); - }); - this._signals.connect(Settings, Settings.SETTING_INNER_GAPS, () => { + this._signals.connect( + Settings, + Settings.KEY_SETTING_LAYOUTS_JSON, + () => { + this._drawLayouts(); + }, + ); + this._signals.connect(Settings, Settings.KEY_INNER_GAPS, () => { this._drawLayouts(); }); // if the selected layout was changed externaly, update the selected button this._signals.connect( Settings, - Settings.SETTING_SELECTED_LAYOUTS, + Settings.KEY_SETTING_SELECTED_LAYOUTS, () => { this._updateScaling(); if (this._layoutsRows.length !== getMonitors().length) this._drawLayouts(); + const selected_layouts = Settings.get_selected_layouts(); + const wsIndex = + global.workspaceManager.get_active_workspace_index(); getMonitors().forEach((m, index) => { const selectedId = - Settings.get_selected_layouts()[ - global.workspaceManager.get_active_workspace_index() - ][index]; + wsIndex < selected_layouts.length + ? selected_layouts[wsIndex][index] + : GlobalState.get().layouts[0].id; this._layoutsRows[index].selectLayout(selectedId); }); }, @@ -200,11 +207,14 @@ export default class DefaultMenu implements CurrentMenu { global.workspaceManager, 'active-workspace-changed', () => { + const selected_layouts = Settings.get_selected_layouts(); + const wsIndex = + global.workspaceManager.get_active_workspace_index(); getMonitors().forEach((m, index) => { const selectedId = - Settings.get_selected_layouts()[ - global.workspaceManager.get_active_workspace_index() - ][index]; + wsIndex < selected_layouts.length + ? selected_layouts[wsIndex][index] + : GlobalState.get().layouts[0].id; this._layoutsRows[index].selectLayout(selectedId); }); }, @@ -333,7 +343,14 @@ export default class DefaultMenu implements CurrentMenu { const ws_index = global.workspaceManager.get_active_workspace_index(); const monitors = getMonitors(); this._layoutsRows = monitors.map((monitor) => { - const selectedId = selected_layouts[ws_index][monitor.index]; + const ws_selected_layouts = + ws_index < selected_layouts.length + ? selected_layouts[ws_index] + : []; + const selectedId = + monitor.index < ws_selected_layouts.length + ? ws_selected_layouts[monitor.index] + : GlobalState.get().layouts[0].id; const row = new LayoutsRow( this._container, layouts, diff --git a/src/indicator/indicator.ts b/src/indicator/indicator.ts index 9cfc8c7..634eaa4 100644 --- a/src/indicator/indicator.ts +++ b/src/indicator/indicator.ts @@ -35,7 +35,7 @@ export default class Indicator extends PanelMenu.Button { // Bind the "show-indicator" setting to the "visible" property Settings.bind( - Settings.SETTING_SHOW_INDICATOR, + Settings.KEY_SHOW_INDICATOR, this, 'visible', Gio.SettingsBindFlags.GET, @@ -214,7 +214,7 @@ export default class Indicator extends PanelMenu.Button { switch (newState) { case IndicatorState.DEFAULT: this._currentMenu = new DefaultMenu(this, this._enableScaling); - if (!Settings.get_show_indicator()) this.hide(); + if (!Settings.SHOW_INDICATOR) this.hide(); if (this._keyPressEvent) { global.stage.disconnect(this._keyPressEvent); this._keyPressEvent = null; diff --git a/src/keybindings.ts b/src/keybindings.ts index 152761a..7b8b3ff 100644 --- a/src/keybindings.ts +++ b/src/keybindings.ts @@ -9,7 +9,7 @@ import { logger } from '@utils/logger'; const debug = logger('KeyBindings'); export enum KeyBindingsDirection { - CENTER = 1, + NODIRECTION = 1, UP, DOWN, LEFT, @@ -51,18 +51,18 @@ export default class KeyBindings extends GObject.Object { this._signals.connect( Settings, - Settings.SETTING_ENABLE_MOVE_KEYBINDINGS, + Settings.KEY_ENABLE_MOVE_KEYBINDINGS, () => { this._setupKeyBindings(extensionSettings); }, ); - if (Settings.get_enable_move_keybindings()) + if (Settings.ENABLE_MOVE_KEYBINDINGS) this._setupKeyBindings(extensionSettings); } private _setupKeyBindings(extensionSettings: Gio.Settings) { - const enabled = Settings.get_enable_move_keybindings(); - if (enabled) this._applyKeybindings(extensionSettings); + if (Settings.ENABLE_MOVE_KEYBINDINGS) + this._applyKeybindings(extensionSettings); else this._removeKeybindings(); } diff --git a/src/prefs.ts b/src/prefs.ts index c0dcbf6..25c5767 100644 --- a/src/prefs.ts +++ b/src/prefs.ts @@ -54,21 +54,21 @@ export default class TilingShellExtensionPreferences extends ExtensionPreference prefsPage.add(appearenceGroup); const showIndicatorRow = this._buildSwitchRow( - Settings.SETTING_SHOW_INDICATOR, + Settings.KEY_SHOW_INDICATOR, _('Show Indicator'), _('Whether to show the panel indicator'), ); appearenceGroup.add(showIndicatorRow); const innerGapsRow = this._buildSpinButtonRow( - Settings.SETTING_INNER_GAPS, + Settings.KEY_INNER_GAPS, _('Inner gaps'), _('Gaps between windows'), ); appearenceGroup.add(innerGapsRow); const outerGapsRow = this._buildSpinButtonRow( - Settings.SETTING_OUTER_GAPS, + Settings.KEY_OUTER_GAPS, _('Outer gaps'), _('Gaps between a window and the monitor borders'), ); @@ -83,7 +83,7 @@ export default class TilingShellExtensionPreferences extends ExtensionPreference appearenceGroup.add(blurRow); const snapAssistantThresholdRow = this._buildSpinButtonRow( - Settings.SETTING_SNAP_ASSISTANT_THRESHOLD, + Settings.KEY_SNAP_ASSISTANT_THRESHOLD, _('Snap Assistant threshold'), _( 'Minimum distance from the Snap Assistant to the pointer to open it', @@ -95,14 +95,14 @@ export default class TilingShellExtensionPreferences extends ExtensionPreference blurRow.add_row( this._buildSwitchRow( - Settings.SETTING_ENABLE_BLUR_SNAP_ASSISTANT, + Settings.KEY_ENABLE_BLUR_SNAP_ASSISTANT, _('Snap Assistant'), _('Apply blur effect to Snap Assistant'), ), ); blurRow.add_row( this._buildSwitchRow( - Settings.SETTING_ENABLE_BLUR_SELECTED_TILEPREVIEW, + Settings.KEY_ENABLE_BLUR_SELECTED_TILEPREVIEW, _('Selected tile preview'), _('Apply blur effect to selected tile preview'), ), @@ -115,14 +115,14 @@ export default class TilingShellExtensionPreferences extends ExtensionPreference appearenceGroup.add(windowBorderRow); windowBorderRow.add_row( this._buildSwitchRow( - Settings.SETTING_ENABLE_WINDOW_BORDER, + Settings.KEY_ENABLE_WINDOW_BORDER, _('Enable'), _('Show a border around focused window'), ), ); windowBorderRow.add_row( this._buildSpinButtonRow( - Settings.SETTING_WINDOW_BORDER_WIDTH, + Settings.KEY_WINDOW_BORDER_WIDTH, _('Width'), _('The size of the border'), 1, @@ -132,8 +132,8 @@ export default class TilingShellExtensionPreferences extends ExtensionPreference this._buildColorRow( _('Border color'), _('Choose the color of the border'), - this._getRGBAFromString(Settings.get_window_border_color()), - (val: string) => Settings.set_window_border_color(val), + this._getRGBAFromString(Settings.WINDOW_BORDER_COLOR), + (val: string) => (Settings.WINDOW_BORDER_COLOR = val), ), ); @@ -144,7 +144,7 @@ export default class TilingShellExtensionPreferences extends ExtensionPreference appearenceGroup.add(animationsRow); animationsRow.add_row( this._buildSpinButtonRow( - Settings.SETTING_SNAP_ASSISTANT_ANIMATION_TIME, + Settings.KEY_SNAP_ASSISTANT_ANIMATION_TIME, _('Snap assistant animation time'), _('The snap assistant animation time in milliseconds'), 0, @@ -153,7 +153,7 @@ export default class TilingShellExtensionPreferences extends ExtensionPreference ); animationsRow.add_row( this._buildSpinButtonRow( - Settings.SETTING_TILE_PREVIEW_ANIMATION_TIME, + Settings.KEY_TILE_PREVIEW_ANIMATION_TIME, _('Tiles animation time'), _('The tiles animation time in milliseconds'), 0, @@ -169,20 +169,20 @@ export default class TilingShellExtensionPreferences extends ExtensionPreference prefsPage.add(behaviourGroup); const snapAssistRow = this._buildSwitchRow( - Settings.SETTING_SNAP_ASSIST, + Settings.KEY_SNAP_ASSIST, _('Enable Snap Assistant'), _('Move the window on top of the screen to snap assist it'), ); behaviourGroup.add(snapAssistRow); const enableTilingSystemRow = this._buildSwitchRow( - Settings.SETTING_TILING_SYSTEM, + Settings.KEY_TILING_SYSTEM, _('Enable Tiling System'), _('Hold the activation key while moving a window to tile it'), this._buildActivationKeysDropDown( - Settings.get_tiling_system_activation_key(), - (newVal: ActivationKey) => - Settings.set_tiling_system_activation_key(newVal), + Settings.TILING_SYSTEM_ACTIVATION_KEY, + (val: ActivationKey) => + (Settings.TILING_SYSTEM_ACTIVATION_KEY = val), ), ); behaviourGroup.add(enableTilingSystemRow); @@ -192,33 +192,33 @@ export default class TilingShellExtensionPreferences extends ExtensionPreference _( 'Hold the deactivation key while moving a window to deactivate the tiling system', ), - Settings.get_tiling_system_deactivation_key(), - (newVal: ActivationKey) => - Settings.set_tiling_system_deactivation_key(newVal), + Settings.TILING_SYSTEM_DEACTIVATION_KEY, + (val: ActivationKey) => + (Settings.TILING_SYSTEM_DEACTIVATION_KEY = val), ); behaviourGroup.add(tilingSystemDeactivationRow); const spanMultipleTilesRow = this._buildSwitchRow( - Settings.SETTING_SPAN_MULTIPLE_TILES, + Settings.KEY_SPAN_MULTIPLE_TILES, _('Span multiple tiles'), _('Hold the activation key to span multiple tiles'), this._buildActivationKeysDropDown( - Settings.get_span_multiple_tiles_activation_key(), - (newVal: ActivationKey) => - Settings.set_span_multiple_tiles_activation_key(newVal), + Settings.SPAN_MULTIPLE_TILES_ACTIVATION_KEY, + (val: ActivationKey) => + (Settings.SPAN_MULTIPLE_TILES_ACTIVATION_KEY = val), ), ); behaviourGroup.add(spanMultipleTilesRow); - /* const autoTilingRow = this._buildSwitchRow( - Settings.SETTING_ENABLE_AUTO_TILING, + const autoTilingRow = this._buildSwitchRow( + Settings.KEY_ENABLE_AUTO_TILING, _('Enable Auto Tiling'), _('Automatically tile new windows to the best tile'), ); - behaviourGroup.add(autoTilingRow);*/ + behaviourGroup.add(autoTilingRow); const resizeComplementingRow = this._buildSwitchRow( - Settings.SETTING_RESIZE_COMPLEMENTING_WINDOWS, + Settings.KEY_RESIZE_COMPLEMENTING_WINDOWS, _('Enable auto-resize of the complementing tiled windows'), _( 'When a tiled window is resized, auto-resize the other tiled windows near it', @@ -227,7 +227,7 @@ export default class TilingShellExtensionPreferences extends ExtensionPreference behaviourGroup.add(resizeComplementingRow); const restoreToOriginalSizeRow = this._buildSwitchRow( - Settings.SETTING_RESTORE_WINDOW_ORIGINAL_SIZE, + Settings.KEY_RESTORE_WINDOW_ORIGINAL_SIZE, _('Restore window size'), _( 'Whether to restore the windows to their original size when untiled', @@ -236,7 +236,7 @@ export default class TilingShellExtensionPreferences extends ExtensionPreference behaviourGroup.add(restoreToOriginalSizeRow); const overrideWindowMenuRow = this._buildSwitchRow( - Settings.SETTING_OVERRIDE_WINDOW_MENU, + Settings.KEY_OVERRIDE_WINDOW_MENU, _('Add snap assistant and auto-tile buttons to window menu'), _( 'Add snap assistant and auto-tile buttons in the menu that shows up when you right click on a window title', @@ -256,18 +256,18 @@ export default class TilingShellExtensionPreferences extends ExtensionPreference }), }); Settings.bind( - Settings.SETTING_ACTIVE_SCREEN_EDGES, + Settings.KEY_ACTIVE_SCREEN_EDGES, activeScreenEdgesGroup.headerSuffix, 'active', ); const topEdgeMaximize = this._buildSwitchRow( - Settings.SETTING_TOP_EDGE_MAXIMIZE, + Settings.KEY_TOP_EDGE_MAXIMIZE, _('Drag against top edge to maximize window'), _('Drag windows against the top edge to maximize them'), ); Settings.bind( - Settings.SETTING_ACTIVE_SCREEN_EDGES, + Settings.KEY_ACTIVE_SCREEN_EDGES, topEdgeMaximize, 'sensitive', ); @@ -277,15 +277,15 @@ export default class TilingShellExtensionPreferences extends ExtensionPreference _('Quarter tiling activation area'), _('Activation area to trigger quarter tiling (% of the screen)'), (sc: Gtk.Scale) => { - Settings.set_quarter_tiling_threshold(sc.get_value()); + Settings.QUARTER_TILING_THRESHOLD = sc.get_value(); }, - Settings.get_quarter_tiling_threshold(), + Settings.QUARTER_TILING_THRESHOLD, 1, 50, 1, ); Settings.bind( - Settings.SETTING_ACTIVE_SCREEN_EDGES, + Settings.KEY_ACTIVE_SCREEN_EDGES, quarterTiling, 'sensitive', ); @@ -460,7 +460,7 @@ export default class TilingShellExtensionPreferences extends ExtensionPreference }), }); Settings.bind( - Settings.SETTING_ENABLE_MOVE_KEYBINDINGS, + Settings.KEY_ENABLE_MOVE_KEYBINDINGS, keybindingsGroup.headerSuffix, 'active', ); @@ -602,7 +602,7 @@ export default class TilingShellExtensionPreferences extends ExtensionPreference ); Settings.bind( - Settings.SETTING_ENABLE_MOVE_KEYBINDINGS, + Settings.KEY_ENABLE_MOVE_KEYBINDINGS, row, 'sensitive', ); @@ -620,7 +620,7 @@ export default class TilingShellExtensionPreferences extends ExtensionPreference }), ); Settings.bind( - Settings.SETTING_ENABLE_MOVE_KEYBINDINGS, + Settings.KEY_ENABLE_MOVE_KEYBINDINGS, openKeybindingsDialogRow, 'sensitive', ); @@ -656,7 +656,7 @@ export default class TilingShellExtensionPreferences extends ExtensionPreference ); Settings.bind( - Settings.SETTING_ENABLE_MOVE_KEYBINDINGS, + Settings.KEY_ENABLE_MOVE_KEYBINDINGS, row, 'sensitive', ); @@ -880,13 +880,13 @@ export default class TilingShellExtensionPreferences extends ExtensionPreference _buildDropDownRow( title: string, subtitle: string, - value: ActivationKey, - onSelected: (v: ActivationKey) => void, + initialValue: ActivationKey, + onChange: (_: ActivationKey) => void, styleClass?: string, ): Adw.ActionRow { const dropDown = this._buildActivationKeysDropDown( - value, - onSelected, + initialValue, + onChange, styleClass, ); dropDown.set_vexpand(false); @@ -965,8 +965,8 @@ export default class TilingShellExtensionPreferences extends ExtensionPreference } _buildActivationKeysDropDown( - value: ActivationKey, - onSelected: (v: ActivationKey) => void, + initialValue: ActivationKey, + onChange: (_: ActivationKey) => void, styleClass?: string, ) { const options = new Gtk.StringList(); @@ -979,7 +979,7 @@ export default class TilingShellExtensionPreferences extends ExtensionPreference options.append('(None)'); const dropdown = new Gtk.DropDown({ model: options, - selected: value, + selected: initialValue, }); dropdown.connect('notify::selected-item', (dd: Gtk.DropDown) => { const index = dd.get_selected(); @@ -987,7 +987,7 @@ export default class TilingShellExtensionPreferences extends ExtensionPreference index < 0 || index >= activationKeys.length ? ActivationKey.NONE : activationKeys[index]; - onSelected(selected); + onChange(selected); }); if (styleClass) dropdown.add_css_class(styleClass); dropdown.set_vexpand(false); diff --git a/src/settings/settings.ts b/src/settings/settings.ts index 07e97d1..31a23ed 100644 --- a/src/settings/settings.ts +++ b/src/settings/settings.ts @@ -9,46 +9,105 @@ export enum ActivationKey { SUPER, } +/** ------------- Utility functions ------------- */ +function get_string(key: string): string { + return ( + Settings.gioSetting.get_string(key) ?? + Settings.gioSetting.get_default_value(key)?.get_string()[0] + ); +} + +function set_string(key: string, val: string): boolean { + return Settings.gioSetting.set_string(key, val); +} + +function get_boolean(key: string): boolean { + return ( + Settings.gioSetting.get_boolean(key) ?? + Settings.gioSetting.get_default_value(key)?.get_boolean() + ); +} + +function set_boolean(key: string, val: boolean): boolean { + return Settings.gioSetting.set_boolean(key, val); +} + +function get_number(key: string): number { + return ( + Settings.gioSetting.get_int(key) ?? + Settings.gioSetting.get_default_value(key)?.get_int64() + ); +} + +function set_number(key: string, val: number): boolean { + return Settings.gioSetting.set_int(key, val); +} + +function get_unsigned_number(key: string): number { + return ( + Settings.gioSetting.get_uint(key) ?? + Settings.gioSetting.get_default_value(key)?.get_uint64() + ); +} + +function set_unsigned_number(key: string, val: number): boolean { + return Settings.gioSetting.set_uint(key, val); +} + +function get_activationkey( + key: string, + defaultValue: ActivationKey, +): ActivationKey { + let val = Settings.gioSetting.get_strv(key); + if (!val || val.length === 0) { + val = Settings.gioSetting.get_default_value(key)?.get_strv() ?? [ + String(defaultValue), + ]; + if (val.length === 0) val = [String(defaultValue)]; + } + return Number(val[0]); +} + +function set_activationkey(key: string, val: ActivationKey): boolean { + return Settings.gioSetting.set_strv(key, [String(val)]); +} + export default class Settings { static _settings: Gio.Settings | null; static _is_initialized: boolean = false; - static SETTING_LAST_VERSION_NAME_INSTALLED = 'last-version-name-installed'; - static SETTING_OVERRIDDEN_SETTINGS = 'overridden-settings'; - static SETTING_TILING_SYSTEM = 'enable-tiling-system'; - static SETTING_TILING_SYSTEM_ACTIVATION_KEY = - 'tiling-system-activation-key'; - static SETTING_TILING_SYSTEM_DEACTIVATION_KEY = + static KEY_LAST_VERSION_NAME_INSTALLED = 'last-version-name-installed'; + static KEY_OVERRIDDEN_SETTINGS = 'overridden-settings'; + static KEY_WINDOW_BORDER_COLOR = 'window-border-color'; + static KEY_TILING_SYSTEM = 'enable-tiling-system'; + static KEY_SNAP_ASSIST = 'enable-snap-assist'; + static KEY_SHOW_INDICATOR = 'show-indicator'; + static KEY_TILING_SYSTEM_ACTIVATION_KEY = 'tiling-system-activation-key'; + static KEY_TILING_SYSTEM_DEACTIVATION_KEY = 'tiling-system-deactivation-key'; - static SETTING_SNAP_ASSIST = 'enable-snap-assist'; - static SETTING_SHOW_INDICATOR = 'show-indicator'; - static SETTING_INNER_GAPS = 'inner-gaps'; - static SETTING_OUTER_GAPS = 'outer-gaps'; - static SETTING_SPAN_MULTIPLE_TILES = 'enable-span-multiple-tiles'; - static SETTING_SPAN_MULTIPLE_TILES_ACTIVATION_KEY = + static KEY_SPAN_MULTIPLE_TILES_ACTIVATION_KEY = 'span-multiple-tiles-activation-key'; - static SETTING_LAYOUTS_JSON = 'layouts-json'; - static SETTING_SELECTED_LAYOUTS = 'selected-layouts'; - static SETTING_RESTORE_WINDOW_ORIGINAL_SIZE = - 'restore-window-original-size'; - static SETTING_RESIZE_COMPLEMENTING_WINDOWS = - 'resize-complementing-windows'; - static SETTING_ENABLE_BLUR_SNAP_ASSISTANT = 'enable-blur-snap-assistant'; - static SETTING_ENABLE_BLUR_SELECTED_TILEPREVIEW = + static KEY_SPAN_MULTIPLE_TILES = 'enable-span-multiple-tiles'; + static KEY_RESTORE_WINDOW_ORIGINAL_SIZE = 'restore-window-original-size'; + static KEY_RESIZE_COMPLEMENTING_WINDOWS = 'resize-complementing-windows'; + static KEY_ENABLE_BLUR_SNAP_ASSISTANT = 'enable-blur-snap-assistant'; + static KEY_ENABLE_BLUR_SELECTED_TILEPREVIEW = 'enable-blur-selected-tilepreview'; - static SETTING_ENABLE_MOVE_KEYBINDINGS = 'enable-move-keybindings'; - static SETTING_ENABLE_AUTO_TILING = 'enable-autotiling'; - static SETTING_ACTIVE_SCREEN_EDGES = 'active-screen-edges'; - static SETTING_TOP_EDGE_MAXIMIZE = 'top-edge-maximize'; - static SETTING_OVERRIDE_WINDOW_MENU = 'override-window-menu'; - static SETTING_SNAP_ASSISTANT_THRESHOLD = 'snap-assistant-threshold'; - static SETTING_QUARTER_TILING_THRESHOLD = 'quarter-tiling-threshold'; - static SETTING_WINDOW_BORDER_COLOR = 'window-border-color'; - static SETTING_WINDOW_BORDER_WIDTH = 'window-border-width'; - static SETTING_ENABLE_WINDOW_BORDER = 'enable-window-border'; - static SETTING_SNAP_ASSISTANT_ANIMATION_TIME = - 'snap-assistant-animation-time'; - static SETTING_TILE_PREVIEW_ANIMATION_TIME = 'tile-preview-animation-time'; + static KEY_ENABLE_MOVE_KEYBINDINGS = 'enable-move-keybindings'; + static KEY_ENABLE_AUTO_TILING = 'enable-autotiling'; + static KEY_ACTIVE_SCREEN_EDGES = 'active-screen-edges'; + static KEY_TOP_EDGE_MAXIMIZE = 'top-edge-maximize'; + static KEY_OVERRIDE_WINDOW_MENU = 'override-window-menu'; + static KEY_SNAP_ASSISTANT_THRESHOLD = 'snap-assistant-threshold'; + static KEY_ENABLE_WINDOW_BORDER = 'enable-window-border'; + static KEY_INNER_GAPS = 'inner-gaps'; + static KEY_OUTER_GAPS = 'outer-gaps'; + static KEY_SNAP_ASSISTANT_ANIMATION_TIME = 'snap-assistant-animation-time'; + static KEY_TILE_PREVIEW_ANIMATION_TIME = 'tile-preview-animation-time'; + static KEY_SETTING_LAYOUTS_JSON = 'layouts-json'; + static KEY_SETTING_SELECTED_LAYOUTS = 'selected-layouts'; + static KEY_WINDOW_BORDER_WIDTH = 'window-border-width'; + static KEY_QUARTER_TILING_THRESHOLD = 'quarter-tiling-threshold'; static SETTING_MOVE_WINDOW_RIGHT = 'move-window-right'; static SETTING_MOVE_WINDOW_LEFT = 'move-window-left'; @@ -80,6 +139,10 @@ export default class Settings { } } + static get gioSetting(): Gio.Settings { + return this._settings ?? new Gio.Settings(); + } + static bind( key: string, // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -90,294 +153,305 @@ export default class Settings { this._settings?.bind(key, object, property, flags); } - static get_last_version_installed(): string { - return ( - this._settings?.get_string( - this.SETTING_LAST_VERSION_NAME_INSTALLED, - ) ?? '0' - ); + static get LAST_VERSION_NAME_INSTALLED(): string { + return get_string(Settings.KEY_LAST_VERSION_NAME_INSTALLED); } - static get_tiling_system_enabled(): boolean { - return this._settings?.get_boolean(this.SETTING_TILING_SYSTEM) ?? true; + static set LAST_VERSION_NAME_INSTALLED(val: string) { + set_string(Settings.KEY_LAST_VERSION_NAME_INSTALLED, val); } - static get_snap_assist_enabled(): boolean { - return this._settings?.get_boolean(this.SETTING_SNAP_ASSIST) ?? true; + static get OVERRIDDEN_SETTINGS(): string { + return get_string(Settings.KEY_OVERRIDDEN_SETTINGS); } - static get_show_indicator(): boolean { - if (!this._settings) return true; - return this._settings.get_boolean(this.SETTING_SHOW_INDICATOR) ?? true; + static set OVERRIDDEN_SETTINGS(val: string) { + set_string(Settings.KEY_OVERRIDDEN_SETTINGS, val); } - static get_inner_gaps(scaleFactor: number = 1): { - top: number; - bottom: number; - left: number; - right: number; - } { - // get the gaps settings and scale by scale factor - const value = - (this._settings?.get_uint(this.SETTING_INNER_GAPS) ?? 0) * - scaleFactor; - return { - top: value, - bottom: value, - left: value, - right: value, - }; + static get TILING_SYSTEM(): boolean { + return get_boolean(Settings.KEY_TILING_SYSTEM); } - static get_outer_gaps(scaleFactor: number = 1): { - top: number; - bottom: number; - left: number; - right: number; - } { - // get the gaps settings and scale by scale factor - const value = - (this._settings?.get_uint(this.SETTING_OUTER_GAPS) ?? 0) * - scaleFactor; - return { - top: value, - bottom: value, - left: value, - right: value, - }; + static set TILING_SYSTEM(val: boolean) { + set_boolean(Settings.KEY_TILING_SYSTEM, val); + } + + static get SNAP_ASSIST(): boolean { + return get_boolean(Settings.KEY_SNAP_ASSIST); } - static get_span_multiple_tiles(): boolean { - return ( - this._settings?.get_boolean(this.SETTING_SPAN_MULTIPLE_TILES) ?? - true + static set SNAP_ASSIST(val: boolean) { + set_boolean(Settings.KEY_SNAP_ASSIST, val); + } + + static get SHOW_INDICATOR(): boolean { + return get_boolean(Settings.KEY_SHOW_INDICATOR); + } + + static set SHOW_INDICATOR(val: boolean) { + set_boolean(Settings.KEY_SHOW_INDICATOR, val); + } + + static get TILING_SYSTEM_ACTIVATION_KEY(): ActivationKey { + return get_activationkey( + Settings.KEY_TILING_SYSTEM_ACTIVATION_KEY, + ActivationKey.CTRL, ); } - static get_layouts_json(): Layout[] { - try { - const layouts = JSON.parse( - this._settings?.get_string(this.SETTING_LAYOUTS_JSON) || '[]', - ) as Layout[]; - if (layouts.length === 0) - throw new Error('At least one layout is required'); - return layouts.filter((layout) => layout.tiles.length > 0); - } catch (ex: unknown) { - this.reset_layouts_json(); - return JSON.parse( - this._settings?.get_string(this.SETTING_LAYOUTS_JSON) || '[]', - ) as Layout[]; - } + static set TILING_SYSTEM_ACTIVATION_KEY(val: ActivationKey) { + set_activationkey(Settings.KEY_TILING_SYSTEM_ACTIVATION_KEY, val); } - static get_selected_layouts(): string[][] { - const variant = this._settings?.get_value( - Settings.SETTING_SELECTED_LAYOUTS, + static get TILING_SYSTEM_DEACTIVATION_KEY(): ActivationKey { + return get_activationkey( + Settings.KEY_TILING_SYSTEM_DEACTIVATION_KEY, + ActivationKey.NONE, ); - if (!variant) return []; + } - const result: string[][] = []; - // for each monitor - for (let i = 0; i < variant.n_children(); i++) { - const monitor_variant = variant.get_child_value(i); - if (!monitor_variant) continue; + static set TILING_SYSTEM_DEACTIVATION_KEY(val: ActivationKey) { + set_activationkey(Settings.KEY_TILING_SYSTEM_DEACTIVATION_KEY, val); + } - const n_workspaces = monitor_variant.n_children(); - const monitor_result: string[] = []; - // for each workspace - for (let j = 0; j < n_workspaces; j++) { - const layout_variant = monitor_variant.get_child_value(j); - if (!layout_variant) continue; + static get INNER_GAPS(): number { + return get_unsigned_number(Settings.KEY_INNER_GAPS); + } - monitor_result.push(layout_variant.get_string()[0]); - } - result.push(monitor_result); - } - return result; + static set INNER_GAPS(val: number) { + set_unsigned_number(Settings.KEY_INNER_GAPS, val); } - static get_restore_window_original_size(): boolean { - return ( - this._settings?.get_boolean( - Settings.SETTING_RESTORE_WINDOW_ORIGINAL_SIZE, - ) ?? true - ); + static get OUTER_GAPS(): number { + return get_unsigned_number(Settings.KEY_OUTER_GAPS); } - static get_resize_complementing_windows(): boolean { - return ( - this._settings?.get_boolean( - Settings.SETTING_RESIZE_COMPLEMENTING_WINDOWS, - ) ?? true - ); + static set OUTER_GAPS(val: number) { + set_unsigned_number(Settings.KEY_OUTER_GAPS, val); } - static get_tiling_system_activation_key(): ActivationKey { - const val = this._settings?.get_strv( - this.SETTING_TILING_SYSTEM_ACTIVATION_KEY, - ); - if (!val || val.length === 0) return ActivationKey.CTRL; - return Number(val[0]); + static get SPAN_MULTIPLE_TILES(): boolean { + return get_boolean(Settings.KEY_SPAN_MULTIPLE_TILES); } - static get_tiling_system_deactivation_key(): ActivationKey { - const val = this._settings?.get_strv( - this.SETTING_TILING_SYSTEM_DEACTIVATION_KEY, - ); - if (!val || val.length === 0) return ActivationKey.NONE; - return Number(val[0]); + static set SPAN_MULTIPLE_TILES(val: boolean) { + set_boolean(Settings.KEY_SPAN_MULTIPLE_TILES, val); } - static get_span_multiple_tiles_activation_key(): ActivationKey { - const val = this._settings?.get_strv( - this.SETTING_SPAN_MULTIPLE_TILES_ACTIVATION_KEY, + static get SPAN_MULTIPLE_TILES_ACTIVATION_KEY(): ActivationKey { + return get_activationkey( + Settings.KEY_SPAN_MULTIPLE_TILES_ACTIVATION_KEY, + ActivationKey.ALT, ); - if (!val || val.length === 0) return ActivationKey.ALT; - return Number(val[0]); } - static get_enable_blur_snap_assistant(): boolean { - return ( - this._settings?.get_boolean( - this.SETTING_ENABLE_BLUR_SNAP_ASSISTANT, - ) ?? false - ); + static set SPAN_MULTIPLE_TILES_ACTIVATION_KEY(val: ActivationKey) { + set_activationkey(Settings.KEY_SPAN_MULTIPLE_TILES_ACTIVATION_KEY, val); } - static get_enable_blur_selected_tilepreview(): boolean { - return ( - this._settings?.get_boolean( - this.SETTING_ENABLE_BLUR_SELECTED_TILEPREVIEW, - ) ?? false - ); + static get RESTORE_WINDOW_ORIGINAL_SIZE(): boolean { + return get_boolean(Settings.KEY_RESTORE_WINDOW_ORIGINAL_SIZE); } - static get_enable_move_keybindings(): boolean { - return ( - this._settings?.get_boolean(this.SETTING_ENABLE_MOVE_KEYBINDINGS) ?? - true - ); + static set RESTORE_WINDOW_ORIGINAL_SIZE(val: boolean) { + set_boolean(Settings.KEY_RESTORE_WINDOW_ORIGINAL_SIZE, val); } - static get_enable_autotiling(): boolean { - return ( - this._settings?.get_boolean(this.SETTING_ENABLE_AUTO_TILING) ?? - false - ); + static get RESIZE_COMPLEMENTING_WINDOWS(): boolean { + return get_boolean(Settings.KEY_RESIZE_COMPLEMENTING_WINDOWS); } - static get_overridden_settings(): string { - return ( - this._settings?.get_string(this.SETTING_OVERRIDDEN_SETTINGS) ?? '{}' - ); + static set RESIZE_COMPLEMENTING_WINDOWS(val: boolean) { + set_boolean(Settings.KEY_RESIZE_COMPLEMENTING_WINDOWS, val); } - static get_active_screen_edges(): boolean { - return ( - this._settings?.get_boolean(this.SETTING_ACTIVE_SCREEN_EDGES) ?? - true - ); + static get ENABLE_BLUR_SNAP_ASSISTANT(): boolean { + return get_boolean(Settings.KEY_ENABLE_BLUR_SNAP_ASSISTANT); } - static get_top_edge_maximize(): boolean { - return ( - this._settings?.get_boolean(this.SETTING_TOP_EDGE_MAXIMIZE) ?? false - ); + static set ENABLE_BLUR_SNAP_ASSISTANT(val: boolean) { + set_boolean(Settings.KEY_ENABLE_BLUR_SNAP_ASSISTANT, val); } - static get_override_window_menu(): boolean { - return ( - this._settings?.get_boolean(this.SETTING_OVERRIDE_WINDOW_MENU) ?? - false - ); + static get ENABLE_BLUR_SELECTED_TILEPREVIEW(): boolean { + return get_boolean(Settings.KEY_ENABLE_BLUR_SELECTED_TILEPREVIEW); } - static get_quarter_tiling_threshold(): number { - return ( - this._settings?.get_uint(this.SETTING_QUARTER_TILING_THRESHOLD) ?? - 40 - ); + static set ENABLE_BLUR_SELECTED_TILEPREVIEW(val: boolean) { + set_boolean(Settings.KEY_ENABLE_BLUR_SELECTED_TILEPREVIEW, val); } - static get_window_border_color(): string { - return ( - this._settings?.get_string(this.SETTING_WINDOW_BORDER_COLOR) ?? - '#ec5e5e' - ); + static get ENABLE_MOVE_KEYBINDINGS(): boolean { + return get_boolean(Settings.KEY_ENABLE_MOVE_KEYBINDINGS); } - static get_window_border_width(): number { - return this._settings?.get_uint(this.SETTING_WINDOW_BORDER_WIDTH) ?? 3; + static set ENABLE_MOVE_KEYBINDINGS(val: boolean) { + set_boolean(Settings.KEY_ENABLE_MOVE_KEYBINDINGS, val); } - static get_enable_window_border(): boolean { - return ( - this._settings?.get_boolean(this.SETTING_ENABLE_WINDOW_BORDER) ?? - false - ); + static get ENABLE_AUTO_TILING(): boolean { + return get_boolean(Settings.KEY_ENABLE_AUTO_TILING); } - static set_last_version_installed(version: string) { - this._settings?.set_string( - this.SETTING_LAST_VERSION_NAME_INSTALLED, - version, - ); + static set ENABLE_AUTO_TILING(val: boolean) { + set_boolean(Settings.KEY_ENABLE_AUTO_TILING, val); } - static set_tiling_system_activation_key(key: ActivationKey) { - this._settings?.set_strv(this.SETTING_TILING_SYSTEM_ACTIVATION_KEY, [ - String(key), - ]); + static get ACTIVE_SCREEN_EDGES(): boolean { + return get_boolean(Settings.KEY_ACTIVE_SCREEN_EDGES); } - static set_tiling_system_deactivation_key(key: ActivationKey) { - this._settings?.set_strv(this.SETTING_TILING_SYSTEM_DEACTIVATION_KEY, [ - String(key), - ]); + static set ACTIVE_SCREEN_EDGES(val: boolean) { + set_boolean(Settings.KEY_ACTIVE_SCREEN_EDGES, val); } - static set_span_multiple_tiles_activation_key(key: ActivationKey) { - this._settings?.set_strv( - this.SETTING_SPAN_MULTIPLE_TILES_ACTIVATION_KEY, - [String(key)], - ); + static get TOP_EDGE_MAXIMIZE(): boolean { + return get_boolean(Settings.KEY_TOP_EDGE_MAXIMIZE); } - static set_show_indicator(value: boolean) { - this._settings?.set_boolean(this.SETTING_SHOW_INDICATOR, value); + static set TOP_EDGE_MAXIMIZE(val: boolean) { + set_boolean(Settings.KEY_TOP_EDGE_MAXIMIZE, val); } - static set_quarter_tiling_threshold(value: number) { - this._settings?.set_uint(this.SETTING_QUARTER_TILING_THRESHOLD, value); + static get OVERRIDE_WINDOW_MENU(): boolean { + return get_boolean(Settings.KEY_OVERRIDE_WINDOW_MENU); } - static set_overridden_settings(newVal: string): boolean { - return ( - this._settings?.set_string( - this.SETTING_OVERRIDDEN_SETTINGS, - newVal, - ) ?? false - ); + static set OVERRIDE_WINDOW_MENU(val: boolean) { + set_boolean(Settings.KEY_OVERRIDE_WINDOW_MENU, val); } - static set_enable_move_keybindings(value: boolean) { - this._settings?.set_boolean( - this.SETTING_ENABLE_MOVE_KEYBINDINGS, - value, - ); + static get SNAP_ASSISTANT_THRESHOLD(): number { + return get_number(Settings.KEY_SNAP_ASSISTANT_THRESHOLD); + } + + static set SNAP_ASSISTANT_THRESHOLD(val: number) { + set_number(Settings.KEY_SNAP_ASSISTANT_THRESHOLD, val); + } + + static get QUARTER_TILING_THRESHOLD(): number { + return get_unsigned_number(Settings.KEY_QUARTER_TILING_THRESHOLD); + } + + static set QUARTER_TILING_THRESHOLD(val: number) { + set_unsigned_number(Settings.KEY_QUARTER_TILING_THRESHOLD, val); + } + + static get WINDOW_BORDER_COLOR(): string { + return get_string(Settings.KEY_WINDOW_BORDER_COLOR); + } + + static set WINDOW_BORDER_COLOR(val: string) { + set_string(Settings.KEY_WINDOW_BORDER_COLOR, val); + } + + static get WINDOW_BORDER_WIDTH(): number { + return get_unsigned_number(Settings.KEY_WINDOW_BORDER_WIDTH); + } + + static set WINDOW_BORDER_WIDTH(val: number) { + set_unsigned_number(Settings.KEY_WINDOW_BORDER_WIDTH, val); + } + + static get ENABLE_WINDOW_BORDER(): boolean { + return get_boolean(Settings.KEY_ENABLE_WINDOW_BORDER); + } + + static set ENABLE_WINDOW_BORDER(val: boolean) { + set_boolean(Settings.KEY_ENABLE_WINDOW_BORDER, val); + } + + static get SNAP_ASSISTANT_ANIMATION_TIME(): number { + return get_unsigned_number(Settings.KEY_SNAP_ASSISTANT_ANIMATION_TIME); + } + + static set SNAP_ASSISTANT_ANIMATION_TIME(val: number) { + set_unsigned_number(Settings.KEY_SNAP_ASSISTANT_ANIMATION_TIME, val); + } + + static get TILE_PREVIEW_ANIMATION_TIME(): number { + return get_unsigned_number(Settings.KEY_TILE_PREVIEW_ANIMATION_TIME); + } + + static set TILE_PREVIEW_ANIMATION_TIME(val: number) { + set_unsigned_number(Settings.KEY_TILE_PREVIEW_ANIMATION_TIME, val); + } + + static get_inner_gaps(scaleFactor: number = 1): { + top: number; + bottom: number; + left: number; + right: number; + } { + // get the gaps settings and scale by scale factor + const value = this.INNER_GAPS * scaleFactor; + return { + top: value, + bottom: value, + left: value, + right: value, + }; } - static set_active_screen_edges(value: boolean) { - this._settings?.set_boolean(this.SETTING_ACTIVE_SCREEN_EDGES, value); + static get_outer_gaps(scaleFactor: number = 1): { + top: number; + bottom: number; + left: number; + right: number; + } { + // get the gaps settings and scale by scale factor + const value = this.OUTER_GAPS * scaleFactor; + return { + top: value, + bottom: value, + left: value, + right: value, + }; } - static set_window_border_color(value: string): boolean { - return ( - this._settings?.set_string( - this.SETTING_WINDOW_BORDER_COLOR, - value, - ) ?? false + static get_layouts_json(): Layout[] { + try { + const layouts = JSON.parse( + this._settings?.get_string(this.KEY_SETTING_LAYOUTS_JSON) || + '[]', + ) as Layout[]; + if (layouts.length === 0) + throw new Error('At least one layout is required'); + return layouts.filter((layout) => layout.tiles.length > 0); + } catch (ex: unknown) { + this.reset_layouts_json(); + return JSON.parse( + this._settings?.get_string(this.KEY_SETTING_LAYOUTS_JSON) || + '[]', + ) as Layout[]; + } + } + + static get_selected_layouts(): string[][] { + const variant = this._settings?.get_value( + Settings.KEY_SETTING_SELECTED_LAYOUTS, ); + if (!variant) return []; + + const result: string[][] = []; + // for each monitor + for (let i = 0; i < variant.n_children(); i++) { + const monitor_variant = variant.get_child_value(i); + if (!monitor_variant) continue; + + const n_workspaces = monitor_variant.n_children(); + const monitor_result: string[] = []; + // for each workspace + for (let j = 0; j < n_workspaces; j++) { + const layout_variant = monitor_variant.get_child_value(j); + if (!layout_variant) continue; + + monitor_result.push(layout_variant.get_string()[0]); + } + result.push(monitor_result); + } + return result; } static reset_layouts_json() { @@ -491,22 +565,25 @@ export default class Settings { static save_layouts_json(layouts: Layout[]) { this._settings?.set_string( - this.SETTING_LAYOUTS_JSON, + this.KEY_SETTING_LAYOUTS_JSON, JSON.stringify(layouts), ); } static save_selected_layouts(ids: string[][]) { if (ids.length === 0) { - this._settings?.reset(Settings.SETTING_SELECTED_LAYOUTS); + this._settings?.reset(Settings.KEY_SETTING_SELECTED_LAYOUTS); return; } const variants = ids.map((monitor_ids) => GLib.Variant.new_strv(monitor_ids), ); const result = GLib.Variant.new_array(null, variants); - // @ts-expect-error "'result' is of a correct variant type" - this._settings?.set_value(Settings.SETTING_SELECTED_LAYOUTS, result); + this._settings?.set_value( + Settings.KEY_SETTING_SELECTED_LAYOUTS, + // @ts-expect-error "'result' is of a correct variant type" + result, + ); } static connect(key: string, func: (...arg: unknown[]) => void): number { diff --git a/src/settings/settingsExport.ts b/src/settings/settingsExport.ts index 6d6fac5..9cafc3e 100644 --- a/src/settings/settingsExport.ts +++ b/src/settings/settingsExport.ts @@ -3,10 +3,10 @@ import Settings from '@settings/settings'; import SettingsOverride from '@settings/settingsOverride'; const dconfPath = '/org/gnome/shell/extensions/tilingshell/'; -const excludedKeys = [ - Settings.SETTING_LAYOUTS_JSON, - Settings.SETTING_LAST_VERSION_NAME_INSTALLED, - Settings.SETTING_OVERRIDDEN_SETTINGS, +const excludedKeys: string[] = [ + Settings.KEY_SETTING_LAYOUTS_JSON, + Settings.KEY_LAST_VERSION_NAME_INSTALLED, + Settings.KEY_OVERRIDDEN_SETTINGS, ]; export default class SettingsExport { @@ -40,8 +40,8 @@ export default class SettingsExport { } restoreToDefault() { - Settings.set_active_screen_edges(false); - Settings.set_enable_move_keybindings(false); + Settings.ACTIVE_SCREEN_EDGES = false; + Settings.ENABLE_MOVE_KEYBINDINGS = false; SettingsOverride.get().restoreAll(); this._gioSettings .list_keys() diff --git a/src/settings/settingsOverride.ts b/src/settings/settingsOverride.ts index edde78b..1e628bb 100644 --- a/src/settings/settingsOverride.ts +++ b/src/settings/settingsOverride.ts @@ -8,7 +8,7 @@ export default class SettingsOverride { private constructor() { this._overriddenKeys = this._jsonToOverriddenKeys( - Settings.get_overridden_settings(), + Settings.OVERRIDDEN_SETTINGS, ); } @@ -91,7 +91,7 @@ export default class SettingsOverride { if (!schemaMap.has(keyToOverride)) { schemaMap.set(keyToOverride, oldValue); - Settings.set_overridden_settings(this._overriddenKeysToJSON()); + Settings.OVERRIDDEN_SETTINGS = this._overriddenKeysToJSON(); } return oldValue; @@ -115,7 +115,7 @@ export default class SettingsOverride { if (overridden.size === 0) this._overriddenKeys.delete(giosettings.schemaId); - Settings.set_overridden_settings(this._overriddenKeysToJSON()); + Settings.OVERRIDDEN_SETTINGS = this._overriddenKeysToJSON(); } return oldValue; @@ -147,6 +147,6 @@ export default class SettingsOverride { if (this._overriddenKeys.size === 0) this._overriddenKeys = new Map(); - Settings.set_overridden_settings(this._overriddenKeysToJSON()); + Settings.OVERRIDDEN_SETTINGS = this._overriddenKeysToJSON(); } } diff --git a/src/utils/globalState.ts b/src/utils/globalState.ts index b1fcb88..4668849 100644 --- a/src/utils/globalState.ts +++ b/src/utils/globalState.ts @@ -65,21 +65,30 @@ export default class GlobalState extends GObject.Object { this.validate_selected_layouts(); Settings.bind( - Settings.SETTING_TILE_PREVIEW_ANIMATION_TIME, + Settings.KEY_TILE_PREVIEW_ANIMATION_TIME, this, 'tilePreviewAnimationTime', Gio.SettingsBindFlags.GET, ); - this._signals.connect(Settings, Settings.SETTING_LAYOUTS_JSON, () => { - this._layouts = Settings.get_layouts_json(); - this.emit(GlobalState.SIGNAL_LAYOUTS_CHANGED); - }); + this._signals.connect( + Settings, + Settings.KEY_SETTING_LAYOUTS_JSON, + () => { + this._layouts = Settings.get_layouts_json(); + this.emit(GlobalState.SIGNAL_LAYOUTS_CHANGED); + }, + ); this._signals.connect( Settings, - Settings.SETTING_SELECTED_LAYOUTS, + Settings.KEY_SETTING_SELECTED_LAYOUTS, () => { const selected_layouts = Settings.get_selected_layouts(); + if (selected_layouts.length === 0) { + this.validate_selected_layouts(); + return; + } + const n_monitors = Main.layoutManager.monitors.length; const n_workspaces = global.workspaceManager.get_n_workspaces(); for (let i = 0; i < n_workspaces; i++) { @@ -87,7 +96,10 @@ export default class GlobalState extends GObject.Object { global.workspaceManager.get_workspace_by_index(i); if (!ws) continue; - const monitors_layouts = selected_layouts[i]; + const monitors_layouts = + i < selected_layouts.length + ? selected_layouts[i] + : [GlobalState.get().layouts[0].id]; while (monitors_layouts.length < n_monitors) monitors_layouts.push(this._layouts[0].id); while (monitors_layouts.length > n_monitors) @@ -264,7 +276,10 @@ export default class GlobalState extends GObject.Object { if (workspaceIndex < 0 || workspaceIndex >= selectedLayouts.length) workspaceIndex = 0; - const monitors_selected = selectedLayouts[workspaceIndex]; + const monitors_selected = + workspaceIndex < selectedLayouts.length + ? selectedLayouts[workspaceIndex] + : GlobalState.get().layouts[0].id; if (monitorIndex < 0 || monitorIndex >= monitors_selected.length) monitorIndex = 0; diff --git a/tsconfig.json b/tsconfig.json index 4309b9e..b917db1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,7 +12,7 @@ "paths": { "@*": ["./src/*"] }, - "experimentalDecorators": true + "experimentalDecorators": true, }, "include": [ "ambient.d.ts",