187static void FlipRect(NSRect& rect,
const NSRect& globalScreenFrame) {
189 rect.origin.y = (globalScreenFrame.origin.y + globalScreenFrame.size.height) -
190 (rect.origin.y + rect.size.height);
193- (void)updatePosition {
194 [
self viewDidUpdateContents:self.flutterViewController.flutterView
195 withSize:self.flutterViewController.flutterView.bounds.size];
198- (void)viewDidUpdateContents:(
FlutterView*)view withSize:(NSSize)newSize {
199 if (_creationRequest.on_get_window_position ==
nullptr) {
204 NSRect globalScreenFrame = ComputeGlobalScreenFrame();
207 [
self.window.parentWindow contentRectForFrameRect:self.window.parentWindow.frame];
208 FlipRect(parentRect, globalScreenFrame);
210 NSRect screenRect = [
self.window.screen visibleFrame];
211 FlipRect(screenRect, globalScreenFrame);
214 auto position = _creationRequest.on_get_window_position(
218 NSRect positionRect = position->toNSRect();
219 FlipRect(positionRect, globalScreenFrame);
221 [
self.window setFrame:positionRect display:NO animate:NO];
227 if (
view.sizedToContents &&
228 (positionRect.size.width < newSize.width || positionRect.size.height < newSize.height)) {
229 _positionerSizeConstraints = positionRect.size;
233 self.window.alphaValue = 1.0;
239 self->_creationRequest.constraints = constraints;
240 [_flutterViewController.flutterView constraintsDidChange];
242 [
self.window flutterSetConstraints:constraints];
253- (
BOOL)canBecomeKeyWindow {
257- (
BOOL)acceptsFirstResponder {
261- (
BOOL)canBecomeMainWindow {
272- (NSRect)windowWillUseStandardFrame:(NSWindow*)
window defaultFrame:(NSRect)newFrame {
274 newFrame.size.width = 110;
275 newFrame.size.height = 110;
283- (instancetype)init {
286 _windows = [NSMutableArray array];
291- (void)fixMoveRunLoopModeIfNeeded {
292 if (_runLoopModeFixApplied) {
302 NSWindow*
window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100)
303 styleMask:NSWindowStyleMaskResizable
304 backing:NSBackingStoreNonretained
308 window.releasedWhenClosed = NO;
309 window.delegate = delegate;
310 window.ignoresMouseEvents = YES;
312 [window orderFront:nil];
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);
321 _runLoopModeFixApplied = YES;
329 NSWindow*
window = [[NSWindow alloc] init];
332 [window setReleasedWhenClosed:NO];
334 window.contentViewController = controller;
336 NSWindowStyleMaskResizable | NSWindowStyleMaskTitled | NSWindowStyleMaskClosable;
337 window.collectionBehavior = NSWindowCollectionBehaviorFullScreenAuxiliary;
338 if (request->has_size) {
339 [window flutterSetContentSize:request->size];
341 if (request->has_constraints) {
342 [window flutterSetConstraints:request->constraints];
346 flutterViewController:controller
347 creationRequest:*request];
349 [_windows addObject:owner];
351 NSWindow* parent = nil;
353 if (request->parent_view_id != 0) {
361 FML_LOG(WARNING) <<
"Failed to find parent window for ID " << request->parent_view_id;
366 dispatch_async(dispatch_get_main_queue(), ^{
367 [
self fixMoveRunLoopModeIfNeeded];
370 [parent beginCriticalSheet:window
371 completionHandler:^(NSModalResponse response){
376 [window setIsVisible:YES];
377 [window makeKeyAndOrderFront:nil];
388 NSWindow*
window = [[NSWindow alloc] init];
391 [window setReleasedWhenClosed:NO];
393 window.contentViewController = controller;
394 window.styleMask = NSWindowStyleMaskBorderless;
400 flutterViewController:controller
401 creationRequest:*request];
403 controller.flutterView.sizingDelegate = owner;
406 [controller.flutterView constraintsDidChange];
410 [_windows addObject:owner];
412 NSWindow* parent = nil;
422 NSAssert(parent != nil,
@"Tooltip window must have a parent window.");
424 window.ignoresMouseEvents = YES;
425 window.collectionBehavior = NSWindowCollectionBehaviorAuxiliary;
426 [parent addChildWindow:window ordered:NSWindowAbove];
442 [window setReleasedWhenClosed:NO];
444 window.contentViewController = controller;
445 window.styleMask = NSWindowStyleMaskBorderless;
451 flutterViewController:controller
452 creationRequest:*request];
454 controller.flutterView.sizingDelegate = w;
455 [controller.flutterView setBackgroundColor:[NSColor clearColor]];
457 [controller.flutterView constraintsDidChange];
461 [_windows addObject:w];
463 NSWindow* parent = nil;
467 if (owner.flutterViewController.viewIdentifier == request->parent_view_id) {
468 parent = owner.window;
473 NSAssert(parent != nil,
@"Popup window must have a parent window.");
475 window.collectionBehavior = NSWindowCollectionBehaviorAuxiliary;
476 [parent addChildWindow:window ordered:NSWindowAbove];
486 NSWindow*
window = [[NSWindow alloc] init];
489 [window setReleasedWhenClosed:NO];
491 window.contentViewController = controller;
492 window.styleMask = NSWindowStyleMaskResizable | NSWindowStyleMaskTitled |
493 NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable;
494 if (request->has_size) {
495 [window flutterSetContentSize:request->size];
497 if (request->has_constraints) {
498 [window flutterSetConstraints:request->constraints];
500 [window setIsVisible:YES];
501 [window makeKeyAndOrderFront:nil];
504 flutterViewController:controller
505 creationRequest:*request];
507 [_windows addObject:owner];
512- (void)destroyWindow:(NSWindow*)
window {
521 [_windows removeObject:owner];
522 for (NSWindow* win in owner.
window.sheets) {
523 [
self destroyWindow:win];
526 for (NSWindow* win in owner.
window.childWindows) {
527 [
self destroyWindow:win];
531 [owner.flutterViewController dispose];
532 owner.
window.delegate = nil;
533 [owner.window close];
534 [owner windowWillClose];
538- (void)closeAllWindows {
540 [owner.flutterViewController dispose];
541 [owner.window close];
543 [_windows removeAllObjects];