Compare commits

...
Author SHA1 Message Date
theupriser 7a84b0dbca Update notifier: Steamify's own tray icon (single-color on GNOME)
Sync git.upriser.nl mirror / sync (push) Skipped
2026-10-14 15:18:26 +02:00
theupriser 0e0bf57ca8 Steamify launcher: StartupWMClass so GNOME's dock matches the app window; session tool records the last desktop from its shell 2026-10-14 15:17:17 +02:00
theupriser 68342e7a24 Preferred desktop for Switch to Desktop (kde/gnome/last), session tools for every login manager when GNOME is installed, GNOME theme texts in the app 2026-10-14 15:09:16 +02:00
theupriser 09ef0b1c71 GNOME theme: no arrow on menus 2026-10-14 15:04:32 +02:00
theupriser 8432f634ef GNOME theme: GTK colors follow the light/dark style; adw-gtk3 2026-10-14 15:00:44 +02:00
theupriser 4221ae6e21 GNOME theme: register the extensions' schemas for GNOME Settings 2026-10-14 14:54:27 +02:00
theupriser eaa3f28fdc GNOME theme: no trash on the desktop (it is in the dock) 2026-10-14 14:48:43 +02:00
theupriser ab3b581f45 GNOME theme: Ubuntu Dock and Tiling Assistant, SteamOS backgrounds in Settings, dock keeps Ubuntu's look, no settings launchers 2026-10-14 14:46:32 +02:00
theupriser ce1aa1bf7d GNOME theme: one Steamify Vapor extension carries the shell colors; no gnome-shell-extensions bundle; dock shape left to the user 2026-10-14 14:38:32 +02:00
theupriser 79048338bf GNOME theme: Dock Settings and Desktop Icons Settings launchers 2026-10-14 14:24:44 +02:00
theupriser c7f5f515a3 GNOME theme: shell theme and dock in Vapor colors, Ubuntu-style extensions, start on the desktop; never pick GNOME Classic 2026-10-14 14:22:58 +02:00
theupriser 12eb56220a GDM steam-set-session: don't exit at boot when nobody is logged in 2026-10-14 14:08:44 +02:00
theupriser 039f2691d8 GNOME: terminal for the Steamify shortcut and notifier, notifier runs on GNOME 2026-10-14 14:00:58 +02:00
theupriser 62a30e6095 GNOME: install Extension Manager 2026-10-14 13:55:23 +02:00
theupriser c5b59d9438 GNOME: AppIndicator extension for tray icons 2026-10-14 13:54:30 +02:00
theupriser 2b84e6afa6 GNOME: desktop icons through the Desktop Icons NG extension 2026-10-14 13:51:49 +02:00
theupriser ae12c1bb41 GNOME: pin the Return to Gaming Mode launcher to the dash; relogin waits for the runtime dir 2026-10-14 13:51:03 +02:00
theupriser fc28ea4c64 GDM relogin: stop GDM while the old user manager shuts down 2026-10-14 13:45:03 +02:00
theupriser 5dfc916b97 GNOME prototype: detect GNOME/GDM, GDM autologin and session switching 2026-10-14 13:40:13 +02:00
27 changed files with 779 additions and 31 deletions

No files matched your search

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"><g fill="#bebebe"><path d="m 26.586,23.6632 8.104641,-0.4201 1.91027,-6.7552 -5.59099,-4.4419 -6.871493,5.8329 z"/><path d="M 31.027515,23.9946 35,23 l 1.976562,-2.9766 -4,-4 -4.949047,4.9712 z"/><path d="M 15.316486,35.7061 21.675457,35.065 23.0333,27.5143 16.403747,25.7462 12.603749,30.3195 Z"/><path d="m 16.985332,35.8717 3.972485,-0.4165 2.210937,-3.4453 -3.0625,-3.1563 -6.933422,3.9868 z"/><path d="m 30.5,11 c -4.142135,0 -7.499999,3.357864 -7.5,7.5 0.0017,0.201484 0.01143,0.402819 0.0293,0.603516 -1.289636,1.575722 -4.80544,5.546997 -5.113281,5.902343 -2.416761,0.03284 -4.577852,1.51258 -5.482422,3.753907 -1.237432,3.074241 0.2518,6.569519 3.326172,7.80664 3.074245,1.237417 6.56952,-0.251813 7.80664,-3.326172 0.274389,-0.686886 0.419405,-1.418587 0.427735,-2.158203 l 5.896484,-5.111328 C 30.093269,25.98873 30.296562,25.998503 30.5,26 34.642135,26 37.999999,22.642136 38,18.5 37.999999,14.357864 34.642135,11 30.5,11 Z m 0,3 c 2.48528,0 4.499999,2.014718 4.5,4.5 -10e-7,2.485282 -2.01472,4.5 -4.5,4.5 -2.48528,0 -4.499999,-2.014718 -4.5,-4.5 1e-6,-2.485282 2.01472,-4.5 4.5,-4.5 z M 18.046875,27 c 0.496175,0.0058 0.986949,0.103774 1.447266,0.289062 2.049689,0.825003 3.042263,3.155585 2.216797,5.205079 -0.825003,2.049668 -3.155579,3.04224 -5.205079,2.216797 C 14.45617,33.885935 13.463596,31.555353 14.289062,29.505859 14.905127,27.975627 16.397393,26.980525 18.046875,27 Z"/><circle cx="30.5" cy="18.4998" r="3.5"/><path d="M 5.0722656,22.564453 A 19,19 0 0 0 5,24 19,19 0 0 0 5.7695312,29.3125 l 11.1113278,4.470703 a 3,3 0 0 0 3.902344,-1.664062 3,3 0 0 0 -1.664062,-3.902344 z"/><path d="M 40.440,33.688 L 42.527,33.983 L 42.527,36.007 L 40.440,36.302 L 39.770,37.921 L 41.037,39.606 L 39.606,41.037 L 37.921,39.770 L 36.302,40.440 L 36.007,42.527 L 33.983,42.527 L 33.688,40.440 L 32.069,39.770 L 30.384,41.037 L 28.953,39.606 L 30.220,37.921 L 29.550,36.302 L 27.463,36.007 L 27.463,33.983 L 29.550,33.688 L 30.220,32.069 L 28.953,30.384 L 30.384,28.953 L 32.069,30.220 L 33.688,29.550 L 33.983,27.463 L 36.007,27.463 L 36.302,29.550 L 37.921,30.220 L 39.606,28.953 L 41.037,30.384 L 39.770,32.069 Z M 37.395,34.995 A 2.4,2.4 0 1 0 32.595,34.995 A 2.4,2.4 0 1 0 37.395,34.995 Z"/></g></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

