| Flutter macOS Embedder |

FlutterWindowController.mm
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterWindowController.h"
6 #include <Foundation/Foundation.h>
7
8 #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterChannels.h"
9 #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h"
10 #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h"
11 #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h"
12
13 #include "flutter/shell/platform/common/isolate_scope.h"
14
15 // A delegate for a Flutter managed window.
16 @interface FlutterWindowOwner : NSObject <NSWindowDelegate, FlutterViewSizingDelegate> {
17 // Strong reference to the window. This is the only strong reference to the
18 // window.
19 NSWindow* _window;
20 FlutterViewController* _flutterViewController;
21 std::optional<flutter::Isolate> _isolate;
22 FlutterWindowCreationRequest _creationRequest;
23
24 // Extra size constraints coming from the window positioner.
25 CGSize _positionerSizeConstraints;
26 }
27
28 @property(readonly, nonatomic) NSWindow* window;
29 @property(readonly, nonatomic) FlutterViewController* flutterViewController;
30 @property(readwrite, nonatomic) BOOL closeWhenParentResignsKey;
31
32 - (instancetype)initWithWindow:(NSWindow*)window
33 flutterViewController:(FlutterViewController*)viewController
34 creationRequest:(const FlutterWindowCreationRequest&)creationRequest;
35
36 @end
37
38 @interface NSWindow (FlutterWindowSizing)
39
40 - (void)flutterSetContentSize:(FlutterWindowSize)contentSize;
41 - (void)flutterSetConstraints:(FlutterWindowConstraints)constraints;
42
43 @end
44
45 @implementation NSWindow (FlutterWindowSizing)
46 - (void)flutterSetContentSize:(FlutterWindowSize)contentSize {
47 [self setContentSize:NSMakeSize(contentSize.width, contentSize.height)];
48 }
49
50 - (void)flutterSetConstraints:(FlutterWindowConstraints)constraints {
51 NSSize size = [self frameRectForContentRect:self.frame].size;
52 NSSize originalSize = size;
53 [self setContentMinSize:NSMakeSize(constraints.min_width, constraints.min_height)];
54 size.width = std::max(size.width, constraints.min_width);
55 size.height = std::max(size.height, constraints.min_height);
56 if (constraints.max_width > 0 && constraints.max_height > 0) {
57 [self setContentMaxSize:NSMakeSize(constraints.max_width, constraints.max_height)];
58 size.width = std::min(size.width, constraints.max_width);
59 size.height = std::min(size.height, constraints.max_height);
60 } else {
61 [self setContentMaxSize:NSMakeSize(CGFLOAT_MAX, CGFLOAT_MAX)];
62 }
63 if (!NSEqualSizes(originalSize, size)) {
64 [self setContentSize:size];
65 }
66 }
67
68 @end
69
70 @interface FlutterWindowController () {
71 NSMutableArray<FlutterWindowOwner*>* _windows;
72 }
73
74 - (void)windowDidResignKey:(FlutterWindowOwner*)window;
75
76 @end
77
78 @implementation FlutterWindowOwner
79
80 @synthesize window = _window;
81 @synthesize flutterViewController = _flutterViewController;
82
83 - (instancetype)initWithWindow:(NSWindow*)window
84 flutterViewController:(FlutterViewController*)viewController
85 creationRequest:(const FlutterWindowCreationRequest&)creationRequest {
86 if (self = [super init]) {
87 _window = window;
88 _flutterViewController = viewController;
89 _creationRequest = creationRequest;
90 _isolate = flutter::Isolate::Current();
91 }
92 return self;
93 }
94
95 - (void)windowDidBecomeKey:(NSNotification*)notification {
96 [_flutterViewController.engine windowDidBecomeKey:_flutterViewController.viewIdentifier];
97 }
98
99 - (void)windowDidResignKey:(NSNotification*)notification {
100 [_flutterViewController.engine windowDidResignKey:_flutterViewController.viewIdentifier];
101 [[_flutterViewController.engine windowController] windowDidResignKey:self];
102 }
103
104 - (BOOL)windowShouldClose:(NSWindow*)sender {
105 flutter::IsolateScope isolate_scope(*_isolate);
106 _creationRequest.on_should_close();
107 return NO;
108 }
109
110 - (void)windowWillClose {
111 _creationRequest.on_will_close();
112 }
113
114 - (void)windowDidResize:(NSNotification*)notification {
115 flutter::IsolateScope isolate_scope(*_isolate);
116 _creationRequest.notify_listeners();
117 }
118
119 // Miniaturize does not trigger resize event, but for now there
120 // is no other way to get notification about the state change.
121 - (void)windowDidMiniaturize:(NSNotification*)notification {
122 flutter::IsolateScope isolate_scope(*_isolate);
123 _creationRequest.notify_listeners();
124 }
125
126 // Deminiaturize does not trigger resize event, but for now there
127 // is no other way to get notification about the state change.
128 - (void)windowDidDeminiaturize:(NSNotification*)notification {
129 flutter::IsolateScope isolate_scope(*_isolate);
130 _creationRequest.notify_listeners();
131 }
132
133 - (void)windowWillEnterFullScreen:(NSNotification*)notification {
134 flutter::IsolateScope isolate_scope(*_isolate);
135 _creationRequest.notify_listeners();
136 }
137
138 - (void)windowWillExitFullScreen:(NSNotification*)notification {
139 flutter::IsolateScope isolate_scope(*_isolate);
140 _creationRequest.notify_listeners();
141 }
142
143 - (std::optional<NSSize>)minimumViewSize:(FlutterView*)view {
144 if (_creationRequest.has_constraints) {
145 return NSMakeSize(_creationRequest.constraints.min_width,
146 _creationRequest.constraints.min_height);
147 } else {
148 return std::nullopt;
149 }
150 }
151
152 - (std::optional<NSSize>)maximumViewSize:(FlutterView*)view {
153 if (!_creationRequest.has_constraints) {
154 // Window is not sized to contents.
155 return std::nullopt;
156 }
157 NSSize screenSize = self.window.screen.visibleFrame.size;
158 double width = screenSize.width;
159 width = std::min(width, _creationRequest.constraints.max_width);
160 if (_positionerSizeConstraints.width > 0) {
161 width = std::min(width, _positionerSizeConstraints.width);
162 }
163 double height = screenSize.height;
164 height = std::min(height, _creationRequest.constraints.max_height);
165 if (_positionerSizeConstraints.height > 0) {
166 height = std::min(height, _positionerSizeConstraints.height);
167 }
168 return NSMakeSize(width, height);
169 }
170
171 // Returns the frame that includes all screen. This is used to flip coordinates
172 // of individual screen to match Flutter coordinate system.
173 static NSRect ComputeGlobalScreenFrame() {
174 NSRect frame = NSZeroRect;
175 for (NSScreen* screen in [NSScreen screens]) {
176 NSRect screenFrame = screen.frame;
177 if (NSIsEmptyRect(frame)) {
178 frame = screenFrame;
179 } else {
180 frame = NSUnionRect(frame, screenFrame);
181 }
182 }
183 return frame;
184 }
185
186 static void FlipRect(NSRect& rect, const NSRect& globalScreenFrame) {
187 // Flip the y coordinate to match Flutter coordinate system.
188 rect.origin.y = (globalScreenFrame.origin.y + globalScreenFrame.size.height) -
189 (rect.origin.y + rect.size.height);
190 }
191
192 - (void)updatePosition {
193 [self viewDidUpdateContents:self.flutterViewController.flutterView
194 withSize:self.flutterViewController.flutterView.bounds.size];
195 }
196
197 - (void)viewDidUpdateContents:(FlutterView*)view withSize:(NSSize)newSize {
198 if (_creationRequest.on_get_window_position == nullptr) {
199 // There is no positioner associated with this window.
200 return;
201 }
202
203 NSRect globalScreenFrame = ComputeGlobalScreenFrame();
204
205 NSRect parentRect =
206 [self.window.parentWindow contentRectForFrameRect:self.window.parentWindow.frame];
207 FlipRect(parentRect, globalScreenFrame);
208
209 NSRect screenRect = [self.window.screen visibleFrame];
210 FlipRect(screenRect, globalScreenFrame);
211
212 flutter::IsolateScope isolate_scope(*_isolate);
213 auto position = _creationRequest.on_get_window_position(
214 FlutterWindowSize::fromNSSize(newSize), FlutterWindowRect::fromNSRect(parentRect),
215 FlutterWindowRect::fromNSRect(screenRect));
216
217 NSRect positionRect = position->toNSRect();
218 FlipRect(positionRect, globalScreenFrame);
219
220 [self.window setFrame:positionRect display:NO animate:NO];
221
222 free(position);
223
224 // For windows sized to contents if the positioner size doesn't match actual size
225 // the requested size needs to be passed through constraints.
226 if (view.sizedToContents &&
227 (positionRect.size.width < newSize.width || positionRect.size.height < newSize.height)) {
228 _positionerSizeConstraints = positionRect.size;
229 [view constraintsDidChange];
230 } else {
231 // Only show the window initially if positioner agrees with the size.
232 self.window.alphaValue = 1.0;
233 }
234 }
235
236 - (void)setConstraints:(FlutterWindowConstraints)constraints {
237 if (_flutterViewController.flutterView.sizedToContents) {
238 self->_creationRequest.constraints = constraints;
239 [_flutterViewController.flutterView constraintsDidChange];
240 } else {
241 [self.window flutterSetConstraints:constraints];
242 }
243 }
244
245 @end
246
247 @interface FlutterPopupWindow : NSPanel
248 @end
249
250 @implementation FlutterPopupWindow
251
252 - (BOOL)canBecomeKeyWindow {
253 return NO;
254 }
255
256 - (BOOL)acceptsFirstResponder {
257 return NO;
258 }
259
260 - (BOOL)canBecomeMainWindow {
261 return NO;
262 }
263
264 @end
265
266 @implementation FlutterWindowController
267
268 - (instancetype)init {
269 self = [super init];
270 if (self != nil) {
271 _windows = [NSMutableArray array];
272 }
273 return self;
274 }
275
276 - (FlutterViewIdentifier)createDialogWindow:(const FlutterWindowCreationRequest*)request {
277 FlutterViewController* controller = [[FlutterViewController alloc] initWithEngine:_engine
278 nibName:nil
279 bundle:nil];
280
281 NSWindow* window = [[NSWindow alloc] init];
282 // If this is not set there will be double free on window close when
283 // using ARC.
284 [window setReleasedWhenClosed:NO];
285
286 window.contentViewController = controller;
287 window.styleMask =
288 NSWindowStyleMaskResizable | NSWindowStyleMaskTitled | NSWindowStyleMaskClosable;
289 window.collectionBehavior = NSWindowCollectionBehaviorFullScreenAuxiliary;
290 if (request->has_size) {
291 [window flutterSetContentSize:request->size];
292 }
293 if (request->has_constraints) {
294 [window flutterSetConstraints:request->constraints];
295 }
296
297 FlutterWindowOwner* owner = [[FlutterWindowOwner alloc] initWithWindow:window
298 flutterViewController:controller
299 creationRequest:*request];
300 window.delegate = owner;
301 [_windows addObject:owner];
302
303 NSWindow* parent = nil;
304
305 if (request->parent_view_id != 0) {
306 for (FlutterWindowOwner* owner in _windows) {
307 if (owner.flutterViewController.viewIdentifier == request->parent_view_id) {
308 parent = owner.window;
309 break;
310 }
311 }
312 if (parent == nil) {
313 FML_LOG(WARNING) << "Failed to find parent window for ID " << request->parent_view_id;
314 }
315 }
316
317 if (parent != nil) {
318 dispatch_async(dispatch_get_main_queue(), ^{
319 // beginCriticalSheet blocks with nested run loop until the
320 // sheet animation is finished.
321 [parent beginCriticalSheet:window
322 completionHandler:^(NSModalResponse response){
323 }];
324 });
325
326 } else {
327 [window setIsVisible:YES];
328 [window makeKeyAndOrderFront:nil];
329 }
330
331 return controller.viewIdentifier;
332 }
333
334 - (FlutterViewIdentifier)createTooltipWindow:(const FlutterWindowCreationRequest*)request {
335 FlutterViewController* controller = [[FlutterViewController alloc] initWithEngine:_engine
336 nibName:nil
337 bundle:nil];
338
339 NSWindow* window = [[NSWindow alloc] init];
340 // If this is not set there will be double free on window close when
341 // using ARC.
342 [window setReleasedWhenClosed:NO];
343
344 window.contentViewController = controller;
345 window.styleMask = NSWindowStyleMaskBorderless;
346 window.hasShadow = NO;
347 window.opaque = NO;
348 window.backgroundColor = [NSColor clearColor];
349
350 FlutterWindowOwner* owner = [[FlutterWindowOwner alloc] initWithWindow:window
351 flutterViewController:controller
352 creationRequest:*request];
353
354 controller.flutterView.sizingDelegate = owner;
355 controller.flutterView.backgroundColor = [NSColor clearColor];
356 // Resend configure event after setting the sizing delegate.
357 [controller.flutterView constraintsDidChange];
358 owner.closeWhenParentResignsKey = YES;
359
360 window.delegate = owner;
361 [_windows addObject:owner];
362
363 NSWindow* parent = nil;
364
365 FML_DCHECK(request->parent_view_id != 0);
366 for (FlutterWindowOwner* owner in _windows) {
367 if (owner.flutterViewController.viewIdentifier == request->parent_view_id) {
368 parent = owner.window;
369 break;
370 }
371 }
372
373 NSAssert(parent != nil, @"Tooltip window must have a parent window.");
374
375 window.ignoresMouseEvents = YES;
376 window.collectionBehavior = NSWindowCollectionBehaviorAuxiliary;
377 [parent addChildWindow:window ordered:NSWindowAbove];
378 window.alphaValue = 0.0;
379 return controller.viewIdentifier;
380 }
381
382 - (FlutterViewIdentifier)createPopupWindow:(const FlutterWindowCreationRequest*)request {
383 FlutterViewController* controller = [[FlutterViewController alloc] initWithEngine:_engine
384 nibName:nil
385 bundle:nil];
386 // By default this is kFlutterMouseTrackingModeInKeyWindow but popup window is never
387 // key window.
388 controller.mouseTrackingMode = kFlutterMouseTrackingModeInActiveApp;
389
390 NSWindow* window = [[FlutterPopupWindow alloc] init];
391 // If this is not set there will be double free on window close when
392 // using ARC.
393 [window setReleasedWhenClosed:NO];
394
395 window.contentViewController = controller;
396 window.styleMask = NSWindowStyleMaskBorderless;
397 window.hasShadow = NO;
398 window.opaque = NO;
399 window.backgroundColor = [NSColor clearColor];
400
401 FlutterWindowOwner* w = [[FlutterWindowOwner alloc] initWithWindow:window
402 flutterViewController:controller
403 creationRequest:*request];
404
405 controller.flutterView.sizingDelegate = w;
406 [controller.flutterView setBackgroundColor:[NSColor clearColor]];
407 // Resend configure event after setting the sizing delegate.
408 [controller.flutterView constraintsDidChange];
409 w.closeWhenParentResignsKey = NO;
410
411 window.delegate = w;
412 [_windows addObject:w];
413
414 NSWindow* parent = nil;
415
416 FML_DCHECK(request->parent_view_id != 0);
417 for (FlutterWindowOwner* owner in _windows) {
418 if (owner.flutterViewController.viewIdentifier == request->parent_view_id) {
419 parent = owner.window;
420 break;
421 }
422 }
423
424 NSAssert(parent != nil, @"Popup window must have a parent window.");
425
426 window.collectionBehavior = NSWindowCollectionBehaviorAuxiliary;
427 [parent addChildWindow:window ordered:NSWindowAbove];
428 window.alphaValue = 0.0;
429 return controller.viewIdentifier;
430 }
431
432 - (FlutterViewIdentifier)createRegularWindow:(const FlutterWindowCreationRequest*)request {
433 FlutterViewController* controller = [[FlutterViewController alloc] initWithEngine:_engine
434 nibName:nil
435 bundle:nil];
436
437 NSWindow* window = [[NSWindow alloc] init];
438 // If this is not set there will be double free on window close when
439 // using ARC.
440 [window setReleasedWhenClosed:NO];
441
442 window.contentViewController = controller;
443 window.styleMask = NSWindowStyleMaskResizable | NSWindowStyleMaskTitled |
444 NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable;
445 if (request->has_size) {
446 [window flutterSetContentSize:request->size];
447 }
448 if (request->has_constraints) {
449 [window flutterSetConstraints:request->constraints];
450 }
451 [window setIsVisible:YES];
452 [window makeKeyAndOrderFront:nil];
453
454 FlutterWindowOwner* owner = [[FlutterWindowOwner alloc] initWithWindow:window
455 flutterViewController:controller
456 creationRequest:*request];
457 window.delegate = owner;
458 [_windows addObject:owner];
459
460 return controller.viewIdentifier;
461 }
462
463 - (void)destroyWindow:(NSWindow*)window {
464 FlutterWindowOwner* owner = nil;
465 for (FlutterWindowOwner* o in _windows) {
466 if (o.window == window) {
467 owner = o;
468 break;
469 }
470 }
471 if (owner != nil) {
472 [_windows removeObject:owner];
473 for (NSWindow* win in owner.window.sheets) {
474 [self destroyWindow:win];
475 }
476
477 for (NSWindow* win in owner.window.childWindows) {
478 [self destroyWindow:win];
479 }
480 // Make sure to unregister the controller from the engine and remove the FlutterView
481 // before destroying the window and Flutter NSView.
482 [owner.flutterViewController dispose];
483 owner.window.delegate = nil;
484 [owner.window close];
485 [owner windowWillClose];
486 }
487 }
488
489 - (void)closeAllWindows {
490 for (FlutterWindowOwner* owner in _windows) {
491 [owner.flutterViewController dispose];
492 [owner.window close];
493 }
494 [_windows removeAllObjects];
495 }
496
497 static BOOL IsChildAncestor(NSWindow* child, NSWindow* ancestor) {
498 NSWindow* current = child.parentWindow;
499 while (current) {
500 if (current == ancestor) {
501 return YES;
502 }
503 current = current.parentWindow;
504 }
505
506 return NO;
507 }
508
509 - (void)windowDidResignKey:(FlutterWindowOwner*)parent {
510 for (FlutterWindowOwner* possibleChild in _windows) {
511 if (possibleChild.closeWhenParentResignsKey &&
512 IsChildAncestor(possibleChild.window, parent.window)) {
513 [possibleChild windowShouldClose:possibleChild.window];
514 }
515 }
516 }
517
518 @end
519
520 // NOLINTBEGIN(google-objc-function-naming)
521
522 int64_t InternalFlutter_WindowController_CreateRegularWindow(
523 int64_t engine_id,
524 const FlutterWindowCreationRequest* request) {
525 FlutterEngine* engine = [FlutterEngine engineForIdentifier:engine_id];
526 [engine enableMultiView];
527 return [engine.windowController createRegularWindow:request];
528 }
529
530 int64_t InternalFlutter_WindowController_CreateDialogWindow(
531 int64_t engine_id,
532 const FlutterWindowCreationRequest* request) {
533 FlutterEngine* engine = [FlutterEngine engineForIdentifier:engine_id];
534 [engine enableMultiView];
535 return [engine.windowController createDialogWindow:request];
536 }
537
538 int64_t InternalFlutter_WindowController_CreateTooltipWindow(
539 int64_t engine_id,
540 const FlutterWindowCreationRequest* request) {
541 FlutterEngine* engine = [FlutterEngine engineForIdentifier:engine_id];
542 [engine enableMultiView];
543 return [engine.windowController createTooltipWindow:request];
544 }
545
546 int64_t InternalFlutter_WindowController_CreatePopupWindow(
547 int64_t engine_id,
548 const FlutterWindowCreationRequest* request) {
549 FlutterEngine* engine = [FlutterEngine engineForIdentifier:engine_id];
550 [engine enableMultiView];
551 return [engine.windowController createPopupWindow:request];
552 }
553
554 void InternalFlutter_Window_Destroy(int64_t engine_id, void* window) {
555 NSWindow* w = (__bridge NSWindow*)window;
556 FlutterEngine* engine = [FlutterEngine engineForIdentifier:engine_id];
557 [engine.windowController destroyWindow:w];
558 }
559
560 void* InternalFlutter_Window_GetHandle(int64_t engine_id, FlutterViewIdentifier view_id) {
561 FlutterEngine* engine = [FlutterEngine engineForIdentifier:engine_id];
562 FlutterViewController* controller = [engine viewControllerForIdentifier:view_id];
563 return (__bridge void*)controller.view.window;
564 }
565
566 FlutterWindowSize InternalFlutter_Window_GetContentSize(void* window) {
567 NSWindow* w = (__bridge NSWindow*)window;
568 NSRect contentRect = [w contentRectForFrameRect:w.frame];
569 return {
570 .width = contentRect.size.width,
571 .height = contentRect.size.height,
572 };
573 }
574
575 void InternalFlutter_Window_SetContentSize(void* window, const FlutterWindowSize* size) {
576 NSWindow* w = (__bridge NSWindow*)window;
577 [w flutterSetContentSize:*size];
578 }
579
580 FLUTTER_DARWIN_EXPORT
581 void InternalFlutter_Window_SetConstraints(void* window,
582 const FlutterWindowConstraints* constraints) {
583 NSWindow* w = (__bridge NSWindow*)window;
584 FlutterWindowOwner* owner = (FlutterWindowOwner*)w.delegate;
585 [owner setConstraints:*constraints];
586 }
587
588 void InternalFlutter_Window_SetTitle(void* window, const char* title) {
589 NSWindow* w = (__bridge NSWindow*)window;
590 w.title = [NSString stringWithUTF8String:title];
591 }
592
593 void InternalFlutter_Window_SetMaximized(void* window, bool maximized) {
594 NSWindow* w = (__bridge NSWindow*)window;
595 if (maximized & !w.isZoomed) {
596 [w zoom:nil];
597 } else if (!maximized && w.isZoomed) {
598 [w zoom:nil];
599 }
600 }
601
602 bool InternalFlutter_Window_IsMaximized(void* window) {
603 NSWindow* w = (__bridge NSWindow*)window;
604 return w.isZoomed;
605 }
606
607 void InternalFlutter_Window_Minimize(void* window) {
608 NSWindow* w = (__bridge NSWindow*)window;
609 [w miniaturize:nil];
610 }
611
612 void InternalFlutter_Window_Unminimize(void* window) {
613 NSWindow* w = (__bridge NSWindow*)window;
614 [w deminiaturize:nil];
615 }
616
617 bool InternalFlutter_Window_IsMinimized(void* window) {
618 NSWindow* w = (__bridge NSWindow*)window;
619 return w.isMiniaturized;
620 }
621
622 void InternalFlutter_Window_SetFullScreen(void* window, bool fullScreen) {
623 NSWindow* w = (__bridge NSWindow*)window;
624 bool isFullScreen = (w.styleMask & NSWindowStyleMaskFullScreen) != 0;
625 if (fullScreen && !isFullScreen) {
626 [w toggleFullScreen:nil];
627 } else if (!fullScreen && isFullScreen) {
628 [w toggleFullScreen:nil];
629 }
630 }
631
632 bool InternalFlutter_Window_IsFullScreen(void* window) {
633 NSWindow* w = (__bridge NSWindow*)window;
634 return (w.styleMask & NSWindowStyleMaskFullScreen) != 0;
635 }
636
637 void InternalFlutter_Window_Activate(void* window) {
638 NSWindow* w = (__bridge NSWindow*)window;
639 [NSApplication.sharedApplication activateIgnoringOtherApps:YES];
640 [w makeKeyAndOrderFront:nil];
641 }
642
643 char* InternalFlutter_Window_GetTitle(void* window) {
644 NSWindow* w = (__bridge NSWindow*)window;
645 return strdup(w.title.UTF8String);
646 }
647
648 bool InternalFlutter_Window_IsActivated(void* window) {
649 NSWindow* w = (__bridge NSWindow*)window;
650 return w.isKeyWindow;
651 }
652
653 void InternalFlutter_Window_UpdatePosition(void* window) {
654 NSWindow* w = (__bridge NSWindow*)window;
655 FlutterWindowOwner* owner = (FlutterWindowOwner*)w.delegate;
656 [owner updatePosition];
657 }
658
659 FlutterWindowOffset InternalFlutter_Window_GetOffsetInParent(void* window) {
660 NSWindow* w = (__bridge NSWindow*)window;
661 NSWindow* parent = w.parentWindow;
662 if (!parent) {
663 return {0, 0};
664 }
665 NSRect globalScreenFrame = ComputeGlobalScreenFrame();
666
667 NSRect parentRect = [parent contentRectForFrameRect:parent.frame];
668 FlipRect(parentRect, globalScreenFrame);
669
670 NSRect childRect = w.frame;
671 FlipRect(childRect, globalScreenFrame);
672
673 return {
674 .x = childRect.origin.x - parentRect.origin.x,
675 .y = childRect.origin.y - parentRect.origin.y,
676 };
677 }
678
679 // NOLINTEND(google-objc-function-naming)
FlutterChannels.h
FlutterCodecs.h
FlutterEngine_Internal.h
FLUTTER_DARWIN_EXPORT
#define FLUTTER_DARWIN_EXPORT
Definition: FlutterMacros.h:14
FlutterViewIdentifier
int64_t FlutterViewIdentifier
Definition: FlutterViewController.h:21
FlutterViewController_Internal.h
FlutterWindowController.h
InternalFlutter_Window_Activate
void InternalFlutter_Window_Activate(void *window)
Definition: FlutterWindowController.mm:637
InternalFlutter_Window_GetHandle
void * InternalFlutter_Window_GetHandle(int64_t engine_id, FlutterViewIdentifier view_id)
Definition: FlutterWindowController.mm:560
InternalFlutter_Window_IsMaximized
bool InternalFlutter_Window_IsMaximized(void *window)
Definition: FlutterWindowController.mm:602
InternalFlutter_WindowController_CreateTooltipWindow
int64_t InternalFlutter_WindowController_CreateTooltipWindow(int64_t engine_id, const FlutterWindowCreationRequest *request)
Definition: FlutterWindowController.mm:538
InternalFlutter_WindowController_CreatePopupWindow
int64_t InternalFlutter_WindowController_CreatePopupWindow(int64_t engine_id, const FlutterWindowCreationRequest *request)
Definition: FlutterWindowController.mm:546
InternalFlutter_Window_SetConstraints
FLUTTER_DARWIN_EXPORT void InternalFlutter_Window_SetConstraints(void *window, const FlutterWindowConstraints *constraints)
Definition: FlutterWindowController.mm:581
InternalFlutter_Window_IsActivated
bool InternalFlutter_Window_IsActivated(void *window)
Definition: FlutterWindowController.mm:648
InternalFlutter_WindowController_CreateDialogWindow
int64_t InternalFlutter_WindowController_CreateDialogWindow(int64_t engine_id, const FlutterWindowCreationRequest *request)
Definition: FlutterWindowController.mm:530
InternalFlutter_Window_GetOffsetInParent
FlutterWindowOffset InternalFlutter_Window_GetOffsetInParent(void *window)
Definition: FlutterWindowController.mm:659
InternalFlutter_WindowController_CreateRegularWindow
int64_t InternalFlutter_WindowController_CreateRegularWindow(int64_t engine_id, const FlutterWindowCreationRequest *request)
Definition: FlutterWindowController.mm:522
InternalFlutter_Window_SetFullScreen
void InternalFlutter_Window_SetFullScreen(void *window, bool fullScreen)
Definition: FlutterWindowController.mm:622
InternalFlutter_Window_UpdatePosition
void InternalFlutter_Window_UpdatePosition(void *window)
Definition: FlutterWindowController.mm:653
InternalFlutter_Window_IsFullScreen
bool InternalFlutter_Window_IsFullScreen(void *window)
Definition: FlutterWindowController.mm:632
InternalFlutter_Window_SetContentSize
void InternalFlutter_Window_SetContentSize(void *window, const FlutterWindowSize *size)
Definition: FlutterWindowController.mm:575
InternalFlutter_Window_Minimize
void InternalFlutter_Window_Minimize(void *window)
Definition: FlutterWindowController.mm:607
InternalFlutter_Window_GetTitle
char * InternalFlutter_Window_GetTitle(void *window)
Definition: FlutterWindowController.mm:643
InternalFlutter_Window_SetTitle
void InternalFlutter_Window_SetTitle(void *window, const char *title)
Definition: FlutterWindowController.mm:588
InternalFlutter_Window_IsMinimized
bool InternalFlutter_Window_IsMinimized(void *window)
Definition: FlutterWindowController.mm:617
InternalFlutter_Window_Destroy
void InternalFlutter_Window_Destroy(int64_t engine_id, void *window)
Definition: FlutterWindowController.mm:554
InternalFlutter_Window_SetMaximized
void InternalFlutter_Window_SetMaximized(void *window, bool maximized)
Definition: FlutterWindowController.mm:593
InternalFlutter_Window_GetContentSize
FlutterWindowSize InternalFlutter_Window_GetContentSize(void *window)
Definition: FlutterWindowController.mm:566
InternalFlutter_Window_Unminimize
void InternalFlutter_Window_Unminimize(void *window)
Definition: FlutterWindowController.mm:612
FlutterWindowController()::_windows
NSMutableArray< FlutterWindowOwner * > * _windows
Definition: FlutterWindowController.mm:71
NSWindow(FlutterWindowSizing)
Definition: FlutterWindowController.mm:38
flutter::Isolate::Current
static Isolate Current()
Definition: isolate_scope.cc:9
flutter::IsolateScope
Definition: isolate_scope.h:33
FlutterEngine
Definition: FlutterEngine.h:32
FlutterPopupWindow
Definition: FlutterWindowController.mm:248
FlutterViewController
Definition: FlutterViewController.h:73
FlutterViewController::backgroundColor
NSColor * backgroundColor
Definition: FlutterViewController.h:210
FlutterViewController::mouseTrackingMode
FlutterMouseTrackingMode mouseTrackingMode
Definition: FlutterViewController.h:84
FlutterViewController::viewIdentifier
FlutterViewIdentifier viewIdentifier
Definition: FlutterViewController.h:130
FlutterView
Definition: FlutterView.h:69
FlutterView::sizedToContents
BOOL sizedToContents
Definition: FlutterView.h:121
-[FlutterView constraintsDidChange]
void constraintsDidChange()
Definition: FlutterView.mm:200
FlutterWindowController
Definition: FlutterWindowController.h:16
FlutterWindowController::engine
FlutterEngine * engine
Definition: FlutterWindowController.h:17
-[FlutterWindowController closeAllWindows]
void closeAllWindows()
Definition: FlutterWindowController.mm:489
FlutterWindowOwner
Definition: FlutterWindowController.mm:16
FlutterWindowOwner::_window
NSWindow * _window
Definition: FlutterWindowController.mm:19
FlutterWindowOwner::_flutterViewController
FlutterViewController * _flutterViewController
Definition: FlutterWindowController.mm:20
FlutterWindowOwner::window
NSWindow * window
Definition: FlutterWindowController.mm:28
FlutterWindowOwner::flutterViewController
FlutterViewController * flutterViewController
Definition: FlutterWindowController.mm:29
FlutterWindowOwner::_isolate
std::optional< flutter::Isolate > _isolate
Definition: FlutterWindowController.mm:21
FlutterWindowOwner::_positionerSizeConstraints
CGSize _positionerSizeConstraints
Definition: FlutterWindowController.mm:25
FlutterWindowOwner::_creationRequest
FlutterWindowCreationRequest _creationRequest
Definition: FlutterWindowController.mm:22
FlutterWindowOwner::closeWhenParentResignsKey
BOOL closeWhenParentResignsKey
Definition: FlutterWindowController.mm:30
isolate_scope.h
FlutterViewSizingDelegate-p
Definition: FlutterView.h:24
FlutterWindowConstraints
Definition: FlutterWindowController.h:65
FlutterWindowConstraints::max_width
double max_width
Definition: FlutterWindowController.h:68
FlutterWindowConstraints::min_height
double min_height
Definition: FlutterWindowController.h:67
FlutterWindowConstraints::max_height
double max_height
Definition: FlutterWindowController.h:69
FlutterWindowConstraints::min_width
double min_width
Definition: FlutterWindowController.h:66
FlutterWindowCreationRequest
Definition: FlutterWindowController.h:72
FlutterWindowCreationRequest::on_should_close
void(* on_should_close)()
Definition: FlutterWindowController.h:78
FlutterWindowCreationRequest::notify_listeners
void(* notify_listeners)()
Definition: FlutterWindowController.h:80
FlutterWindowCreationRequest::has_constraints
bool has_constraints
Definition: FlutterWindowController.h:75
FlutterWindowCreationRequest::constraints
struct FlutterWindowConstraints constraints
Definition: FlutterWindowController.h:76
FlutterWindowCreationRequest::on_get_window_position
FlutterWindowRect *(* on_get_window_position)(const FlutterWindowSize &child_size, const FlutterWindowRect &parent_rect, const FlutterWindowRect &output_rect)
Definition: FlutterWindowController.h:83
FlutterWindowCreationRequest::on_will_close
void(* on_will_close)()
Definition: FlutterWindowController.h:79
FlutterWindowOffset
Definition: FlutterWindowController.h:53
FlutterWindowRect::toNSRect
NSRect toNSRect() const
Definition: FlutterWindowController.h:38
FlutterWindowRect::fromNSRect
static FlutterWindowRect fromNSRect(const NSRect &rect)
Definition: FlutterWindowController.h:29
FlutterWindowSize
Definition: FlutterWindowController.h:41
FlutterWindowSize::fromNSSize
static FlutterWindowSize fromNSSize(const NSSize &size)
Definition: FlutterWindowController.h:45
FlutterWindowSize::width
double width
Definition: FlutterWindowController.h:42