In the previous two posts, we looked at how to retrieve a window that had focus and how to open a system preference pane. To recap, check out the previous two posts here and here. In this post, we will look how to retrieve certain properties of the window that we retrieve using the Accessibility API. We will look at how to modify the window’s position and size so that the window will occupy the left half of the screen.
Pre-Requisites
- Know how to retrieve the focused window. To recap, check out the previous post.
- Should have checked “Enable access for assitive devices” in the Universal Access preference pane
Implementation
First, we will look at how to retrieve the window’s properties. In this example, we will look at how to retrieve the window’s position and size. To make it easier to modify these properties, we create a few variables to temporarily store the properties.
AXUIElementRef _systemWideElement;
AXUIElementRef _focusedApp;
CFTypeRef _focusedWindow;
CFTypeRef _position;
CFTypeRef _size;
I have assumed that you have already initialized the _systemWideElement. If not, you can use the following line to do so.
_systemWideElement = AXUIElementCreateSystemWide();
Then, we are going to use this AXUiElement to first retrieve the app that focus. Then we will retrieve the window that has focus. After which, we can get its properties by using the following method:
extern AXError AXUIElementCopyAttributeValue (
AXUIElementRef element,
CFStringRef attribute,
CFTypeRef *value);
Parameters:
- element – It is the system wide element
- attribute – For this example, the attribute will be size(NSAccessibilitySizeAttribute) and position(NSAccessibilityPositionAttribute). There are a lot more attributes that you can get. Go here for other properties.
- value. This is where the value of the attribute will be copied to.
Lets look at how this method can be used.
//Get the app that has the focus
AXUIElementCopyAttributeValue(_systemWideElement,
(CFStringRef)kAXFocusedApplicationAttribute,
(CFTypeRef*)&_focusedApp);
//Get the window that has the focus
if(AXUIElementCopyAttributeValue((AXUIElementRef)_focusedApp,
(CFStringRef)NSAccessibilityFocusedWindowAttribute,
(CFTypeRef*)&_focusedWindow) == kAXErrorSuccess) {
if(CFGetTypeID(_focusedWindow) == AXUIElementGetTypeID()) {
//Get the Window's Current Position
if(AXUIElementCopyAttributeValue((AXUIElementRef)_focusedWindow,
(CFStringRef)NSAccessibilityPositionAttribute,
(CFTypeRef*)&_position) != kAXErrorSuccess) {
NSLog(@"Can't Retrieve Window Position");
}
//Get the Window's Current Size
if(AXUIElementCopyAttributeValue((AXUIElementRef)_focusedWindow,
(CFStringRef)NSAccessibilitySizeAttribute,
(CFTypeRef*)&_size) != kAXErrorSuccess) {
NSLog(@"Can't Retrieve Window Size");
}
}
}else {
NSLog(@"Problem with App");
}
Now that we have retrieved the position and size of the window, we will look at how to modify these properties. In the following example, we are trying to move the window to the (0,0) coordinate and fill left half of the screen. To set a property, we will use the following method,
extern AXError AXUIElementSetAttributeValue (
AXUIElementRef element,
CFStringRef attribute,
CFTypeRef value);
The parameters are the same as the AXUIElementCopyAttributeValue method.
NSPoint thePoint;
thePoint.x = 0;
thePoint.y = 0;
//convert the NSPoint to CFTypeRef
_position = (CFTypeRef)(AXValueCreate(kAXValueCGPointType, (const void *)&thePoint));
if(AXUIElementSetAttributeValue((AXUIElementRef)_focusedWindow,
(CFStringRef)NSAccessibilityPositionAttribute,
(CFTypeRef*)_position) != kAXErrorSuccess){
NSLog(@"Position cannot be changed");
}
NSSize theSize;
NSSize _fullScreenSize = [[[NSScreen mainScreen] frame] size];
if(AXValueGetType(_size) == kAXValueCGSizeType) {
theSize.width = ((_fullScreenSize.width)/2);
theSize.height = _fullScreenSize.height;
// convert from NSSize to CFTypeRef
_size = (CFTypeRef)(AXValueCreate(kAXValueCGSizeType, (const void *)&theSize));
}
if(AXUIElementSetAttributeValue((AXUIElementRef)_focusedWindow,
(CFStringRef)NSAccessibilitySizeAttribute,
(CFTypeRef*)_size) != kAXErrorSuccess){
NSLog(@"Size cannot be modified");
}
There we go! That should do it.
