Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,4 @@ debian/*
!debian/*install
.confirm_shortcut_change
.vscode
node_modules
tsconfig.tsbuildinfo
node_modules
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ sources = src/*.ts *.css
all: depcheck compile

clean:
rm -rf _build target tsconfig.tsbuildinfo
rm -rf _build target

# Configure local settings on system
configure:
Expand Down
5 changes: 1 addition & 4 deletions metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@
"uuid": "pop-shell@system76.com",
"settings-schema": "org.gnome.shell.extensions.pop-shell",
"shell-version": [
"45",
"46",
"47",
"48",
"49",
"50"
"48"
]
}
48 changes: 39 additions & 9 deletions src/auto_tiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,43 @@ export class AutoTiler {
this.attached = attached;
}

private sync_smart_gapped(ext: Ext, fork: Fork) {
let toplevel = fork;
let parent = this.forest.parents.get(toplevel.entity);

/* Walk upwards to get the actual top-level root from the fork. */
while (parent) {
const next = this.forest.forks.get(parent);
if (!next)
break;

toplevel = next;
parent = this.forest.parents.get(toplevel.entity);
}

const smart_gapped = (
toplevel.is_toplevel &&
toplevel.smart_gapped &&
toplevel.right === null
);

/* Set smart_gapped for each window. */
for (const branch of this.forest.iter(toplevel.entity)) {
let entities: Entity[] = [];

if (branch.inner.kind === NodeKind.WINDOW)
entities = [branch.inner.entity];
else if (branch.inner.kind === NodeKind.STACK)
entities = branch.inner.entities;

for (const entity of entities) {
const win = ext.windows.get(entity);
if (win)
win.smart_gapped = smart_gapped;
}
}
}

