Bring any window to the front
March 4, 2008 – 18:39 Share on TwitterA question was asked on the apple dev mailing list on how to bring a window with a certain name to the front.
Since I was already working on how to get the list of windows on the screen, I just added some AppleScript to bring the window to the front.
This snippet doesnt use any undocumented techniques, it uses the CGWindow API introduced in Leopard.
I dont consider this code to be production ready, but it works.
Of course, TIMTOWTDI
See the code after the jump:
- (BOOL) bringWindowWithNameToFront:(NSString *) windowName
{
// Try to find a window named "windowName", and if found,
// bring it to the front
// Stephan Burlot 4/3/08
CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
ProcessSerialNumber myPSN = {kNoProcess, kNoProcess};
BOOL returnValue = FALSE;
for (NSMutableDictionary *entry in (NSArray *)windowList) {
NSString *currentWindow = [entry objectForKey:(id)kCGWindowName];
if ((currentWindow != NULL) && ([currentWindow isEqualToString:windowName]))
{
NSString *applicationName = [entry objectForKey:(id)kCGWindowOwnerName];
int pid = [[entry objectForKey:(id)kCGWindowOwnerPID] intValue];
GetProcessForPID(pid, &myPSN);
NSString *script= [NSString stringWithFormat:@"tell application \"System Events\" to tell process \"%@\" to perform action \"AXRaise\" of window \"%@\"\ntell application \"%@\" to activate\n", applicationName, windowName, applicationName];
NSAppleScript *as = [[NSAppleScript alloc] initWithSource:script];
[as compileAndReturnError:NULL];
[as executeAndReturnError:NULL]; // Bring it on!
[as release];
returnValue = TRUE;
}
}
CFRelease(windowList);
return returnValue;
}
Inspiration camed from the following codes:
2 Responses to “Bring any window to the front”
Thanks for the example, this is almost exactly what I’m looking for.
Do you know of a way to tell the application to bring *just* the specified window to the foreground when it activates?
I have a whole bunch of iTerm windows, and I’d like to be able to tell a specific one to raise and focus, without bringing *all* of them to the front.
The other dilemma that I have is that the window name for many of my iTerm sessions is “Default”. Is there any way to use a window number instead of the window name?
The right solution is probably for me to change how I use iTerm. But old habits die hard.
By ryan on Dec 8, 2008
Answered my own question. Get rid of the ‘tell application “foo” to raise” and instead do:
SetFrontProcessWithOptions(&psn, kSetFrontProcessFrontWindowOnly);
after the AXRaise AppleScript stuff.
By ryan on Dec 8, 2008