Snap layout overlay for Cinnamon 6.6. Drag a window to the top edge to reveal a picker with 14 tiling presets (halves, quarters, thirds). Layout previews use the system theme's accent color and update live when the theme changes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2.6 KiB
Agent guidance for CTile
What this project is
A Cinnamon desktop extension (JavaScript, GJS runtime). There is no build step — files are loaded directly by Cinnamon's JS interpreter.
Repository layout
ctile/
extension.js ← all logic; entry points are init(), enable(), disable()
metadata.json ← UUID, display name, supported Cinnamon versions
stylesheet.css ← St/CSS styles for the overlay and buttons
README.md
AGENTS.md
Install by copying the whole directory to ~/.local/share/cinnamon/extensions/ctile@ctile/.
Runtime environment
- Engine: GJS (GNOME JavaScript, SpiderMonkey-based)
- Cinnamon version: 6.6.7 · Muffin version: 6.6.3
- Imports:
imports.gi.*for GObject introspection bindings;imports.ui.*for Cinnamon shell modules;imports.mainloopfor timers - No npm, no bundler, no transpiler — plain ES6 classes work;
import/exportdo not
How to test changes
- Copy changed files into the installed location:
cp ctile@ctile/* ~/.local/share/cinnamon/extensions/ctile@ctile/ - Reload the extension without restarting Cinnamon:
dbus-send --session --dest=org.Cinnamon /org/Cinnamon org.Cinnamon.Eval \ string:'const es = imports.ui.extensionSystem; es.disableExtension("ctile@ctile"); es.enableExtension("ctile@ctile");' - Check logs:
grep '\[ctile\]' ~/.xsession-errors
Syntax-check JS before deploying:
node --check ctile@ctile/extension.js
Key implementation details
Signal arity (important gotcha)
Muffin 6.6 fires grab-op-begin with four arguments: (display, screen, window, op).
Older Muffin versions used three. Getting this wrong silently breaks everything — the op check never matches and no drag is detected.
Overlay z-ordering
The overlay actor is added to global.stage (not Main.uiGroup) and raised to the top sibling on each show, so it appears above panels and all windows.
Accent color
Read at build time via Gtk.Button().get_style_context().lookup_color('accent_color') and refreshed on both St.ThemeContext 'changed' and Gtk.Settings 'notify::gtk-theme-name' signals.
Pointer tracking during drag
Muffin consumes pointer events during a window drag, so overlay buttons are reactive: false. Hover state is computed manually in a Mainloop.timeout_add poll loop (every 40 ms) by comparing raw pointer coordinates against each button's transformed bounding box.
Overlay visibility logic
- Show when pointer Y ≤
TRIGGER_Ypx below the monitor's top edge - Stay visible while pointer is within 20 px of the overlay's bounding box
- Hide otherwise