[FIXED] Enhance native display window API

Started by princec, July 06, 2011, 23:13:30

Previous topic - Next topic

kappa

Quote from: CodeBunny on July 14, 2011, 11:41:00
Is there any form of callback? How can I detect if the Display has changed size?
Just call Display.wasResized() every frame, if it returns true you will know that the window has been resized and that new Display.getWidth() and Display.getHeight() values are available. You can then take the appropriate steps to reposition/resize your content.

Quote from: CodeBunny on July 14, 2011, 11:41:00
Also, what happens to the viewport when it is set smaller than the full Display but the window is resized?
Only the window size is increased (i.e. more/less of the opengl context is visible at top right), nothing on the opengl side is changed (nor any viewport), that's up to you on how you want it to behave, whether you want to zoom/scale everything to new sizes or increase usable area by repositioning stuff.

Each of the above methods have JavaDoc defining the behaviour of the methods (just download the docs bundle from nightly builds and look at the Display class).

CodeBunny


princec

Sounds perfect. Just need a way to determine if the window has focus or not now, and a way to grab it if possible (I'm aware that the crossplatform behaviour in this instance is sketchy). One reason I'd like to be able to do this is when switching a setParented display to fullscreen, we actually get two windows on the taskbar in Windows; if you alt-tab off the fullscreen display you're confronted with a rather strange big black window. I was hoping to be able to check that the fullscreen display was no longer focused and setVisible(false) on the AWT frame but of course that causes the LWJGL display to explode. So going back to the LWJGL Display seemed like the best idea. For which I needed the resizing stuff :)

How complex would it be to add setLocation()/setBounds()/setX()/setY()/setSize()/setWidth()/setHeight() API do you think? I suspect there are people out there who want to use an undecorated Display and manage their mouse interactions with custom widgetry rendered in OpenGL (TWL springs to mind).

Cas :)

kappa

Another update, Matzon's already finished the windows implementation and just needs to iron out some quirks, so we're almost done with implementing the resize api for all 3 platforms.

Quote from: princec on July 15, 2011, 09:46:26
Sounds perfect. Just need a way to determine if the window has focus or not now, and a way to grab it if possible (I'm aware that the crossplatform behaviour in this instance is sketchy). One reason I'd like to be able to do this is when switching a setParented display to fullscreen, we actually get two windows on the taskbar in Windows; if you alt-tab off the fullscreen display you're confronted with a rather strange big black window. I was hoping to be able to check that the fullscreen display was no longer focused and setVisible(false) on the AWT frame but of course that causes the LWJGL display to explode. So going back to the LWJGL Display seemed like the best idea. For which I needed the resizing stuff :)
The Display.isActive() call should tell you whether the window has focus.

As for the setParent issue you could try unparent the Display before switching to fullscreen and then reparent when going back to windowed mode, use Display.setParent(null) to unparent.

Quote from: princec on July 15, 2011, 09:46:26
How complex would it be to add setLocation()/setBounds()/setX()/setY()/setSize()/setWidth()/setHeight() API do you think? I suspect there are people out there who want to use an undecorated Display and manage their mouse interactions with custom widgetry rendered in OpenGL (TWL springs to mind).
Display.setLocation(x, y) is already implemented :). As for setting the window size this can be done using

Display.setDisplayMode(new DisplayMode(width,height));

so you can pretty easily write your own wrapper methods for setBounds(), setX(), setY(), setSize(), setWidth(), setHeight(), especially now that Display has the new methods Display.getWidth() and Display.getHeight().

The above is also some of the reason why only a subset of the original RFE was picked, however the extra methods you mentioned are nice and provide a much cleaner API. LWJGL 3.0 will probably be the API Breakage release and the plan is to rethink the API to be nice, simple and consistent without worrying about backwards compatibility or bloating the Display API. Probably need to reconsider if DisplayMode's should be used for windowed mode, IMO they're a bit ugly for such a usecase.

spasi

Awesome job guys, that was very fast.

princec

Aha of course. Funny how after all these years I've only just gotten around to looking at this :)
Yes, the use of DisplayModes for windowed mode is rather strange - though of course there is the issue of aux/stencil/depth buffers and bitdepth as well; looks like the dimensions and buffer configurations probably need factoring apart.

Cas :)

jediTofu

This is probably by design, but "Display.wasResized()" doesn't work in Applets (and probably never when in a Canvas?).  Just something to remember when writing Javadoc for these new methods ;)  The workaround is to use ComponentListener's of course.
cool story, bro

kappa

