Closed PlanetTeamSpeakk closed 7 months ago
There has been some discussion on this before. I don't have time to dig back through and find them at the moment. It can be done but you would need to use the private slint api's. If you dig through the Issues and Discussions some you should be able to find some tips to how to do it currently.
This was kind of part of the meta issue https://github.com/slint-ui/slint/issues/333 but it is now closed. (There was also https://github.com/slint-ui/slint/issues/3331 but this was for fullscreen) So let's keep this issue open for it.
Currently, one way to do it is to use the private API of the i-slint-backend-winit crate to access the winit API.
In order to add this in Slint, we have to make the API for it. I guess the most sensible way to do it is to copy the API of winit with set_maximized / set_minimized.
Another API could be to merge them in some state API like Qt does. But note that a window can be both minimized and maximized at the same time (it means that if the user un-minimize the window, it will be restored as maximized) so the API should account for that.
Implementation-wise, it should be easy, just do the same as Window::set_fullscreen This is why i'm making this issue as a good first issue.
After a bit of poking around, this is not as simple as Window::set_fullscreen
. For this implementation we can maintain state inside WindowInner
to track the fullscreen state since the only way to change it is programmatically through the app. Therefore we can localize changes to the update_window_properties
.
However, minimize/maximize can be invoked by the user "nonprogramatically" through the window manager. Following the same pattern as set_fullscreen
can result in the following:
Window::set_minimized()
calledWindowInner
sets minimized = true
and calls update_window_properties
on adapterupdate_window_properties
is called which minimizes the windowupdate_window_properties
but the variable on WindowInner
was not updated so it remains as minimized = true
indefinitelyIdeally the window minimized/maximized state should not be kept in slint to avoid these issues. For the Window
-> WindowInner
-> WindowAdapter
chain to be fully stateless the WindowAdapter
trait could be extended to support these actions directly but I'm not sure the appetite for changing a core trait like that? Alternatively, maybe the maximize/minimize events could be captured in Qt/winit/etc. and propagated in the notify chain but this can be error prone in my experience working on related issues with SDL.
Thanks @rminderhoud for your research. You're right, I overlooked the fact that the WM can set the state as well. (In fact, this is even possible for full screen, the user can select full screen from the plasma menu)
By the way, the way you suggest was how it was first implemented in https://github.com/slint-ui/slint/pull/4286 , but then we decided to go with the current API instead in https://github.com/slint-ui/slint/pull/4304
So that means that the backend have to call set_minimized() or set_maximized on the slint::Window when this happens. We probably receive an event when the user change the state.
Or we go back to an api where we add set_maximized(bool)
, set_minimized(bool)
and even set_fullscreen(bool)
to the WindowAdaptor
We can also make it enum WindowState(Maximized, Minimized, Fullscreen)
and have a set_window_state(WindowState, bool)
Not sure what's best.
@tronical : opinion?
I had a quick chat with @tronical and the reason why we need to keep the state within the Slint's Window is to be able to easier provide a possibility to add a property later on the Window that can be used from Slint.
So my recommendation would be to still do the same as what set_fullscreen does. But the backend should notify Slint when the state changes by calling window::set_minimized when an event comes from the windowing system. (We also discussed the fact that we could add event to the WindowEvent enum for the notification, but since it would have practically the same effect as the faller on the window, i don't think it's needed)
In my application, I have hidden the frame and made my own control buttons instead. However, I have only managed to make my own close button which calls
ui.window().hide()
, for the other two, minimize and maximize, there doesn't seem to be a method in the API that can mimic that behaviour.Hence, I'd like to request such methods to be added.