From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon Nov 26 09:32:14 2018 +0900 Subject: fix_trackpad_scrolling.patch Backport https://chromium-review.googlesource.com/c/chromium/src/+/1299342. This patch fixes https://github.com/electron/electron/issues/8960, and can be removed after upgraded to Chrome 72. diff --git a/gpu/ipc/service/child_window_win.cc b/gpu/ipc/service/child_window_win.cc index 0f432fe2233e0ba90950f4ea9164d03df4ac9cf6..8bf56a44543be44cda74c341ba59dab87c8f69cb 100644 --- a/gpu/ipc/service/child_window_win.cc +++ b/gpu/ipc/service/child_window_win.cc @@ -9,7 +9,6 @@ #include "base/compiler_specific.h" #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" -#include "base/threading/thread.h" #include "base/win/scoped_hdc.h" #include "base/win/wrapped_window_proc.h" #include "gpu/ipc/common/gpu_messages.h" @@ -21,48 +20,10 @@ namespace gpu { -// This owns the thread and contains data that's shared between the threads. -struct SharedData { - SharedData() : thread("Window owner thread") {} - - base::Lock rect_lock; - gfx::Rect rect_to_clear; - - base::Thread thread; -}; - namespace { ATOM g_window_class; -// This runs on the window owner thread. -LRESULT CALLBACK IntermediateWindowProc(HWND window, - UINT message, - WPARAM w_param, - LPARAM l_param) { - switch (message) { - case WM_ERASEBKGND: - // Prevent windows from erasing the background. - return 1; - case WM_PAINT: - PAINTSTRUCT paint; - if (BeginPaint(window, &paint)) { - SharedData* shared_data = - reinterpret_cast(gfx::GetWindowUserData(window)); - DCHECK(shared_data); - { - base::AutoLock lock(shared_data->rect_lock); - shared_data->rect_to_clear.Union(gfx::Rect(paint.rcPaint)); - } - - EndPaint(window, &paint); - } - return 0; - default: - return DefWindowProc(window, message, w_param, l_param); - } -} - // This runs on the window owner thread. void InitializeWindowClass() { if (g_window_class) @@ -71,9 +32,9 @@ void InitializeWindowClass() { WNDCLASSEX intermediate_class; base::win::InitializeWindowClass( L"Intermediate D3D Window", - &base::win::WrappedWindowProc, CS_OWNDC, 0, 0, - nullptr, reinterpret_cast(GetStockObject(BLACK_BRUSH)), nullptr, - nullptr, nullptr, &intermediate_class); + &base::win::WrappedWindowProc<::DefWindowProc>, CS_OWNDC, 0, 0, nullptr, + reinterpret_cast(GetStockObject(BLACK_BRUSH)), nullptr, nullptr, + nullptr, &intermediate_class); g_window_class = RegisterClassEx(&intermediate_class); if (!g_window_class) { LOG(ERROR) << "RegisterClass failed."; @@ -122,7 +83,6 @@ class HiddenPopupWindow : public gfx::WindowImpl { // This runs on the window owner thread. void CreateWindowsOnThread(const gfx::Size& size, base::WaitableEvent* event, - SharedData* shared_data, HWND* child_window, HWND* parent_window) { InitializeWindowClass(); @@ -131,20 +91,25 @@ void CreateWindowsOnThread(const gfx::Size& size, // Create hidden parent window on the current thread. *parent_window = HiddenPopupWindow::Create(); // Create child window. + // WS_EX_NOPARENTNOTIFY and WS_EX_LAYERED make the window transparent for + // input. WS_EX_NOREDIRECTIONBITMAP avoids allocating a + // bitmap that would otherwise be allocated with WS_EX_LAYERED, the bitmap is + // only necessary if using Gdi objects with the window. HWND window = CreateWindowEx( - WS_EX_NOPARENTNOTIFY, reinterpret_cast(g_window_class), L"", + WS_EX_NOPARENTNOTIFY | WS_EX_LAYERED | WS_EX_TRANSPARENT | + WS_EX_NOREDIRECTIONBITMAP, + reinterpret_cast(g_window_class), L"", WS_CHILDWINDOW | WS_DISABLED | WS_VISIBLE, 0, 0, size.width(), size.height(), *parent_window, nullptr, nullptr, nullptr); CHECK(window); *child_window = window; - gfx::SetWindowUserData(window, shared_data); event->Signal(); } // This runs on the main thread after the window was destroyed on window owner // thread. -void DestroySharedData(std::unique_ptr shared_data) { - shared_data->thread.Stop(); +void DestroyThread(std::unique_ptr thread) { + thread->Stop(); } // This runs on the window owner thread. @@ -164,10 +129,9 @@ bool ChildWindowWin::Initialize() { if (window_) return true; - shared_data_ = std::make_unique(); - + thread_ = std::make_unique("Window owner thread"); base::Thread::Options options(base::MessageLoop::TYPE_UI, 0); - shared_data_->thread.StartWithOptions(options); + thread_->StartWithOptions(options); base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC, base::WaitableEvent::InitialState::NOT_SIGNALED); @@ -175,44 +139,30 @@ bool ChildWindowWin::Initialize() { RECT window_rect; GetClientRect(parent_window_, &window_rect); - shared_data_->thread.task_runner()->PostTask( + thread_->task_runner()->PostTask( FROM_HERE, base::Bind(&CreateWindowsOnThread, gfx::Rect(window_rect).size(), &event, - shared_data_.get(), &window_, &initial_parent_window_)); + &window_, &initial_parent_window_)); event.Wait(); delegate_->DidCreateAcceleratedSurfaceChildWindow(parent_window_, window_); return true; } -void ChildWindowWin::ClearInvalidContents() { - base::AutoLock lock(shared_data_->rect_lock); - if (!shared_data_->rect_to_clear.IsEmpty()) { - base::win::ScopedGetDC dc(window_); - - RECT rect = shared_data_->rect_to_clear.ToRECT(); - - // DirectComposition composites with the contents under the SwapChain, - // so ensure that's cleared. GDI treats black as transparent. - FillRect(dc, &rect, reinterpret_cast(GetStockObject(BLACK_BRUSH))); - shared_data_->rect_to_clear = gfx::Rect(); - } -} - ChildWindowWin::~ChildWindowWin() { - if (shared_data_) { - scoped_refptr task_runner = - shared_data_->thread.task_runner(); + if (thread_) { + scoped_refptr task_runner = thread_->task_runner(); task_runner->PostTaskAndReply( FROM_HERE, - base::Bind(&DestroyWindowsOnThread, window_, initial_parent_window_), - base::Bind(&DestroySharedData, base::Passed(std::move(shared_data_)))); + base::BindOnce(&DestroyWindowsOnThread, window_, + initial_parent_window_), + base::BindOnce(&DestroyThread, base::Passed(std::move(thread_)))); } } scoped_refptr ChildWindowWin::GetTaskRunnerForTesting() { - DCHECK(shared_data_); - return shared_data_->thread.task_runner(); + DCHECK(thread_); + return thread_->task_runner(); } } // namespace gpu diff --git a/gpu/ipc/service/child_window_win.h b/gpu/ipc/service/child_window_win.h index c11202b12da8fc540a78c3b13f731fc33d2d63b3..2b29fc641a810d2b521fa14e40da5bffb42ad722 100644 --- a/gpu/ipc/service/child_window_win.h +++ b/gpu/ipc/service/child_window_win.h @@ -7,14 +7,13 @@ #include "base/memory/weak_ptr.h" #include "base/task_runner.h" +#include "base/threading/thread.h" #include "gpu/ipc/service/image_transport_surface_delegate.h" #include namespace gpu { -struct SharedData; - // The window DirectComposition renders into needs to be owned by the process // that's currently doing the rendering. The class creates and owns a window // which is reparented by the browser to be a child of its window. @@ -25,15 +24,13 @@ class ChildWindowWin { ~ChildWindowWin(); bool Initialize(); - void ClearInvalidContents(); HWND window() const { return window_; } scoped_refptr GetTaskRunnerForTesting(); private: - // This member contains all the data that can be accessed from the main or - // window owner threads. - std::unique_ptr shared_data_; + // The window owner thread. + std::unique_ptr thread_; // The eventual parent of the window living in the browser process. HWND parent_window_; HWND window_; diff --git a/gpu/ipc/service/direct_composition_surface_win.cc b/gpu/ipc/service/direct_composition_surface_win.cc index da05d806bfa7e8710833eec7a2d85dfaeb9ed37a..761384364cb2544bc984f391b7c433e12fae1c33 100644 --- a/gpu/ipc/service/direct_composition_surface_win.cc +++ b/gpu/ipc/service/direct_composition_surface_win.cc @@ -1573,8 +1573,6 @@ gfx::SwapResult DirectCompositionSurfaceWin::SwapBuffers( gl::GLSurfacePresentationHelper::ScopedSwapBuffers scoped_swap_buffers( presentation_helper_.get(), callback); - child_window_.ClearInvalidContents(); - bool succeeded = true; if (root_surface_->SwapBuffers(PresentationCallback()) ==