以编程方式向Mac添加/删除工作区 [英] Add/remove workspace to mac programmatically

查看:146
本文介绍了以编程方式向Mac添加/删除工作区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a fairly simple question. How would I programmatically add/remove the workspaces found in mission control. I have seen this post here about changing to another space programmatically, and I think that it could be something similar to the answer, using CGSPrivate.h. I don't need to worry about private frameworks, as it's not going on the app store.

我还看到了有关修改com.apple.spaces.plist并添加工作区的帖子,但是我不知道如何添加,因为该字典包含UUID和其他内容.

I also saw a post about modifying the com.apple.spaces.plist and adding workspaces, but I have no Idea how I would add that, as the dict has UUID and other things.

推荐答案

在任务控制中,这是Dock的可访问性层次结构(在我的Mac上为OS X 10.10):

While in Mission Control this is the Accessibility Hierarchy of Dock (on my Mac, OS X 10.10):

Role    Position    Title   Value   Description
AXList 632.000000, 1136.000000 (null) (null) (null)
    AXDockItem 636.300049, 1138.000000 Finder (null) (null)
    AXDockItem 688.300049, 1138.000000 Firefox (null) (null)
    …
    AXDockItem 1231.699951, 1138.000000 Trash (null) (null)
AXGroup 0.000000, 0.000000 (null) (null) (null)
    AXGroup 20.000000, 227.000000 (null) (null) exposéd windows
    AXList 0.000000, -2.000000 (null) (null) (null)
        AXButton 592.000000, 20.000000 Desktop 1 (null) select Desktop 1
        AXButton 864.000000, 20.000000 Desktop 2 (null) select Desktop 2
        AXButton 1136.000000, 20.000000 Desktop 3 (null) select Desktop 3
    AXButton 1824.000000, 20.000000 (null) (null) add desktop

工作区按钮的位置位于删除"按钮的中间.

The location of the workspace buttons is the middle of the remove button.

我的测试应用:

- (AXUIElementRef)copyAXUIElementFrom:(AXUIElementRef)theContainer role:(CFStringRef)theRole atIndex:(NSInteger)theIndex {
    AXUIElementRef aResultElement = NULL;
    CFTypeRef aChildren;
    AXError anAXError = AXUIElementCopyAttributeValue(theContainer, kAXChildrenAttribute, &aChildren);
    if (anAXError == kAXErrorSuccess) {
        NSUInteger anIndex = -1;
        for (id anElement in (__bridge NSArray *)aChildren) {
            if (theRole) {
                CFTypeRef aRole;
                anAXError = AXUIElementCopyAttributeValue((__bridge AXUIElementRef)anElement, kAXRoleAttribute, &aRole);
                if (anAXError == kAXErrorSuccess) {
                    if (CFStringCompare(aRole, theRole, 0) == kCFCompareEqualTo)
                        anIndex++;
                    CFRelease(aRole);
                }
            }
            else
                anIndex++;
            if (anIndex == theIndex) {
                aResultElement = (AXUIElementRef)CFRetain((__bridge CFTypeRef)(anElement));
                break;
            }
        }
        CFRelease(aChildren);
    }
    return aResultElement;
}

