diff --git a/README.md b/README.md index 494b8a6..b964c57 100644 --- a/README.md +++ b/README.md @@ -431,6 +431,27 @@ See [Recovery from a Black Screen](#recovery-from-a-black-screen) for how to get - Check PipeWire config exists: `cat /etc/pipewire/pipewire.conf.d/10-gaming-latency.conf` - Try lower quantum: edit the config and set `default.clock.min-quantum = 128` +**Screen sharing in Chromium / Firefox is broken after returning from Gaming Mode (only "Share a tab" works)** + +`xdg-desktop-portal-hyprland` is bound to the killed Hyprland instance — tab capture works because it bypasses the portal, but desktop/window capture goes through it and fails silently. + +DeckShift handles this automatically via `/usr/local/bin/deckshift-portal-recovery` (autostarted from `~/.config/hypr/autostart.conf`). If you installed before this fix or the autostart hook didn't get added, run: + +```bash +systemctl --user restart xdg-desktop-portal-hyprland xdg-desktop-portal pipewire pipewire-pulse wireplumber +``` + +then re-open the browser tab. + +**Suspend fails with "Access denied" after returning from Gaming Mode** + +The runtime mask on `suspend.target` from the gaming switch wasn't cleared. DeckShift now handles this in `switch-to-desktop`. For older installs, the one-time fix is: + +```bash +sudo systemctl unmask --runtime sleep.target suspend.target hibernate.target hybrid-sleep.target +sudo systemctl daemon-reload +``` + **Power profile stays on `performance` after Gaming Mode exit** If you're on AC and using Omarchy, this is expected — see the *Performance Mode* caveat above. The deckshift restore is correctly running; Omarchy's session-init policy is overriding it on the next Hyprland start. diff --git a/deckshift.sh b/deckshift.sh index 887bcf3..404c756 100755 --- a/deckshift.sh +++ b/deckshift.sh @@ -2286,6 +2286,14 @@ fi sleep 2 +# Marker for the next Hyprland startup — tells deckshift-portal-recovery +# that we're returning from Gaming Mode and the xdg-desktop-portal stack +# needs a kick. Without this, Chromium/Firefox screen-sharing on Wayland +# silently fails (only tab-sharing works) because the portal is still bound +# to the killed Hyprland instance. /tmp survives SDDM restart; /run/user +# does not (logind tears down the user manager). +touch /tmp/.deckshift-just-returned 2>/dev/null || true + sudo -n chvt 2 2>/dev/null || true sleep 0.5 # Atomic restart — stop+start (with stop and start as separate sudo calls) @@ -2402,6 +2410,61 @@ KEYBIND_MONITOR sudo chmod +x "$keybind_monitor" info "Created $keybind_monitor" + # Portal Recovery Helper — runs at every Hyprland startup + # + # When switch-to-desktop restarts SDDM, the new Hyprland instance gets a + # fresh HYPRLAND_INSTANCE_SIGNATURE, but xdg-desktop-portal-hyprland (and + # the pipewire stack) may still be bound to the old, dead instance. The + # symptom is Chromium/Firefox "Share desktop / window" failing silently on + # Google Meet etc. while "Share a tab" still works (because tab capture + # bypasses the portal entirely). + # + # switch-to-desktop drops /tmp/.deckshift-just-returned right before the + # SDDM restart. This helper, run as exec-once from Hyprland's autostart, + # checks for that marker on every Hyprland start, and if present, bounces + # the portal + pipewire user services so they reattach to the live HIS. + # No marker = no-op (cheap; runs in milliseconds). + info "Creating portal recovery helper..." + local portal_recovery="/usr/local/bin/deckshift-portal-recovery" + + sudo tee "$portal_recovery" > /dev/null << 'PORTAL_RECOVERY' +#!/bin/bash +[[ -f /tmp/.deckshift-just-returned ]] || exit 0 +rm -f /tmp/.deckshift-just-returned + +# Give the new Hyprland a moment to fully come up and the user manager to +# import HYPRLAND_INSTANCE_SIGNATURE / WAYLAND_DISPLAY into its environment. +sleep 2 + +systemctl --user restart \ + xdg-desktop-portal-hyprland.service \ + xdg-desktop-portal.service \ + pipewire.service \ + pipewire-pulse.service \ + wireplumber.service 2>/dev/null || true +PORTAL_RECOVERY + + sudo chmod +x "$portal_recovery" + info "Created $portal_recovery" + + # Hyprland autostart hook for portal recovery + local hypr_autostart="${user_home}/.config/hypr/autostart.conf" + if [[ -f "$hypr_autostart" ]]; then + if grep -q "deckshift-portal-recovery" "$hypr_autostart" 2>/dev/null; then + info "Portal recovery already wired into autostart.conf" + else + sudo -u "$current_user" tee -a "$hypr_autostart" > /dev/null << 'HYPR_PORTAL' + +# DeckShift — restart xdg-desktop-portal stack after returning from Gaming Mode +exec-once = /usr/local/bin/deckshift-portal-recovery +HYPR_PORTAL + info "Added portal recovery exec-once to $hypr_autostart" + fi + else + warn "autostart.conf not found at $hypr_autostart — portal recovery not auto-wired" + warn "Add manually: exec-once = /usr/local/bin/deckshift-portal-recovery" + fi + # SDDM Session Switching Config # # SDDM supports auto-login — it can automatically log in a user to a @@ -2660,6 +2723,7 @@ verify_installation() { ["/usr/local/bin/switch-to-gaming"]="755:Hyprland to Gaming Mode switcher" ["/usr/local/bin/switch-to-desktop"]="755:Gaming Mode to Desktop switcher (Super+Shift+R)" ["/usr/local/bin/gaming-keybind-monitor"]="755:Keybind monitor for Super+Shift+R" + ["/usr/local/bin/deckshift-portal-recovery"]="755:xdg-desktop-portal restart helper (post-Gaming-Mode)" ["/usr/local/bin/gamescope-nm-start"]="755:NetworkManager start script" ["/usr/local/bin/gamescope-nm-stop"]="755:NetworkManager stop script" ["/usr/local/bin/steam-library-mount"]="755:Steam library drive auto-mount script"