diff --git a/.github/workflows/packages.yml b/.github/workflows/packages.yml index bd5ac15..91b8845 100644 --- a/.github/workflows/packages.yml +++ b/.github/workflows/packages.yml @@ -229,26 +229,126 @@ jobs: - name: Stage the install run: just install "$PWD/stage" /usr - # The staged tree is what all three packages wrap, so it is worth failing - # here rather than shipping a package that is missing the compositor. The - # negative assertion is the one that would rot quietly: nothing may return - # to the private libexec layout this fork used to install into, because a - # copy there is a second compositor that nothing runs and no uninstall - # removes. - - name: Assert the staged tree is a complete desktop + # The three binaries this fork actually changes, under their own names. + # + # Done on every distribution, because start-hyprcosmic and the session + # entry name these paths and there is no reason for those to differ per + # distribution. cosmic-session takes the compositor as argv[1], so the + # pair is arranged in start-hyprcosmic and needs no source change. + - name: Give this fork's binaries their own names run: | set -eux - test -x stage/usr/bin/cosmic-comp - test -x stage/usr/bin/cosmic-session - test -x stage/usr/bin/cosmic-conf + mv stage/usr/bin/cosmic-comp stage/usr/bin/hyprcosmic-comp + mv stage/usr/bin/cosmic-session stage/usr/bin/hyprcosmic-session + mv stage/usr/bin/cosmic-conf stage/usr/bin/hyprcosmic-conf + + # The stock session entry goes with it, on Debian only. + # + # start-cosmic execs /usr/bin/cosmic-session, which the rename above just + # took away, so cosmic.desktop would sit on the greeter's menu and die + # silently when chosen. Everywhere else the reduction below removes both + # and the distribution's own cosmic-session package supplies a working + # pair; on Debian there is no such package, so they are removed here and + # the greeter offers the HyprCosmic entry alone. + - name: Drop the stock session entry it can no longer start + if: matrix.distro == 'debian' + run: | + set -eux + rm -f stage/usr/bin/start-cosmic + rm -f stage/usr/share/wayland-sessions/cosmic.desktop + + # HyprCosmic installs beside COSMIC rather than over it, and this is the + # step that makes that true. + # + # `just install` stages the whole desktop, because it builds the whole + # tree. Nearly all of it is byte-identical to what the distribution + # already ships, and the parts that are not are file conflicts that stop + # the install outright -- 62 of them on a stock Fedora COSMIC, across 25 + # packages, which rpm reports only in the transaction check, long after + # dnf's dependency solving has said the transaction is fine. + # + # The alternative to reducing the tree is to claim all 25 packages with + # Conflicts, which means erasing them to install this, which on Fedora + # includes cosmic-greeter -- the display manager. A fork you can only try + # by removing the desktop you would fall back to is a fork with no way + # back. So everything the distribution already owns is dropped, and the + # package depends on the distribution's COSMIC for it. + # + # Not on Debian, which has no COSMIC to depend on: neither cosmic-session + # nor cosmic-comp is packaged there, in any suite. Reducing the tree there + # would produce a package whose dependency can never be satisfied, so the + # Debian build keeps the whole desktop it just compiled and stands alone. + # Revisit when Debian packages COSMIC. + - name: Reduce the staged tree to this fork's own files + if: matrix.distro != 'debian' + run: | + set -eux + # /usr/share/cosmic goes too, all of it. Those are the defaults the + # compositor reads at first run, and this fork carries upstream's + # copies unmodified -- every one of them is byte-identical to a file a + # distribution package already owns. rpm permits two packages to own + # an identical file, so keeping them would install today and then + # collide the first time the distribution changed one. They arrive + # with the cosmic-comp this package depends on. + ( cd stage && find . \( -type f -o -type l \) -printf '%P\n' ) | + while read -r p; do + case $p in + usr/bin/hyprcosmic-*|usr/bin/start-hyprcosmic) continue ;; + usr/share/hyprcosmic/*) continue ;; + usr/share/wayland-sessions/hyprcosmic.desktop) continue ;; + esac + rm -f "stage/$p" + done + find stage -type d -empty -delete + + # Worth failing here rather than shipping a package that is missing the + # compositor. The negative assertions are the ones that would rot quietly: + # nothing may return to the private libexec layout this fork used to + # install into, and no cosmic-* name may come back, because either one is + # a file conflict that only shows up on a machine that has COSMIC + # installed -- which is every machine this is meant for. + - name: Assert the staged tree is this fork and nothing else + if: matrix.distro != 'debian' + run: | + set -eux + test -x stage/usr/bin/hyprcosmic-comp + test -x stage/usr/bin/hyprcosmic-session + test -x stage/usr/bin/hyprcosmic-conf test -x stage/usr/bin/start-hyprcosmic - test -x stage/usr/bin/start-cosmic test -f stage/usr/share/wayland-sessions/hyprcosmic.desktop - test -f stage/usr/share/wayland-sessions/cosmic.desktop - test -f stage/usr/lib/systemd/user/cosmic-session.target - test -f stage/usr/share/cosmic/com.system76.CosmicSettings.Shortcuts/v1/defaults test -d stage/usr/share/hyprcosmic test ! -e stage/usr/libexec/hyprcosmic + test ! -e stage/usr/bin/cosmic-comp + test ! -e stage/usr/bin/cosmic-session + test ! -e stage/usr/share/wayland-sessions/cosmic.desktop + test ! -e stage/usr/share/cosmic + test -z "$(find stage/usr/bin -mindepth 1 ! -name 'hyprcosmic-*' ! -name 'start-hyprcosmic')" + echo "staged files: $(find stage -type f | wc -l)" + + # Debian is not reduced, so the assertion is the opposite one: the package + # stands alone there and has to carry a desktop that starts. The renamed + # three must be present under their new names, and the components the + # session launches must still be in the tree rather than assumed to arrive + # from a distribution package that does not exist. + - name: Assert the staged tree is a complete desktop + if: matrix.distro == 'debian' + run: | + set -eux + test -x stage/usr/bin/hyprcosmic-comp + test -x stage/usr/bin/hyprcosmic-session + test -x stage/usr/bin/hyprcosmic-conf + test -x stage/usr/bin/start-hyprcosmic + test -f stage/usr/share/wayland-sessions/hyprcosmic.desktop + test -d stage/usr/share/hyprcosmic + test -d stage/usr/share/cosmic + test ! -e stage/usr/libexec/hyprcosmic + test ! -e stage/usr/bin/cosmic-comp + test ! -e stage/usr/bin/cosmic-session + test ! -e stage/usr/bin/start-cosmic + test ! -e stage/usr/share/wayland-sessions/cosmic.desktop + for c in cosmic-settings cosmic-settings-daemon cosmic-osd cosmic-notifications; do + test -x "stage/usr/bin/$c" || { echo "missing $c" >&2; exit 1; } + done echo "staged files: $(find stage -type f | wc -l)" # Checked here, once, rather than in each of the three packaging recipes, diff --git a/README.md b/README.md index 0e28f09..5f32498 100644 --- a/README.md +++ b/README.md @@ -18,12 +18,13 @@ Three things distinguish a HyprCosmic session from a COSMIC one: - **HyDE's shell.** waybar instead of cosmic-panel, rofi instead of cosmic-launcher, `awww` instead of cosmic-bg. HyDE themes are imported directly, palette and wallpapers and all. -- **It replaces COSMIC rather than sitting next to it.** The binaries install as - `/usr/bin/cosmic-comp` and `/usr/bin/cosmic-session`, the paths a cosmic-comp - and a cosmic-session go to, and the packages conflict with the distribution's - accordingly. Both session entries are installed, so the greeter still offers a - stock COSMIC shell for the day the HyDE one does not start — now served by - these binaries rather than by a second copy on disk. +- **It installs next to COSMIC rather than over it.** The binaries are + `/usr/bin/hyprcosmic-comp`, `/usr/bin/hyprcosmic-session` and + `/usr/bin/hyprcosmic-conf`, and nothing here writes a path the distribution + owns. The stock COSMIC entry stays on the greeter's menu, served by the + distribution's own binaries, so the day the HyDE session does not start is one + logout away from a desktop that does. (On Debian, where COSMIC is not + packaged, the `.deb` carries the desktop itself — see [Installing](#installing).) ## Repository layout @@ -54,8 +55,9 @@ current. deliberately small: `dispatch exec` and `dispatch killactive` are rejected, because this is the surface any process that can open the socket gets. - New windows open *beside* the focused window rather than inside it. -- The install goes to `/usr/bin/cosmic-comp`, at upstream's paths and alongside - upstream's two `.ron` defaults files, which are carried unmodified. +- The install goes to `/usr/bin/hyprcosmic-comp`, alongside upstream's two + `.ron` defaults files, which are carried unmodified. The distribution's + `cosmic-comp` is left where it is, for the stock session to keep using. **cosmic-session** — profiles. `HYPRCOSMIC_PROFILE=hyprcosmic` (set by `hyprcosmic.desktop`) skips cosmic-panel, cosmic-launcher, cosmic-app-library, @@ -93,14 +95,24 @@ sudo pacman -U ./hyprcosmic-*.pkg.tar.zst # Arch sudo dpkg -i ./hyprcosmic_*_amd64.deb # Debian ``` -Expect this to fail the first time, and read what it says when it does. These -packages provide `/usr/bin/cosmic-comp` and `/usr/bin/cosmic-session`, so they -**conflict with the distribution's `cosmic-comp` and `cosmic-session`** and your -package manager will refuse until those are removed. That refusal is the design: -installing HyprCosmic replaces the machine's desktop, and it should take a -deliberate `dnf remove cosmic-comp cosmic-session` to say so rather than a -resolver deciding on your behalf. Both session entries survive the swap, so the -greeter still offers a stock COSMIC shell afterwards. +Nothing is removed and nothing conflicts. COSMIC is a dependency rather than a +casualty: the package installs `hyprcosmic-comp`, `hyprcosmic-session` and +`hyprcosmic-conf` beside the distribution's, and takes cosmic-settings, the +portal, the OSD and the rest from the distribution at the version it tested +them at. Log out and pick **HyprCosmic** from the greeter; pick **COSMIC** to go +back. + +An earlier revision did take the `cosmic-*` names, and it could not be +installed. Its files collided with 25 distribution packages, and the only way to +satisfy that was to erase them — including cosmic-greeter, which on a Fedora +COSMIC install *is* the display manager. A desktop you can only try by removing +the desktop you would fall back to is not one worth shipping. + +**Debian is the exception**, because COSMIC is not packaged there — no +`cosmic-session`, no `cosmic-comp`, in any suite. There is nothing to depend on +and nothing to install beside, so the `.deb` carries the whole desktop it +compiled and stands alone, and the greeter offers **HyprCosmic** only. The +Fedora and Arch packages ship this fork's three binaries and nothing else. Building it yourself instead: @@ -125,6 +137,13 @@ This installs all of COSMIC — the 27 unmodified components as well — plus `cosmic-conf` at `$prefix/bin/cosmic-conf`, the shared waybar and rofi assets under `$prefix/share/hyprcosmic/`, and `hyprcosmic-powermenu`. +Note that `just install` is not what the packages do. It writes upstream's whole +desktop at upstream's names, so run against `/usr` on a machine that has COSMIC +packaged it will overwrite files your package manager owns. The packages are +built from this same tree and then reduced to this fork's own files and renamed; +that step lives in `.github/workflows/packages.yml`, not in the justfile, which +is upstream's. Stage to a directory and inspect it, or install a package. + `install` depends on `build`, which is upstream's arrangement and means `sudo just install` compiles as root. That is inherited, not chosen; if you would rather not, build into a staging root as your own user and copy it into place. @@ -161,9 +180,9 @@ Font for the bar's glyphs. `cosmic-config` by: ```shell -cosmic-conf apply # once -cosmic-conf apply --diff # show what would change, write nothing -cosmic-conf watch # recompile on every edit, for the whole session +hyprcosmic-conf apply # once +hyprcosmic-conf apply --diff # show what would change, write nothing +hyprcosmic-conf watch # recompile on every edit, for the whole session ``` `watch` is the first line of the shipped `autostart`, which is what makes "the @@ -208,7 +227,7 @@ the reference for what is supported. ## Theming ```shell -cosmic-conf import-theme ~/.config/hyde/themes/'Tokyo Night'/hypr.theme \ +hyprcosmic-conf import-theme ~/.config/hyde/themes/'Tokyo Night'/hypr.theme \ --out ~/.config/hyprcosmic/theme.conf --report --assets ``` diff --git a/config/autostart b/config/autostart index ebe82d2..ca3737e 100644 --- a/config/autostart +++ b/config/autostart @@ -23,7 +23,7 @@ # A malformed edit is not fatal. It is reported to the session log and the last # good configuration stays in place, so a typo cannot leave you at a broken # desktop -- fix the file and the next save applies. -cosmic-conf watch +hyprcosmic-conf watch # The bar. The layout is shared and lives under /usr/share, but the stylesheet # has to be per-user: it imports a sibling theme.css holding the installed HyDE diff --git a/cosmic-conf/src/assets.rs b/cosmic-conf/src/assets.rs index 613f522..ca8f20f 100644 --- a/cosmic-conf/src/assets.rs +++ b/cosmic-conf/src/assets.rs @@ -630,7 +630,7 @@ fn render_local_rasi(icon_theme: Option<&str>, wallpaper_link: Option<&Path>) -> let mut out = String::from( r#"/* Per-machine launcher settings for HyprCosmic. * - * Generated by `cosmic-conf import-theme --assets`. It is the last of the four + * Generated by `hyprcosmic-conf import-theme --assets`. It is the last of the four * imports in config.rasi, so anything here wins; it is also overwritten by the * next import run with --overwrite, so keep hand edits somewhere else. * diff --git a/cosmic-conf/src/import.rs b/cosmic-conf/src/import.rs index 9214d11..ee7c5e8 100644 --- a/cosmic-conf/src/import.rs +++ b/cosmic-conf/src/import.rs @@ -272,9 +272,9 @@ fn render_conf( notes: &[Note], ) -> String { let mut out = format!( - "# Generated by `cosmic-conf import-theme` from the HyDE theme {theme_name:?}.\n\ + "# Generated by `hyprcosmic-conf import-theme` from the HyDE theme {theme_name:?}.\n\ # Edit freely — this file is the source of truth; cosmic-settings changes\n\ - # are overwritten on the next `cosmic-conf apply`.\n" + # are overwritten on the next `hyprcosmic-conf apply`.\n" ); let dropped: Vec<&Note> = notes diff --git a/cosmic-conf/src/main.rs b/cosmic-conf/src/main.rs index dc4c2b4..fc53046 100644 --- a/cosmic-conf/src/main.rs +++ b/cosmic-conf/src/main.rs @@ -7,14 +7,18 @@ use std::process::ExitCode; use cosmic_conf::{assets, emit::Emitter, import, render_diagnostic, watch}; +// Names the installed binary, hyprcosmic-conf, not the crate. The package +// installs beside COSMIC and keeps every path it owns under a hyprcosmic-* +// name, so a usage line saying `cosmic-conf` would name something that is not +// on the system. const USAGE: &str = "\ -cosmic-conf — compile cosmic.conf into the cosmic-config tree +hyprcosmic-conf — compile cosmic.conf into the cosmic-config tree USAGE: - cosmic-conf apply [--diff] [--config ] - cosmic-conf watch [--config ] - cosmic-conf import-theme [--out ] [--report] - [--assets [--source ] [--overwrite] [--dry-run]] + hyprcosmic-conf apply [--diff] [--config ] + hyprcosmic-conf watch [--config ] + hyprcosmic-conf import-theme [--out ] [--report] + [--assets [--source ] [--overwrite] [--dry-run]] COMMANDS: apply Compile the config once and exit diff --git a/cosmic-conf/src/workspace.rs b/cosmic-conf/src/workspace.rs index 99cf0bd..ad52ab1 100644 --- a/cosmic-conf/src/workspace.rs +++ b/cosmic-conf/src/workspace.rs @@ -26,7 +26,7 @@ //! when you use it, which is Hyprland's behaviour rather than a compromise. //! 3. **It lands at the next login, not on apply.** `Workspaces::new` reads the //! key once when the compositor starts and there is no reload path for it, -//! while `cosmic-conf watch` is started from the autostart file *after* +//! while `hyprcosmic-conf watch` is started from the autostart file *after* //! COSMIC's own components. So an edit is written immediately and takes //! effect the next time the session starts. Every other key in cosmic.conf //! is live, so this one is worth saying out loud. @@ -450,7 +450,7 @@ mod tests { assert!(render(&[ws("1")], false).contains(r#"output: (name: "", edid: None)"#)); } - /// Ids have to survive a re-apply, or every `cosmic-conf apply` would hand + /// Ids have to survive a re-apply, or every `hyprcosmic-conf apply` would hand /// the same workspaces new identities. #[test] fn ids_are_stable_across_runs_and_unique_per_index() { diff --git a/cosmic-session b/cosmic-session index 73867a5..d65baf6 160000 --- a/cosmic-session +++ b/cosmic-session @@ -1 +1 @@ -Subproject commit 73867a5d6a31560507ad86a6fb9ab4d929c21258 +Subproject commit d65baf688c0bdf21d0c3f9831b87eca037daee66 diff --git a/packaging/arch/PKGBUILD b/packaging/arch/PKGBUILD index a20378c..7d70ca3 100644 --- a/packaging/arch/PKGBUILD +++ b/packaging/arch/PKGBUILD @@ -19,10 +19,14 @@ arch=('x86_64') url="https://github.com/outbackdingo/hyprcosmic" license=('GPL-3.0-only') -# The HyDE shell. Without these the session starts to a blank screen: no bar, -# no launcher, no wallpaper. -depends=('waybar' 'rofi-wayland' 'wayland' 'libxkbcommon' 'libinput' 'seatd' - 'mesa' 'pixman' 'libdisplay-info' 'systemd-libs') +# cosmic-session is COSMIC itself, which this runs on rather than replaces: one +# entry pulls the whole desktop, and cosmic-settings, cosmic-osd, the portal and +# the rest are taken from the repositories at the version they were tested at. +# +# The rest is the HyDE shell. Without those the session starts to a blank +# screen: no bar, no launcher, no wallpaper. +depends=('cosmic-session' 'waybar' 'rofi-wayland' 'wayland' 'libxkbcommon' + 'libinput' 'seatd' 'mesa' 'pixman' 'libdisplay-info' 'systemd-libs') # awww is in the AUR rather than in the repositories, so it cannot be a hard # depends without making the package uninstallable for anyone who has not built @@ -32,15 +36,11 @@ optdepends=('awww: wallpaper daemon, required for HyDE theme wallpapers' 'ttf-nerd-fonts-symbols: glyphs the waybar config draws with' 'qt5ct: Qt application theming to match the GTK theme') -# What "complete replacement" means in packaging terms. Every path this writes -# under /usr/bin is one cosmic-comp and cosmic-session also own, so the two -# cannot coexist -- which is correct, they are two builds of the same programs. -# -# conflicts without replaces/provides-driven auto-removal: pacman stops and -# names the conflict rather than quietly removing the desktop the machine is -# currently running. -conflicts=('cosmic-comp' 'cosmic-session') -provides=("cosmic-comp=$pkgver" "cosmic-session=$pkgver") +# No conflicts and no provides, deliberately. This installs beside COSMIC: its +# binaries are hyprcosmic-comp, hyprcosmic-session and hyprcosmic-conf, and it +# writes no path that cosmic-comp or cosmic-session owns. An earlier revision +# took the cosmic-* names and could not be installed over a COSMIC system +# without erasing the desktop it forked. options=('!strip' '!debug') @@ -56,13 +56,12 @@ package() { fi cp -a "$HYPRCOSMIC_STAGEDIR/." "$pkgdir/" - # No desktop-file-validate on the session entries. It rejects DesktopNames, + # No desktop-file-validate on the session entry. It rejects DesktopNames, # the key a display manager reads to set XDG_CURRENT_DESKTOP, because the # Desktop Entry Specification registers keys for application launchers and - # these are session files. cosmic.desktop here is upstream cosmic-session's, - # unchanged by this fork apart from the Exec path, and the copy Fedora ships - # as cosmic-session-1.5.0-1.fc44 fails the identical check -- so this is the - # validator's gap, not something the fork introduced. The workflow - # checks what actually matters instead -- that Exec names a file this - # package installs -- against the staged tree, before makepkg sees it. + # this is a session file. The copy Fedora ships as cosmic-session-1.5.0-1.fc44 + # fails the identical check -- so this is the validator's gap, not something + # the fork introduced. The workflow checks what actually matters instead -- + # that Exec names a file this package installs -- against the staged tree, + # before makepkg sees it. } diff --git a/packaging/debian/control.in b/packaging/debian/control.in index b66f7fa..d2d67b3 100644 --- a/packaging/debian/control.in +++ b/packaging/debian/control.in @@ -9,16 +9,13 @@ Installed-Size: @INSTALLED_SIZE@ Depends: @SHLIB_DEPENDS@ Recommends: waybar, rofi Suggests: fonts-hack-ttf, qt5ct -Conflicts: cosmic-comp, cosmic-session -Provides: cosmic-comp, cosmic-session -Replaces: cosmic-comp, cosmic-session Description: COSMIC configured in Hyprland's idiom, with a HyDE shell HyprCosmic is a fork of the COSMIC desktop that takes its configuration in Hyprland's idiom and wears a HyDE-style shell. . A single ~/.config/hyprcosmic/cosmic.conf -- with general { } blocks, bind = lines and $variables -- is compiled into COSMIC's own configuration tree by - cosmic-conf. The file is the source of truth: keys it names are applied at + hyprcosmic-conf. The file is the source of truth: keys it names are applied at every login over whatever the settings UI last stored, and keys it does not name are left alone. . @@ -27,6 +24,9 @@ Description: COSMIC configured in Hyprland's idiom, with a HyDE shell COSMIC's, with a Hyprland-compatible IPC socket so that HyDE's scripts and waybar's hyprland modules work unmodified. . - This package replaces the distribution's COSMIC. It installs both session - entries, so the greeter offers a stock COSMIC shell as well as the HyDE one, - both served by these binaries. + This package carries the whole desktop, which on Debian it has to: COSMIC is + not packaged there, in any suite, so there is nothing to depend on and nothing + to install beside. The Fedora and Arch packages ship only this fork's three + binaries and take the rest from the distribution. Here the forked binaries are + hyprcosmic-comp, hyprcosmic-session and hyprcosmic-conf, the components they + launch are included, and the session entry is the HyprCosmic one alone. diff --git a/packaging/fedora/hyprcosmic.spec b/packaging/fedora/hyprcosmic.spec index 5e99675..e63052c 100644 --- a/packaging/fedora/hyprcosmic.spec +++ b/packaging/fedora/hyprcosmic.spec @@ -20,14 +20,19 @@ # it on the release you intend to install it on. The workflow does that by # running the whole job inside a container of the target distribution. # -# WHY IT IS ONE PACKAGE AND NOT TWENTY-SEVEN -# ------------------------------------------ +# WHY IT IS ONE PACKAGE, AND WHY IT IS A SMALL ONE +# ------------------------------------------------ # Fedora splits COSMIC into a package per component, which is right for a -# distribution tracking upstream. This is a fork that replaces the desktop as a -# unit: the compositor, the session and the config compiler are versioned and -# tested together, and there is no supported combination in which you take the -# HyprCosmic cosmic-comp and the distribution's cosmic-session. One package is -# an accurate description of what is actually supported. +# distribution tracking upstream. This fork changes three of them -- the +# compositor, the session and the config compiler it adds -- and they are +# versioned and tested together, so one package is an accurate description of +# what is actually supported. +# +# It is not a package per component and it is not the whole desktop either. The +# build tree produces all of COSMIC, because it is COSMIC's tree, but shipping +# all of it would mean owning files that 25 distribution packages already own. +# The workflow reduces the staged tree to what this fork actually produces +# before any of the three packaging recipes see it. %global _hardened_build 1 @@ -45,34 +50,22 @@ License: GPL-3.0-only URL: https://github.com/outbackdingo/hyprcosmic BuildArch: x86_64 -# These are what "complete replacement" means in packaging terms. Every path -# this package writes under /usr/bin and /usr/share/cosmic is owned by one of -# these on a stock Fedora, so the two cannot be installed at once -- which is -# correct, because they are two builds of the same programs. +# COSMIC itself, which this runs on rather than replaces. # -# Conflicts rather than Obsoletes, deliberately. Obsoletes would let a routine -# `dnf install hyprcosmic` quietly remove the desktop the machine is currently -# running. Conflicts stops and says so, and removing the COSMIC packages stays -# something a person decides to do rather than something a resolver does on -# their behalf. -Conflicts: cosmic-comp -Conflicts: cosmic-session - -# What it stands in for, so anything depending on a COSMIC session is satisfied. +# One line pulls the whole desktop, because cosmic-session requires every +# component. That is exactly what is wanted: HyprCosmic forks the compositor, +# the session and adds the config compiler, and takes cosmic-settings, +# cosmic-osd, the portal and the rest from the distribution at the version the +# distribution tested them at. # -# Versioned at the COSMIC release this fork stands in for, not at this package's -# own version, and that distinction is the whole point. cosmic-greeter requires -# `cosmic-comp >= 1.5.0`; a Provides of 0.1.0 does not satisfy it, so dnf -# resolves the swap by removing the greeter -- which on a stock Fedora COSMIC is -# the display manager, and the machine comes back to a text console. The failure -# is silent, in that the transaction succeeds and you find out at the next boot. -# -# Bump this when rebasing on a newer COSMIC. It has to be at least the version -# the target distribution ships, because the packages that stay behind pin it. -%global cosmic_compat_version 1.5.0 - -Provides: cosmic-comp = %{cosmic_compat_version} -Provides: cosmic-session = %{cosmic_compat_version} +# There is deliberately no Conflicts and no Provides here. An earlier revision +# had both, on the reading that a fork of the desktop replaces the desktop, and +# it could not be installed: this package's files collided with 25 others in +# rpm's transaction check, and satisfying that by claiming all 25 with Conflicts +# would have erased cosmic-greeter, which on a stock Fedora COSMIC is the +# display manager. Installing beside COSMIC costs three renamed binaries and +# leaves the stock session on the greeter's menu to fall back to. +Requires: cosmic-session >= 1.5.0 # The HyDE shell. These are separate programs this fork drives rather than # builds, and without them the session starts to a blank screen with no bar and @@ -97,7 +90,7 @@ Hyprland's idiom and wears a HyDE-style shell. A single ~/.config/hyprcosmic/cosmic.conf -- with general { } blocks, bind = lines and $variables -- is compiled into COSMIC's own configuration tree by -cosmic-conf. The file is the source of truth: keys it names are applied at every +hyprcosmic-conf. The file is the source of truth: keys it names are applied at every login over whatever the settings UI last stored, and keys it does not name are left alone. @@ -106,9 +99,11 @@ cosmic-bg, and HyDE themes are imported directly. The compositor is COSMIC's, with a Hyprland-compatible IPC socket so that HyDE's scripts and waybar's hyprland modules work unmodified. -This package replaces the distribution's COSMIC. It installs both session -entries, so the greeter offers a stock COSMIC shell as well as the HyDE one, -both served by these binaries. +This package installs beside the distribution's COSMIC rather than over it. Its +binaries are hyprcosmic-comp, hyprcosmic-session and hyprcosmic-conf, and it +adds one session entry; the stock COSMIC entry stays on the greeter's menu, +served by the distribution's own binaries, so a session that will not start is +one logout away from a desktop that will. %prep # Nothing to unpack. See the note at the top of this file. @@ -118,15 +113,14 @@ test -n "%{stagedir}" || { echo "define stagedir: see .github/workflows/packages test -d "%{stagedir}/usr" || { echo "%{stagedir}/usr missing; run just install first" >&2; exit 1; } cp -a "%{stagedir}/." "%{buildroot}/" -# The session entries are checked by the workflow against the staged tree, not +# The session entry is checked by the workflow against the staged tree, not # with desktop-file-validate here. desktop-file-validate rejects DesktopNames, # the key a display manager reads to set XDG_CURRENT_DESKTOP, because the # Desktop Entry Specification registers keys for application launchers and this -# is a session file. cosmic.desktop here is upstream cosmic-session's, unchanged -# by this fork apart from the Exec path, and the copy Fedora already ships as -# cosmic-session-1.5.0-1.fc44 fails the identical check -- so this is the -# validator's gap, not something the fork introduced. Dropping the key would -# satisfy the validator and break the session. +# is a session file. The copy Fedora already ships as cosmic-session-1.5.0-1.fc44 +# fails the identical check -- so this is the validator's gap, not something the +# fork introduced. Dropping the key would satisfy the validator and break the +# session. # See "Check the session entries" in .github/workflows/packages.yml, which # tests what actually matters: that Exec names a file this package installs. @@ -138,4 +132,5 @@ cp -a "%{stagedir}/." "%{buildroot}/" %changelog * Mon Aug 10 2026 dingo - 0.1.0-1 -- First package of the fork: COSMIC replaced as a unit, HyDE shell, cosmic-conf. +- First package of the fork: hyprcosmic-comp, hyprcosmic-session and + hyprcosmic-conf installed beside the distribution's COSMIC, with a HyDE shell.