diff options
author | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-22 02:01:57 +0000 |
---|---|---|
committer | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-22 02:01:57 +0000 |
commit | 365632b6511797f47983a1bbae1dc4fd84e0ba1b (patch) | |
tree | 1f765e845fb917886a8338a29478738645fbeed0 | |
parent | 69ac9dc297cdf825abc78d1b097580fafea8ea40 (diff) | |
download | chromium_src-365632b6511797f47983a1bbae1dc4fd84e0ba1b.zip chromium_src-365632b6511797f47983a1bbae1dc4fd84e0ba1b.tar.gz chromium_src-365632b6511797f47983a1bbae1dc4fd84e0ba1b.tar.bz2 |
Make right-clicking the omnibox with nothing selected select all (just like left-clicking).
Eat middle-mouse clicks on the omnibox to avoid tripping a CRichEditCtrl bug.
Original patch by Jared Wein (see http://codereview.chromium.org/2241003 ), r=me.
BUG=6873, 30134
TEST=Middle-click the omnibox, then try to click it (or any other UI element), and make sure the click has an effect. Select a portion of the URL and right-click on the omnibox. Notice that the selection does not change. Clear the selection and right-click on the omnibox and notice that the URL is automatically selected.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50420 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | build/common.gypi | 2 | ||||
-rw-r--r-- | chrome/browser/autocomplete/autocomplete_edit_view_win.cc | 145 | ||||
-rw-r--r-- | chrome/browser/autocomplete/autocomplete_edit_view_win.h | 43 |
3 files changed, 119 insertions, 71 deletions
diff --git a/build/common.gypi b/build/common.gypi index ee19492..0867e42 100644 --- a/build/common.gypi +++ b/build/common.gypi @@ -1258,7 +1258,7 @@ '$(VSInstallDir)/VC/atlmfc/include', ], 'msvs_cygwin_dirs': ['<(DEPTH)/third_party/cygwin'], - 'msvs_disabled_warnings': [4396, 4503, 4819], + 'msvs_disabled_warnings': [4351, 4396, 4503, 4819], 'msvs_settings': { 'VCCLCompilerTool': { 'MinimalRebuild': 'false', diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc index 7bf2fa7..8710100 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc +++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc @@ -402,7 +402,7 @@ AutocompleteEditViewWin::AutocompleteEditViewWin( command_updater_(command_updater), popup_window_mode_(popup_window_mode), force_hidden_(false), - tracking_click_(false), + tracking_click_(), tracking_double_click_(false), double_click_time_(0), can_discard_mousemove_(false), @@ -1394,13 +1394,8 @@ void AutocompleteEditViewWin::OnLButtonDblClk(UINT keys, const CPoint& point) { } void AutocompleteEditViewWin::OnLButtonDown(UINT keys, const CPoint& point) { + TrackMousePosition(kLeft, point); if (gaining_focus_.get()) { - // This click is giving us focus, so we need to track how much the mouse - // moves to see if it's a drag or just a click. Clicks should select all - // the text. - tracking_click_ = true; - mouse_down_point_ = point; - // When Chrome was already the activated app, we haven't reached // OnSetFocus() yet. When we get there, don't restore the saved selection, // since it will just screw up the user's interaction with the edit. @@ -1450,17 +1445,38 @@ void AutocompleteEditViewWin::OnLButtonUp(UINT keys, const CPoint& point) { DefWindowProc(WM_LBUTTONUP, keys, MAKELPARAM(ClipXCoordToVisibleText(point.x, false), point.y)); - // When the user has clicked and released to give us focus, select all. - if (tracking_click_ && !win_util::IsDrag(mouse_down_point_, point)) { - // Select all in the reverse direction so as not to scroll the caret - // into view and shift the contents jarringly. - SelectAll(true); - possible_drag_ = false; - } + SelectAllIfNecessary(kLeft, point); + + tracking_click_[kLeft] = false; + + possible_drag_ = false; +} + +void AutocompleteEditViewWin::OnMButtonDblClk(UINT /*keys*/, + const CPoint& /*point*/) { + gaining_focus_.reset(); // See NOTE in OnMouseActivate(). - tracking_click_ = false; + // By default, the edit responds to middle-clicks by capturing the mouse and + // ignoring all subsequent events until it receives another click (of any of + // the left, middle, or right buttons). This bizarre behavior is not only + // useless but can cause the UI to appear unresponsive if a user accidentally + // middle-clicks the edit (instead of a tab above it), so we purposefully eat + // this message (instead of calling SetMsgHandled(false)) to avoid triggering + // this. +} + +void AutocompleteEditViewWin::OnMButtonDown(UINT /*keys*/, + const CPoint& /*point*/) { + tracking_double_click_ = false; + + // See note in OnMButtonDblClk above. +} + +void AutocompleteEditViewWin::OnMButtonUp(UINT /*keys*/, + const CPoint& /*point*/) { + possible_drag_ = false; - UpdateDragDone(keys); + // See note in OnMButtonDblClk above. } LRESULT AutocompleteEditViewWin::OnMouseActivate(HWND window, @@ -1471,20 +1487,21 @@ LRESULT AutocompleteEditViewWin::OnMouseActivate(HWND window, LRESULT result = DefWindowProc(WM_MOUSEACTIVATE, reinterpret_cast<WPARAM>(window), MAKELPARAM(hit_test, mouse_message)); - // Check if we're getting focus from a left click. We have to do this here - // rather than in OnLButtonDown() since in many scenarios OnSetFocus() will be - // reached before OnLButtonDown(), preventing us from detecting this properly + // Check if we're getting focus from a click. We have to do this here rather + // than in OnXButtonDown() since in many scenarios OnSetFocus() will be + // reached before OnXButtonDown(), preventing us from detecting this properly // there. Also in those cases, we need to already know in OnSetFocus() that // we should not restore the saved selection. - if (!model_->has_focus() && (mouse_message == WM_LBUTTONDOWN) && + if (!model_->has_focus() && + ((mouse_message == WM_LBUTTONDOWN || mouse_message == WM_RBUTTONDOWN)) && (result == MA_ACTIVATE)) { DCHECK(!gaining_focus_.get()); gaining_focus_.reset(new ScopedFreeze(this, GetTextObjectModel())); - // NOTE: Despite |mouse_message| being WM_LBUTTONDOWN here, we're not - // guaranteed to call OnLButtonDown() later! Specifically, if this is the + // NOTE: Despite |mouse_message| being WM_XBUTTONDOWN here, we're not + // guaranteed to call OnXButtonDown() later! Specifically, if this is the // second click of a double click, we'll reach here but later call - // OnLButtonDblClk(). Make sure |gaining_focus_| gets reset both places, or - // we'll have visual glitchiness and then DCHECK failures. + // OnXButtonDblClk(). Make sure |gaining_focus_| gets reset both places, + // or we'll have visual glitchiness and then DCHECK failures. // Don't restore saved selection, it will just screw up our interaction // with this edit. @@ -1501,10 +1518,10 @@ void AutocompleteEditViewWin::OnMouseMove(UINT keys, const CPoint& point) { return; } - if (tracking_click_ && !win_util::IsDrag(mouse_down_point_, point)) + if (tracking_click_[kLeft] && !win_util::IsDrag(click_point_[kLeft], point)) return; - tracking_click_ = false; + tracking_click_[kLeft] = false; // Return quickly if this can't change the selection/cursor, so we don't // create a ScopedFreeze (and thus do an UpdateWindow()) on every @@ -1630,25 +1647,6 @@ void AutocompleteEditViewWin::OnPaint(HDC bogus_hdc) { edit_hwnd = old_edit_hwnd; } -void AutocompleteEditViewWin::OnNonLButtonDown(UINT keys, - const CPoint& point) { - // Interestingly, the edit doesn't seem to cancel triple clicking when the - // x-buttons (which usually means "thumb buttons") are pressed, so we only - // call this for M and R down. - tracking_double_click_ = false; - - OnPossibleDrag(point); - - SetMsgHandled(false); -} - -void AutocompleteEditViewWin::OnNonLButtonUp(UINT keys, const CPoint& point) { - UpdateDragDone(keys); - - // Let default handler have a crack at this. - SetMsgHandled(false); -} - void AutocompleteEditViewWin::OnPaste() { // Replace the selection if we have something to paste. const std::wstring text(GetClipboardText()); @@ -1665,6 +1663,27 @@ void AutocompleteEditViewWin::OnPaste() { } } +void AutocompleteEditViewWin::OnRButtonDblClk(UINT /*keys*/, + const CPoint& /*point*/) { + gaining_focus_.reset(); // See NOTE in OnMouseActivate(). + SetMsgHandled(false); +} + +void AutocompleteEditViewWin::OnRButtonDown(UINT /*keys*/, + const CPoint& point) { + TrackMousePosition(kRight, point); + tracking_double_click_ = false; + possible_drag_ = false; + gaining_focus_.reset(); + SetMsgHandled(false); +} + +void AutocompleteEditViewWin::OnRButtonUp(UINT /*keys*/, const CPoint& point) { + SelectAllIfNecessary(kRight, point); + tracking_click_[kRight] = false; + SetMsgHandled(false); +} + void AutocompleteEditViewWin::OnSetFocus(HWND focus_wnd) { views::FocusManager* focus_manager = parent_view_->GetFocusManager(); if (focus_manager) { @@ -2293,7 +2312,7 @@ ITextDocument* AutocompleteEditViewWin::GetTextObjectModel() const { } void AutocompleteEditViewWin::StartDragIfNecessary(const CPoint& point) { - if (initiated_drag_ || !win_util::IsDrag(mouse_down_point_, point)) + if (initiated_drag_ || !win_util::IsDrag(click_point_[kLeft], point)) return; OSExchangeData data; @@ -2313,7 +2332,7 @@ void AutocompleteEditViewWin::StartDragIfNecessary(const CPoint& point) { { ScopedFreeze freeze(this, GetTextObjectModel()); DefWindowProc(WM_LBUTTONUP, 0, - MAKELPARAM(mouse_down_point_.x, mouse_down_point_.y)); + MAKELPARAM(click_point_[kLeft].x, click_point_[kLeft].y)); SetSelectionRange(sel); } @@ -2378,14 +2397,14 @@ void AutocompleteEditViewWin::StartDragIfNecessary(const CPoint& point) { } initiated_drag_ = true; - tracking_click_ = false; + tracking_click_[kLeft] = false; } void AutocompleteEditViewWin::OnPossibleDrag(const CPoint& point) { if (possible_drag_) return; - mouse_down_point_ = point; + click_point_[kLeft] = point; initiated_drag_ = false; CHARRANGE selection; @@ -2401,11 +2420,6 @@ void AutocompleteEditViewWin::OnPossibleDrag(const CPoint& point) { } } -void AutocompleteEditViewWin::UpdateDragDone(UINT keys) { - possible_drag_ = (possible_drag_ && - ((keys & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) != 0)); -} - void AutocompleteEditViewWin::RepaintDropHighlight(int position) { if ((position != -1) && (position <= GetTextLength())) { const POINT min_loc(PosFromChar(position)); @@ -2441,3 +2455,26 @@ void AutocompleteEditViewWin::BuildContextMenu() { } context_menu_.reset(new views::Menu2(context_menu_contents_.get())); } + +void AutocompleteEditViewWin::SelectAllIfNecessary(MouseButton button, + const CPoint& point) { + // When the user has clicked and released to give us focus, select all. + if (tracking_click_[button] && + !win_util::IsDrag(click_point_[button], point)) { + // Select all in the reverse direction so as not to scroll the caret + // into view and shift the contents jarringly. + SelectAll(true); + possible_drag_ = false; + } +} + +void AutocompleteEditViewWin::TrackMousePosition(MouseButton button, + const CPoint& point) { + if (gaining_focus_.get()) { + // This click is giving us focus, so we need to track how much the mouse + // moves to see if it's a drag or just a click. Clicks should select all + // the text. + tracking_click_[button] = true; + click_point_[button] = point; + } +} diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.h b/chrome/browser/autocomplete/autocomplete_edit_view_win.h index 4f3e51e..8157706 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_win.h +++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.h @@ -170,15 +170,17 @@ class AutocompleteEditViewWin MSG_WM_LBUTTONDBLCLK(OnLButtonDblClk) MSG_WM_LBUTTONDOWN(OnLButtonDown) MSG_WM_LBUTTONUP(OnLButtonUp) - MSG_WM_MBUTTONDOWN(OnNonLButtonDown) - MSG_WM_MBUTTONUP(OnNonLButtonUp) + MSG_WM_MBUTTONDBLCLK(OnMButtonDblClk) + MSG_WM_MBUTTONDOWN(OnMButtonDown) + MSG_WM_MBUTTONUP(OnMButtonUp) MSG_WM_MOUSEACTIVATE(OnMouseActivate) MSG_WM_MOUSEMOVE(OnMouseMove) MSG_WM_MOUSEWHEEL(OnMouseWheel) MSG_WM_PAINT(OnPaint) MSG_WM_PASTE(OnPaste) - MSG_WM_RBUTTONDOWN(OnNonLButtonDown) - MSG_WM_RBUTTONUP(OnNonLButtonUp) + MSG_WM_RBUTTONDBLCLK(OnRButtonDblClk) + MSG_WM_RBUTTONDOWN(OnRButtonDown) + MSG_WM_RBUTTONUP(OnRButtonUp) MSG_WM_SETFOCUS(OnSetFocus) MSG_WM_SETTEXT(OnSetText) MSG_WM_SYSCHAR(OnSysChar) // WM_SYSxxx == WM_xxx with ALT down @@ -198,6 +200,11 @@ class AutocompleteEditViewWin virtual void ExecuteCommand(int command_id); private: + enum MouseButton { + kLeft = 0, + kRight = 1, + }; + // This object freezes repainting of the edit until the object is destroyed. // Some methods of the CRichEditCtrl draw synchronously to the screen. If we // don't freeze, the user will see a rapid series of calls to these as @@ -256,13 +263,17 @@ class AutocompleteEditViewWin void OnLButtonDblClk(UINT keys, const CPoint& point); void OnLButtonDown(UINT keys, const CPoint& point); void OnLButtonUp(UINT keys, const CPoint& point); + void OnMButtonDblClk(UINT keys, const CPoint& point); + void OnMButtonDown(UINT keys, const CPoint& point); + void OnMButtonUp(UINT keys, const CPoint& point); LRESULT OnMouseActivate(HWND window, UINT hit_test, UINT mouse_message); void OnMouseMove(UINT keys, const CPoint& point); BOOL OnMouseWheel(UINT flags, short delta, CPoint point); - void OnNonLButtonDown(UINT keys, const CPoint& point); - void OnNonLButtonUp(UINT keys, const CPoint& point); void OnPaint(HDC bogus_hdc); void OnPaste(); + void OnRButtonDblClk(UINT keys, const CPoint& point); + void OnRButtonDown(UINT keys, const CPoint& point); + void OnRButtonUp(UINT keys, const CPoint& point); void OnSetFocus(HWND focus_wnd); LRESULT OnSetText(const wchar_t* text); void OnSysChar(TCHAR ch, UINT repeat_count, UINT flags); @@ -361,10 +372,6 @@ class AutocompleteEditViewWin // user moves the mouse far enough to start a drag. void OnPossibleDrag(const CPoint& point); - // Invoked when a mouse button is released. If none of the buttons are still - // down, this sets possible_drag_ to false. - void UpdateDragDone(UINT keys); - // Redraws the necessary region for a drop highlight at the specified // position. This does nothing if position is beyond the bounds of the // text. @@ -373,6 +380,9 @@ class AutocompleteEditViewWin // Generates the context menu for the edit field. void BuildContextMenu(); + void SelectAllIfNecessary(MouseButton button, const CPoint& point); + void TrackMousePosition(MouseButton button, const CPoint& point); + scoped_ptr<AutocompleteEditModel> model_; scoped_ptr<AutocompletePopupView> popup_view_; @@ -412,12 +422,13 @@ class AutocompleteEditViewWin // When the user clicks to give us focus, we watch to see if they're clicking // or dragging. When they're clicking, we select nothing until mouseup, then - // select all the text in the edit. During this process, tracking_click_ is - // true and mouse_down_point_ holds the original click location. At other - // times, tracking_click_ is false, and the contents of mouse_down_point_ - // should be ignored. - bool tracking_click_; - CPoint mouse_down_point_; + // select all the text in the edit. During this process, tracking_click_[X] + // is true and click_point_[X] holds the original click location. + // At other times, tracking_click_[X] is false, and the contents of + // click_point_[X] should be ignored. The arrays hold the state for the + // left and right mouse buttons, and are indexed using the MouseButton enum. + bool tracking_click_[2]; + CPoint click_point_[2]; // We need to know if the user triple-clicks, so track double click points // and times so we can see if subsequent clicks are actually triple clicks. |