Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/nsView.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#ifndef nsView_h__
7
#define nsView_h__
8
9
#include "nsCoord.h"
10
#include "nsRect.h"
11
#include "nsPoint.h"
12
#include "nsRegion.h"
13
#include "nsCRT.h"
14
#include "nsCOMPtr.h"
15
#include "nsWidgetInitData.h" // for nsWindowType
16
#include "nsIWidgetListener.h"
17
#include "Units.h"
18
#include "mozilla/EventForwards.h"
19
20
class nsViewManager;
21
class nsIWidget;
22
class nsIFrame;
23
24
// Enumerated type to indicate the visibility of a layer.
25
// hide - the layer is not shown.
26
// show - the layer is shown irrespective of the visibility of
27
//        the layer's parent.
28
enum nsViewVisibility {
29
  nsViewVisibility_kHide = 0,
30
  nsViewVisibility_kShow = 1
31
};
32
33
// Public view flags
34
35
// Indicates that the view is using auto z-indexing
36
#define NS_VIEW_FLAG_AUTO_ZINDEX          0x0004
37
38
// Indicates that the view is a floating view.
39
#define NS_VIEW_FLAG_FLOATING             0x0008
40
41
//----------------------------------------------------------------------
42
43
/**
44
 * View interface
45
 *
46
 * Views are NOT reference counted. Use the Destroy() member function to
47
 * destroy a view.
48
 *
49
 * The lifetime of the view hierarchy is bounded by the lifetime of the
50
 * view manager that owns the views.
51
 *
52
 * Most of the methods here are read-only. To set the corresponding properties
53
 * of a view, go through nsViewManager.
54
 */
