mirror of
https://github.com/theupriser/steamify-cachyos.git
synced 2026-10-15 21:15:24 +02:00
Merge pull request #89 from theupriser/feature/gnome-relogin-auto
App: a run that only needs a GNOME login ends with a countdown and logs in again
This commit is contained in:
5 files changed
+60
-5
No files matched your search
@@ -16,6 +16,8 @@ one per merged pull request.
|
|||||||
- **feat: after the GNOME theme is applied in a GNOME session, the app's done screen has "Restart GNOME" (GNOME Shell on Wayland can't restart in place, and the dock, extensions and Settings panel only show after a new login): with GDM autologin (the SteamOS conversion) Steamify's relogin helper logs the user straight back into the session they were in (without changing the session gaming mode's boot goes back to), else it is a plain logout (`gnome-session-quit`)**
|
- **feat: after the GNOME theme is applied in a GNOME session, the app's done screen has "Restart GNOME" (GNOME Shell on Wayland can't restart in place, and the dock, extensions and Settings panel only show after a new login): with GDM autologin (the SteamOS conversion) Steamify's relogin helper logs the user straight back into the session they were in (without changing the session gaming mode's boot goes back to), else it is a plain logout (`gnome-session-quit`)**
|
||||||
- **fix: the app on a desktop (a window, however large, also fullscreen) keeps the desktop's own scale instead of blowing its 1280x720 layout up to the screen's height (twice as big on a 1440p or ultrawide monitor): the layout fills the window at the scale of GNOME or KDE, and only a window smaller than 1280x720 shrinks it. The TV mode (`--fullscreen`, gamescope) still scales to the screen**
|
- **fix: the app on a desktop (a window, however large, also fullscreen) keeps the desktop's own scale instead of blowing its 1280x720 layout up to the screen's height (twice as big on a 1440p or ultrawide monitor): the layout fills the window at the scale of GNOME or KDE, and only a window smaller than 1280x720 shrinks it. The TV mode (`--fullscreen`, gamescope) still scales to the screen**
|
||||||
- **fix: in the app a click on a row only selects it (a second click on the selected row used to flip it, so a click on a switch needed two); a click on the switch itself, or on the BIOS update button, acts at once and selects the row too**
|
- **fix: in the app a click on a row only selects it (a second click on the selected row used to flip it, so a click on a switch needed two); a click on the switch itself, or on the BIOS update button, acts at once and selects the row too**
|
||||||
|
- **feat: a run that only needs a new GNOME login (the theme, no reboot) ends with a countdown on the done screen ("Restarting GNOME in 10 s", with Restart GNOME now and Cancel) and then logs in again by itself, the counterpart of KDE restarting plasmashell (GNOME Shell on Wayland is the compositor too and can't restart in place). A run that needs a reboot keeps "Restart now" (it loads GNOME fresh): before, the Restart GNOME button was hidden then, and nothing started by itself**
|
||||||
|
- **fix: Restart GNOME logs in to GNOME: after the SteamOS conversion the account's session is gaming mode, and the relogin went there (a restart that took a minute: Steam starting in gaming mode). `steamify-gdm-relogin` takes the session to log in to (the one the app runs in) for this login only and puts the account's session, the one the next boot goes to, back once the new session is up**
|
||||||
|
|
||||||
## 2.12.0 - 2026-10-13
|
## 2.12.0 - 2026-10-13
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -123,7 +123,7 @@ gnometheme_relogin() {
|
|||||||
# steamos-session-select, which would make GNOME the one gaming mode's boot goes back to). Without that helper there
|
# steamos-session-select, which would make GNOME the one gaming mode's boot goes back to). Without that helper there
|
||||||
# is no autologin: a plain logout, and the user logs in again.
|
# is no autologin: a plain logout, and the user logs in again.
|
||||||
local helper=/usr/local/libexec/steamify-gdm-relogin
|
local helper=/usr/local/libexec/steamify-gdm-relogin
|
||||||
if [[ -x "$helper" ]] && sudo -n "$helper"; then return 0; fi
|
if [[ -x "$helper" ]] && sudo -n "$helper" "${XDG_SESSION_DESKTOP:-gnome}"; then return 0; fi
|
||||||
gnome-session-quit --logout --no-prompt
|
gnome-session-quit --logout --no-prompt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,36 @@
|
|||||||
# ("A graphical session is already running!"): so the user is ended first,
|
# ("A graphical session is already running!"): so the user is ended first,
|
||||||
# then GDM restarted. That work runs in its own transient unit, because
|
# then GDM restarted. That work runs in its own transient unit, because
|
||||||
# ending the user kills this process too.
|
# ending the user kills this process too.
|
||||||
|
#
|
||||||
|
# An optional session id as the argument ("gnome"): that session is logged in
|
||||||
|
# for this time only. The session in AccountsService (what the next boot goes
|
||||||
|
# to: gaming mode after the SteamOS conversion) is put back once the new
|
||||||
|
# session is up.
|
||||||
if [[ "$1" != --work ]]; then
|
if [[ "$1" != --work ]]; then
|
||||||
[[ -n "${SUDO_USER:-}" ]] || exit 1
|
[[ -n "${SUDO_USER:-}" ]] || exit 1
|
||||||
exec systemd-run --no-block --collect --unit=steamify-gdm-relogin "$0" --work "$SUDO_USER"
|
exec systemd-run --no-block --collect --unit=steamify-gdm-relogin "$0" --work "$SUDO_USER" "${1:-}"
|
||||||
fi
|
fi
|
||||||
USER_NAME="$2"
|
USER_NAME="$2"
|
||||||
|
SESSION="$3"
|
||||||
|
ACCOUNT="/var/lib/AccountsService/users/$USER_NAME"
|
||||||
|
|
||||||
|
# Session= and XSession= of the user, as GDM reads them at the next login.
|
||||||
|
get_session() { sed -n "s/^$1=//p" "$ACCOUNT" 2>/dev/null | head -1; }
|
||||||
|
set_session() {
|
||||||
|
local key
|
||||||
|
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=$1|" "$ACCOUNT"
|
||||||
|
else sed -i "/^\[User\]/a $key=$1" "$ACCOUNT"; fi
|
||||||
|
done
|
||||||
|
systemctl restart accounts-daemon 2>/dev/null || true
|
||||||
|
}
|
||||||
|
if [[ -n "$SESSION" ]]; then
|
||||||
|
OLD_SESSION="$(get_session Session)"; OLD_XSESSION="$(get_session XSession)"
|
||||||
|
set_session "${SESSION%.desktop}"
|
||||||
|
fi
|
||||||
|
|
||||||
# GDM is stopped first, so its login screen doesn't show while the old user
|
# 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
|
# 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.
|
# already running!", or the session dies at once), so wait until it is gone.
|
||||||
@@ -20,3 +45,14 @@ loginctl terminate-user "$USER_NAME"
|
|||||||
USER_RUNTIME="/run/user/$(id -u "$USER_NAME")"
|
USER_RUNTIME="/run/user/$(id -u "$USER_NAME")"
|
||||||
for _ in $(seq 120); do [[ -d "$USER_RUNTIME" ]] || break; sleep 0.25; done
|
for _ in $(seq 120); do [[ -d "$USER_RUNTIME" ]] || break; sleep 0.25; done
|
||||||
systemctl start gdm.service
|
systemctl start gdm.service
|
||||||
|
|
||||||
|
if [[ -n "$SESSION" ]]; then
|
||||||
|
# The new session has read what it logs in to once its user manager runs; then the next boot's session goes back.
|
||||||
|
for _ in $(seq 120); do [[ -d "$USER_RUNTIME" ]] && break; sleep 0.25; done
|
||||||
|
sleep 8
|
||||||
|
if [[ -n "$OLD_SESSION" ]]; then
|
||||||
|
sed -i "s|^Session=.*|Session=$OLD_SESSION|" "$ACCOUNT"
|
||||||
|
if [[ -n "$OLD_XSESSION" ]]; then sed -i "s|^XSession=.*|XSession=$OLD_XSESSION|" "$ACCOUNT"; fi
|
||||||
|
systemctl restart accounts-daemon 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
+17
-2
@@ -7,10 +7,24 @@ import QtQuick.Controls.Basic
|
|||||||
Item {
|
Item {
|
||||||
required property AppState app
|
required property AppState app
|
||||||
readonly property bool problem: app.failed.length > 0 || app.runError !== ""
|
readonly property bool problem: app.failed.length > 0 || app.runError !== ""
|
||||||
|
// GNOME Shell on Wayland can't restart in place (it is the compositor too), so what a KDE run does for plasmashell is a
|
||||||
|
// new login here: started by itself after a countdown, unless the run needs a reboot anyway (which does the same).
|
||||||
|
readonly property bool relogin: app.reloginNeeded && !app.restartNeeded && !problem
|
||||||
|
property int countdown: 10
|
||||||
|
property bool cancelled: false
|
||||||
|
property bool fired: false
|
||||||
|
readonly property bool counting: relogin && !cancelled && !fired
|
||||||
|
onVisibleChanged: if (visible) { countdown = 10; cancelled = false; fired = false; }
|
||||||
|
function reloginNow() { fired = true; app.backend.restartGnome(); }
|
||||||
|
Timer {
|
||||||
|
interval: 1000; repeat: true; running: parent.visible && parent.counting
|
||||||
|
onTriggered: { parent.countdown -= 1; if (parent.countdown <= 0) parent.reloginNow(); }
|
||||||
|
}
|
||||||
readonly property string message: {
|
readonly property string message: {
|
||||||
if (app.runError) return app.runError;
|
if (app.runError) return app.runError;
|
||||||
if (!app.biosRun) return app.plan.length + (app.plan.length === 1 ? " change" : " changes") + " applied." + (app.restartNeeded ? " Some take effect after a restart." : "")
|
if (!app.biosRun) return app.plan.length + (app.plan.length === 1 ? " change" : " changes") + " applied." + (app.restartNeeded ? " Some take effect after a restart." : "")
|
||||||
+ (app.reloginNeeded && !app.restartNeeded ? " GNOME shows the dock, extensions and Settings panel after you log in again: Restart GNOME does that." : "");
|
+ (counting ? " Restarting GNOME in " + countdown + " s, so it loads the new dock, extensions and Settings panel."
|
||||||
|
: (relogin ? " GNOME shows the dock, extensions and Settings panel after you log in again." : ""));
|
||||||
if (app.failed.length) return "The BIOS was not changed.";
|
if (app.failed.length) return "The BIOS was not changed.";
|
||||||
return (app.bios && app.bios.dryRun ? "Dry run: nothing was flashed. " : "BIOS " + (app.biosInfo.newest || "") + " is staged and is written during the restart. ")
|
return (app.bios && app.bios.dryRun ? "Dry run: nothing was flashed. " : "BIOS " + (app.biosInfo.newest || "") + " is staged and is written during the restart. ")
|
||||||
+ "Keep the power on and don't touch the machine until it has fully started again, even if the screen stays black.";
|
+ "Keep the power on and don't touch the machine until it has fully started again, even if the screen stays black.";
|
||||||
@@ -35,6 +49,7 @@ Item {
|
|||||||
Row { anchors.horizontalCenter: parent.horizontalCenter; spacing: 14; topPadding: 8
|
Row { anchors.horizontalCenter: parent.horizontalCenter; spacing: 14; topPadding: 8
|
||||||
Btn { k: Input.g.back; text: "Back to the menu"; height: 52; onClicked: app.act("back") }
|
Btn { k: Input.g.back; text: "Back to the menu"; height: 52; onClicked: app.act("back") }
|
||||||
Btn { visible: app.restartNeeded; k: Input.g.ok; text: "Restart now"; primary: true; height: 52; onClicked: app.backend.restart() }
|
Btn { visible: app.restartNeeded; k: Input.g.ok; text: "Restart now"; primary: true; height: 52; onClicked: app.backend.restart() }
|
||||||
Btn { visible: app.reloginNeeded && !app.restartNeeded; k: Input.g.ok; text: "Restart GNOME"; primary: true; height: 52; onClicked: app.backend.restartGnome() } }
|
Btn { visible: relogin; k: Input.g.ok; text: counting ? "Restart GNOME now" : "Restart GNOME"; primary: true; height: 52; onClicked: reloginNow() }
|
||||||
|
Btn { visible: counting; text: "Cancel"; height: 52; onClicked: cancelled = true } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
-1
@@ -351,7 +351,9 @@ class Backend(QObject):
|
|||||||
# Steamify's helper logs the user straight back in; else a plain logout.
|
# Steamify's helper logs the user straight back in; else a plain logout.
|
||||||
import subprocess
|
import subprocess
|
||||||
helper = "/usr/local/libexec/steamify-gdm-relogin"
|
helper = "/usr/local/libexec/steamify-gdm-relogin"
|
||||||
if os.access(helper, os.X_OK) and subprocess.run(["sudo", "-n", helper], capture_output=True).returncode == 0:
|
# The session this one is, for this login only: the default (gaming mode, after the conversion) would log in there.
|
||||||
|
session = os.environ.get("XDG_SESSION_DESKTOP") or "gnome"
|
||||||
|
if os.access(helper, os.X_OK) and subprocess.run(["sudo", "-n", helper, session], capture_output=True).returncode == 0:
|
||||||
return
|
return
|
||||||
QProcess.startDetached("gnome-session-quit", ["--logout", "--no-prompt"])
|
QProcess.startDetached("gnome-session-quit", ["--logout", "--no-prompt"])
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user