is there a way to add an application to all spaces programmatically? I'd like my application to be on all spaces by default.
5 Answers
The methods you need are in NSWindow.
For Lion use:
- (void)setCollectionBehavior:(NSWindowCollectionBehavior)behavior
For pre-Lion override the following to return YES:
- (BOOL)canBeVisibleOnAllSpaces

- 14,676
- 2
- 42
- 46
-
Doesn't that only set what is allowed by the window. I think you have to specifically tell com.apple.dock via what was suggested previously. – Larvell Jones Sep 18 '11 at 01:46
This piece of code works for me (at least on 10.6.8 in a little project I recently worked on):
-(void)windowDidLoad {
// Make the window visible on all Spaces
if([[self window] respondsToSelector: @selector(setCollectionBehavior:)]) {
[[self window] setCollectionBehavior: NSWindowCollectionBehaviorCanJoinAllSpaces];
}
else if([[self window] respondsToSelector: @selector(canBeVisibleOnAllSpaces)]) {
[[self window] canBeVisibleOnAllSpaces]; // AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED
}
}
I put this code in a (custom subclass of a) WindowController for the main app window.

- 166
- 5
-
Works just fine for floating windows of my faceless bg app. No need to mess with the Dock preferences. – Thomas Tempelmann Jan 12 '13 at 10:26
Ok. Just setting the workspaces-app-bindings programmatically didn't work. I tried:
1) Verified no entries were in System Preferences->Spaces
2) defaults write com.apple.dock workspaces-app-bindings -dict-add com.apple.mail 65544
3) killall Dock (also needed to kill System Preferences )
4) Opened System Preferences->Spaces to verify the Mail app entry
appeared and was set to Every Space
5) Launched Mail, but it was still stuck to Space 1
6) Only when I went back into System Preferences->Spaces and changed the
Mail app *from* Every Space and then *back* to Every Space did the Mail
app stick to every space
So clearly system preferences is doing something extra to activate the setting. Does anyone know what this could be? Thanks!
Update: So I was able to get this working by using the applescript api instead of the user defaults api. The following post tells how to append an entry using applescript. Then just kill the dock.

- 1
- 1

- 159
- 2
- 15
Use the defaults-command that ships with OS X, like so:
defaults write com.apple.dock workspaces-app-bindings -dict-add com.apple.mail 65544
By issuing the above command, you set the application identified by “com.apple.mail” to appear on every space. 65544 is a magic value saying “every space”. If the key-value pair (identifier + settings) exists it will be overwritten.
Note that you have to reload the Dock (killall Dock
) and somehow execute these commands from within your application. From within objective-c you can use the following snippet to quit the Dock:
NSRunningApplication *dock = [NSRunningApplicationrunningApplicationWithBundleIdentifier:@"com.apple.dock"];
[dock terminate];
From within AppleScript use the following:
quit application "Dock"

- 11,904
- 14
- 72
- 127
-
Thanks for the response! Running a command line tool from an app seems a little hackish (no offense) though. Is there no API for this? – Larvell Jones Sep 17 '11 at 23:30
-
You can use NSUserDefaults from the Cocoa API to write Defaults: http://www.cocoadev.com/index.pl?NSUserDefaults – scravy Sep 17 '11 at 23:35
Your app delegate should look like this...
#import "alwaysOnTopAppDelegate.h"
@implementation alwaysOnTopAppDelegate
@synthesize window;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[window setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces];
}
@end

- 4,368
- 5
- 44
- 72
-
What's wrong with @Sjoerd can Geffen's answer? It appears to be more complete and also more correct as it's executed inside the window's instantiation code and not, like yours, in the app's instantiation code (at which time not all windows might be opened). – Thomas Tempelmann Jan 12 '13 at 10:15