Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Window state  (Read 39933 times)

0 Members and 3 Guests are viewing this topic.

Foaly

  • Sr. Member
  • ****
  • Posts: 453
    • View Profile
Window state
« on: February 01, 2018, 11:35:24 pm »
Hello everybody,
I was looking into a ticket that I have already been working on in the past. It is on maximing a window from code. Reading over the discussion again it seems to end with an already pretty good concept for an API. I though about it some more and I want to propose a design here. I'd like to hear your thoughts and if we can agree on it or develop it further I would like to start an implementation soon. Oh and a thing you guys are gonna like: we don't have to change the existing API, except for one deprecation ;)

So I would suggest this:
enum State
{
    Windowed,
    Minimized,
    Maximized,
    Fullscreen
};


sf::Window::State state = sf::Window::State::Minimized;
window.create(videoMode, title, style, settings, state);
state = window.getState();
window.setState(state);

So as you can see we have a seperation between state and style. Style is now only for the appearance/decoration of a window. The state of the window can now be described seperatly. An enum somewhere contains the possible window states. States are exclusive, so a window can only ever have one state. The create method will be extended by another parameter for the style, which can default to Windowed. The platform implementation of create will then open the window in the given state. There is also a getter and a setter in sf::Window. The setter will simply apply the state to the window. The getter will return the windows current state. Those are all the additions to the API. The Fullscreen window style would have to be deprecated in order to make a clear distinction between style and state.

This API would have two welcome side effects. You could finally switch to fullscreen mode and back (at least I have found it very annoying in the past that you always have to recreate the window for that, especially since things like the mouse visibility are not saved). Also it would allow creating a hidden/invisible window on creation by passing the minimized state to the create function.

So I would like to hear your thoughts on this :)


FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Window state
« Reply #1 on: February 02, 2018, 12:45:35 am »
Looks fine to me, maybe allowing creating hidden Windows would be an additional nice thing to have?

It looks close to how LCL does it too: http://lazarus-ccr.sourceforge.net/docs/lcl/forms/twindowstate.html

I'd do it differently (but I'm biased towards Windows): add a new style flag to allow creating a hidden window and add a maximize() call but it might come from the fact that latter is doable with WinApi right now and former isn't (not easily anyway, I could create my entire own window handle and use the other constructor...) so there is a flicker on Window creation due to initial non-maximized Window being shown.
« Last Edit: February 02, 2018, 12:47:30 am by FRex »
Back to C++ gamedev with SFML in May 2023

Foaly

  • Sr. Member
  • ****
  • Posts: 453
    • View Profile
Re: Window state
« Reply #2 on: February 02, 2018, 01:21:49 am »
Cool, thank!
Well I think with the proposed API you could achive similar results. When you pass the style to the create method the style is applied to the window directly on creation. On windows this is possible by passing the dwStyle flag to CreateWindow. The style can be any of these. So in order to get a hidden window you could create a minimized window. Of course you could also start with a maximized right away.
On MacOS NSWindow does not seem to have a way to apply a style on init. We will have to see if there is a flickering when applyed immediately afterwards.

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Window state
« Reply #3 on: February 02, 2018, 01:33:02 am »
A minimized window still appears in the task bar. A true hidden Window would just not have WS_VISIBLE set in dwStyle on creation on Windows.

The only possible use for this is if someone wants a hidden window without flicker (I have no idea what for, I wanted it to not have flicker before I maximize it with WinApi).

I know how to look up stuff in WinApi or SFML source code but creating own window is still a lot of additional code to go around this compared to a single ShowWindow to maximize a window via handle.

I'm just saying since even if I don't now need hidden windows if this is accepted someone else might and SFML has hidden windows already, just not initially hidden ones and that causes a flicker on Windows as if a virus has just popped up a cmd.exe window to hack you or something tried to start and failed or something... it's also visually jarring.
« Last Edit: February 02, 2018, 01:38:18 am by FRex »
Back to C++ gamedev with SFML in May 2023

Sub

  • Full Member
  • ***
  • Posts: 159
    • View Profile
Re: Window state
« Reply #4 on: February 02, 2018, 01:56:00 am »
Out of pure curiosity, what's the use case in having a hidden window?

edit:  Also, thank you Foaly.  This is something I've long wanted in SFML.
« Last Edit: February 02, 2018, 02:09:04 am by Sub »

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Window state
« Reply #5 on: February 02, 2018, 02:19:53 am »
I don't know, maybe something like not destroying the Window and GL context it has if you just want it to not be shown for some time.

I wanted the initial hidden window to then maximize it myself and have no flicker due to initial one being shown.

SFML already has a setVisible function too so there has to be some use deemed important enough.
Back to C++ gamedev with SFML in May 2023

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Window state
« Reply #6 on: February 02, 2018, 08:34:35 am »
The proposed API is fine and can be done in SFML 2.x, but I have one problem with it so let me suggest a slight variation.

The thing is, it adds yet another argument to the constructor and create function ; moreover, if we don't want to break API compatibility, it has to be the last one but the "right" order for it would clearly be between "style" and "settings". Not the end of the world, but not ideal.

Why do we have so many arguments to create the window? Because it's shown directly as it is created, so it has to have all its final attributes right away.

What if instead we allow to create an invisible window, then set whatever attributes with (already existing or new) setter functions, and finally show it? Yes, this is basically what FRex suggests.

