From 6a777e320079184a4ab3aee56c1d51b28f554102 Mon Sep 17 00:00:00 2001 From: Tristan Tarrant Date: Tue, 25 Aug 2026 16:25:52 +0200 Subject: [PATCH] [#604] GNOME 51 support --- resources/metadata.json | 3 ++- src/extension.ts | 21 ++++----------------- src/utils/ui.ts | 33 ++++++++++++++++++++++++++++++++- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/resources/metadata.json b/resources/metadata.json index e58a93c7..410b7caf 100644 --- a/resources/metadata.json +++ b/resources/metadata.json @@ -11,7 +11,8 @@ "47", "48", "49", - "50" + "50", + "51" ], "version": 99, "version-name": "17.3", diff --git a/src/extension.ts b/src/extension.ts index eee13a99..c1c7c3b5 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -27,6 +27,7 @@ import { filterUnfocusableWindows, getMonitors, getWindows, + isFractionalScalingEnabled, squaredEuclideanDistance, } from './utils/ui'; import * as Main from 'resource:///org/gnome/shell/ui/main.js'; @@ -132,7 +133,7 @@ export default class TilingShellExtension extends Extension { // force initialization and tracking of windows TilingShellWindowManager.get(); - this._fractionalScalingEnabled = this._isFractionalScalingEnabled( + this._fractionalScalingEnabled = isFractionalScalingEnabled( new Gio.Settings({ schema: 'org.gnome.mutter' }), ); @@ -226,7 +227,7 @@ export default class TilingShellExtension extends Extension { if (!_mutterSettings) return; const fractionalScalingEnabled = - this._isFractionalScalingEnabled(_mutterSettings); + isFractionalScalingEnabled(_mutterSettings); if (this._fractionalScalingEnabled === fractionalScalingEnabled) return; @@ -240,7 +241,7 @@ export default class TilingShellExtension extends Extension { if (this._windowBorderManager) this._windowBorderManager.destroy(); this._windowBorderManager = new WindowBorderManager( - this._fractionalScalingEnabled, + !this._fractionalScalingEnabled, ); this._windowBorderManager.enable(); }, @@ -748,20 +749,6 @@ export default class TilingShellExtension extends Extension { monitorTilingManager.onUntileWindow(focus_window, true); } - private _isFractionalScalingEnabled( - _mutterSettings: Gio.Settings, - ): boolean { - return ( - _mutterSettings - .get_strv('experimental-features') - .find( - (feat) => - feat === 'scale-monitor-framebuffer' || - feat === 'x11-randr-fractional-scaling', - ) !== undefined - ); - } - disable(): void { // bring back overridden keybindings this._keybindings?.destroy(); diff --git a/src/utils/ui.ts b/src/utils/ui.ts index 76cea4ed..c183bbcb 100644 --- a/src/utils/ui.ts +++ b/src/utils/ui.ts @@ -1,9 +1,40 @@ -import { St, Meta, Mtk, Clutter } from '../gi/ext'; +import { St, Meta, Mtk, Clutter, Gio, GLib } from '../gi/ext'; import * as Main from 'resource:///org/gnome/shell/ui/main.js'; import { Monitor } from 'resource:///org/gnome/shell/ui/layout.js'; +import * as Config from 'resource:///org/gnome/shell/misc/config.js'; export const getMonitors = (): Monitor[] => Main.layoutManager.monitors; +export const isFractionalScalingEnabled = ( + mutterSettings: Gio.Settings, +): boolean => { + // Since GNOME 49, fractional scaling (the logical monitor layout mode) is + // enabled by default on Wayland and is no longer an experimental feature + const GNOME_VERSION_MAJOR = Number(Config.PACKAGE_VERSION.split('.')[0]); + // Meta.is_wayland_compositor() was removed in newer GNOME versions + const isWayland = Meta.is_wayland_compositor + ? Meta.is_wayland_compositor() + : GLib.getenv('XDG_SESSION_TYPE') === 'wayland'; + if (isWayland && GNOME_VERSION_MAJOR >= 49) return true; + + // The experimental-features key was removed from the org.gnome.mutter + // schema in mutter 51, so only read it when the schema still has it + const source = Gio.SettingsSchemaSource.get_default(); + const schema = source?.lookup('org.gnome.mutter', true); + if (!schema || !schema.list_keys().includes('experimental-features')) + return false; + + return ( + mutterSettings + .get_strv('experimental-features') + .find( + (feat) => + feat === 'scale-monitor-framebuffer' || + feat === 'x11-randr-fractional-scaling', + ) !== undefined + ); +}; + export const isPointInsideRect = ( point: { x: number; y: number }, rect: Mtk.Rectangle,