<!--
{
  "documentType" : "article",
  "framework" : "AppKit",
  "identifier" : "/documentation/AppKit/passing-control-from-one-app-to-another-with-cooperative-activation",
  "metadataVersion" : "0.1.0",
  "role" : "article",
  "title" : "Passing control from one app to another with cooperative activation"
}
-->

# Passing control from one app to another with cooperative activation

Request focus for your app, and coordinate passing control from one app to another.

## Discussion

When someone uses your app and another app unexpectedly steals focus, the user experience can be compromised. Not only is it inconvenient for people to switch back to their original app, if they’re typing when the switch occurs, they might accidentally enter text into the wrong app, inadvertently disclosing sensitive information.

Cooperative activation addresses this problem by making app activation a request instead of a command. Instead of apps stealing focus, they now request focus from the system when they’re ready. This means apps should set expectations accordingly when requesting activation and not assume the system will grant them activation. The system dynamically determines whether to grant activation state based on the context. This lets you request focus for your app when needed, and hand off focus from one app to another.

> Related sessions from WWDC23:
> Session 10054: [What’s new in AppKit](https://developer.apple.com/videos/play/wwdc2023/10054)

### Request activation to gain focus

When your app needs focus, call [`activate()`](/documentation/AppKit/NSApplication/activate()) on your app’s [`shared`](/documentation/AppKit/NSApplication/shared) instance, or its shorthand version `NSApp`:

```swift
// Call this function when you want your app to request activation for itself.
NSApp.activate()
```

Calling this function sends a message to the system requesting activation for the app. Requesting activation doesn’t guarantee your app gains focus. People ultimately decide which apps gain focus by activating them through their device’s user interface. But if, after considering the user’s intent and larger system context, the system honors your app’s request, your app activates.

### Transfer control from one app to another by yielding and then activating

Passing control from one app to another is a two-step process.

1. First yield from the currently running active app to the target app that you want to gain focus.
2. Then activate the target app when it’s ready.

![A block diagram showing two app instances on the left stacked on top of one another, with arrows pointing out of the boxes into another box titled System makes a decision on the right. Within the topmost app instance box, titled Active app, is another box titled Yield to target. It’s sequentially to the left of a similar box in the bottom app instance titled Activate. The sequence of boxes implies you call Yield to target on the Active app instance before Activate on the Target app instance.](images/com.apple.appkit/media-4311539@2x.png)

Only the active app can influence the activation context. It does so by yielding to an explicit target app before the target app activates. Then, when the target app requests activation, the system uses the yield as part of the context when making its decision. If the system honors the request, the active app deactivates, and the target app activates. Otherwise, the active app remains active. [`NSWorkspace`](/documentation/AppKit/NSWorkspace) automatically handles this for you when opening URLs or applications.

For example, to pass control from your active app to another target app (such as TextEdit, which is a good test candidate because it comes installed on every Mac):

1. Get an instance of the target app you want to pass control to by calling [`runningApplications(withBundleIdentifier:)`](/documentation/AppKit/NSRunningApplication/runningApplications(withBundleIdentifier:)), passing in the bundle identifier of the target app.
2. Yield to the target app by calling [`yieldActivation(to:)`](/documentation/AppKit/NSApplication/yieldActivation(to:)), passing the target app instance.
3. Then activate the target by calling [`activate()`](/documentation/AppKit/NSApplication/activate()) on the target app instance.

```swift
// When you want to pass control to another application.

// Get an instance of the app you want to activate.
if let targetApp = NSRunningApplication.runningApplications(withBundleIdentifier:
                                                                "com.apple.TextEdit").first {
    // Yield to it.
    NSApp.yieldActivation(to:targetApp)
    
    // Then activate it.
    targetApp.activate()
}
```

Alternatively, if the app you want to pass control to isn’t currently running, call [`yieldActivation(toApplicationWithBundleIdentifier:)`](/documentation/AppKit/NSApplication/yieldActivation(toApplicationWithBundleIdentifier:)) on the `NSApp` instance, passing in the bundle identifier of the target app you want to activate.

```swift
// Call this function from the active process.
// Yield to the app using the app's bundleIdentifier.
NSApp.yieldActivation(toApplicationWithBundleIdentifier: "com.example.targetApp")
```

Then call [`activate()`](/documentation/AppKit/NSApplication/activate()) on the target app when it’s ready to gain focus.

```swift
// Call this function from the target process.
// Have the app activate itself when it's ready.
NSApp.activate()
```

Choosing between [`NSRunningApplication`](/documentation/AppKit/NSRunningApplication) or [`NSApplication`](/documentation/AppKit/NSApplication) for activation depends on which app you want to initiate the activation. Use `NSRunningApplication` if you want the active app to control when the target app activates. Use `NSApplication` (or `NSApp`) if you want the target app to activate itself.

### Replace calls to deactivate

When you call [`yieldActivation(to:)`](/documentation/AppKit/NSApplication/yieldActivation(to:)), there’s no need to call [`deactivate()`](/documentation/AppKit/NSApplication/deactivate()) on the app losing focus. Cooperative activation APIs cause the receiver to draw inactive when another app activates. This is typically the behavior you want.

Replace calls to [`deactivate()`](/documentation/AppKit/NSApplication/deactivate()) with [`yieldActivation(to:)`](/documentation/AppKit/NSApplication/yieldActivation(to:)) or equivalent. There’s also no need to call `deactivate()` if an app is hidden by calling [`hide()`](/documentation/AppKit/NSRunningApplication/hide()). The system implies deactivation when the app hides.

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)