dlangui
dlangui copied to clipboard
Feature Request: Programmatically change window state
It should be possible to change/retrieve a windows state. Possible states should be: Normal, Minimized, Maximized and maybe Fullscreen.
Implemented for Windows.
Looked briefly at the code for commit 60a6ed5ac319488ce42274ef914edc30a0f56a0e. Looks like this won't work for applications that want to spawn multiple windows at once, will it?
should work, but after window is shown. Probably it makes sense to apply state when creating window, as well. Now new windows are created in normal state.
setWindowState works on window level
That's good then. And being able to change/influence state before showing a window is useful. You often want to start your window as maximized (would make sense for DlangIDE as well).
I was about to post a similar request, but about window size instead. I'm not sure if this exists in the API already, but I could not for the life of me find out a way to change the size of a window. (If I can't, then my program will have to start off at a size that squishes the controls, which I'd rather not have...)
Changing window size is implemented (but now on win32 only, and if window is already created) Try window.resizeWindow()
The current situation is far from ideal and the whole thing should be carefully designed.
Resizing and moving
I don't see a reason why setWindowState should be responsible for window resizing and moving. This just leads to ugly hacks with ugly RECT_VALUE_IS_NOT_SET constant. Also current implementations uses Rect as a way to pass point and size that is very confusing especially considering that rect.right and rect.bottom are used as width and height. This is big misuse since coordinates are not distances. Same for resizeWindow function that expects argument of Point type. But that's the global issue of dlangui. While Point is practically just 2-value tuple, it's very confusing to use it as size argument. We should consider creating separate Size type and use it instead.
So regarding sizing/positioning:
- Remove the third argument from setWindowState. Use separate API for settings size and position.
- Remove RECT_VALUE_IS_NOT_SET if it's not used in other places.
- Don't use Point to pass or return size values. Create separate Size type and use it in every size-related function.
About WindowState.
Actually there're 4 types of state:
- Visibility: Shown vs Hidden
- State: Normal (restored) vs Maximized vs Minimized vs Fullscreen
- Focus ownership: Activated (focused) vs Nonactive (unfocused)
- Position in window stack: Raised vs Lowered
In theory all four kinds of states can be used independently. On practice we should check how they are handled by each platform. E.g. I don't see a way how to restore window on SDL without activating it. Also I don't know it's possible to maximize/minimize window while leaving it hidden if it was hidden before.
API for Visibility
- hide: hide window completely without changing the current State (normal vs maximized vs etc.). Probably state is preserved by window managers, so no need for additional code. Hidden window loses focus and not raised.
- show: should be opposite of hide. Should show the window in the same state it had before hiding unless state was changed by restore, minimize, maximize or setState (see below) after hiding. Not sure about focus and position in window stack (your suggestions?)
API for State
- showNormal: make window visible and restore it. Probably make active and raised by default.
- showMinimized: make window visible and minimize it.
- showMaximized: make window visible and maximize it. Probably make active and raised by default.
- showFullscreen (or showFullScreen, not sure which notation is better): make window visible and make it fullscreen. Probably make active and raised by default.
-
restore:
- If window is currently hidden mark it as restored so the next call to show will have the same effect as showNormal.
- If window is currently visible just restore it and probably make active and raised by default.
-
minimize:
- If window is currently hidden mark it as minimized so the next call to show will have the same effect as showMinimized.
- If window is currently visible just minimize it.
-
maximize:
- If window is currently hidden mark it as maximized so the next call to show will have the same effect as showMaximized.
- If window is currently visible just maximize it and probably make active and raised by default.
Probably restore, minimize and maximize will not be used often. So instead of (or in addition to) them we can have single setState with the same rules as described functions (i.e. if window is hidden then just mark what state window should have on the next show) and also ability to make window fullscreen.
Considering that it's possible to change State when window is hidden we probably should remove WindowState.hidden from enum and add separate property to check window visibility (e.g. isVisible or isHidden).
API for Focus ownership
-
activate:
- If window is visible: make window focused.
- If window is hidden: mark window as active for the next show OR do nothing (what do you think?)
No need for losing focus function. It's not clear how to give focus to the window of other application. If user wants to give focus to other window of the same application, one should just call activate on that window.
API for Position in window stack
-
raise:
- If window is visible: make window raised.
- If window is hidden: mark window as raised for the next show OR do nothing (what do you think?)
-
lower:
- If window is visible: lower window in window stack.
- If window is hidden: mark window as lowered for the next show OR do nothing (what do you think?)
WindowState handling
Currently Windows implementation never call handleWindowStateChange function. It should be fixed. I like how SDL2 version calls it in response to events because that way we can track window state even if it's changed by user or window manager (though SDL_WINDOWEVENT_MAXIMIZED is not delivered on my platform for some reason - should be investigated). It's not clear if handleWindowStateChange should be called when state is marked for change (when window is hidden). Probably not. Let's stick to the events for now.
Here's the plan:
- Call handleWindowStateChange on Windows in response to events
- Investigate and fix issues on SDL2
- Call handleWindowStateChange on X11 in response to events
I had similar conclusions when working on windowRect
on SDL. Rect
has right
, bottom
fields and height
/width
properties so using right
, bottom
for size is a little confusing.
I made some fixes for SDL see #372. Old SDL versions has a lot of problems on linux for example changing window size by dragging on my Mint with SDL 2.0.4 always reset window position to 8,9. SDL 2.0.5 works OK.
Regarding rects there's also a problem that width != right - left and height != bottom - top actually. E.g. imagine 2-pixel width rect. Left x is 0 and right x is 1. right - left = 1, but there're two pixels, so width should be 2.
Right/bottom bounds of Rects, at least in DlangUI, are non-inclusive. So, (0, 0, 2, 2) is 2x2 rect.
Right/bottom bounds of Rects, at least in DlangUI, are non-inclusive. So, (0, 0, 2, 2) is 2x2 rect.
It would be good to add this information to Rect
documentation :)
Added doc comments to Rect
Now window management is working on SDL, windows and X11 (high priority so is repaired but not redesigned yet). The last thing is fix focus (currently if you open two windows with edits there are blinking carets in both windows). I start working on this. After this we can make clean up and redesign (if Vadim approve changes).
Great news.
Focus is implemented and released in v0.9.89. Clean up platform code is the next step.
hello. just want to summarize/clarify 'bottom' and 'right' properties meaning of windowRect. currently those properties are equal to window height and width - is this as it should be or will this change? aren't bottom and right should represent second coordinate of window?
here is the testing code https://github.com/AnimusPEXUS/dlangtests/tree/master/t17
and screenshot of it's work