summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgrt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-25 13:58:22 +0000
committergrt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-25 13:58:22 +0000
commit2b5034075bce34d79aa716eb6525f6bc43b26777 (patch)
treed90179252d64793b14d903c98bd404ddb9bbb651
parentf958054738592c984e713a2582ac66d0e9bd5b4c (diff)
downloadchromium_src-2b5034075bce34d79aa716eb6525f6bc43b26777.zip
chromium_src-2b5034075bce34d79aa716eb6525f6bc43b26777.tar.gz
chromium_src-2b5034075bce34d79aa716eb6525f6bc43b26777.tar.bz2
Fix cross-window focus in Chrome Frame.
Text input wasn't working due to requirements of the IME/TSF machinery that weren't being met by ExternalTabContainerWin. * ExternalTabContainerWin now provides an implementation for WebContentsDelegate::WebContentsFocused that calls into its WebView's OnWebContentsFocused method. This mimics BrowserView, and permits proper focus tracking via the FocusManager. * ExternalTabContainerWin now provides a specialization of DesktopRootWindowHostWin that saves and restores focus on blur/focus events. The stock DRWHW does this based on window activation, but this doesn't work for ETCW since the ETCW's DRWHW doesn't receive activation messages due to it being a child of an IE window rather than a top-level window. * IEEventSink::SendKeys now sets focus to the renderer before sending key down/up messages. BUG=241081 Review URL: https://chromiumcodereview.appspot.com/15944007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@202270 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/ui/views/external_tab_container_win.cc43
-rw-r--r--chrome/browser/ui/views/external_tab_container_win.h1
-rw-r--r--chrome_frame/test/data/window_open.html6
-rw-r--r--chrome_frame/test/ie_event_sink.cc4
-rw-r--r--chrome_frame/test/navigation_test.cc5
-rw-r--r--chrome_frame/test/simulate_input.cc10
6 files changed, 56 insertions, 13 deletions
diff --git a/chrome/browser/ui/views/external_tab_container_win.cc b/chrome/browser/ui/views/external_tab_container_win.cc
index a452a90..2175d55 100644
--- a/chrome/browser/ui/views/external_tab_container_win.cc
+++ b/chrome/browser/ui/views/external_tab_container_win.cc
@@ -82,6 +82,7 @@
#if defined(USE_AURA)
#include "ui/aura/root_window.h"
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
+#include "ui/views/widget/desktop_aura/desktop_root_window_host_win.h"
#endif
using content::BrowserThread;
@@ -231,6 +232,36 @@ class ContainerWindow : public ATL::CWindowImpl<ContainerWindow,
DISALLOW_COPY_AND_ASSIGN(ContainerWindow);
};
+
+// A specialization of DesktopRootWindowHost for an external tab container that
+// saves and restores focus as the ETC is blurred and focused. DRWHW ordinarily
+// does this during window activation and deactivation. Since the ETC is a child
+// window, it does not receive activation messages.
+class ExternalTabRootWindowHost : public views::DesktopRootWindowHostWin {
+ public:
+ ExternalTabRootWindowHost(
+ views::internal::NativeWidgetDelegate* native_widget_delegate,
+ views::DesktopNativeWidgetAura* desktop_native_widget_aura,
+ const gfx::Rect& initial_bounds)
+ : views::DesktopRootWindowHostWin(native_widget_delegate,
+ desktop_native_widget_aura,
+ initial_bounds) {}
+
+ protected:
+ // HWNDMessageHandlerDelegate methods:
+ virtual void HandleNativeFocus(HWND last_focused_window) OVERRIDE {
+ views::DesktopRootWindowHostWin::HandleNativeFocus(last_focused_window);
+ RestoreFocusOnActivate();
+ }
+
+ virtual void HandleNativeBlur(HWND focused_window) OVERRIDE {
+ SaveFocusOnDeactivate();
+ views::DesktopRootWindowHostWin::HandleNativeBlur(focused_window);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ExternalTabRootWindowHost);
+};
#endif
base::LazyInstance<ExternalTabContainerWin::PendingTabs>
@@ -305,7 +336,11 @@ bool ExternalTabContainerWin::Init(Profile* profile,
tab_container_window_ =
(new ContainerWindow(HWND_DESKTOP, params.bounds))->AsWeakPtr();
- params.native_widget = new views::DesktopNativeWidgetAura(widget_);
+ views::DesktopNativeWidgetAura* native_widget =
+ new views::DesktopNativeWidgetAura(widget_);
+ params.native_widget = native_widget;
+ params.desktop_root_window_host =
+ new ExternalTabRootWindowHost(widget_, native_widget, params.bounds);
params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
#endif
widget_->Init(params);
@@ -760,6 +795,12 @@ bool ExternalTabContainerWin::TakeFocus(content::WebContents* source,
return true;
}
+void ExternalTabContainerWin::WebContentsFocused(
+ content::WebContents* contents) {
+ DCHECK_EQ(tab_contents_container_->GetWebContents(), contents);
+ tab_contents_container_->OnWebContentsFocused(contents);
+}
+
void ExternalTabContainerWin::CanDownload(
RenderViewHost* render_view_host,
int request_id,
diff --git a/chrome/browser/ui/views/external_tab_container_win.h b/chrome/browser/ui/views/external_tab_container_win.h
index 7709bf0..761e1b1 100644
--- a/chrome/browser/ui/views/external_tab_container_win.h
+++ b/chrome/browser/ui/views/external_tab_container_win.h
@@ -131,6 +131,7 @@ class ExternalTabContainerWin : public ExternalTabContainer,
content::WebContents* source,
const content::NativeWebKeyboardEvent& event) OVERRIDE;
virtual bool TakeFocus(content::WebContents* source, bool reverse) OVERRIDE;
+ virtual void WebContentsFocused(content::WebContents* contents) OVERRIDE;
virtual void CanDownload(content::RenderViewHost* render_view_host,
int request_id,
const std::string& request_method,
diff --git a/chrome_frame/test/data/window_open.html b/chrome_frame/test/data/window_open.html
index 7708491..2478c42 100644
--- a/chrome_frame/test/data/window_open.html
+++ b/chrome_frame/test/data/window_open.html
@@ -7,8 +7,10 @@
function OnClick() {
// Open popup to the url from the given query string.
var url = window.location.search.substring(1);
- new_window = window.open(url, "_blank",
- "left=10, top=10, height=250, width=250");
+ if (!new_window) {
+ new_window = window.open(url, "_blank",
+ "left=10, top=10, height=250, width=250");
+ }
}
function OnKeyPress() {
diff --git a/chrome_frame/test/ie_event_sink.cc b/chrome_frame/test/ie_event_sink.cc
index 6caa4cd..4ba7126 100644
--- a/chrome_frame/test/ie_event_sink.cc
+++ b/chrome_frame/test/ie_event_sink.cc
@@ -15,6 +15,7 @@
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/strings/string_piece.h"
+#include "base/test/test_timeouts.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
#include "base/win/scoped_bstr.h"
@@ -317,7 +318,8 @@ void IEEventSink::SetFocusToRenderer() {
void IEEventSink::SendKeys(const char* input_string) {
HWND window = GetRendererWindow();
- const base::TimeDelta kMessageSleep = base::TimeDelta::FromMilliseconds(50);
+ simulate_input::SetKeyboardFocusToWindow(window);
+ const base::TimeDelta kMessageSleep = TestTimeouts::tiny_timeout();
const base::StringPiece codes(input_string);
for (size_t i = 0; i < codes.length(); ++i) {
char character = codes[i];
diff --git a/chrome_frame/test/navigation_test.cc b/chrome_frame/test/navigation_test.cc
index 50f9134..1f8485f 100644
--- a/chrome_frame/test/navigation_test.cc
+++ b/chrome_frame/test/navigation_test.cc
@@ -369,12 +369,7 @@ TEST_P(FullTabNavigationTest, DISABLED_JavascriptWindowOpenDifferentDomain) {
// Tests that the parent window can successfully close its popup through
// the javascript close method.
-#if defined(USE_AURA)
-// Key events don't work after window.open; http://crbug.com/241081.
-TEST_P(FullTabNavigationTest, DISABLED_JavascriptWindowOpenCanClose) {
-#else
TEST_P(FullTabNavigationTest, JavascriptWindowOpenCanClose) {
-#endif
// Please see http://code.google.com/p/chromium/issues/detail?id=60987
// for more information on why this test is disabled for Vista with IE7.
if (base::win::GetVersion() == base::win::VERSION_VISTA &&
diff --git a/chrome_frame/test/simulate_input.cc b/chrome_frame/test/simulate_input.cc
index 6317d14..3dca6f1 100644
--- a/chrome_frame/test/simulate_input.cc
+++ b/chrome_frame/test/simulate_input.cc
@@ -7,6 +7,8 @@
#include <atlbase.h>
#include <atlwin.h>
+#include "base/test/test_timeouts.h"
+#include "base/threading/platform_thread.h"
#include "chrome_frame/utils.h"
namespace simulate_input {
@@ -191,6 +193,7 @@ void SetKeyboardFocusToWindow(HWND window) {
}
void SendMouseClick(int x, int y, MouseButton button) {
+ const base::TimeDelta kMessageTimeout = TestTimeouts::tiny_timeout();
// TODO(joshia): Fix this. GetSystemMetrics(SM_CXSCREEN) will
// retrieve screen size of the primarary monitor only. And monitors
// arrangement could be pretty arbitrary.
@@ -208,16 +211,15 @@ void SendMouseClick(int x, int y, MouseButton button) {
input_info.mi.dx = static_cast<LONG>(location_x);
input_info.mi.dy = static_cast<LONG>(location_y);
::SendInput(1, &input_info, sizeof(INPUT));
-
- Sleep(10);
+ base::PlatformThread::Sleep(kMessageTimeout);
input_info.mi.dwFlags = button_flag | MOUSEEVENTF_ABSOLUTE;
::SendInput(1, &input_info, sizeof(INPUT));
-
- Sleep(10);
+ base::PlatformThread::Sleep(kMessageTimeout);
input_info.mi.dwFlags = (button_flag << 1) | MOUSEEVENTF_ABSOLUTE;
::SendInput(1, &input_info, sizeof(INPUT));
+ base::PlatformThread::Sleep(kMessageTimeout);
}
void SendMouseClick(HWND window, int x, int y, MouseButton button) {