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

Unified Diff: views/widget/widget_win.cc

Issue 155343: Attempt at once-and-for-all fix for bug #2993 (Windows) (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 11 years, 5 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 | « views/widget/widget_win.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: views/widget/widget_win.cc
===================================================================
--- views/widget/widget_win.cc (revision 20614)
+++ views/widget/widget_win.cc (working copy)
@@ -144,10 +144,15 @@
delete_on_destroy_(true),
can_update_layered_window_(true),
last_mouse_event_was_move_(false),
+ mouse_buttons_are_swapped_(0 != GetSystemMetrics(SM_SWAPBUTTON)),
+ buttons_pressed_(0),
+ released_buttons_out_of_order_(0),
is_mouse_down_(false),
is_window_(false),
class_style_(CS_DBLCLKS),
hwnd_(NULL) {
+ left_button_code_ = mouse_buttons_are_swapped_ ? VK_RBUTTON : VK_LBUTTON;
+ right_button_code_ = mouse_buttons_are_swapped_ ? VK_LBUTTON : VK_RBUTTON;
}
WidgetWin::~WidgetWin() {
@@ -616,11 +621,21 @@
}
void WidgetWin::OnLButtonDown(UINT flags, const CPoint& point) {
- ProcessMousePressed(point, flags | MK_LBUTTON, false, false);
+ // Clear out-of-order release flag in case the "button released" event
+ // was truly completely swallowed.
+ released_buttons_out_of_order_ &= ~left_button_code_;
+ if (ProcessMousePressed(point, flags | MK_LBUTTON, false, false))
+ buttons_pressed_ |= left_button_code_;
}
void WidgetWin::OnLButtonUp(UINT flags, const CPoint& point) {
- ProcessMouseReleased(point, flags | MK_LBUTTON);
+ // If we already generated the event for this button out of order,
+ // avoid doing it twice.
+ if (0 == (released_buttons_out_of_order_ & left_button_code_)) {
+ ProcessMouseReleased(point, flags | MK_LBUTTON);
+ }
+ released_buttons_out_of_order_ &= ~left_button_code_;
+ buttons_pressed_ &= ~left_button_code_;
}
void WidgetWin::OnLButtonDblClk(UINT flags, const CPoint& point) {
@@ -628,11 +643,21 @@
}
void WidgetWin::OnMButtonDown(UINT flags, const CPoint& point) {
- ProcessMousePressed(point, flags | MK_MBUTTON, false, false);
+ // Clear out-of-order release flag in case the "button released" event
+ // was truly completely swallowed.
+ released_buttons_out_of_order_ &= ~VK_MBUTTON;
+ if (ProcessMousePressed(point, flags | MK_MBUTTON, false, false))
+ buttons_pressed_ |= VK_MBUTTON;
}
void WidgetWin::OnMButtonUp(UINT flags, const CPoint& point) {
- ProcessMouseReleased(point, flags | MK_MBUTTON);
+ // If we already generated the event for this button out of order,
+ // avoid doing it twice.
+ if (0 == (released_buttons_out_of_order_ & VK_MBUTTON)) {
+ ProcessMouseReleased(point, flags | MK_MBUTTON);
+ }
+ released_buttons_out_of_order_ &= ~VK_MBUTTON;
+ buttons_pressed_ &= ~VK_MBUTTON;
}
void WidgetWin::OnMButtonDblClk(UINT flags, const CPoint& point) {
@@ -749,11 +774,21 @@
}
void WidgetWin::OnRButtonDown(UINT flags, const CPoint& point) {
- ProcessMousePressed(point, flags | MK_RBUTTON, false, false);
+ // Clear out-of-order release flag in case the "button released" event
+ // was truly completely swallowed.
+ released_buttons_out_of_order_ &= ~right_button_code_;
+ if (ProcessMousePressed(point, flags | MK_RBUTTON, false, false))
+ buttons_pressed_ |= right_button_code_;
}
void WidgetWin::OnRButtonUp(UINT flags, const CPoint& point) {
- ProcessMouseReleased(point, flags | MK_RBUTTON);
+ // If we already generated the event for this button out of order,
+ // avoid doing it twice.
+ if (0 == (released_buttons_out_of_order_ & right_button_code_)) {
+ ProcessMouseReleased(point, flags | MK_RBUTTON);
+ }
+ released_buttons_out_of_order_ &= ~right_button_code_;
+ buttons_pressed_ &= ~right_button_code_;
}
void WidgetWin::OnRButtonDblClk(UINT flags, const CPoint& point) {
@@ -819,6 +854,11 @@
Event::ConvertWindowsFlags(flags));
if (root_view_->OnMousePressed(mouse_pressed)) {
is_mouse_down_ = true;
+ gfx::Point screen_loc(point);
+ View::ConvertPointToScreen(root_view_.get(), &screen_loc);
+ last_mouse_move_x_ = screen_loc.x();
+ last_mouse_move_y_ = screen_loc.y();
+ last_mouse_event_was_move_ = false;
if (!has_capture_) {
SetCapture();
has_capture_ = true;
@@ -855,23 +895,28 @@
void WidgetWin::ProcessMouseMoved(const CPoint &point, UINT flags,
bool is_nonclient) {
+ // Under heavy load it may happen that a mouse release event gets
+ // "swallowed" or postponed. Explicitely check mouse button state here
+ // to make sure this hasn't happened.
+ CheckOutOfOrderMouseButtonRelease(left_button_code_);
+ CheckOutOfOrderMouseButtonRelease(VK_MBUTTON);
+ CheckOutOfOrderMouseButtonRelease(right_button_code_);
// 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 (!has_capture_)
TrackMouseEvents(is_nonclient ? TME_NONCLIENT | TME_LEAVE : TME_LEAVE);
+
+ gfx::Point screen_loc(point);
+ View::ConvertPointToScreen(root_view_.get(), &screen_loc);
if (has_capture_ && is_mouse_down_) {
ProcessMouseDragged(point, flags);
} else {
- gfx::Point screen_loc(point);
- View::ConvertPointToScreen(root_view_.get(), &screen_loc);
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;
}
- last_mouse_move_x_ = screen_loc.x();
- last_mouse_move_y_ = screen_loc.y();
last_mouse_event_was_move_ = true;
MouseEvent mouse_move(Event::ET_MOUSE_MOVED,
point.x,
@@ -879,6 +924,8 @@
Event::ConvertWindowsFlags(flags));
root_view_->OnMouseMoved(mouse_move);
}
+ last_mouse_move_x_ = screen_loc.x();
+ last_mouse_move_y_ = screen_loc.y();
}
void WidgetWin::ProcessMouseExited() {
@@ -889,6 +936,19 @@
active_mouse_tracking_flags_ = 0;
}
+void WidgetWin::CheckOutOfOrderMouseButtonRelease(int code) {
+ SHORT key_state = ::GetAsyncKeyState(code);
+ if ((0 == (key_state & 0x8000)) &&
+ (0 != (buttons_pressed_ & code))) {
+ // left button was released in the meantime
+ // generate an out-of-order event for this, at the last recorded position
+ CPoint pt(last_mouse_move_x_, last_mouse_move_y_);
+ ProcessMouseReleased(pt, code);
+ released_buttons_out_of_order_ |= code;
+ buttons_pressed_ &= ~code;
+ }
+}
+
void WidgetWin::ChangeSize(UINT size_param, const CSize& size) {
CRect rect;
if (use_layered_buffer_) {
« no previous file with comments | « views/widget/widget_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698