// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_VIEWS_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_ #define CHROME_BROWSER_VIEWS_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_ #include #include "base/basictypes.h" #include "base/hash_tables.h" #include "base/singleton.h" #include "base/task.h" #include "chrome/browser/accessibility_events.h" #include "views/view.h" #include "views/widget/root_view.h" class Profile; // Allows us to use (View*) and (FocusManager*) in a hash_map with gcc. #if defined(COMPILER_GCC) namespace __gnu_cxx { template<> struct hash { size_t operator()(views::FocusManager* focus_manager) const { return reinterpret_cast(focus_manager); } }; template<> struct hash { size_t operator()(views::View* view) const { return reinterpret_cast(view); } }; } // namespace __gnu_cxx #endif // defined(COMPILER_GCC) // NOTE: This class is part of the Accessibility Extension API, which lets // extensions receive accessibility events. It's distinct from code that // implements platform accessibility APIs like MSAA or ATK. // // Singleton class that adds listeners to many views, then sends an // accessibility notification whenever a relevant event occurs in an // accessible view. // // Views are not accessible by default. When you register a root widget, // that widget and all of its descendants will start sending accessibility // event notifications. You can then override the default behavior for // specific descendants using other methods. // // You can use Profile::PauseAccessibilityEvents to prevent a flurry // of accessibility events when a window is being created or initialized. class AccessibilityEventRouterViews : public views::FocusChangeListener { public: // Internal information about a particular view to override the // information we get directly from the view. struct ViewInfo { ViewInfo() : ignore(false), focus_manager(NULL) {} // If nonempty, will use this name instead of the view's label. std::string name; // If true, will ignore this widget and not send accessibility events. bool ignore; // The focus manager that this view is part of - saved because // GetFocusManager may not succeed while a view is being deleted. views::FocusManager* focus_manager; }; // Get the single instance of this class. static AccessibilityEventRouterViews* GetInstance(); // Start sending accessibility events for this view and all of its // descendants. Notifications will go to the specified profile. // Returns true on success, false if "view" was already registered. // It is the responsibility of the caller to call RemoveViewTree if // this view is ever deleted; consider using AccessibleViewHelper. bool AddViewTree(views::View* view, Profile* profile); // Stop sending accessibility events for this view and all of its // descendants. void RemoveViewTree(views::View* view); // Don't send any events for this view. void IgnoreView(views::View* view); // Use the following string as the name of this view, instead of the // gtk label associated with the view. void SetViewName(views::View* view, std::string name); // Forget all information about this view. void RemoveView(views::View* view); // Implementation of views::FocusChangeListener: virtual void FocusWillChange( views::View* focused_before, views::View* focused_now); private: // Given a view, determine if it's part of a view tree that's mapped to // a profile and if so, if it's marked as accessible. void FindView(views::View* view, Profile** profile, bool* is_accessible); // Checks the type of the view and calls one of the more specific // Send*Notification methods, below. void DispatchAccessibilityNotification( views::View* view, NotificationType type); // Return the name of a view. std::string GetViewName(views::View* view); // Each of these methods constructs an AccessibilityControlInfo object // and sends a notification of a specific accessibility event. void SendButtonNotification( views::View* view, NotificationType type, Profile* profile); void SendLinkNotification( views::View* view, NotificationType type, Profile* profile); void SendMenuNotification( views::View* view, NotificationType type, Profile* profile); private: AccessibilityEventRouterViews(); virtual ~AccessibilityEventRouterViews(); friend struct DefaultSingletonTraits; // The set of all view tree roots; only descendants of these will generate // accessibility notifications. base::hash_map view_tree_profile_map_; // Extra information about specific views. base::hash_map view_info_map_; // Count of the number of references to each focus manager. base::hash_map focus_manager_ref_count_; // Used to defer handling of some events until the next time // through the event loop. ScopedRunnableMethodFactory method_factory_; }; #endif // CHROME_BROWSER_VIEWS_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_