File: docked_magnifier_controller.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (232 lines) | stat: -rw-r--r-- 9,213 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef ASH_ACCESSIBILITY_MAGNIFIER_DOCKED_MAGNIFIER_CONTROLLER_H_
#define ASH_ACCESSIBILITY_MAGNIFIER_DOCKED_MAGNIFIER_CONTROLLER_H_

#include <memory>

#include "ash/ash_export.h"
#include "ash/public/cpp/session/session_observer.h"
#include "base/memory/raw_ptr.h"
#include "base/timer/timer.h"
#include "ui/base/cursor/cursor_size.h"
#include "ui/display/manager/display_manager_observer.h"
#include "ui/events/event_handler.h"
#include "ui/views/widget/widget_observer.h"

class PrefRegistrySimple;
class PrefService;
class PrefChangeRegistrar;

namespace aura {
class Window;
class WindowTreeHost;
}  // namespace aura

namespace ui {
class Layer;
}  // namespace ui

namespace views {
class Widget;
}  // namespace views

namespace ash {

// Controls the Docked Magnifier (a.k.a. picture-in-picture magnifier) feature,
// which allocates the top portion of the currently active display as a
// magnified viewport of an area around the point of interest in the screen
// (which follows the cursor location, text input caret location, or focus
// changes). In a multiple display scenario, the magnifier viewport is located
// on the same display as that of the point of interest.
class ASH_EXPORT DockedMagnifierController
    : public SessionObserver,
      public ui::EventHandler,
      public views::WidgetObserver,
      public display::DisplayManagerObserver {
 public:
  DockedMagnifierController();
  DockedMagnifierController(const DockedMagnifierController&) = delete;
  DockedMagnifierController& operator=(const DockedMagnifierController&) =
      delete;
  ~DockedMagnifierController() override;

  // The height of the black separator layer between the magnifier viewport and
  // the rest of the screen.
  static constexpr int kSeparatorHeight = 10;

  // The default value by which the screen height is divided to calculate the
  // height of the magnifier viewport.
  static constexpr float kDefaultScreenHeightDivisor = 3.0f;

  static void RegisterProfilePrefs(PrefRegistrySimple* registry);

  // Get the Docked Magnifier settings for the current active user prefs.
  bool GetEnabled() const;
  float GetScale() const;
  float GetScreenHeightDivisor() const;

  // Set the Docked Magnifier settings in the current active user prefs.
  void SetEnabled(bool enabled);
  void SetScale(float scale);
  void SetScreenHeightDivisor(float screen_height_divisor);

  // Maps the current scale value to an index in the range between the minimum
  // and maximum scale values, and steps up or down the scale depending on the
  // value of |delta_index|.
  void StepToNextScaleValue(int delta_index);

  void CenterOnPoint(const gfx::Point& point_in_screen);
  void MoveMagnifierToRect(const gfx::Rect& rect_in_screen);
  int GetMagnifierHeightForTesting() const;

  // ash::SessionObserver:
  void OnActiveUserPrefServiceChanged(PrefService* pref_service) override;
  void OnSigninScreenPrefServiceInitialized(PrefService* prefs) override;

  // ui::EventHandler:
  void OnMouseEvent(ui::MouseEvent* event) override;
  void OnScrollEvent(ui::ScrollEvent* event) override;
  void OnTouchEvent(ui::TouchEvent* event) override;

  // views::WidgetObserver:
  void OnWidgetDestroying(views::Widget* widget) override;

  // display::DisplayManagerObserver:
  void OnDidApplyDisplayChanges() override;

  // Getters and setters of the enabled status of the Fullscreen Magnifier.
  // We need these so that we can guarantee that both magnifiers are mutually
  // exclusive (i.e. only one can be on at the same time).
  // Note: We can't use the ash::MagnificationController since it's not hooked
  // to the associated user-prefs except when Chrome is running (via
  // MagnificationManager), so we can't assert this behavior in ash_unittests.
  // Keep them public for now.
  // TODO(afakhry): Refactor the Fullscreen Magnifier and remove these
  // functions. https://crbug.com/817157.
  bool GetFullscreenMagnifierEnabled() const;
  void SetFullscreenMagnifierEnabled(bool enabled);

  // Returns the total height of the Docked Magnifier, which is the height of
  // the viewport widget plus the height of the separator, if enabled, or zero
  // if disabled.
  int GetTotalMagnifierHeight() const;

  // Returns the total bounds of the magnifier region (i.e. magnifier viewport
  // plus the separator) if the magnifier is shown for the given |root|. Returns
  // empty bounds otherwise.
  gfx::Rect GetTotalMagnifierBoundsForRoot(aura::Window* root) const;

  const views::Widget* GetViewportWidgetForTesting() const;

  const ui::Layer* GetViewportMagnifierLayerForTesting() const;

  float GetMinimumPointOfInterestHeightForTesting() const;

 private:
  // If user has large cursor enabled, don't change the cursor size.
  // Otherwise, set the cursor to be the specified size.
  void MaybeSetCursorSize(ui::CursorSize cursor_size);

  // If user is starting or continuing to drag the separator, move the
  // separator and resize the viewport.
  void MaybePerformViewportResizing(ui::MouseEvent* event);

  // Resets the large docked magnifier viewport resizing cursor if
  // it was locked because it was over the separator.
  void MaybeResetResizingCursor();

  // Switches the current source root window to |new_root_window| if it's
  // different than |current_source_root_window_|, destroys (if any) old
  // viewport layers and widgets, and recreates them if |new_root_window| is not
  // |nullptr|.
  // In the event of a display removal in which the magnifier viewport was
  // resident, use |update_old_root_workarea = true| to avoid updating the
  // workarea of a removed display which involves re-layout of the shelf which
  // may have been destroyed.
  void SwitchCurrentSourceRootWindowIfNeeded(aura::Window* new_root_window,
                                             bool update_old_root_workarea);

  void InitFromUserPrefs();

  // Handlers of prefs changes.
  void OnEnabledPrefChanged();
  void OnScalePrefChanged();
  void OnFullscreenMagnifierEnabledPrefChanged();

  void Refresh();

  void NotifyClientWithStatusChanged();

  void CreateMagnifierViewport();

  // Whenever there's a change that affects the screen size, rotation, the
  // current root window or the scale of the magnified view, this function is
  // used to recalculate (if needed) minimum height of the point of interest,
  // which is used to avoid translating the magnifier layer such that magnifier
  // viewport shows a magnified version of itself.
  void MaybeCachePointOfInterestMinimumHeight(aura::WindowTreeHost* host);

  // Prevents the mouse cursor from being able to enter inside the magnifier
  // viewport.
  void ConfineMouseCursorOutsideViewport();

  // Invoked when |move_magnifier_timer_| fires to move the magnifier window to
  // follow the caret.
  void OnMoveMagnifierTimer();

  // Whether or not user has started resizing the Docked Magnifier.
  bool is_resizing_ = false;

  // Vertical offset from user's mouse cursor to the top of separator. Stored to
  // later compute how far offset the new separator position should be based on
  // location user initially clicked separator.
  int resize_offset_ = 0;

  // The current root window of the source display from which we are reflecting
  // and magnifying into the viewport. It is set to |nullptr| when the magnifier
  // is disabled. The viewport is placed on the same display.
  raw_ptr<aura::Window> current_source_root_window_ = nullptr;

  // The height below which the point of interest is not allowed to go. This is
  // so that we can avoid mirroring the magnifier viewport into itself.
  float minimum_point_of_interest_height_ = 0.0f;

  // Indicates the the above value is valid and doesn't need to be recalculated.
  bool is_minimum_point_of_interest_height_valid_ = false;

  // Indicates cursor is locked, because cursor has moved over separator.
  bool is_cursor_locked_ = false;

  // The viewport widget which occupies the top 1/4th of the current display on
  // which it is shown. It contains all the magnifier related layer.
  raw_ptr<views::Widget> viewport_widget_ = nullptr;

  // A solid color layer that shows a dark gray background behind the magnifier
  // layer.
  std::unique_ptr<ui::Layer> viewport_background_layer_;

  // The layer into which the current display's compositor is reflected and
  // magnified. It is transformed such that only the area around the point of
  // interest shows up in the viewport.
  std::unique_ptr<ui::Layer> viewport_magnifier_layer_;

  // A solid color layer that shows a black line separating the magnifier
  // viewport from the rest of the display contents.
  std::unique_ptr<ui::Layer> separator_layer_;

  // The pref service of the currently active user. Can be null in
  // ash_unittests.
  raw_ptr<PrefService> active_user_pref_service_ = nullptr;

  std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;

  // Timer for moving magnifier window when it fires.
  base::OneShotTimer move_magnifier_timer_;
};

}  // namespace ash

#endif  // ASH_ACCESSIBILITY_MAGNIFIER_DOCKED_MAGNIFIER_CONTROLLER_H_