window_targeter.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // Copyright (c) 2013 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. #ifndef UI_AURA_WINDOW_TARGETER_H_
  5. #define UI_AURA_WINDOW_TARGETER_H_
  6. #include <memory>
  7. #include <vector>
  8. #include "base/memory/raw_ptr.h"
  9. #include "ui/aura/aura_export.h"
  10. #include "ui/events/event_targeter.h"
  11. #include "ui/gfx/geometry/insets.h"
  12. namespace gfx {
  13. class Point;
  14. class Rect;
  15. }
  16. namespace ui {
  17. class LocatedEvent;
  18. } // namespace ui
  19. namespace aura {
  20. class Window;
  21. class AURA_EXPORT WindowTargeter : public ui::EventTargeter {
  22. public:
  23. WindowTargeter();
  24. WindowTargeter(const WindowTargeter&) = delete;
  25. WindowTargeter& operator=(const WindowTargeter&) = delete;
  26. ~WindowTargeter() override;
  27. using HitTestRects = std::vector<gfx::Rect>;
  28. // Returns true if |window| or one of its descendants can be a target of
  29. // |event|. This requires that |window| and its descendants are not
  30. // prohibited from accepting the event, and that the event is within an
  31. // actionable region of the target's bounds. Note that the location etc. of
  32. // |event| is in |window|'s parent's coordinate system.
  33. virtual bool SubtreeShouldBeExploredForEvent(Window* window,
  34. const ui::LocatedEvent& event);
  35. // Returns true if the |target| is accepting LocatedEvents, false otherwise.
  36. // |hit_test_rect_mouse| and |hit_test_rect_touch| must be not null and return
  37. // the bounds that can be used for hit testing. The default implementation
  38. // extends the |target|'s |bounds()| by insets provided with SetInsets().
  39. // This can be used to extend the hit-test area for touch events and make
  40. // targeting windows with imprecise input devices easier.
  41. // Returned rectangles are in |target|'s parent's coordinates.
  42. virtual bool GetHitTestRects(Window* target,
  43. gfx::Rect* hit_test_rect_mouse,
  44. gfx::Rect* hit_test_rect_touch) const;
  45. // Returns additional hit-test areas or nullptr when there are none. Used when
  46. // a window needs a complex shape hit-test area. This additional area is
  47. // clipped to |hit_test_rect_mouse| returned by GetHitTestRects or the window
  48. // bounds when GetHitTestRects is not overridden.
  49. // Returned rectangles are in |target|'s coordinates.
  50. virtual std::unique_ptr<HitTestRects> GetExtraHitTestShapeRects(
  51. Window* target) const;
  52. // Sets additional mouse and touch insets that are factored into the hit-test
  53. // regions returned by GetHitTestRects.
  54. void SetInsets(const gfx::Insets& mouse_and_touch_extend);
  55. void SetInsets(const gfx::Insets& mouse_extend,
  56. const gfx::Insets& touch_extend);
  57. // If there is a target that takes priority over normal WindowTargeter (such
  58. // as a capture window) this returns it.
  59. Window* GetPriorityTargetInRootWindow(Window* root_window,
  60. const ui::LocatedEvent& event);
  61. Window* FindTargetInRootWindow(Window* root_window,
  62. const ui::LocatedEvent& event);
  63. // If |target| is not a child of |root_window|, then converts |event| to
  64. // be relative to |root_window| and dispatches the event to |root_window|.
  65. // Returns false if the |target| is a child of |root_window|.
  66. bool ProcessEventIfTargetsDifferentRootWindow(Window* root_window,
  67. Window* target,
  68. ui::Event* event);
  69. // ui::EventTargeter:
  70. ui::EventTarget* FindTargetForEvent(ui::EventTarget* root,
  71. ui::Event* event) override;
  72. ui::EventTarget* FindNextBestTarget(ui::EventTarget* previous_target,
  73. ui::Event* event) override;
  74. Window* FindTargetForKeyEvent(Window* root_window);
  75. protected:
  76. aura::Window* window() { return window_; }
  77. const aura::Window* window() const { return window_; }
  78. // This is called by Window when the targeter is set on a window.
  79. virtual void OnInstalled(Window* window);
  80. // Same as FindTargetForEvent(), but used for positional events. The location
  81. // etc. of |event| are in |window|'s coordinate system. When finding the
  82. // target for the event, the targeter can mutate the |event| (e.g. change the
  83. // coordinate to be in the returned target's coordinate system) so that it can
  84. // be dispatched to the target without any further modification.
  85. virtual Window* FindTargetForLocatedEvent(Window* window,
  86. ui::LocatedEvent* event);
  87. // Returns false if neither |window| nor any of its descendants are allowed
  88. // to accept |event| for reasons unrelated to the event's location or the
  89. // target's bounds. For example, overrides of this function may consider
  90. // attributes such as the visibility or enabledness of |window|. Note that
  91. // the location etc. of |event| is in |window|'s parent's coordinate system.
  92. virtual bool SubtreeCanAcceptEvent(Window* window,
  93. const ui::LocatedEvent& event) const;
  94. // Returns whether the location of the event is in an actionable region of the
  95. // target. Note that the location etc. of |event| is in the |window|'s
  96. // parent's coordinate system.
  97. virtual bool EventLocationInsideBounds(Window* target,
  98. const ui::LocatedEvent& event) const;
  99. // Returns true if the hit testing (GetHitTestRects()) should use the
  100. // extended bounds.
  101. virtual bool ShouldUseExtendedBounds(const aura::Window* w) const;
  102. const gfx::Insets& mouse_extend() const { return mouse_extend_; }
  103. const gfx::Insets& touch_extend() const { return touch_extend_; }
  104. static gfx::Point ConvertEventLocationToWindowCoordinates(
  105. Window* window,
  106. const ui::LocatedEvent& event);
  107. private:
  108. // To call OnInstalled().
  109. friend class Window;
  110. enum class BoundsType {
  111. kMouse,
  112. kTouch,
  113. kGesture,
  114. };
  115. Window* FindTargetForNonKeyEvent(Window* root_window, ui::Event* event);
  116. Window* FindTargetForLocatedEventRecursively(Window* root_window,
  117. ui::LocatedEvent* event);
  118. // Whether |point| is inside |window| or its descendents using |bounds_type|
  119. // as a rect source. |point| should be relative to |window|.
  120. bool PointInsideBounds(Window* window,
  121. BoundsType bounds_type,
  122. const gfx::Point& point) const;
  123. // The Window this WindowTargeter is installed on. Null if not attached to a
  124. // Window.
  125. raw_ptr<aura::Window> window_ = nullptr;
  126. gfx::Insets mouse_extend_;
  127. gfx::Insets touch_extend_;
  128. };
  129. } // namespace aura
  130. #endif // UI_AURA_WINDOW_TARGETER_H_