forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			395 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			395 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 | |
|  *
 | |
|  * This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| #ifndef mozilla_AppWindow_h__
 | |
| #define mozilla_AppWindow_h__
 | |
| 
 | |
| // Local Includes
 | |
| #include "nsChromeTreeOwner.h"
 | |
| #include "nsContentTreeOwner.h"
 | |
| 
 | |
| // Helper classes
 | |
| #include "nsCOMPtr.h"
 | |
| #include "nsTArray.h"
 | |
| #include "nsString.h"
 | |
| #include "nsWeakReference.h"
 | |
| #include "nsCOMArray.h"
 | |
| #include "nsDocShell.h"
 | |
| #include "nsRect.h"
 | |
| #include "Units.h"
 | |
| #include "mozilla/Maybe.h"
 | |
| #include "mozilla/Mutex.h"
 | |
| 
 | |
| // Interfaces needed
 | |
| #include "nsIBaseWindow.h"
 | |
| #include "nsIDocShellTreeItem.h"
 | |
| #include "nsIInterfaceRequestor.h"
 | |
| #include "nsIInterfaceRequestorUtils.h"
 | |
| #include "nsIAppWindow.h"
 | |
| #include "nsIPrompt.h"
 | |
| #include "nsIAuthPrompt.h"
 | |
| #include "nsIXULBrowserWindow.h"
 | |
| #include "nsIWidgetListener.h"
 | |
| #include "nsIRemoteTab.h"
 | |
| #include "nsIWebProgressListener.h"
 | |
| #include "nsITimer.h"
 | |
| #include "nsIXULStore.h"
 | |
| 
 | |
| class nsAtom;
 | |
| class nsXULTooltipListener;
 | |
| 
 | |
| namespace mozilla {
 | |
| class PresShell;
 | |
| class AppWindowTimerCallback;
 | |
| class L10nReadyPromiseHandler;
 | |
| namespace dom {
 | |
| class Element;
 | |
| }  // namespace dom
 | |
| namespace widget {
 | |
| struct InitData;
 | |
| }  // namespace widget
 | |
| }  // namespace mozilla
 | |
| 
 | |
| // AppWindow
 | |
| 
 | |
| #define NS_APPWINDOW_IMPL_CID                        \
 | |
|   { /* 8eaec2f3-ed02-4be2-8e0f-342798477298 */       \
 | |
|     0x8eaec2f3, 0xed02, 0x4be2, {                    \
 | |
|       0x8e, 0x0f, 0x34, 0x27, 0x98, 0x47, 0x72, 0x98 \
 | |
|     }                                                \
 | |
|   }
 | |
| 
 | |
| class nsContentShellInfo;
 | |
| 
 | |
