Line data Source code
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/. */
7 :
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.
13 : */
14 :
15 : #ifndef mozilla_widget_PuppetWidget_h__
16 : #define mozilla_widget_PuppetWidget_h__
17 :
18 : #include "mozilla/gfx/2D.h"
19 : #include "mozilla/RefPtr.h"
20 : #include "nsBaseScreen.h"
21 : #include "nsBaseWidget.h"
22 : #include "nsCOMArray.h"
23 : #include "nsIKeyEventInPluginCallback.h"
24 : #include "nsIScreenManager.h"
25 : #include "nsThreadUtils.h"
26 : #include "mozilla/Attributes.h"
27 : #include "mozilla/ContentCache.h"
28 : #include "mozilla/EventForwards.h"
29 : #include "mozilla/TextEventDispatcherListener.h"
30 :
31 : namespace mozilla {
32 :
33 : namespace dom {
34 : class TabChild;
35 : } // namespace dom
36 :
37 : namespace widget {
38 :
39 : struct AutoCacheNativeKeyCommands;
40 :
41 : class PuppetWidget : public nsBaseWidget
42 : , public TextEventDispatcherListener
43 : {
44 : typedef mozilla::CSSRect CSSRect;
45 : typedef mozilla::dom::TabChild TabChild;
46 : typedef mozilla::gfx::DrawTarget DrawTarget;
47 :
48 : // Avoiding to make compiler confused between mozilla::widget and nsIWidget.
49 : typedef mozilla::widget::TextEventDispatcher TextEventDispatcher;
50 : typedef mozilla::widget::TextEventDispatcherListener
51 : TextEventDispatcherListener;
52 :
53 : typedef nsBaseWidget Base;
54 :
55 : // The width and height of the "widget" are clamped to this.
56 : static const size_t kMaxDimension;
57 :
58 : public:
59 : explicit PuppetWidget(TabChild* aTabChild);
60 :
61 : protected:
62 : virtual ~PuppetWidget();
63 :
64 : public:
65 : NS_DECL_ISUPPORTS_INHERITED
66 :
67 : // PuppetWidget creation is infallible, hence InfallibleCreate(), which
68 : // Create() calls.
69 : using nsBaseWidget::Create; // for Create signature not overridden here
70 : virtual nsresult Create(nsIWidget* aParent,
71 : nsNativeWidget aNativeParent,
72 : const LayoutDeviceIntRect& aRect,
73 : nsWidgetInitData* aInitData = nullptr)
74 : override;
75 : void InfallibleCreate(nsIWidget* aParent,
76 : nsNativeWidget aNativeParent,
77 : const LayoutDeviceIntRect& aRect,
78 : nsWidgetInitData* aInitData = nullptr);
79 :
80 : void InitIMEState();
81 :
82 : virtual already_AddRefed<nsIWidget>
83 : CreateChild(const LayoutDeviceIntRect& aRect,
84 : nsWidgetInitData* aInitData = nullptr,
85 : bool aForceUseIWidgetParent = false) override;
86 :
87 : virtual void Destroy() override;
88 :
89 : virtual void Show(bool aState) override;
90 :
91 1 : virtual bool IsVisible() const override
92 1 : { return mVisible; }
93 :
94 0 : virtual void ConstrainPosition(bool /*ignored aAllowSlop*/,
95 : int32_t* aX,
96 : int32_t* aY) override
97 0 : { *aX = kMaxDimension; *aY = kMaxDimension; }
98 :
99 : // Widget position is controlled by the parent process via TabChild.
100 0 : virtual void Move(double aX, double aY) override {}
101 :
102 : virtual void Resize(double aWidth,
103 : double aHeight,
104 : bool aRepaint) override;
105 4 : virtual void Resize(double aX,
106 : double aY,
107 : double aWidth,
108 : double aHeight,
109 : bool aRepaint) override
110 : {
111 4 : if (mBounds.x != aX || mBounds.y != aY) {
112 2 : NotifyWindowMoved(aX, aY);
113 : }
114 4 : mBounds.x = aX;
115 4 : mBounds.y = aY;
116 4 : return Resize(aWidth, aHeight, aRepaint);
117 : }
118 :
119 : // XXX/cjones: copying gtk behavior here; unclear what disabling a
120 : // widget is supposed to entail
121 0 : virtual void Enable(bool aState) override
122 0 : { mEnabled = aState; }
123 0 : virtual bool IsEnabled() const override
124 0 : { return mEnabled; }
125 :
126 : virtual nsresult SetFocus(bool aRaise = false) override;
127 :
128 : virtual nsresult ConfigureChildren(const nsTArray<Configuration>& aConfigurations) override;
129 :
130 : virtual void Invalidate(const LayoutDeviceIntRect& aRect) override;
131 :
132 : // PuppetWidgets don't have native data, as they're purely nonnative.
133 : virtual void* GetNativeData(uint32_t aDataType) override;
134 : #if defined(XP_WIN)
135 : void SetNativeData(uint32_t aDataType, uintptr_t aVal) override;
136 : #endif
137 :
138 : // PuppetWidgets don't have any concept of titles.
139 0 : virtual nsresult SetTitle(const nsAString& aTitle) override
140 0 : { return NS_ERROR_UNEXPECTED; }
141 :
142 0 : virtual LayoutDeviceIntPoint WidgetToScreenOffset() override
143 0 : { return LayoutDeviceIntPoint::FromUnknownPoint(GetWindowPosition() + GetChromeDimensions()); }
144 :
145 : int32_t RoundsWidgetCoordinatesTo() override;
146 :
147 : void InitEvent(WidgetGUIEvent& aEvent,
148 : LayoutDeviceIntPoint* aPoint = nullptr);
149 :
150 : virtual nsresult DispatchEvent(WidgetGUIEvent* aEvent,
151 : nsEventStatus& aStatus) override;
152 : nsEventStatus DispatchInputEvent(WidgetInputEvent* aEvent) override;
153 : void SetConfirmedTargetAPZC(uint64_t aInputBlockId,
154 : const nsTArray<ScrollableLayerGuid>& aTargets) const override;
155 : void UpdateZoomConstraints(const uint32_t& aPresShellId,
156 : const FrameMetrics::ViewID& aViewId,
157 : const mozilla::Maybe<ZoomConstraints>& aConstraints) override;
158 : bool AsyncPanZoomEnabled() const override;
159 :
160 : virtual void GetEditCommands(
161 : NativeKeyBindingsType aType,
162 : const mozilla::WidgetKeyboardEvent& aEvent,
163 : nsTArray<mozilla::CommandInt>& aCommands) override;
164 :
165 : friend struct AutoCacheNativeKeyCommands;
166 :
167 : //
168 : // nsBaseWidget methods we override
169 : //
170 :
171 : // Documents loaded in child processes are always subdocuments of
172 : // other docs in an ancestor process. To ensure that the
173 : // backgrounds of those documents are painted like those of
174 : // same-process subdocuments, we force the widget here to be
175 : // transparent, which in turn will cause layout to use a transparent
176 : // backstop background color.
177 4 : virtual nsTransparencyMode GetTransparencyMode() override
178 4 : { return eTransparencyTransparent; }
179 :
180 : virtual LayerManager*
181 : GetLayerManager(PLayerTransactionChild* aShadowManager = nullptr,
182 : LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE,
183 : LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT) override;
184 :
185 : // This is used after a compositor reset.
186 : LayerManager* RecreateLayerManager(PLayerTransactionChild* aShadowManager);
187 :
188 : virtual void SetInputContext(const InputContext& aContext,
189 : const InputContextAction& aAction) override;
190 : virtual InputContext GetInputContext() override;
191 : virtual NativeIMEContext GetNativeIMEContext() override;
192 0 : TextEventDispatcherListener* GetNativeTextEventDispatcherListener() override
193 : {
194 : return mNativeTextEventDispatcherListener ?
195 0 : mNativeTextEventDispatcherListener.get() : this;
196 : }
197 : void SetNativeTextEventDispatcherListener(TextEventDispatcherListener* aListener)
198 : { mNativeTextEventDispatcherListener = aListener; }
199 :
200 : virtual void SetCursor(nsCursor aCursor) override;
201 : virtual nsresult SetCursor(imgIContainer* aCursor,
202 : uint32_t aHotspotX, uint32_t aHotspotY) override;
203 :
204 : virtual void ClearCachedCursor() override;
205 :
206 : // Gets the DPI of the screen corresponding to this widget.
207 : // Contacts the parent process which gets the DPI from the
208 : // proper widget there. TODO: Handle DPI changes that happen
209 : // later on.
210 : virtual float GetDPI() override;
211 : virtual double GetDefaultScaleInternal() override;
212 :
213 : virtual bool NeedsPaint() override;
214 :
215 : // Paint the widget immediately if any paints are queued up.
216 : void PaintNowIfNeeded();
217 :
218 9 : virtual TabChild* GetOwningTabChild() override { return mTabChild; }
219 :
220 0 : void UpdateBackingScaleCache(float aDpi, int32_t aRounding, double aScale)
221 : {
222 0 : mDPI = aDpi;
223 0 : mRounding = aRounding;
224 0 : mDefaultScale = aScale;
225 0 : }
226 :
227 : nsIntSize GetScreenDimensions();
228 :
229 : // Get the size of the chrome of the window that this tab belongs to.
230 : nsIntPoint GetChromeDimensions();
231 :
232 : // Get the screen position of the application window.
233 : nsIntPoint GetWindowPosition();
234 :
235 : virtual LayoutDeviceIntRect GetScreenBounds() override;
236 :
237 : virtual MOZ_MUST_USE nsresult
238 : StartPluginIME(const mozilla::WidgetKeyboardEvent& aKeyboardEvent,
239 : int32_t aPanelX, int32_t aPanelY,
240 : nsString& aCommitted) override;
241 :
242 : virtual void SetPluginFocused(bool& aFocused) override;
243 : virtual void DefaultProcOfPluginEvent(
244 : const mozilla::WidgetPluginEvent& aEvent) override;
245 :
246 : virtual nsresult SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout,
247 : int32_t aNativeKeyCode,
248 : uint32_t aModifierFlags,
249 : const nsAString& aCharacters,
250 : const nsAString& aUnmodifiedCharacters,
251 : nsIObserver* aObserver) override;
252 : virtual nsresult SynthesizeNativeMouseEvent(LayoutDeviceIntPoint aPoint,
253 : uint32_t aNativeMessage,
254 : uint32_t aModifierFlags,
255 : nsIObserver* aObserver) override;
256 : virtual nsresult SynthesizeNativeMouseMove(LayoutDeviceIntPoint aPoint,
257 : nsIObserver* aObserver) override;
258 : virtual nsresult SynthesizeNativeMouseScrollEvent(LayoutDeviceIntPoint aPoint,
259 : uint32_t aNativeMessage,
260 : double aDeltaX,
261 : double aDeltaY,
262 : double aDeltaZ,
263 : uint32_t aModifierFlags,
264 : uint32_t aAdditionalFlags,
265 : nsIObserver* aObserver) override;
266 : virtual nsresult SynthesizeNativeTouchPoint(uint32_t aPointerId,
267 : TouchPointerState aPointerState,
268 : LayoutDeviceIntPoint aPoint,
269 : double aPointerPressure,
270 : uint32_t aPointerOrientation,
271 : nsIObserver* aObserver) override;
272 : virtual nsresult SynthesizeNativeTouchTap(LayoutDeviceIntPoint aPoint,
273 : bool aLongTap,
274 : nsIObserver* aObserver) override;
275 : virtual nsresult ClearNativeTouchSequence(nsIObserver* aObserver) override;
276 : virtual uint32_t GetMaxTouchPoints() const override;
277 :
278 : virtual void StartAsyncScrollbarDrag(const AsyncDragMetrics& aDragMetrics) override;
279 :
280 : virtual void SetCandidateWindowForPlugin(
281 : const CandidateWindowPosition& aPosition) override;
282 :
283 : virtual void ZoomToRect(const uint32_t& aPresShellId,
284 : const FrameMetrics::ViewID& aViewId,
285 : const CSSRect& aRect,
286 : const uint32_t& aFlags) override;
287 :
288 : virtual bool HasPendingInputEvent() override;
289 :
290 : void HandledWindowedPluginKeyEvent(const NativeEventData& aKeyEventData,
291 : bool aIsConsumed);
292 : virtual nsresult OnWindowedPluginKeyEvent(
293 : const NativeEventData& aKeyEventData,
294 : nsIKeyEventInPluginCallback* aCallback) override;
295 :
296 : virtual void LookUpDictionary(
297 : const nsAString& aText,
298 : const nsTArray<mozilla::FontRange>& aFontRangeArray,
299 : const bool aIsVertical,
300 : const LayoutDeviceIntPoint& aPoint) override;
301 :
302 : // TextEventDispatcherListener
303 : using nsBaseWidget::NotifyIME;
304 : NS_IMETHOD NotifyIME(TextEventDispatcher* aTextEventDispatcher,
305 : const IMENotification& aNotification) override;
306 : NS_IMETHOD_(IMENotificationRequests) GetIMENotificationRequests() override;
307 : NS_IMETHOD_(void) OnRemovedFrom(
308 : TextEventDispatcher* aTextEventDispatcher) override;
309 : NS_IMETHOD_(void) WillDispatchKeyboardEvent(
310 : TextEventDispatcher* aTextEventDispatcher,
311 : WidgetKeyboardEvent& aKeyboardEvent,
312 : uint32_t aIndexOfKeypress,
313 : void* aData) override;
314 :
315 : protected:
316 : virtual nsresult NotifyIMEInternal(
317 : const IMENotification& aIMENotification) override;
318 :
319 : private:
320 : nsresult Paint();
321 :
322 : void SetChild(PuppetWidget* aChild);
323 :
324 : nsresult RequestIMEToCommitComposition(bool aCancel);
325 : nsresult NotifyIMEOfFocusChange(const IMENotification& aIMENotification);
326 : nsresult NotifyIMEOfSelectionChange(const IMENotification& aIMENotification);
327 : nsresult NotifyIMEOfCompositionUpdate(const IMENotification& aIMENotification);
328 : nsresult NotifyIMEOfTextChange(const IMENotification& aIMENotification);
329 : nsresult NotifyIMEOfMouseButtonEvent(const IMENotification& aIMENotification);
330 : nsresult NotifyIMEOfPositionChange(const IMENotification& aIMENotification);
331 :
332 : bool CacheEditorRect();
333 : bool CacheCompositionRects(uint32_t& aStartOffset,
334 : nsTArray<LayoutDeviceIntRect>& aRectArray,
335 : uint32_t& aTargetCauseOffset);
336 : bool GetCaretRect(LayoutDeviceIntRect& aCaretRect, uint32_t aCaretOffset);
337 : uint32_t GetCaretOffset();
338 :
339 : nsIWidgetListener* GetCurrentWidgetListener();
340 :
341 6 : class PaintTask : public Runnable {
342 : public:
343 : NS_DECL_NSIRUNNABLE
344 2 : explicit PaintTask(PuppetWidget* widget)
345 2 : : Runnable("PuppetWidget::PaintTask"), mWidget(widget) {}
346 2 : void Revoke() { mWidget = nullptr; }
347 : private:
348 : PuppetWidget* mWidget;
349 : };
350 :
351 : class MemoryPressureObserver : public nsIObserver {
352 : public:
353 : NS_DECL_ISUPPORTS
354 : NS_DECL_NSIOBSERVER
355 1 : explicit MemoryPressureObserver(PuppetWidget* aWidget) : mWidget(aWidget) {}
356 : void Remove();
357 : private:
358 0 : virtual ~MemoryPressureObserver() {}
359 : PuppetWidget* mWidget;
360 : };
361 : friend class MemoryPressureObserver;
362 :
363 : // TabChild normally holds a strong reference to this PuppetWidget
364 : // or its root ancestor, but each PuppetWidget also needs a
365 : // reference back to TabChild (e.g. to delegate nsIWidget IME calls
366 : // to chrome) So we hold a weak reference to TabChild here. Since
367 : // it's possible for TabChild to outlive the PuppetWidget, we clear
368 : // this weak reference in Destroy()
369 : TabChild* mTabChild;
370 : // The "widget" to which we delegate events if we don't have an
371 : // event handler.
372 : RefPtr<PuppetWidget> mChild;
373 : LayoutDeviceIntRegion mDirtyRegion;
374 : nsRevocableEventPtr<PaintTask> mPaintTask;
375 : RefPtr<MemoryPressureObserver> mMemoryPressureObserver;
376 : // XXX/cjones: keeping this around until we teach LayerManager to do
377 : // retained-content-only transactions
378 : RefPtr<DrawTarget> mDrawTarget;
379 : // IME
380 : IMENotificationRequests mIMENotificationRequestsOfParent;
381 : InputContext mInputContext;
382 : // mNativeIMEContext is initialized when this dispatches every composition
383 : // event both from parent process's widget and TextEventDispatcher in same
384 : // process. If it hasn't been started composition yet, this isn't necessary
385 : // for XP code since there is no TextComposition instance which is caused by
386 : // the PuppetWidget instance.
387 : NativeIMEContext mNativeIMEContext;
388 : ContentCacheInChild mContentCache;
389 :
390 : // The DPI of the screen corresponding to this widget
391 : float mDPI;
392 : int32_t mRounding;
393 : double mDefaultScale;
394 :
395 : nsCOMPtr<imgIContainer> mCustomCursor;
396 : uint32_t mCursorHotspotX, mCursorHotspotY;
397 :
398 : nsCOMArray<nsIKeyEventInPluginCallback> mKeyEventInPluginCallbacks;
399 :
400 : RefPtr<TextEventDispatcherListener> mNativeTextEventDispatcherListener;
401 :
402 : protected:
403 : bool mEnabled;
404 : bool mVisible;
405 :
406 : private:
407 : bool mNeedIMEStateInit;
408 : };
409 :
410 : class PuppetScreen : public nsBaseScreen
411 : {
412 : public:
413 : explicit PuppetScreen(void* nativeScreen);
414 : ~PuppetScreen();
415 :
416 : NS_IMETHOD GetRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight) override;
417 : NS_IMETHOD GetAvailRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight) override;
418 : NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth) override;
419 : NS_IMETHOD GetColorDepth(int32_t* aColorDepth) override;
420 : };
421 :
422 : class PuppetScreenManager final : public nsIScreenManager
423 : {
424 : ~PuppetScreenManager();
425 :
426 : public:
427 : PuppetScreenManager();
428 :
429 : NS_DECL_ISUPPORTS
430 : NS_DECL_NSISCREENMANAGER
431 :
432 : protected:
433 : nsCOMPtr<nsIScreen> mOneScreen;
434 : };
435 :
436 : } // namespace widget
437 : } // namespace mozilla
438 :
439 : #endif // mozilla_widget_PuppetWidget_h__
|