mirror of
https://github.com/lhns/steam-frame-nix.git
synced 2026-10-06 04:04:16 +02:00
README keeps intro, feature list linking docs/, install, two sessions, usage, the complete options table, changes outside Nix, rollback, uninstall. Each feature's details (problem, what you get, configuration, limitations, how it works) move to its own page in docs/; docs/dashboard.md is split per feature and docs/changes-outside-nix.md becomes docs/cleanup.md.
86 lines
3.7 KiB
Markdown
86 lines
3.7 KiB
Markdown
# Window curvature
|
||
|
||
`dashboard.windowCurvature.*`, module `window-curvature` ([options](../README.md#options)).
|
||
|
||
A [SteamVR dashboard patch](ui-patches.md#steamvr-dashboard-patches).
|
||
|
||
## Problem
|
||
|
||
SteamVR dashboard windows are either curved (fixed radius) or flat, and
|
||
world windows start flat.
|
||
|
||
## What you get
|
||
|
||
The "Toggle Curvature" row of a window's three-dot menu becomes a control
|
||
showing the window's value; the same control in the bottom bar (see
|
||
[window control bar](window-control-bar.md)) works without the value, with
|
||
haptic steps.
|
||
|
||
- **click:** curved → flat, flat → stock (1);
|
||
- **drag up/down** with the laser: curvature from 0 (flat) to `max`,
|
||
relative to stock (2 = half the radius), rounded to `step`, with a detent
|
||
of `detentPixels` of drag at each of `detentPoints` (no values skipped),
|
||
and haptics (`haptics`) for detents, edges and steps. Drag distance:
|
||
`dragPixelsPerUnit` in the menu, `barDragPixelsPerUnit` on the bar button,
|
||
after `dragThresholdPixels`.
|
||
|
||
A window without its own value is shown at `initial` once curved in the
|
||
world or on a hand, at 1 in the dashboard or theater. Values are kept per
|
||
window until SteamVR restarts.
|
||
|
||
## Configuration
|
||
|
||
```nix
|
||
steamFrame.dashboard.windowCurvature = {
|
||
enable = true;
|
||
# initial = 1.0; max = 3.0; step = 0.05;
|
||
# detentPoints = [ 0 1.0 ]; detentPixels = 24;
|
||
# dragPixelsPerUnit = 60; # full range in one drag (see below)
|
||
};
|
||
```
|
||
|
||
## Limitations
|
||
|
||
- Laser only; with gamepad navigation the row is the stock toggle.
|
||
- No thumbstick scrolling (SteamVR sends no wheel events to the menu).
|
||
- The laser stops at the menu's edge (~190 px above the row): with the
|
||
default 120 px per 1.0, 0 → 1 fits into one drag, 0 → 3 takes two. Lower
|
||
`dragPixelsPerUnit` (≤ 60) for the full range in one drag.
|
||
|
||
## How it works
|
||
|
||
Stock curvature: the frame renders a transform `frame:<id>:curvature-origin`
|
||
at `z = DashboardStore.curvatureDistance` when curved, else 1000; its panels
|
||
reference it as `curvature-origin-id` and vrcompositor bends them onto a
|
||
cylinder around it (curvature = 1/radius). Those MobX properties are
|
||
non-configurable, so the patch hooks the mailbox `SendMessage`
|
||
([shared hooks](ui-patches.md#shared-method-hooks), shared with
|
||
[dashboard windows](dashboard-windows.md)) and rewrites the origin's z in
|
||
outgoing scene graphs to stock / value. On/off stays the stock toggle state,
|
||
so stock toggle and wheel always agree.
|
||
|
||
Values are kept per window (key: first overlay key) in
|
||
`window.__sfuiWindowCurvatureState`, across re-patch and unpatch, not across
|
||
a dashboard reload. The bar button uses the coordinates SteamVR keeps
|
||
sending past the pressed panel's edge while the trigger is held; the bar
|
||
panel is never resized.
|
||
|
||
Debugging: `window.__sfuiWindowCurvature.dump()` (`.log` recent events).
|
||
|
||
### Contract for other patches
|
||
|
||
For patches handling presses on the curvature controls (e.g. the window
|
||
control bar's long press): every element the patch drives has class
|
||
`sfui-curv-ctl`; when a press becomes a drag, a bubbling `CustomEvent`
|
||
`sfui-curv-dragstart` (detail `{ frameID, where: 'menu' | 'bar' }`) is
|
||
dispatched on it, and `sfui-curv-dragend` when it ends;
|
||
`window.__sfuiWindowCurvature.scalePressDragThreshold(factor)` sets the
|
||
current press's drag threshold to `factor` × `dragThresholdPixels` (from the
|
||
press start; returns whether it applied, i.e. a press that is not yet a
|
||
drag); `window.__sfuiWindowCurvature.cancelPress()` ends a press without its
|
||
click. A patch with its own gesture lets `mousemove` through while
|
||
undecided, drops its gesture on `sfui-curv-dragstart`, may raise the
|
||
threshold while its gesture is under way, and calls `cancelPress()` when it
|
||
takes the press over. The window control bar uses factor 3 once its
|
||
progress ring shows.
|