Keep a mouse selection out of the window's shadow margin #10

Closed
asxpi wants to merge 0 commits from asxpi/anotherim-js:fix/csd-selection-strip into develop
First-time contributor

Linux, with the app's own window frame (data-csd-frame): selecting text in a chat and dragging below the window painted a dark strip over the transparent shadow margin under the window. It stayed until the selection was cleared and came back on the next drag outside.

The margin is html's padding, and the drag ended the selection there. The root is now unselectable and the body selectable again, so a selection dragged out of the window ends at the nearest text inside it. This only applies when the pointer isn't coarse, so on a touch screen the existing coarse-pointer rule still keeps a touch from selecting anything.

  • ui/src/styles/app.css: the rule, under @media not all and (pointer: coarse).
  • tools/smoke-webkit.py: the csd frame screen checks that the rule is there. Broadway has no mouse, so the page matches (pointer: coarse) there and the rule can be read but not applied.

Checked by hand in a local Flatpak build of 0.5.2: the strip no longer appears. The csd frame, header csd, chat night and chat day smoke screens pass (41/41).

🤖 Generated with Claude Code

Linux, with the app's own window frame (`data-csd-frame`): selecting text in a chat and dragging below the window painted a dark strip over the transparent shadow margin under the window. It stayed until the selection was cleared and came back on the next drag outside. The margin is `html`'s padding, and the drag ended the selection there. The root is now unselectable and the body selectable again, so a selection dragged out of the window ends at the nearest text inside it. This only applies when the pointer isn't coarse, so on a touch screen the existing coarse-pointer rule still keeps a touch from selecting anything. - `ui/src/styles/app.css`: the rule, under `@media not all and (pointer: coarse)`. - `tools/smoke-webkit.py`: the `csd frame` screen checks that the rule is there. Broadway has no mouse, so the page matches `(pointer: coarse)` there and the rule can be read but not applied. Checked by hand in a local Flatpak build of 0.5.2: the strip no longer appears. The `csd frame`, `header csd`, `chat night` and `chat day` smoke screens pass (41/41). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
With the page drawing the Linux window (data-csd-frame), html's
padding is the transparent margin the body's shadow sits in. A text
selection dragged out of the window ended there, and WebKitGTK
painted a dark strip over the margin under the window until the
selection was cleared.

Make the root unselectable and the body selectable again, so the
selection ends at the nearest text inside the window. Not on a
coarse pointer, whose rule keeps a touch from selecting anything.

The smoke's csd frame screen checks the rule is there; broadway has
no mouse, so the page matches (pointer: coarse) and the rule can be
read but not applied there. Checked by hand in a local Flatpak build.

Assisted-by: Claude:opus-5
Owner

Merged into develop by hand with a merge commit and released in 0.5.3 (v0.5.3 = 87ebd52b, https://dev.another.im/another-im/anotherim-js/releases/tag/v0.5.3). The forge does not mark a hand merge as merged, so this PR is closed here. One follow-up on top: the chat reads the selection once per press rather than per selectionchange event (d231e462).

Merged into develop by hand with a merge commit and released in 0.5.3 (v0.5.3 = 87ebd52b, https://dev.another.im/another-im/anotherim-js/releases/tag/v0.5.3). The forge does not mark a hand merge as merged, so this PR is closed here. One follow-up on top: the chat reads the selection once per press rather than per selectionchange event (d231e462).
ann closed this pull request 2026-10-16 06:19:15 +00:00
ann referenced this pull request from a commit 2026-10-27 11:52:18 +00:00
Android lock fixes from the final audit of 2026-10-27 (findings 1, 3, 4, 7, 8, 9, 10, 11): every lock now runs on DeviceLock's one worker and looks at the store itself (storage info) when its turn comes, so a screen-off heard while the silent reopen is still opening the tier closes it again instead of being dropped (H1), and a reopen or a fingerprint open that ends with the phone already off or locked is closed again at once (DeviceLock.opened, called from MainActivity.presence after Relock.keep); behind a secure lock an open split store closes at every lock whether or not a copy of K2 is held, the copy deciding only whether the unlock is silent, and with no copy the page is told __anotherDeviceLocked('fingerprint') and the gate says why it asks (M3, new string in en ru uk et es); a close libtacky holds back for a call or a transfer (close_main closed 0) sets DeviceLock.closeHeld, the bridge's deviceClosePending(status) makes the page take that unlocked store as call (shellStatus in store.begin and recheck), so a fresh window after a swipe during a call gets the fingerprint, and open-main over the held close releases K2 through the prompt and calls the close off, or opens the tier with it where the close went meanwhile (M4); the page publishes its drafts and answers deviceLockFlushed after a request round trip before close_main goes (at most a second, #11); the gate offers the fingerprint after RELOCK_WAIT_MS (15 s) of a reopen that never comes (#10); Relock.take sleeps for its retry outside the object's lock (#9); EnrolmentProbe counts an unexpected Keystore exception on a made probe as a change, fail closed (#8); the headers of DeviceLock, Relock and docs/push.md now say K2 passes through JVM strings that are released, not zeroed (#7, K2 over JNI as bytes left for later). Ringing still counts as busy in libtacky's MainTierBusy (libtacky's, not changed here). Tests: RelockTest 8 new (screen off during the reopen with the keyguard locked and within the lock delay, both failing on the old code; an open ending behind the lock; a held close keeping a fresh window at the fingerprint and called off by the prompt, or opened by it where it went; the close waiting for the page's drafts; a take's retry not holding drop), DeviceLockTest and WatchesTest updated for the close without a copy, KeystoreSealersTest for the fail-closed probe; device-lock.test.ts and storage-gate.test.ts 6 new; JVM free 485, gms 488, all passing; make check STRICT=1 clean; make test-ui 380 files, 4168 passed, 8 skipped; make test-shell ok.

Pull request closed

Sign in to join this conversation.
No description provided.