Bug 1214

Summary: NEWT: MacOSX incorrect auto-resize GLWindow when it is larger than screen.
Product: [JogAmp] Newt Reporter: Xerxes Rånby <xerxes>
Component: macosxAssignee: Sven Gothel <sgothel>
Status: RESOLVED FIXED    
Severity: normal CC: andres.colubri, xerxes
Priority: ---    
Version: 2.3.2   
Hardware: All   
OS: macosx   
Type: --- SCM Refs:
d3185d3c79f04012e604039f84466479bab755f9 10ad1270e7b8f821ef9bb3612669342c7dc56586
Workaround: ---
Bug Depends on: 1188    
Bug Blocks:    
Attachments: processing-3-macosx-auto-resize-issue-[a].png

Description Xerxes Rånby 2015-09-06 23:23:54 CEST
Created attachment 730 [details]
processing-3-macosx-auto-resize-issue-[a].png

Processing 3 reports a bug with the JogAmp JOGL 2.3.1 using NEWT on MacOSX that the GLWindow gets incorrectly auto-resized to fit inside the screen when a user has created a GLWindow that is larger than the screen.

The downsteam processing 3 bug discusses two issues:

[a] the GLWindow gets incorrectly auto-resized, content is rendered outside the window, see attached processing-3-macosx-auto-resize-issue-[a].png
[b] discussion if jogl auto-resize in general according to hardware limitations or API enforced limitations.

Resources:
[1ab] Downstream Processing 3  bug: https://github.com/processing/processing/issues/3401

[2b] Discussion on jogamp forum: http://forum.jogamp.org/unusual-GLWindow-behavior-on-OS-X-td4035234.html

