diff --git a/src/lib/ecore_cocoa/Ecore_Cocoa.h b/src/lib/ecore_cocoa/Ecore_Cocoa.h index a1c1e22218..b187f81e61 100644 --- a/src/lib/ecore_cocoa/Ecore_Cocoa.h +++ b/src/lib/ecore_cocoa/Ecore_Cocoa.h @@ -80,6 +80,17 @@ typedef struct _Ecore_Cocoa_Event_Window_Unfocused Ecore_Cocoa_Event_Window_Unfo */ typedef struct _Ecore_Cocoa_Event_Window_Destroy Ecore_Cocoa_Event_Window_Destroy; +/** + * @typedef Ecore_Cocoa_Terminate_Cb + * Callback called when a delete request is sent to the application. + * Such function must return EINA_TRUE for the application to terminate, + * and EINA_FALSE to ignore application termination. + * It is typically called by a CMD+Q signal. + * @param sender The NSApplication instance to be terminated + * @since 1.19 + */ +typedef Eina_Bool (*Ecore_Cocoa_Terminate_Cb)(Ecore_Cocoa_Object *sender); + /** * @typedef Ecore_Cocoa_Cursor * Values of the Cocoa cursors handled by Ecore_Cocoa @@ -527,6 +538,17 @@ EAPI void ecore_cocoa_window_cursor_set(Ecore_Cocoa_Window *win, EAPI void ecore_cocoa_window_cursor_show(Ecore_Cocoa_Window *win, Eina_Bool show); EINA_ARG_NONNULL(1); +/** + * Overrides the default behaviour in response to an application delete + * request. When an application receives a delete request (i.e. CMD+Q) + * the termination callback will be called and its result will determine + * whether the application should terminate or not + * @param cb The custom termination callback to set + * @see Ecore_Cocoa_Terminate_Cb + * @since 1.19 + */ +EAPI void ecore_cocoa_terminate_cb_set(Ecore_Cocoa_Terminate_Cb cb) + EINA_ARG_NONNULL(1); /* diff --git a/src/lib/ecore_cocoa/ecore_cocoa.m b/src/lib/ecore_cocoa/ecore_cocoa.m index 1c9c20f358..05de6f4bc5 100644 --- a/src/lib/ecore_cocoa/ecore_cocoa.m +++ b/src/lib/ecore_cocoa/ecore_cocoa.m @@ -387,3 +387,10 @@ ecore_cocoa_titlebar_height_get(void) } return height; } + +EAPI void +ecore_cocoa_terminate_cb_set(Ecore_Cocoa_Terminate_Cb cb) +{ + EINA_SAFETY_ON_NULL_RETURN(cb); + [NSApp setTerminateCb: cb]; +} diff --git a/src/lib/ecore_cocoa/ecore_cocoa_app.h b/src/lib/ecore_cocoa/ecore_cocoa_app.h index 0cc01615af..e6eac097fc 100644 --- a/src/lib/ecore_cocoa/ecore_cocoa_app.h +++ b/src/lib/ecore_cocoa/ecore_cocoa_app.h @@ -8,6 +8,7 @@ { Ecore_Timer *_timer; NSDate *_expiration; + Ecore_Cocoa_Terminate_Cb _terminate_cb; } - (NSDate *)eventExpirationDate; @@ -17,6 +18,8 @@ - (void)sendEvent:(NSEvent *)anEvent; - (id)init; - (void)internalUpdate; +- (void)setTerminateCb:(Ecore_Cocoa_Terminate_Cb)cb; +- (Ecore_Cocoa_Terminate_Cb)terminateCb; - (void) pauseNSRunLoopMonitoring; - (void) resumeNSRunLoopMonitoring; diff --git a/src/lib/ecore_cocoa/ecore_cocoa_app.m b/src/lib/ecore_cocoa/ecore_cocoa_app.m index 04391f61ff..8df1be1830 100644 --- a/src/lib/ecore_cocoa/ecore_cocoa_app.m +++ b/src/lib/ecore_cocoa/ecore_cocoa_app.m @@ -112,6 +112,16 @@ _ecore_cocoa_run_loop_cb(void *data EINA_UNUSED) ecore_timer_thaw(_timer); } +- (void)setTerminateCb:(Ecore_Cocoa_Terminate_Cb)cb +{ + _terminate_cb = cb; +} + +- (Ecore_Cocoa_Terminate_Cb)terminateCb +{ + return _terminate_cb; +} + @end @@ -131,8 +141,19 @@ static Ecore_Cocoa_AppDelegate *_appDelegate = nil; - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *) EINA_UNUSED sender { // XXX This should be alterable (by Elm_Window policy) - return YES; + return NO; +} + +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender +{ + NSApplicationTerminateReply status = NSTerminateNow; + const Ecore_Cocoa_Terminate_Cb cb = [(Ecore_Cocoa_Application *)sender terminateCb]; + if (cb) + { + const Eina_Bool ret = cb(sender); + if (!ret) status = NSTerminateCancel; + } + return status; } @end -