1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/xpwidgets/nsBaseWidget.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,478 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 +#ifndef nsBaseWidget_h__ 1.9 +#define nsBaseWidget_h__ 1.10 + 1.11 +#include "mozilla/EventForwards.h" 1.12 +#include "mozilla/WidgetUtils.h" 1.13 +#include "nsRect.h" 1.14 +#include "nsIWidget.h" 1.15 +#include "nsWidgetsCID.h" 1.16 +#include "nsIFile.h" 1.17 +#include "nsString.h" 1.18 +#include "nsCOMPtr.h" 1.19 +#include "nsAutoPtr.h" 1.20 +#include "nsIRollupListener.h" 1.21 +#include "nsIObserver.h" 1.22 +#include "nsIWidgetListener.h" 1.23 +#include "nsPIDOMWindow.h" 1.24 +#include <algorithm> 1.25 +class nsIContent; 1.26 +class nsAutoRollup; 1.27 +class gfxContext; 1.28 + 1.29 +namespace mozilla { 1.30 +#ifdef ACCESSIBILITY 1.31 +namespace a11y { 1.32 +class Accessible; 1.33 +} 1.34 +#endif 1.35 + 1.36 +namespace layers { 1.37 +class BasicLayerManager; 1.38 +class CompositorChild; 1.39 +class CompositorParent; 1.40 +} 1.41 +} 1.42 + 1.43 +namespace base { 1.44 +class Thread; 1.45 +} 1.46 + 1.47 +// Windows specific constant indicating the maximum number of touch points the 1.48 +// inject api will allow. This also sets the maximum numerical value for touch 1.49 +// ids we can use when injecting touch points on Windows. 1.50 +#define TOUCH_INJECT_MAX_POINTS 256 1.51 + 1.52 +class nsBaseWidget; 1.53 + 1.54 +class WidgetShutdownObserver MOZ_FINAL : public nsIObserver 1.55 +{ 1.56 +public: 1.57 + WidgetShutdownObserver(nsBaseWidget* aWidget) 1.58 + : mWidget(aWidget) 1.59 + { } 1.60 + 1.61 + NS_DECL_ISUPPORTS 1.62 + NS_DECL_NSIOBSERVER 1.63 + 1.64 + nsBaseWidget *mWidget; 1.65 +}; 1.66 + 1.67 +/** 1.68 + * Common widget implementation used as base class for native 1.69 + * or crossplatform implementations of Widgets. 1.70 + * All cross-platform behavior that all widgets need to implement 1.71 + * should be placed in this class. 1.72 + * (Note: widget implementations are not required to use this 1.73 + * class, but it gives them a head start.) 1.74 + */ 1.75 + 1.76 +class nsBaseWidget : public nsIWidget 1.77 +{ 1.78 + friend class nsAutoRollup; 1.79 + 1.80 +protected: 1.81 + typedef base::Thread Thread; 1.82 + typedef mozilla::layers::BasicLayerManager BasicLayerManager; 1.83 + typedef mozilla::layers::BufferMode BufferMode; 1.84 + typedef mozilla::layers::CompositorChild CompositorChild; 1.85 + typedef mozilla::layers::CompositorParent CompositorParent; 1.86 + typedef mozilla::ScreenRotation ScreenRotation; 1.87 + 1.88 +public: 1.89 + nsBaseWidget(); 1.90 + virtual ~nsBaseWidget(); 1.91 + 1.92 + NS_DECL_ISUPPORTS 1.93 + 1.94 + // nsIWidget interface 1.95 + NS_IMETHOD CaptureMouse(bool aCapture); 1.96 + virtual nsIWidgetListener* GetWidgetListener(); 1.97 + virtual void SetWidgetListener(nsIWidgetListener* alistener); 1.98 + NS_IMETHOD Destroy(); 1.99 + NS_IMETHOD SetParent(nsIWidget* aNewParent); 1.100 + virtual nsIWidget* GetParent(void); 1.101 + virtual nsIWidget* GetTopLevelWidget(); 1.102 + virtual nsIWidget* GetSheetWindowParent(void); 1.103 + virtual float GetDPI(); 1.104 + virtual void AddChild(nsIWidget* aChild); 1.105 + virtual void RemoveChild(nsIWidget* aChild); 1.106 + 1.107 + void SetZIndex(int32_t aZIndex); 1.108 + NS_IMETHOD PlaceBehind(nsTopLevelWidgetZPlacement aPlacement, 1.109 + nsIWidget *aWidget, bool aActivate); 1.110 + 1.111 + NS_IMETHOD SetSizeMode(int32_t aMode); 1.112 + virtual int32_t SizeMode() MOZ_OVERRIDE 1.113 + { 1.114 + return mSizeMode; 1.115 + } 1.116 + 1.117 + virtual nsCursor GetCursor(); 1.118 + NS_IMETHOD SetCursor(nsCursor aCursor); 1.119 + NS_IMETHOD SetCursor(imgIContainer* aCursor, 1.120 + uint32_t aHotspotX, uint32_t aHotspotY); 1.121 + virtual void SetTransparencyMode(nsTransparencyMode aMode); 1.122 + virtual nsTransparencyMode GetTransparencyMode(); 1.123 + virtual void GetWindowClipRegion(nsTArray<nsIntRect>* aRects); 1.124 + NS_IMETHOD SetWindowShadowStyle(int32_t aStyle); 1.125 + virtual void SetShowsToolbarButton(bool aShow) {} 1.126 + virtual void SetShowsFullScreenButton(bool aShow) {} 1.127 + virtual void SetWindowAnimationType(WindowAnimationType aType) {} 1.128 + NS_IMETHOD HideWindowChrome(bool aShouldHide); 1.129 + NS_IMETHOD MakeFullScreen(bool aFullScreen); 1.130 + virtual nsDeviceContext* GetDeviceContext(); 1.131 + virtual LayerManager* GetLayerManager(PLayerTransactionChild* aShadowManager = nullptr, 1.132 + LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE, 1.133 + LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT, 1.134 + bool* aAllowRetaining = nullptr); 1.135 + 1.136 + virtual CompositorParent* NewCompositorParent(int aSurfaceWidth, int aSurfaceHeight); 1.137 + virtual void CreateCompositor(); 1.138 + virtual void CreateCompositor(int aWidth, int aHeight); 1.139 + virtual void PrepareWindowEffects() {} 1.140 + virtual void CleanupWindowEffects() {} 1.141 + virtual bool PreRender(LayerManagerComposite* aManager) { return true; } 1.142 + virtual void PostRender(LayerManagerComposite* aManager) {} 1.143 + virtual void DrawWindowUnderlay(LayerManagerComposite* aManager, nsIntRect aRect) {} 1.144 + virtual void DrawWindowOverlay(LayerManagerComposite* aManager, nsIntRect aRect) {} 1.145 + virtual mozilla::TemporaryRef<mozilla::gfx::DrawTarget> StartRemoteDrawing(); 1.146 + virtual void EndRemoteDrawing() { }; 1.147 + virtual void CleanupRemoteDrawing() { }; 1.148 + virtual void UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries) {} 1.149 + virtual gfxASurface* GetThebesSurface(); 1.150 + NS_IMETHOD SetModal(bool aModal); 1.151 + virtual uint32_t GetMaxTouchPoints() const; 1.152 + NS_IMETHOD SetWindowClass(const nsAString& xulWinType); 1.153 + // Return whether this widget interprets parameters to Move and Resize APIs 1.154 + // as "global display pixels" rather than "device pixels", and therefore 1.155 + // applies its GetDefaultScale() value to them before using them as mBounds 1.156 + // etc (which are always stored in device pixels). 1.157 + // Note that APIs that -get- the widget's position/size/bounds, rather than 1.158 + // -setting- them (i.e. moving or resizing the widget) will always return 1.159 + // values in the widget's device pixels. 1.160 + bool BoundsUseDisplayPixels() const { 1.161 + return mWindowType <= eWindowType_popup; 1.162 + } 1.163 + NS_IMETHOD MoveClient(double aX, double aY); 1.164 + NS_IMETHOD ResizeClient(double aWidth, double aHeight, bool aRepaint); 1.165 + NS_IMETHOD ResizeClient(double aX, double aY, double aWidth, double aHeight, bool aRepaint); 1.166 + NS_IMETHOD GetBounds(nsIntRect &aRect); 1.167 + NS_IMETHOD GetClientBounds(nsIntRect &aRect); 1.168 + NS_IMETHOD GetScreenBounds(nsIntRect &aRect); 1.169 + NS_IMETHOD GetNonClientMargins(nsIntMargin &margins); 1.170 + NS_IMETHOD SetNonClientMargins(nsIntMargin &margins); 1.171 + virtual nsIntPoint GetClientOffset(); 1.172 + NS_IMETHOD EnableDragDrop(bool aEnable); 1.173 + NS_IMETHOD GetAttention(int32_t aCycleCount); 1.174 + virtual bool HasPendingInputEvent(); 1.175 + NS_IMETHOD SetIcon(const nsAString &anIconSpec); 1.176 + NS_IMETHOD SetWindowTitlebarColor(nscolor aColor, bool aActive); 1.177 + virtual void SetDrawsInTitlebar(bool aState) {} 1.178 + virtual bool ShowsResizeIndicator(nsIntRect* aResizerRect); 1.179 + virtual void FreeNativeData(void * data, uint32_t aDataType) {} 1.180 + NS_IMETHOD BeginResizeDrag(mozilla::WidgetGUIEvent* aEvent, 1.181 + int32_t aHorizontal, 1.182 + int32_t aVertical); 1.183 + NS_IMETHOD BeginMoveDrag(mozilla::WidgetMouseEvent* aEvent); 1.184 + virtual nsresult ActivateNativeMenuItemAt(const nsAString& indexString) { return NS_ERROR_NOT_IMPLEMENTED; } 1.185 + virtual nsresult ForceUpdateNativeMenuAt(const nsAString& indexString) { return NS_ERROR_NOT_IMPLEMENTED; } 1.186 + NS_IMETHOD NotifyIME(const IMENotification& aIMENotification) MOZ_OVERRIDE { return NS_ERROR_NOT_IMPLEMENTED; } 1.187 + NS_IMETHOD AttachNativeKeyEvent(mozilla::WidgetKeyboardEvent& aEvent) MOZ_OVERRIDE { return NS_ERROR_NOT_IMPLEMENTED; } 1.188 + NS_IMETHOD_(bool) ExecuteNativeKeyBinding( 1.189 + NativeKeyBindingsType aType, 1.190 + const mozilla::WidgetKeyboardEvent& aEvent, 1.191 + DoCommandCallback aCallback, 1.192 + void* aCallbackData) MOZ_OVERRIDE { return false; } 1.193 + NS_IMETHOD SetLayersAcceleration(bool aEnabled); 1.194 + virtual bool GetLayersAcceleration() { return mUseLayersAcceleration; } 1.195 + virtual bool ComputeShouldAccelerate(bool aDefault); 1.196 + NS_IMETHOD GetToggledKeyState(uint32_t aKeyCode, bool* aLEDState) { return NS_ERROR_NOT_IMPLEMENTED; } 1.197 + virtual nsIMEUpdatePreference GetIMEUpdatePreference() MOZ_OVERRIDE { return nsIMEUpdatePreference(); } 1.198 + NS_IMETHOD OnDefaultButtonLoaded(const nsIntRect &aButtonRect) { return NS_ERROR_NOT_IMPLEMENTED; } 1.199 + NS_IMETHOD OverrideSystemMouseScrollSpeed(double aOriginalDeltaX, 1.200 + double aOriginalDeltaY, 1.201 + double& aOverriddenDeltaX, 1.202 + double& aOverriddenDeltaY); 1.203 + virtual already_AddRefed<nsIWidget> 1.204 + CreateChild(const nsIntRect &aRect, 1.205 + nsDeviceContext *aContext, 1.206 + nsWidgetInitData *aInitData = nullptr, 1.207 + bool aForceUseIWidgetParent = false); 1.208 + NS_IMETHOD AttachViewToTopLevel(bool aUseAttachedEvents, nsDeviceContext *aContext); 1.209 + virtual nsIWidgetListener* GetAttachedWidgetListener(); 1.210 + virtual void SetAttachedWidgetListener(nsIWidgetListener* aListener); 1.211 + NS_IMETHOD RegisterTouchWindow(); 1.212 + NS_IMETHOD UnregisterTouchWindow(); 1.213 + 1.214 + void NotifyWindowDestroyed(); 1.215 + void NotifySizeMoveDone(); 1.216 + void NotifyWindowMoved(int32_t aX, int32_t aY); 1.217 + 1.218 + // Should be called by derived implementations to notify on system color and 1.219 + // theme changes. 1.220 + void NotifySysColorChanged(); 1.221 + void NotifyThemeChanged(); 1.222 + void NotifyUIStateChanged(UIStateChangeType aShowAccelerators, 1.223 + UIStateChangeType aShowFocusRings); 1.224 + 1.225 +#ifdef ACCESSIBILITY 1.226 + // Get the accessible for the window. 1.227 + mozilla::a11y::Accessible* GetRootAccessible(); 1.228 +#endif 1.229 + 1.230 + nsPopupLevel PopupLevel() { return mPopupLevel; } 1.231 + 1.232 + virtual nsIntSize ClientToWindowSize(const nsIntSize& aClientSize) 1.233 + { 1.234 + return aClientSize; 1.235 + } 1.236 + 1.237 + // return true if this is a popup widget with a native titlebar 1.238 + bool IsPopupWithTitleBar() const 1.239 + { 1.240 + return (mWindowType == eWindowType_popup && 1.241 + mBorderStyle != eBorderStyle_default && 1.242 + mBorderStyle & eBorderStyle_title); 1.243 + } 1.244 + 1.245 + NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent) = 0; 1.246 + 1.247 + virtual uint32_t GetGLFrameBufferFormat() MOZ_OVERRIDE; 1.248 + 1.249 + virtual const SizeConstraints& GetSizeConstraints() const; 1.250 + virtual void SetSizeConstraints(const SizeConstraints& aConstraints); 1.251 + 1.252 + /** 1.253 + * Use this when GetLayerManager() returns a BasicLayerManager 1.254 + * (nsBaseWidget::GetLayerManager() does). This sets up the widget's 1.255 + * layer manager to temporarily render into aTarget. 1.256 + * 1.257 + * |aNaturalWidgetBounds| is the un-rotated bounds of |aWidget|. 1.258 + * |aRotation| is the "virtual rotation" to apply when rendering to 1.259 + * the target. When |aRotation| is ROTATION_0, 1.260 + * |aNaturalWidgetBounds| is not used. 1.261 + */ 1.262 + class AutoLayerManagerSetup { 1.263 + public: 1.264 + AutoLayerManagerSetup(nsBaseWidget* aWidget, gfxContext* aTarget, 1.265 + BufferMode aDoubleBuffering, 1.266 + ScreenRotation aRotation = mozilla::ROTATION_0); 1.267 + ~AutoLayerManagerSetup(); 1.268 + private: 1.269 + nsBaseWidget* mWidget; 1.270 + nsRefPtr<BasicLayerManager> mLayerManager; 1.271 + }; 1.272 + friend class AutoLayerManagerSetup; 1.273 + 1.274 + class AutoUseBasicLayerManager { 1.275 + public: 1.276 + AutoUseBasicLayerManager(nsBaseWidget* aWidget); 1.277 + ~AutoUseBasicLayerManager(); 1.278 + private: 1.279 + nsBaseWidget* mWidget; 1.280 + bool mPreviousTemporarilyUseBasicLayerManager; 1.281 + }; 1.282 + friend class AutoUseBasicLayerManager; 1.283 + 1.284 + virtual bool ShouldUseOffMainThreadCompositing(); 1.285 + 1.286 + static nsIRollupListener* GetActiveRollupListener(); 1.287 + 1.288 + void Shutdown(); 1.289 + 1.290 +protected: 1.291 + 1.292 + virtual void ResolveIconName(const nsAString &aIconName, 1.293 + const nsAString &aIconSuffix, 1.294 + nsIFile **aResult); 1.295 + virtual void OnDestroy(); 1.296 + virtual void BaseCreate(nsIWidget *aParent, 1.297 + const nsIntRect &aRect, 1.298 + nsDeviceContext *aContext, 1.299 + nsWidgetInitData *aInitData); 1.300 + 1.301 + virtual nsIContent* GetLastRollup() 1.302 + { 1.303 + return mLastRollup; 1.304 + } 1.305 + 1.306 + virtual nsresult SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout, 1.307 + int32_t aNativeKeyCode, 1.308 + uint32_t aModifierFlags, 1.309 + const nsAString& aCharacters, 1.310 + const nsAString& aUnmodifiedCharacters) 1.311 + { return NS_ERROR_UNEXPECTED; } 1.312 + 1.313 + virtual nsresult SynthesizeNativeMouseEvent(nsIntPoint aPoint, 1.314 + uint32_t aNativeMessage, 1.315 + uint32_t aModifierFlags) 1.316 + { return NS_ERROR_UNEXPECTED; } 1.317 + 1.318 + virtual nsresult SynthesizeNativeMouseMove(nsIntPoint aPoint) 1.319 + { return NS_ERROR_UNEXPECTED; } 1.320 + 1.321 + virtual nsresult SynthesizeNativeMouseScrollEvent(nsIntPoint aPoint, 1.322 + uint32_t aNativeMessage, 1.323 + double aDeltaX, 1.324 + double aDeltaY, 1.325 + double aDeltaZ, 1.326 + uint32_t aModifierFlags, 1.327 + uint32_t aAdditionalFlags) 1.328 + { return NS_ERROR_UNEXPECTED; } 1.329 + 1.330 + virtual nsresult SynthesizeNativeTouchPoint(uint32_t aPointerId, 1.331 + TouchPointerState aPointerState, 1.332 + nsIntPoint aPointerScreenPoint, 1.333 + double aPointerPressure, 1.334 + uint32_t aPointerOrientation) 1.335 + { return NS_ERROR_UNEXPECTED; } 1.336 + 1.337 +protected: 1.338 + // Stores the clip rectangles in aRects into mClipRects. Returns true 1.339 + // if the new rectangles are different from the old rectangles. 1.340 + bool StoreWindowClipRegion(const nsTArray<nsIntRect>& aRects); 1.341 + 1.342 + virtual already_AddRefed<nsIWidget> 1.343 + AllocateChildPopupWidget() 1.344 + { 1.345 + static NS_DEFINE_IID(kCPopUpCID, NS_CHILD_CID); 1.346 + nsCOMPtr<nsIWidget> widget = do_CreateInstance(kCPopUpCID); 1.347 + return widget.forget(); 1.348 + } 1.349 + 1.350 + LayerManager* CreateBasicLayerManager(); 1.351 + 1.352 + nsPopupType PopupType() const { return mPopupType; } 1.353 + 1.354 + void NotifyRollupGeometryChange() 1.355 + { 1.356 + // XULPopupManager isn't interested in this notification, so only 1.357 + // send it if gRollupListener is set. 1.358 + if (gRollupListener) { 1.359 + gRollupListener->NotifyGeometryChange(); 1.360 + } 1.361 + } 1.362 + 1.363 + /** 1.364 + * Apply the current size constraints to the given size. 1.365 + * 1.366 + * @param aWidth width to constrain 1.367 + * @param aHeight height to constrain 1.368 + */ 1.369 + void ConstrainSize(int32_t* aWidth, int32_t* aHeight) const 1.370 + { 1.371 + *aWidth = std::max(mSizeConstraints.mMinSize.width, 1.372 + std::min(mSizeConstraints.mMaxSize.width, *aWidth)); 1.373 + *aHeight = std::max(mSizeConstraints.mMinSize.height, 1.374 + std::min(mSizeConstraints.mMaxSize.height, *aHeight)); 1.375 + } 1.376 + 1.377 + virtual CompositorChild* GetRemoteRenderer() MOZ_OVERRIDE; 1.378 + 1.379 + virtual void GetPreferredCompositorBackends(nsTArray<mozilla::layers::LayersBackend>& aHints); 1.380 + 1.381 + /** 1.382 + * Notify the widget that this window is being used with OMTC. 1.383 + */ 1.384 + virtual void WindowUsesOMTC() {} 1.385 + 1.386 +protected: 1.387 + /** 1.388 + * Starts the OMTC compositor destruction sequence. 1.389 + * 1.390 + * When this function returns, the compositor should not be 1.391 + * able to access the opengl context anymore. 1.392 + * It is safe to call it several times if platform implementations 1.393 + * require the compositor to be destroyed before ~nsBaseWidget is 1.394 + * reached (This is the case with gtk2 for instance). 1.395 + */ 1.396 + void DestroyCompositor(); 1.397 + 1.398 + nsIWidgetListener* mWidgetListener; 1.399 + nsIWidgetListener* mAttachedWidgetListener; 1.400 + nsDeviceContext* mContext; 1.401 + nsRefPtr<LayerManager> mLayerManager; 1.402 + nsRefPtr<LayerManager> mBasicLayerManager; 1.403 + nsRefPtr<CompositorChild> mCompositorChild; 1.404 + nsRefPtr<CompositorParent> mCompositorParent; 1.405 + nsRefPtr<WidgetShutdownObserver> mShutdownObserver; 1.406 + nsCursor mCursor; 1.407 + nsBorderStyle mBorderStyle; 1.408 + bool mUseLayersAcceleration; 1.409 + bool mForceLayersAcceleration; 1.410 + bool mTemporarilyUseBasicLayerManager; 1.411 + // Windows with out-of-process tabs always require OMTC. This flag designates 1.412 + // such windows. 1.413 + bool mRequireOffMainThreadCompositing; 1.414 + bool mUseAttachedEvents; 1.415 + bool mContextInitialized; 1.416 + nsIntRect mBounds; 1.417 + nsIntRect* mOriginalBounds; 1.418 + // When this pointer is null, the widget is not clipped 1.419 + nsAutoArrayPtr<nsIntRect> mClipRects; 1.420 + uint32_t mClipRectCount; 1.421 + nsSizeMode mSizeMode; 1.422 + nsPopupLevel mPopupLevel; 1.423 + nsPopupType mPopupType; 1.424 + SizeConstraints mSizeConstraints; 1.425 + 1.426 + static nsIRollupListener* gRollupListener; 1.427 + 1.428 + // the last rolled up popup. Only set this when an nsAutoRollup is in scope, 1.429 + // so it can be cleared automatically. 1.430 + static nsIContent* mLastRollup; 1.431 + 1.432 +#ifdef DEBUG 1.433 +protected: 1.434 + static nsAutoString debug_GuiEventToString(mozilla::WidgetGUIEvent* aGuiEvent); 1.435 + static bool debug_WantPaintFlashing(); 1.436 + 1.437 + static void debug_DumpInvalidate(FILE * aFileOut, 1.438 + nsIWidget * aWidget, 1.439 + const nsIntRect * aRect, 1.440 + const nsAutoCString & aWidgetName, 1.441 + int32_t aWindowID); 1.442 + 1.443 + static void debug_DumpEvent(FILE* aFileOut, 1.444 + nsIWidget* aWidget, 1.445 + mozilla::WidgetGUIEvent* aGuiEvent, 1.446 + const nsAutoCString& aWidgetName, 1.447 + int32_t aWindowID); 1.448 + 1.449 + static void debug_DumpPaintEvent(FILE * aFileOut, 1.450 + nsIWidget * aWidget, 1.451 + const nsIntRegion & aPaintEvent, 1.452 + const nsAutoCString & aWidgetName, 1.453 + int32_t aWindowID); 1.454 + 1.455 + static bool debug_GetCachedBoolPref(const char* aPrefName); 1.456 +#endif 1.457 +}; 1.458 + 1.459 +// A situation can occur when a mouse event occurs over a menu label while the 1.460 +// menu popup is already open. The expected behaviour is to close the popup. 1.461 +// This happens by calling nsIRollupListener::Rollup before the mouse event is 1.462 +// processed. However, in cases where the mouse event is not consumed, this 1.463 +// event will then get targeted at the menu label causing the menu to open 1.464 +// again. To prevent this, we store in mLastRollup a reference to the popup 1.465 +// that was closed during the Rollup call, and prevent this popup from 1.466 +// reopening while processing the mouse event. 1.467 +// mLastRollup should only be set while an nsAutoRollup is in scope; 1.468 +// when it goes out of scope mLastRollup is cleared automatically. 1.469 +// As mLastRollup is static, it can be retrieved by calling 1.470 +// nsIWidget::GetLastRollup on any widget. 1.471 +class nsAutoRollup 1.472 +{ 1.473 + bool wasClear; 1.474 + 1.475 + public: 1.476 + 1.477 + nsAutoRollup(); 1.478 + ~nsAutoRollup(); 1.479 +}; 1.480 + 1.481 +#endif // nsBaseWidget_h__