2014-10-31 18:17:05 +00:00
|
|
|
// Copyright (c) 2014 GitHub, Inc.
|
2014-07-16 07:33:40 +00:00
|
|
|
// Use of this source code is governed by the MIT license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
2019-06-19 20:46:59 +00:00
|
|
|
#include "shell/browser/ui/views/frameless_view.h"
|
2014-07-16 07:33:40 +00:00
|
|
|
|
2020-12-01 23:03:00 +00:00
|
|
|
#include "shell/browser/native_browser_view_views.h"
|
2019-06-19 20:46:59 +00:00
|
|
|
#include "shell/browser/native_window_views.h"
|
2014-07-16 07:33:40 +00:00
|
|
|
#include "ui/aura/window.h"
|
2014-07-16 08:00:08 +00:00
|
|
|
#include "ui/base/hit_test.h"
|
2014-07-16 07:33:40 +00:00
|
|
|
#include "ui/views/widget/widget.h"
|
|
|
|
#include "ui/views/widget/widget_delegate.h"
|
|
|
|
|
2019-06-19 21:23:04 +00:00
|
|
|
namespace electron {
|
2014-07-16 07:33:40 +00:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
const int kResizeInsideBoundsSize = 5;
|
|
|
|
const int kResizeAreaCornerSize = 16;
|
2014-07-16 07:40:22 +00:00
|
|
|
|
2014-07-16 07:33:40 +00:00
|
|
|
} // namespace
|
|
|
|
|
2018-05-15 18:49:27 +00:00
|
|
|
// static
|
|
|
|
const char FramelessView::kViewClassName[] = "FramelessView";
|
|
|
|
|
2019-09-16 22:12:00 +00:00
|
|
|
FramelessView::FramelessView() = default;
|
2014-07-16 07:33:40 +00:00
|
|
|
|
2019-09-16 22:12:00 +00:00
|
|
|
FramelessView::~FramelessView() = default;
|
2014-07-16 07:33:40 +00:00
|
|
|
|
|
|
|
void FramelessView::Init(NativeWindowViews* window, views::Widget* frame) {
|
|
|
|
window_ = window;
|
|
|
|
frame_ = frame;
|
|
|
|
}
|
|
|
|
|
|
|
|
int FramelessView::ResizingBorderHitTest(const gfx::Point& point) {
|
|
|
|
// Check the frame first, as we allow a small area overlapping the contents
|
|
|
|
// to be used for resize handles.
|
2018-04-18 01:55:30 +00:00
|
|
|
bool can_ever_resize = frame_->widget_delegate()
|
|
|
|
? frame_->widget_delegate()->CanResize()
|
|
|
|
: false;
|
2021-06-21 01:10:40 +00:00
|
|
|
|
|
|
|
// https://github.com/electron/electron/issues/611
|
|
|
|
// If window isn't resizable, we should always return HTCLIENT, otherwise the
|
|
|
|
// hover state of DOM will not be cleared probably.
|
|
|
|
if (!can_ever_resize)
|
|
|
|
return HTCLIENT;
|
|
|
|
|
2014-07-16 07:33:40 +00:00
|
|
|
// Don't allow overlapping resize handles when the window is maximized or
|
|
|
|
// fullscreen, as it can't be resized in those states.
|
2018-04-18 01:55:30 +00:00
|
|
|
int resize_border = frame_->IsMaximized() || frame_->IsFullscreen()
|
|
|
|
? 0
|
|
|
|
: kResizeInsideBoundsSize;
|
2021-07-06 12:17:13 +00:00
|
|
|
return GetHTComponentForFrame(point, gfx::Insets(resize_border),
|
2018-04-18 01:55:30 +00:00
|
|
|
kResizeAreaCornerSize, kResizeAreaCornerSize,
|
|
|
|
can_ever_resize);
|
2014-07-16 07:33:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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& cursor) {
|
|
|
|
if (frame_->IsFullscreen())
|
|
|
|
return HTCLIENT;
|
|
|
|
|
2020-12-01 23:03:00 +00:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2021-08-11 18:07:36 +00:00
|
|
|
// Support resizing frameless window by dragging the border.
|
|
|
|
int frame_component = ResizingBorderHitTest(cursor);
|
|
|
|
if (frame_component != HTNOWHERE)
|
|
|
|
return frame_component;
|
|
|
|
|
2014-07-16 07:33:40 +00:00
|
|
|
// Check for possible draggable region in the client area for the frameless
|
|
|
|
// window.
|
|
|
|
SkRegion* draggable_region = window_->draggable_region();
|
|
|
|
if (draggable_region && draggable_region->contains(cursor.x(), cursor.y()))
|
|
|
|
return HTCAPTION;
|
|
|
|
|
|
|
|
return HTCLIENT;
|
|
|
|
}
|
|
|
|
|
2019-01-31 22:14:32 +00:00
|
|
|
void FramelessView::GetWindowMask(const gfx::Size& size, SkPath* window_mask) {}
|
2014-07-16 07:33:40 +00:00
|
|
|
|
2018-04-18 01:55:30 +00:00
|
|
|
void FramelessView::ResetWindowControls() {}
|
2014-07-16 07:33:40 +00:00
|
|
|
|
2018-04-18 01:55:30 +00:00
|
|
|
void FramelessView::UpdateWindowIcon() {}
|
2014-07-16 07:33:40 +00:00
|
|
|
|
2018-04-18 01:55:30 +00:00
|
|
|
void FramelessView::UpdateWindowTitle() {}
|
2014-07-16 07:33:40 +00:00
|
|
|
|
2018-04-18 01:55:30 +00:00
|
|
|
void FramelessView::SizeConstraintsChanged() {}
|
2014-12-10 00:52:11 +00:00
|
|
|
|
2017-09-12 15:32:11 +00:00
|
|
|
gfx::Size FramelessView::CalculatePreferredSize() const {
|
2018-04-18 01:55:30 +00:00
|
|
|
return frame_->non_client_view()
|
|
|
|
->GetWindowBoundsForClientBounds(
|
|
|
|
gfx::Rect(frame_->client_view()->GetPreferredSize()))
|
|
|
|
.size();
|
2014-07-16 07:33:40 +00:00
|
|
|
}
|
|
|
|
|
2014-09-01 12:10:14 +00:00
|
|
|
gfx::Size FramelessView::GetMinimumSize() const {
|
2018-05-12 15:37:31 +00:00
|
|
|
return window_->GetContentMinimumSize();
|
2014-07-16 07:33:40 +00:00
|
|
|
}
|
|
|
|
|
2014-09-01 12:10:14 +00:00
|
|
|
gfx::Size FramelessView::GetMaximumSize() const {
|
2021-01-05 08:17:33 +00:00
|
|
|
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;
|
2014-07-16 07:33:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const char* FramelessView::GetClassName() const {
|
|
|
|
return kViewClassName;
|
|
|
|
}
|
|
|
|
|
2019-06-19 21:23:04 +00:00
|
|
|
} // namespace electron
|