From f76622688f860de7f59174f1d3c9c683570670b9 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Sun, 2 Oct 2022 23:58:56 -0700 Subject: [PATCH 01/10] Impl1 --- shell/platform/common/accessibility_bridge.cc | 10 ++- shell/platform/common/accessibility_bridge.h | 10 ++- .../Source/AccessibilityBridgeMacDelegate.h | 4 +- .../Source/AccessibilityBridgeMacDelegate.mm | 27 +++---- .../AccessibilityBridgeMacDelegateTest.mm | 40 ++++++---- .../macos/framework/Source/FlutterEngine.mm | 10 ++- .../Source/FlutterPlatformNodeDelegateMac.h | 7 +- .../Source/FlutterPlatformNodeDelegateMac.mm | 29 +++----- .../Source/FlutterTextInputPluginTest.mm | 4 +- .../FlutterTextInputSemanticsObjectTest.mm | 2 +- .../framework/Source/FlutterWindowPlugin.h | 17 +++++ .../framework/Source/FlutterWindowPlugin.mm | 74 +++++++++++++++++++ .../accessibility_bridge_delegate_windows.cc | 11 ++- .../accessibility_bridge_delegate_windows.h | 5 +- .../flutter_platform_node_delegate_windows.cc | 20 ++--- .../flutter_platform_node_delegate_windows.h | 5 +- 16 files changed, 194 insertions(+), 81 deletions(-) create mode 100644 shell/platform/darwin/macos/framework/Source/FlutterWindowPlugin.h create mode 100644 shell/platform/darwin/macos/framework/Source/FlutterWindowPlugin.mm diff --git a/shell/platform/common/accessibility_bridge.cc b/shell/platform/common/accessibility_bridge.cc index d0f19089dd86f..b382a8d50f4f0 100644 --- a/shell/platform/common/accessibility_bridge.cc +++ b/shell/platform/common/accessibility_bridge.cc @@ -19,13 +19,17 @@ constexpr int kHasScrollingAction = FlutterSemanticsAction::kFlutterSemanticsActionScrollDown; // AccessibilityBridge -AccessibilityBridge::AccessibilityBridge( - std::unique_ptr delegate) - : delegate_(std::move(delegate)) { +AccessibilityBridge::AccessibilityBridge() { event_generator_.SetTree(&tree_); tree_.AddObserver(static_cast(this)); } +AccessibilityBridge::AccessibilityBridge( + std::unique_ptr delegate) + : AccessibilityBridge() { + UpdateDelegate(std::move(delegate)); +} + AccessibilityBridge::~AccessibilityBridge() { event_generator_.ReleaseTree(); tree_.RemoveObserver(static_cast(this)); diff --git a/shell/platform/common/accessibility_bridge.h b/shell/platform/common/accessibility_bridge.h index 70fcd20c3d2f7..ad455fe6f1ceb 100644 --- a/shell/platform/common/accessibility_bridge.h +++ b/shell/platform/common/accessibility_bridge.h @@ -63,6 +63,7 @@ class AccessibilityBridge class AccessibilityBridgeDelegate { public: virtual ~AccessibilityBridgeDelegate() = default; + //--------------------------------------------------------------------------- /// @brief Handle accessibility events generated due to accessibility /// tree changes. These events are generated in accessibility @@ -104,9 +105,12 @@ class AccessibilityBridge //----------------------------------------------------------------------------- /// @brief Creates a new instance of a accessibility bridge. /// - /// @param[in] user_data A custom pointer to the data of your - /// choice. This pointer can be retrieve later - /// through GetUserData(). + /// The bridge is not ready for use until a delegate has been + /// assigned. See AccessibilityBridge::UpdateDelegate. + AccessibilityBridge(); + + //----------------------------------------------------------------------------- + /// @brief Creates a new instance of a accessibility bridge. explicit AccessibilityBridge( std::unique_ptr delegate); ~AccessibilityBridge(); diff --git a/shell/platform/darwin/macos/framework/Source/AccessibilityBridgeMacDelegate.h b/shell/platform/darwin/macos/framework/Source/AccessibilityBridgeMacDelegate.h index 772234b5b606c..7bd7dff056ac2 100644 --- a/shell/platform/darwin/macos/framework/Source/AccessibilityBridgeMacDelegate.h +++ b/shell/platform/darwin/macos/framework/Source/AccessibilityBridgeMacDelegate.h @@ -24,7 +24,8 @@ class AccessibilityBridgeMacDelegate : public AccessibilityBridge::Accessibility /// @param[in] flutter_engine The weak reference to the FlutterEngine. /// @param[in] view_controller The weak reference to the FlutterViewController. explicit AccessibilityBridgeMacDelegate(__weak FlutterEngine* flutter_engine, - __weak FlutterViewController* view_controller); + __weak FlutterViewController* view_controller, + std::weak_ptr bridge); virtual ~AccessibilityBridgeMacDelegate() = default; // |AccessibilityBridge::AccessibilityBridgeDelegate| @@ -80,6 +81,7 @@ class AccessibilityBridgeMacDelegate : public AccessibilityBridge::Accessibility __weak FlutterEngine* flutter_engine_; __weak FlutterViewController* view_controller_; + std::weak_ptr accessibility_bridge_; }; } // namespace flutter diff --git a/shell/platform/darwin/macos/framework/Source/AccessibilityBridgeMacDelegate.mm b/shell/platform/darwin/macos/framework/Source/AccessibilityBridgeMacDelegate.mm index 21917a72ed1dd..b32bfc55a2918 100644 --- a/shell/platform/darwin/macos/framework/Source/AccessibilityBridgeMacDelegate.mm +++ b/shell/platform/darwin/macos/framework/Source/AccessibilityBridgeMacDelegate.mm @@ -22,12 +22,15 @@ AccessibilityBridgeMacDelegate::AccessibilityBridgeMacDelegate( __weak FlutterEngine* flutter_engine, - __weak FlutterViewController* view_controller) - : flutter_engine_(flutter_engine), view_controller_(view_controller) {} + __weak FlutterViewController* view_controller, + std::weak_ptr bridge) + : flutter_engine_(flutter_engine), + view_controller_(view_controller), + accessibility_bridge_(bridge) {} void AccessibilityBridgeMacDelegate::OnAccessibilityEvent( ui::AXEventGenerator::TargetedEvent targeted_event) { - if (!flutter_engine_.viewController.viewLoaded || !flutter_engine_.viewController.view.window) { + if (!view_controller_.viewLoaded || !view_controller_.view.window) { // Don't need to send accessibility events if the there is no view or window. return; } @@ -47,9 +50,8 @@ AccessibilityBridgeMacDelegate::MacOSEventsFromAXEvent(ui::AXEventGenerator::Event event_type, const ui::AXNode& ax_node) const { // Gets the native_node with the node_id. - NSCAssert(flutter_engine_, @"Flutter engine should not be deallocated"); - auto bridge = flutter_engine_.accessibilityBridge.lock(); - NSCAssert(bridge, @"Accessibility bridge in flutter engine must not be null."); + auto bridge = accessibility_bridge_.lock(); + NSCAssert(bridge, @"Accessibility bridge should not be expired"); auto platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(ax_node.id()).lock(); NSCAssert(platform_node_delegate, @"Event target must exist in accessibility bridge."); auto mac_platform_node_delegate = @@ -292,10 +294,10 @@ case ui::AXEventGenerator::Event::CHILDREN_CHANGED: { // NSAccessibilityCreatedNotification seems to be the only way to let // Voiceover pick up layout changes. - NSCAssert(flutter_engine_.viewController, @"The viewController must not be nil"); + NSCAssert(view_controller_, @"The viewController must not be nil"); events.push_back({ .name = NSAccessibilityCreatedNotification, - .target = flutter_engine_.viewController.view.window, + .target = view_controller_.view.window, .user_info = nil, }); break; @@ -363,7 +365,7 @@ FlutterSemanticsAction action, fml::MallocMapping data) { NSCAssert(flutter_engine_, @"Flutter engine should not be deallocated"); - NSCAssert(flutter_engine_.viewController.viewLoaded && flutter_engine_.viewController.view.window, + NSCAssert(view_controller_.viewLoaded && view_controller_.view.window, @"The accessibility bridge should not receive accessibility actions if the flutter view" @"is not loaded or attached to a NSWindow."); [flutter_engine_ dispatchSemanticsAction:action toTarget:target withData:std::move(data)]; @@ -371,7 +373,7 @@ std::shared_ptr AccessibilityBridgeMacDelegate::CreateFlutterPlatformNodeDelegate() { - return std::make_shared(flutter_engine_, view_controller_); + return std::make_shared(view_controller_, accessibility_bridge_); } // Private method @@ -394,9 +396,8 @@ } bool AccessibilityBridgeMacDelegate::HasPendingEvent(ui::AXEventGenerator::Event event) const { - NSCAssert(flutter_engine_, @"Flutter engine should not be deallocated"); - auto bridge = flutter_engine_.accessibilityBridge.lock(); - NSCAssert(bridge, @"Accessibility bridge in flutter engine must not be null."); + auto bridge = accessibility_bridge_.lock(); + NSCAssert(bridge, @"Accessibility bridge should not be expired"); std::vector pending_events = bridge->GetPendingEvents(); for (const auto& pending_event : bridge->GetPendingEvents()) { if (pending_event.event_params.event == event) { diff --git a/shell/platform/darwin/macos/framework/Source/AccessibilityBridgeMacDelegateTest.mm b/shell/platform/darwin/macos/framework/Source/AccessibilityBridgeMacDelegateTest.mm index 5f4a6d6a8d125..a70ebd76eec75 100644 --- a/shell/platform/darwin/macos/framework/Source/AccessibilityBridgeMacDelegateTest.mm +++ b/shell/platform/darwin/macos/framework/Source/AccessibilityBridgeMacDelegateTest.mm @@ -14,8 +14,9 @@ class AccessibilityBridgeMacDelegateSpy : public AccessibilityBridgeMacDelegate { public: AccessibilityBridgeMacDelegateSpy(__weak FlutterEngine* flutter_engine, - __weak FlutterViewController* view_controller) - : AccessibilityBridgeMacDelegate(flutter_engine, view_controller) {} + __weak FlutterViewController* view_controller, + std::weak_ptr bridge) + : AccessibilityBridgeMacDelegate(flutter_engine, view_controller, bridge) {} std::unordered_map actual_notifications; @@ -55,7 +56,12 @@ void DispatchMacOSNotification(gfx::NativeViewAccessible native_node, // Setting up bridge so that the AccessibilityBridgeMacDelegateSpy // can query semantics information from. engine.semanticsEnabled = YES; + + AccessibilityBridgeMacDelegateSpy* spy = + new AccessibilityBridgeMacDelegateSpy(engine, viewController, engine.accessibilityBridge); auto bridge = engine.accessibilityBridge.lock(); + bridge->UpdateDelegate(std::unique_ptr(spy)); + FlutterSemanticsNode root; root.id = 0; root.flags = static_cast(0); @@ -74,8 +80,6 @@ void DispatchMacOSNotification(gfx::NativeViewAccessible native_node, bridge->CommitUpdates(); auto platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock(); - AccessibilityBridgeMacDelegateSpy spy(engine, viewController); - // Creates a targeted event. ui::AXTree tree; ui::AXNode ax_node(&tree, nullptr, 0, 0); @@ -87,10 +91,10 @@ void DispatchMacOSNotification(gfx::NativeViewAccessible native_node, ax::mojom::EventFrom::kNone, intent); ui::AXEventGenerator::TargetedEvent targeted_event(&ax_node, event_params); - spy.OnAccessibilityEvent(targeted_event); + spy->OnAccessibilityEvent(targeted_event); - EXPECT_EQ(spy.actual_notifications.size(), 1u); - EXPECT_EQ(spy.actual_notifications.find([NSAccessibilityCreatedNotification UTF8String])->second, + EXPECT_EQ(spy->actual_notifications.size(), 1u); + EXPECT_EQ(spy->actual_notifications.find([NSAccessibilityCreatedNotification UTF8String])->second, expectedTarget); [engine shutDownEngine]; } @@ -107,7 +111,12 @@ void DispatchMacOSNotification(gfx::NativeViewAccessible native_node, // Setting up bridge so that the AccessibilityBridgeMacDelegateSpy // can query semantics information from. engine.semanticsEnabled = YES; + + AccessibilityBridgeMacDelegateSpy* spy = + new AccessibilityBridgeMacDelegateSpy(engine, viewController, engine.accessibilityBridge); auto bridge = engine.accessibilityBridge.lock(); + bridge->UpdateDelegate(std::unique_ptr(spy)); + FlutterSemanticsNode root; root.id = 0; root.flags = static_cast(0); @@ -126,8 +135,6 @@ void DispatchMacOSNotification(gfx::NativeViewAccessible native_node, bridge->CommitUpdates(); auto platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock(); - AccessibilityBridgeMacDelegateSpy spy(engine, viewController); - // Creates a targeted event. ui::AXTree tree; ui::AXNode ax_node(&tree, nullptr, 0, 0); @@ -139,10 +146,10 @@ void DispatchMacOSNotification(gfx::NativeViewAccessible native_node, ax::mojom::EventFrom::kNone, intent); ui::AXEventGenerator::TargetedEvent targeted_event(&ax_node, event_params); - spy.OnAccessibilityEvent(targeted_event); + spy->OnAccessibilityEvent(targeted_event); // Does not send any notification if the engine is headless. - EXPECT_EQ(spy.actual_notifications.size(), 0u); + EXPECT_EQ(spy->actual_notifications.size(), 0u); [engine shutDownEngine]; } @@ -160,7 +167,12 @@ void DispatchMacOSNotification(gfx::NativeViewAccessible native_node, // Setting up bridge so that the AccessibilityBridgeMacDelegateSpy // can query semantics information from. engine.semanticsEnabled = YES; + + AccessibilityBridgeMacDelegateSpy* spy = + new AccessibilityBridgeMacDelegateSpy(engine, viewController, engine.accessibilityBridge); auto bridge = engine.accessibilityBridge.lock(); + bridge->UpdateDelegate(std::unique_ptr(spy)); + FlutterSemanticsNode root; root.id = 0; root.flags = static_cast(0); @@ -179,8 +191,6 @@ void DispatchMacOSNotification(gfx::NativeViewAccessible native_node, bridge->CommitUpdates(); auto platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock(); - AccessibilityBridgeMacDelegateSpy spy(engine, viewController); - // Creates a targeted event. ui::AXTree tree; ui::AXNode ax_node(&tree, nullptr, 0, 0); @@ -192,10 +202,10 @@ void DispatchMacOSNotification(gfx::NativeViewAccessible native_node, ax::mojom::EventFrom::kNone, intent); ui::AXEventGenerator::TargetedEvent targeted_event(&ax_node, event_params); - spy.OnAccessibilityEvent(targeted_event); + spy->OnAccessibilityEvent(targeted_event); // Does not send any notification if the flutter view is not attached to a NSWindow. - EXPECT_EQ(spy.actual_notifications.size(), 0u); + EXPECT_EQ(spy->actual_notifications.size(), 0u); [engine shutDownEngine]; } diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index 9c15b52f7d8ff..88e98392a01e5 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -414,8 +414,8 @@ - (void)setViewController:(FlutterViewController*)controller { [_renderer setFlutterView:controller.flutterView]; if (_semanticsEnabled && _bridge) { - _bridge->UpdateDelegate( - std::make_unique(self, _viewController)); + _bridge->UpdateDelegate(std::make_unique( + self, _viewController, _bridge)); } if (!controller && !_allowHeadlessExecution) { @@ -597,8 +597,10 @@ - (void)setSemanticsEnabled:(BOOL)enabled { if (!_semanticsEnabled && _bridge) { _bridge.reset(); } else if (_semanticsEnabled && !_bridge) { - _bridge = std::make_shared( - std::make_unique(self, self.viewController)); + _bridge = std::make_shared(); + auto bridge_delegate = std::make_unique( + self, self.viewController, _bridge); + _bridge->UpdateDelegate(std::move(bridge_delegate)); } _embedderAPI.UpdateSemanticsEnabled(_engine, _semanticsEnabled); } diff --git a/shell/platform/darwin/macos/framework/Source/FlutterPlatformNodeDelegateMac.h b/shell/platform/darwin/macos/framework/Source/FlutterPlatformNodeDelegateMac.h index 3077ab2fef6d2..82d78fa4fb890 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterPlatformNodeDelegateMac.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterPlatformNodeDelegateMac.h @@ -9,6 +9,7 @@ #import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterEngine.h" +#include "flutter/shell/platform/common/accessibility_bridge.h" #include "flutter/shell/platform/common/flutter_platform_node_delegate.h" #include "flutter/shell/platform/embedder/embedder.h" @@ -20,8 +21,8 @@ namespace flutter { class FlutterPlatformNodeDelegateMac : public FlutterPlatformNodeDelegate { public: explicit FlutterPlatformNodeDelegateMac( - __weak FlutterEngine* engine, - __weak FlutterViewController* view_controller); + __weak FlutterViewController* view_controller, + std::weak_ptr accessibility_bridge); virtual ~FlutterPlatformNodeDelegateMac(); void Init(std::weak_ptr bridge, ui::AXNode* node) override; @@ -49,8 +50,8 @@ class FlutterPlatformNodeDelegateMac : public FlutterPlatformNodeDelegate { private: ui::AXPlatformNode* ax_platform_node_; - __weak FlutterEngine* engine_; __weak FlutterViewController* view_controller_; + std::weak_ptr accessibility_bridge_; gfx::RectF ConvertBoundsFromLocalToScreen( const gfx::RectF& local_bounds) const; diff --git a/shell/platform/darwin/macos/framework/Source/FlutterPlatformNodeDelegateMac.mm b/shell/platform/darwin/macos/framework/Source/FlutterPlatformNodeDelegateMac.mm index ab95291d504c9..ac17653fe013c 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterPlatformNodeDelegateMac.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterPlatformNodeDelegateMac.mm @@ -5,7 +5,6 @@ #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformNodeDelegateMac.h" #import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterAppDelegate.h" -#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h" #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputSemanticsObject.h" #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h" @@ -21,9 +20,9 @@ namespace flutter { // namespace FlutterPlatformNodeDelegateMac::FlutterPlatformNodeDelegateMac( - __weak FlutterEngine* engine, - __weak FlutterViewController* view_controller) - : engine_(engine), view_controller_(view_controller) {} + __weak FlutterViewController* view_controller, + std::weak_ptr accessibility_bridge) + : view_controller_(view_controller), accessibility_bridge_(accessibility_bridge) {} void FlutterPlatformNodeDelegateMac::Init(std::weak_ptr bridge, ui::AXNode* node) { FlutterPlatformNodeDelegate::Init(bridge, node); @@ -48,9 +47,9 @@ gfx::NativeViewAccessible FlutterPlatformNodeDelegateMac::GetParent() { gfx::NativeViewAccessible parent = FlutterPlatformNodeDelegate::GetParent(); if (!parent) { - NSCAssert(engine_, @"Flutter engine should not be deallocated"); - NSCAssert(engine_.viewController.viewLoaded, @"Flutter view must be loaded"); - return engine_.viewController.flutterView; + NSCAssert(!accessibility_bridge_.expired(), @"Accessibility bridge should not be expired"); + NSCAssert(view_controller_.viewLoaded, @"Flutter view must be loaded"); + return view_controller_.flutterView; } return parent; } @@ -80,9 +79,8 @@ if (!text.empty()) { return text; }; - NSCAssert(engine_, @"Flutter engine should not be deallocated"); - auto bridge_ptr = engine_.accessibilityBridge.lock(); - NSCAssert(bridge_ptr, @"Accessibility bridge in flutter engine must not be null."); + auto bridge_ptr = accessibility_bridge_.lock(); + NSCAssert(bridge_ptr, @"Accessibility bridge should not be expired"); for (int32_t child : GetData().child_ids) { auto delegate_child = bridge_ptr->GetFlutterPlatformNodeDelegateFromID(child).lock(); if (!delegate_child) { @@ -105,14 +103,11 @@ // it converts the bounds from flutter coordinates to macOS coordinates. ns_local_bounds.origin.y = -ns_local_bounds.origin.y - ns_local_bounds.size.height; - NSCAssert(engine_, @"Flutter engine should not be deallocated"); - NSCAssert(engine_.viewController.viewLoaded, @"Flutter view must be loaded."); - NSRect ns_view_bounds = - [engine_.viewController.flutterView convertRectFromBacking:ns_local_bounds]; - NSRect ns_window_bounds = [engine_.viewController.flutterView convertRect:ns_view_bounds - toView:nil]; + NSCAssert(view_controller_.viewLoaded, @"Flutter view must be loaded."); + NSRect ns_view_bounds = [view_controller_.flutterView convertRectFromBacking:ns_local_bounds]; + NSRect ns_window_bounds = [view_controller_.flutterView convertRect:ns_view_bounds toView:nil]; NSRect ns_screen_bounds = - [[engine_.viewController.flutterView window] convertRectToScreen:ns_window_bounds]; + [[view_controller_.flutterView window] convertRectToScreen:ns_window_bounds]; gfx::RectF screen_bounds(ns_screen_bounds.origin.x, ns_screen_bounds.origin.y, ns_screen_bounds.size.width, ns_screen_bounds.size.height); return screen_bounds; diff --git a/shell/platform/darwin/macos/framework/Source/FlutterTextInputPluginTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterTextInputPluginTest.mm index 4efb4d3e30bf5..8b743d1b358eb 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterTextInputPluginTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterTextInputPluginTest.mm @@ -1427,7 +1427,7 @@ - (bool)testSelectorsAreForwardedToFramework { engine.semanticsEnabled = YES; auto bridge = engine.accessibilityBridge.lock(); - FlutterPlatformNodeDelegateMac delegate(engine, viewController); + FlutterPlatformNodeDelegateMac delegate(viewController, engine.accessibilityBridge); ui::AXTree tree; ui::AXNode ax_node(&tree, nullptr, 0, 0); ui::AXNodeData node_data; @@ -1486,7 +1486,7 @@ - (bool)testSelectorsAreForwardedToFramework { engine.semanticsEnabled = YES; auto bridge = engine.accessibilityBridge.lock(); - FlutterPlatformNodeDelegateMac delegate(engine, viewController); + FlutterPlatformNodeDelegateMac delegate(viewController, engine.accessibilityBridge); ui::AXTree tree; ui::AXNode ax_node(&tree, nullptr, 0, 0); ui::AXNodeData node_data; diff --git a/shell/platform/darwin/macos/framework/Source/FlutterTextInputSemanticsObjectTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterTextInputSemanticsObjectTest.mm index 2080cdbdb8fce..91c4ff8da0292 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterTextInputSemanticsObjectTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterTextInputSemanticsObjectTest.mm @@ -44,7 +44,7 @@ engine.semanticsEnabled = YES; auto bridge = engine.accessibilityBridge.lock(); - FlutterPlatformNodeDelegateMac delegate(engine, viewController); + FlutterPlatformNodeDelegateMac delegate(viewController, bridge); ui::AXTree tree; ui::AXNode ax_node(&tree, nullptr, 0, 0); ui::AXNodeData node_data; diff --git a/shell/platform/darwin/macos/framework/Source/FlutterWindowPlugin.h b/shell/platform/darwin/macos/framework/Source/FlutterWindowPlugin.h new file mode 100644 index 0000000000000..5fc33cdb9b51b --- /dev/null +++ b/shell/platform/darwin/macos/framework/Source/FlutterWindowPlugin.h @@ -0,0 +1,17 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import + +#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h" +#import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterEngine.h" +#import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterPluginMacOS.h" +#import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterViewController.h" + +@interface FlutterWindowPlugin : NSObject + ++ (void)registerWithRegistrar:(nonnull id)registrar + engine:(nonnull FlutterEngine*)engine; + +@end diff --git a/shell/platform/darwin/macos/framework/Source/FlutterWindowPlugin.mm b/shell/platform/darwin/macos/framework/Source/FlutterWindowPlugin.mm new file mode 100644 index 0000000000000..9fda9a168226e --- /dev/null +++ b/shell/platform/darwin/macos/framework/Source/FlutterWindowPlugin.mm @@ -0,0 +1,74 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "FlutterWindowPlugin.h" +#import "FlutterEngine_Internal.h" + +#include + +static NSString* const kChannelName = @"flutter/window"; + +@interface FlutterWindowPlugin () +- (instancetype)initWithChannel:(FlutterMethodChannel*)channel engine:(FlutterEngine*)engine; +@end + +@implementation FlutterWindowPlugin { + FlutterMethodChannel* _channel; + FlutterEngine* _engine; +} + +#pragma mark - Private Methods + +- (instancetype)initWithChannel:(FlutterMethodChannel*)channel engine:(FlutterEngine*)engine { + self = [super init]; + if (self) { + _channel = channel; + _engine = engine; + } + return self; +} + +- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { + NSLog(@">>> method %@", call.method); + if ([call.method isEqualToString:@"new"]) { + // dispatch_async(dispatch_get_main_queue(), ^{ + NSRect graphicsRect = NSMakeRect(100.0, 350.0, 844.0, 626.0); + NSWindow* myWindow = [[NSWindow alloc] + initWithContentRect:graphicsRect + styleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | + NSWindowStyleMaskResizable + backing:NSBackingStoreBuffered + defer:NO]; + [myWindow setTitle:@"Test Test"]; + + FlutterViewController* controller = [[FlutterViewController alloc] initWithEngine:_engine + nibName:nil + [myWindow setContentViewController:controller]; + [myWindow setFrame:graphicsRect display:YES]; + + // [myWindow setDelegate:*myView ]; // set window's delegate + [myWindow makeKeyAndOrderFront:nil]; // display window + [_engine updateWindowMetrics:controller.flutterView id:controller.id]; + NSLog(@"New view ID: %@", @(controller.id)); + result(@(controller.id)); + // }); + } +} + +#pragma mark - Public Class Methods + ++ (void)registerWithRegistrar:(nonnull id)registrar + engine:(nonnull FlutterEngine*)engine { + FlutterMethodChannel* channel = [FlutterMethodChannel methodChannelWithName:kChannelName + binaryMessenger:registrar.messenger]; + FlutterWindowPlugin* instance = [[FlutterWindowPlugin alloc] initWithChannel:channel + engine:engine]; + [registrar addMethodCallDelegate:instance channel:channel]; +} + ++ (void)registerWithRegistrar:(nonnull id)registrar { + NSLog(@"ERROR CALL TO registerWithRegistrar"); +} + +@end diff --git a/shell/platform/windows/accessibility_bridge_delegate_windows.cc b/shell/platform/windows/accessibility_bridge_delegate_windows.cc index dd2a4b0592154..bdca167b7d564 100644 --- a/shell/platform/windows/accessibility_bridge_delegate_windows.cc +++ b/shell/platform/windows/accessibility_bridge_delegate_windows.cc @@ -11,8 +11,10 @@ namespace flutter { AccessibilityBridgeDelegateWindows::AccessibilityBridgeDelegateWindows( - FlutterWindowsEngine* engine) - : engine_(engine) { + FlutterWindowsEngine* engine, + FlutterWindowsView* view, + std::weak_ptr bridge) + : engine_(engine), view_(view), accessibility_bridge_(bridge) { assert(engine_); } @@ -22,7 +24,7 @@ void AccessibilityBridgeDelegateWindows::OnAccessibilityEvent( ui::AXEventGenerator::Event event_type = targeted_event.event_params.event; // Look up the flutter platform node delegate. - auto bridge = engine_->accessibility_bridge().lock(); + auto bridge = accessibility_bridge_.lock(); assert(bridge); auto node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(ax_node->id()).lock(); @@ -147,7 +149,8 @@ void AccessibilityBridgeDelegateWindows::DispatchAccessibilityAction( std::shared_ptr AccessibilityBridgeDelegateWindows::CreateFlutterPlatformNodeDelegate() { - return std::make_shared(engine_); + return std::make_shared( + view_, accessibility_bridge_); } void AccessibilityBridgeDelegateWindows::DispatchWinAccessibilityEvent( diff --git a/shell/platform/windows/accessibility_bridge_delegate_windows.h b/shell/platform/windows/accessibility_bridge_delegate_windows.h index d9c2060867876..876514780fc03 100644 --- a/shell/platform/windows/accessibility_bridge_delegate_windows.h +++ b/shell/platform/windows/accessibility_bridge_delegate_windows.h @@ -24,7 +24,8 @@ class FlutterWindowsEngine; class AccessibilityBridgeDelegateWindows : public AccessibilityBridge::AccessibilityBridgeDelegate { public: - explicit AccessibilityBridgeDelegateWindows(FlutterWindowsEngine* engine); + AccessibilityBridgeDelegateWindows(FlutterWindowsEngine* engine, + std::weak_ptr bridge); virtual ~AccessibilityBridgeDelegateWindows() = default; // |AccessibilityBridge::AccessibilityBridgeDelegate| @@ -53,6 +54,8 @@ class AccessibilityBridgeDelegateWindows private: FlutterWindowsEngine* engine_; + FlutterWindowsView* view_; + std::weak_ptr accessibility_bridge_; }; } // namespace flutter diff --git a/shell/platform/windows/flutter_platform_node_delegate_windows.cc b/shell/platform/windows/flutter_platform_node_delegate_windows.cc index a2c95daa817bd..949abe9bceb9c 100644 --- a/shell/platform/windows/flutter_platform_node_delegate_windows.cc +++ b/shell/platform/windows/flutter_platform_node_delegate_windows.cc @@ -13,10 +13,9 @@ namespace flutter { FlutterPlatformNodeDelegateWindows::FlutterPlatformNodeDelegateWindows( - FlutterWindowsEngine* engine) - : engine_(engine) { - assert(engine_); -} + FlutterWindowsView* view, + AccessibilityBridge* bridge) + : view_(view) {} FlutterPlatformNodeDelegateWindows::~FlutterPlatformNodeDelegateWindows() { if (ax_platform_node_) { @@ -53,12 +52,10 @@ gfx::NativeViewAccessible FlutterPlatformNodeDelegateWindows::HitTestSync( } // If any child in this node's subtree contains the point, return that child. - auto bridge = engine_->accessibility_bridge().lock(); - assert(bridge); for (const ui::AXNode* child : GetAXNode()->children()) { std::shared_ptr win_delegate = std::static_pointer_cast( - bridge->GetFlutterPlatformNodeDelegateFromID(child->id()).lock()); + bridge_->GetFlutterPlatformNodeDelegateFromID(child->id()).lock()); assert(win_delegate); auto hit_view = win_delegate->HitTestSync(screen_physical_pixel_x, screen_physical_pixel_y); @@ -80,19 +77,18 @@ gfx::Rect FlutterPlatformNodeDelegateWindows::GetBoundsRect( coordinate_system, clipping_behavior, offscreen_result); POINT origin{bounds.x(), bounds.y()}; POINT extent{bounds.x() + bounds.width(), bounds.y() + bounds.height()}; - ClientToScreen(engine_->view()->GetPlatformWindow(), &origin); - ClientToScreen(engine_->view()->GetPlatformWindow(), &extent); + ClientToScreen(view_->GetPlatformWindow(), &origin); + ClientToScreen(view_->GetPlatformWindow(), &extent); return gfx::Rect(origin.x, origin.y, extent.x - origin.x, extent.y - origin.y); } void FlutterPlatformNodeDelegateWindows::DispatchWinAccessibilityEvent( DWORD event_type) { - FlutterWindowsView* view = engine_->view(); - if (!view) { + if (!view_) { return; } - HWND hwnd = view->GetPlatformWindow(); + HWND hwnd = view_->GetPlatformWindow(); if (!hwnd) { return; } diff --git a/shell/platform/windows/flutter_platform_node_delegate_windows.h b/shell/platform/windows/flutter_platform_node_delegate_windows.h index b77cc0ca7e107..22df72177393f 100644 --- a/shell/platform/windows/flutter_platform_node_delegate_windows.h +++ b/shell/platform/windows/flutter_platform_node_delegate_windows.h @@ -20,7 +20,8 @@ class FlutterWindowsEngine; // that compose the accessibility tree. class FlutterPlatformNodeDelegateWindows : public FlutterPlatformNodeDelegate { public: - explicit FlutterPlatformNodeDelegateWindows(FlutterWindowsEngine* engine); + FlutterPlatformNodeDelegateWindows(FlutterWindowsView* view, + std::weak_ptr bridge); virtual ~FlutterPlatformNodeDelegateWindows(); // |ui::AXPlatformNodeDelegate| @@ -51,7 +52,7 @@ class FlutterPlatformNodeDelegateWindows : public FlutterPlatformNodeDelegate { private: ui::AXPlatformNode* ax_platform_node_; - FlutterWindowsEngine* engine_; + FlutterWindowsView* view_; }; } // namespace flutter From 80a735a436b1a481030c7932927ce6eb13f1cead Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 3 Oct 2022 12:52:44 -0700 Subject: [PATCH 02/10] Win --- .../accessibility_bridge_delegate_windows.h | 1 + ...ility_bridge_delegate_windows_unittests.cc | 44 +++++++++++++------ .../flutter_platform_node_delegate_windows.cc | 10 +++-- .../flutter_platform_node_delegate_windows.h | 3 ++ .../windows/flutter_windows_engine.cc | 6 ++- 5 files changed, 45 insertions(+), 19 deletions(-) diff --git a/shell/platform/windows/accessibility_bridge_delegate_windows.h b/shell/platform/windows/accessibility_bridge_delegate_windows.h index 876514780fc03..ee188294219a7 100644 --- a/shell/platform/windows/accessibility_bridge_delegate_windows.h +++ b/shell/platform/windows/accessibility_bridge_delegate_windows.h @@ -25,6 +25,7 @@ class AccessibilityBridgeDelegateWindows : public AccessibilityBridge::AccessibilityBridgeDelegate { public: AccessibilityBridgeDelegateWindows(FlutterWindowsEngine* engine, + FlutterWindowsView* view, std::weak_ptr bridge); virtual ~AccessibilityBridgeDelegateWindows() = default; diff --git a/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc b/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc index 5db7fc4c7de38..a5ee6fb49d9f1 100644 --- a/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc +++ b/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc @@ -36,8 +36,11 @@ struct MsaaEvent { class AccessibilityBridgeDelegateWindowsSpy : public AccessibilityBridgeDelegateWindows { public: - explicit AccessibilityBridgeDelegateWindowsSpy(FlutterWindowsEngine* engine) - : AccessibilityBridgeDelegateWindows(engine) {} + explicit AccessibilityBridgeDelegateWindowsSpy( + FlutterWindowsEngine* engine, + FlutterWindowsView* view, + std::weak_ptr bridge) + : AccessibilityBridgeDelegateWindows(engine, view, bridge) {} void DispatchWinAccessibilityEvent( std::shared_ptr node_delegate, @@ -154,11 +157,13 @@ void ExpectWinEventFromAXEvent(int32_t node_id, auto bridge = view.GetEngine()->accessibility_bridge().lock(); PopulateAXTree(bridge); - AccessibilityBridgeDelegateWindowsSpy spy(view.GetEngine()); - spy.OnAccessibilityEvent({AXNodeFromID(bridge, node_id), + auto spy = new AccessibilityBridgeDelegateWindowsSpy( + view.GetEngine(), &view, view.GetEngine()->accessibility_bridge()); + bridge->UpdateDelegate(std::unique_ptr(spy)); + spy->OnAccessibilityEvent({AXNodeFromID(bridge, node_id), {ax_event, ax::mojom::EventFrom::kNone, {}}}); - ASSERT_EQ(spy.dispatched_events().size(), 1); - EXPECT_EQ(spy.dispatched_events()[0].event_type, expected_event); + ASSERT_EQ(spy->dispatched_events().size(), 1); + EXPECT_EQ(spy->dispatched_events()[0].event_type, expected_event); } } // namespace @@ -171,6 +176,9 @@ TEST(AccessibilityBridgeDelegateWindows, GetParent) { view.OnUpdateSemanticsEnabled(true); auto bridge = view.GetEngine()->accessibility_bridge().lock(); + auto spy = new AccessibilityBridgeDelegateWindowsSpy( + view.GetEngine(), &view, view.GetEngine()->accessibility_bridge()); + bridge->UpdateDelegate(std::unique_ptr(spy)); PopulateAXTree(bridge); auto node0_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock(); @@ -187,6 +195,9 @@ TEST(AccessibilityBridgeDelegateWindows, GetParentOnRootRetunsNullptr) { view.OnUpdateSemanticsEnabled(true); auto bridge = view.GetEngine()->accessibility_bridge().lock(); + auto spy = new AccessibilityBridgeDelegateWindowsSpy( + view.GetEngine(), &view, view.GetEngine()->accessibility_bridge()); + bridge->UpdateDelegate(std::unique_ptr(spy)); PopulateAXTree(bridge); auto node0_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock(); @@ -201,6 +212,9 @@ TEST(AccessibilityBridgeDelegateWindows, DispatchAccessibilityAction) { view.OnUpdateSemanticsEnabled(true); auto bridge = view.GetEngine()->accessibility_bridge().lock(); + auto spy = new AccessibilityBridgeDelegateWindowsSpy( + view.GetEngine(), &view, view.GetEngine()->accessibility_bridge()); + bridge->UpdateDelegate(std::unique_ptr(spy)); PopulateAXTree(bridge); FlutterSemanticsAction actual_action = kFlutterSemanticsActionTap; @@ -214,8 +228,7 @@ TEST(AccessibilityBridgeDelegateWindows, DispatchAccessibilityAction) { return kSuccess; })); - AccessibilityBridgeDelegateWindows delegate(view.GetEngine()); - delegate.DispatchAccessibilityAction(1, kFlutterSemanticsActionCopy, {}); + spy->DispatchAccessibilityAction(1, kFlutterSemanticsActionCopy, {}); EXPECT_EQ(actual_action, kFlutterSemanticsActionCopy); } @@ -239,16 +252,19 @@ TEST(AccessibilityBridgeDelegateWindows, OnAccessibilityEventFocusChanged) { auto bridge = view.GetEngine()->accessibility_bridge().lock(); PopulateAXTree(bridge); - AccessibilityBridgeDelegateWindowsSpy spy(view.GetEngine()); - spy.OnAccessibilityEvent({AXNodeFromID(bridge, 1), + auto spy = new AccessibilityBridgeDelegateWindowsSpy( + view.GetEngine(), &view, view.GetEngine()->accessibility_bridge()); + bridge->UpdateDelegate(std::unique_ptr(spy)); + + spy->OnAccessibilityEvent({AXNodeFromID(bridge, 1), {ui::AXEventGenerator::Event::FOCUS_CHANGED, ax::mojom::EventFrom::kNone, {}}}); - ASSERT_EQ(spy.dispatched_events().size(), 1); - EXPECT_EQ(spy.dispatched_events()[0].event_type, EVENT_OBJECT_FOCUS); + ASSERT_EQ(spy->dispatched_events().size(), 1); + EXPECT_EQ(spy->dispatched_events()[0].event_type, EVENT_OBJECT_FOCUS); - ASSERT_EQ(spy.focused_nodes().size(), 1); - EXPECT_EQ(spy.focused_nodes()[0], 1); + ASSERT_EQ(spy->focused_nodes().size(), 1); + EXPECT_EQ(spy->focused_nodes()[0], 1); } TEST(AccessibilityBridgeDelegateWindows, OnAccessibilityEventIgnoredChanged) { diff --git a/shell/platform/windows/flutter_platform_node_delegate_windows.cc b/shell/platform/windows/flutter_platform_node_delegate_windows.cc index 949abe9bceb9c..fbcc2f16c8174 100644 --- a/shell/platform/windows/flutter_platform_node_delegate_windows.cc +++ b/shell/platform/windows/flutter_platform_node_delegate_windows.cc @@ -14,8 +14,8 @@ namespace flutter { FlutterPlatformNodeDelegateWindows::FlutterPlatformNodeDelegateWindows( FlutterWindowsView* view, - AccessibilityBridge* bridge) - : view_(view) {} + std::weak_ptr bridge) + : view_(view), bridge_(bridge) {} FlutterPlatformNodeDelegateWindows::~FlutterPlatformNodeDelegateWindows() { if (ax_platform_node_) { @@ -52,10 +52,14 @@ gfx::NativeViewAccessible FlutterPlatformNodeDelegateWindows::HitTestSync( } // If any child in this node's subtree contains the point, return that child. + auto bridge = bridge_.lock(); + if (!bridge) { + return nullptr; + } for (const ui::AXNode* child : GetAXNode()->children()) { std::shared_ptr win_delegate = std::static_pointer_cast( - bridge_->GetFlutterPlatformNodeDelegateFromID(child->id()).lock()); + bridge->GetFlutterPlatformNodeDelegateFromID(child->id()).lock()); assert(win_delegate); auto hit_view = win_delegate->HitTestSync(screen_physical_pixel_x, screen_physical_pixel_y); diff --git a/shell/platform/windows/flutter_platform_node_delegate_windows.h b/shell/platform/windows/flutter_platform_node_delegate_windows.h index 22df72177393f..c89638f8aee45 100644 --- a/shell/platform/windows/flutter_platform_node_delegate_windows.h +++ b/shell/platform/windows/flutter_platform_node_delegate_windows.h @@ -5,6 +5,8 @@ #ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_FLUTTER_PLATFORM_NODE_DELEGATE_H_ #define FLUTTER_SHELL_PLATFORM_WINDOWS_FLUTTER_PLATFORM_NODE_DELEGATE_H_ +#include + #include "flutter/shell/platform/common/flutter_platform_node_delegate.h" #include "flutter/shell/platform/windows/flutter_windows_engine.h" #include "flutter/third_party/accessibility/ax/platform/ax_platform_node.h" @@ -53,6 +55,7 @@ class FlutterPlatformNodeDelegateWindows : public FlutterPlatformNodeDelegate { private: ui::AXPlatformNode* ax_platform_node_; FlutterWindowsView* view_; + std::weak_ptr bridge_; }; } // namespace flutter diff --git a/shell/platform/windows/flutter_windows_engine.cc b/shell/platform/windows/flutter_windows_engine.cc index e862a94029b11..a7e65205e4a84 100644 --- a/shell/platform/windows/flutter_windows_engine.cc +++ b/shell/platform/windows/flutter_windows_engine.cc @@ -594,8 +594,10 @@ void FlutterWindowsEngine::UpdateSemanticsEnabled(bool enabled) { if (!semantics_enabled_ && accessibility_bridge_) { accessibility_bridge_.reset(); } else if (semantics_enabled_ && !accessibility_bridge_) { - accessibility_bridge_ = std::make_shared( - std::make_unique(this)); + accessibility_bridge_ = std::make_shared(); + auto delegate = + std::make_unique(this, view_, accessibility_bridge_); + accessibility_bridge_->UpdateDelegate(std::move(delegate)); } } } From 65edba4aff6074fc1d8cc85297af265e0433751f Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 3 Oct 2022 12:53:41 -0700 Subject: [PATCH 03/10] Format --- ...ility_bridge_delegate_windows_unittests.cc | 23 +++++++++++-------- .../windows/flutter_windows_engine.cc | 4 ++-- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc b/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc index a5ee6fb49d9f1..27dfe762d8a26 100644 --- a/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc +++ b/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc @@ -159,9 +159,10 @@ void ExpectWinEventFromAXEvent(int32_t node_id, auto spy = new AccessibilityBridgeDelegateWindowsSpy( view.GetEngine(), &view, view.GetEngine()->accessibility_bridge()); - bridge->UpdateDelegate(std::unique_ptr(spy)); + bridge->UpdateDelegate( + std::unique_ptr(spy)); spy->OnAccessibilityEvent({AXNodeFromID(bridge, node_id), - {ax_event, ax::mojom::EventFrom::kNone, {}}}); + {ax_event, ax::mojom::EventFrom::kNone, {}}}); ASSERT_EQ(spy->dispatched_events().size(), 1); EXPECT_EQ(spy->dispatched_events()[0].event_type, expected_event); } @@ -178,7 +179,8 @@ TEST(AccessibilityBridgeDelegateWindows, GetParent) { auto bridge = view.GetEngine()->accessibility_bridge().lock(); auto spy = new AccessibilityBridgeDelegateWindowsSpy( view.GetEngine(), &view, view.GetEngine()->accessibility_bridge()); - bridge->UpdateDelegate(std::unique_ptr(spy)); + bridge->UpdateDelegate( + std::unique_ptr(spy)); PopulateAXTree(bridge); auto node0_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock(); @@ -197,7 +199,8 @@ TEST(AccessibilityBridgeDelegateWindows, GetParentOnRootRetunsNullptr) { auto bridge = view.GetEngine()->accessibility_bridge().lock(); auto spy = new AccessibilityBridgeDelegateWindowsSpy( view.GetEngine(), &view, view.GetEngine()->accessibility_bridge()); - bridge->UpdateDelegate(std::unique_ptr(spy)); + bridge->UpdateDelegate( + std::unique_ptr(spy)); PopulateAXTree(bridge); auto node0_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock(); @@ -214,7 +217,8 @@ TEST(AccessibilityBridgeDelegateWindows, DispatchAccessibilityAction) { auto bridge = view.GetEngine()->accessibility_bridge().lock(); auto spy = new AccessibilityBridgeDelegateWindowsSpy( view.GetEngine(), &view, view.GetEngine()->accessibility_bridge()); - bridge->UpdateDelegate(std::unique_ptr(spy)); + bridge->UpdateDelegate( + std::unique_ptr(spy)); PopulateAXTree(bridge); FlutterSemanticsAction actual_action = kFlutterSemanticsActionTap; @@ -254,12 +258,13 @@ TEST(AccessibilityBridgeDelegateWindows, OnAccessibilityEventFocusChanged) { auto spy = new AccessibilityBridgeDelegateWindowsSpy( view.GetEngine(), &view, view.GetEngine()->accessibility_bridge()); - bridge->UpdateDelegate(std::unique_ptr(spy)); + bridge->UpdateDelegate( + std::unique_ptr(spy)); spy->OnAccessibilityEvent({AXNodeFromID(bridge, 1), - {ui::AXEventGenerator::Event::FOCUS_CHANGED, - ax::mojom::EventFrom::kNone, - {}}}); + {ui::AXEventGenerator::Event::FOCUS_CHANGED, + ax::mojom::EventFrom::kNone, + {}}}); ASSERT_EQ(spy->dispatched_events().size(), 1); EXPECT_EQ(spy->dispatched_events()[0].event_type, EVENT_OBJECT_FOCUS); diff --git a/shell/platform/windows/flutter_windows_engine.cc b/shell/platform/windows/flutter_windows_engine.cc index a7e65205e4a84..216876b0635b4 100644 --- a/shell/platform/windows/flutter_windows_engine.cc +++ b/shell/platform/windows/flutter_windows_engine.cc @@ -595,8 +595,8 @@ void FlutterWindowsEngine::UpdateSemanticsEnabled(bool enabled) { accessibility_bridge_.reset(); } else if (semantics_enabled_ && !accessibility_bridge_) { accessibility_bridge_ = std::make_shared(); - auto delegate = - std::make_unique(this, view_, accessibility_bridge_); + auto delegate = std::make_unique( + this, view_, accessibility_bridge_); accessibility_bridge_->UpdateDelegate(std::move(delegate)); } } From eda5c5d3b9da5e714c7f6b5af1252420ab9bef2b Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 3 Oct 2022 13:26:02 -0700 Subject: [PATCH 04/10] better comment --- shell/platform/common/accessibility_bridge.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/shell/platform/common/accessibility_bridge.h b/shell/platform/common/accessibility_bridge.h index ad455fe6f1ceb..b33a2fbb8c651 100644 --- a/shell/platform/common/accessibility_bridge.h +++ b/shell/platform/common/accessibility_bridge.h @@ -103,7 +103,8 @@ class AccessibilityBridge }; //----------------------------------------------------------------------------- - /// @brief Creates a new instance of a accessibility bridge. + /// @brief Creates a new instance of a accessibility bridge without a + /// delegate. /// /// The bridge is not ready for use until a delegate has been /// assigned. See AccessibilityBridge::UpdateDelegate. @@ -111,6 +112,9 @@ class AccessibilityBridge //----------------------------------------------------------------------------- /// @brief Creates a new instance of a accessibility bridge. + /// + /// This is effectively identical to the default constructor + /// followed by AccessibilityBridge::UpdateDelegate. explicit AccessibilityBridge( std::unique_ptr delegate); ~AccessibilityBridge(); From 186778d895d3036d6fa1e7c98c888b618f3ac864 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 3 Oct 2022 14:09:42 -0700 Subject: [PATCH 05/10] Rm window plugin --- .../framework/Source/FlutterWindowPlugin.h | 17 ----- .../framework/Source/FlutterWindowPlugin.mm | 74 ------------------- 2 files changed, 91 deletions(-) delete mode 100644 shell/platform/darwin/macos/framework/Source/FlutterWindowPlugin.h delete mode 100644 shell/platform/darwin/macos/framework/Source/FlutterWindowPlugin.mm diff --git a/shell/platform/darwin/macos/framework/Source/FlutterWindowPlugin.h b/shell/platform/darwin/macos/framework/Source/FlutterWindowPlugin.h deleted file mode 100644 index 5fc33cdb9b51b..0000000000000 --- a/shell/platform/darwin/macos/framework/Source/FlutterWindowPlugin.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import - -#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h" -#import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterEngine.h" -#import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterPluginMacOS.h" -#import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterViewController.h" - -@interface FlutterWindowPlugin : NSObject - -+ (void)registerWithRegistrar:(nonnull id)registrar - engine:(nonnull FlutterEngine*)engine; - -@end diff --git a/shell/platform/darwin/macos/framework/Source/FlutterWindowPlugin.mm b/shell/platform/darwin/macos/framework/Source/FlutterWindowPlugin.mm deleted file mode 100644 index 9fda9a168226e..0000000000000 --- a/shell/platform/darwin/macos/framework/Source/FlutterWindowPlugin.mm +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "FlutterWindowPlugin.h" -#import "FlutterEngine_Internal.h" - -#include - -static NSString* const kChannelName = @"flutter/window"; - -@interface FlutterWindowPlugin () -- (instancetype)initWithChannel:(FlutterMethodChannel*)channel engine:(FlutterEngine*)engine; -@end - -@implementation FlutterWindowPlugin { - FlutterMethodChannel* _channel; - FlutterEngine* _engine; -} - -#pragma mark - Private Methods - -- (instancetype)initWithChannel:(FlutterMethodChannel*)channel engine:(FlutterEngine*)engine { - self = [super init]; - if (self) { - _channel = channel; - _engine = engine; - } - return self; -} - -- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { - NSLog(@">>> method %@", call.method); - if ([call.method isEqualToString:@"new"]) { - // dispatch_async(dispatch_get_main_queue(), ^{ - NSRect graphicsRect = NSMakeRect(100.0, 350.0, 844.0, 626.0); - NSWindow* myWindow = [[NSWindow alloc] - initWithContentRect:graphicsRect - styleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | - NSWindowStyleMaskResizable - backing:NSBackingStoreBuffered - defer:NO]; - [myWindow setTitle:@"Test Test"]; - - FlutterViewController* controller = [[FlutterViewController alloc] initWithEngine:_engine - nibName:nil - [myWindow setContentViewController:controller]; - [myWindow setFrame:graphicsRect display:YES]; - - // [myWindow setDelegate:*myView ]; // set window's delegate - [myWindow makeKeyAndOrderFront:nil]; // display window - [_engine updateWindowMetrics:controller.flutterView id:controller.id]; - NSLog(@"New view ID: %@", @(controller.id)); - result(@(controller.id)); - // }); - } -} - -#pragma mark - Public Class Methods - -+ (void)registerWithRegistrar:(nonnull id)registrar - engine:(nonnull FlutterEngine*)engine { - FlutterMethodChannel* channel = [FlutterMethodChannel methodChannelWithName:kChannelName - binaryMessenger:registrar.messenger]; - FlutterWindowPlugin* instance = [[FlutterWindowPlugin alloc] initWithChannel:channel - engine:engine]; - [registrar addMethodCallDelegate:instance channel:channel]; -} - -+ (void)registerWithRegistrar:(nonnull id)registrar { - NSLog(@"ERROR CALL TO registerWithRegistrar"); -} - -@end From dfc01b7ba234e870e95c8989fbd38c8f49c692b9 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 3 Oct 2022 15:35:15 -0700 Subject: [PATCH 06/10] Comment --- shell/platform/common/accessibility_bridge.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/shell/platform/common/accessibility_bridge.h b/shell/platform/common/accessibility_bridge.h index b33a2fbb8c651..b5e7d08777495 100644 --- a/shell/platform/common/accessibility_bridge.h +++ b/shell/platform/common/accessibility_bridge.h @@ -20,9 +20,9 @@ namespace flutter { //------------------------------------------------------------------------------ -/// Use this class to maintain an accessibility tree. This class consumes -/// semantics updates from the embedder API and produces an accessibility tree -/// in the native format. +/// Use this class to maintain the accessibility tree for a view. This class +/// consumes semantics updates from the embedder API and produces an +/// accessibility tree in the native format. /// /// The bridge creates an AXTree to hold the semantics data that comes from /// Flutter semantics updates. The tree holds AXNode[s] which contain the From 17e33dbbb5df61c270aae1240afea00594cd83b8 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 3 Oct 2022 15:40:21 -0700 Subject: [PATCH 07/10] Merge UpdateDelegate --- .../darwin/macos/framework/Source/FlutterEngine.mm | 5 ++--- ...ccessibility_bridge_delegate_windows_unittests.cc | 12 +++++------- shell/platform/windows/flutter_windows_engine.cc | 6 +++--- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index 88e98392a01e5..5bcc9152cf276 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -598,9 +598,8 @@ - (void)setSemanticsEnabled:(BOOL)enabled { _bridge.reset(); } else if (_semanticsEnabled && !_bridge) { _bridge = std::make_shared(); - auto bridge_delegate = std::make_unique( - self, self.viewController, _bridge); - _bridge->UpdateDelegate(std::move(bridge_delegate)); + _bridge->UpdateDelegate(std::make_unique( + self, self.viewController, _bridge)); } _embedderAPI.UpdateSemanticsEnabled(_engine, _semanticsEnabled); } diff --git a/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc b/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc index 27dfe762d8a26..216c4d743ee7f 100644 --- a/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc +++ b/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc @@ -157,10 +157,9 @@ void ExpectWinEventFromAXEvent(int32_t node_id, auto bridge = view.GetEngine()->accessibility_bridge().lock(); PopulateAXTree(bridge); - auto spy = new AccessibilityBridgeDelegateWindowsSpy( - view.GetEngine(), &view, view.GetEngine()->accessibility_bridge()); bridge->UpdateDelegate( - std::unique_ptr(spy)); + std::make_unique( + view.GetEngine(), &view, view.GetEngine()->accessibility_bridge())); spy->OnAccessibilityEvent({AXNodeFromID(bridge, node_id), {ax_event, ax::mojom::EventFrom::kNone, {}}}); ASSERT_EQ(spy->dispatched_events().size(), 1); @@ -197,10 +196,9 @@ TEST(AccessibilityBridgeDelegateWindows, GetParentOnRootRetunsNullptr) { view.OnUpdateSemanticsEnabled(true); auto bridge = view.GetEngine()->accessibility_bridge().lock(); - auto spy = new AccessibilityBridgeDelegateWindowsSpy( - view.GetEngine(), &view, view.GetEngine()->accessibility_bridge()); bridge->UpdateDelegate( - std::unique_ptr(spy)); + std::make_unique( + view.GetEngine(), &view, view.GetEngine()->accessibility_bridge())); PopulateAXTree(bridge); auto node0_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock(); @@ -218,7 +216,7 @@ TEST(AccessibilityBridgeDelegateWindows, DispatchAccessibilityAction) { auto spy = new AccessibilityBridgeDelegateWindowsSpy( view.GetEngine(), &view, view.GetEngine()->accessibility_bridge()); bridge->UpdateDelegate( - std::unique_ptr(spy)); + std::make_unique(spy)); PopulateAXTree(bridge); FlutterSemanticsAction actual_action = kFlutterSemanticsActionTap; diff --git a/shell/platform/windows/flutter_windows_engine.cc b/shell/platform/windows/flutter_windows_engine.cc index 216876b0635b4..9f5d017b015ee 100644 --- a/shell/platform/windows/flutter_windows_engine.cc +++ b/shell/platform/windows/flutter_windows_engine.cc @@ -595,9 +595,9 @@ void FlutterWindowsEngine::UpdateSemanticsEnabled(bool enabled) { accessibility_bridge_.reset(); } else if (semantics_enabled_ && !accessibility_bridge_) { accessibility_bridge_ = std::make_shared(); - auto delegate = std::make_unique( - this, view_, accessibility_bridge_); - accessibility_bridge_->UpdateDelegate(std::move(delegate)); + accessibility_bridge_->UpdateDelegate( + std::make_unique( + this, view_, accessibility_bridge_)); } } } From 8b4f6892d232595e2e295ab1a3cc0c1a8a0b7a99 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 3 Oct 2022 16:49:49 -0700 Subject: [PATCH 08/10] Fix windows build --- .../accessibility_bridge_delegate_windows_unittests.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc b/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc index 216c4d743ee7f..238dac862e397 100644 --- a/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc +++ b/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc @@ -157,9 +157,11 @@ void ExpectWinEventFromAXEvent(int32_t node_id, auto bridge = view.GetEngine()->accessibility_bridge().lock(); PopulateAXTree(bridge); + + auto spy = new AccessibilityBridgeDelegateWindowsSpy( + view.GetEngine(), &view, view.GetEngine()->accessibility_bridge()); bridge->UpdateDelegate( - std::make_unique( - view.GetEngine(), &view, view.GetEngine()->accessibility_bridge())); + std::unique_ptr(spy)); spy->OnAccessibilityEvent({AXNodeFromID(bridge, node_id), {ax_event, ax::mojom::EventFrom::kNone, {}}}); ASSERT_EQ(spy->dispatched_events().size(), 1); From 9bb124fd8a4327316f05cf1ea9e2e67938ea2be3 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 3 Oct 2022 19:25:07 -0700 Subject: [PATCH 09/10] format --- .../windows/accessibility_bridge_delegate_windows_unittests.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc b/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc index 238dac862e397..b98953fd16b7e 100644 --- a/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc +++ b/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc @@ -157,7 +157,6 @@ void ExpectWinEventFromAXEvent(int32_t node_id, auto bridge = view.GetEngine()->accessibility_bridge().lock(); PopulateAXTree(bridge); - auto spy = new AccessibilityBridgeDelegateWindowsSpy( view.GetEngine(), &view, view.GetEngine()->accessibility_bridge()); bridge->UpdateDelegate( From 6cd5c6772db791371239e4f8546836d6d8527998 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 4 Oct 2022 01:06:25 -0700 Subject: [PATCH 10/10] Fix build --- .../windows/accessibility_bridge_delegate_windows_unittests.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc b/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc index b98953fd16b7e..1fdc136b55443 100644 --- a/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc +++ b/shell/platform/windows/accessibility_bridge_delegate_windows_unittests.cc @@ -217,7 +217,7 @@ TEST(AccessibilityBridgeDelegateWindows, DispatchAccessibilityAction) { auto spy = new AccessibilityBridgeDelegateWindowsSpy( view.GetEngine(), &view, view.GetEngine()->accessibility_bridge()); bridge->UpdateDelegate( - std::make_unique(spy)); + std::unique_ptr(spy)); PopulateAXTree(bridge); FlutterSemanticsAction actual_action = kFlutterSemanticsActionTap;