public void updateSecurityWarningVisibility() { if (warningWindow == null) { return; } if (!isVisible()) { return; // The warning window should already be hidden. } boolean show = false; if (!platformWindow.isFullScreenMode()) { if (isVisible()) { if (LWKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow() == getTarget()) { show = true; } if (platformWindow.isUnderMouse() || warningWindow.isUnderMouse()) { show = true; } } } warningWindow.setVisible(show, true); }
/* * Requests platform to set native focus on a frame/dialog. * In case of a simple window, triggers appropriate java focus change. */ public boolean requestWindowFocus(CausedFocusEvent.Cause cause) { if (focusLog.isLoggable(PlatformLogger.FINE)) { focusLog.fine("requesting native focus to " + this); } if (!focusAllowedFor()) { focusLog.fine("focus is not allowed"); return false; } if (platformWindow.rejectFocusRequest(cause)) { return false; } Window currentActive = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow(); Window opposite = LWKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow(); // Make the owner active window. if (isSimpleWindow()) { LWWindowPeer owner = getOwnerFrameDialog(this); // If owner is not natively active, request native // activation on it w/o sending events up to java. if (owner != null && !owner.platformWindow.isActive()) { if (focusLog.isLoggable(PlatformLogger.FINE)) { focusLog.fine("requesting native focus to the owner " + owner); } LWWindowPeer currentActivePeer = (currentActive != null ? (LWWindowPeer) currentActive.getPeer() : null); // Ensure the opposite is natively active and suppress sending events. if (currentActivePeer != null && currentActivePeer.platformWindow.isActive()) { if (focusLog.isLoggable(PlatformLogger.FINE)) { focusLog.fine("the opposite is " + currentActivePeer); } currentActivePeer.skipNextFocusChange = true; } owner.skipNextFocusChange = true; owner.platformWindow.requestWindowFocus(); } // DKFM will synthesize all the focus/activation events correctly. changeFocusedWindow(true, opposite); return true; // In case the toplevel is active but not focused, change focus directly, // as requesting native focus on it will not have effect. } else if (getTarget() == currentActive && !getTarget().hasFocus()) { changeFocusedWindow(true, opposite); return true; } return platformWindow.requestWindowFocus(); }
private void replaceSurfaceData( int newBackBufferCount, BufferCapabilities newBackBufferCaps, boolean blit) { synchronized (surfaceDataLock) { final SurfaceData oldData = getSurfaceData(); surfaceData = platformWindow.replaceSurfaceData(); // TODO: volatile image // VolatileImage oldBB = backBuffer; BufferedImage oldBB = backBuffer; backBufferCount = newBackBufferCount; backBufferCaps = newBackBufferCaps; final Rectangle size = getSize(); if (getSurfaceData() != null && oldData != getSurfaceData()) { clearBackground(size.width, size.height); } if (blit) { blitSurfaceData(oldData, getSurfaceData()); } if (oldData != null && oldData != getSurfaceData()) { // TODO: drop oldData for D3D/WGL pipelines // This can only happen when this peer is being created oldData.flush(); } // TODO: volatile image // backBuffer = (VolatileImage)delegate.createBackBuffer(); backBuffer = (BufferedImage) platformWindow.createBackBuffer(); if (backBuffer != null) { Graphics g = backBuffer.getGraphics(); try { Rectangle r = getBounds(); if (g instanceof Graphics2D) { ((Graphics2D) g).setComposite(AlphaComposite.Src); } g.setColor(nonOpaqueBackground); g.fillRect(0, 0, r.width, r.height); if (g instanceof SunGraphics2D) { ((SunGraphics2D) g).constrain(0, 0, r.width, r.height, getRegion()); } if (!isTextured()) { g.setColor(getBackground()); g.fillRect(0, 0, r.width, r.height); } if (oldBB != null) { // Draw the old back buffer to the new one g.drawImage(oldBB, 0, 0, null); oldBB.flush(); } } finally { g.dispose(); } } } flushOnscreenGraphics(); }
@Override public void updateMinimumSize() { final Dimension min; if (getTarget().isMinimumSizeSet()) { min = getTarget().getMinimumSize(); min.width = Math.max(min.width, MINIMUM_WIDTH); min.height = Math.max(min.height, MINIMUM_HEIGHT); } else { min = new Dimension(MINIMUM_WIDTH, MINIMUM_HEIGHT); } final int maxW, maxH; if (graphicsConfig instanceof TextureSizeConstraining) { maxW = ((TextureSizeConstraining) graphicsConfig).getMaxTextureWidth(); maxH = ((TextureSizeConstraining) graphicsConfig).getMaxTextureHeight(); } else { maxW = maxH = Integer.MAX_VALUE; } final Dimension max; if (getTarget().isMaximumSizeSet()) { max = getTarget().getMaximumSize(); max.width = Math.min(max.width, maxW); max.height = Math.min(max.height, maxH); } else { max = new Dimension(maxW, maxH); } platformWindow.setSizeConstraints(min.width, min.height, max.width, max.height); }
@Override public void setBounds(int x, int y, int w, int h, int op) { if ((op & NO_EMBEDDED_CHECK) == 0 && getPeerType() == PeerType.VIEW_EMBEDDED_FRAME) { return; } if ((op & SET_CLIENT_SIZE) != 0) { // SET_CLIENT_SIZE is only applicable to window peers, so handle it here // instead of pulling 'insets' field up to LWComponentPeer // no need to add insets since Window's notion of width and height includes insets. op &= ~SET_CLIENT_SIZE; op |= SET_SIZE; } // Don't post ComponentMoved/Resized and Paint events // until we've got a notification from the delegate Rectangle cb = constrainBounds(x, y, w, h); Rectangle newBounds = new Rectangle(getBounds()); if ((op & (SET_LOCATION | SET_BOUNDS)) != 0) { newBounds.x = cb.x; newBounds.y = cb.y; } if ((op & (SET_SIZE | SET_BOUNDS)) != 0) { newBounds.width = cb.width; newBounds.height = cb.height; } // Native system could constraint bounds, so the peer wold be updated in the callback platformWindow.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height); }
/** * Called by the {@code PlatformWindow} when this window is moved/resized by user or window insets * are changed. There's no notifyReshape() in LWComponentPeer as the only components which could * be resized by user are top-level windows. */ @Override public void notifyReshape(int x, int y, int w, int h) { Rectangle oldBounds = getBounds(); final boolean invalid = updateInsets(platformWindow.getInsets()); final boolean moved = (x != oldBounds.x) || (y != oldBounds.y); final boolean resized = (w != oldBounds.width) || (h != oldBounds.height); // Check if anything changed if (!moved && !resized && !invalid) { return; } // First, update peer's bounds setBounds(x, y, w, h, SET_BOUNDS, false, false); // Second, update the graphics config and surface data final boolean isNewDevice = updateGraphicsDevice(); if (resized || isNewDevice) { replaceSurfaceData(); updateMinimumSize(); } // Third, COMPONENT_MOVED/COMPONENT_RESIZED/PAINT events if (moved || invalid) { handleMove(x, y, true); } if (resized || invalid || isNewDevice) { handleResize(w, h, true); repaintPeer(); } repositionSecurityWarning(); }
@Override void initializeImpl() { super.initializeImpl(); if (getTarget() instanceof Frame) { setTitle(((Frame) getTarget()).getTitle()); setState(((Frame) getTarget()).getExtendedState()); } else if (getTarget() instanceof Dialog) { setTitle(((Dialog) getTarget()).getTitle()); } updateAlwaysOnTopState(); updateMinimumSize(); updateFocusableWindowState(); final Shape shape = getTarget().getShape(); if (shape != null) { applyShape(Region.getInstance(shape, null)); } final float opacity = getTarget().getOpacity(); if (opacity < 1.0f) { setOpacity(opacity); } setOpaque(getTarget().isOpaque()); updateInsets(platformWindow.getInsets()); if (getSurfaceData() == null) { replaceSurfaceData(false); } activateDisplayListener(); }
@Override protected void setVisibleImpl(final boolean visible) { if (!visible && warningWindow != null) { warningWindow.setVisible(false, false); } updateFocusableWindowState(); super.setVisibleImpl(visible); // TODO: update graphicsConfig, see 4868278 platformWindow.setVisible(visible); if (isSimpleWindow()) { KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance(); if (visible) { if (!getTarget().isAutoRequestFocus()) { return; } else { requestWindowFocus(CausedFocusEvent.Cause.ACTIVATION); } // Focus the owner in case this window is focused. } else if (kfmPeer.getCurrentFocusedWindow() == getTarget()) { // Transfer focus to the owner. LWWindowPeer owner = getOwnerFrameDialog(LWWindowPeer.this); if (owner != null) { owner.requestWindowFocus(CausedFocusEvent.Cause.ACTIVATION); } } } }
public LWWindowPeer( Window target, PlatformComponent platformComponent, PlatformWindow platformWindow, PeerType peerType) { super(target, platformComponent); this.platformWindow = platformWindow; this.peerType = peerType; Window owner = target.getOwner(); LWWindowPeer ownerPeer = owner == null ? null : (LWWindowPeer) AWTAccessor.getComponentAccessor().getPeer(owner); PlatformWindow ownerDelegate = (ownerPeer != null) ? ownerPeer.getPlatformWindow() : null; // The delegate.initialize() needs a non-null GC on X11. GraphicsConfiguration gc = getTarget().getGraphicsConfiguration(); synchronized (getStateLock()) { // graphicsConfig should be updated according to the real window // bounds when the window is shown, see 4868278 this.graphicsConfig = gc; } if (!target.isFontSet()) { target.setFont(DEFAULT_FONT); } if (!target.isBackgroundSet()) { target.setBackground(SystemColor.window); } else { // first we check if user provided alpha for background. This is // similar to what Apple's Java do. // Since JDK7 we should rely on setOpacity() only. // this.opacity = c.getAlpha(); } if (!target.isForegroundSet()) { target.setForeground(SystemColor.windowText); // we should not call setForeground because it will call a repaint // which the peer may not be ready to do yet. } platformWindow.initialize(target, this, ownerDelegate); // Init warning window(for applets) SecurityWarningWindow warn = null; if (target.getWarningString() != null) { // accessSystemTray permission allows to display TrayIcon, TrayIcon tooltip // and TrayIcon balloon windows without a warning window. if (!AWTAccessor.getWindowAccessor().isTrayIconWindow(target)) { LWToolkit toolkit = (LWToolkit) Toolkit.getDefaultToolkit(); warn = toolkit.createSecurityWarning(target, this); } } warningWindow = warn; }
@Override public void setModalBlocked(Dialog blocker, boolean blocked) { synchronized (getPeerTreeLock()) { if (blocked && blocker.getPeer() instanceof LWWindowPeer) { this.blocker = (LWWindowPeer) blocker.getPeer(); } else { this.blocker = null; } } platformWindow.setModalBlocked(blocked); }
@Override public void setModalBlocked(Dialog blocker, boolean blocked) { synchronized (getPeerTreeLock()) { ComponentPeer peer = AWTAccessor.getComponentAccessor().getPeer(blocker); if (blocked && (peer instanceof LWWindowPeer)) { this.blocker = (LWWindowPeer) peer; } else { this.blocker = null; } } platformWindow.setModalBlocked(blocked); }
protected final Graphics getOnscreenGraphics(Color fg, Color bg, Font f) { if (getSurfaceData() == null) { return null; } if (fg == null) { fg = SystemColor.windowText; } if (bg == null) { bg = SystemColor.window; } if (f == null) { f = DEFAULT_FONT; } return platformWindow.transformGraphics(new SunGraphics2D(getSurfaceData(), fg, bg, f)); }
@Override protected void disposeImpl() { deactivateDisplayListener(); SurfaceData oldData = getSurfaceData(); synchronized (surfaceDataLock) { surfaceData = null; } if (oldData != null) { oldData.invalidate(); } if (isGrabbing()) { ungrab(); } if (warningWindow != null) { warningWindow.dispose(); } platformWindow.dispose(); super.disposeImpl(); }
@Override public void setBounds(int x, int y, int w, int h, int op) { if ((op & NO_EMBEDDED_CHECK) == 0 && getPeerType() == PeerType.VIEW_EMBEDDED_FRAME) { return; } if ((op & SET_CLIENT_SIZE) != 0) { // SET_CLIENT_SIZE is only applicable to window peers, so handle it here // instead of pulling 'insets' field up to LWComponentPeer // no need to add insets since Window's notion of width and height includes insets. op &= ~SET_CLIENT_SIZE; op |= SET_SIZE; } if (w < MINIMUM_WIDTH) { w = MINIMUM_WIDTH; } if (h < MINIMUM_HEIGHT) { h = MINIMUM_HEIGHT; } if (graphicsConfig instanceof TextureSizeConstraining) { final int maxW = ((TextureSizeConstraining) graphicsConfig).getMaxTextureWidth(); final int maxH = ((TextureSizeConstraining) graphicsConfig).getMaxTextureHeight(); if (w > maxW) { w = maxW; } if (h > maxH) { h = maxH; } } // Don't post ComponentMoved/Resized and Paint events // until we've got a notification from the delegate setBounds(x, y, w, h, op, false, false); // Get updated bounds, so we don't have to handle 'op' here manually Rectangle r = getBounds(); platformWindow.setBounds(r.x, r.y, r.width, r.height); }
private void replaceSurfaceData(final boolean blit) { synchronized (surfaceDataLock) { final SurfaceData oldData = getSurfaceData(); surfaceData = platformWindow.replaceSurfaceData(); final Rectangle size = getSize(); if (getSurfaceData() != null && oldData != getSurfaceData()) { clearBackground(size.width, size.height); } if (blit) { blitSurfaceData(oldData, getSurfaceData()); } if (oldData != null && oldData != getSurfaceData()) { // TODO: drop oldData for D3D/WGL pipelines // This can only happen when this peer is being created oldData.flush(); } } flushOnscreenGraphics(); }
@Override public void updateMinimumSize() { final Dimension min; if (getTarget().isMinimumSizeSet()) { min = getTarget().getMinimumSize(); min.width = Math.max(min.width, MINIMUM_WIDTH); min.height = Math.max(min.height, MINIMUM_HEIGHT); } else { min = new Dimension(MINIMUM_WIDTH, MINIMUM_HEIGHT); } final Dimension max; if (getTarget().isMaximumSizeSet()) { max = getTarget().getMaximumSize(); max.width = Math.min(max.width, getLWGC().getMaxTextureWidth()); max.height = Math.min(max.height, getLWGC().getMaxTextureHeight()); } else { max = new Dimension(getLWGC().getMaxTextureWidth(), getLWGC().getMaxTextureHeight()); } platformWindow.setSizeConstraints(min.width, min.height, max.width, max.height); }
/** Returns true if the GraphicsDevice has been changed, false otherwise. */ public boolean updateGraphicsDevice() { GraphicsDevice newGraphicsDevice = platformWindow.getGraphicsDevice(); synchronized (getStateLock()) { if (graphicsDevice == newGraphicsDevice) { return false; } graphicsDevice = newGraphicsDevice; } final GraphicsConfiguration newGC = newGraphicsDevice.getDefaultConfiguration(); if (!setGraphicsConfig(newGC)) return false; SunToolkit.executeOnEventHandlerThread( getTarget(), new Runnable() { public void run() { AWTAccessor.getComponentAccessor().setGraphicsConfiguration(getTarget(), newGC); } }); return true; }
/** * Called by the {@code PlatformWindow} when this window is moved/resized by user or window insets * are changed. There's no notifyReshape() in LWComponentPeer as the only components which could * be resized by user are top-level windows. */ @Override public final void notifyReshape(int x, int y, int w, int h) { final boolean moved; final boolean resized; final boolean invalid = updateInsets(platformWindow.getInsets()); synchronized (getStateLock()) { moved = (x != sysX) || (y != sysY); resized = (w != sysW) || (h != sysH); sysX = x; sysY = y; sysW = w; sysH = h; } // Check if anything changed if (!moved && !resized && !invalid) { return; } // First, update peer's bounds setBounds(x, y, w, h, SET_BOUNDS, false, false); // Second, update the graphics config and surface data final boolean isNewDevice = updateGraphicsDevice(); if (resized || isNewDevice) { replaceSurfaceData(); } // Third, COMPONENT_MOVED/COMPONENT_RESIZED/PAINT events if (moved || invalid) { handleMove(x, y, true); } if (resized || invalid || isNewDevice) { handleResize(w, h, true); repaintPeer(); } repositionSecurityWarning(); }
@Override public void setMenuBar(MenuBar mb) { platformWindow.setMenuBar(mb); }
@Override public void exitFullScreenMode() { platformWindow.exitFullScreenMode(); updateSecurityWarningVisibility(); }
@Override // FramePeer and DialogPeer public void setTitle(String title) { platformWindow.setTitle(title == null ? "" : title); }
@Override // FramePeer and DialogPeer public void setResizable(boolean resizable) { platformWindow.setResizable(resizable); }
@Override public void updateFocusableWindowState() { targetFocusable = getTarget().isFocusableWindow(); platformWindow.updateFocusableWindowState(); }
@Override public void updateAlwaysOnTopState() { platformWindow.setAlwaysOnTop(getTarget().isAlwaysOnTop()); }
@Override public void toBack() { platformWindow.toBack(); }
@Override public void toFront() { platformWindow.toFront(); }
@Override public void setState(int state) { platformWindow.setWindowState(state); }
@Override public Point getLocationOnScreen() { return platformWindow.getLocationOnScreen(); }
/* * Called by the delegate to dispatch the event to Java. Event * coordinates are relative to non-client window are, i.e. the top-left * point of the client area is (insets.top, insets.left). */ @Override public void notifyMouseEvent( PlatformWindow eventPlatformWindow, int id, long when, int button, int x, int y, int screenX, int screenY, int modifiers, int clickCount, boolean popupTrigger, byte[] bdata) { // TODO: fill "bdata" member of AWTEvent Rectangle r = getBounds(); // findPeerAt() expects parent coordinates LWComponentPeer<?, ?> targetPeer = findPeerAt(r.x + x, r.y + y); if (id == MouseEvent.MOUSE_EXITED) { isMouseOver = false; if (lastMouseEventPeer != null) { if (lastMouseEventPeer.isEnabled()) { Point lp = lastMouseEventPeer.windowToLocal(x, y, this); Component target = lastMouseEventPeer.getTarget(); postMouseExitedEvent( target, when, modifiers, lp, screenX, screenY, clickCount, popupTrigger, button); } // Sometimes we may get MOUSE_EXITED after lastCommonMouseEventPeer is switched // to a peer from another window. So we must first check if this peer is // the same as lastWindowPeer if (lastCommonMouseEventPeer != null && lastCommonMouseEventPeer.getWindowPeerOrSelf() == this) { lastCommonMouseEventPeer = null; } lastMouseEventPeer = null; } } else if (id == MouseEvent.MOUSE_ENTERED) { isMouseOver = true; if (targetPeer != null) { if (targetPeer.isEnabled()) { Point lp = targetPeer.windowToLocal(x, y, this); Component target = targetPeer.getTarget(); postMouseEnteredEvent( target, when, modifiers, lp, screenX, screenY, clickCount, popupTrigger, button); } lastCommonMouseEventPeer = targetPeer; lastMouseEventPeer = targetPeer; } } else { LWWindowPeer topmostWindowPeer = eventPlatformWindow != null ? eventPlatformWindow.getPeer() : null; // topmostWindowPeer == null condition is added for the backward // compatibility with applets. It can be removed when the // getTopmostPlatformWindowUnderMouse() method will be properly // implemented in CPlatformEmbeddedFrame class if (topmostWindowPeer == this || topmostWindowPeer == null) { generateMouseEnterExitEventsForComponents( when, button, x, y, screenX, screenY, modifiers, clickCount, popupTrigger, targetPeer); } else { LWComponentPeer<?, ?> topmostTargetPeer = topmostWindowPeer.findPeerAt(r.x + x, r.y + y); topmostWindowPeer.generateMouseEnterExitEventsForComponents( when, button, x, y, screenX, screenY, modifiers, clickCount, popupTrigger, topmostTargetPeer); } // TODO: fill "bdata" member of AWTEvent int eventButtonMask = (button > 0) ? MouseEvent.getMaskForButton(button) : 0; int otherButtonsPressed = modifiers & ~eventButtonMask; // For pressed/dragged/released events OS X treats other // mouse buttons as if they were BUTTON2, so we do the same int targetIdx = (button > 3) ? MouseEvent.BUTTON2 - 1 : button - 1; // MOUSE_ENTERED/EXITED are generated for the components strictly under // mouse even when dragging. That's why we first update lastMouseEventPeer // based on initial targetPeer value and only then recalculate targetPeer // for MOUSE_DRAGGED/RELEASED events if (id == MouseEvent.MOUSE_PRESSED) { // Ungrab only if this window is not an owned window of the grabbing one. if (!isGrabbing() && grabbingWindow != null && !grabbingWindow.isOneOfOwnersOf(this)) { grabbingWindow.ungrab(); } if (otherButtonsPressed == 0) { mouseClickButtons = eventButtonMask; } else { mouseClickButtons |= eventButtonMask; } // The window should be focused on mouse click. If it gets activated by the native platform, // this request will be no op. It will take effect when: // 1. A simple not focused window is clicked. // 2. An active but not focused owner frame/dialog is clicked. // The mouse event then will trigger a focus request "in window" to the component, so the // window // should gain focus before. requestWindowFocus(CausedFocusEvent.Cause.MOUSE_EVENT); mouseDownTarget[targetIdx] = targetPeer; } else if (id == MouseEvent.MOUSE_DRAGGED) { // Cocoa dragged event has the information about which mouse // button is being dragged. Use it to determine the peer that // should receive the dragged event. targetPeer = mouseDownTarget[targetIdx]; mouseClickButtons &= ~modifiers; } else if (id == MouseEvent.MOUSE_RELEASED) { // TODO: currently, mouse released event goes to the same component // that received corresponding mouse pressed event. For most cases, // it's OK, however, we need to make sure that our behavior is consistent // with 1.6 for cases where component in question have been // hidden/removed in between of mouse pressed/released events. targetPeer = mouseDownTarget[targetIdx]; if ((modifiers & eventButtonMask) == 0) { mouseDownTarget[targetIdx] = null; } // mouseClickButtons is updated below, after MOUSE_CLICK is sent } if (targetPeer == null) { // TODO This can happen if this window is invisible. this is correct behavior in this case? targetPeer = this; } Point lp = targetPeer.windowToLocal(x, y, this); if (targetPeer.isEnabled()) { MouseEvent event = new MouseEvent( targetPeer.getTarget(), id, when, modifiers, lp.x, lp.y, screenX, screenY, clickCount, popupTrigger, button); postEvent(event); } if (id == MouseEvent.MOUSE_RELEASED) { if ((mouseClickButtons & eventButtonMask) != 0 && targetPeer.isEnabled()) { postEvent( new MouseEvent( targetPeer.getTarget(), MouseEvent.MOUSE_CLICKED, when, modifiers, lp.x, lp.y, screenX, screenY, clickCount, popupTrigger, button)); } mouseClickButtons &= ~eventButtonMask; } } notifyUpdateCursor(); }
@Override public FontMetrics getFontMetrics(Font f) { // TODO: check for "use platform metrics" settings return platformWindow.getFontMetrics(f); }