55
56
class nsView final : public nsIWidgetListener
57
{
58
public:
59
  friend class nsViewManager;
60
61
  typedef mozilla::LayoutDeviceIntRect LayoutDeviceIntRect;
62
  typedef mozilla::LayoutDeviceIntRegion LayoutDeviceIntRegion;
63
64
  void operator delete(void* ptr) {
65
    ::operator delete(ptr);
66
  }
67
68
  /**
69
   * Get the view manager which "owns" the view.
70
   * This method might require some expensive traversal work in the future. If you can get the
71
   * view manager from somewhere else, do that instead.
72
   * @result the view manager
73
   */
74
  nsViewManager* GetViewManager() const { return mViewManager; }
75
76
  /**
77
   * Find the view for the given widget, if there is one.
78
   * @return the view the widget belongs to, or null if the widget doesn't
79
   * belong to any view.
80
   */
81
  static nsView* GetViewFor(nsIWidget* aWidget);
82
83
  /**
84
   * Destroy the view.
85
   *
86
   * The view destroys its child views, and destroys and releases its
87
   * widget (if it has one).
88
   *
89
   * Also informs the view manager that the view is destroyed by calling
90
   * SetRootView(NULL) if the view is the root view and calling RemoveChild()
91
   * otherwise.
92
   */
93
  void Destroy();
94
95
  /**
96
   * Called to get the position of a view.
97
   * The specified coordinates are relative to the parent view's origin, but
98
   * are in appunits of this.
99
   * This is the (0, 0) origin of the coordinate space established by this view.
100
   * @param x out parameter for x position
101
   * @param y out parameter for y position
102
   */
103
  nsPoint GetPosition() const {
104
    NS_ASSERTION(!IsRoot() || (mPosX == 0 && mPosY == 0),
105
                 "root views should always have explicit position of (0,0)");
106
    return nsPoint(mPosX, mPosY);
107
  }
108
109
  /**
110
   * Called to get the dimensions and position of the view's bounds.
111
   * The view's bounds (x,y) are relative to the origin of the parent view, but
112
   * are in appunits of this.
113
   * The view's bounds (x,y) might not be the same as the view's position,
114
   * if the view has content above or to the left of its origin.
115
   * @param aBounds out parameter for bounds
116
   */
117
0
  nsRect GetBounds() const { return mDimBounds; }
118
119
  /**
120
   * The bounds of this view relative to this view. So this is the same as
121
   * GetBounds except this is relative to this view instead of the parent view.
122
   */
123
  nsRect GetDimensions() const {
124
    nsRect r = mDimBounds; r.MoveBy(-mPosX, -mPosY); return r;
125
  }
126
127
  /**
128
   * Get the offset between the coordinate systems of |this| and aOther.
129
   * Adding the return value to a point in the coordinate system of |this|
130
   * will transform the point to the coordinate system of aOther.
131
   *
132
   * The offset is expressed in appunits of |this|. So if you are getting the
133
   * offset between views in different documents that might have different
134
   * appunits per devpixel ratios you need to be careful how you use the
135
   * result.
136
   *
137
   * If aOther is null, this will return the offset of |this| from the
138
   * root of the viewmanager tree.
139
   *
140
   * This function is fastest when aOther is an ancestor of |this|.
141
   *
142
   * NOTE: this actually returns the offset from aOther to |this|, but
143
   * that offset is added to transform _coordinates_ from |this| to aOther.
144
   */
145
  nsPoint GetOffsetTo(const nsView* aOther) const;
146
147
  /**
148
   * Get the offset between the origin of |this| and the origin of aWidget.
149
   * Adding the return value to a point in the coordinate system of |this|
150
   * will transform the point to the coordinate system of aWidget.
151
   *
152
   * The offset is expressed in appunits of |this|.
153
   */
154
  nsPoint GetOffsetToWidget(nsIWidget* aWidget) const;
155
156
  /**
157
   * Takes a point aPt that is in the coordinate system of |this|'s parent view
158
   * and converts it to be in the coordinate system of |this| taking into
159
   * account the offset and any app unit per dev pixel ratio differences.
160
   */
161
  nsPoint ConvertFromParentCoords(nsPoint aPt) const;
162
163
  /**
164
   * Called to query the visibility state of a view.
165
   * @result current visibility state
166
   */
167
  nsViewVisibility GetVisibility() const { return mVis; }
168
169
  /**
170
   * Get whether the view "floats" above all other views,
171
   * which tells the compositor not to consider higher views in
172
   * the view hierarchy that would geometrically intersect with
173
   * this view. This is a hack, but it fixes some problems with
174
   * views that need to be drawn in front of all other views.
175
   * @result true if the view floats, false otherwise.
176
   */
177
  bool GetFloating() const { return (mVFlags & NS_VIEW_FLAG_FLOATING) != 0; }
178
179
  /**
180
   * Called to query the parent of the view.
181
   * @result view's parent
182
   */
183
  nsView* GetParent() const { return mParent; }
184
185
  /**
186
   * The view's first child is the child which is earliest in document order.
187
   * @result first child
188
   */
189
  nsView* GetFirstChild() const { return mFirstChild; }
190
191
  /**
192
   * Called to query the next sibling of the view.
193
   * @result view's next sibling
194
   */
195
  nsView* GetNextSibling() const { return mNextSibling; }
196
197
  /**
198
   * Set the view's frame.
199
   */
200
0
  void SetFrame(nsIFrame* aRootFrame) { mFrame = aRootFrame; }
201
202
  /**
203
   * Retrieve the view's frame.
204
   */
205
0
  nsIFrame* GetFrame() const { return mFrame; }
206
207
  /**
208
   * Get the nearest widget in this view or a parent of this view and
209
   * the offset from the widget's origin to this view's origin
210
   * @param aOffset - if non-null the offset from this view's origin to the
211
   * widget's origin (usually positive) expressed in appunits of this will be
212
   * returned in aOffset.
213
   * @return the widget closest to this view; can be null because some view trees
214
   * don't have widgets at all (e.g., printing), but if any view in the view tree
215
   * has a widget, then it's safe to assume this will not return null
216
   */
217
  nsIWidget* GetNearestWidget(nsPoint* aOffset) const;
218
219
  /**
220
   * Create a widget to associate with this view.  This variant of
221
   * CreateWidget*() will look around in the view hierarchy for an
222
   * appropriate parent widget for the view.
223
   *
224
   * @param aWidgetInitData data used to initialize this view's widget before
225
   *        its create is called.
226
   * @return error status
227
   */
228
  nsresult CreateWidget(nsWidgetInitData *aWidgetInitData = nullptr,
229
                        bool aEnableDragDrop = true,
230
                        bool aResetVisibility = true);
231
232
  /**
233
   * Create a widget for this view with an explicit parent widget.
234
   * |aParentWidget| must be nonnull.  The other params are the same
235
   * as for |CreateWidget()|.
236
   */
237
  nsresult CreateWidgetForParent(nsIWidget* aParentWidget,
238
                                 nsWidgetInitData *aWidgetInitData = nullptr,
239
                                 bool aEnableDragDrop = true,
240
                                 bool aResetVisibility = true);
241
242
  /**
243
   * Create a popup widget for this view.  Pass |aParentWidget| to
244
   * explicitly set the popup's parent.  If it's not passed, the view
245
   * hierarchy will be searched for an appropriate parent widget.  The
246
   * other params are the same as for |CreateWidget()|, except that
247
   * |aWidgetInitData| must be nonnull.
248
   */
249
  nsresult CreateWidgetForPopup(nsWidgetInitData *aWidgetInitData,
250
                                nsIWidget* aParentWidget = nullptr,
251
                                bool aEnableDragDrop = true,
252
                                bool aResetVisibility = true);
253
254
  /**
255
   * Destroys the associated widget for this view.  If this method is
256
   * not called explicitly, the widget when be destroyed when its
257
   * view gets destroyed.
258
   */
259
  void DestroyWidget();
260
261
  /**
262
   * Attach/detach a top level widget from this view. When attached, the view
263
   * updates the widget's device context and allows the view to begin receiving
264
   * gecko events. The underlying base window associated with the widget will
265
   * continues to receive events it expects.
266
   *
267
   * An attached widget will not be destroyed when the view is destroyed,
268
   * allowing the recycling of a single top level widget over multiple views.
269
   *
270
   * @param aWidget The widget to attach to / detach from.
271
   */
272
  nsresult AttachToTopLevelWidget(nsIWidget* aWidget);
273
  nsresult DetachFromTopLevelWidget();
274
275
  /**
276
   * Returns a flag indicating whether the view owns it's widget
277
   * or is attached to an existing top level widget.
278
   */
279
  bool IsAttachedToTopLevel() const { return mWidgetIsTopLevel; }
280
281
  /**
282
   * In 4.0, the "cutout" nature of a view is queryable.
283
   * If we believe that all cutout view have a native widget, this
284
   * could be a replacement.
285
   * @param aWidget out parameter for widget that this view contains,
286
   *        or nullptr if there is none.
287
   */
288
0
  nsIWidget* GetWidget() const { return mWindow; }
289
290
  /**
291
   * The widget which we have attached a listener to can also have a "previous"
292
   * listener set on it. This is to keep track of the last nsView when navigating
293
   * to a new one so that we can continue to paint that if the new one isn't ready
294
   * yet.
295
   */
296
  void SetPreviousWidget(nsIWidget* aWidget) { mPreviousWindow = aWidget; }
297
298
  /**
299
   * Returns true if the view has a widget associated with it.
300
   */
301
  bool HasWidget() const { return mWindow != nullptr; }
302
303
  void SetForcedRepaint(bool aForceRepaint) {
304
    mForcedRepaint = aForceRepaint;
305
  }
306
307
  void SetNeedsWindowPropertiesSync();
308
309
  /**
310
   * Make aWidget direct its events to this view.
311
   * The caller must call DetachWidgetEventHandler before this view
312
   * is destroyed.
313
   */
314
  void AttachWidgetEventHandler(nsIWidget* aWidget);
315
  /**
316
   * Stop aWidget directing its events to this view.
317
   */
318
  void DetachWidgetEventHandler(nsIWidget* aWidget);
319
320
#ifdef DEBUG
321
  /**
322
   * Output debug info to FILE
323
   * @param out output file handle
324
   * @param aIndent indentation depth
325
   * NOTE: virtual so that debugging tools not linked into gklayout can access it
326
   */
327
  virtual void List(FILE* out, int32_t aIndent = 0) const;
328
#endif // DEBUG
329
330
  /**
331
   * @result true iff this is the root view for its view manager
332
   */
333
  bool IsRoot() const;
334
335
  LayoutDeviceIntRect CalcWidgetBounds(nsWindowType aType);
336
337
  // This is an app unit offset to add when converting view coordinates to
338
  // widget coordinates.  It is the offset in view coordinates from widget
339
  // origin (unlike views, widgets can't extend above or to the left of their
340
  // origin) to view origin expressed in appunits of this.
341
  nsPoint ViewToWidgetOffset() const { return mViewToWidgetOffset; }
342
343
  /**
344
   * Called to indicate that the position of the view has been changed.
345
   * The specified coordinates are in the parent view's coordinate space.
346
   * @param x new x position
347
   * @param y new y position
348
   */
349
  void SetPosition(nscoord aX, nscoord aY);
350
351
  /**
352
   * Called to indicate that the z-index of a view has been changed.
353
   * The z-index is relative to all siblings of the view.
354
   * @param aAuto Indicate that the z-index of a view is "auto". An "auto" z-index
355
   * means that the view does not define a new stacking context,
356
   * which means that the z-indicies of the view's children are
357
   * relative to the view's siblings.
358
   * @param zindex new z depth
359
   */
360
  void SetZIndex(bool aAuto, int32_t aZIndex);
361
  bool GetZIndexIsAuto() const { return (mVFlags & NS_VIEW_FLAG_AUTO_ZINDEX) != 0; }
362
  int32_t GetZIndex() const { return mZIndex; }
363
364
  void SetParent(nsView *aParent) { mParent = aParent; }
365
  void SetNextSibling(nsView *aSibling)
366
  {
367
    NS_ASSERTION(aSibling != this, "Can't be our own sibling!");
368
    mNextSibling = aSibling;
369
  }
370
371
  nsRegion* GetDirtyRegion() {
372
    if (!mDirtyRegion) {
373
      NS_ASSERTION(!mParent || GetFloating(),
374
                   "Only display roots should have dirty regions");
375
      mDirtyRegion = new nsRegion();
376
      NS_ASSERTION(mDirtyRegion, "Out of memory!");
377
    }
378
    return mDirtyRegion;
379
  }
380
381
  // nsIWidgetListener
382
  virtual nsIPresShell* GetPresShell() override;
383
  virtual nsView* GetView() override { return this; }
384
  virtual bool WindowMoved(nsIWidget* aWidget, int32_t x, int32_t y) override;
385
  virtual bool WindowResized(nsIWidget* aWidget, int32_t aWidth, int32_t aHeight) override;
386
  virtual bool RequestWindowClose(nsIWidget* aWidget) override;
387
  virtual void WillPaintWindow(nsIWidget* aWidget) override;
388
  virtual bool PaintWindow(nsIWidget* aWidget,
389
                           LayoutDeviceIntRegion aRegion) override;
390
  virtual void DidPaintWindow() override;
391
  virtual void DidCompositeWindow(mozilla::layers::TransactionId aTransactionId,
392
                                  const mozilla::TimeStamp& aCompositeStart,
393
                                  const mozilla::TimeStamp& aCompositeEnd) override;
394
  virtual void RequestRepaint() override;
395
  virtual nsEventStatus HandleEvent(mozilla::WidgetGUIEvent* aEvent,
396
                                    bool aUseAttachedEvents) override;
397
398
  virtual ~nsView();
399
400
  nsPoint GetOffsetTo(const nsView* aOther, const int32_t aAPD) const;
401
  nsIWidget* GetNearestWidget(nsPoint* aOffset, const int32_t aAPD) const;
402
403
  bool IsPrimaryFramePaintSuppressed();
404
405
private:
406
  explicit nsView(nsViewManager* aViewManager = nullptr,
407
                  nsViewVisibility aVisibility = nsViewVisibility_kShow);
408
409
  bool ForcedRepaint() { return mForcedRepaint; }
410
411
  // Do the actual work of ResetWidgetBounds, unconditionally.  Don't
412
  // call this method if we have no widget.
413
  void DoResetWidgetBounds(bool aMoveOnly, bool aInvalidateChangedSize);
414
  void InitializeWindow(bool aEnableDragDrop, bool aResetVisibility);
415
416
  bool IsEffectivelyVisible();
417
418
  /**
419
   * Called to indicate that the dimensions of the view have been changed.
420
   * The x and y coordinates may be < 0, indicating that the view extends above
421
   * or to the left of its origin position. The term 'dimensions' indicates it
422
   * is relative to this view.
423
   */
424
  void SetDimensions(const nsRect &aRect, bool aPaint = true,
425
                     bool aResizeWidget = true);
426
427
  /**
428
   * Called to indicate that the visibility of a view has been
429
   * changed.
430
   * @param visibility new visibility state
431
   */
432
  void SetVisibility(nsViewVisibility visibility);
433
434
  /**
435
   * Set/Get whether the view "floats" above all other views,
436
   * which tells the compositor not to consider higher views in
437
   * the view hierarchy that would geometrically intersect with
438
   * this view. This is a hack, but it fixes some problems with
439
   * views that need to be drawn in front of all other views.
440
   * @result true if the view floats, false otherwise.
441
   */
442
  void SetFloating(bool aFloatingView);
443
444
  // Helper function to get mouse grabbing off this view (by moving it to the
445
  // parent, if we can)
446
  void DropMouseGrabbing();
447
448
  // Same as GetBounds but converts to parent appunits if they are different.
449
  nsRect GetBoundsInParentUnits() const;
450
451
  bool HasNonEmptyDirtyRegion() {
452
    return mDirtyRegion && !mDirtyRegion->IsEmpty();
453
  }
454
455
  void InsertChild(nsView *aChild, nsView *aSibling);
456
  void RemoveChild(nsView *aChild);
457
458
  void ResetWidgetBounds(bool aRecurse, bool aForceSync);
459
  void AssertNoWindow();
460
461
  void NotifyEffectiveVisibilityChanged(bool aEffectivelyVisible);
462
463
  // Update the cached RootViewManager for all view manager descendents.
464
  void InvalidateHierarchy();
465
466
  nsViewManager    *mViewManager;
467
  nsView           *mParent;
468
  nsCOMPtr<nsIWidget> mWindow;
469
  nsCOMPtr<nsIWidget> mPreviousWindow;
470
  nsView           *mNextSibling;
471
  nsView           *mFirstChild;
472
  nsIFrame         *mFrame;
473
  nsRegion         *mDirtyRegion;
474
  int32_t           mZIndex;
475
  nsViewVisibility  mVis;
476
  // position relative our parent view origin but in our appunits
477
  nscoord           mPosX, mPosY;
478
  // relative to parent, but in our appunits
479
  nsRect            mDimBounds;
480
  // in our appunits
481
  nsPoint           mViewToWidgetOffset;
482
  uint32_t          mVFlags;
483
  bool              mWidgetIsTopLevel;
484
  bool              mForcedRepaint;
485
  bool              mNeedsWindowPropertiesSync;
486
};
487
488
#endif