summaryrefslogtreecommitdiff
path: root/chromium/ui/aura/root_window.h
blob: d905517516390cc032c4a54aeb29978031077136 (plain)
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
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
// 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_

#include <vector>

#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "ui/aura/aura_export.h"
#include "ui/aura/client/capture_delegate.h"
#include "ui/aura/root_window_host_delegate.h"
#include "ui/aura/window.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/events/event_constants.h"
#include "ui/base/events/event_dispatcher.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"
#include "ui/gfx/transform.h"

namespace gfx {
class Size;
class Transform;
}

namespace ui {
class GestureEvent;
class GestureRecognizer;
class KeyEvent;
class LayerAnimationSequence;
class MouseEvent;
class ScrollEvent;
class TouchEvent;
class ViewProp;
}

namespace aura {
class TestScreen;
class RootWindow;
class RootWindowHost;
class RootWindowObserver;
class RootWindowTransformer;

// RootWindow is responsible for hosting a set of windows.
class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
                               public ui::CompositorObserver,
                               public Window,
                               public ui::EventDispatcherDelegate,
                               public ui::GestureEventHelper,
                               public ui::LayerAnimationObserver,
                               public aura::client::CaptureDelegate,
                               public aura::RootWindowHostDelegate {
 public:
  struct AURA_EXPORT CreateParams {
    // CreateParams with initial_bounds and default host in pixel.
    explicit CreateParams(const gfx::Rect& initial_bounds);
    ~CreateParams() {}

    gfx::Rect initial_bounds;

    // A host to use in place of the default one that RootWindow will create.
    // NULL by default.
    RootWindowHost* host;
  };

  explicit RootWindow(const CreateParams& params);
  virtual ~RootWindow();

  // Returns the RootWindowHost for the specified accelerated widget, or NULL
  // if there is none associated.
  static RootWindow* GetForAcceleratedWidget(gfx::AcceleratedWidget widget);

  ui::Compositor* compositor() { return compositor_.get(); }
  gfx::NativeCursor last_cursor() const { return last_cursor_; }
  Window* mouse_pressed_handler() { return mouse_pressed_handler_; }

  // Initializes the root window.
  void Init();

  // Shows the root window host.
  void ShowRootWindow();

  // Hides the root window host.
  void HideRootWindow();

  // Stop listening events in preparation for shutdown.
  void PrepareForShutdown();

  // Repost event for re-processing. Used when exiting context menus.
  void RepostEvent(const ui::LocatedEvent& event);

  RootWindowHostDelegate* AsRootWindowHostDelegate();

  // Gets/sets the size of the host 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_pizel);

  // 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);

  // Invoked when the cursor's visibility has changed.
  void OnCursorVisibilityChanged(bool visible);

  // Invoked when the mouse events get enabled or disabled.
  void OnMouseEventsEnableStateChanged(bool enabled);

  // Moves the cursor to the specified location relative to the root window.
  virtual void MoveCursorTo(const gfx::Point& location) OVERRIDE;

  // Moves the cursor to the |host_location| given in host coordinates.
  void MoveCursorToHostLocation(const gfx::Point& host_location);

  // Clips the cursor movement to the root_window.
  bool ConfineCursorToWindow();

  // Draws the necessary set of windows.
  void Draw();

  // Draw the whole screen.
  void ScheduleFullRedraw();

  // Draw the damage_rect.
  void ScheduleRedrawRect(const gfx::Rect& damage_rect);

  // Returns a target window for the given gesture event.
  Window* GetGestureTarget(ui::GestureEvent* 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(ui::GestureEvent* event);

  // 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);

  // Dispatches OnMouseExited to the |window| which is hiding if nessessary.
  void DispatchMouseExitToHidingWindow(Window* window);

  // Invoked when |window|'s visibility has 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 OnRootWindowHostCloseRequested();

  // 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;

  // Converts |point| from native screen coordinate system to the root window's.
  void ConvertPointFromNativeScreen(gfx::Point* point) const;

  // Converts |point| from the root window's coordinate system to the
  // host window's.
  void ConvertPointToHost(gfx::Point* point) const;

  // Converts |point| from the host window's coordinate system to the
  // root window's.
  void ConvertPointFromHost(gfx::Point* point) const;

  // Gesture Recognition -------------------------------------------------------

  // When a touch event is dispatched to a Window, it may want to process the
  // touch event asynchronously. In such cases, the window should consume the
  // event during the event dispatch. Once the event is properly processed, the
  // window should let the RootWindow know about the result of the event
  // processing, so that gesture events can be properly created and dispatched.
  void ProcessedTouchEvent(ui::TouchEvent* event,
                           Window* window,
                           ui::EventResult result);

  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();

  // Toggles the host's full screen state.
  void ToggleFullScreen();

  // These methods are used to defer the processing of mouse/touch events
  // related to resize. A client (typically a RenderWidgetHostViewAura) can call
  // HoldPointerMoves when an resize is initiated and then ReleasePointerMoves
  // 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 HoldPointerMoves();
  void ReleasePointerMoves();

  // Sets if the window should be focused when shown.
  void SetFocusWhenShown(bool focus_when_shown);

  // Gets the last location seen in a mouse event in this root window's
  // coordinates. This may return a point outside the root window's bounds.
  gfx::Point GetLastMouseLocationInRoot() const;

  // Overridden from Window:
  virtual RootWindow* GetRootWindow() OVERRIDE;
  virtual const RootWindow* GetRootWindow() const OVERRIDE;
  virtual void SetTransform(const gfx::Transform& transform) OVERRIDE;

  // Overridden from ui::EventTarget:
  virtual ui::EventTarget* GetParentTarget() OVERRIDE;

  // Overridden from ui::CompositorDelegate:
  virtual void ScheduleDraw() OVERRIDE;

  // Overridden from ui::CompositorObserver:
  virtual void OnCompositingDidCommit(ui::Compositor*) OVERRIDE;
  virtual void OnCompositingStarted(ui::Compositor*,
                                    base::TimeTicks start_time) OVERRIDE;
  virtual void OnCompositingEnded(ui::Compositor*) OVERRIDE;
  virtual void OnCompositingAborted(ui::Compositor*) OVERRIDE;
  virtual void OnCompositingLockStateChanged(ui::Compositor*) OVERRIDE;
  virtual void OnUpdateVSyncParameters(ui::Compositor* compositor,
                                       base::TimeTicks timebase,
                                       base::TimeDelta interval) OVERRIDE;

  // Overridden from ui::LayerDelegate:
  virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE;

  // Overridden from Window:
  virtual bool CanFocus() const OVERRIDE;
  virtual bool CanReceiveEvents() const OVERRIDE;

  // Overridden from aura::client::CaptureDelegate:
  virtual void UpdateCapture(Window* old_capture, Window* new_capture) OVERRIDE;
  virtual void SetNativeCapture() OVERRIDE;
  virtual void ReleaseNativeCapture() OVERRIDE;

  // Exposes RootWindowHost::QueryMouseLocation() for test purposes.
  bool QueryMouseLocationForTest(gfx::Point* point) const;

  // Clears internal mouse state (such as mouse ups should be sent to the same
  // window that ate mouse downs).
  void ClearMouseHandlers();

  void SetRootWindowTransformer(scoped_ptr<RootWindowTransformer> transformer);
  gfx::Transform GetRootTransform() const;

 private:
  FRIEND_TEST_ALL_PREFIXES(RootWindowTest, KeepTranslatedEventInRoot);

  friend class Window;
  friend class TestScreen;

  // The parameter for OnWindowHidden() to specify why window is hidden.
  enum WindowHiddenReason {
    WINDOW_DESTROYED,  // Window is destroyed.
    WINDOW_HIDDEN,     // Window is hidden.
    WINDOW_MOVING,     // Window is temporarily marked as hidden due to move
                       // across root windows.
  };

  // Updates the event with the appropriate transform for the device scale
  // factor. The RootWindowHostDelegate dispatches events in the physical pixel
  // coordinate. But the event processing from RootWindow onwards happen in
  // device-independent pixel coordinate. So it is necessary to update the event
  // received from the host.
  void TransformEventForDeviceScaleFactor(ui::LocatedEvent* event);

  // Moves the cursor to the specified location. This method is internally used
  // by MoveCursorTo() and MoveCursorToHostLocation().
  void MoveCursorToInternal(const gfx::Point& root_location,
                            const gfx::Point& host_location);

  // Called whenever the mouse moves, tracks the current |mouse_moved_handler_|,
  // sending exited and entered events as its value changes.
  void HandleMouseMoved(const ui::MouseEvent& event, Window* target);

  // Dispatches the specified event type (intended for enter/exit) to the
  // |mouse_moved_handler_|.
  void DispatchMouseEnterOrExit(const ui::MouseEvent& event,
                                ui::EventType type);

  void ProcessEvent(Window* target, ui::Event* 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, RootWindow* new_root);

  // Called when a window becomes invisible, either by being removed
  // from root window hierarchy, via SetVisible(false) or being destroyed.
  // |reason| specifies what triggered the hiding.
  void OnWindowHidden(Window* invisible, WindowHiddenReason reason);

  // Cleans up the gesture recognizer for all windows in |window| (including
  // |window| itself).
  void CleanupGestureRecognizerState(Window* window);

  // Updates the root window's size using |host_size|, current
  // transform and insets.
  void UpdateRootWindowSize(const gfx::Size& host_size);

  // Overridden from ui::EventDispatcherDelegate.
  virtual bool CanDispatchToTarget(EventTarget* target) OVERRIDE;

  // Overridden from ui::GestureEventHelper.
  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 aura::RootWindowHostDelegate:
  virtual bool OnHostKeyEvent(ui::KeyEvent* event) OVERRIDE;
  virtual bool OnHostMouseEvent(ui::MouseEvent* event) OVERRIDE;
  virtual bool OnHostScrollEvent(ui::ScrollEvent* event) OVERRIDE;
  virtual bool OnHostTouchEvent(ui::TouchEvent* event) OVERRIDE;
  virtual void OnHostCancelMode() OVERRIDE;
  virtual void OnHostActivated() OVERRIDE;
  virtual void OnHostLostWindowCapture() OVERRIDE;
  virtual void OnHostLostMouseGrab() OVERRIDE;
  virtual void OnHostPaint(const gfx::Rect& damage_rect) OVERRIDE;
  virtual void OnHostMoved(const gfx::Point& origin) OVERRIDE;
  virtual void OnHostResized(const gfx::Size& size) OVERRIDE;
  virtual float GetDeviceScaleFactor() OVERRIDE;
  virtual RootWindow* AsRootWindow() OVERRIDE;

  // We hold and aggregate mouse drags and touch moves as a way of throttling
  // resizes when HoldMouseMoves() is called. The following methods are used to
  // dispatch held and newly incoming mouse and touch events, typically when an
  // event other than one of these needs dispatching or a matching
  // ReleaseMouseMoves()/ReleaseTouchMoves() is called.  NOTE: because these
  // methods dispatch events from RootWindowHost the coordinates are in terms of
  // the root.
  bool DispatchMouseEventImpl(ui::MouseEvent* event);
  bool DispatchMouseEventRepost(ui::MouseEvent* event);
  bool DispatchMouseEventToTarget(ui::MouseEvent* event, Window* target);
  bool DispatchTouchEventImpl(ui::TouchEvent* event);
  void DispatchHeldEvents();

  // 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();

  gfx::Transform GetInverseRootTransform() const;

  scoped_ptr<ui::Compositor> compositor_;

  scoped_ptr<RootWindowHost> host_;

  // Used to schedule painting.
  base::WeakPtrFactory<RootWindow> schedule_paint_factory_;

  // Use to post mouse move event.
  base::WeakPtrFactory<RootWindow> event_factory_;

  // Touch ids that are currently down.
  uint32 touch_ids_down_;

  // Last cursor set.  Used for testing.
  gfx::NativeCursor last_cursor_;

  ObserverList<RootWindowObserver> observers_;

  Window* mouse_pressed_handler_;
  Window* mouse_moved_handler_;
  Window* mouse_event_dispatch_target_;
  Window* event_dispatch_target_;

  // 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 move holds are outstanding. We try to defer dispatching
  // touch/mouse moves while the count is > 0.
  int move_hold_count_;
  // Used to schedule DispatchHeldEvents() when |move_hold_count_| goes to 0.
  base::WeakPtrFactory<RootWindow> held_event_factory_;
  scoped_ptr<ui::LocatedEvent> held_move_event_;

  // Allowing for reposting of events. Used when exiting context menus.
  scoped_ptr<ui::LocatedEvent>  held_repostable_event_;
  base::WeakPtrFactory<RootWindow> repostable_event_factory_;

  scoped_ptr<ui::ViewProp> prop_;

  scoped_ptr<RootWindowTransformer> transformer_;

  DISALLOW_COPY_AND_ASSIGN(RootWindow);
};

}  // namespace aura

#endif  // UI_AURA_ROOT_WINDOW_H_