diff options
author | beng@google.com <beng@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-08 04:12:45 +0000 |
---|---|---|
committer | beng@google.com <beng@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-08 04:12:45 +0000 |
commit | c2176e789af9629724d538b0ccc5ede157f7cb5a (patch) | |
tree | 4192edbfc21d9b0cee97eaed2144009c53733dad /chrome | |
parent | 19b8e5925bb7fc2d76d9afa8b97408020c556ad6 (diff) | |
download | chromium_src-c2176e789af9629724d538b0ccc5ede157f7cb5a.zip chromium_src-c2176e789af9629724d538b0ccc5ede157f7cb5a.tar.gz chromium_src-c2176e789af9629724d538b0ccc5ede157f7cb5a.tar.bz2 |
Eliminate non-client flicker of the standard windows title bar when handling WM_SETTEXT.
Make sure mouse leave messages are sent for controls within the non-client areas
of the window too.
http://crbug.com/2689
http://crbug.com/2710
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@2992 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/views/custom_frame_window.cc | 39 | ||||
-rw-r--r-- | chrome/views/custom_frame_window.h | 2 | ||||
-rw-r--r-- | chrome/views/hwnd_view_container.cc | 45 | ||||
-rw-r--r-- | chrome/views/hwnd_view_container.h | 22 |
4 files changed, 79 insertions, 29 deletions
diff --git a/chrome/views/custom_frame_window.cc b/chrome/views/custom_frame_window.cc index d058543..dbbc29d 100644 --- a/chrome/views/custom_frame_window.cc +++ b/chrome/views/custom_frame_window.cc @@ -944,18 +944,6 @@ LRESULT CustomFrameWindow::OnNCHitTest(const CPoint& point) { return non_client_view_->NonClientHitTest(gfx::Point(temp.x, temp.y)); } -LRESULT CustomFrameWindow::OnNCMouseMove(UINT flags, const CPoint& point) { - // NC points are in screen coordinates. - CPoint temp = point; - MapWindowPoints(HWND_DESKTOP, GetHWND(), &temp, 1); - ProcessMouseMoved(temp, 0); - - // 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; -} - struct ClipState { // The window being painted. HWND parent; @@ -1136,6 +1124,33 @@ LRESULT CustomFrameWindow::OnSetCursor(HWND window, UINT hittest_code, return 0; } +LRESULT CustomFrameWindow::OnSetText(const wchar_t* text) { + // Sadly, the default implementation of WM_SETTEXT actually paints the native + // title bar of the application. That's right, it just paints it. It doesn't + // go through WM_NCPAINT or anything like that. What this means is that we + // end up with occasional flicker of the title bar whenever we change the + // title text. The solution is to handle WM_SETTEXT ourselves and remove the + // window's WS_VISIBLE style before calling DefWindowProc directly. + // Afterwards we add it back. Sigh. + LONG window_style = GetWindowLong(GetHWND(), GWL_STYLE); + bool was_visible = !!(window_style & WS_VISIBLE); + if (was_visible) { + window_style &= ~WS_VISIBLE; + SetWindowLong(GetHWND(), GWL_STYLE, window_style); + } + + LRESULT result = DefWindowProc(GetHWND(), WM_SETTEXT, NULL, + reinterpret_cast<LPARAM>(text)); + + // Add the WS_VISIBLE style back if needed and re-set the window style. + if (was_visible) { + window_style |= WS_VISIBLE; + SetWindowLong(GetHWND(), GWL_STYLE, window_style); + } + + return result; +} + void CustomFrameWindow::OnSize(UINT param, const CSize& size) { Window::OnSize(param, size); diff --git a/chrome/views/custom_frame_window.h b/chrome/views/custom_frame_window.h index c8015f1..6b8238b 100644 --- a/chrome/views/custom_frame_window.h +++ b/chrome/views/custom_frame_window.h @@ -53,12 +53,12 @@ class CustomFrameWindow : public Window { virtual LRESULT OnNCActivate(BOOL active); virtual LRESULT OnNCCalcSize(BOOL mode, LPARAM l_param); virtual LRESULT OnNCHitTest(const CPoint& point); - virtual LRESULT OnNCMouseMove(UINT flags, const CPoint& point); virtual void OnNCPaint(HRGN rgn); virtual void OnNCLButtonDown(UINT ht_component, const CPoint& point); virtual LRESULT OnNCUAHDrawCaption(UINT msg, WPARAM w_param, LPARAM l_param); virtual LRESULT OnNCUAHDrawFrame(UINT msg, WPARAM w_param, LPARAM l_param); virtual LRESULT OnSetCursor(HWND window, UINT hittest_code, UINT message); + virtual LRESULT OnSetText(const wchar_t* text); virtual void OnSize(UINT param, const CSize& size); private: diff --git a/chrome/views/hwnd_view_container.cc b/chrome/views/hwnd_view_container.cc index 9c723d9..b1b56bb 100644 --- a/chrome/views/hwnd_view_container.cc +++ b/chrome/views/hwnd_view_container.cc @@ -120,7 +120,7 @@ static RegisteredClasses* registered_classes = NULL; // HWNDViewContainer, public HWNDViewContainer::HWNDViewContainer() - : tracking_mouse_events_(false), + : active_mouse_tracking_flags_(0), has_capture_(false), current_action_(FA_NONE), toplevel_(false), @@ -536,7 +536,7 @@ LRESULT HWNDViewContainer::OnMouseActivate(HWND window, } void HWNDViewContainer::OnMouseMove(UINT flags, const CPoint& point) { - ProcessMouseMoved(point, flags); + ProcessMouseMoved(point, flags, false); } void HWNDViewContainer::OnMouseLeave() { @@ -573,8 +573,22 @@ void HWNDViewContainer::OnNCLButtonUp(UINT flags, const CPoint& point) { SetMsgHandled(FALSE); } +LRESULT HWNDViewContainer::OnNCMouseLeave(UINT uMsg, + WPARAM w_param, + LPARAM l_param) { + ProcessMouseExited(); + return 0; +} + LRESULT HWNDViewContainer::OnNCMouseMove(UINT flags, const CPoint& point) { - SetMsgHandled(FALSE); + // NC points are in screen coordinates. + CPoint temp = point; + MapWindowPoints(HWND_DESKTOP, GetHWND(), &temp, 1); + ProcessMouseMoved(temp, 0, true); + + // 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; } @@ -652,17 +666,27 @@ void HWNDViewContainer::OnFinalMessage(HWND window) { /////////////////////////////////////////////////////////////////////////////// // HWNDViewContainer, protected -void HWNDViewContainer::TrackMouseEvents() { +void HWNDViewContainer::TrackMouseEvents(DWORD mouse_tracking_flags) { // Begin tracking mouse events for this HWND so that we get WM_MOUSELEAVE // when the user moves the mouse outside this HWND's bounds. - if (!tracking_mouse_events_) { + if (active_mouse_tracking_flags_ == 0 || mouse_tracking_flags & TME_CANCEL) { + if (mouse_tracking_flags & TME_CANCEL) { + // We're about to cancel active mouse tracking, so empty out the stored + // state. + active_mouse_tracking_flags_ = 0; + } else { + active_mouse_tracking_flags_ = mouse_tracking_flags; + } + TRACKMOUSEEVENT tme; tme.cbSize = sizeof(tme); - tme.dwFlags = TME_LEAVE; + tme.dwFlags = mouse_tracking_flags; tme.hwndTrack = GetHWND(); tme.dwHoverTime = 0; TrackMouseEvent(&tme); - tracking_mouse_events_ = true; + } else if (mouse_tracking_flags != active_mouse_tracking_flags_) { + TrackMouseEvents(active_mouse_tracking_flags_ | TME_CANCEL); + TrackMouseEvents(mouse_tracking_flags); } } @@ -713,12 +737,13 @@ void HWNDViewContainer::ProcessMouseReleased(const CPoint& point, UINT flags) { root_view_->OnMouseReleased(mouse_up, false); } -void HWNDViewContainer::ProcessMouseMoved(const CPoint &point, UINT flags) { +void HWNDViewContainer::ProcessMouseMoved(const CPoint &point, UINT flags, + bool is_nonclient) { // 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(); + TrackMouseEvents(is_nonclient ? TME_NONCLIENT | TME_LEAVE : TME_LEAVE); if (has_capture_ && is_mouse_down_) { ProcessMouseDragged(point, flags); } else { @@ -745,7 +770,7 @@ void HWNDViewContainer::ProcessMouseExited() { root_view_->ProcessOnMouseExited(); // Reset our tracking flag so that future mouse movement over this // HWNDViewContainer results in a new tracking session. - tracking_mouse_events_ = false; + active_mouse_tracking_flags_ = 0; } void HWNDViewContainer::AdjustWindowToFitScreenSize() { diff --git a/chrome/views/hwnd_view_container.h b/chrome/views/hwnd_view_container.h index 7cfb000..069cc87 100644 --- a/chrome/views/hwnd_view_container.h +++ b/chrome/views/hwnd_view_container.h @@ -174,9 +174,11 @@ class HWNDViewContainer : public ViewContainer, // CustomFrameWindow hacks MESSAGE_HANDLER_EX(WM_NCUAHDRAWCAPTION, OnNCUAHDrawCaption) MESSAGE_HANDLER_EX(WM_NCUAHDRAWFRAME, OnNCUAHDrawFrame) + // Non-atlcrack.h handlers MESSAGE_HANDLER_EX(WM_GETOBJECT, OnGetObject) + MESSAGE_HANDLER_EX(WM_NCMOUSELEAVE, OnNCMouseLeave) // This list is in _ALPHABETICAL_ order! OR I WILL HURT YOU. MSG_WM_ACTIVATE(OnActivate) @@ -227,6 +229,7 @@ class HWNDViewContainer : public ViewContainer, MSG_WM_RBUTTONUP(OnRButtonUp) MSG_WM_SETCURSOR(OnSetCursor) MSG_WM_SETFOCUS(OnSetFocus) + MSG_WM_SETTEXT(OnSetText) MSG_WM_SIZE(OnSize) MSG_WM_SYSCOMMAND(OnSysCommand) MSG_WM_THEMECHANGED(OnThemeChanged) @@ -387,6 +390,7 @@ class HWNDViewContainer : public ViewContainer, virtual void OnNCLButtonDblClk(UINT flags, const CPoint& point); virtual void OnNCLButtonDown(UINT flags, const CPoint& point); virtual void OnNCLButtonUp(UINT flags, const CPoint& point); + virtual LRESULT OnNCMouseLeave(UINT uMsg, WPARAM w_param, LPARAM l_param); virtual LRESULT OnNCMouseMove(UINT flags, const CPoint& point); virtual void OnNCPaint(HRGN rgn) { SetMsgHandled(FALSE); } virtual void OnNCRButtonDblClk(UINT flags, const CPoint& point); @@ -422,6 +426,10 @@ class HWNDViewContainer : public ViewContainer, virtual void OnSetFocus(HWND focused_window) { SetMsgHandled(FALSE); } + virtual LRESULT OnSetText(const wchar_t* text) { + SetMsgHandled(FALSE); + return 0; + } virtual LRESULT OnSettingChange(UINT msg, WPARAM w_param, LPARAM l_param); virtual void OnSize(UINT param, const CSize& size); virtual void OnSysCommand(UINT notification_code, CPoint click) { } @@ -438,8 +446,9 @@ class HWNDViewContainer : public ViewContainer, virtual void OnFinalMessage(HWND window); // Start tracking all mouse events so that this window gets sent mouse leave - // messages too. - void TrackMouseEvents(); + // messages too. |is_nonclient| is true when we should track WM_NCMOUSELEAVE + // messages instead of WM_MOUSELEAVE ones. + 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 @@ -447,7 +456,7 @@ class HWNDViewContainer : public ViewContainer, bool ProcessMousePressed(const CPoint& point, UINT flags, bool dbl_click); void ProcessMouseDragged(const CPoint& point, UINT flags); void ProcessMouseReleased(const CPoint& point, UINT flags); - void ProcessMouseMoved(const CPoint& point, UINT flags); + void ProcessMouseMoved(const CPoint& point, UINT flags, bool is_nonclient); void ProcessMouseExited(); // Makes sure the window still fits on screen after a settings change message @@ -512,9 +521,10 @@ class HWNDViewContainer : public ViewContainer, // instance. ScopedRunnableMethodFactory<HWNDViewContainer> close_container_factory_; - // Whether or not we are currently tracking mouse events for this HWND - // using |::TrackMouseEvent| - bool tracking_mouse_events_; + // The flags currently being used with TrackMouseEvent to track mouse + // messages. 0 if there is no active tracking. The value of this member is + // used when tracking is canceled. + DWORD active_mouse_tracking_flags_; // Whether or not this is a top level window. bool toplevel_; |