diff options
author | grt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-25 13:58:22 +0000 |
---|---|---|
committer | grt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-25 13:58:22 +0000 |
commit | 2b5034075bce34d79aa716eb6525f6bc43b26777 (patch) | |
tree | d90179252d64793b14d903c98bd404ddb9bbb651 | |
parent | f958054738592c984e713a2582ac66d0e9bd5b4c (diff) | |
download | chromium_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.cc | 43 | ||||
-rw-r--r-- | chrome/browser/ui/views/external_tab_container_win.h | 1 | ||||
-rw-r--r-- | chrome_frame/test/data/window_open.html | 6 | ||||
-rw-r--r-- | chrome_frame/test/ie_event_sink.cc | 4 | ||||
-rw-r--r-- | chrome_frame/test/navigation_test.cc | 5 | ||||
-rw-r--r-- | chrome_frame/test/simulate_input.cc | 10 |
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) { |