mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 15:23:51 +00:00
ec80afc7a4
When entering fullscreen and saving the original position of a window, also save the position to which it was moved. When leaving fullscreen, keep the window on the same screen. Restore its _screen-relative_ position, rather than its absolute position. Differential Revision: https://phabricator.services.mozilla.com/D153410
792 lines
30 KiB
C++
792 lines
30 KiB
C++
/* -*- 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(nsBorderStyle aBorderStyle);
|
|
|
|
NS_DECL_THREADSAFE_ISUPPORTS
|
|
|
|
// nsIWidget interface
|
|
void CaptureMouse(bool aCapture) override {}
|
|
void CaptureRollupEvents(nsIRollupListener* aListener,
|
|
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 ClearCachedCursor() final {
|
|
mCursor = {};
|
|
mUpdateCursor = true;
|
|
}
|
|
void SetTransparencyMode(nsTransparencyMode aMode) override;
|
|
nsTransparencyMode GetTransparencyMode() override;
|
|
void SetWindowShadowStyle(mozilla::StyleWindowShadow aStyle) 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<nsIScreen> 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.
|
|
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) 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 <= eWindowType_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(bool aAllowSlop, int32_t* aX, int32_t* aY) 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(LayoutDeviceIntMargin& aMargins) 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 {}
|
|
void SetDrawsInTitlebar(bool aState) override {}
|
|
bool ShowsResizeIndicator(LayoutDeviceIntRect* aResizerRect) override;
|
|
void FreeNativeData(void* data, uint32_t aDataType) override {}
|
|
[[nodiscard]] nsresult BeginResizeDrag(mozilla::WidgetGUIEvent* aEvent,
|
|
int32_t aHorizontal,
|
|
int32_t aVertical) override {
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
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, nsWidgetInitData* 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);
|
|
struct SwipeInfo {
|
|
bool wantsSwipe;
|
|
uint32_t allowedDirections;
|
|
};
|
|
SwipeInfo SendMayStartSwipe(const mozilla::PanGestureInput& aSwipeStartEvent);
|
|
enum class CanTriggerSwipe : bool {
|
|
No = false,
|
|
Yes = true,
|
|
};
|
|
// 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,
|
|
CanTriggerSwipe aCanTriggerSwipe);
|
|
|
|
// Returns true if |aPanInput| event was used for SwipeTracker, false
|
|
// otherwise.
|
|
bool MayStartSwipeForNonAPZ(const mozilla::PanGestureInput& aPanInput,
|
|
CanTriggerSwipe aCanTriggerSwipe);
|
|
|
|
void NotifyWindowDestroyed();
|
|
void NotifySizeMoveDone();
|
|
|
|
using ByMoveToRect = nsIWidgetListener::ByMoveToRect;
|
|
void NotifyWindowMoved(int32_t aX, int32_t aY,
|
|
ByMoveToRect = ByMoveToRect::No);
|
|
|
|
void SetNativeData(uint32_t aDataType, uintptr_t aVal) override {}
|
|
|
|
// Should be called by derived implementations to notify on system color and
|
|
// theme changes.
|
|
void NotifyThemeChanged(mozilla::widget::ThemeChangeKind);
|
|
void NotifyUIStateChanged(UIStateChangeType aShowFocusRings);
|
|
|
|
#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;
|
|
|
|
nsPopupLevel PopupLevel() { return mPopupLevel; }
|
|
|
|
LayoutDeviceIntSize ClientToWindowSize(
|
|
const LayoutDeviceIntSize& aClientSize) override {
|
|
return aClientSize;
|
|
}
|
|
|
|
// return true if this is a popup widget with a native titlebar
|
|
bool IsPopupWithTitleBar() const {
|
|
return (mWindowType == eWindowType_popup &&
|
|
mBorderStyle != eBorderStyle_default &&
|
|
mBorderStyle & eBorderStyle_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, nsWidgetInitData* 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();
|
|
|
|
nsPopupType PopupType() 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, uint32_t aTime,
|
|
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();
|
|
|
|
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;
|
|
nsBorderStyle mBorderStyle;
|
|
LayoutDeviceIntRect mBounds;
|
|
bool mIsTiled;
|
|
nsPopupLevel mPopupLevel;
|
|
nsPopupType 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;
|
|
|
|
static nsIRollupListener* gRollupListener;
|
|
|
|
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__
|