views:

299

answers:

1

I want to set a certain window, from an external app (for example textedit), to be front most.

I can successfully get a reference to the app itself using GetFrontProcess, and check whether it is front most. If it is not, I can use setFrontProcess to make it focussed.

I can then use the the accessibility API to examine all the windows under that application. I am checking that a certain window exists, and if so I compare it against the front most window of the application:

//get the front window of textEditApp and store it in 'currentFrontWindow'
    AXUIElementCopyAttributeValue(textEditApp, kAXFocusedWindowAttribute, (CFTypeRef *)&currentFrontWindow);

If the window I am interested in is not frontmost, I need to set it so. I thought that I could use AXUIElement Set AttributeValue to do this but I am not getting any success. Below is how I have tried to do it.

//set the front window of textEditApp to be desiredFrontWindow
AXUIElementSetAttributeValue(textEditApp, kAXFocusedUIElementAttribute, desiredFrontWindow);

I have checked that the window exists, and the application is 'switched to' successfully. But why doesn't this line of code bring the specified window to the front?

Thanks.

+2  A: 

But why doesn't this line of code bring the specified window to the front?

Because you tried to set a read-only attribute.

In order to make a window frontmost, you need to set the appropriate property of the window. The same goes for an application: To make an application frontmost, you need to set the appropriate property of the application.

The Cocoa/Mac OS X name for the frontmost window is “the main window”. (See, for example, NSApplication's and NSWindow's methods relating to that concept.) Accessibility uses the same name, so to make a single window frontmost, set the value of its kAXMainAttribute to kCFBooleanTrue.

The way to make the application frontmost is similar: Set the value of its kAXFrontmostAttribute to kCFBooleanTrue. You'll need to do both of these to both set the frontmost window of the application and make the application active.

As far as I can tell, there is no way to bring only a single window of an application frontmost and give it session focus.

Peter Hosey
Thanks (once again) Peter - this works a charm.As for the application, I've been using setFrontProcess rather than kAXFrontMostAttribute - is this a bad idea?Having navigated my way through the application and window, there is a certain AXUIElementRef I am interested in bring to the front (ie giving it keyboard focus). I can bury down through the layers of elements to get a reference to it, but how do i set it in focus? Is there an equivalent of kAXMainAttribute for elements? Maybe I should post (yet) another Q.
Ben Packard