|
@@ -0,0 +1,241 @@
|
|
|
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
+From: Cheng Zhao <[email protected]>
|
|
|
+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<SharedData*>(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<IntermediateWindowProc>, CS_OWNDC, 0, 0,
|
|
|
+- nullptr, reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)), nullptr,
|
|
|
+- nullptr, nullptr, &intermediate_class);
|
|
|
++ &base::win::WrappedWindowProc<::DefWindowProc>, CS_OWNDC, 0, 0, nullptr,
|
|
|
++ reinterpret_cast<HBRUSH>(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<wchar_t*>(g_window_class), L"",
|
|
|
++ WS_EX_NOPARENTNOTIFY | WS_EX_LAYERED | WS_EX_TRANSPARENT |
|
|
|
++ WS_EX_NOREDIRECTIONBITMAP,
|
|
|
++ reinterpret_cast<wchar_t*>(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<SharedData> shared_data) {
|
|
|
+- shared_data->thread.Stop();
|
|
|
++void DestroyThread(std::unique_ptr<base::Thread> 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<SharedData>();
|
|
|
+-
|
|
|
++ thread_ = std::make_unique<base::Thread>("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<HBRUSH>(GetStockObject(BLACK_BRUSH)));
|
|
|
+- shared_data_->rect_to_clear = gfx::Rect();
|
|
|
+- }
|
|
|
+-}
|
|
|
+-
|
|
|
+ ChildWindowWin::~ChildWindowWin() {
|
|
|
+- if (shared_data_) {
|
|
|
+- scoped_refptr<base::TaskRunner> task_runner =
|
|
|
+- shared_data_->thread.task_runner();
|
|
|
++ if (thread_) {
|
|
|
++ scoped_refptr<base::TaskRunner> 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<base::TaskRunner> 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 <windows.h>
|
|
|
+
|
|
|
+ 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<base::TaskRunner> GetTaskRunnerForTesting();
|
|
|
+
|
|
|
+ private:
|
|
|
+- // This member contains all the data that can be accessed from the main or
|
|
|
+- // window owner threads.
|
|
|
+- std::unique_ptr<SharedData> shared_data_;
|
|
|
++ // The window owner thread.
|
|
|
++ std::unique_ptr<base::Thread> 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);
|