mirror of
https://github.com/outbackdingo/hyprcosmic-session.git
synced 2026-08-25 14:53:23 +00:00
73867a5d6a31560507ad86a6fb9ab4d929c21258
13
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
73867a5d6a |
Install as the session, at upstream's paths
Eight files: upstream's six, where upstream puts them, plus this fork's start-hyprcosmic and hyprcosmic.desktop. Replaces the private libexec prefix, matching the same change in cosmic-comp. A machine that installs this gets its cosmic-session from here, so there is nothing else on disk to provide the systemd target, the mimeapps list or the dconf profile. Omitting them produced a session that started and then had no user target for the portals to attach to, which surfaces much later and much less clearly than a missing file. Both session entries are installed and both are served by these binaries. Replacing COSMIC need not mean removing its shell, and keeping cosmic.desktop costs one file while preserving the one property worth keeping from the beside-install layout: if the HyDE shell will not start, there is still something on the greeter's menu that will. start-hyprcosmic now names /usr/bin for both binaries, still through overridable variables so the check below it can say which path was missing and so the session still runs out of a build tree. The dconf asymmetry is deliberate and now asserted in CI, because it is easy to get backwards once both scripts are installed: start-cosmic is sed'd to an absolute profile path, as upstream does; start-hyprcosmic is not, because it searches /etc/dconf/profile and XDG_DATA_DIRS at runtime and pinning a build prefix would break an administrator's override. |
||
|
|
8ff1e72d3e |
test: follow the autostart template off its author's home directory, and let CI compile
The template it parses stopped naming /home/dingo, so the two assertions that
named it had to move with it: the bar is now an `sh -c` invocation rather than a
bare waybar, and the wallpaper path is $HOME. The wallpaper assertion keeps the
surrounding double quotes in the expected string deliberately -- dropping them
is what would split the path at a space in someone's home directory, which is
the failure the test exists to catch.
Adds a ratchet: no line in the shipped autostart may contain "/home/". Both
lines carried an author's home directory right up until the repository was about
to be published, which is a bad moment to find out.
CI is fixed at the same time, because it could never have run these two tests.
They read ../config/autostart through include_str!, so the crate does not
compile its own test profile unless the parent repository is its parent
directory -- and a workflow checkout puts this repository at the workspace root,
alone. Confirmed by building a standalone export of HEAD:
error: couldn't read `.../standalone/../config/autostart`: No such file
error: could not compile `cosmic-session` (bin "cosmic-session" test)
So the job now checks the parent out first and this repository over the top of
where its submodule sits, which is the layout the working tree already has. The
coupling is worth keeping: the point of those tests is that the template this
session actually ships still parses to the commands it documents, and a copy
vendored in here to make the build self-contained would be a copy that goes
stale without anyone noticing.
The three dependency-install steps override working-directory back to the
workspace root, since they run before the checkout that creates the directory
the job otherwise defaults to, and a run step whose working-directory does not
exist fails before it runs anything.
|
||
|
|
03cd10c0d9 |
ci: build on three distros, and assert the four dangerous files stay unwritten
Upstream ships no workflows here, so nothing is displaced; the file is named hyprcosmic.yml anyway, to match the compositor fork where ci.yml is already upstream's. A lighter matrix than the compositor's, because this crate has no system libraries to find -- what actually varies per distribution is the toolchain and `just`. Rust comes from rustup for the same reason as in cosmic-comp: bookworm ships rustc 1.63 against a crate that needs 1.93 and edition 2024. `just` comes from the distribution on Fedora and Arch and from crates.io on Debian, which has no such package until trixie. The assertions are the reason this exists. Until recently `just install` wrote /usr/bin/cosmic-session, cosmic.desktop, the systemd target and the mimeapps list -- all files the distribution's own cosmic-session package owns. Anyone who cloned this repository and ran the documented build command replaced their working COSMIC session with this one, and had nothing left to log into when the fork failed to start. The negative tests are the important half: it is the files that must NOT appear that made the old recipe dangerous, and a `test ! -e` is the only thing that will notice if one of them comes back. The session scripts are checked off the matrix, on a bare runner. Shell does not vary by distribution, and doing it there avoids naming the shellcheck package in three package managers to check the same file three times. Both scripts are parsed, because a syntax error in either is a black screen at login with nowhere to print the reason. Only start-hyprcosmic is linted: start-cosmic is upstream's, this fork no longer installs it, and its existing findings are not ours to rewrite. |
||
|
|
b22fe1687d |
Install the fork's own three files, not upstream's seven
`just install` still wrote the stock session: /usr/bin/cosmic-session, the cosmic.desktop entry, the systemd target, the mimeapps list and the dconf profile. Every one of those is a file the distro's cosmic-session package already owns, so running it replaced a working COSMIC install with this fork and left no session to log into if the fork failed to start. What HyprCosmic has actually been installing, by hand, is three files; this teaches the recipe that. The binary moves to $prefix/libexec/hyprcosmic for the reason the compositor did in Patch D: the stock session has to keep working, because it is what you use to fix this one. cosmic.desktop is replaced by hyprcosmic.desktop, which adds a second entry to the greeter's menu rather than overwriting the first. The four dropped files are not things this fork changes, and a HyprCosmic session needs stock COSMIC present anyway -- the greeter, the portals and the settings daemon all come from it -- so reading that package's copies costs nothing and avoids a packaging conflict over files we have no opinion about. Upstream's `sed` over DCONF_PROFILE is deliberately not carried across. start-hyprcosmic searches /etc/dconf/profile and then XDG_DATA_DIRS and exports the bare profile name only if it finds one; rewriting a prefix into it would pin one location and defeat an administrator's /etc override. The script already explains this at the point where it does the search. Verified by staging into a rootdir: all three files come out byte-identical to the copies currently installed on this machine, and install-assets.sh --check still reports all 9 managed files matching. |
||
|
|
e6f8d560ab |
Re-exec through the login shell, so the session sees /etc/profile
The greeter starts this script with what pam and systemd put in the environment and nothing else. start-cosmic re-execs itself through $SHELL to pick up /etc/profile and the user's login files; not doing the same here is why the two sessions disagreed about the environment. Measured here, the difference is XDG_DATA_DIRS: empty without this, and with it the two flatpak exports directories that hold the .desktop files and icons the launcher reads. PATH is unchanged either way -- /etc/profile only appends what is missing. Differs from upstream in two ways. The recursion guard is an exported variable rather than a positional --in-login-shell flag, because a flag has to survive being quoted through another shell to be seen on the way back in, and if it ever failed to, the login would hang instead of failing; an exported variable survives exec by definition. And it uses bash's own `exec -l` rather than an extra `bash -c` hop, since this script is already bash. First in the file, deliberately: the login files may set XDG_CACHE_HOME, which is where the log goes, so this happens while there is nothing to lose. Verified the log still rotates exactly once per login. see: https://github.com/pop-os/cosmic-session/issues/23 |
||
|
|
f8fec1360b |
Export the toolkit hints and the dconf profile
The toolkit variables are the generic Wayland session contract, not anything COSMIC-specific: Firefox on Wayland instead of XWayland, Qt preferring the Wayland platform plugin with an xcb fallback, and Java AWT told not to expect a reparenting window manager, without which Swing windows come up blank or mispositioned. Leaving them out is why Qt and Java applications behaved differently under HyprCosmic than under the stock session on the same machine. They are set with `:-` like the XDG lines above rather than assigned outright, so a value already chosen in the environment survives. The Qt platform theme stays pointed at CuteCosmic rather than being switched to qt5ct the way HyDE would have it. This fork themes GTK, waybar and rofi and has no Qt pipeline at all, so handing Qt applications to qt5ct would hand them to a configuration nothing here writes; CuteCosmic at least follows the COSMIC palette that cosmic.conf does drive. Worth revisiting if Qt theming ever gets built. DCONF_PROFILE is guarded, which start-cosmic's is not. Naming a profile dconf cannot find is not a soft failure: it logs "using null configuration" and from then on every GSettings read returns schema defaults while writes go nowhere, so a desktop's worth of settings simply appears blank. Measured on this machine -- `DCONF_PROFILE=cosmic` dumps 33 keys, a name that does not resolve dumps zero. So the profile is looked for first and the variable is only exported once found. The bare name is used rather than an absolute path. start-cosmic gets its prefix rewritten in at install time by the Justfile, which pins one prefix; dconf searches /etc/dconf/profile first and XDG_DATA_DIRS after, so the bare name finds the packaged profile under /usr/share while still letting an administrator override it from /etc. DCONF_PROFILE joins SSH_AUTH_SOCK in the systemd and D-Bus activation environments, matching what start-cosmic imports. |
||
|
|
bdff38edac |
Start gnome-keyring, so the session has an ssh-agent
PAM starts the daemon at login but brings up only its `control` socket. Nothing else brought up the rest, so a HyprCosmic session had no agent at all: SSH_AUTH_SOCK unset, every SSH operation asking for the passphrase again, and callers of the secrets API finding nothing listening. Under the stock COSMIC session the same machine works, which makes it look like a key problem rather than a session-script omission. `--start` attaches to the daemon that is already running and brings up the missing components; on this machine that created `pkcs11` and `ssh` alongside the existing `control`. Where the socket path comes from is the part worth writing down. start-cosmic evals the daemon's stdout, but the eval is `eval "$(... > /dev/null 2>&1)"` -- the redirect is inside the substitution, so it always evaluates the empty string, and the block works only because of the socket checks after it. Rather than repair that by evaluating whatever a daemon writes to stdout, this reads out the single variable we want and keeps the fixed paths as the fallback. The daemon also writes chatter to stderr, so the 2>/dev/null is load-bearing for the parse rather than tidiness. start-cosmic's rule is kept intact: set the correct socket or set none at all, never a wrong one. A plain file sitting where the socket belongs is rejected by the `-S` test, and a machine with no keyring directory skips the block entirely. SSH_AUTH_SOCK then joins the systemd and D-Bus activation environments for the same reason XDG_CURRENT_DESKTOP did: a user unit or an activated app looks there, not in this script's environment. `import-environment` ignores an unset name and exits 0, so a machine without a keyring still logs in. |
||
|
|
22e894330e |
Hand the session's identity to systemd --user, so portals work
Pressing PrtScr said "COSMIC screenshot crashed". cosmic-screenshot was aborting on an unwrap, because org.freedesktop.portal.Screenshot had no implementation behind it. start-hyprcosmic exported XDG_CURRENT_DESKTOP=COSMIC, and the compositor had it. But an export only reaches processes started by this script, and the portal is not one of them: xdg-desktop-portal is launched by `systemd --user`, which is older than the session and carries its own environment block. Its copy had XDG_SESSION_TYPE and nothing else. xdg-desktop-portal chooses a backend by matching the `UseIn=` line of /usr/share/xdg-desktop-portal/portals/*.portal against XDG_CURRENT_DESKTOP. Unset, `UseIn=COSMIC` never matched, no backend loaded, and the Screenshot interface was never exported. Nothing anywhere logged a missing portal. The crash was the only symptom, and it pointed at the screenshot tool. `systemctl --user import-environment` fixes it, which is what start-cosmic has always done and this script had not. Ordering works out: the portal unit is `After=` and `Requisite=graphical-session.target`, which cosmic-session brings up later, so it cannot start ahead of the import. dbus-update-activation-environment as well, for any backend whose .service file has no `SystemdService=` line -- but only when a bus already exists, since in the dbus-run-session branch the bus is created after this point. Everything is `||:`. Losing a portal is bad; refusing to log in is worse. Verified by clearing all three variables out of the user manager, running the script's environment block, restarting xdg-desktop-portal, and watching the Screenshot interface come back and cosmic-screenshot exit 0 with a real PNG. |
||
|
|
6400f64791 |
Point the autostart test at the wallpaper symlink
config/autostart now sets the wallpaper through the `current` symlink that `cosmic-conf import-theme --assets` maintains, rather than naming a file inside the theme directory. The test still asserted the old path and failed. The hazard it was written for is gone with it: the path no longer contains a space, because it no longer contains a theme name. That case is still covered on synthetic input by quotes_hold_arguments_containing_spaces_together, so this one now asserts what actually matters here -- that the script arrives as a single argument, that it names the link rather than one of the copies beside it, and that it waits for the daemon before setting an image. 11 profile tests pass. |
||
|
|
c67cb01f2d |
Backport the session log block from the installed copy
/usr/bin/start-hyprcosmic gained this during the blank-screen debugging and the versioned copy never did, so the next install from this repository would have silently removed it. Found by diffing the two while writing an installer; the installer's --check exists so that the next one is not found by hunch. What it does, unchanged from the copy that has been running: redirect the session's own output to ~/.cache/hyprcosmic/session.log. A session that fails drops you at the greeter taking its stderr with it, and by then the journal cannot be read from inside a session that no longer exists. A plain redirect rather than tee into a process substitution -- tee would be a child the session writes through, so its death would deliver SIGPIPE, and nothing about diagnostics should be able to kill the desktop. Every step is guarded, so a failure here starts the session with no log rather than refusing to log in. The previous log is kept as .1 so a second attempt does not erase the evidence from the first. |
||
|
|
04b61b49df |
Test that the shipped autostart parses to what it documents
The template is mostly prose, and `#` starts a comment wherever a word would start -- so a comment marker landing in the wrong column drops a command silently rather than failing. Parsing the real file in a test means editing the explanatory text around a command cannot quietly disable it. Tests only; no behaviour change, so the installed session binary is unaffected. |
||
|
|
1c3e3c3e53 |
Give profile extras real argv, and point the session entry at the fork
Two defects in the previous commit, both of which would have failed silently at the greeter rather than loudly at build time. `start_component` passes its whole string to `Process::with_executable`, which treats it as the program name. An autostart line like `waybar -c <path>` was therefore looked up as a binary literally called "waybar -c <path>", and the bar would simply never appear. The unit test asserting that "rofi -show drun" parses as one entry implied arguments worked; they did not. Extras are now split into argv and spawned through a `start_process` helper, which is upstream's `start_component` body with args threaded through -- `start_component` keeps its signature so no upstream call site changes. The splitter honours quoting, because config paths contain spaces, and treats `#` as a comment only where a word would start, so `--color=#1a1b26` survives. It expands nothing else: no variables, globs or command substitution, so a file that names programs cannot be escalated into running arbitrary shell. `start-hyprcosmic` also defaulted HYPRCOSMIC_SESSION_BIN to /usr/bin/cosmic-session -- the stock binary, which has no profile module. The session would have come up as ordinary COSMIC with the gating apparently doing nothing. It now points at /usr/libexec/hyprcosmic, so the fork installs alongside the packaged COSMIC instead of over it, a dnf update cannot clobber it, and the stock entry stays as the escape hatch. It fails loudly with a pointer back to that entry if the binary is missing. Verified: 9 unit tests, including a regression test for the argv defect and one asserting nothing is expanded; `cargo build -j1` clean. |
||
|
|
80958c24da |
Add session profiles so HyprCosmic can replace the COSMIC shell
Upstream hardcodes the set of cosmic-* components a session launches. HyprCosmic needs cosmic-comp for window management but waybar and rofi in place of cosmic-panel and cosmic-launcher, so `profile` gates that set. The default profile is upstream behaviour exactly, and it is what an unconfigured build gets; the alternate set is opt-in through HYPRCOSMIC_PROFILE, which only the new session entry sets. So installing this fork cannot change how the stock session boots, and a broken HyprCosmic config is always one logout away from being escaped. Gating lives at the single definition of `start_component` rather than at its call sites, keeping the diff against upstream small enough to rebase against a fast-moving tree. cosmic-panel and cosmic-notifications are the exception: they are started as a coupled pair sharing notification fds and cannot go through that path, so they are gated where they are spawned (hence the re-indentation in the diff). cosmic-greeter is deliberately never disabled - a display manager is the easiest thing to lock yourself out of. cosmic-osd and cosmic-idle stay too, since HyDE's equivalents are separate programs a user may not have and neither competes with waybar for layer-shell space. Verified: 5 unit tests over profile selection and extras parsing; `cargo check -j1` and `cargo build -j1` clean. NOT verified: the gating has never been observed at runtime. Two attempts to run this session nested inside the live desktop logged the developer out instead, so runtime confirmation is deferred to logging into the hyprcosmic.desktop entry from the greeter. Two hazards found along the way and worth recording: name-matching (pkill/pgrep) cannot distinguish this fork's processes from the live session's, and a nested cosmic-session steals the well-known D-Bus name com.system76.CosmicSession from the running session unless it is given a private bus. |