From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Cheng Zhao <zcbenz@gmail.com>
Date: Mon, 26 Nov 2018 09:32:14 +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 d531234e480e8b67582f69105de9ec42d857d840..3cce23ef71563a8106b35dcbdf561acd33c22625 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<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)
@@ -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 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 <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 e6ac8301cffe14cc55445a89d2013b61739d7e1f..2fc7cd93d82acf377391fa727d3fdfbb31d304f6 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);
