[gnome] Bump extension versions ... I should probably get these out of here

This commit is contained in:
2025-06-19 09:27:02 -04:00
parent b69326ba18
commit 80d725a18a
26 changed files with 312 additions and 473 deletions

View File

@ -36,6 +36,18 @@
"wmClass": "org.mozilla.Thunderbird.desktop",
"wmTitle": "!Mozilla Thunderbird",
"mode": "float"
},
{
"wmClass": "evolution-alarm-notify",
"mode": "float"
},
{
"wmClass": "variety",
"mode": "float"
},
{
"wmClass": "update-manager",
"mode": "float"
}
]
}

View File

@ -74,7 +74,27 @@ export class WindowManager extends GObject.Object {
this.eventQueue = new Queue();
this.theme = this.ext.theme;
this.lastFocusedWindow = null;
this.shouldFocusOnHover = this.ext.settings.get_boolean("focus-on-hover-enabled");
Logger.info("forge initialized");
if (this.shouldFocusOnHover) {
// Start the pointer loop to observe the pointer position
// and change the focus window accordingly
this.pointerLoopInit();
}
}
pointerLoopInit() {
if (this._pointerFocusTimeoutId) {
GLib.Source.remove(this._pointerFocusTimeoutId);
}
this._pointerFocusTimeoutId = GLib.timeout_add(
GLib.PRIORITY_DEFAULT,
16,
this._focusWindowUnderPointer.bind(this)
);
}
addFloatOverride(metaWindow, withWmId) {
@ -267,6 +287,14 @@ export class WindowManager extends GObject.Object {
switch (settingName) {
case "focus-border-toggle":
this.renderTree(settingName);
break;
case "focus-on-hover-enabled":
this.shouldFocusOnHover = settings.get_boolean(settingName);
if (this.shouldFocusOnHover) {
this.pointerLoopInit();
}
break;
case "tiling-mode-enabled":
this.renderTree(settingName);
@ -891,16 +919,20 @@ export class WindowManager extends GObject.Object {
});
}
hideActorBorder(actor) {
if (actor.border) {
actor.border.hide();
}
if (actor.splitBorder) {
actor.splitBorder.hide();
}
}
hideWindowBorders() {
this.tree.nodeWindows.forEach((nodeWindow) => {
let actor = nodeWindow.windowActor;
if (actor) {
if (actor.border) {
actor.border.hide();
}
if (actor.splitBorder) {
actor.splitBorder.hide();
}
this.hideActorBorder(actor);
}
if (nodeWindow.parentNode.isTabbed()) {
if (nodeWindow.tab) {
@ -1090,6 +1122,11 @@ export class WindowManager extends GObject.Object {
this._queueSourceId = 0;
}
if (this._pointerFocusTimeoutId) {
GLib.Source.remove(this._pointerFocusTimeoutId);
this._pointerFocusTimeoutId = 0;
}
if (this._prefsOpenSrcId) {
GLib.Source.remove(this._prefsOpenSrcId);
this._prefsOpenSrcId = 0;
@ -1410,6 +1447,9 @@ export class WindowManager extends GObject.Object {
let from = "size-changed";
this.updateMetaPositionSize(_metaWindow, from);
}),
metaWindow.connect("unmanaged", (_metaWindow) => {
this.hideActorBorder(windowActor);
}),
metaWindow.connect("focus", (_metaWindowFocus) => {
this.queueEvent({
name: "focus-update",
@ -2243,6 +2283,62 @@ export class WindowManager extends GObject.Object {
return nodeWinAtPointer;
}
/**
* Focus the window under the pointer and raise it.
*
* @returns {boolean} true if we should continue polling, false otherwise
*/
_focusWindowUnderPointer() {
// Break the loop if the user has disabled the feature
// or if the window manager is disabled
if (!this.shouldFocusOnHover || this.disabled) return false;
// We don't want to focus windows when the overview is visible
if (Main.overview.visible) return true;
// Get the global mouse position
let pointer = global.get_pointer();
const metaWindow = this._getMetaWindowAtPointer(pointer);
if (metaWindow) {
// If window is not null, focus it
metaWindow.focus(global.get_current_time());
// Raise it to the top
metaWindow.raise();
}
// Continue polling
return true;
}
/**
* Get the Meta.Window at the pointer coordinates
*
* @param {[number, number]} pointer x and y coordinates
* @returns null if no window is found, otherwise the Meta.Window
*/
_getMetaWindowAtPointer(pointer) {
const windows = global.get_window_actors();
const [x, y] = pointer;
// Iterate through the windows in reverse order to get the top-most window
for (let i = windows.length - 1; i >= 0; i--) {
let window = windows[i];
let metaWindow = window.meta_window;
let { x: wx, y: wy, width, height } = metaWindow.get_frame_rect();
// Check if the position is within the window bounds
if (x >= wx && x <= wx + width && y >= wy && y <= wy + height) {
return metaWindow;
}
}
// No window found at the pointer
return null;
}
/**
* Finds the NodeWindow under the Meta.Window and the
* current pointer coordinates;

View File

@ -25,16 +25,17 @@ export class AppearancePage extends PreferencesPage {
*/
static getCssSelectorAsMessage(selector) {
switch (selector) {
// TODO: make separate color selection for preview hint
case ".window-tiled-border":
return _("Tiled Focus Hint and Preview");
case ".window-floated-border":
return _("Floated Focus Hint");
case ".window-split-border":
return _("Split Direction Hint");
case ".window-stacked-border":
return _("Stacked Focus Hint and Preview");
return _("Tiled window");
case ".window-tabbed-border":
return _("Tabbed Focus Hint and Preview");
return _("Tabbed window");
case ".window-stacked-border":
return _("Stacked window");
case ".window-floated-border":
return _("Floating window");
case ".window-split-border":
return _("Split direction hint");
}
}
@ -45,32 +46,63 @@ export class AppearancePage extends PreferencesPage {
this.themeMgr = new PrefsThemeManager(this);
this.add_group({
title: _("Gaps"),
description: _("Change the gap size between windows"),
children: [
// Gaps size
new SpinButtonRow({
title: _("Gaps Size"),
title: _("Gap size"),
range: [0, 32, 1],
settings,
bind: "window-gap-size",
}),
// Gaps size multiplier
new SpinButtonRow({
title: _("Gaps Size Multiplier"),
range: [0, 8, 1],
title: _("Gap size multiplier"),
range: [0, 32, 1],
settings,
bind: "window-gap-size-increment",
}),
// Gap Hidden when Single Window
new SwitchRow({
title: _("Gaps Hidden when Single"),
title: _("Disable gaps for single window"),
subtitle: _("Disables window gaps when only a single window is present"),
settings,
bind: "window-gap-hidden-on-single",
}),
],
});
this.add_group({
title: _("Style"),
description: _("Change how the shell looks"),
children: [
new SwitchRow({
title: _("Preview hint"),
subtitle: _("Shows where the window will be tiled when you let go of it"),
experimental: true,
settings,
bind: "preview-hint-enabled",
}),
new SwitchRow({
title: _("Border around focused window"),
subtitle: _("Display a colored border around the focused window"),
settings,
bind: "focus-border-toggle",
}),
new SwitchRow({
title: _("Window split hint border"),
subtitle: _("Show split direction border on focused window"),
settings,
bind: "split-border-toggle",
}),
new SwitchRow({
title: _("Forge in quick settings"),
subtitle: _("Toggles the Forge tile in quick settings"),
experimental: true,
settings,
bind: "quick-settings-enabled",
}),
],
});
this.add_group({
title: _("Color"),
description: _("Changes the focused window's border and preview hint colors"),
children: [
"window-tiled-border",
"window-tabbed-border",
@ -92,7 +124,7 @@ export class AppearancePage extends PreferencesPage {
const row = new Adw.ExpanderRow({ title });
const borderSizeRow = new SpinButtonRow({
title: _("Border Size"),
title: _("Border size"),
range: [1, 6, 1],
// subtitle: 'Properties of the focus hint',
max_width_chars: 1,
@ -164,7 +196,7 @@ export class AppearancePage extends PreferencesPage {
};
const borderColorRow = new ColorRow({
title: _("Border Color"),
title: _("Border color"),
init: theme.getCssProperty(selector, "border-color").value,
onChange: updateCssColors,
});

View File

@ -18,34 +18,14 @@ export class KeyboardPage extends PreferencesPage {
constructor({ kbdSettings }) {
super({ title: _("Keyboard"), icon_name: "input-keyboard-symbolic" });
const description = `${_("Syntax")}: &lt;Super&gt;h, &lt;Shift&gt;g, &lt;Shift&gt;&lt;Super&gt;h
${_("Legend")}: &lt;Super&gt; - ${_("Windows key")}, &lt;Primary&gt; - ${_("Control key")}
${_("Delete text to unset. Press Return key to accept. Focus out to ignore.")} <i>${_(
"Resets"
)}</i> ${_("to previous value when invalid")}`;
this.add_group({
title: _("Update Shortcuts"),
description,
children: Object.entries({
window: "Window Shortcuts",
workspace: "Workspace Shortcuts",
con: "Container Shortcuts",
focus: "Focus Shortcuts",
prefs: "Other Shortcuts",
}).map(([prefix, gettextKey]) =>
KeyboardPage.makeKeygroupExpander(prefix, gettextKey, kbdSettings)
title: _("Drag-and-drop modifier key"),
description: _(
"Change the modifier key for tiling windows via drag-and-drop. Select 'None' to always tile"
),
});
this.add_group({
title: _("Drag-Drop Tiling Modifier Key Options"),
description: `<i>${_(
"Change the modifier for <b>tiling</b> windows via mouse/drag-drop"
)}</i> ${_("Select <i>None</i> to <u>always tile immediately</u> by default")}`,
children: [
new RadioRow({
title: _("Tile Modifier"),
title: _("Modifier key"),
settings: kbdSettings,
bind: "mod-mask-mouse-tile",
options: {
@ -57,6 +37,21 @@ export class KeyboardPage extends PreferencesPage {
}),
],
});
this.add_group({
title: _("Shortcuts"),
description: _(
'Change the tiling shortcuts. To clear a shortcut clear the input field. To apply a shortcut press enter. <a href="https://github.com/forge-ext/forge/wiki/Keyboard-Shortcuts">Syntax examples</a>'
),
children: Object.entries({
window: "Tiling shortcuts",
con: "Container shortcuts",
workspace: "Workspace shortcuts",
focus: "Appearance shortcuts",
prefs: "Other shortcuts",
}).map(([prefix, gettextKey]) =>
KeyboardPage.makeKeygroupExpander(prefix, gettextKey, kbdSettings)
),
});
}
static makeKeygroupExpander(prefix, gettextKey, settings) {

View File

@ -8,7 +8,7 @@ import { Logger } from "../shared/logger.js";
import { production } from "../shared/settings.js";
// Prefs UI
import { DropDownRow, SwitchRow, PreferencesPage } from "./widgets.js";
import { DropDownRow, SwitchRow, PreferencesPage, EntryRow } from "./widgets.js";
// Extension imports
import { gettext as _ } from "resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js";
@ -51,65 +51,57 @@ export class SettingsPage extends PreferencesPage {
}
constructor({ settings, window, metadata }) {
super({ title: _("Settings"), icon_name: "settings-symbolic" });
super({ title: _("Tiling"), icon_name: "view-grid-symbolic" });
this.add_group({
title: _("Settings"),
description: _("Toggle Forge's high-level features"),
title: _("Behavior"),
description: _("Change how the tiling behaves"),
header_suffix: makeAboutButton(window, metadata),
children: [
new SwitchRow({
title: _("Stacked Tiling Mode"),
subtitle: _("Stack windows on top of each other while still being tiled"),
title: _("Focus on Hover"),
subtitle: _("Window focus follows the pointer"),
experimental: true,
settings,
bind: "focus-on-hover-enabled",
}),
new SwitchRow({
title: _("Move pointer with focused window"),
subtitle: _("Moves the pointer when focusing or swapping via keyboard"),
experimental: true,
settings,
bind: "move-pointer-focus-enabled",
}),
new SwitchRow({
title: _("Quarter tiling"),
subtitle: _("Places new windows in a clock-wise fashion"),
experimental: true,
settings,
bind: "auto-split-enabled",
}),
new SwitchRow({
title: _("Stacked tiling"),
subtitle: _("Stacks windows on top of each other while still tiling them"),
experimental: true,
settings,
bind: "stacked-tiling-mode-enabled",
}),
new SwitchRow({
title: _("Tabbed Tiling Mode"),
subtitle: _("Group tiles windows as tabs"),
title: _("Tabbed tiling"),
subtitle: _("Groups windows as tabs"),
experimental: true,
settings,
bind: "tabbed-tiling-mode-enabled",
}),
],
});
this.add_group({
title: _("Behavior"),
children: [
new SwitchRow({
title: _("Move Pointer with the Focus"),
subtitle: _("Move the pointer when focusing or swapping via keyboard"),
experimental: true,
title: _("Auto exit tabbed tiling"),
subtitle: _("Exit tabbed tiling mode when only a single tab remains"),
settings,
bind: "auto-exit-tabbed",
bind: "move-pointer-focus-enabled",
}),
],
});
this.add_group({
title: _("Tiling"),
children: [
new SwitchRow({
title: _("Preview Hint Toggle"),
experimental: true,
settings,
bind: "preview-hint-enabled",
}),
new SwitchRow({
title: _("Show Focus Hint Border"),
subtitle: _("Display a colored border around the focused window"),
settings,
bind: "focus-border-toggle",
}),
new SwitchRow({
title: _("Show Window Split Hint Border"),
subtitle: _("Show split direction border on focused window"),
settings,
bind: "split-border-toggle",
}),
new DropDownRow({
title: _("Default Drag-and-Drop Center Layout"),
title: _("Drag-and-drop behavior"),
subtitle: _("What to do when dragging one window on top of another"),
settings,
type: "s",
bind: "dnd-center-layout",
@ -120,35 +112,25 @@ export class SettingsPage extends PreferencesPage {
],
}),
new SwitchRow({
title: _("Auto Exit Tabbed Tiling Mode"),
subtitle: _("Exit tabbed tiling mode when only a single tab remains"),
settings,
bind: "auto-exit-tabbed",
}),
new SwitchRow({
title: _("Auto Split"),
subtitle: _("Quarter Tiling"),
experimental: true,
settings,
bind: "auto-split-enabled",
}),
new SwitchRow({
title: _("Float Mode Always On Top"),
subtitle: _("Floating windows always above tiling windows"),
title: _("Always on Top mode for floating windows"),
subtitle: _("Makes floating windows appear above tiled windows"),
experimental: true,
settings,
bind: "float-always-on-top-enabled",
}),
new SwitchRow({
title: _("Show Tiling Quick Settings"),
subtitle: _("Toggle showing Forge on quick settings"),
experimental: true,
],
});
this.add_group({
title: _("Non-tiling workspaces"),
description: _("Disables tiling on specified workspaces. Starts from 0, separated by commas"),
children: [
new EntryRow({
title: _("Example: 0,1,2"),
settings,
bind: "quick-settings-enabled",
bind: "workspace-skip-tile",
}),
],
});
if (!production) {
this.add_group({
title: _("Logger"),

View File

@ -218,7 +218,7 @@ export class ResetButton extends Gtk.Button {
constructor({ settings = undefined, bind = undefined, onReset }) {
super({
icon_name: "edit-clear-symbolic",
icon_name: "edit-undo-symbolic",
tooltip_text: _("Reset"),
valign: Gtk.Align.CENTER,
});

View File

@ -1,29 +0,0 @@
// Gnome imports
import GObject from "gi://GObject";
import { gettext as _ } from "resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js";
import { EntryRow, PreferencesPage } from "./widgets.js";
export class WorkspacePage extends PreferencesPage {
static {
GObject.registerClass(this);
}
constructor({ settings }) {
super({ title: _("Workspace"), icon_name: "shell-overview-symbolic" });
this.add_group({
title: _("Update Workspace Settings"),
description: _(
"Provide workspace indices to skip. E.g. 0,1. Empty text to disable. Enter to accept"
),
children: [
new EntryRow({
title: _("Skip Workspace Tiling"),
settings,
bind: "workspace-skip-tile",
}),
],
});
}
}

View File

@ -16,5 +16,5 @@
],
"url": "https://github.com/forge-ext/forge",
"uuid": "forge@jmmaranan.com",
"version": 84
}
"version": 88
}

View File

@ -24,7 +24,6 @@ import { ExtensionPreferences } from "resource:///org/gnome/Shell/Extensions/js/
import { KeyboardPage } from "./lib/prefs/keyboard.js";
import { AppearancePage } from "./lib/prefs/appearance.js";
import { WorkspacePage } from "./lib/prefs/workspace.js";
import { SettingsPage } from "./lib/prefs/settings.js";
export default class ForgeExtensionPreferences extends ExtensionPreferences {
@ -45,7 +44,6 @@ export default class ForgeExtensionPreferences extends ExtensionPreferences {
window._kbdSettings = this.kbdSettings;
window.add(new SettingsPage(this));
window.add(new AppearancePage(this));
window.add(new WorkspacePage(this));
window.add(new KeyboardPage(this));
window.search_enabled = true;
window.can_navigate_back = true;

View File

@ -123,6 +123,10 @@
<default>false</default>
<summary>Move the pointer when focusing or swapping via kbd</summary>
</key>
<key type="b" name="focus-on-hover-enabled">
<default>false</default>
<summary>Focus switches to the window under the pointer.</summary>
</key>
<key type="b" name="float-always-on-top-enabled">
<default>true</default>
<summary>Floating windows toggle always-on-top</summary>