Bug 1869043 assert that graph set access is main thread only r=padenot
[gecko.git] / widget / PuppetWidget.h
blob65050bb4553bcbf32439fcae857520af676098c2
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: sw=2 ts=8 et :
3 */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 /**
9 * This "puppet widget" isn't really a platform widget. It's intended
10 * to be used in widgetless rendering contexts, such as sandboxed
11 * content processes. If any "real" widgetry is needed, the request
12 * is forwarded to and/or data received from elsewhere.
15 #ifndef mozilla_widget_PuppetWidget_h__
16 #define mozilla_widget_PuppetWidget_h__
18 #include "mozilla/gfx/2D.h"
19 #include "mozilla/RefPtr.h"
20 #include "nsBaseWidget.h"
21 #include "nsCOMArray.h"
22 #include "nsThreadUtils.h"
23 #include "mozilla/Attributes.h"
24 #include "mozilla/ContentCache.h"
25 #include "mozilla/EventForwards.h"
26 #include "mozilla/TextEventDispatcherListener.h"
27 #include "mozilla/layers/MemoryPressureObserver.h"
29 namespace mozilla {
30 enum class NativeKeyBindingsType : uint8_t;
32 namespace dom {
33 class BrowserChild;
34 } // namespace dom
36 namespace layers {
37 class WebRenderLayerManager;
38 } // namespace layers
40 namespace widget {
42 struct AutoCacheNativeKeyCommands;
44 class PuppetWidget : public nsBaseWidget,
45 public TextEventDispatcherListener,
46 public layers::MemoryPressureListener {
47 typedef mozilla::CSSRect CSSRect;
48 typedef mozilla::dom::BrowserChild BrowserChild;
49 typedef mozilla::gfx::DrawTarget DrawTarget;
50 typedef mozilla::layers::WebRenderLayerManager WebRenderLayerManager;
52 // Avoiding to make compiler confused between mozilla::widget and nsIWidget.
53 typedef mozilla::widget::TextEventDispatcher TextEventDispatcher;
54 typedef mozilla::widget::TextEventDispatcherListener
55 TextEventDispatcherListener;
57 typedef nsBaseWidget Base;
59 // The width and height of the "widget" are clamped to this.
60 public:
61 explicit PuppetWidget(BrowserChild* aBrowserChild);
63 protected:
64 virtual ~PuppetWidget();
66 public:
67 NS_DECL_ISUPPORTS_INHERITED
69 // PuppetWidget creation is infallible, hence InfallibleCreate(), which
70 // Create() calls.
71 using nsBaseWidget::Create; // for Create signature not overridden here
72 virtual nsresult Create(nsIWidget* aParent, nsNativeWidget aNativeParent,
73 const LayoutDeviceIntRect& aRect,
74 widget::InitData* aInitData = nullptr) override;
75 void InfallibleCreate(nsIWidget* aParent, nsNativeWidget aNativeParent,
76 const LayoutDeviceIntRect& aRect,
77 widget::InitData* aInitData = nullptr);
79 void InitIMEState();
81 virtual already_AddRefed<nsIWidget> CreateChild(
82 const LayoutDeviceIntRect& aRect, widget::InitData* aInitData = nullptr,
83 bool aForceUseIWidgetParent = false) override;
85 virtual void Destroy() override;
87 virtual void Show(bool aState) override;
89 virtual bool IsVisible() const override { return mVisible; }
91 // Widget position is controlled by the parent process via BrowserChild.
92 virtual void Move(double aX, double aY) override {}
94 virtual void Resize(double aWidth, double aHeight, bool aRepaint) override;
95 virtual void Resize(double aX, double aY, double aWidth, double aHeight,
96 bool aRepaint) override {
97 if (!mBounds.IsEqualXY(aX, aY)) {
98 NotifyWindowMoved(aX, aY);
100 mBounds.MoveTo(aX, aY);
101 return Resize(aWidth, aHeight, aRepaint);
104 // XXX/cjones: copying gtk behavior here; unclear what disabling a
105 // widget is supposed to entail
106 virtual void Enable(bool aState) override { mEnabled = aState; }
107 virtual bool IsEnabled() const override { return mEnabled; }
109 virtual nsSizeMode SizeMode() override { return mSizeMode; }
110 virtual void SetSizeMode(nsSizeMode aMode) override { mSizeMode = aMode; }
112 virtual void SetFocus(Raise, mozilla::dom::CallerType aCallerType) override;
114 virtual void Invalidate(const LayoutDeviceIntRect& aRect) override;
116 // PuppetWidgets don't have native data, as they're purely nonnative.
117 virtual void* GetNativeData(uint32_t aDataType) override { return nullptr; }
119 // PuppetWidgets don't have any concept of titles.
120 virtual nsresult SetTitle(const nsAString& aTitle) override {
121 return NS_ERROR_UNEXPECTED;
124 virtual mozilla::LayoutDeviceToLayoutDeviceMatrix4x4
125 WidgetToTopLevelWidgetTransform() override;
127 virtual LayoutDeviceIntPoint WidgetToScreenOffset() override;
129 virtual LayoutDeviceIntPoint TopLevelWidgetToScreenOffset() override {
130 return GetWindowPosition();
133 int32_t RoundsWidgetCoordinatesTo() override { return mRounding; }
135 void InitEvent(WidgetGUIEvent& aEvent,
136 LayoutDeviceIntPoint* aPoint = nullptr);
138 virtual nsresult DispatchEvent(WidgetGUIEvent* aEvent,
139 nsEventStatus& aStatus) override;
140 ContentAndAPZEventStatus DispatchInputEvent(
141 WidgetInputEvent* aEvent) override;
142 void SetConfirmedTargetAPZC(
143 uint64_t aInputBlockId,
144 const nsTArray<ScrollableLayerGuid>& aTargets) const override;
145 void UpdateZoomConstraints(
146 const uint32_t& aPresShellId, const ScrollableLayerGuid::ViewID& aViewId,
147 const mozilla::Maybe<ZoomConstraints>& aConstraints) override;
148 bool AsyncPanZoomEnabled() const override;
150 MOZ_CAN_RUN_SCRIPT virtual bool GetEditCommands(
151 NativeKeyBindingsType aType, const mozilla::WidgetKeyboardEvent& aEvent,
152 nsTArray<mozilla::CommandInt>& aCommands) override;
154 friend struct AutoCacheNativeKeyCommands;
157 // nsBaseWidget methods we override
160 // Documents loaded in child processes are always subdocuments of
161 // other docs in an ancestor process. To ensure that the
162 // backgrounds of those documents are painted like those of
163 // same-process subdocuments, we force the widget here to be
164 // transparent, which in turn will cause layout to use a transparent
165 // backstop background color.
166 virtual TransparencyMode GetTransparencyMode() override {
167 return TransparencyMode::Transparent;
170 virtual WindowRenderer* GetWindowRenderer() override;
172 // This is used for creating remote layer managers and for re-creating
173 // them after a compositor reset. The lambda aInitializeFunc is used to
174 // perform any caller-required initialization for the newly created layer
175 // manager; in the event of a failure, return false and it will destroy the
176 // new layer manager without changing the state of the widget.
177 bool CreateRemoteLayerManager(
178 const std::function<bool(WebRenderLayerManager*)>& aInitializeFunc);
180 virtual void SetInputContext(const InputContext& aContext,
181 const InputContextAction& aAction) override;
182 virtual InputContext GetInputContext() override;
183 virtual NativeIMEContext GetNativeIMEContext() override;
184 TextEventDispatcherListener* GetNativeTextEventDispatcherListener() override {
185 return mNativeTextEventDispatcherListener
186 ? mNativeTextEventDispatcherListener.get()
187 : this;
189 void SetNativeTextEventDispatcherListener(
190 TextEventDispatcherListener* aListener) {
191 mNativeTextEventDispatcherListener = aListener;
194 virtual void SetCursor(const Cursor&) override;
196 float GetDPI() override { return mDPI; }
197 double GetDefaultScaleInternal() override { return mDefaultScale; }
199 virtual bool NeedsPaint() override;
201 // Paint the widget immediately if any paints are queued up.
202 void PaintNowIfNeeded();
204 virtual BrowserChild* GetOwningBrowserChild() override {
205 return mBrowserChild;
208 void UpdateBackingScaleCache(float aDpi, int32_t aRounding, double aScale) {
209 mDPI = aDpi;
210 mRounding = aRounding;
211 mDefaultScale = aScale;
214 // safe area insets support
215 virtual ScreenIntMargin GetSafeAreaInsets() const override;
216 void UpdateSafeAreaInsets(const ScreenIntMargin& aSafeAreaInsets);
218 // Get the offset to the chrome of the window that this tab belongs to.
220 // NOTE: In OOP iframes this value is zero. You should use
221 // WidgetToTopLevelWidgetTransform instead which is already including the
222 // chrome offset.
223 LayoutDeviceIntPoint GetChromeOffset();
225 // Get the screen position of the application window.
226 LayoutDeviceIntPoint GetWindowPosition();
228 virtual LayoutDeviceIntRect GetScreenBounds() override;
230 virtual nsresult SynthesizeNativeKeyEvent(
231 int32_t aNativeKeyboardLayout, int32_t aNativeKeyCode,
232 uint32_t aModifierFlags, const nsAString& aCharacters,
233 const nsAString& aUnmodifiedCharacters, nsIObserver* aObserver) override;
234 virtual nsresult SynthesizeNativeMouseEvent(
235 LayoutDeviceIntPoint aPoint, NativeMouseMessage aNativeMessage,
236 MouseButton aButton, nsIWidget::Modifiers aModifierFlags,
237 nsIObserver* aObserver) override;
238 virtual nsresult SynthesizeNativeMouseMove(LayoutDeviceIntPoint aPoint,
239 nsIObserver* aObserver) override;
240 virtual nsresult SynthesizeNativeMouseScrollEvent(
241 LayoutDeviceIntPoint aPoint, uint32_t aNativeMessage, double aDeltaX,
242 double aDeltaY, double aDeltaZ, uint32_t aModifierFlags,
243 uint32_t aAdditionalFlags, nsIObserver* aObserver) override;
244 virtual nsresult SynthesizeNativeTouchPoint(uint32_t aPointerId,
245 TouchPointerState aPointerState,
246 LayoutDeviceIntPoint aPoint,
247 double aPointerPressure,
248 uint32_t aPointerOrientation,
249 nsIObserver* aObserver) override;
250 virtual nsresult SynthesizeNativeTouchPadPinch(
251 TouchpadGesturePhase aEventPhase, float aScale,
252 LayoutDeviceIntPoint aPoint, int32_t aModifierFlags) override;
253 virtual nsresult SynthesizeNativeTouchTap(LayoutDeviceIntPoint aPoint,
254 bool aLongTap,
255 nsIObserver* aObserver) override;
256 virtual nsresult ClearNativeTouchSequence(nsIObserver* aObserver) override;
257 virtual uint32_t GetMaxTouchPoints() const override;
258 virtual nsresult SynthesizeNativePenInput(uint32_t aPointerId,
259 TouchPointerState aPointerState,
260 LayoutDeviceIntPoint aPoint,
261 double aPressure,
262 uint32_t aRotation, int32_t aTiltX,
263 int32_t aTiltY, int32_t aButton,
264 nsIObserver* aObserver) override;
266 virtual nsresult SynthesizeNativeTouchpadDoubleTap(
267 LayoutDeviceIntPoint aPoint, uint32_t aModifierFlags) override;
269 virtual nsresult SynthesizeNativeTouchpadPan(TouchpadGesturePhase aEventPhase,
270 LayoutDeviceIntPoint aPoint,
271 double aDeltaX, double aDeltaY,
272 int32_t aModifierFlags,
273 nsIObserver* aObserver) override;
275 virtual void LockNativePointer() override;
276 virtual void UnlockNativePointer() override;
278 virtual void StartAsyncScrollbarDrag(
279 const AsyncDragMetrics& aDragMetrics) override;
281 virtual void ZoomToRect(const uint32_t& aPresShellId,
282 const ScrollableLayerGuid::ViewID& aViewId,
283 const CSSRect& aRect,
284 const uint32_t& aFlags) override;
286 virtual bool HasPendingInputEvent() override;
288 virtual void LookUpDictionary(
289 const nsAString& aText,
290 const nsTArray<mozilla::FontRange>& aFontRangeArray,
291 const bool aIsVertical, const LayoutDeviceIntPoint& aPoint) override;
293 nsresult SetSystemFont(const nsCString& aFontName) override;
294 nsresult GetSystemFont(nsCString& aFontName) override;
296 // TextEventDispatcherListener
297 using nsBaseWidget::NotifyIME;
298 NS_IMETHOD NotifyIME(TextEventDispatcher* aTextEventDispatcher,
299 const IMENotification& aNotification) override;
300 NS_IMETHOD_(IMENotificationRequests) GetIMENotificationRequests() override;
301 NS_IMETHOD_(void)
302 OnRemovedFrom(TextEventDispatcher* aTextEventDispatcher) override;
303 NS_IMETHOD_(void)
304 WillDispatchKeyboardEvent(TextEventDispatcher* aTextEventDispatcher,
305 WidgetKeyboardEvent& aKeyboardEvent,
306 uint32_t aIndexOfKeypress, void* aData) override;
308 virtual void OnMemoryPressure(layers::MemoryPressureReason aWhy) override;
310 private:
311 void Paint();
313 void SetChild(PuppetWidget* aChild);
315 nsresult RequestIMEToCommitComposition(bool aCancel);
316 nsresult NotifyIMEOfFocusChange(const IMENotification& aIMENotification);
317 nsresult NotifyIMEOfSelectionChange(const IMENotification& aIMENotification);
318 nsresult NotifyIMEOfCompositionUpdate(
319 const IMENotification& aIMENotification);
320 nsresult NotifyIMEOfTextChange(const IMENotification& aIMENotification);
321 nsresult NotifyIMEOfMouseButtonEvent(const IMENotification& aIMENotification);
322 nsresult NotifyIMEOfPositionChange(const IMENotification& aIMENotification);
324 bool CacheEditorRect();
325 bool CacheCompositionRects(uint32_t& aStartOffset,
326 nsTArray<LayoutDeviceIntRect>& aRectArray,
327 uint32_t& aTargetCauseOffset);
328 bool GetCaretRect(LayoutDeviceIntRect& aCaretRect, uint32_t aCaretOffset);
329 uint32_t GetCaretOffset();
331 nsIWidgetListener* GetCurrentWidgetListener();
333 // When this widget caches input context and currently managed by
334 // IMEStateManager, the cache is valid.
335 bool HaveValidInputContextCache() const;
337 class WidgetPaintTask : public Runnable {
338 public:
339 NS_DECL_NSIRUNNABLE
340 explicit WidgetPaintTask(PuppetWidget* widget)
341 : Runnable("PuppetWidget::WidgetPaintTask"), mWidget(widget) {}
342 void Revoke() { mWidget = nullptr; }
344 private:
345 PuppetWidget* mWidget;
348 nsRefreshDriver* GetTopLevelRefreshDriver() const;
350 // BrowserChild normally holds a strong reference to this PuppetWidget
351 // or its root ancestor, but each PuppetWidget also needs a
352 // reference back to BrowserChild (e.g. to delegate nsIWidget IME calls
353 // to chrome) So we hold a weak reference to BrowserChild here. Since
354 // it's possible for BrowserChild to outlive the PuppetWidget, we clear
355 // this weak reference in Destroy()
356 BrowserChild* mBrowserChild;
357 // The "widget" to which we delegate events if we don't have an
358 // event handler.
359 RefPtr<PuppetWidget> mChild;
360 nsRevocableEventPtr<WidgetPaintTask> mWidgetPaintTask;
361 RefPtr<layers::MemoryPressureObserver> mMemoryPressureObserver;
362 // XXX/cjones: keeping this around until we teach LayerManager to do
363 // retained-content-only transactions
364 RefPtr<DrawTarget> mDrawTarget;
365 // IME
366 IMENotificationRequests mIMENotificationRequestsOfParent;
367 InputContext mInputContext;
368 // mNativeIMEContext is initialized when this dispatches every composition
369 // event both from parent process's widget and TextEventDispatcher in same
370 // process. If it hasn't been started composition yet, this isn't necessary
371 // for XP code since there is no TextComposition instance which is caused by
372 // the PuppetWidget instance.
373 NativeIMEContext mNativeIMEContext;
374 ContentCacheInChild mContentCache;
376 // The DPI of the parent widget containing this widget.
377 float mDPI = GetFallbackDPI();
378 int32_t mRounding = 1;
379 double mDefaultScale = GetFallbackDefaultScale().scale;
381 ScreenIntMargin mSafeAreaInsets;
383 RefPtr<TextEventDispatcherListener> mNativeTextEventDispatcherListener;
385 protected:
386 bool mEnabled;
387 bool mVisible;
389 private:
390 nsSizeMode mSizeMode;
392 bool mNeedIMEStateInit;
393 // When remote process requests to commit/cancel a composition, the
394 // composition may have already been committed in the main process. In such
395 // case, this will receive remaining composition events for the old
396 // composition even after requesting to commit/cancel the old composition
397 // but the TextComposition for the old composition has already been
398 // destroyed. So, until this meets new eCompositionStart, following
399 // composition events should be ignored if this is set to true.
400 bool mIgnoreCompositionEvents;
403 } // namespace widget
404 } // namespace mozilla
406 #endif // mozilla_widget_PuppetWidget_h__