mirror of
https://github.com/zoriya/fairy.git
synced 2025-12-06 05:36:09 +00:00
Add gaps
This commit is contained in:
@@ -11,7 +11,8 @@ const Indicator = Me.imports.sources.indicator;
|
||||
class Extension {
|
||||
constructor() {
|
||||
this._state = new State.StateManager();
|
||||
this._renderer = new Renderer.Renderer(this._state);
|
||||
this._settings = ExtensionUtils.getSettings("org.gnome.shell.extensions.fairy");
|
||||
this._renderer = new Renderer.Renderer(this._state, this._settings);
|
||||
this._keybinds = new Keybinds.KeyboardManager(this._state, this._renderer);
|
||||
this._indicator = new Indicator.Indicator(this._state, this._renderer);
|
||||
}
|
||||
|
||||
79
prefs.js
79
prefs.js
@@ -5,7 +5,7 @@ const { Adw, Gio, Gtk } = imports.gi;
|
||||
const ExtensionUtils = imports.misc.extensionUtils;
|
||||
const Me = ExtensionUtils.getCurrentExtension();
|
||||
|
||||
function init() { }
|
||||
function init() {}
|
||||
|
||||
function _createKeybind(settings, keybind) {
|
||||
// TODO: Set the title to the gsettings's title.
|
||||
@@ -16,7 +16,39 @@ function _createKeybind(settings, keybind) {
|
||||
// settings.bind(keybind, listener, );
|
||||
row.add_suffix(listener);
|
||||
row.activable_widget = listener;
|
||||
return row
|
||||
return row;
|
||||
}
|
||||
|
||||
function _createBool(settings, { title, key }) {
|
||||
const row = new Adw.ActionRow({ title: title });
|
||||
|
||||
const toggle = new Gtk.Switch({
|
||||
active: settings.get_boolean(key),
|
||||
valign: Gtk.Align.CENTER,
|
||||
});
|
||||
settings.bind(key, toggle, "active", Gio.SettingsBindFlags.DEFAULT);
|
||||
|
||||
row.add_suffix(toggle);
|
||||
row.activatable_widget = toggle;
|
||||
return row;
|
||||
}
|
||||
|
||||
function _createUint(settings, { title, key }) {
|
||||
const row = new Adw.ActionRow({ title: title });
|
||||
|
||||
const input = new Gtk.SpinButton({
|
||||
adjustment: new Gtk.Adjustment({
|
||||
lower: 0,
|
||||
upper: 100,
|
||||
step_increment: 1,
|
||||
value: settings.get_uint(key),
|
||||
}),
|
||||
});
|
||||
settings.bind(key, input, "value", Gio.SettingsBindFlags.DEFAULT);
|
||||
|
||||
row.add_suffix(input);
|
||||
row.activatable_widget = input;
|
||||
return row;
|
||||
}
|
||||
|
||||
function fillPreferencesWindow(window) {
|
||||
@@ -26,25 +58,36 @@ function fillPreferencesWindow(window) {
|
||||
|
||||
const page = new Adw.PreferencesPage();
|
||||
page.set_title("General");
|
||||
const group = new Adw.PreferencesGroup();
|
||||
page.add(group);
|
||||
|
||||
const row = new Adw.ActionRow({ title: "Show Layout Indicator" });
|
||||
group.add(row);
|
||||
|
||||
const toggle = new Gtk.Switch({
|
||||
active: settings.get_boolean("show-layout"),
|
||||
valign: Gtk.Align.CENTER,
|
||||
});
|
||||
settings.bind(
|
||||
"show-layout",
|
||||
toggle,
|
||||
"active",
|
||||
Gio.SettingsBindFlags.DEFAULT
|
||||
const general = new Adw.PreferencesGroup();
|
||||
page.add(general);
|
||||
general.add(
|
||||
_createBool(settings, {
|
||||
title: "Show Layout Indicator",
|
||||
key: "show-layout",
|
||||
})
|
||||
);
|
||||
|
||||
row.add_suffix(toggle);
|
||||
row.activatable_widget = toggle;
|
||||
const gaps = new Adw.PreferencesGroup();
|
||||
page.add(gaps);
|
||||
gaps.add(
|
||||
_createUint(settings, {
|
||||
title: "Gap size",
|
||||
key: "gap-size",
|
||||
})
|
||||
);
|
||||
gaps.add(
|
||||
_createUint(settings, {
|
||||
title: "Outer gap size",
|
||||
key: "outer-gap-size",
|
||||
})
|
||||
);
|
||||
gaps.add(
|
||||
_createBool(settings, {
|
||||
title: "Smart gaps",
|
||||
key: "smart-gaps",
|
||||
})
|
||||
);
|
||||
|
||||
const keybinds = new Adw.PreferencesPage();
|
||||
keybinds.set_title("Keybinds");
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<schemalist>
|
||||
<schema id="org.gnome.shell.extensions.fairy" path="/org/gnome/shell/extensions/fairy/">
|
||||
<!-- Behavior things -->
|
||||
<key type="s" name="default-layout">
|
||||
<default>'tiling'</default>
|
||||
<summary>Available: floating, tiling, monocle</summary>
|
||||
</key>
|
||||
|
||||
<!-- Visual things -->
|
||||
<key type="b" name="show-layout">
|
||||
<default>true</default>
|
||||
@@ -24,10 +18,15 @@
|
||||
</key>
|
||||
|
||||
<key type="u" name="gap-size">
|
||||
<default>4</default>
|
||||
<default>10</default>
|
||||
<summary> The size of the gap between windows in the workarea</summary>
|
||||
</key>
|
||||
|
||||
<key type="u" name="outer-gap-size">
|
||||
<default>20</default>
|
||||
<summary> The size of the gap between windows and the edge of the monitor</summary>
|
||||
</key>
|
||||
|
||||
<key type="b" name="smart-gaps">
|
||||
<default>true</default>
|
||||
<summary>True to hide gaps when there is a single window</summary>
|
||||
|
||||
@@ -10,9 +10,15 @@ const Me = ExtensionUtils.getCurrentExtension();
|
||||
|
||||
var Renderer = GObject.registerClass(
|
||||
class Renderer extends GObject.Object {
|
||||
_init(state) {
|
||||
_init(state, settings) {
|
||||
super._init();
|
||||
this._state = state;
|
||||
this._settings = settings;
|
||||
this.gaps = {
|
||||
smart: true,
|
||||
size: 10,
|
||||
outerGaps: 20,
|
||||
};
|
||||
log("fairy init!");
|
||||
}
|
||||
|
||||
@@ -23,6 +29,12 @@ var Renderer = GObject.registerClass(
|
||||
enable() {
|
||||
this._bindSignals();
|
||||
|
||||
this.gaps = {
|
||||
smart: this._settings.get_boolean("smart-gaps"),
|
||||
size: this._settings.get_uint("gap-size"),
|
||||
outerGaps: this._settings.get_uint("outer-gap-size"),
|
||||
};
|
||||
|
||||
for (const window of global.display.list_all_windows())
|
||||
this.trackWindow(window);
|
||||
|
||||
@@ -69,8 +81,7 @@ var Renderer = GObject.registerClass(
|
||||
// Wait until window actor is available
|
||||
let waitForWindowId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
|
||||
// Stop if the window doesn't exist anymore or the parent is gone
|
||||
if (!window.get_workspace())
|
||||
return GLib.SOURCE_REMOVE;
|
||||
if (!window.get_workspace()) return GLib.SOURCE_REMOVE;
|
||||
|
||||
// Continue if there's no actor available yet
|
||||
if (!windowActor) {
|
||||
@@ -116,6 +127,8 @@ var Renderer = GObject.registerClass(
|
||||
}
|
||||
}
|
||||
this._state.windows = [];
|
||||
|
||||
this._settings.disconnect("changed");
|
||||
}
|
||||
|
||||
_bindSignals() {
|
||||
@@ -123,7 +136,11 @@ var Renderer = GObject.registerClass(
|
||||
global.display.connect("window-created", (_display, window) =>
|
||||
this._waitForWindow(window, () => {
|
||||
this.trackWindow(window);
|
||||
this._state.focus(window);
|
||||
GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
|
||||
this._state.focus(window);
|
||||
// Do not retrigger this idle.
|
||||
return false;
|
||||
});
|
||||
this.renderForWindow(window);
|
||||
})
|
||||
),
|
||||
@@ -135,8 +152,8 @@ var Renderer = GObject.registerClass(
|
||||
global.workspace_manager.connect("active-workspace-changed", () => {
|
||||
// Convert gnome workspaces to fairy's tags
|
||||
const workspace = global.display
|
||||
.get_workspace_manager()
|
||||
.get_active_workspace_index();
|
||||
.get_workspace_manager()
|
||||
.get_active_workspace_index();
|
||||
const tags = 0b1 << workspace;
|
||||
log("Switch to tags", tags);
|
||||
if (Meta.prefs_get_workspaces_only_on_primary()) {
|
||||
@@ -150,6 +167,24 @@ var Renderer = GObject.registerClass(
|
||||
}
|
||||
}),
|
||||
];
|
||||
|
||||
this._settings.connect("changed", (_, key) => {
|
||||
log("Proprety changed", key);
|
||||
switch (key) {
|
||||
case "gap-size":
|
||||
this.gaps.size = this._settings.get_uint(key);
|
||||
this.renderAll();
|
||||
break;
|
||||
case "outer-gap-size":
|
||||
this.gaps.outerGaps = this._settings.get_uint(key);
|
||||
this.renderAll();
|
||||
break;
|
||||
case "smart-gaps":
|
||||
this.gaps.smart = this._settings.get_boolean(key);
|
||||
this.renderAll();
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -215,11 +250,11 @@ var Renderer = GObject.registerClass(
|
||||
|
||||
const tags = this._state.monitors[mon].tags;
|
||||
// This retrieve the lower tag present in the tags set.
|
||||
const tag = (tags & ~(tags - 1));
|
||||
const tag = tags & ~(tags - 1);
|
||||
if (tags !== tag) return;
|
||||
// Retrieve the gnome workspace for the tag (inverse of 0b1 << tag)
|
||||
const workspace = Math.log2(tag);
|
||||
console.log("Switching to", tags, tag, workspace)
|
||||
console.log("Switching to", tags, tag, workspace);
|
||||
|
||||
global.display
|
||||
.get_workspace_manager()
|
||||
@@ -255,10 +290,10 @@ var Renderer = GObject.registerClass(
|
||||
.get_workspace_manager()
|
||||
.get_active_workspace_index();
|
||||
|
||||
for (const window of this._state.render(mon, tags)) {
|
||||
const windows = this._state.render(mon, tags);
|
||||
for (const window of windows) {
|
||||
if (window.handle.get_monitor() !== mon)
|
||||
window.handle.move_to_monitor(mon);
|
||||
// if (!(window.tags & 0b1 << workIdx) || window.currentWorkspace !== workIdx) {
|
||||
if (window.handle.get_workspace().index() !== workIdx) {
|
||||
// The window is visible because another tag as been bringed
|
||||
// so we need to ask gnome to move windows (temporarly to the current workspace)
|
||||
@@ -282,35 +317,47 @@ var Renderer = GObject.registerClass(
|
||||
window.handle.maximize(Meta.MaximizeFlags.BOTH);
|
||||
// Do not resize if maximizing to keep the overview tiled.
|
||||
continue;
|
||||
}
|
||||
else window.handle.unmaximize(Meta.MaximizeFlags.BOTH);
|
||||
} else window.handle.unmaximize(Meta.MaximizeFlags.BOTH);
|
||||
}
|
||||
|
||||
// TODO: Add gaps
|
||||
log(
|
||||
"Rezing percent: ",
|
||||
window.x,
|
||||
window.y,
|
||||
window.width,
|
||||
window.height,
|
||||
"Real values",
|
||||
monGeo.x + (window.x * monGeo.width) / 100,
|
||||
monGeo.y + (window.y * monGeo.height) / 100,
|
||||
(window.width * monGeo.width) / 100,
|
||||
(window.height * monGeo.height) / 100
|
||||
);
|
||||
let size = {
|
||||
x: (window.x * monGeo.width) / 100,
|
||||
y: (window.y * monGeo.height) / 100,
|
||||
width: (window.width * monGeo.width) / 100,
|
||||
height: (window.height * monGeo.height) / 100,
|
||||
};
|
||||
|
||||
// let cmpWindow = window.handle.get_compositor_private();
|
||||
// cmpWindow.remove_all_transitions();
|
||||
if (this._state.monitors[mon].layout !== "monocle" && (windows.length > 1 || !this.gaps.smart))
|
||||
size = this.addGaps(size, monGeo);
|
||||
|
||||
window.handle.move_resize_frame(
|
||||
true,
|
||||
monGeo.x + (window.x * monGeo.width) / 100,
|
||||
monGeo.y + (window.y * monGeo.height) / 100,
|
||||
(window.width * monGeo.width) / 100,
|
||||
(window.height * monGeo.height) / 100
|
||||
monGeo.x + size.x,
|
||||
monGeo.y + size.y,
|
||||
size.width,
|
||||
size.height
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
addGaps(window, monGeo) {
|
||||
const gapSize = this.gaps.size;
|
||||
// Inner gaps are applied two times so to make outers the same visual size we 2x
|
||||
const outerGaps = this.gaps.outerGaps * 2;
|
||||
|
||||
return {
|
||||
...window,
|
||||
x: window.x === 0 ? outerGaps : window.x + gapSize,
|
||||
y: window.y === 0 ? outerGaps : window.y + gapSize,
|
||||
width:
|
||||
window.width -
|
||||
(window.x === 0 ? outerGaps : gapSize) -
|
||||
(window.x + window.width === monGeo.width ? outerGaps : gapSize),
|
||||
height:
|
||||
window.height -
|
||||
(window.y === 0 ? outerGaps : gapSize) -
|
||||
(window.y + window.height === monGeo.height ? outerGaps : gapSize),
|
||||
};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user