-
Notifications
You must be signed in to change notification settings - Fork 52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
wx events end_session and query_end_session are not propagated on macos #4
Comments
I notice a related issue on macOS when trying to close the app with P.S |
I have found the following:
https://github.com/erlang/otp/blob/OTP-24.1.4/lib/wx/c_src/wxe_impl.cpp#L161:L168 What worked for me was to subscribe to menu bar events and add an explicit handler for the "quit" menu item (event with id wxID_EXIT aka 5006) Here is my full test rig for this: defmodule Example.App do
@moduledoc false
@behaviour :wx_object
# https://github.com/erlang/otp/blob/OTP-24.1.2/lib/wx/include/wx.hrl#L1314
@wx_id_exit 5006
def start_link() do
:wx_object.start_link(__MODULE__, [], [])
end
@impl true
def init(_) do
title = "Example"
size = {400, 400}
wx = :wx.new()
frame = :wxFrame.new(wx, -1, title, size: size)
:wxFrame.show(frame)
# Menubar
menubar = :wxMenuBar.new()
:wxFrame.setMenuBar(frame, menubar)
# App Menu
menu = :wxMenuBar.oSXGetAppleMenu(menubar)
:wxMenu.setTitle(menu, title)
# Remove all items except for Quit since we don't yet handle the standard items
# like "Hide <app>", "Hide Others", "Show All", etc
for item <- :wxMenu.getMenuItems(menu) do
if :wxMenuItem.getId(item) == @wx_id_exit do
:wxMenuItem.setText(item, "Quit #{title}\tCtrl+Q")
else
:wxMenu.delete(menu, item)
end
end
:wxFrame.connect(frame, :command_menu_selected)
state = %{frame: frame}
{frame, state}
end
@impl true
def handle_event({:wx, @wx_id_exit, _, _, _}, state) do
{:stop, :normal, state}
end
end
defmodule Example.Main do
@moduledoc false
def main(_args) do
{:wx_ref, _, _, pid} = Example.App.start_link()
ref = Process.monitor(pid)
receive do
{:DOWN, ^ref, _, _, _} ->
:ok
end
end
end
Example.Main.main(System.argv()) |
That's awesome @wojtekmach I'll have a look at that |
@wojtekmach and @mazz-seven I've fixed the MacOS quit button issue in 1.3.2! But the original issue here is still open :-) |
Problem
When a user wants to shut down his mac, the running erlang application will ignore the shutdown signal and stay open, and this way it will block the macOS shutdown.
Root Cause
The root problem is that
:wxFrame.connect(frame, :end_session)
inwindow.ex
does not have any effect. And the:end_session
event is never delivered to the application. Only:wxFrame.connect(frame, :close_window)
is delivered but does not make it possible to differentiate between the user closing a window or the system shutting down.Current Workaround
Currently, we're checking on receiving the
:close_window
event whether any window is shown -- if no window is shown, we assume this is a system shutdown and trigger aOS.shutdown()
- the problem with this approach is that when a window is open, the window will be closed, but a system shutdown is still being prevented until the user tries again.Steps to reproduce
Open the sample app and open the main window. Now open the macOS activity monitor and use the "Stop" option to stop the application. The application should be stopped -- but actually, only the window is closed, only a second "Stop" call will make the application stop if now window is shown (the workaround is in effect)
Background
When using the macOS "Activity Monitor" or when doing a system shutdown to stop an app macOS is not sending a Unix signal but instead an
apple event
to the app to close it.wxWidgets is internally creating two events for this. From the docs:
Reference:
https://github.com/wxWidgets/wxWidgets/blob/master/src/osx/carbon/app.cpp#L209
https://docs.wxwidgets.org/3.0/classwx_close_event.html
Solution Proposal
A) One option to make these events available is to add Connect() calls in
wxe_impl.cpp
and pipe them through from there (https://github.com/erlang/otp/blob/master/lib/wx/c_src/wxe_impl.cpp#L151)B) or alternatively make it possible to issue
wxEventHandler:connect(:wxApp, :end_session)
calls from erlang and trigger the corresponding appConnect()
calls. Currently there is no way to reference in:wxApp
instance from erlang space so that would be needed to be added.there might be other options as well.
The text was updated successfully, but these errors were encountered: