summaryrefslogtreecommitdiffstats
path: root/widget/nsBaseWidget.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--widget/nsBaseWidget.h777
1 files changed, 777 insertions, 0 deletions
diff --git a/widget/nsBaseWidget.h b/widget/nsBaseWidget.h
new file mode 100644
index 0000000000..8b6e8ad0eb
--- /dev/null
+++ b/widget/nsBaseWidget.h
@@ -0,0 +1,777 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#ifndef nsBaseWidget_h__
+#define nsBaseWidget_h__
+
+#include "InputData.h"
+#include "mozilla/EventForwards.h"
+#include "mozilla/Mutex.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/UniquePtr.h"
+#include "mozilla/WidgetUtils.h"
+#include "mozilla/dom/MouseEventBinding.h"
+#include "mozilla/layers/APZCCallbackHelper.h"
+#include "mozilla/layers/CompositorOptions.h"
+#include "mozilla/layers/NativeLayer.h"
+#include "mozilla/widget/ThemeChangeKind.h"
+#include "mozilla/widget/WindowOcclusionState.h"
+#include "nsRect.h"
+#include "nsIWidget.h"
+#include "nsWidgetsCID.h"
+#include "nsIFile.h"
+#include "nsString.h"
+#include "nsCOMPtr.h"
+#include "nsIRollupListener.h"
+#include "nsIObserver.h"
+#include "nsIWidgetListener.h"
+#include "nsPIDOMWindow.h"
+#include "nsWeakReference.h"
+
+#include <algorithm>
+
+class nsIContent;
+class gfxContext;
+
+namespace mozilla {
+class CompositorVsyncDispatcher;
+class LiveResizeListener;
+class FallbackRenderer;
+class SwipeTracker;
+struct SwipeEventQueue;
+class WidgetWheelEvent;
+
+#ifdef ACCESSIBILITY
+namespace a11y {
+class LocalAccessible;
+}
+#endif
+
+namespace gfx {
+class DrawTarget;
+class SourceSurface;
+} // namespace gfx
+
+namespace layers {
+class CompositorBridgeChild;
+class CompositorBridgeParent;
+class IAPZCTreeManager;
+class GeckoContentController;
+class APZEventState;
+struct APZEventResult;
+class CompositorSession;
+class ImageContainer;
+class WebRenderLayerManager;
+struct ScrollableLayerGuid;
+class RemoteCompositorSession;
+} // namespace layers
+
+namespace widget {
+class CompositorWidgetDelegate;
+class InProcessCompositorWidget;
+class WidgetRenderingContext;
+} // namespace widget
+
+class CompositorVsyncDispatcher;
+} // namespace mozilla
+
+namespace base {
+class Thread;
+} // namespace base
+
+// Windows specific constant indicating the maximum number of touch points the
+// inject api will allow. This also sets the maximum numerical value for touch
+// ids we can use when injecting touch points on Windows.
+#define TOUCH_INJECT_MAX_POINTS 256
+
+class nsBaseWidget;
+
+// Helper class used in shutting down gfx related code.
+class WidgetShutdownObserver final : public nsIObserver {
+ ~WidgetShutdownObserver();
+
+ public:
+ explicit WidgetShutdownObserver(nsBaseWidget* aWidget);
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIOBSERVER
+
+ void Register();
+ void Unregister();
+
+ nsBaseWidget* mWidget;
+ bool mRegistered;
+};
+
+// Helper class used for observing locales change.
+class LocalesChangedObserver final : public nsIObserver {
+ ~LocalesChangedObserver();
+
+ public:
+ explicit LocalesChangedObserver(nsBaseWidget* aWidget);
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIOBSERVER
+
+ void Register();
+ void Unregister();
+
+ nsBaseWidget* mWidget;
+ bool mRegistered;
+};
+
+/**
+ * Common widget implementation used as base class for native
+ * or crossplatform implementations of Widgets.
+ * All cross-platform behavior that all widgets need to implement
+ * should be placed in this class.
+ * (Note: widget implementations are not required to use this
+ * class, but it gives them a head start.)
+ */
+
+class nsBaseWidget : public nsIWidget, public nsSupportsWeakReference {
+ template <class EventType, class InputType>
+ friend class DispatchEventOnMainThread;
+ friend class mozilla::widget::InProcessCompositorWidget;
+ friend class mozilla::layers::RemoteCompositorSession;
+
+ protected:
+ typedef base::Thread Thread;
+ typedef mozilla::gfx::DrawTarget DrawTarget;
+ typedef mozilla::gfx::SourceSurface SourceSurface;
+ typedef mozilla::layers::BufferMode BufferMode;
+ typedef mozilla::layers::CompositorBridgeChild CompositorBridgeChild;
+ typedef mozilla::layers::CompositorBridgeParent CompositorBridgeParent;
+ typedef mozilla::layers::IAPZCTreeManager IAPZCTreeManager;
+ typedef mozilla::layers::GeckoContentController GeckoContentController;
+ typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid;
+ typedef mozilla::layers::APZEventState APZEventState;
+ typedef mozilla::CSSIntRect CSSIntRect;
+ typedef mozilla::CSSRect CSSRect;
+ typedef mozilla::ScreenRotation ScreenRotation;
+ typedef mozilla::widget::CompositorWidgetDelegate CompositorWidgetDelegate;
+ typedef mozilla::layers::CompositorSession CompositorSession;
+ typedef mozilla::layers::ImageContainer ImageContainer;
+
+ virtual ~nsBaseWidget();
+
+ public:
+ nsBaseWidget();
+
+ explicit nsBaseWidget(BorderStyle aBorderStyle);
+
+ NS_DECL_THREADSAFE_ISUPPORTS
+
+ // nsIWidget interface
+ void CaptureRollupEvents(bool aDoCapture) override {}
+ nsIWidgetListener* GetWidgetListener() const override;
+ void SetWidgetListener(nsIWidgetListener* alistener) override;
+ void Destroy() override;
+ void SetParent(nsIWidget* aNewParent) override{};
+ nsIWidget* GetParent() override;
+ nsIWidget* GetTopLevelWidget() override;
+ nsIWidget* GetSheetWindowParent(void) override;
+ float GetDPI() override;
+ void AddChild(nsIWidget* aChild) override;
+ void RemoveChild(nsIWidget* aChild) override;
+
+ void SetZIndex(int32_t aZIndex) override;
+ void PlaceBehind(nsTopLevelWidgetZPlacement aPlacement, nsIWidget* aWidget,
+ bool aActivate) override {}
+
+ void GetWorkspaceID(nsAString& workspaceID) override;
+ void MoveToWorkspace(const nsAString& workspaceID) override;
+ bool IsTiled() const override { return mIsTiled; }
+
+ bool IsFullyOccluded() const override { return mIsFullyOccluded; }
+
+ void SetCursor(const Cursor&) override;
+ void SetCustomCursorAllowed(bool) override;
+ void ClearCachedCursor() final {
+ mCursor = {};
+ mUpdateCursor = true;
+ }
+ void SetTransparencyMode(TransparencyMode aMode) override;
+ TransparencyMode GetTransparencyMode() override;
+ void SetWindowShadowStyle(mozilla::WindowShadow) override {}
+ void SetShowsToolbarButton(bool aShow) override {}
+ void SetSupportsNativeFullscreen(bool aSupportsNativeFullscreen) override {}
+ void SetWindowAnimationType(WindowAnimationType aType) override {}
+ void HideWindowChrome(bool aShouldHide) override {}
+ bool PrepareForFullscreenTransition(nsISupports** aData) override {
+ return false;
+ }
+ void PerformFullscreenTransition(FullscreenTransitionStage aStage,
+ uint16_t aDuration, nsISupports* aData,
+ nsIRunnable* aCallback) override;
+ void CleanupFullscreenTransition() override {}
+ already_AddRefed<Screen> GetWidgetScreen() override;
+ nsresult MakeFullScreen(bool aFullScreen) override;
+ void InfallibleMakeFullScreen(bool aFullScreen);
+
+ WindowRenderer* GetWindowRenderer() override;
+ bool HasWindowRenderer() const final { return !!mWindowRenderer; }
+
+ // A remote compositor session tied to this window has been lost and IPC
+ // messages will no longer work. The widget must clean up any lingering
+ // resources and possibly schedule another paint.
+ //
+ // A reference to the session object is held until this function has
+ // returned. Callers should hold a reference to the widget, since this
+ // function could deallocate the widget if it is unparented.
+ virtual void NotifyCompositorSessionLost(
+ mozilla::layers::CompositorSession* aSession);
+
+ already_AddRefed<mozilla::CompositorVsyncDispatcher>
+ GetCompositorVsyncDispatcher();
+ virtual void CreateCompositorVsyncDispatcher();
+ virtual void CreateCompositor();
+ virtual void CreateCompositor(int aWidth, int aHeight);
+ virtual void SetCompositorWidgetDelegate(CompositorWidgetDelegate*) {}
+ void PrepareWindowEffects() override {}
+ void UpdateThemeGeometries(
+ const nsTArray<ThemeGeometry>& aThemeGeometries) override {}
+ void SetModal(bool aModal) override {}
+ uint32_t GetMaxTouchPoints() const override;
+ void SetWindowClass(const nsAString& xulWinType, const nsAString& xulWinClass,
+ const nsAString& xulWinName) override {}
+ // Return whether this widget interprets parameters to Move and Resize APIs
+ // as "desktop pixels" rather than "device pixels", and therefore
+ // applies its GetDefaultScale() value to them before using them as mBounds
+ // etc (which are always stored in device pixels).
+ // Note that APIs that -get- the widget's position/size/bounds, rather than
+ // -setting- them (i.e. moving or resizing the widget) will always return
+ // values in the widget's device pixels.
+ bool BoundsUseDesktopPixels() const {
+ return mWindowType <= WindowType::Popup;
+ }
+ // Default implementation, to be overridden by platforms where desktop coords
+ // are virtualized and may not correspond to device pixels on the screen.
+ mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() override {
+ return mozilla::DesktopToLayoutDeviceScale(1.0);
+ }
+ mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScaleByScreen()
+ override;
+
+ void ConstrainPosition(DesktopIntPoint&) override {}
+ void MoveClient(const DesktopPoint& aOffset) override;
+ void ResizeClient(const DesktopSize& aSize, bool aRepaint) override;
+ void ResizeClient(const DesktopRect& aRect, bool aRepaint) override;
+ LayoutDeviceIntRect GetBounds() override;
+ LayoutDeviceIntRect GetClientBounds() override;
+ LayoutDeviceIntRect GetScreenBounds() override;
+ [[nodiscard]] nsresult GetRestoredBounds(LayoutDeviceIntRect& aRect) override;
+ nsresult SetNonClientMargins(const LayoutDeviceIntMargin&) override;
+ LayoutDeviceIntPoint GetClientOffset() override;
+ void EnableDragDrop(bool aEnable) override{};
+ nsresult AsyncEnableDragDrop(bool aEnable) override;
+ void SetResizeMargin(mozilla::LayoutDeviceIntCoord aResizeMargin) override;
+ [[nodiscard]] nsresult GetAttention(int32_t aCycleCount) override {
+ return NS_OK;
+ }
+ bool HasPendingInputEvent() override;
+ void SetIcon(const nsAString& aIconSpec) override {}
+ bool ShowsResizeIndicator(LayoutDeviceIntRect* aResizerRect) override;
+ void FreeNativeData(void* data, uint32_t aDataType) override {}
+ nsresult ActivateNativeMenuItemAt(const nsAString& indexString) override {
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+ nsresult ForceUpdateNativeMenuAt(const nsAString& indexString) override {
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+ nsresult NotifyIME(const IMENotification& aIMENotification) final;
+ [[nodiscard]] nsresult AttachNativeKeyEvent(
+ mozilla::WidgetKeyboardEvent& aEvent) override {
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+ bool ComputeShouldAccelerate();
+ virtual bool WidgetTypeSupportsAcceleration() { return true; }
+ [[nodiscard]] nsresult OnDefaultButtonLoaded(
+ const LayoutDeviceIntRect& aButtonRect) override {
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+ already_AddRefed<nsIWidget> CreateChild(
+ const LayoutDeviceIntRect& aRect, InitData* aInitData = nullptr,
+ bool aForceUseIWidgetParent = false) override;
+ void AttachViewToTopLevel(bool aUseAttachedEvents) override;
+ nsIWidgetListener* GetAttachedWidgetListener() const override;
+ void SetAttachedWidgetListener(nsIWidgetListener* aListener) override;
+ nsIWidgetListener* GetPreviouslyAttachedWidgetListener() override;
+ void SetPreviouslyAttachedWidgetListener(nsIWidgetListener*) override;
+ NativeIMEContext GetNativeIMEContext() override;
+ TextEventDispatcher* GetTextEventDispatcher() final;
+ TextEventDispatcherListener* GetNativeTextEventDispatcherListener() override;
+ void ZoomToRect(const uint32_t& aPresShellId,
+ const ScrollableLayerGuid::ViewID& aViewId,
+ const CSSRect& aRect, const uint32_t& aFlags) override;
+
+ // Dispatch an event that must be first be routed through APZ.
+ ContentAndAPZEventStatus DispatchInputEvent(
+ mozilla::WidgetInputEvent* aEvent) override;
+ void DispatchEventToAPZOnly(mozilla::WidgetInputEvent* aEvent) override;
+
+ bool DispatchWindowEvent(mozilla::WidgetGUIEvent& event) override;
+
+ void SetConfirmedTargetAPZC(
+ uint64_t aInputBlockId,
+ const nsTArray<ScrollableLayerGuid>& aTargets) const override;
+
+ void UpdateZoomConstraints(
+ const uint32_t& aPresShellId, const ScrollableLayerGuid::ViewID& aViewId,
+ const mozilla::Maybe<ZoomConstraints>& aConstraints) override;
+
+ bool AsyncPanZoomEnabled() const override;
+
+ void SwipeFinished() override;
+ void ReportSwipeStarted(uint64_t aInputBlockId, bool aStartSwipe) override;
+ void TrackScrollEventAsSwipe(const mozilla::PanGestureInput& aSwipeStartEvent,
+ uint32_t aAllowedDirections,
+ uint64_t aInputBlockId);
+ struct SwipeInfo {
+ bool wantsSwipe;
+ uint32_t allowedDirections;
+ };
+ SwipeInfo SendMayStartSwipe(const mozilla::PanGestureInput& aSwipeStartEvent);
+ // Returns a WidgetWheelEvent which needs to be handled by APZ regardless of
+ // whether |aPanInput| event was used for SwipeTracker or not.
+ mozilla::WidgetWheelEvent MayStartSwipeForAPZ(
+ const mozilla::PanGestureInput& aPanInput,
+ const mozilla::layers::APZEventResult& aApzResult);
+
+ // Returns true if |aPanInput| event was used for SwipeTracker, false
+ // otherwise.
+ bool MayStartSwipeForNonAPZ(const mozilla::PanGestureInput& aPanInput);
+
+ void NotifyWindowDestroyed();
+ void NotifySizeMoveDone();
+
+ using ByMoveToRect = nsIWidgetListener::ByMoveToRect;
+ void NotifyWindowMoved(int32_t aX, int32_t aY,
+ ByMoveToRect = ByMoveToRect::No);
+
+ // Should be called by derived implementations to notify on system color and
+ // theme changes.
+ void NotifyThemeChanged(mozilla::widget::ThemeChangeKind);
+
+#ifdef ACCESSIBILITY
+ // Get the accessible for the window.
+ mozilla::a11y::LocalAccessible* GetRootAccessible();
+#endif
+
+ // Return true if this is a simple widget (that is typically not worth
+ // accelerating)
+ bool IsSmallPopup() const;
+
+ PopupLevel GetPopupLevel() { return mPopupLevel; }
+
+ // return true if this is a popup widget with a native titlebar
+ bool IsPopupWithTitleBar() const {
+ return (mWindowType == WindowType::Popup &&
+ mBorderStyle != BorderStyle::Default &&
+ mBorderStyle & BorderStyle::Title);
+ }
+
+ void ReparentNativeWidget(nsIWidget* aNewParent) override {}
+
+ const SizeConstraints GetSizeConstraints() override;
+ void SetSizeConstraints(const SizeConstraints& aConstraints) override;
+
+ void StartAsyncScrollbarDrag(const AsyncDragMetrics& aDragMetrics) override;
+
+ bool StartAsyncAutoscroll(const ScreenPoint& aAnchorLocation,
+ const ScrollableLayerGuid& aGuid) override;
+
+ void StopAsyncAutoscroll(const ScrollableLayerGuid& aGuid) override;
+
+ mozilla::layers::LayersId GetRootLayerTreeId() override;
+
+ /**
+ * Use this when GetLayerManager() returns a BasicLayerManager
+ * (nsBaseWidget::GetLayerManager() does). This sets up the widget's
+ * layer manager to temporarily render into aTarget.
+ *
+ * |aNaturalWidgetBounds| is the un-rotated bounds of |aWidget|.
+ * |aRotation| is the "virtual rotation" to apply when rendering to
+ * the target. When |aRotation| is ROTATION_0,
+ * |aNaturalWidgetBounds| is not used.
+ */
+ class AutoLayerManagerSetup {
+ public:
+ AutoLayerManagerSetup(nsBaseWidget* aWidget, gfxContext* aTarget,
+ BufferMode aDoubleBuffering);
+ ~AutoLayerManagerSetup();
+
+ private:
+ nsBaseWidget* mWidget;
+ mozilla::FallbackRenderer* mRenderer = nullptr;
+ };
+ friend class AutoLayerManagerSetup;
+
+ virtual bool ShouldUseOffMainThreadCompositing();
+
+ static nsIRollupListener* GetActiveRollupListener();
+
+ void Shutdown();
+
+ void QuitIME();
+
+ // These functions should be called at the start and end of a "live" widget
+ // resize (i.e. when the window contents are repainting during the resize,
+ // such as when the user drags a window border). It will suppress the
+ // displayport during the live resize to avoid unneccessary overpainting.
+ void NotifyLiveResizeStarted();
+ void NotifyLiveResizeStopped();
+
+#if defined(MOZ_WIDGET_ANDROID)
+ void RecvToolbarAnimatorMessageFromCompositor(int32_t) override{};
+ void UpdateRootFrameMetrics(const ScreenPoint& aScrollOffset,
+ const CSSToScreenScale& aZoom) override{};
+ void RecvScreenPixels(mozilla::ipc::Shmem&& aMem, const ScreenIntSize& aSize,
+ bool aNeedsYFlip) override{};
+#endif
+
+ virtual void LocalesChanged() {}
+
+ virtual void NotifyOcclusionState(mozilla::widget::OcclusionState aState) {}
+
+ protected:
+ // These are methods for CompositorWidgetWrapper, and should only be
+ // accessed from that class. Derived widgets can choose which methods to
+ // implement, or none if supporting out-of-process compositing.
+ virtual bool PreRender(mozilla::widget::WidgetRenderingContext* aContext) {
+ return true;
+ }
+ virtual void PostRender(mozilla::widget::WidgetRenderingContext* aContext) {}
+ virtual RefPtr<mozilla::layers::NativeLayerRoot> GetNativeLayerRoot() {
+ return nullptr;
+ }
+ virtual already_AddRefed<DrawTarget> StartRemoteDrawing();
+ virtual already_AddRefed<DrawTarget> StartRemoteDrawingInRegion(
+ const LayoutDeviceIntRegion& aInvalidRegion, BufferMode* aBufferMode) {
+ return StartRemoteDrawing();
+ }
+ virtual void EndRemoteDrawing() {}
+ virtual void EndRemoteDrawingInRegion(
+ DrawTarget* aDrawTarget, const LayoutDeviceIntRegion& aInvalidRegion) {
+ EndRemoteDrawing();
+ }
+ virtual void CleanupRemoteDrawing() {}
+ virtual void CleanupWindowEffects() {}
+ virtual bool InitCompositor(mozilla::layers::Compositor* aCompositor) {
+ return true;
+ }
+ virtual uint32_t GetGLFrameBufferFormat();
+ virtual bool CompositorInitiallyPaused() { return false; }
+
+ protected:
+ void ResolveIconName(const nsAString& aIconName, const nsAString& aIconSuffix,
+ nsIFile** aResult);
+ virtual void OnDestroy();
+ void BaseCreate(nsIWidget* aParent, InitData* aInitData);
+
+ virtual void ConfigureAPZCTreeManager();
+ virtual void ConfigureAPZControllerThread();
+ virtual already_AddRefed<GeckoContentController>
+ CreateRootContentController();
+
+ // Dispatch an event that has already been routed through APZ.
+ nsEventStatus ProcessUntransformedAPZEvent(
+ mozilla::WidgetInputEvent* aEvent,
+ const mozilla::layers::APZEventResult& aApzResult);
+
+ nsresult SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout,
+ int32_t aNativeKeyCode,
+ uint32_t aModifierFlags,
+ const nsAString& aCharacters,
+ const nsAString& aUnmodifiedCharacters,
+ nsIObserver* aObserver) override {
+ mozilla::widget::AutoObserverNotifier notifier(aObserver, "keyevent");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ nsresult SynthesizeNativeMouseEvent(LayoutDeviceIntPoint aPoint,
+ NativeMouseMessage aNativeMessage,
+ mozilla::MouseButton aButton,
+ nsIWidget::Modifiers aModifierFlags,
+ nsIObserver* aObserver) override {
+ mozilla::widget::AutoObserverNotifier notifier(aObserver, "mouseevent");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ nsresult SynthesizeNativeMouseMove(LayoutDeviceIntPoint aPoint,
+ nsIObserver* aObserver) override {
+ mozilla::widget::AutoObserverNotifier notifier(aObserver, "mouseevent");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ nsresult SynthesizeNativeMouseScrollEvent(
+ LayoutDeviceIntPoint aPoint, uint32_t aNativeMessage, double aDeltaX,
+ double aDeltaY, double aDeltaZ, uint32_t aModifierFlags,
+ uint32_t aAdditionalFlags, nsIObserver* aObserver) override {
+ mozilla::widget::AutoObserverNotifier notifier(aObserver,
+ "mousescrollevent");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ nsresult SynthesizeNativeTouchPoint(uint32_t aPointerId,
+ TouchPointerState aPointerState,
+ LayoutDeviceIntPoint aPoint,
+ double aPointerPressure,
+ uint32_t aPointerOrientation,
+ nsIObserver* aObserver) override {
+ mozilla::widget::AutoObserverNotifier notifier(aObserver, "touchpoint");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ nsresult SynthesizeNativeTouchPadPinch(TouchpadGesturePhase aEventPhase,
+ float aScale,
+ LayoutDeviceIntPoint aPoint,
+ int32_t aModifierFlags) override {
+ MOZ_RELEASE_ASSERT(
+ false, "This method is not implemented on the current platform");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ nsresult SynthesizeNativePenInput(uint32_t aPointerId,
+ TouchPointerState aPointerState,
+ LayoutDeviceIntPoint aPoint,
+ double aPressure, uint32_t aRotation,
+ int32_t aTiltX, int32_t aTiltY,
+ int32_t aButton,
+ nsIObserver* aObserver) override {
+ MOZ_RELEASE_ASSERT(
+ false, "This method is not implemented on the current platform");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ nsresult SynthesizeNativeTouchpadDoubleTap(LayoutDeviceIntPoint aPoint,
+ uint32_t aModifierFlags) override {
+ MOZ_RELEASE_ASSERT(
+ false, "This method is not implemented on the current platform");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ nsresult SynthesizeNativeTouchpadPan(TouchpadGesturePhase aEventPhase,
+ LayoutDeviceIntPoint aPoint,
+ double aDeltaX, double aDeltaY,
+ int32_t aModifierFlags,
+ nsIObserver* aObserver) override {
+ MOZ_RELEASE_ASSERT(
+ false, "This method is not implemented on the current platform");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ /**
+ * GetPseudoIMEContext() returns pseudo IME context when TextEventDispatcher
+ * has non-native input transaction. Otherwise, returns nullptr.
+ */
+ void* GetPseudoIMEContext();
+
+ protected:
+ virtual already_AddRefed<nsIWidget> AllocateChildPopupWidget() {
+ return nsIWidget::CreateChildWindow();
+ }
+
+ WindowRenderer* CreateFallbackRenderer();
+
+ PopupType GetPopupType() const { return mPopupType; }
+
+ bool HasRemoteContent() const { return mHasRemoteContent; }
+
+ /**
+ * Apply the current size constraints to the given size.
+ *
+ * @param aWidth width to constrain
+ * @param aHeight height to constrain
+ */
+ void ConstrainSize(int32_t* aWidth, int32_t* aHeight) override {
+ SizeConstraints c = GetSizeConstraints();
+ *aWidth = std::max(c.mMinSize.width, std::min(c.mMaxSize.width, *aWidth));
+ *aHeight =
+ std::max(c.mMinSize.height, std::min(c.mMaxSize.height, *aHeight));
+ }
+
+ CompositorBridgeChild* GetRemoteRenderer() override;
+
+ void ClearCachedWebrenderResources() override;
+
+ void ClearWebrenderAnimationResources() override;
+
+ bool SetNeedFastSnaphot() override;
+
+ /**
+ * Notify the widget that this window is being used with OMTC.
+ */
+ virtual void WindowUsesOMTC() {}
+ virtual void RegisterTouchWindow() {}
+
+ mozilla::dom::Document* GetDocument() const;
+
+ void EnsureTextEventDispatcher();
+
+ // Notify the compositor that a device reset has occurred.
+ void OnRenderingDeviceReset();
+
+ bool UseAPZ();
+
+ bool AllowWebRenderForThisWindow();
+
+ /**
+ * For widgets that support synthesizing native touch events, this function
+ * can be used to manage the current state of synthetic pointers. Each widget
+ * must maintain its own MultiTouchInput instance and pass it in as the state,
+ * along with the desired parameters for the changes. This function returns
+ * a new MultiTouchInput object that is ready to be dispatched.
+ */
+ mozilla::MultiTouchInput UpdateSynthesizedTouchState(
+ mozilla::MultiTouchInput* aState, mozilla::TimeStamp aTimeStamp,
+ uint32_t aPointerId, TouchPointerState aPointerState,
+ LayoutDeviceIntPoint aPoint, double aPointerPressure,
+ uint32_t aPointerOrientation);
+
+ /**
+ * Dispatch the given MultiTouchInput through APZ to Gecko (if APZ is enabled)
+ * or directly to gecko (if APZ is not enabled). This function must only
+ * be called from the main thread, and if APZ is enabled, that must also be
+ * the APZ controller thread.
+ */
+ void DispatchTouchInput(
+ mozilla::MultiTouchInput& aInput,
+ uint16_t aInputSource =
+ mozilla::dom::MouseEvent_Binding::MOZ_SOURCE_TOUCH);
+
+ /**
+ * Dispatch the given PanGestureInput through APZ to Gecko (if APZ is enabled)
+ * or directly to gecko (if APZ is not enabled). This function must only
+ * be called from the main thread, and if APZ is enabled, that must also be
+ * the APZ controller thread.
+ */
+ void DispatchPanGestureInput(mozilla::PanGestureInput& aInput);
+ void DispatchPinchGestureInput(mozilla::PinchGestureInput& aInput);
+
+ static bool ConvertStatus(nsEventStatus aStatus) {
+ return aStatus == nsEventStatus_eConsumeNoDefault;
+ }
+
+ protected:
+ // Returns whether compositing should use an external surface size.
+ virtual bool UseExternalCompositingSurface() const { return false; }
+
+ /**
+ * Starts the OMTC compositor destruction sequence.
+ *
+ * When this function returns, the compositor should not be
+ * able to access the opengl context anymore.
+ * It is safe to call it several times if platform implementations
+ * require the compositor to be destroyed before ~nsBaseWidget is
+ * reached (This is the case with gtk2 for instance).
+ */
+ virtual void DestroyCompositor();
+ void DestroyLayerManager();
+ void ReleaseContentController();
+ void RevokeTransactionIdAllocator();
+
+ void FreeShutdownObserver();
+ void FreeLocalesChangedObserver();
+
+ bool IsPIPWindow() const { return mIsPIPWindow; };
+
+ nsIWidgetListener* mWidgetListener;
+ nsIWidgetListener* mAttachedWidgetListener;
+ nsIWidgetListener* mPreviouslyAttachedWidgetListener;
+ RefPtr<WindowRenderer> mWindowRenderer;
+ RefPtr<CompositorSession> mCompositorSession;
+ RefPtr<CompositorBridgeChild> mCompositorBridgeChild;
+
+ mozilla::UniquePtr<mozilla::Mutex> mCompositorVsyncDispatcherLock;
+ RefPtr<mozilla::CompositorVsyncDispatcher> mCompositorVsyncDispatcher;
+
+ RefPtr<IAPZCTreeManager> mAPZC;
+ RefPtr<GeckoContentController> mRootContentController;
+ RefPtr<APZEventState> mAPZEventState;
+ RefPtr<WidgetShutdownObserver> mShutdownObserver;
+ RefPtr<LocalesChangedObserver> mLocalesChangedObserver;
+ RefPtr<TextEventDispatcher> mTextEventDispatcher;
+ RefPtr<mozilla::SwipeTracker> mSwipeTracker;
+ mozilla::UniquePtr<mozilla::SwipeEventQueue> mSwipeEventQueue;
+ Cursor mCursor;
+ bool mCustomCursorAllowed = true;
+ BorderStyle mBorderStyle;
+ LayoutDeviceIntRect mBounds;
+ bool mIsTiled;
+ PopupLevel mPopupLevel;
+ PopupType mPopupType;
+ SizeConstraints mSizeConstraints;
+ bool mHasRemoteContent;
+
+ struct FullscreenSavedState {
+ DesktopRect windowRect;
+ DesktopRect screenRect;
+ };
+ mozilla::Maybe<FullscreenSavedState> mSavedBounds;
+
+ bool mUpdateCursor;
+ bool mUseAttachedEvents;
+ bool mIMEHasFocus;
+ bool mIMEHasQuit;
+ bool mIsFullyOccluded;
+ bool mNeedFastSnaphot;
+ // This flag is only used when APZ is off. It indicates that the current pan
+ // gesture was processed as a swipe. Sometimes the swipe animation can finish
+ // before momentum events of the pan gesture have stopped firing, so this
+ // flag tells us that we shouldn't allow the remaining events to cause
+ // scrolling. It is reset to false once a new gesture starts (as indicated by
+ // a PANGESTURE_(MAY)START event).
+ bool mCurrentPanGestureBelongsToSwipe;
+
+ // It's PictureInPicture window.
+ bool mIsPIPWindow : 1;
+
+ struct InitialZoomConstraints {
+ InitialZoomConstraints(const uint32_t& aPresShellID,
+ const ScrollableLayerGuid::ViewID& aViewID,
+ const ZoomConstraints& aConstraints)
+ : mPresShellID(aPresShellID),
+ mViewID(aViewID),
+ mConstraints(aConstraints) {}
+
+ uint32_t mPresShellID;
+ ScrollableLayerGuid::ViewID mViewID;
+ ZoomConstraints mConstraints;
+ };
+
+ mozilla::Maybe<InitialZoomConstraints> mInitialZoomConstraints;
+
+ // This points to the resize listeners who have been notified that a live
+ // resize is in progress. This should always be empty when a live-resize is
+ // not in progress.
+ nsTArray<RefPtr<mozilla::LiveResizeListener>> mLiveResizeListeners;
+
+#ifdef DEBUG
+ protected:
+ static nsAutoString debug_GuiEventToString(
+ mozilla::WidgetGUIEvent* aGuiEvent);
+
+ static void debug_DumpInvalidate(FILE* aFileOut, nsIWidget* aWidget,
+ const LayoutDeviceIntRect* aRect,
+ const char* aWidgetName, int32_t aWindowID);
+
+ static void debug_DumpEvent(FILE* aFileOut, nsIWidget* aWidget,
+ mozilla::WidgetGUIEvent* aGuiEvent,
+ const char* aWidgetName, int32_t aWindowID);
+
+ static void debug_DumpPaintEvent(FILE* aFileOut, nsIWidget* aWidget,
+ const nsIntRegion& aPaintEvent,
+ const char* aWidgetName, int32_t aWindowID);
+
+ static bool debug_GetCachedBoolPref(const char* aPrefName);
+#endif
+
+ private:
+ already_AddRefed<mozilla::layers::WebRenderLayerManager>
+ CreateCompositorSession(int aWidth, int aHeight,
+ mozilla::layers::CompositorOptions* aOptionsOut);
+};
+
+#endif // nsBaseWidget_h__