- (IBAction)addWorkspace:(id)sender {
    if (!AXIsProcessTrustedWithOptions((__bridge CFDictionaryRef)@{(__bridge NSString *)kAXTrustedCheckOptionPrompt:@YES}))
        return;
    // type control-arrow-up
    CGEventRef anEvent = CGEventCreateKeyboardEvent(NULL, 0x7E, true);
    CGEventSetFlags(anEvent, kCGEventFlagMaskControl);
    CGEventPost(kCGHIDEventTap, anEvent);
    CFRelease(anEvent);
    [NSThread sleepForTimeInterval:0.05];
    anEvent = CGEventCreateKeyboardEvent(NULL, 0x7E, false);
    CGEventSetFlags(anEvent, kCGEventFlagMaskControl);
    CGEventPost(kCGHIDEventTap, anEvent);
    CFRelease(anEvent);
    [NSThread sleepForTimeInterval:0.05];

    // option down
    anEvent = CGEventCreateKeyboardEvent(NULL, 0x3A, true);
    CGEventPost(kCGHIDEventTap, anEvent);
    [NSThread sleepForTimeInterval:0.05];

    // click on the + button
    NSArray *anArray = [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.dock"];
    AXUIElementRef anAXDockApp = AXUIElementCreateApplication([[anArray objectAtIndex:0] processIdentifier]);
    CFTypeRef aGroup = [self copyAXUIElementFrom:anAXDockApp role:kAXGroupRole atIndex:0];
    CFTypeRef aButton = [self copyAXUIElementFrom:aGroup role:kAXButtonRole atIndex:0];
    CFRelease(aGroup);
    if (aButton) {
        AXError anAXError = AXUIElementPerformAction(aButton, kAXPressAction); 
        CFRelease(aButton);
    }

    // option up
    anEvent = CGEventCreateKeyboardEvent(NULL, 0x3A, false);
    CGEventPost(kCGHIDEventTap, anEvent);
    [NSThread sleepForTimeInterval:0.05];

    // type escape
    anEvent = CGEventCreateKeyboardEvent(NULL, 0x35, true);
    CGEventPost(kCGHIDEventTap, anEvent);
    CFRelease(anEvent);
    [NSThread sleepForTimeInterval:0.05];
    anEvent = CGEventCreateKeyboardEvent(NULL, 0x35, false);
    CGEventPost(kCGHIDEventTap, anEvent);
    CFRelease(anEvent);
}

- (IBAction)removeWorkspace:(id)sender {
    if (!AXIsProcessTrustedWithOptions((__bridge CFDictionaryRef)@{(__bridge NSString *)kAXTrustedCheckOptionPrompt:@YES}))
        return;
    // type control-arrow-up
    CGEventRef anEvent = CGEventCreateKeyboardEvent(NULL, 0x7E, true);
    CGEventSetFlags(anEvent, kCGEventFlagMaskControl);
    CGEventPost(kCGHIDEventTap, anEvent);
    CFRelease(anEvent);
    [NSThread sleepForTimeInterval:0.05];
    anEvent = CGEventCreateKeyboardEvent(NULL, 0x7E, false);
    CGEventSetFlags(anEvent, kCGEventFlagMaskControl);
    CGEventPost(kCGHIDEventTap, anEvent);
    CFRelease(anEvent);
    [NSThread sleepForTimeInterval:0.05];

    // move mouse to the top of the screen
    CGPoint aPoint;
    aPoint.x = 10.0;
    aPoint.y = 10.0;
    anEvent = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved, aPoint, 0);
    CGEventPost(kCGHIDEventTap, anEvent);
    CFRelease(anEvent);
    [NSThread sleepForTimeInterval:0.05];

    // option down
    anEvent = CGEventCreateKeyboardEvent(NULL, 0x3A, true);
    CGEventPost(kCGHIDEventTap, anEvent);
    [NSThread sleepForTimeInterval:0.05];

    // option down
    anEvent = CGEventCreateKeyboardEvent(NULL, 0x3A, true);
    CGEventPost(kCGHIDEventTap, anEvent);
    [NSThread sleepForTimeInterval:0.05];

    // click at the location of the workspace
    NSArray *anArray = [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.dock"];
    AXUIElementRef anAXDockApp = AXUIElementCreateApplication([[anArray objectAtIndex:0] processIdentifier]);
    CFTypeRef aGroup = [self copyAXUIElementFrom:anAXDockApp role:kAXGroupRole atIndex:0];
    CFTypeRef aList = [self copyAXUIElementFrom:aGroup role:kAXListRole atIndex:0];
    CFRelease(aGroup);
    CFTypeRef aButton = [self copyAXUIElementFrom:aList role:kAXButtonRole atIndex:1];  // index of the workspace
    CFRelease(aList);
    if (aButton) {
        CFTypeRef aPosition;
        AXError anAXError = AXUIElementCopyAttributeValue(aButton, kAXPositionAttribute, &aPosition);
        if (anAXError == kAXErrorSuccess) {
            AXValueGetValue(aPosition, kAXValueCGPointType, &aPoint);
            CFRelease(aPosition);

            // click
            anEvent = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDown, aPoint, kCGMouseButtonLeft);
            CGEventPost(kCGHIDEventTap, anEvent);
            CFRelease(anEvent);
            [NSThread sleepForTimeInterval:0.05];
            anEvent = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseUp, aPoint, kCGMouseButtonLeft);
            CGEventPost(kCGHIDEventTap, anEvent);
            CFRelease(anEvent);
            [NSThread sleepForTimeInterval:0.05];
            CFRelease(aButton);
        }
    }

    // option up
    anEvent = CGEventCreateKeyboardEvent(NULL, 0x3A, false);
    CGEventPost(kCGHIDEventTap, anEvent);
    [NSThread sleepForTimeInterval:0.05];

    // type escape
    anEvent = CGEventCreateKeyboardEvent(NULL, 0x35, true);
    CGEventPost(kCGHIDEventTap, anEvent);
    CFRelease(anEvent);
    [NSThread sleepForTimeInterval:0.05];
    anEvent = CGEventCreateKeyboardEvent(NULL, 0x35, false);
    CGEventPost(kCGHIDEventTap, anEvent);
    CFRelease(anEvent);
}

这篇关于以编程方式向Mac添加/删除工作区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