Quote from: jediTofu on July 20, 2011, 03:52:07
This is probably by design, but "Display.wasResized()" doesn't work in Applets (and probably never when in a Canvas?).  Just something to remember when writing Javadoc for these new methods ;)  The workaround is to use ComponentListener's of course.

Yup, the JavaDoc does mention if Display.setParent() or Fullscreen is being used then Display.setResized() will always return false.

Just curious, are you already using the resize api?

jediTofu

Quote from: kappa on July 20, 2011, 08:40:26
Quote from: jediTofu on July 20, 2011, 03:52:07
This is probably by design, but "Display.wasResized()" doesn't work in Applets (and probably never when in a Canvas?).  Just something to remember when writing Javadoc for these new methods ;)  The workaround is to use ComponentListener's of course.

Yup, the JavaDoc does mention if Display.setParent() or Fullscreen is being used then Display.setResized() will always return false.

Just curious, are you already using the resize api?

Well, I was just testing it out, because I thought that it'd be useful for my applet (since I'm setting width and height to 100% of the browser window).  When I'm done, I'll probably also deploy it using Java WebStart though and use the resize api there.  However, for the applet, I'm just using a component listener on the canvas.  So the answer is...yes and no haha
cool story, bro

princec

Hm returning "false" is I think exactly the sort of abuse of return values that exceptions were designed for. I think it should throw an IllegalStateException if you attempt to ask if it's resized when in fullscreen mode.

Cas :)

jediTofu

Quote from: princec on July 21, 2011, 12:13:18
Hm returning "false" is I think exactly the sort of abuse of return values that exceptions were designed for. I think it should throw an IllegalStateException if you attempt to ask if it's resized when in fullscreen mode.

Cas :)

But then you'd have to put a try-catch block in your game loop (plus the if statement), and I think that's more computationally expensive than an if statement?
cool story, bro

kappa

Another quick update on this, Matzon committed the resizing code for the windows implementation yesterday, so hopefully folk on Windows can start testing it too with the nightly builds.

It still has a few quirks in it namely:

Quote<Mazon> known issues/kinks:
1) window moves a bit when enabling resize (and back when disabling) - "normal" behavior?,
2) resize mouse cursor seems to sometimes stay when inside window (?)
3) when enabling resize, the client area seems to be off by x pixels - at least in mousetest, oddly minimizing and maximizing seems to "fix" the issue

All 3 of the above seem to be related to some odd Win API stuff, if anyone here is familiar with that API, do consider providing some feedback to assist in ironing them out.

Liam

Hi there,

I have tested the new API on Windows 7 64 bit and no problems here - great job! It feels a lot sturdier than the AWT workaround and I look forward to scrapping my Frame. As someone who is looking to use this, I do however have one request if I may?

As I see it the only thing that is missing is the ability to maximize the window. If that could be considered for the API requirements I would be a happy camper, at the moment I am forced to continue using the AWT workaround as my window needs to be that flexible.

Just thought I would drop this in. Great work so far!
Liam

EDIT: I have added a page to the Wiki with the AWT workaround and example code. I have dropped mention of the efforts being made here, when this is finalized either I'll update it with the new implementation or let you guys do it ^.^

http://www.lwjgl.org/wiki/index.php?title=Using_a_Resizeable_Native_Window

jediTofu

Quote1) window moves a bit when enabling resize (and back when disabling) - "normal" behavior?,
I would think that this would be from calling AdjustWindowRectEx in WindowsDisplay#setResizable.  If AdjustWindowRectEx is already called somewhere else first, I'd think all you would have to do is call setWindowPos and use the rect from GetWindowRect instead of GetClientRect.  You usually call AdjustWindowRect just the first time when creating the window, or if you add/change some GUI components.

Or if you're really wanting to adjust the client rect, then you'll have to take the window rect into consideration:
http://www.suite101.com/content/client-area-size-with-movewindow-a17846

Quote2) resize mouse cursor seems to sometimes stay when inside window (?)
I don't understand the question  ???

Quote3) when enabling resize, the client area seems to be off by x pixels - at least in mousetest, oddly minimizing and maximizing seems to "fix" the issue
Not sure here.  Sounds like you need to get the insets somehow and then add that to the x and y of the client rect.  The link above would do that.  I'm not sure how else to get the insets like you can in Java.
cool story, bro

princec

Quote
Quote2) resize mouse cursor seems to sometimes stay when inside window (?)
I don't understand the question  ???
It's a bug - sometimes, when the mouse cursor is in the border of a resizable window, and hence in the "Resize N/S" or "Resize E/W" shape, and you move it back into the window, it stays the wrong shape instead of turning back into an ordinary pointer.

Cas :)