Skip to content
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

x/exp/shiny/example/basic: program does not exit if closed by clicking "Close" system button (on windows) #14187

Closed
alexbrainman opened this issue Feb 2, 2016 · 5 comments

Comments

@alexbrainman
Copy link
Member

Run x/exp/shiny/example/basic program on Windows. Click program's window "Close" system button. The window disappears from the screen. But program continues to run. If I press Ctrl-C, the program exits.

Once main window is closed, it is impossible to do anything with that program. I think program should exit. That is how every Windows program behaves.

Maybe unrelated. The program exits if I press Escape key. That is unusual for Windows program. But, I guess, it is OK, if clicking "Close" also works.

I also noticed that Alt+F4 closes main window too. (but does not exit program). Alt+F4 is suppose to do what clicking "Close" does. It does that.

Alex

@alexbrainman
Copy link
Member Author

/cc @nigeltao @crawshaw for their input

Alex

@nigeltao
Copy link
Contributor

nigeltao commented Feb 9, 2016

Well, yes, once the main window is closed, the program should exit, but I'm not familiar enough with Win32 to know what the mechanism should be.

On X11, the program is sent an X11 ClientMessageEvent (WM_DELETE_WINDOW), which the x11driver converts to a shiny lifecycle.StageDead event, which the program responds to by exiting the main loop and thus the main function.

On Win32, the OS is presumably sending the Windows' equivalent of X11's WM_DELETE_WINDOW, call it a Foo event, and the windriver should convert that to a shiny lifecycle.StageDead event. As I said, though, I am not familiar enough with Win32 to know what that Foo event is.

For the gldriver, on Mac, grep the source code for windowWillClose and follow the trail. For gldriver on Linux and Windows, there's TODOs but no working code. For Linux, the TODO is to do the same as the x11 driver. For Windows, the TODO is the same as it is for windriver, but as I said, I don't know what that Foo event mechanism should be.

Fixing this may involve the shiny/driver/internal/win32 package instead of the windriver package, possibly involving a missing LifecycleEvent call on the appropriate message, but I'm only guessing.

@alexbrainman
Copy link
Member Author

Well, yes, once the main window is closed, the program should exit, but I'm not familiar enough with Win32 to know what the mechanism should be.

https://msdn.microsoft.com/en-us/library/windows/desktop/ms632598(v=vs.85).aspx#destroying_win illustrates what normally happens on Windows. But we need to consider 3 separate concepts here:

  • an app window is getting closed;
  • a message pump is exited (one pump occupy single thread and can service many windows);
  • an app exits (one app can have as many message pumps as required).
    (shiny/driver/internal/win32.Main implements one single message pump that services all our windows).

On Win32, the OS is presumably sending the Windows' equivalent of X11's WM_DELETE_WINDOW, call it a Foo event, and the windriver should convert that to a shiny lifecycle.StageDead event.

How does closing message by clicking on it (we'll get WM_CLOSE event in our window procedure) translates into app exiting? We cannot hard wire WM_CLOSE into sending lifecycle.StageDead, there might be other windows still opened. Is there event for "window closing" that app has to act upon?

For the gldriver, on Mac, grep the source code for windowWillClose and follow the trail. ...

Yes, we also need to make sure window.Realese really closes the window. And close the app, if that follows.

Fixing this may involve the shiny/driver/internal/win32 package instead of the windriver package, possibly involving a missing LifecycleEvent call on the appropriate message, but I'm only guessing.

I am happy to try and fix it in shiny/driver/internal/win32, but I still don't understand how to convert "close window" event into "exit app".

Thank you.

Alex

@nigeltao
Copy link
Contributor

I think that you can hard wire WM_CLOSE into sending lifecycle.StageDead. The lifecycle stages, such as "visible" or "focused" are per-window, not per-app. If an app is single-window, it can translate lifecycle.StageDead to return from the app.Main func-typed arg (i.e. exit the app). If an app is multiple-window, it's up to the app to count how many windows are still open. All of the example programs so far are single-window apps. We should probably add a multiple-window example app at some point, but it hasn't been a priority.

@gopherbot
Copy link

CL https://golang.org/cl/20185 mentions this issue.

@golang golang locked and limited conversation to collaborators Mar 13, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants