diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-11 22:57:16 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-11 22:57:16 +0000 |
commit | b93542fd121fa7f1ec65a27fdf94ccdcbbd638b9 (patch) | |
tree | 9deefa0a108bf596f3616897b2389c6c28e20cb6 /chrome | |
parent | d72aa00d29a465e37454afc6db6d1080c62051e3 (diff) | |
download | chromium_src-b93542fd121fa7f1ec65a27fdf94ccdcbbd638b9.zip chromium_src-b93542fd121fa7f1ec65a27fdf94ccdcbbd638b9.tar.gz chromium_src-b93542fd121fa7f1ec65a27fdf94ccdcbbd638b9.tar.bz2 |
Linux: Special case focus handling so that we don't tell webkit it's lost focus when a context menu is showing.
BUG=13404,13554
TEST=copy/paste *via the right-click context menu* works as expected in gmail.
Review URL: http://codereview.chromium.org/118339
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18225 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
6 files changed, 50 insertions, 17 deletions
diff --git a/chrome/browser/renderer_host/render_widget_host_view.h b/chrome/browser/renderer_host/render_widget_host_view.h index 41eecf6..2c4a3dc 100644 --- a/chrome/browser/renderer_host/render_widget_host_view.h +++ b/chrome/browser/renderer_host/render_widget_host_view.h @@ -136,6 +136,10 @@ class RenderWidgetHostView { // back to the renderer asynchronously. virtual void PasteFromSelectionClipboard() { } + // Tells the View whether the context menu is showing. This is used on Linux + // to suppress updates to webkit focus for the duration of the show. + virtual void ShowingContextMenu(bool showing) { } + // Allocate a backing store for this view virtual BackingStore* AllocBackingStore(const gfx::Size& size) = 0; 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 d1ec4bf..8cb406b 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc @@ -145,7 +145,10 @@ class RenderWidgetHostViewGtkWidget { // Whenever we lose focus, set the cursor back to that of our parent window, // which should be the default arrow. gdk_window_set_cursor(widget->window, NULL); - host_view->GetRenderWidgetHost()->Blur(); + // If we are showing a context menu, maintain the illusion that webkit has + // focus. + if (!host_view->is_showing_context_menu_) + host_view->GetRenderWidgetHost()->Blur(); return FALSE; } @@ -220,11 +223,12 @@ RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget( RenderWidgetHostViewGtk::RenderWidgetHostViewGtk(RenderWidgetHost* widget_host) : host_(widget_host), - parent_host_view_(NULL), - parent_(NULL), about_to_validate_and_paint_(false), - is_loading_(false), is_hidden_(false), + is_loading_(false), + is_showing_context_menu_(false), + parent_host_view_(NULL), + parent_(NULL), is_popup_first_mouse_release_(true) { host_->set_view(this); } @@ -455,6 +459,14 @@ void RenderWidgetHostViewGtk::PasteFromSelectionClipboard() { gtk_clipboard_request_text(x_clipboard, ReceivedSelectionText, this); } +void RenderWidgetHostViewGtk::ShowingContextMenu(bool showing) { + is_showing_context_menu_ = showing; + // Note that GTK_WIDGET_HAS_FOCUS differs gtom gtk_widget_is_focus() in that + // the latter doesn't care whether the toplevel has focus. + if (!showing && !GTK_WIDGET_HAS_FOCUS(view_.get())) + GetRenderWidgetHost()->Blur(); +} + void RenderWidgetHostViewGtk::Paint(const gfx::Rect& damage_rect) { DCHECK(!about_to_validate_and_paint_); 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 fdd5a97..0bed0c5 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_gtk.h +++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.h @@ -59,6 +59,7 @@ class RenderWidgetHostViewGtk : public RenderWidgetHostView { void SetTooltipText(const std::wstring& tooltip_text); void SelectionChanged(const std::string& text); void PasteFromSelectionClipboard(); + void ShowingContextMenu(bool showing); BackingStore* AllocBackingStore(const gfx::Size& size); // --------------------------------------------------------------------------- @@ -82,12 +83,7 @@ class RenderWidgetHostViewGtk : public RenderWidgetHostView { RenderWidgetHost *const host_; // The native UI widget. OwnedWidgetGtk view_; - // Variables used only for popups -------------------------------------------- - // Our parent widget. - RenderWidgetHostView* parent_host_view_; - // The native view of our parent, equivalent to - // parent_host_view_->GetNativeView(). - GtkWidget* parent_; + // This is true when we are currently painting and thus should handle extra // paint requests by expanding the invalid rect rather than actually // painting. @@ -95,15 +91,23 @@ class RenderWidgetHostViewGtk : public RenderWidgetHostView { // This is the rectangle which we'll paint. gfx::Rect invalid_rect_; + // Whether or not this widget is hidden. + bool is_hidden_; + // Whether we are currently loading. bool is_loading_; - // The cursor for the page. This is passed up from the renderer. WebCursor current_cursor_; - // Whether or not this widget is hidden. - bool is_hidden_; + // Whether we are showing a context menu. + bool is_showing_context_menu_; + // Variables used only for popups -------------------------------------------- + // Our parent widget. + RenderWidgetHostView* parent_host_view_; + // The native view of our parent, equivalent to + // parent_host_view_->GetNativeView(). + GtkWidget* parent_; // We ignore the first mouse release on popups. This allows the popup to // stay open. bool is_popup_first_mouse_release_; diff --git a/chrome/browser/tab_contents/render_view_context_menu_gtk.cc b/chrome/browser/tab_contents/render_view_context_menu_gtk.cc index bf147dc..c58a7f3 100644 --- a/chrome/browser/tab_contents/render_view_context_menu_gtk.cc +++ b/chrome/browser/tab_contents/render_view_context_menu_gtk.cc @@ -7,15 +7,19 @@ #include <gtk/gtk.h> #include "base/string_util.h" +#include "chrome/browser/renderer_host/render_widget_host_view.h" +#include "chrome/browser/tab_contents/tab_contents.h" #include "webkit/glue/context_menu.h" RenderViewContextMenuGtk::RenderViewContextMenuGtk( TabContents* web_contents, const ContextMenuParams& params, - guint32 triggering_event_time) + guint32 triggering_event_time, + RenderWidgetHostView* rwhv) : RenderViewContextMenu(web_contents, params), making_submenu_(false), - triggering_event_time_(triggering_event_time) { + triggering_event_time_(triggering_event_time), + host_view_(rwhv) { InitMenu(params.node); DoneMakingMenu(&menu_); gtk_menu_.reset(new MenuGtk(this, menu_.data(), NULL)); @@ -25,6 +29,7 @@ RenderViewContextMenuGtk::~RenderViewContextMenuGtk() { } void RenderViewContextMenuGtk::Popup() { + host_view_->ShowingContextMenu(true); gtk_menu_->PopupAsContext(triggering_event_time_); } @@ -49,6 +54,10 @@ std::string RenderViewContextMenuGtk::GetLabel(int id) const { return std::string(); } +void RenderViewContextMenuGtk::StoppedShowing() { + host_view_->ShowingContextMenu(false); +} + void RenderViewContextMenuGtk::AppendMenuItem(int id) { AppendItem(id, std::wstring(), MENU_NORMAL); } diff --git a/chrome/browser/tab_contents/render_view_context_menu_gtk.h b/chrome/browser/tab_contents/render_view_context_menu_gtk.h index 62c0066..8b6ebb6 100644 --- a/chrome/browser/tab_contents/render_view_context_menu_gtk.h +++ b/chrome/browser/tab_contents/render_view_context_menu_gtk.h @@ -14,6 +14,7 @@ #include "chrome/browser/tab_contents/render_view_context_menu.h" class ContextMenuParams; +class RenderWidgetHostView; // TODO(port): we need accelerator support for this class. class RenderViewContextMenuGtk : public RenderViewContextMenu, @@ -21,7 +22,8 @@ class RenderViewContextMenuGtk : public RenderViewContextMenu, public: RenderViewContextMenuGtk(TabContents* web_contents, const ContextMenuParams& params, - uint32_t triggering_event_time); + uint32_t triggering_event_time, + RenderWidgetHostView* rwhv); ~RenderViewContextMenuGtk(); @@ -33,6 +35,7 @@ class RenderViewContextMenuGtk : public RenderViewContextMenu, virtual bool IsItemChecked(int id) const; virtual void ExecuteCommand(int id); virtual std::string GetLabel(int id) const; + virtual void StoppedShowing(); protected: // RenderViewContextMenu implementation -------------------------------------- @@ -55,6 +58,7 @@ class RenderViewContextMenuGtk : public RenderViewContextMenu, std::vector<MenuCreateMaterial> submenu_; bool making_submenu_; uint32_t triggering_event_time_; + RenderWidgetHostView* host_view_; }; #endif // CHROME_BROWSER_TAB_CONTENTS_RENDER_VIEW_CONTEXT_MENU_GTK_H_ diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/tab_contents/tab_contents_view_gtk.cc index faffd18..30cef96 100644 --- a/chrome/browser/tab_contents/tab_contents_view_gtk.cc +++ b/chrome/browser/tab_contents/tab_contents_view_gtk.cc @@ -311,7 +311,7 @@ void TabContentsViewGtk::Observe(NotificationType type, void TabContentsViewGtk::ShowContextMenu(const ContextMenuParams& params) { context_menu_.reset(new RenderViewContextMenuGtk(tab_contents(), params, - last_mouse_down_time_)); + last_mouse_down_time_, tab_contents()->render_widget_host_view())); context_menu_->Popup(); } |