/** Swap window associations in the auto-tiler
*
* Call this when a window has swapped positions with another, so that we
Expand Down Expand Up @@ -106,13 +143,6 @@ export class AutoTiler {
rect.height -= ext.gap_outer * 2;
}

if (fork.left.inner.kind === 2) {
const win = ext.windows.get(fork.left.inner.entity);
if (win) {
win.smart_gapped = fork.smart_gapped;
}
}

fork.area = fork.set_area(rect.clone());
fork.length_left = Math.round(fork.prev_ratio * fork.length());
this.tile(ext, fork, fork.area);
Expand All @@ -132,7 +162,6 @@ export class AutoTiler {
const [entity, fork] = this.forest.create_toplevel(win.entity, rect.clone(), workspace_id);
this.forest.on_attach(entity, win.entity);
fork.smart_gapped = smart_gaps;
win.smart_gapped = smart_gaps;

this.tile(ext, fork, rect);
}
Expand Down Expand Up @@ -490,6 +519,7 @@ export class AutoTiler {
}

tile(ext: Ext, fork: Fork, area: Rectangle) {
this.sync_smart_gapped(ext, fork);
this.forest.tile(ext, fork, area);
}

Expand Down Expand Up @@ -700,7 +730,7 @@ export class AutoTiler {
}

private toggle_orientation_(ext: Ext, focused: ShellWindow): Result<void, string> {
if (focused.is_maximized()) {
if (focused.meta.get_maximized()) {
return Err('cannot toggle maximized window');
}

Expand Down
2 changes: 1 addition & 1 deletion src/color_dialog/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"target": "es2015",
"strict": true,
"outDir": "../../target/color_dialog",
"rootDir": "./src",
"forceConsistentCasingInFileNames": true,
"downlevelIteration": true,
"lib": ["es2015"],
"pretty": true,
"removeComments": true,
Expand Down
4 changes: 4 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ export const DEFAULT_FLOAT_RULES: Array<FloatRule> = [
{ class: 'zoom' },
{ class: '^.*action=join.*$' },
{ class: 'gjs' },
{ class: 'io.github.bugaevc.wl-clipboard' },
{ class: 'org.gnome.NautilusPreviewer' },
];

export interface WindowRule {
Expand All @@ -77,6 +79,8 @@ export const SKIPTASKBAR_EXCEPTIONS: Array<WindowRule> = [
{ class: 'Guake' },
{ class: 'Com.github.amezin.ddterm' },
{ class: 'plank' },
{ class: 'io.github.bugaevc.wl-clipboard' },
{ class: 'org.gnome.NautilusPreviewer' },
];

export interface FloatRule {
Expand Down
34 changes: 13 additions & 21 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,6 @@ import Gio from 'gi://Gio';
import St from 'gi://St';
import Shell from 'gi://Shell';
import Meta from 'gi://Meta';
// Try to import Mtk for newer GNOME versions, fallback to Meta for older versions
let Mtk: any;
try {
Mtk = imports.gi.Mtk;
} catch (e) {
Mtk = null;
}
const { GlobalEvent, WindowEvent } = Events;
const { cursor_rect, is_keyboard_op, is_resize_op, is_move_op } = Lib;
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
Expand Down Expand Up @@ -487,7 +480,7 @@ export class Ext extends Ecs.System<ExtEvent> {
if (old) {
try {
GLib.source_remove(old);
} catch (_) { }
} catch (_) {}
}

const new_s = GLib.timeout_add(GLib.PRIORITY_LOW, 500, () => {
Expand Down Expand Up @@ -1265,7 +1258,7 @@ export class Ext extends Ecs.System<ExtEvent> {

this.register(Events.window_move(this, win, rect));
} else {
win.move(this, rect, () => { });
win.move(this, rect, () => {});
// if the resulting dimensions of rect == next
if (rect.width == next_area.width && rect.height == next_area.height) {
win.meta.maximize(Meta.MaximizeFlags.BOTH);
Expand Down Expand Up @@ -1488,7 +1481,7 @@ export class Ext extends Ecs.System<ExtEvent> {

[area, monitor_attachment] =
(win.stack === null && attach_to.stack === null && is_sibling) ||
(win.stack === null && is_sibling)
(win.stack === null && is_sibling)
? [fork.area, false]
: [attach_to.meta.get_frame_rect(), false];
} else {
Expand Down Expand Up @@ -1519,8 +1512,8 @@ export class Ext extends Ecs.System<ExtEvent> {
? [area.x, area.y, half_width, area.height]
: [area.x + half_width, area.y, half_width, area.height]
: swap
? [area.x, area.y, area.width, half_height]
: [area.x, area.y + half_height, area.width, half_height];
? [area.x, area.y, area.width, half_height]
: [area.x, area.y + half_height, area.width, half_height];

this.overlay.x = new_area[0];
this.overlay.y = new_area[1];
Expand Down Expand Up @@ -1549,8 +1542,8 @@ export class Ext extends Ecs.System<ExtEvent> {
this.current_style = this.settings.is_dark()
? Style.Dark
: this.settings.is_high_contrast()
? Style.HighContrast
: Style.Light;
? Style.HighContrast
: Style.Light;
}

/** Handle window maximization notifications */
Expand Down Expand Up @@ -2299,7 +2292,7 @@ export class Ext extends Ecs.System<ExtEvent> {
this.moved_by_mouse = false;
}

update_display_configuration_before() { }
update_display_configuration_before() {}

