/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim: sw=2 ts=8 et : *//* 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/. *//** * This "puppet widget" isn't really a platform widget. It's intended * to be used in widgetless rendering contexts, such as sandboxed * content processes. If any "real" widgetry is needed, the request * is forwarded to and/or data received from elsewhere. */#ifndef mozilla_widget_PuppetWidget_h__#define mozilla_widget_PuppetWidget_h__#include"mozilla/gfx/2D.h"#include"mozilla/RefPtr.h"#include"nsBaseScreen.h"#include"nsBaseWidget.h"#include"nsCOMArray.h"#include"nsIScreenManager.h"#include"nsThreadUtils.h"#include"mozilla/Attributes.h"#include"mozilla/ContentCache.h"#include"mozilla/EventForwards.h"#include"mozilla/TextEventDispatcherListener.h"#include"mozilla/layers/MemoryPressureObserver.h"namespacemozilla{namespacedom{classBrowserChild;}// namespace domnamespacelayers{classWebRenderLayerManager;}// namespace layersnamespacewidget{structAutoCacheNativeKeyCommands;classPuppetWidget:publicnsBaseWidget,publicTextEventDispatcherListener,publiclayers::MemoryPressureListener{typedefmozilla::CSSRectCSSRect;typedefmozilla::dom::BrowserChildBrowserChild;typedefmozilla::gfx::DrawTargetDrawTarget;typedefmozilla::layers::WebRenderLayerManagerWebRenderLayerManager;// Avoiding to make compiler confused between mozilla::widget and nsIWidget.typedefmozilla::widget::TextEventDispatcherTextEventDispatcher;typedefmozilla::widget::TextEventDispatcherListenerTextEventDispatcherListener;typedefnsBaseWidgetBase;// The width and height of the "widget" are clamped to this.staticconstsize_tkMaxDimension;public:explicitPuppetWidget(BrowserChild*aBrowserChild);protected:virtual~PuppetWidget();public:NS_DECL_ISUPPORTS_INHERITED// PuppetWidget creation is infallible, hence InfallibleCreate(), which// Create() calls.usingnsBaseWidget::Create;// for Create signature not overridden herevirtualnsresultCreate(nsIWidget*aParent,nsNativeWidgetaNativeParent,constLayoutDeviceIntRect&aRect,nsWidgetInitData*aInitData=nullptr)override;voidInfallibleCreate(nsIWidget*aParent,nsNativeWidgetaNativeParent,constLayoutDeviceIntRect&aRect,nsWidgetInitData*aInitData=nullptr);voidInitIMEState();virtualalready_AddRefed<nsIWidget>CreateChild(constLayoutDeviceIntRect&aRect,nsWidgetInitData*aInitData=nullptr,boolaForceUseIWidgetParent=false)override;virtualvoidDestroy()override;virtualvoidShow(boolaState)override;virtualboolIsVisible()constoverride{returnmVisible;}virtualvoidConstrainPosition(bool/*ignored aAllowSlop*/,int32_t*aX,int32_t*aY)override{*aX=kMaxDimension;*aY=kMaxDimension;}// Widget position is controlled by the parent process via BrowserChild.virtualvoidMove(doubleaX,doubleaY)override{}virtualvoidResize(doubleaWidth,doubleaHeight,boolaRepaint)override;virtualvoidResize(doubleaX,doubleaY,doubleaWidth,doubleaHeight,boolaRepaint)override{if(!mBounds.IsEqualXY(aX,aY)){NotifyWindowMoved(aX,aY);}mBounds.MoveTo(aX,aY);returnResize(aWidth,aHeight,aRepaint);}// XXX/cjones: copying gtk behavior here; unclear what disabling a// widget is supposed to entailvirtualvoidEnable(boolaState)override{mEnabled=aState;}virtualboolIsEnabled()constoverride{returnmEnabled;}virtualvoidSetFocus(Raise,mozilla::dom::CallerTypeaCallerType)override;virtualnsresultConfigureChildren(constnsTArray<Configuration>&aConfigurations)override;virtualvoidInvalidate(constLayoutDeviceIntRect&aRect)override;// PuppetWidgets don't have native data, as they're purely nonnative.virtualvoid*GetNativeData(uint32_taDataType)override{returnnullptr;}// PuppetWidgets don't have any concept of titles.virtualnsresultSetTitle(constnsAString&aTitle)override{returnNS_ERROR_UNEXPECTED;}virtualmozilla::LayoutDeviceToLayoutDeviceMatrix4x4WidgetToTopLevelWidgetTransform()override;virtualLayoutDeviceIntPointWidgetToScreenOffset()override;virtualLayoutDeviceIntPointTopLevelWidgetToScreenOffset()override{returnGetWindowPosition();}int32_tRoundsWidgetCoordinatesTo()override;voidInitEvent(WidgetGUIEvent&aEvent,LayoutDeviceIntPoint*aPoint=nullptr);virtualnsresultDispatchEvent(WidgetGUIEvent*aEvent,nsEventStatus&aStatus)override;ContentAndAPZEventStatusDispatchInputEvent(WidgetInputEvent*aEvent)override;voidSetConfirmedTargetAPZC(uint64_taInputBlockId,constnsTArray<ScrollableLayerGuid>&aTargets)constoverride;voidUpdateZoomConstraints(constuint32_t&aPresShellId,constScrollableLayerGuid::ViewID&aViewId,constmozilla::Maybe<ZoomConstraints>&aConstraints)override;boolAsyncPanZoomEnabled()constoverride;MOZ_CAN_RUN_SCRIPTvirtualboolGetEditCommands(NativeKeyBindingsTypeaType,constmozilla::WidgetKeyboardEvent&aEvent,nsTArray<mozilla::CommandInt>&aCommands)override;friendstructAutoCacheNativeKeyCommands;//// nsBaseWidget methods we override//// Documents loaded in child processes are always subdocuments of// other docs in an ancestor process. To ensure that the// backgrounds of those documents are painted like those of// same-process subdocuments, we force the widget here to be// transparent, which in turn will cause layout to use a transparent// backstop background color.virtualnsTransparencyModeGetTransparencyMode()override{returneTransparencyTransparent;}virtualWindowRenderer*GetWindowRenderer()override;// This is used for creating remote layer managers and for re-creating// them after a compositor reset. The lambda aInitializeFunc is used to// perform any caller-required initialization for the newly created layer// manager; in the event of a failure, return false and it will destroy the// new layer manager without changing the state of the widget.boolCreateRemoteLayerManager(conststd::function<bool(WebRenderLayerManager*)>&aInitializeFunc);boolHasLayerManager(){return!!mWindowRenderer;}virtualvoidSetInputContext(constInputContext&aContext,constInputContextAction&aAction)override;virtualInputContextGetInputContext()override;virtualNativeIMEContextGetNativeIMEContext()override;TextEventDispatcherListener*GetNativeTextEventDispatcherListener()override{returnmNativeTextEventDispatcherListener?mNativeTextEventDispatcherListener.get():this;}voidSetNativeTextEventDispatcherListener(TextEventDispatcherListener*aListener){mNativeTextEventDispatcherListener=aListener;}virtualvoidSetCursor(constCursor&)override;// Gets the DPI of the screen corresponding to this widget.// Contacts the parent process which gets the DPI from the// proper widget there. TODO: Handle DPI changes that happen// later on.virtualfloatGetDPI()override;virtualdoubleGetDefaultScaleInternal()override;virtualboolNeedsPaint()override;// Paint the widget immediately if any paints are queued up.voidPaintNowIfNeeded();virtualBrowserChild*GetOwningBrowserChild()override{returnmBrowserChild;}voidUpdateBackingScaleCache(floataDpi,int32_taRounding,doubleaScale){mDPI=aDpi;mRounding=aRounding;mDefaultScale=aScale;}nsIntSizeGetScreenDimensions();// safe area insets supportvirtualScreenIntMarginGetSafeAreaInsets()constoverride;voidUpdateSafeAreaInsets(constScreenIntMargin&aSafeAreaInsets);// Get the offset to the chrome of the window that this tab belongs to.//// NOTE: In OOP iframes this value is zero. You should use// WidgetToTopLevelWidgetTransform instead which is already including the// chrome offset.LayoutDeviceIntPointGetChromeOffset();// Get the screen position of the application window.LayoutDeviceIntPointGetWindowPosition();virtualLayoutDeviceIntRectGetScreenBounds()override;virtualnsresultSynthesizeNativeKeyEvent(int32_taNativeKeyboardLayout,int32_taNativeKeyCode,uint32_taModifierFlags,constnsAString&aCharacters,constnsAString&aUnmodifiedCharacters,nsIObserver*aObserver)override;virtualnsresultSynthesizeNativeMouseEvent(LayoutDeviceIntPointaPoint,NativeMouseMessageaNativeMessage,MouseButtonaButton,nsIWidget::ModifiersaModifierFlags,nsIObserver*aObserver)override;virtualnsresultSynthesizeNativeMouseMove(LayoutDeviceIntPointaPoint,nsIObserver*aObserver)override;virtualnsresultSynthesizeNativeMouseScrollEvent(LayoutDeviceIntPointaPoint,uint32_taNativeMessage,doubleaDeltaX,doubleaDeltaY,doubleaDeltaZ,uint32_taModifierFlags,uint32_taAdditionalFlags,nsIObserver*aObserver)override;virtualnsresultSynthesizeNativeTouchPoint(uint32_taPointerId,TouchPointerStateaPointerState,LayoutDeviceIntPointaPoint,doubleaPointerPressure,uint32_taPointerOrientation,nsIObserver*aObserver)override;virtualnsresultSynthesizeNativeTouchPadPinch(TouchpadGesturePhaseaEventPhase,floataScale,LayoutDeviceIntPointaPoint,int32_taModifierFlags)override;virtualnsresultSynthesizeNativeTouchTap(LayoutDeviceIntPointaPoint,boolaLongTap,nsIObserver*aObserver)override;virtualnsresultClearNativeTouchSequence(nsIObserver*aObserver)override;virtualuint32_tGetMaxTouchPoints()constoverride;virtualnsresultSynthesizeNativePenInput(uint32_taPointerId,TouchPointerStateaPointerState,LayoutDeviceIntPointaPoint,doubleaPressure,uint32_taRotation,int32_taTiltX,int32_taTiltY,nsIObserver*aObserver)override;virtualnsresultSynthesizeNativeTouchpadDoubleTap(LayoutDeviceIntPointaPoint,uint32_taModifierFlags)override;virtualnsresultSynthesizeNativeTouchpadPan(TouchpadGesturePhaseaEventPhase,LayoutDeviceIntPointaPoint,doubleaDeltaX,doubleaDeltaY,int32_taModifierFlags)override;virtualvoidLockNativePointer()override;virtualvoidUnlockNativePointer()override;virtualvoidStartAsyncScrollbarDrag(constAsyncDragMetrics&aDragMetrics)override;virtualvoidZoomToRect(constuint32_t&aPresShellId,constScrollableLayerGuid::ViewID&aViewId,constCSSRect&aRect,constuint32_t&aFlags)override;virtualboolHasPendingInputEvent()override;virtualvoidLookUpDictionary(constnsAString&aText,constnsTArray<mozilla::FontRange>&aFontRangeArray,constboolaIsVertical,constLayoutDeviceIntPoint&aPoint)override;nsresultSetSystemFont(constnsCString&aFontName)override;nsresultGetSystemFont(nsCString&aFontName)override;// TextEventDispatcherListenerusingnsBaseWidget::NotifyIME;NS_IMETHODNotifyIME(TextEventDispatcher*aTextEventDispatcher,constIMENotification&aNotification)override;NS_IMETHOD_(IMENotificationRequests)GetIMENotificationRequests()override;NS_IMETHOD_(void)OnRemovedFrom(TextEventDispatcher*aTextEventDispatcher)override;NS_IMETHOD_(void)WillDispatchKeyboardEvent(TextEventDispatcher*aTextEventDispatcher,WidgetKeyboardEvent&aKeyboardEvent,uint32_taIndexOfKeypress,void*aData)override;virtualvoidOnMemoryPressure(layers::MemoryPressureReasonaWhy)override;private:voidPaint();voidSetChild(PuppetWidget*aChild);nsresultRequestIMEToCommitComposition(boolaCancel);nsresultNotifyIMEOfFocusChange(constIMENotification&aIMENotification);nsresultNotifyIMEOfSelectionChange(constIMENotification&aIMENotification);nsresultNotifyIMEOfCompositionUpdate(constIMENotification&aIMENotification);nsresultNotifyIMEOfTextChange(constIMENotification&aIMENotification);nsresultNotifyIMEOfMouseButtonEvent(constIMENotification&aIMENotification);nsresultNotifyIMEOfPositionChange(constIMENotification&aIMENotification);boolCacheEditorRect();boolCacheCompositionRects(uint32_t&aStartOffset,nsTArray<LayoutDeviceIntRect>&aRectArray,uint32_t&aTargetCauseOffset);boolGetCaretRect(LayoutDeviceIntRect&aCaretRect,uint32_taCaretOffset);uint32_tGetCaretOffset();nsIWidgetListener*GetCurrentWidgetListener();// When this widget caches input context and currently managed by// IMEStateManager, the cache is valid.boolHaveValidInputContextCache()const;classWidgetPaintTask:publicRunnable{public:NS_DECL_NSIRUNNABLEexplicitWidgetPaintTask(PuppetWidget*widget):Runnable("PuppetWidget::WidgetPaintTask"),mWidget(widget){}voidRevoke(){mWidget=nullptr;}private:PuppetWidget*mWidget;};nsRefreshDriver*GetTopLevelRefreshDriver()const;// BrowserChild normally holds a strong reference to this PuppetWidget// or its root ancestor, but each PuppetWidget also needs a// reference back to BrowserChild (e.g. to delegate nsIWidget IME calls// to chrome) So we hold a weak reference to BrowserChild here. Since// it's possible for BrowserChild to outlive the PuppetWidget, we clear// this weak reference in Destroy()BrowserChild*mBrowserChild;// The "widget" to which we delegate events if we don't have an// event handler.RefPtr<PuppetWidget>mChild;nsRevocableEventPtr<WidgetPaintTask>mWidgetPaintTask;RefPtr<layers::MemoryPressureObserver>mMemoryPressureObserver;// XXX/cjones: keeping this around until we teach LayerManager to do// retained-content-only transactionsRefPtr<DrawTarget>mDrawTarget;// IMEIMENotificationRequestsmIMENotificationRequestsOfParent;InputContextmInputContext;// mNativeIMEContext is initialized when this dispatches every composition// event both from parent process's widget and TextEventDispatcher in same// process. If it hasn't been started composition yet, this isn't necessary// for XP code since there is no TextComposition instance which is caused by// the PuppetWidget instance.NativeIMEContextmNativeIMEContext;ContentCacheInChildmContentCache;// The DPI of the screen corresponding to this widgetfloatmDPI;int32_tmRounding;doublemDefaultScale;ScreenIntMarginmSafeAreaInsets;RefPtr<TextEventDispatcherListener>mNativeTextEventDispatcherListener;protected:boolmEnabled;boolmVisible;private:boolmNeedIMEStateInit;// When remote process requests to commit/cancel a composition, the// composition may have already been committed in the main process. In such// case, this will receive remaining composition events for the old// composition even after requesting to commit/cancel the old composition// but the TextComposition for the old composition has already been// destroyed. So, until this meets new eCompositionStart, following// composition events should be ignored if this is set to true.boolmIgnoreCompositionEvents;};classPuppetScreen:publicnsBaseScreen{public:explicitPuppetScreen(void*nativeScreen);~PuppetScreen();NS_IMETHODGetRect(int32_t*aLeft,int32_t*aTop,int32_t*aWidth,int32_t*aHeight)override;NS_IMETHODGetAvailRect(int32_t*aLeft,int32_t*aTop,int32_t*aWidth,int32_t*aHeight)override;NS_IMETHODGetPixelDepth(int32_t*aPixelDepth)override;NS_IMETHODGetColorDepth(int32_t*aColorDepth)override;};classPuppetScreenManagerfinal:publicnsIScreenManager{~PuppetScreenManager();public:PuppetScreenManager();NS_DECL_ISUPPORTSNS_DECL_NSISCREENMANAGERprotected:nsCOMPtr<nsIScreen>mOneScreen;};}// namespace widget}// namespace mozilla#endif // mozilla_widget_PuppetWidget_h__