mirror of
https://github.com/DeeJanuz/frametop.git
synced 2026-10-04 22:00:05 +02:00
Remove leftovers before a release
- gaze/tracker/lab/eyes_track.py: nothing used it - Input Settings: the pointer role backend, whose page was removed - ft-screens: no log line for every floating-window resize - hands: ft-hands --help gives the palm-down default (1: off), the uninstall removes ft-handsctl's link, .frame-job is ignored - Display Settings: "Save as profile…", not "Save current arrangement" - two stale comments (ft-pointer's grabprobe, ft-gaze) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3da17bc838
commit
0ac2b10cd7
10 files changed
+14
-70
No files matched your search
@@ -445,7 +445,7 @@ class Backend(QObject):
|
||||
f"{reply or 'the desktop is not running'}", True)
|
||||
elif which == "all" and where != "none":
|
||||
place = "on your head" if where == "head" else f"on your {where} wrist"
|
||||
self.message.emit(f"All screens ride {place} now. Save current arrangement (Layout) keeps it.", False)
|
||||
self.message.emit(f"All screens ride {place} now. Save as profile… (Layout & profiles) keeps it.", False)
|
||||
self._check_running()
|
||||
|
||||
# --- power: ft-powerd and Steam's sleep setting ---
|
||||
|
||||
@@ -411,8 +411,8 @@ Kirigami.ApplicationWindow {
|
||||
text: spage.md
|
||||
? "Each screen is a real monitor of its own: any resolution, portrait by choosing a tall one. Resolution, "
|
||||
+ "width, and curve apply at once. In VR: move a screen by the bar underneath, curve it with the round "
|
||||
+ "button next to the bar, resize it by the tab on its bottom right corner; Save current arrangement on the "
|
||||
+ "Layout page keeps all of it."
|
||||
+ "button next to the bar, resize it by the tab on its bottom right corner; Save as profile… on the "
|
||||
+ "Layout & profiles page keeps all of it."
|
||||
: "gamescope draws every screen at the same resolution, at most 1920 × 1080 worth of pixels. Portrait turns "
|
||||
+ "a screen on its side. Rotation and scale apply at once; the rest when the desktop starts."
|
||||
}
|
||||
@@ -949,7 +949,7 @@ Kirigami.ApplicationWindow {
|
||||
+ "it.\n\nPin a screen to your head: choose On your head above. It rides on the headset where it "
|
||||
+ "is now, like a HUD, and shows whenever the screens do. Grab its bar to move it; it stays on "
|
||||
+ "your head where you let go. Choosing a pin above keeps the screen where it is now, so place "
|
||||
+ "it first. Save current arrangement (Layout) keeps pins."
|
||||
+ "it first. Save as profile… (Layout) keeps pins."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// ft-gaze: the headset's eye tracking as rays and Frametop screen pixels (OpenVR overlay
|
||||
// client, runs in the dev container). An experiment for gaze input; ft-gazeprobe reads it.
|
||||
// client, runs in the dev container). The gaze service (ft-gazed) and the gaze probe run it.
|
||||
//
|
||||
// Every eye tracker sample (90 Hz) becomes one JSON line on stdout with each gaze source
|
||||
// hit-tested against the Frametop screens:
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
"""Per-frame pupil ellipses through a recording, cached in the capture (numbers only).
|
||||
|
||||
ellipses(cap) -> {camera: array of rows (t, x, y, a, b, major, fill, glint mid x, y)}, every
|
||||
EVERY-th frame of each camera; the glint midpoint is NaN when the pair isn't seen.
|
||||
"""
|
||||
import numpy as np
|
||||
|
||||
import eyes_lab # noqa: F401 (puts gaze/tracker on the path)
|
||||
import eyes_pupil
|
||||
|
||||
EVERY = 2
|
||||
VERSION = 2
|
||||
|
||||
|
||||
def load_index(cap):
|
||||
return np.array([[float(v) for v in l.split()]
|
||||
for l in (cap / "index.txt").read_text().splitlines() if len(l.split()) == 4])
|
||||
|
||||
|
||||
def ellipses(cap):
|
||||
cache = cap / f"ellipses-v{VERSION}.npz"
|
||||
if cache.exists():
|
||||
z = np.load(cache)
|
||||
return {0: z["cam0"], 1: z["cam1"]}
|
||||
idx = load_index(cap)
|
||||
frames = np.memmap(cap / "frames.raw", dtype=np.uint8, mode="r").reshape(-1, 400, 512)
|
||||
idx = idx[:len(frames)]
|
||||
out = {}
|
||||
for c in (0, 1):
|
||||
rows, prev = [], None
|
||||
for i in np.where(idx[:, 2] == c)[0][::EVERY]:
|
||||
p = eyes_pupil.find_pupil(frames[i], prev)
|
||||
prev = p
|
||||
if p is None:
|
||||
continue
|
||||
pair = eyes_pupil.glint_pair(p)
|
||||
mx, my = ((pair[0][0] + pair[1][0]) / 2, (pair[0][1] + pair[1][1]) / 2) if pair else (np.nan, np.nan)
|
||||
rows.append((idx[i, 3], p["x"], p["y"], p["a"], p["b"], p["major"], p["fill"], mx, my))
|
||||
out[c] = np.array(rows).reshape(-1, 9)
|
||||
np.savez(cache, cam0=out[0], cam1=out[1])
|
||||
return out
|
||||
@@ -1,3 +1,5 @@
|
||||
# Model sources that tools/convert_models.py downloads; the converted ncnn models are kept
|
||||
models/onnx/
|
||||
models/*.task
|
||||
# frame-job settings (where replays run, and the lab's capture folder): personal, not shipped
|
||||
.frame-job
|
||||
+2
-1
@@ -54,7 +54,8 @@ mkdir -p ~/.local/bin && ln -sfn $(printf %q "$FRAME_REPO/hands/ft-handsctl") ~/
|
||||
$states; echo 'start it with: ft-handsctl on'" ;;
|
||||
caps) set_caps ;;
|
||||
uninstall) "$frame" --host "systemctl --user disable --now $units 2>/dev/null
|
||||
for u in $units; do rm -f ~/.config/systemd/user/\$u; done; systemctl --user daemon-reload; echo removed" ;;
|
||||
for u in $units; do rm -f ~/.config/systemd/user/\$u; done; systemctl --user daemon-reload
|
||||
[ -L ~/.local/bin/ft-handsctl ] && rm -f ~/.local/bin/ft-handsctl; echo removed" ;;
|
||||
start|stop|restart) "$frame" --host "systemctl --user $1 $units; $states" ;;
|
||||
status) "$frame" --host "$states; journalctl --user -u frametop-hands.service --no-pager -o cat -n 4" || true ;;
|
||||
log) "$frame" --host "journalctl --user -u frametop-camd.service -u frametop-hands.service --no-pager -o short -n ${2:-30}" ;;
|
||||
|
||||
@@ -221,7 +221,7 @@ int main(int argc, char **argv) {
|
||||
" [--keep-presence P] (0.5) [--ring PATH] (ft-camd's, or ft-ringplay's)\n"
|
||||
" [--cams auto|mono|color|all] (auto) [--bright all|color] (all) [--bright-on L] (40) [--bright-off L] (25)\n"
|
||||
" [--color-left color_video0|color_video3] [--color-crop subtract|none]\n"
|
||||
" [--pinch-begin M] (0.020) [--pinch-end M] (0.035) [--pinch-triangulated] [--pinch-palm-down MAX] (0.6)\n"
|
||||
" [--pinch-begin M] (0.020) [--pinch-end M] (0.035) [--pinch-triangulated] [--pinch-palm-down MAX] (1: off)\n"
|
||||
" [--grip-begin R] (1.2) [--grip-end R] (1.45) [--gesture-log]\n"
|
||||
" [--contrast MODE|PALM/HAND] (clahe[:CLIP], none, stretch; default clahe:2/none)\n"
|
||||
"Recording saves every frame set for S seconds (120) to DIR/sets.bin, for ft-handreplay; SIGUSR1\n"
|
||||
|
||||
@@ -138,8 +138,6 @@ GAZE_SETTINGS = [
|
||||
# In gaze mode, what the mouse's left button does (POINTER_GAZE_MOUSE).
|
||||
GAZE_MOUSE = {"precision": "Gaze precision: hold to steer with the mouse, release to click",
|
||||
"direct": "Click right away where the pointer is"}
|
||||
# The hand role the pointer's virtual controller takes (POINTER_ROLE).
|
||||
POINTER_ROLES = {"right": "Right hand", "left": "Left hand", "stylus": "Stylus (no hand)"}
|
||||
# Key combinations ("key_bindings" in the rules): modifiers, either side folded into the left code.
|
||||
MODIFIER_CODES = {29: 29, 97: 29, 42: 42, 54: 42, 56: 56, 100: 56, 125: 125, 126: 125}
|
||||
MODIFIER_NAMES = {29: "Ctrl", 42: "Shift", 56: "Alt", 125: "Meta"}
|
||||
@@ -885,23 +883,6 @@ class Backend(QObject):
|
||||
self.pointerChanged.emit()
|
||||
self.message.emit("Gaze dot: " + ("always shown" if on else "shown only while the mouse moves it"), False)
|
||||
|
||||
@Property(str, notify=pointerChanged)
|
||||
def pointerRole(self):
|
||||
v = read_conf().get("POINTER_ROLE", "right")
|
||||
return v if v in POINTER_ROLES else "right"
|
||||
|
||||
@Property("QVariantList", constant=True)
|
||||
def pointerRoles(self):
|
||||
return [{"value": k, "text": v} for k, v in POINTER_ROLES.items()]
|
||||
|
||||
@Slot(str)
|
||||
def setPointerRole(self, role):
|
||||
if role in POINTER_ROLES:
|
||||
write_conf_value("POINTER_ROLE", role)
|
||||
self.reload_timer.start()
|
||||
self.pointerChanged.emit()
|
||||
self.message.emit(f"Pointer role: {POINTER_ROLES[role].lower()} (from its next wake)", False)
|
||||
|
||||
# --- key combinations ("key_bindings") ---
|
||||
def comboName(self, combo):
|
||||
parts = [int(c) for c in combo.split("+") if c.isdigit()]
|
||||
|
||||
@@ -1139,8 +1139,8 @@ int main() {
|
||||
return "";
|
||||
};
|
||||
|
||||
// Spike: aim down from the panel's bottom edge, 1 cm a step, and log where SteamVR's
|
||||
// laser hits something (the hit dot shows) and whether the window controls are up.
|
||||
// grabprobe (maintenance): aim down from the panel's bottom edge, 1 cm a step, and log where
|
||||
// SteamVR's laser hits something (the hit dot shows) and whether the window controls are up.
|
||||
auto grabProbe = [&](const char *key) {
|
||||
Panel p;
|
||||
Vec3 eye;
|
||||
|
||||
+2
-1
@@ -890,7 +890,8 @@ void SendFloat(const std::string &msg) {
|
||||
std::memcpy(addr.sun_path + 1, name, sizeof name - 1);
|
||||
sendto(fd, msg.data(), msg.size(), MSG_DONTWAIT, reinterpret_cast<sockaddr *>(&addr),
|
||||
socklen_t(offsetof(sockaddr_un, sun_path) + 1 + sizeof name - 1));
|
||||
std::printf("to ft-floatd: %s\n", msg.c_str());
|
||||
if (msg.rfind("resize ", 0) != 0) // an edge drag sends many resizes a second
|
||||
std::printf("to ft-floatd: %s\n", msg.c_str());
|
||||
}
|
||||
|
||||
// Where a device's ray meets the screen's plane, in the screen's x (right) and y (up),
|
||||
|
||||
Reference in new issue
Block a user