8000307: Jre7cert: focusgained does not get called for all focus req when do alt + tab
Reviewed-by: ant, art
--- a/src/share/classes/com/sun/java/swing/plaf/windows/WindowsRootPaneUI.java Tue Oct 02 18:09:16 2012 +0400
+++ b/src/share/classes/com/sun/java/swing/plaf/windows/WindowsRootPaneUI.java Tue Oct 02 23:15:57 2012 +0400
@@ -30,6 +30,8 @@ import java.awt.Event;
import java.awt.Event;
import java.awt.KeyEventPostProcessor;
import java.awt.Window;
+import java.awt.Toolkit;
+import sun.awt.SunToolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
@@ -125,7 +127,19 @@ public class WindowsRootPaneUI extends B
}
JMenu menu = mbar != null ? mbar.getMenu(0) : null;
- if (menu != null) {
+ // It might happen that the altRelease event is processed
+ // with a reasonable delay since it has been generated.
+ // Here we check the last deactivation time of the containing
+ // window. If this time appears to be greater than the altRelease
+ // event time the event is skipped to avoid unexpected menu
+ // activation. See 7121442.
+ boolean skip = false;
+ Toolkit tk = Toolkit.getDefaultToolkit();
+ if (tk instanceof SunToolkit) {
+ skip = ev.getWhen() <= ((SunToolkit)tk).getWindowDeactivationTime(winAncestor);
+ }
+
+ if (menu != null && !skip) {
MenuElement[] path = new MenuElement[2];
path[0] = mbar;
path[1] = menu;
--- a/src/share/classes/java/awt/SequencedEvent.java Tue Oct 02 18:09:16 2012 +0400
+++ b/src/share/classes/java/awt/SequencedEvent.java Tue Oct 02 23:15:57 2012 +0400
@@ -26,6 +26,7 @@ package java.awt;
package java.awt;
import java.util.LinkedList;
+import sun.awt.AWTAccessor;
import sun.awt.AppContext;
import sun.awt.SunToolkit;
@@ -53,6 +54,17 @@ class SequencedEvent extends AWTEvent im
private final AWTEvent nested;
private AppContext appContext;
private boolean disposed;
+
+ static {
+ AWTAccessor.setSequencedEventAccessor(new AWTAccessor.SequencedEventAccessor() {
+ public AWTEvent getNested(AWTEvent sequencedEvent) {
+ return ((SequencedEvent)sequencedEvent).nested;
+ }
+ public boolean isSequencedEvent(AWTEvent event) {
+ return event instanceof SequencedEvent;
+ }
+ });
+ }
/**
* Constructs a new SequencedEvent which will dispatch the specified
--- a/src/share/classes/sun/awt/AWTAccessor.java Tue Oct 02 18:09:16 2012 +0400
+++ b/src/share/classes/sun/awt/AWTAccessor.java Tue Oct 02 23:15:57 2012 +0400
@@ -668,6 +668,21 @@ public final class AWTAccessor {
}
/*
+ * An accessor for the SequencedEventAccessor class
+ */
+ public interface SequencedEventAccessor {
+ /*
+ * Returns the nested event.
+ */
+ AWTEvent getNested(AWTEvent sequencedEvent);
+
+ /*
+ * Returns true if the event is an instances of SequencedEvent.
+ */
+ boolean isSequencedEvent(AWTEvent event);
+ }
+
+ /*
* Accessor instances are initialized in the static initializers of
* corresponding AWT classes by using setters defined below.
*/
@@ -693,6 +708,7 @@ public final class AWTAccessor {
private static SystemTrayAccessor systemTrayAccessor;
private static TrayIconAccessor trayIconAccessor;
private static DefaultKeyboardFocusManagerAccessor defaultKeyboardFocusManagerAccessor;
+ private static SequencedEventAccessor sequencedEventAccessor;
/*
* Set an accessor object for the java.awt.Component class.
@@ -1071,4 +1087,20 @@ public final class AWTAccessor {
return defaultKeyboardFocusManagerAccessor;
}
+ /*
+ * Set an accessor object for the java.awt.SequencedEvent class.
+ */
+ public static void setSequencedEventAccessor(SequencedEventAccessor sea) {
+ sequencedEventAccessor = sea;
+ }
+
+ /*
+ * Get the accessor object for the java.awt.SequencedEvent class.
+ */
+ public static SequencedEventAccessor getSequencedEventAccessor() {
+ // The class is not public. So we can't ensure it's initialized.
+ // Null returned value means it's not initialized
+ // (so not a single instance of the event has been created).
+ return sequencedEventAccessor;
+ }
}
--- a/src/share/classes/sun/awt/SunToolkit.java Tue Oct 02 18:09:16 2012 +0400
+++ b/src/share/classes/sun/awt/SunToolkit.java Tue Oct 02 23:15:57 2012 +0400
@@ -462,6 +462,19 @@ public abstract class SunToolkit extends
if (event == null) {
throw new NullPointerException();
}
+
+ AWTAccessor.SequencedEventAccessor sea = AWTAccessor.getSequencedEventAccessor();
+ if (sea != null && sea.isSequencedEvent(event)) {
+ AWTEvent nested = sea.getNested(event);
+ if (nested.getID() == WindowEvent.WINDOW_LOST_FOCUS &&
+ nested instanceof TimedWindowEvent)
+ {
+ TimedWindowEvent twe = (TimedWindowEvent)nested;
+ ((SunToolkit)Toolkit.getDefaultToolkit()).
+ setWindowDeactivationTime((Window)twe.getSource(), twe.getWhen());
+ }
+ }
+
// All events posted via this method are system-generated.
// Placing the following call here reduces considerably the
// number of places throughout the toolkit that would
@@ -1857,6 +1870,28 @@ public abstract class SunToolkit extends
return false;
}
+ private static final Object DEACTIVATION_TIMES_MAP_KEY = new Object();
+
+ public synchronized void setWindowDeactivationTime(Window w, long time) {
+ AppContext ctx = getAppContext(w);
+ WeakHashMap<Window, Long> map = (WeakHashMap<Window, Long>)ctx.get(DEACTIVATION_TIMES_MAP_KEY);
+ if (map == null) {
+ map = new WeakHashMap<Window, Long>();
+ ctx.put(DEACTIVATION_TIMES_MAP_KEY, map);
+ }
+ map.put(w, time);
+ }
+
+ public synchronized long getWindowDeactivationTime(Window w) {
+ AppContext ctx = getAppContext(w);
+ WeakHashMap<Window, Long> map = (WeakHashMap<Window, Long>)ctx.get(DEACTIVATION_TIMES_MAP_KEY);
+ if (map == null) {
+ return -1;
+ }
+ Long time = map.get(w);
+ return time == null ? -1 : time;
+ }
+
// Cosntant alpha
public boolean isWindowOpacitySupported() {
return false;
--- a/src/windows/native/sun/windows/awt_Window.cpp Tue Oct 02 18:09:16 2012 +0400
+++ b/src/windows/native/sun/windows/awt_Window.cpp Tue Oct 02 23:15:57 2012 +0400
@@ -1477,7 +1477,7 @@ void AwtWindow::SendWindowEvent(jint id,
if (wClassEvent == NULL) {
if (env->PushLocalFrame(1) < 0)
return;
- wClassEvent = env->FindClass("java/awt/event/WindowEvent");
+ wClassEvent = env->FindClass("sun/awt/TimedWindowEvent");
if (wClassEvent != NULL) {
wClassEvent = (jclass)env->NewGlobalRef(wClassEvent);
}
@@ -1491,7 +1491,7 @@ void AwtWindow::SendWindowEvent(jint id,
if (wEventInitMID == NULL) {
wEventInitMID =
env->GetMethodID(wClassEvent, "<init>",
- "(Ljava/awt/Window;ILjava/awt/Window;II)V");
+ "(Ljava/awt/Window;ILjava/awt/Window;IIJ)V");
DASSERT(wEventInitMID);
if (wEventInitMID == NULL) {
return;
@@ -1532,7 +1532,7 @@ void AwtWindow::SendWindowEvent(jint id,
}
}
jobject event = env->NewObject(wClassEvent, wEventInitMID, target, id,
- jOpposite, oldState, newState);
+ jOpposite, oldState, newState, TimeHelper::getMessageTimeUTC());
DASSERT(!safe_ExceptionOccurred(env));
DASSERT(event != NULL);
if (jOpposite != NULL) {
@@ -1559,21 +1559,8 @@ void AwtWindow::SendWindowEvent(jint id,
BOOL AwtWindow::AwtSetActiveWindow(BOOL isMouseEventCause, UINT hittest)
{
- // Fix for 6458497.
- // Retreat if current foreground window is out of both our and embedder process.
- // The exception is when activation is requested due to a mouse event.
- if (!isMouseEventCause) {
- HWND fgWindow = ::GetForegroundWindow();
- if (NULL != fgWindow) {
- DWORD fgProcessID;
- ::GetWindowThreadProcessId(fgWindow, &fgProcessID);
- if (fgProcessID != ::GetCurrentProcessId()
- && !AwtToolkit::GetInstance().IsEmbedderProcessId(fgProcessID))
- {
- return FALSE;
- }
- }
- }
+ // We used to reject non mouse window activation if our app wasn't active.
+ // This code since has been removed as the fix for 7185280
HWND proxyContainerHWnd = GetProxyToplevelContainer();
HWND proxyHWnd = GetProxyFocusOwner();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/awt/TimedWindowEvent.java Tue Oct 02 23:15:57 2012 +0400
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.awt;
+
+import java.awt.event.WindowEvent;
+import java.awt.Window;
+
+public class TimedWindowEvent extends WindowEvent {
+
+ private long time;
+
+ public long getWhen() {
+ return time;
+ }
+
+ public TimedWindowEvent(Window source, int id, Window opposite, long time) {
+ super(source, id, opposite);
+ this.time = time;
+ }
+
+ public TimedWindowEvent(Window source, int id, Window opposite,
+ int oldState, int newState, long time)
+ {
+ super(source, id, opposite, oldState, newState);
+ this.time = time;
+ }
+}
+