SDL  2.0
SDL_cocoawindow.m
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../../SDL_internal.h"
22 
23 #if SDL_VIDEO_DRIVER_COCOA
24 
25 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
26 # error SDL for Mac OS X must be built with a 10.7 SDK or above.
27 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1070 */
28 
29 #include "SDL_syswm.h"
30 #include "SDL_timer.h" /* For SDL_GetTicks() */
31 #include "SDL_hints.h"
32 #include "../SDL_sysvideo.h"
33 #include "../../events/SDL_keyboard_c.h"
34 #include "../../events/SDL_mouse_c.h"
35 #include "../../events/SDL_touch_c.h"
36 #include "../../events/SDL_windowevents_c.h"
37 #include "../../events/SDL_dropevents_c.h"
38 #include "SDL_cocoavideo.h"
39 #include "SDL_cocoashape.h"
40 #include "SDL_cocoamouse.h"
41 #include "SDL_cocoamousetap.h"
42 #include "SDL_cocoaopengl.h"
43 #include "SDL_assert.h"
44 
45 /* #define DEBUG_COCOAWINDOW */
46 
47 #ifdef DEBUG_COCOAWINDOW
48 #define DLog(fmt, ...) printf("%s: " fmt "\n", __func__, ##__VA_ARGS__)
49 #else
50 #define DLog(...) do { } while (0)
51 #endif
52 
53 
54 #define FULLSCREEN_MASK (SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN)
55 
56 
57 @interface SDLWindow : NSWindow <NSDraggingDestination>
58 /* These are needed for borderless/fullscreen windows */
59 - (BOOL)canBecomeKeyWindow;
60 - (BOOL)canBecomeMainWindow;
61 - (void)sendEvent:(NSEvent *)event;
62 - (void)doCommandBySelector:(SEL)aSelector;
63 
64 /* Handle drag-and-drop of files onto the SDL window. */
65 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender;
66 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender;
67 - (BOOL)wantsPeriodicDraggingUpdates;
68 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem;
69 
70 - (SDL_Window*)findSDLWindow;
71 @end
72 
73 @implementation SDLWindow
74 
75 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
76 {
77  /* Only allow using the macOS native fullscreen toggle menubar item if the
78  * window is resizable and not in a SDL fullscreen mode.
79  */
80  if ([menuItem action] == @selector(toggleFullScreen:)) {
81  SDL_Window *window = [self findSDLWindow];
82  if (window == NULL) {
83  return NO;
84  } else if ((window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_FULLSCREEN_DESKTOP)) != 0) {
85  return NO;
86  } else if ((window->flags & SDL_WINDOW_RESIZABLE) == 0) {
87  return NO;
88  }
89  }
90  return [super validateMenuItem:menuItem];
91 }
92 
93 - (BOOL)canBecomeKeyWindow
94 {
95  return YES;
96 }
97 
98 - (BOOL)canBecomeMainWindow
99 {
100  return YES;
101 }
102 
103 - (void)sendEvent:(NSEvent *)event
104 {
105  [super sendEvent:event];
106 
107  if ([event type] != NSEventTypeLeftMouseUp) {
108  return;
109  }
110 
111  id delegate = [self delegate];
112  if (![delegate isKindOfClass:[Cocoa_WindowListener class]]) {
113  return;
114  }
115 
116  if ([delegate isMoving]) {
117  [delegate windowDidFinishMoving];
118  }
119 }
120 
121 /* We'll respond to selectors by doing nothing so we don't beep.
122  * The escape key gets converted to a "cancel" selector, etc.
123  */
124 - (void)doCommandBySelector:(SEL)aSelector
125 {
126  /*NSLog(@"doCommandBySelector: %@\n", NSStringFromSelector(aSelector));*/
127 }
128 
129 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
130 {
131  if (([sender draggingSourceOperationMask] & NSDragOperationGeneric) == NSDragOperationGeneric) {
132  return NSDragOperationGeneric;
133  }
134 
135  return NSDragOperationNone; /* no idea what to do with this, reject it. */
136 }
137 
138 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
139 { @autoreleasepool
140 {
141  NSPasteboard *pasteboard = [sender draggingPasteboard];
142  NSArray *types = [NSArray arrayWithObject:NSFilenamesPboardType];
143  NSString *desiredType = [pasteboard availableTypeFromArray:types];
144  SDL_Window *sdlwindow = [self findSDLWindow];
145 
146  if (desiredType == nil) {
147  return NO; /* can't accept anything that's being dropped here. */
148  }
149 
150  NSData *data = [pasteboard dataForType:desiredType];
151  if (data == nil) {
152  return NO;
153  }
154 
155  SDL_assert([desiredType isEqualToString:NSFilenamesPboardType]);
156  NSArray *array = [pasteboard propertyListForType:@"NSFilenamesPboardType"];
157 
158  for (NSString *path in array) {
159  NSURL *fileURL = [NSURL fileURLWithPath:path];
160  NSNumber *isAlias = nil;
161 
162  [fileURL getResourceValue:&isAlias forKey:NSURLIsAliasFileKey error:nil];
163 
164  /* If the URL is an alias, resolve it. */
165  if ([isAlias boolValue]) {
166  NSURLBookmarkResolutionOptions opts = NSURLBookmarkResolutionWithoutMounting | NSURLBookmarkResolutionWithoutUI;
167  NSData *bookmark = [NSURL bookmarkDataWithContentsOfURL:fileURL error:nil];
168  if (bookmark != nil) {
169  NSURL *resolvedURL = [NSURL URLByResolvingBookmarkData:bookmark
170  options:opts
171  relativeToURL:nil
172  bookmarkDataIsStale:nil
173  error:nil];
174 
175  if (resolvedURL != nil) {
176  fileURL = resolvedURL;
177  }
178  }
179  }
180 
181  if (!SDL_SendDropFile(sdlwindow, [[fileURL path] UTF8String])) {
182  return NO;
183  }
184  }
185 
186  SDL_SendDropComplete(sdlwindow);
187  return YES;
188 }}
189 
190 - (BOOL)wantsPeriodicDraggingUpdates
191 {
192  return NO;
193 }
194 
195 - (SDL_Window*)findSDLWindow
196 {
197  SDL_Window *sdlwindow = NULL;
199 
200  /* !!! FIXME: is there a better way to do this? */
201  if (_this) {
202  for (sdlwindow = _this->windows; sdlwindow; sdlwindow = sdlwindow->next) {
203  NSWindow *nswindow = ((SDL_WindowData *) sdlwindow->driverdata)->nswindow;
204  if (nswindow == self) {
205  break;
206  }
207  }
208  }
209 
210  return sdlwindow;
211 }
212 
213 @end
214 
215 
216 static Uint32 s_moveHack;
217 
218 static void ConvertNSRect(NSScreen *screen, BOOL fullscreen, NSRect *r)
219 {
220  r->origin.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - r->origin.y - r->size.height;
221 }
222 
223 static void
224 ScheduleContextUpdates(SDL_WindowData *data)
225 {
226  NSOpenGLContext *currentContext = [NSOpenGLContext currentContext];
227  NSMutableArray *contexts = data->nscontexts;
228  @synchronized (contexts) {
229  for (SDLOpenGLContext *context in contexts) {
230  if (context == currentContext) {
231  [context update];
232  } else {
233  [context scheduleUpdate];
234  }
235  }
236  }
237 }
238 
239 /* !!! FIXME: this should use a hint callback. */
240 static int
241 GetHintCtrlClickEmulateRightClick()
242 {
244 }
245 
246 static NSUInteger
247 GetWindowStyle(SDL_Window * window)
248 {
249  NSUInteger style = 0;
250 
251  if (window->flags & SDL_WINDOW_FULLSCREEN) {
252  style = NSWindowStyleMaskBorderless;
253  } else {
254  if (window->flags & SDL_WINDOW_BORDERLESS) {
255  style = NSWindowStyleMaskBorderless;
256  } else {
257  style = (NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable);
258  }
259  if (window->flags & SDL_WINDOW_RESIZABLE) {
260  style |= NSWindowStyleMaskResizable;
261  }
262  }
263  return style;
264 }
265 
266 static SDL_bool
267 SetWindowStyle(SDL_Window * window, NSUInteger style)
268 {
269  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
270  NSWindow *nswindow = data->nswindow;
271 
272  /* The view responder chain gets messed with during setStyleMask */
273  if ([[nswindow contentView] nextResponder] == data->listener) {
274  [[nswindow contentView] setNextResponder:nil];
275  }
276 
277  [nswindow setStyleMask:style];
278 
279  /* The view responder chain gets messed with during setStyleMask */
280  if ([[nswindow contentView] nextResponder] != data->listener) {
281  [[nswindow contentView] setNextResponder:data->listener];
282  }
283 
284  return SDL_TRUE;
285 }
286 
287 
288 @implementation Cocoa_WindowListener
289 
290 - (void)listen:(SDL_WindowData *)data
291 {
292  NSNotificationCenter *center;
293  NSWindow *window = data->nswindow;
294  NSView *view = [window contentView];
295 
296  _data = data;
297  observingVisible = YES;
298  wasCtrlLeft = NO;
299  wasVisible = [window isVisible];
300  isFullscreenSpace = NO;
303  isMoving = NO;
304  isDragAreaRunning = NO;
305 
306  center = [NSNotificationCenter defaultCenter];
307 
308  if ([window delegate] != nil) {
309  [center addObserver:self selector:@selector(windowDidExpose:) name:NSWindowDidExposeNotification object:window];
310  [center addObserver:self selector:@selector(windowDidMove:) name:NSWindowDidMoveNotification object:window];
311  [center addObserver:self selector:@selector(windowDidResize:) name:NSWindowDidResizeNotification object:window];
312  [center addObserver:self selector:@selector(windowDidMiniaturize:) name:NSWindowDidMiniaturizeNotification object:window];
313  [center addObserver:self selector:@selector(windowDidDeminiaturize:) name:NSWindowDidDeminiaturizeNotification object:window];
314  [center addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:window];
315  [center addObserver:self selector:@selector(windowDidResignKey:) name:NSWindowDidResignKeyNotification object:window];
316  [center addObserver:self selector:@selector(windowDidChangeBackingProperties:) name:NSWindowDidChangeBackingPropertiesNotification object:window];
317  [center addObserver:self selector:@selector(windowWillEnterFullScreen:) name:NSWindowWillEnterFullScreenNotification object:window];
318  [center addObserver:self selector:@selector(windowDidEnterFullScreen:) name:NSWindowDidEnterFullScreenNotification object:window];
319  [center addObserver:self selector:@selector(windowWillExitFullScreen:) name:NSWindowWillExitFullScreenNotification object:window];
320  [center addObserver:self selector:@selector(windowDidExitFullScreen:) name:NSWindowDidExitFullScreenNotification object:window];
321  [center addObserver:self selector:@selector(windowDidFailToEnterFullScreen:) name:@"NSWindowDidFailToEnterFullScreenNotification" object:window];
322  [center addObserver:self selector:@selector(windowDidFailToExitFullScreen:) name:@"NSWindowDidFailToExitFullScreenNotification" object:window];
323  } else {
324  [window setDelegate:self];
325  }
326 
327  /* Haven't found a delegate / notification that triggers when the window is
328  * ordered out (is not visible any more). You can be ordered out without
329  * minimizing, so DidMiniaturize doesn't work. (e.g. -[NSWindow orderOut:])
330  */
331  [window addObserver:self
332  forKeyPath:@"visible"
333  options:NSKeyValueObservingOptionNew
334  context:NULL];
335 
336  [window setNextResponder:self];
337  [window setAcceptsMouseMovedEvents:YES];
338 
339  [view setNextResponder:self];
340 
341  [view setAcceptsTouchEvents:YES];
342 }
343 
344 - (void)observeValueForKeyPath:(NSString *)keyPath
345  ofObject:(id)object
346  change:(NSDictionary *)change
347  context:(void *)context
348 {
349  if (!observingVisible) {
350  return;
351  }
352 
353  if (object == _data->nswindow && [keyPath isEqualToString:@"visible"]) {
354  int newVisibility = [[change objectForKey:@"new"] intValue];
355  if (newVisibility) {
357  } else {
359  }
360  }
361 }
362 
364 {
365  observingVisible = NO;
366  wasVisible = [_data->nswindow isVisible];
367 }
368 
370 {
371  BOOL isVisible = [_data->nswindow isVisible];
372  observingVisible = YES;
373  if (wasVisible != isVisible) {
374  if (isVisible) {
376  } else {
378  }
379 
380  wasVisible = isVisible;
381  }
382 }
383 
384 -(BOOL) setFullscreenSpace:(BOOL) state
385 {
386  SDL_Window *window = _data->window;
387  NSWindow *nswindow = _data->nswindow;
388  SDL_VideoData *videodata = ((SDL_WindowData *) window->driverdata)->videodata;
389 
390  if (!videodata->allow_spaces) {
391  return NO; /* Spaces are forcibly disabled. */
392  } else if (state && ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP)) {
393  return NO; /* we only allow you to make a Space on FULLSCREEN_DESKTOP windows. */
395  return NO; /* we only handle leaving the Space on windows that were previously FULLSCREEN_DESKTOP. */
396  } else if (state == isFullscreenSpace) {
397  return YES; /* already there. */
398  }
399 
401  if (state) {
402  [self addPendingWindowOperation:PENDING_OPERATION_ENTER_FULLSCREEN];
403  } else {
404  [self addPendingWindowOperation:PENDING_OPERATION_LEAVE_FULLSCREEN];
405  }
406  return YES;
407  }
409 
410  /* you need to be FullScreenPrimary, or toggleFullScreen doesn't work. Unset it again in windowDidExitFullScreen. */
411  [nswindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
412  [nswindow performSelectorOnMainThread: @selector(toggleFullScreen:) withObject:nswindow waitUntilDone:NO];
413  return YES;
414 }
415 
416 -(BOOL) isInFullscreenSpace
417 {
418  return isFullscreenSpace;
419 }
420 
422 {
423  return inFullscreenTransition;
424 }
425 
426 -(void) addPendingWindowOperation:(PendingWindowOperation) operation
427 {
428  pendingWindowOperation = operation;
429 }
430 
431 - (void)close
432 {
433  NSNotificationCenter *center;
434  NSWindow *window = _data->nswindow;
435  NSView *view = [window contentView];
436 
437  center = [NSNotificationCenter defaultCenter];
438 
439  if ([window delegate] != self) {
440  [center removeObserver:self name:NSWindowDidExposeNotification object:window];
441  [center removeObserver:self name:NSWindowDidMoveNotification object:window];
442  [center removeObserver:self name:NSWindowDidResizeNotification object:window];
443  [center removeObserver:self name:NSWindowDidMiniaturizeNotification object:window];
444  [center removeObserver:self name:NSWindowDidDeminiaturizeNotification object:window];
445  [center removeObserver:self name:NSWindowDidBecomeKeyNotification object:window];
446  [center removeObserver:self name:NSWindowDidResignKeyNotification object:window];
447  [center removeObserver:self name:NSWindowDidChangeBackingPropertiesNotification object:window];
448  [center removeObserver:self name:NSWindowWillEnterFullScreenNotification object:window];
449  [center removeObserver:self name:NSWindowDidEnterFullScreenNotification object:window];
450  [center removeObserver:self name:NSWindowWillExitFullScreenNotification object:window];
451  [center removeObserver:self name:NSWindowDidExitFullScreenNotification object:window];
452  [center removeObserver:self name:@"NSWindowDidFailToEnterFullScreenNotification" object:window];
453  [center removeObserver:self name:@"NSWindowDidFailToExitFullScreenNotification" object:window];
454  } else {
455  [window setDelegate:nil];
456  }
457 
458  [window removeObserver:self forKeyPath:@"visible"];
459 
460  if ([window nextResponder] == self) {
461  [window setNextResponder:nil];
462  }
463  if ([view nextResponder] == self) {
464  [view setNextResponder:nil];
465  }
466 }
467 
468 - (BOOL)isMoving
469 {
470  return isMoving;
471 }
472 
473 -(void) setPendingMoveX:(int)x Y:(int)y
474 {
477 }
478 
480 {
481  if ([self isMoving]) {
482  isMoving = NO;
483 
484  SDL_Mouse *mouse = SDL_GetMouse();
485  if (pendingWindowWarpX != INT_MAX && pendingWindowWarpY != INT_MAX) {
488  }
489  if (mouse->relative_mode && !mouse->relative_mode_warp && mouse->focus == _data->window) {
491  }
492  }
493 }
494 
495 - (BOOL)windowShouldClose:(id)sender
496 {
498  return NO;
499 }
500 
501 - (void)windowDidExpose:(NSNotification *)aNotification
502 {
504 }
505 
506 - (void)windowWillMove:(NSNotification *)aNotification
507 {
508  if ([_data->nswindow isKindOfClass:[SDLWindow class]]) {
510  isMoving = YES;
511  }
512 }
513 
514 - (void)windowDidMove:(NSNotification *)aNotification
515 {
516  int x, y;
517  SDL_Window *window = _data->window;
518  NSWindow *nswindow = _data->nswindow;
519  BOOL fullscreen = window->flags & FULLSCREEN_MASK;
520  NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
521  ConvertNSRect([nswindow screen], fullscreen, &rect);
522 
524  /* We'll take care of this at the end of the transition */
525  return;
526  }
527 
528  if (s_moveHack) {
529  SDL_bool blockMove = ((SDL_GetTicks() - s_moveHack) < 500);
530 
531  s_moveHack = 0;
532 
533  if (blockMove) {
534  /* Cocoa is adjusting the window in response to a mode change */
535  rect.origin.x = window->x;
536  rect.origin.y = window->y;
537  ConvertNSRect([nswindow screen], fullscreen, &rect);
538  [nswindow setFrameOrigin:rect.origin];
539  return;
540  }
541  }
542 
543  x = (int)rect.origin.x;
544  y = (int)rect.origin.y;
545 
546  ScheduleContextUpdates(_data);
547 
549 }
550 
551 - (void)windowDidResize:(NSNotification *)aNotification
552 {
554  /* We'll take care of this at the end of the transition */
555  return;
556  }
557 
558  SDL_Window *window = _data->window;
559  NSWindow *nswindow = _data->nswindow;
560  int x, y, w, h;
561  NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
562  ConvertNSRect([nswindow screen], (window->flags & FULLSCREEN_MASK), &rect);
563  x = (int)rect.origin.x;
564  y = (int)rect.origin.y;
565  w = (int)rect.size.width;
566  h = (int)rect.size.height;
567 
568  if (SDL_IsShapedWindow(window)) {
569  Cocoa_ResizeWindowShape(window);
570  }
571 
572  ScheduleContextUpdates(_data);
573 
574  /* The window can move during a resize event, such as when maximizing
575  or resizing from a corner */
578 
579  const BOOL zoomed = [nswindow isZoomed];
580  if (!zoomed) {
582  } else if (zoomed) {
584  }
585 }
586 
587 - (void)windowDidMiniaturize:(NSNotification *)aNotification
588 {
590 }
591 
592 - (void)windowDidDeminiaturize:(NSNotification *)aNotification
593 {
595 }
596 
597 - (void)windowDidBecomeKey:(NSNotification *)aNotification
598 {
599  SDL_Window *window = _data->window;
600  SDL_Mouse *mouse = SDL_GetMouse();
601 
602  /* We're going to get keyboard events, since we're key. */
603  /* This needs to be done before restoring the relative mouse mode. */
604  SDL_SetKeyboardFocus(window);
605 
606  if (mouse->relative_mode && !mouse->relative_mode_warp && ![self isMoving]) {
608  }
609 
610  /* If we just gained focus we need the updated mouse position */
611  if (!mouse->relative_mode) {
612  NSPoint point;
613  int x, y;
614 
615  point = [_data->nswindow mouseLocationOutsideOfEventStream];
616  x = (int)point.x;
617  y = (int)(window->h - point.y);
618 
619  if (x >= 0 && x < window->w && y >= 0 && y < window->h) {
620  SDL_SendMouseMotion(window, 0, 0, x, y);
621  }
622  }
623 
624  /* Check to see if someone updated the clipboard */
626 
628  [NSMenu setMenuBarVisible:NO];
629  }
630 
631  const unsigned int newflags = [NSEvent modifierFlags] & NSEventModifierFlagCapsLock;
633  SDL_ToggleModState(KMOD_CAPS, newflags != 0);
634 }
635 
636 - (void)windowDidResignKey:(NSNotification *)aNotification
637 {
638  SDL_Mouse *mouse = SDL_GetMouse();
639  if (mouse->relative_mode && !mouse->relative_mode_warp) {
641  }
642 
643  /* Some other window will get mouse events, since we're not key. */
644  if (SDL_GetMouseFocus() == _data->window) {
646  }
647 
648  /* Some other window will get keyboard events, since we're not key. */
649  if (SDL_GetKeyboardFocus() == _data->window) {
651  }
652 
653  if (isFullscreenSpace) {
654  [NSMenu setMenuBarVisible:YES];
655  }
656 }
657 
658 - (void)windowDidChangeBackingProperties:(NSNotification *)aNotification
659 {
660  NSNumber *oldscale = [[aNotification userInfo] objectForKey:NSBackingPropertyOldScaleFactorKey];
661 
663  return;
664  }
665 
666  if ([oldscale doubleValue] != [_data->nswindow backingScaleFactor]) {
667  /* Force a resize event when the backing scale factor changes. */
668  _data->window->w = 0;
669  _data->window->h = 0;
670  [self windowDidResize:aNotification];
671  }
672 }
673 
674 - (void)windowWillEnterFullScreen:(NSNotification *)aNotification
675 {
676  SDL_Window *window = _data->window;
677 
678  SetWindowStyle(window, (NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable));
679 
680  isFullscreenSpace = YES;
682 }
683 
684 - (void)windowDidFailToEnterFullScreen:(NSNotification *)aNotification
685 {
686  SDL_Window *window = _data->window;
687 
688  if (window->is_destroying) {
689  return;
690  }
691 
692  SetWindowStyle(window, GetWindowStyle(window));
693 
694  isFullscreenSpace = NO;
696 
697  [self windowDidExitFullScreen:nil];
698 }
699 
700 - (void)windowDidEnterFullScreen:(NSNotification *)aNotification
701 {
702  SDL_Window *window = _data->window;
703  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
704  NSWindow *nswindow = data->nswindow;
705 
707 
710  [self setFullscreenSpace:NO];
711  } else {
712  /* Unset the resizable flag.
713  This is a workaround for https://bugzilla.libsdl.org/show_bug.cgi?id=3697
714  */
715  SetWindowStyle(window, [nswindow styleMask] & (~NSWindowStyleMaskResizable));
716 
718  [NSMenu setMenuBarVisible:NO];
719  }
720 
722  /* Force the size change event in case it was delivered earlier
723  while the window was still animating into place.
724  */
725  window->w = 0;
726  window->h = 0;
727  [self windowDidMove:aNotification];
728  [self windowDidResize:aNotification];
729  }
730 }
731 
732 - (void)windowWillExitFullScreen:(NSNotification *)aNotification
733 {
734  SDL_Window *window = _data->window;
735 
736  isFullscreenSpace = NO;
738 
739  /* As of OS X 10.11, the window seems to need to be resizable when exiting
740  a Space, in order for it to resize back to its windowed-mode size.
741  */
742  SetWindowStyle(window, GetWindowStyle(window) | NSWindowStyleMaskResizable);
743 }
744 
745 - (void)windowDidFailToExitFullScreen:(NSNotification *)aNotification
746 {
747  SDL_Window *window = _data->window;
748 
749  if (window->is_destroying) {
750  return;
751  }
752 
753  SetWindowStyle(window, (NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable));
754 
755  isFullscreenSpace = YES;
757 
758  [self windowDidEnterFullScreen:nil];
759 }
760 
761 - (void)windowDidExitFullScreen:(NSNotification *)aNotification
762 {
763  SDL_Window *window = _data->window;
764  NSWindow *nswindow = _data->nswindow;
765 
767 
768  SetWindowStyle(window, GetWindowStyle(window));
769 
770  [nswindow setLevel:kCGNormalWindowLevel];
771 
774  [self setFullscreenSpace:YES];
777  [nswindow miniaturize:nil];
778  } else {
779  /* Adjust the fullscreen toggle button and readd menu now that we're here. */
780  if (window->flags & SDL_WINDOW_RESIZABLE) {
781  /* resizable windows are Spaces-friendly: they get the "go fullscreen" toggle button on their titlebar. */
782  [nswindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
783  } else {
784  [nswindow setCollectionBehavior:NSWindowCollectionBehaviorManaged];
785  }
786  [NSMenu setMenuBarVisible:YES];
787 
789 
790 #if 0
791 /* This fixed bug 3719, which is that changing window size while fullscreen
792  doesn't take effect when leaving fullscreen, but introduces bug 3809,
793  which is that a maximized window doesn't go back to normal size when
794  restored, so this code is disabled until we can properly handle the
795  beginning and end of maximize and restore.
796  */
797  /* Restore windowed size and position in case it changed while fullscreen */
798  {
799  NSRect rect;
800  rect.origin.x = window->windowed.x;
801  rect.origin.y = window->windowed.y;
802  rect.size.width = window->windowed.w;
803  rect.size.height = window->windowed.h;
804  ConvertNSRect([nswindow screen], NO, &rect);
805 
806  s_moveHack = 0;
807  [nswindow setContentSize:rect.size];
808  [nswindow setFrameOrigin:rect.origin];
809  s_moveHack = SDL_GetTicks();
810  }
811 #endif /* 0 */
812 
813  /* Force the size change event in case it was delivered earlier
814  while the window was still animating into place.
815  */
816  window->w = 0;
817  window->h = 0;
818  [self windowDidMove:aNotification];
819  [self windowDidResize:aNotification];
820 
821  /* FIXME: Why does the window get hidden? */
822  if (window->flags & SDL_WINDOW_SHOWN) {
824  }
825  }
826 }
827 
828 -(NSApplicationPresentationOptions)window:(NSWindow *)window willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions
829 {
831  return NSApplicationPresentationFullScreen | NSApplicationPresentationHideDock | NSApplicationPresentationHideMenuBar;
832  } else {
833  return proposedOptions;
834  }
835 }
836 
837 
838 /* We'll respond to key events by doing nothing so we don't beep.
839  * We could handle key messages here, but we lose some in the NSApp dispatch,
840  * where they get converted to action messages, etc.
841  */
842 - (void)flagsChanged:(NSEvent *)theEvent
843 {
844  /*Cocoa_HandleKeyEvent(SDL_GetVideoDevice(), theEvent);*/
845 }
846 - (void)keyDown:(NSEvent *)theEvent
847 {
848  /*Cocoa_HandleKeyEvent(SDL_GetVideoDevice(), theEvent);*/
849 }
850 - (void)keyUp:(NSEvent *)theEvent
851 {
852  /*Cocoa_HandleKeyEvent(SDL_GetVideoDevice(), theEvent);*/
853 }
854 
855 /* We'll respond to selectors by doing nothing so we don't beep.
856  * The escape key gets converted to a "cancel" selector, etc.
857  */
858 - (void)doCommandBySelector:(SEL)aSelector
859 {
860  /*NSLog(@"doCommandBySelector: %@\n", NSStringFromSelector(aSelector));*/
861 }
862 
863 - (BOOL)processHitTest:(NSEvent *)theEvent
864 {
865  SDL_assert(isDragAreaRunning == [_data->nswindow isMovableByWindowBackground]);
866 
867  if (_data->window->hit_test) { /* if no hit-test, skip this. */
868  const NSPoint location = [theEvent locationInWindow];
869  const SDL_Point point = { (int) location.x, _data->window->h - (((int) location.y)-1) };
871  if (rc == SDL_HITTEST_DRAGGABLE) {
872  if (!isDragAreaRunning) {
873  isDragAreaRunning = YES;
874  [_data->nswindow setMovableByWindowBackground:YES];
875  }
876  return YES; /* dragging! */
877  }
878  }
879 
880  if (isDragAreaRunning) {
881  isDragAreaRunning = NO;
882  [_data->nswindow setMovableByWindowBackground:NO];
883  return YES; /* was dragging, drop event. */
884  }
885 
886  return NO; /* not a special area, carry on. */
887 }
888 
889 - (void)mouseDown:(NSEvent *)theEvent
890 {
891  int button;
892  int clicks;
893 
894  /* Ignore events that aren't inside the client area (i.e. title bar.) */
895  if ([theEvent window]) {
896  NSRect windowRect = [[[theEvent window] contentView] frame];
897  if (!NSMouseInRect([theEvent locationInWindow], windowRect, NO)) {
898  return;
899  }
900  }
901 
902  if ([self processHitTest:theEvent]) {
904  return; /* dragging, drop event. */
905  }
906 
907  switch ([theEvent buttonNumber]) {
908  case 0:
909  if (([theEvent modifierFlags] & NSEventModifierFlagControl) &&
910  GetHintCtrlClickEmulateRightClick()) {
911  wasCtrlLeft = YES;
912  button = SDL_BUTTON_RIGHT;
913  } else {
914  wasCtrlLeft = NO;
915  button = SDL_BUTTON_LEFT;
916  }
917  break;
918  case 1:
919  button = SDL_BUTTON_RIGHT;
920  break;
921  case 2:
922  button = SDL_BUTTON_MIDDLE;
923  break;
924  default:
925  button = (int) [theEvent buttonNumber] + 1;
926  break;
927  }
928 
929  clicks = (int) [theEvent clickCount];
930  SDL_SendMouseButtonClicks(_data->window, 0, SDL_PRESSED, button, clicks);
931 }
932 
933 - (void)rightMouseDown:(NSEvent *)theEvent
934 {
935  [self mouseDown:theEvent];
936 }
937 
938 - (void)otherMouseDown:(NSEvent *)theEvent
939 {
940  [self mouseDown:theEvent];
941 }
942 
943 - (void)mouseUp:(NSEvent *)theEvent
944 {
945  int button;
946  int clicks;
947 
948  if ([self processHitTest:theEvent]) {
950  return; /* stopped dragging, drop event. */
951  }
952 
953  switch ([theEvent buttonNumber]) {
954  case 0:
955  if (wasCtrlLeft) {
956  button = SDL_BUTTON_RIGHT;
957  wasCtrlLeft = NO;
958  } else {
959  button = SDL_BUTTON_LEFT;
960  }
961  break;
962  case 1:
963  button = SDL_BUTTON_RIGHT;
964  break;
965  case 2:
966  button = SDL_BUTTON_MIDDLE;
967  break;
968  default:
969  button = (int) [theEvent buttonNumber] + 1;
970  break;
971  }
972 
973  clicks = (int) [theEvent clickCount];
974  SDL_SendMouseButtonClicks(_data->window, 0, SDL_RELEASED, button, clicks);
975 }
976 
977 - (void)rightMouseUp:(NSEvent *)theEvent
978 {
979  [self mouseUp:theEvent];
980 }
981 
982 - (void)otherMouseUp:(NSEvent *)theEvent
983 {
984  [self mouseUp:theEvent];
985 }
986 
987 - (void)mouseMoved:(NSEvent *)theEvent
988 {
989  SDL_Mouse *mouse = SDL_GetMouse();
990  SDL_Window *window = _data->window;
991  NSPoint point;
992  int x, y;
993 
994  if ([self processHitTest:theEvent]) {
996  return; /* dragging, drop event. */
997  }
998 
999  if (mouse->relative_mode) {
1000  return;
1001  }
1002 
1003  point = [theEvent locationInWindow];
1004  x = (int)point.x;
1005  y = (int)(window->h - point.y);
1006 
1007  if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
1008  if (x < 0 || x >= window->w || y < 0 || y >= window->h) {
1009  if (x < 0) {
1010  x = 0;
1011  } else if (x >= window->w) {
1012  x = window->w - 1;
1013  }
1014  if (y < 0) {
1015  y = 0;
1016  } else if (y >= window->h) {
1017  y = window->h - 1;
1018  }
1019 
1020 #if !SDL_MAC_NO_SANDBOX
1021  CGPoint cgpoint;
1022 
1023  /* When SDL_MAC_NO_SANDBOX is set, this is handled by
1024  * SDL_cocoamousetap.m.
1025  */
1026 
1027  cgpoint.x = window->x + x;
1028  cgpoint.y = window->y + y;
1029 
1030  CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint);
1031  CGAssociateMouseAndMouseCursorPosition(YES);
1032 
1033  Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y);
1034 #endif
1035  }
1036  }
1037  SDL_SendMouseMotion(window, 0, 0, x, y);
1038 }
1039 
1040 - (void)mouseDragged:(NSEvent *)theEvent
1041 {
1042  [self mouseMoved:theEvent];
1043 }
1044 
1045 - (void)rightMouseDragged:(NSEvent *)theEvent
1046 {
1047  [self mouseMoved:theEvent];
1048 }
1049 
1050 - (void)otherMouseDragged:(NSEvent *)theEvent
1051 {
1052  [self mouseMoved:theEvent];
1053 }
1054 
1055 - (void)scrollWheel:(NSEvent *)theEvent
1056 {
1057  Cocoa_HandleMouseWheel(_data->window, theEvent);
1058 }
1059 
1060 - (void)touchesBeganWithEvent:(NSEvent *) theEvent
1061 {
1062  NSSet *touches = [theEvent touchesMatchingPhase:NSTouchPhaseAny inView:nil];
1063  int existingTouchCount = 0;
1064 
1065  for (NSTouch* touch in touches) {
1066  if ([touch phase] != NSTouchPhaseBegan) {
1067  existingTouchCount++;
1068  }
1069  }
1070  if (existingTouchCount == 0) {
1071  SDL_TouchID touchID = (SDL_TouchID)(intptr_t)[[touches anyObject] device];
1072  int numFingers = SDL_GetNumTouchFingers(touchID);
1073  DLog("Reset Lost Fingers: %d", numFingers);
1074  for (--numFingers; numFingers >= 0; --numFingers) {
1075  SDL_Finger* finger = SDL_GetTouchFinger(touchID, numFingers);
1076  SDL_SendTouch(touchID, finger->id, SDL_FALSE, 0, 0, 0);
1077  }
1078  }
1079 
1080  DLog("Began Fingers: %lu .. existing: %d", (unsigned long)[touches count], existingTouchCount);
1081  [self handleTouches:NSTouchPhaseBegan withEvent:theEvent];
1082 }
1083 
1084 - (void)touchesMovedWithEvent:(NSEvent *) theEvent
1085 {
1086  [self handleTouches:NSTouchPhaseMoved withEvent:theEvent];
1087 }
1088 
1089 - (void)touchesEndedWithEvent:(NSEvent *) theEvent
1090 {
1091  [self handleTouches:NSTouchPhaseEnded withEvent:theEvent];
1092 }
1093 
1094 - (void)touchesCancelledWithEvent:(NSEvent *) theEvent
1095 {
1096  [self handleTouches:NSTouchPhaseCancelled withEvent:theEvent];
1097 }
1098 
1099 - (void)handleTouches:(NSTouchPhase) phase withEvent:(NSEvent *) theEvent
1100 {
1101  NSSet *touches = [theEvent touchesMatchingPhase:phase inView:nil];
1102 
1103  for (NSTouch *touch in touches) {
1104  const SDL_TouchID touchId = (SDL_TouchID)(intptr_t)[touch device];
1105  if (SDL_AddTouch(touchId, "") < 0) {
1106  return;
1107  }
1108 
1109  const SDL_FingerID fingerId = (SDL_FingerID)(intptr_t)[touch identity];
1110  float x = [touch normalizedPosition].x;
1111  float y = [touch normalizedPosition].y;
1112  /* Make the origin the upper left instead of the lower left */
1113  y = 1.0f - y;
1114 
1115  switch (phase) {
1116  case NSTouchPhaseBegan:
1117  SDL_SendTouch(touchId, fingerId, SDL_TRUE, x, y, 1.0f);
1118  break;
1119  case NSTouchPhaseEnded:
1120  case NSTouchPhaseCancelled:
1121  SDL_SendTouch(touchId, fingerId, SDL_FALSE, x, y, 1.0f);
1122  break;
1123  case NSTouchPhaseMoved:
1124  SDL_SendTouchMotion(touchId, fingerId, x, y, 1.0f);
1125  break;
1126  default:
1127  break;
1128  }
1129  }
1130 }
1131 
1132 @end
1133 
1134 @interface SDLView : NSView {
1135  SDL_Window *_sdlWindow;
1136 }
1137 
1138 - (void)setSDLWindow:(SDL_Window*)window;
1139 
1140 /* The default implementation doesn't pass rightMouseDown to responder chain */
1141 - (void)rightMouseDown:(NSEvent *)theEvent;
1142 - (BOOL)mouseDownCanMoveWindow;
1143 - (void)drawRect:(NSRect)dirtyRect;
1144 - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent;
1145 @end
1146 
1147 @implementation SDLView
1148 - (void)setSDLWindow:(SDL_Window*)window
1149 {
1150  _sdlWindow = window;
1151 }
1152 
1153 - (void)drawRect:(NSRect)dirtyRect
1154 {
1155  SDL_SendWindowEvent(_sdlWindow, SDL_WINDOWEVENT_EXPOSED, 0, 0);
1156 }
1157 
1158 - (void)rightMouseDown:(NSEvent *)theEvent
1159 {
1160  [[self nextResponder] rightMouseDown:theEvent];
1161 }
1162 
1163 - (BOOL)mouseDownCanMoveWindow
1164 {
1165  /* Always say YES, but this doesn't do anything until we call
1166  -[NSWindow setMovableByWindowBackground:YES], which we ninja-toggle
1167  during mouse events when we're using a drag area. */
1168  return YES;
1169 }
1170 
1171 - (void)resetCursorRects
1172 {
1173  [super resetCursorRects];
1174  SDL_Mouse *mouse = SDL_GetMouse();
1175 
1176  if (mouse->cursor_shown && mouse->cur_cursor && !mouse->relative_mode) {
1177  [self addCursorRect:[self bounds]
1178  cursor:mouse->cur_cursor->driverdata];
1179  } else {
1180  [self addCursorRect:[self bounds]
1181  cursor:[NSCursor invisibleCursor]];
1182  }
1183 }
1184 
1185 - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
1186 {
1189  } else {
1190  return SDL_GetHintBoolean("SDL_MAC_MOUSE_FOCUS_CLICKTHROUGH", SDL_FALSE);
1191  }
1192 }
1193 @end
1194 
1195 static int
1196 SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created)
1197 { @autoreleasepool
1198 {
1199  SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
1200  SDL_WindowData *data;
1201 
1202  /* Allocate the window data */
1203  window->driverdata = data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data));
1204  if (!data) {
1205  return SDL_OutOfMemory();
1206  }
1207  data->window = window;
1208  data->nswindow = nswindow;
1209  data->created = created;
1210  data->videodata = videodata;
1211  data->nscontexts = [[NSMutableArray alloc] init];
1212 
1213  /* Create an event listener for the window */
1214  data->listener = [[Cocoa_WindowListener alloc] init];
1215 
1216  /* Fill in the SDL window with the window data */
1217  {
1218  NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
1219  ConvertNSRect([nswindow screen], (window->flags & FULLSCREEN_MASK), &rect);
1220  window->x = (int)rect.origin.x;
1221  window->y = (int)rect.origin.y;
1222  window->w = (int)rect.size.width;
1223  window->h = (int)rect.size.height;
1224  }
1225 
1226  /* Set up the listener after we create the view */
1227  [data->listener listen:data];
1228 
1229  if ([nswindow isVisible]) {
1230  window->flags |= SDL_WINDOW_SHOWN;
1231  } else {
1232  window->flags &= ~SDL_WINDOW_SHOWN;
1233  }
1234 
1235  {
1236  unsigned long style = [nswindow styleMask];
1237 
1238  if (style == NSWindowStyleMaskBorderless) {
1239  window->flags |= SDL_WINDOW_BORDERLESS;
1240  } else {
1241  window->flags &= ~SDL_WINDOW_BORDERLESS;
1242  }
1243  if (style & NSWindowStyleMaskResizable) {
1244  window->flags |= SDL_WINDOW_RESIZABLE;
1245  } else {
1246  window->flags &= ~SDL_WINDOW_RESIZABLE;
1247  }
1248  }
1249 
1250  /* isZoomed always returns true if the window is not resizable */
1251  if ((window->flags & SDL_WINDOW_RESIZABLE) && [nswindow isZoomed]) {
1252  window->flags |= SDL_WINDOW_MAXIMIZED;
1253  } else {
1254  window->flags &= ~SDL_WINDOW_MAXIMIZED;
1255  }
1256 
1257  if ([nswindow isMiniaturized]) {
1258  window->flags |= SDL_WINDOW_MINIMIZED;
1259  } else {
1260  window->flags &= ~SDL_WINDOW_MINIMIZED;
1261  }
1262 
1263  if ([nswindow isKeyWindow]) {
1264  window->flags |= SDL_WINDOW_INPUT_FOCUS;
1266  }
1267 
1268  /* Prevents the window's "window device" from being destroyed when it is
1269  * hidden. See http://www.mikeash.com/pyblog/nsopenglcontext-and-one-shot.html
1270  */
1271  [nswindow setOneShot:NO];
1272 
1273  /* All done! */
1274  window->driverdata = data;
1275  return 0;
1276 }}
1277 
1278 int
1280 { @autoreleasepool
1281 {
1282  SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
1283  NSWindow *nswindow;
1284  SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
1285  NSRect rect;
1286  SDL_Rect bounds;
1287  NSUInteger style;
1288  NSArray *screens = [NSScreen screens];
1289 
1290  Cocoa_GetDisplayBounds(_this, display, &bounds);
1291  rect.origin.x = window->x;
1292  rect.origin.y = window->y;
1293  rect.size.width = window->w;
1294  rect.size.height = window->h;
1295  ConvertNSRect([screens objectAtIndex:0], (window->flags & FULLSCREEN_MASK), &rect);
1296 
1297  style = GetWindowStyle(window);
1298 
1299  /* Figure out which screen to place this window */
1300  NSScreen *screen = nil;
1301  for (NSScreen *candidate in screens) {
1302  NSRect screenRect = [candidate frame];
1303  if (rect.origin.x >= screenRect.origin.x &&
1304  rect.origin.x < screenRect.origin.x + screenRect.size.width &&
1305  rect.origin.y >= screenRect.origin.y &&
1306  rect.origin.y < screenRect.origin.y + screenRect.size.height) {
1307  screen = candidate;
1308  rect.origin.x -= screenRect.origin.x;
1309  rect.origin.y -= screenRect.origin.y;
1310  }
1311  }
1312 
1313  @try {
1314  nswindow = [[SDLWindow alloc] initWithContentRect:rect styleMask:style backing:NSBackingStoreBuffered defer:NO screen:screen];
1315  }
1316  @catch (NSException *e) {
1317  return SDL_SetError("%s", [[e reason] UTF8String]);
1318  }
1319  [nswindow setBackgroundColor:[NSColor blackColor]];
1320 
1321  if (videodata->allow_spaces) {
1322  SDL_assert(floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6);
1323  SDL_assert([nswindow respondsToSelector:@selector(toggleFullScreen:)]);
1324  /* we put FULLSCREEN_DESKTOP windows in their own Space, without a toggle button or menubar, later */
1325  if (window->flags & SDL_WINDOW_RESIZABLE) {
1326  /* resizable windows are Spaces-friendly: they get the "go fullscreen" toggle button on their titlebar. */
1327  [nswindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
1328  }
1329  }
1330 
1331  /* Create a default view for this window */
1332  rect = [nswindow contentRectForFrameRect:[nswindow frame]];
1333  SDLView *contentView = [[SDLView alloc] initWithFrame:rect];
1334  [contentView setSDLWindow:window];
1335 
1336  if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
1337  if ([contentView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) {
1338  [contentView setWantsBestResolutionOpenGLSurface:YES];
1339  }
1340  }
1341 
1342  [nswindow setContentView:contentView];
1343  [contentView release];
1344 
1345  /* Allow files and folders to be dragged onto the window by users */
1346  [nswindow registerForDraggedTypes:[NSArray arrayWithObject:(NSString *)kUTTypeFileURL]];
1347 
1348  if (SetupWindowData(_this, window, nswindow, SDL_TRUE) < 0) {
1349  [nswindow release];
1350  return -1;
1351  }
1352  return 0;
1353 }}
1354 
1355 int
1356 Cocoa_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
1357 { @autoreleasepool
1358 {
1359  NSWindow *nswindow = (NSWindow *) data;
1360  NSString *title;
1361 
1362  /* Query the title from the existing window */
1363  title = [nswindow title];
1364  if (title) {
1365  window->title = SDL_strdup([title UTF8String]);
1366  }
1367 
1368  return SetupWindowData(_this, window, nswindow, SDL_FALSE);
1369 }}
1370 
1371 void
1373 { @autoreleasepool
1374 {
1375  const char *title = window->title ? window->title : "";
1376  NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
1377  NSString *string = [[NSString alloc] initWithUTF8String:title];
1378  [nswindow setTitle:string];
1379  [string release];
1380 }}
1381 
1382 void
1384 { @autoreleasepool
1385 {
1386  NSImage *nsimage = Cocoa_CreateImage(icon);
1387 
1388  if (nsimage) {
1389  [NSApp setApplicationIconImage:nsimage];
1390  }
1391 }}
1392 
1393 void
1395 { @autoreleasepool
1396 {
1397  SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
1398  NSWindow *nswindow = windata->nswindow;
1399  NSRect rect;
1400  Uint32 moveHack;
1401 
1402  rect.origin.x = window->x;
1403  rect.origin.y = window->y;
1404  rect.size.width = window->w;
1405  rect.size.height = window->h;
1406  ConvertNSRect([nswindow screen], (window->flags & FULLSCREEN_MASK), &rect);
1407 
1408  moveHack = s_moveHack;
1409  s_moveHack = 0;
1410  [nswindow setFrameOrigin:rect.origin];
1411  s_moveHack = moveHack;
1412 
1413  ScheduleContextUpdates(windata);
1414 }}
1415 
1416 void
1418 { @autoreleasepool
1419 {
1420  SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
1421  NSWindow *nswindow = windata->nswindow;
1422  NSRect rect;
1423  Uint32 moveHack;
1424 
1425  /* Cocoa will resize the window from the bottom-left rather than the
1426  * top-left when -[nswindow setContentSize:] is used, so we must set the
1427  * entire frame based on the new size, in order to preserve the position.
1428  */
1429  rect.origin.x = window->x;
1430  rect.origin.y = window->y;
1431  rect.size.width = window->w;
1432  rect.size.height = window->h;
1433  ConvertNSRect([nswindow screen], (window->flags & FULLSCREEN_MASK), &rect);
1434 
1435  moveHack = s_moveHack;
1436  s_moveHack = 0;
1437  [nswindow setFrame:[nswindow frameRectForContentRect:rect] display:YES];
1438  s_moveHack = moveHack;
1439 
1440  ScheduleContextUpdates(windata);
1441 }}
1442 
1443 void
1445 { @autoreleasepool
1446 {
1447  SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
1448 
1449  NSSize minSize;
1450  minSize.width = window->min_w;
1451  minSize.height = window->min_h;
1452 
1453  [windata->nswindow setContentMinSize:minSize];
1454 }}
1455 
1456 void
1458 { @autoreleasepool
1459 {
1460  SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
1461 
1462  NSSize maxSize;
1463  maxSize.width = window->max_w;
1464  maxSize.height = window->max_h;
1465 
1466  [windata->nswindow setContentMaxSize:maxSize];
1467 }}
1468 
1469 void
1471 { @autoreleasepool
1472 {
1473  SDL_WindowData *windowData = ((SDL_WindowData *) window->driverdata);
1474  NSWindow *nswindow = windowData->nswindow;
1475 
1476  if (![nswindow isMiniaturized]) {
1477  [windowData->listener pauseVisibleObservation];
1478  [nswindow makeKeyAndOrderFront:nil];
1479  [windowData->listener resumeVisibleObservation];
1480  }
1481 }}
1482 
1483 void
1485 { @autoreleasepool
1486 {
1487  NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
1488 
1489  [nswindow orderOut:nil];
1490 }}
1491 
1492 void
1494 { @autoreleasepool
1495 {
1496  SDL_WindowData *windowData = ((SDL_WindowData *) window->driverdata);
1497  NSWindow *nswindow = windowData->nswindow;
1498 
1499  /* makeKeyAndOrderFront: has the side-effect of deminiaturizing and showing
1500  a minimized or hidden window, so check for that before showing it.
1501  */
1502  [windowData->listener pauseVisibleObservation];
1503  if (![nswindow isMiniaturized] && [nswindow isVisible]) {
1504  [NSApp activateIgnoringOtherApps:YES];
1505  [nswindow makeKeyAndOrderFront:nil];
1506  }
1507  [windowData->listener resumeVisibleObservation];
1508 }}
1509 
1510 void
1512 { @autoreleasepool
1513 {
1514  SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
1515  NSWindow *nswindow = windata->nswindow;
1516 
1517  [nswindow zoom:nil];
1518 
1519  ScheduleContextUpdates(windata);
1520 }}
1521 
1522 void
1524 { @autoreleasepool
1525 {
1526  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1527  NSWindow *nswindow = data->nswindow;
1528 
1529  if ([data->listener isInFullscreenSpaceTransition]) {
1530  [data->listener addPendingWindowOperation:PENDING_OPERATION_MINIMIZE];
1531  } else {
1532  [nswindow miniaturize:nil];
1533  }
1534 }}
1535 
1536 void
1538 { @autoreleasepool
1539 {
1540  NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
1541 
1542  if ([nswindow isMiniaturized]) {
1543  [nswindow deminiaturize:nil];
1544  } else if ((window->flags & SDL_WINDOW_RESIZABLE) && [nswindow isZoomed]) {
1545  [nswindow zoom:nil];
1546  }
1547 }}
1548 
1549 void
1550 Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
1551 { @autoreleasepool
1552 {
1553  if (SetWindowStyle(window, GetWindowStyle(window))) {
1554  if (bordered) {
1555  Cocoa_SetWindowTitle(_this, window); /* this got blanked out. */
1556  }
1557  }
1558 }}
1559 
1560 void
1561 Cocoa_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable)
1562 { @autoreleasepool
1563 {
1564  /* Don't set this if we're in a space!
1565  * The window will get permanently stuck if resizable is false.
1566  * -flibit
1567  */
1568  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1569  Cocoa_WindowListener *listener = data->listener;
1570  if (![listener isInFullscreenSpace]) {
1571  SetWindowStyle(window, GetWindowStyle(window));
1572  }
1573 }}
1574 
1575 void
1576 Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
1577 { @autoreleasepool
1578 {
1579  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1580  NSWindow *nswindow = data->nswindow;
1581  NSRect rect;
1582 
1583  /* The view responder chain gets messed with during setStyleMask */
1584  if ([[nswindow contentView] nextResponder] == data->listener) {
1585  [[nswindow contentView] setNextResponder:nil];
1586  }
1587 
1588  if (fullscreen) {
1589  SDL_Rect bounds;
1590 
1591  Cocoa_GetDisplayBounds(_this, display, &bounds);
1592  rect.origin.x = bounds.x;
1593  rect.origin.y = bounds.y;
1594  rect.size.width = bounds.w;
1595  rect.size.height = bounds.h;
1596  ConvertNSRect([nswindow screen], fullscreen, &rect);
1597 
1598  /* Hack to fix origin on Mac OS X 10.4 */
1599  NSRect screenRect = [[nswindow screen] frame];
1600  if (screenRect.size.height >= 1.0f) {
1601  rect.origin.y += (screenRect.size.height - rect.size.height);
1602  }
1603 
1604  [nswindow setStyleMask:NSWindowStyleMaskBorderless];
1605  } else {
1606  rect.origin.x = window->windowed.x;
1607  rect.origin.y = window->windowed.y;
1608  rect.size.width = window->windowed.w;
1609  rect.size.height = window->windowed.h;
1610  ConvertNSRect([nswindow screen], fullscreen, &rect);
1611 
1612  [nswindow setStyleMask:GetWindowStyle(window)];
1613 
1614  /* Hack to restore window decorations on Mac OS X 10.10 */
1615  NSRect frameRect = [nswindow frame];
1616  [nswindow setFrame:NSMakeRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width + 1, frameRect.size.height) display:NO];
1617  [nswindow setFrame:frameRect display:NO];
1618  }
1619 
1620  /* The view responder chain gets messed with during setStyleMask */
1621  if ([[nswindow contentView] nextResponder] != data->listener) {
1622  [[nswindow contentView] setNextResponder:data->listener];
1623  }
1624 
1625  s_moveHack = 0;
1626  [nswindow setContentSize:rect.size];
1627  [nswindow setFrameOrigin:rect.origin];
1628  s_moveHack = SDL_GetTicks();
1629 
1630  /* When the window style changes the title is cleared */
1631  if (!fullscreen) {
1632  Cocoa_SetWindowTitle(_this, window);
1633  }
1634 
1635  if (SDL_ShouldAllowTopmost() && fullscreen) {
1636  /* OpenGL is rendering to the window, so make it visible! */
1637  [nswindow setLevel:CGShieldingWindowLevel()];
1638  } else {
1639  [nswindow setLevel:kCGNormalWindowLevel];
1640  }
1641 
1642  if ([nswindow isVisible] || fullscreen) {
1643  [data->listener pauseVisibleObservation];
1644  [nswindow makeKeyAndOrderFront:nil];
1645  [data->listener resumeVisibleObservation];
1646  }
1647 
1648  ScheduleContextUpdates(data);
1649 }}
1650 
1651 int
1652 Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp)
1653 {
1654  SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
1655  CGDirectDisplayID display_id = ((SDL_DisplayData *)display->driverdata)->display;
1656  const uint32_t tableSize = 256;
1657  CGGammaValue redTable[tableSize];
1658  CGGammaValue greenTable[tableSize];
1659  CGGammaValue blueTable[tableSize];
1660  uint32_t i;
1661  float inv65535 = 1.0f / 65535.0f;
1662 
1663  /* Extract gamma values into separate tables, convert to floats between 0.0 and 1.0 */
1664  for (i = 0; i < 256; i++) {
1665  redTable[i] = ramp[0*256+i] * inv65535;
1666  greenTable[i] = ramp[1*256+i] * inv65535;
1667  blueTable[i] = ramp[2*256+i] * inv65535;
1668  }
1669 
1670  if (CGSetDisplayTransferByTable(display_id, tableSize,
1671  redTable, greenTable, blueTable) != CGDisplayNoErr) {
1672  return SDL_SetError("CGSetDisplayTransferByTable()");
1673  }
1674  return 0;
1675 }
1676 
1677 int
1679 {
1680  SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
1681  CGDirectDisplayID display_id = ((SDL_DisplayData *)display->driverdata)->display;
1682  const uint32_t tableSize = 256;
1683  CGGammaValue redTable[tableSize];
1684  CGGammaValue greenTable[tableSize];
1685  CGGammaValue blueTable[tableSize];
1686  uint32_t i, tableCopied;
1687 
1688  if (CGGetDisplayTransferByTable(display_id, tableSize,
1689  redTable, greenTable, blueTable, &tableCopied) != CGDisplayNoErr) {
1690  return SDL_SetError("CGGetDisplayTransferByTable()");
1691  }
1692 
1693  for (i = 0; i < tableCopied; i++) {
1694  ramp[0*256+i] = (Uint16)(redTable[i] * 65535.0f);
1695  ramp[1*256+i] = (Uint16)(greenTable[i] * 65535.0f);
1696  ramp[2*256+i] = (Uint16)(blueTable[i] * 65535.0f);
1697  }
1698  return 0;
1699 }
1700 
1701 void
1702 Cocoa_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
1703 {
1704  SDL_Mouse *mouse = SDL_GetMouse();
1705  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1706 
1707  /* Enable or disable the event tap as necessary */
1708  Cocoa_EnableMouseEventTap(mouse->driverdata, grabbed);
1709 
1710  /* Move the cursor to the nearest point in the window */
1711  if (grabbed && data && ![data->listener isMoving]) {
1712  int x, y;
1713  CGPoint cgpoint;
1714 
1715  SDL_GetMouseState(&x, &y);
1716  cgpoint.x = window->x + x;
1717  cgpoint.y = window->y + y;
1718 
1719  Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y);
1720 
1721  DLog("Returning cursor to (%g, %g)", cgpoint.x, cgpoint.y);
1722  CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint);
1723  }
1724 
1725  if ( data && (window->flags & SDL_WINDOW_FULLSCREEN) ) {
1727  && ![data->listener isInFullscreenSpace]) {
1728  /* OpenGL is rendering to the window, so make it visible! */
1729  /* Doing this in 10.11 while in a Space breaks things (bug #3152) */
1730  [data->nswindow setLevel:CGShieldingWindowLevel()];
1731  } else {
1732  [data->nswindow setLevel:kCGNormalWindowLevel];
1733  }
1734  }
1735 }
1736 
1737 void
1739 { @autoreleasepool
1740 {
1741  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1742 
1743  if (data) {
1744  if ([data->listener isInFullscreenSpace]) {
1745  [NSMenu setMenuBarVisible:YES];
1746  }
1747  [data->listener close];
1748  [data->listener release];
1749  if (data->created) {
1750  [data->nswindow close];
1751  }
1752 
1753  NSArray *contexts = [[data->nscontexts copy] autorelease];
1754  for (SDLOpenGLContext *context in contexts) {
1755  /* Calling setWindow:NULL causes the context to remove itself from the context list. */
1756  [context setWindow:NULL];
1757  }
1758  [data->nscontexts release];
1759 
1760  SDL_free(data);
1761  }
1762  window->driverdata = NULL;
1763 }}
1764 
1765 SDL_bool
1767 {
1768  NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
1769 
1770  if (info->version.major <= SDL_MAJOR_VERSION) {
1771  info->subsystem = SDL_SYSWM_COCOA;
1772  info->info.cocoa.window = nswindow;
1773  return SDL_TRUE;
1774  } else {
1775  SDL_SetError("Application not compiled with SDL %d.%d",
1777  return SDL_FALSE;
1778  }
1779 }
1780 
1781 SDL_bool
1782 Cocoa_IsWindowInFullscreenSpace(SDL_Window * window)
1783 {
1784  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1785 
1786  if ([data->listener isInFullscreenSpace]) {
1787  return SDL_TRUE;
1788  } else {
1789  return SDL_FALSE;
1790  }
1791 }
1792 
1793 SDL_bool
1794 Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state)
1795 { @autoreleasepool
1796 {
1797  SDL_bool succeeded = SDL_FALSE;
1798  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1799 
1800  if ([data->listener setFullscreenSpace:(state ? YES : NO)]) {
1801  const int maxattempts = 3;
1802  int attempt = 0;
1803  while (++attempt <= maxattempts) {
1804  /* Wait for the transition to complete, so application changes
1805  take effect properly (e.g. setting the window size, etc.)
1806  */
1807  const int limit = 10000;
1808  int count = 0;
1809  while ([data->listener isInFullscreenSpaceTransition]) {
1810  if ( ++count == limit ) {
1811  /* Uh oh, transition isn't completing. Should we assert? */
1812  break;
1813  }
1814  SDL_Delay(1);
1815  SDL_PumpEvents();
1816  }
1817  if ([data->listener isInFullscreenSpace] == (state ? YES : NO))
1818  break;
1819  /* Try again, the last attempt was interrupted by user gestures */
1820  if (![data->listener setFullscreenSpace:(state ? YES : NO)])
1821  break; /* ??? */
1822  }
1823  /* Return TRUE to prevent non-space fullscreen logic from running */
1824  succeeded = SDL_TRUE;
1825  }
1826 
1827  return succeeded;
1828 }}
1829 
1830 int
1832 {
1833  return 0; /* just succeed, the real work is done elsewhere. */
1834 }
1835 
1836 int
1837 Cocoa_SetWindowOpacity(_THIS, SDL_Window * window, float opacity)
1838 {
1839  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1840  [data->nswindow setAlphaValue:opacity];
1841  return 0;
1842 }
1843 
1844 #endif /* SDL_VIDEO_DRIVER_COCOA */
1845 
1846 /* vi: set ts=4 sw=4 expandtab: */
SDL_Window * next
Definition: SDL_sysvideo.h:114
int Cocoa_CreateWindowFrom(_THIS, SDL_Window *window, const void *data)
EGLNativeDisplayType * display_id
Definition: eglext.h:1024
#define SDL_MINOR_VERSION
Definition: SDL_version.h:61
GLint limit
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
SDL_Mouse * SDL_GetMouse(void)
Definition: SDL_mouse.c:112
NSMutableArray * nscontexts
#define SDL_IsShapedWindow
SDL_Texture * button
void SDL_SetKeyboardFocus(SDL_Window *window)
Definition: SDL_keyboard.c:630
void Cocoa_MinimizeWindow(_THIS, SDL_Window *window)
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 Uint32 * e
void * hit_test_data
Definition: SDL_sysvideo.h:107
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
void Cocoa_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon)
#define SDL_MAJOR_VERSION
Definition: SDL_version.h:60
SDL_bool relative_mode_warp
Definition: SDL_mouse_c.h:88
void Cocoa_SetWindowMaximumSize(_THIS, SDL_Window *window)
SDL_Window * focus
Definition: SDL_mouse_c.h:77
Sint64 SDL_FingerID
Definition: SDL_touch.h:42
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1571
SDL_Rect rect
Definition: testrelative.c:27
int(* SetRelativeMouseMode)(SDL_bool enabled)
Definition: SDL_mouse_c.h:67
int SDL_SendDropFile(SDL_Window *window, const char *file)
void Cocoa_SetWindowResizable(_THIS, SDL_Window *window, SDL_bool resizable)
void Cocoa_SetWindowBordered(_THIS, SDL_Window *window, SDL_bool bordered)
GLfloat GLfloat GLfloat GLfloat h
#define SDL_BUTTON_RIGHT
Definition: SDL_mouse.h:284
void Cocoa_EnableMouseEventTap(SDL_MouseData *driverdata, SDL_bool enabled)
#define SDL_GetTouchFinger
The structure that defines a point.
Definition: SDL_rect.h:48
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
static screen_context_t context
Definition: video.c:25
#define SDL_GetHint
int SDL_SendMouseButtonClicks(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks)
Definition: SDL_mouse.c:499
int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_bool down, float x, float y, float pressure)
Definition: SDL_touch.c:222
SDL_version version
Definition: SDL_syswm.h:196
Uint8 major
Definition: SDL_version.h:53
GLfloat f
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
SDL_bool is_destroying
Definition: SDL_sysvideo.h:101
#define SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK
A variable that determines whether ctrl+click should generate a right-click event on Mac...
Definition: SDL_hints.h:511
SDL_SYSWM_TYPE subsystem
Definition: SDL_syswm.h:197
void Cocoa_SetWindowTitle(_THIS, SDL_Window *window)
GLsizei GLenum GLenum * types
int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1, int data2)
SDL_Window * window
void SDL_SetMouseFocus(SDL_Window *window)
Definition: SDL_mouse.c:151
void Cocoa_HandleMouseWarp(CGFloat x, CGFloat y)
#define SDL_GetKeyboardFocus
uint32_t Uint32
Definition: SDL_stdinc.h:181
void Cocoa_SetWindowPosition(_THIS, SDL_Window *window)
unsigned int modifierFlags
SDL_Rect windowed
Definition: SDL_sysvideo.h:87
int SDL_SendDropComplete(SDL_Window *window)
int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, float x, float y, float pressure)
Definition: SDL_touch.c:284
#define SDL_GetHintBoolean
#define SDL_PumpEvents
static SDL_VideoDevice * _this
Definition: SDL_video.c:121
SDL_HitTestResult
Possible return values from the SDL_HitTest callback.
Definition: SDL_video.h:991
void Cocoa_RestoreWindow(_THIS, SDL_Window *window)
int x
Definition: SDL_rect.h:50
BOOL isInFullscreenSpaceTransition()
void Cocoa_ShowWindow(_THIS, SDL_Window *window)
NSImage * Cocoa_CreateImage(SDL_Surface *surface)
int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
Definition: SDL_mouse.c:237
#define SDL_BUTTON_LEFT
Definition: SDL_mouse.h:282
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
Cocoa_WindowListener * listener
#define _THIS
struct SDL_VideoData * videodata
#define SDL_free
int Cocoa_SetWindowGammaRamp(_THIS, SDL_Window *window, const Uint16 *ramp)
void Cocoa_DestroyWindow(_THIS, SDL_Window *window)
GLint location
void Cocoa_RaiseWindow(_THIS, SDL_Window *window)
SDL_bool cursor_shown
Definition: SDL_mouse_c.h:102
SDL_bool relative_mode
Definition: SDL_mouse_c.h:87
SDL_bool Cocoa_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
void Cocoa_CheckClipboardUpdate(struct SDL_VideoData *data)
GLubyte GLubyte GLubyte GLubyte w
SDL_WindowData * _data
Sint64 SDL_TouchID
Definition: SDL_touch.h:41
void Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event)
#define SDL_BUTTON_MIDDLE
Definition: SDL_mouse.h:283
PendingWindowOperation
char * title
Definition: SDL_sysvideo.h:77
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
#define SDL_GetNumTouchFingers
int x
Definition: SDL_rect.h:66
int Cocoa_SetWindowOpacity(_THIS, SDL_Window *window, float opacity)
SDL_Window * windows
Definition: SDL_sysvideo.h:313
int SDL_AddTouch(SDL_TouchID touchID, const char *name)
Definition: SDL_touch.c:136
int w
Definition: SDL_rect.h:67
void Cocoa_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
static const NSUInteger NSEventModifierFlagCapsLock
GLsizeiptr size
int(* WarpMouseGlobal)(int x, int y)
Definition: SDL_mouse_c.h:64
NSWindow * nswindow
#define SDL_Delay
GLenum GLenum GLsizei const GLuint GLboolean enabled
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
void SDL_ToggleModState(const SDL_Keymod modstate, const SDL_bool toggle)
Definition: SDL_keyboard.c:865
#define SDL_assert(condition)
Definition: SDL_assert.h:169
PendingWindowOperation pendingWindowOperation
Window window
Definition: SDL_syswm.h:218
SDL_bool SDL_ShouldAllowTopmost(void)
Definition: SDL_video.c:3888
#define NULL
Definition: begin_code.h:164
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_bool
Definition: SDL_stdinc.h:139
#define SDL_GetMouseFocus
SDL_HitTest hit_test
Definition: SDL_sysvideo.h:106
unsigned int uint32_t
Uint32 last_fullscreen_flags
Definition: SDL_sysvideo.h:84
#define SDL_SetError
int Cocoa_CreateWindow(_THIS, SDL_Window *window)
int Cocoa_GetWindowGammaRamp(_THIS, SDL_Window *window, Uint16 *ramp)
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
#define SDL_calloc
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:1073
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
int h
Definition: SDL_rect.h:67
#define SDL_strdup
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
The type used to identify a window.
Definition: SDL_sysvideo.h:73
void Cocoa_SetWindowSize(_THIS, SDL_Window *window)
int Cocoa_ResizeWindowShape(SDL_Window *window)
uint16_t Uint16
Definition: SDL_stdinc.h:169
GLuint GLuint GLsizei GLenum type
Definition: SDL_opengl.h:1571
SDL_VideoDevice * SDL_GetVideoDevice(void)
Definition: SDL_video.c:586
union SDL_SysWMinfo::@18 info
GLenum array
SDL_FingerID id
Definition: SDL_touch.h:46
GLsizei const GLchar *const * path
void Cocoa_HideWindow(_THIS, SDL_Window *window)
int Cocoa_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect)
void * driverdata
Definition: SDL_sysvideo.h:111
#define FULLSCREEN_MASK
Definition: SDL_video.c:147
void Cocoa_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed)
#define SDL_PRESSED
Definition: SDL_events.h:50
SDL_Cursor * cur_cursor
Definition: SDL_mouse_c.h:101
void * driverdata
Definition: SDL_mouse_c.h:105
Uint32 flags
Definition: SDL_sysvideo.h:83
#define SDL_RELEASED
Definition: SDL_events.h:49
GLuint in
#define SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH
Allow mouse click events when clicking to focus an SDL window.
Definition: SDL_hints.h:282
SDL_Renderer * screen
#define floor
Definition: math_private.h:37
int y
Definition: SDL_rect.h:66
#define SDL_GetMouseState
void Cocoa_MaximizeWindow(_THIS, SDL_Window *window)
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:64
int Cocoa_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
void Cocoa_SetWindowMinimumSize(_THIS, SDL_Window *window)