| namespace mozilla {
 | |
| 
 | |
| class AppWindow final : public nsIBaseWindow,
 | |
|                         public nsIInterfaceRequestor,
 | |
|                         public nsIAppWindow,
 | |
|                         public nsSupportsWeakReference,
 | |
|                         public nsIWebProgressListener {
 | |
|   friend class ::nsChromeTreeOwner;
 | |
|   friend class ::nsContentTreeOwner;
 | |
| 
 | |
|  public:
 | |
|   // The implementation of non-refcounted nsIWidgetListener, which would hold a
 | |
|   // strong reference on stack before calling AppWindow's
 | |
|   // MOZ_CAN_RUN_SCRIPT methods.
 | |
|   class WidgetListenerDelegate : public nsIWidgetListener {
 | |
|    public:
 | |
|     explicit WidgetListenerDelegate(AppWindow* aAppWindow)
 | |
|         : mAppWindow(aAppWindow) {}
 | |
| 
 | |
|     MOZ_CAN_RUN_SCRIPT_BOUNDARY
 | |
|     virtual nsIAppWindow* GetAppWindow() override;
 | |
|     MOZ_CAN_RUN_SCRIPT_BOUNDARY
 | |
|     virtual mozilla::PresShell* GetPresShell() override;
 | |
|     MOZ_CAN_RUN_SCRIPT_BOUNDARY
 | |
|     virtual bool WindowMoved(nsIWidget* aWidget, int32_t x, int32_t y,
 | |
|                              ByMoveToRect) override;
 | |
|     MOZ_CAN_RUN_SCRIPT_BOUNDARY
 | |
|     virtual bool WindowResized(nsIWidget* aWidget, int32_t aWidth,
 | |
|                                int32_t aHeight) override;
 | |
|     MOZ_CAN_RUN_SCRIPT_BOUNDARY
 | |
|     virtual bool RequestWindowClose(nsIWidget* aWidget) override;
 | |
|     MOZ_CAN_RUN_SCRIPT_BOUNDARY
 | |
|     virtual void SizeModeChanged(nsSizeMode sizeMode) override;
 | |
|     MOZ_CAN_RUN_SCRIPT_BOUNDARY
 | |
|     virtual void MacFullscreenMenubarOverlapChanged(
 | |
|         mozilla::DesktopCoord aOverlapAmount) override;
 | |
|     MOZ_CAN_RUN_SCRIPT_BOUNDARY
 | |
|     virtual void OcclusionStateChanged(bool aIsFullyOccluded) override;
 | |
|     MOZ_CAN_RUN_SCRIPT_BOUNDARY
 | |
|     virtual void OSToolbarButtonPressed() override;
 | |
|     MOZ_CAN_RUN_SCRIPT_BOUNDARY
 | |
|     virtual bool ZLevelChanged(bool aImmediate, nsWindowZ* aPlacement,
 | |
|                                nsIWidget* aRequestBelow,
 | |
|                                nsIWidget** aActualBelow) override;
 | |
|     MOZ_CAN_RUN_SCRIPT_BOUNDARY
 | |
|     virtual void WindowActivated() override;
 | |
|     MOZ_CAN_RUN_SCRIPT_BOUNDARY
 | |
|     virtual void WindowDeactivated() override;
 | |
| 
 | |
|    private:
 | |
|     // The lifetime of WidgetListenerDelegate is bound to AppWindow so
 | |
|     // we just use a raw pointer here.
 | |
|     AppWindow* mAppWindow;
 | |
|   };
 | |
| 
 | |
|   NS_DECL_THREADSAFE_ISUPPORTS
 | |
| 
 | |
|   NS_DECL_NSIINTERFACEREQUESTOR
 | |
|   NS_DECL_NSIAPPWINDOW
 | |
|   NS_DECL_NSIBASEWINDOW
 | |
| 
 | |
|   NS_DECLARE_STATIC_IID_ACCESSOR(NS_APPWINDOW_IMPL_CID)
 | |
| 
 | |
|   void LockUntilChromeLoad() { mLockedUntilChromeLoad = true; }
 | |
|   bool IsLocked() const { return mLockedUntilChromeLoad; }
 | |
|   void IgnoreXULSizeMode(bool aEnable) { mIgnoreXULSizeMode = aEnable; }
 | |
|   void WasRegistered() { mRegistered = true; }
 | |
| 
 | |
|   using nsIBaseWindow::GetPositionAndSize;
 | |
|   using nsIBaseWindow::GetSize;
 | |
| 
 | |
|   // AppWindow methods...
 | |
|   nsresult Initialize(nsIAppWindow* aParent, nsIAppWindow* aOpener,
 | |
|                       int32_t aInitialWidth, int32_t aInitialHeight,
 | |
|                       bool aIsHiddenWindow, widget::InitData& widgetInitData);
 | |
| 
 | |
|   nsDocShell* GetDocShell() { return mDocShell; }
 | |
| 
 | |
|   nsresult Toolbar();
 | |
| 
 | |
|   // nsIWebProgressListener
 | |
|   NS_DECL_NSIWEBPROGRESSLISTENER
 | |
| 
 | |
|   // nsIWidgetListener methods for WidgetListenerDelegate.
 | |
|   nsIAppWindow* GetAppWindow() { return this; }
 | |
|   mozilla::PresShell* GetPresShell();
 | |
|   MOZ_CAN_RUN_SCRIPT
 | |
|   bool WindowMoved(nsIWidget* aWidget, int32_t aX, int32_t aY);
 | |
|   MOZ_CAN_RUN_SCRIPT
 | |
|   bool WindowResized(nsIWidget* aWidget, int32_t aWidth, int32_t aHeight);
 | |
|   MOZ_CAN_RUN_SCRIPT bool RequestWindowClose(nsIWidget* aWidget);
 | |
|   MOZ_CAN_RUN_SCRIPT void SizeModeChanged(nsSizeMode aSizeMode);
 | |
|   MOZ_CAN_RUN_SCRIPT void FullscreenWillChange(bool aInFullscreen);
 | |
|   MOZ_CAN_RUN_SCRIPT void FullscreenChanged(bool aInFullscreen);
 | |
|   MOZ_CAN_RUN_SCRIPT void MacFullscreenMenubarOverlapChanged(
 | |
|       mozilla::DesktopCoord aOverlapAmount);
 | |
|   MOZ_CAN_RUN_SCRIPT void OcclusionStateChanged(bool aIsFullyOccluded);
 | |
|   void RecomputeBrowsingContextVisibility();
 | |
|   MOZ_CAN_RUN_SCRIPT void OSToolbarButtonPressed();
 | |
|   MOZ_CAN_RUN_SCRIPT
 | |
|   bool ZLevelChanged(bool aImmediate, nsWindowZ* aPlacement,
 | |
|                      nsIWidget* aRequestBelow, nsIWidget** aActualBelow);
 | |
|   MOZ_CAN_RUN_SCRIPT void WindowActivated();
 | |
|   MOZ_CAN_RUN_SCRIPT void WindowDeactivated();
 | |
| 
 | |
|   explicit AppWindow(uint32_t aChromeFlags);
 | |
| 
 | |
|  protected:
 | |
|   enum class PersistentAttribute : uint8_t {
 | |
|     Position,
 | |
|     Size,
 | |
|     Misc,
 | |
|   };
 | |
|   using PersistentAttributes = EnumSet<PersistentAttribute>;
 | |
| 
 | |
|   static PersistentAttributes AllPersistentAttributes() {
 | |
|     return {PersistentAttribute::Position, PersistentAttribute::Size,
 | |
|             PersistentAttribute::Misc};
 | |
|   }
 | |
| 
 | |
|   virtual ~AppWindow();
 | |
| 
 | |
|   friend class mozilla::AppWindowTimerCallback;
 | |
| 
 | |
|   MOZ_CAN_RUN_SCRIPT bool ExecuteCloseHandler();
 | |
|   void ConstrainToOpenerScreen(int32_t* aX, int32_t* aY);
 | |
| 
 | |
|   void SetPersistenceTimer(uint32_t aDirtyFlags);
 | |
|   void FirePersistenceTimer();
 | |
| 
 | |
|   NS_IMETHOD EnsureChromeTreeOwner();
 | |
|   NS_IMETHOD EnsureContentTreeOwner();
 | |
|   NS_IMETHOD EnsurePrimaryContentTreeOwner();
 | |
|   NS_IMETHOD EnsurePrompter();
 | |
|   NS_IMETHOD EnsureAuthPrompter();
 | |
|   NS_IMETHOD ForceRoundedDimensions();
 | |
|   NS_IMETHOD GetAvailScreenSize(int32_t* aAvailWidth, int32_t* aAvailHeight);
 | |
| 
 | |
|   void FinishFullscreenChange(bool aInFullscreen);
 | |
| 
 | |
|   void ApplyChromeFlags();
 | |
|   MOZ_CAN_RUN_SCRIPT_BOUNDARY void SizeShell();
 | |
|   void OnChromeLoaded();
 | |
|   void StaggerPosition(int32_t& aRequestedX, int32_t& aRequestedY,
 | |
|                        int32_t aSpecWidth, int32_t aSpecHeight);
 | |
|   bool LoadPositionFromXUL(int32_t aSpecWidth, int32_t aSpecHeight);
 | |
|   bool LoadSizeFromXUL(int32_t& aSpecWidth, int32_t& aSpecHeight);
 | |
|   void SetSpecifiedSize(int32_t aSpecWidth, int32_t aSpecHeight);
 | |
|   bool UpdateWindowStateFromMiscXULAttributes();
 | |
|   void SyncAttributesToWidget();
 | |
|   void SavePersistentAttributes(PersistentAttributes);
 | |
|   void MaybeSavePersistentPositionAndSize(PersistentAttributes,
 | |
|                                           dom::Element& aRootElement,
 | |
|                                           const nsAString& aPersistString,
 | |
|                                           bool aShouldPersist);
 | |
|   void MaybeSavePersistentMiscAttributes(PersistentAttributes,
 | |
|                                          dom::Element& aRootElement,
 | |
|                                          const nsAString& aPersistString,
 | |
|                                          bool aShouldPersist);
 | |
|   void SavePersistentAttributes() {
 | |
|     SavePersistentAttributes(mPersistentAttributesDirty);
 | |
|   }
 | |
| 
 | |
|   bool NeedsTooltipListener();
 | |
|   void AddTooltipSupport();
 | |
|   void RemoveTooltipSupport();
 | |
| 
 | |
|   NS_IMETHOD GetWindowDOMWindow(mozIDOMWindowProxy** aDOMWindow);
 | |
|   dom::Element* GetWindowDOMElement() const;
 | |
| 
 | |
|   // See nsIDocShellTreeOwner for docs on next two methods
 | |
|   nsresult ContentShellAdded(nsIDocShellTreeItem* aContentShell, bool aPrimary);
 | |
|   nsresult ContentShellRemoved(nsIDocShellTreeItem* aContentShell);
 | |
|   NS_IMETHOD GetPrimaryContentSize(int32_t* aWidth, int32_t* aHeight);
 | |
|   NS_IMETHOD SetPrimaryContentSize(int32_t aWidth, int32_t aHeight);
 | |
|   nsresult GetRootShellSize(int32_t* aWidth, int32_t* aHeight);
 | |
|   nsresult SetRootShellSize(int32_t aWidth, int32_t aHeight);
 | |
| 
 | |
|   NS_IMETHOD SizeShellTo(nsIDocShellTreeItem* aShellItem, int32_t aCX,
 | |
|                          int32_t aCY);
 | |
|   NS_IMETHOD ExitModalLoop(nsresult aStatus);
 | |
|   NS_IMETHOD CreateNewChromeWindow(int32_t aChromeFlags,
 | |
|                                    nsIAppWindow** _retval);
 | |
|   NS_IMETHOD CreateNewContentWindow(int32_t aChromeFlags,
 | |
|                                     nsIOpenWindowInfo* aOpenWindowInfo,
 | |
|                                     nsIAppWindow** _retval);
 | |
|   NS_IMETHOD GetHasPrimaryContent(bool* aResult);
 | |
| 
 | |
|   void EnableParent(bool aEnable);
 | |
|   bool ConstrainToZLevel(bool aImmediate, nsWindowZ* aPlacement,
 | |
|                          nsIWidget* aReqBelow, nsIWidget** aActualBelow);
 | |
|   void PlaceWindowLayersBehind(uint32_t aLowLevel, uint32_t aHighLevel,
 | |
|                                nsIAppWindow* aBehind);
 | |
|   void SetContentScrollbarVisibility(bool aVisible);
 | |
| 
 | |
|   enum PersistentAttributeUpdate { Sync, Async };
 | |
|   void PersistentAttributesDirty(PersistentAttributes,
 | |
|                                  PersistentAttributeUpdate);
 | |
|   nsresult GetTabCount(uint32_t* aResult);
 | |
| 
 | |
|   void LoadPersistentWindowState();
 | |
|   nsresult GetPersistentValue(const nsAtom* aAttr, nsAString& aValue);
 | |
|   nsresult SetPersistentValue(const nsAtom* aAttr, const nsAString& aValue);
 | |
| 
 | |
|   // Saves window size and positioning values in order to display a very early
 | |
|   // skeleton UI. This has to happen before we can reasonably initialize the
 | |
|   // xulstore (i.e., before even loading libxul), so they have to use a special
 | |
|   // purpose store to do so.
 | |
|   nsresult MaybeSaveEarlyWindowPersistentValues(
 | |
|       const LayoutDeviceIntRect& aRect);
 | |
| 
 | |
|   // Gets the uri spec and the window element ID for this window.
 | |
|   nsresult GetDocXulStoreKeys(nsString& aUriSpec, nsString& aWindowElementId);
 | |
| 
 | |
|   // Enum for the current state of a fullscreen change.
 | |
|   //
 | |
|   // It is used to ensure that fullscreen change is issued after both
 | |
|   // the window state change and the window size change at best effort.
 | |
|   // This is needed because some platforms can't guarantee the order
 | |
|   // between such two events.
 | |
|   //
 | |
|   // It's changed in the following way:
 | |
|   // +---------------------------+--------------------------------------+
 | |
|   // |                           |                                      |
 | |
|   // |                           v                                      |
 | |
|   // |                      NotChanging                                 |
 | |
|   // |                           +                                      |
 | |
|   // |                           | FullscreenWillChange                 |
 | |
|   // |                           v                                      |
 | |
|   // |        +-----------+ WillChange +------------------+             |
 | |
|   // |        | WindowResized           FullscreenChanged |             |
 | |
|   // |        v                                           v             |
 | |
|   // |  WidgetResized                         WidgetEnteredFullscreen   |
 | |
|   // |        +                              or WidgetExitedFullscreen  |
 | |
|   // |        | FullscreenChanged                         +             |
 | |
|   // |        v                          WindowResized or |             |
 | |
|   // +--------+                          delayed dispatch |             |
 | |
|   //                                                      v             |
 | |
|   //                                                      +-------------+
 | |
|   //
 | |
|   // The delayed dispatch serves as timeout, which is necessary because it's
 | |
|   // not even guaranteed that the widget will be resized at all.
 | |
|   enum class FullscreenChangeState : uint8_t {
 | |
|     // No current fullscreen change. Any previous change has finished.
 | |
|     NotChanging,
 | |
|     // Indicate there is going to be a fullscreen change.
 | |
|     WillChange,
 | |
|     // The widget has been resized since WillChange.
 | |
|     WidgetResized,
 | |
|     // The widget has entered fullscreen state since WillChange.
 | |
|     WidgetEnteredFullscreen,
 | |
|     // The widget has exited fullscreen state since WillChange.
 | |
|     WidgetExitedFullscreen,
 | |
|   };
 | |
| 
 | |
|   nsChromeTreeOwner* mChromeTreeOwner;
 | |
|   nsContentTreeOwner* mContentTreeOwner;
 | |
|   nsContentTreeOwner* mPrimaryContentTreeOwner;
 | |
|   nsCOMPtr<nsIWidget> mWindow;
 | |
|   RefPtr<nsDocShell> mDocShell;
 | |
|   nsCOMPtr<nsPIDOMWindowOuter> mDOMWindow;
 | |
|   nsWeakPtr mParentWindow;
 | |
|   nsCOMPtr<nsIPrompt> mPrompter;
 | |
|   nsCOMPtr<nsIAuthPrompt> mAuthPrompter;
 | |
|   nsCOMPtr<nsIXULBrowserWindow> mXULBrowserWindow;
 | |
|   nsCOMPtr<nsIDocShellTreeItem> mPrimaryContentShell;
 | |
|   nsresult mModalStatus;
 | |
|   FullscreenChangeState mFullscreenChangeState;
 | |
|   bool mContinueModalLoop;
 | |
|   bool mDebuting;            // being made visible right now
 | |
|   bool mChromeLoaded;        // True when chrome has loaded
 | |
|   bool mSizingShellFromXUL;  // true when in SizeShell()
 | |
|   bool mShowAfterLoad;
 | |
|   bool mIntrinsicallySized;
 | |
|   bool mCenterAfterLoad;
 | |
|   bool mIsHiddenWindow;
 | |
|   bool mLockedUntilChromeLoad;
 | |
|   bool mIgnoreXULSize;
 | |
|   bool mIgnoreXULPosition;
 | |
|   bool mChromeFlagsFrozen;
 | |
|   bool mIgnoreXULSizeMode;
 | |
|   // mDestroying is used to prevent reentry into into Destroy(), which can
 | |
|   // otherwise happen due to script running as we tear down various things.
 | |
|   bool mDestroying;
 | |
|   bool mRegistered;
 | |
|   // Indicator for whether the client size, instead of the window size, should
 | |
|   // be maintained in case of a change in their relation.
 | |
|   bool mDominantClientSize;
 | |
|   PersistentAttributes mPersistentAttributesDirty;
 | |
|   PersistentAttributes mPersistentAttributesMask;
 | |
|   uint32_t mChromeFlags;
 | |
|   nsCOMPtr<nsIOpenWindowInfo> mInitialOpenWindowInfo;
 | |
|   nsString mTitle;
 | |
| 
 | |
|   // The screen rect of the opener.
 | |
|   mozilla::DesktopIntRect mOpenerScreenRect;
 | |
| 
 | |
|   nsCOMPtr<nsIRemoteTab> mPrimaryBrowserParent;
 | |
| 
 | |
|   nsCOMPtr<nsITimer> mSPTimer;
 | |
|   WidgetListenerDelegate mWidgetListenerDelegate;
 | |
| 
 | |
|  private:
 | |
|   MOZ_CAN_RUN_SCRIPT void IntrinsicallySizeShell(const CSSIntSize& aWindowDiff,
 | |
|                                                  int32_t& aSpecWidth,
 | |
|                                                  int32_t& aSpecHeight);
 | |
| 
 | |
|   // GetPrimaryBrowserParentSize is called from xpidl methods and we don't have
 | |
|   // a good way to annotate those with MOZ_CAN_RUN_SCRIPT yet.  It takes no
 | |
|   // refcounted args other than "this", and the "this" uses seem ok.
 | |
|   MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult
 | |
|   GetPrimaryRemoteTabSize(int32_t* aWidth, int32_t* aHeight);
 | |
|   nsresult GetPrimaryContentShellSize(int32_t* aWidth, int32_t* aHeight);
 | |
|   nsresult SetPrimaryRemoteTabSize(int32_t aWidth, int32_t aHeight);
 | |
|   void SizeShellToWithLimit(int32_t aDesiredWidth, int32_t aDesiredHeight,
 | |
|                             int32_t shellItemWidth, int32_t shellItemHeight);
 | |
|   nsresult MoveResize(const Maybe<LayoutDeviceIntPoint>& aPosition,
 | |
|                       const Maybe<LayoutDeviceIntSize>& aSize, bool aRepaint);
 | |
|   nsresult MoveResize(const Maybe<DesktopPoint>& aPosition,
 | |
|                       const Maybe<DesktopSize>& aSize, bool aRepaint);
 | |
|   nsCOMPtr<nsIXULStore> mLocalStore;
 | |
|   bool mIsWidgetInFullscreen = false;
 | |
| };
 | |
| 
 | |
| NS_DEFINE_STATIC_IID_ACCESSOR(AppWindow, NS_APPWINDOW_IMPL_CID)
 | |
| 
 | |
| }  // namespace mozilla
 | |
| 
 | |
| #endif /* mozilla_AppWindow_h__ */
 | 
