From 04214dbfc1b8ad0a770aed43acfe45cf98566445 Mon Sep 17 00:00:00 2001 From: Dominic Letz Date: Sun, 13 Sep 2026 18:17:33 +0200 Subject: [PATCH 1/4] Assert the native tray is removed when Desktop.Menu crashes. Co-authored-by: Cursor --- test/e2e/e2e_test.exs | 53 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/test/e2e/e2e_test.exs b/test/e2e/e2e_test.exs index ec4c618..4e71025 100644 --- a/test/e2e/e2e_test.exs +++ b/test/e2e/e2e_test.exs @@ -356,6 +356,59 @@ defmodule DesktopWebview.E2ETest do assert length(list) >= 2 end + defmodule IconMenu do + use Desktop.Menu, server: false + + def mount(menu), do: {:ok, menu} + def handle_event(_event, menu), do: {:noreply, menu} + def handle_info(_msg, menu), do: {:noreply, menu} + + def render(assigns) do + ~H""" + + Quit + + """ + end + end + + test "menu process crash destroys native tray" do + assert {:ok, %{"icon_id" => iid}} = Transport.call("icon.create", %{}) + + test = self() + + parent = + spawn(fn -> + {:ok, pid} = + Desktop.Menu.start_link( + module: IconMenu, + adapter: DesktopWebview.Menu.Adapter, + wx: {:taskbar, {:icon, iid}} + ) + + send(test, {:menu, pid}) + + receive do + :crash -> exit(:crash) + end + end) + + assert_receive {:menu, menu}, 2000 + assert Process.alive?(menu) + + assert {:ok, trays} = Transport.call("test.tray.list", %{}) + assert Enum.any?(trays, &is_binary(&1["tray_id"])) + + ref = Process.monitor(menu) + + ExUnit.CaptureLog.capture_log(fn -> + send(parent, :crash) + assert_receive {:DOWN, ^ref, :process, ^menu, :crash}, 2000 + end) + + assert {:ok, []} = Transport.call("test.tray.list", %{}) + end + test "default edit menu is installed with copy/paste/cut/selectAll", %{platform: platform} do # The macOS host installs a default Edit submenu and exposes it via # test.menu.list. The Linux host uses GTK menu bars and does not yet From 47fdebfe7748f27ff9fba7ccbc5fdfa7197f0579 Mon Sep 17 00:00:00 2001 From: Dominic Letz Date: Sun, 13 Sep 2026 18:27:42 +0200 Subject: [PATCH 2/4] Point CI at the desktop tray-cleanup branch for Menu terminate. Co-authored-by: Cursor --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b3a5a34..568c981 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,6 +21,7 @@ jobs: uses: actions/checkout@v4 with: repository: elixir-desktop/desktop + ref: fix/tray-cleanup-on-window-crash path: desktop - run: mix deps.get - run: mix test --exclude e2e @@ -40,6 +41,7 @@ jobs: uses: actions/checkout@v4 with: repository: elixir-desktop/desktop + ref: fix/tray-cleanup-on-window-crash path: desktop - name: Build host run: ./scripts/build_macos.sh @@ -65,6 +67,7 @@ jobs: uses: actions/checkout@v4 with: repository: elixir-desktop/desktop + ref: fix/tray-cleanup-on-window-crash path: desktop - name: Install GTK / WebKitGTK run: | @@ -101,6 +104,7 @@ jobs: uses: actions/checkout@v4 with: repository: elixir-desktop/desktop + ref: fix/tray-cleanup-on-window-crash path: desktop - name: Build host shell: pwsh From 4420fcd65305f836e136c4587670e2e07cff9bcc Mon Sep 17 00:00:00 2001 From: Dominic Letz Date: Sun, 13 Sep 2026 18:40:50 +0200 Subject: [PATCH 3/4] Run the Menu crash e2e test last so tray.destroy cannot poison later tests. Co-authored-by: Cursor --- .github/workflows/ci.yml | 13 ++++++++++--- test/e2e/e2e_test.exs | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 568c981..c8632eb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,7 +48,10 @@ jobs: - name: Ad-hoc sign run: codesign -s - --force --deep priv/native/macos/DesktopWebView || true - run: mix deps.get - - run: mix test + - name: Tests + run: | + mix test --exclude menu_crash + mix test --only menu_crash env: DESKTOP_WEBVIEW_BINARY: ${{ github.workspace }}/priv/native/macos/DesktopWebView @@ -81,7 +84,9 @@ jobs: run: ./scripts/build_linux.sh - run: mix deps.get - name: E2E under Xvfb - run: dbus-run-session -- xvfb-run -a mix test + run: | + dbus-run-session -- xvfb-run -a mix test --exclude menu_crash + dbus-run-session -- xvfb-run -a mix test --only menu_crash env: DESKTOP_WEBVIEW_BINARY: ${{ github.workspace }}/priv/native/linux/DesktopWebView WEBKIT_DISABLE_COMPOSITING_MODE: "1" @@ -112,7 +117,9 @@ jobs: - run: mix deps.get - name: E2E shell: pwsh - run: mix test + run: | + mix test --exclude menu_crash + mix test --only menu_crash env: DESKTOP_WEBVIEW_BINARY: ${{ github.workspace }}\priv\native\windows\DesktopWebView.exe WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS: --disable-gpu --disable-gpu-compositing diff --git a/test/e2e/e2e_test.exs b/test/e2e/e2e_test.exs index 4e71025..b4ce1b2 100644 --- a/test/e2e/e2e_test.exs +++ b/test/e2e/e2e_test.exs @@ -372,9 +372,13 @@ defmodule DesktopWebview.E2ETest do end end + @tag :menu_crash test "menu process crash destroys native tray" do assert {:ok, %{"icon_id" => iid}} = Transport.call("icon.create", %{}) + # Own EventBridge from this process so Menu exit does not take it down. + DesktopWebview.EventBridge.ensure_started() + test = self() parent = @@ -407,6 +411,8 @@ defmodule DesktopWebview.E2ETest do end) assert {:ok, []} = Transport.call("test.tray.list", %{}) + + restore_transport() end test "default edit menu is installed with copy/paste/cut/selectAll", %{platform: platform} do @@ -448,6 +454,22 @@ defmodule DesktopWebview.E2ETest do end end + defp restore_transport do + case Process.whereis(Transport) do + pid when is_pid(pid) -> + if Process.alive?(pid) do + :ok + else + {:ok, _} = Transport.start_link([]) + :ok + end + + nil -> + {:ok, _} = Transport.start_link([]) + :ok + end + end + defp fixture_url(filename) do html = File.read!(Path.expand("test/fixtures/#{filename}")) "data:text/html;base64," <> Base.encode64(html) From 4fd82d8bd1b04b5d740a83dbe82b29b5d1570ab2 Mon Sep 17 00:00:00 2001 From: Dominic Letz Date: Sun, 13 Sep 2026 18:46:20 +0200 Subject: [PATCH 4/4] Point CI at desktop main now that tray cleanup is merged. Co-authored-by: Cursor --- .github/workflows/ci.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c8632eb..cc7c1a7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,6 @@ jobs: uses: actions/checkout@v4 with: repository: elixir-desktop/desktop - ref: fix/tray-cleanup-on-window-crash path: desktop - run: mix deps.get - run: mix test --exclude e2e @@ -41,7 +40,6 @@ jobs: uses: actions/checkout@v4 with: repository: elixir-desktop/desktop - ref: fix/tray-cleanup-on-window-crash path: desktop - name: Build host run: ./scripts/build_macos.sh @@ -70,7 +68,6 @@ jobs: uses: actions/checkout@v4 with: repository: elixir-desktop/desktop - ref: fix/tray-cleanup-on-window-crash path: desktop - name: Install GTK / WebKitGTK run: | @@ -109,7 +106,6 @@ jobs: uses: actions/checkout@v4 with: repository: elixir-desktop/desktop - ref: fix/tray-cleanup-on-window-crash path: desktop - name: Build host shell: pwsh