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