Commit Graph
6 Commits
Author SHA1 Message Date
gitops 08028e6f2c Add a power menu, so a session can be left without rebooting
The hyprcosmic profile disables cosmic-panel, and COSMIC's power applet lives
in that panel. Nothing replaced it, so the session had no logout, reboot or
shutdown anywhere in it: the only way out was `systemctl reboot` typed into a
terminal, which also meant every login-time change cost a reboot to test.

hyprcosmic-powermenu is a rofi menu offering lock, suspend, log out, reboot and
shut down. It is reached two ways -- $mainMod SHIFT E and a button at the right
end of waybar -- and both run the same script, so a click cannot bypass the
confirmation a keypress gets.

Logging out calls com.system76.CosmicSession.Exit, which is the method the
panel applet used and the only one that stops the session's clients in order
rather than pulling the compositor out from under them. Reboot and poweroff go
straight to systemd; polkit already authorises both for an active local session
without a prompt, verified with pkcheck, so no pkexec is involved. Lock uses
loginctl, which cosmic-greeter is listening for.

Confirmation is asked only for the three that end the session. Lock and suspend
undo themselves with a keypress, so a prompt there is pure friction; the other
three throw away everything unsaved and are one keystroke away at all times.
"No" is listed first so it is the row already selected.

The menu entries are plain words rather than Nerd Font glyphs. The bar icon is
the only glyph involved, and it comes through generate-config.py, whose whole
purpose is that no Private Use Area character is ever typed by hand -- U+F011,
confirmed present in the installed JetBrainsMono Nerd Font.

rules.css names every module id explicitly, so #custom-power had to be added
there too or the button would have rendered with no pill behind it.

The script sits under config/bin/ rather than a new top-level directory so that
install-assets.sh's audit still covers it: that check refuses to run unless
every file under config/ is classified, which is what stops a new file from
being silently left uninstalled.
2026-08-10 15:35:45 +07:00
gitops 178dfbec1a Expose preserve_split, and turn it on
`general.preserve_split` maps straight to the compositor key Patch C adds,
so opening a third window gives three panes in a row instead of quadrants.

Every other key under `general` exists upstream; this one is the fork's
own field on `CosmicCompConfig`. If a rebase ever loses that field the
compositor would ignore the key without saying anything, so the target is
pinned in a test of its own rather than left to the generic registry
checks.
2026-08-10 14:53:27 +07:00
gitops 563fdc7330 Turn autotile on, which is what makes placement automatic
COSMIC ships autotile off, so every new window opened floating at whatever
size the application asked for, on top of whatever you were looking at. The
key already existed in cosmic-conf's registry and had simply never been set.

Gaps come with it. They are invisible until windows tile -- with nothing being
laid out, nothing has a gap -- so setting one without the other is half a
change. gaps_out is doubled so the screen edge reads as margin rather than as
one more seam.

autotile_behavior is deliberately not a conf key. It defaults to Global, which
retiles workspaces that already exist rather than only arming new ones, and
that is the value worth having; anyone who wants PerWorkspace can set it in
cosmic-settings without this file overwriting them.
2026-08-10 14:31:21 +07:00
gitops b8b5ce546d Check the IPC from outside, and write down the input bug we did not solve
tools/verify-hypr-ipc.py exercises the fork's Hyprland IPC the way a client
reaches it, which the compositor's own log cannot show you. It checks the
socket names, that the five read commands answer JSON, that `bogus`,
`dispatch exec rofi`, `dispatch killactive`, `dispatch workspace +1` and
`dispatch workspace 0` are all refused, and that a real switch returns `ok`.
It moves the focused workspace, so it returns to the one you started on.

It is a validated negative test, not a hopeful one: run against the old
compositor before the socket rename was installed, it failed on the names and
exited 1.

docs/unreproducible-dead-input-2026-08-10.md records the session that came up
with no keyboard or pointer at all, and did not come back after a reboot. It
is closed deliberately rather than fixed, and most of its value is the list of
things it is not -- the fork's patches, `seats.for_device()` returning None,
the modifier-only Super binding, a shortcuts-config race, and two scary log
lines that stock COSMIC prints too. The one suspicious fact is that it was the
fourth compositor start on that boot. If it recurs, there is a list of what to
collect before rebooting destroys it.

The design spec said `.socket` and `.socket2`; corrected to the names clients
actually open.

cosmic.conf's bare-Super binding gets a comment saying why the key field is
empty, since an empty field in a `bind` line reads like a typo. COSMIC
supports modifier-only bindings and Hyprland's `bind` cannot express one.
2026-08-10 12:59:04 +07:00
gitops a32596216a import-theme: say when the file it wrote is inert
Keeping the imported theme in its own file, sourced from cosmic.conf, is what
stops a re-import from clobbering the keybindings. But a sourced file only
does anything if something sources it, and until now `import-theme --out`
reported "Wrote ..." whether or not anything did -- which looks like success
while the desktop stays exactly as it was.

It now checks the sibling cosmic.conf and prints the line to add when the file
is unreachable. The match is by filename and deliberately loose: it is looking
for evidence the user already knows about the file, not parsing the config.

The shipped template carries that `source` line commented out rather than
live, because `source` naming a file that does not exist is a hard error, and
a fresh checkout has no theme.conf yet. Copying the template and running
`apply` has to work before any theme is imported.
2026-08-10 09:16:04 +07:00
gitops 19927bc00b cosmic-conf: translate Hyprland bind lines into COSMIC shortcuts
`bind = SUPER, D, exec, rofi -show drun` is the most recognisable line in a
hyprland.conf, and the hyprcosmic profile makes it necessary rather than just
idiomatic: with cosmic-launcher and cosmic-app-library not running, COSMIC's
stock Super, Super+/ and Super+A bindings point at nothing.

Binds are the one repeatable key in the language -- many lines fold into a
single map instead of the last one winning -- so they bypass the schema, which
is built around one conf key naming one value. They land in the Shortcuts
`custom` key, which cosmic-comp merges over `defaults`, so the system file is
untouched and reverting means deleting the lines and re-applying.

Actions are rendered as RON text rather than modelled as an enum: COSMIC's
Action has forty-odd variants, this crate deliberately does not link the cosmic
crates, and the mapping table only ever needs a handful. Dispatchers without a
genuine equivalent are refused rather than approximated, since a keybinding
that silently does the wrong thing is worse than one that fails to compile.

Verified the emitted file deserializes into cosmic-settings-config's own
`Shortcuts` type: five bindings, keysyms XK_a/XK_slash/XK_Return, Spawn actions.
2026-08-10 08:51:16 +07:00