Drop cookie import; click-through notifications; per-app zoom

The cookie import is gone. It worked mechanically - 43 cookies decrypted
from Arc and verifiably visible to the page - but Google, Microsoft and
Odoo all refused the imported sessions, because each binds a session to
the browser that created it. Signing in once inside the app is simpler
and actually works, so the whole path is deleted rather than kept as a
feature that mostly fails. That takes rusqlite, aes, cbc, pbkdf2, hmac,
sha1 and sha2 out of the build with it.

Notifications are now raised through mac-notification-sys rather than
Tauri's notification plugin, because the plugin cannot report that one
was clicked. A click switches to the app that raised it and then runs
the page's own click handler - the only thing that knows which message
the notification was about.

Zoom is per app, on a fixed ladder so Cmd+0 returns to exactly 100%.
The shortcuts are menu-bar accelerators rather than a key listener,
since the keystroke has to work while a remote page has focus.

The hidden-element count is off the nav rows.
This commit is contained in:
2026-09-01 12:53:52 +02:00
parent f057268103
commit 3525d454bf
18 changed files with 416 additions and 1073 deletions
+17 -14
View File
@@ -39,24 +39,27 @@ sentinel, because a strict navigation filter breaks every OAuth chain the moment
through `accounts.google.com`.
**Sessions persist.** Each webview keeps its cookies across restarts, so you log into a
tool once. Every app also claims a real Chrome user agent by default, because Google
tool once and it sticks. Every app also claims a real Chrome user agent by default, because Google
refuses logins from anything it identifies as an embedded webview.
**Pairing imports a browser's cookies.** Settings lists the browsers installed, most
recently used first, and pairing decrypts that browser's cookie store — PBKDF2-HMAC-SHA1
against its Keychain key, then AES-128-CBC — and injects the result into WebKit's shared
jar. Only cookies for the apps on your list and their sign-in hosts are read; everything
else is dropped before anything is written. macOS asks for Keychain permission the first
time, which is the consent gate and cannot be skipped.
Google and Microsoft increasingly tie a session to the browser that created it, so those
may still ask you to sign in once. After that the persistent jar keeps it.
**Notifications work, and clicking one lands on the message.** WKWebView *defines*
`window.Notification` but it is inert: constructing one throws nothing and shows nothing,
so a page believes it notified you and you never hear about it. It is replaced with a shim
that forwards to a real macOS notification carrying the app's name.
**Notifications work, with one gap.** WKWebView *defines* `window.Notification` but it is
inert: constructing one throws nothing and shows nothing, so a page believes it notified
you and you never hear about it. It is replaced with a shim that forwards to a real macOS
notification carrying the app's name. Service-worker push in the background is not
covered — only notifications a page raises while it is open.
Clicking the banner switches to that app and then runs **the page's own click handler**,
which is the only thing that knows which message it was about — Gmail opens the thread,
Chat opens the conversation. This is why notifications are raised directly through
`mac-notification-sys` rather than Tauri's notification plugin: the plugin has no way to
report that a notification was clicked.
Service-worker push in the background is not covered — only notifications a page raises
while it is open.
**Zoom is per app.** ⌘+ and ⌘− step a ladder that always returns to exactly 100% with ⌘0,
and each app remembers its own size. The shortcuts are menu-bar accelerators rather than a
key listener, because they have to work while a remote page has focus.
**Anything on a page can be hidden.** Right-click it and choose *Hide this element*, or
use the eye button in the nav to point at one (arrow-up widens the selection to the