electron/shell/browser/ui/views/frameless_view.cc
trop[bot] 0a73b80127
feat: enable Windows Control Overlay on Linux (#42681)
* feat: enable Windows Control Overlay on Linux

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* docs: update documentation for Linux WCO

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* fix: initial symbol painting

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* test: enable WCO tests for Linux

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* fix: add missing Layer include

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* chore: fix gn-check failure

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* fix: enable BrowserWindow.setTitleBarOverlay on Linux

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* test: fix test for maximize event on Linux

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* fix: geometry updating on BrowserWindow.setTitleBarOverlay

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* fix: crash when invalid titleBarStyle set

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* chore: clean up ordering and comments

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* Update docs/api/structures/base-window-options.md

Co-authored-by: Erick Zhao <erick@hotmail.ca>

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* feat: enable customizing symbolColor

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* docs: correct symbolColor reference

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>

* chore: remove Chrome-specific padding

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* fixup .patches after rebase

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2024-07-03 18:56:40 -04:00

136 lines
4.2 KiB
C++

// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/browser/ui/views/frameless_view.h"
#include "shell/browser/native_window_views.h"
#include "shell/browser/ui/inspectable_web_contents_view.h"
#include "ui/aura/window.h"
#include "ui/base/hit_test.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
namespace electron {
namespace {
const int kResizeInsideBoundsSize = 5;
const int kResizeAreaCornerSize = 16;
} // namespace
FramelessView::FramelessView() = default;
FramelessView::~FramelessView() = default;
void FramelessView::Init(NativeWindowViews* window, views::Widget* frame) {
window_ = window;
frame_ = frame;
}
int FramelessView::ResizingBorderHitTest(const gfx::Point& point) {
return ResizingBorderHitTestImpl(point, gfx::Insets(kResizeInsideBoundsSize));
}
int FramelessView::ResizingBorderHitTestImpl(const gfx::Point& point,
const gfx::Insets& resize_border) {
// to be used for resize handles.
bool can_ever_resize = frame_->widget_delegate()
? frame_->widget_delegate()->CanResize()
: false;
// https://github.com/electron/electron/issues/611
// If window isn't resizable, we should always return HTNOWHERE, otherwise the
// hover state of DOM will not be cleared probably.
if (!can_ever_resize)
return HTNOWHERE;
// Don't allow overlapping resize handles when the window is maximized or
// fullscreen, as it can't be resized in those states.
bool allow_overlapping_handles =
!frame_->IsMaximized() && !frame_->IsFullscreen();
return GetHTComponentForFrame(
point, allow_overlapping_handles ? resize_border : gfx::Insets(),
kResizeAreaCornerSize, kResizeAreaCornerSize, can_ever_resize);
}
gfx::Rect FramelessView::GetBoundsForClientView() const {
return bounds();
}
gfx::Rect FramelessView::GetWindowBoundsForClientBounds(
const gfx::Rect& client_bounds) const {
gfx::Rect window_bounds = client_bounds;
// Enforce minimum size (1, 1) in case that client_bounds is passed with
// empty size. This could occur when the frameless window is being
// initialized.
if (window_bounds.IsEmpty()) {
window_bounds.set_width(1);
window_bounds.set_height(1);
}
return window_bounds;
}
int FramelessView::NonClientHitTest(const gfx::Point& point) {
if (frame_->IsFullscreen())
return HTCLIENT;
int contents_hit_test = window_->NonClientHitTest(point);
if (contents_hit_test != HTNOWHERE)
return contents_hit_test;
// Support resizing frameless window by dragging the border.
int frame_component = ResizingBorderHitTest(point);
if (frame_component != HTNOWHERE)
return frame_component;
return HTCLIENT;
}
void FramelessView::GetWindowMask(const gfx::Size& size, SkPath* window_mask) {}
void FramelessView::ResetWindowControls() {}
void FramelessView::UpdateWindowIcon() {}
void FramelessView::InvalidateCaptionButtons() {}
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 views::SizeBounds& available_size) const {
return frame_->non_client_view()
->GetWindowBoundsForClientBounds(gfx::Rect(
frame_->client_view()->CalculatePreferredSize(available_size)))
.size();
}
gfx::Size FramelessView::GetMinimumSize() const {
return window_->GetContentMinimumSize();
}
gfx::Size FramelessView::GetMaximumSize() const {
gfx::Size size = window_->GetContentMaximumSize();
// Electron public APIs returns (0, 0) when maximum size is not set, but it
// would break internal window APIs like HWNDMessageHandler::SetAspectRatio.
return size.IsEmpty() ? gfx::Size(INT_MAX, INT_MAX) : size;
}
BEGIN_METADATA(FramelessView)
END_METADATA
} // namespace electron