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
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
|
// Copyright (c) 2012 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 UI_AURA_ROOT_WINDOW_H_
#define UI_AURA_ROOT_WINDOW_H_
#pragma once
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop.h"
#include "ui/aura/aura_export.h"
#include "ui/aura/focus_manager.h"
#include "ui/aura/window.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/events.h"
#include "ui/base/gestures/gesture_recognizer.h"
#include "ui/base/gestures/gesture_types.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/compositor_observer.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/point.h"
namespace gfx {
class Size;
}
namespace ui {
class GestureRecognizer;
class LayerAnimationSequence;
class Transform;
}
namespace aura {
class RootWindow;
class RootWindowHost;
class RootWindowObserver;
class KeyEvent;
class MouseEvent;
class StackingClient;
class ScrollEvent;
class TouchEvent;
class GestureEvent;
// This class represents a lock on the compositor, that can be used to prevent a
// compositing pass from happening while we're waiting for an asynchronous
// event. The typical use case is when waiting for a renderer to produce a frame
// at the right size. The caller keeps a reference on this object, and drops the
// reference once it desires to release the lock.
// Note however that the lock is canceled after a short timeout to ensure
// responsiveness of the UI, so the compositor tree should be kept in a
// "reasonable" state while the lock is held.
// Don't instantiate this class directly, use RootWindow::GetCompositorLock.
class AURA_EXPORT CompositorLock :
public base::RefCounted<CompositorLock>,
public base::SupportsWeakPtr<CompositorLock> {
public:
~CompositorLock();
private:
friend class RootWindow;
CompositorLock(RootWindow* root_window);
void CancelLock();
RootWindow* root_window_;
DISALLOW_COPY_AND_ASSIGN(CompositorLock);
};
// RootWindow is responsible for hosting a set of windows.
class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
public ui::CompositorObserver,
public Window,
public internal::FocusManager,
public ui::GestureEventHelper,
public ui::LayerAnimationObserver {
public:
explicit RootWindow(const gfx::Rect& initial_bounds);
virtual ~RootWindow();
static void set_hide_host_cursor(bool hide) {
hide_host_cursor_ = hide;
}
static bool hide_host_cursor() {
return hide_host_cursor_;
}
ui::Compositor* compositor() { return compositor_.get(); }
gfx::Point last_mouse_location() const { return last_mouse_location_; }
gfx::NativeCursor last_cursor() const { return last_cursor_; }
bool cursor_shown() const { return cursor_shown_; }
Window* mouse_pressed_handler() { return mouse_pressed_handler_; }
Window* capture_window() { return capture_window_; }
Window* focused_window() { return focused_window_; }
// Initializes the root window.
void Init();
// Shows the root window host.
void ShowRootWindow();
// Sets the size of the root window.
void SetHostSize(const gfx::Size& size_in_pixel);
gfx::Size GetHostSize() const;
// Sets the bounds of the host window.
void SetHostBounds(const gfx::Rect& size_in_pixel);
// Returns where the RootWindow is on screen.
gfx::Point GetHostOrigin() const;
// Sets the currently-displayed cursor. If the cursor was previously hidden
// via ShowCursor(false), it will remain hidden until ShowCursor(true) is
// called, at which point the cursor that was last set via SetCursor() will be
// used.
void SetCursor(gfx::NativeCursor cursor);
// Shows or hides the cursor.
void ShowCursor(bool show);
// Moves the cursor to the specified location relative to the root window.
void MoveCursorTo(const gfx::Point& location);
// Clips the cursor movement to |capture_window_|. Should be invoked only
// after SetCapture(). ReleaseCapture() implicitly removes any confines set
// using this function. Returns true if successful.
bool ConfineCursorToWindow();
// Draws the necessary set of windows.
void Draw();
// Draw the whole screen.
void ScheduleFullDraw();
// Handles a mouse event. Returns true if handled.
bool DispatchMouseEvent(MouseEvent* event);
// Handles a key event. Returns true if handled.
bool DispatchKeyEvent(KeyEvent* event);
// Handles a scroll event. Returns true if handled.
bool DispatchScrollEvent(ScrollEvent* event);
// Handles a touch event. Returns true if handled.
bool DispatchTouchEvent(TouchEvent* event);
// Handles a gesture event. Returns true if handled. Unlike the other
// event-dispatching function (e.g. for touch/mouse/keyboard events), gesture
// events are dispatched from GestureRecognizer instead of RootWindowHost.
bool DispatchGestureEvent(GestureEvent* event);
// Called when the host changes size.
void OnHostResized(const gfx::Size& size_in_pixel);
// Invoked when |window| is being destroyed.
void OnWindowDestroying(Window* window);
// Invoked when |window|'s bounds have changed. |contained_mouse| indicates if
// the bounds before change contained the |last_moust_location()|.
void OnWindowBoundsChanged(Window* window, bool contained_mouse);
// Invoked when |window|'s visibility is changed.
void OnWindowVisibilityChanged(Window* window, bool is_visible);
// Invoked when |window|'s tranfrom has changed. |contained_mouse|
// indicates if the bounds before change contained the
// |last_moust_location()|.
void OnWindowTransformed(Window* window, bool contained_mouse);
// Invoked when the keyboard mapping (in X11 terms: the mapping between
// keycodes and keysyms) has changed.
void OnKeyboardMappingChanged();
// The system windowing system has sent a request that we close our window.
void OnRootWindowHostClosed();
// Add/remove observer. There is no need to remove the observer if
// the root window is being deleted. In particular, you SHOULD NOT remove
// in |WindowObserver::OnWindowDestroying| of the observer observing
// the root window because it is too late to remove it.
void AddRootWindowObserver(RootWindowObserver* observer);
void RemoveRootWindowObserver(RootWindowObserver* observer);
// Posts |native_event| to the platform's event queue.
void PostNativeEvent(const base::NativeEvent& native_event);
// Converts |point| from the root window's coordinate system to native
// screen's.
void ConvertPointToNativeScreen(gfx::Point* point) const;
// Capture -------------------------------------------------------------------
// Sets capture to the specified window.
void SetCapture(Window* window);
// If |window| has capture, the current capture window is set to NULL.
void ReleaseCapture(Window* window);
// Gesture Recognition -------------------------------------------------------
// When a touch event is dispatched to a Window, it can notify the RootWindow
// to queue the touch event for asynchronous gesture recognition. These are
// the entry points for the asynchronous processing of the queued touch
// events.
// Process the next touch event for gesture recognition. |processed| indicates
// whether the queued event was processed by the window or not.
void AdvanceQueuedTouchEvent(Window* window, bool processed);
ui::GestureRecognizer* gesture_recognizer() const {
return gesture_recognizer_.get();
}
// Provided only for testing:
void SetGestureRecognizerForTesting(ui::GestureRecognizer* gr);
// Returns the accelerated widget from the RootWindowHost.
gfx::AcceleratedWidget GetAcceleratedWidget();
#if !defined(NDEBUG)
// Toggles the host's full screen state.
void ToggleFullScreen();
#endif
// These methods are used to defer the processing of mouse events related
// to resize. A client (typically a RenderWidgetHostViewAura) can call
// HoldMouseMoves when an resize is initiated and then ReleaseMouseMoves
// once the resize is completed.
//
// More than one hold can be invoked and each hold must be cancelled by a
// release before we resume normal operation.
void HoldMouseMoves();
void ReleaseMouseMoves();
// Creates a compositor lock.
scoped_refptr<CompositorLock> GetCompositorLock();
// Sets if the window should be focused when shown.
void SetFocusWhenShown(bool focus_when_shown);
// Overridden from Window:
virtual RootWindow* GetRootWindow() OVERRIDE;
virtual const RootWindow* GetRootWindow() const OVERRIDE;
virtual void SetTransform(const ui::Transform& transform) OVERRIDE;
// Overridden from ui::CompositorDelegate:
virtual void ScheduleDraw() OVERRIDE;
// Overridden from ui::CompositorObserver:
virtual void OnCompositingStarted(ui::Compositor*) OVERRIDE;
virtual void OnCompositingEnded(ui::Compositor*) OVERRIDE;
private:
friend class Window;
friend class CompositorLock;
// Called whenever the mouse moves, tracks the current |mouse_moved_handler_|,
// sending exited and entered events as its value changes.
void HandleMouseMoved(const MouseEvent& event, Window* target);
// Called whenever the |capture_window_| changes.
// Sends capture changed events to event filters for old capture window.
void HandleMouseCaptureChanged(Window* old_capture_window);
bool ProcessMouseEvent(Window* target, MouseEvent* event);
bool ProcessKeyEvent(Window* target, KeyEvent* event);
ui::TouchStatus ProcessTouchEvent(Window* target, TouchEvent* event);
ui::GestureStatus ProcessGestureEvent(Window* target, GestureEvent* event);
bool ProcessGestures(ui::GestureRecognizer::Gestures* gestures);
// Called when a Window is attached or detached from the RootWindow.
void OnWindowAddedToRootWindow(Window* window);
void OnWindowRemovedFromRootWindow(Window* window);
// Called when a window becomes invisible, either by being removed
// from root window hierachy, via SetVisible(false) or being destroyed.
// |destroyed| is set to true when the window is being destroyed.
void OnWindowHidden(Window* invisible, bool destroyed);
// Overridden from Window:
virtual bool CanFocus() const OVERRIDE;
virtual bool CanReceiveEvents() const OVERRIDE;
virtual internal::FocusManager* GetFocusManager() OVERRIDE;
// Overridden from ui::GestureEventHelper.
virtual ui::GestureEvent* CreateGestureEvent(ui::EventType type,
const gfx::Point& location,
int flags,
const base::Time time,
float param_first,
float param_second,
unsigned int touch_id_bitfield) OVERRIDE;
virtual ui::TouchEvent* CreateTouchEvent(ui::EventType type,
const gfx::Point& location,
int touch_id,
base::TimeDelta time_stamp) OVERRIDE;
virtual bool DispatchLongPressGestureEvent(ui::GestureEvent* event) OVERRIDE;
virtual bool DispatchCancelTouchEvent(ui::TouchEvent* event) OVERRIDE;
// Overridden from ui::LayerAnimationObserver:
virtual void OnLayerAnimationEnded(
ui::LayerAnimationSequence* animation) OVERRIDE;
virtual void OnLayerAnimationScheduled(
ui::LayerAnimationSequence* animation) OVERRIDE;
virtual void OnLayerAnimationAborted(
ui::LayerAnimationSequence* animation) OVERRIDE;
// Overridden from FocusManager:
virtual void SetFocusedWindow(Window* window,
const aura::Event* event) OVERRIDE;
virtual Window* GetFocusedWindow() OVERRIDE;
virtual bool IsFocusedWindow(const Window* window) const OVERRIDE;
// We hold and aggregate mouse drags as a way of throttling resizes when
// HoldMouseMoves() is called. The following methods are used to dispatch held
// and newly incoming mouse events, typically when an event other than a mouse
// drag needs dispatching or a matching ReleaseMouseMoves() is called.
// NOTE: because these methods dispatch events from RootWindowHost the
// coordinates are in terms of the root.
bool DispatchMouseEventImpl(MouseEvent* event);
bool DispatchMouseEventToTarget(MouseEvent* event, Window* target);
void DispatchHeldMouseMove();
// Parses the switch describing the initial size for the host window and
// returns bounds for the window.
gfx::Rect GetInitialHostWindowBounds() const;
// Posts a task to send synthesized mouse move event if there
// is no a pending task.
void PostMouseMoveEventAfterWindowChange();
// Creates and dispatches synthesized mouse move event using the
// current mouse location.
void SynthesizeMouseMoveEvent();
// Called by CompositorLock.
void UnlockCompositor();
scoped_ptr<ui::Compositor> compositor_;
scoped_ptr<RootWindowHost> host_;
// If set before the RootWindow is created, the cursor will be drawn within
// the Aura root window but hidden outside of it, and it'll remain hidden
// after the Aura window is closed.
static bool hide_host_cursor_;
// Used to schedule painting.
base::WeakPtrFactory<RootWindow> schedule_paint_factory_;
// Use to post mouse move event.
base::WeakPtrFactory<RootWindow> event_factory_;
// Last location seen in a mouse event.
gfx::Point last_mouse_location_;
// ui::EventFlags containing the current state of the mouse buttons.
int mouse_button_flags_;
// Last cursor set. Used for testing.
gfx::NativeCursor last_cursor_;
// Is the cursor currently shown? Used for testing.
bool cursor_shown_;
ObserverList<RootWindowObserver> observers_;
// The capture window. When not-null, this window receives all the mouse and
// touch events.
Window* capture_window_;
Window* mouse_pressed_handler_;
Window* mouse_moved_handler_;
Window* focused_window_;
// The gesture_recognizer_ for this.
scoped_ptr<ui::GestureRecognizer> gesture_recognizer_;
bool synthesize_mouse_move_;
bool waiting_on_compositing_end_;
bool draw_on_compositing_end_;
bool defer_draw_scheduling_;
// How many holds are outstanding. We try to defer dispatching mouse moves
// while the count is > 0.
int mouse_move_hold_count_;
bool should_hold_mouse_moves_;
scoped_ptr<MouseEvent> held_mouse_move_;
CompositorLock* compositor_lock_;
bool draw_on_compositor_unlock_;
int draw_trace_count_;
DISALLOW_COPY_AND_ASSIGN(RootWindow);
};
} // namespace aura
#endif // UI_AURA_ROOT_WINDOW_H_
|