Re: How to deactivate an app
On 2 Feb 2012, at 00:51, Leo wrote: What happens if you send set frontmost of process yourApp to false then, using the name of your app? Will it reveal the previous app by a chance? It seems that process has to be followed by a number. I tried this in AppleScript Editor: tell application System Events set proCount to count of processes repeat with x from (1) to (proCount) set appName to name of process x if appName = AppleScript Editor then set frontmost of process x to false exit repeat end if end repeat end tell and it had no effect and no error messages. Tried it inside my app - again, no effect. If not, then is there any way to capture the name of the app you need to activate at an earlier stage, so you can send it set frontmost to true later? I am getting the previous app by watching for the relevant Carbon events. But then there is no need to use Apple Script to activate it - activateWithOptions: is probably more efficient. Kind regards, Gerriet. On 2/1/12 1:44:49 AM, Gerriet M. Denkmann wrote: On 1 Feb 2012, at 11:33, Leo wrote: If I understand your goals correctly, you can send the following AppleScript script: tell application System Events to set frontmost of process yourApp to true I tried the following in AppleScript Editor: set appList to processes tell application System Events set proCount to count of processes set appList to appList ( proCount ): repeat with x from (1) to (proCount) set appName to name of process x set appList to appList appName , end repeat end tell log appList But the resulting list of apps has only a very rough resemblance to the list displayed by Command-Tab. So the following: NSString *source = @tell application \System Events\ to set frontmost of process 2 to true; NSAppleScript *appleScript = [ [ NSAppleScript alloc ] initWithSource: source ]; NSDictionary *errorInfo; NSAppleEventDescriptor *aed = [ appleScript executeAndReturnError:errorInfo ]; [ appleScript release ]; does work in that is activates some app, but process 2 is NOT the previous active app. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: How to deactivate an app
On 1 Feb 2012, at 14:29, Ken Thomases wrote: On Feb 1, 2012, at 1:20 AM, Gerriet M. Denkmann wrote: I tried: - (void)applicationWillBecomeActive:(NSNotification *)aNotification { (void)aNotification; NSRunningApplication *currentApplication = [ NSRunningApplication currentApplication ]; NSString *bundleIdentifier = currentApplication.bundleIdentifier; NSLog(@%s current: %@,__FUNCTION__, bundleIdentifier); NSWorkspace *sharedWorkspace = [ NSWorkspace sharedWorkspace ]; NSArray *runningApplications = [ sharedWorkspace runningApplications ]; for( NSRunningApplication *ru in runningApplications ) { if ( ru.isActive ) { NSString *bundleIdentifier = ru.bundleIdentifier; NSLog(@%s active: %@,__FUNCTION__, bundleIdentifier); }; }; } But both the currentApplication and the active one is our app (NOT the previously active one). Although the name of the notification is applicationWillBecomeActive it acts more like applicationIsAlreadySomehowActiveAndWIllBecomeFullyActiveRealSoonNow. Well, remember that this is Cocoa responding to an event delivered from the system. Events are delivered asynchronously. The system can't afford to wait for an app to respond to an event before moving on. There is bound to be an interval of time between when the system changed which app is active and when Cocoa actually acts on the event it received because of that change. Yes, I understand this. The good news is: in applicationWillFinishLaunching the active app (not the currentApplication) is still the previously active app. Using this, together with your suggestion of watching Carbon events, I now have a perfect solution. Thanks for your help. Thanks also to Lee Ann Rucker for suggesting using the app delegate methods. Kind regards, Gerriet. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: How to deactivate an app
What happens if you send set frontmost of process yourApp to false then, using the name of your app? Will it reveal the previous app by a chance? If not, then is there any way to capture the name of the app you need to activate at an earlier stage, so you can send it set frontmost to true later? Leo On 2/1/12 1:44:49 AM, Gerriet M. Denkmann wrote: On 1 Feb 2012, at 11:33, Leo wrote: If I understand your goals correctly, you can send the following AppleScript script: tell application System Events to set frontmost of process yourApp to true I tried the following in AppleScript Editor: set appList to processes tell application System Events set proCount to count of processes set appList to appList ( proCount ): repeat with x from (1) to (proCount) set appName to name of process x set appList to appList appName , end repeat end tell log appList But the resulting list of apps has only a very rough resemblance to the list displayed by Command-Tab. So the following: NSString *source = @tell application \System Events\ to set frontmost of process 2 to true; NSAppleScript *appleScript = [ [ NSAppleScript alloc ] initWithSource: source ]; NSDictionary *errorInfo; NSAppleEventDescriptor *aed = [ appleScript executeAndReturnError:errorInfo ]; [ appleScript release ]; does work in that is activates some app, but process 2 is NOT the previous active app. Kind regards, Gerriet. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: How to deactivate an app
On Jan 31, 2012, at 11:29 PM, Ken Thomases wrote: On Feb 1, 2012, at 1:20 AM, Gerriet M. Denkmann wrote: Although the name of the notification is applicationWillBecomeActive it acts more like applicationIsAlreadySomehowActiveAndWIllBecomeFullyActiveRealSoonNow. Well, remember that this is Cocoa responding to an event delivered from the system. Events are delivered asynchronously. The system can't afford to wait for an app to respond to an event before moving on. There is bound to be an interval of time between when the system changed which app is active and when Cocoa actually acts on the event it received because of that change. Regards, Ken It would be nice if it were one of the notifications that tells you what's losing the state that you're gaining. I suppose it's worth filing a bug requesting that; the last active app is a useful thing to know. I dug into this because when I put up a dialog saying that an inter-app operation failed, I wanted the activation to go back to the app that started the operation when the dialog was dismissed. Glad to hear it was helpful anyway. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
How to deactivate an app
I have an app A, where I can select a word and press a button. This starts (or activates) another app called B, which displays some information about this word. Works fine so far. But if there is no information about the word, app B should make app A active again. But how? (B should not be hidden; it should remain visible, so that the user sees: Word not found.) I tried [NSApp deactivate] - the documentation says, I should not use this method - and indeed, it makes the B-window look inactive, but does NOT make A active - the menu bar still belongs to B. No good. The there is NSWorkspace runningApplications - but: The order of the array is unspecified. Not really useful. I just want the equivalent of Command-Tab: making the next most recent app active. There probably is a simple, direct and obvious solution. But I cannot see it. Kind regards, Gerriet. P.S. 10.7.2 ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: How to deactivate an app
Along with the word, send [[NSRunningApplication currentApplication] processIdentifier], then do [[NSRunningApplication runningApplicationWithProcessIdentifier:pid] activateWithOptions: NSApplicationActivateIgnoringOtherApps]; It says You should rarely pass this flag because stealing key focus produces a very bad user experience., but this seems like a valid exception - you're returning focus to where it was. - Original Message - From: Gerriet M. Denkmann gerr...@mdenkmann.de To: cocoa-dev@lists.apple.com Sent: Monday, January 30, 2012 11:55:31 PM Subject: How to deactivate an app I have an app A, where I can select a word and press a button. This starts (or activates) another app called B, which displays some information about this word. Works fine so far. But if there is no information about the word, app B should make app A active again. But how? (B should not be hidden; it should remain visible, so that the user sees: Word not found.) I tried [NSApp deactivate] - the documentation says, I should not use this method - and indeed, it makes the B-window look inactive, but does NOT make A active - the menu bar still belongs to B. No good. The there is NSWorkspace runningApplications - but: The order of the array is unspecified. Not really useful. I just want the equivalent of Command-Tab: making the next most recent app active. There probably is a simple, direct and obvious solution. But I cannot see it. Kind regards, Gerriet. P.S. 10.7.2 ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/lrucker%40vmware.com This email sent to lruc...@vmware.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: How to deactivate an app
On Jan 31, 2012, at 1:55 AM, Gerriet M. Denkmann wrote: I have an app A, where I can select a word and press a button. This starts (or activates) another app called B, which displays some information about this word. But if there is no information about the word, app B should make app A active again. But how? (B should not be hidden; it should remain visible, so that the user sees: Word not found.) There probably is a simple, direct and obvious solution. But I cannot see it. There isn't, as far as I know. The best general-purpose solution I'm aware of is for app B to track activations of other apps using Carbon events (kEventClassApplication , kEventAppFrontSwitched). Then, use that info to switch back to the last activate app. I suppose, these days, you can also key-value observe the runningApplications property of [NSWorkspace sharedWorkspace] to learn when apps come and go, and then key-value observe the active property of all of the NSRunningApplication objects in that collection to track which was last active. That doesn't seem like much of an improvement over the Carbon events approach, though. However, your case seems more specific. Are both apps A and B ones that you're writing? Can't you just switch back to app A directly, if it's the only thing that will be invoking app B? Or have I misunderstood your case (in which case, maybe you could clarify). Regards, Ken ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: How to deactivate an app
On 31 Jan 2012, at 17:18, Ken Thomases wrote: On Jan 31, 2012, at 1:55 AM, Gerriet M. Denkmann wrote: I have an app A, where I can select a word and press a button. This starts (or activates) another app called B, which displays some information about this word. But if there is no information about the word, app B should make app A active again. But how? (B should not be hidden; it should remain visible, so that the user sees: Word not found.) There probably is a simple, direct and obvious solution. But I cannot see it. There isn't, as far as I know. The best general-purpose solution I'm aware of is for app B to track activations of other apps using Carbon events (kEventClassApplication , kEventAppFrontSwitched). Then, use that info to switch back to the last activate app. I suppose, these days, you can also key-value observe the runningApplications property of [NSWorkspace sharedWorkspace] to learn when apps come and go, and then key-value observe the active property of all of the NSRunningApplication objects in that collection to track which was last active. That doesn't seem like much of an improvement over the Carbon events approach, though. However, your case seems more specific. Are both apps A and B ones that you're writing? Yes, they are. Can't you just switch back to app A directly, if it's the only thing that will be invoking app B? Or have I misunderstood your case (in which case, maybe you could clarify). App B offers a service look up word. And app A uses this service. While usually it is app A which uses this service, it could be really any app which displays text. Lee Ann Rucker's solution looks interesting, but would not work between any app and B. Ideally the service mechanism should have an argument like pid of sending app but there is (as far as I can see) none. Probably I have to watch for these Carbon events you have mentioned. (Just tried these Carbon events. This is a royal pain, because of non-existence of any documentation. And the switching back does not work, if A (using services) did start B. But this is a minor inconvenience.) Kind regards, Gerriet. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: How to deactivate an app
I was afraid you were going to say Services :) When I'm using this both apps are under my control. Haven't tried this, but you could try checking which app is active in applicationWillBecomeActive: and restore that when you're done. - Original Message - From: Gerriet M. Denkmann gerr...@mdenkmann.de To: Ken Thomases k...@codeweavers.com Cc: cocoa-dev@lists.apple.com Sent: Tuesday, January 31, 2012 10:40:11 AM Subject: Re: How to deactivate an app On 31 Jan 2012, at 17:18, Ken Thomases wrote: On Jan 31, 2012, at 1:55 AM, Gerriet M. Denkmann wrote: I have an app A, where I can select a word and press a button. This starts (or activates) another app called B, which displays some information about this word. But if there is no information about the word, app B should make app A active again. But how? (B should not be hidden; it should remain visible, so that the user sees: Word not found.) There probably is a simple, direct and obvious solution. But I cannot see it. There isn't, as far as I know. The best general-purpose solution I'm aware of is for app B to track activations of other apps using Carbon events (kEventClassApplication , kEventAppFrontSwitched). Then, use that info to switch back to the last activate app. I suppose, these days, you can also key-value observe the runningApplications property of [NSWorkspace sharedWorkspace] to learn when apps come and go, and then key-value observe the active property of all of the NSRunningApplication objects in that collection to track which was last active. That doesn't seem like much of an improvement over the Carbon events approach, though. However, your case seems more specific. Are both apps A and B ones that you're writing? Yes, they are. Can't you just switch back to app A directly, if it's the only thing that will be invoking app B? Or have I misunderstood your case (in which case, maybe you could clarify). App B offers a service look up word. And app A uses this service. While usually it is app A which uses this service, it could be really any app which displays text. Lee Ann Rucker's solution looks interesting, but would not work between any app and B. Ideally the service mechanism should have an argument like pid of sending app but there is (as far as I can see) none. Probably I have to watch for these Carbon events you have mentioned. (Just tried these Carbon events. This is a royal pain, because of non-existence of any documentation. And the switching back does not work, if A (using services) did start B. But this is a minor inconvenience.) Kind regards, Gerriet. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/lrucker%40vmware.com This email sent to lruc...@vmware.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: How to deactivate an app
If I understand your goals correctly, you can send the following AppleScript script: tell application System Events to set frontmost of process yourApp to true You can use NSAppleScript of Scripting Bridge (although the latter maybe an overkill for just one line). Leo On 1/31/12 2:55:31 AM, Gerriet M. Denkmann wrote: I have an app A, where I can select a word and press a button. This starts (or activates) another app called B, which displays some information about this word. Works fine so far. But if there is no information about the word, app B should make app A active again. But how? (B should not be hidden; it should remain visible, so that the user sees: Word not found.) I tried [NSApp deactivate] - the documentation says, I should not use this method - and indeed, it makes the B-window look inactive, but does NOT make A active - the menu bar still belongs to B. No good. The there is NSWorkspace runningApplications - but: The order of the array is unspecified. Not really useful. I just want the equivalent of Command-Tab: making the next most recent app active. There probably is a simple, direct and obvious solution. But I cannot see it. Kind regards, Gerriet. P.S. 10.7.2 ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/leo.r%40rogers.com This email sent to le...@rogers.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: How to deactivate an app
On 1 Feb 2012, at 11:33, Leo wrote: If I understand your goals correctly, you can send the following AppleScript script: tell application System Events to set frontmost of process yourApp to true I tried the following in AppleScript Editor: set appList to processes tell application System Events set proCount to count of processes set appList to appList ( proCount ): repeat with x from (1) to (proCount) set appName to name of process x set appList to appList appName , end repeat end tell log appList But the resulting list of apps has only a very rough resemblance to the list displayed by Command-Tab. So the following: NSString *source = @tell application \System Events\ to set frontmost of process 2 to true; NSAppleScript *appleScript = [ [ NSAppleScript alloc ] initWithSource: source ]; NSDictionary *errorInfo; NSAppleEventDescriptor *aed = [ appleScript executeAndReturnError: errorInfo ]; [ appleScript release ]; does work in that is activates some app, but process 2 is NOT the previous active app. Kind regards, Gerriet. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: How to deactivate an app
On 1 Feb 2012, at 04:43, Lee Ann Rucker wrote: I was afraid you were going to say Services :) When I'm using this both apps are under my control. Haven't tried this, but you could try checking which app is active in applicationWillBecomeActive: and restore that when you're done. I tried: - (void)applicationWillBecomeActive:(NSNotification *)aNotification { (void)aNotification; NSRunningApplication *currentApplication = [ NSRunningApplication currentApplication ]; NSString *bundleIdentifier = currentApplication.bundleIdentifier; NSLog(@%s current: %@,__FUNCTION__, bundleIdentifier); NSWorkspace *sharedWorkspace = [ NSWorkspace sharedWorkspace ]; NSArray *runningApplications = [ sharedWorkspace runningApplications ]; for( NSRunningApplication *ru in runningApplications ) { if ( ru.isActive ) { NSString *bundleIdentifier = ru.bundleIdentifier; NSLog(@%s active: %@,__FUNCTION__, bundleIdentifier); }; }; } But both the currentApplication and the active one is our app (NOT the previously active one). Although the name of the notification is applicationWillBecomeActive it acts more like applicationIsAlreadySomehowActiveAndWIllBecomeFullyActiveRealSoonNow. Kind regards, Gerriet. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: How to deactivate an app
On Feb 1, 2012, at 1:20 AM, Gerriet M. Denkmann wrote: I tried: - (void)applicationWillBecomeActive:(NSNotification *)aNotification { (void)aNotification; NSRunningApplication *currentApplication = [ NSRunningApplication currentApplication ]; NSString *bundleIdentifier = currentApplication.bundleIdentifier; NSLog(@%s current: %@,__FUNCTION__, bundleIdentifier); NSWorkspace *sharedWorkspace = [ NSWorkspace sharedWorkspace ]; NSArray *runningApplications = [ sharedWorkspace runningApplications ]; for( NSRunningApplication *ru in runningApplications ) { if ( ru.isActive ) { NSString *bundleIdentifier = ru.bundleIdentifier; NSLog(@%s active: %@,__FUNCTION__, bundleIdentifier); }; }; } But both the currentApplication and the active one is our app (NOT the previously active one). Although the name of the notification is applicationWillBecomeActive it acts more like applicationIsAlreadySomehowActiveAndWIllBecomeFullyActiveRealSoonNow. Well, remember that this is Cocoa responding to an event delivered from the system. Events are delivered asynchronously. The system can't afford to wait for an app to respond to an event before moving on. There is bound to be an interval of time between when the system changed which app is active and when Cocoa actually acts on the event it received because of that change. Regards, Ken ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com