All we'd need is an additional style flag, something like sf::Style::Hidden -- which is fine because the style is set at creation time and can never be changed later -- and then call setState, setTitle or whatever, and finally setVisible(true).

TL;DR: keep everything as proposed, but simply replace the additional "state" argument with a new "Hidden" style flag.
Laurent Gomila - SFML developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Window state
« Reply #7 on: February 02, 2018, 10:29:15 am »
By "replace" do you mean, use it as default value?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Window state
« Reply #8 on: February 02, 2018, 11:02:22 am »
I mean, don't add the "state" argument to constructor, instead provide a new "Hidden" style. As for the defaults, there's no need to change the current behaviour.
Laurent Gomila - SFML developer

Foaly

  • Sr. Member
  • ****
  • Posts: 453
    • View Profile
Re: Window state
« Reply #9 on: February 02, 2018, 11:24:13 am »
Thanks for the feedback.
But now you got me confused. I understood it like exploiter explained it.
So to my understanding you propose the following: As discribed above by me, but don't add a new style parameter to create, but instead always create a window in the hidden state. So a reagular call would look something like this:
window.create(videoMode, title, style, settings);
// or
window.create(videoMode, title);
// window is NOT visible at this point

// call some setters

window.setState(sf::State::Windowed); // or maximized or whatever

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Window state
« Reply #10 on: February 02, 2018, 12:51:53 pm »
Is that really what I said? :o

You got me wrong, here is what I suggest:

// NO CHANGE, create visible and windowed, as in current version
window.create(videoMode, title, style, settings);

// ADDED function
window.setState(sf::State::Maximized);

// BUT IF YOU WANT you can also create the window hidden, configure it and show it later
window.create(videoMode, title, style | sf::Style::Hidden, settings);
window.setState(sf::State::Fullscreen);
window.setVisible(true);

So it's:
- add the sf::State enum and Window::setState/getState functions, as proposed initially
- deprecate sf::Style::Fullscreen, of course
- add sf::Style::Hidden (it's the only thing that changes in my proposal)
« Last Edit: February 02, 2018, 12:53:25 pm by Laurent »
Laurent Gomila - SFML developer

Foaly

  • Sr. Member
  • ****
  • Posts: 453
    • View Profile
Re: Window state
« Reply #11 on: February 02, 2018, 04:14:46 pm »
I thought it sounded weird, thats why I was confused :D
Well ok, I guess this would be possible too. I don't really see anything that speaks against it. It is nice to have the constructor with few arguments, but I wouldn't consider the wrong order a real problem. One thing that will be unexpected for users is that the default way to create a fullscreen window will look like this:
window.create(videoMode, title, style | sf::Style::Hidden, settings);
window.setState(sf::State::Fullscreen);
window.setVisible(true);
Which might be confusing as you didn't really have to deal with those things before.
Also thinking about it I would consider the visibility more of a state than a style, but then the design you proposed wouldn't work.
Another question I have is what happens if the user only passes sf::Style::Hidden to a window and then calls setVisible(true)? Should a default window (Titlebar | Resize | Close) or a window without any decorations (None) be shown?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Window state
« Reply #12 on: February 02, 2018, 05:23:26 pm »
Quote
I wouldn't consider the wrong order a real problem
I do ;D

Quote
One thing that will be unexpected for users is that the default way to create a fullscreen window will look like this
Only for those who care about seeing the window not fullscreen for a fraction of second. For the rest of the world, it's just
window.create(videoMode, title, style, settings);
window.setState(sf::State::Fullscreen);
... which looks more natural.

Quote
Also thinking about it I would consider the visibility more of a state than a style, but then the design you proposed wouldn't work.
Well, visibility is a state (we have set/getVisible that we can call anytime), maybe naming the flag sf::Style::InitiallyHidden would be less confusing? Because that's what this flag is for: deciding the initial visibility of the window.

Quote
Another question I have is what happens if the user only passes sf::Style::Hidden to a window and then calls setVisible(true)? Should a default window (Titlebar | Resize | Close) or a window without any decorations (None) be shown?
The addition of sf::Style::Hidden doesn't change anything, if you don't pass other flags it's equivalent to sf::Style::None.
Laurent Gomila - SFML developer

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Window state
« Reply #13 on: February 03, 2018, 04:52:30 pm »
I quite like the proposal of adding sf::Style::Hidden to allow the window to be hidden initially and allow some state alterations before making the window visible.

However, instead of deprecating sf::Style::Fullscreen, it could remain so that it would automatically set the state. This would continue to allow the previous (and still simple) and expected SFML 2 code:
window.create(videomode, title, sf::Style::Fullscreen, settings);

This would then automatically set the state to sf::State::Fullscreen. If sf::Style::Fullscreen remains as exclusive to other styles then a decision would need to be made as to which style the window actually is for when the state is set to windowed. However, the option now is to allow the style to be provided along with the fullscreen 'style' for this reason. Of course, if only sf::Style::Fullscreen is used here, this would mean sf::Style::None | sf::Style::Fullscreen.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Window state
« Reply #14 on: February 04, 2018, 11:20:03 am »
Quote
However, instead of deprecating sf::Style::Fullscreen, it could remain so that it would automatically set the state.
Sounds like really confusing to have both sf::Style::Fullscreen and sf::State::Fullscreen. And why would we make a special case for this one, and not for the others? I think we should make things simple, clean and consistent.
Laurent Gomila - SFML developer