From 2215f55ef975843c70cfca0c42d06e4559c53534 Mon Sep 17 00:00:00 2001 From: Marco Antognini Date: Wed, 21 May 2014 22:45:04 +0200 Subject: [PATCH] Moved more responsibilities to SFOpenGLView These changes will ease the implementation of mouse grab (#394) --- src/SFML/Window/OSX/SFOpenGLView.h | 21 +--- src/SFML/Window/OSX/SFOpenGLView.mm | 137 +++++++++++++++++----- src/SFML/Window/OSX/SFWindowController.h | 6 +- src/SFML/Window/OSX/SFWindowController.mm | 48 ++------ 4 files changed, 120 insertions(+), 92 deletions(-) diff --git a/src/SFML/Window/OSX/SFOpenGLView.h b/src/SFML/Window/OSX/SFOpenGLView.h index dc3a1104..3d69ee5b 100644 --- a/src/SFML/Window/OSX/SFOpenGLView.h +++ b/src/SFML/Window/OSX/SFOpenGLView.h @@ -43,8 +43,6 @@ namespace sf { /// /// NSTrackingArea is used to keep track of mouse events. We also /// need to be able to ignore mouse event when exiting fullscreen. -/// The SFWindowController should call -[SFOpenGLView exitFullscreen] -/// and -[SFOpenGLView enterFullscreen] when appropriate. /// /// Modifiers keys (cmd, ctrl, alt, shift) are handled by this class /// but the actual logic is done in SFKeyboardModifiersHelper.(h|mm). @@ -56,6 +54,7 @@ namespace sf { BOOL m_useKeyRepeat; ///< Key repeat setting BOOL m_mouseIsIn; ///< Mouse positional state NSTrackingArea* m_trackingArea; ///< Mouse tracking area + BOOL m_fullscreen; ///< Indicate whether the window is fullscreen or not // Hidden text view used to convert key event to actual chars. // We use a silent responder to prevent sound alerts. @@ -66,24 +65,16 @@ namespace sf { //////////////////////////////////////////////////////////// /// \brief Create the SFML OpenGL view /// +/// NB: -initWithFrame: is also implemented to default isFullscreen to NO +/// in case SFOpenGLView is created with the standard message. +/// /// \param frameRect dimension of the view +/// \param isFullscreen fullscreen flag /// /// \return an initialized view /// //////////////////////////////////////////////////////////// --(id)initWithFrame:(NSRect)frameRect; - -//////////////////////////////////////////////////////////// -/// \brief Handle going in fullscreen mode -/// -//////////////////////////////////////////////////////////// --(void)enterFullscreen; - -//////////////////////////////////////////////////////////// -/// \brief Handle exiting fullscreen mode -/// -//////////////////////////////////////////////////////////// --(void)exitFullscreen; +-(id)initWithFrame:(NSRect)frameRect fullscreen:(BOOL)isFullscreen; //////////////////////////////////////////////////////////// /// \brief Apply the given requester to the view diff --git a/src/SFML/Window/OSX/SFOpenGLView.mm b/src/SFML/Window/OSX/SFOpenGLView.mm index 532a890c..c1fa0e40 100644 --- a/src/SFML/Window/OSX/SFOpenGLView.mm +++ b/src/SFML/Window/OSX/SFOpenGLView.mm @@ -77,6 +77,30 @@ BOOL isValidTextUnicode(NSEvent* event); //////////////////////////////////////////////////////////// -(void)updateMouseState; +//////////////////////////////////////////////////////////// +/// \brief Callback for focus event +/// +//////////////////////////////////////////////////////////// +-(void)windowDidBecomeKey:(NSNotification*)notification; + +//////////////////////////////////////////////////////////// +/// \brief Callback for unfocus event +/// +//////////////////////////////////////////////////////////// +-(void)windowDidResignKey:(NSNotification*)notification; + +//////////////////////////////////////////////////////////// +/// \brief Handle going in fullscreen mode +/// +//////////////////////////////////////////////////////////// +-(void)enterFullscreen; + +//////////////////////////////////////////////////////////// +/// \brief Handle exiting fullscreen mode +/// +//////////////////////////////////////////////////////////// +-(void)exitFullscreen; + //////////////////////////////////////////////////////////// /// \brief Convert the NSEvent mouse button type to SFML type /// @@ -108,6 +132,12 @@ BOOL isValidTextUnicode(NSEvent* event); //////////////////////////////////////////////////////// -(id)initWithFrame:(NSRect)frameRect +{ + return [self initWithFrame:frameRect fullscreen:NO]; +} + +//////////////////////////////////////////////////////// +-(id)initWithFrame:(NSRect)frameRect fullscreen:(BOOL)isFullscreen { if ((self = [super initWithFrame:frameRect])) { @@ -123,6 +153,22 @@ BOOL isValidTextUnicode(NSEvent* event); userInfo:nil]; [self addTrackingArea:m_trackingArea]; + m_fullscreen = isFullscreen; + + // Register for window focus events + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(windowDidBecomeKey:) + name:NSWindowDidBecomeKeyNotification + object:[self window]]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(windowDidResignKey:) + name:NSWindowDidResignKeyNotification + object:[self window]]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(windowDidResignKey:) + name:NSWindowWillCloseNotification + object:[self window]]; + // Create a hidden text view for parsing key down event properly m_silentResponder = [[SFSilentResponder alloc] init]; m_hiddenTextView = [[NSTextView alloc] initWithFrame:NSZeroRect]; @@ -136,37 +182,6 @@ BOOL isValidTextUnicode(NSEvent* event); } -//////////////////////////////////////////////////////// --(void)enterFullscreen -{ - // Remove the tracking area first, - // just to be sure we don't add it twice! - [self removeTrackingArea:m_trackingArea]; - [self addTrackingArea:m_trackingArea]; - - // Fire an mouse entered event if needed - if (!m_mouseIsIn && (m_requester != 0)) - m_requester->mouseMovedIn(); - - // Update status - m_mouseIsIn = YES; -} - - -//////////////////////////////////////////////////////// --(void)exitFullscreen -{ - [self removeTrackingArea:m_trackingArea]; - - // Fire an mouse left event if needed - if (m_mouseIsIn && (m_requester != 0)) - m_requester->mouseMovedOut(); - - // Update status - m_mouseIsIn = NO; -} - - //////////////////////////////////////////////////////// -(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester { @@ -276,6 +291,63 @@ BOOL isValidTextUnicode(NSEvent* event); } +//////////////////////////////////////////////////////// +-(void)windowDidBecomeKey:(NSNotification*)notification +{ + (void)notification; + + if (m_requester) + m_requester->windowGainedFocus(); + + if (m_fullscreen) + [self enterFullscreen]; +} + + +//////////////////////////////////////////////////////// +-(void)windowDidResignKey:(NSNotification*)notification +{ + (void)notification; + + if (m_requester) + m_requester->windowLostFocus(); + + if (m_fullscreen) + [self exitFullscreen]; +} + + +//////////////////////////////////////////////////////// +-(void)enterFullscreen +{ + // Remove the tracking area first, + // just to be sure we don't add it twice! + [self removeTrackingArea:m_trackingArea]; + [self addTrackingArea:m_trackingArea]; + + // Fire an mouse entered event if needed + if (!m_mouseIsIn && (m_requester != 0)) + m_requester->mouseMovedIn(); + + // Update status + m_mouseIsIn = YES; +} + + +//////////////////////////////////////////////////////// +-(void)exitFullscreen +{ + [self removeTrackingArea:m_trackingArea]; + + // Fire an mouse left event if needed + if (m_mouseIsIn && (m_requester != 0)) + m_requester->mouseMovedOut(); + + // Update status + m_mouseIsIn = NO; +} + + #pragma mark #pragma mark Subclassing methods @@ -283,6 +355,9 @@ BOOL isValidTextUnicode(NSEvent* event); //////////////////////////////////////////////////////// -(void)dealloc { + // Unregister for window focus events + [[NSNotificationCenter defaultCenter] removeObserver:self]; + // Unregister [self removeTrackingArea:m_trackingArea]; diff --git a/src/SFML/Window/OSX/SFWindowController.h b/src/SFML/Window/OSX/SFWindowController.h index c0cf45f6..2ff489bc 100644 --- a/src/SFML/Window/OSX/SFWindowController.h +++ b/src/SFML/Window/OSX/SFWindowController.h @@ -44,21 +44,17 @@ namespace sf { //////////////////////////////////////////////////////////// /// \brief Implementation of WindowImplDelegateProtocol for window management /// -/// Key and mouse events are delegated to its view. -/// Window events are managed by this class. +/// Key, mouse and Window focus events are delegated to its view, SFOpenGLView. /// /// Used when SFML handle everything and when a NSWindow* is given /// as handle to WindowImpl. /// -/// m_fullscreenMode is bind to default video mode if we don't need to change screen size. -/// //////////////////////////////////////////////////////////// @interface SFWindowController : NSResponder { NSWindow* m_window; ///< Underlying Cocoa window to be controlled SFOpenGLView* m_oglView; ///< OpenGL view for rendering sf::priv::WindowImplCocoa* m_requester; ///< Requester - 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 b5f0343e..35c6c528 100644 --- a/src/SFML/Window/OSX/SFWindowController.mm +++ b/src/SFML/Window/OSX/SFWindowController.mm @@ -94,7 +94,6 @@ m_window = nil; m_oglView = nil; m_requester = 0; - m_fullscreen = NO; // Retain the window for our own use. m_window = [window retain]; @@ -106,7 +105,8 @@ } // Create the view. - m_oglView = [[SFOpenGLView alloc] initWithFrame:[[m_window contentView] frame]]; + m_oglView = [[SFOpenGLView alloc] initWithFrame:[[m_window contentView] frame] + fullscreen:NO]; if (m_oglView == nil) { @@ -144,9 +144,8 @@ m_window = nil; m_oglView = nil; m_requester = 0; - m_fullscreen = style & sf::Style::Fullscreen; - if (m_fullscreen) + if (style & sf::Style::Fullscreen) [self setupFullscreenViewWithMode:mode]; else [self setupWindowWithMode:mode andStyle:style]; @@ -204,7 +203,8 @@ CGFloat y = (desktop.height - mode.height) / 2.0; NSRect oglRect = NSMakeRect(x, y, mode.width, mode.height); - m_oglView = [[SFOpenGLView alloc] initWithFrame:oglRect]; + m_oglView = [[SFOpenGLView alloc] initWithFrame:oglRect + fullscreen:YES]; if (m_oglView == nil) { @@ -217,9 +217,6 @@ // Populate the window and views [masterView addSubview:m_oglView]; [m_window setContentView:masterView]; - - // Finalize setup - [m_oglView enterFullscreen]; } @@ -265,7 +262,8 @@ } // Create the view. - m_oglView = [[SFOpenGLView alloc] initWithFrame:[[m_window contentView] frame]]; + m_oglView = [[SFOpenGLView alloc] initWithFrame:[[m_window contentView] frame] + fullscreen:NO]; if (m_oglView == nil) { @@ -553,38 +551,6 @@ } -//////////////////////////////////////////////////////// --(void)windowDidBecomeKey:(NSNotification*)notification -{ - (void)notification; - - // Send event. - if (m_requester == 0) - return; - - m_requester->windowGainedFocus(); - - if (m_fullscreen) - [m_oglView enterFullscreen]; -} - - -//////////////////////////////////////////////////////// --(void)windowDidResignKey:(NSNotification*)notification -{ - (void)notification; - - // Send event. - if (m_requester == 0) - return; - - m_requester->windowLostFocus(); - - if (m_fullscreen) - [m_oglView exitFullscreen]; -} - - #pragma mark #pragma mark Other methods