summaryrefslogtreecommitdiffstats
path: root/chrome/browser/renderer_host
diff options
context:
space:
mode:
authortwiz@chromium.org <twiz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-10 22:46:47 +0000
committertwiz@chromium.org <twiz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-10 22:46:47 +0000
commit2db27be7dbb16f02587b90f150a843d8ad234563 (patch)
tree9bfd5b6b2ff4637a69744ce35249361d1f3ea353 /chrome/browser/renderer_host
parente1ce144bd04336891bb12b967095e938ed5f1bbb (diff)
downloadchromium_src-2db27be7dbb16f02587b90f150a843d8ad234563.zip
chromium_src-2db27be7dbb16f02587b90f150a843d8ad234563.tar.gz
chromium_src-2db27be7dbb16f02587b90f150a843d8ad234563.tar.bz2
CL implementing focus-dismissal of the chrome.experimental.popup set of extension APIs.
Specifically, these changes cause a displayed pop-up to be dismissed when the focus shifts away from both the pop-up view, and the extension-view that launched the pop-up.I had to do a lot of investigating and trial-and-error to converge to the solution present here. I was hoping to be able to piggy-back on the existing FocusManager's various listener routines, but because the pop-up is hosted in a BubbleWidget, which is a separate top-level window with its own focus manager, I could not rely on a given focus manager to take care of the focus change notifications. To get around the above issue, I added a new type of focus listener that can listen on native-window focus change events. I added invocations to this listener throughout the Widget classes in the system so that registered listeners will be notified on focus change. I found some of the focus change events problematic, as the system will arbitrarily reassign the focus to the main browser window when shifting activation between chrome windows. (SeefocusManagerWin::ClearNativeFocus). To prevent this focus bounce from confusing focus listeners, I added a means to suppress notification of focus change during these operations. I added GTK and Mac stubs for the new widget functions that will assert when called. GTK and Cocoa development is not my expertise, so I thought // TODO(port) would be wiser.I'm uncertain of the best means to unit-test these changes. Direction in this regard would be appreciated. BUG=None TEST=None Review URL: http://codereview.chromium.org/552167 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38685 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/renderer_host')
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view.h9
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_gtk.cc22
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_gtk.h1
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_mac.h1
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_mac.mm18
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_win.cc45
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_win.h1
-rw-r--r--chrome/browser/renderer_host/test/test_render_view_host.h4
8 files changed, 100 insertions, 1 deletions
diff --git a/chrome/browser/renderer_host/render_widget_host_view.h b/chrome/browser/renderer_host/render_widget_host_view.h
index f761053..e2f58d8 100644
--- a/chrome/browser/renderer_host/render_widget_host_view.h
+++ b/chrome/browser/renderer_host/render_widget_host_view.h
@@ -51,6 +51,11 @@ class RenderWidgetHostView {
// going to be a regular RenderWidgetHost or a RenderViewHost (a subclass).
static RenderWidgetHostView* CreateViewForWidget(RenderWidgetHost* widget);
+ // Retrieves the RenderWidgetHostView corresponding to the specified
+ // |native_view|, or NULL if there is no such instance.
+ static RenderWidgetHostView* GetRenderWidgetHostViewFromNativeView(
+ gfx::NativeView native_view);
+
// Perform all the initialization steps necessary for this object to represent
// a popup (such as a <select> dropdown), then shows the popup at |pos|.
virtual void InitAsPopup(RenderWidgetHostView* parent_host_view,
@@ -204,6 +209,10 @@ class RenderWidgetHostView {
}
const SkBitmap& background() const { return background_; }
+ // Returns true if the native view, |native_view|, is contained within in the
+ // widget associated with this RenderWidgetHostView.
+ virtual bool ContainsNativeView(gfx::NativeView native_view) const = 0;
+
protected:
// Interface class only, do not construct.
RenderWidgetHostView() : activatable_(true) {}
diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
index 66cbe52..dffb61f 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
+++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
@@ -43,6 +43,8 @@ static const int kMaxWindowHeight = 4000;
// TODO(brettw) make this a command line option.
static const bool kUseGPURendering = false;
+static const char* kRenderWidgetHostViewKey = "__RENDER_WIDGET_HOST_VIEW__";
+
using WebKit::WebInputEventFactory;
// This class is a simple convenience wrapper for Gtk functions. It has only
@@ -102,6 +104,9 @@ class RenderWidgetHostViewGtkWidget {
g_signal_connect_after(widget, "scroll-event",
G_CALLBACK(MouseScrollEvent), host_view);
+ g_object_set_data(G_OBJECT(widget), kRenderWidgetHostViewKey,
+ static_cast<RenderWidgetHostView*>(host_view));
+
return widget;
}
@@ -744,6 +749,14 @@ void RenderWidgetHostViewGtk::DestroyPluginContainer(
plugin_container_manager_.DestroyPluginContainer(id);
}
+bool RenderWidgetHostViewGtk::ContainsNativeView(
+ gfx::NativeView native_view) const {
+ // TODO(port)
+ NOTREACHED() <<
+ "RenderWidgetHostViewGtk::ContainsNativeView not implemented.";
+ return false;
+}
+
void RenderWidgetHostViewGtk::ForwardKeyboardEvent(
const NativeWebKeyboardEvent& event) {
if (!host_)
@@ -755,3 +768,12 @@ void RenderWidgetHostViewGtk::ForwardKeyboardEvent(
}
host_->ForwardKeyboardEvent(event);
}
+
+// static
+RenderWidgetHostView*
+ RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView(
+ gfx::NativeView widget) {
+ gpointer user_data = g_object_get_data(G_OBJECT(widget),
+ kRenderWidgetHostViewKey);
+ return reinterpret_cast<RenderWidgetHostView*>(user_data);
+}
diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.h b/chrome/browser/renderer_host/render_widget_host_view_gtk.h
index f44a92b..fd2b579 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_gtk.h
+++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.h
@@ -71,6 +71,7 @@ class RenderWidgetHostViewGtk : public RenderWidgetHostView {
virtual void SetBackground(const SkBitmap& background);
virtual void CreatePluginContainer(gfx::PluginWindowHandle id);
virtual void DestroyPluginContainer(gfx::PluginWindowHandle id);
+ virtual bool ContainsNativeView(gfx::NativeView native_view) const;
gfx::NativeView native_view() const { return view_.get(); }
diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.h b/chrome/browser/renderer_host/render_widget_host_view_mac.h
index c707205..34903f0 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_mac.h
+++ b/chrome/browser/renderer_host/render_widget_host_view_mac.h
@@ -115,6 +115,7 @@ class RenderWidgetHostViewMac : public RenderWidgetHostView {
virtual void SetWindowVisibility(bool visible);
virtual void WindowFrameChanged();
virtual void SetBackground(const SkBitmap& background);
+ virtual bool ContainsNativeView(gfx::NativeView native_view) const;
// Methods associated with GPU plugin instances
virtual gfx::PluginWindowHandle AllocateFakePluginWindowHandle();
diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.mm b/chrome/browser/renderer_host/render_widget_host_view_mac.mm
index 6e6df70..ac76e90 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/chrome/browser/renderer_host/render_widget_host_view_mac.mm
@@ -93,6 +93,16 @@ RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget(
return new RenderWidgetHostViewMac(widget);
}
+// static
+RenderWidgetHostView* RenderWidgetHostView::
+ GetRenderWidgetHostViewFromNativeView(gfx::NativeView native_view) {
+ // TODO(port)
+ NOTREACHED() <<
+ "RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView not"
+ "implemented";
+ return NULL;
+}
+
///////////////////////////////////////////////////////////////////////////////
// RenderWidgetHostViewMac, public:
@@ -645,6 +655,14 @@ void RenderWidgetHostViewMac::SetBackground(const SkBitmap& background) {
render_widget_host_->routing_id(), background));
}
+bool RenderWidgetHostViewMac::ContainsNativeView(
+ gfx::NativeView native_view) const {
+ // TODO(port)
+ NOTREACHED() <<
+ "RenderWidgetHostViewMac::ContainsNativeView not implemented.";
+ return false;
+}
+
// EditCommandMatcher ---------------------------------------------------------
// This class is used to capture the shortcuts that a given key event maps to.
diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.cc b/chrome/browser/renderer_host/render_widget_host_view_win.cc
index 8bff4d2..3216c7c 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_win.cc
+++ b/chrome/browser/renderer_host/render_widget_host_view_win.cc
@@ -35,6 +35,7 @@
#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
#include "third_party/WebKit/WebKit/chromium/public/win/WebInputEventFactory.h"
#include "views/accessibility/view_accessibility.h"
+#include "views/focus/focus_manager.h"
#include "views/focus/focus_util_win.h"
// Included for views::kReflectedMessage - TODO(beng): move this to win_util.h!
#include "views/widget/widget_win.h"
@@ -58,6 +59,8 @@ const int kTooltipMaxWidthPixels = 300;
// Maximum number of characters we allow in a tooltip.
const int kMaxTooltipLength = 1024;
+const wchar_t* kRenderWidgetHostViewKey = L"__RENDER_WIDGET_HOST_VIEW__";
+
// A callback function for EnumThreadWindows to enumerate and dismiss
// any owned popop windows
BOOL CALLBACK DismissOwnedPopups(HWND window, LPARAM arg) {
@@ -728,6 +731,23 @@ void RenderWidgetHostViewWin::SetBackground(const SkBitmap& background) {
background));
}
+bool RenderWidgetHostViewWin::ContainsNativeView(
+ gfx::NativeView native_view) const {
+ if (m_hWnd == native_view)
+ return true;
+
+ // Traverse the set of parents of the given view to determine if native_view
+ // is a descendant of this window.
+ HWND parent_window = ::GetParent(native_view);
+ while (parent_window) {
+ if (parent_window == m_hWnd)
+ return true;
+ parent_window = ::GetParent(parent_window);
+ }
+
+ return false;
+}
+
///////////////////////////////////////////////////////////////////////////////
// RenderWidgetHostViewWin, private:
@@ -740,7 +760,9 @@ LRESULT RenderWidgetHostViewWin::OnCreate(CREATESTRUCT* create_struct) {
views::SetWindowSupportsRerouteMouseWheel(m_hWnd);
// Save away our HWND in the parent window as a property so that the
// accessibility code can find it.
- SetProp(GetParent(), kViewsNativeHostPropForAccessibility, m_hWnd);
+ ::SetProp(GetParent(), kViewsNativeHostPropForAccessibility, m_hWnd);
+ ::SetProp(m_hWnd, kRenderWidgetHostViewKey,
+ static_cast<RenderWidgetHostView*>(this));
return 0;
}
@@ -771,6 +793,8 @@ void RenderWidgetHostViewWin::OnDestroy() {
// sequence as part of the usual cleanup when the plugin instance goes away.
EnumChildWindows(m_hWnd, DetachPluginWindowsCallback, NULL);
+ ::RemoveProp(m_hWnd, kRenderWidgetHostViewKey);
+
ResetTooltip();
TrackMouseLeave(false);
}
@@ -919,11 +943,17 @@ LRESULT RenderWidgetHostViewWin::OnSetCursor(HWND window, UINT hittest_code,
}
void RenderWidgetHostViewWin::OnSetFocus(HWND window) {
+ views::FocusManager::GetWidgetFocusManager()->OnWidgetFocusEvent(window,
+ m_hWnd);
+
if (render_widget_host_)
render_widget_host_->GotFocus();
}
void RenderWidgetHostViewWin::OnKillFocus(HWND window) {
+ views::FocusManager::GetWidgetFocusManager()->OnWidgetFocusEvent(m_hWnd,
+ window);
+
if (render_widget_host_)
render_widget_host_->Blur();
}
@@ -1516,3 +1546,16 @@ void RenderWidgetHostViewWin::ShutdownHost() {
render_widget_host_->Shutdown();
// Do not touch any members at this point, |this| has been deleted.
}
+
+// static
+RenderWidgetHostView*
+ RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView(
+ gfx::NativeView native_view) {
+ if (::IsWindow(native_view)) {
+ HANDLE raw_render_host_view = ::GetProp(native_view,
+ kRenderWidgetHostViewKey);
+ if (raw_render_host_view)
+ return reinterpret_cast<RenderWidgetHostView*>(raw_render_host_view);
+ }
+ return NULL;
+}
diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.h b/chrome/browser/renderer_host/render_widget_host_view_win.h
index 5555495..64224fc 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_win.h
+++ b/chrome/browser/renderer_host/render_widget_host_view_win.h
@@ -137,6 +137,7 @@ class RenderWidgetHostViewWin
virtual void SetTooltipText(const std::wstring& tooltip_text);
virtual BackingStore* AllocBackingStore(const gfx::Size& size);
virtual void SetBackground(const SkBitmap& background);
+ virtual bool ContainsNativeView(gfx::NativeView native_view) const;
protected:
// Windows Message Handlers
diff --git a/chrome/browser/renderer_host/test/test_render_view_host.h b/chrome/browser/renderer_host/test/test_render_view_host.h
index 0521de9..85e6eca 100644
--- a/chrome/browser/renderer_host/test/test_render_view_host.h
+++ b/chrome/browser/renderer_host/test/test_render_view_host.h
@@ -94,6 +94,10 @@ class TestRenderWidgetHostView : public RenderWidgetHostView {
virtual void DestroyPluginContainer(gfx::PluginWindowHandle id) { }
#endif
+ virtual bool ContainsNativeView(gfx::NativeView native_view) const {
+ return false;
+ }
+
bool is_showing() const { return is_showing_; }
private: