Added support for new style fullscreen transitions on Mac OS X
parent
2b93fa0892
commit
4c1322f693
|
@ -147,6 +147,7 @@ CreateApplicationMenus(void)
|
||||||
NSMenu *appleMenu;
|
NSMenu *appleMenu;
|
||||||
NSMenu *serviceMenu;
|
NSMenu *serviceMenu;
|
||||||
NSMenu *windowMenu;
|
NSMenu *windowMenu;
|
||||||
|
NSMenu *viewMenu;
|
||||||
NSMenuItem *menuItem;
|
NSMenuItem *menuItem;
|
||||||
|
|
||||||
if (NSApp == nil) {
|
if (NSApp == nil) {
|
||||||
|
@ -220,6 +221,25 @@ CreateApplicationMenus(void)
|
||||||
/* Tell the application object that this is now the window menu */
|
/* Tell the application object that this is now the window menu */
|
||||||
[NSApp setWindowsMenu:windowMenu];
|
[NSApp setWindowsMenu:windowMenu];
|
||||||
[windowMenu release];
|
[windowMenu release];
|
||||||
|
|
||||||
|
|
||||||
|
/* Add the fullscreen view toggle menu option, if supported */
|
||||||
|
if ([NSApp respondsToSelector:@selector(setPresentationOptions:)]) {
|
||||||
|
/* Create the view menu */
|
||||||
|
viewMenu = [[NSMenu alloc] initWithTitle:@"View"];
|
||||||
|
|
||||||
|
/* Add menu items */
|
||||||
|
menuItem = [viewMenu addItemWithTitle:@"Toggle Full Screen" action:@selector(toggleFullScreen:) keyEquivalent:@"f"];
|
||||||
|
[menuItem setKeyEquivalentModifierMask:NSControlKeyMask | NSCommandKeyMask];
|
||||||
|
|
||||||
|
/* Put menu into the menubar */
|
||||||
|
menuItem = [[NSMenuItem alloc] initWithTitle:@"View" action:nil keyEquivalent:@""];
|
||||||
|
[menuItem setSubmenu:viewMenu];
|
||||||
|
[[NSApp mainMenu] addItem:menuItem];
|
||||||
|
[menuItem release];
|
||||||
|
|
||||||
|
[viewMenu release];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -32,11 +32,14 @@ typedef struct SDL_WindowData SDL_WindowData;
|
||||||
BOOL observingVisible;
|
BOOL observingVisible;
|
||||||
BOOL wasCtrlLeft;
|
BOOL wasCtrlLeft;
|
||||||
BOOL wasVisible;
|
BOOL wasVisible;
|
||||||
|
BOOL isFullscreen;
|
||||||
|
BOOL inFullscreenTransition;
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void) listen:(SDL_WindowData *) data;
|
-(void) listen:(SDL_WindowData *) data;
|
||||||
-(void) pauseVisibleObservation;
|
-(void) pauseVisibleObservation;
|
||||||
-(void) resumeVisibleObservation;
|
-(void) resumeVisibleObservation;
|
||||||
|
-(BOOL) isToggledFullscreen;
|
||||||
-(void) close;
|
-(void) close;
|
||||||
|
|
||||||
/* Window delegate functionality */
|
/* Window delegate functionality */
|
||||||
|
@ -48,6 +51,10 @@ typedef struct SDL_WindowData SDL_WindowData;
|
||||||
-(void) windowDidDeminiaturize:(NSNotification *) aNotification;
|
-(void) windowDidDeminiaturize:(NSNotification *) aNotification;
|
||||||
-(void) windowDidBecomeKey:(NSNotification *) aNotification;
|
-(void) windowDidBecomeKey:(NSNotification *) aNotification;
|
||||||
-(void) windowDidResignKey:(NSNotification *) aNotification;
|
-(void) windowDidResignKey:(NSNotification *) aNotification;
|
||||||
|
-(void) windowWillEnterFullScreen:(NSNotification *) aNotification;
|
||||||
|
-(void) windowDidEnterFullScreen:(NSNotification *) aNotification;
|
||||||
|
-(void) windowWillExitFullScreen:(NSNotification *) aNotification;
|
||||||
|
-(void) windowDidExitFullScreen:(NSNotification *) aNotification;
|
||||||
|
|
||||||
/* Window event handling */
|
/* Window event handling */
|
||||||
-(void) mouseDown:(NSEvent *) theEvent;
|
-(void) mouseDown:(NSEvent *) theEvent;
|
||||||
|
|
|
@ -50,7 +50,8 @@ static void ConvertNSRect(NSRect *r)
|
||||||
r->origin.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - r->origin.y - r->size.height;
|
r->origin.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - r->origin.y - r->size.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ScheduleContextUpdates(SDL_WindowData *data)
|
static void
|
||||||
|
ScheduleContextUpdates(SDL_WindowData *data)
|
||||||
{
|
{
|
||||||
NSMutableArray *contexts = data->nscontexts;
|
NSMutableArray *contexts = data->nscontexts;
|
||||||
@synchronized (contexts) {
|
@synchronized (contexts) {
|
||||||
|
@ -60,12 +61,34 @@ static void ScheduleContextUpdates(SDL_WindowData *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetHintCtrlClickEmulateRightClick()
|
static int
|
||||||
|
GetHintCtrlClickEmulateRightClick()
|
||||||
{
|
{
|
||||||
const char *hint = SDL_GetHint( SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK );
|
const char *hint = SDL_GetHint( SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK );
|
||||||
return hint != NULL && *hint != '0';
|
return hint != NULL && *hint != '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
GetWindowStyle(SDL_Window * window)
|
||||||
|
{
|
||||||
|
unsigned int style;
|
||||||
|
|
||||||
|
if (window->flags & SDL_WINDOW_FULLSCREEN) {
|
||||||
|
style = NSBorderlessWindowMask;
|
||||||
|
} else {
|
||||||
|
if (window->flags & SDL_WINDOW_BORDERLESS) {
|
||||||
|
style = NSBorderlessWindowMask;
|
||||||
|
} else {
|
||||||
|
style = (NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask);
|
||||||
|
}
|
||||||
|
if (window->flags & SDL_WINDOW_RESIZABLE) {
|
||||||
|
style |= NSResizableWindowMask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@implementation Cocoa_WindowListener
|
@implementation Cocoa_WindowListener
|
||||||
|
|
||||||
- (void)listen:(SDL_WindowData *)data
|
- (void)listen:(SDL_WindowData *)data
|
||||||
|
@ -78,6 +101,8 @@ static int GetHintCtrlClickEmulateRightClick()
|
||||||
observingVisible = YES;
|
observingVisible = YES;
|
||||||
wasCtrlLeft = NO;
|
wasCtrlLeft = NO;
|
||||||
wasVisible = [window isVisible];
|
wasVisible = [window isVisible];
|
||||||
|
isFullscreen = NO;
|
||||||
|
inFullscreenTransition = NO;
|
||||||
|
|
||||||
center = [NSNotificationCenter defaultCenter];
|
center = [NSNotificationCenter defaultCenter];
|
||||||
|
|
||||||
|
@ -89,6 +114,10 @@ static int GetHintCtrlClickEmulateRightClick()
|
||||||
[center addObserver:self selector:@selector(windowDidDeminiaturize:) name:NSWindowDidDeminiaturizeNotification object:window];
|
[center addObserver:self selector:@selector(windowDidDeminiaturize:) name:NSWindowDidDeminiaturizeNotification object:window];
|
||||||
[center addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:window];
|
[center addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:window];
|
||||||
[center addObserver:self selector:@selector(windowDidResignKey:) name:NSWindowDidResignKeyNotification object:window];
|
[center addObserver:self selector:@selector(windowDidResignKey:) name:NSWindowDidResignKeyNotification object:window];
|
||||||
|
[center addObserver:self selector:@selector(windowWillEnterFullScreen:) name:NSWindowWillEnterFullScreenNotification object:window];
|
||||||
|
[center addObserver:self selector:@selector(windowDidEnterFullScreen:) name:NSWindowDidEnterFullScreenNotification object:window];
|
||||||
|
[center addObserver:self selector:@selector(windowWillExitFullScreen:) name:NSWindowWillExitFullScreenNotification object:window];
|
||||||
|
[center addObserver:self selector:@selector(windowDidExitFullScreen:) name:NSWindowDidExitFullScreenNotification object:window];
|
||||||
} else {
|
} else {
|
||||||
[window setDelegate:self];
|
[window setDelegate:self];
|
||||||
}
|
}
|
||||||
|
@ -152,6 +181,11 @@ static int GetHintCtrlClickEmulateRightClick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL) isToggledFullscreen
|
||||||
|
{
|
||||||
|
return isFullscreen;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)close
|
- (void)close
|
||||||
{
|
{
|
||||||
NSNotificationCenter *center;
|
NSNotificationCenter *center;
|
||||||
|
@ -169,6 +203,10 @@ static int GetHintCtrlClickEmulateRightClick()
|
||||||
[center removeObserver:self name:NSWindowDidDeminiaturizeNotification object:window];
|
[center removeObserver:self name:NSWindowDidDeminiaturizeNotification object:window];
|
||||||
[center removeObserver:self name:NSWindowDidBecomeKeyNotification object:window];
|
[center removeObserver:self name:NSWindowDidBecomeKeyNotification object:window];
|
||||||
[center removeObserver:self name:NSWindowDidResignKeyNotification object:window];
|
[center removeObserver:self name:NSWindowDidResignKeyNotification object:window];
|
||||||
|
[center removeObserver:self name:NSWindowWillEnterFullScreenNotification object:window];
|
||||||
|
[center removeObserver:self name:NSWindowDidEnterFullScreenNotification object:window];
|
||||||
|
[center removeObserver:self name:NSWindowWillExitFullScreenNotification object:window];
|
||||||
|
[center removeObserver:self name:NSWindowDidExitFullScreenNotification object:window];
|
||||||
} else {
|
} else {
|
||||||
[window setDelegate:nil];
|
[window setDelegate:nil];
|
||||||
}
|
}
|
||||||
|
@ -250,8 +288,15 @@ static int GetHintCtrlClickEmulateRightClick()
|
||||||
y = (int)rect.origin.y;
|
y = (int)rect.origin.y;
|
||||||
w = (int)rect.size.width;
|
w = (int)rect.size.width;
|
||||||
h = (int)rect.size.height;
|
h = (int)rect.size.height;
|
||||||
if (SDL_IsShapedWindow(_data->window))
|
|
||||||
|
if (inFullscreenTransition) {
|
||||||
|
/* We'll take care of this at the end of the transition */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SDL_IsShapedWindow(_data->window)) {
|
||||||
Cocoa_ResizeWindowShape(_data->window);
|
Cocoa_ResizeWindowShape(_data->window);
|
||||||
|
}
|
||||||
|
|
||||||
ScheduleContextUpdates(_data);
|
ScheduleContextUpdates(_data);
|
||||||
|
|
||||||
|
@ -317,6 +362,46 @@ static int GetHintCtrlClickEmulateRightClick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)windowWillEnterFullScreen:(NSNotification *)aNotification
|
||||||
|
{
|
||||||
|
SDL_Window *window = _data->window;
|
||||||
|
NSWindow *nswindow = _data->nswindow;
|
||||||
|
|
||||||
|
if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
|
||||||
|
if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) {
|
||||||
|
[nswindow setStyleMask:(NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask)];
|
||||||
|
} else {
|
||||||
|
[nswindow setStyleMask:NSBorderlessWindowMask];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isFullscreen = YES;
|
||||||
|
inFullscreenTransition = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)windowDidEnterFullScreen:(NSNotification *)aNotification
|
||||||
|
{
|
||||||
|
inFullscreenTransition = NO;
|
||||||
|
[self windowDidResize:aNotification];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)windowWillExitFullScreen:(NSNotification *)aNotification
|
||||||
|
{
|
||||||
|
inFullscreenTransition = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)windowDidExitFullScreen:(NSNotification *)aNotification
|
||||||
|
{
|
||||||
|
SDL_Window *window = _data->window;
|
||||||
|
NSWindow *nswindow = _data->nswindow;
|
||||||
|
|
||||||
|
if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
|
||||||
|
[nswindow setStyleMask:GetWindowStyle(window)];
|
||||||
|
}
|
||||||
|
isFullscreen = NO;
|
||||||
|
inFullscreenTransition = NO;
|
||||||
|
[self windowDidResize:aNotification];
|
||||||
|
}
|
||||||
|
|
||||||
/* We'll respond to key events by doing nothing so we don't beep.
|
/* We'll respond to key events by doing nothing so we don't beep.
|
||||||
* We could handle key messages here, but we lose some in the NSApp dispatch,
|
* We could handle key messages here, but we lose some in the NSApp dispatch,
|
||||||
* where they get converted to action messages, etc.
|
* where they get converted to action messages, etc.
|
||||||
|
@ -606,26 +691,6 @@ static int GetHintCtrlClickEmulateRightClick()
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
static unsigned int
|
|
||||||
GetWindowStyle(SDL_Window * window)
|
|
||||||
{
|
|
||||||
unsigned int style;
|
|
||||||
|
|
||||||
if (window->flags & SDL_WINDOW_FULLSCREEN) {
|
|
||||||
style = NSBorderlessWindowMask;
|
|
||||||
} else {
|
|
||||||
if (window->flags & SDL_WINDOW_BORDERLESS) {
|
|
||||||
style = NSBorderlessWindowMask;
|
|
||||||
} else {
|
|
||||||
style = (NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask);
|
|
||||||
}
|
|
||||||
if (window->flags & SDL_WINDOW_RESIZABLE) {
|
|
||||||
style |= NSResizableWindowMask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return style;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created)
|
SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created)
|
||||||
{
|
{
|
||||||
|
@ -758,6 +823,7 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
[nswindow setBackgroundColor:[NSColor blackColor]];
|
[nswindow setBackgroundColor:[NSColor blackColor]];
|
||||||
|
[nswindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
|
||||||
|
|
||||||
/* Create a default view for this window */
|
/* Create a default view for this window */
|
||||||
rect = [nswindow contentRectForFrameRect:[nswindow frame]];
|
rect = [nswindow contentRectForFrameRect:[nswindow frame]];
|
||||||
|
@ -1020,10 +1086,45 @@ Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
|
||||||
[pool release];
|
[pool release];
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static SDL_bool
|
||||||
Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
|
Cocoa_CanToggleFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
|
||||||
|
{
|
||||||
|
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||||
|
NSWindow *nswindow = data->nswindow;
|
||||||
|
|
||||||
|
if (![nswindow respondsToSelector: @selector(toggleFullScreen:)]) {
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We can enter new style fullscreen mode for "fullscreen desktop" */
|
||||||
|
if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) {
|
||||||
|
return SDL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We can always leave new style fullscreen mode */
|
||||||
|
if (!fullscreen && [data->listener isToggledFullscreen]) {
|
||||||
|
return SDL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Requesting a mode switched fullscreen mode */
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
Cocoa_SetWindowFullscreen_NewStyle(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
|
||||||
|
{
|
||||||
|
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||||
|
NSWindow *nswindow = data->nswindow;
|
||||||
|
|
||||||
|
if (fullscreen != [data->listener isToggledFullscreen]) {
|
||||||
|
[nswindow toggleFullScreen:nil];
|
||||||
|
}
|
||||||
|
ScheduleContextUpdates(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
Cocoa_SetWindowFullscreen_OldStyle(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
|
||||||
{
|
{
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
|
||||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||||
NSWindow *nswindow = data->nswindow;
|
NSWindow *nswindow = data->nswindow;
|
||||||
NSRect rect;
|
NSRect rect;
|
||||||
|
@ -1097,6 +1198,18 @@ Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display
|
||||||
}
|
}
|
||||||
|
|
||||||
ScheduleContextUpdates(data);
|
ScheduleContextUpdates(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
|
||||||
|
{
|
||||||
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
|
if (Cocoa_CanToggleFullscreen(_this, window, display, fullscreen)) {
|
||||||
|
Cocoa_SetWindowFullscreen_NewStyle(_this, window, display, fullscreen);
|
||||||
|
} else {
|
||||||
|
Cocoa_SetWindowFullscreen_OldStyle(_this, window, display, fullscreen);
|
||||||
|
}
|
||||||
|
|
||||||
[pool release];
|
[pool release];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue