Add --help, terminal scrollback + scrollbar, run-dialog fix, client-safe exit, true rounded corners
- -h/--help prints a full usage overview (modes, config keys, keys, mouse) - Run dialog now executes the typed command directly in the new window (previously it spawned the default shell and typed the command into it, which showed up as just an empty terminal) - Virtual terminals get vt100 scrollback (config scrollback_lines, default 1000): mouse wheel scrolls history when the app doesn't capture the mouse, arrow-key fallback on the alternate screen, any keypress jumps back to the bottom; optional scrollbar on the right border (show_scrollbar) plus configurable default_window_size - Exit triggered from a connected display client (ctrl+q / panel button) now only disconnects that client — the daemon/standalone session and its programs keep running - Windows now paint the border zone in the desktop background color so rounded corners actually look rounded instead of a filled square with an inner rounded frame; popup dialogs rounded too - Integration suite extended to 19 checks (scrollback, run dialog, client-safe exit) — all passing Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -59,10 +59,16 @@ class Conn:
|
||||
|
||||
def recv(self):
|
||||
while len(self.buf) < 4:
|
||||
self.buf += self.sock.recv(65536)
|
||||
data = self.sock.recv(65536)
|
||||
if not data:
|
||||
raise EOFError("servern stängde anslutningen")
|
||||
self.buf += data
|
||||
(length,) = struct.unpack(">I", self.buf[:4])
|
||||
while len(self.buf) < 4 + length:
|
||||
self.buf += self.sock.recv(65536)
|
||||
data = self.sock.recv(65536)
|
||||
if not data:
|
||||
raise EOFError("servern stängde anslutningen")
|
||||
self.buf += data
|
||||
payload = self.buf[4 : 4 + length]
|
||||
self.buf = self.buf[4 + length :]
|
||||
return json.loads(payload)
|
||||
@@ -135,6 +141,23 @@ def main():
|
||||
frame = disp.recv_until("frame")
|
||||
check("frames strömmas till display", frame.get("width", 0) > 0)
|
||||
|
||||
# ── 1b. Exit från en klient kopplar bara ner klienten ───────────
|
||||
disp2 = Conn(sock_path)
|
||||
disp2.send({"type": "hello", "role": "display", "width": 80, "height": 24})
|
||||
disp2.recv_until("hello_ok")
|
||||
disp2.recv_until("frame")
|
||||
disp2.send(key_event(ch="q", modifiers="CONTROL"))
|
||||
try:
|
||||
deadline = time.time() + 3
|
||||
while time.time() < deadline:
|
||||
disp2.recv()
|
||||
disconnected = False
|
||||
except (EOFError, TimeoutError, OSError):
|
||||
disconnected = True
|
||||
check("ctrl+q från klient kopplar ner klienten", disconnected)
|
||||
frame = disp.recv_until("frame")
|
||||
check("daemonen överlever klientens exit", frame.get("width", 0) > 0)
|
||||
|
||||
# ── 2. spawn_window med mus-tracking-testapp ────────────────────
|
||||
# printf slår på AnyMotion + SGR-mus-tracking, cat -v ekar allt
|
||||
# PTY:n tar emot — inklusive forwardade mus-sekvenser.
|
||||
@@ -188,6 +211,46 @@ def main():
|
||||
f"frame-text: {text[-200:]!r}")
|
||||
app.send({"type": "close_window", "window_id": emoji_open["id"]})
|
||||
|
||||
# ── 4c. Scrollback: mushjul utan mus-tracking scrollar historiken ─
|
||||
app.send({"type": "spawn_window",
|
||||
"command": "seq 1 200; exec cat",
|
||||
"request_id": "w-scroll"})
|
||||
scroll_open = app.recv_until("window_opened")
|
||||
text = disp.frame_text(timeout=5.0, contains="200")
|
||||
app.send({"type": "list_windows", "request_id": "ls"})
|
||||
wls = app.recv_until("window_list")
|
||||
sw = next(w for w in wls["windows"] if w["id"] == scroll_open["id"])
|
||||
scx, scy = sw["x"] + 10, sw["y"] + 5
|
||||
visible_before = "163" in text
|
||||
for _ in range(8):
|
||||
disp.send(mouse_event("ScrollUp", scx, scy))
|
||||
text = disp.frame_text(timeout=5.0, contains="163")
|
||||
check("mushjul scrollar terminalens historik",
|
||||
"163" in text and not visible_before,
|
||||
f"före: {visible_before}, frame-tail: {text[-150:]!r}")
|
||||
# Tangenttryck hoppar tillbaka till botten av historiken
|
||||
disp.send(key_event(ch="x"))
|
||||
text = disp.frame_text(timeout=5.0, contains="200")
|
||||
check("tangenttryck hoppar till historikens botten", "200" in text)
|
||||
app.send({"type": "close_window", "window_id": scroll_open["id"]})
|
||||
|
||||
# ── 4d. Kommandodialogen kör kommandot direkt ────────────────────
|
||||
disp.send(key_event(ch=" ", modifiers="CONTROL")) # ctrl+space
|
||||
time.sleep(0.3)
|
||||
for ch in "top":
|
||||
disp.send(key_event(ch=ch))
|
||||
disp.send(key_event(code="Enter"))
|
||||
text = disp.frame_text(timeout=8.0, contains="PID")
|
||||
check("kommandodialogen kör programmet (top)", "PID" in text,
|
||||
f"frame-tail: {text[-200:]!r}")
|
||||
app.send({"type": "list_windows", "request_id": "lt"})
|
||||
wlt = app.recv_until("window_list")
|
||||
top_win = next((w for w in wlt["windows"] if w["title"].strip() == "top"), None)
|
||||
check("fönstret har programmets namn som titel", top_win is not None,
|
||||
f"fönster: {[w['title'] for w in wlt['windows']]}")
|
||||
if top_win:
|
||||
app.send({"type": "close_window", "window_id": top_win["id"]})
|
||||
|
||||
# ── 5. Popup + popup_result via Enter ───────────────────────────
|
||||
app.send({
|
||||
"type": "spawn_popup", "message": "Integrationstest?",
|
||||
|
||||
Reference in New Issue
Block a user