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

* refactor: better solution for resizable frameless DCHECK

* fix: also implement TargetForRectin WinFrameView
This commit is contained in:
Shelley Vohr 2022-04-29 02:34:12 +02:00 committed by GitHub
parent 192a7fad0d
commit fb534c927a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 9 deletions

View file

@ -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(

View file

@ -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;

View file

@ -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);

View file

@ -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