返回 CodeWhale
darwin-targeting.m
根目录 / crates / tui / plugins / computer-use / tests / fixtures / darwin-targeting.m
1 // Use the production resolver with a synthetic workspace. The fixture entry
2 // point never calls execute(), AX observation, activation, capture, or input.
3 #import <Cocoa/Cocoa.h>
4 @interface CUFixtureApplication : NSObject
5 @property pid_t processIdentifier;
6 @property NSString *localizedName;
7 @property NSString *bundleIdentifier;
8 @property(getter=isTerminated) BOOL terminated;
9 @end
10 @implementation CUFixtureApplication
11 @end
12 @interface CUFixtureWorkspace : NSObject
13 + (instancetype)sharedWorkspace;
14 - (NSArray *)runningApplications;
15 - (NSRunningApplication *)frontmostApplication;
16 @end
17 @implementation CUFixtureWorkspace
18 + (instancetype)sharedWorkspace { static id workspace; if(!workspace) workspace=[self new]; return workspace; }
19 - (NSArray *)runningApplications {
20 CUFixtureApplication *target=[CUFixtureApplication new], *front=[CUFixtureApplication new];
21 target.processIdentifier=123; target.localizedName=@"Fixture"; target.bundleIdentifier=@"test.fixture";
22 front.processIdentifier=999; front.localizedName=@"Other"; front.bundleIdentifier=@"test.other";
23 // Two running instances sharing one name and bundle (a second browser
24 // profile, an `open -n` copy): only a pid may choose between them.
25 CUFixtureApplication *twinA=[CUFixtureApplication new], *twinB=[CUFixtureApplication new];
26 twinA.processIdentifier=200; twinA.localizedName=@"Twin"; twinA.bundleIdentifier=@"test.twin";
27 twinB.processIdentifier=201; twinB.localizedName=@"Twin"; twinB.bundleIdentifier=@"test.twin";
28 return @[front,target,twinA,twinB];
29 }
30 - (NSRunningApplication *)frontmostApplication { return (NSRunningApplication *)self.runningApplications[0]; }
31 @end
32 #define NSWorkspace CUFixtureWorkspace
33 #import <ApplicationServices/ApplicationServices.h>
34 static int fixturePosts=0, fixtureActivations=0;
35 static void fixturePost(CGEventTapLocation location, CGEventRef event) { fixturePosts++; }
36 static AXError fixtureSet(AXUIElementRef element, CFStringRef name, CFTypeRef value) { fixtureActivations++; return kAXErrorSuccess; }
37 #define CGEventPost fixturePost
38 #define AXUIElementSetAttributeValue fixtureSet
39 #define AXIsProcessTrusted() true
40 #define CU_TEST 1
41 #define main unusedNativeMain
42 #include "../../src/backends/darwin-accessibility.m"
43 #undef main
44 #undef NSWorkspace
45
46 int main(int argc, const char *argv[]) { @autoreleasepool {
47 if(argc!=2) return 2;
48 NSDictionary *request=[NSJSONSerialization JSONObjectWithData:[[NSString stringWithUTF8String:argv[1]] dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
49 if([request[@"tool"] isEqual:@"inspect_pointer_guard"]) {
50 cuTestLockDir=request[@"args"][@"lock_dir"];
51 NSString *refusal=nil;
52 @try { execute(@{@"tool":@"pointer_sequence",@"args":@{@"foreground_input":@YES,@"input_app_ref":@{@"pid":@123},@"steps":@[@{@"type":@1,@"x":@10,@"y":@10,@"button":@0}]}}); }
53 @catch(NSException *error) { refusal=error.reason; }
54 cuPrint(@{@"refusal":refusal?:NSNull.null,@"posts":@(fixturePosts),@"activations":@(fixtureActivations)});
55 return 0;
56 }
57 if(![@[@"list_windows",@"get_app_state",@"resolve_element",@"window_info"] containsObject:request[@"tool"]]) return 2;
58 NSRunningApplication *app=nil;
59 @try { app=resolve(request[@"args"][@"app_ref"]); }
60 @catch(NSException *error) { fprintf(stderr,"%s\n",error.reason.UTF8String); return 1; }
61 if(!app) { fputs("application not found\n",stderr); return 1; }
62 NSDictionary *receipt=@{@"found":@YES,@"pid":@(app.processIdentifier),@"name":app.localizedName,@"bundle_id":app.bundleIdentifier,@"windows":@[],@"elements":@[]};
63 NSData *json=[NSJSONSerialization dataWithJSONObject:receipt options:0 error:nil];
64 fwrite(json.bytes,1,json.length,stdout); fputc('\n',stdout);
65 return 0;
66 } }
67
67 lines Plain Text