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>
64 lines
2.6 KiB
Markdown
64 lines
2.6 KiB
Markdown
# 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.mainloop` for timers
|
|
- **No npm, no bundler, no transpiler** — plain ES6 classes work; `import`/`export` do not
|
|
|
|
## How to test changes
|
|
|
|
1. Copy changed files into the installed location:
|
|
```bash
|
|
cp ctile@ctile/* ~/.local/share/cinnamon/extensions/ctile@ctile/
|
|
```
|
|
2. Reload the extension without restarting Cinnamon:
|
|
```bash
|
|
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");'
|
|
```
|
|
3. Check logs: `grep '\[ctile\]' ~/.xsession-errors`
|
|
|
|
Syntax-check JS before deploying:
|
|
```bash
|
|
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_Y` px below the monitor's top edge
|
|
- Stay visible while pointer is within 20 px of the overlay's bounding box
|
|
- Hide otherwise
|