dukke / FXThemes

Utility classes for advanced Theme development for JavaFX (Java)
https://pixelduke.com/fxthemes
39 stars 5 forks source link

Windows 10 - Issue with maximized windows... #8

Open regice202 opened 4 months ago

regice202 commented 4 months ago

Hey @dukke!

So I ran into something quite interesting today.. I forgot in an old FXML file that I automatically maximized my application, so I added that back in. What I found out was some strange behavior that is quite noteworthy.. For whatever reason, if the Stage in question is maximized, it doesn't update right away; however if it is anything BUT maximized, it works fine. I tried setIconified(true); on the main window, and whenever I opened it back while my dialog was open it would update, as well as after the dialog had been closed and I reopened the main window (regardless of it being maximized or not when iconified). It has something to do with the focus I'm assuming?.. Anyways, something I figured I'd bring to your attention. It's probably a Windows or JFX thing, not necessarily specific to this library; but again, noteworthy nonetheless.

Here you can see the maximized behavior, pay attention to the title bar. java_0NCzsvISbg

And this in the regular behavior in every other state. java_wAKpLESUSr

This may be fixable/worked around if you check for the isMaximized() boolean of the stage and also check isIconified() == false, then do some trickery with the focus of the Stage. I'm going to probe further and see if I can come up with a fix. If I can I'll post an update here which could help resolve this issue for other users in future, adding a fix/work around when the ThemeManager makes changes to the window (Stage).

regice202 commented 4 months ago

UPDATE!!!

So I did manage to put in a fix, albeit not a pretty one. It does have something to do with the focus of the Stages. I couldn't request focus for the main Stage even if the dialog was just show()n and not waiting for a result (showAndWait()). There may exist a prettier solution, but it's getting late and I can't find/think of a better one at the moment. So for now I have to quickly hide and show the dialog to bring the focus back to the main Stage for a split second. Here's the code used:

applyWindowTheme(mainStage);
if (pane.getScene() != null){ //Didn't hit the OK button which closes the dialog immediately
    applyWindowTheme(settingsStage);

    //Check for weird maximized condition
    if (settingsStage.isFocused() && !mainStage.isIconified() && mainStage.isMaximized()){
        settingsStage.hide();
        settingsStage.show();
    }
}
dukke commented 3 months ago

The thing is I had to do a hack to update the Stage on Windows 10. The way I do it is to resize the Stage just a bit, so it is not perceived by the user. Resizing the Stage makes the window frame update. That's why it isn't working when you have it maximized (since you can't resize a maximized Stage). It's hacky but it's the only way I found to update the Stage on Win10.

regice202 commented 3 months ago

@dukke Thanks for the info!

That does help a bit. I was going to suggest maybe shifting the position of the window slightly (again a very unperceptible change), but that most likely wouldn't work with a maximized window.. Though it might be worth trying out.

dukke commented 3 months ago

Yeah I don't think it will work with a maximized window. If you find any other way please share.. I'm a bit busy at the moment with another open-source project and work...

Thanks @regice202 ! :)

regice202 commented 3 months ago

I'll give it a shot anyways, you never know. The only other idea I have would be hooking into the JFX rendering engine via reflection or something else and updating it in there somehow. Again, focus seems to play some role in updating the Window itself in Windows. Not sure if we can force focus somehow other than my little hack, but maybe. Either way it seems like other options would be pretty bulky/invasive.

Edit: Woops! Didn't mean to press that close button lol.