There are many Apps that if you click the red X (close) , the App will not close but the window will hide instead.
I have an App with one Window. It has a ‘Quit’ button that calls quit.
I want the window to hide when the red X is clicked.
I assumed I could just do Me.Hide and Return True in the CancelClose of the window.
That seems to works but the window doesn’t restore when the dock App icon is clicked again.
How do I show the window again when the dock App icon is clicked? Or is there a better way to do this?
If you want to limit it to only the Dock icon clicks, you can respond to the AppleEvent that’s generated when the user does that. I’m not in front of my computer at the moment or I’d tell you exactly what that is.
Ah, cool. Almost there.
That works but only if the App lost focus. Otherwise the event won’t fire.
So if I ‘close’ the App (it hides), the App is still active. When I click the dock icon, nothing happens. Only when I click another App first and then click the dock icon, it opens again.
Now I’m about to find a way to make it lose focus but is that really the way to do it? It seems odd.
[quote=210670:@Marco Hof]Ah, cool. Almost there.
That works but only if the App lost focus. Otherwise the event won’t fire.
So if I ‘close’ the App (it hides), the App is still active. When I click the dock icon, nothing happens. Only when I click another App first and then click the dock icon, it opens again.
Now I’m about to find a way to make it lose focus but is that really the way to do it? It seems odd.[/quote]
HandleAppleEvent fires for more than just clicking the dock icon. You want to test the parameters to identify your kind of event and only handle that (I forgot this recently and the docks Quit menu item stopped working because I always returned true).
Anyways, if it passes the if condition then the dock icon was clicked. The wasFront variable is extra and tells you if your app was in front or in the background when the click happened. I use this so if the app is in the background the first click brings it forward, then the next click shows a special window.
[code]//App Event
Function HandleAppleEvent(theEvent As AppleEvent, eventClass As String, eventID As String) As Boolean
if eventClass = “aevt” and eventID = “rapp” then
dim wasFront As boolean = theEvent.BooleanParam("frnt")
System.DebugLog "dock clicked, app was front: " + Str(wasFront)
return true
Anytime the app is brought to the front for any reason, you will get App.Activate. However, normal behavior on OS X is that switching to the app via cmd-tab will not open a new window, only clicking on the Dock. Try it out with something like Safari.
I’m not sure what you mean.
What I have now is that App.Activate indeed fires but only if it’s not the first on the row of icons you see with command-tab.
So if the App is hidden and before clicking anywhere else, the Apps icon is the first in the row of icons in command-tab. I guess that means that the App is still the Active one?
When I command-tab to the App’s icon, nothing happens. Both App.Activate and App.HandleEvent aren’t fired.
When I click somewhere else, the App icon in command-tab becomes the second one. Then App.Activate is fired.
Is that what you mean?
Is some other event raised or is it possible to ‘de-activate’ my App?
When you press command-tab and the highlighted icon is your app, yes, it is indeed already active. In fact, your app’s name should appear in the menubar. No event will fire in that case because nothing has really happened.
A solution might be to activate another app once the user closes the last window in your app, and for that you’d need either declares or an AppleScript (you can use System Events for this). The question is, which app do you activate? If you don’t care, this AppleScript should do the trick:
tell application "System Events"
try
set p to first application process whose background only is false and ¬
visible is true and ¬
bundle identifier is not "my.bundle.identifier"
tell p to activate
end try
end tell
Replace “my.bundle.identifier” with the identifier for your app. This will keep it from activating your own app if that’s the first one it finds.
tell application "System Events"
set p to first application process whose bundle identifier is "my.bundle.identifier"
set visible of p to false
end tell
For future searchers…
I stumbled on a declare-way to do it. This way of hiding the App moves the focus automatically so the Cmd-Tab works correctly.
In the CancelClose event of the Window:
If Not appQuitting Then
// This way of hiding makes Cmd-Tab work correctly.
#if TargetCocoa
Declare Function NSClassFromString Lib "Cocoa"(inName As CFStringRef) As Ptr
Declare Function sharedApplication Lib "Cocoa" selector "sharedApplication"(classRef As Ptr) As Ptr
Dim thisApp As Ptr = sharedApplication(NSClassFromString("NSApplication"))
Declare Sub Hide Lib "Cocoa" Selector "hide:"(id As Ptr)
Hide thisApp
#else
Self.Hide
#endif
Return True
End If
The Show -part stays the same in App.HandleAppleEvent.