PuppetWidget.h 17 KB

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