|
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 "nsBaseScreen.h" |
|
19 #include "nsBaseWidget.h" |
|
20 #include "nsIScreenManager.h" |
|
21 #include "nsThreadUtils.h" |
|
22 #include "nsWeakReference.h" |
|
23 #include "mozilla/Attributes.h" |
|
24 #include "mozilla/EventForwards.h" |
|
25 |
|
26 class gfxASurface; |
|
27 |
|
28 namespace mozilla { |
|
29 |
|
30 namespace dom { |
|
31 class TabChild; |
|
32 } |
|
33 |
|
34 namespace widget { |
|
35 |
|
36 class AutoCacheNativeKeyCommands; |
|
37 |
|
38 class PuppetWidget : public nsBaseWidget, public nsSupportsWeakReference |
|
39 { |
|
40 typedef mozilla::dom::TabChild TabChild; |
|
41 typedef nsBaseWidget Base; |
|
42 |
|
43 // The width and height of the "widget" are clamped to this. |
|
44 static const size_t kMaxDimension; |
|
45 |
|
46 public: |
|
47 PuppetWidget(TabChild* aTabChild); |
|
48 virtual ~PuppetWidget(); |
|
49 |
|
50 NS_DECL_ISUPPORTS_INHERITED |
|
51 |
|
52 NS_IMETHOD Create(nsIWidget* aParent, |
|
53 nsNativeWidget aNativeParent, |
|
54 const nsIntRect& aRect, |
|
55 nsDeviceContext* aContext, |
|
56 nsWidgetInitData* aInitData = nullptr); |
|
57 |
|
58 void InitIMEState(); |
|
59 |
|
60 virtual already_AddRefed<nsIWidget> |
|
61 CreateChild(const nsIntRect &aRect, |
|
62 nsDeviceContext *aContext, |
|
63 nsWidgetInitData *aInitData = nullptr, |
|
64 bool aForceUseIWidgetParent = false); |
|
65 |
|
66 NS_IMETHOD Destroy(); |
|
67 |
|
68 NS_IMETHOD Show(bool aState); |
|
69 |
|
70 virtual bool IsVisible() const |
|
71 { return mVisible; } |
|
72 |
|
73 NS_IMETHOD ConstrainPosition(bool /*ignored aAllowSlop*/, |
|
74 int32_t* aX, |
|
75 int32_t* aY) |
|
76 { *aX = kMaxDimension; *aY = kMaxDimension; return NS_OK; } |
|
77 |
|
78 // We're always at <0, 0>, and so ignore move requests. |
|
79 NS_IMETHOD Move(double aX, double aY) |
|
80 { return NS_OK; } |
|
81 |
|
82 NS_IMETHOD Resize(double aWidth, |
|
83 double aHeight, |
|
84 bool aRepaint); |
|
85 NS_IMETHOD Resize(double aX, |
|
86 double aY, |
|
87 double aWidth, |
|
88 double aHeight, |
|
89 bool aRepaint) |
|
90 // (we're always at <0, 0>) |
|
91 { return Resize(aWidth, aHeight, aRepaint); } |
|
92 |
|
93 // XXX/cjones: copying gtk behavior here; unclear what disabling a |
|
94 // widget is supposed to entail |
|
95 NS_IMETHOD Enable(bool aState) |
|
96 { mEnabled = aState; return NS_OK; } |
|
97 virtual bool IsEnabled() const |
|
98 { return mEnabled; } |
|
99 |
|
100 NS_IMETHOD SetFocus(bool aRaise = false); |
|
101 |
|
102 // PuppetWidgets don't care about children. |
|
103 virtual nsresult ConfigureChildren(const nsTArray<Configuration>& aConfigurations) |
|
104 { return NS_OK; } |
|
105 |
|
106 NS_IMETHOD Invalidate(const nsIntRect& aRect); |
|
107 |
|
108 // This API is going away, steer clear. |
|
109 virtual void Scroll(const nsIntPoint& aDelta, |
|
110 const nsTArray<nsIntRect>& aDestRects, |
|
111 const nsTArray<Configuration>& aReconfigureChildren) |
|
112 { /* dead man walking */ } |
|
113 |
|
114 // PuppetWidgets don't have native data, as they're purely nonnative. |
|
115 virtual void* GetNativeData(uint32_t aDataType); |
|
116 NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent) |
|
117 { return NS_ERROR_UNEXPECTED; } |
|
118 |
|
119 // PuppetWidgets don't have any concept of titles. |
|
120 NS_IMETHOD SetTitle(const nsAString& aTitle) |
|
121 { return NS_ERROR_UNEXPECTED; } |
|
122 |
|
123 // PuppetWidgets are always at <0, 0>. |
|
124 virtual nsIntPoint WidgetToScreenOffset() |
|
125 { return nsIntPoint(0, 0); } |
|
126 |
|
127 void InitEvent(WidgetGUIEvent& aEvent, nsIntPoint* aPoint = nullptr); |
|
128 |
|
129 NS_IMETHOD DispatchEvent(WidgetGUIEvent* aEvent, nsEventStatus& aStatus); |
|
130 |
|
131 NS_IMETHOD CaptureRollupEvents(nsIRollupListener* aListener, |
|
132 bool aDoCapture) |
|
133 { return NS_ERROR_UNEXPECTED; } |
|
134 |
|
135 NS_IMETHOD_(bool) |
|
136 ExecuteNativeKeyBinding(NativeKeyBindingsType aType, |
|
137 const mozilla::WidgetKeyboardEvent& aEvent, |
|
138 DoCommandCallback aCallback, |
|
139 void* aCallbackData) MOZ_OVERRIDE; |
|
140 |
|
141 friend class AutoCacheNativeKeyCommands; |
|
142 |
|
143 // |
|
144 // nsBaseWidget methods we override |
|
145 // |
|
146 |
|
147 // Documents loaded in child processes are always subdocuments of |
|
148 // other docs in an ancestor process. To ensure that the |
|
149 // backgrounds of those documents are painted like those of |
|
150 // same-process subdocuments, we force the widget here to be |
|
151 // transparent, which in turn will cause layout to use a transparent |
|
152 // backstop background color. |
|
153 virtual nsTransparencyMode GetTransparencyMode() MOZ_OVERRIDE |
|
154 { return eTransparencyTransparent; } |
|
155 |
|
156 virtual LayerManager* |
|
157 GetLayerManager(PLayerTransactionChild* aShadowManager = nullptr, |
|
158 LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE, |
|
159 LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT, |
|
160 bool* aAllowRetaining = nullptr); |
|
161 virtual gfxASurface* GetThebesSurface(); |
|
162 |
|
163 NS_IMETHOD NotifyIME(const IMENotification& aIMENotification) MOZ_OVERRIDE; |
|
164 NS_IMETHOD_(void) SetInputContext(const InputContext& aContext, |
|
165 const InputContextAction& aAction); |
|
166 NS_IMETHOD_(InputContext) GetInputContext(); |
|
167 virtual nsIMEUpdatePreference GetIMEUpdatePreference() MOZ_OVERRIDE; |
|
168 |
|
169 NS_IMETHOD SetCursor(nsCursor aCursor); |
|
170 NS_IMETHOD SetCursor(imgIContainer* aCursor, |
|
171 uint32_t aHotspotX, uint32_t aHotspotY) |
|
172 { |
|
173 return nsBaseWidget::SetCursor(aCursor, aHotspotX, aHotspotY); |
|
174 } |
|
175 |
|
176 // Gets the DPI of the screen corresponding to this widget. |
|
177 // Contacts the parent process which gets the DPI from the |
|
178 // proper widget there. TODO: Handle DPI changes that happen |
|
179 // later on. |
|
180 virtual float GetDPI(); |
|
181 virtual double GetDefaultScaleInternal(); |
|
182 |
|
183 virtual bool NeedsPaint() MOZ_OVERRIDE; |
|
184 |
|
185 virtual TabChild* GetOwningTabChild() MOZ_OVERRIDE { return mTabChild; } |
|
186 |
|
187 private: |
|
188 nsresult Paint(); |
|
189 |
|
190 void SetChild(PuppetWidget* aChild); |
|
191 |
|
192 nsresult IMEEndComposition(bool aCancel); |
|
193 nsresult NotifyIMEOfFocusChange(bool aFocus); |
|
194 nsresult NotifyIMEOfSelectionChange(const IMENotification& aIMENotification); |
|
195 nsresult NotifyIMEOfUpdateComposition(); |
|
196 nsresult NotifyIMEOfTextChange(const IMENotification& aIMENotification); |
|
197 |
|
198 class PaintTask : public nsRunnable { |
|
199 public: |
|
200 NS_DECL_NSIRUNNABLE |
|
201 PaintTask(PuppetWidget* widget) : mWidget(widget) {} |
|
202 void Revoke() { mWidget = nullptr; } |
|
203 private: |
|
204 PuppetWidget* mWidget; |
|
205 }; |
|
206 |
|
207 // TabChild normally holds a strong reference to this PuppetWidget |
|
208 // or its root ancestor, but each PuppetWidget also needs a |
|
209 // reference back to TabChild (e.g. to delegate nsIWidget IME calls |
|
210 // to chrome) So we hold a weak reference to TabChild here. Since |
|
211 // it's possible for TabChild to outlive the PuppetWidget, we clear |
|
212 // this weak reference in Destroy() |
|
213 TabChild* mTabChild; |
|
214 // The "widget" to which we delegate events if we don't have an |
|
215 // event handler. |
|
216 nsRefPtr<PuppetWidget> mChild; |
|
217 nsIntRegion mDirtyRegion; |
|
218 nsRevocableEventPtr<PaintTask> mPaintTask; |
|
219 bool mEnabled; |
|
220 bool mVisible; |
|
221 // XXX/cjones: keeping this around until we teach LayerManager to do |
|
222 // retained-content-only transactions |
|
223 nsRefPtr<gfxASurface> mSurface; |
|
224 // IME |
|
225 nsIMEUpdatePreference mIMEPreferenceOfParent; |
|
226 bool mIMEComposing; |
|
227 // Latest seqno received through events |
|
228 uint32_t mIMELastReceivedSeqno; |
|
229 // Chrome's seqno value when last blur occurred |
|
230 // arriving events with seqno up to this should be discarded |
|
231 // Note that if seqno overflows (~50 days at 1 ms increment rate), |
|
232 // events will be discarded until new focus/blur occurs |
|
233 uint32_t mIMELastBlurSeqno; |
|
234 bool mNeedIMEStateInit; |
|
235 |
|
236 // The DPI of the screen corresponding to this widget |
|
237 float mDPI; |
|
238 double mDefaultScale; |
|
239 |
|
240 // Precomputed answers for ExecuteNativeKeyBinding |
|
241 bool mNativeKeyCommandsValid; |
|
242 InfallibleTArray<mozilla::CommandInt> mSingleLineCommands; |
|
243 InfallibleTArray<mozilla::CommandInt> mMultiLineCommands; |
|
244 InfallibleTArray<mozilla::CommandInt> mRichTextCommands; |
|
245 }; |
|
246 |
|
247 struct AutoCacheNativeKeyCommands |
|
248 { |
|
249 AutoCacheNativeKeyCommands(PuppetWidget* aWidget) |
|
250 : mWidget(aWidget) |
|
251 { |
|
252 mSavedValid = mWidget->mNativeKeyCommandsValid; |
|
253 mSavedSingleLine = mWidget->mSingleLineCommands; |
|
254 mSavedMultiLine = mWidget->mMultiLineCommands; |
|
255 mSavedRichText = mWidget->mRichTextCommands; |
|
256 } |
|
257 |
|
258 void Cache(const InfallibleTArray<mozilla::CommandInt>& aSingleLineCommands, |
|
259 const InfallibleTArray<mozilla::CommandInt>& aMultiLineCommands, |
|
260 const InfallibleTArray<mozilla::CommandInt>& aRichTextCommands) |
|
261 { |
|
262 mWidget->mNativeKeyCommandsValid = true; |
|
263 mWidget->mSingleLineCommands = aSingleLineCommands; |
|
264 mWidget->mMultiLineCommands = aMultiLineCommands; |
|
265 mWidget->mRichTextCommands = aRichTextCommands; |
|
266 } |
|
267 |
|
268 void CacheNoCommands() |
|
269 { |
|
270 mWidget->mNativeKeyCommandsValid = true; |
|
271 mWidget->mSingleLineCommands.Clear(); |
|
272 mWidget->mMultiLineCommands.Clear(); |
|
273 mWidget->mRichTextCommands.Clear(); |
|
274 } |
|
275 |
|
276 ~AutoCacheNativeKeyCommands() |
|
277 { |
|
278 mWidget->mNativeKeyCommandsValid = mSavedValid; |
|
279 mWidget->mSingleLineCommands = mSavedSingleLine; |
|
280 mWidget->mMultiLineCommands = mSavedMultiLine; |
|
281 mWidget->mRichTextCommands = mSavedRichText; |
|
282 } |
|
283 |
|
284 private: |
|
285 PuppetWidget* mWidget; |
|
286 bool mSavedValid; |
|
287 InfallibleTArray<mozilla::CommandInt> mSavedSingleLine; |
|
288 InfallibleTArray<mozilla::CommandInt> mSavedMultiLine; |
|
289 InfallibleTArray<mozilla::CommandInt> mSavedRichText; |
|
290 }; |
|
291 |
|
292 class PuppetScreen : public nsBaseScreen |
|
293 { |
|
294 public: |
|
295 PuppetScreen(void* nativeScreen); |
|
296 ~PuppetScreen(); |
|
297 |
|
298 NS_IMETHOD GetRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight) MOZ_OVERRIDE; |
|
299 NS_IMETHOD GetAvailRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight) MOZ_OVERRIDE; |
|
300 NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth) MOZ_OVERRIDE; |
|
301 NS_IMETHOD GetColorDepth(int32_t* aColorDepth) MOZ_OVERRIDE; |
|
302 NS_IMETHOD GetRotation(uint32_t* aRotation) MOZ_OVERRIDE; |
|
303 NS_IMETHOD SetRotation(uint32_t aRotation) MOZ_OVERRIDE; |
|
304 }; |
|
305 |
|
306 class PuppetScreenManager MOZ_FINAL : public nsIScreenManager |
|
307 { |
|
308 public: |
|
309 PuppetScreenManager(); |
|
310 ~PuppetScreenManager(); |
|
311 |
|
312 NS_DECL_ISUPPORTS |
|
313 NS_DECL_NSISCREENMANAGER |
|
314 |
|
315 protected: |
|
316 nsCOMPtr<nsIScreen> mOneScreen; |
|
317 }; |
|
318 |
|
319 } // namespace widget |
|
320 } // namespace mozilla |
|
321 |
|
322 #endif // mozilla_widget_PuppetWidget_h__ |