Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
612 views
in Technique[技术] by (71.8m points)

objective c - Detecting when a space changes in Spaces in Mac OS X

Let's say I want to write a simple Cocoa app to make the Spaces feature of Leopard more useful. I would like to configure each space to have, say, different

  • screen resolutions
  • keyboard layouts
  • volume (for audio)

So there are two parts to my question:

  1. I suppose there are ways to modify these three things independently of Spaces, right? If so, how?
  2. How can I detect in my app when a space change occurs, and when that happens, determine what space the user just switched to? Does Leopard send out some distributed notifications or something?

Update: There has to be some public API way of doing this, judging from all the Spaces-related apps on the Mac App Store.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As Peter says, in 10.6 you can use the NSWorkSpace NSWorkspaceActiveSpaceDidChangeNotification to get a notification when the workspace changes.

You can then determine the current space using Quartz API, the kCGWindowWorkspace dictionary key holds the workspace. e.g:

int currentSpace;
// get an array of all the windows in the current Space
CFArrayRef windowsInSpace = CGWindowListCopyWindowInfo(kCGWindowListOptionAll | kCGWindowListOptionOnScreenOnly, kCGNullWindowID);      

// now loop over the array looking for a window with the kCGWindowWorkspace key
for (NSMutableDictionary *thisWindow in (NSArray *)windowsInSpace)
{
     if ([thisWindow objectForKey:(id)kCGWindowWorkspace])
       {
           currentSpace = [thisWindow objectForKey(id)kCGWindowWorkspace] intValue];
           break;
       }
}

Alternatively you can get the Space using the private API, take a look at CGSPrivate.h which allows you to do this:

int currentSpace = 0;
CGSGetWorkspace(_CGSDefaultConnection(), &currentSpace);

To change the screen resolution you'll want to look at Quartz services, for altering the volume this may be helpful.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...