Added "switch back to desktop mode" feature when switching to another application while the SFML one is in fullscreen mode. Using more demanding screen choice : request the use of the primary screen when several monitors are available.

git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/trunk@1216 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
ceylo 2009-09-12 12:13:28 +00:00
parent 447a9ac7c3
commit c140de772d
4 changed files with 85 additions and 52 deletions

View File

@ -50,6 +50,16 @@ enum {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
+ (AppController *)sharedController; + (AppController *)sharedController;
////////////////////////////////////////////////////////////
/// Returns the primay computer's screen
////////////////////////////////////////////////////////////
+ (CGDirectDisplayID)primaryScreen;
////////////////////////////////////////////////////////////
/// Reset notifictions about application focus
////////////////////////////////////////////////////////////
- (void)setNotifications;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Make the menu bar /// Make the menu bar
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -103,25 +103,7 @@
throw std::bad_alloc(); throw std::bad_alloc();
} }
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [self setNotifications];
// I want to go back to the desktop mode
// if we've a fullscreen window when hiding
[nc addObserver:self
selector:@selector(applicationWillHide:)
name:NSApplicationWillHideNotification
object:NSApp];
// And restore de fullscreen mode when unhiding
[nc addObserver:self
selector:@selector(applicationWillUnhide:)
name:NSApplicationWillUnhideNotification
object:NSApp];
// Go back to desktop mode before exit
[nc addObserver:self
selector:@selector(applicationWillTerminate:)
name:NSApplicationWillTerminateNotification
object:NSApp];
if ([NSApp mainMenu] == nil) { if ([NSApp mainMenu] == nil) {
[self makeMenuBar]; [self makeMenuBar];
@ -155,31 +137,72 @@
} }
////////////////////////////////////////////////////////////
/// Returns the primay computer's screen
////////////////////////////////////////////////////////////
+ (CGDirectDisplayID)primaryScreen
{
static BOOL firstTime = YES;
static CGDirectDisplayID screen = kCGNullDirectDisplay;
if (firstTime) {
CGDisplayCount numScr;
CGDisplayErr err = CGGetDisplaysWithPoint(CGPointMake(0, 0), 1, &screen, &numScr);
if (err != kCGErrorSuccess || numScr < 1) {
std::cerr << "Unable to get primary screen (error code " << err
<< " ). Using the main screen.";
screen = CGMainDisplayID();
}
firstTime = NO;
}
return screen;
}
////////////////////////////////////////////////////////////
/// Reset notifictions about application focus
////////////////////////////////////////////////////////////
- (void)setNotifications
{
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self
selector:@selector(applicationWillDeactivate:)
name:NSApplicationWillResignActiveNotification
object:NSApp];
[nc addObserver:self
selector:@selector(applicationWillActivate:)
name:NSApplicationWillBecomeActiveNotification
object:NSApp];
[nc addObserver:self
selector:@selector(applicationWillTerminate:)
name:NSApplicationWillTerminateNotification
object:NSApp];
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Hide all the fullscreen windows and switch back to the desktop display mode /// Hide all the fullscreen windows and switch back to the desktop display mode
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
- (void)applicationWillHide:(NSNotification *)aNotification - (void)applicationWillDeactivate:(NSNotification *)aNotification
{ {
// Note: not using fading because it produces reactivation issues
if (myFullscreenWrapper) { if (myFullscreenWrapper) {
myPrevMode = sf::VideoMode::GetDesktopMode(); myPrevMode = sf::VideoMode::GetDesktopMode();
CFDictionaryRef displayMode = CGDisplayBestModeForParameters (kCGDirectMainDisplay, CFDictionaryRef displayMode = CGDisplayBestModeForParameters ([AppController primaryScreen],
myDesktopMode.BitsPerPixel, myDesktopMode.BitsPerPixel,
myDesktopMode.Width, myDesktopMode.Width,
myDesktopMode.Height, myDesktopMode.Height,
NULL); NULL);
// Fade to black screen
[self doFadeOperation:FillScreen time:0.2f sync:true];
// Make the full screen window unvisible // Make the full screen window unvisible
[[myFullscreenWrapper window] setAlphaValue:0.0f]; [[myFullscreenWrapper window] setAlphaValue:0.0f];
// Switch to the wished display mode // Switch to the wished display mode
CGDisplaySwitchToMode(kCGDirectMainDisplay, displayMode); CGDisplaySwitchToMode([AppController primaryScreen], displayMode);
// Fade to normal screen
[self doFadeOperation:CleanScreen time:0.5f sync:false];
} }
} }
@ -187,31 +210,26 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Unhide all the fullscreen windows and switch to full screen display mode /// Unhide all the fullscreen windows and switch to full screen display mode
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
- (void)applicationWillUnhide:(NSNotification *)aNotification - (void)applicationWillActivate:(NSNotification *)aNotification
{ {
if (myFullscreenWrapper) { if (myFullscreenWrapper) {
CFDictionaryRef displayMode = CGDisplayBestModeForParameters (kCGDirectMainDisplay, CFDictionaryRef displayMode = CGDisplayBestModeForParameters ([AppController primaryScreen],
myPrevMode.BitsPerPixel, myPrevMode.BitsPerPixel,
myPrevMode.Width, myPrevMode.Width,
myPrevMode.Height, myPrevMode.Height,
NULL); NULL);
// Fade to a black screen
[self doFadeOperation:FillScreen time:0.5f sync:true];
[NSMenu setMenuBarVisible:NO]; [NSMenu setMenuBarVisible:NO];
// Switch to the wished display mode // Switch to the wished display mode
CGDisplaySwitchToMode(kCGDirectMainDisplay, displayMode); CGDisplaySwitchToMode([AppController primaryScreen], displayMode);
// Show the fullscreen window if existing // Show the fullscreen window if existing
if (myFullscreenWrapper) if (myFullscreenWrapper)
{ {
[[myFullscreenWrapper window] setAlphaValue:1.0f]; [[myFullscreenWrapper window] setAlphaValue:1.0f];
[[myFullscreenWrapper window] center]; [[myFullscreenWrapper window] center];
[[myFullscreenWrapper window] makeKeyAndOrderFront:self];
} }
// Fade to normal screen
[self doFadeOperation:CleanScreen time:0.5f sync:false];
} }
} }
@ -228,7 +246,6 @@
- (void)makeMenuBar - (void)makeMenuBar
{ {
// Source taken from SDL 1.3 // Source taken from SDL 1.3
NSString *appName = nil; NSString *appName = nil;
NSString *title = nil; NSString *title = nil;
NSMenu *appleMenu = nil; NSMenu *appleMenu = nil;
@ -393,7 +410,7 @@
if (aWrapper == nil && myFullscreenWrapper) if (aWrapper == nil && myFullscreenWrapper)
{ {
// Get the CoreGraphics display mode according to the desktop mode // Get the CoreGraphics display mode according to the desktop mode
CFDictionaryRef displayMode = CGDisplayBestModeForParameters (kCGDirectMainDisplay, CFDictionaryRef displayMode = CGDisplayBestModeForParameters ([AppController primaryScreen],
myDesktopMode.BitsPerPixel, myDesktopMode.BitsPerPixel,
myDesktopMode.Width, myDesktopMode.Width,
myDesktopMode.Height, myDesktopMode.Height,
@ -405,7 +422,7 @@
#endif #endif
// Switch to the desktop display mode // Switch to the desktop display mode
CGDisplaySwitchToMode(kCGDirectMainDisplay, displayMode); CGDisplaySwitchToMode([AppController primaryScreen], displayMode);
// Close the window // Close the window
[[myFullscreenWrapper window] close]; [[myFullscreenWrapper window] close];
@ -423,10 +440,11 @@
} }
else if (aWrapper) else if (aWrapper)
{ {
// else if we want to SET fullscreen
assert(fullscreenMode != NULL); assert(fullscreenMode != NULL);
// Get the CoreGraphics display mode according to the given sf mode // Get the CoreGraphics display mode according to the given sf mode
CFDictionaryRef displayMode = CGDisplayBestModeForParameters (kCGDirectMainDisplay, CFDictionaryRef displayMode = CGDisplayBestModeForParameters ([AppController primaryScreen],
fullscreenMode->BitsPerPixel, fullscreenMode->BitsPerPixel,
fullscreenMode->Width, fullscreenMode->Width,
fullscreenMode->Height, fullscreenMode->Height,
@ -446,7 +464,8 @@
if (myPrevMode != *fullscreenMode) if (myPrevMode != *fullscreenMode)
{ {
// Switch to the wished display mode // Switch to the wished display mode
CGDisplaySwitchToMode(kCGDirectMainDisplay, displayMode); myPrevMode = *fullscreenMode;
CGDisplaySwitchToMode([AppController primaryScreen], displayMode);
} }
if (myFullscreenWrapper) if (myFullscreenWrapper)
@ -495,7 +514,7 @@
if (!result) { if (!result) {
// Capture display but do not fill the screen with black // Capture display but do not fill the screen with black
// so that we can see the fade operation // so that we can see the fade operation
capture = CGDisplayCaptureWithOptions(kCGDirectMainDisplay, kCGCaptureNoFill); capture = CGDisplayCaptureWithOptions([AppController primaryScreen], kCGCaptureNoFill);
if (!capture) { if (!capture) {
// Do the increasing fade operation // Do the increasing fade operation
@ -505,11 +524,11 @@
0.0f, 0.0f, 0.0f, sync); 0.0f, 0.0f, 0.0f, sync);
// Now, release the non black-filling capture // Now, release the non black-filling capture
CGDisplayRelease(kCGDirectMainDisplay); CGDisplayRelease([AppController primaryScreen]);
// And capture with filling // And capture with filling
// so that we don't see the switching in the meantime // so that we don't see the switching in the meantime
CGDisplayCaptureWithOptions(kCGDirectMainDisplay, kCGCaptureNoOptions); CGDisplayCaptureWithOptions([AppController primaryScreen], kCGCaptureNoOptions);
} }
prevToken = token; prevToken = token;
@ -522,10 +541,10 @@
if (!result) { if (!result) {
if (!capture) { if (!capture) {
// Release the black-filling capture // Release the black-filling capture
CGDisplayRelease(kCGDirectMainDisplay); CGDisplayRelease([AppController primaryScreen]);
// Capture the display but do not fill with black (still for the fade operation) // Capture the display but do not fill with black (still for the fade operation)
CGDisplayCaptureWithOptions(kCGDirectMainDisplay, kCGCaptureNoFill); CGDisplayCaptureWithOptions([AppController primaryScreen], kCGCaptureNoFill);
// Do the decreasing fading // Do the decreasing fading
CGDisplayFade(token, time, CGDisplayFade(token, time,
@ -541,7 +560,7 @@
} }
// Release the captured display // Release the captured display
CGDisplayRelease(kCGDirectMainDisplay); CGDisplayRelease([AppController primaryScreen]);
} }
} }
} }

View File

@ -85,6 +85,10 @@
ctxtAttribs[idx++] = NSOpenGLPFADoubleBuffer; ctxtAttribs[idx++] = NSOpenGLPFADoubleBuffer;
ctxtAttribs[idx++] = NSOpenGLPFAAccelerated; ctxtAttribs[idx++] = NSOpenGLPFAAccelerated;
// Force use of first screen
//ctxtAttribs[idx++] = NSOpenGLPFAScreenMask;
//ctxtAttribs[idx++] = CGDisplayIDToOpenGLDisplayMask([AppController primaryScreen]);
// windowed context (even fullscreen mode uses a window) // windowed context (even fullscreen mode uses a window)
ctxtAttribs[idx++] = NSOpenGLPFAWindow; ctxtAttribs[idx++] = NSOpenGLPFAWindow;
@ -512,7 +516,7 @@
// Check display mode and put new values in 'mode' if needed // Check display mode and put new values in 'mode' if needed
boolean_t exact = true; boolean_t exact = true;
CFDictionaryRef properties = CGDisplayBestModeForParameters(kCGDirectMainDisplay, mode.BitsPerPixel, CFDictionaryRef properties = CGDisplayBestModeForParameters([AppController primaryScreen], mode.BitsPerPixel,
mode.Width, mode.Height, &exact); mode.Width, mode.Height, &exact);
if (!properties) { if (!properties) {

View File

@ -606,7 +606,7 @@ void WindowImplCocoa::SetCursorPosition(unsigned int Left, unsigned int Top)
absolute.y = [[NSScreen mainScreen] frame].size.height - absolute.y; absolute.y = [[NSScreen mainScreen] frame].size.height - absolute.y;
// Move cursor // Move cursor
CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, CGPointMake(absolute.x, absolute.y)); CGDisplayMoveCursorToPoint([AppController primaryScreen], CGPointMake(absolute.x, absolute.y));
} }
} }