From 58756bbd1d1fd63bb84dbfe2d6419d63de2da7ba Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sun, 5 Jan 2014 18:21:26 +0100 Subject: Bug 935: NEWT PointerIcon/Visibility: Perform OffscreenLayerSurface delegation _always_ in common WindowImpl ; Workaround for Windows+Applet issue. Perform OffscreenLayerSurface delegation _always_ in common WindowImpl Instead of performing OffscreenLayerSurface task on OSX's WindowDriver implementation, use generic implementation in WindowImpl for all platform exposing same behavior. ReparentAction takes care of reset/setup of PointerIcon/Visibility states. +++ This is also a workaround for Windows+Applet issue, where the PointerIcon gets periodically overridden by the AWT Component's icon. --- src/newt/classes/jogamp/newt/WindowImpl.java | 162 ++++++++++++++++----- .../jogamp/newt/driver/macosx/WindowDriver.java | 34 +---- 2 files changed, 127 insertions(+), 69 deletions(-) (limited to 'src/newt/classes') diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 8d9fb8d7e..50f30f04d 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -34,56 +34,59 @@ package jogamp.newt; -import java.util.ArrayList; -import java.util.List; import java.lang.ref.WeakReference; import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.CapabilitiesChooser; +import javax.media.nativewindow.CapabilitiesImmutable; +import javax.media.nativewindow.NativeSurface; +import javax.media.nativewindow.NativeWindow; +import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.NativeWindowFactory; +import javax.media.nativewindow.OffscreenLayerSurface; +import javax.media.nativewindow.SurfaceUpdatedListener; +import javax.media.nativewindow.WindowClosingProtocol; +import javax.media.nativewindow.util.DimensionImmutable; +import javax.media.nativewindow.util.Insets; +import javax.media.nativewindow.util.InsetsImmutable; +import javax.media.nativewindow.util.Point; +import javax.media.nativewindow.util.PointImmutable; +import javax.media.nativewindow.util.Rectangle; +import javax.media.nativewindow.util.RectangleImmutable; + +import jogamp.nativewindow.SurfaceUpdatedHelper; import com.jogamp.common.util.ArrayHashSet; +import com.jogamp.common.util.IOUtil; import com.jogamp.common.util.IntBitfield; import com.jogamp.common.util.ReflectionUtil; +import com.jogamp.common.util.locks.LockFactory; +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.NewtFactory; -import com.jogamp.newt.Display; import com.jogamp.newt.Screen; import com.jogamp.newt.Window; -import com.jogamp.common.util.locks.LockFactory; -import com.jogamp.common.util.locks.RecursiveLock; import com.jogamp.newt.event.DoubleTapScrollGesture; import com.jogamp.newt.event.GestureHandler; import com.jogamp.newt.event.InputEvent; import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.event.KeyListener; import com.jogamp.newt.event.MonitorEvent; +import com.jogamp.newt.event.MonitorModeListener; import com.jogamp.newt.event.MouseEvent; +import com.jogamp.newt.event.MouseEvent.PointerType; import com.jogamp.newt.event.MouseListener; import com.jogamp.newt.event.NEWTEvent; import com.jogamp.newt.event.NEWTEventConsumer; -import com.jogamp.newt.event.MonitorModeListener; import com.jogamp.newt.event.WindowEvent; import com.jogamp.newt.event.WindowListener; import com.jogamp.newt.event.WindowUpdateEvent; -import com.jogamp.newt.event.MouseEvent.PointerType; - -import javax.media.nativewindow.AbstractGraphicsConfiguration; -import javax.media.nativewindow.AbstractGraphicsDevice; -import javax.media.nativewindow.CapabilitiesChooser; -import javax.media.nativewindow.CapabilitiesImmutable; -import javax.media.nativewindow.NativeSurface; -import javax.media.nativewindow.NativeWindow; -import javax.media.nativewindow.NativeWindowException; -import javax.media.nativewindow.NativeWindowFactory; -import javax.media.nativewindow.SurfaceUpdatedListener; -import javax.media.nativewindow.WindowClosingProtocol; -import javax.media.nativewindow.util.DimensionImmutable; -import javax.media.nativewindow.util.Insets; -import javax.media.nativewindow.util.InsetsImmutable; -import javax.media.nativewindow.util.Point; -import javax.media.nativewindow.util.Rectangle; -import javax.media.nativewindow.util.RectangleImmutable; - -import jogamp.nativewindow.SurfaceUpdatedHelper; public abstract class WindowImpl implements Window, NEWTEventConsumer { @@ -171,7 +174,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer private String title = "Newt Window"; private boolean undecorated = false; private boolean alwaysOnTop = false; - private PointerIcon pointerIcon = null; + private PointerIconImpl pointerIcon = null; private boolean pointerVisible = true; private boolean pointerConfined = false; private LifecycleHook lifecycleHook = null; @@ -438,10 +441,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer createNativeImpl(); screen.addMonitorModeListener(monitorModeListenerImpl); setTitleImpl(title); - if( null != pointerIcon ) { - setPointerIconImpl((PointerIconImpl)pointerIcon); - } - setPointerVisibleImpl(pointerVisible); + setPointerIconIntern(pointerIcon); + setPointerVisibleIntern(pointerVisible); confinePointerImpl(pointerConfined); setKeyboardVisible(keyboardVisible); final long remainingV = waitForVisible(true, false); @@ -1379,6 +1380,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer return; } + if( null == newParentWindow ) { + // CLIENT -> TOP: Reset Parent's Pointer State + setOffscreenPointerIcon(null); + setOffscreenPointerVisible(true, null); + } + // rearrange window tree if(null!=parentWindow && parentWindow instanceof Window) { ((Window)parentWindow).removeChild(WindowImpl.this); @@ -1461,6 +1468,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } destroy( becomesVisible ); operation = ReparentOperation.ACTION_NATIVE_CREATION ; + } else { + if( null != parentWindow ) { + // TOP -> CLIENT: Setup Parent's Pointer State + setOffscreenPointerIcon(pointerIcon); + setOffscreenPointerVisible(pointerVisible, pointerIcon); + } } } else { // Case @@ -1670,32 +1683,109 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer return pointerVisible; } @Override - public final void setPointerVisible(boolean pointerVisible) { + public final void setPointerVisible(final boolean pointerVisible) { if(this.pointerVisible != pointerVisible) { boolean setVal = 0 == getWindowHandle(); if(!setVal) { - setVal = setPointerVisibleImpl(pointerVisible); + setVal = setPointerVisibleIntern(pointerVisible); } if(setVal) { this.pointerVisible = pointerVisible; } } } + private boolean setPointerVisibleIntern(final boolean pointerVisible) { + boolean res = setOffscreenPointerVisible(pointerVisible, pointerIcon); + return setPointerVisibleImpl(pointerVisible) || res; // accept onscreen or offscreen positive result! + } + /** + * Helper method to delegate {@link #setPointerVisibleImpl(boolean)} to + * {@link OffscreenLayerSurface#hideCursor()} or {@link OffscreenLayerSurface#setCursor(IOUtil.ClassResources, PointImmutable)}. + *

+ * Note: JAWTWindow is an OffscreenLayerSurface. + *

+ *

+ * Performing OffscreenLayerSurface's setCursor(..)/hideCursor(), if available, + * gives same behavior on all platforms. + *

+ *

+ * If visible, implementation invokes {@link #setOffscreenPointerIcon(OffscreenLayerSurface, PointerIconImpl)} using the + * given defaultPointerIcon, otherwise {@link OffscreenLayerSurface#hideCursor()} is invoked. + *

+ * @param pointerVisible true for visible, otherwise invisible. + * @param defaultPointerIcon default PointerIcon for visibility + * @param ols the {@link OffscreenLayerSurface} instance, if null method does nothing. + */ + private boolean setOffscreenPointerVisible(final boolean pointerVisible, final PointerIconImpl defaultPointerIcon) { + if( pointerVisible ) { + return setOffscreenPointerIcon(defaultPointerIcon); + } else { + final NativeWindow parent = getParent(); + if( parent instanceof OffscreenLayerSurface ) { + final OffscreenLayerSurface ols = (OffscreenLayerSurface) parent; + try { + return ols.hideCursor(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + return false; + } @Override public final PointerIcon getPointerIcon() { return pointerIcon; } @Override public final void setPointerIcon(final PointerIcon pi) { - if( this.pointerIcon != pi ) { + final PointerIconImpl piImpl = (PointerIconImpl)pi; + if( this.pointerIcon != piImpl ) { if( isNativeValid() ) { runOnEDTIfAvail(true, new Runnable() { public void run() { - setPointerIconImpl((PointerIconImpl)pi); + setPointerIconIntern(piImpl); } } ); } - this.pointerIcon = pi; + this.pointerIcon = piImpl; + } + } + private void setPointerIconIntern(final PointerIconImpl pi) { + setOffscreenPointerIcon(pi); + setPointerIconImpl(pi); + } + /** + * Helper method to delegate {@link #setPointerIconIntern(PointerIconImpl)} to + * {@link OffscreenLayerSurface#setCursor(IOUtil.ClassResources, PointImmutable)}. + *

+ * Note: JAWTWindow is an OffscreenLayerSurface. + *

+ *

+ * Performing OffscreenLayerSurface's setCursor(..), if available, + * gives same behavior on all platforms. + *

+ *

+ * Workaround for AWT/Windows bug within browser, + * where the PointerIcon gets periodically overridden + * by the AWT Component's icon. + *

+ * @param ols the {@link OffscreenLayerSurface} instance, if null method does nothing. + * @param pi the {@link PointerIconImpl} instance, if null PointerIcon gets reset. + */ + private boolean setOffscreenPointerIcon(final PointerIconImpl pi) { + final NativeWindow parent = getParent(); + if( parent instanceof OffscreenLayerSurface ) { + final OffscreenLayerSurface ols = (OffscreenLayerSurface) parent; + try { + if( null != pi ) { + return ols.setCursor(pi.getResource(), pi.getHotspot()); + } else { + return ols.setCursor(null, null); // default + } + } catch (Exception e) { + e.printStackTrace(); + } } + return false; } @Override diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java index edeb69f84..e2a57debc 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java @@ -39,8 +39,6 @@ import javax.media.nativewindow.GraphicsConfigurationFactory; import javax.media.nativewindow.NativeWindow; import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.MutableSurface; -import javax.media.nativewindow.NativeWindowFactory; -import javax.media.nativewindow.OffscreenLayerSurface; import javax.media.nativewindow.VisualIDHolder; import javax.media.nativewindow.util.Insets; import javax.media.nativewindow.util.Point; @@ -403,22 +401,6 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl public void run() { setPointerIcon0(getWindowHandle(), piHandle); } } ); - } else { - final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(this, true); - if( null != ols ) { - try { - setOLSPointer(ols, pi); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } - private static void setOLSPointer(final OffscreenLayerSurface ols, final PointerIconImpl pi) throws Exception { - if( null != pi ) { - ols.setCursor(pi.getResource(), pi.getHotspot()); - } else { - ols.setCursor(null, null); // default } } @@ -430,21 +412,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl public void run() { setPointerVisible0(getWindowHandle(), hasFocus(), pointerVisible); } } ); - return true; // setPointerVisible0 always returns true .. - } else { - final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(this, true); - if( null != ols ) { - try { - if( pointerVisible ) { - setOLSPointer(ols, (PointerIconImpl)getPointerIcon()); - } else { - ols.hideCursor(); - } - return true; - } catch (Exception e) { - e.printStackTrace(); - } - } + return true; } return false; } -- cgit v1.2.3