fix: some more work on close-crashing

This commit is contained in:
2026-05-01 22:45:36 +02:00
parent 11df11dbdb
commit fef722c4c9
2 changed files with 46 additions and 2 deletions

View File

@@ -2,19 +2,29 @@ defmodule BDS.Desktop.Shutdown do
@moduledoc false @moduledoc false
alias BDS.Desktop.MainWindow alias BDS.Desktop.MainWindow
alias Desktop.Wx
alias Desktop.Window alias Desktop.Window
require Record
Record.defrecordp(:wx, Record.extract(:wx, from_lib: "wx/include/wx.hrl"))
@spec install_handlers(term()) :: :ok @spec install_handlers(term()) :: :ok
def install_handlers(frame) do def install_handlers(frame) do
:wx.set_env(Desktop.Env.wx_env()) :wx.set_env(Desktop.Env.wx_env())
_ = :wxFrame.disconnect(frame, :close_window) _ = :wxFrame.disconnect(frame, :close_window)
_ = :wxFrame.disconnect(frame, :command_menu_selected)
:wxFrame.connect(frame, :close_window, :wxFrame.connect(frame, :close_window,
callback: &__MODULE__.close_window/2, callback: &__MODULE__.close_window/2,
userData: self() userData: self()
) )
:wxFrame.connect(frame, :command_menu_selected,
callback: &__MODULE__.command_menu_selected/2
)
:ok :ok
rescue rescue
_error -> :ok _error -> :ok
@@ -42,6 +52,17 @@ defmodule BDS.Desktop.Shutdown do
request_quit() request_quit()
end end
@spec command_menu_selected(tuple(), term()) :: :ok
def command_menu_selected(wx(id: id), _command_event) do
if id == Wx.wxID_EXIT() do
request_quit()
end
:ok
end
def command_menu_selected(_event, _command_event), do: :ok
defp start_shutdown_task do defp start_shutdown_task do
Task.start(fn -> Task.start(fn ->
MainWindow.persist_now() MainWindow.persist_now()

View File

@@ -3,6 +3,12 @@ defmodule BDS.DesktopTest do
import Plug.Test import Plug.Test
alias Desktop.Wx
require Record
Record.defrecordp(:wx, Record.extract(:wx, from_lib: "wx/include/wx.hrl"))
defmodule FakeShutdown do defmodule FakeShutdown do
def request_quit do def request_quit do
send(Application.fetch_env!(:bds, :desktop_shutdown_test_pid), :quit_requested) send(Application.fetch_env!(:bds, :desktop_shutdown_test_pid), :quit_requested)
@@ -145,8 +151,25 @@ defmodule BDS.DesktopTest do
assert_receive :quit_requested assert_receive :quit_requested
end end
test "cmd-q remains handled by the desktop window quit handler" do test "cmd-q is handled by the app-owned shutdown handler" do
refute function_exported?(BDS.Desktop.Shutdown, :command_menu_selected, 2) assert {:module, BDS.Desktop.Shutdown} = Code.ensure_loaded(BDS.Desktop.Shutdown)
assert function_exported?(BDS.Desktop.Shutdown, :command_menu_selected, 2)
end
test "cmd-q callback requests app-owned shutdown" do
previous_module = Application.get_env(:bds, :desktop_shutdown_module)
previous_pid = Application.get_env(:bds, :desktop_shutdown_test_pid)
Application.put_env(:bds, :desktop_shutdown_module, FakeShutdown)
Application.put_env(:bds, :desktop_shutdown_test_pid, self())
on_exit(fn ->
restore_env(:desktop_shutdown_module, previous_module)
restore_env(:desktop_shutdown_test_pid, previous_pid)
end)
assert :ok = BDS.Desktop.Shutdown.command_menu_selected(wx(id: Wx.wxID_EXIT()), nil)
assert_receive :quit_requested
end end
test "app-owned shutdown delegates final termination to the desktop hard quit path" do test "app-owned shutdown delegates final termination to the desktop hard quit path" do