以编程方式将工作区添加/删除到mac

Min*_*ber 5 macos workspace cocoa mission-control

我有一个相当简单的问题.我将如何以编程方式添加/删除任务控制中找到的工作空间.我在这里看过这篇关于以编程方式更改到另一个空间的帖子,我认为它可能类似于答案,使用CGSPrivate.h.我不需要担心私有框架,因为它不会在应用商店中出现.

编辑:我也看到一篇关于修改com.apple.spaces.plist和添加工作区的帖子,但我不知道如何添加它,因为dict有UUID和其他东西.

Wil*_*eke 2

在 Mission Control 中,这是 Dock 的辅助功能层次结构(在我的 Mac,OS X 10.10 上):

\n\n
Role    Position    Title   Value   Description\nAXList 632.000000, 1136.000000 (null) (null) (null)\n    AXDockItem 636.300049, 1138.000000 Finder (null) (null)\n    AXDockItem 688.300049, 1138.000000 Firefox (null) (null)\n    \xe2\x80\xa6\n    AXDockItem 1231.699951, 1138.000000 Trash (null) (null)\nAXGroup 0.000000, 0.000000 (null) (null) (null)\n    AXGroup 20.000000, 227.000000 (null) (null) expos\xc3\xa9d windows\n    AXList 0.000000, -2.000000 (null) (null) (null)\n        AXButton 592.000000, 20.000000 Desktop 1 (null) select Desktop 1\n        AXButton 864.000000, 20.000000 Desktop 2 (null) select Desktop 2\n        AXButton 1136.000000, 20.000000 Desktop 3 (null) select Desktop 3\n    AXButton 1824.000000, 20.000000 (null) (null) add desktop\n
Run Code Online (Sandbox Code Playgroud)\n\n

工作区按钮的位置是删除按钮的中间。

\n\n

我的测试应用程序:

