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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « views/widget/widget_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "views/widget/widget_win.h" 5 #include "views/widget/widget_win.h"
6 6
7 #include "app/gfx/canvas.h" 7 #include "app/gfx/canvas.h"
8 #include "app/gfx/path.h" 8 #include "app/gfx/path.h"
9 #include "app/win_util.h" 9 #include "app/win_util.h"
10 #include "base/gfx/native_theme.h" 10 #include "base/gfx/native_theme.h"
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 : close_widget_factory_(this), 137 : close_widget_factory_(this),
138 active_mouse_tracking_flags_(0), 138 active_mouse_tracking_flags_(0),
139 has_capture_(false), 139 has_capture_(false),
140 window_style_(0), 140 window_style_(0),
141 window_ex_style_(kWindowDefaultExStyle), 141 window_ex_style_(kWindowDefaultExStyle),
142 use_layered_buffer_(true), 142 use_layered_buffer_(true),
143 layered_alpha_(255), 143 layered_alpha_(255),
144 delete_on_destroy_(true), 144 delete_on_destroy_(true),
145 can_update_layered_window_(true), 145 can_update_layered_window_(true),
146 last_mouse_event_was_move_(false), 146 last_mouse_event_was_move_(false),
147 mouse_buttons_are_swapped_(0 != GetSystemMetrics(SM_SWAPBUTTON)),
148 buttons_pressed_(0),
149 released_buttons_out_of_order_(0),
147 is_mouse_down_(false), 150 is_mouse_down_(false),
148 is_window_(false), 151 is_window_(false),
149 class_style_(CS_DBLCLKS), 152 class_style_(CS_DBLCLKS),
150 hwnd_(NULL) { 153 hwnd_(NULL) {
154 left_button_code_ = mouse_buttons_are_swapped_ ? VK_RBUTTON : VK_LBUTTON;
155 right_button_code_ = mouse_buttons_are_swapped_ ? VK_LBUTTON : VK_RBUTTON;
151 } 156 }
152 157
153 WidgetWin::~WidgetWin() { 158 WidgetWin::~WidgetWin() {
154 MessageLoopForUI::current()->RemoveObserver(this); 159 MessageLoopForUI::current()->RemoveObserver(this);
155 } 160 }
156 161
157 void WidgetWin::Init(HWND parent, const gfx::Rect& bounds) { 162 void WidgetWin::Init(HWND parent, const gfx::Rect& bounds) {
158 if (window_style_ == 0) 163 if (window_style_ == 0)
159 window_style_ = parent ? kWindowDefaultChildStyle : kWindowDefaultStyle; 164 window_style_ = parent ? kWindowDefaultChildStyle : kWindowDefaultStyle;
160 165
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 KeyEvent event(Event::ET_KEY_PRESSED, c, rep_cnt, flags); 614 KeyEvent event(Event::ET_KEY_PRESSED, c, rep_cnt, flags);
610 SetMsgHandled(root_view_->ProcessKeyEvent(event)); 615 SetMsgHandled(root_view_->ProcessKeyEvent(event));
611 } 616 }
612 617
613 void WidgetWin::OnKeyUp(TCHAR c, UINT rep_cnt, UINT flags) { 618 void WidgetWin::OnKeyUp(TCHAR c, UINT rep_cnt, UINT flags) {
614 KeyEvent event(Event::ET_KEY_RELEASED, c, rep_cnt, flags); 619 KeyEvent event(Event::ET_KEY_RELEASED, c, rep_cnt, flags);
615 SetMsgHandled(root_view_->ProcessKeyEvent(event)); 620 SetMsgHandled(root_view_->ProcessKeyEvent(event));
616 } 621 }
617 622
618 void WidgetWin::OnLButtonDown(UINT flags, const CPoint& point) { 623 void WidgetWin::OnLButtonDown(UINT flags, const CPoint& point) {
619 ProcessMousePressed(point, flags | MK_LBUTTON, false, false); 624 // Clear out-of-order release flag in case the "button released" event
625 // was truly completely swallowed.
626 released_buttons_out_of_order_ &= ~left_button_code_;
627 if (ProcessMousePressed(point, flags | MK_LBUTTON, false, false))
628 buttons_pressed_ |= left_button_code_;
620 } 629 }
621 630
622 void WidgetWin::OnLButtonUp(UINT flags, const CPoint& point) { 631 void WidgetWin::OnLButtonUp(UINT flags, const CPoint& point) {
623 ProcessMouseReleased(point, flags | MK_LBUTTON); 632 // If we already generated the event for this button out of order,
633 // avoid doing it twice.
634 if (0 == (released_buttons_out_of_order_ & left_button_code_)) {
635 ProcessMouseReleased(point, flags | MK_LBUTTON);
636 }
637 released_buttons_out_of_order_ &= ~left_button_code_;
638 buttons_pressed_ &= ~left_button_code_;
624 } 639 }
625 640
626 void WidgetWin::OnLButtonDblClk(UINT flags, const CPoint& point) { 641 void WidgetWin::OnLButtonDblClk(UINT flags, const CPoint& point) {
627 ProcessMousePressed(point, flags | MK_LBUTTON, true, false); 642 ProcessMousePressed(point, flags | MK_LBUTTON, true, false);
628 } 643 }
629 644
630 void WidgetWin::OnMButtonDown(UINT flags, const CPoint& point) { 645 void WidgetWin::OnMButtonDown(UINT flags, const CPoint& point) {
631 ProcessMousePressed(point, flags | MK_MBUTTON, false, false); 646 // Clear out-of-order release flag in case the "button released" event
647 // was truly completely swallowed.
648 released_buttons_out_of_order_ &= ~VK_MBUTTON;
649 if (ProcessMousePressed(point, flags | MK_MBUTTON, false, false))
650 buttons_pressed_ |= VK_MBUTTON;
632 } 651 }
633 652
634 void WidgetWin::OnMButtonUp(UINT flags, const CPoint& point) { 653 void WidgetWin::OnMButtonUp(UINT flags, const CPoint& point) {
635 ProcessMouseReleased(point, flags | MK_MBUTTON); 654 // If we already generated the event for this button out of order,
655 // avoid doing it twice.
656 if (0 == (released_buttons_out_of_order_ & VK_MBUTTON)) {
657 ProcessMouseReleased(point, flags | MK_MBUTTON);
658 }
659 released_buttons_out_of_order_ &= ~VK_MBUTTON;
660 buttons_pressed_ &= ~VK_MBUTTON;
636 } 661 }
637 662
638 void WidgetWin::OnMButtonDblClk(UINT flags, const CPoint& point) { 663 void WidgetWin::OnMButtonDblClk(UINT flags, const CPoint& point) {
639 ProcessMousePressed(point, flags | MK_MBUTTON, true, false); 664 ProcessMousePressed(point, flags | MK_MBUTTON, true, false);
640 } 665 }
641 666
642 LRESULT WidgetWin::OnMouseActivate(HWND window, UINT hittest_code, 667 LRESULT WidgetWin::OnMouseActivate(HWND window, UINT hittest_code,
643 UINT message) { 668 UINT message) {
644 SetMsgHandled(FALSE); 669 SetMsgHandled(FALSE);
645 return MA_ACTIVATE; 670 return MA_ACTIVATE;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 } 767 }
743 SetMsgHandled(FALSE); 768 SetMsgHandled(FALSE);
744 return 0; 769 return 0;
745 } 770 }
746 771
747 void WidgetWin::OnPaint(HDC dc) { 772 void WidgetWin::OnPaint(HDC dc) {
748 root_view_->OnPaint(GetNativeView()); 773 root_view_->OnPaint(GetNativeView());
749 } 774 }
750 775
751 void WidgetWin::OnRButtonDown(UINT flags, const CPoint& point) { 776 void WidgetWin::OnRButtonDown(UINT flags, const CPoint& point) {
752 ProcessMousePressed(point, flags | MK_RBUTTON, false, false); 777 // Clear out-of-order release flag in case the "button released" event
778 // was truly completely swallowed.
779 released_buttons_out_of_order_ &= ~right_button_code_;
780 if (ProcessMousePressed(point, flags | MK_RBUTTON, false, false))
781 buttons_pressed_ |= right_button_code_;
753 } 782 }
754 783
755 void WidgetWin::OnRButtonUp(UINT flags, const CPoint& point) { 784 void WidgetWin::OnRButtonUp(UINT flags, const CPoint& point) {
756 ProcessMouseReleased(point, flags | MK_RBUTTON); 785 // If we already generated the event for this button out of order,
786 // avoid doing it twice.
787 if (0 == (released_buttons_out_of_order_ & right_button_code_)) {
788 ProcessMouseReleased(point, flags | MK_RBUTTON);
789 }
790 released_buttons_out_of_order_ &= ~right_button_code_;
791 buttons_pressed_ &= ~right_button_code_;
757 } 792 }
758 793
759 void WidgetWin::OnRButtonDblClk(UINT flags, const CPoint& point) { 794 void WidgetWin::OnRButtonDblClk(UINT flags, const CPoint& point) {
760 ProcessMousePressed(point, flags | MK_RBUTTON, true, false); 795 ProcessMousePressed(point, flags | MK_RBUTTON, true, false);
761 } 796 }
762 797
763 void WidgetWin::OnSize(UINT param, const CSize& size) { 798 void WidgetWin::OnSize(UINT param, const CSize& size) {
764 ChangeSize(param, size); 799 ChangeSize(param, size);
765 } 800 }
766 801
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 if (non_client) 847 if (non_client)
813 View::ConvertPointToView(NULL, root_view_.get(), &converted_point); 848 View::ConvertPointToView(NULL, root_view_.get(), &converted_point);
814 MouseEvent mouse_pressed(Event::ET_MOUSE_PRESSED, 849 MouseEvent mouse_pressed(Event::ET_MOUSE_PRESSED,
815 converted_point.x(), 850 converted_point.x(),
816 converted_point.y(), 851 converted_point.y(),
817 (dbl_click ? MouseEvent::EF_IS_DOUBLE_CLICK : 0) | 852 (dbl_click ? MouseEvent::EF_IS_DOUBLE_CLICK : 0) |
818 (non_client ? MouseEvent::EF_IS_NON_CLIENT : 0) | 853 (non_client ? MouseEvent::EF_IS_NON_CLIENT : 0) |
819 Event::ConvertWindowsFlags(flags)); 854 Event::ConvertWindowsFlags(flags));
820 if (root_view_->OnMousePressed(mouse_pressed)) { 855 if (root_view_->OnMousePressed(mouse_pressed)) {
821 is_mouse_down_ = true; 856 is_mouse_down_ = true;
857 gfx::Point screen_loc(point);
858 View::ConvertPointToScreen(root_view_.get(), &screen_loc);
859 last_mouse_move_x_ = screen_loc.x();
860 last_mouse_move_y_ = screen_loc.y();
861 last_mouse_event_was_move_ = false;
822 if (!has_capture_) { 862 if (!has_capture_) {
823 SetCapture(); 863 SetCapture();
824 has_capture_ = true; 864 has_capture_ = true;
825 } 865 }
826 return true; 866 return true;
827 } 867 }
828 return false; 868 return false;
829 } 869 }
830 870
831 void WidgetWin::ProcessMouseDragged(const CPoint& point, UINT flags) { 871 void WidgetWin::ProcessMouseDragged(const CPoint& point, UINT flags) {
(...skipping 16 matching lines...) Expand all
848 if (has_capture_ && ReleaseCaptureOnMouseReleased()) { 888 if (has_capture_ && ReleaseCaptureOnMouseReleased()) {
849 has_capture_ = false; 889 has_capture_ = false;
850 ReleaseCapture(); 890 ReleaseCapture();
851 } 891 }
852 is_mouse_down_ = false; 892 is_mouse_down_ = false;
853 root_view_->OnMouseReleased(mouse_up, false); 893 root_view_->OnMouseReleased(mouse_up, false);
854 } 894 }
855 895
856 void WidgetWin::ProcessMouseMoved(const CPoint &point, UINT flags, 896 void WidgetWin::ProcessMouseMoved(const CPoint &point, UINT flags,
857 bool is_nonclient) { 897 bool is_nonclient) {
898 // Under heavy load it may happen that a mouse release event gets
899 // "swallowed" or postponed. Explicitely check mouse button state here
900 // to make sure this hasn't happened.
901 CheckOutOfOrderMouseButtonRelease(left_button_code_);
902 CheckOutOfOrderMouseButtonRelease(VK_MBUTTON);
903 CheckOutOfOrderMouseButtonRelease(right_button_code_);
858 // Windows only fires WM_MOUSELEAVE events if the application begins 904 // Windows only fires WM_MOUSELEAVE events if the application begins
859 // "tracking" mouse events for a given HWND during WM_MOUSEMOVE events. 905 // "tracking" mouse events for a given HWND during WM_MOUSEMOVE events.
860 // We need to call |TrackMouseEvents| to listen for WM_MOUSELEAVE. 906 // We need to call |TrackMouseEvents| to listen for WM_MOUSELEAVE.
861 if (!has_capture_) 907 if (!has_capture_)
862 TrackMouseEvents(is_nonclient ? TME_NONCLIENT | TME_LEAVE : TME_LEAVE); 908 TrackMouseEvents(is_nonclient ? TME_NONCLIENT | TME_LEAVE : TME_LEAVE);
909
910 gfx::Point screen_loc(point);
911 View::ConvertPointToScreen(root_view_.get(), &screen_loc);
863 if (has_capture_ && is_mouse_down_) { 912 if (has_capture_ && is_mouse_down_) {
864 ProcessMouseDragged(point, flags); 913 ProcessMouseDragged(point, flags);
865 } else { 914 } else {
866 gfx::Point screen_loc(point);
867 View::ConvertPointToScreen(root_view_.get(), &screen_loc);
868 if (last_mouse_event_was_move_ && last_mouse_move_x_ == screen_loc.x() && 915 if (last_mouse_event_was_move_ && last_mouse_move_x_ == screen_loc.x() &&
869 last_mouse_move_y_ == screen_loc.y()) { 916 last_mouse_move_y_ == screen_loc.y()) {
870 // Don't generate a mouse event for the same location as the last. 917 // Don't generate a mouse event for the same location as the last.
871 return; 918 return;
872 } 919 }
873 last_mouse_move_x_ = screen_loc.x();
874 last_mouse_move_y_ = screen_loc.y();
875 last_mouse_event_was_move_ = true; 920 last_mouse_event_was_move_ = true;
876 MouseEvent mouse_move(Event::ET_MOUSE_MOVED, 921 MouseEvent mouse_move(Event::ET_MOUSE_MOVED,
877 point.x, 922 point.x,
878 point.y, 923 point.y,
879 Event::ConvertWindowsFlags(flags)); 924 Event::ConvertWindowsFlags(flags));
880 root_view_->OnMouseMoved(mouse_move); 925 root_view_->OnMouseMoved(mouse_move);
881 } 926 }
927 last_mouse_move_x_ = screen_loc.x();
928 last_mouse_move_y_ = screen_loc.y();
882 } 929 }
883 930
884 void WidgetWin::ProcessMouseExited() { 931 void WidgetWin::ProcessMouseExited() {
885 last_mouse_event_was_move_ = false; 932 last_mouse_event_was_move_ = false;
886 root_view_->ProcessOnMouseExited(); 933 root_view_->ProcessOnMouseExited();
887 // Reset our tracking flag so that future mouse movement over this WidgetWin 934 // Reset our tracking flag so that future mouse movement over this WidgetWin
888 // results in a new tracking session. 935 // results in a new tracking session.
889 active_mouse_tracking_flags_ = 0; 936 active_mouse_tracking_flags_ = 0;
890 } 937 }
891 938
939 void WidgetWin::CheckOutOfOrderMouseButtonRelease(int code) {
940 SHORT key_state = ::GetAsyncKeyState(code);
941 if ((0 == (key_state & 0x8000)) &&
942 (0 != (buttons_pressed_ & code))) {
943 // left button was released in the meantime
944 // generate an out-of-order event for this, at the last recorded position
945 CPoint pt(last_mouse_move_x_, last_mouse_move_y_);
946 ProcessMouseReleased(pt, code);
947 released_buttons_out_of_order_ |= code;
948 buttons_pressed_ &= ~code;
949 }
950 }
951
892 void WidgetWin::ChangeSize(UINT size_param, const CSize& size) { 952 void WidgetWin::ChangeSize(UINT size_param, const CSize& size) {
893 CRect rect; 953 CRect rect;
894 if (use_layered_buffer_) { 954 if (use_layered_buffer_) {
895 GetWindowRect(&rect); 955 GetWindowRect(&rect);
896 SizeContents(rect); 956 SizeContents(rect);
897 } else { 957 } else {
898 GetClientRect(&rect); 958 GetClientRect(&rect);
899 } 959 }
900 960
901 // Resizing changes the size of the view hierarchy and thus forces a 961 // Resizing changes the size of the view hierarchy and thus forces a
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 } 1142 }
1083 if (WA_INACTIVE == activation_state) { 1143 if (WA_INACTIVE == activation_state) {
1084 widget->focus_manager_->StoreFocusedView(); 1144 widget->focus_manager_->StoreFocusedView();
1085 } else { 1145 } else {
1086 // We must restore the focus after the message has been DefProc'ed as it 1146 // We must restore the focus after the message has been DefProc'ed as it
1087 // does set the focus to the last focused HWND. 1147 // does set the focus to the last focused HWND.
1088 widget->focus_manager_->RestoreFocusedView(); 1148 widget->focus_manager_->RestoreFocusedView();
1089 } 1149 }
1090 } 1150 }
1091 } // namespace views 1151 } // namespace views
OLDNEW
« 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