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 /src/newt/classes | |
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.
Diffstat (limited to 'src/newt/classes')
3 files changed, 164 insertions, 74 deletions
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); |