LWWindowPeer.java revision 4802
4767N/A * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. 4632N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4632N/A * This code is free software; you can redistribute it and/or modify it 4632N/A * under the terms of the GNU General Public License version 2 only, as 4632N/A * published by the Free Software Foundation. Oracle designates this 4632N/A * particular file as subject to the "Classpath" exception as provided 4632N/A * by Oracle in the LICENSE file that accompanied this code. 4632N/A * This code is distributed in the hope that it will be useful, but WITHOUT 4632N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4632N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4632N/A * version 2 for more details (a copy is included in the LICENSE file that 4632N/A * You should have received a copy of the GNU General Public License version 4632N/A * 2 along with this work; if not, write to the Free Software Foundation, 4632N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4632N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4632N/A * or visit www.oracle.com if you need additional information or have any 4632N/A // Window bounds reported by the native system (as opposed to 4632N/A // regular bounds inherited from LWComponentPeer which are 4632N/A // requested by user and may haven't been applied yet because 4632N/A // of asynchronous requests to the windowing system) 4632N/A // The back buffer is used for two purposes: 4632N/A // 1. To render all the lightweight peers 4632N/A // 2. To provide user with a BufferStrategy 4632N/A // Need to check if a single back buffer can be used for both 4632N/A// private VolatileImage backBuffer; 4632N/A // A peer where the last mouse event came to. Used to generate 4632N/A // find the component under cursor 4632N/A // depending on what mouse button is being dragged according to Cocoa 4632N/A // A bitmask that indicates what mouse buttons produce MOUSE_CLICKED events 4632N/A // on MOUSE_RELEASE. Click events are only generated if there were no drag 4632N/A // events between MOUSE_PRESSED and MOUSE_RELEASED for particular button 5232N/A * Current modal blocker or null. 5233N/A * Synchronization: peerTreeLock. 4632N/A // graphicsConfig should be updated according to the real window 4632N/A // bounds when the window is shown, see 4868278 4691N/A // first we check if user provided alpha for background. This is 4691N/A // similar to what Apple's Java do. 4691N/A // Since JDK7 we should rely on setOpacity() only. 4691N/A // this.opacity = c.getAlpha(); 4691N/A // System.out.println("Delegate assigns alpha (we ignore setOpacity()):" 4691N/A // we should not call setForeground because it will call a repaint 4691N/A // which the peer may not be ready to do yet. 4632N/A // No-op as LWWindowPeer doesn't have any containerPeer 4632N/A // ---- PEER METHODS ---- // 4632N/A // TODO: update graphicsConfig, see 4868278 4632N/A // TODO: don't notify the delegate if our visibility is unchanged 4632N/A // it is important to call this method on EDT 5166N/A // to prevent the deadlocks during the painting of the lightweight delegates 5166N/A //TODO: WHY? This is a native-system related call. Perhaps NOT calling 4632N/A // the painting procedure right from the setVisible(), but rather relying 5166N/A // on the native Expose event (or, scheduling the repainting asynchronously) 5166N/A // Focus the owner in case this window is focused. 4632N/A // KFM will do all the rest. 4632N/A // Assume this method is never called with numBuffers <= 1, as 0 is 4632N/A // unsupported, and 1 corresponds to a SingleBufferStrategy which 4632N/A // doesn't depend on the peer. Screen is considered as a separate 4632N/A // "buffer", that's why numBuffers - 1 4693N/A // SET_CLIENT_SIZE is only applicable to window peers, so handle it here 4693N/A // instead of pulling 'insets' field up to LWComponentPeer 4693N/A // no need to add insets since Window's notion of width and height includes insets. 4632N/A // until we've got a notification from the delegate 4632N/A // Get updated bounds, so we don't have to handle 'op' here manually 4639N/A * Overridden from LWContainerPeer to return the correct insets. 4632N/A * Insets are queried from the delegate and are kept up to date by 5276N/A * requiering when needed (i.e. when the window geometry is changed). 5276N/A // TODO: check for "use platform metrics" settings 5276N/A // ---- FRAME PEER METHODS ---- // 5233N/A // ---- DIALOG PEER METHODS ---- // 5233N/A //TODO: LWX will probably need some collectJavaToplevels to speed this up 5233N/A // ---- PEER NOTIFICATIONS ---- // 5233N/A //The toplevel target is Frame and states are applicable to it. 5232N/A //Otherwise, the target is Window and it don't have state property. 5232N/A //Hopefully, no such events are posted in the queue so consider the 5232N/A //target as Frame in all cases. 5232N/A // REMIND: should we send it anyway if the state not changed since last 4632N/A // REMIND: RepaintManager doesn't repaint iconified windows and 4632N/A // hence ignores any repaint request during deiconification. 4632N/A // So, we need to repaint window explicitly when it becomes normal. 4632N/A * Called by the delegate when any part of the window should be repainted. 4632N/A // TODO: there's a serious problem with Swing here: it handles 4632N/A // the exposition internally, so SwingPaintEventDispatcher always 4632N/A // return null from createPaintEvent(). However, we flush the 4632N/A // back buffer here unconditionally, so some flickering may appear. 4632N/A // A possible solution is to split postPaintEvent() into two parts, 4632N/A // and override that part which is only called after if 4632N/A // createPaintEvent() returned non-null value and flush the buffer 4632N/A // from the overridden method 4632N/A * There's no notifyReshape() in LWComponentPeer as the only 4632N/A * components which could be resized by user are top-level windows. 4632N/A // Check if anything changed 4632N/A // First, update peer's bounds 4632N/A // Second, update the graphics config and surface data 4632N/A // MouseDown in non-client area 4632N/A // Ungrab except for a click on a Dialog with the grabbing owner 4639N/A * Called by the delegate to dispatch the event to Java. Event 4632N/A * coordinates are relative to non-client window are, i.e. the top-left 4632N/A * point of the client area is (insets.top, insets.left). 4632N/A // TODO: fill "bdata" member of AWTEvent 4632N/A // findPeerAt() expects parent coordinates 4632N/A // Sometimes we may get MOUSE_EXITED after lastMouseEventPeer is switched 4632N/A // to a peer from another window. So we must first check if this peer is 4632N/A // the same as lastWindowPeer 4639N/A // lastMouseEventPeer may be null if mouse was out of Java windows 4639N/A // Sometimes, MOUSE_EXITED is not sent by delegate (or is sent a bit 4639N/A // later), in which case lastWindowPeer is another window 4639N/A // Additionally translate from this to lastWindowPeer coordinates 4886N/A // TODO: fill "bdata" member of AWTEvent 4665N/A // mouse buttons as if they were BUTTON2, so we do the same 4665N/A // mouse even when dragging. That's why we first update lastMouseEventPeer 4665N/A // based on initial targetPeer value and only then recalculate targetPeer 4632N/A // Ungrab only if this window is not an owned window of the grabbing one. 4632N/A // Cocoa dragged event has the information about which mouse 4632N/A // button is being dragged. Use it to determine the peer that 4632N/A // should receive the dragged event. 4632N/A // TODO: currently, mouse released event goes to the same component 4632N/A // that received corresponding mouse pressed event. For most cases, 4632N/A // it's OK, however, we need to make sure that our behavior is consistent 4632N/A // with 1.6 for cases where component in question have been 4632N/A // mouseClickButtons is updated below, after MOUSE_CLICK is sent 4632N/A // check if we receive mouseEvent from outside the window's bounds 4632N/A // it can be either mouseDragged or mouseReleased 5295N/A //TODO This can happen if this window is invisible. this is correct behavior in this case? 5295N/A //TODO This can happen if this window is invisible. this is correct behavior in this case? 4734N/A // TODO: could we just use the last mouse event target here? 4734N/A // findPeerAt() expects parent coordinates 4665N/A // TODO: fill "bdata" member of AWTEvent 4632N/A 0 /* clickCount */,
false /* popupTrigger */,
4632N/A * Called by the delegate when a key is pressed. 4632N/A // Null focus owner may receive key event when 4632N/A // application hides the focused window upon ESC press 4632N/A // may come to already hidden window. This check eliminates NPE. 4632N/A // ---- UTILITY METHODS ---- // 4632N/A // TODO: this method can be implemented in a more 4632N/A // efficient way by forwarding to the delegate 4632N/A // Should never happen if gc is a screen device config 4632N/A // the default screen device in this case 4632N/A * This method is called when window's graphics config is changed from 4632N/A * the app code (e.g. when the window is made non-opaque) or when 4632N/A * the window is moved to another screen by user. 4632N/A * Returns true if the graphics config has been changed, false otherwise. 4632N/A // If window's graphics config is changed from the app code, the 4632N/A // config correspond to the same device as before; when the window 4632N/A // is moved by user, screenOn is updated in checkIfOnNewScreen(). 4632N/A // In either case, there's nothing to do with screenOn here 4632N/A // SurfaceData is replaced later in updateGraphicsData() 5642N/A // TODO: DisplayChangedListener stuff 4632N/A * This method returns a back buffer Graphics to render all the 4632N/A * peers to. After the peer is painted, the back buffer contents 4632N/A * should be flushed to the screen. All the target painting 4632N/A * (Component.paint() method) should be done directly to the screen. 4632N/A * May be called by delegate to provide SD to Java2D code. 4632N/A // VolatileImage oldBB = backBuffer; 5041N/A // This can only happen when this peer is being created 4632N/A // backBuffer = (VolatileImage)delegate.createBackBuffer(); 4686N/A // Draw the old back buffer to the new one 4632N/A //TODO blit. proof-of-concept 4686N/A * Request the window insets from the delegate and compares it 4686N/A * with the current one. This method is mostly called by the 4639N/A * delegate, e.g. when the window state is changed and insets 4686N/A * This method may be called on the toolkit thread. 4639N/A // Cross-app activation requests are not allowed. 4639N/A // Make the owner active window. 4632N/A // If owner is not natively active, request native 4632N/A // activation on it w/o sending events up to java. 4632N/A // Ensure the opposite is natively active and suppress sending events. 4767N/A // In case the toplevel is active but not focused, change focus directly, 4632N/A // as requesting native focus on it will not have effect. 5137N/A // TODO: check if modal blocked 4717N/A * "Delegates" the responsibility of managing focus to keyboard focus manager. 4717N/A // Note, the method is not called: 4722N/A // - for a simple window in any case. 4717N/A // ungrab a simple window if its owner looses activation. 4717N/A // TODO: wrap in SequencedEvent 4878N/A * Returns the foremost modal blocker of this window, or null.