Chromium Code Reviews| Index: ui/views/win/hwnd_message_handler.cc |
| diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc |
| index 6f80d3e568e2ca1dc1471d563356f850ec2bdc39..202b2c097426fcf5fa423e729034e0e553317253 100644 |
| --- a/ui/views/win/hwnd_message_handler.cc |
| +++ b/ui/views/win/hwnd_message_handler.cc |
| @@ -257,6 +257,20 @@ const int kSynthesizedMouseTouchMessagesTimeDifference = 500; |
| // it doesn't guard against direct visiblility changes, and multiple locks may |
| // exist simultaneously to handle certain nested Windows messages. |
| // |
| +// This lock is disabled when DirectComposition is used and there's a child |
| +// rendering window, as the WS_CLIPCHILDREN on the parent window should |
| +// prevent the glitched rendering and making the window contents non-visible |
| +// can cause a them to disappear for a frame. |
| +// |
| +// We normally skip locked updates when Aero is on for two reasons: |
| +// 1. Because it isn't necessary. However, for windows without WS_CAPTION a |
| +// close button may still be drawn, so the resize lock remains enabled for |
| +// them. See http://crrev.com/130323 |
| +// 2. Because toggling the WS_VISIBLE flag may occur while the GPU process is |
| +// attempting to present a child window's backbuffer onscreen. When these |
| +// two actions race with one another, the child window will either flicker |
| +// or will simply stop updating entirely. |
| +// |
| // IMPORTANT: Do not use this scoping object for large scopes or periods of |
| // time! IT WILL PREVENT THE WINDOW FROM BEING REDRAWN! (duh). |
| // |
| @@ -265,18 +279,20 @@ const int kSynthesizedMouseTouchMessagesTimeDifference = 500; |
| class HWNDMessageHandler::ScopedRedrawLock { |
| public: |
| explicit ScopedRedrawLock(HWNDMessageHandler* owner) |
| - : owner_(owner), |
| - hwnd_(owner_->hwnd()), |
| - was_visible_(owner_->IsVisible()), |
| - cancel_unlock_(false), |
| - force_(!(GetWindowLong(hwnd_, GWL_STYLE) & WS_CAPTION)) { |
| - if (was_visible_ && ::IsWindow(hwnd_)) |
| - owner_->LockUpdates(force_); |
| + : owner_(owner), |
| + hwnd_(owner_->hwnd()), |
| + was_visible_(owner_->IsVisible()), |
| + cancel_unlock_(false), |
| + should_lock_(!owner->HasChildRenderingWindow() && |
| + (!(GetWindowLong(hwnd_, GWL_STYLE) & WS_CAPTION) || |
| + !ui::win::IsAeroGlassEnabled())) { |
| + if (was_visible_ && should_lock_ && ::IsWindow(hwnd_)) |
|
sky
2016/11/29 18:05:19
Can should_lock_ include was_visible_ and ::IsWind
|
| + owner_->LockUpdates(); |
| } |
| ~ScopedRedrawLock() { |
| - if (!cancel_unlock_ && was_visible_ && ::IsWindow(hwnd_)) |
| - owner_->UnlockUpdates(force_); |
| + if (!cancel_unlock_ && was_visible_ && ::IsWindow(hwnd_) && should_lock_) |
| + owner_->UnlockUpdates(); |
| } |
| // Cancel the unlock operation, call this if the Widget is being destroyed. |
| @@ -291,8 +307,8 @@ class HWNDMessageHandler::ScopedRedrawLock { |
| bool was_visible_; |
| // A flag indicating that the unlock operation was canceled. |
| bool cancel_unlock_; |
| - // If true, perform the redraw lock regardless of Aero state. |
| - bool force_; |
| + // If false, don't use redraw lock. |
| + bool should_lock_; |
| DISALLOW_COPY_AND_ASSIGN(ScopedRedrawLock); |
| }; |
| @@ -1225,21 +1241,15 @@ LRESULT HWNDMessageHandler::DefWindowProcWithRedrawLock(UINT message, |
| return result; |
| } |
| -void HWNDMessageHandler::LockUpdates(bool force) { |
| - // We skip locked updates when Aero is on for two reasons: |
| - // 1. Because it isn't necessary |
| - // 2. Because toggling the WS_VISIBLE flag may occur while the GPU process is |
| - // attempting to present a child window's backbuffer onscreen. When these |
| - // two actions race with one another, the child window will either flicker |
| - // or will simply stop updating entirely. |
| - if ((force || !ui::win::IsAeroGlassEnabled()) && ++lock_updates_count_ == 1) { |
| +void HWNDMessageHandler::LockUpdates() { |
| + if (++lock_updates_count_ == 1) { |
| SetWindowLong(hwnd(), GWL_STYLE, |
| GetWindowLong(hwnd(), GWL_STYLE) & ~WS_VISIBLE); |
| } |
| } |
| -void HWNDMessageHandler::UnlockUpdates(bool force) { |
| - if ((force || !ui::win::IsAeroGlassEnabled()) && --lock_updates_count_ <= 0) { |
| +void HWNDMessageHandler::UnlockUpdates() { |
| + if (--lock_updates_count_ <= 0) { |
| SetWindowLong(hwnd(), GWL_STYLE, |
| GetWindowLong(hwnd(), GWL_STYLE) | WS_VISIBLE); |
| lock_updates_count_ = 0; |