Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
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
6#include <Foundation/Foundation.h>
7
12
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;
21 std::optional<flutter::Isolate> _isolate;
23
24 // Extra size constraints coming from the window positioner.
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
71 NSMutableArray<FlutterWindowOwner*>* _windows;
73}
74
75- (void)windowDidResignKey:(FlutterWindowOwner*)window;
76
77@end
78
79@implementation FlutterWindowOwner
80
81@synthesize window = _window;
82@synthesize flutterViewController = _flutterViewController;
83
84- (instancetype)initWithWindow:(NSWindow*)window
85 flutterViewController:(FlutterViewController*)viewController
86 creationRequest:(const FlutterWindowCreationRequest&)creationRequest {
87 if (self = [super init]) {
88 _window = window;
90 _creationRequest = creationRequest;
91 _isolate = flutter::Isolate::Current();
92 }
93 return self;
94}
95
96- (void)windowDidBecomeKey:(NSNotification*)notification {
97 [_flutterViewController.engine windowDidBecomeKey:_flutterViewController.viewIdentifier];
98}
99
100- (void)windowDidResignKey:(NSNotification*)notification {
101 [_flutterViewController.engine windowDidResignKey:_flutterViewController.viewIdentifier];
102 [[_flutterViewController.engine windowController] windowDidResignKey:self];
103}
104
105- (BOOL)windowShouldClose:(NSWindow*)sender {
106 flutter::IsolateScope isolate_scope(*_isolate);
107 _creationRequest.on_should_close();
108 return NO;
109}
110
111- (void)windowWillClose {
112 _creationRequest.on_will_close();
113}
114
115- (void)windowDidResize:(NSNotification*)notification {
116 flutter::IsolateScope isolate_scope(*_isolate);
117 _creationRequest.notify_listeners();
118}
119
120// Miniaturize does not trigger resize event, but for now there
121// is no other way to get notification about the state change.
122- (void)windowDidMiniaturize:(NSNotification*)notification {
123 flutter::IsolateScope isolate_scope(*_isolate);
124 _creationRequest.notify_listeners();
125}
126
127// Deminiaturize does not trigger resize event, but for now there
128// is no other way to get notification about the state change.
129- (void)windowDidDeminiaturize:(NSNotification*)notification {
130 flutter::IsolateScope isolate_scope(*_isolate);
131 _creationRequest.notify_listeners();
132}
133
134- (void)windowWillEnterFullScreen:(NSNotification*)notification {
135 flutter::IsolateScope isolate_scope(*_isolate);
136 _creationRequest.notify_listeners();
137}
138
139- (void)windowWillExitFullScreen:(NSNotification*)notification {
140 flutter::IsolateScope isolate_scope(*_isolate);
141 _creationRequest.notify_listeners();
142}
143
144- (std::optional<NSSize>)minimumViewSize:(FlutterView*)view {
145 if (_creationRequest.has_constraints) {
146 return NSMakeSize(_creationRequest.constraints.min_width,
147 _creationRequest.constraints.min_height);
148 } else {
149 return std::nullopt;
150 }
151}
152
153- (std::optional<NSSize>)maximumViewSize:(FlutterView*)view {
154 if (!_creationRequest.has_constraints) {
155 // Window is not sized to contents.
156 return std::nullopt;
157 }
158 NSSize screenSize = self.window.screen.visibleFrame.size;
159 double width = screenSize.width;
160 width = std::min(width, _creationRequest.constraints.max_width);
161 if (_positionerSizeConstraints.width > 0) {
162 width = std::min(width, _positionerSizeConstraints.width);
163 }
164 double height = screenSize.height;
165 height = std::min(height, _creationRequest.constraints.max_height);
166 if (_positionerSizeConstraints.height > 0) {
167 height = std::min(height, _positionerSizeConstraints.height);
168 }
169 return NSMakeSize(width, height);
170}
171
172// Returns the frame that includes all screen. This is used to flip coordinates
173// of individual screen to match Flutter coordinate system.
174static NSRect ComputeGlobalScreenFrame() {
175 NSRect frame = NSZeroRect;
176 for (NSScreen* screen in [NSScreen screens]) {
177 NSRect screenFrame = screen.frame;
178 if (NSIsEmptyRect(frame)) {
179 frame = screenFrame;
180 } else {
181 frame = NSUnionRect(frame, screenFrame);
182 }
183 }
184 return frame;
185}
186
187static void FlipRect(NSRect& rect, const NSRect& globalScreenFrame) {
188 // Flip the y coordinate to match Flutter coordinate system.
189 rect.origin.y = (globalScreenFrame.origin.y + globalScreenFrame.size.height) -
190 (rect.origin.y + rect.size.height);
191}
192
193- (void)updatePosition {
194 [self viewDidUpdateContents:self.flutterViewController.flutterView
195 withSize:self.flutterViewController.flutterView.bounds.size];
196}
197
198- (void)viewDidUpdateContents:(FlutterView*)view withSize:(NSSize)newSize {
199 if (_creationRequest.on_get_window_position == nullptr) {
200 // There is no positioner associated with this window.
201 return;
202 }
203
204 NSRect globalScreenFrame = ComputeGlobalScreenFrame();
205
206 NSRect parentRect =
207 [self.window.parentWindow contentRectForFrameRect:self.window.parentWindow.frame];
208 FlipRect(parentRect, globalScreenFrame);
209
210 NSRect screenRect = [self.window.screen visibleFrame];
211 FlipRect(screenRect, globalScreenFrame);
212
213 flutter::IsolateScope isolate_scope(*_isolate);
214 auto position = _creationRequest.on_get_window_position(
217
218 NSRect positionRect = position->toNSRect();
219 FlipRect(positionRect, globalScreenFrame);
220
221 [self.window setFrame:positionRect display:NO animate:NO];
222
223 free(position);
224
225 // For windows sized to contents if the positioner size doesn't match actual size
226 // the requested size needs to be passed through constraints.
227 if (view.sizedToContents &&
228 (positionRect.size.width < newSize.width || positionRect.size.height < newSize.height)) {
229 _positionerSizeConstraints = positionRect.size;
231 } else {
232 // Only show the window initially if positioner agrees with the size.
233 self.window.alphaValue = 1.0;
234 }
235}
236
237- (void)setConstraints:(FlutterWindowConstraints)constraints {
238 if (_flutterViewController.flutterView.sizedToContents) {
239 self->_creationRequest.constraints = constraints;
240 [_flutterViewController.flutterView constraintsDidChange];
241 } else {
242 [self.window flutterSetConstraints:constraints];
243 }
244}
245
246@end
247
248@interface FlutterPopupWindow : NSPanel
249@end
250
251@implementation FlutterPopupWindow
252
253- (BOOL)canBecomeKeyWindow {
254 return NO;
255}
256
257- (BOOL)acceptsFirstResponder {
258 return NO;
259}
260
261- (BOOL)canBecomeMainWindow {
262 return NO;
263}
264
265@end
266
267@interface _FlutterRunLoopModeFixWindowDelegate : NSObject <NSWindowDelegate>
268@end
269
271
272- (NSRect)windowWillUseStandardFrame:(NSWindow*)window defaultFrame:(NSRect)newFrame {
273 // Small frame difference (100px to 110px) to trigger the animation but make it fast.
274 newFrame.size.width = 110;
275 newFrame.size.height = 110;
276 return newFrame;
277}
278
279@end
280
281@implementation FlutterWindowController
282
283- (instancetype)init {
284 self = [super init];
285 if (self != nil) {
286 _windows = [NSMutableArray array];
287 }
288 return self;
289}
290
291- (void)fixMoveRunLoopModeIfNeeded {
292 if (_runLoopModeFixApplied) {
293 return;
294 }
295 // When modal sheet is presented, for the duration of the animation the run loop
296 // is running in _NSMoveTimerRunLoopMode. This prevents Flutter content from
297 // being rendered. The solution is to add _NSMoveTimerRunLoopMode to common
298 // run loop modes, but referencing it directly may be flagged as SPI usage.
299 // Instead as a workaround a very short window zoom animation is triggered, which
300 // runs in _NSMoveTimerRunLoopMode adding the mode to CFRunLoop all modes list.
301 // After that it can be queried and added to common modes.
302 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100)
303 styleMask:NSWindowStyleMaskResizable
304 backing:NSBackingStoreNonretained
305 defer:NO];
308 window.releasedWhenClosed = NO;
309 window.delegate = delegate;
310 window.ignoresMouseEvents = YES;
311 window.alphaValue = 0;
312 [window orderFront:nil];
313 [window zoom:nil];
314 [window close];
315 NSArray* modes = (__bridge_transfer NSArray*)CFRunLoopCopyAllModes(CFRunLoopGetCurrent());
316 for (NSString* mode in modes) {
317 if ([mode hasSuffix:@"MoveTimerRunLoopMode"]) {
318 CFRunLoopAddCommonMode(CFRunLoopGetCurrent(), (__bridge CFStringRef)mode);
319 }
320 }
321 _runLoopModeFixApplied = YES;
322}
323
324- (FlutterViewIdentifier)createDialogWindow:(const FlutterWindowCreationRequest*)request {
325 FlutterViewController* controller = [[FlutterViewController alloc] initWithEngine:_engine
326 nibName:nil
327 bundle:nil];
328
329 NSWindow* window = [[NSWindow alloc] init];
330 // If this is not set there will be double free on window close when
331 // using ARC.
332 [window setReleasedWhenClosed:NO];
333
334 window.contentViewController = controller;
335 window.styleMask =
336 NSWindowStyleMaskResizable | NSWindowStyleMaskTitled | NSWindowStyleMaskClosable;
337 window.collectionBehavior = NSWindowCollectionBehaviorFullScreenAuxiliary;
338 if (request->has_size) {
339 [window flutterSetContentSize:request->size];
340 }
341 if (request->has_constraints) {
342 [window flutterSetConstraints:request->constraints];
343 }
344
345 FlutterWindowOwner* owner = [[FlutterWindowOwner alloc] initWithWindow:window
346 flutterViewController:controller
347 creationRequest:*request];
348 window.delegate = owner;
349 [_windows addObject:owner];
350
351 NSWindow* parent = nil;
352
353 if (request->parent_view_id != 0) {
354 for (FlutterWindowOwner* owner in _windows) {
355 if (owner.flutterViewController.viewIdentifier == request->parent_view_id) {
356 parent = owner.window;
357 break;
358 }
359 }
360 if (parent == nil) {
361 FML_LOG(WARNING) << "Failed to find parent window for ID " << request->parent_view_id;
362 }
363 }
364
365 if (parent != nil) {
366 dispatch_async(dispatch_get_main_queue(), ^{
367 [self fixMoveRunLoopModeIfNeeded];
368 // beginCriticalSheet blocks with nested run loop until the
369 // sheet animation is finished.
370 [parent beginCriticalSheet:window
371 completionHandler:^(NSModalResponse response){
372 }];
373 });
374
375 } else {
376 [window setIsVisible:YES];
377 [window makeKeyAndOrderFront:nil];
378 }
379
380 return controller.viewIdentifier;
381}
382
383- (FlutterViewIdentifier)createTooltipWindow:(const FlutterWindowCreationRequest*)request {
384 FlutterViewController* controller = [[FlutterViewController alloc] initWithEngine:_engine
385 nibName:nil
386 bundle:nil];
387
388 NSWindow* window = [[NSWindow alloc] init];
389 // If this is not set there will be double free on window close when
390 // using ARC.
391 [window setReleasedWhenClosed:NO];
392
393 window.contentViewController = controller;
394 window.styleMask = NSWindowStyleMaskBorderless;
395 window.hasShadow = NO;
396 window.opaque = NO;
397 window.backgroundColor = [NSColor clearColor];
398
399 FlutterWindowOwner* owner = [[FlutterWindowOwner alloc] initWithWindow:window
400 flutterViewController:controller
401 creationRequest:*request];
402
403 controller.flutterView.sizingDelegate = owner;
404 controller.flutterView.backgroundColor = [NSColor clearColor];
405 // Resend configure event after setting the sizing delegate.
406 [controller.flutterView constraintsDidChange];
407 owner.closeWhenParentResignsKey = YES;
408
409 window.delegate = owner;
410 [_windows addObject:owner];
411
412 NSWindow* parent = nil;
413
414 FML_DCHECK(request->parent_view_id != 0);
415 for (FlutterWindowOwner* owner in _windows) {
416 if (owner.flutterViewController.viewIdentifier == request->parent_view_id) {
417 parent = owner.window;
418 break;
419 }
420 }
421
422 NSAssert(parent != nil, @"Tooltip window must have a parent window.");
423
424 window.ignoresMouseEvents = YES;
425 window.collectionBehavior = NSWindowCollectionBehaviorAuxiliary;
426 [parent addChildWindow:window ordered:NSWindowAbove];
427 window.alphaValue = 0.0;
428 return controller.viewIdentifier;
429}
430
431- (FlutterViewIdentifier)createPopupWindow:(const FlutterWindowCreationRequest*)request {
432 FlutterViewController* controller = [[FlutterViewController alloc] initWithEngine:_engine
433 nibName:nil
434 bundle:nil];
435 // By default this is kFlutterMouseTrackingModeInKeyWindow but popup window is never
436 // key window.
437 controller.mouseTrackingMode = kFlutterMouseTrackingModeInActiveApp;
438
439 NSWindow* window = [[FlutterPopupWindow alloc] init];
440 // If this is not set there will be double free on window close when
441 // using ARC.
442 [window setReleasedWhenClosed:NO];
443
444 window.contentViewController = controller;
445 window.styleMask = NSWindowStyleMaskBorderless;
446 window.hasShadow = NO;
447 window.opaque = NO;
448 window.backgroundColor = [NSColor clearColor];
449
450 FlutterWindowOwner* w = [[FlutterWindowOwner alloc] initWithWindow:window
451 flutterViewController:controller
452 creationRequest:*request];
453
454 controller.flutterView.sizingDelegate = w;
455 [controller.flutterView setBackgroundColor:[NSColor clearColor]];
456 // Resend configure event after setting the sizing delegate.
457 [controller.flutterView constraintsDidChange];
459
460 window.delegate = w;
461 [_windows addObject:w];
462
463 NSWindow* parent = nil;
464
465 FML_DCHECK(request->parent_view_id != 0);
466 for (FlutterWindowOwner* owner in _windows) {
467 if (owner.flutterViewController.viewIdentifier == request->parent_view_id) {
468 parent = owner.window;
469 break;
470 }
471 }
472
473 NSAssert(parent != nil, @"Popup window must have a parent window.");
474
475 window.collectionBehavior = NSWindowCollectionBehaviorAuxiliary;
476 [parent addChildWindow:window ordered:NSWindowAbove];
477 window.alphaValue = 0.0;
478 return controller.viewIdentifier;
479}
480
481- (FlutterViewIdentifier)createRegularWindow:(const FlutterWindowCreationRequest*)request {
482 FlutterViewController* controller = [[FlutterViewController alloc] initWithEngine:_engine
483 nibName:nil
484 bundle:nil];
485
486 NSWindow* window = [[NSWindow alloc] init];
487 // If this is not set there will be double free on window close when
488 // using ARC.
489 [window setReleasedWhenClosed:NO];
490
491 window.contentViewController = controller;
492 window.styleMask = NSWindowStyleMaskResizable | NSWindowStyleMaskTitled |
493 NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable;
494 if (request->has_size) {
495 [window flutterSetContentSize:request->size];
496 }
497 if (request->has_constraints) {
498 [window flutterSetConstraints:request->constraints];
499 }
500 [window setIsVisible:YES];
501 [window makeKeyAndOrderFront:nil];
502
503 FlutterWindowOwner* owner = [[FlutterWindowOwner alloc] initWithWindow:window
504 flutterViewController:controller
505 creationRequest:*request];
506 window.delegate = owner;
507 [_windows addObject:owner];
508
509 return controller.viewIdentifier;
510}
511
512- (void)destroyWindow:(NSWindow*)window {
513 FlutterWindowOwner* owner = nil;
514 for (FlutterWindowOwner* o in _windows) {
515 if (o.window == window) {
516 owner = o;
517 break;
518 }
519 }
520 if (owner != nil) {
521 [_windows removeObject:owner];
522 for (NSWindow* win in owner.window.sheets) {
523 [self destroyWindow:win];
524 }
525
526 for (NSWindow* win in owner.window.childWindows) {
527 [self destroyWindow:win];
528 }
529 // Make sure to unregister the controller from the engine and remove the FlutterView
530 // before destroying the window and Flutter NSView.
531 [owner.flutterViewController dispose];
532 owner.window.delegate = nil;
533 [owner.window close];
534 [owner windowWillClose];
535 }
536}
537
538- (void)closeAllWindows {
539 for (FlutterWindowOwner* owner in _windows) {
540 [owner.flutterViewController dispose];
541 [owner.window close];
542 }
543 [_windows removeAllObjects];
544}
545
546static BOOL IsChildAncestor(NSWindow* child, NSWindow* ancestor) {
547 NSWindow* current = child.parentWindow;
548 while (current) {
549 if (current == ancestor) {
550 return YES;
551 }
552 current = current.parentWindow;
553 }
554
555 return NO;
556}
557
558- (void)windowDidResignKey:(FlutterWindowOwner*)parent {
559 for (FlutterWindowOwner* possibleChild in _windows) {
560 if (possibleChild.closeWhenParentResignsKey &&
561 IsChildAncestor(possibleChild.window, parent.window)) {
562 [possibleChild windowShouldClose:possibleChild.window];
563 }
564 }
565}
566
567@end
568
569// NOLINTBEGIN(google-objc-function-naming)
570
572 int64_t engine_id,
573 const FlutterWindowCreationRequest* request) {
574 FlutterEngine* engine = [FlutterEngine engineForIdentifier:engine_id];
575 [engine enableMultiView];
576 return [engine.windowController createRegularWindow:request];
577}
578
580 int64_t engine_id,
581 const FlutterWindowCreationRequest* request) {
582 FlutterEngine* engine = [FlutterEngine engineForIdentifier:engine_id];
583 [engine enableMultiView];
584 return [engine.windowController createDialogWindow:request];
585}
586
588 int64_t engine_id,
589 const FlutterWindowCreationRequest* request) {
590 FlutterEngine* engine = [FlutterEngine engineForIdentifier:engine_id];
591 [engine enableMultiView];
592 return [engine.windowController createTooltipWindow:request];
593}
594
596 int64_t engine_id,
597 const FlutterWindowCreationRequest* request) {
598 FlutterEngine* engine = [FlutterEngine engineForIdentifier:engine_id];
599 [engine enableMultiView];
600 return [engine.windowController createPopupWindow:request];
601}
602
603void InternalFlutter_Window_Destroy(int64_t engine_id, void* window) {
604 NSWindow* w = (__bridge NSWindow*)window;
605 FlutterEngine* engine = [FlutterEngine engineForIdentifier:engine_id];
606 [engine.windowController destroyWindow:w];
607}
608
610 FlutterEngine* engine = [FlutterEngine engineForIdentifier:engine_id];
611 FlutterViewController* controller = [engine viewControllerForIdentifier:view_id];
612 return (__bridge void*)controller.view.window;
613}
614
616 NSWindow* w = (__bridge NSWindow*)window;
617 NSRect contentRect = [w contentRectForFrameRect:w.frame];
618 return {
619 .width = contentRect.size.width,
620 .height = contentRect.size.height,
621 };
622}
623
625 NSWindow* w = (__bridge NSWindow*)window;
626 [w flutterSetContentSize:*size];
627}
628
631 const FlutterWindowConstraints* constraints) {
632 NSWindow* w = (__bridge NSWindow*)window;
633 FlutterWindowOwner* owner = (FlutterWindowOwner*)w.delegate;
634 [owner setConstraints:*constraints];
635}
636
637void InternalFlutter_Window_SetTitle(void* window, const char* title) {
638 NSWindow* w = (__bridge NSWindow*)window;
639 w.title = [NSString stringWithUTF8String:title];
640}
641
642void InternalFlutter_Window_SetMaximized(void* window, bool maximized) {
643 NSWindow* w = (__bridge NSWindow*)window;
644 if (maximized & !w.isZoomed) {
645 [w zoom:nil];
646 } else if (!maximized && w.isZoomed) {
647 [w zoom:nil];
648 }
649}
650
652 NSWindow* w = (__bridge NSWindow*)window;
653 return w.isZoomed;
654}
655
657 NSWindow* w = (__bridge NSWindow*)window;
658 [w miniaturize:nil];
659}
660
662 NSWindow* w = (__bridge NSWindow*)window;
663 [w deminiaturize:nil];
664}
665
667 NSWindow* w = (__bridge NSWindow*)window;
668 return w.isMiniaturized;
669}
670
671void InternalFlutter_Window_SetFullScreen(void* window, bool fullScreen) {
672 NSWindow* w = (__bridge NSWindow*)window;
673 bool isFullScreen = (w.styleMask & NSWindowStyleMaskFullScreen) != 0;
674 if (fullScreen && !isFullScreen) {
675 [w toggleFullScreen:nil];
676 } else if (!fullScreen && isFullScreen) {
677 [w toggleFullScreen:nil];
678 }
679}
680
682 NSWindow* w = (__bridge NSWindow*)window;
683 return (w.styleMask & NSWindowStyleMaskFullScreen) != 0;
684}
685
687 NSWindow* w = (__bridge NSWindow*)window;
688 [NSApplication.sharedApplication activateIgnoringOtherApps:YES];
689 [w makeKeyAndOrderFront:nil];
690}
691
693 NSWindow* w = (__bridge NSWindow*)window;
694 return strdup(w.title.UTF8String);
695}
696
698 NSWindow* w = (__bridge NSWindow*)window;
699 return w.isKeyWindow;
700}
701
703 NSWindow* w = (__bridge NSWindow*)window;
704 FlutterWindowOwner* owner = (FlutterWindowOwner*)w.delegate;
705 [owner updatePosition];
706}
707
709 NSWindow* w = (__bridge NSWindow*)window;
710 NSWindow* parent = w.parentWindow;
711 if (!parent) {
712 return {0, 0};
713 }
714 NSRect globalScreenFrame = ComputeGlobalScreenFrame();
715
716 NSRect parentRect = [parent contentRectForFrameRect:parent.frame];
717 FlipRect(parentRect, globalScreenFrame);
718
719 NSRect childRect = w.frame;
720 FlipRect(childRect, globalScreenFrame);
721
722 return {
723 .x = childRect.origin.x - parentRect.origin.x,
724 .y = childRect.origin.y - parentRect.origin.y,
725 };
726}
727
728// NOLINTEND(google-objc-function-naming)
#define FLUTTER_DARWIN_EXPORT
UIViewController< FlutterViewResponder > * _flutterViewController
FLUTTER_DARWIN_EXPORT int64_t InternalFlutter_WindowController_CreateRegularWindow(int64_t engine_id, const FlutterWindowCreationRequest *request)
FLUTTER_DARWIN_EXPORT void InternalFlutter_Window_UpdatePosition(void *window)
FLUTTER_DARWIN_EXPORT FlutterWindowSize InternalFlutter_Window_GetContentSize(void *window)
FLUTTER_DARWIN_EXPORT void * InternalFlutter_Window_GetHandle(int64_t engine_id, FlutterViewIdentifier view_id)
FLUTTER_DARWIN_EXPORT FlutterWindowOffset InternalFlutter_Window_GetOffsetInParent(void *window)
FLUTTER_DARWIN_EXPORT int64_t InternalFlutter_WindowController_CreateTooltipWindow(int64_t engine_id, const FlutterWindowCreationRequest *request)
FLUTTER_DARWIN_EXPORT void InternalFlutter_Window_SetMaximized(void *window, bool maximized)
FLUTTER_DARWIN_EXPORT int64_t InternalFlutter_WindowController_CreatePopupWindow(int64_t engine_id, const FlutterWindowCreationRequest *request)
FLUTTER_DARWIN_EXPORT void InternalFlutter_Window_SetConstraints(void *window, const FlutterWindowConstraints *constraints)
FLUTTER_DARWIN_EXPORT void InternalFlutter_Window_Destroy(int64_t engine_id, void *window)
FLUTTER_DARWIN_EXPORT void InternalFlutter_Window_Unminimize(void *window)
FLUTTER_DARWIN_EXPORT char * InternalFlutter_Window_GetTitle(void *window)
FLUTTER_DARWIN_EXPORT void InternalFlutter_Window_SetContentSize(void *window, const FlutterWindowSize *size)
FLUTTER_DARWIN_EXPORT void InternalFlutter_Window_SetFullScreen(void *window, bool fullScreen)
FLUTTER_DARWIN_EXPORT bool InternalFlutter_Window_IsMaximized(void *window)
FLUTTER_DARWIN_EXPORT bool InternalFlutter_Window_IsMinimized(void *window)
FLUTTER_DARWIN_EXPORT int64_t InternalFlutter_WindowController_CreateDialogWindow(int64_t engine_id, const FlutterWindowCreationRequest *request)
FLUTTER_DARWIN_EXPORT void InternalFlutter_Window_SetTitle(void *window, const char *title)
FLUTTER_DARWIN_EXPORT void InternalFlutter_Window_Activate(void *window)
FLUTTER_DARWIN_EXPORT bool InternalFlutter_Window_IsFullScreen(void *window)
FLUTTER_DARWIN_EXPORT bool InternalFlutter_Window_IsActivated(void *window)
FLUTTER_DARWIN_EXPORT void InternalFlutter_Window_Minimize(void *window)
NSMutableArray< FlutterWindowOwner * > * _windows
static Isolate Current()
GLFWwindow * window
Definition main.cc:60
FlutterEngine engine
Definition main.cc:84
FlView * view
G_BEGIN_DECLS FlutterViewId view_id
#define FML_LOG(severity)
Definition logging.h:101
#define FML_DCHECK(condition)
Definition logging.h:122
FlutterMouseTrackingMode mouseTrackingMode
FlutterViewIdentifier viewIdentifier
UIScreen * screen()
void constraintsDidChange()
FlutterViewController * _flutterViewController
FlutterViewController * flutterViewController
std::optional< flutter::Isolate > _isolate
FlutterWindowCreationRequest _creationRequest
FlutterViewController * viewController
int64_t FlutterViewIdentifier
Definition ref_ptr.h:261
int32_t height
int32_t width
static FlutterWindowRect fromNSRect(const NSRect &rect)
static FlutterWindowSize fromNSSize(const NSSize &size)
int BOOL