[3b] Discussion on jogamp IRC:
http://jogamp.org/log/irc/jogamp_20150903050508.html#l107
20150903 13:45:58 <xranby> sgothel: if a user create an enourmous GLWindow lets say size 8000,6000 and use setResizable(false) before making a GLWindow visible, should this window still be auto-resized to fit within the screen limits?
20150903 13:46:29 <xranby> i have creates a junit test that expose this issue ( if we expect the window to stay 8000x6000)
20150903 13:47:19 <xranby> the user surely expects the window to stay 8000x6000
20150903 13:56:19 <xranby> sgothel: junit test https://github.com/xranby/jogl/commit/401a01ba31cf6c98d95a67dfa1021af854438044
20150903 14:01:38 <xranby> the above testcase fail with AssertionError: expected:<8000> but was:<1855>
20150903 14:01:52 <xranby> since newt has auto resized the window
20150903 15:00:53 <sgothel> clipping .. is expected
20150903 15:02:09 <sgothel> I assume they use it this way due to some hi-res screenshot or printin?
20150903 15:02:14 <sgothel> printing
20150903 15:02:36 <sgothel> then they shall use offscreen and maybe even tilted-renderer .. as we use for printing
20150903 15:03:03 <sgothel> b/c no platform can guarantee such window sized >> virtual desktop size
Comment 1 Xerxes Rånby 2015-09-06 23:33:51 CEST
It would be very good if someone with MacOSX can copy and change one of the JOGL junit tests and make it demonstrate the issue [a] as described in [1ab] without using Processing 3.
Comment 2 Xerxes Rånby 2015-09-06 23:38:56 CEST
(In reply to comment #0)
> [3b] Discussion on jogamp IRC:
> http://jogamp.org/log/irc/jogamp_20150903050508.html#l107
> 20150903 13:45:58 <xranby> sgothel: if a user create an enourmous GLWindow
> lets say size 8000,6000 and use setResizable(false) before making a GLWindow
> visible, should this window still be auto-resized to fit within the screen
> limits?
> 20150903 13:46:29 <xranby> i have creates a junit test that expose this
> issue ( if we expect the window to stay 8000x6000)
> 20150903 13:47:19 <xranby> the user surely expects the window to stay
> 8000x6000
> 20150903 13:56:19 <xranby> sgothel: junit test
> https://github.com/xranby/jogl/commit/
> 401a01ba31cf6c98d95a67dfa1021af854438044
> 20150903 14:01:38 <xranby> the above testcase fail with AssertionError:
> expected:<8000> but was:<1855>
> 20150903 14:01:52 <xranby> since newt has auto resized the window
> 20150903 15:00:53 <sgothel> clipping .. is expected
...
> 20150903 15:03:03 <sgothel> b/c no platform can guarantee such window sized
> >> virtual desktop size

It is understood that no platform can guarantee that a window is sized larger that the virtual desktop size.
However today the window is auto-re-sized according to screen size.
Should we auto.re-size according to virtual desktop size instead?
Comment 3 Xerxes Rånby 2015-09-06 23:43:29 CEST
(In reply to comment #2)
> (In reply to comment #0)
> > [3b] Discussion on jogamp IRC:
> > http://jogamp.org/log/irc/jogamp_20150903050508.html#l107
> > 20150903 13:45:58 <xranby> sgothel: if a user create an enourmous GLWindow
> > lets say size 8000,6000 and use setResizable(false) before making a GLWindow
> > visible, should this window still be auto-resized to fit within the screen
> > limits?
> > 20150903 13:46:29 <xranby> i have creates a junit test that expose this
> > issue ( if we expect the window to stay 8000x6000)
> > 20150903 13:47:19 <xranby> the user surely expects the window to stay
> > 8000x6000
> > 20150903 13:56:19 <xranby> sgothel: junit test
> > https://github.com/xranby/jogl/commit/
> > 401a01ba31cf6c98d95a67dfa1021af854438044
> > 20150903 14:01:38 <xranby> the above testcase fail with AssertionError:
> > expected:<8000> but was:<1855>
> > 20150903 14:01:52 <xranby> since newt has auto resized the window
> > 20150903 15:00:53 <sgothel> clipping .. is expected
> ...
> > 20150903 15:03:03 <sgothel> b/c no platform can guarantee such window sized
> > >> virtual desktop size
> 
> It is understood that no platform can guarantee that a window is sized
> larger that the virtual desktop size.
> However today the window is auto-re-sized according to screen size.
> Should we auto.re-size according to virtual desktop size instead?

Example on my hardware the maximum virtual desktop size is according to xrandr: 16384 x 16384

Screen 0: minimum 8 x 8, current 1920 x 1080, maximum 16384 x 16384
Comment 4 ac 2015-09-07 17:21:59 CEST
Hi Xerxes, thanks for putting together the junit test. I will try it on windows, mac, and linux using a single/multiple monitor setups and will report back.

Andres
Comment 5 ac 2015-09-07 17:22:12 CEST
Hi Xerxes, thanks for putting together the junit test. I will try it on windows, mac, and linux using a single/multiple monitor setups and will report back.

Andres
Comment 6 Xerxes Rånby 2015-09-08 00:03:51 CEST
(In reply to comment #5)
> Hi Xerxes, thanks for putting together the junit test. I will try it on
> windows, mac, and linux using a single/multiple monitor setups and will
> report back.
> 
> Andres

We have analysed issue [a] and [b] on the jogamp irc:
http://jogamp.org/log/irc/jogamp_20150907050509.html#l46

[b] discussion the origin of auto-resize in general
20150907 19:59:15 <sgothel> so reconfigureImpl for OSX, X11 and Windows don't clip the size
20150907 19:59:24 <sgothel> let me check our native code
20150907 20:02:12 <sgothel> x11, windows: no clipping - so here it comes from the native WM

20150907 20:18:30 <sgothel> so you experienced, that on X11 the window size is already clipped to virt-screen size ?
20150907 20:18:46 <sgothel> then we should do that in WindowImpl .. explicitly .. agreed ..
20150907 20:20:52 <sgothel> hope we don't break some weird use-case .. but IMHO it is ok ..
20150907 20:21:18 <sgothel> so a validateSize @ native-creation _and_ at setSize_if_nativeCreated
20150907 20:21:32 <sgothel> only then we have the virtual screen size available
20150907 20:21:56 <sgothel> ok?
20150907 20:22:26 * xranby_f22 is parsing what you said
20150907 20:22:37 <xranby_f22> one moment
20150907 20:26:48 <xranby_f22> sgothel: i experience that on X11 if i create windows larger than the screen then the windowmanager tries to fit the window inside the screen, however if i resize the window after it has been created then i can make them XXL large
20150907 20:27:13 <xranby_f22> thus large windows are supported on the hardware level
20150907 20:28:14 <sgothel> GLWindow/X11: req. size 4096 x 4096 -> 3840x2136 (max-size)
20150907 20:28:29 <sgothel> (i.e. WM auto-clipping)
20150907 20:28:58 <sgothel> hmm .. one sec
20150907 20:30:04 <sgothel> yes - possible
20150907 20:30:23 <sgothel> clipped at creation - manual resize possible later on ..
20150907 20:30:51 <sgothel> so .. need to fix the OSX method first I guess


[a] on MacOSX the GLWindow gets incorrectly auto-resized, content is rendered outside the window, see attached processing-3-macosx-auto-resize-issue-[a].png
[a] OSX issue is caused by:
20150907 20:05:07 <sgothel> On OSX 'setWindowClientTopLeftPointAndSize(..)' is used, which does not clip .. but performs a 'coordinate system swap'
20150907 20:07:03 <sgothel> y-flip from TL-screen -> BL-screen
20150907 20:07:21 <sgothel> TopLeft -> BottomLeft
20150907 20:07:58 <sgothel> NewtMacWindow::newtAbsClientTLWinPos2AbsBLScreenPos(..)
20150907 20:08:41 <sgothel> yes .. that method uses the screen size to calculate the top-left .. autch
20150907 20:08:59 <sgothel> sorry, to calculate the Bottom-Left
20150907 20:09:14 <sgothel> doesn't work here, since window height >> screen height
Comment 7 ac 2015-09-12 03:36:57 CEST
Hi Xerxes, 

I run your unit test on Windows 10, Ubuntu 12.04, and Mac OS X 10.9.5. 

Windows and Ubuntu behave in the same way: the window gets resized to the screen dimensions, and the new width/height are reported by window.getWidth() and window.getHeight().

However, on Mac while the window is clipped to the size of the screen, window.getWidth()/getHeight() report the original dimensions.

I think the best solution would be to ensure that GLWindow on Mac behaves in the same way as in Windows and Linux, i.e.: the window is resized and getWidth/getHeight return the resized values.

Andres
Comment 8 ac 2015-09-21 01:19:42 CEST
Hey guys,

I was looking at the native newt code for OS X, and it seems to me that one possible approach to solve this issue could be to add clippedWidth/Height functions to MacWindow.m, and then to use these functions to obtain the clipped with/height values before calling initWindow() in WindowDriver.java... what do you think? I could work on this approach some more if you think it is reasonable, and eventually create a pull request.

We are aiming to release Processing 3.0 final soon, and this issue is a stopper for us. Let me know if you have any other thoughts.

Cheers,

Andres
Comment 9 ac 2015-09-21 23:49:16 CEST
This commit in my fork of the jogl repo contains the resize method I have been working on:

https://github.com/codeanticode/jogl/commit/2f0172d597b61629c428052ad412aaea2eb2b29d
Comment 10 Sven Gothel 2015-09-22 01:28:15 CEST
(In reply to ac from comment #9)
> This commit in my fork of the jogl repo contains the resize method I have
> been working on:
> 
> https://github.com/codeanticode/jogl/commit/
> 2f0172d597b61629c428052ad412aaea2eb2b29d

Thank you Andres! KUDOS for pushing code!

I review your code right now.

Originally I wanted to drop this case 
into setWindowClientTopLeftPointAndSize(..)
which will also tackles the resize case
via reconfigureImpl(..).

Let me analyze this .. you will have a fix and build
by tomorrow.
Comment 11 ac 2015-09-22 23:22:44 CEST
Please let me know if there is anything I can help with, such as testing, etc.
Comment 12 Sven Gothel 2015-09-25 09:44:22 CEST
commit d3185d3c79f04012e604039f84466479bab755f9

NEWT MacOSX: Detect auto-resize of Window when it is larger than screen
    
- On OSX (similar to X11) a created window with size > screen
  will get resized to fit screen size implicitly.
    
- Fix detects insets, position and size after onscreen window creation.
  
- Patch also merges insets and size change java callback
Comment 13 ac 2015-09-25 13:25:30 CEST
nice, thanks so much Sven!

I will run some tests on my end, and let you know how it goes
Comment 14 ac 2015-09-25 15:31:30 CEST
I tested the fix from Processing, including in a multiple monitor configuration, and it is working very nicely. Thanks again!
Comment 16 Sven Gothel 2015-09-26 02:59:33 CEST
commit 10ad1270e7b8f821ef9bb3612669342c7dc56586
    
- Fix Deadlock in screenPositionChanged(..)
  Defer requires to spawn whole child-window action to another thread
  since we may come from native 'NewtWindow::windowDidMove()' on MainThread.
    
- Use screenPositionChanged(..) in size[Screen]PosInsetsChanged(..) on OSX
  Move callback WindowImpl::sizePosInsetsChanged(..)
  to OSX's WindowDriver::sizeScreenPosInsetsChanged(..),
  since we need to use screenPositionChanged(..) to calculate
  child window relative position to parent.
  I.e. we receive the location on screen.
    
- Cleanup OSX Code
  - Native JNI entries shall handle NULL windowHandle -> return

  - Clarify usage of 'getWindowHandle()' and use 'isNativeValid()'
    if appropriate.
    
  - Don't re-use cached getWindowHandle()
    for non-blocking off-thread actions, since handle may become invalid.
    
  - Clarify getLocationOnScreen*(..) implementation code,
    i.e. separate getLocationOnScreenByParent(..) semantics.
Comment 17 Sven Gothel 2015-09-26 03:43:15 CEST
commit 10ad1270e7b8f821ef9bb3612669342c7dc56586
closes this bug.