/
frameless_view.cc
134 lines (104 loc) · 4.26 KB
/
frameless_view.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// 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_browser_view_views.h"
#include "shell/browser/native_window_views.h"
#include "ui/aura/window.h"
#include "ui/base/hit_test.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
// static
const char FramelessView::kViewClassName[] = "FramelessView";
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) {
// Check the frame first, as we allow a small area overlapping the contents
// 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.
int resize_border = frame_->IsMaximized() || frame_->IsFullscreen()
? 0
: kResizeInsideBoundsSize;
return GetHTComponentForFrame(point, gfx::Insets(resize_border),
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& 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;
}
// Support resizing frameless window by dragging the border.
int frame_component = ResizingBorderHitTest(cursor);
if (frame_component != HTNOWHERE)
return frame_component;
// 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;
}
void FramelessView::GetWindowMask(const gfx::Size& size, SkPath* window_mask) {}
void FramelessView::ResetWindowControls() {}
void FramelessView::UpdateWindowIcon() {}
void FramelessView::UpdateWindowTitle() {}
void FramelessView::SizeConstraintsChanged() {}
gfx::Size FramelessView::CalculatePreferredSize() const {
return frame_->non_client_view()
->GetWindowBoundsForClientBounds(
gfx::Rect(frame_->client_view()->GetPreferredSize()))
.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;
}
const char* FramelessView::GetClassName() const {
return kViewClassName;
}
} // namespace electron