/
atom_ns_window.mm
209 lines (172 loc) · 6.28 KB
/
atom_ns_window.mm
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
// Copyright (c) 2018 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/cocoa/atom_ns_window.h"
#include "base/strings/sys_string_conversions.h"
#include "shell/browser/native_window_mac.h"
#include "shell/browser/ui/cocoa/atom_preview_item.h"
#include "shell/browser/ui/cocoa/atom_touch_bar.h"
#include "shell/browser/ui/cocoa/root_view_mac.h"
#include "ui/base/cocoa/window_size_constants.h"
namespace electron {
bool ScopedDisableResize::disable_resize_ = false;
} // namespace electron
@implementation AtomNSWindow
@synthesize acceptsFirstMouse;
@synthesize enableLargerThanScreen;
@synthesize disableAutoHideCursor;
@synthesize disableKeyOrMainWindow;
@synthesize vibrantView;
- (id)initWithShell:(electron::NativeWindowMac*)shell
styleMask:(NSUInteger)styleMask {
if ((self = [super initWithContentRect:ui::kWindowSizeDeterminedLater
styleMask:styleMask
backing:NSBackingStoreBuffered
defer:YES])) {
shell_ = shell;
}
return self;
}
- (electron::NativeWindowMac*)shell {
return shell_;
}
- (id)accessibilityFocusedUIElement {
views::Widget* widget = shell_->widget();
id superFocus = [super accessibilityFocusedUIElement];
if (!widget || shell_->IsFocused())
return superFocus;
return nil;
}
- (NSRect)originalContentRectForFrameRect:(NSRect)frameRect {
return [super contentRectForFrameRect:frameRect];
}
- (NSTouchBar*)makeTouchBar API_AVAILABLE(macosx(10.12.2)) {
if (shell_->touch_bar())
return [shell_->touch_bar() makeTouchBar];
else
return nil;
}
// NSWindow overrides.
- (void)swipeWithEvent:(NSEvent*)event {
if (event.deltaY == 1.0) {
shell_->NotifyWindowSwipe("up");
} else if (event.deltaX == -1.0) {
shell_->NotifyWindowSwipe("right");
} else if (event.deltaY == -1.0) {
shell_->NotifyWindowSwipe("down");
} else if (event.deltaX == 1.0) {
shell_->NotifyWindowSwipe("left");
}
}
- (void)rotateWithEvent:(NSEvent*)event {
shell_->NotifyWindowRotateGesture(event.rotation);
}
- (NSRect)contentRectForFrameRect:(NSRect)frameRect {
if (shell_->has_frame())
return [super contentRectForFrameRect:frameRect];
else
return frameRect;
}
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen*)screen {
// Resizing is disabled.
if (electron::ScopedDisableResize::IsResizeDisabled())
return [self frame];
// Enable the window to be larger than screen.
if ([self enableLargerThanScreen])
return frameRect;
else
return [super constrainFrameRect:frameRect toScreen:screen];
}
- (void)setFrame:(NSRect)windowFrame display:(BOOL)displayViews {
// constrainFrameRect is not called on hidden windows so disable adjusting
// the frame directly when resize is disabled
if (!electron::ScopedDisableResize::IsResizeDisabled())
[super setFrame:windowFrame display:displayViews];
}
- (id)accessibilityAttributeValue:(NSString*)attribute {
if ([attribute isEqual:NSAccessibilityEnabledAttribute])
return [NSNumber numberWithBool:YES];
if (![attribute isEqualToString:@"AXChildren"])
return [super accessibilityAttributeValue:attribute];
// Filter out objects that aren't the title bar buttons. This has the effect
// of removing the window title, which VoiceOver already sees.
// * when VoiceOver is disabled, this causes Cmd+C to be used for TTS but
// still leaves the buttons available in the accessibility tree.
// * when VoiceOver is enabled, the full accessibility tree is used.
// Without removing the title and with VO disabled, the TTS would always read
// the window title instead of using Cmd+C to get the selected text.
NSPredicate* predicate = [NSPredicate
predicateWithFormat:@"(self isKindOfClass: %@) OR (self.className == %@)",
[NSButtonCell class], @"RenderWidgetHostViewCocoa"];
NSArray* children = [super accessibilityAttributeValue:attribute];
return [children filteredArrayUsingPredicate:predicate];
}
- (NSString*)accessibilityTitle {
return base::SysUTF8ToNSString(shell_->GetTitle());
}
- (BOOL)canBecomeMainWindow {
return !self.disableKeyOrMainWindow;
}
- (BOOL)canBecomeKeyWindow {
return !self.disableKeyOrMainWindow;
}
- (NSView*)frameView {
return [[self contentView] superview];
}
// Quicklook methods
- (BOOL)acceptsPreviewPanelControl:(QLPreviewPanel*)panel {
return YES;
}
- (void)beginPreviewPanelControl:(QLPreviewPanel*)panel {
panel.delegate = [self delegate];
panel.dataSource = static_cast<id<QLPreviewPanelDataSource>>([self delegate]);
}
- (void)endPreviewPanelControl:(QLPreviewPanel*)panel {
panel.delegate = nil;
panel.dataSource = nil;
}
// Custom window button methods
- (BOOL)windowShouldClose:(id)sender {
return YES;
}
- (void)performClose:(id)sender {
if (shell_->title_bar_style() ==
electron::NativeWindowMac::TitleBarStyle::CUSTOM_BUTTONS_ON_HOVER) {
[[self delegate] windowShouldClose:self];
} else if (shell_->IsSimpleFullScreen()) {
if ([[self delegate] respondsToSelector:@selector(windowShouldClose:)]) {
if (![[self delegate] windowShouldClose:self])
return;
} else if ([self respondsToSelector:@selector(windowShouldClose:)]) {
if (![self windowShouldClose:self])
return;
}
[self close];
} else {
[super performClose:sender];
}
}
- (void)toggleFullScreenMode:(id)sender {
bool is_simple_fs = shell_->IsSimpleFullScreen();
bool always_simple_fs = shell_->always_simple_fullscreen();
// If we're in simple fullscreen mode and trying to exit it
// we need to ensure we exit it properly to prevent a crash
// with NSWindowStyleMaskTitled mode.
if (is_simple_fs || always_simple_fs) {
shell_->SetSimpleFullScreen(!is_simple_fs);
} else {
bool maximizable = shell_->IsMaximizable();
[super toggleFullScreen:sender];
// Exiting fullscreen causes Cocoa to redraw the NSWindow, which resets
// the enabled state for NSWindowZoomButton. We need to persist it.
shell_->SetMaximizable(maximizable);
}
}
- (void)performMiniaturize:(id)sender {
if (shell_->title_bar_style() ==
electron::NativeWindowMac::TitleBarStyle::CUSTOM_BUTTONS_ON_HOVER)
[self miniaturize:self];
else
[super performMiniaturize:sender];
}
@end