Add settings schema for edge trigger options in CTile extension

This commit is contained in:
prairienerd18
2026-04-06 20:34:04 -05:00
parent 10fcf99adf
commit 3d6111f785
2 changed files with 94 additions and 9 deletions

View File

@@ -6,6 +6,7 @@
const { Clutter, St, Meta, GLib, Gtk, Gio } = imports.gi; const { Clutter, St, Meta, GLib, Gtk, Gio } = imports.gi;
const Main = imports.ui.main; const Main = imports.ui.main;
const Mainloop = imports.mainloop; const Mainloop = imports.mainloop;
const Settings = imports.ui.settings;
// ─── tunables ──────────────────────────────────────────────────────────────── // ─── tunables ────────────────────────────────────────────────────────────────
const TRIGGER_Y = 50; // px from screen top that activates the overlay const TRIGGER_Y = 50; // px from screen top that activates the overlay
@@ -176,6 +177,7 @@ class TileOverlay {
this._buttons = []; this._buttons = [];
this._visible = false; this._visible = false;
this._currentMonIdx = -1; this._currentMonIdx = -1;
this._currentEdge = null;
} }
_build() { _build() {
@@ -211,12 +213,13 @@ class TileOverlay {
log('overlay built and added to stage'); log('overlay built and added to stage');
} }
show(monitorIndex) { show(monitorIndex, edge) {
this._build(); this._build();
// Re-show on new monitor; guard same-monitor repeated calls // Re-show on new monitor/edge; guard same-monitor+edge repeated calls
if (this._visible && this._currentMonIdx === monitorIndex) return; if (this._visible && this._currentMonIdx === monitorIndex && this._currentEdge === edge) return;
this._currentMonIdx = monitorIndex; this._currentMonIdx = monitorIndex;
this._currentEdge = edge;
this._visible = true; this._visible = true;
const mon = global.display.get_monitor_geometry(monitorIndex); const mon = global.display.get_monitor_geometry(monitorIndex);
@@ -230,11 +233,23 @@ class TileOverlay {
Mainloop.idle_add(() => { Mainloop.idle_add(() => {
if (!this._actor) return GLib.SOURCE_REMOVE; if (!this._actor) return GLib.SOURCE_REMOVE;
const aw = this._actor.width; const aw = this._actor.width;
const ah = this._actor.height; // eslint-disable-line no-unused-vars const ah = this._actor.height;
const ax = mon.x + Math.round((mon.width - aw) / 2); let ax, ay;
const ay = mon.y + 10; if (edge === 'bottom') {
ax = mon.x + Math.round((mon.width - aw) / 2);
ay = mon.y + mon.height - ah - 10;
} else if (edge === 'left') {
ax = mon.x + 10;
ay = mon.y + Math.round((mon.height - ah) / 2);
} else if (edge === 'right') {
ax = mon.x + mon.width - aw - 10;
ay = mon.y + Math.round((mon.height - ah) / 2);
} else { // 'top' (default)
ax = mon.x + Math.round((mon.width - aw) / 2);
ay = mon.y + 10;
}
this._actor.set_position(ax, ay); this._actor.set_position(ax, ay);
log(`overlay shown at ${ax},${ay} size=${aw}x${ah} monitor=${monitorIndex}`); log(`overlay shown at ${ax},${ay} size=${aw}x${ah} monitor=${monitorIndex} edge=${edge}`);
this._actor.ease({ this._actor.ease({
opacity : 255, opacity : 255,
duration : SHOW_ANIM_MS, duration : SHOW_ANIM_MS,
@@ -249,6 +264,7 @@ class TileOverlay {
this._clearHover(); this._clearHover();
this._visible = false; this._visible = false;
this._currentMonIdx = -1; this._currentMonIdx = -1;
this._currentEdge = null;
log('overlay hiding'); log('overlay hiding');
this._actor.ease({ this._actor.ease({
@@ -326,6 +342,12 @@ class CTileExtension {
this._gtkThemeChangedId = null; this._gtkThemeChangedId = null;
this._muffinSettings = null; this._muffinSettings = null;
this._savedEdgeTiling = null; this._savedEdgeTiling = null;
this._settings = null;
// trigger-edge flags (kept in sync with settings)
this._triggerTop = true;
this._triggerBottom = false;
this._triggerLeft = false;
this._triggerRight = false;
} }
enable() { enable() {
@@ -342,6 +364,21 @@ class CTileExtension {
this._savedEdgeTiling = null; this._savedEdgeTiling = null;
} }
// Load per-extension settings
try {
this._settings = new Settings.ExtensionSettings(this, 'ctile@ctile');
this._settings.bindProperty(Settings.BindingDirection.IN,
'trigger-top', '_triggerTop', null, null);
this._settings.bindProperty(Settings.BindingDirection.IN,
'trigger-bottom', '_triggerBottom', null, null);
this._settings.bindProperty(Settings.BindingDirection.IN,
'trigger-left', '_triggerLeft', null, null);
this._settings.bindProperty(Settings.BindingDirection.IN,
'trigger-right', '_triggerRight', null, null);
} catch(e) {
log(`could not load settings: ${e}`);
}
this._overlay = new TileOverlay(); this._overlay = new TileOverlay();
this._grabBeginId = global.display.connect( this._grabBeginId = global.display.connect(
@@ -377,6 +414,11 @@ class CTileExtension {
this._muffinSettings = null; this._muffinSettings = null;
this._savedEdgeTiling = null; this._savedEdgeTiling = null;
if (this._settings) {
this._settings.finalize();
this._settings = null;
}
this._stopPoll(); this._stopPoll();
if (this._grabBeginId) { if (this._grabBeginId) {
global.display.disconnect(this._grabBeginId); global.display.disconnect(this._grabBeginId);
@@ -452,10 +494,17 @@ class CTileExtension {
const [px, py] = global.get_pointer(); const [px, py] = global.get_pointer();
const monIdx = getMonitorForPointer(px, py); const monIdx = getMonitorForPointer(px, py);
const monGeo = global.display.get_monitor_geometry(monIdx); const monGeo = global.display.get_monitor_geometry(monIdx);
const relX = px - monGeo.x;
const relY = py - monGeo.y; const relY = py - monGeo.y;
if (relY <= TRIGGER_Y) { let triggerEdge = null;
this._overlay.show(monIdx); if (this._triggerTop && relY <= TRIGGER_Y) triggerEdge = 'top';
else if (this._triggerBottom && relY >= monGeo.height - TRIGGER_Y) triggerEdge = 'bottom';
else if (this._triggerLeft && relX <= TRIGGER_Y) triggerEdge = 'left';
else if (this._triggerRight && relX >= monGeo.width - TRIGGER_Y) triggerEdge = 'right';
if (triggerEdge) {
this._overlay.show(monIdx, triggerEdge);
this._grabbedLayout = this._overlay.updatePointer(px, py); this._grabbedLayout = this._overlay.updatePointer(px, py);
} else if (this._overlay.visible) { } else if (this._overlay.visible) {
if (this._overlay.isNearPointer(px, py, 20)) { if (this._overlay.isNearPointer(px, py, 20)) {

36
settings-schema.json Normal file
View File

@@ -0,0 +1,36 @@
{
"layout": {
"type": "layout",
"pages": ["trigger-edges"],
"trigger-edges": {
"type": "page",
"title": "Trigger Edges",
"sections": ["edges-section"]
},
"edges-section": {
"type": "section",
"title": "Show overlay when dragging to edge",
"keys": ["trigger-top", "trigger-bottom", "trigger-left", "trigger-right"]
}
},
"trigger-top": {
"type": "checkbox",
"default": true,
"description": "Top edge"
},
"trigger-bottom": {
"type": "checkbox",
"default": false,
"description": "Bottom edge"
},
"trigger-left": {
"type": "checkbox",
"default": false,
"description": "Left edge"
},
"trigger-right": {
"type": "checkbox",
"default": false,
"description": "Right edge"
}
}