diff --git a/src/SFML/Window/OSX/SFContext.mm b/src/SFML/Window/OSX/SFContext.mm index a73649509..9989af70b 100644 --- a/src/SFML/Window/OSX/SFContext.mm +++ b/src/SFML/Window/OSX/SFContext.mm @@ -75,7 +75,7 @@ m_window(0) // Create the context. createContext(shared, VideoMode::getDesktopMode().bitsPerPixel, settings); - // Create a dummy window/view pair (hidden) and asign it our context. + // Create a dummy window/view pair (hidden) and assign it our context. m_window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, width, height) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered diff --git a/src/SFML/Window/OSX/SFOpenGLView.h b/src/SFML/Window/OSX/SFOpenGLView.h index cafca61b3..b54dbbeca 100644 --- a/src/SFML/Window/OSX/SFOpenGLView.h +++ b/src/SFML/Window/OSX/SFOpenGLView.h @@ -62,7 +62,6 @@ namespace sf { BOOL m_useKeyRepeat; ///< Key repeat setting BOOL m_mouseIsIn; ///< Mouse positional state NSTrackingArea* m_trackingArea; ///< Mouse tracking area - NSSize m_realSize; ///< Actual size of the view // Hidden text view used to convert key event to actual chars. // We use a silent responder to prevent sound alerts. @@ -100,18 +99,6 @@ namespace sf { //////////////////////////////////////////////////////////// -(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester; -//////////////////////////////////////////////////////////// -/// \brief Set the real size of view (it should be the back buffer size) -/// -/// If not set, or set to its default value NSZeroSize, the view -/// won't recompute the mouse coordinates before sending them -/// to the requester. -/// -/// \param newSize actual size of the view -/// -//////////////////////////////////////////////////////////// --(void)setRealSize:(NSSize)newSize; - //////////////////////////////////////////////////////////// /// \brief Compute the position in global coordinate /// diff --git a/src/SFML/Window/OSX/SFOpenGLView.mm b/src/SFML/Window/OSX/SFOpenGLView.mm index ad7bbd77c..d18ce9c18 100644 --- a/src/SFML/Window/OSX/SFOpenGLView.mm +++ b/src/SFML/Window/OSX/SFOpenGLView.mm @@ -113,7 +113,6 @@ BOOL isValidTextUnicode(NSEvent* event); { [self setRequesterTo:0]; [self enableKeyRepeat]; - m_realSize = NSZeroSize; // Register for mouse move event m_mouseIsIn = [self isMouseInside]; @@ -172,23 +171,9 @@ BOOL isValidTextUnicode(NSEvent* event); } -//////////////////////////////////////////////////////// --(void)setRealSize:(NSSize)newSize -{ - m_realSize = newSize; -} - - //////////////////////////////////////////////////////// -(NSPoint)computeGlobalPositionOfRelativePoint:(NSPoint)point { - // Recompute the mouse pos if required. - if (!NSEqualSizes(m_realSize, NSZeroSize)) - { - point.x = (point.x / m_realSize.width) * [self frame].size.width; - point.y = (point.y / m_realSize.height) * [self frame].size.height; - } - // Note : -[NSWindow convertBaseToScreen:] is deprecated on 10.7 // but the recommended -[NSWindow convertRectToScreen] is not // available until 10.7. @@ -538,13 +523,6 @@ BOOL isValidTextUnicode(NSEvent* event); float h = [self frame].size.height; loc.y = h - loc.y; - // Recompute the mouse pos if required. - if (!NSEqualSizes(m_realSize, NSZeroSize)) - { - loc.x = (loc.x * m_realSize.width) / [self frame].size.width; - loc.y = (loc.y * m_realSize.height) / [self frame].size.height; - } - return loc; } diff --git a/src/SFML/Window/OSX/SFWindowController.h b/src/SFML/Window/OSX/SFWindowController.h index 1867ec365..c0cf45f6b 100644 --- a/src/SFML/Window/OSX/SFWindowController.h +++ b/src/SFML/Window/OSX/SFWindowController.h @@ -58,9 +58,7 @@ namespace sf { NSWindow* m_window; ///< Underlying Cocoa window to be controlled SFOpenGLView* m_oglView; ///< OpenGL view for rendering sf::priv::WindowImplCocoa* m_requester; ///< Requester - sf::VideoMode* m_fullscreenMode; ///< Fullscreen mode - - /// Note: C++ ctor/dtor are not called for Obj-C fields! Use manual allocation instead. + BOOL m_fullscreen; ///< Indicate whether the window is fullscreen or not } //////////////////////////////////////////////////////////// diff --git a/src/SFML/Window/OSX/SFWindowController.mm b/src/SFML/Window/OSX/SFWindowController.mm index 63b8454d7..dc19c294f 100644 --- a/src/SFML/Window/OSX/SFWindowController.mm +++ b/src/SFML/Window/OSX/SFWindowController.mm @@ -39,6 +39,24 @@ #import #import +//////////////////////////////////////////////////////////// +/// SFBlackView is a simple view filled with black, nothing more +/// +//////////////////////////////////////////////////////////// +@interface SFBlackView : NSView +@end + +@implementation SFBlackView + +//////////////////////////////////////////////////////////// +-(void)drawRect:(NSRect)dirtyRect +{ + [[NSColor blackColor] setFill]; + NSRectFill(dirtyRect); +} + +@end + //////////////////////////////////////////////////////////// /// SFWindowController class: private interface /// @@ -73,15 +91,17 @@ { if ((self = [super init])) { + m_window = nil; + m_oglView = nil; m_requester = 0; - m_fullscreenMode = new sf::VideoMode(); + m_fullscreen = NO; // Retain the window for our own use. m_window = window; if (m_window == nil) { - sf::err() << "No window was given to initWithWindow:." << std::endl; + sf::err() << "No window was given to -[SFWindowController -initWithWindow:]." << std::endl; return self; } @@ -91,7 +111,7 @@ if (m_oglView == nil) { sf::err() << "Could not create an instance of NSOpenGLView " - << "in (SFWindowController -initWithWindow:)." + << "in -[SFWindowController -initWithWindow:]." << std::endl; return self; } @@ -121,133 +141,156 @@ if ((self = [super init])) { + m_window = nil; + m_oglView = nil; m_requester = 0; - m_fullscreenMode = new sf::VideoMode(); + m_fullscreen = style & sf::Style::Fullscreen; - // Create our window size. - NSRect rect = NSZeroRect; - if ((style & sf::Style::Fullscreen) && (mode != sf::VideoMode::getDesktopMode())) - { - // We use desktop mode to size the window - // but we set the back buffer size to 'mode' in applyContext method. - *m_fullscreenMode = mode; - - sf::VideoMode dm = sf::VideoMode::getDesktopMode(); - rect = NSMakeRect(0, 0, dm.width, dm.height); - } + if (m_fullscreen) + [self setupFullscreenViewWithMode:mode]; else - { - // no fullscreen requested. - rect = NSMakeRect(0, 0, mode.width, mode.height); - } - - // Convert the SFML window style to Cocoa window style. - unsigned int nsStyle = NSBorderlessWindowMask; - - // if fullscrean we keep our NSBorderlessWindowMask. - if (!(style & sf::Style::Fullscreen)) - { - if (style & sf::Style::Titlebar) - nsStyle |= NSTitledWindowMask | NSMiniaturizableWindowMask; - - if (style & sf::Style::Resize) - nsStyle |= NSResizableWindowMask; - - if (style & sf::Style::Close) - nsStyle |= NSClosableWindowMask; - - } - - // Create the window. - m_window = [[SFWindow alloc] initWithContentRect:rect - styleMask:nsStyle - backing:NSBackingStoreBuffered - defer:NO]; // Don't defer it! - /* - "YES" produces some "invalid drawable". - See http://www.cocoabuilder.com/archive/cocoa/152482-nsviews-and-nsopenglcontext-invalid-drawable-error.html - - [...] - As best as I can figure, this is happening because the NSWindow (and - hence my view) are not visible on screen yet, and the system doesn't like that. - [...] - */ - - if (m_window == nil) - { - sf::err() << "Could not create an instance of NSWindow " - << "in (SFWindowController -initWithMode:andStyle:)." - << std::endl; - - return self; - } - - // Apply special feature for fullscreen window. - if (style & sf::Style::Fullscreen) - { - // We place the window above everything else. - [m_window setOpaque:YES]; - [m_window setHidesOnDeactivate:YES]; - [m_window setLevel:NSMainMenuWindowLevel+1]; - - // And hide the menu bar - [NSMenu setMenuBarVisible:NO]; - - /* --------------------------- - * | Note for future version | - * --------------------------- - * - * starting with OS 10.6 NSView provides - * a new method -enterFullScreenMode:withOptions: - * which could be a good alternative. - */ - } - - // Centre the window to be cool =) - [m_window center]; - - // Create the view. - m_oglView = [[SFOpenGLView alloc] initWithFrame:[[m_window contentView] frame]]; - - if (m_oglView == nil) - { - sf::err() << "Could not create an instance of NSOpenGLView " - << "in (SFWindowController -initWithMode:andStyle:)." - << std::endl; - - return self; - } - - // If a fullscreen window was requested... - if (style & sf::Style::Fullscreen) - { - /// ... we tell the OpenGL view - [m_oglView enterFullscreen]; - - // ... and if the resolution is not the default one... - if (mode != sf::VideoMode::getDesktopMode()) - { - // ... we set the "real size" of the view (that is the back buffer size). - [m_oglView setRealSize:NSMakeSize(m_fullscreenMode->width, m_fullscreenMode->height)]; - } - } - - // Set the view to the window as its content view. - [m_window setContentView:m_oglView]; - - // Register for event. - [m_window setDelegate:self]; - [m_window setAcceptsMouseMovedEvents:YES]; - [m_window setIgnoresMouseEvents:NO]; - - // And some other things... - [m_window setAutodisplay:YES]; - [m_window setReleasedWhenClosed:NO]; - } // if super init ok - + [self setupWindowWithMode:mode andStyle:style]; + } return self; } + +//////////////////////////////////////////////////////// +-(void)setupFullscreenViewWithMode:(const sf::VideoMode&)mode +{ + // Create a screen-sized window on the main display + sf::VideoMode desktop = sf::VideoMode::getDesktopMode(); + NSRect windowRect = NSMakeRect(0, 0, desktop.width, desktop.height); + m_window = [[SFWindow alloc] initWithContentRect:windowRect + styleMask:NSBorderlessWindowMask + backing:NSBackingStoreBuffered + defer:NO]; + + if (m_window == nil) + { + sf::err() << "Could not create an instance of NSWindow " + << "in -[SFWindowController setupFullscreenViewWithMode:]." + << std::endl; + return; + } + + // Set the window level to be above the menu bar + [m_window setLevel:NSMainMenuWindowLevel+1]; + + // More window configuration... + [m_window setOpaque:YES]; + [m_window setHidesOnDeactivate:YES]; + [m_window setAutodisplay:YES]; + [m_window setReleasedWhenClosed:YES]; + + // Register for event + [m_window setDelegate:self]; + [m_window setAcceptsMouseMovedEvents:YES]; + [m_window setIgnoresMouseEvents:NO]; + + // Create a master view containing our OpenGL view + NSView* masterView = [[SFBlackView alloc] initWithFrame:windowRect]; + + if (masterView == nil) + { + sf::err() << "Could not create an instance of SFBlackView " + << "in -[SFWindowController setupFullscreenViewWithMode:]." + << std::endl; + return; + } + + // Create our OpenGL view size and the view + CGFloat x = (desktop.width - mode.width) / 2.0; + CGFloat y = (desktop.height - mode.height) / 2.0; + NSRect oglRect = NSMakeRect(x, y, mode.width, mode.height); + + m_oglView = [[SFOpenGLView alloc] initWithFrame:oglRect]; + + if (m_oglView == nil) + { + sf::err() << "Could not create an instance of NSOpenGLView " + << "in -[SFWindowController setupFullscreenViewWithMode:]." + << std::endl; + return; + } + + // Populate the window and views + [masterView addSubview:m_oglView]; + [m_window setContentView:masterView]; + + // Finalize setup + [m_oglView enterFullscreen]; +} + + +//////////////////////////////////////////////////////// +-(void)setupWindowWithMode:(const sf::VideoMode&)mode andStyle:(unsigned long)style +{ + // We know that style & sf::Style::Fullscreen is false. + + // Create our window size. + NSRect rect = NSMakeRect(0, 0, mode.width, mode.height); + + // Convert the SFML window style to Cocoa window style. + unsigned int nsStyle = NSBorderlessWindowMask; + if (style & sf::Style::Titlebar) + nsStyle |= NSTitledWindowMask | NSMiniaturizableWindowMask; + if (style & sf::Style::Resize) + nsStyle |= NSResizableWindowMask; + if (style & sf::Style::Close) + nsStyle |= NSClosableWindowMask; + + // Create the window. + m_window = [[SFWindow alloc] initWithContentRect:rect + styleMask:nsStyle + backing:NSBackingStoreBuffered + defer:NO]; // Don't defer it! + /* + "YES" produces some "invalid drawable". + See http://www.cocoabuilder.com/archive/cocoa/152482-nsviews-and-nsopenglcontext-invalid-drawable-error.html + + [...] + As best as I can figure, this is happening because the NSWindow (and + hence my view) are not visible on screen yet, and the system doesn't like that. + [...] + */ + + if (m_window == nil) + { + sf::err() << "Could not create an instance of NSWindow " + << "in -[SFWindowController setupWindowWithMode:andStyle:]." + << std::endl; + + return; + } + + // Create the view. + m_oglView = [[SFOpenGLView alloc] initWithFrame:[[m_window contentView] frame]]; + + if (m_oglView == nil) + { + sf::err() << "Could not create an instance of NSOpenGLView " + << "in -[SFWindowController setupWindowWithMode:andStyle:]." + << std::endl; + + return; + } + + // Set the view to the window as its content view. + [m_window setContentView:m_oglView]; + + // Register for event. + [m_window setDelegate:self]; + [m_window setAcceptsMouseMovedEvents:YES]; + [m_window setIgnoresMouseEvents:NO]; + + // And some other things... + [m_window center]; + [m_window setAutodisplay:YES]; + [m_window setReleasedWhenClosed:YES]; +} + + //////////////////////////////////////////////////////// -(void)dealloc { @@ -256,7 +299,6 @@ m_window = nil; m_oglView = nil; - delete m_fullscreenMode; } @@ -335,10 +377,7 @@ //////////////////////////////////////////////////////// -(NSSize)size { - if (*m_fullscreenMode == sf::VideoMode()) - return [m_oglView frame].size; - else - return NSMakeSize(m_fullscreenMode->width, m_fullscreenMode->height); + return [m_oglView frame].size; } @@ -472,19 +511,6 @@ { [m_oglView setOpenGLContext:context]; [context setView:m_oglView]; - - // If fullscreen was requested and the mode used to create the window - // was not the desktop mode, we change the back buffer size of the - // context. - if (*m_fullscreenMode != sf::VideoMode()) - { - CGLContextObj cgcontext = (CGLContextObj)[context CGLContextObj]; - - GLint dim[2] = {m_fullscreenMode->width, m_fullscreenMode->height}; - - CGLSetParameter(cgcontext, kCGLCPSurfaceBackingSize, dim); - CGLEnable(cgcontext, kCGLCESurfaceBackingSize); - } } @@ -516,7 +542,7 @@ m_requester->windowGainedFocus(); - if (*m_fullscreenMode != sf::VideoMode()) + if (m_fullscreen) [m_oglView enterFullscreen]; } @@ -532,7 +558,7 @@ m_requester->windowLostFocus(); - if (*m_fullscreenMode != sf::VideoMode()) + if (m_fullscreen) [m_oglView exitFullscreen]; }