提交 15633233 编写于 作者: A aivanov

8056915: Focus lost in applet when browser window is minimized and restored

Reviewed-by: ant, dtitov, dcherepanov
上级 1c91ada3
/* /*
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -682,7 +682,12 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable { ...@@ -682,7 +682,12 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable {
if (toFocus != null) { if (toFocus != null) {
if (parent instanceof EmbeddedFrame) { if (parent instanceof EmbeddedFrame) {
((EmbeddedFrame)parent).synthesizeWindowActivation(true); // JDK-8056915: Try to request focus to the embedder first and
// activate the embedded frame through it
if (!((EmbeddedFrame) parent).requestFocusToEmbedder()) {
// Otherwise activate the embedded frame directly
((EmbeddedFrame) parent).synthesizeWindowActivation(true);
}
} }
// EmbeddedFrame might have focus before the applet was added. // EmbeddedFrame might have focus before the applet was added.
// Thus after its activation the most recent focus owner will be // Thus after its activation the most recent focus owner will be
......
/* /*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -360,6 +360,15 @@ public abstract class EmbeddedFrame extends Frame ...@@ -360,6 +360,15 @@ public abstract class EmbeddedFrame extends Frame
*/ */
public void synthesizeWindowActivation(boolean doActivate) {} public void synthesizeWindowActivation(boolean doActivate) {}
/**
* Requests the focus to the embedder.
*
* @return {@code true} if focus request was successful, and {@code false} otherwise.
*/
public boolean requestFocusToEmbedder() {
return false;
}
/** /**
* Moves this embedded frame to a new location. The top-left corner of * Moves this embedded frame to a new location. The top-left corner of
* the new location is specified by the <code>x</code> and <code>y</code> * the new location is specified by the <code>x</code> and <code>y</code>
......
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -51,6 +51,11 @@ public class WEmbeddedFrame extends EmbeddedFrame { ...@@ -51,6 +51,11 @@ public class WEmbeddedFrame extends EmbeddedFrame {
private static int pScale = 0; private static int pScale = 0;
private static final int MAX_BAND_SIZE = (1024*30); private static final int MAX_BAND_SIZE = (1024*30);
/**
* This flag is set to {@code true} if this embedded frame is hosted by Internet Explorer.
*/
private boolean isEmbeddedInIE = false;
private static String printScale = AccessController.doPrivileged( private static String printScale = AccessController.doPrivileged(
new GetPropertyAction("sun.java2d.print.pluginscalefactor")); new GetPropertyAction("sun.java2d.print.pluginscalefactor"));
...@@ -243,6 +248,14 @@ public class WEmbeddedFrame extends EmbeddedFrame { ...@@ -243,6 +248,14 @@ public class WEmbeddedFrame extends EmbeddedFrame {
} }
} }
@SuppressWarnings("deprecation")
public boolean requestFocusToEmbedder() {
if (isEmbeddedInIE) {
return ((WEmbeddedFramePeer) getPeer()).requestFocusToEmbedder();
}
return false;
}
public void registerAccelerator(AWTKeyStroke stroke) {} public void registerAccelerator(AWTKeyStroke stroke) {}
public void unregisterAccelerator(AWTKeyStroke stroke) {} public void unregisterAccelerator(AWTKeyStroke stroke) {}
......
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -78,4 +78,11 @@ public class WEmbeddedFramePeer extends WFramePeer { ...@@ -78,4 +78,11 @@ public class WEmbeddedFramePeer extends WFramePeer {
// false on other systems. // false on other systems.
return !Win32GraphicsEnvironment.isDWMCompositionEnabled(); return !Win32GraphicsEnvironment.isDWMCompositionEnabled();
} }
/**
* Sets the focus to plugin control window, the parent of embedded frame.
* Eventually, it will synthesizeWindowActivation to activate the embedded frame,
* if plugin control window gets the focus.
*/
public native boolean requestFocusToEmbedder();
} }
/* /*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -82,6 +82,15 @@ struct BlockedThreadStruct { ...@@ -82,6 +82,15 @@ struct BlockedThreadStruct {
HHOOK mouseHook; HHOOK mouseHook;
HHOOK modalHook; HHOOK modalHook;
}; };
// Communication with plugin control
// The value must be the same as in AxControl.h
#define WM_AX_REQUEST_FOCUS_TO_EMBEDDER (WM_USER + 197)
static bool SetFocusToPluginControl(HWND hwndPlugin);
/************************************************************************ /************************************************************************
* AwtFrame fields * AwtFrame fields
*/ */
...@@ -93,6 +102,7 @@ jmethodID AwtFrame::getExtendedStateMID; ...@@ -93,6 +102,7 @@ jmethodID AwtFrame::getExtendedStateMID;
jmethodID AwtFrame::setExtendedStateMID; jmethodID AwtFrame::setExtendedStateMID;
jmethodID AwtFrame::activateEmbeddingTopLevelMID; jmethodID AwtFrame::activateEmbeddingTopLevelMID;
jfieldID AwtFrame::isEmbeddedInIEID;
Hashtable AwtFrame::sm_BlockedThreads("AWTBlockedThreads"); Hashtable AwtFrame::sm_BlockedThreads("AWTBlockedThreads");
...@@ -104,6 +114,7 @@ AwtFrame::AwtFrame() { ...@@ -104,6 +114,7 @@ AwtFrame::AwtFrame() {
m_parentWnd = NULL; m_parentWnd = NULL;
menuBar = NULL; menuBar = NULL;
m_isEmbedded = FALSE; m_isEmbedded = FALSE;
m_isEmbeddedInIE = FALSE;
m_isLightweight = FALSE; m_isLightweight = FALSE;
m_ignoreWmSize = FALSE; m_ignoreWmSize = FALSE;
m_isMenuDropped = FALSE; m_isMenuDropped = FALSE;
...@@ -199,6 +210,13 @@ AwtFrame* AwtFrame::Create(jobject self, jobject parent) ...@@ -199,6 +210,13 @@ AwtFrame* AwtFrame::Create(jobject self, jobject parent)
if (isEmbedded) { if (isEmbedded) {
hwndParent = (HWND)handle; hwndParent = (HWND)handle;
// JDK-8056915: Handle focus communication between plugin and frame
frame->m_isEmbeddedInIE = IsEmbeddedInIE(hwndParent);
if (frame->m_isEmbeddedInIE) {
env->SetBooleanField(target, isEmbeddedInIEID, JNI_TRUE);
}
RECT rect; RECT rect;
::GetClientRect(hwndParent, &rect); ::GetClientRect(hwndParent, &rect);
//Fix for 6328675: SWT_AWT.new_Frame doesn't occupy client area under JDK6 //Fix for 6328675: SWT_AWT.new_Frame doesn't occupy client area under JDK6
...@@ -338,6 +356,21 @@ done: ...@@ -338,6 +356,21 @@ done:
return frame; return frame;
} }
/*
* Returns true if the frame is embedded into Internet Explorer.
* The function checks the class name of the parent window of the embedded frame.
*/
BOOL AwtFrame::IsEmbeddedInIE(HWND hwndParent)
{
const char *pluginClass = "Java Plug-in Control Window";
#define PARENT_CLASS_BUFFER_SIZE 64
char parentClass[PARENT_CLASS_BUFFER_SIZE];
return (::GetClassNameA(hwndParent, parentClass, PARENT_CLASS_BUFFER_SIZE) > 0)
&& (strncmp(parentClass, pluginClass, PARENT_CLASS_BUFFER_SIZE) == 0);
}
LRESULT AwtFrame::ProxyWindowProc(UINT message, WPARAM wParam, LPARAM lParam, MsgRouting &mr) LRESULT AwtFrame::ProxyWindowProc(UINT message, WPARAM wParam, LPARAM lParam, MsgRouting &mr)
{ {
LRESULT retValue = 0L; LRESULT retValue = 0L;
...@@ -1039,6 +1072,19 @@ BOOL AwtFrame::AwtSetActiveWindow(BOOL isMouseEventCause, UINT hittest) ...@@ -1039,6 +1072,19 @@ BOOL AwtFrame::AwtSetActiveWindow(BOOL isMouseEventCause, UINT hittest)
if (IsLightweightFrame()) { if (IsLightweightFrame()) {
return TRUE; return TRUE;
} }
if (isMouseEventCause && IsEmbeddedFrame() && m_isEmbeddedInIE) {
HWND hwndProxy = GetProxyFocusOwner();
// Do nothing if this frame is focused already
if (::GetFocus() != hwndProxy) {
// Fix for JDK-8056915:
// If window activated with mouse, set focus to plugin control window
// first to preserve focus owner inside browser window
if (SetFocusToPluginControl(::GetParent(GetHWnd()))) {
return TRUE;
}
// Plugin control window is already focused, so do normal processing
}
}
return AwtWindow::AwtSetActiveWindow(isMouseEventCause); return AwtWindow::AwtSetActiveWindow(isMouseEventCause);
} }
...@@ -1819,6 +1865,9 @@ Java_sun_awt_windows_WEmbeddedFrame_initIDs(JNIEnv *env, jclass cls) ...@@ -1819,6 +1865,9 @@ Java_sun_awt_windows_WEmbeddedFrame_initIDs(JNIEnv *env, jclass cls)
AwtFrame::activateEmbeddingTopLevelMID = env->GetMethodID(cls, "activateEmbeddingTopLevel", "()V"); AwtFrame::activateEmbeddingTopLevelMID = env->GetMethodID(cls, "activateEmbeddingTopLevel", "()V");
DASSERT(AwtFrame::activateEmbeddingTopLevelMID != NULL); DASSERT(AwtFrame::activateEmbeddingTopLevelMID != NULL);
AwtFrame::isEmbeddedInIEID = env->GetFieldID(cls, "isEmbeddedInIE", "Z");
DASSERT(AwtFrame::isEmbeddedInIEID != NULL);
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
} }
...@@ -1911,4 +1960,44 @@ Java_sun_awt_windows_WFramePeer_synthesizeWmActivate(JNIEnv *env, jobject self, ...@@ -1911,4 +1960,44 @@ Java_sun_awt_windows_WFramePeer_synthesizeWmActivate(JNIEnv *env, jobject self,
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
} }
JNIEXPORT jboolean JNICALL
Java_sun_awt_windows_WEmbeddedFramePeer_requestFocusToEmbedder(JNIEnv *env, jobject self)
{
jboolean result = JNI_FALSE;
TRY;
AwtFrame *frame = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
frame = (AwtFrame *)pData;
// JDK-8056915: During initial applet activation, set focus to plugin control window
HWND hwndParent = ::GetParent(frame->GetHWnd());
result = SetFocusToPluginControl(hwndParent);
CATCH_BAD_ALLOC_RET(JNI_FALSE);
ret:
return result;
}
} /* extern "C" */ } /* extern "C" */
static bool SetFocusToPluginControl(HWND hwndPlugin)
{
HWND hwndFocus = ::GetFocus();
if (hwndFocus == hwndPlugin) {
return false;
}
::SetFocus(hwndPlugin);
DWORD dwError = ::GetLastError();
if (dwError != ERROR_SUCCESS) {
// If direct call failed, use a special message to set focus
return (::SendMessage(hwndPlugin, WM_AX_REQUEST_FOCUS_TO_EMBEDDER, 0, 0) == 0);
}
return true;
}
/* /*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -60,6 +60,9 @@ public: ...@@ -60,6 +60,9 @@ public:
/* method id for WEmbeddedFrame.requestActivate() method */ /* method id for WEmbeddedFrame.requestActivate() method */
static jmethodID activateEmbeddingTopLevelMID; static jmethodID activateEmbeddingTopLevelMID;
/* field id for WEmbeddedFrame.isEmbeddedInIE */
static jfieldID isEmbeddedInIEID;
AwtFrame(); AwtFrame();
virtual ~AwtFrame(); virtual ~AwtFrame();
...@@ -171,6 +174,13 @@ private: ...@@ -171,6 +174,13 @@ private:
/* The frame is an EmbeddedFrame. */ /* The frame is an EmbeddedFrame. */
BOOL m_isEmbedded; BOOL m_isEmbedded;
/* Fix for JDK-8056915:
The embedded frame must gain focus by setting focus to its parent. */
BOOL m_isEmbeddedInIE;
/* Checks whether the frame is embedded in IE */
static BOOL IsEmbeddedInIE(HWND hwndParent);
/* The frame is a LightweightFrame */ /* The frame is a LightweightFrame */
BOOL m_isLightweight; BOOL m_isLightweight;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册