Skip to content
This repository has been archived by the owner on May 19, 2018. It is now read-only.

Commit

Permalink
Merge pull request #5 from numist/merge-okocsis
Browse files Browse the repository at this point in the history
Merge changes from okocsis:develop to master.
  • Loading branch information
numist committed Mar 7, 2015
2 parents cbfc622 + 9a216b4 commit 4d2d3eb
Show file tree
Hide file tree
Showing 16 changed files with 362 additions and 88 deletions.
6 changes: 2 additions & 4 deletions Classes/HAXApplication.h
Expand Up @@ -10,11 +10,9 @@

@property (nonatomic, readonly) HAXWindow *focusedWindow;
@property (nonatomic, readonly) NSArray *windows;

+(instancetype)applicationWithPID:(pid_t)pid;

@property (nonatomic, copy, readonly) NSString *localizedName;

@property (nonatomic, readonly) pid_t processIdentifier;

+(instancetype)applicationWithPID:(pid_t)pid;

@end
11 changes: 4 additions & 7 deletions Classes/HAXApplication.m
Expand Up @@ -8,7 +8,7 @@

@implementation HAXApplication

+(instancetype)applicationWithPID:(pid_t)pid; {
+(instancetype)applicationWithPID:(pid_t)pid {
AXUIElementRef app = AXUIElementCreateApplication(pid);
id result = nil;
if (app) {
Expand All @@ -19,25 +19,22 @@ +(instancetype)applicationWithPID:(pid_t)pid; {
}

-(HAXWindow *)focusedWindow {
NSError *error = nil;
return [self elementOfClass:[HAXWindow class] forKey:(NSString *)kAXFocusedWindowAttribute error:&error];
return [self elementOfClass:[HAXWindow class] forKey:(NSString *)kAXFocusedWindowAttribute error:NULL];
}

-(NSArray *)windows {
NSArray *axWindowObjects = CFBridgingRelease([self copyAttributeValueForKey:(NSString *)kAXWindowsAttribute error:nil]);
NSArray *axWindowObjects = [self getAttributeValueForKey:(NSString *)kAXWindowsAttribute error:NULL];
NSMutableArray *result = [NSMutableArray arrayWithCapacity:[axWindowObjects count]];
for (id axObject in axWindowObjects) {
[result addObject:[HAXWindow elementWithElementRef:(AXUIElementRef)axObject]];
}
return result;
}


-(NSString *)localizedName {
return [self copyAttributeValueForKey:(NSString *)kAXTitleAttribute error:NULL];
return [self getAttributeValueForKey:(NSString *)kAXTitleAttribute error:NULL];
}


-(pid_t)processIdentifier {
pid_t processIdentifier = 0;
AXUIElementGetPid(self.elementRef, &processIdentifier);
Expand Down
11 changes: 11 additions & 0 deletions Classes/HAXButton.h
@@ -0,0 +1,11 @@
// HAXButton.h
// Created by Kocsis Olivér on 2014-05-21
// Copyright 2014 Joinect Technologies

#import <HAXcessibility/HAXView.h>

@interface HAXButton : HAXView

-(void)press;

@end
14 changes: 14 additions & 0 deletions Classes/HAXButton.m
@@ -0,0 +1,14 @@
// HAXButton.m
// Created by Kocsis Olivér on 2014-05-21
// Copyright 2014 Joinect Technologies

#import "HAXButton.h"
#import "HAXElement+Protected.h"

@implementation HAXButton

-(void)press {
[self performAction:(__bridge NSString *)kAXPressAction error:NULL];
}

@end
5 changes: 3 additions & 2 deletions Classes/HAXElement+Protected.h
Expand Up @@ -11,9 +11,10 @@

@property (nonatomic, readonly) AXUIElementRef elementRef __attribute__((NSObject));

-(id)getAttributeValueForKey:(NSString *)key error:(NSError **)error __attribute__((nonnull(1)));
-(CFTypeRef)copyAttributeValueForKey:(NSString *)key error:(NSError **)error __attribute__((nonnull(1)));
-(bool)setAttributeValue:(CFTypeRef)value forKey:(NSString *)key error:(NSError **)error __attribute__((nonnull(1,2)));
-(bool)performAction:(NSString *)action error:(NSError **)error __attribute__((nonnull(1)));
-(BOOL)setAttributeValue:(CFTypeRef)value forKey:(NSString *)key error:(NSError **)error __attribute__((nonnull(1,2)));
-(BOOL)performAction:(NSString *)action error:(NSError **)error __attribute__((nonnull(1)));

-(id)elementOfClass:(Class)klass forKey:(NSString *)key error:(NSError **)error __attribute__((nonnull(1,2)));

Expand Down
8 changes: 7 additions & 1 deletion Classes/HAXElement.h
Expand Up @@ -9,8 +9,14 @@
@interface HAXElement : NSObject

@property (nonatomic, weak) id<HAXElementDelegate> delegate;
@property (nonatomic, readonly) NSString *title;
@property (nonatomic, readonly) NSString *role;
@property (nonatomic, readonly) BOOL hasChildren;
@property (nonatomic, readonly) NSArray *children;
@property (nonatomic, readonly) NSArray *attributeNames;
@property (nonatomic, readonly) NSArray *buttons;

-(bool)isEqualToElement:(HAXElement *)other;
-(BOOL)isEqualToElement:(HAXElement *)other;

@end

Expand Down
84 changes: 74 additions & 10 deletions Classes/HAXElement.m
Expand Up @@ -3,15 +3,17 @@
// Copyright 2011 Rob Rix

#import "HAXElement+Protected.h"
#import "HAXButton.h"


@interface HAXElement ()

@property (nonatomic, strong) AXObserverRef observer __attribute__((NSObject));
@end

@implementation HAXElement
@end

@synthesize elementRef = _elementRef;

@implementation HAXElement

+(instancetype)elementWithElementRef:(AXUIElementRef)elementRef {
return [[self alloc] initWithElementRef:elementRef];
Expand All @@ -34,8 +36,7 @@ -(void)dealloc {
}
}


-(bool)isEqualToElement:(HAXElement *)other {
-(BOOL)isEqualToElement:(HAXElement *)other {
return
[other isKindOfClass:self.class]
&& CFEqual(self.elementRef, other.elementRef);
Expand All @@ -49,15 +50,17 @@ -(NSUInteger)hash {
return CFHash(self.elementRef);
}


- (void)setDelegate:(id<HAXElementDelegate>)delegate;
{
-(void)setDelegate:(id<HAXElementDelegate>)delegate {
if (delegate && !_observer) {
[self addAXObserver];
}
_delegate = delegate;
}

-(id)getAttributeValueForKey:(NSString *)key error:(NSError **)error {
CFTypeRef result = [self copyAttributeValueForKey:key error:error];
return result ? CFBridgingRelease(result) : nil;
}

-(CFTypeRef)copyAttributeValueForKey:(NSString *)key error:(NSError **)error {
NSParameterAssert(key != nil);
Expand All @@ -72,7 +75,7 @@ -(CFTypeRef)copyAttributeValueForKey:(NSString *)key error:(NSError **)error {
return attributeRef;
}

-(bool)setAttributeValue:(CFTypeRef)value forKey:(NSString *)key error:(NSError **)error {
-(BOOL)setAttributeValue:(CFTypeRef)value forKey:(NSString *)key error:(NSError **)error {
NSParameterAssert(value != nil);
NSParameterAssert(key != nil);
AXError result = AXUIElementSetAttributeValue(self.elementRef, (__bridge CFStringRef)key, value);
Expand All @@ -85,7 +88,7 @@ -(bool)setAttributeValue:(CFTypeRef)value forKey:(NSString *)key error:(NSError
return result == kAXErrorSuccess;
}

-(bool)performAction:(NSString *)action error:(NSError **)error {
-(BOOL)performAction:(NSString *)action error:(NSError **)error {
NSParameterAssert(action != nil);
AXError result = AXUIElementPerformAction(self.elementRef, (__bridge CFStringRef)action);
if ((result != kAXErrorSuccess) && error) {
Expand Down Expand Up @@ -162,4 +165,65 @@ -(void)removeAXObserver {
self.observer = NULL;
}

-(BOOL)hasChildren {
return (self.children.count > 0);
}

-(NSArray *)children {
NSArray * axUIElements = nil;
NSMutableArray * result = nil;

axUIElements = [self getAttributeValueForKey:(__bridge NSString *)kAXChildrenAttribute error:NULL];
if (axUIElements != nil) {
result = [NSMutableArray arrayWithCapacity:[axUIElements count]];
for (id elementI in axUIElements) {
[result addObject:[HAXElement elementWithElementRef:(AXUIElementRef)(elementI)]];
}
}

return result;
}

-(NSString *)role {
NSString * result = [self getAttributeValueForKey:(__bridge NSString *)kAXRoleAttribute error:NULL];
if ([result isKindOfClass:[NSString class]] == NO) {
result = nil;
}
return result;
}

-(NSArray *) buttons {
NSArray *axChildren = self.children;
NSMutableArray *result = [NSMutableArray array];

NSString * axRole;
for (HAXElement *haxElementI in axChildren) {
axRole = CFBridgingRelease([haxElementI copyAttributeValueForKey:(__bridge NSString *)kAXRoleAttribute error:NULL]);
if (axRole == nil) {
result = nil;
break;
}
if ([axRole isEqualToString:(__bridge NSString *)kAXButtonRole]) {
HAXButton *button = [HAXButton elementWithElementRef:(AXUIElementRef)haxElementI.elementRef];
[result addObject:button];
}
}

return result;
}

-(NSString *)title {
NSString * result = [self getAttributeValueForKey:NSAccessibilityTitleAttribute error:NULL];
if ([result isKindOfClass:[NSString class]] == NO) {
result = nil;
}
return result;
}

-(NSArray *)attributeNames {
CFArrayRef attrNamesRef = NULL;
AXUIElementCopyAttributeNames(_elementRef, &attrNamesRef);
return attrNamesRef ? CFBridgingRelease(attrNamesRef) : nil;
}

@end
3 changes: 1 addition & 2 deletions Classes/HAXSystem.m
Expand Up @@ -17,8 +17,7 @@ +(instancetype)system {


-(HAXApplication *)focusedApplication {
NSError *error = nil;
return [self elementOfClass:[HAXApplication class] forKey:(NSString *)kAXFocusedApplicationAttribute error:&error];
return [self elementOfClass:[HAXApplication class] forKey:(NSString *)kAXFocusedApplicationAttribute error:NULL];
}

@end
19 changes: 19 additions & 0 deletions Classes/HAXView.h
@@ -0,0 +1,19 @@
// HAXView.h
// Created by Kocsis Olivér on 2014-05-12
// Copyright 2014 Joinect Technologies

#import <Cocoa/Cocoa.h>
#import <Haxcessibility/HAXElement.h>

@interface HAXView : HAXElement

@property (nonatomic, assign) CGPoint carbonOrigin;
@property (nonatomic, assign, readonly) NSPoint origin;
@property (nonatomic, assign) NSSize size;
@property (nonatomic, assign) CGRect carbonFrame;
@property (nonatomic, assign, readonly) NSRect frame;
@property (nonatomic, readonly) NSString *title;
@property (nonatomic, readonly) NSScreen *screen;
@property (nonatomic, readonly, getter=isFullscreen) BOOL fullscreen;

@end
98 changes: 98 additions & 0 deletions Classes/HAXView.m
@@ -0,0 +1,98 @@
// HAXView.m
// Created by Kocsis Olivér on 2014-05-12
// Copyright 2014 Joinect Technologies

#import "HAXView.h"
#import "HAXElement+Protected.h"
#import "NSScreen+HAXPointConvert.h"

@implementation HAXView

-(CGPoint)carbonOrigin {
CGPoint origin = {0};
AXValueRef originRef = (AXValueRef)[self copyAttributeValueForKey:(__bridge NSString *)kAXPositionAttribute error:NULL];
if(originRef) {
AXValueGetValue(originRef, kAXValueCGPointType, &origin);
CFRelease(originRef);
originRef = NULL;
}
return origin;
}

-(void)setCarbonOrigin:(CGPoint)carbonOrigin {
AXValueRef originRef = AXValueCreate(kAXValueCGPointType, &carbonOrigin);
[self setAttributeValue:originRef forKey:(__bridge NSString *)kAXPositionAttribute error:NULL];
CFRelease(originRef);
}

-(NSPoint)origin {
return [NSScreen hax_cocoaScreenFrameFromCarbonScreenFrame:self.carbonFrame].origin;
}

-(NSSize)size {
CGSize size = {0};
AXValueRef sizeRef = (AXValueRef)[self copyAttributeValueForKey:(__bridge NSString *)kAXSizeAttribute error:NULL];
if(sizeRef) {
AXValueGetValue(sizeRef, kAXValueCGSizeType, &size);
CFRelease(sizeRef);
sizeRef = NULL;
}
return size;
}

-(void)setSize:(NSSize)size {
AXValueRef sizeRef = AXValueCreate(kAXValueCGSizeType, &size);
[self setAttributeValue:sizeRef forKey:(__bridge NSString *)kAXSizeAttribute error:NULL];
CFRelease(sizeRef);
}

-(CGRect)carbonFrame {
return (CGRect){ .origin = self.carbonOrigin, .size = self.size };
}

-(void)setCarbonFrame:(CGRect)carbonFrame {
self.carbonOrigin = carbonFrame.origin;
self.size = carbonFrame.size;
}

-(NSRect)frame {
return [NSScreen hax_cocoaScreenFrameFromCarbonScreenFrame:self.carbonFrame];
}

-(NSString *)title {
return [self getAttributeValueForKey:(__bridge NSString *)kAXTitleAttribute error:NULL];
}

-(NSScreen *)screen {
NSScreen *matchingScreen = nil;
NSRect viewFrame = self.frame;
NSUInteger bestOverlap = 0;
for (NSScreen * screenI in [NSScreen screens]) {
NSRect intersection = NSIntersectionRect(screenI.frame, viewFrame);
NSUInteger intersectionOverlap = intersection.size.width * intersection.size.height;
if(intersectionOverlap > bestOverlap) {
matchingScreen = screenI;
bestOverlap = intersectionOverlap;
}
}
return matchingScreen;
}

-(BOOL)isFullscreen {
BOOL isFullScreen = NO;
NSArray * sceenArray = [NSScreen screens];
NSRect windowFrame = self.frame;

for (NSScreen * screenI in sceenArray) {
NSRect screenFrame;
screenFrame = [screenI frame];
if(NSEqualRects(screenFrame, windowFrame)) {
isFullScreen = YES;
break;
}
}

return isFullScreen;
}

@end
15 changes: 6 additions & 9 deletions Classes/HAXWindow.h
Expand Up @@ -2,17 +2,14 @@
// Created by Rob Rix on 2011-01-06
// Copyright 2011 Rob Rix

#import <Haxcessibility/HAXElement.h>
#import <Cocoa/Cocoa.h>
#import <Haxcessibility/HAXView.h>

@interface HAXWindow : HAXElement
@interface HAXWindow : HAXView

@property (nonatomic, assign) CGPoint origin;
@property (nonatomic, assign) CGSize size;
@property (nonatomic, assign) CGRect frame;
@property (nonatomic, readonly) NSArray *views;

@property (nonatomic, readonly) NSString *title;

-(bool)raise;
-(bool)close;
-(BOOL)raise;
-(BOOL)close;

@end

0 comments on commit 4d2d3eb

Please sign in to comment.