Browse Source

fix: draggable views on BrowserViews on Windows (#27222)

Shelley Vohr 4 years ago
parent
commit
079251f168

+ 23 - 0
shell/browser/native_browser_view_views.cc

@@ -4,6 +4,11 @@
 
 #include "shell/browser/native_browser_view_views.h"
 
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "shell/browser/ui/drag_util.h"
 #include "shell/browser/ui/inspectable_web_contents_view.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/views/background.h"
@@ -22,6 +27,24 @@ void NativeBrowserViewViews::SetAutoResizeFlags(uint8_t flags) {
   ResetAutoResizeProportions();
 }
 
+void NativeBrowserViewViews::UpdateDraggableRegions(
+    const std::vector<mojom::DraggableRegionPtr>& regions) {
+  // We need to snap the regions to the bounds of the current BrowserView.
+  // For example, if an attached BrowserView is draggable but its bounds are
+  // { x: 200,  y: 100, width: 300, height: 300 }
+  // then we need to add 200 to the x-value and 100 to the
+  // y-value of each of the passed regions or it will be incorrectly
+  // assumed that the regions begin in the top left corner as they
+  // would for the main client window.
+  auto const offset = GetBounds().OffsetFromOrigin();
+  auto snapped_regions = mojo::Clone(regions);
+  for (auto& snapped_region : snapped_regions) {
+    snapped_region->bounds.Offset(offset);
+  }
+
+  draggable_region_ = DraggableRegionsToSkRegion(snapped_regions);
+}
+
 void NativeBrowserViewViews::SetAutoResizeProportions(
     const gfx::Size& window_size) {
   if ((auto_resize_flags_ & AutoResizeFlags::kAutoResizeHorizontal) &&

+ 10 - 0
shell/browser/native_browser_view_views.h

@@ -5,7 +5,11 @@
 #ifndef SHELL_BROWSER_NATIVE_BROWSER_VIEW_VIEWS_H_
 #define SHELL_BROWSER_NATIVE_BROWSER_VIEW_VIEWS_H_
 
+#include <memory>
+#include <vector>
+
 #include "shell/browser/native_browser_view.h"
+#include "third_party/skia/include/core/SkRegion.h"
 
 namespace electron {
 
@@ -26,6 +30,10 @@ class NativeBrowserViewViews : public NativeBrowserView {
   void SetBounds(const gfx::Rect& bounds) override;
   gfx::Rect GetBounds() override;
   void SetBackgroundColor(SkColor color) override;
+  void UpdateDraggableRegions(
+      const std::vector<mojom::DraggableRegionPtr>& regions) override;
+
+  SkRegion* draggable_region() const { return draggable_region_.get(); }
 
  private:
   void ResetAutoResizeProportions();
@@ -40,6 +48,8 @@ class NativeBrowserViewViews : public NativeBrowserView {
   float auto_vertical_proportion_height_ = 0.;
   float auto_vertical_proportion_top_ = 0.;
 
+  std::unique_ptr<SkRegion> draggable_region_;
+
   DISALLOW_COPY_AND_ASSIGN(NativeBrowserViewViews);
 };
 

+ 10 - 0
shell/browser/native_window_views.cc

@@ -1411,6 +1411,16 @@ views::View* NativeWindowViews::GetContentsView() {
 bool NativeWindowViews::ShouldDescendIntoChildForEventHandling(
     gfx::NativeView child,
     const gfx::Point& location) {
+  // App window should claim mouse events that fall within any BrowserViews'
+  // draggable region.
+  for (auto* view : browser_views()) {
+    auto* native_view = static_cast<NativeBrowserViewViews*>(view);
+    auto* view_draggable_region = native_view->draggable_region();
+    if (view_draggable_region &&
+        view_draggable_region->contains(location.x(), location.y()))
+      return false;
+  }
+
   // App window should claim mouse events that fall within the draggable region.
   if (draggable_region() &&
       draggable_region()->contains(location.x(), location.y()))

+ 10 - 0
shell/browser/ui/views/frameless_view.cc

@@ -4,6 +4,7 @@
 
 #include "shell/browser/ui/views/frameless_view.h"
 
+#include "shell/browser/native_browser_view_views.h"
 #include "shell/browser/native_window_views.h"
 #include "ui/aura/window.h"
 #include "ui/base/hit_test.h"
@@ -68,6 +69,15 @@ int FramelessView::NonClientHitTest(const gfx::Point& cursor) {
   if (frame_->IsFullscreen())
     return HTCLIENT;
 
+  // Check attached BrowserViews for potential draggable areas.
+  for (auto* view : window_->browser_views()) {
+    auto* native_view = static_cast<NativeBrowserViewViews*>(view);
+    auto* view_draggable_region = native_view->draggable_region();
+    if (view_draggable_region &&
+        view_draggable_region->contains(cursor.x(), cursor.y()))
+      return HTCAPTION;
+  }
+
   // Check for possible draggable region in the client area for the frameless
   // window.
   SkRegion* draggable_region = window_->draggable_region();