Browse Source

refactor: better solution for resizable frameless DCHECK (#33974)

* refactor: better solution for resizable frameless DCHECK

* fix: also implement TargetForRectin WinFrameView

Co-authored-by: Shelley Vohr <[email protected]>
trop[bot] 3 years ago
parent
commit
eb3abf4c98

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

@@ -112,6 +112,16 @@ void FramelessView::UpdateWindowTitle() {}
 
 void FramelessView::SizeConstraintsChanged() {}
 
+views::View* FramelessView::TargetForRect(views::View* root,
+                                          const gfx::Rect& rect) {
+  CHECK_EQ(root, this);
+
+  if (NonClientHitTest(rect.origin()) != HTCLIENT)
+    return this;
+
+  return NonClientFrameView::TargetForRect(root, rect);
+}
+
 gfx::Size FramelessView::CalculatePreferredSize() const {
   return frame_->non_client_view()
       ->GetWindowBoundsForClientBounds(

+ 4 - 1
shell/browser/ui/views/frameless_view.h

@@ -47,7 +47,10 @@ class FramelessView : public views::NonClientFrameView {
   void UpdateWindowTitle() override;
   void SizeConstraintsChanged() override;
 
-  // Overridden from View:
+  // views::ViewTargeterDelegate:
+  views::View* TargetForRect(views::View* root, const gfx::Rect& rect) override;
+
+  // views::View:
   gfx::Size CalculatePreferredSize() const override;
   gfx::Size GetMinimumSize() const override;
   gfx::Size GetMaximumSize() const override;

+ 19 - 8
shell/browser/ui/views/win_frame_view.cc

@@ -34,14 +34,6 @@ void WinFrameView::Init(NativeWindowViews* window, views::Widget* frame) {
   window_ = window;
   frame_ = frame;
 
-  // Prevent events from trickling down the views hierarchy here, since
-  // when a given resizable window is frameless we only want to use
-  // FramelessView's ResizingBorderHitTest in
-  // ShouldDescendIntoChildForEventHandling. See
-  // https://chromium-review.googlesource.com/c/chromium/src/+/3251980.
-  if (!window_->has_frame() && window_->IsResizable())
-    frame_->client_view()->SetCanProcessEventsWithinSubtree(false);
-
   if (window->IsWindowControlsOverlayEnabled()) {
     caption_button_container_ =
         AddChildView(std::make_unique<WinCaptionButtonContainer>(this));
@@ -83,6 +75,25 @@ int WinFrameView::FrameBorderThickness() const {
              : display::win::ScreenWin::GetSystemMetricsInDIP(SM_CXSIZEFRAME);
 }
 
+views::View* WinFrameView::TargetForRect(views::View* root,
+                                         const gfx::Rect& rect) {
+  if (NonClientHitTest(rect.origin()) != HTCLIENT) {
+    // Custom system titlebar returns non HTCLIENT value, however event should
+    // be handled by the view, not by the system, because there are no system
+    // buttons underneath.
+    if (!ShouldCustomDrawSystemTitlebar()) {
+      return this;
+    }
+    auto local_point = rect.origin();
+    ConvertPointToTarget(parent(), caption_button_container_, &local_point);
+    if (!caption_button_container_->HitTestPoint(local_point)) {
+      return this;
+    }
+  }
+
+  return NonClientFrameView::TargetForRect(root, rect);
+}
+
 int WinFrameView::NonClientHitTest(const gfx::Point& point) {
   if (window_->has_frame())
     return frame_->client_view()->NonClientHitTest(point);

+ 3 - 0
shell/browser/ui/views/win_frame_view.h

@@ -61,6 +61,9 @@ class WinFrameView : public FramelessView {
 
   int FrameBorderThickness() const;
 
+  // views::ViewTargeterDelegate:
+  views::View* TargetForRect(views::View* root, const gfx::Rect& rect) override;
+
   // Returns the thickness of the window border for the top edge of the frame,
   // which is sometimes different than FrameBorderThickness(). Does not include
   // the titlebar/tabstrip area. If |restored| is true, this is calculated as if