summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorbeng@google.com <beng@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-08 04:12:45 +0000
committerbeng@google.com <beng@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-08 04:12:45 +0000
commitc2176e789af9629724d538b0ccc5ede157f7cb5a (patch)
tree4192edbfc21d9b0cee97eaed2144009c53733dad /chrome
parent19b8e5925bb7fc2d76d9afa8b97408020c556ad6 (diff)
downloadchromium_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.cc39
-rw-r--r--chrome/views/custom_frame_window.h2
-rw-r--r--chrome/views/hwnd_view_container.cc45
-rw-r--r--chrome/views/hwnd_view_container.h22
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_;