\n\n
- (AXUIElementRef)copyAXUIElementFrom:(AXUIElementRef)theContainer role:(CFStringRef)theRole atIndex:(NSInteger)theIndex {\n    AXUIElementRef aResultElement = NULL;\n    CFTypeRef aChildren;\n    AXError anAXError = AXUIElementCopyAttributeValue(theContainer, kAXChildrenAttribute, &aChildren);\n    if (anAXError == kAXErrorSuccess) {\n        NSUInteger anIndex = -1;\n        for (id anElement in (__bridge NSArray *)aChildren) {\n            if (theRole) {\n                CFTypeRef aRole;\n                anAXError = AXUIElementCopyAttributeValue((__bridge AXUIElementRef)anElement, kAXRoleAttribute, &aRole);\n                if (anAXError == kAXErrorSuccess) {\n                    if (CFStringCompare(aRole, theRole, 0) == kCFCompareEqualTo)\n                        anIndex++;\n                    CFRelease(aRole);\n                }\n            }\n            else\n                anIndex++;\n            if (anIndex == theIndex) {\n                aResultElement = (AXUIElementRef)CFRetain((__bridge CFTypeRef)(anElement));\n                break;\n            }\n        }\n        CFRelease(aChildren);\n    }\n    return aResultElement;\n}\n\n- (IBAction)addWorkspace:(id)sender {\n    if (!AXIsProcessTrustedWithOptions((__bridge CFDictionaryRef)@{(__bridge NSString *)kAXTrustedCheckOptionPrompt:@YES}))\n        return;\n    // type control-arrow-up\n    CGEventRef anEvent = CGEventCreateKeyboardEvent(NULL, 0x7E, true);\n    CGEventSetFlags(anEvent, kCGEventFlagMaskControl);\n    CGEventPost(kCGHIDEventTap, anEvent);\n    CFRelease(anEvent);\n    [NSThread sleepForTimeInterval:0.05];\n    anEvent = CGEventCreateKeyboardEvent(NULL, 0x7E, false);\n    CGEventSetFlags(anEvent, kCGEventFlagMaskControl);\n    CGEventPost(kCGHIDEventTap, anEvent);\n    CFRelease(anEvent);\n    [NSThread sleepForTimeInterval:0.05];\n\n    // option down\n    anEvent = CGEventCreateKeyboardEvent(NULL, 0x3A, true);\n    CGEventPost(kCGHIDEventTap, anEvent);\n    [NSThread sleepForTimeInterval:0.05];\n\n    // click on the + button\n    NSArray *anArray = [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.dock"];\n    AXUIElementRef anAXDockApp = AXUIElementCreateApplication([[anArray objectAtIndex:0] processIdentifier]);\n    CFTypeRef aGroup = [self copyAXUIElementFrom:anAXDockApp role:kAXGroupRole atIndex:0];\n    CFTypeRef aButton = [self copyAXUIElementFrom:aGroup role:kAXButtonRole atIndex:0];\n    CFRelease(aGroup);\n    if (aButton) {\n        AXError anAXError = AXUIElementPerformAction(aButton, kAXPressAction); \n        CFRelease(aButton);\n    }\n\n    // option up\n    anEvent = CGEventCreateKeyboardEvent(NULL, 0x3A, false);\n    CGEventPost(kCGHIDEventTap, anEvent);\n    [NSThread sleepForTimeInterval:0.05];\n\n    // type escape\n    anEvent = CGEventCreateKeyboardEvent(NULL, 0x35, true);\n    CGEventPost(kCGHIDEventTap, anEvent);\n    CFRelease(anEvent);\n    [NSThread sleepForTimeInterval:0.05];\n    anEvent = CGEventCreateKeyboardEvent(NULL, 0x35, false);\n    CGEventPost(kCGHIDEventTap, anEvent);\n    CFRelease(anEvent);\n}\n\n- (IBAction)removeWorkspace:(id)sender {\n    if (!AXIsProcessTrustedWithOptions((__bridge CFDictionaryRef)@{(__bridge NSString *)kAXTrustedCheckOptionPrompt:@YES}))\n        return;\n    // type control-arrow-up\n    CGEventRef anEvent = CGEventCreateKeyboardEvent(NULL, 0x7E, true);\n    CGEventSetFlags(anEvent, kCGEventFlagMaskControl);\n    CGEventPost(kCGHIDEventTap, anEvent);\n    CFRelease(anEvent);\n    [NSThread sleepForTimeInterval:0.05];\n    anEvent = CGEventCreateKeyboardEvent(NULL, 0x7E, false);\n    CGEventSetFlags(anEvent, kCGEventFlagMaskControl);\n    CGEventPost(kCGHIDEventTap, anEvent);\n    CFRelease(anEvent);\n    [NSThread sleepForTimeInterval:0.05];\n\n    // move mouse to the top of the screen\n    CGPoint aPoint;\n    aPoint.x = 10.0;\n    aPoint.y = 10.0;\n    anEvent = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved, aPoint, 0);\n    CGEventPost(kCGHIDEventTap, anEvent);\n    CFRelease(anEvent);\n    [NSThread sleepForTimeInterval:0.05];\n\n    // option down\n    anEvent = CGEventCreateKeyboardEvent(NULL, 0x3A, true);\n    CGEventPost(kCGHIDEventTap, anEvent);\n    [NSThread sleepForTimeInterval:0.05];\n\n    // option down\n    anEvent = CGEventCreateKeyboardEvent(NULL, 0x3A, true);\n    CGEventPost(kCGHIDEventTap, anEvent);\n    [NSThread sleepForTimeInterval:0.05];\n\n    // click at the location of the workspace\n    NSArray *anArray = [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.dock"];\n    AXUIElementRef anAXDockApp = AXUIElementCreateApplication([[anArray objectAtIndex:0] processIdentifier]);\n    CFTypeRef aGroup = [self copyAXUIElementFrom:anAXDockApp role:kAXGroupRole atIndex:0];\n    CFTypeRef aList = [self copyAXUIElementFrom:aGroup role:kAXListRole atIndex:0];\n    CFRelease(aGroup);\n    CFTypeRef aButton = [self copyAXUIElementFrom:aList role:kAXButtonRole atIndex:1];  // index of the workspace\n    CFRelease(aList);\n    if (aButton) {\n        CFTypeRef aPosition;\n        AXError anAXError = AXUIElementCopyAttributeValue(aButton, kAXPositionAttribute, &aPosition);\n        if (anAXError == kAXErrorSuccess) {\n            AXValueGetValue(aPosition, kAXValueCGPointType, &aPoint);\n            CFRelease(aPosition);\n\n            // click\n            anEvent = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDown, aPoint, kCGMouseButtonLeft);\n            CGEventPost(kCGHIDEventTap, anEvent);\n            CFRelease(anEvent);\n            [NSThread sleepForTimeInterval:0.05];\n            anEvent = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseUp, aPoint, kCGMouseButtonLeft);\n            CGEventPost(kCGHIDEventTap, anEvent);\n            CFRelease(anEvent);\n            [NSThread sleepForTimeInterval:0.05];\n            CFRelease(aButton);\n        }\n    }\n\n    // option up\n    anEvent = CGEventCreateKeyboardEvent(NULL, 0x3A, false);\n    CGEventPost(kCGHIDEventTap, anEvent);\n    [NSThread sleepForTimeInterval:0.05];\n\n    // type escape\n    anEvent = CGEventCreateKeyboardEvent(NULL, 0x35, true);\n    CGEventPost(kCGHIDEventTap, anEvent);\n    CFRelease(anEvent);\n    [NSThread sleepForTimeInterval:0.05];\n    anEvent = CGEventCreateKeyboardEvent(NULL, 0x35, false);\n    CGEventPost(kCGHIDEventTap, anEvent);\n    CFRelease(anEvent);\n}\n
Run Code Online (Sandbox Code Playgroud)\n