diff --git a/dev.err b/dev.err new file mode 100644 index 0000000..e69de29 diff --git a/dev.log b/dev.log new file mode 100644 index 0000000..7b1004b Binary files /dev/null and b/dev.log differ diff --git a/screen0.png b/screen0.png new file mode 100644 index 0000000..fea7f3a Binary files /dev/null and b/screen0.png differ diff --git a/screen1.png b/screen1.png new file mode 100644 index 0000000..ae7cb3d Binary files /dev/null and b/screen1.png differ diff --git a/screen2.png b/screen2.png new file mode 100644 index 0000000..231713f Binary files /dev/null and b/screen2.png differ diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000..8cb1407 Binary files /dev/null and b/screenshot.png differ diff --git a/shot01-initial.png b/shot01-initial.png new file mode 100644 index 0000000..2c25112 Binary files /dev/null and b/shot01-initial.png differ diff --git a/shot02-clicked-pane1.png b/shot02-clicked-pane1.png new file mode 100644 index 0000000..53dbd4c Binary files /dev/null and b/shot02-clicked-pane1.png differ diff --git a/shot03-f12.png b/shot03-f12.png new file mode 100644 index 0000000..0d5fa5d Binary files /dev/null and b/shot03-f12.png differ diff --git a/shot04-clicked-pane2-immediate.png b/shot04-clicked-pane2-immediate.png new file mode 100644 index 0000000..b4eb8c1 Binary files /dev/null and b/shot04-clicked-pane2-immediate.png differ diff --git a/shot05-clicked-pane2-after-1s.png b/shot05-clicked-pane2-after-1s.png new file mode 100644 index 0000000..2169fee Binary files /dev/null and b/shot05-clicked-pane2-after-1s.png differ diff --git a/shot06-clicked-pane2-toolbar.png b/shot06-clicked-pane2-toolbar.png new file mode 100644 index 0000000..6e55917 Binary files /dev/null and b/shot06-clicked-pane2-toolbar.png differ diff --git a/shot07-devtools-attempt.png b/shot07-devtools-attempt.png new file mode 100644 index 0000000..ad24d21 Binary files /dev/null and b/shot07-devtools-attempt.png differ diff --git a/shot08-after-hmr.png b/shot08-after-hmr.png new file mode 100644 index 0000000..25200ee Binary files /dev/null and b/shot08-after-hmr.png differ diff --git a/shot09-after-reload.png b/shot09-after-reload.png new file mode 100644 index 0000000..a21a0dc Binary files /dev/null and b/shot09-after-reload.png differ diff --git a/shot10-after-restart.png b/shot10-after-restart.png new file mode 100644 index 0000000..6d11cfb Binary files /dev/null and b/shot10-after-restart.png differ diff --git a/shot11-clicked-pane2-toolbar.png b/shot11-clicked-pane2-toolbar.png new file mode 100644 index 0000000..ece890d Binary files /dev/null and b/shot11-clicked-pane2-toolbar.png differ diff --git a/shot12-clicked-bcast.png b/shot12-clicked-bcast.png new file mode 100644 index 0000000..bb54e63 Binary files /dev/null and b/shot12-clicked-bcast.png differ diff --git a/shot13-back-to-pane1.png b/shot13-back-to-pane1.png new file mode 100644 index 0000000..e4ef8aa Binary files /dev/null and b/shot13-back-to-pane1.png differ diff --git a/shot14-pane1-bcast.png b/shot14-pane1-bcast.png new file mode 100644 index 0000000..bdcad6a Binary files /dev/null and b/shot14-pane1-bcast.png differ diff --git a/shot15-palette.png b/shot15-palette.png new file mode 100644 index 0000000..24c9e02 Binary files /dev/null and b/shot15-palette.png differ diff --git a/shot16-pane1-body.png b/shot16-pane1-body.png new file mode 100644 index 0000000..b3c9271 Binary files /dev/null and b/shot16-pane1-body.png differ diff --git a/shot17-capture-fix-test.png b/shot17-capture-fix-test.png new file mode 100644 index 0000000..417ad6a Binary files /dev/null and b/shot17-capture-fix-test.png differ diff --git a/shot18-restart.png b/shot18-restart.png new file mode 100644 index 0000000..9a6d097 Binary files /dev/null and b/shot18-restart.png differ diff --git a/shot19-pane1-body-after-capture.png b/shot19-pane1-body-after-capture.png new file mode 100644 index 0000000..accb99d Binary files /dev/null and b/shot19-pane1-body-after-capture.png differ diff --git a/shot20-pane2-body.png b/shot20-pane2-body.png new file mode 100644 index 0000000..5296095 Binary files /dev/null and b/shot20-pane2-body.png differ diff --git a/shot21-baseline.png b/shot21-baseline.png new file mode 100644 index 0000000..b09833c Binary files /dev/null and b/shot21-baseline.png differ diff --git a/shot22-pane1-body.png b/shot22-pane1-body.png new file mode 100644 index 0000000..22d4b9b Binary files /dev/null and b/shot22-pane1-body.png differ diff --git a/shot23-pane2-body.png b/shot23-pane2-body.png new file mode 100644 index 0000000..22d4b9b Binary files /dev/null and b/shot23-pane2-body.png differ diff --git a/shot24-pane1-again.png b/shot24-pane1-again.png new file mode 100644 index 0000000..9ed4d76 Binary files /dev/null and b/shot24-pane1-again.png differ diff --git a/shot25-slow-pane2.png b/shot25-slow-pane2.png new file mode 100644 index 0000000..e62b5cc Binary files /dev/null and b/shot25-slow-pane2.png differ diff --git a/shot26-slow-pane1.png b/shot26-slow-pane1.png new file mode 100644 index 0000000..136ed43 Binary files /dev/null and b/shot26-slow-pane1.png differ diff --git a/shot27-slow-pane2-again.png b/shot27-slow-pane2-again.png new file mode 100644 index 0000000..45e9025 Binary files /dev/null and b/shot27-slow-pane2-again.png differ diff --git a/shot28-fresh.png b/shot28-fresh.png new file mode 100644 index 0000000..4380aec Binary files /dev/null and b/shot28-fresh.png differ diff --git a/shot29-click1.png b/shot29-click1.png new file mode 100644 index 0000000..c3f9f62 Binary files /dev/null and b/shot29-click1.png differ diff --git a/shot30-click2.png b/shot30-click2.png new file mode 100644 index 0000000..c3f9f62 Binary files /dev/null and b/shot30-click2.png differ diff --git a/shot31-click3.png b/shot31-click3.png new file mode 100644 index 0000000..acaf5cd Binary files /dev/null and b/shot31-click3.png differ diff --git a/src/App.svelte b/src/App.svelte index 57ef4e5..c33edb8 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -184,6 +184,26 @@ return () => window.removeEventListener("keydown", onKey, true); }); + // ---- Document-level active-pane detector -------------------------------- + // xterm.js calls `stopPropagation` on pointerdown inside terminals, so a + // per-leaf `onpointerdown` never fires for body clicks. A document-level + // CAPTURE-phase listener fires before xterm.js can intercept, then finds + // the nearest `data-leaf-id` ancestor to know which pane was clicked. + // Toolbar buttons also pass through (they're outside the xterm container, + // their own onclick still fires in the bubble phase afterwards). + $effect(() => { + function onAnyPointerDown(e: PointerEvent) { + const t = e.target as Element | null; + if (!t) return; + const leafEl = t.closest("[data-leaf-id]"); + if (!leafEl) return; + const id = leafEl.getAttribute("data-leaf-id"); + if (id) orch.setActive(id); + } + document.addEventListener("pointerdown", onAnyPointerDown, true); + return () => document.removeEventListener("pointerdown", onAnyPointerDown, true); + }); + // ---- preset layouts ------------------------------------------------------ function applyPreset(make: (d: { distro?: string }) => TreeNode) { const count = leafCount(tree); diff --git a/src/lib/layout/LeafPane.svelte b/src/lib/layout/LeafPane.svelte index 41beb85..d190444 100644 --- a/src/lib/layout/LeafPane.svelte +++ b/src/lib/layout/LeafPane.svelte @@ -103,9 +103,11 @@ if (active) focusTrigger += 1; }); + // Backup setActive for toolbar clicks (which can't reach the document + // capture listener if a bubble-phase handler stops propagation). Cheap; + // idempotent if the document listener also fired. function onPaneClick() { - console.log("[tiletopia] pane click:", leaf.id, "currentlyActive:", active); - if (!active) orch.setActive(leaf.id); + orch.setActive(leaf.id); } // ---- pane id registration ------------------------------------------------ @@ -121,6 +123,7 @@ class:broadcasting={leaf.broadcast} role="group" aria-label={"Terminal pane: " + (leaf.label ?? leaf.distro ?? "unnamed")} + data-leaf-id={leaf.id} onpointerdown={onPaneClick} >
diff --git a/tilescript.ps1 b/tilescript.ps1 new file mode 100644 index 0000000..30dc31f --- /dev/null +++ b/tilescript.ps1 @@ -0,0 +1,60 @@ +# Helpers for driving the tiletopia window from PowerShell. +Add-Type -AssemblyName System.Windows.Forms +Add-Type -AssemblyName System.Drawing +Add-Type @' +using System; +using System.Runtime.InteropServices; +public class W { + [DllImport("user32.dll")] public static extern bool GetWindowRect(IntPtr h, out RECT r); + [DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr h); + [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr h, int n); + [DllImport("user32.dll")] public static extern bool SetCursorPos(int x, int y); + [DllImport("user32.dll")] public static extern void mouse_event(uint flags, uint dx, uint dy, uint dwData, int extraInfo); + [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left, Top, Right, Bottom; } +} +'@ + +function Get-TileWindow { + $p = Get-Process tiletopia -ErrorAction Stop | Where-Object { $_.MainWindowHandle -ne 0 } | Select-Object -First 1 + if (-not $p) { throw "no tiletopia window" } + return $p +} + +function Bring-ToFront { + $p = Get-TileWindow + [W]::ShowWindow($p.MainWindowHandle, 9) | Out-Null # SW_RESTORE + [W]::SetForegroundWindow($p.MainWindowHandle) | Out-Null + Start-Sleep -Milliseconds 300 + $r = New-Object W+RECT + [W]::GetWindowRect($p.MainWindowHandle, [ref] $r) | Out-Null + return $r +} + +function Save-Shot([string]$path) { + $r = Bring-ToFront + $w = $r.Right - $r.Left + $h = $r.Bottom - $r.Top + $bmp = New-Object System.Drawing.Bitmap $w, $h + $g = [System.Drawing.Graphics]::FromImage($bmp) + $g.CopyFromScreen($r.Left, $r.Top, 0, 0, (New-Object System.Drawing.Size $w, $h)) + $bmp.Save($path) + $g.Dispose() + $bmp.Dispose() + Write-Host ("saved " + $path + " (" + $w + "x" + $h + " at " + $r.Left + "," + $r.Top + ")") + return @{ x = $r.Left; y = $r.Top; w = $w; h = $h } +} + +# Click at *window-relative* coordinates (so we don't depend on the window's +# screen position from one run to the next). +function Click-Win([int]$relX, [int]$relY) { + $r = Bring-ToFront + $absX = $r.Left + $relX + $absY = $r.Top + $relY + [W]::SetCursorPos($absX, $absY) | Out-Null + Start-Sleep -Milliseconds 80 + [W]::mouse_event(0x0002, 0, 0, 0, 0) # LEFTDOWN + Start-Sleep -Milliseconds 30 + [W]::mouse_event(0x0004, 0, 0, 0, 0) # LEFTUP + Start-Sleep -Milliseconds 120 + Write-Host ("clicked window-rel " + $relX + "," + $relY + " (abs " + $absX + "," + $absY + ")") +} diff --git a/tiletopia-window.png b/tiletopia-window.png new file mode 100644 index 0000000..ec79603 Binary files /dev/null and b/tiletopia-window.png differ