-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Windows implementation of setTitlebarVisible (#75) #286
base: main
Are you sure you want to change the base?
Conversation
1158559
to
1a98350
Compare
1a98350
to
bdce4c5
Compare
It took me quite a while to successfully setup the dev environment and compile the project. Now I can confirm that after This works both in normal application mode and full screen mode (after |
I also checked the PR and it works great!
I think so, yes. As much as it’s possible. Reasistically people will also probably set this once after creating a window, but the problem is, it happens on the very first toggle (create -> hide title bar). I’d prefer that it doesn’t change size here |
JWM demo works with Ctrl+T "Toggle Resize" Update README.md with JWM_DEBUG env instructions & $JAVA_HOME/bin
bdce4c5
to
6b583ae
Compare
Fixed the "window size increasing" behavior, updated I ended up deleting handler in
Test Instructions
Hopefully this is the mergeable commit! 🤞 |
This does work better! I do think that correcting the size right in the setTitlebarVisible is ultimately the right move. Can I ask you to change one more thing, though? The way I feel this should work is that
and
should produce the same result. In other words, you tell your window to occupy certain amount of space on a screen. For example, 1/2 on the left. Then, no matter whether you turn titlebar on or off, the amount of space it occupies should stay the same. The external border of the window should not move. Content area will expand/compact a little when removing titlebar, but that’s about it. I feel this is the most natural behavior. What do you think? If you agree, then the order you have your conditions is reversed: e.g. if I remove titlebar, I should take window size, hide titlebar, and then set content size to previous coordinates/dimensions. I tried it myself and it didn’t produce desirable results. Looks like this is because we actually measure window boundary wrong! See #289 So this is what I suggest. Can you fix #289 first and then we come back here and swap the windowSize/contentSize in the setTitlebarVisible and it will all work flawlessly? |
RE: I'm trying to fix #289 but ran into an issue where Windows doesn't report the dropshadow width/height until the first render of the window. This means that the shadow width/height can't be immediately accounted for when restoring the titlebar. To fix this, maybe we can react to a Alternatively, we can "remember" the dropshadow size from the first time we hid the window and use those values when restoring the titlebar+border styles. I'll work on this some more in a few days. |
I think remembering is fine? They don’t change anyway, right? |
It shouldn't change unless the user changes the Windows theming (removing drop shadow), but that seems like a fine compromise for not having the intermediate possibly-bugged state while we wait for a |
I was able to workaround the bugged local behavior but the code is nasty.
|
@tonsky Are you trying to support Windows XP?
This .h itself is only available on Vista or later. To support XP, this needs to somehow be dynamically loaded without breaking the linker on Vista+. Note that the If we drop Windows XP support then I can submit this PR immediately without needing to add Windows version detection. I've cleaned up the code (as much as is possible) but I need to solve "Windows version detection" before I can submit it. You're supposed to use the below snippet to get the bounds of the application without the dropshadow, but it's only available on Vista or later (majorVersion > 6)
It turns out that detecting the OS version is nontrivial, the methods have been deprecated multiple times, and Windows would prefer you test for the presence of features. Except there's no universally available feature that tells you if DwmGetWindowAttributes exists or if you're on Vista+. There is https://learn.microsoft.com/en-us/windows/win32/api/versionhelpers/nf-versionhelpers-iswindowsvistaorgreater , but this requires a correct Windows manifest to be set & I suspect we can't rely on that. This could use more investigation. https://learn.microsoft.com/en-us/windows/win32/sysinfo/targeting-your-application-at-windows-8-1 So I'm working on a shim to determine OS version for the sake of |
That’s fine I think, we probably won’t run on Vista any time soon. Maybe we should care about Win 10 but not lowerOn 26 Feb 2024, at 20:42, Quest Yarbrough ***@***.***> wrote:
I've cleaned up the code (as much as is possible) but I need to solve "Windows version detection" before I can submit it. You're supposed to use the below snippet to get the bounds of the application without the dropshadow, but it's only available on Vista or later (majorVersion > 6)
DwmGetWindowAttribute(_hWnd, DWMWA_EXTENDED_FRAME_BOUNDS, &rect, sizeof(rect));
It turns out that detecting the OS version is nontrivial, the methods have been deprecated multiple times, and Windows would prefer you test for the presence of features. Except there's no supported feature that tells you if DwmGetWindowAttributes exists or if you're on Vista+.
https://learn.microsoft.com/en-us/windows/win32/sysinfo/targeting-your-application-at-windows-8-1
So I'm working on a shim to determine OS version for the sake of getWindowRect() & will submit the PR once this is complete.
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you were mentioned.Message ID: ***@***.***>
|
See getWindowRect, setTitlebarVisible, setContentSize, setWindowSize
Added latest commit. I misspoke earlier -- this should work on Vista but won't on Windows XP. The code seems nasty to me. I suspect @tonsky will have some comments to address before the final commit. For the sake of diff, I've just added a 2nd commit instead of squashing both commits down. |
Re: code itself. I see you change _windowShadowWidth/Height back and forth. Wouldn’t it be better if you just identify them after window is first shown and remember these values? As I understand, you need to account for shadow if titlebar is visible and not account for it if it’s not. Might this be just a condition in setWindowSize? Something along the lines of
I find it easier to work with when state is immutable |
I see what you mean with the changes. I'll try to remove the windowShadow vars on next commit & fix the DPI calculation. I remember something in the MS docs about DPI sensitivity & I'm sure there's a way to work around it but it'll take some testing to figure it out. I'll do this as soon as I can but I'm unexpectedly buying & moving to a new place. It may be a few months before I get my programming time back but I'm looking forward to landing this PR and thanks for the feedback along the way. 🙏 |
c4ee4a9
to
5bdc87b
Compare
Opening as Windows impl of #75. First commit has working
setTitlebarVisible
in JWM's demo.I was going to implement more methods but
setTitle(title)
is already implemented & works on my machine. The rest of the methods Tonsky mentions in #75 (comment) are Mac specific & may not have clear Windows analogues.For my own usage I only hide the titlebar. I'm happy to leave Windows style extension to a future PR, but thoughts @tonsky ?
TODOs
Bugs
Can probably solve this by handling WM_STYLECHANGED event in
jwm::WindowWin32::processEvent
switchsee https://learn.microsoft.com/en-us/windows/win32/winmsg/wm-stylechanged
setContentSize
inWM_STYLECHANGED
, but has logical side-effect of growing the window by the titlebar-height on every other toggleTest Instructions
Assuming you have Windows local build setup & you're in the VS x64 command prompt:
python script/build.py && python script/run.py
Ctrl+T
in JWM's demo window toToggle Titlebar
. The titlebar should disappear from the top of the window.Toggle Titlebar
again & the default titlebar should reappearNote that I've only tested this on Windows 10.