Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(425)

Unified Diff: ui/views/widget/widget.cc

Issue 12529012: Context menu on views must show on mouse down for non-WIN. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: patch Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/views/widget/widget.h ('k') | ui/views/widget/widget_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/widget/widget.cc
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc
index 394715dac9046319cee0b6f7368d426c78820ac4..f0cd1db60d329aff22f59b063f3468767b032112 100644
--- a/ui/views/widget/widget.cc
+++ b/ui/views/widget/widget.cc
@@ -61,6 +61,48 @@ NativeWidget* CreateNativeWidget(NativeWidget* native_widget,
return native_widget;
}
+class PostMousePressedProcessor : public WidgetObserver {
sky 2013/03/21 22:17:48 How about declaring this as an inner class (you ca
varunjain 2013/03/21 22:47:14 Done.
+ public:
+ explicit PostMousePressedProcessor(views::Widget* owner) : owner_(owner) {
+ owner_->AddObserver(this);
+ }
+
+ virtual ~PostMousePressedProcessor() {
+ if (owner_) {
+ owner_->RemoveObserver(this);
+ owner_ = NULL;
+ }
+ }
+
+ void DoPostMousePressedProcessing() {
+ // Make sure we're still visible before we attempt capture as the mouse
+ // press processing may have made the window hide (as happens with menus).
+ if (!owner_ || !owner_->IsVisible())
+ return;
+
+ owner_->set_is_mouse_button_pressed(true);
+
+ // OnNativeWidgetDestroying also notifies all
+ // WidgetObservers::OnWidgetDestroying. So we can be sure that if |owner_|
+ // is non-NULL, |owner_->native_widget_| will also be non-NULL.
+ if (!owner_->native_widget_private()->HasCapture())
+ owner_->native_widget_private()->SetCapture();
+ }
+
+ // Overridden from WidgetObserver.
+ virtual void OnWidgetDestroying(Widget* widget) OVERRIDE {
+ if (owner_) {
sky 2013/03/21 22:17:48 Consolidate this and 71-74.
varunjain 2013/03/21 22:47:14 Done.
+ owner_->RemoveObserver(this);
+ owner_ = NULL;
+ }
+ }
+
+ private:
+ views::Widget* owner_;
+
+ DISALLOW_COPY_AND_ASSIGN(PostMousePressedProcessor);
+};
+
} // namespace
// This class is used to keep track of the event a Widget is processing, and
@@ -1143,17 +1185,18 @@ void Widget::OnMouseEvent(ui::MouseEvent* event) {
ScopedEvent scoped(this, *event);
View* root_view = GetRootView();
switch (event->type()) {
- case ui::ET_MOUSE_PRESSED:
+ case ui::ET_MOUSE_PRESSED: {
last_mouse_event_was_move_ = false;
- // Make sure we're still visible before we attempt capture as the mouse
- // press processing may have made the window hide (as happens with menus).
- if (root_view && root_view->OnMousePressed(*event) && IsVisible()) {
- is_mouse_button_pressed_ = true;
- if (!native_widget_->HasCapture())
- native_widget_->SetCapture();
+
+ // We may get deleted by the time we return from OnMousePressed. So we
+ // use an observer to do capture after OnMousePressed in a safe way.
+ PostMousePressedProcessor post_mouse_pressed_processor(this);
+ if (root_view && root_view->OnMousePressed(*event)) {
+ post_mouse_pressed_processor.DoPostMousePressedProcessing();
event->SetHandled();
}
return;
+ }
case ui::ET_MOUSE_RELEASED:
last_mouse_event_was_move_ = false;
is_mouse_button_pressed_ = false;
« no previous file with comments | « ui/views/widget/widget.h ('k') | ui/views/widget/widget_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698