update_display_configuration(workareas_only: boolean) {
if (!this.auto_tiler || sessionMode.isLocked) return;
Expand Down Expand Up @@ -2630,10 +2623,7 @@ export class Ext extends Ecs.System<ExtEvent> {

cursor_status(): [Rectangle, number] {
const cursor = cursor_rect();
// Use Mtk.Rectangle if available (newer GNOME), otherwise fallback to Meta.Rectangle
const rect = Mtk ?
new Mtk.Rectangle({ x: cursor.x, y: cursor.y, width: 1, height: 1 }) :
new Meta.Rectangle({ x: cursor.x, y: cursor.y, width: 1, height: 1 });
const rect = new Meta.Rectangle({ x: cursor.x, y: cursor.y, width: 1, height: 1 });
const monitor = display.get_monitor_index_for_rect(rect);
return [cursor, monitor];
}
Expand Down Expand Up @@ -2675,12 +2665,12 @@ let ext: Ext | null = null;
let indicator: Indicator | null = null;

declare global {
var popShellExtension: any;
var popShellExtension: any;
}

export default class PopShellExtension extends Extension {
enable() {
globalThis.popShellExtension = this;
globalThis.popShellExtension = this;
log.info('enable');

if (!ext) {
Expand Down Expand Up @@ -2715,6 +2705,7 @@ export default class PopShellExtension extends Extension {
}

ext.keybindings.enable(ext.keybindings.global).enable(ext.keybindings.window_focus);
ext.tiler.enable_keybindings(ext);

if (ext.settings.tile_by_default()) {
ext.auto_tile_on();
Expand All @@ -2740,6 +2731,7 @@ export default class PopShellExtension extends Extension {
layoutManager.removeChrome(ext.overlay);

ext.keybindings.disable(ext.keybindings.global).disable(ext.keybindings.window_focus);
ext.tiler.disable_keybindings(ext);

if (ext.auto_tiler) {
ext.auto_tiler.destroy(ext);
Expand Down
2 changes: 1 addition & 1 deletion src/floating_exceptions/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Gtk from 'gi://Gtk?version=3.0';
import Pango from 'gi://Pango';

/** The directory that this script is executed from. */
const SCRIPT_DIR = GLib.path_get_dirname(new Error().stack!.split(':')[0].slice(1));
const SCRIPT_DIR = GLib.path_get_dirname(new Error().stack.split(':')[0].slice(1));

/** Add our directory so we can import modules from it. */
imports.searchPath.push(SCRIPT_DIR);
Expand Down
2 changes: 1 addition & 1 deletion src/floating_exceptions/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"target": "es2015",
// "strict": true,
"outDir": "../../target/floating_exceptions",
"rootDir": "./src",
"forceConsistentCasingInFileNames": true,
"downlevelIteration": true,
"lib": ["es2015"],
"pretty": true,
"removeComments": true,
Expand Down
26 changes: 24 additions & 2 deletions src/keybindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export class Keybindings {
global: Object;
window_focus: Object;

private active: Set<string> = new Set();

private ext: Ext;

constructor(ext: Ext) {
Expand Down Expand Up @@ -62,23 +64,43 @@ export class Keybindings {
};
}

enable(keybindings: any) {
enable(keybindings: any, modes: number = Shell.ActionMode.NORMAL) {
for (const name in keybindings) {
if (this.active.has(name)) {
wm.allowKeybinding(name, modes);
continue;
}

wm.addKeybinding(
name,
this.ext.settings.ext,
Meta.KeyBindingFlags.NONE,
Shell.ActionMode.NORMAL,
modes,
keybindings[name],
);

this.active.add(name);
}

return this;
}

disable(keybindings: Object) {
for (const name in keybindings) {
if (!this.active.has(name))
continue;

wm.removeKeybinding(name);
this.active.delete(name);
}

return this;
}

allow(keybindings: Object, modes: number) {
for (const name in keybindings) {
if (this.active.has(name))
wm.allowKeybinding(name, modes);
}

return this;
Expand Down
3 changes: 1 addition & 2 deletions src/mod.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,6 @@ declare namespace Meta {
minimized: Readonly<boolean>;
window_type: Readonly<any>;
decorated: Readonly<boolean>;
maximized_horizontally: Readonly<boolean>;
maximized_vertically: Readonly<boolean>;

activate(time: number): void;
change_workspace_by_index(workspace: number, append: boolean): void;
Expand All @@ -286,6 +284,7 @@ declare namespace Meta {
get_display(): Meta.Display | null;
get_description(): string;
get_frame_rect(): Rectangular;
get_maximized(): number;
get_monitor(): number;
get_pid(): number;
get_role(): null | string;
Expand Down
10 changes: 8 additions & 2 deletions src/stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,14 @@ const TabButton = GObject.registerClass(
}),
);

close_button.connect('clicked', () => {
window.meta.delete(global.get_current_time());
this._running_close = false;

close_button.connect('clicked', () => {
if (!this._running_close) {
this._running_close = true;
window.meta.delete(global.get_current_time());
this._running_close = false;
}
});

close_button.set_x_align(Clutter.ActorAlign.END);
Expand Down
Loading