diff options
author | msw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-31 20:38:03 +0000 |
---|---|---|
committer | msw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-31 20:38:03 +0000 |
commit | 66e5af67ff42c6db608aad2bc87393c468c8a642 (patch) | |
tree | 7ba907d99e1c86e0680ef8e4282cc9973a2d36bd /views/widget | |
parent | 5332b834259dbab2ebbefba1944824df469139d4 (diff) | |
download | chromium_src-66e5af67ff42c6db608aad2bc87393c468c8a642.zip chromium_src-66e5af67ff42c6db608aad2bc87393c468c8a642.tar.gz chromium_src-66e5af67ff42c6db608aad2bc87393c468c8a642.tar.bz2 |
Consolidate Widget Event code, other cleanup.
Rename *NativeCapture to *MouseCapture.
Rename and move ShouldReleaseCaptureOnMouseReleased.
Move static flag function to Event.
BUG=72040
TEST=Mouse interaction on win & linux_views.
Review URL: http://codereview.chromium.org/6756043
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@80065 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views/widget')
-rw-r--r-- | views/widget/aero_tooltip_manager.cc | 13 | ||||
-rw-r--r-- | views/widget/aero_tooltip_manager.h | 1 | ||||
-rw-r--r-- | views/widget/native_widget.h | 6 | ||||
-rw-r--r-- | views/widget/native_widget_delegate.h | 4 | ||||
-rw-r--r-- | views/widget/root_view.cc | 2 | ||||
-rw-r--r-- | views/widget/tooltip_manager_win.h | 4 | ||||
-rw-r--r-- | views/widget/widget.cc | 54 | ||||
-rw-r--r-- | views/widget/widget.h | 16 | ||||
-rw-r--r-- | views/widget/widget_gtk.cc | 209 | ||||
-rw-r--r-- | views/widget/widget_gtk.h | 35 | ||||
-rw-r--r-- | views/widget/widget_win.cc | 201 | ||||
-rw-r--r-- | views/widget/widget_win.h | 49 |
12 files changed, 189 insertions, 405 deletions
diff --git a/views/widget/aero_tooltip_manager.cc b/views/widget/aero_tooltip_manager.cc index 8a5caca..8cc6821 100644 --- a/views/widget/aero_tooltip_manager.cc +++ b/views/widget/aero_tooltip_manager.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -28,6 +28,12 @@ AeroTooltipManager::~AeroTooltipManager() { } void AeroTooltipManager::OnMouse(UINT u_msg, WPARAM w_param, LPARAM l_param) { + if (u_msg == WM_MOUSELEAVE) { + last_mouse_pos_.SetPoint(-1, -1); + UpdateTooltip(); + return; + } + if (initial_timer_) initial_timer_->Disown(); @@ -62,11 +68,6 @@ void AeroTooltipManager::OnMouse(UINT u_msg, WPARAM w_param, LPARAM l_param) { } } -void AeroTooltipManager::OnMouseLeave() { - last_mouse_pos_.SetPoint(-1, -1); - UpdateTooltip(); -} - /////////////////////////////////////////////////////////////////////////////// // AeroTooltipManager, private: diff --git a/views/widget/aero_tooltip_manager.h b/views/widget/aero_tooltip_manager.h index abdb54bc..025e428 100644 --- a/views/widget/aero_tooltip_manager.h +++ b/views/widget/aero_tooltip_manager.h @@ -33,7 +33,6 @@ class AeroTooltipManager : public TooltipManagerWin { virtual ~AeroTooltipManager(); virtual void OnMouse(UINT u_msg, WPARAM w_param, LPARAM l_param); - virtual void OnMouseLeave(); private: void Init(); diff --git a/views/widget/native_widget.h b/views/widget/native_widget.h index b362453..089cfb3 100644 --- a/views/widget/native_widget.h +++ b/views/widget/native_widget.h @@ -70,11 +70,11 @@ class NativeWidget { virtual bool IsScreenReaderActive() const = 0; // Sets or releases event capturing for this native widget. - virtual void SetNativeCapture() = 0; - virtual void ReleaseNativeCapture() = 0; + virtual void SetMouseCapture() = 0; + virtual void ReleaseMouseCapture() = 0; // Returns true if this native widget is capturing all events. - virtual bool HasNativeCapture() const = 0; + virtual bool HasMouseCapture() const = 0; protected: friend class Widget; diff --git a/views/widget/native_widget_delegate.h b/views/widget/native_widget_delegate.h index 26e4828..e5e3752 100644 --- a/views/widget/native_widget_delegate.h +++ b/views/widget/native_widget_delegate.h @@ -40,6 +40,10 @@ class NativeWidgetDelegate { // Paints the rootview in the canvas. This will also refresh the compositor // tree if necessary when accelerated painting is enabled. virtual void OnNativeWidgetPaint(gfx::Canvas* canvas) = 0; + + // MouseEvent handlers. + virtual bool OnMouseEvent(const MouseEvent& event) = 0; + virtual void OnMouseCaptureLost() = 0; }; } // namespace internal diff --git a/views/widget/root_view.cc b/views/widget/root_view.cc index aae04b7..323612e 100644 --- a/views/widget/root_view.cc +++ b/views/widget/root_view.cc @@ -271,7 +271,7 @@ void RootView::OnMouseReleased(const MouseEvent& event) { void RootView::OnMouseCaptureLost() { if (mouse_pressed_handler_) { - // Synthesize a release event for UpdateCursor and OnMouseReleased. + // Synthesize a release event for UpdateCursor. MouseEvent release_event(ui::ET_MOUSE_RELEASED, last_mouse_event_x_, last_mouse_event_y_, last_mouse_event_flags_); UpdateCursor(release_event); diff --git a/views/widget/tooltip_manager_win.h b/views/widget/tooltip_manager_win.h index add4531..d6a9a35 100644 --- a/views/widget/tooltip_manager_win.h +++ b/views/widget/tooltip_manager_win.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -77,8 +77,6 @@ class TooltipManagerWin : public TooltipManager { // Message handlers. These forward to the tooltip control. virtual void OnMouse(UINT u_msg, WPARAM w_param, LPARAM l_param); LRESULT OnNotify(int w_param, NMHDR* l_param, bool* handled); - // Not used directly by TooltipManager, but provided for AeroTooltipManager. - virtual void OnMouseLeave() {} protected: virtual void Init(); diff --git a/views/widget/widget.cc b/views/widget/widget.cc index 65382c4..09a9eb3 100644 --- a/views/widget/widget.cc +++ b/views/widget/widget.cc @@ -47,7 +47,9 @@ Widget::CreateParams::CreateParams(Type type) // Widget, public: Widget::Widget() - : native_widget_(NULL), + : is_mouse_button_pressed_(false), + last_mouse_event_was_move_(false), + native_widget_(NULL), widget_delegate_(NULL), dragged_view_(NULL) { } @@ -303,6 +305,56 @@ void Widget::OnNativeWidgetPaint(gfx::Canvas* canvas) { RefreshCompositeTree(); } +bool Widget::OnMouseEvent(const MouseEvent& event) { + switch (event.type()) { + case ui::ET_MOUSE_PRESSED: + last_mouse_event_was_move_ = false; + if (GetRootView()->OnMousePressed(event)) { + is_mouse_button_pressed_ = true; + if (!native_widget_->HasMouseCapture()) + native_widget_->SetMouseCapture(); + return true; + } + return false; + case ui::ET_MOUSE_RELEASED: + last_mouse_event_was_move_ = false; + is_mouse_button_pressed_ = false; + // Release capture first, to avoid confusion if OnMouseReleased blocks. + if (native_widget_->HasMouseCapture() && + ShouldReleaseCaptureOnMouseReleased()) { + native_widget_->ReleaseMouseCapture(); + } + GetRootView()->OnMouseReleased(event); + return (event.flags() & ui::EF_IS_NON_CLIENT) ? false : true; + case ui::ET_MOUSE_MOVED: + case ui::ET_MOUSE_DRAGGED: + if (native_widget_->HasMouseCapture() && is_mouse_button_pressed_) { + last_mouse_event_was_move_ = false; + GetRootView()->OnMouseDragged(event); + } else if (!last_mouse_event_was_move_ || + last_mouse_event_position_ != event.location()) { + last_mouse_event_position_ = event.location(); + last_mouse_event_was_move_ = true; + GetRootView()->OnMouseMoved(event); + } + return false; + case ui::ET_MOUSE_EXITED: + last_mouse_event_was_move_ = false; + GetRootView()->OnMouseExited(event); + return false; + default: + return false; + } + return true; +} + +void Widget::OnMouseCaptureLost() { + if (is_mouse_button_pressed_) + GetRootView()->OnMouseCaptureLost(); + is_mouse_button_pressed_ = false; +} + + //////////////////////////////////////////////////////////////////////////////// // Widget, FocusTraversable implementation: diff --git a/views/widget/widget.h b/views/widget/widget.h index b0e22a3..eb61361 100644 --- a/views/widget/widget.h +++ b/views/widget/widget.h @@ -274,6 +274,8 @@ class Widget : public internal::NativeWidgetDelegate, virtual void OnSizeChanged(const gfx::Size& new_size) OVERRIDE; virtual bool HasFocusManager() const OVERRIDE; virtual void OnNativeWidgetPaint(gfx::Canvas* canvas) OVERRIDE; + virtual bool OnMouseEvent(const MouseEvent& event) OVERRIDE; + virtual void OnMouseCaptureLost() OVERRIDE; // Overridden from FocusTraversable: virtual FocusSearch* GetFocusSearch() OVERRIDE; @@ -300,6 +302,17 @@ class Widget : public internal::NativeWidgetDelegate, // Used for testing. void ReplaceFocusManager(FocusManager* focus_manager); + // TODO(msw): Make this mouse state member private. + // If true, the mouse is currently down. + bool is_mouse_button_pressed_; + + // TODO(msw): Make these mouse state members private. + // The following are used to detect duplicate mouse move events and not + // deliver them. Displaying a window may result in the system generating + // duplicate move events even though the mouse hasn't moved. + bool last_mouse_event_was_move_; + gfx::Point last_mouse_event_position_; + private: // Refresh the compositor tree. This is called by a View whenever its texture // is updated. @@ -309,6 +322,9 @@ class Widget : public internal::NativeWidgetDelegate, // a compositor couldn't be created. bool EnsureCompositor(); + // Returns whether capture should be released on mouse release. + virtual bool ShouldReleaseCaptureOnMouseReleased() const { return true; } + NativeWidget* native_widget_; // Non-owned pointer to the Widget's delegate. May be NULL if no delegate is diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc index 3014b5c..1be51c9 100644 --- a/views/widget/widget_gtk.cc +++ b/views/widget/widget_gtk.cc @@ -267,8 +267,6 @@ WidgetGtk::WidgetGtk(Type type) type_(type), widget_(NULL), window_contents_(NULL), - is_mouse_down_(false), - last_mouse_event_was_move_(false), ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), delete_on_destroy_(true), transparent_(false), @@ -314,9 +312,9 @@ void WidgetGtk::SetCreateParams(const CreateParams& params) { if (params.type == CreateParams::TYPE_MENU) { GdkEvent* event = gtk_get_current_event(); if (event) { - is_mouse_down_ = event->type == GDK_BUTTON_PRESS || - event->type == GDK_2BUTTON_PRESS || - event->type == GDK_3BUTTON_PRESS; + is_mouse_button_pressed_ = event->type == GDK_BUTTON_PRESS || + event->type == GDK_2BUTTON_PRESS || + event->type == GDK_3BUTTON_PRESS; gdk_event_free(event); } } @@ -701,28 +699,6 @@ bool WidgetGtk::HandleKeyboardEvent(GdkEventKey* event) { } // static -int WidgetGtk::GetFlagsForEventButton(const GdkEventButton& event) { - int flags = Event::GetFlagsFromGdkState(event.state); - switch (event.button) { - case 1: - flags |= ui::EF_LEFT_BUTTON_DOWN; - break; - case 2: - flags |= ui::EF_MIDDLE_BUTTON_DOWN; - break; - case 3: - flags |= ui::EF_RIGHT_BUTTON_DOWN; - break; - default: - // We only deal with 1-3. - break; - } - if (event.type == GDK_2BUTTON_PRESS) - flags |= ui::EF_IS_DOUBLE_CLICK; - return flags; -} - -// static void WidgetGtk::EnableDebugPaint() { debug_paint_enabled_ = true; } @@ -776,17 +752,17 @@ bool WidgetGtk::IsScreenReaderActive() const { return false; } -void WidgetGtk::SetNativeCapture() { - DCHECK(!HasNativeCapture()); +void WidgetGtk::SetMouseCapture() { + DCHECK(!HasMouseCapture()); gtk_grab_add(window_contents_); } -void WidgetGtk::ReleaseNativeCapture() { - if (HasNativeCapture()) +void WidgetGtk::ReleaseMouseCapture() { + if (HasMouseCapture()) gtk_grab_remove(window_contents_); } -bool WidgetGtk::HasNativeCapture() const { +bool WidgetGtk::HasMouseCapture() const { // TODO(beng): Should be able to use gtk_widget_has_grab() here but the // trybots don't have Gtk 2.18. return GTK_WIDGET_HAS_GRAB(window_contents_); @@ -1110,38 +1086,29 @@ gboolean WidgetGtk::OnDragMotion(GtkWidget* widget, } gboolean WidgetGtk::OnEnterNotify(GtkWidget* widget, GdkEventCrossing* event) { - if (last_mouse_event_was_move_ && last_mouse_move_x_ == event->x_root && - last_mouse_move_y_ == event->y_root) { - // Don't generate a mouse event for the same location as the last. - return false; - } - - if (HasNativeCapture() && event->mode == GDK_CROSSING_GRAB) { + if (HasMouseCapture() && event->mode == GDK_CROSSING_GRAB) { // Doing a grab results an async enter event, regardless of where the mouse // is. We don't want to generate a mouse move in this case. return false; } - if (!last_mouse_event_was_move_ && !is_mouse_down_) { + if (!last_mouse_event_was_move_ && !is_mouse_button_pressed_) { // When a mouse button is pressed gtk generates a leave, enter, press. // RootView expects to get a mouse move before a press, otherwise enter is // not set. So we generate a move here. - last_mouse_move_x_ = event->x_root; - last_mouse_move_y_ = event->y_root; - last_mouse_event_was_move_ = true; - int x = 0, y = 0; GetContainedWidgetEventCoordinates(event, &x, &y); + int flags = Event::GetFlagsFromGdkEvent(reinterpret_cast<GdkEvent*>(event)); // If this event is the result of pressing a button then one of the button // modifiers is set. Unset it as we're compensating for the leave generated // when you press a button. - int flags = (Event::GetFlagsFromGdkState(event->state) & - ~(ui::EF_LEFT_BUTTON_DOWN | - ui::EF_MIDDLE_BUTTON_DOWN | - ui::EF_RIGHT_BUTTON_DOWN)); + flags &= ~(ui::EF_LEFT_BUTTON_DOWN | + ui::EF_MIDDLE_BUTTON_DOWN | + ui::EF_RIGHT_BUTTON_DOWN); + MouseEvent mouse_move(ui::ET_MOUSE_MOVED, x, y, flags); - GetRootView()->OnMouseMoved(mouse_move); + delegate_->OnMouseEvent(mouse_move); } return false; @@ -1149,9 +1116,9 @@ gboolean WidgetGtk::OnEnterNotify(GtkWidget* widget, GdkEventCrossing* event) { gboolean WidgetGtk::OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event) { last_mouse_event_was_move_ = false; - if (!HasNativeCapture() && !is_mouse_down_) { + if (!HasMouseCapture() && !is_mouse_button_pressed_) { MouseEvent mouse_event(reinterpret_cast<GdkEvent*>(event)); - GetRootView()->OnMouseExited(mouse_event); + delegate_->OnMouseEvent(mouse_event); } return false; } @@ -1159,40 +1126,63 @@ gboolean WidgetGtk::OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event) { gboolean WidgetGtk::OnMotionNotify(GtkWidget* widget, GdkEventMotion* event) { int x = 0, y = 0; GetContainedWidgetEventCoordinates(event, &x, &y); - - if (HasNativeCapture() && is_mouse_down_) { - last_mouse_event_was_move_ = false; - int flags = Event::GetFlagsFromGdkState(event->state); - MouseEvent mouse_drag(ui::ET_MOUSE_DRAGGED, x, y, flags); - GetRootView()->OnMouseDragged(mouse_drag); - return true; - } - gfx::Point screen_loc(event->x_root, event->y_root); - if (last_mouse_event_was_move_ && last_mouse_move_x_ == screen_loc.x() && - last_mouse_move_y_ == screen_loc.y()) { - // Don't generate a mouse event for the same location as the last. - return true; - } - last_mouse_move_x_ = screen_loc.x(); - last_mouse_move_y_ = screen_loc.y(); - last_mouse_event_was_move_ = true; - int flags = Event::GetFlagsFromGdkState(event->state); - MouseEvent mouse_move(ui::ET_MOUSE_MOVED, x, y, flags); - GetRootView()->OnMouseMoved(mouse_move); + int flags = Event::GetFlagsFromGdkEvent(reinterpret_cast<GdkEvent*>(event)); + MouseEvent mouse_event((HasMouseCapture() && is_mouse_button_pressed_) ? + ui::ET_MOUSE_DRAGGED : ui::ET_MOUSE_MOVED, x, y, flags); + delegate_->OnMouseEvent(mouse_event); return true; } gboolean WidgetGtk::OnButtonPress(GtkWidget* widget, GdkEventButton* event) { - return ProcessMousePressed(event); + if (event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS) { + // The sequence for double clicks is press, release, press, 2press, release. + // This means that at the time we get the second 'press' we don't know + // whether it corresponds to a double click or not. For now we're completely + // ignoring the 2press/3press events as they are duplicate. To make this + // work right we need to write our own code that detects if the press is a + // double/triple. For now we're completely punting, which means we always + // get single clicks. + // TODO: fix this. + return true; + } + + // An event may come from a contained widget which has its own gdk window. + // Translate it to the widget's coordinates. + int x = 0, y = 0; + GetContainedWidgetEventCoordinates(event, &x, &y); + int flags = Event::GetFlagsFromGdkEvent(reinterpret_cast<GdkEvent*>(event)); + MouseEvent mouse_pressed(ui::ET_MOUSE_PRESSED, x, y, flags); + + // Returns true to consume the event when widget is not transparent. + return delegate_->OnMouseEvent(mouse_pressed) || !transparent_; } gboolean WidgetGtk::OnButtonRelease(GtkWidget* widget, GdkEventButton* event) { - ProcessMouseReleased(event); + // GTK generates a mouse release at the end of dnd. We need to ignore it. + if (drag_data_) + return true; + + // An event may come from a contained widget which has its own gdk window. + // Translate it to the widget's coordinates. + int x = 0, y = 0; + GetContainedWidgetEventCoordinates(event, &x, &y); + int flags = Event::GetFlagsFromGdkEvent(reinterpret_cast<GdkEvent*>(event)); + MouseEvent mouse_up(ui::ET_MOUSE_RELEASED, x, y, flags); + delegate_->OnMouseEvent(mouse_up); return true; } gboolean WidgetGtk::OnScroll(GtkWidget* widget, GdkEventScroll* event) { - return ProcessScroll(event); + // An event may come from a contained widget which has its own gdk window. + // Translate it to the widget's coordinates. + int x = 0, y = 0; + GetContainedWidgetEventCoordinates(event, &x, &y); + GdkEventScroll translated_event = *event; + translated_event.x = x; + translated_event.y = y; + + MouseWheelEvent wheel_event(reinterpret_cast<GdkEvent*>(&translated_event)); + return GetRootView()->OnMouseWheel(wheel_event); } gboolean WidgetGtk::OnFocusIn(GtkWidget* widget, GdkEventFocus* event) { @@ -1325,17 +1315,11 @@ void WidgetGtk::OnMap(GtkWidget* widget) { void WidgetGtk::OnHide(GtkWidget* widget) { } -bool WidgetGtk::ReleaseCaptureOnMouseReleased() { - return true; -} - void WidgetGtk::HandleXGrabBroke() { } void WidgetGtk::HandleGtkGrabBroke() { - if (is_mouse_down_) - GetRootView()->OnMouseCaptureLost(); - is_mouse_down_ = false; + delegate_->OnMouseCaptureLost(); } //////////////////////////////////////////////////////////////////////////////// @@ -1358,69 +1342,6 @@ gboolean WidgetGtk::OnWindowPaint(GtkWidget* widget, GdkEventExpose* event) { return false; } -bool WidgetGtk::ProcessMousePressed(GdkEventButton* event) { - if (event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS) { - // The sequence for double clicks is press, release, press, 2press, release. - // This means that at the time we get the second 'press' we don't know - // whether it corresponds to a double click or not. For now we're completely - // ignoring the 2press/3press events as they are duplicate. To make this - // work right we need to write our own code that detects if the press is a - // double/triple. For now we're completely punting, which means we always - // get single clicks. - // TODO: fix this. - return true; - } - - // An event may come from a contained widget which has its own gdk window. - // Translate it to the widget's coordinates. - int x = 0; - int y = 0; - GetContainedWidgetEventCoordinates(event, &x, &y); - last_mouse_event_was_move_ = false; - MouseEvent mouse_pressed(ui::ET_MOUSE_PRESSED, x, y, - GetFlagsForEventButton(*event)); - - if (GetRootView()->OnMousePressed(mouse_pressed)) { - is_mouse_down_ = true; - if (!HasNativeCapture()) - SetNativeCapture(); - return true; - } - - // Returns true to consume the event when widget is not transparent. - return !transparent_; -} - -void WidgetGtk::ProcessMouseReleased(GdkEventButton* event) { - int x = 0, y = 0; - GetContainedWidgetEventCoordinates(event, &x, &y); - - last_mouse_event_was_move_ = false; - MouseEvent mouse_up(ui::ET_MOUSE_RELEASED, x, y, - GetFlagsForEventButton(*event)); - // Release the capture first, that way we don't get confused if - // OnMouseReleased blocks. - if (HasNativeCapture() && ReleaseCaptureOnMouseReleased()) - ReleaseNativeCapture(); - is_mouse_down_ = false; - // GTK generates a mouse release at the end of dnd. We need to ignore it. - if (!drag_data_) - GetRootView()->OnMouseReleased(mouse_up); -} - -bool WidgetGtk::ProcessScroll(GdkEventScroll* event) { - // An event may come from a contained widget which has its own gdk window. - // Translate it to the widget's coordinates. - int x = 0, y = 0; - GetContainedWidgetEventCoordinates(event, &x, &y); - GdkEventScroll translated_event = *event; - translated_event.x = x; - translated_event.y = y; - - MouseWheelEvent wheel_event(reinterpret_cast<GdkEvent*>(&translated_event)); - return GetRootView()->OnMouseWheel(wheel_event); -} - // static Window* WidgetGtk::GetWindowImpl(GtkWidget* widget) { GtkWidget* parent = widget; diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h index 1bb4adc..9ddc0a4 100644 --- a/views/widget/widget_gtk.h +++ b/views/widget/widget_gtk.h @@ -173,9 +173,6 @@ class WidgetGtk : public Widget, // Returns true if it's handled by the focus manager. bool HandleKeyboardEvent(GdkEventKey* event); - // Returns the view::Event::flags for a GdkEventButton. - static int GetFlagsForEventButton(const GdkEventButton& event); - // Enables debug painting. See |debug_paint_enabled_| for details. static void EnableDebugPaint(); @@ -196,9 +193,9 @@ class WidgetGtk : public Widget, virtual void* GetNativeWindowProperty(const char* name) OVERRIDE; virtual TooltipManager* GetTooltipManager() const OVERRIDE; virtual bool IsScreenReaderActive() const OVERRIDE; - virtual void SetNativeCapture() OVERRIDE; - virtual void ReleaseNativeCapture() OVERRIDE; - virtual bool HasNativeCapture() const OVERRIDE; + virtual void SetMouseCapture() OVERRIDE; + virtual void ReleaseMouseCapture() OVERRIDE; + virtual bool HasMouseCapture() const OVERRIDE; virtual gfx::Rect GetWindowScreenBounds() const OVERRIDE; virtual gfx::Rect GetClientAreaScreenBounds() const OVERRIDE; virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE; @@ -279,12 +276,6 @@ class WidgetGtk : public Widget, CHROMEGTK_CALLBACK_0(WidgetGtk, void, OnMap); CHROMEGTK_CALLBACK_0(WidgetGtk, void, OnHide); - void set_mouse_down(bool mouse_down) { is_mouse_down_ = mouse_down; } - - // Returns whether capture should be released on mouse release. The default - // is true. - virtual bool ReleaseCaptureOnMouseReleased(); - // Invoked when gtk grab is stolen by other GtkWidget in the same // application. virtual void HandleGtkGrabBroke(); @@ -308,12 +299,6 @@ class WidgetGtk : public Widget, CHROMEGTK_CALLBACK_1(WidgetGtk, gboolean, OnWindowPaint, GdkEventExpose*); - // Process a mouse click. - bool ProcessMousePressed(GdkEventButton* event); - void ProcessMouseReleased(GdkEventButton* event); - // Process scroll event. - bool ProcessScroll(GdkEventScroll* event); - // Returns the first ancestor of |widget| that is a window. static Window* GetWindowImpl(GtkWidget* widget); @@ -357,20 +342,6 @@ class WidgetGtk : public Widget, scoped_ptr<DropTargetGtk> drop_target_; - // If true, the mouse is currently down. - bool is_mouse_down_; - - // The following are used to detect duplicate mouse move events and not - // deliver them. Displaying a window may result in the system generating - // duplicate move events even though the mouse hasn't moved. - - // If true, the last event was a mouse move event. - bool last_mouse_event_was_move_; - - // Coordinates of the last mouse move event, in screen coordinates. - int last_mouse_move_x_; - int last_mouse_move_y_; - // The following factory is used to delay destruction. ScopedRunnableMethodFactory<WidgetGtk> close_widget_factory_; diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc index f0a43c5..4c8b974 100644 --- a/views/widget/widget_win.cc +++ b/views/widget/widget_win.cc @@ -139,8 +139,6 @@ WidgetWin::WidgetWin() ALLOW_THIS_IN_INITIALIZER_LIST(paint_layered_window_factory_(this)), delete_on_destroy_(true), can_update_layered_window_(true), - last_mouse_event_was_move_(false), - is_mouse_down_(false), is_window_(false), restore_focus_when_enabled_(false), accessibility_view_events_index_(-1), @@ -190,7 +188,7 @@ void WidgetWin::SetCreateParams(const CreateParams& params) { break; case CreateParams::TYPE_MENU: style |= WS_POPUP; - is_mouse_down_ = + is_mouse_button_pressed_ = ((GetKeyState(VK_LBUTTON) & 0x80) || (GetKeyState(VK_RBUTTON) & 0x80) || (GetKeyState(VK_MBUTTON) & 0x80) || @@ -322,16 +320,16 @@ bool WidgetWin::IsScreenReaderActive() const { return screen_reader_active_; } -void WidgetWin::SetNativeCapture() { - DCHECK(!HasNativeCapture()); +void WidgetWin::SetMouseCapture() { + DCHECK(!HasMouseCapture()); SetCapture(hwnd()); } -void WidgetWin::ReleaseNativeCapture() { +void WidgetWin::ReleaseMouseCapture() { ReleaseCapture(); } -bool WidgetWin::HasNativeCapture() const { +bool WidgetWin::HasMouseCapture() const { return GetCapture() == hwnd(); } @@ -566,9 +564,7 @@ void WidgetWin::OnCancelMode() { } void WidgetWin::OnCaptureChanged(HWND hwnd) { - if (is_mouse_down_) - GetRootView()->OnMouseCaptureLost(); - is_mouse_down_ = false; + delegate_->OnMouseCaptureLost(); } void WidgetWin::OnClose() { @@ -718,8 +714,7 @@ LRESULT WidgetWin::OnKeyDown(UINT message, WPARAM w_param, LPARAM l_param) { if (!root_view) root_view = GetRootView(); - MSG msg; - MakeMSG(&msg, message, w_param, l_param); + MSG msg = { hwnd(), message, w_param, l_param }; SetMsgHandled(root_view->ProcessKeyEvent(KeyEvent(msg))); return 0; } @@ -729,8 +724,7 @@ LRESULT WidgetWin::OnKeyUp(UINT message, WPARAM w_param, LPARAM l_param) { if (!root_view) root_view = GetRootView(); - MSG msg; - MakeMSG(&msg, message, w_param, l_param); + MSG msg = { hwnd(), message, w_param, l_param }; SetMsgHandled(root_view->ProcessKeyEvent(KeyEvent(msg))); return 0; } @@ -749,42 +743,35 @@ LRESULT WidgetWin::OnMouseActivate(UINT message, return MA_ACTIVATE; } -LRESULT WidgetWin::OnMouseLeave(UINT message, WPARAM w_param, LPARAM l_param) { - tooltip_manager_->OnMouseLeave(); - ProcessMouseExited(message, w_param, l_param); - return 0; -} +LRESULT WidgetWin::OnMouseRange(UINT message, WPARAM w_param, LPARAM l_param) { + if (message == WM_MOUSEWHEEL) + return 0; -LRESULT WidgetWin::OnMouseMove(UINT message, WPARAM w_param, LPARAM l_param) { - ProcessMouseMoved(message, w_param, l_param); - return 0; -} + MSG msg = { hwnd(), message, w_param, l_param, 0, + { GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param) } }; + MouseEvent event(msg); -LRESULT WidgetWin::OnMouseRange(UINT message, WPARAM w_param, LPARAM l_param) { - tooltip_manager_->OnMouse(message, w_param, l_param); + if (!(event.flags() & ui::EF_IS_NON_CLIENT)) + tooltip_manager_->OnMouse(message, w_param, l_param); - switch (message) { - case WM_LBUTTONDBLCLK: - case WM_LBUTTONDOWN: - case WM_MBUTTONDBLCLK: - case WM_MBUTTONDOWN: - case WM_RBUTTONDBLCLK: - case WM_RBUTTONDOWN: - SetMsgHandled(ProcessMousePressed(message, w_param, l_param)); - break; - case WM_LBUTTONUP: - case WM_MBUTTONUP: - case WM_RBUTTONUP: - SetMsgHandled(ProcessMouseReleased(message, w_param, l_param)); - break; - default: - SetMsgHandled(FALSE); + if (event.type() == ui::ET_MOUSE_MOVED && !HasMouseCapture()) { + // Windows only fires WM_MOUSELEAVE events if the application begins + // "tracking" mouse events for a given HWND during WM_MOUSEMOVE events. + // We need to call |TrackMouseEvents| to listen for WM_MOUSELEAVE. + TrackMouseEvents((message == WM_NCMOUSEMOVE) ? + TME_NONCLIENT | TME_LEAVE : TME_LEAVE); + } else if (event.type() == ui::ET_MOUSE_EXITED) { + // Reset our tracking flags so future mouse movement over this WidgetWin + // results in a new tracking session. Fall through for OnMouseEvent. + active_mouse_tracking_flags_ = 0; } + SetMsgHandled(delegate_->OnMouseEvent(event)); return 0; } LRESULT WidgetWin::OnMouseWheel(UINT message, WPARAM w_param, LPARAM l_param) { + tooltip_manager_->OnMouse(message, w_param, l_param); // Reroute the mouse-wheel to the window under the mouse pointer if // applicable. if (message == WM_MOUSEWHEEL && @@ -792,9 +779,8 @@ LRESULT WidgetWin::OnMouseWheel(UINT message, WPARAM w_param, LPARAM l_param) { return 0; } - MSG msg; - MakeMSG(&msg, message, w_param, l_param, 0, - GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param)); + MSG msg = { hwnd(), message, w_param, l_param, 0, + { GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param) } }; return GetRootView()->OnMouseWheel(MouseWheelEvent(msg)) ? 0 : 1; } @@ -824,45 +810,6 @@ LRESULT WidgetWin::OnNCHitTest(const CPoint& pt) { return 0; } -LRESULT WidgetWin::OnNCMouseLeave(UINT message, - WPARAM w_param, - LPARAM l_param) { - ProcessMouseExited(message, w_param, l_param); - return 0; -} - -LRESULT WidgetWin::OnNCMouseMove(UINT message, WPARAM w_param, LPARAM l_param) { - tooltip_manager_->OnMouse(message, w_param, l_param); - ProcessMouseMoved(message, w_param, l_param); - - // We need to process this message to stop Windows from drawing the window - // controls as the mouse moves over the title bar area when the window is - // maximized. - return 0; -} - -LRESULT WidgetWin::OnNCMouseRange(UINT message, - WPARAM w_param, - LPARAM l_param) { - switch (message) { - case WM_NCLBUTTONDBLCLK: - case WM_NCLBUTTONDOWN: - case WM_NCMBUTTONDBLCLK: - case WM_NCMBUTTONDOWN: - case WM_NCRBUTTONDBLCLK: - case WM_NCRBUTTONDOWN: - SetMsgHandled(ProcessMousePressed(message, w_param, l_param)); - break; - case WM_NCLBUTTONUP: - case WM_NCMBUTTONUP: - case WM_NCRBUTTONUP: - default: - SetMsgHandled(FALSE); - } - - return 0; -} - void WidgetWin::OnNCPaint(HRGN rgn) { SetMsgHandled(FALSE); } @@ -993,87 +940,10 @@ void WidgetWin::TrackMouseEvents(DWORD mouse_tracking_flags) { } } -bool WidgetWin::ProcessMousePressed(UINT message, - WPARAM w_param, - LPARAM l_param) { - last_mouse_event_was_move_ = false; - - MSG msg; - MakeMSG(&msg, message, w_param, l_param, 0, GET_X_LPARAM(l_param), - GET_Y_LPARAM(l_param)); - if (GetRootView()->OnMousePressed(MouseEvent(msg))) { - is_mouse_down_ = true; - if (!HasNativeCapture()) - SetNativeCapture(); - return true; - } - return false; -} - -bool WidgetWin::ProcessMouseReleased(UINT message, - WPARAM w_param, - LPARAM l_param) { - last_mouse_event_was_move_ = false; - is_mouse_down_ = false; - - // Release the capture first, that way we don't get confused if - // OnMouseReleased blocks. - if (HasNativeCapture() && ReleaseCaptureOnMouseReleased()) - ReleaseNativeCapture(); - - MSG msg; - MakeMSG(&msg, message, w_param, l_param, 0, GET_X_LPARAM(l_param), - GET_Y_LPARAM(l_param)); - GetRootView()->OnMouseReleased(MouseEvent(msg)); - return true; -} - -bool WidgetWin::ProcessMouseMoved(UINT message, - WPARAM w_param, - LPARAM l_param) { - // Windows only fires WM_MOUSELEAVE events if the application begins - // "tracking" mouse events for a given HWND during WM_MOUSEMOVE events. - // We need to call |TrackMouseEvents| to listen for WM_MOUSELEAVE. - if (!HasNativeCapture()) - TrackMouseEvents((message == WM_NCMOUSEMOVE) ? - TME_NONCLIENT | TME_LEAVE : TME_LEAVE); - MSG msg; - MakeMSG(&msg, message, w_param, l_param, 0, GET_X_LPARAM(l_param), - GET_Y_LPARAM(l_param)); - if (HasNativeCapture() && is_mouse_down_) - GetRootView()->OnMouseDragged(MouseEvent(msg)); - else if (!last_mouse_event_was_move_ || - (last_mouse_move_x_ != GET_X_LPARAM(l_param) || - last_mouse_move_y_ != GET_Y_LPARAM(l_param))) { - last_mouse_move_x_ = GET_X_LPARAM(l_param); - last_mouse_move_y_ = GET_Y_LPARAM(l_param); - last_mouse_event_was_move_ = true; - GetRootView()->OnMouseMoved(MouseEvent(msg)); - } - return true; -} - -void WidgetWin::ProcessMouseExited(UINT message, - WPARAM w_param, - LPARAM l_param) { - last_mouse_event_was_move_ = false; - MSG msg; - MakeMSG(&msg, message, w_param, l_param, 0, GET_X_LPARAM(l_param), - GET_Y_LPARAM(l_param)); - GetRootView()->OnMouseExited(MouseEvent(msg)); - // Reset our tracking flag so that future mouse movement over this WidgetWin - // results in a new tracking session. - active_mouse_tracking_flags_ = 0; -} - void WidgetWin::OnScreenReaderDetected() { screen_reader_active_ = true; } -bool WidgetWin::ReleaseCaptureOnMouseReleased() { - return true; -} - //////////////////////////////////////////////////////////////////////////////// // WidgetWin, private: @@ -1136,17 +1006,6 @@ void WidgetWin::PostProcessActivateMessage(WidgetWin* widget, } } -void WidgetWin::MakeMSG(MSG* msg, UINT message, WPARAM w_param, LPARAM l_param, - DWORD time, LONG x, LONG y) const { - msg->hwnd = hwnd(); - msg->message = message; - msg->wParam = w_param; - msg->lParam = l_param; - msg->time = time; - msg->pt.x = x; - msg->pt.y = y; -} - void WidgetWin::RedrawInvalidRect() { if (!use_layered_buffer_) { RECT r = { 0, 0, 0, 0 }; diff --git a/views/widget/widget_win.h b/views/widget/widget_win.h index 48ac644..53e5f50 100644 --- a/views/widget/widget_win.h +++ b/views/widget/widget_win.h @@ -206,9 +206,9 @@ class WidgetWin : public ui::WindowImpl, virtual void* GetNativeWindowProperty(const char* name) OVERRIDE; virtual TooltipManager* GetTooltipManager() const OVERRIDE; virtual bool IsScreenReaderActive() const OVERRIDE; - virtual void SetNativeCapture() OVERRIDE; - virtual void ReleaseNativeCapture() OVERRIDE; - virtual bool HasNativeCapture() const OVERRIDE; + virtual void SetMouseCapture() OVERRIDE; + virtual void ReleaseMouseCapture() OVERRIDE; + virtual bool HasMouseCapture() const OVERRIDE; virtual gfx::Rect GetWindowScreenBounds() const OVERRIDE; virtual gfx::Rect GetClientAreaScreenBounds() const OVERRIDE; virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE; @@ -246,7 +246,7 @@ class WidgetWin : public ui::WindowImpl, BEGIN_MSG_MAP_EX(WidgetWin) // Range handlers must go first! MESSAGE_RANGE_HANDLER_EX(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseRange) - MESSAGE_RANGE_HANDLER_EX(WM_NCMOUSEMOVE, WM_NCXBUTTONDBLCLK, OnNCMouseRange) + MESSAGE_RANGE_HANDLER_EX(WM_NCMOUSEMOVE, WM_NCXBUTTONDBLCLK, OnMouseRange) // Reflected message handler MESSAGE_HANDLER_EX(kReflectedMessage, OnReflectedMessage) @@ -263,11 +263,9 @@ class WidgetWin : public ui::WindowImpl, // Mouse events. MESSAGE_HANDLER_EX(WM_MOUSEACTIVATE, OnMouseActivate) - MESSAGE_HANDLER_EX(WM_MOUSELEAVE, OnMouseLeave) - MESSAGE_HANDLER_EX(WM_MOUSEMOVE, OnMouseMove) + MESSAGE_HANDLER_EX(WM_MOUSELEAVE, OnMouseRange) MESSAGE_HANDLER_EX(WM_MOUSEWHEEL, OnMouseWheel) - MESSAGE_HANDLER_EX(WM_NCMOUSELEAVE, OnNCMouseLeave) - MESSAGE_HANDLER_EX(WM_NCMOUSEMOVE, OnNCMouseMove) + MESSAGE_HANDLER_EX(WM_NCMOUSELEAVE, OnMouseRange) // Key events. MESSAGE_HANDLER_EX(WM_KEYDOWN, OnKeyDown) @@ -355,8 +353,6 @@ class WidgetWin : public ui::WindowImpl, virtual LRESULT OnKeyUp(UINT message, WPARAM w_param, LPARAM l_param); virtual void OnKillFocus(HWND focused_window); virtual LRESULT OnMouseActivate(UINT message, WPARAM w_param, LPARAM l_param); - virtual LRESULT OnMouseLeave(UINT message, WPARAM w_param, LPARAM l_param); - virtual LRESULT OnMouseMove(UINT message, WPARAM w_param, LPARAM l_param); virtual LRESULT OnMouseRange(UINT message, WPARAM w_param, LPARAM l_param); virtual LRESULT OnMouseWheel(UINT message, WPARAM w_param, LPARAM l_param); virtual void OnMove(const CPoint& point); @@ -364,9 +360,6 @@ class WidgetWin : public ui::WindowImpl, virtual LRESULT OnNCActivate(BOOL active); virtual LRESULT OnNCCalcSize(BOOL w_param, LPARAM l_param); virtual LRESULT OnNCHitTest(const CPoint& pt); - virtual LRESULT OnNCMouseLeave(UINT message, WPARAM w_param, LPARAM l_param); - virtual LRESULT OnNCMouseMove(UINT message, WPARAM w_param, LPARAM l_param); - virtual LRESULT OnNCMouseRange(UINT message, WPARAM w_param, LPARAM l_param); virtual void OnNCPaint(HRGN rgn); virtual LRESULT OnNCUAHDrawCaption(UINT msg, WPARAM w_param, @@ -395,21 +388,9 @@ class WidgetWin : public ui::WindowImpl, // messages too. void TrackMouseEvents(DWORD mouse_tracking_flags); - // Actually handle mouse events. These functions are called by subclasses who - // override the message handlers above to do the actual real work of handling - // the event in the View system. - bool ProcessMousePressed(UINT message, WPARAM w_param, LPARAM l_param); - bool ProcessMouseReleased(UINT message, WPARAM w_param, LPARAM l_param); - bool ProcessMouseMoved(UINT message, WPARAM w_param, LPARAM l_param); - void ProcessMouseExited(UINT message, WPARAM w_param, LPARAM l_param); - // Called when a MSAA screen reader client is detected. virtual void OnScreenReaderDetected(); - // Returns whether capture should be released on mouse release. The default - // is true. - virtual bool ReleaseCaptureOnMouseReleased(); - // The TooltipManager. // WARNING: RootView's destructor calls into the TooltipManager. As such, this // must be destroyed AFTER root_view_. @@ -417,9 +398,6 @@ class WidgetWin : public ui::WindowImpl, scoped_refptr<DropTargetWin> drop_target_; - // If true, the mouse is currently down. - bool is_mouse_down_; - // Are a subclass of WindowWin? bool is_window_; @@ -439,10 +417,6 @@ class WidgetWin : public ui::WindowImpl, static void PostProcessActivateMessage(WidgetWin* widget, int activation_state); - // Fills out a MSG struct with the supplied values. - void MakeMSG(MSG* msg, UINT message, WPARAM w_param, LPARAM l_param, - DWORD time = 0, LONG x = 0, LONG y = 0) const; - // Synchronously paints the invalid contents of the Widget. void RedrawInvalidRect(); @@ -504,17 +478,6 @@ class WidgetWin : public ui::WindowImpl, // store if necessary. bool can_update_layered_window_; - // The following are used to detect duplicate mouse move events and not - // deliver them. Displaying a window may result in the system generating - // duplicate move events even though the mouse hasn't moved. - - // If true, the last event was a mouse move event. - bool last_mouse_event_was_move_; - - // Coordinates of the last mouse move event. - int last_mouse_move_x_; - int last_mouse_move_y_; - // Whether the focus should be restored next time we get enabled. Needed to // restore focus correctly when Windows modal dialogs are displayed. bool restore_focus_when_enabled_; |