Skip to content

EventBridge + dialog RPCs for macOS app integration - #2

Merged
dominicletz merged 10 commits into
masterfrom
macos-event-bridge-dialogs
Aug 3, 2026
Merged

EventBridge + dialog RPCs for macOS app integration#2
dominicletz merged 10 commits into
masterfrom
macos-event-bridge-dialogs

Conversation

@dominicletz

Copy link
Copy Markdown
Contributor

Summary

  • Add DesktopWebview.EventBridge so host event.* notifications fan out to Desktop.Window / Desktop.Menu / Desktop.Env (close, focus, open_url/file, reopen, menu.click).
  • Add dialog.choose_file, dialog.choose_directory, and dialog.prompt RPCs on macOS (NSOpenPanel / NSAlert); Linux returns -32004 until ported.
  • Expose DesktopWebview.Dialog, Backend.set_context_menu/2, and Backend.create_icon_from_png_base64/1 for consumer apps (e.g. Diode Collab).

Test plan

  • NO_WX=1 mix test.unit
  • ./scripts/build_macos.sh
  • Manual: dialog panels on macOS
  • E2E smoke with host binary if CI available

Made with Cursor

dominicletz and others added 10 commits August 3, 2026 16:46
Translate host events into Desktop.Env/Window/Menu messages, and expose
dialog.choose_file/choose_directory/prompt on macOS (Linux stubs with -32004).

Co-authored-by: Cursor <cursoragent@cursor.com>
put_webview_backend ran via GenServer.call while Desktop.Env.init was
still on the stack, which crashed desktop startup on macOS.

Co-authored-by: Cursor <cursoragent@cursor.com>
Apple menu Quit called NSApplication.terminate, which killed DesktopWebView
and left the Elixir node running. Intercept terminate, emit event.system.quit,
let Desktop.Window.quit halt BEAM, then finish host teardown on disconnect.
Also halt BEAM if the host process exits unexpectedly.

Co-authored-by: Cursor <cursoragent@cursor.com>
AppKit titles the first main-menu item with the process name. The raw
DesktopWebView binary plus set_menubar installing Zones first produced
duplicate process-named menus. Keep the Apple menu first and set
processName from menu.set_apple.

Co-authored-by: Cursor <cursoragent@cursor.com>
reconnect lifetime left the host running after iex/mix stopped. Treat
--edw-no-beam like coupled on client disconnect, and default Launcher
lifetime to coupled for BEAM-first launches.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Desktop.Menu creates the tray against an empty first DOM, then updates
the menu object; NSStatusItem kept the empty menu. Reattach on update
and call tray.set_menu from the Elixir adapter after mount/refresh.

Co-authored-by: Cursor <cursoragent@cursor.com>
Template NSImages render as gray menu-bar silhouettes; Diode paints
status colors into PNGs and needs those colors preserved.

Co-authored-by: Cursor <cursoragent@cursor.com>
PNG pixel dimensions were used as AppKit point size (32pt), so padding
in the bitmap did not change on-screen size. Set NSImage.size from
NSStatusBar.thickness instead.

Co-authored-by: Cursor <cursoragent@cursor.com>
Desktop.Window passes filenames like diode.png; Path.expand looked in
cwd, failed silently, and icon.create installed a blank NSImage used as
NSApp.applicationIconImage. Mirror wx Application.app_dir(priv) lookup
and error when a path cannot be loaded.

Co-authored-by: Cursor <cursoragent@cursor.com>
@dominicletz
dominicletz merged commit c61761d into master Aug 3, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant