|
|
@@ -1,66 +1,19 @@
|
|
|
#include "common.h"
|
|
|
#include "automation.h"
|
|
|
+#include "AvnAutomationNode.h"
|
|
|
#include "AvnString.h"
|
|
|
#include "INSWindowHolder.h"
|
|
|
#include "AvnView.h"
|
|
|
-
|
|
|
-@interface AvnAccessibilityElement (Events)
|
|
|
-- (void) raiseChildrenChanged;
|
|
|
-@end
|
|
|
-
|
|
|
-@interface AvnRootAccessibilityElement : AvnAccessibilityElement
|
|
|
-- (AvnView *) ownerView;
|
|
|
-- (AvnRootAccessibilityElement *) initWithPeer:(IAvnAutomationPeer *) peer owner:(AvnView*) owner;
|
|
|
-- (void) raiseFocusChanged;
|
|
|
-@end
|
|
|
-
|
|
|
-class AutomationNode : public ComSingleObject<IAvnAutomationNode, &IID_IAvnAutomationNode>
|
|
|
-{
|
|
|
-public:
|
|
|
- FORWARD_IUNKNOWN()
|
|
|
-
|
|
|
- AutomationNode(AvnAccessibilityElement* owner)
|
|
|
- {
|
|
|
- _owner = owner;
|
|
|
- }
|
|
|
-
|
|
|
- AvnAccessibilityElement* GetOwner()
|
|
|
- {
|
|
|
- return _owner;
|
|
|
- }
|
|
|
-
|
|
|
- virtual void Dispose() override
|
|
|
- {
|
|
|
- _owner = nil;
|
|
|
- }
|
|
|
-
|
|
|
- virtual void ChildrenChanged () override
|
|
|
- {
|
|
|
- [_owner raiseChildrenChanged];
|
|
|
- }
|
|
|
-
|
|
|
- virtual void PropertyChanged (AvnAutomationProperty property) override
|
|
|
- {
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- virtual void FocusChanged () override
|
|
|
- {
|
|
|
- [(AvnRootAccessibilityElement*)_owner raiseFocusChanged];
|
|
|
- }
|
|
|
-
|
|
|
-private:
|
|
|
- __strong AvnAccessibilityElement* _owner;
|
|
|
-};
|
|
|
+#include "WindowInterfaces.h"
|
|
|
|
|
|
@implementation AvnAccessibilityElement
|
|
|
{
|
|
|
IAvnAutomationPeer* _peer;
|
|
|
- AutomationNode* _node;
|
|
|
+ AvnAutomationNode* _node;
|
|
|
NSMutableArray* _children;
|
|
|
}
|
|
|
|
|
|
-+ (AvnAccessibilityElement *)acquire:(IAvnAutomationPeer *)peer
|
|
|
++ (id _Nullable)acquire:(IAvnAutomationPeer *)peer
|
|
|
{
|
|
|
if (peer == nullptr)
|
|
|
return nil;
|
|
|
@@ -68,7 +21,7 @@ private:
|
|
|
auto instance = peer->GetNode();
|
|
|
|
|
|
if (instance != nullptr)
|
|
|
- return dynamic_cast<AutomationNode*>(instance)->GetOwner();
|
|
|
+ return dynamic_cast<AvnAutomationNode*>(instance)->GetOwner();
|
|
|
|
|
|
if (peer->IsRootProvider())
|
|
|
{
|
|
|
@@ -82,7 +35,7 @@ private:
|
|
|
|
|
|
auto holder = dynamic_cast<INSViewHolder*>(window);
|
|
|
auto view = holder->GetNSView();
|
|
|
- return [[AvnRootAccessibilityElement alloc] initWithPeer:peer owner:view];
|
|
|
+ return [view window];
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
@@ -94,7 +47,7 @@ private:
|
|
|
{
|
|
|
self = [super init];
|
|
|
_peer = peer;
|
|
|
- _node = new AutomationNode(self);
|
|
|
+ _node = new AvnAutomationNode(self);
|
|
|
_peer->SetNode(_node);
|
|
|
return self;
|
|
|
}
|
|
|
@@ -256,25 +209,8 @@ private:
|
|
|
|
|
|
- (NSRect)accessibilityFrame
|
|
|
{
|
|
|
- id topLevel = [self accessibilityTopLevelUIElement];
|
|
|
- auto result = NSZeroRect;
|
|
|
-
|
|
|
- if ([topLevel isKindOfClass:[AvnRootAccessibilityElement class]])
|
|
|
- {
|
|
|
- auto root = (AvnRootAccessibilityElement*)topLevel;
|
|
|
- auto view = [root ownerView];
|
|
|
-
|
|
|
- if (view)
|
|
|
- {
|
|
|
- auto window = [view window];
|
|
|
- auto bounds = ToNSRect(_peer->GetBoundingRectangle());
|
|
|
- auto windowBounds = [view convertRect:bounds toView:nil];
|
|
|
- auto screenBounds = [window convertRectToScreen:windowBounds];
|
|
|
- result = screenBounds;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return result;
|
|
|
+ auto bounds = _peer->GetBoundingRectangle();
|
|
|
+ return [self rectToScreen:bounds];
|
|
|
}
|
|
|
|
|
|
- (id)accessibilityParent
|
|
|
@@ -389,6 +325,24 @@ private:
|
|
|
return [super isAccessibilitySelectorAllowed:selector];
|
|
|
}
|
|
|
|
|
|
+- (NSRect)rectToScreen:(AvnRect)rect
|
|
|
+{
|
|
|
+ id topLevel = [self accessibilityTopLevelUIElement];
|
|
|
+
|
|
|
+ if (![topLevel isKindOfClass:[AvnWindow class]])
|
|
|
+ return NSZeroRect;
|
|
|
+
|
|
|
+ auto window = (AvnWindow*)topLevel;
|
|
|
+ auto view = [window view];
|
|
|
+
|
|
|
+ if (view == nil)
|
|
|
+ return NSZeroRect;
|
|
|
+
|
|
|
+ auto nsRect = ToNSRect(rect);
|
|
|
+ auto windowRect = [view convertRect:nsRect toView:nil];
|
|
|
+ return [window convertRectToScreen:windowRect];
|
|
|
+}
|
|
|
+
|
|
|
- (void)raiseChildrenChanged
|
|
|
{
|
|
|
auto changed = _children ? [NSMutableSet setWithArray:_children] : [NSMutableSet set];
|
|
|
@@ -429,7 +383,7 @@ private:
|
|
|
|
|
|
if (childPeers->Get(i, &child) == S_OK)
|
|
|
{
|
|
|
- auto element = [AvnAccessibilityElement acquire:child];
|
|
|
+ id element = [AvnAccessibilityElement acquire:child];
|
|
|
[_children addObject:element];
|
|
|
}
|
|
|
}
|
|
|
@@ -441,64 +395,3 @@ private:
|
|
|
}
|
|
|
|
|
|
@end
|
|
|
-
|
|
|
-@implementation AvnRootAccessibilityElement
|
|
|
-{
|
|
|
- AvnView* _owner;
|
|
|
-}
|
|
|
-
|
|
|
-- (AvnRootAccessibilityElement *)initWithPeer:(IAvnAutomationPeer *)peer owner:(AvnView *)owner
|
|
|
-{
|
|
|
- self = [super initWithPeer:peer];
|
|
|
- _owner = owner;
|
|
|
-
|
|
|
- // Seems we need to raise a focus changed notification here if we have focus
|
|
|
- auto focusedPeer = [self peer]->RootProvider_GetFocus();
|
|
|
- id focused = [AvnAccessibilityElement acquire:focusedPeer];
|
|
|
-
|
|
|
- if (focused)
|
|
|
- NSAccessibilityPostNotification(focused, NSAccessibilityFocusedUIElementChangedNotification);
|
|
|
-
|
|
|
- return self;
|
|
|
-}
|
|
|
-
|
|
|
-- (AvnView *)ownerView
|
|
|
-{
|
|
|
- return _owner;
|
|
|
-}
|
|
|
-
|
|
|
-- (id)accessibilityFocusedUIElement
|
|
|
-{
|
|
|
- auto focusedPeer = [self peer]->RootProvider_GetFocus();
|
|
|
- return [AvnAccessibilityElement acquire:focusedPeer];
|
|
|
-}
|
|
|
-
|
|
|
-- (id)accessibilityHitTest:(NSPoint)point
|
|
|
-{
|
|
|
- auto clientPoint = [[_owner window] convertPointFromScreen:point];
|
|
|
- auto localPoint = [_owner translateLocalPoint:ToAvnPoint(clientPoint)];
|
|
|
- auto hit = [self peer]->RootProvider_GetPeerFromPoint(localPoint);
|
|
|
- return [AvnAccessibilityElement acquire:hit];
|
|
|
-}
|
|
|
-
|
|
|
-- (id)accessibilityParent
|
|
|
-{
|
|
|
- return _owner;
|
|
|
-}
|
|
|
-
|
|
|
-- (void)raiseFocusChanged
|
|
|
-{
|
|
|
- id focused = [self accessibilityFocusedUIElement];
|
|
|
- NSAccessibilityPostNotification(focused, NSAccessibilityFocusedUIElementChangedNotification);
|
|
|
-}
|
|
|
-
|
|
|
-// Although this method is marked as deprecated we get runtime warnings if we don't handle it.
|
|
|
-#pragma clang diagnostic push
|
|
|
-#pragma clang diagnostic ignored "-Wdeprecated-implementations"
|
|
|
-- (void)accessibilityPerformAction:(NSAccessibilityActionName)action
|
|
|
-{
|
|
|
- [_owner accessibilityPerformAction:action];
|
|
|
-}
|
|
|
-#pragma clang diagnostic pop
|
|
|
-
|
|
|
-@end
|