EventClose on Dock
-
- Enthusiast
- Posts: 347
- Joined: Thu Jul 02, 2009 5:42 am
EventClose on Dock
If I minimize my application, then right click on the icon on the dock, the one with the little light under it, then select quit no event is fired?
How do I detect this event, I don't want anyone clicking on the dock icon and just closing my application without a warning
How do I detect this event, I don't want anyone clicking on the dock icon and just closing my application without a warning
Re: EventClose on Dock
This event is #pb_menu_quit (or something like that).
-
- Enthusiast
- Posts: 347
- Joined: Thu Jul 02, 2009 5:42 am
Re: EventClose on Dock
No, that is not the one. That is when you click on the top menu and select "Quit". I am talking about your application being minimizedPolo wrote:This event is #pb_menu_quit (or something like that).
on the dock, then right clicking the icon and selecting "Quit".
Re: EventClose on Dock
From what I remember it's the same event, did you try?
Re: EventClose on Dock
Unfortunately #PB_Menu_Quit doesn't work in detecting the selection of "Quit" after a right click onto the application's minimized dock icon. It's a little bit more complicated: you have to define a callback for the NSApplicationDelegate method applicationShouldTerminate: and then you are even able to ask the user for a confirmation to terminate the application. Without this workaround your program will terminate with a debugger error message. Therefore I have already posted this bug report.
I have tested the following code with MacOS X 10.6.8 (Snow Leopard) with PB 5.30 x86 and x64 in both ASCII and Unicode mode:
I have tested the following code with MacOS X 10.6.8 (Snow Leopard) with PB 5.30 x86 and x64 in both ASCII and Unicode mode:
Code: Select all
EnableExplicit
ImportC ""
sel_registerName(MethodName.S)
class_addMethod(Class.I, Selector.I, Implementation.I, Types.S)
EndImport
ProcedureC AppShouldTerminate(Object.I, Selector.I, Sender.I)
If MessageRequester("Confirmation", "Do you want to terminate the application?",
#PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
End
Else
ProcedureReturn #NO
EndIf
EndProcedure
Procedure.S ConvertToUTF8(String.S)
Protected UTF8String.S = Space(StringByteLength(String))
PokeS(@UTF8String, String, -1, #PB_UTF8)
ProcedureReturn UTF8String
EndProcedure
Define AppDelegate.I = CocoaMessage(0, CocoaMessage(0, 0,
"NSApplication sharedApplication"), "delegate")
OpenWindow(0, 270, 100, 200, 170, "Test", #PB_Window_MinimizeGadget)
class_addMethod(CocoaMessage(0, AppDelegate, "class"),
sel_registerName(ConvertToUTF8("applicationShouldTerminate:")),
@AppShouldTerminate(), "v@:@")
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Re: EventClose on Dock
THANK YOU SHARDIK
I have not tested your code yet, but this looks like exactly what I need.
(My program isn't catching the "Quit" dock event, so it doesn't exit properly, which later causes problems the next time it runs!)
I have not tested your code yet, but this looks like exactly what I need.
(My program isn't catching the "Quit" dock event, so it doesn't exit properly, which later causes problems the next time it runs!)
Re: EventClose on Dock
The code of Shardik doesn't seem to work anymore?
Just interested in getting the applicationShouldTerminate and applicationWillTerminate notificatoin.
Just interested in getting the applicationShouldTerminate and applicationWillTerminate notificatoin.
Re: EventClose on Dock
class_addMethod only adds a method if it doesn't exist.
It appears PureBasic itself started using applicationShouldTerminate: which wasn't the case at the time this code was posted.
One way would be to use class_replaceMethod and call the previous implementation of applicationShouldTerminate: from within the callback.
Something like this.
If you only need a notification, you could probably also use NSNotificationCenter and observe for NSApplicationWillTerminateNotification .
It appears PureBasic itself started using applicationShouldTerminate: which wasn't the case at the time this code was posted.
One way would be to use class_replaceMethod and call the previous implementation of applicationShouldTerminate: from within the callback.
Something like this.
Code: Select all
EnableExplicit
Prototype Proto_AppShouldTerminate(Object, Selector, Sender)
DeclareC AppShouldTerminate(Object, Selector, Sender)
Global AppDelegate, AppShouldTerminate_.Proto_AppShouldTerminate
AppDelegate = CocoaMessage(0, CocoaMessage(0, 0, "NSApplication sharedApplication"), "delegate")
AppShouldTerminate_ = class_replaceMethod_(CocoaMessage(0, AppDelegate, "class"),
sel_registerName_("applicationShouldTerminate:"),
@AppShouldTerminate(), "v@:@")
ProcedureC AppShouldTerminate(Object, Selector, Sender)
If AppShouldTerminate_
AppShouldTerminate_(Object, Selector, Sender)
EndIf
If MessageRequester("Confirmation", "Do you want to terminate the application?",
#PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
End
Else
ProcedureReturn #NO
EndIf
EndProcedure
OpenWindow(0, 270, 100, 200, 170, "Test", #PB_Window_MinimizeGadget)
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
Re: EventClose on Dock
And thanks again mr iGuru. Is there anything you can't figure out irt macPB?
Re: EventClose on Dock
Of courseRinzwind wrote:Is there anything you can't figure out irt macPB?
But I like macOS and do know a bit about it.
I'm sure Shardik would also have been able to figure this out since he posted the original code and knows a lot about macOS.
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
Re: EventClose on Dock
Hmm additional unclarity...
"For Cocoa applications, termination is partly handled by the Application Kit, which calls the applicationShouldTerminate: delegate method. To abort the termination sequence, implement this method and return NSTerminateCancel; otherwise, termination of your application continues normally."
"NSTerminateLater = 2
It may be OK to proceed with termination later. Returning this value causes Cocoa to run the run loop in the NSModalPanelRunLoopMode until your app subsequently calls replyToApplicationShouldTerminate: with the value YES or NO. This return value is for delegates that need to provide document modal alerts (sheets) in order to decide whether to quit.
"
If I return NSTerminateLater the main event loop is indeed not called anymore... a new event loop is started it seems. I have no clue how to handle that bit NSModalPanelRunLoopMode. I want to just continue with the main loop and call replyToApplicationShouldTerminate whenever convenient...
"For Cocoa applications, termination is partly handled by the Application Kit, which calls the applicationShouldTerminate: delegate method. To abort the termination sequence, implement this method and return NSTerminateCancel; otherwise, termination of your application continues normally."
"NSTerminateLater = 2
It may be OK to proceed with termination later. Returning this value causes Cocoa to run the run loop in the NSModalPanelRunLoopMode until your app subsequently calls replyToApplicationShouldTerminate: with the value YES or NO. This return value is for delegates that need to provide document modal alerts (sheets) in order to decide whether to quit.
"
If I return NSTerminateLater the main event loop is indeed not called anymore... a new event loop is started it seems. I have no clue how to handle that bit NSModalPanelRunLoopMode. I want to just continue with the main loop and call replyToApplicationShouldTerminate whenever convenient...
Re: EventClose on Dock
I doubt if what you want is possible this way.Rinzwind wrote:f I return NSTerminateLater the main event loop is indeed not called anymore... a new event loop is started it seems. I have no clue how to handle that bit NSModalPanelRunLoopMode. I want to just continue with the main loop and call replyToApplicationShouldTerminate whenever convenient...
Like what you quoted already mentions, this is intended for something like the PureBasic MessageRequester to get confirmation if you want the app to quit or not.
If you want to continue with the main loop, just cancel the quit. You can set a flag or post an event and act on that from the main loop.
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
Re: EventClose on Dock
If I return #NSTerminateNow the application is instantly killed. If I return #NSTerminateCancel (0) the OS dialog app prevents shutdown is shown and shutdown is cancelled. With #NSTerminateLater the app becomes unresponsive. Hmm
Re: EventClose on Dock
Any way to at least show some moving gui like progressbar in that “sheet” runmode?
Re: EventClose on Dock
Is the event method I suggested not working for you ?
Code: Select all
Enumeration #PB_Event_FirstCustomValue
#Event_TerminateRequested
EndEnumeration
Prototype Proto_AppShouldTerminate(Object, Selector, Sender)
DeclareC AppShouldTerminate(Object, Selector, Sender)
Global AppDelegate, AppShouldTerminate_.Proto_AppShouldTerminate
AppDelegate = CocoaMessage(0, CocoaMessage(0, 0, "NSApplication sharedApplication"), "delegate")
AppShouldTerminate_ = class_replaceMethod_(CocoaMessage(0, AppDelegate, "class"),
sel_registerName_("applicationShouldTerminate:"),
@AppShouldTerminate(), "v@:@")
ProcedureC AppShouldTerminate(Object, Selector, Sender)
PostEvent(#Event_TerminateRequested)
If AppShouldTerminate_
ProcedureReturn AppShouldTerminate_(Object, Selector, Sender)
EndIf
ProcedureReturn #NO
EndProcedure
OpenWindow(0, 0, 0, 420, 320, "Terminate request example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
EditorGadget(0, 10, 10, 400, 300)
Repeat
Event = WaitWindowEvent()
If Event = #Event_TerminateRequested
AddGadgetItem(0, -1, "Terminate requested at:" + FormatDate("%hh:%ii:%ss", Date()))
EndIf
Until Event = #PB_Event_CloseWindow
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)