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 #ifndef nsBaseWidget_h__
6 #define nsBaseWidget_h__
8 #include "mozilla/EventForwards.h"
9 #include "mozilla/WidgetUtils.h"
11 #include "nsIWidget.h"
12 #include "nsWidgetsCID.h"
16 #include "nsAutoPtr.h"
17 #include "nsIRollupListener.h"
18 #include "nsIObserver.h"
19 #include "nsIWidgetListener.h"
20 #include "nsPIDOMWindow.h"
21 #include "nsWeakReference.h"
35 class BasicLayerManager
;
36 class CompositorChild
;
37 class CompositorParent
;
38 class APZCTreeManager
;
39 class GoannaContentController
;
41 struct ScrollableLayerGuid
;
42 struct SetTargetAPZCCallback
;
45 class CompositorVsyncDispatcher
;
52 // Windows specific constant indicating the maximum number of touch points the
53 // inject api will allow. This also sets the maximum numerical value for touch
54 // ids we can use when injecting touch points on Windows.
55 #define TOUCH_INJECT_MAX_POINTS 256
59 class WidgetShutdownObserver final
: public nsIObserver
61 ~WidgetShutdownObserver() {}
64 explicit WidgetShutdownObserver(nsBaseWidget
* aWidget
)
71 nsBaseWidget
*mWidget
;
75 * Common widget implementation used as base class for native
76 * or crossplatform implementations of Widgets.
77 * All cross-platform behavior that all widgets need to implement
78 * should be placed in this class.
79 * (Note: widget implementations are not required to use this
80 * class, but it gives them a head start.)
83 class nsBaseWidget
: public nsIWidget
, public nsSupportsWeakReference
85 friend class nsAutoRollup
;
88 typedef base::Thread Thread
;
89 typedef mozilla::layers::BasicLayerManager BasicLayerManager
;
90 typedef mozilla::layers::BufferMode BufferMode
;
91 typedef mozilla::layers::CompositorChild CompositorChild
;
92 typedef mozilla::layers::CompositorParent CompositorParent
;
93 typedef mozilla::layers::APZCTreeManager APZCTreeManager
;
94 typedef mozilla::layers::GoannaContentController GoannaContentController
;
95 typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid
;
96 typedef mozilla::layers::APZEventState APZEventState
;
97 typedef mozilla::layers::SetTargetAPZCCallback SetTargetAPZCCallback
;
98 typedef mozilla::ScreenRotation ScreenRotation
;
100 virtual ~nsBaseWidget();
107 // nsIWidget interface
108 NS_IMETHOD
CaptureMouse(bool aCapture
) override
;
109 virtual nsIWidgetListener
* GetWidgetListener() override
;
110 virtual void SetWidgetListener(nsIWidgetListener
* alistener
) override
;
111 NS_IMETHOD
Destroy() override
;
112 NS_IMETHOD
SetParent(nsIWidget
* aNewParent
) override
;
113 virtual nsIWidget
* GetParent(void) override
;
114 virtual nsIWidget
* GetTopLevelWidget() override
;
115 virtual nsIWidget
* GetSheetWindowParent(void) override
;
116 virtual float GetDPI() override
;
117 virtual void AddChild(nsIWidget
* aChild
) override
;
118 virtual void RemoveChild(nsIWidget
* aChild
) override
;
120 void SetZIndex(int32_t aZIndex
) override
;
121 NS_IMETHOD
PlaceBehind(nsTopLevelWidgetZPlacement aPlacement
,
122 nsIWidget
*aWidget
, bool aActivate
) override
;
124 NS_IMETHOD
SetSizeMode(int32_t aMode
) override
;
125 virtual int32_t SizeMode() override
130 virtual nsCursor
GetCursor() override
;
131 NS_IMETHOD
SetCursor(nsCursor aCursor
) override
;
132 NS_IMETHOD
SetCursor(imgIContainer
* aCursor
,
133 uint32_t aHotspotX
, uint32_t aHotspotY
) override
;
134 virtual void ClearCachedCursor() override
{ mUpdateCursor
= true; }
135 virtual void SetTransparencyMode(nsTransparencyMode aMode
) override
;
136 virtual nsTransparencyMode
GetTransparencyMode() override
;
137 virtual void GetWindowClipRegion(nsTArray
<nsIntRect
>* aRects
) override
;
138 NS_IMETHOD
SetWindowShadowStyle(int32_t aStyle
) override
;
139 virtual void SetShowsToolbarButton(bool aShow
) override
{}
140 virtual void SetShowsFullScreenButton(bool aShow
) override
{}
141 virtual void SetWindowAnimationType(WindowAnimationType aType
) override
{}
142 NS_IMETHOD
HideWindowChrome(bool aShouldHide
) override
;
143 NS_IMETHOD
MakeFullScreen(bool aFullScreen
, nsIScreen
* aScreen
= nullptr) override
;
144 virtual LayerManager
* GetLayerManager(PLayerTransactionChild
* aShadowManager
= nullptr,
145 LayersBackend aBackendHint
= mozilla::layers::LayersBackend::LAYERS_NONE
,
146 LayerManagerPersistence aPersistence
= LAYER_MANAGER_CURRENT
,
147 bool* aAllowRetaining
= nullptr) override
;
149 CompositorVsyncDispatcher
* GetCompositorVsyncDispatcher() override
;
150 void CreateCompositorVsyncDispatcher();
151 virtual CompositorParent
* NewCompositorParent(int aSurfaceWidth
, int aSurfaceHeight
);
152 virtual void CreateCompositor();
153 virtual void CreateCompositor(int aWidth
, int aHeight
);
154 virtual void PrepareWindowEffects() override
{}
155 virtual void CleanupWindowEffects() override
{}
156 virtual bool PreRender(LayerManagerComposite
* aManager
) override
{ return true; }
157 virtual void PostRender(LayerManagerComposite
* aManager
) override
{}
158 virtual void DrawWindowUnderlay(LayerManagerComposite
* aManager
, nsIntRect aRect
) override
{}
159 virtual void DrawWindowOverlay(LayerManagerComposite
* aManager
, nsIntRect aRect
) override
{}
160 virtual mozilla::TemporaryRef
<mozilla::gfx::DrawTarget
> StartRemoteDrawing() override
;
161 virtual void EndRemoteDrawing() override
{ };
162 virtual void CleanupRemoteDrawing() override
{ };
163 virtual void UpdateThemeGeometries(const nsTArray
<ThemeGeometry
>& aThemeGeometries
) override
{}
164 NS_IMETHOD
SetModal(bool aModal
) override
;
165 virtual uint32_t GetMaxTouchPoints() const override
;
166 NS_IMETHOD
SetWindowClass(const nsAString
& xulWinType
) override
;
167 virtual nsresult
SetWindowClipRegion(const nsTArray
<nsIntRect
>& aRects
, bool aIntersectWithExisting
) override
;
168 // Return whether this widget interprets parameters to Move and Resize APIs
169 // as "global display pixels" rather than "device pixels", and therefore
170 // applies its GetDefaultScale() value to them before using them as mBounds
171 // etc (which are always stored in device pixels).
172 // Note that APIs that -get- the widget's position/size/bounds, rather than
173 // -setting- them (i.e. moving or resizing the widget) will always return
174 // values in the widget's device pixels.
175 bool BoundsUseDisplayPixels() const {
176 return mWindowType
<= eWindowType_popup
;
178 NS_IMETHOD
MoveClient(double aX
, double aY
) override
;
179 NS_IMETHOD
ResizeClient(double aWidth
, double aHeight
, bool aRepaint
) override
;
180 NS_IMETHOD
ResizeClient(double aX
, double aY
, double aWidth
, double aHeight
, bool aRepaint
) override
;
181 NS_IMETHOD
GetBounds(nsIntRect
&aRect
) override
;
182 NS_IMETHOD
GetClientBounds(nsIntRect
&aRect
) override
;
183 NS_IMETHOD
GetScreenBounds(nsIntRect
&aRect
) override
;
184 NS_IMETHOD
GetRestoredBounds(nsIntRect
&aRect
) override
;
185 NS_IMETHOD
GetNonClientMargins(nsIntMargin
&margins
) override
;
186 NS_IMETHOD
SetNonClientMargins(nsIntMargin
&margins
) override
;
187 virtual nsIntPoint
GetClientOffset() override
;
188 NS_IMETHOD
EnableDragDrop(bool aEnable
) override
;
189 NS_IMETHOD
GetAttention(int32_t aCycleCount
) override
;
190 virtual bool HasPendingInputEvent() override
;
191 NS_IMETHOD
SetIcon(const nsAString
&anIconSpec
) override
;
192 NS_IMETHOD
SetWindowTitlebarColor(nscolor aColor
, bool aActive
) override
;
193 virtual void SetDrawsInTitlebar(bool aState
) override
{}
194 virtual bool ShowsResizeIndicator(nsIntRect
* aResizerRect
) override
;
195 virtual void FreeNativeData(void * data
, uint32_t aDataType
) override
{}
196 NS_IMETHOD
BeginResizeDrag(mozilla::WidgetGUIEvent
* aEvent
,
198 int32_t aVertical
) override
;
199 NS_IMETHOD
BeginMoveDrag(mozilla::WidgetMouseEvent
* aEvent
) override
;
200 virtual nsresult
ActivateNativeMenuItemAt(const nsAString
& indexString
) override
{ return NS_ERROR_NOT_IMPLEMENTED
; }
201 virtual nsresult
ForceUpdateNativeMenuAt(const nsAString
& indexString
) override
{ return NS_ERROR_NOT_IMPLEMENTED
; }
202 NS_IMETHOD
NotifyIME(const IMENotification
& aIMENotification
) override final
;
203 NS_IMETHOD
StartPluginIME(const mozilla::WidgetKeyboardEvent
& aKeyboardEvent
,
204 int32_t aPanelX
, int32_t aPanelY
,
205 nsString
& aCommitted
) override
206 { return NS_ERROR_NOT_IMPLEMENTED
; }
207 NS_IMETHOD
SetPluginFocused(bool& aFocused
) override
208 { return NS_ERROR_NOT_IMPLEMENTED
; }
209 NS_IMETHOD
AttachNativeKeyEvent(mozilla::WidgetKeyboardEvent
& aEvent
) override
{ return NS_ERROR_NOT_IMPLEMENTED
; }
210 NS_IMETHOD_(bool) ExecuteNativeKeyBinding(
211 NativeKeyBindingsType aType
,
212 const mozilla::WidgetKeyboardEvent
& aEvent
,
213 DoCommandCallback aCallback
,
214 void* aCallbackData
) override
{ return false; }
215 virtual bool ComputeShouldAccelerate(bool aDefault
);
216 NS_IMETHOD
GetToggledKeyState(uint32_t aKeyCode
, bool* aLEDState
) override
{ return NS_ERROR_NOT_IMPLEMENTED
; }
217 virtual nsIMEUpdatePreference
GetIMEUpdatePreference() override
{ return nsIMEUpdatePreference(); }
218 NS_IMETHOD
OnDefaultButtonLoaded(const nsIntRect
&aButtonRect
) override
{ return NS_ERROR_NOT_IMPLEMENTED
; }
219 NS_IMETHOD
OverrideSystemMouseScrollSpeed(double aOriginalDeltaX
,
220 double aOriginalDeltaY
,
221 double& aOverriddenDeltaX
,
222 double& aOverriddenDeltaY
) override
;
223 virtual already_AddRefed
<nsIWidget
>
224 CreateChild(const nsIntRect
&aRect
,
225 nsWidgetInitData
*aInitData
= nullptr,
226 bool aForceUseIWidgetParent
= false) override
;
227 NS_IMETHOD
AttachViewToTopLevel(bool aUseAttachedEvents
) override
;
228 virtual nsIWidgetListener
* GetAttachedWidgetListener() override
;
229 virtual void SetAttachedWidgetListener(nsIWidgetListener
* aListener
) override
;
230 NS_IMETHOD
RegisterTouchWindow() override
;
231 NS_IMETHOD
UnregisterTouchWindow() override
;
232 NS_IMETHOD_(TextEventDispatcher
*) GetTextEventDispatcher() override final
;
234 void NotifyWindowDestroyed();
235 void NotifySizeMoveDone();
236 void NotifyWindowMoved(int32_t aX
, int32_t aY
);
238 // Register plugin windows for remote updates from the compositor
239 virtual void RegisterPluginWindowForRemoteUpdates() override
;
240 virtual void UnregisterPluginWindowForRemoteUpdates() override
;
242 virtual void SetNativeData(uint32_t aDataType
, uintptr_t aVal
) override
{};
244 // Should be called by derived implementations to notify on system color and
246 void NotifySysColorChanged();
247 void NotifyThemeChanged();
248 void NotifyUIStateChanged(UIStateChangeType aShowAccelerators
,
249 UIStateChangeType aShowFocusRings
);
252 // Get the accessible for the window.
253 mozilla::a11y::Accessible
* GetRootAccessible();
256 nsPopupLevel
PopupLevel() { return mPopupLevel
; }
258 virtual nsIntSize
ClientToWindowSize(const nsIntSize
& aClientSize
) override
263 // return true if this is a popup widget with a native titlebar
264 bool IsPopupWithTitleBar() const
266 return (mWindowType
== eWindowType_popup
&&
267 mBorderStyle
!= eBorderStyle_default
&&
268 mBorderStyle
& eBorderStyle_title
);
271 NS_IMETHOD
ReparentNativeWidget(nsIWidget
* aNewParent
) override
= 0;
273 virtual uint32_t GetGLFrameBufferFormat() override
;
275 virtual const SizeConstraints
& GetSizeConstraints() const override
;
276 virtual void SetSizeConstraints(const SizeConstraints
& aConstraints
) override
;
279 * Use this when GetLayerManager() returns a BasicLayerManager
280 * (nsBaseWidget::GetLayerManager() does). This sets up the widget's
281 * layer manager to temporarily render into aTarget.
283 * |aNaturalWidgetBounds| is the un-rotated bounds of |aWidget|.
284 * |aRotation| is the "virtual rotation" to apply when rendering to
285 * the target. When |aRotation| is ROTATION_0,
286 * |aNaturalWidgetBounds| is not used.
288 class AutoLayerManagerSetup
{
290 AutoLayerManagerSetup(nsBaseWidget
* aWidget
, gfxContext
* aTarget
,
291 BufferMode aDoubleBuffering
,
292 ScreenRotation aRotation
= mozilla::ROTATION_0
);
293 ~AutoLayerManagerSetup();
295 nsBaseWidget
* mWidget
;
296 nsRefPtr
<BasicLayerManager
> mLayerManager
;
298 friend class AutoLayerManagerSetup
;
300 class AutoUseBasicLayerManager
{
302 explicit AutoUseBasicLayerManager(nsBaseWidget
* aWidget
);
303 ~AutoUseBasicLayerManager();
305 nsBaseWidget
* mWidget
;
306 bool mPreviousTemporarilyUseBasicLayerManager
;
308 friend class AutoUseBasicLayerManager
;
310 virtual bool ShouldUseOffMainThreadCompositing();
312 static nsIRollupListener
* GetActiveRollupListener();
318 void ResolveIconName(const nsAString
&aIconName
,
319 const nsAString
&aIconSuffix
,
321 virtual void OnDestroy();
322 void BaseCreate(nsIWidget
*aParent
,
323 const nsIntRect
&aRect
,
324 nsWidgetInitData
*aInitData
);
326 virtual void ConfigureAPZCTreeManager();
327 virtual already_AddRefed
<GoannaContentController
> CreateRootContentController();
329 // Dispatch an event that has been routed through APZ directly from the
331 nsEventStatus
DispatchEventForAPZ(mozilla::WidgetGUIEvent
* aEvent
,
332 const ScrollableLayerGuid
& aGuid
,
333 uint64_t aInputBlockId
);
335 const nsIntRegion
RegionFromArray(const nsTArray
<nsIntRect
>& aRects
);
336 void ArrayFromRegion(const nsIntRegion
& aRegion
, nsTArray
<nsIntRect
>& aRects
);
338 virtual nsIContent
* GetLastRollup() override
343 virtual nsresult
SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout
,
344 int32_t aNativeKeyCode
,
345 uint32_t aModifierFlags
,
346 const nsAString
& aCharacters
,
347 const nsAString
& aUnmodifiedCharacters
) override
348 { return NS_ERROR_UNEXPECTED
; }
350 virtual nsresult
SynthesizeNativeMouseEvent(mozilla::LayoutDeviceIntPoint aPoint
,
351 uint32_t aNativeMessage
,
352 uint32_t aModifierFlags
) override
353 { return NS_ERROR_UNEXPECTED
; }
355 virtual nsresult
SynthesizeNativeMouseMove(mozilla::LayoutDeviceIntPoint aPoint
) override
356 { return NS_ERROR_UNEXPECTED
; }
358 virtual nsresult
SynthesizeNativeMouseScrollEvent(mozilla::LayoutDeviceIntPoint aPoint
,
359 uint32_t aNativeMessage
,
363 uint32_t aModifierFlags
,
364 uint32_t aAdditionalFlags
) override
365 { return NS_ERROR_UNEXPECTED
; }
367 virtual nsresult
SynthesizeNativeTouchPoint(uint32_t aPointerId
,
368 TouchPointerState aPointerState
,
369 nsIntPoint aPointerScreenPoint
,
370 double aPointerPressure
,
371 uint32_t aPointerOrientation
) override
372 { return NS_ERROR_UNEXPECTED
; }
374 virtual nsresult
NotifyIMEInternal(const IMENotification
& aIMENotification
)
375 { return NS_ERROR_NOT_IMPLEMENTED
; }
378 // Utility to check if an array of clip rects is equal to our
379 // internally stored clip rect array mClipRects.
380 bool IsWindowClipRegionEqual(const nsTArray
<nsIntRect
>& aRects
);
382 // Stores the clip rectangles in aRects into mClipRects.
383 void StoreWindowClipRegion(const nsTArray
<nsIntRect
>& aRects
);
385 virtual already_AddRefed
<nsIWidget
>
386 AllocateChildPopupWidget()
388 static NS_DEFINE_IID(kCPopUpCID
, NS_CHILD_CID
);
389 nsCOMPtr
<nsIWidget
> widget
= do_CreateInstance(kCPopUpCID
);
390 return widget
.forget();
393 LayerManager
* CreateBasicLayerManager();
395 nsPopupType
PopupType() const { return mPopupType
; }
397 void NotifyRollupGeometryChange()
399 // XULPopupManager isn't interested in this notification, so only
400 // send it if gRollupListener is set.
401 if (gRollupListener
) {
402 gRollupListener
->NotifyGeometryChange();
407 * Apply the current size constraints to the given size.
409 * @param aWidth width to constrain
410 * @param aHeight height to constrain
412 void ConstrainSize(int32_t* aWidth
, int32_t* aHeight
) const
414 *aWidth
= std::max(mSizeConstraints
.mMinSize
.width
,
415 std::min(mSizeConstraints
.mMaxSize
.width
, *aWidth
));
416 *aHeight
= std::max(mSizeConstraints
.mMinSize
.height
,
417 std::min(mSizeConstraints
.mMaxSize
.height
, *aHeight
));
420 virtual CompositorChild
* GetRemoteRenderer() override
;
422 virtual void GetPreferredCompositorBackends(nsTArray
<mozilla::layers::LayersBackend
>& aHints
);
425 * Notify the widget that this window is being used with OMTC.
427 virtual void WindowUsesOMTC() {}
429 nsIDocument
* GetDocument() const;
433 * Starts the OMTC compositor destruction sequence.
435 * When this function returns, the compositor should not be
436 * able to access the opengl context anymore.
437 * It is safe to call it several times if platform implementations
438 * require the compositor to be destroyed before ~nsBaseWidget is
439 * reached (This is the case with gtk2 for instance).
441 void DestroyCompositor();
443 nsIWidgetListener
* mWidgetListener
;
444 nsIWidgetListener
* mAttachedWidgetListener
;
445 nsRefPtr
<LayerManager
> mLayerManager
;
446 nsRefPtr
<LayerManager
> mBasicLayerManager
;
447 nsRefPtr
<CompositorChild
> mCompositorChild
;
448 nsRefPtr
<CompositorParent
> mCompositorParent
;
449 nsRefPtr
<mozilla::CompositorVsyncDispatcher
> mCompositorVsyncDispatcher
;
450 nsRefPtr
<APZCTreeManager
> mAPZC
;
451 nsRefPtr
<APZEventState
> mAPZEventState
;
452 nsRefPtr
<SetTargetAPZCCallback
> mSetTargetAPZCCallback
;
453 nsRefPtr
<WidgetShutdownObserver
> mShutdownObserver
;
454 nsRefPtr
<TextEventDispatcher
> mTextEventDispatcher
;
457 nsBorderStyle mBorderStyle
;
458 bool mUseLayersAcceleration
;
459 bool mForceLayersAcceleration
;
460 bool mTemporarilyUseBasicLayerManager
;
461 // Windows with out-of-process tabs always require OMTC. This flag designates
463 bool mRequireOffMainThreadCompositing
;
464 bool mUseAttachedEvents
;
466 nsIntRect
* mOriginalBounds
;
467 // When this pointer is null, the widget is not clipped
468 nsAutoArrayPtr
<nsIntRect
> mClipRects
;
469 uint32_t mClipRectCount
;
470 nsSizeMode mSizeMode
;
471 nsPopupLevel mPopupLevel
;
472 nsPopupType mPopupType
;
473 SizeConstraints mSizeConstraints
;
475 static nsIRollupListener
* gRollupListener
;
477 // the last rolled up popup. Only set this when an nsAutoRollup is in scope,
478 // so it can be cleared automatically.
479 static nsIContent
* mLastRollup
;
483 static nsAutoString
debug_GuiEventToString(mozilla::WidgetGUIEvent
* aGuiEvent
);
484 static bool debug_WantPaintFlashing();
486 static void debug_DumpInvalidate(FILE * aFileOut
,
488 const nsIntRect
* aRect
,
489 const nsAutoCString
& aWidgetName
,
492 static void debug_DumpEvent(FILE* aFileOut
,
494 mozilla::WidgetGUIEvent
* aGuiEvent
,
495 const nsAutoCString
& aWidgetName
,
498 static void debug_DumpPaintEvent(FILE * aFileOut
,
500 const nsIntRegion
& aPaintEvent
,
501 const nsAutoCString
& aWidgetName
,
504 static bool debug_GetCachedBoolPref(const char* aPrefName
);
508 // A situation can occur when a mouse event occurs over a menu label while the
509 // menu popup is already open. The expected behaviour is to close the popup.
510 // This happens by calling nsIRollupListener::Rollup before the mouse event is
511 // processed. However, in cases where the mouse event is not consumed, this
512 // event will then get targeted at the menu label causing the menu to open
513 // again. To prevent this, we store in mLastRollup a reference to the popup
514 // that was closed during the Rollup call, and prevent this popup from
515 // reopening while processing the mouse event.
516 // mLastRollup should only be set while an nsAutoRollup is in scope;
517 // when it goes out of scope mLastRollup is cleared automatically.
518 // As mLastRollup is static, it can be retrieved by calling
519 // nsIWidget::GetLastRollup on any widget.
530 #endif // nsBaseWidget_h__