1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/xpwidgets/PuppetWidget.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,322 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * vim: sw=2 ts=8 et : 1.6 + */ 1.7 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.8 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.9 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.10 + 1.11 +/** 1.12 + * This "puppet widget" isn't really a platform widget. It's intended 1.13 + * to be used in widgetless rendering contexts, such as sandboxed 1.14 + * content processes. If any "real" widgetry is needed, the request 1.15 + * is forwarded to and/or data received from elsewhere. 1.16 + */ 1.17 + 1.18 +#ifndef mozilla_widget_PuppetWidget_h__ 1.19 +#define mozilla_widget_PuppetWidget_h__ 1.20 + 1.21 +#include "nsBaseScreen.h" 1.22 +#include "nsBaseWidget.h" 1.23 +#include "nsIScreenManager.h" 1.24 +#include "nsThreadUtils.h" 1.25 +#include "nsWeakReference.h" 1.26 +#include "mozilla/Attributes.h" 1.27 +#include "mozilla/EventForwards.h" 1.28 + 1.29 +class gfxASurface; 1.30 + 1.31 +namespace mozilla { 1.32 + 1.33 +namespace dom { 1.34 +class TabChild; 1.35 +} 1.36 + 1.37 +namespace widget { 1.38 + 1.39 +class AutoCacheNativeKeyCommands; 1.40 + 1.41 +class PuppetWidget : public nsBaseWidget, public nsSupportsWeakReference 1.42 +{ 1.43 + typedef mozilla::dom::TabChild TabChild; 1.44 + typedef nsBaseWidget Base; 1.45 + 1.46 + // The width and height of the "widget" are clamped to this. 1.47 + static const size_t kMaxDimension; 1.48 + 1.49 +public: 1.50 + PuppetWidget(TabChild* aTabChild); 1.51 + virtual ~PuppetWidget(); 1.52 + 1.53 + NS_DECL_ISUPPORTS_INHERITED 1.54 + 1.55 + NS_IMETHOD Create(nsIWidget* aParent, 1.56 + nsNativeWidget aNativeParent, 1.57 + const nsIntRect& aRect, 1.58 + nsDeviceContext* aContext, 1.59 + nsWidgetInitData* aInitData = nullptr); 1.60 + 1.61 + void InitIMEState(); 1.62 + 1.63 + virtual already_AddRefed<nsIWidget> 1.64 + CreateChild(const nsIntRect &aRect, 1.65 + nsDeviceContext *aContext, 1.66 + nsWidgetInitData *aInitData = nullptr, 1.67 + bool aForceUseIWidgetParent = false); 1.68 + 1.69 + NS_IMETHOD Destroy(); 1.70 + 1.71 + NS_IMETHOD Show(bool aState); 1.72 + 1.73 + virtual bool IsVisible() const 1.74 + { return mVisible; } 1.75 + 1.76 + NS_IMETHOD ConstrainPosition(bool /*ignored aAllowSlop*/, 1.77 + int32_t* aX, 1.78 + int32_t* aY) 1.79 + { *aX = kMaxDimension; *aY = kMaxDimension; return NS_OK; } 1.80 + 1.81 + // We're always at <0, 0>, and so ignore move requests. 1.82 + NS_IMETHOD Move(double aX, double aY) 1.83 + { return NS_OK; } 1.84 + 1.85 + NS_IMETHOD Resize(double aWidth, 1.86 + double aHeight, 1.87 + bool aRepaint); 1.88 + NS_IMETHOD Resize(double aX, 1.89 + double aY, 1.90 + double aWidth, 1.91 + double aHeight, 1.92 + bool aRepaint) 1.93 + // (we're always at <0, 0>) 1.94 + { return Resize(aWidth, aHeight, aRepaint); } 1.95 + 1.96 + // XXX/cjones: copying gtk behavior here; unclear what disabling a 1.97 + // widget is supposed to entail 1.98 + NS_IMETHOD Enable(bool aState) 1.99 + { mEnabled = aState; return NS_OK; } 1.100 + virtual bool IsEnabled() const 1.101 + { return mEnabled; } 1.102 + 1.103 + NS_IMETHOD SetFocus(bool aRaise = false); 1.104 + 1.105 + // PuppetWidgets don't care about children. 1.106 + virtual nsresult ConfigureChildren(const nsTArray<Configuration>& aConfigurations) 1.107 + { return NS_OK; } 1.108 + 1.109 + NS_IMETHOD Invalidate(const nsIntRect& aRect); 1.110 + 1.111 + // This API is going away, steer clear. 1.112 + virtual void Scroll(const nsIntPoint& aDelta, 1.113 + const nsTArray<nsIntRect>& aDestRects, 1.114 + const nsTArray<Configuration>& aReconfigureChildren) 1.115 + { /* dead man walking */ } 1.116 + 1.117 + // PuppetWidgets don't have native data, as they're purely nonnative. 1.118 + virtual void* GetNativeData(uint32_t aDataType); 1.119 + NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent) 1.120 + { return NS_ERROR_UNEXPECTED; } 1.121 + 1.122 + // PuppetWidgets don't have any concept of titles. 1.123 + NS_IMETHOD SetTitle(const nsAString& aTitle) 1.124 + { return NS_ERROR_UNEXPECTED; } 1.125 + 1.126 + // PuppetWidgets are always at <0, 0>. 1.127 + virtual nsIntPoint WidgetToScreenOffset() 1.128 + { return nsIntPoint(0, 0); } 1.129 + 1.130 + void InitEvent(WidgetGUIEvent& aEvent, nsIntPoint* aPoint = nullptr); 1.131 + 1.132 + NS_IMETHOD DispatchEvent(WidgetGUIEvent* aEvent, nsEventStatus& aStatus); 1.133 + 1.134 + NS_IMETHOD CaptureRollupEvents(nsIRollupListener* aListener, 1.135 + bool aDoCapture) 1.136 + { return NS_ERROR_UNEXPECTED; } 1.137 + 1.138 + NS_IMETHOD_(bool) 1.139 + ExecuteNativeKeyBinding(NativeKeyBindingsType aType, 1.140 + const mozilla::WidgetKeyboardEvent& aEvent, 1.141 + DoCommandCallback aCallback, 1.142 + void* aCallbackData) MOZ_OVERRIDE; 1.143 + 1.144 + friend class AutoCacheNativeKeyCommands; 1.145 + 1.146 + // 1.147 + // nsBaseWidget methods we override 1.148 + // 1.149 + 1.150 + // Documents loaded in child processes are always subdocuments of 1.151 + // other docs in an ancestor process. To ensure that the 1.152 + // backgrounds of those documents are painted like those of 1.153 + // same-process subdocuments, we force the widget here to be 1.154 + // transparent, which in turn will cause layout to use a transparent 1.155 + // backstop background color. 1.156 + virtual nsTransparencyMode GetTransparencyMode() MOZ_OVERRIDE 1.157 + { return eTransparencyTransparent; } 1.158 + 1.159 + virtual LayerManager* 1.160 + GetLayerManager(PLayerTransactionChild* aShadowManager = nullptr, 1.161 + LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE, 1.162 + LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT, 1.163 + bool* aAllowRetaining = nullptr); 1.164 + virtual gfxASurface* GetThebesSurface(); 1.165 + 1.166 + NS_IMETHOD NotifyIME(const IMENotification& aIMENotification) MOZ_OVERRIDE; 1.167 + NS_IMETHOD_(void) SetInputContext(const InputContext& aContext, 1.168 + const InputContextAction& aAction); 1.169 + NS_IMETHOD_(InputContext) GetInputContext(); 1.170 + virtual nsIMEUpdatePreference GetIMEUpdatePreference() MOZ_OVERRIDE; 1.171 + 1.172 + NS_IMETHOD SetCursor(nsCursor aCursor); 1.173 + NS_IMETHOD SetCursor(imgIContainer* aCursor, 1.174 + uint32_t aHotspotX, uint32_t aHotspotY) 1.175 + { 1.176 + return nsBaseWidget::SetCursor(aCursor, aHotspotX, aHotspotY); 1.177 + } 1.178 + 1.179 + // Gets the DPI of the screen corresponding to this widget. 1.180 + // Contacts the parent process which gets the DPI from the 1.181 + // proper widget there. TODO: Handle DPI changes that happen 1.182 + // later on. 1.183 + virtual float GetDPI(); 1.184 + virtual double GetDefaultScaleInternal(); 1.185 + 1.186 + virtual bool NeedsPaint() MOZ_OVERRIDE; 1.187 + 1.188 + virtual TabChild* GetOwningTabChild() MOZ_OVERRIDE { return mTabChild; } 1.189 + 1.190 +private: 1.191 + nsresult Paint(); 1.192 + 1.193 + void SetChild(PuppetWidget* aChild); 1.194 + 1.195 + nsresult IMEEndComposition(bool aCancel); 1.196 + nsresult NotifyIMEOfFocusChange(bool aFocus); 1.197 + nsresult NotifyIMEOfSelectionChange(const IMENotification& aIMENotification); 1.198 + nsresult NotifyIMEOfUpdateComposition(); 1.199 + nsresult NotifyIMEOfTextChange(const IMENotification& aIMENotification); 1.200 + 1.201 + class PaintTask : public nsRunnable { 1.202 + public: 1.203 + NS_DECL_NSIRUNNABLE 1.204 + PaintTask(PuppetWidget* widget) : mWidget(widget) {} 1.205 + void Revoke() { mWidget = nullptr; } 1.206 + private: 1.207 + PuppetWidget* mWidget; 1.208 + }; 1.209 + 1.210 + // TabChild normally holds a strong reference to this PuppetWidget 1.211 + // or its root ancestor, but each PuppetWidget also needs a 1.212 + // reference back to TabChild (e.g. to delegate nsIWidget IME calls 1.213 + // to chrome) So we hold a weak reference to TabChild here. Since 1.214 + // it's possible for TabChild to outlive the PuppetWidget, we clear 1.215 + // this weak reference in Destroy() 1.216 + TabChild* mTabChild; 1.217 + // The "widget" to which we delegate events if we don't have an 1.218 + // event handler. 1.219 + nsRefPtr<PuppetWidget> mChild; 1.220 + nsIntRegion mDirtyRegion; 1.221 + nsRevocableEventPtr<PaintTask> mPaintTask; 1.222 + bool mEnabled; 1.223 + bool mVisible; 1.224 + // XXX/cjones: keeping this around until we teach LayerManager to do 1.225 + // retained-content-only transactions 1.226 + nsRefPtr<gfxASurface> mSurface; 1.227 + // IME 1.228 + nsIMEUpdatePreference mIMEPreferenceOfParent; 1.229 + bool mIMEComposing; 1.230 + // Latest seqno received through events 1.231 + uint32_t mIMELastReceivedSeqno; 1.232 + // Chrome's seqno value when last blur occurred 1.233 + // arriving events with seqno up to this should be discarded 1.234 + // Note that if seqno overflows (~50 days at 1 ms increment rate), 1.235 + // events will be discarded until new focus/blur occurs 1.236 + uint32_t mIMELastBlurSeqno; 1.237 + bool mNeedIMEStateInit; 1.238 + 1.239 + // The DPI of the screen corresponding to this widget 1.240 + float mDPI; 1.241 + double mDefaultScale; 1.242 + 1.243 + // Precomputed answers for ExecuteNativeKeyBinding 1.244 + bool mNativeKeyCommandsValid; 1.245 + InfallibleTArray<mozilla::CommandInt> mSingleLineCommands; 1.246 + InfallibleTArray<mozilla::CommandInt> mMultiLineCommands; 1.247 + InfallibleTArray<mozilla::CommandInt> mRichTextCommands; 1.248 +}; 1.249 + 1.250 +struct AutoCacheNativeKeyCommands 1.251 +{ 1.252 + AutoCacheNativeKeyCommands(PuppetWidget* aWidget) 1.253 + : mWidget(aWidget) 1.254 + { 1.255 + mSavedValid = mWidget->mNativeKeyCommandsValid; 1.256 + mSavedSingleLine = mWidget->mSingleLineCommands; 1.257 + mSavedMultiLine = mWidget->mMultiLineCommands; 1.258 + mSavedRichText = mWidget->mRichTextCommands; 1.259 + } 1.260 + 1.261 + void Cache(const InfallibleTArray<mozilla::CommandInt>& aSingleLineCommands, 1.262 + const InfallibleTArray<mozilla::CommandInt>& aMultiLineCommands, 1.263 + const InfallibleTArray<mozilla::CommandInt>& aRichTextCommands) 1.264 + { 1.265 + mWidget->mNativeKeyCommandsValid = true; 1.266 + mWidget->mSingleLineCommands = aSingleLineCommands; 1.267 + mWidget->mMultiLineCommands = aMultiLineCommands; 1.268 + mWidget->mRichTextCommands = aRichTextCommands; 1.269 + } 1.270 + 1.271 + void CacheNoCommands() 1.272 + { 1.273 + mWidget->mNativeKeyCommandsValid = true; 1.274 + mWidget->mSingleLineCommands.Clear(); 1.275 + mWidget->mMultiLineCommands.Clear(); 1.276 + mWidget->mRichTextCommands.Clear(); 1.277 + } 1.278 + 1.279 + ~AutoCacheNativeKeyCommands() 1.280 + { 1.281 + mWidget->mNativeKeyCommandsValid = mSavedValid; 1.282 + mWidget->mSingleLineCommands = mSavedSingleLine; 1.283 + mWidget->mMultiLineCommands = mSavedMultiLine; 1.284 + mWidget->mRichTextCommands = mSavedRichText; 1.285 + } 1.286 + 1.287 +private: 1.288 + PuppetWidget* mWidget; 1.289 + bool mSavedValid; 1.290 + InfallibleTArray<mozilla::CommandInt> mSavedSingleLine; 1.291 + InfallibleTArray<mozilla::CommandInt> mSavedMultiLine; 1.292 + InfallibleTArray<mozilla::CommandInt> mSavedRichText; 1.293 +}; 1.294 + 1.295 +class PuppetScreen : public nsBaseScreen 1.296 +{ 1.297 +public: 1.298 + PuppetScreen(void* nativeScreen); 1.299 + ~PuppetScreen(); 1.300 + 1.301 + NS_IMETHOD GetRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight) MOZ_OVERRIDE; 1.302 + NS_IMETHOD GetAvailRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight) MOZ_OVERRIDE; 1.303 + NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth) MOZ_OVERRIDE; 1.304 + NS_IMETHOD GetColorDepth(int32_t* aColorDepth) MOZ_OVERRIDE; 1.305 + NS_IMETHOD GetRotation(uint32_t* aRotation) MOZ_OVERRIDE; 1.306 + NS_IMETHOD SetRotation(uint32_t aRotation) MOZ_OVERRIDE; 1.307 +}; 1.308 + 1.309 +class PuppetScreenManager MOZ_FINAL : public nsIScreenManager 1.310 +{ 1.311 +public: 1.312 + PuppetScreenManager(); 1.313 + ~PuppetScreenManager(); 1.314 + 1.315 + NS_DECL_ISUPPORTS 1.316 + NS_DECL_NSISCREENMANAGER 1.317 + 1.318 +protected: 1.319 + nsCOMPtr<nsIScreen> mOneScreen; 1.320 +}; 1.321 + 1.322 +} // namespace widget 1.323 +} // namespace mozilla 1.324 + 1.325 +#endif // mozilla_widget_PuppetWidget_h__