-
Notifications
You must be signed in to change notification settings - Fork 903
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
API change proposal for window closing #434
Comments
Should a Closing a window within an event loop could then be handled by having users wrap their windows in |
@Osspial I'm definitely in favor of having As far as the |
We should keep in mind that it's always the compositor or the operating system that has the last word when it comes to closing windows. It can simply decide to close one of our window without asking. |
I think this is necessary for the 'X' button to work correctly in Vulkano apps - currently, pressing 'X' causes the window to be immediately destroyed, which means that if there's a live surface/swapchain pointing to that window we've fallen into "undefined behavior" territory Vulkan-wise. This can cause hangs or crashes (it hangs on my system). There is no way for an application to clean up its resources in a safe way here. Previously this wasn't a problem, since "closed" really meant "close requested" on X11 prior to d667a39 |
@tomaka well, optimistically we at least know when that happens, though I agree that we should be cautious about the guarantees we make. For now I'm just going to focus on implementing the original proposal of @branan sorry about that! The good news is that I've already finished implementing this on X11 and Windows. The bad news is that I have no idea how to do this on Wayland, and while I think I know how to do it on macOS, I can't actually test it myself anyway. So, there are really two approaches that could be taken:
I personally want to go with option 1.5, which is to try to get a macOS implementation first, but to just go ahead with option 2 if no one volunteers for that within a reasonable window of time. |
@francesca64 No worries. It was easy enough to work around for now by leaking my swapchain. Safety with windows is apparently hard. I think the safest way to go is @Osspial's suggestion - a live Window object needs to reference a live system window. That plays nicely with the work I did in vulkano-win to allow a live Surface (which is always an Arc, referenced by other Vulkan objects that depend on it) to keep its Window around until all those referencing objects are in turn dropped. An application, on recieving CloseRequested, would start deleting its Vulkan objects, which would eventually unref the Surface and cause it and the Window to be dropped Since it's not always possible to guarantee a window is not destroyed out-of-band, perhaps firing the Destroyed event only for windows which have been destroyed outside of a drop is a good idea? That way an application can catch that event if it has special cleanup needs (Vulkano is the one I care about, but probably other 3D APIs, video decoders, etc. would have similar issues?). The safest approach would be to panic inside Winit in this case, but I suspect in the real world that's too aggressive. |
Currently on Wayland, the Due to how the wayland protocol works, once a close has been requested, it is not possible for the client to know if its window is actually still visible or not, but in all cases it is still up to the client to cleanup its resources when it sees fit. |
I feel like panicking inside winit if the OS or another application closes the window is an appropriate action to take, given that
It makes sense to have some sort of API to detect if the OS has closed the window or not, but I don't think it's important enough to have the user explicitly check it every time they try to get an attribute from the window. |
@branan alright, if it's easy to workaround, then we can take our time with this. @vberger ah, thanks. Is there any way for us to send an event to the user when the window's destroyed? Also, what's the best way to figure things like this out? I'd like to be able to give Wayland the proper attention, but I'm not really sure where to look for info on accomplishing Wayland stuff. @Osspial for me to feel comfortable with that, I'd really want to have a firm understanding of all the scenarios where it can happen. I do agree that almost no one is actually going to handle this case either way, and it's also possible that we can't do a good job of assuring winit wouldn't inadvertently panic anyway. |
Looking at the |
We can mostly do whatever we want here, as it'll always be winit that destroys the window (as in the protocol object itself). However, it is by design of wayland impossible for a client app to know where/how its surfaces are displayed, or even if they are displayed at all. As a consequence, the classic course for a wayland client is to just assume it is always visible, and gracefully exit when the server send an event requesting the window to be closed, as it cannot know if the server has already hidden the window or not.
Well, I agree with you that wayland's documentation is quite lacking in general. For the record, I'm the maintainer of wayland-client which is used for winit's wayland backend, and I wrote a large part of the winit backend as well. I've tried to make some documentation effort on my work, though while it is still very WIP (I sadly have only so much time...), you can have a general overview of the wayland protocol here: https://smithay.github.io/book/intro.html. You can also ping me, I've definitely not had the time to write all my findings about wayland yet... (if you want to chat about it, feel free to join the Smithay&wayland-rs chatroom, on matrix, gitter or IRC (#smithay on the mozilla servers)) Also, FYI, I am in the process of a complete rework of wayland-client which, when done, should among others allow me to simplify the winit backend code. My plan was to come back to winit and update it once the rework is finished. |
Since discussion over making substantial design changes seems to be brewing, I'd like to just get My stance is also to leave out the I've implemented this on Windows, macOS, X11, so I just need to take care of Wayland, then do some more testing+documentation and I should have a PR up pretty soon. @vberger thanks! I'll keep all of that in mind, though fortunately things look easy this time. This looks like the right place to send So I figure I should change |
@francesca64 This would generate the Not sure how much sense it would make to generate event for a |
Implements rust-windowing#434 The existing Closed event had ambiguous meaning, both in name and in cross-platform behavior. Closed is now split into two more precise events: * CloseRequested - the window has been requested to close, most commonly by having clicked the window's close button. Whether or not you choose to respond by closing the window is up to you. * Destroyed - the window has been destroyed, and can no longer be safely used. Most notably, now you can reliably implement classic patterns like prompting the user to save their work before closing. Migrating to the new API is straightforward. In most cases, you can simply replace all existing usages of Closed with CloseRequested. For more information, see the example programs, particularly handling_close and multiwindow. iOS applications must replace all usages of Closed with Destroyed, and require no other changes.
Implements rust-windowing#434 The existing Closed event had ambiguous meaning, both in name and in cross-platform behavior. Closed is now split into two more precise events: * CloseRequested - the window has been requested to close, most commonly by having clicked the window's close button. Whether or not you respond by closing the window is up to you. * Destroyed - the window has been destroyed, and can no longer be safely used. Most notably, now you can reliably implement classic patterns like prompting the user to save their work before closing, and have the opportunity to perform any necessary cleanup. Migrating to the new API is straightforward. In most cases, you can simply replace all existing usages of Closed with CloseRequested. For more information, see the example programs, particularly handling_close and multiwindow. iOS applications must replace all usages of Closed with Destroyed, and require no other changes.
Alright, PR is up: #476 |
* Replace Closed event with CloseRequested and Destroyed Implements #434 The existing Closed event had ambiguous meaning, both in name and in cross-platform behavior. Closed is now split into two more precise events: * CloseRequested - the window has been requested to close, most commonly by having clicked the window's close button. Whether or not you respond by closing the window is up to you. * Destroyed - the window has been destroyed, and can no longer be safely used. Most notably, now you can reliably implement classic patterns like prompting the user to save their work before closing, and have the opportunity to perform any necessary cleanup. Migrating to the new API is straightforward. In most cases, you can simply replace all existing usages of Closed with CloseRequested. For more information, see the example programs, particularly handling_close and multiwindow. iOS applications must replace all usages of Closed with Destroyed, and require no other changes.
I've confirmed that with current master I can remove my workaround. Thanks! |
Currently, the
Closed
event indicates when a window has been destroyed, and clicking the × button (or closing the window through some other external means) leads to the unconditional destruction of the window. Ideally, application developers should have the opportunity to decide how to handle external requests for the window to close, such as prompting the user about unsaved work, but that's not presently possible.Proposal
A new event named
Destroyed
should be created, taking the place of the existingClosed
event. This is consistent with the naming scheme used in both Win32 and X11.The existing
Closed
event should be removed in favor ofCloseRequested
. This prevents existing code from missing the API change, and prevents ambiguity in future code. When × is pressed/etc., the only behavior that should occur is this event being sent, allowing the application developer to decide what action to take.A
close
method could be added toWindow
(#13). In the simplest case,CloseRequested
would be handled by callingclose
for that window. However, since this method would have the same effect as dropping the window, it could be preferable to leave out this method and just make dropping the canonical solution.The text was updated successfully, but these errors were encountered: