Ich versuche, eine OS X-Anwendung zu erstellen, die eine externe Anwendung (d. H. TextEdit) auf der laufenden Anwendung ohne Schwerpunkt zu schweben, aber nie verschwinden lässt. Im Grunde versuche ich die ForceQuit-Anwendung nachzuahmen (drücke Option-Befehl-esc, um sie zu sehen), wo sie immer oben ist, aber nicht immer den Fokus hat.Making externe App schweben über OS X-Anwendung
Was mache ich jetzt mit begrenztem Erfolg, ist dies:
ein NSTimer Erstellen zu halten es oben setzen:
_timer = [NSTimer scheduleTimerWithTimeInterval:0.1 target:self selector:@selector(keepTextEditOnTop) userInfo:nil repeats:YES];
...
Bringt textEdit nach vorne:
- (void)keepTextEditOnTop {
AXUIElementRef appRef = AXUIElementCreateApplication(_textEditProcessID);
AXUIElementSetAttributeValue(appRef, kAXFrontmostAttribute, kCFBooleanTrue);
}
Das wird textEdit Fenster an der Spitze bleiben, wenn Sie darauf klicken aus (es verlieren machen Fokus). Aber es gibt zwei Probleme. 1.) Es wird kurz blinken und es wieder in den Vordergrund bringen 2.) Es wird im Wesentlichen immer den Fokus behalten, so dass Sie nicht mit der zugrunde liegenden App interagieren können.
Vom appRef, können Sie das Fenster:
CFArrayRef windowList;
AXUIElementCopyAttributeValue(appRef, kAXWindowsAttribute, (CFTypeRef *)&windowList);
AXUIElementRef windowRef = (AXUIElementRef) CFArrayGetValueAtIndex(windowList, 0);
Aber ich glaube nicht, es möglich sein wird, sie in eine NSWindow zu konvertieren. Wenn ich das könnte, könnte ich mir vorstellen, dass ich ein Kindfenster des Hauptfensters oder vielleicht nur ein schwebendes Fenster machen könnte.
Irgendwelche Ideen, wie dies getan werden könnte?
Bearbeiten- Hinzufügen Vorschläge von @TheDarkKnight
Ich versuche dies:
- (void)testing{
CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
for (NSMutableDictionary* entry in (__bridge NSArray*)windowList)
{
NSString* ownerName = [entry objectForKey:(__bridge id)kCGWindowOwnerName];
NSString *windowNum = [entry objectForKey:(__bridge id)kCGWindowNumber];
if([ownerName isEqualToString:@"Sublime Text"]){
[self holdToTheFront:[windowNum integerValue]];
}
}
CFRelease(windowList);
}
ein EXC_BAD_ACCESS Fehler bekommen, wie unten im Kommentar bemerkt:
- (void)holdToTheFront:(NSInteger)winNum {
objc_object* nsviewObject = reinterpret_cast<objc_object *>(winNum);
//Getting a "Thread 1:EXC_BAD_ACCESS (code=1, address=0x18)" at the line below:
NSWindow* nsWindowObject = ((id (*)(id, SEL))objc_msgSend)((__bridge NSView *)nsviewObject, sel_registerName("window"));
int NSWindowCollectionBehaviorCanJoinAllSpaces = 1 << 0;
((id (*)(id, SEL, NSUInteger))objc_msgSend)(nsWindowObject, sel_registerName("setCollectionBehavior:"), NSWindowCollectionBehaviorCanJoinAllSpaces);
}
Danke! Ich werde es am Morgen versuchen. – user3564870
Ich glaube nicht, dass es möglich ist, eine Fensternummer für Fenster zu erhalten, die die App nicht besitzt. Dann gäbe es die Annahme, dass die externe App Cocoa ist. – user3564870
Hilft dies [http://stackoverflow.com/questions/2107657/mac-cocoa-getting-a-list-of-windows-using-accessibility-api]? – TheDarkKnight