Install as the compositor, at upstream's paths

HyprCosmic is a fork of COSMIC, not an add-on to it, so cosmic-comp goes
where a cosmic-comp goes: $(bindir)/cosmic-comp.

This reverses the private $(libexecdir)/hyprcosmic layout. That bought a
fallback -- both compositors on disk, both sessions bootable -- and cost
coherence: a session that had to name absolute paths to find its own
binary, and no answer to "which cosmic-comp is running". The fallback
survives in a better form, because cosmic-session installs cosmic.desktop
as well as hyprcosmic.desktop and both are now served by this binary.

The consequence is stated rather than hidden: a package built from this
conflicts with the distribution's cosmic-comp over /usr/bin/cosmic-comp.
That is the honest relationship between two builds of the same program.

libexecdir is dropped from the Makefile, having been added by this fork
and used by nothing else. CI asserts the binary and both .ron defaults
land at upstream's paths, and that nothing returns to the libexec
directory -- a stray copy there is a second compositor that nothing runs
and no uninstall removes.
This commit is contained in:
2026-08-10 18:21:34 +07:00
parent 139a1de4e8
commit 5f176995dc
2 changed files with 43 additions and 34 deletions
+16 -9
View File
@@ -132,17 +132,24 @@ jobs:
- name: Install into a staging root
run: make install DESTDIR="$PWD/stage" prefix=/usr
# These two assertions are Patch D as an executable statement. HyprCosmic
# installs beside COSMIC rather than over it, which is what keeps the stock
# session available to log into when this compositor will not start. If a
# future edit sends the binary back to $(bindir)/cosmic-comp, that stops
# being true silently -- unless something fails here.
- name: Assert it installs beside COSMIC, not over it
# HyprCosmic replaces COSMIC rather than sitting beside it, so this build
# is *the* cosmic-comp on a machine that installs it and has to place
# everything upstream's does. The compositor starts without the two .ron
# defaults and then has no shortcuts and no tiling exceptions, which is a
# failure that looks like "the keyboard does nothing" rather than like a
# missing file -- worth an assertion rather than a bug report.
#
# The negative assertion is the one that would rot quietly: nothing may go
# back to the private libexec directory this fork used to install into,
# because a stray copy there is a second compositor that nothing runs and
# that no `uninstall` removes.
- name: Assert it installs as the compositor, at upstream's paths
run: |
set -eux
test -x stage/usr/libexec/hyprcosmic/cosmic-comp
test ! -e stage/usr/bin/cosmic-comp
test ! -e stage/usr/share/cosmic/com.system76.CosmicSettings.Shortcuts/v1/defaults
test -x stage/usr/bin/cosmic-comp
test -f stage/usr/share/cosmic/com.system76.CosmicSettings.Shortcuts/v1/defaults
test -f stage/usr/share/cosmic/com.system76.CosmicSettings.WindowRules/v1/tiling_exception_defaults
test ! -e stage/usr/libexec/hyprcosmic/cosmic-comp
find stage -type f -printf '%M %10s %P\n'
- uses: actions/upload-artifact@v4
+27 -25
View File
@@ -2,7 +2,6 @@ export prefix ?= /usr
sysconfdir ?= /etc
bindir = $(prefix)/bin
libdir = $(prefix)/lib
libexecdir ?= $(prefix)/libexec
sharedir = $(prefix)/share
BINARY = cosmic-comp
@@ -10,7 +9,7 @@ CARGO_TARGET_DIR ?= target
TARGET = debug
DEBUG ?= 0
.PHONY = all clean install install-defaults uninstall vendor
.PHONY = all clean install uninstall vendor
ifeq ($(DEBUG),0)
TARGET = release
@@ -22,15 +21,20 @@ ifneq ($(VENDOR),0)
ARGS += --offline --locked
endif
# HyprCosmic installs *beside* the distro's COSMIC rather than over it. Both
# sessions stay on the greeter's menu -- /usr/share/wayland-sessions holds
# cosmic.desktop and hyprcosmic.desktop at the same time -- which only works
# while this binary stays out of $(bindir)/cosmic-comp, where it would replace
# the compositor the stock session runs. A private directory is what keeps
# installing HyprCosmic from being a one-way door: if the fork misbehaves, the
# stock session is still there to log into and fix it from.
compdir ?= $(libexecdir)/hyprcosmic
TARGET_BIN="$(DESTDIR)$(compdir)/$(BINARY)"
# HyprCosmic is a fork of COSMIC, not an add-on to it, so this binary goes where
# a cosmic-comp goes: $(bindir)/cosmic-comp. It is the compositor on a machine
# that installs it, and a HyprCosmic package accordingly conflicts with the
# distribution's cosmic-comp over this path -- which is the honest relationship
# between two builds of the same program, and is how every other distro-level
# fork declares itself.
#
# This used to install to a private $(libexecdir)/hyprcosmic so both sessions
# could coexist. That bought a fallback and cost coherence: two compositors on
# disk, a session that had to name absolute paths to find its own, and no
# answer to "which cosmic-comp is running". The fallback survives in a better
# form -- cosmic-session installs cosmic.desktop as well as hyprcosmic.desktop,
# so the greeter still offers a stock COSMIC shell, now served by this binary.
TARGET_BIN="$(DESTDIR)$(bindir)/$(BINARY)"
KEYBINDINGS_CONF="$(DESTDIR)$(sharedir)/cosmic/com.system76.CosmicSettings.Shortcuts/v1/defaults"
TILING_EXCEPTIONS_CONF="$(DESTDIR)$(sharedir)/cosmic/com.system76.CosmicSettings.WindowRules/v1/tiling_exception_defaults"
@@ -57,19 +61,17 @@ ifeq ($(VENDOR),1)
rm -rf vendor; tar pxf vendor.tar
endif
# The binary only. The two .ron files are COSMIC's *shared* defaults, and they
# sit at paths the distro's own cosmic-comp package already owns, so installing
# them from here would make a HyprCosmic package conflict with that one over two
# files it has no reason to change. The fork reads the stock copies instead --
# which is honest, because a HyprCosmic session needs the rest of COSMIC present
# anyway for the greeter, the portals and the settings daemon.
# Upstream's install, restored. The two .ron files are the compositor's shared
# defaults and it will not find a shortcut or a tiling exception without them,
# so a build that means to be the only cosmic-comp on the machine has to place
# them. They were split out into `install-defaults` while this fork installed
# beside a COSMIC it could borrow them from; there is nothing to borrow from now.
#
# `install-defaults` keeps them reachable for anyone building this fork on its
# own, without a COSMIC install to borrow them from.
# `bind` lines in cosmic.conf are still written to the Shortcuts *custom* key,
# which cosmic-comp merges over these defaults. That is unchanged and is what
# keeps `cosmic-conf apply` from having to edit the file installed here.
install:
install -Dm0755 "$(CARGO_TARGET_DIR)/$(TARGET)/$(BINARY)" "$(TARGET_BIN)"
install-defaults:
install -Dm0644 "data/keybindings.ron" "$(KEYBINDINGS_CONF)"
install -Dm0644 "data/tiling-exceptions.ron" "$(TILING_EXCEPTIONS_CONF)"
@@ -80,11 +82,11 @@ install-bare-session: install
install -Dm0644 "data/cosmic-comp.service" "$(DESTDIR)$(libdir)/systemd/user/cosmic-comp.service"
install -Dm0755 "data/cosmic-service" "$(DESTDIR)/$(bindir)/cosmic-service"
# Only what `install` placed. Removing KEYBINDINGS_CONF here would delete a file
# belonging to the distro's cosmic-comp, breaking the stock session on the way
# out -- the exact failure the private compdir above exists to prevent.
# Upstream's uninstall, restored along with the install it undoes. It leaves
# TILING_EXCEPTIONS_CONF behind, which is upstream's omission rather than a
# decision of this fork's, and is left alone so the two files stay diffable.
uninstall:
rm "$(TARGET_BIN)"
rm "$(TARGET_BIN)" "$(KEYBINDINGS_CONF)"
uninstall-bare-session:
rm "$(DESTDIR)$(sharedir)/wayland-sessions/cosmic.desktop"