mirror of
https://github.com/zoriya/fairy.git
synced 2026-06-04 19:26:33 +00:00
Add focus keybinds
This commit is contained in:
+1
-4
@@ -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;
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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,
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user