Add focus keybinds

This commit is contained in:
2023-05-13 18:10:35 +09:00
parent ff369047d0
commit 1848b3ec8e
6 changed files with 123 additions and 44 deletions
+1 -4
View File
@@ -1,10 +1,7 @@
const Gio = imports.gi.Gio;
const St = imports.gi.St;
"use strict";
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const State = Me.imports.sources.state;
const Renderer = Me.imports.sources.renderer;
+13 -5
View File
@@ -48,13 +48,21 @@ function fillPreferencesWindow(window) {
const keybinds = new Adw.PreferencesPage();
keybinds.set_title("Keybinds");
const layoutBindings = new Adw.PreferencesGroup();
keybinds.add(layoutBindings);
layoutBindings.add(_createKeybind(settings, "set-layout-tiling"));
layoutBindings.add(_createKeybind(settings, "set-layout-monocle"));
layoutBindings.add(_createKeybind(settings, "set-layout-floating"));
const focusBindings = new Adw.PreferencesGroup();
keybinds.add(focusBindings);
focusBindings.add(_createKeybind(settings, "cycle-next"));
focusBindings.add(_createKeybind(settings, "cycle-prev"));
focusBindings.add(_createKeybind(settings, "zoom"));
const tileBindings = new Adw.PreferencesGroup();
keybinds.add(tileBindings);
tileBindings.add(_createKeybind(settings, "set-layout-tiling"));
tileBindings.add(_createKeybind(settings, "set-layout-monocle"));
tileBindings.add(_createKeybind(settings, "set-layout-floating"));
tileBindings.add(_createKeybind(settings, "incrmfact"));
tileBindings.add(_createKeybind(settings, "decmfact"));
tileBindings.add(_createKeybind(settings, "incrnmaster"));
+8 -7
View File
@@ -1,9 +1,14 @@
"use strict";
const Gio = imports.gi.Gio;
const St = imports.gi.St;
const GObject = imports.gi.GObject;
const Main = imports.ui.main;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const PanelMenu = imports.ui.panelMenu;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
@@ -20,12 +25,9 @@ var Indicator = GObject.registerClass(
"org.gnome.shell.extensions.fairy"
);
let indicatorName = `${Me.metadata.name} Indicator`;
this._layoutIndicator = new PanelMenu.Button(0.0, indicatorName, false);
// Add an icon
let icon = new St.Icon({
const indicatorName = `${Me.metadata.name} Indicator`;
this._layoutIndicator = new PanelMenu.Button(0.0, indicatorName);
const icon = new St.Icon({
gicon: new Gio.ThemedIcon({ name: "face-laugh-symbolic" }),
style_class: "system-status-icon",
});
@@ -37,7 +39,6 @@ var Indicator = GObject.registerClass(
"visible",
Gio.SettingsBindFlags.DEFAULT
);
Main.panel.addToStatusArea(indicatorName, this._layoutIndicator);
}
+35 -9
View File
@@ -39,26 +39,48 @@ var KeyboardManager = GObject.registerClass(
Main.wm.removeKeybinding(key);
}
_switchLayout(mode) {
const mon = global.display.get_current_monitor();
const state = this._state.monitors[mon];
const currentLayout = state.layout;
if (state.layout === mode)
state.layout = state.oldLayout;
else
state.layout = mode;
state.oldLayout = currentLayout;
this._renderer.render(mon);
}
enable() {
this._addBinding("set-layout-tiling", () => {
this._addBinding("set-layout-tiling", () => this._switchLayout("tiling"));
this._addBinding("set-layout-monocle", () => this._switchLayout("monocle"));
this._addBinding("set-layout-floating", () => this._switchLayout("floating"));
this._addBinding("cycle-next", () => {
const mon = global.display.get_current_monitor();
const state = this._state.monitors[mon];
state.layout = "tiling";
this._renderer.render(mon);
const idx = this._state.workIndexByHandle(state.focused);
this._state.focus(this._state.workIndex(mon, state.tags, idx + 1));
});
this._addBinding("set-layout-monocle", () => {
this._addBinding("cycle-prev", () => {
const mon = global.display.get_current_monitor();
const state = this._state.monitors[mon];
state.layout = "monocle";
this._renderer.render(mon);
const idx = this._state.workIndexByHandle(state.focused);
this._state.focus(this._state.workIndex(mon, state.tags, idx - 1));
});
this._addBinding("set-layout-floating", () => {
this._addBinding("zoom", () => {
const mon = global.display.get_current_monitor();
const state = this._state.monitors[mon];
state.layout = "floating";
this._renderer.render(mon);
const idx = this._state.workIndexByHandle(state.focused);
if (this._state.workIndexByHandle(state.focused))
this._state.focus(this._state.workIndex(mon, state.tags, 0));
else
this.state.focus(state.beforeZoom);
state.beforeZoom = state.focused;
});
this._addBinding("incrmfact", () => {
const mon = global.display.get_current_monitor();
const state = this._state.monitors[mon];
@@ -90,6 +112,10 @@ var KeyboardManager = GObject.registerClass(
this._removeBinding("set-layout-monocle");
this._removeBinding("set-layout-floating");
this._removeBinding("cycle-next");
this._removeBinding("cycle-prev");
this._removeBinding("zoom");
this._removeBinding("incrmfact");
this._removeBinding("decrmfact");
this._removeBinding("incrnmaster");
+13 -11
View File
@@ -123,6 +123,7 @@ var Renderer = GObject.registerClass(
global.display.connect("window-created", (_display, window) =>
this._waitForWindow(window, () => {
this.trackWindow(window);
this._state.focus(window);
this.renderForWindow(window);
})
),
@@ -159,10 +160,18 @@ var Renderer = GObject.registerClass(
if (!this._isValidWindow(window)) return;
// Add window signals
window._signals = [
window.connect("unmanaging", (window) => {
window._isInvalid = true;
const faWindow = this._state.popByActor(actor);
if (faWindow) this.render(faWindow.monitor, faWindow.tags);
window.connect("unmanaging", (handle) => {
handle._isInvalid = true;
const idx = this._state.workIndexByHandle(handle);
const faWindow = this._state.popByHandle(handle);
if (!faWindow) return;
const tags = this._state.monitors[faWindow.monitor].tags;
// Since we retrieved the idx, the window as been removed so we don't need to +1.
const newWindow = this._state.workIndex(faWindow.monitor, tags, idx);
if (newWindow) this._state.focus(newWindow.handle);
this.render(faWindow.monitor, tags);
}),
window.connect("workspace-changed", (window) => {
if (!this._isValidWindow(window)) return;
@@ -175,13 +184,6 @@ var Renderer = GObject.registerClass(
this._state.monitors[window.get_monitor()].focused = window;
}),
];
const actor = window.get_compositor_private();
// actor._signals = [
// actor.connect("destroy", (actor) => {
// const faWindow = this._state.popByActor(actor);
// if (faWindow) this.render(faWindow.monitor, faWindow.tags);
// }),
// ];
this._state.newWindow(window);
}
+53 -8
View File
@@ -12,8 +12,13 @@ var StateManager = GObject.registerClass(
* @type {Meta.Window} focused window's handle
*/
focused: null,
/**
* @type {Meta.Window} window's handle that was focused just before a zoom
*/
beforeZoom: null,
tags: 1,
layout: "tiling",
oldLayout: "monocle",
nmaster: 1,
mfact: 55,
}));
@@ -46,8 +51,8 @@ var StateManager = GObject.registerClass(
* @param {Meta.Window} handle
*/
newWindow(handle) {
this.windows.push(this._windowFromHandle(handle));
log("New window on tag", this.windows[this.windows.length - 1].tags);
this.windows.unshift(this._windowFromHandle(handle));
log("New window on tag", this.windows[0].tags);
}
/**
@@ -61,13 +66,53 @@ var StateManager = GObject.registerClass(
return [old, this.windows[i]];
}
popByActor(actor) {
const window = this.windows.find((x) => x.actor === actor);
popByHandle(handle) {
const window = this.windows.find((x) => x.handle === handle);
if (!window) return null;
this.windows = this.windows.filter((x) => x !== window);
return window;
}
/**
* @param {number} mon
* @param {number} tags
* @param {number} idx (will loop if over/under flow)
* @returns {FairyWindow}
*/
workIndex(mon, tags, idx) {
const windows = this.windows.filter(
(x) => x.monitor === mon && x.tags & tags
);
if (idx < 0) idx = windows.length + idx;
return windows[idx % windows.length];
}
/**
* @param {Meta.Window} handle
* @returns {number} idx
*/
workIndexByHandle(handle) {
const window = this.windows.find((x) => x.handle === handle);
const windows = this.windows.filter(
(x) => x.monitor === window.monitor && x.tags & window.tags
);
return windows.findIndex((x) => x.handle === handle);
}
/**
* @param {Meta.Window} handle
* @param {boolean} internalOnly
*/
focus(handle, internalOnly = false) {
const mon = handle.get_monitor();
this.monitors[mon].focused = handle;
// This was focused without a zoom, removing the old zoom value.
this.monitors[mon].beforeZoom = null;
if (!internalOnly)
handle.focus(global.display.get_current_time());
}
/**
* @param {number} mon
* @param {number} tags
@@ -116,14 +161,14 @@ var StateManager = GObject.registerClass(
handle: x.handle,
maximized: false,
minimized: false,
x: (i < nmaster || nmaster <= 0) ? 0 : mfact,
x: i < nmaster || nmaster <= 0 ? 0 : mfact,
y: stackIndex * (100 / stackLength),
width:
(windows.length <= nmaster || nmaster <= 0)
windows.length <= nmaster || nmaster <= 0
? 100
: i < nmaster
? mfact
: 100 - mfact,
? mfact
: 100 - mfact,
height: 100 / stackLength,
};
});