diff --git a/src/SFML/Window/OSX/SFWindow.h b/src/SFML/Window/OSX/SFWindow.h index 2f290220..3eecc258 100644 --- a/src/SFML/Window/OSX/SFWindow.h +++ b/src/SFML/Window/OSX/SFWindow.h @@ -65,6 +65,26 @@ //////////////////////////////////////////////////////////// -(void)keyDown:(NSEvent*)theEvent; +//////////////////////////////////////////////////////////// +/// \brief This action method simulates the user clicking the close button +/// +/// Override NSWindow implementation, see implementation for details +/// +/// \param sender The message’s sender +/// +//////////////////////////////////////////////////////////// +-(void)performClose:(id)sender; + +//////////////////////////////////////////////////////////// +/// \brief Enabling or disabling a specific menu item +/// +/// \param menuItem An NSMenuItem object that represents the menu item +/// +/// \return YES to enable menuItem, NO to disable it. +/// +//////////////////////////////////////////////////////////// +-(BOOL)validateMenuItem:(NSMenuItem*)menuItem; + @end diff --git a/src/SFML/Window/OSX/SFWindow.m b/src/SFML/Window/OSX/SFWindow.m index d2544364..70e7ee87 100644 --- a/src/SFML/Window/OSX/SFWindow.m +++ b/src/SFML/Window/OSX/SFWindow.m @@ -59,6 +59,44 @@ } +//////////////////////////////////////////////////////// +-(void)performClose:(id)sender +{ + // From Apple documentation: + // + // > If the window’s delegate or the window itself implements windowShouldClose:, + // > that message is sent with the window as the argument. (Only one such message is sent; + // > if both the delegate and the NSWindow object implement the method, only the delegate + // > receives the message.) If the windowShouldClose: method returns NO, the window isn’t + // > closed. If it returns YES, or if it isn’t implemented, performClose: invokes the + // > close method to close the window. + // > + // > If the window doesn’t have a close button or can’t be closed (for example, if the + // > delegate replies NO to a windowShouldClose: message), the system emits the alert sound. + // + // The last paragraph is problematic for SFML fullscreen window since they don't have + // a close button (style is NSBorderlessWindowMask). So we reimplement this function. + + BOOL shouldClose = NO; + + if ([self delegate] && [[self delegate] respondsToSelector:@selector(windowShouldClose:)]) + shouldClose = [[self delegate] windowShouldClose:sender]; + // else if ([self respondsToSelector:@selector(windowShouldClose:)]) + // shouldClose = [self windowShouldClose:sender]; + // error: no visible @interface for 'SFWindow' declares the selector 'windowShouldClose:' + + if (shouldClose) + [self close]; +} + + +//////////////////////////////////////////////////////// +-(BOOL)validateMenuItem:(NSMenuItem*)menuItem +{ + return [menuItem action] == @selector(performClose:); +} + + @end