dlangui icon indicating copy to clipboard operation
dlangui copied to clipboard

Feature Request: Programmatically change window state

Open default0 opened this issue 8 years ago • 17 comments

It should be possible to change/retrieve a windows state. Possible states should be: Normal, Minimized, Maximized and maybe Fullscreen.

default0 avatar May 05 '16 15:05 default0

Implemented for Windows.

buggins avatar May 19 '16 12:05 buggins

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?

default0 avatar May 19 '16 20:05 default0

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.

buggins avatar May 20 '16 04:05 buggins

setWindowState works on window level

buggins avatar May 20 '16 04:05 buggins

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).

default0 avatar May 20 '16 05:05 default0

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...)

TheGag96 avatar May 27 '16 02:05 TheGag96

Changing window size is implemented (but now on win32 only, and if window is already created) Try window.resizeWindow()

buggins avatar May 30 '16 12:05 buggins

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:

  1. Remove the third argument from setWindowState. Use separate API for settings size and position.
  2. Remove RECT_VALUE_IS_NOT_SET if it's not used in other places.
  3. 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:

  1. Visibility: Shown vs Hidden
  2. State: Normal (restored) vs Maximized vs Minimized vs Fullscreen
  3. Focus ownership: Activated (focused) vs Nonactive (unfocused)
  4. 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:

  1. Call handleWindowStateChange on Windows in response to events
  2. Investigate and fix issues on SDL2
  3. Call handleWindowStateChange on X11 in response to events

FreeSlave avatar Jun 10 '17 19:06 FreeSlave

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.

and3md avatar Jun 11 '17 05:06 and3md

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.

FreeSlave avatar Jun 11 '17 11:06 FreeSlave

Right/bottom bounds of Rects, at least in DlangUI, are non-inclusive. So, (0, 0, 2, 2) is 2x2 rect.

buggins avatar Jun 13 '17 10:06 buggins

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 :)

and3md avatar Jun 13 '17 15:06 and3md

Added doc comments to Rect

buggins avatar Jun 14 '17 05:06 buggins

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).

and3md avatar Aug 08 '17 17:08 and3md

Great news.

buggins avatar Aug 10 '17 10:08 buggins

Focus is implemented and released in v0.9.89. Clean up platform code is the next step.

and3md avatar Aug 15 '17 17:08 and3md

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 Screenshot from 2021-05-24 15-32-54

AnimusPEXUS avatar May 24 '21 12:05 AnimusPEXUS