1 // Copyright 2018 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef UI_BASE_COCOA_ACCESSIBILITY_FOCUS_OVERRIDER_H_ 6 #define UI_BASE_COCOA_ACCESSIBILITY_FOCUS_OVERRIDER_H_ 7 8 #include "ui/base/ui_base_export.h" 9 10 namespace ui { 11 12 // This object is used to enable cross-process accessibility focus querying. 13 // 14 // The following bullet points describe the need for this class: 15 // * The NSViews in out-of-process NSViews (e.g, for PWAs) will return a 16 // NSRemoteAccessibilityElement from -[NSView accessibilityFocusedUIElement]. 17 // * The focus query is then continued in the browser process by a call to 18 // -[NSApplication accessibilityFocusedUIElement]. 19 // * The default implementation -[NSApplication accessibilityFocusedUIElement] 20 // in turn queries -[NSApplication keyWindow]'s accessibilityFocusedUIElement 21 // method. 22 // * This is not what the PWA process wants. The PWA process wants its focus, 23 // not the browser's focus. 24 // * To make this happen, when the PWA process' NSViews are focused, they 25 // force the browser's -[NSApplication accessibilityFocusedUIElement] to 26 // return their accessibility focus. 27 // 28 // The above-required overriding of focus is done by instantiating an 29 // AccessibilityFocusOverrider and updating its state when the NSView in the 30 // PWA process is focused. 31 class UI_BASE_EXPORT AccessibilityFocusOverrider { 32 public: 33 class Client { 34 public: 35 virtual id GetAccessibilityFocusedUIElement() = 0; 36 }; 37 38 AccessibilityFocusOverrider(Client* client); 39 ~AccessibilityFocusOverrider(); 40 41 // Indicate if the NSApplication that is viewing this element is not this 42 // process. Focus overriding is only needed for cross-process focus. 43 void SetAppIsRemote(bool app_is_remote); 44 45 // Indicate whether or not the view's window is currently key. This object 46 // will override the application's focused accessibility element only if its 47 // window is key (and the view is the window's first responder). 48 void SetWindowIsKey(bool window_is_key); 49 50 // Indicate whether or not the view is its window's first responder. This 51 // object will override the application's focused accessibility element only 52 // if the view is the window's first responder (and its window is key). 53 void SetViewIsFirstResponder(bool view_is_first_responder); 54 55 // Return the overridden focus, or nil if there is no overridden focus. 56 static id GetFocusedUIElement(); 57 58 private: 59 void UpdateOverriddenKeyElement(); 60 bool app_is_remote_ = false; 61 bool window_is_key_ = false; 62 bool view_is_first_responder_ = false; 63 Client* const client_; 64 }; 65 66 } // namespace ui 67 68 #endif // UI_BASE_COCOA_ACCESSIBILITY_FOCUS_OVERRIDER_H_ 69