mirror of
https://github.com/DeeJanuz/frametop.git
synced 2026-10-06 01:00:06 +02:00
Let the headset sleep with the helper idle; keep the container out of our units
With the pointer released, the helper still listed overlays by running vrcmd every second, a new SteamVR client each time, which kept SteamVR from going to standby. The list now pauses while the pointer is off. Starting the dev container from one of our services made that service own it, so stopping the service stopped the container and the desktop's compositor with it. scripts/container-up.sh starts the container in a systemd scope of its own before every distrobox enter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
938dabe9c4
commit
4d845492e7
9 files changed
+40
-4
No files matched your search
@@ -10,6 +10,7 @@ case $wl in /*) ;; *) wl="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/$wl" ;; esac
|
||||
session_bus=${DBUS_SESSION_BUS_ADDRESS:-}
|
||||
export XDG_RUNTIME_DIR=/run/user/$(id -u)
|
||||
export DBUS_SESSION_BUS_ADDRESS=unix:path=$XDG_RUNTIME_DIR/bus
|
||||
"$here/../scripts/container-up.sh"
|
||||
exec "$HOME/.local/bin/distrobox" enter dev -- env WAYLAND_DISPLAY="$wl" DISPLAY="${DISPLAY:-}" \
|
||||
XAUTHORITY="${XAUTHORITY:-}" DBUS_SESSION_BUS_ADDRESS="$session_bus" \
|
||||
QT_QPA_PLATFORM="wayland;xcb" \
|
||||
|
||||
@@ -106,6 +106,8 @@ Keyboard: still open. SteamVR opens keyboards (vrserver held the Z3 Keyboard), b
|
||||
|
||||
## Findings log
|
||||
|
||||
- 2026-09-26: The headset's displays didn't sleep when it came off (SteamVR reports the HMD idle the moment it's removed, and turns the screens off 5 s later, `power.turnOffScreensTimeout`). A removal test that stopped one piece every 20 s found the pointer helper: standby 5 s after it stopped, nothing from hiding the screens or stopping the relay. Two causes in the helper: an awake pointer (connected controller, laser mode forced on) until 30 s without mouse input, and, even with the pointer released, its background `vrcmd --overlays` every second, a new SteamVR client connection each time (the per-second "External connection from /run/host/opt/steamvr/.../vrcmd" lines in vrcompositor.txt; `/run/host` is the container's view of the host). Now the helper releases the pointer when `GetTrackedDeviceActivityLevel(HMD)` is Idle, Standby, or Idle_Timeout, won't wake until it's worn again, and pauses the overlay list while the pointer is off. Separately: a podman container's monitor (conmon) stays in the cgroup of whatever started it, and `distrobox enter` from a systemd service starts the container on demand, so stopping frametop-pointer (which had started it at boot) killed the container, and with it the desktop's compositor. `scripts/container-up.sh` starts the container in a scope of its own before every `distrobox enter` (services, session, apps, build scripts).
|
||||
|
||||
- 2026-09-26: Screens over VR games. Visible screens with VROverlayFlags_MakeOverlaysInteractiveIfVisible keep SteamVR's laser mouse on, which takes the controllers from a VR game. `IVRApplications::GetCurrentSceneProcessId()` is 0 with no game (the Frame's home isn't a scene app) and the game's pid while one runs, so ft-screens clears the flag while it's nonzero (checked twice a second; the `controllers` setting, default outside_games). Tested in a VR game: the screens stay up over it, the controllers stay in the game, and the screens take the lasers again while the SteamVR dashboard is open.
|
||||
|
||||
- 2026-09-26: Programs that stop their own helpers when their window closes still lose them on a desktop restart, even after keep-apps.sh moved them out of the unit (22 processes moved, all gone 7 s later when the compositor went): nothing outside the app can keep them. Run such work somewhere independent of the desktop, like a systemd user service. Controls: shown only while some controller ray passes within max(1.5 x button, 12% of the bar) of a control (5 points along the bar, each button, the tab), 0.4 s linger; a zone covering the lower quarter of the screen showed them whenever a screen was in use.
|
||||
|
||||
@@ -10,6 +10,7 @@ case $wl in /*) ;; *) wl="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/$wl" ;; esac
|
||||
session_bus=${DBUS_SESSION_BUS_ADDRESS:-}
|
||||
export XDG_RUNTIME_DIR=/run/user/$(id -u)
|
||||
export DBUS_SESSION_BUS_ADDRESS=unix:path=$XDG_RUNTIME_DIR/bus
|
||||
"$here/../scripts/container-up.sh"
|
||||
exec "$HOME/.local/bin/distrobox" enter dev -- env WAYLAND_DISPLAY="$wl" DISPLAY="${DISPLAY:-}" \
|
||||
XAUTHORITY="${XAUTHORITY:-}" DBUS_SESSION_BUS_ADDRESS="$session_bus" \
|
||||
QT_QPA_PLATFORM="wayland;xcb" \
|
||||
|
||||
@@ -9,6 +9,9 @@ PartOf=steamvr.service
|
||||
[Service]
|
||||
# Runs in the dev container (built there against its libraries). The helper process
|
||||
# lives in the container, so clean it up explicitly around distrobox enter.
|
||||
# Start the container in a scope of its own first: started by this service (distrobox enter
|
||||
# does that on demand), stopping the service would stop the container and all in it.
|
||||
ExecStartPre=-@REPO@/scripts/container-up.sh
|
||||
ExecStartPre=-/usr/bin/pkill -x ft-pointer
|
||||
ExecStart=%h/.local/bin/distrobox enter dev -- @REPO@/pointer/helper/build/ft-pointer
|
||||
ExecStopPost=-/usr/bin/pkill -x ft-pointer
|
||||
|
||||
@@ -32,7 +32,9 @@
|
||||
// It's restored when a controller takes the pointer back.
|
||||
//
|
||||
// Headset off: when SteamVR says nobody is wearing the headset, the pointer is released and
|
||||
// stays off until it's worn again, so the displays can sleep (see the main loop).
|
||||
// stays off until it's worn again, so the displays can sleep (see the main loop). While the
|
||||
// pointer is off the helper also stops listing overlays with vrcmd, whose connection every
|
||||
// second kept SteamVR from going to standby.
|
||||
//
|
||||
// Last used wins: when a real controller moves (picked up), the pointer is released
|
||||
// at once (driver "hide", which also drops its hand role hint), so the controller gets
|
||||
@@ -194,16 +196,24 @@ void SendTo(int fd, const char *name, const std::string &msg) {
|
||||
// public call to enumerate other apps' overlays). Hidden ones are listed too: the
|
||||
// window controls under a floating panel only appear while something hovers the
|
||||
// panel, and the cursor has to find them the moment they do, not a second later.
|
||||
// Paused while the pointer is off: each vrcmd run connects to SteamVR as a new app, and a new
|
||||
// app every second kept SteamVR (and the headset's displays) from going to standby.
|
||||
class OverlayList {
|
||||
public:
|
||||
void Start() {
|
||||
thread_ = std::thread([this] {
|
||||
while (running_) {
|
||||
Refresh();
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
if (!paused_) Refresh();
|
||||
// Wait a second, or less when the pointer wakes (refresh right away then).
|
||||
for (int i = 0; i < 10 && running_; ++i) {
|
||||
const bool wasPaused = paused_;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
if (wasPaused && !paused_) break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
void SetPaused(bool paused) { paused_ = paused; }
|
||||
void Stop() {
|
||||
running_ = false;
|
||||
if (thread_.joinable()) thread_.join();
|
||||
@@ -239,6 +249,7 @@ private:
|
||||
}
|
||||
|
||||
std::thread thread_;
|
||||
std::atomic<bool> paused_{false};
|
||||
std::atomic<bool> running_{true};
|
||||
std::mutex lock_;
|
||||
std::vector<std::string> keys_;
|
||||
@@ -686,6 +697,9 @@ int main() {
|
||||
claimHeld = false;
|
||||
}
|
||||
|
||||
// The overlay list is only needed while the pointer is awake (see OverlayList).
|
||||
overlays.SetPaused(!active || headsetOff);
|
||||
|
||||
// Laser mode on while the pointer is awake.
|
||||
if (active != laserModeShown) {
|
||||
laserModeShown = active;
|
||||
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
# Runs on the Frame host. Starts the dev container, if it isn't running, in a systemd scope
|
||||
# of its own. Whoever starts a podman container owns its monitor (conmon): started from one
|
||||
# of our services (distrobox enter starts it on demand), the container, and everything in it
|
||||
# like the desktop's compositor, would be killed when that service stops. Call this before
|
||||
# `distrobox enter`.
|
||||
box=${FRAME_BOX:-dev}
|
||||
export XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR:-/run/user/$(id -u)}
|
||||
[ "$(podman container inspect -f '{{.State.Running}}' "$box" 2>/dev/null)" = true ] && exit 0
|
||||
podman container exists "$box" 2>/dev/null || exit 0 # not created yet: setup/dev-container.sh does that
|
||||
exec systemd-run --user --scope --quiet --collect --description="$box container (started for Frametop)" \
|
||||
podman start "$box" >/dev/null
|
||||
+2
-1
@@ -30,6 +30,7 @@ if [ "$FRAME_LOCAL" = 1 ]; then
|
||||
if [ "$on_host" = 1 ]; then
|
||||
exec bash -c "$*"
|
||||
fi
|
||||
"$REPO_ROOT/scripts/container-up.sh" # in a scope of its own, not this shell's session
|
||||
exec "$HOME/.local/bin/distrobox" enter "$FRAME_BOX" -- bash -lc "$*"
|
||||
fi
|
||||
|
||||
@@ -39,5 +40,5 @@ if [ "$on_host" = 1 ]; then
|
||||
exec ssh "${tty[@]}" "$FRAME_HOST" "cd $(printf %q "$dir") && $*"
|
||||
else
|
||||
exec ssh "${tty[@]}" "$FRAME_HOST" \
|
||||
"cd $(printf %q "$dir") && ~/.local/bin/distrobox enter $(printf %q "$FRAME_BOX") -- bash -lc $(printf %q "$*")"
|
||||
"$(printf %q "$FRAME_REPO")/scripts/container-up.sh; cd $(printf %q "$dir") && ~/.local/bin/distrobox enter $(printf %q "$FRAME_BOX") -- bash -lc $(printf %q "$*")"
|
||||
fi
|
||||
@@ -69,6 +69,7 @@ if [ "${1:-}" != --inner ]; then
|
||||
socket=ft-screens-0
|
||||
read -ra screen_args <<< "$("$here/../layout/ft-layout" screen-args)"
|
||||
export FT_SCREEN_COUNT=$(( ${#screen_args[@]} / 2 ))
|
||||
"$here/../scripts/container-up.sh" # not owned by this desktop, or stopping it would stop the container
|
||||
"$HOME/.local/bin/distrobox" enter dev -- "$here/../screens/build/ft-screens" --socket "$socket" \
|
||||
"${screen_args[@]}" > /tmp/frametop-screens.log 2>&1 < /dev/null &
|
||||
stop_screens() { pkill -x ft-screens 2>/dev/null || true; }
|
||||
|
||||
@@ -34,6 +34,7 @@ if ! podman container exists dev; then
|
||||
echo "creating the dev container (Fedora 44 toolbox)"
|
||||
"$distrobox" create --yes --name dev --image registry.fedoraproject.org/fedora-toolbox:44
|
||||
fi
|
||||
"$root/scripts/container-up.sh"
|
||||
"$distrobox" enter dev -- bash -c '
|
||||
set -euo pipefail
|
||||
echo "installing ${#@} packages (already-installed ones are skipped)"
|
||||
|
||||
Reference in new issue
Block a user