From bc6f502b3fa917532fe8b886189fb124c982669e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 26 Nov 2018 09:33:40 +0900 Subject: [PATCH] fix: backport patch to fix scrolling problem --- patches/common/chromium/.patches | 1 + .../chromium/fix_trackpad_scrolling.patch | 241 ++++++++++++++++++ 2 files changed, 242 insertions(+) create mode 100644 patches/common/chromium/fix_trackpad_scrolling.patch diff --git a/patches/common/chromium/.patches b/patches/common/chromium/.patches index eb46624cd18c8..ef8938bc1222f 100644 --- a/patches/common/chromium/.patches +++ b/patches/common/chromium/.patches @@ -76,3 +76,4 @@ chrome_process_finder.patch customizable_app_indicator_id_prefix.patch cross_site_document_resource_handler.patch content_allow_embedder_to_prevent_locking_scheme_registry.patch +fix_trackpad_scrolling.patch diff --git a/patches/common/chromium/fix_trackpad_scrolling.patch b/patches/common/chromium/fix_trackpad_scrolling.patch new file mode 100644 index 0000000000000..d66bb6277adee --- /dev/null +++ b/patches/common/chromium/fix_trackpad_scrolling.patch @@ -0,0 +1,241 @@ +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 d531234..3cce23e 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,49 +20,11 @@ + + 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) + return; +@@ -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, NULL, NULL, NULL); + 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 c11202b..2b29fc6 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 e6ac830..2fc7cd93 100644 +--- a/gpu/ipc/service/direct_composition_surface_win.cc ++++ b/gpu/ipc/service/direct_composition_surface_win.cc +@@ -1541,8 +1541,6 @@ gfx::SwapResult DirectCompositionSurfaceWin::SwapBuffers( + gl::GLSurfacePresentationHelper::ScopedSwapBuffers scoped_swap_buffers( + presentation_helper_.get(), callback); + +- child_window_.ClearInvalidContents(); +- + if (root_surface_->SwapBuffers(PresentationCallback()) == + gfx::SwapResult::SWAP_FAILED) + scoped_swap_buffers.set_result(gfx::SwapResult::SWAP_FAILED);