summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-11 22:57:16 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-11 22:57:16 +0000
commitb93542fd121fa7f1ec65a27fdf94ccdcbbd638b9 (patch)
tree9deefa0a108bf596f3616897b2389c6c28e20cb6 /chrome
parentd72aa00d29a465e37454afc6db6d1080c62051e3 (diff)
downloadchromium_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')
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view.h4
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_gtk.cc20
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_gtk.h22
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu_gtk.cc13
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu_gtk.h6
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_gtk.cc2
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();
}