+1 -2
View File
@@ -178,8 +178,7 @@ backend_apply() {
backend_sudo || return 1
LOGIN_MANAGER=plasmalogin
[[ "${WANTED[single]}" == 1 ]] && LOGIN_MANAGER=sddm
choose_login_manager
local -a failed=()
for c in "${TO_DISABLE[@]}"; do
if backend_run_component "$c" disable; then feature_record "$c" disable; else failed+=("$c"); fi
+6 -1
View File
@@ -17,13 +17,18 @@ boot_status() {
[[ -f "$BOOT_UNIT" ]] && systemctl is-enabled -q "$BOOT_UNIT_NAME" 2>/dev/null
}
boot_desktop_arg() {
# Our session tool (installed with GNOME) resolves "desktop" to the preferred desktop; CachyOS's own takes a session name.
if [[ -f "$GDM_FIX_DIR/steam-set-session" ]]; then echo desktop; else echo plasma.desktop; fi
}
boot_enable() {
info "Setting the PC to boot into the desktop..."
# The sync bridge (plasma-login-manager only; not there with SDDM) copies
# the session into the base config; run it right away rather than rely
# on its path unit, which could still be pending when the login manager
# starts.
service_file "$BOOT_UNIT_NAME" SESSION_SYNC="$SESSION_SYNC" | sudo tee "$BOOT_UNIT" > /dev/null
service_file "$BOOT_UNIT_NAME" SESSION_SYNC="$SESSION_SYNC" DESKTOP_SESSION="$(boot_desktop_arg)" | sudo tee "$BOOT_UNIT" > /dev/null
sudo systemctl daemon-reload
sudo systemctl enable "$BOOT_UNIT_NAME" || { err "Enabling $BOOT_UNIT_NAME failed."; return 1; }
ok "Boots into the desktop from the next boot on (Return to Gaming Mode still works)."
+59 -2
View File
@@ -23,7 +23,10 @@ create_desktop_shortcut() {
# the shortcut can't sudo for interactively (Terminal=false), so it gets
# a password-less rule scoped to exactly those two commands.
local exec_line="steamos-session-select gamescope"
if [[ "$LOGIN_MANAGER" == "plasmalogin" ]]; then
if [[ "$LOGIN_MANAGER" == "gdm" ]]; then
# Its own steamos-session-select (lib/login-manager.sh) restarts GDM, through the helper and rule gdm_fix_install adds.
:
elif [[ "$LOGIN_MANAGER" == "plasmalogin" ]]; then
exec_line="sh -c 'steamos-session-select gamescope && sudo -n /usr/bin/systemctl start sync-steamos-session.service && sudo -n /usr/bin/systemctl restart plasmalogin'"
local sudoers_tmp
sudoers_tmp="$(mktemp)"
@@ -40,6 +43,9 @@ EOF
else
sudo rm -f /etc/sudoers.d/gamescope-session-switch
fi
# GNOME shows no icons on the desktop: the application grid gets the shortcut too.
gnome_app_shortcut=false
[[ "$(desktop_kind)" == gnome ]] && gnome_app_shortcut=true
# SteamOS itself uses Valve's "gaming-return" icon (Steam logo with a
# return arrow; the Deck-style arrow is only used on Steam Deck
@@ -66,6 +72,14 @@ EOF
# Fix permissions for the target user and KDE Plasma desktop ecosystem
chmod +x "$shortcut_path"
if [[ "$gnome_app_shortcut" == true ]]; then
mkdir -p "$user_home/.local/share/applications"
cp "$shortcut_path" "$user_home/.local/share/applications/steamify-return-to-gaming-mode.desktop"
# GNOME only starts launchers it trusts.
gio set "$shortcut_path" metadata::trusted true 2>/dev/null || true
gnome_dash_pin
gnome_extensions_enable
fi
ok "Desktop shortcut created successfully."
}
@@ -81,6 +95,49 @@ set_shortcut_icon() {
remove_desktop_shortcut() {
local desktop_dir
desktop_dir="$(xdg-user-dir DESKTOP 2>/dev/null || echo "$HOME/Desktop")"
rm -f "$desktop_dir/Return to Gaming Mode.desktop"
rm -f "$desktop_dir/Return to Gaming Mode.desktop" "$HOME/.local/share/applications/steamify-return-to-gaming-mode.desktop"
gnome_dash_unpin
sudo rm -f /etc/sudoers.d/gamescope-session-switch
}
# GNOME draws no icons on the desktop: the shortcut is pinned to the dash
# (the favorites bar) as well. Only in a running session (gsettings needs its dconf).
GNOME_SHORTCUT_ID=steamify-return-to-gaming-mode.desktop
gnome_dash_pin() {
user_session && command -v gsettings >/dev/null || return 0
local favorites
favorites="$(gsettings get org.gnome.shell favorite-apps 2>/dev/null)" || return 0
[[ "$favorites" == *"$GNOME_SHORTCUT_ID"* ]] && return 0
favorites="$(sed "s/\]\$/, '$GNOME_SHORTCUT_ID']/; s/^\[, /[/; s/\[\], /[/" <<< "$favorites")"
[[ "$favorites" == "[ '$GNOME_SHORTCUT_ID']" ]] && favorites="['$GNOME_SHORTCUT_ID']"
gsettings set org.gnome.shell favorite-apps "$favorites"
}
gnome_dash_unpin() {
user_session && command -v gsettings >/dev/null || return 0
local favorites
favorites="$(gsettings get org.gnome.shell favorite-apps 2>/dev/null)" || return 0
[[ "$favorites" == *"$GNOME_SHORTCUT_ID"* ]] || return 0
favorites="$(sed -e "s/, '$GNOME_SHORTCUT_ID'//; s/'$GNOME_SHORTCUT_ID', //; s/'$GNOME_SHORTCUT_ID'//" <<< "$favorites")"
gsettings set org.gnome.shell favorite-apps "$favorites"
}
# GNOME draws no desktop icons and no tray icons (Steam's, for one) itself:
# the Desktop Icons NG and AppIndicator extensions, installed with the other
# GNOME packages (lib/packages.sh). Enabled in the user's settings; GNOME
# loads a new extension at the next login.
GNOME_EXTENSIONS=(ding@rastersoft.com appindicatorsupport@rgcjonas.gmail.com)
gnome_extensions_enable() {
user_session && command -v gsettings >/dev/null || return 0
local uuid enabled
for uuid in "${GNOME_EXTENSIONS[@]}"; do
[[ -d "/usr/share/gnome-shell/extensions/$uuid" ]] || continue
enabled="$(gsettings get org.gnome.shell enabled-extensions 2>/dev/null)" || return 0
[[ "$enabled" == *"$uuid"* ]] && continue
if [[ "$enabled" == "@as []" || "$enabled" == "[]" ]]; then enabled="['$uuid']"
else enabled="${enabled%]}, '$uuid']"; fi
gsettings set org.gnome.shell enabled-extensions "$enabled"
done
}
+68
View File
@@ -0,0 +1,68 @@
#!/bin/bash
# Which desktop Steamify is running on (KDE Plasma or GNOME), and the
# session the login manager has to start for it. GNOME (GDM) is a prototype.
# Sourced by steamify.sh; not meant to be run on its own.
desktop_kind() {
# gnome or kde: the running session first, else what the login manager
# is (GDM means GNOME), else KDE, which Steamify was made for.
case ":${STEAMIFY_DESKTOP:-${XDG_CURRENT_DESKTOP:-}}:" in
*:GNOME:*|*:gnome:*) echo gnome; return ;;
*:KDE:*|*:kde:*) echo kde; return ;;
esac
[[ "$(current_display_manager)" == gdm ]] && { echo gnome; return; }
echo kde
}
desktop_session_file() {
# The login manager's session entry for the desktop: plasma.desktop, or
# whichever GNOME one is installed (gnome.desktop, gnome-xorg.desktop).
local f
if [[ "$(desktop_kind)" == gnome ]]; then
# The plain session, not GNOME Classic (gnome-classic.desktop, from gnome-shell-extensions) or Xorg's.
for f in /usr/share/wayland-sessions/gnome.desktop /usr/share/xsessions/gnome.desktop \
/usr/share/wayland-sessions/gnome-wayland.desktop; do
[[ -f "$f" ]] && { basename "$f"; return; }
done
echo gnome.desktop
else
echo plasma.desktop
fi
}
choose_login_manager() {
# LOGIN_MANAGER for gaming_enable. With KDE and GNOME both installed the active login
# manager stays (switching it would be a surprise); otherwise gdm on GNOME, sddm with
# single user mode and plasmalogin without.
local current
current="$(current_display_manager)"
if desktop_installed gnome && desktop_installed kde; then
case "$current" in gdm|sddm|plasmalogin) LOGIN_MANAGER="$current"; return ;; esac
fi
if [[ "$(desktop_kind)" == gnome ]]; then LOGIN_MANAGER=gdm
elif [[ "${WANTED[single]:-0}" == 1 ]]; then LOGIN_MANAGER=sddm
else LOGIN_MANAGER=plasmalogin; fi
}
# Which desktop "Switch to Desktop" (and booting into the desktop) goes to when both are
# installed: kde, gnome, or last (the one you left for gamescope). Read by the session tool.
DESKTOP_PREF_FILE=/etc/steamify/desktop
desktop_pref_get() {
cat "$DESKTOP_PREF_FILE" 2>/dev/null || echo last
}
desktop_pref_set() {
printf '%s\n' "$1" | sudo install -Dm644 /dev/stdin "$DESKTOP_PREF_FILE"
}
desktop_installed() {
# desktop_installed kde|gnome: its session is installed (both can be: the
# menu then offers the theme of each).
local name=plasma f
[[ "$1" == gnome ]] && name=gnome
for f in /usr/share/wayland-sessions/$name*.desktop /usr/share/xsessions/$name*.desktop; do
[[ -f "$f" ]] && return 0
done
return 1
}
+159
View File
@@ -0,0 +1,159 @@
#!/bin/bash
# SteamOS look for GNOME, the counterpart of lib/vapor-theme.sh: the Vapor
# palette from CachyOS's cachyos-vapor package (also the Steam Deck
# wallpapers), as dark mode, a blue accent, the wallpaper and libadwaita/GTK4
# colors. Settings go through gsettings and its undo journal (lib/state.sh).
# Sourced by steamify.sh; not meant to be run on its own.
GNOME_THEME_MARK="/* Steamify GNOME theme */"
GNOME_THEME_CSS="${XDG_CONFIG_HOME:-$HOME/.config}/gtk-4.0/gtk.css"
# The Ubuntu-style look: the dock (Ubuntu Dock is Dash to Dock) and our own extension,
# Steamify Vapor, which carries the shell colors (its stylesheet.css) and starts GNOME on
# the desktop. (Desktop Icons NG and AppIndicator come with the conversion, lib/desktop-shortcut.sh.)
GNOME_THEME_EXTENSIONS=(ubuntu-dock@ubuntu.com tiling-assistant@ubuntu.com steamify-vapor@steamify.github.io)
# Ubuntu's own builds, the ones Ubuntu 26.04 ships (they are the more mature): Ubuntu Dock from its source tag
# (built here: needs make, sassc and gettext) and Tiling Assistant (Ubuntu maintains it now) from its release.
DOCK_URL="https://github.com/micheleg/dash-to-dock/archive/refs/tags/ubuntu-dock-109ubuntu2.tar.gz"
DOCK_SHA256=599057fa27d922d4730bfc27c803b1b14b05f49a20e580e154e151b8481e5d41
TILING_URL="https://github.com/ubuntu/Tiling-Assistant/releases/download/v56/tiling-assistant@leleat-on-github.shell-extension.zip"
TILING_SHA256=961da0c6b8e5960770e68a06d71205765870435dbe8fe0ccc1ec50d4cc78265a
GNOME_USER_EXTENSIONS="${XDG_DATA_HOME:-$HOME/.local/share}/gnome-shell/extensions"
GNOME_THEME_WALLPAPER="/usr/share/wallpapers/Steam Deck Logo Default.jpg"
gnometheme_status() {
grep -qsF "$GNOME_THEME_MARK" "$GNOME_THEME_CSS"
}
gnometheme_extensions_install() {
# Ubuntu Dock and Tiling Assistant (pinned downloads, checked) and our own Steamify Vapor, in the user's own extensions folder.
local file work dir
dir="$GNOME_USER_EXTENSIONS/ubuntu-dock@ubuntu.com"
if [[ ! -f "$dir/metadata.json" ]]; then
file="$(mktemp --suffix=.tar.gz)"; work="$(mktemp -d)"
sudo pacman -S --needed --noconfirm make sassc gettext >/dev/null 2>&1
if curl -fsSL --max-time 60 "$DOCK_URL" -o "$file" && [[ "$(sha256sum < "$file")" == "$DOCK_SHA256 -" ]] &&
tar xzf "$file" -C "$work" --strip-components=1 &&
make -C "$work" install-local INSTALLBASE="$GNOME_USER_EXTENSIONS" >/dev/null 2>&1; then
:
else
warn "Couldn't set up Ubuntu Dock; the dock stays off."
fi
rm -rf "$file" "$work"
fi
dir="$GNOME_USER_EXTENSIONS/tiling-assistant@ubuntu.com"
if [[ ! -f "$dir/metadata.json" ]]; then
file="$(mktemp --suffix=.zip)"
if curl -fsSL --max-time 60 "$TILING_URL" -o "$file" && [[ "$(sha256sum < "$file")" == "$TILING_SHA256 -" ]]; then
rm -rf "$dir"; mkdir -p "$dir"
python3 -c 'import sys,zipfile;zipfile.ZipFile(sys.argv[1]).extractall(sys.argv[2])' "$file" "$dir"
# Under the name Ubuntu gives it (GNOME Settings' desktop panel looks for it).
sed -i 's|"uuid": "tiling-assistant@leleat-on-github"|"uuid": "tiling-assistant@ubuntu.com"|' "$dir/metadata.json"
glib-compile-schemas "$dir/schemas" 2>/dev/null
else
warn "Couldn't download Tiling Assistant; it stays off."
fi
rm -f "$file"
fi
# GNOME Settings' Desktop panel finds the settings of the dock and of tiling in the default schema folders.
local schemas="${XDG_DATA_HOME:-$HOME/.local/share}/glib-2.0/schemas" ext
mkdir -p "$schemas"
for ext in ubuntu-dock@ubuntu.com tiling-assistant@ubuntu.com; do
cp "$GNOME_USER_EXTENSIONS/$ext"/schemas/*.gschema.xml "$schemas/" 2>/dev/null
done
glib-compile-schemas "$schemas" 2>/dev/null
dir="$GNOME_USER_EXTENSIONS/steamify-vapor@steamify.github.io"
mkdir -p "$dir"
patch_file steamify-vapor.js > "$dir/extension.js"
patch_file steamify-vapor.json > "$dir/metadata.json"
patch_file steamify-gnome-shell.css > "$dir/stylesheet.css"
}
gnometheme_backgrounds() {
# The SteamOS wallpapers of cachyos-vapor in GNOME Settings' background list: its XML list in the user's folder.
local xml="${XDG_DATA_HOME:-$HOME/.local/share}/gnome-background-properties/steamify-steamos.xml" f name
mkdir -p "$(dirname "$xml")"
{
printf '%s\n' '<?xml version="1.0"?>' '<!DOCTYPE wallpapers SYSTEM "gnome-wp-list.dtd">' '<wallpapers>'
for f in /usr/share/wallpapers/*.jpg; do
[[ -f "$f" ]] || continue
name="$(basename "$f" .jpg)"
printf ' <wallpaper deleted="false">\n <name>SteamOS: %s</name>\n <filename>%s</filename>\n <filename-dark>%s</filename-dark>\n <options>zoom</options>\n <pcolor>#24272c</pcolor>\n <scolor>#24272c</scolor>\n <shade_type>solid</shade_type>\n </wallpaper>\n' "$name" "$f" "$f"
done
echo '</wallpapers>'
} > "$xml"
}
gnometheme_shell() {
# The top bar and dash colors (the Steamify Vapor extension), and the dock beside it.
gnometheme_extensions_install
gnometheme_backgrounds
# Like Ubuntu's dock: on the left, always there; its look is Ubuntu's own, left as it is. Its shape (a
# panel to the screen edge or floating) is left to the user: Dock Settings.
local d=org.gnome.shell.extensions.dash-to-dock
gset gnometheme $d dock-position "'LEFT'" || true
gset gnometheme $d dock-fixed true || true
gset gnometheme $d running-indicator-style "'DOTS'" || true
gset gnometheme $d click-action "'minimize-or-previews'" || true
# Trash is in the dock, not on the desktop (Ubuntu does the same).
gset gnometheme org.gnome.shell.extensions.ding show-trash false || true
gset gnometheme $d show-trash true || true
local uuid enabled
for uuid in "${GNOME_THEME_EXTENSIONS[@]}"; do
enabled="$(gs get org.gnome.shell enabled-extensions 2>/dev/null)" || return 0
[[ "$enabled" == *"$uuid"* ]] && continue
if [[ "$enabled" == "@as []" || "$enabled" == "[]" ]]; then enabled="['$uuid']"
else enabled="${enabled%]}, '$uuid']"; fi
gset gnometheme org.gnome.shell enabled-extensions "$enabled"
done
}
gnometheme_enable() {
if ! pacman -Q cachyos-vapor >/dev/null 2>&1; then
info "Installing cachyos-vapor (its wallpapers and colors)..."
sudo pacman -S --needed --noconfirm cachyos-vapor || { err "Installing cachyos-vapor failed."; return 1; }
# Only remove it again on disable if we were the ones installing it.
state_set gnometheme installed_pkg 1
fi
info "Applying the SteamOS look to GNOME..."
gset gnometheme org.gnome.desktop.interface color-scheme "'prefer-dark'"
gset gnometheme org.gnome.desktop.interface accent-color "'blue'" || true
# adw-gtk3 follows the light/dark style of Settings > Appearance (CachyOS's adw-gtk3-dark would pin it dark).
[[ -d /usr/share/themes/adw-gtk3 ]] && gset gnometheme org.gnome.desktop.interface gtk-theme "'adw-gtk3'"
# Windows with minimize and maximize buttons, like Ubuntu (GNOME shows only close by default).
gset gnometheme org.gnome.desktop.wm.preferences button-layout "'appmenu:minimize,maximize,close'" || true
if [[ -f "$GNOME_THEME_WALLPAPER" ]]; then
local uri="file://${GNOME_THEME_WALLPAPER// /%20}"
gset gnometheme org.gnome.desktop.background picture-uri "'$uri'"
gset gnometheme org.gnome.desktop.background picture-uri-dark "'$uri'" || true
gset gnometheme org.gnome.desktop.background picture-options "'zoom'"
fi
# GTK4/libadwaita apps ignore GTK themes: their colors come from this file.
mkdir -p "$(dirname "$GNOME_THEME_CSS")"
if [[ -f "$GNOME_THEME_CSS" ]] && ! gnometheme_status; then
cp -a "$GNOME_THEME_CSS" "$STATE_DIR/gnometheme-gtk4.css"
fi
{ echo "$GNOME_THEME_MARK"; patch_file steamify-gnome-gtk4.css; } > "$GNOME_THEME_CSS"
gnometheme_shell
ok "SteamOS theme for GNOME on (apps pick up the colors when they start again)."
}
gnometheme_disable() {
info "Restoring GNOME's previous look..."
grevert gnometheme
# (The Dock/Desktop Icons/Tiling Settings launchers of earlier prototypes.)
rm -f "${XDG_DATA_HOME:-$HOME/.local/share}"/applications/steamify-{dock,icons,tiling}-settings.desktop \
"${XDG_DATA_HOME:-$HOME/.local/share}/gnome-background-properties/steamify-steamos.xml"
rm -rf "$GNOME_USER_EXTENSIONS/steamify-vapor@steamify.github.io" "$GNOME_USER_EXTENSIONS/ubuntu-dock@ubuntu.com" "$GNOME_USER_EXTENSIONS/tiling-assistant@ubuntu.com"
if [[ -f "$STATE_DIR/gnometheme-gtk4.css" ]]; then
mv -f "$STATE_DIR/gnometheme-gtk4.css" "$GNOME_THEME_CSS"
else
gnometheme_status && rm -f "$GNOME_THEME_CSS"
fi
if [[ -n "$(state_get gnometheme installed_pkg)" ]]; then
# Fails, and stays installed, when the KDE theme or another package needs it.
sudo pacman -R --noconfirm cachyos-vapor >/dev/null 2>&1 ||
info "Keeping cachyos-vapor installed (another package needs it)."
fi
state_clear gnometheme
ok "Previous GNOME look restored."
}
+98 -2
View File
@@ -4,6 +4,11 @@
# Sourced by steamify.sh; not meant to be run on its own.
BASE_CONF="/etc/plasmalogin.conf"
GDM_CONF="/etc/gdm/custom.conf"
GDM_FIX_DIR=/usr/local/share/steamify-gdm
GDM_HOOK=/etc/pacman.d/hooks/95-steamify-gdm.hook
GDM_SUDOERS=/etc/sudoers.d/steamify-gdm-relogin
GDM_RELOGIN=/usr/local/libexec/steamify-gdm-relogin
# The "SteamOS conversion" menu item: gaming mode boot, the Return to
# Gaming Mode shortcut and Steam on the desktop (lib/steam-desktop.sh).
@@ -14,6 +19,9 @@ gaming_status() {
plasmalogin)
sed -n '/^\[Autologin\]/,/^\[/p' "$BASE_CONF" 2>/dev/null | grep -qx "User=$USER" &&
[[ -f /etc/systemd/system/sync-steamos-session.path ]] ;;
gdm)
sed -n '/^\[daemon\]/,/^\[/p' /etc/gdm/custom.conf 2>/dev/null | grep -qx "AutomaticLogin=$USER" &&
[[ -f "$GDM_FIX_DIR/steam-set-session" ]] ;;
*) return 1 ;;
esac
}
@@ -108,7 +116,16 @@ gaming_enable() {
configure_autologin
install_session_sync
;;
gdm)
# GNOME (prototype): GDM autologin, plus CachyOS's session tools made GDM-aware.
remove_sddm_autologin
remove_session_sync
switch_to_gdm || return 1
configure_gdm_autologin || return 1
;;
esac
# CachyOS's own session tools only go to Plasma and only know SDDM and plasma-login-manager: with GNOME installed ours replace them.
if [[ "$LOGIN_MANAGER" == gdm ]] || desktop_installed gnome; then session_tools_install || return 1; fi
# (NVIDIA with single user mode from before the conversion: its desktop autologin would pin the Plasma session.)
single_login_release
create_desktop_shortcut
@@ -122,8 +139,13 @@ gaming_disable() {
info "Turning off booting into gaming mode..."
remove_sddm_autologin
remove_session_sync
restore_plasmalogin_config
switch_to_plasmalogin
session_tools_remove
if [[ "$(current_display_manager)" == gdm ]]; then
restore_gdm_config
else
restore_plasmalogin_config
switch_to_plasmalogin
fi
remove_desktop_shortcut
steam_disable
gsn_disable
@@ -297,3 +319,77 @@ install_session_sync() {
sudo cat "$BASE_CONF"
echo
}
switch_to_gdm() {
# Already the login manager on a GNOME install; this only makes sure it is installed and enabled.
[[ "$(current_display_manager)" == gdm ]] && return 0
info "Installing and enabling GDM..."
sudo pacman -S --needed --noconfirm gdm || { err "Installing gdm failed."; return 1; }
local current
current="$(systemctl show -p Id --value display-manager 2>/dev/null)"
[[ -n "$current" && "$current" != gdm.service ]] && sudo systemctl disable "$current"
sudo systemctl enable -f gdm.service || { err "Enabling gdm failed."; return 1; }
ok "GDM is the login manager from the next boot on."
}
configure_gdm_autologin() {
# [daemon] AutomaticLogin: GDM reads it when it starts, which is why the
# session tools restart GDM to log in again (see patches/steamify-gdm-session-select.sh).
info "Configuring GDM autologin for $TARGET_USER"
sudo mkdir -p /etc/gdm
sudo touch "$GDM_CONF"
[[ -f "$GDM_CONF.bak-steamify" ]] || sudo cp -a "$GDM_CONF" "$GDM_CONF.bak-steamify"
sudo awk '
/^\[daemon\]/ { print; indaemon=1; next }
/^\[/ { indaemon=0 }
indaemon && /^(AutomaticLoginEnable|AutomaticLogin)=/ { next }
{ print }
' "$GDM_CONF" | sudo tee "$GDM_CONF.tmp" > /dev/null
grep -q '^\[daemon\]' "$GDM_CONF.tmp" || printf '[daemon]\n' | sudo tee -a "$GDM_CONF.tmp" > /dev/null
sudo sed -i "/^\[daemon\]/a AutomaticLoginEnable=True\nAutomaticLogin=$TARGET_USER" "$GDM_CONF.tmp"
sudo mv "$GDM_CONF.tmp" "$GDM_CONF"
ok "GDM autologin configured."
}
restore_gdm_config() {
if [[ -f "$GDM_CONF.bak-steamify" ]]; then
sudo cp -a "$GDM_CONF.bak-steamify" "$GDM_CONF" && sudo rm -f "$GDM_CONF.bak-steamify"
else
sudo sed -i '/^AutomaticLoginEnable=/d;/^AutomaticLogin=/d' "$GDM_CONF" 2>/dev/null
fi
}
session_tools_install() {
# CachyOS's steam-set-session and steamos-session-select only know
# plasma-login-manager/SDDM and KDE. Ours replace them at the same paths
# (Steam's Switch to Desktop calls them by path); a pacman hook puts them
# back after every update of gamescope-session-cachyos.
info "Making the session switching GDM-aware..."
sudo mkdir -p "$GDM_FIX_DIR"
patch_file steamify-gdm-steam-set-session.sh | sudo install -Dm755 /dev/stdin "$GDM_FIX_DIR/steam-set-session" &&
patch_file steamify-gdm-session-select.sh |
sudo install -Dm755 /dev/stdin "$GDM_FIX_DIR/steamos-session-select" || { err "Installing the GDM session tools failed."; return 1; }
patch_file steamify-gdm.hook | fill DIR="$GDM_FIX_DIR" | sudo install -Dm644 /dev/stdin "$GDM_HOOK"
if [[ "$(current_display_manager)" == gdm || "$LOGIN_MANAGER" == gdm ]]; then
# steamos-session-select logs in again through this helper (no password: it runs from the gaming session and from a shortcut).
patch_file steamify-gdm-relogin.sh | sudo install -Dm755 /dev/stdin "$GDM_RELOGIN"
echo "$TARGET_USER ALL=(root) NOPASSWD: $GDM_RELOGIN" | sudo install -Dm440 /dev/stdin "$GDM_SUDOERS"
sudo visudo -cf "$GDM_SUDOERS" > /dev/null || { sudo rm -f "$GDM_SUDOERS"; err "The sudoers rule for GDM is invalid."; return 1; }
fi
for f in /usr/lib/steamos/steam-set-session /usr/bin/steamos-session-select; do
[[ -f "$f" && ! -f "$f.bak-steamify" ]] && sudo cp -a "$f" "$f.bak-steamify"
done
sudo install -m755 "$GDM_FIX_DIR/steam-set-session" /usr/lib/steamos/steam-set-session &&
sudo install -m755 "$GDM_FIX_DIR/steamos-session-select" /usr/bin/steamos-session-select || return 1
# Start in gamescope, as with the other login managers.
sudo /usr/lib/steamos/steam-set-session gamescope-session.desktop
ok "GDM autologin into gamescope is set up."
}
session_tools_remove() {
sudo rm -f "$GDM_HOOK" "$GDM_SUDOERS" "$GDM_RELOGIN"
for f in /usr/lib/steamos/steam-set-session /usr/bin/steamos-session-select; do
[[ -f "$f.bak-steamify" ]] && sudo mv "$f.bak-steamify" "$f"
done
sudo rm -rf "$GDM_FIX_DIR"
}
+8 -4
View File
@@ -5,7 +5,7 @@
# Menu order. Components are turned on in this order and off in reverse;
# gaming must come first (single user builds on it).
COMPONENTS=(gaming boot silent glyphs nvidia bigpicture nvsilent theme single launcher steamgame notify extended_controller_support vram cec machine poweroff kpin hdmi bios)
COMPONENTS=(gaming boot silent glyphs nvidia bigpicture nvsilent theme gnometheme single launcher steamgame notify extended_controller_support vram cec machine poweroff kpin hdmi bios)
# One-off actions rather than on/off components: never preselected, never
# re-applied, not listed as on or off.
ACTIONS=(bios)
@@ -26,7 +26,7 @@ NO_PRESELECT=(boot silent nvsilent cec kpin hdmi extended_controller_support)
# FEATURE_BASELINE.
FEATURE_BASELINE=2.1.0
declare -A FEATURE_VERSION=(
[gaming]=2.9.0 [boot]=2.1.0 [silent]=2.11.0 [nvidia]=2.12.0 [bigpicture]=2.10.0 [nvsilent]=2.11.0 [theme]=2.1.0 [glyphs]=2.1.0 [single]=2.1.0
[gaming]=2.9.0 [boot]=2.1.0 [silent]=2.11.0 [nvidia]=2.12.0 [bigpicture]=2.10.0 [nvsilent]=2.11.0 [theme]=2.1.0 [gnometheme]=2.12.0 [glyphs]=2.1.0 [single]=2.1.0
[launcher]=2.1.0 [cec]=2.7.0 [machine]=2.9.0 [poweroff]=2.2.0 [vram]=2.3.0 [notify]=2.5.0 [steamgame]=2.5.1 [extended_controller_support]=2.10.0
[kpin]=2.1.0 [hdmi]=2.1.0
)
@@ -39,6 +39,7 @@ declare -A LABEL=(
[nvsilent]="Start Steam silently: in the tray at login, no window (untick: Steam's normal window)"
[bigpicture]="Steam starts in Big Picture: the controller-friendly Steam (untick: Steam's normal window)"
[theme]="Install SteamOS theme: Vapor look (cachyos-vapor)"
[gnometheme]="Install SteamOS theme for GNOME: Vapor look (dark, blue accent, Steam Deck wallpaper)"
[glyphs]="Install Steam Deck/Machine icons: Deck button icons in gaming mode"
[single]="Single user mode: no password, lock screen or log out (SDDM)"
[launcher]="Steamify shortcut: the app on the desktop, Steamify Terminal in the launcher"
@@ -60,6 +61,10 @@ component_available() {
# The SteamOS conversion is offered on NVIDIA PCs too: it installs the patched gamescope there (lib/gamescope-nvidia.sh)
# and turns off "Gaming on NVIDIA" (lib/nvidia.sh), which is not offered any more (nvidia_available).
nvidia|bigpicture|nvsilent) nvidia_available ;;
# Plasma's Vapor theme and single user mode (KDE Wallet, screen locker, Plasma's menu): when Plasma is installed.
# The GNOME theme: when GNOME is. With both installed, each shows.
theme|single) desktop_installed kde ;;
gnometheme) desktop_installed gnome ;;
machine|poweroff) machine_available ;;
vram) vram_available ;;
# Steamify in the Steam library is for gaming mode's controller: not needed for Big Picture on the desktop (NVIDIA PCs;
@@ -503,8 +508,7 @@ plan_changes() {
apply_changes() {
local c failed=()
LOGIN_MANAGER=plasmalogin
[[ "${WANTED[single]}" == 1 ]] && LOGIN_MANAGER=sddm
choose_login_manager
for c in "${TO_DISABLE[@]}"; do
if [[ "$c" == boot ]]; then echo; echo -e "${c_bold}Boot into: gamescope${c_reset}"
+5 -3
View File
@@ -84,9 +84,11 @@ python_hid_shim_ensure() {
install_required_packages() {
# Step 2: gamescope/Steam and the desktop helpers the rest of the setup uses.
local -a MISSING
info "Checking required packages: gamescope-session-cachyos, steam, mangohud, xterm, ttf-liberation, wqy-zenhei, plasma-keyboard"
mapfile -t MISSING < <(pacman -T gamescope-session-cachyos steam mangohud xterm ttf-liberation wqy-zenhei plasma-keyboard)
local -a MISSING required=(gamescope-session-cachyos steam mangohud xterm ttf-liberation wqy-zenhei)
# Plasma's on-screen keyboard; on GNOME kconfig instead, for the kreadconfig6/kwriteconfig6 Steamify's undo journal uses.
if [[ "$(desktop_kind)" == gnome ]]; then required+=(kconfig accountsservice gnome-shell-extension-desktop-icons-ng gnome-shell-extension-appindicator extension-manager); else required+=(plasma-keyboard); fi
info "Checking required packages: ${required[*]}"
mapfile -t MISSING < <(pacman -T "${required[@]}")
if [[ ${#MISSING[@]} -gt 0 ]]; then
python_hid_shim_ensure || return 1
+34
View File
@@ -59,6 +59,40 @@ krevert() {
rm -f "$journal"
}
gs() {
# gsettings, also without a session (the installer's chroot): then in a
# session bus of its own, which writes the user's dconf database.
if user_session; then gsettings "$@"; else dbus-run-session -- gsettings "$@"; fi
}
gset() {
# gset <component> <schema> <key> <value>: gsettings (GNOME), recording the
# old value in the component's journal like kset does. <value> is in
# GVariant text form ('prefer-dark', true, 5). A key the schema lacks
# (newer GNOME only) is skipped, returning 1.
local component="$1" schema="$2" key="$3" value="$4"
local journal="$STATE_DIR/$component.gjournal" old id
gs get "$schema" "$key" >/dev/null 2>&1 || return 1
mkdir -p "$STATE_DIR"
id="$(printf '%s\t%s' "$schema" "$key")"
if ! grep -qxF -- "$id" <(cut -f1-2 "$journal" 2>/dev/null); then
old="$(gs get "$schema" "$key")"
printf '%s\t%s\n' "$id" "$(printf '%s' "$old" | base64 -w0)" >> "$journal"
fi
gs set "$schema" "$key" "$value"
}
grevert() {
# grevert <component>: put back every gsettings key the component changed.
local journal="$STATE_DIR/$1.gjournal" schema key old
[[ -f "$journal" ]] || return 0
while IFS=$'\t' read -r schema key old; do
old="$(printf '%s' "$old" | base64 -d)"
gs set "$schema" "$key" "$old" 2>/dev/null || gs reset "$schema" "$key" 2>/dev/null
done < <(tac "$journal")
rm -f "$journal"
}
has_journal() {
[[ -s "$STATE_DIR/$1.journal" ]]
}
+2 -2
View File
@@ -9,8 +9,8 @@ steam_enable() {
steam_env_dir="$HOME/.config/environment.d"
mkdir -p "$steam_env_dir"
# 2. Prevent KDE Wayland from blocking the virtual keyboard overlay
echo "KWIN_IM_SHOW_ALWAYS=1" > "$steam_env_dir/99-kde-virtual-keyboard.conf"
# 2. Prevent KDE Wayland from blocking the virtual keyboard overlay (KWin only)
[[ "$(desktop_kind)" == kde ]] && echo "KWIN_IM_SHOW_ALWAYS=1" > "$steam_env_dir/99-kde-virtual-keyboard.conf"
ok "Steam UI parameters and keyboard fix deployed successfully."
}
+4
View File
@@ -35,6 +35,9 @@ notify_enable() {
sudo pacman -S --needed --noconfirm "${missing[@]}" ||
{ err "Installing ${missing[*]} failed."; return 1; }
fi
# The single-color icon for GNOME's top bar tray.
patch_file steamify-symbolic.svg | install -D -m 644 /dev/stdin \
"${XDG_DATA_HOME:-$HOME/.local/share}/icons/hicolor/symbolic/apps/steamify-symbolic.svg"
patch_file steamify-notifier.py | install_executable "$NOTIFY_SCRIPT" 755 ||
{ err "Couldn't write $NOTIFY_SCRIPT."; return 1; }
mkdir -p "$NOTIFY_UNITS"
@@ -51,6 +54,7 @@ notify_enable() {
notify_disable() {
user_systemctl disable --now "$NOTIFY_NAME.timer" "$NOTIFY_NAME.service" >/dev/null 2>&1
rm -f "$NOTIFY_UNITS/$NOTIFY_NAME.service" "$NOTIFY_UNITS/$NOTIFY_NAME.timer" "$NOTIFY_SCRIPT"
rm -f "${XDG_DATA_HOME:-$HOME/.local/share}/icons/hicolor/symbolic/apps/steamify-symbolic.svg"
rmdir "$STEAMIFY_BIN" 2>/dev/null || true
user_systemctl daemon-reload
state_clear notify
+1 -1
View File
@@ -157,7 +157,7 @@ theme_disable() {
restart_plasmashell_if_stopped
qdbus6 org.kde.KWin /KWin org.kde.KWin.reconfigure >/dev/null 2>&1 || true
if [[ -n "$(state_get theme installed_pkg)" ]]; then
if [[ -n "$(state_get theme installed_pkg)" ]] && ! gnometheme_status; then
# Fails, and stays installed, when another package (e.g.
# cachyos-handheld) depends on it.
sudo pacman -R --noconfirm cachyos-vapor >/dev/null 2>&1 ||
+21 -4
View File
@@ -22,6 +22,18 @@ WIZARD_TERMINAL_ENTRY="$WIZARD_APPS/steamify-terminal.desktop"
# Before 2.0.1 the shortcut opened the terminal menu under this name.
WIZARD_OLD_NAME="cachyos-gamescope-boot-wizard.desktop"
wizard_terminal() {
# The command prefix that runs a program in a terminal window: Konsole on
# Plasma, on GNOME whichever of Ptyxis, Console or GNOME Terminal is there.
if [[ "$(desktop_kind)" == gnome ]]; then
if command -v ptyxis >/dev/null; then echo "ptyxis --"
elif command -v kgx >/dev/null; then echo "kgx -e"
else echo "gnome-terminal --"; fi
else
echo "konsole -e"
fi
}
wizard_desktop_dir() {
xdg-user-dir DESKTOP 2>/dev/null || echo "$HOME/Desktop"
}
@@ -47,6 +59,8 @@ launcher_status() {
launcher_repair() { [[ -f "$WIZARD_APPS/$WIZARD_OLD_NAME" ]] && ! launcher_status; }
launcher_enable() {
local terminal
terminal="$(wizard_terminal)"
info "Adding the Steamify shortcut (the app on the desktop and in the launcher, Steamify Terminal in the launcher)..."
install_executable "$WIZARD_LAUNCHER" 755 << EOF
#!/bin/bash
@@ -70,18 +84,18 @@ echo
EOF
# The app, without a terminal. Only the first time, when PySide6 still
# has to be installed, it runs in Konsole: sudo asks for the password there.
# has to be installed, it runs in a terminal: sudo asks for the password there.
install_executable "$WIZARD_APP_LAUNCHER" 755 << EOF
#!/bin/bash
# Installed by Steamify CachyOS: start the newest release of its app.
set -o pipefail
if [[ "\${1:-}" != --in-terminal ]] && ! python3 -c 'import PySide6.QtQml' 2>/dev/null; then
exec konsole -e "\$0" --in-terminal
exec $terminal "\$0" --in-terminal
fi
if ! curl -fsSL --max-time 30 "$WIZARD_APP_URL" | bash; then
msg="Couldn't download or start Steamify. Are you connected to the internet?"
if [[ "\${1:-}" == --in-terminal ]]; then echo; echo "\$msg"; read -rp "Press Enter to close this window... " _
else kdialog --title Steamify --sorry "\$msg" 2>/dev/null; fi
else kdialog --title Steamify --sorry "\$msg" 2>/dev/null || zenity --error --title Steamify --text "\$msg" 2>/dev/null; fi
exit 1
fi
EOF
@@ -107,14 +121,17 @@ Exec=$WIZARD_APP_LAUNCHER
Icon=$icon
Terminal=false
Categories=Game;System;Settings;
StartupWMClass=steamify-ui
X-Steamify-Shortcut=true"
printf '%s\n' "$entry" | install_executable "$WIZARD_APP_ENTRY" 644
printf '%s\n' "$entry" | install_executable "$(wizard_desktop_dir)/$WIZARD_DESKTOP_NAME" 755
# GNOME only starts desktop launchers it trusts.
gio set "$(wizard_desktop_dir)/$WIZARD_DESKTOP_NAME" metadata::trusted true 2>/dev/null || true
printf '%s\n' "[Desktop Entry]
Type=Application
Name=Steamify Terminal
Comment=Steamify CachyOS's menu in a terminal
Exec=konsole -e $WIZARD_LAUNCHER
Exec=$terminal $WIZARD_LAUNCHER
Icon=$icon
Terminal=false
Categories=Game;System;Settings;" | install_executable "$WIZARD_TERMINAL_ENTRY" 644
+22
View File
@@ -0,0 +1,22 @@
#!/bin/bash
# Log the autologin user in again, into the session steam-set-session picked
# (Steamify prototype, GDM). Run as root through sudo, from inside the session
# that is being left. GDM logs in by itself only when the daemon starts, and
# a new session refuses to start while the old user manager still runs
# ("A graphical session is already running!"): so the user is ended first,
# then GDM restarted. That work runs in its own transient unit, because
# ending the user kills this process too.
if [[ "$1" != --work ]]; then
[[ -n "${SUDO_USER:-}" ]] || exit 1
exec systemd-run --no-block --collect --unit=steamify-gdm-relogin "$0" --work "$SUDO_USER"
fi
USER_NAME="$2"
# GDM is stopped first, so its login screen doesn't show while the old user
# manager shuts down; a new login right away fails ("A graphical session is
# already running!", or the session dies at once), so wait until it is gone.
systemctl stop gdm.service
loginctl terminate-user "$USER_NAME"
# (not `loginctl show-user`: it still lists the user about 10 s after it is gone)
USER_RUNTIME="/run/user/$(id -u "$USER_NAME")"
for _ in $(seq 120); do [[ -d "$USER_RUNTIME" ]] || break; sleep 0.25; done
systemctl start gdm.service
+49
View File
@@ -0,0 +1,49 @@
#!/bin/bash
# steamos-session-select for GNOME (Steamify prototype): CachyOS's own ends the
# session with a KDE-only D-Bus call and goes to Plasma only. GDM logs in by itself only when it
# starts, so after the new session is set the user is ended and GDM restarted
# (patches/steamify-gdm-relogin.sh): it then logs the autologin user straight into it.
set -e
DM_ID="$(systemctl show -p Id --value display-manager)"
DM_ID="${DM_ID%.service}"
relogin() {
# Out of the running session into the one that was set.
case "$DM_ID" in
gdm) sudo -n /usr/local/libexec/steamify-gdm-relogin ;;
*)
# sddm and plasma-login-manager log in again by themselves (Relogin=true): just end the session.
if [[ "${XDG_CURRENT_DESKTOP:-}" == *GNOME* ]]; then gnome-session-quit --no-prompt --logout
else qdbus6 org.kde.Shutdown /Shutdown org.kde.Shutdown.logout; fi ;;
esac
}
case "$1" in
persistent)
systemctl --user mask cachyos-gamescope-autologin.service
pkexec /usr/lib/steamos/steam-set-session desktop ;;
oneshot)
systemctl --user unmask cachyos-gamescope-autologin.service
pkexec /usr/lib/steamos/steam-set-session gamescope-session.desktop ;;
gamescope)
pkexec /usr/lib/steamos/steam-set-session gamescope-session.desktop
relogin ;;
desktop|plasma|gnome)
# desktop: the preferred one; plasma or gnome: that one.
case "$1" in plasma) target=plasma.desktop ;; gnome) target=gnome.desktop ;; *) target=desktop ;; esac
pkexec /usr/lib/steamos/steam-set-session "$target"
steam -shutdown || true
systemctl --user stop gamescope-session.target || true
# Under GDM nothing logs in again by itself after the session ends.
[[ "$DM_ID" == gdm ]] && relogin ;;
*)
[[ -n "$1" ]] && echo -e "Unknown session '$1'\n"
echo "Usage: $(basename "$0") persistent|oneshot|gamescope|desktop"
exit 1 ;;
esac
if [[ -e /dev/input/.hidden ]]; then
pkexec mv /dev/input/.hidden/* /dev/input
pkexec rm -r /dev/input/.hidden
fi
+66
View File
@@ -0,0 +1,66 @@
#!/bin/bash
# steam-set-session with GDM support (Steamify prototype). CachyOS's own only
# knows plasma-login-manager and SDDM and quietly does nothing on GDM. GDM
# has no autologin fragment: it takes the user's session from
# AccountsService, so that is where the session goes.
set -e
DM_ID="$(systemctl show -p Id --value display-manager)"
DM_ID="${DM_ID%.service}"
SESSION="${1:-gamescope-session.desktop}"
# "desktop" is the desktop to go back to: the one chosen in Steamify (/etc/steamify/desktop: kde, gnome or last),
# else the one used last (recorded below when leaving it for gamescope), else whichever is installed.
have_session() { [[ -f "/usr/share/wayland-sessions/$1" || -f "/usr/share/xsessions/$1" ]]; }
resolve_desktop() {
local pref last
pref="$(cat /etc/steamify/desktop 2>/dev/null || true)"
last="$(cat /var/lib/steamify/last-desktop 2>/dev/null || true)"
[[ -z "$pref" || "$pref" == last ]] && pref="$last"
case "$pref" in
gnome) have_session gnome.desktop && { echo gnome.desktop; return; } ;;
kde) have_session plasma.desktop && { echo plasma.desktop; return; } ;;
esac
have_session plasma.desktop && { echo plasma.desktop; return; }
echo gnome.desktop
}
remember_desktop() {
# Leaving a desktop for gamescope: which desktop it was, from the shell the user is running.
local uid="${PKEXEC_UID:-}" kind
[[ -n "$uid" ]] || return 0
if pgrep -u "$uid" -x gnome-shell >/dev/null; then kind=gnome
elif pgrep -u "$uid" -x plasmashell >/dev/null; then kind=kde
else return 0; fi
mkdir -p /var/lib/steamify && echo "$kind" > /var/lib/steamify/last-desktop
}
[[ "$SESSION" == desktop ]] && SESSION="$(resolve_desktop)"
[[ "$SESSION" == gamescope-session* ]] && remember_desktop
case "$DM_ID" in
plasmalogin) CONF_FILE="/etc/plasmalogin.conf.d/zz-steamos-autologin.conf" ;;
sddm) CONF_FILE="/etc/sddm.conf.d/zz-steamos-autologin.conf" ;;
gdm)
if [[ -n "${PKEXEC_UID:-}" ]]; then TARGET_USER="$(id -un "$PKEXEC_UID")"
else TARGET_USER="${SUDO_USER:-}"; fi
# (|| true: logname fails without a login, and set -e would end the script before the fallback.)
[[ -n "$TARGET_USER" ]] || TARGET_USER="$(logname 2>/dev/null || true)"
# At boot (steamify-boot-desktop.service) nobody is logged in: the autologin user.
[[ -n "$TARGET_USER" ]] || TARGET_USER="$(sed -n 's/^AutomaticLogin=//p' /etc/gdm/custom.conf 2>/dev/null)"
[[ -n "$TARGET_USER" ]] || exit 0
ACCOUNT="/var/lib/AccountsService/users/$TARGET_USER"
SESSION_ID="${SESSION%.desktop}"
mkdir -p /var/lib/AccountsService/users
touch "$ACCOUNT"
grep -q '^\[User\]' "$ACCOUNT" || echo "[User]" >> "$ACCOUNT"
for key in Session XSession; do
if grep -q "^$key=" "$ACCOUNT"; then sed -i "s|^$key=.*|$key=$SESSION_ID|" "$ACCOUNT"
else sed -i "/^\[User\]/a $key=$SESSION_ID" "$ACCOUNT"; fi
done
systemctl restart accounts-daemon 2>/dev/null || true
exit 0 ;;
esac
# Any other login manager: nothing to do.
[[ -n "${CONF_FILE:-}" ]] || exit 0
mkdir -p "$(dirname "$CONF_FILE")"
printf '[Autologin]\nSession=%s\n' "$SESSION" > "$CONF_FILE"
+10
View File
@@ -0,0 +1,10 @@
[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = gamescope-session-cachyos
[Action]
Description = Steamify: GDM support for gamescope-session-cachyos...
When = PostTransaction
Exec = /bin/sh -c 'install -m755 @DIR@/steam-set-session /usr/lib/steamos/steam-set-session && install -m755 @DIR@/steamos-session-select /usr/bin/steamos-session-select'
+29
View File
@@ -0,0 +1,29 @@
/* Steamify Vapor: libadwaita/GTK4 colors. In the dark style: Vapor's palette (cachyos-vapor, Vapor.colors);
* in the light style (Settings > Appearance): libadwaita's own light colors, with Vapor's blue accent. */
@define-color accent_bg_color #2a8fd0;
@define-color accent_fg_color #ffffff;
@define-color accent_color #1b6ea7;
@media (prefers-color-scheme: dark) {
@define-color accent_bg_color #569fcc;
@define-color accent_fg_color #1f1f26;
@define-color accent_color #3daee9;
@define-color window_bg_color #24272c;
@define-color window_fg_color #eff0f1;
@define-color view_bg_color #151c23;
@define-color view_fg_color #eff0f1;
@define-color headerbar_bg_color #24272c;
@define-color headerbar_fg_color #eff0f1;
@define-color card_bg_color #2a2e32;
@define-color popover_bg_color #2a2e32;
@define-color sidebar_bg_color #1f2328;
@define-color dialog_bg_color #2a2e32;
}
/* Menus without the arrow pointing at the cursor (like Ubuntu's). */
popover.menu > arrow {
min-width: 0;
min-height: 0;
background: none;
border: none;
box-shadow: none;
}
+44
View File
@@ -0,0 +1,44 @@
/* Steamify Vapor: the SteamOS look for GNOME Shell, loaded by the Steamify Vapor
* extension on top of the stock theme: the palette of the Vapor theme (KDE Plasma's SteamOS look, cachyos-vapor). */
/* Top bar: Vapor's panel color. */
#panel,
#panel.lock-screen,
#panel.unlock-screen {
background-color: #24272c;
}
#panel .panel-button { color: #eff0f1; }
#panel .panel-button:hover,
#panel .panel-button:focus,
#panel .panel-button:active,
#panel .panel-button:checked,
#panel .panel-button:overview {
background-color: rgba(86, 159, 204, 0.35);
color: #eff0f1;
}
/* Popups and the calendar (the dock keeps Ubuntu's own look). */
.popup-menu-content,
.candidate-popup-content,
.message-list-clear-button {
background-color: #24272c;
}
.popup-menu-item:hover,
.popup-menu-item:focus,
.popup-menu-item:active {
background-color: rgba(86, 159, 204, 0.35);
}
/* Selection and focus in Vapor's blue. */
.app-well-app:focus .overview-icon,
.app-well-app:selected .overview-icon,
.overview-tile:focus,
.overview-tile:selected,
.search-entry:focus {
background-color: rgba(86, 159, 204, 0.3);
border-color: #3daee9;
}
.button:focus,
.check-box:focus StBin { border-color: #3daee9; }
.slider { color: #3daee9; }
.workspace-thumbnail-indicator { border-color: #3daee9; }
+33 -7
View File
@@ -8,6 +8,7 @@
import configparser
import json
import os
import shutil
import subprocess
import sys
import threading
@@ -56,10 +57,35 @@ def pending(new):
def desktop():
# Only on the Plasma desktop: gamescope doesn't show notifications or a
# tray, so an update found in gaming mode waits for the next desktop login.
return subprocess.run(["pgrep", "-u", str(os.getuid()), "-x", "plasmashell"],
stdout=subprocess.DEVNULL).returncode == 0
# Only on the Plasma or GNOME desktop: gamescope doesn't show notifications
# or a tray, so an update found in gaming mode waits for the next desktop login.
return any(subprocess.run(["pgrep", "-u", str(os.getuid()), "-x", shell],
stdout=subprocess.DEVNULL).returncode == 0
for shell in ("plasmashell", "gnome-shell"))
def terminal():
# The command prefix that runs a program in a terminal window.
for program, prefix in (("konsole", ["konsole", "-e"]), ("ptyxis", ["ptyxis", "--"]),
("kgx", ["kgx", "-e"]), ("gnome-terminal", ["gnome-terminal", "--"])):
if shutil.which(program):
return prefix
return ["xterm", "-e"]
def tray_icon():
# Steamify's icon: the single-color one in GNOME's top bar (it draws its tray icons that way),
# the colored one elsewhere; Steam's own only when neither is installed.
from PySide6.QtGui import QIcon
icons = os.path.join(DATA, "icons", "hicolor")
names = ["symbolic/apps/steamify-symbolic.svg", "scalable/apps/steamify.svg"]
if "GNOME" not in os.environ.get("XDG_CURRENT_DESKTOP", ""):
names.reverse()
for name in names:
path = os.path.join(icons, name)
if os.path.exists(path):
return QIcon(path)
return QIcon.fromTheme("steamify", QIcon.fromTheme("steam"))
def main():
@@ -83,7 +109,7 @@ def main():
app.setApplicationName("Steamify")
app.setDesktopFileName("steamify-ui")
app.setQuitOnLastWindowClosed(False)
icon = QIcon.fromTheme("steamify", QIcon.fromTheme("steam"))
icon = tray_icon()
def open_app():
# The way Steamify was last used (the app or the terminal menu), the
@@ -91,8 +117,8 @@ def main():
# ends the reminder. In its own unit: this one's processes are
# stopped when the check exits.
if state("frontend") == "terminal":
cmd = ["konsole", "-e", RUN_TERMINAL] if os.access(RUN_TERMINAL, os.X_OK) else \
["konsole", "-e", "bash", "-c",
cmd = [*terminal(), RUN_TERMINAL] if os.access(RUN_TERMINAL, os.X_OK) else \
[*terminal(), "bash", "-c",
f"set -o pipefail; curl -fsSL --max-time 30 {RELEASE}/steamify.sh | bash; read -rp 'Press Enter to close. ' _"]
else:
cmd = [RUN_APP] if os.access(RUN_APP, os.X_OK) else \
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"><g fill="#bebebe"><path d="m 26.586,23.6632 8.104641,-0.4201 1.91027,-6.7552 -5.59099,-4.4419 -6.871493,5.8329 z"/><path d="M 31.027515,23.9946 35,23 l 1.976562,-2.9766 -4,-4 -4.949047,4.9712 z"/><path d="M 15.316486,35.7061 21.675457,35.065 23.0333,27.5143 16.403747,25.7462 12.603749,30.3195 Z"/><path d="m 16.985332,35.8717 3.972485,-0.4165 2.210937,-3.4453 -3.0625,-3.1563 -6.933422,3.9868 z"/><path d="m 30.5,11 c -4.142135,0 -7.499999,3.357864 -7.5,7.5 0.0017,0.201484 0.01143,0.402819 0.0293,0.603516 -1.289636,1.575722 -4.80544,5.546997 -5.113281,5.902343 -2.416761,0.03284 -4.577852,1.51258 -5.482422,3.753907 -1.237432,3.074241 0.2518,6.569519 3.326172,7.80664 3.074245,1.237417 6.56952,-0.251813 7.80664,-3.326172 0.274389,-0.686886 0.419405,-1.418587 0.427735,-2.158203 l 5.896484,-5.111328 C 30.093269,25.98873 30.296562,25.998503 30.5,26 34.642135,26 37.999999,22.642136 38,18.5 37.999999,14.357864 34.642135,11 30.5,11 Z m 0,3 c 2.48528,0 4.499999,2.014718 4.5,4.5 -10e-7,2.485282 -2.01472,4.5 -4.5,4.5 -2.48528,0 -4.499999,-2.014718 -4.5,-4.5 1e-6,-2.485282 2.01472,-4.5 4.5,-4.5 z M 18.046875,27 c 0.496175,0.0058 0.986949,0.103774 1.447266,0.289062 2.049689,0.825003 3.042263,3.155585 2.216797,5.205079 -0.825003,2.049668 -3.155579,3.04224 -5.205079,2.216797 C 14.45617,33.885935 13.463596,31.555353 14.289062,29.505859 14.905127,27.975627 16.397393,26.980525 18.046875,27 Z"/><circle cx="30.5" cy="18.4998" r="3.5"/><path d="M 5.0722656,22.564453 A 19,19 0 0 0 5,24 19,19 0 0 0 5.7695312,29.3125 l 11.1113278,4.470703 a 3,3 0 0 0 3.902344,-1.664062 3,3 0 0 0 -1.664062,-3.902344 z"/><path d="M 40.440,33.688 L 42.527,33.983 L 42.527,36.007 L 40.440,36.302 L 39.770,37.921 L 41.037,39.606 L 39.606,41.037 L 37.921,39.770 L 36.302,40.440 L 36.007,42.527 L 33.983,42.527 L 33.688,40.440 L 32.069,39.770 L 30.384,41.037 L 28.953,39.606 L 30.220,37.921 L 29.550,36.302 L 27.463,36.007 L 27.463,33.983 L 29.550,33.688 L 30.220,32.069 L 28.953,30.384 L 30.384,28.953 L 32.069,30.220 L 33.688,29.550 L 33.983,27.463 L 36.007,27.463 L 36.302,29.550 L 37.921,30.220 L 39.606,28.953 L 41.037,30.384 L 39.770,32.069 Z M 37.395,34.995 A 2.4,2.4 0 1 0 32.595,34.995 A 2.4,2.4 0 1 0 37.395,34.995 Z"/></g></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

+28
View File
@@ -0,0 +1,28 @@
// Steamify Vapor (Steamify GNOME theme). Its stylesheet.css, which GNOME Shell loads
// by itself, is the SteamOS look. This code: GNOME opens the overview after login;
// Ubuntu starts on the desktop. So does this: the overview stays closed while the
// shell starts up, and is available again right after.
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import {Extension} from 'resource:///org/gnome/shell/extensions/extension.js';
export default class SteamifyDesktopStart extends Extension {
enable() {
if (!Main.layoutManager._startingUp)
return;
this._hadOverview = Main.sessionMode.hasOverview;
Main.sessionMode.hasOverview = false;
this._startupId = Main.layoutManager.connect('startup-complete', () => {
Main.sessionMode.hasOverview = this._hadOverview;
Main.overview.hide();
});
}
disable() {
if (this._startupId) {
Main.layoutManager.disconnect(this._startupId);
this._startupId = null;
}
if (this._hadOverview !== undefined)
Main.sessionMode.hasOverview = this._hadOverview;
}
}
+14
View File
@@ -0,0 +1,14 @@
{
"uuid": "steamify-vapor@steamify.github.io",
"name": "Steamify Vapor",
"description": "The SteamOS (Vapor) look for the shell, and log in to the desktop, not the overview.",
"shell-version": [
"45",
"46",
"47",
"48",
"49",
"50",
"51"
]
}
+2 -2
View File
@@ -1,10 +1,10 @@
[Unit]
Description=Steamify CachyOS: boot into the desktop instead of gaming mode
Before=display-manager.service sddm.service plasmalogin.service
Before=display-manager.service sddm.service plasmalogin.service gdm.service
[Service]
Type=oneshot
ExecStart=/usr/lib/steamos/steam-set-session plasma.desktop
ExecStart=/usr/lib/steamos/steam-set-session @DESKTOP_SESSION@
ExecStart=/bin/sh -c '[ -x @SESSION_SYNC@ ] && exec @SESSION_SYNC@ || true'
[Install]
+11 -1
View File
@@ -19,7 +19,7 @@ VERSION=2.12.0
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
for lib in common state packages login-manager single-user steam-desktop steam-machine fremont-poweroff vram-booster hdmi-refresh nvidia gamescope-nvidia controllers cec boot-session vapor-theme steamos-extras bios desktop-shortcut wizard-shortcut steam-game update-notifier first-login menu backend; do
for lib in common state desktop packages login-manager single-user steam-desktop steam-machine fremont-poweroff vram-booster hdmi-refresh nvidia gamescope-nvidia controllers cec boot-session vapor-theme gnome-theme steamos-extras bios desktop-shortcut wizard-shortcut steam-game update-notifier first-login menu backend; do
# shellcheck source=/dev/null
source "$SCRIPT_DIR/lib/$lib.sh"
done
@@ -137,6 +137,16 @@ if [[ "$LIST" == true ]]; then
exit 0
fi
# --desktop kde|gnome|last: which desktop "Switch to Desktop" goes to (when both are installed).
if [[ "${1:-}" == --desktop ]]; then
case "${2:-}" in
kde|gnome|last) ;;
*) err "--desktop takes kde, gnome or last (the one you used last)"; exit 1 ;;
esac
desktop_pref_set "$2" || exit 1
ok "Switch to Desktop goes to: $2."
exit 0
fi
if [[ "$DEFAULTS" == true ]]; then
RESTART_FOR_LOGIN=false
REAPPLY=false
+3
View File
@@ -25,6 +25,9 @@ QtObject {
theme: { label: "SteamOS theme", hint: "Vapor look for the desktop, Add to Steam",
body: "The Vapor look of SteamOS for the desktop, with its panel, launcher icon and wallpaper.",
changes: ["cachyos-vapor global theme", "Add to Steam in right-click menus", "Nested Desktop, Steam keyboard window rule"] },
gnometheme: { label: "SteamOS theme for GNOME", hint: "Vapor look, Ubuntu-style dock and desktop icons",
body: "The Vapor look of SteamOS for GNOME: dark or light style with Vapor's blue, the Steam Deck wallpapers in Settings, the top bar in Vapor's panel color, and the extensions Ubuntu uses (Ubuntu Dock, desktop icons, tray icons, tiling).",
changes: ["Colors for GTK4 apps and the shell (a stylesheet extension)", "Ubuntu Dock, Tiling Assistant, Desktop Icons NG, AppIndicator", "SteamOS wallpapers in GNOME Settings", "Window buttons with minimize and maximize", "Off: your settings and files are put back"] },
glyphs: { label: "Steam Deck/Machine icons", hint: "Deck button icons in gaming mode",
body: "Steam shows Steam Deck button icons in gaming mode.", changes: ["STEAM_GAMEPADUI_ARGS -steamos3"] },
single: { label: "Single user mode", hint: "No password, lock screen or wallet prompts",