MacOSX Lion: как переместить именованное окно, используя CoreGraphics, без AppleScript? - PullRequest
0 голосов
/ 30 декабря 2011

Используя CoreGraphics в программе-какао target-c, работающей под Lion, я бы хотел переместить именованное окно, которое принадлежит другому процессу. Я знаю, что могу сделать это с помощью вспомогательного метода AppleScript через ASOC, но я хочу выполнить эту задачу полностью в какао, используя CoreGraphics (или, по крайней мере, полностью в C или target-c), и вообще без AppleScript.

Я знаю, как найти именованное окно именованного процесса, используя приведенный ниже код, но как только я получил информацию об этом окне, я не смог понять, как его переместить (см. Комментарий «Что делать?»). Я делаю здесь ...? "В этом коде). Может ли кто-нибудь указать мне на некоторые документы или предложить, как мне действовать дальше?

Заранее спасибо.

+(boolean_t)moveWindow:(NSString*)windowName ofProcess:(NSString*)processName to:(CGPoint*)location {

    boolean_t result = false;

    if (windowName == nil || processName == nil || location == nil) {
        return (result);
    }

    CFArrayRef windows = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
    CFIndex   nWindows = CFArrayGetCount(windows);

    for (CFIndex i = 0; i < nWindows; i++) {
        CFDictionaryRef windict = CFArrayGetValueAtIndex(windows, i);
        CFNumberRef winOwnerPidRef = CFDictionaryGetValue(windict, kCGWindowOwnerPID);
        if (winOwnerPidRef == nil) {
            continue;
        }
        pid_t winOwnerPid = 0;
        CFNumberGetValue(winOwnerPidRef, kCFNumberSInt32Type, (int*)&winOwnerPid);
        if (winOwnerPid < 1) {
            continue;
        }
        ProcessSerialNumber winOwnerPSN;
        GetProcessForPID(winOwnerPid, &winOwnerPSN);

        NSString* winOwner = nil;

        ProcessSerialNumber psn;
        psn.lowLongOfPSN  = kNoProcess;
        psn.highLongOfPSN = 0;

        while (winOwner == nil && GetNextProcess(&psn) == noErr) {

            if (psn.lowLongOfPSN  != winOwnerPSN.lowLongOfPSN ||
                psn.highLongOfPSN != winOwnerPSN.highLongOfPSN) {
                continue;
            }
            CFStringRef procName = NULL;
            if (CopyProcessName(&psn, &procName) == noErr) {
                winOwner = (NSString*) procName;
            }
            CFRelease(procName);
        }

        if (winOwner == nil || [winOwner compare:processName] != NSOrderedSame) {
            continue;
        }

        CFStringRef winNameRef = CFDictionaryGetValue(windict, kCGWindowName);
        NSString* winName = (NSString*) winNameRef;
        if (winName != nil && [winName compare:windowName] == NSOrderedSame) {
            // ********************************************** //
            // What do I do here in order to move the window? //
            // ********************************************** //
            result = true;
            break;
        }
    }

    return (result);
}

1 Ответ

1 голос
/ 30 декабря 2011

Вы можете перемещать окна других приложений, используя Специальные возможности. Посмотрите на AXUIElementCreateApplication() и AXUIElementSetAttributeValue() с атрибутом kAXPositionAttribute.

Обратите внимание, что Accessibility должен быть включен (отметьте «Включить доступ для вспомогательных устройств» в настройках Universal Access), или вашему процессу нужно будет доверять (см. AXMakeProcessTrusted())

...