I am trying to automate a left mouse click in iTunes from Objective-C. I am doing the following.
first I am listening to iTunes events
[[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(allDistributedNotifications:) name:nil object:nil];
when the allDistributedNotifications is called I do the following:
- (void) allDistributedNotifications:(NSNotification *)note { NSString *object = [note object]; NSString *name = [note name]; NSDictionary *userInfo = [note userInfo]; NSLog(@"object: %@ name: %@ userInfo: %@",object, name, userInfo); if([object isEqualToString:@"com.apple.iTunes.dialog"]&& [userInfo objectForKey:@"Showing Dialog"] == 0){ NSLog(@"*** ended iTunes Dialogue"); } if([name isEqualToString:@"com.apple.iTunes.sourceSaved"]){ NSLog(@"*** iTunes saved to file"); currentURLIndex +=1; [self loadWithData:[itmsURLs objectAtIndex:currentURLIndex] fromBot:YES]; } }
LoadWithData looks like this
-(void) loadWithData:(NSURL*) url fromBot:(BOOL)aBot { BOOL success; success = [[NSWorkspace sharedWorkspace] openURLs:[NSArray arrayWithObject:url] withAppBundleIdentifier:@"com.apple.itunes" options:NSWorkspaceLaunchDefault additionalEventParamDescriptor:nil launchIdentifiers:nil]; if(success){ [numAppsDownloaded setStringValue:[NSString stringWithFormat: @"%lu",currentURLIndex+1]]; } if(success && aBot){ [self performSelector:@selector(clickDownload) withObject:nil afterDelay:0.5]; } }
clickdownload in turn looks like this
-(void) clickDownload { NSPoint mouseLoc; mouseLoc = [NSEvent mouseLocation]; //get current mouse position CGPoint point = CGPointMake(mouseLoc.x, mouseLoc.y); CGEventRef theEvent; CGEventType type; CGMouseButton button = kCGMouseButtonLeft; type = kCGEventLeftMouseDown; // kCGEventLeftMouseDown = NX_LMOUSEDOWN, theEvent = CGEventCreateMouseEvent(NULL,type, point, button); NSEvent* downEvent = [NSEvent eventWithCGEvent:theEvent]; [self forwardEvent:downEvent]; [NSThread sleepForTimeInterval:0.2]; type = kCGEventLeftMouseUp; theEvent = CGEventCreateMouseEvent(NULL,type, point, button); NSEvent* upEvent = [NSEvent eventWithCGEvent:theEvent]; [self forwardEvent:upEvent]; }
5.Finally, forwardEvent looks like this
- (void)forwardEvent: (NSEvent *)event { NSLog(@"event: %@",event); pid_t PID; NSInteger WID; // get the iTunes Window ID NSArray* windows = (NSArray*)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID); NSEnumerator* windowEnumerator = [windows objectEnumerator]; while( (window = [windowEnumerator nextObject] ) ) { if([[(NSDictionary*) window objectForKey:@"kCGWindowName"] isEqualToString:@"iTunes"]) WID = (NSInteger)[(NSDictionary*) window objectForKey:@"kCGWindowNumber"]; } ProcessSerialNumber psn; CGEventRef CGEvent; NSEvent *customEvent; NSPoint mouseLoc = [NSEvent mouseLocation]; //get current mouse position NSPoint clickpoint = CGPointMake(mouseLoc.x, mouseLoc.y); customEvent = [NSEvent mouseEventWithType: [event type] location: clickpoint modifierFlags: [event modifierFlags] | NSCommandKeyMask timestamp: [event timestamp] windowNumber: WID context: nil eventNumber: 0 clickCount: 1 pressure: 0]; CGEvent = [customEvent CGEvent]; // get the iTunes PID NSRunningApplication* app; NSArray* runningApps = [[NSWorkspace sharedWorkspace] runningApplications]; NSEnumerator* appEnumerator = [runningApps objectEnumerator]; while ((app = [appEnumerator nextObject])) { if ([[app bundleIdentifier] isEqualToString:@"com.apple.iTunes"]) PID = [app processIdentifier]; } NSLog(@"found iTunes: %d %@",(int)PID,WID); NSAssert(GetProcessForPID(PID, &psn) == noErr, @"GetProcessForPID failed!"); CGEventPostToPSN(&psn, CGEvent); }
The problem is that I cannot see the mouse click being performed.