I learned that makeKeyDelay has been deprecated in matrix-js-sdk ever since the switch to the new encryption manager, so this config option has no effect.
Compound's Tooltip floats its bubble through floating-ui's FloatingPortal,
into the body: outside the element the component build confines its
stylesheet to, so a label tooltip shows as bare text at all times. An
enclosing FloatingPortal rooted at the container makes the nested portals
land inside it instead.
The call goes in an isolating wrapper there, standing in for the standalone
page's #root, so that its footer layer no longer paints above the modals.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
With this change, views now read every reactive value through `useBehavior`, as
`architecture.md` already prescribes. Where a view reads a plain stream, the view
model now exposes a `Behavior`.
Where the host can't delegate the user's click (Firefox, Safari, WebKitGTK),
lotus.20 showed EC's own screenshare button floating in the frame's corner,
apart from the host's call bar. Now the host keeps its bar button and sends
the new toWidget io.lotus.prompt_screenshare; the fork shows a small
"Share your screen?" card inside the frame, just above the bar, and its
Share button starts the share with the frame's own click. Same two clicks as
the host's confirm on Chromium.
- The card focuses Share; Cancel and Escape close it; it closes if a share
starts some other way or the room's call policy stops allowing sharing,
and never opens where the policy forbids it (set_frame_screenshare).
- Picture-in-picture (~158 px tall): compact card without the description.
- controls_state: frameScreenshare is now always false (the corner button is
gone), screensharePrompt says the host should use the prompt, and
screensharePromptOpen lets the host stop covering the frame meanwhile.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
Two things tied EC to the host's origin:
- Widget message check: matrix-widget-api's strictOriginCheck compares
ev.origin with THIS frame's origin, so on call.chat.lotusguild.org every
message from chat.lotusguild.org would be dropped and calls would not
start. restrictToHost() instead requires ev.source === window.parent and
ev.origin === parentUrl's origin. Same-origin deployments keep working
(the host origin is our own origin there), and it is stricter than
before: the sender must also be our parent window.
- Soundboard: the host's blob: clip URL is origin-bound. io.lotus.inject_audio
now accepts the clip's bytes (`audio`, ArrayBuffer, <= 8 MiB) and prefers
them over `url`; hosts that only send `url` are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA