diff options
author | Sven Gothel <[email protected]> | 2015-08-12 03:01:26 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2015-08-12 03:01:26 +0200 |
commit | 2c23b1cb343a008621e3fe642c5b8abacca48b1a (patch) | |
tree | df62efc34cd8344888cbfa2bff8ad9210e4f48f2 | |
parent | 8df37534138e15061e66e6460391dcdc413b521f (diff) |
Bug 1188: Refine Maximized on X11 / Impl. Maximized and Iconify on Windows
WindowImpl
- remove updateMinMaxSize(..) - unused info
- fix appendStateToString: show all maximized state changes if reconfig
- add sizePosMaxInsetsChanged(..) and sendMouseEventRequestFocus(..)
accumulating multiple callbacks from impl.
- add: maximizedChanged(..) notification from native impl.
- refine manual maximized mode
used for OSX and Windows (single extent)
- reconfigMaximizedManual(..)
- resetMaximizedManual(..)
X11 WindowDriver:
- Update maximized at xreconfig, read from _NET_WM_STATE
- Use less Java callbacks from JNI
Windows WindowDriver:
- Use native maximized, if HORZ && VERT,
otherwise use manual maximized for single extent.
- Invisible of top-window -> MINIMIZED/ICONIFY
showing the app in task-bar.
-rwxr-xr-x | make/scripts/tests-win.bat | 4 | ||||
-rwxr-xr-x | make/scripts/tests-x64-dbg.bat | 4 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/WindowImpl.java | 152 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java | 40 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java | 46 | ||||
-rw-r--r-- | src/newt/native/WindowsWindow.c | 122 | ||||
-rw-r--r-- | src/newt/native/X11Common.h | 8 | ||||
-rw-r--r-- | src/newt/native/X11Display.c | 41 | ||||
-rw-r--r-- | src/newt/native/X11Window.c | 112 | ||||
-rw-r--r-- | src/test/com/jogamp/opengl/test/junit/util/NEWTDemoListener.java | 6 |
10 files changed, 352 insertions, 183 deletions
diff --git a/make/scripts/tests-win.bat b/make/scripts/tests-win.bat index d91de44b7..d468fdb2e 100755 --- a/make/scripts/tests-win.bat +++ b/make/scripts/tests-win.bat @@ -7,7 +7,7 @@ REM scripts\java-win.bat com.jogamp.oculusvr.OVRVersion %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNewtAWTWrapper %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT -time 30000 REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestGearsES1NEWT %* -REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT %* +scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT -vsync -time 4000 -x 10 -y 10 -width 100 -height 100 -screen 0 REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT -vsync -time 40000 -width 100 -height 100 -screen 0 %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWT %* @@ -59,7 +59,7 @@ REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedConte REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2SWT3 %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextNewtAWTBug523 %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListAWT %* -scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedExternalContextAWT %* +REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedExternalContextAWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBOOffThreadSharedContextMix2DemosES2NEWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBOOnThreadSharedContext1DemoES2NEWT %* diff --git a/make/scripts/tests-x64-dbg.bat b/make/scripts/tests-x64-dbg.bat index ca625b2f1..5b522672a 100755 --- a/make/scripts/tests-x64-dbg.bat +++ b/make/scripts/tests-x64-dbg.bat @@ -31,7 +31,7 @@ REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" "-Djogamp.debug=all" "-Djogl.debug.EGLDrawableFactory.DontQuery"
REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" "-Djogl.debug.windows.cpu_affinity_mode=0" "-Djogl.debug.GLContext.TraceSwitch" "-Djogl.debug.GLContext"
REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" "-Djogl.debug.GLContext.TraceSwitch" "-Djogl.debug.GLContext"
-set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" "-Djogl.debug.GLContext"
+REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" "-Djogl.debug.GLContext"
REM set D_ARGS="-Djogl.disable.opengles"
REM set D_ARGS="-Djogl.disable.openglcore"
REM set D_ARGS="-Djogl.disable.openglarbcontext"
@@ -70,7 +70,7 @@ REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.GLJPanel" "-Djogl.debug.Til REM set D_ARGS="-Djogl.debug.GLContext" "-Djogl.debug.GLJPanel"
REM set D_ARGS="-Djogl.gljpanel.noverticalflip"
REM set D_ARGS="-Dnewt.debug=all"
-REM set D_ARGS="-Dnewt.debug.Window"
+set D_ARGS="-Dnewt.debug.Window"
REM set D_ARGS="-Dnewt.debug.Window.KeyEvent"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Window.KeyEvent" "-Dnewt.debug.EDT"
REM set D_ARGS="-Dnewt.debug.Window.MouseEvent"
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 9a12286fe..5e8a1d806 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -73,6 +73,7 @@ import com.jogamp.common.util.locks.RecursiveLock; import com.jogamp.newt.Display; import com.jogamp.newt.Display.PointerIcon; import com.jogamp.newt.MonitorDevice; +import com.jogamp.newt.MonitorMode; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.Screen; import com.jogamp.newt.Window; @@ -173,8 +174,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer protected CapabilitiesChooser capabilitiesChooser = null; // default null -> default private List<MonitorDevice> fullscreenMonitors = null; - private final RectangleImmutable undefSize = new Rectangle(0, 0, 0, 0); - private final Rectangle minmax_size = new Rectangle(undefSize); // current min/max size or undef private int nfs_width, nfs_height, nfs_x, nfs_y; // non fullscreen client-area size/pos w/o insets private NativeWindow nfs_parent = null; // non fullscreen parent, in case explicit reparenting is performed (offscreen) private String title = "Newt Window"; @@ -258,6 +257,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer stateMask.set(STATE_BIT_POINTERVISIBLE); stateMask.set(PSTATE_BIT_FULLSCREEN_NFS_RESIZABLE); stateMask.set(PSTATE_BIT_FULLSCREEN_MAINMONITOR); + normPosSizeStored[0] = false; + normPosSizeStored[1] = false; } @Override @@ -350,19 +351,21 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer if( showChangeFlags && 0 != ( ( CHANGE_MASK_MAXIMIZED_HORZ | CHANGE_MASK_MAXIMIZED_VERT ) & mask) ) { sb.append("max["); - if( 0 != ( STATE_MASK_MAXIMIZED_HORZ & mask) ) { - if( 0 != ( CHANGE_MASK_MAXIMIZED_HORZ & mask) ) { - sb.append("*"); - } - sb.append("h"); - sb.append(", "); + if( 0 != ( CHANGE_MASK_MAXIMIZED_HORZ & mask) ) { + sb.append("*"); } - if( 0 != ( STATE_MASK_MAXIMIZED_VERT & mask) ) { - if( 0 != ( CHANGE_MASK_MAXIMIZED_VERT & mask) ) { - sb.append("*"); - } - sb.append("v"); + if( 0 == ( STATE_MASK_MAXIMIZED_HORZ & mask) ) { + sb.append("!"); + } + sb.append("h"); + sb.append(", "); + if( 0 != ( CHANGE_MASK_MAXIMIZED_VERT & mask) ) { + sb.append("*"); } + if( 0 == ( STATE_MASK_MAXIMIZED_VERT & mask) ) { + sb.append("!"); + } + sb.append("v"); sb.append("], "); } else if( 0 != ( ( STATE_MASK_MAXIMIZED_HORZ | STATE_MASK_MAXIMIZED_VERT ) & mask) ) { sb.append("max["); @@ -879,6 +882,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer return appendStateBits(new StringBuilder(), flags, true).toString(); } + protected void setTitleImpl(final String title) {} /** @@ -1260,7 +1264,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } @Override public final void setTopLevelSize(final int width, final int height) { - setSize(width - getInsets().getTotalWidth(), height - getInsets().getTotalHeight()); + final InsetsImmutable insets = getInsets(); + setSize(width - insets.getTotalWidth(), height - insets.getTotalHeight()); } private final Runnable destroyAction = new Runnable() { @@ -2092,6 +2097,84 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer public final boolean isMaximizedHorz() { return stateMask.get(STATE_BIT_MAXIMIZED_HORZ); } + /** Triggered by implementation's WM events to update maximized window state. */ + protected void maximizedChanged(final boolean newMaxHorz, final boolean newMaxVert) { + final String stateMask0 = DEBUG_IMPLEMENTATION ? getStateMaskString() : null; + final boolean changedHorz = stateMask.put(STATE_BIT_MAXIMIZED_HORZ, newMaxHorz) != newMaxHorz; + final boolean changedVert = stateMask.put(STATE_BIT_MAXIMIZED_VERT, newMaxVert) != newMaxVert; + if ( DEBUG_IMPLEMENTATION ) { + if( changedHorz || changedVert ) { + System.err.println("Window.maximizedChanged: "+stateMask0+" -> "+getStateMaskString()); + } + } + } + /** + * Manually calculate maximized and de-maximized position and size + * not regarding a fixed taskbar etc. + * <p> + * Use only if: + * <code> + * 0 != ( ( CHANGE_MASK_MAXIMIZED_HORZ | CHANGE_MASK_MAXIMIZED_VERT ) & flags ) + * </code> + * </p> + * @param flags + * @param posSize + */ + protected void reconfigMaximizedManual(final int flags, final int posSize[], final InsetsImmutable insets) { + //if( 0 != ( ( CHANGE_MASK_MAXIMIZED_HORZ | CHANGE_MASK_MAXIMIZED_VERT ) & flags ) ) { + final MonitorMode mm = getMainMonitor().getCurrentMode(); + // FIXME HiDPI: Shortcut, may need to adjust if we change scaling methodology + final int mmWidth = SurfaceScaleUtils.scaleInv(mm.getRotatedWidth(), getPixelScaleX()); + final int mmHeight = SurfaceScaleUtils.scaleInv(mm.getRotatedHeight(), getPixelScaleY()); + + if( 0 != ( CHANGE_MASK_MAXIMIZED_HORZ & flags ) ) { + if( 0 != ( STATE_MASK_MAXIMIZED_HORZ & flags ) ) { + // max-h on + normPosSizeStored[0] = true; + normPosSize[0] = posSize[0]; + normPosSize[2] = posSize[2]; + posSize[0] = insets.getLeftWidth(); + posSize[2] = mmWidth - insets.getTotalWidth(); + } else { + // max-h off + normPosSizeStored[0] = false; + posSize[0] = normPosSize[0]; + posSize[2] = normPosSize[2]; + } + } + if( 0 != ( CHANGE_MASK_MAXIMIZED_VERT & flags ) ) { + if( 0 != ( STATE_MASK_MAXIMIZED_VERT & flags ) ) { + // max-v on + normPosSizeStored[1] = true; + normPosSize[1] = posSize[1]; + normPosSize[3] = posSize[3]; + posSize[1] = insets.getTopHeight(); + posSize[3] = mmHeight - insets.getTotalHeight(); + } else { + // max-v off + normPosSizeStored[1] = false; + posSize[1] = normPosSize[1]; + posSize[3] = normPosSize[3]; + } + } + //} + } + protected void resetMaximizedManual(final int posSize[]) { + if( normPosSizeStored[0] ) { + // max-h off + normPosSizeStored[0] = false; + posSize[0] = normPosSize[0]; + posSize[2] = normPosSize[2]; + } + if( normPosSizeStored[1] ) { + // max-v off + normPosSizeStored[1] = false; + posSize[1] = normPosSize[1]; + posSize[3] = normPosSize[3]; + } + } + private final int[] normPosSize = { 0, 0, 0, 0 }; + private final boolean[] normPosSizeStored = { false, false }; @Override public final String getTitle() { @@ -2630,7 +2713,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer @Override public final void setTopLevelPosition(final int x, final int y) { - setPosition(x + getInsets().getLeftWidth(), y + getInsets().getTopHeight()); + final InsetsImmutable insets = getInsets(); + setPosition(x + insets.getLeftWidth(), y + insets.getTopHeight()); } private class FullScreenAction implements Runnable { @@ -3096,6 +3180,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer final int x, final int y, final short button, final float rotation) { doMouseEvent(false, false, eventType, modifiers, x, y, button, MouseEvent.getRotationXYZ(rotation, modifiers), 1f); } + public final void enqueueMouseEvent(final boolean wait, final short eventType, final int modifiers, final int x, final int y, final short button, final float rotation) { doMouseEvent(true, wait, eventType, modifiers, x, y, button, MouseEvent.getRotationXYZ(rotation, modifiers), 1f); @@ -4111,20 +4196,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } - /** Triggered by implementation's WM events to update the position. */ - protected final void minMaxSizeChanged(final int min_width, final int min_height, final int max_width, final int max_height) { - if( 0 <= min_width && 0 <= min_height && 0 <= max_width && 0 <= max_height) { - final RectangleImmutable sz = new Rectangle(min_width, min_height, max_width, max_height); - if( !minmax_size.equals(sz) ) { - stateMask.put(PSTATE_BIT_MINMAXSIZE_SET, !sz.equals(undefSize)); - if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.minMaxSizeChanged: ("+getThreadName()+"): Current "+minmax_size+" -> "+sz); - } - minmax_size.set(sz); - } - } - } - /** Triggered by implementation's WM events to update the focus state. */ protected void focusChanged(final boolean defer, final boolean focusGained) { if( stateMask.get(PSTATE_BIT_FOCUS_CHANGE_BROKEN) || @@ -4408,6 +4479,29 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } // + // Accumulated actions + // + + /** Triggered by implementation's WM events to update the client-area position, size and maximized flags. */ + protected void sizePosMaxInsetsChanged(final boolean defer, + final int newX, final int newY, + final int newWidth, final int newHeight, + final boolean newMaxHorz, final boolean newMaxVert, + final int left, final int right, final int top, final int bottom, + final boolean force) { + sizeChanged(defer, newWidth, newHeight, force); + positionChanged(defer, newX, newY); + maximizedChanged(newMaxHorz, newMaxVert); + insetsChanged(defer, left, right, top, bottom); + } + /** Triggered by implementation. */ + protected final void sendMouseEventRequestFocus(final short eventType, final int modifiers, + final int x, final int y, final short button, final float rotation) { + sendMouseEvent(eventType, modifiers, x, y, button, rotation); + requestFocus(false /* wait */); + } + + // // Reflection helper .. // diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java index e62e0f5aa..0ab400fa3 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java @@ -42,7 +42,6 @@ import com.jogamp.nativewindow.MutableSurface; import com.jogamp.nativewindow.ScalableSurface; import com.jogamp.nativewindow.VisualIDHolder; import com.jogamp.nativewindow.util.Insets; -import com.jogamp.nativewindow.util.InsetsImmutable; import com.jogamp.nativewindow.util.Point; import com.jogamp.nativewindow.util.PointImmutable; @@ -54,7 +53,6 @@ import jogamp.newt.WindowImpl; import jogamp.newt.driver.DriverClearFocus; import jogamp.newt.driver.DriverUpdatePosition; -import com.jogamp.newt.MonitorMode; import com.jogamp.newt.event.InputEvent; import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.event.MonitorEvent; @@ -407,38 +405,12 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl pClientLevelOnSreen = getLocationOnScreenImpl(_x, _y, parent, useParent); } else { if( 0 != ( ( CHANGE_MASK_MAXIMIZED_HORZ | CHANGE_MASK_MAXIMIZED_VERT ) & flags ) ) { - final InsetsImmutable insets = getInsets(); - final MonitorMode mm = getMainMonitor().getCurrentMode(); - // FIXME HiDPI: Shortcut, may need to adjust if we change scaling methodology - final int mmWidth = SurfaceScaleUtils.scaleInv(mm.getRotatedWidth(), getPixelScaleX()); - final int mmHeight = SurfaceScaleUtils.scaleInv(mm.getRotatedHeight(), getPixelScaleY()); - - if( 0 != ( CHANGE_MASK_MAXIMIZED_HORZ & flags ) ) { - if( 0 != ( STATE_MASK_MAXIMIZED_HORZ & flags ) ) { - // max-h on - normPosSize[0] = _x; - normPosSize[2] = _width; - _x = insets.getLeftWidth(); - _width = mmWidth - insets.getTotalWidth(); - } else { - // max-h off - _x = normPosSize[0]; - _width = normPosSize[2]; - } - } - if( 0 != ( CHANGE_MASK_MAXIMIZED_VERT & flags ) ) { - if( 0 != ( STATE_MASK_MAXIMIZED_VERT & flags ) ) { - // max-v on - normPosSize[1] = _y; - normPosSize[3] = _height; - _y = insets.getTopHeight(); - _height = mmHeight - insets.getTotalHeight(); - } else { - // max-h off - _y = normPosSize[1]; - _height = normPosSize[3]; - } - } + final int[] posSize = { _x, _y, _width, _height }; + reconfigMaximizedManual(flags, posSize, getInsets()); + _x = posSize[0]; + _y = posSize[1]; + _width = posSize[2]; + _height = posSize[3]; } pClientLevelOnSreen = new Point(_x, _y); } diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java index 973b6ec4d..2eaedc101 100644 --- a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java @@ -45,7 +45,6 @@ import com.jogamp.nativewindow.AbstractGraphicsConfiguration; import com.jogamp.nativewindow.GraphicsConfigurationFactory; import com.jogamp.nativewindow.NativeWindowException; import com.jogamp.nativewindow.VisualIDHolder; -import com.jogamp.nativewindow.util.Insets; import com.jogamp.nativewindow.util.InsetsImmutable; import com.jogamp.nativewindow.util.Point; @@ -141,17 +140,30 @@ public class WindowDriver extends WindowImpl { } setGraphicsConfiguration(cfg); final VersionNumber winVer = Platform.getOSVersionNumber(); - final int flags = getReconfigureMask(0, true) & STATE_MASK_CREATENATIVE; + int flags = getReconfigureMask(0, true) & STATE_MASK_CREATENATIVE; + int maxCount = 0; + if( 0 != ( STATE_MASK_MAXIMIZED_HORZ & flags ) ) { + flags |= CHANGE_MASK_MAXIMIZED_HORZ; + maxCount++; + } + if( 0 != ( STATE_MASK_MAXIMIZED_VERT & flags ) ) { + flags |= CHANGE_MASK_MAXIMIZED_VERT; + maxCount++; + } final long _windowHandle = CreateWindow0(DisplayDriver.getHInstance(), display.getWindowClassName(), display.getWindowClassName(), winVer.getMajor(), winVer.getMinor(), getParentWindowHandle(), - getX(), getY(), getWidth(), getHeight(), autoPosition(), flags); + getX(), getY(), getWidth(), getHeight(), flags); if ( 0 == _windowHandle ) { throw new NativeWindowException("Error creating window"); } setWindowHandle(_windowHandle); windowHandleClose = _windowHandle; + if( 0 == ( STATE_MASK_CHILDWIN & flags ) && 1 == maxCount ) { + reconfigureWindowImpl(getX(), getY(), getWidth(), getHeight(), flags); + } + if(DEBUG_IMPLEMENTATION) { final Exception e = new Exception("Info: Window new window handle "+Thread.currentThread().getName()+ " (Parent HWND "+toHexString(getParentWindowHandle())+ @@ -193,18 +205,30 @@ public class WindowDriver extends WindowImpl { System.err.println("WindowsWindow reconfig.0: "+x+"/"+y+" "+width+"x"+height+ ", "+getReconfigStateMaskString(flags)); } - + final InsetsImmutable insets = getInsets(); + + if( 0 == ( STATE_MASK_CHILDWIN & flags ) && + 0 != ( ( CHANGE_MASK_MAXIMIZED_HORZ | CHANGE_MASK_MAXIMIZED_VERT ) & flags ) ) { + final int[] posSize = { x, y, width, height }; + if( ( 0 != ( STATE_MASK_MAXIMIZED_HORZ & flags ) ) == ( 0 != ( STATE_MASK_MAXIMIZED_VERT & flags ) ) ) { + resetMaximizedManual(posSize); // reset before native maximize/reset + } else { + reconfigMaximizedManual(flags, posSize, insets); + } + x = posSize[0]; + y = posSize[1]; + width = posSize[2]; + height = posSize[3]; + } if(0 == ( STATE_MASK_UNDECORATED & flags)) { - final InsetsImmutable i = getInsets(); - // client position -> top-level window position - x -= i.getLeftWidth() ; - y -= i.getTopHeight() ; + x -= insets.getLeftWidth() ; + y -= insets.getTopHeight() ; if(0<width && 0<height) { // client size -> top-level window size - width += i.getTotalWidth(); - height += i.getTotalHeight(); + width += insets.getTotalWidth(); + height += insets.getTotalHeight(); } } reconfigureWindow0( getParentWindowHandle(), getWindowHandle(), x, y, width, height, flags); @@ -367,7 +391,7 @@ public class WindowDriver extends WindowImpl { protected static native boolean initIDs0(long hInstance); private native long CreateWindow0(long hInstance, String wndClassName, String wndName, int winMajor, int winMinor, - long parentWindowHandle, int x, int y, int width, int height, boolean autoPosition, int flags); + long parentWindowHandle, int x, int y, int width, int height, int flags); private native long MonitorFromWindow0(long windowHandle); private native void reconfigureWindow0(long parentWindowHandle, long windowHandle, int x, int y, int width, int height, int flags); diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index ad4111ec7..a1ba4d3b8 100644 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -177,6 +177,7 @@ static jmethodID insetsChangedID = NULL; static jmethodID sizeChangedID = NULL; +static jmethodID maximizedChangedID = NULL; static jmethodID positionChangedID = NULL; static jmethodID focusChangedID = NULL; static jmethodID visibleChangedID = NULL; @@ -218,9 +219,13 @@ typedef struct { HCURSOR setPointerHandle; HCURSOR defPointerHandle; /** Bool: 0 NOP, 1 FULLSCREEN */ - int isFullscreen; + BOOL isFullscreen; /** Bool: 0 TOP, 1 CHILD */ - int isChildWindow; + BOOL isChildWindow; + /** Bool: 0 NOP, 1 minimized/iconic */ + BOOL isMinimized; + /** Bool: 0 NOP, 1 maximized */ + BOOL isMaximized; int pointerCaptured; int pointerInside; int touchDownCount; @@ -787,11 +792,27 @@ static void WmSize(JNIEnv *env, WindowUserData * wud, HWND wnd, UINT type) RECT rc; BOOL isVisible = IsWindowVisible(wnd); jobject window = wud->jinstance; + BOOL maxChanged = FALSE; + + DBG_PRINT("*** WindowsWindow: WmSize.0 window %p, %dx%d, isMinimized %d, isMaximized %d, visible %d\n", + (void*)wnd, wud->width, wud->height, wud->isMinimized, wud->isMaximized, isVisible); if (type == SIZE_MINIMIZED) { - // TODO: deal with minimized window sizing + wud->isMinimized = TRUE; return; } + if (type == SIZE_MAXIMIZED) { + if( !wud->isMaximized ) { + wud->isMaximized = 1; + maxChanged = TRUE; + } + } else if (type == SIZE_RESTORED) { + wud->isMinimized = FALSE; + if( wud->isMaximized ) { + wud->isMaximized = FALSE; + maxChanged = TRUE; + } + } // make sure insets are up to date (void)UpdateInsets(env, window, wnd); @@ -802,8 +823,13 @@ static void WmSize(JNIEnv *env, WindowUserData * wud, HWND wnd, UINT type) wud->width = (int) ( rc.right - rc.left ); wud->height = (int) ( rc.bottom - rc.top ); - DBG_PRINT("*** WindowsWindow: WmSize window %p, %dx%d, visible %d\n", (void*)wnd, wud->width, wud->height, isVisible); + DBG_PRINT("*** WindowsWindow: WmSize.X window %p, %dx%d, isMinimized %d, isMaximized %d (changed %d), visible %d\n", + (void*)wnd, wud->width, wud->height, wud->isMinimized, wud->isMaximized, maxChanged, isVisible); + if( maxChanged ) { + jboolean v = wud->isMaximized ? JNI_TRUE : JNI_FALSE; + (*env)->CallVoidMethod(env, window, maximizedChangedID, v, v); + } (*env)->CallVoidMethod(env, window, sizeChangedID, JNI_FALSE, wud->width, wud->height, JNI_FALSE); } @@ -1020,6 +1046,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP break; case WM_SHOWWINDOW: + DBG_PRINT("*** WindowsWindow: WM_SHOWWINDOW window %p: %d\n", wnd, wParam==TRUE); (*env)->CallVoidMethod(env, window, visibleChangedID, JNI_FALSE, wParam==TRUE?JNI_TRUE:JNI_FALSE); break; @@ -2032,6 +2059,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowDriver_initIDs0 insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)V"); sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZIIZ)V"); + maximizedChangedID = (*env)->GetMethodID(env, clazz, "maximizedChanged", "(ZZ)V"); positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(ZII)V"); focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)V"); visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V"); @@ -2044,6 +2072,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowDriver_initIDs0 if (insetsChangedID == NULL || sizeChangedID == NULL || + maximizedChangedID == NULL || positionChangedID == NULL || focusChangedID == NULL || visibleChangedID == NULL || @@ -2088,32 +2117,51 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_getNewtWndP return (jlong) (intptr_t) wndProc; } -static void NewtWindow_setVisiblePosSize(HWND hwnd, BOOL atop, BOOL visible, +static void NewtWindow_setVisiblePosSize(WindowUserData *wud, HWND hwnd, int jflags, BOOL visible, int x, int y, int width, int height) { - UINT flags; - BOOL bRes; - - DBG_PRINT("*** WindowsWindow: NewtWindow_setVisiblePosSize %d/%d %dx%d, atop %d, visible %d\n", - x, y, width, height, atop, visible); + BOOL atop = TST_FLAG_IS_ALWAYSONTOP(jflags); + BOOL abottom = TST_FLAG_IS_ALWAYSONBOTTOM(jflags); + UINT wflags; + + DBG_PRINT("*** WindowsWindow: NewtWindow_setVisiblePosSize %d/%d %dx%d, atop %d, abottom %d, max[change[%d %d], is[%d %d]], visible %d\n", + x, y, width, height, atop, abottom, + TST_FLAG_CHANGE_MAXIMIZED_VERT(jflags), TST_FLAG_CHANGE_MAXIMIZED_HORZ(jflags), + TST_FLAG_IS_MAXIMIZED_VERT(jflags), TST_FLAG_IS_MAXIMIZED_HORZ(jflags), + visible); if(visible) { - flags = SWP_SHOWWINDOW; + wflags = SWP_SHOWWINDOW; } else { - flags = SWP_NOACTIVATE | SWP_NOZORDER; + wflags = SWP_NOACTIVATE | SWP_NOZORDER; } if(0>=width || 0>=height ) { - flags |= SWP_NOSIZE; + wflags |= SWP_NOSIZE; } if(atop) { - SetWindowPos(hwnd, HWND_TOP, x, y, width, height, flags); - SetWindowPos(hwnd, HWND_TOPMOST, x, y, width, height, flags); + SetWindowPos(hwnd, HWND_TOP, x, y, width, height, wflags); + SetWindowPos(hwnd, HWND_TOPMOST, x, y, width, height, wflags); + } else if(abottom) { + SetWindowPos(hwnd, HWND_NOTOPMOST, x, y, width, height, wflags); + SetWindowPos(hwnd, HWND_BOTTOM, x, y, width, height, wflags); } else { - SetWindowPos(hwnd, HWND_NOTOPMOST, x, y, width, height, flags); - SetWindowPos(hwnd, HWND_TOP, x, y, width, height, flags); + SetWindowPos(hwnd, HWND_NOTOPMOST, x, y, width, height, wflags); + SetWindowPos(hwnd, HWND_TOP, x, y, width, height, wflags); + } + // SetWindowPos(hwnd, atop ? HWND_TOPMOST : HWND_TOP, x, y, width, height, wflags); + + if( TST_FLAG_CHANGE_MAXIMIZED_ANY(jflags) ) { + if( TST_FLAG_IS_MAXIMIZED_VERT(jflags) && TST_FLAG_IS_MAXIMIZED_HORZ(jflags) ) { + wud->isMaximized = 1; + ShowWindow(hwnd, SW_MAXIMIZE); + } else if( !TST_FLAG_IS_MAXIMIZED_VERT(jflags) && !TST_FLAG_IS_MAXIMIZED_HORZ(jflags) ) { + if( wud->isMaximized ) { + ShowWindow(hwnd, SW_RESTORE); + wud->isMaximized = 0; + } + } } - // SetWindowPos(hwnd, atop ? HWND_TOPMOST : HWND_TOP, x, y, width, height, flags); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); @@ -2128,7 +2176,7 @@ static void NewtWindow_setVisiblePosSize(HWND hwnd, BOOL atop, BOOL visible, JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindow0 (JNIEnv *env, jobject obj, jlong hInstance, jstring jWndClassName, jstring jWndName, jint winMajor, jint winMinor, - jlong parent, jint jx, jint jy, jint defaultWidth, jint defaultHeight, jboolean autoPosition, jint flags) + jlong parent, jint jx, jint jy, jint defaultWidth, jint defaultHeight, jint flags) { HWND parentWindow = (HWND) (intptr_t) parent; const TCHAR* wndClassName = NULL; @@ -2157,7 +2205,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindo windowStyle |= WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX; } else { windowStyle |= WS_OVERLAPPEDWINDOW; - if(JNI_TRUE == autoPosition) { + if( TST_FLAG_IS_AUTOPOSITION(flags) ) { // user didn't requested specific position, use WM default _x = CW_USEDEFAULT; _y = 0; @@ -2172,7 +2220,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindo DBG_PRINT("*** WindowsWindow: CreateWindow thread 0x%X, win %d.%d parent %p, window %p, %d/%d %dx%d, undeco %d, alwaysOnTop %d, autoPosition %d\n", (int)GetCurrentThreadId(), winMajor, winMinor, parentWindow, window, x, y, width, height, - TST_FLAG_IS_UNDECORATED(flags), TST_FLAG_IS_ALWAYSONTOP(flags), autoPosition); + TST_FLAG_IS_UNDECORATED(flags), TST_FLAG_IS_ALWAYSONTOP(flags), TST_FLAG_IS_AUTOPOSITION(flags)); if (NULL == window) { int lastError = (int) GetLastError(); @@ -2188,8 +2236,10 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindo wud->setPointerAction = 0; wud->defPointerHandle = LoadCursor( NULL, IDC_ARROW); wud->setPointerHandle = wud->defPointerHandle; - wud->isFullscreen = 0; + wud->isFullscreen = FALSE; wud->isChildWindow = NULL!=parentWindow; + wud->isMinimized = FALSE; + wud->isMaximized = FALSE; wud->pointerCaptured = 0; wud->pointerInside = 0; wud->touchDownCount = 0; @@ -2224,12 +2274,12 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindo insets = UpdateInsets(env, wud->jinstance, window); (*env)->CallVoidMethod(env, wud->jinstance, visibleChangedID, JNI_FALSE, JNI_TRUE); - if(JNI_TRUE == autoPosition) { + if( TST_FLAG_IS_AUTOPOSITION(flags) ) { GetWindowRect(window, &rc); x = rc.left + insets->left; // client coords y = rc.top + insets->top; // client coords } - DBG_PRINT("*** WindowsWindow: CreateWindow client: %d/%d %dx%d (autoPosition %d)\n", x, y, width, height, autoPosition); + DBG_PRINT("*** WindowsWindow: CreateWindow client: %d/%d %dx%d (autoPosition %d)\n", x, y, width, height, TST_FLAG_IS_AUTOPOSITION(flags)); x -= insets->left; // top-level y -= insets->top; // top-level @@ -2237,7 +2287,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindo height += insets->top + insets->bottom; // top-level DBG_PRINT("*** WindowsWindow: CreateWindow top-level %d/%d %dx%d\n", x, y, width, height); - NewtWindow_setVisiblePosSize(window, TST_FLAG_IS_ALWAYSONTOP(flags), TRUE, x, y, width, height); + NewtWindow_setVisiblePosSize(wud, window, flags, TRUE, x, y, width, height); } if( wud->supportsMTouch ) { WinTouch_RegisterTouchWindow(window, 0); @@ -2288,7 +2338,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureW HWND hwndP = (HWND) (intptr_t) parent; HWND hwnd = (HWND) (intptr_t) window; DWORD windowStyle = WS_DEFAULT_STYLES; - BOOL styleChange = TST_FLAG_CHANGE_DECORATION(flags) || TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_PARENTING(flags) ; + BOOL styleChange = TST_FLAG_CHANGE_DECORATION(flags) || TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_PARENTING(flags); WindowUserData * wud; #if !defined(__MINGW64__) && ( defined(UNDER_CE) || _MSC_VER <= 1200 ) wud = (WindowUserData *) GetWindowLong(hwnd, GWL_USERDATA); @@ -2297,13 +2347,14 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureW #endif - DBG_PRINT( "*** WindowsWindow: reconfigureWindow0 parent %p, window %p, %d/%d %dx%d, parentChange %d, isChild %d, decorationChange %d, undecorated %d, fullscreenChange %d, fullscreen %d, alwaysOnTopChange %d, alwaysOnTop %d, visibleChange %d, visible %d -> styleChange %d, isChild %d, isFullscreen %d\n", + DBG_PRINT( "*** WindowsWindow: reconfigureWindow0 parent %p, window %p, %d/%d %dx%d, parentChange %d, isChild %d, decorationChange %d, undecorated %d, fullscreenChange %d, fullscreen %d, alwaysOnTopChange %d, alwaysOnTop %d, visibleChange %d, visible %d -> styleChange %d, isChild %d, isMinimized %d, isMaximized %d, isFullscreen %d\n", parent, window, x, y, width, height, TST_FLAG_CHANGE_PARENTING(flags), TST_FLAG_IS_CHILD(flags), TST_FLAG_CHANGE_DECORATION(flags), TST_FLAG_IS_UNDECORATED(flags), TST_FLAG_CHANGE_FULLSCREEN(flags), TST_FLAG_IS_FULLSCREEN(flags), TST_FLAG_CHANGE_ALWAYSONTOP(flags), TST_FLAG_IS_ALWAYSONTOP(flags), - TST_FLAG_CHANGE_VISIBILITY(flags), TST_FLAG_IS_VISIBLE(flags), styleChange, wud->isChildWindow, wud->isFullscreen); + TST_FLAG_CHANGE_VISIBILITY(flags), TST_FLAG_IS_VISIBLE(flags), styleChange, + wud->isChildWindow, wud->isMinimized, wud->isMaximized, wud->isFullscreen); if (!IsWindow(hwnd)) { DBG_PRINT("*** WindowsWindow: reconfigureWindow0 failure: Passed window %p is invalid\n", (void*)hwnd); @@ -2336,7 +2387,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureW if( TST_FLAG_CHANGE_FULLSCREEN(flags) && TST_FLAG_IS_FULLSCREEN(flags) ) { // FS on // TOP: in -> out - wud->isFullscreen = 1; + wud->isFullscreen = TRUE; NewtWindows_setFullScreen(JNI_TRUE); } @@ -2354,7 +2405,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureW if( TST_FLAG_CHANGE_FULLSCREEN(flags) && !TST_FLAG_IS_FULLSCREEN(flags) ) { // FS off // CHILD: out -> in - wud->isFullscreen = 0; + wud->isFullscreen = FALSE; NewtWindows_setFullScreen(JNI_FALSE); } @@ -2363,17 +2414,22 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureW SetParent(hwnd, hwndP ); } - NewtWindow_setVisiblePosSize(hwnd, TST_FLAG_IS_ALWAYSONTOP(flags), TST_FLAG_IS_VISIBLE(flags), x, y, width, height); + NewtWindow_setVisiblePosSize(wud, hwnd, flags, TST_FLAG_IS_VISIBLE(flags), x, y, width, height); if( TST_FLAG_CHANGE_VISIBILITY(flags) ) { if( TST_FLAG_IS_VISIBLE(flags) ) { - ShowWindow(hwnd, SW_SHOW); + int cmd = wud->isMinimized ? SW_RESTORE : SW_SHOW; + wud->isMinimized = FALSE; + ShowWindow(hwnd, cmd); + } else if( !TST_FLAG_CHANGE_VISIBILITY_FAST(flags) && !TST_FLAG_IS_CHILD(flags) ) { + wud->isMinimized = TRUE; + ShowWindow(hwnd, SW_MINIMIZE); } else { ShowWindow(hwnd, SW_HIDE); } } - DBG_PRINT("*** WindowsWindow: reconfigureWindow0.X isChild %d, isFullscreen %d\n", wud->isChildWindow, wud->isFullscreen); + DBG_PRINT("*** WindowsWindow: reconfigureWindow0.X isChild %d, isMinimized %d, isFullscreen %d\n", wud->isChildWindow, wud->isMinimized, wud->isFullscreen); } /* diff --git a/src/newt/native/X11Common.h b/src/newt/native/X11Common.h index 309e62683..cdfb65d50 100644 --- a/src/newt/native/X11Common.h +++ b/src/newt/native/X11Common.h @@ -71,7 +71,7 @@ extern jclass X11NewtWindowClazz; extern jmethodID insetsChangedID; extern jmethodID visibleChangedID; -extern jmethodID minMaxSizeChangedID; +extern jmethodID sizePosMaxInsetsChanged; typedef struct { Window window; @@ -81,13 +81,15 @@ typedef struct { Atom windowDeleteAtom; uint32_t supportedAtoms; uint32_t lastDesktop; + Bool maxHorz; + Bool maxVert; } JavaWindow; JavaWindow * getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning); Status NewtWindows_getRootAndParent (Display *dpy, Window w, Window * root_return, Window * parent_return); -Status NewtWindows_updateInsets(JNIEnv *env, Display *dpy, JavaWindow * w, int *left, int *right, int *top, int *bottom); -void NewtWindows_updateMinMaxSize(JNIEnv *env, Display *dpy, JavaWindow * w); +Bool NewtWindows_updateInsets(Display *dpy, JavaWindow * w, int *left, int *right, int *top, int *bottom); +Bool NewtWindows_updateMaximized(Display *dpy, JavaWindow * w); #endif /* _X11COMMON_H_ */ diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c index 0ba454a00..68aa43887 100644 --- a/src/newt/native/X11Display.c +++ b/src/newt/native/X11Display.c @@ -35,7 +35,7 @@ jclass X11NewtWindowClazz = NULL; jmethodID insetsChangedID = NULL; jmethodID visibleChangedID = NULL; -jmethodID minMaxSizeChangedID = NULL; +jmethodID sizePosMaxInsetsChangedID = NULL; static const char * const ClazzNameX11NewtWindow = "jogamp/newt/driver/x11/WindowDriver"; @@ -52,7 +52,7 @@ static jmethodID windowDestroyNotifyID = NULL; static jmethodID windowRepaintID = NULL; static jmethodID sendMouseEventID = NULL; static jmethodID sendKeyEventID = NULL; -static jmethodID requestFocusID = NULL; +static jmethodID sendMouseEventRequestFocusID = NULL; /** * Keycode @@ -254,13 +254,13 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0 positionChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "positionChanged", "(ZII)V"); focusChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "focusChanged", "(ZZ)V"); visibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "visibleChanged", "(ZZ)V"); - minMaxSizeChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "minMaxSizeChanged", "(IIII)V"); + sizePosMaxInsetsChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sizePosMaxInsetsChanged", "(ZIIIIZZIIIIZ)V"); reparentNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "reparentNotify", "(J)V"); windowDestroyNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowDestroyNotify", "(Z)Z"); windowRepaintID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowRepaint", "(ZIIII)V"); sendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEvent", "(SIIISF)V"); + sendMouseEventRequestFocusID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEventRequestFocus", "(SIIISF)V"); sendKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendKeyEvent", "(SISSCLjava/lang/String;)V"); - requestFocusID = (*env)->GetMethodID(env, X11NewtWindowClazz, "requestFocus", "(Z)V"); if (displayCompletedID == NULL || sendRRScreenChangeNotifyID == NULL || @@ -271,13 +271,13 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0 positionChangedID == NULL || focusChangedID == NULL || visibleChangedID == NULL || - minMaxSizeChangedID == NULL || + sizePosMaxInsetsChangedID == NULL || reparentNotifyID == NULL || windowDestroyNotifyID == NULL || windowRepaintID == NULL || sendMouseEventID == NULL || - sendKeyEventID == NULL || - requestFocusID == NULL) { + sendMouseEventRequestFocusID == NULL || + sendKeyEventID == NULL) { return JNI_FALSE; } @@ -522,8 +522,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage switch(evt.type) { case ButtonPress: - (*env)->CallVoidMethod(env, jw->jwindow, requestFocusID, JNI_FALSE); - (*env)->CallVoidMethod(env, jw->jwindow, sendMouseEventID, (jshort) EVENT_MOUSE_PRESSED, + (*env)->CallVoidMethod(env, jw->jwindow, sendMouseEventRequestFocusID, (jshort) EVENT_MOUSE_PRESSED, modifiers, (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jshort) evt.xbutton.button, 0.0f /*rotation*/); break; @@ -579,16 +578,16 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage evt.xconfigure.override_redirect, evt.xconfigure.window != evt.xconfigure.event); if ( evt.xconfigure.window == evt.xconfigure.event ) { // ignore child window change notification - { - // update insets - int left, right, top, bottom; - NewtWindows_updateInsets(env, dpy, jw, &left, &right, &top, &bottom); - } - NewtWindows_updateMinMaxSize(env, dpy, jw); - (*env)->CallVoidMethod(env, jw->jwindow, sizeChangedID, JNI_FALSE, - (jint) evt.xconfigure.width, (jint) evt.xconfigure.height, JNI_FALSE); - (*env)->CallVoidMethod(env, jw->jwindow, positionChangedID, JNI_FALSE, - (jint) evt.xconfigure.x, (jint) evt.xconfigure.y); + // update insets + int left=-1, right=-1, top=-1, bottom=-1; + NewtWindows_updateInsets(dpy, jw, &left, &right, &top, &bottom); + NewtWindows_updateMaximized(dpy, jw); + (*env)->CallVoidMethod(env, jw->jwindow, sizePosMaxInsetsChangedID, JNI_FALSE, + (jint) evt.xconfigure.x, (jint) evt.xconfigure.y, + (jint) evt.xconfigure.width, (jint) evt.xconfigure.height, + (jboolean)jw->maxHorz, (jboolean)jw->maxVert, + (jint)left, (jint)right, (jint)top, (jint)bottom, + JNI_FALSE); } break; case ClientMessage: @@ -633,7 +632,9 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage { // update insets int left, right, top, bottom; - NewtWindows_updateInsets(env, dpy, jw, &left, &right, &top, &bottom); + if( NewtWindows_updateInsets(dpy, jw, &left, &right, &top, &bottom) ) { + (*env)->CallVoidMethod(env, jw->jwindow, insetsChangedID, JNI_FALSE, left, right, top, bottom); + } } (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE); } diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 778b71cc5..6fa3cc195 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -178,21 +178,21 @@ static uint32_t NewtWindows_getSupportedFeatureEWMH(Display *dpy, const Atom * a return 0; } static uint32_t NewtWindows_getSupportedFeaturesEWMH(Display *dpy, Window root, Atom * allAtoms, Bool verbose) { - Atom * actions = NULL; + Atom * properties = NULL; Atom type = 0; - unsigned long action_len = 0, remain = 0; + unsigned long props_count = 0, remain = 0; int form = 0, i = 0; uint32_t res = 0; Status s; XSync(dpy, False); if ( Success == (s = XGetWindowProperty(dpy, root, allAtoms[_NET_SUPPORTED_IDX], 0, 1024, False, AnyPropertyType, - &type, &form, &action_len, &remain, (unsigned char**)&actions)) ) { - if( NULL != actions ) { - for(i=0; i<action_len; i++) { - res |= NewtWindows_getSupportedFeatureEWMH(dpy, allAtoms, actions[i], i, verbose); + &type, &form, &props_count, &remain, (unsigned char**)&properties)) ) { + if( NULL != properties ) { + for(i=0; i<props_count; i++) { + res |= NewtWindows_getSupportedFeatureEWMH(dpy, allAtoms, properties[i], i, verbose); } - XFree(actions); + XFree(properties); } if(verbose) { fprintf(stderr, "**************** X11: Feature EWMH CHECK: 0x%X\n", res); @@ -202,6 +202,31 @@ static uint32_t NewtWindows_getSupportedFeaturesEWMH(Display *dpy, Window root, } return res; } +static uint32_t NewtWindows_getNET_WM_STATE(Display *dpy, Window window, Atom * allAtoms, Bool verbose) { + Atom * properties = NULL; + Atom type = 0; + unsigned long props_count = 0, remain = 0; + int form = 0, i = 0; + uint32_t res = 0; + Status s; + + XSync(dpy, False); + if ( Success == (s = XGetWindowProperty(dpy, window, allAtoms[_NET_WM_STATE_IDX], 0, 1024, False, AnyPropertyType, + &type, &form, &props_count, &remain, (unsigned char**)&properties)) ) { + if( NULL != properties ) { + for(i=0; i<props_count; i++) { + res |= NewtWindows_getSupportedFeatureEWMH(dpy, allAtoms, properties[i], i, verbose); + } + XFree(properties); + } + if(verbose) { + fprintf(stderr, "**************** X11: WM_STATE of %p: 0x%X\n", (void*)window, res); + } + } else if(verbose) { + fprintf(stderr, "**************** X11: WM_STATE of %p: XGetWindowProperty failed: %d\n", (void*)window, s); + } + return res; +} static JavaWindow* createJavaWindowProperty(JNIEnv *env, Display *dpy, Window root, Window window, jlong javaObjectAtom, jlong windowDeleteAtom, jobject obj, Bool verbose) { @@ -222,6 +247,8 @@ static JavaWindow* createJavaWindowProperty(JNIEnv *env, Display *dpy, Window ro res->windowDeleteAtom = (Atom)windowDeleteAtom; res->supportedAtoms = NewtWindows_getSupportedFeaturesEWMH(dpy, root, allAtoms, verbose); res->lastDesktop = 0; //undef + res->maxHorz = False; + res->maxVert = False; } unsigned long jogl_java_object_data[2]; // X11 is based on 'unsigned long' int nitems_32 = putPtrIn32Long( jogl_java_object_data, (uintptr_t) res); @@ -465,12 +492,10 @@ static void NewtWindows_requestFocus (Display *dpy, JavaWindow * jw, Bool force) XSync(dpy, False); } -Status NewtWindows_updateInsets(JNIEnv *env, Display *dpy, JavaWindow * w, int *left, int *right, int *top, int *bottom) { +Bool NewtWindows_updateInsets(Display *dpy, JavaWindow * w, int *left, int *right, int *top, int *bottom) { if(0 != NewtWindows_getFrameExtends(dpy, w, left, right, top, bottom)) { - DBG_PRINT( "NewtWindows_updateInsets: insets by _NET_FRAME_EXTENTS [ l %d, r %d, t %d, b %d ]\n", - *left, *right, *top, *bottom); - (*env)->CallVoidMethod(env, w->jwindow, insetsChangedID, JNI_FALSE, *left, *right, *top, *bottom); - return 1; // OK + DBG_PRINT( "NewtWindows_updateInsets: insets by _NET_FRAME_EXTENTS [ l %d, r %d, t %d, b %d ]\n", *left, *right, *top, *bottom); + return True; // OK } Bool hasDecor = NewtWindows_hasDecorations (dpy, w); @@ -480,43 +505,30 @@ Status NewtWindows_updateInsets(JNIEnv *env, Display *dpy, JavaWindow * w, int * Window parent = NewtWindows_getParent(dpy, w->window); if(0 != NewtWindows_getWindowPositionRelative2Parent (dpy, parent, left, top)) { *right = *left; *bottom = *top; - DBG_PRINT( "NewtWindows_updateInsets: insets by parent position [ l %d, r %d, t %d, b %d ]\n", - *left, *right, *top, *bottom); - (*env)->CallVoidMethod(env, w->jwindow, insetsChangedID, JNI_FALSE, *left, *right, *top, *bottom); - return 1; // OK + DBG_PRINT( "NewtWindows_updateInsets: insets by parent position [ l %d, r %d, t %d, b %d ]\n", *left, *right, *top, *bottom); + return True; // OK } } DBG_PRINT( "NewtWindows_updateInsets: cannot determine insets - hasDecor %d\n", hasDecor); - return 0; // Error + return False; // Error } -void NewtWindows_updateMinMaxSize(JNIEnv *env, Display *dpy, JavaWindow * w) { - XSizeHints * xsh = XAllocSizeHints(); - long xsh_bits = 0; - int min_width=-1, min_height=-1; - int max_width=-1, max_height=-1; - if( NULL != xsh ) { - xsh->flags = 0; - xsh->min_width=0; - xsh->min_height=0; - xsh->max_width=0; - xsh->max_height=0; - if( 0 != XGetWMNormalHints(dpy, w->window, xsh, &xsh_bits) ) { - // OK - if( 0 != ( xsh_bits & PMinSize ) ) { - min_width = xsh->min_width; - min_height = xsh->min_height; - } - if( 0 != ( xsh_bits & PMaxSize ) ) { - max_width = xsh->max_width; - max_height = xsh->max_height; - } - DBG_PRINT( "NewtWindows_updateMinMaxSize: XGetWMNormalHints 0x%X / 0x%X for window %p on display %p\n", xsh_bits, xsh->flags, (void*)w->window, dpy); - (*env)->CallVoidMethod(env, w->jwindow, minMaxSizeChangedID, min_width, min_height, max_width, max_height); - } else { - DBG_PRINT( "NewtWindows_updateMinMaxSize: XGetWMNormalHints failed (0x%X / 0x%X) for window %p on display %p\n", xsh_bits, xsh->flags, (void*)w->window, dpy); - } - XFree(xsh); +Bool NewtWindows_updateMaximized(Display *dpy, JavaWindow * w) { + uint32_t state = NewtWindows_getNET_WM_STATE(dpy, w->window, w->allAtoms, +#ifdef VERBOSE_ON + True +#else + False +#endif + ); + Bool maxHorz = 0 != ( _MASK_NET_WM_STATE_MAXIMIZED_HORZ & state ) ; + Bool maxVert = 0 != ( _MASK_NET_WM_STATE_MAXIMIZED_VERT & state ) ; + if( w->maxHorz != maxHorz || w->maxVert != maxVert ) { + w->maxHorz = maxHorz; + w->maxVert = maxVert; + return True; + } else { + return False; } } @@ -671,9 +683,15 @@ static void NewtWindows_setStackingEWMHFlags (Display *dpy, Window root, JavaWin XChangeProperty( dpy, w->window, w->allAtoms[_NET_WM_BYPASS_COMPOSITOR_IDX], XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&value, 1); } } else if( changeMaxVert || changeMaxHorz ) { + if( changeMaxHorz ) { + w->maxHorz = enable; + } + if( changeMaxVert ) { + w->maxVert = enable; + } NewtWindows_sendNET_WM_STATE(dpy, root, w, - changeMaxVert ? _NET_WM_STATE_MAXIMIZED_VERT_IDX : 0, changeMaxHorz ? _NET_WM_STATE_MAXIMIZED_HORZ_IDX : 0, + changeMaxVert ? _NET_WM_STATE_MAXIMIZED_VERT_IDX : 0, enable); } XSync(dpy, False); @@ -916,7 +934,9 @@ JNIEXPORT jlongArray JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWind } // send insets before visibility, allowing java code a proper sync point! - NewtWindows_updateInsets(env, dpy, javaWindow, &left, &right, &top, &bottom); + if( NewtWindows_updateInsets(dpy, javaWindow, &left, &right, &top, &bottom) ) { + (*env)->CallVoidMethod(env, javaWindow->jwindow, insetsChangedID, JNI_FALSE, left, right, top, bottom); + } (*env)->CallVoidMethod(env, javaWindow->jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE); if( TST_FLAG_IS_AUTOPOSITION(flags) ) { diff --git a/src/test/com/jogamp/opengl/test/junit/util/NEWTDemoListener.java b/src/test/com/jogamp/opengl/test/junit/util/NEWTDemoListener.java index b70beae69..68a983a27 100644 --- a/src/test/com/jogamp/opengl/test/junit/util/NEWTDemoListener.java +++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTDemoListener.java @@ -235,9 +235,9 @@ public class NEWTDemoListener extends MouseAdapter implements KeyListener { horz = false; vert = false; } else if( e.isShiftDown() ) { - final boolean anyMax = glWindow.isMaximizedHorz() || glWindow.isMaximizedVert(); - horz = !anyMax; - vert = !anyMax; + final boolean bothMax = glWindow.isMaximizedHorz() && glWindow.isMaximizedVert(); + horz = !bothMax; + vert = !bothMax; } else if( !e.isAltDown() ) { horz = glWindow.isMaximizedHorz(); vert = !glWindow.isMaximizedVert(); |