michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsCocoaWindow_h_ michael@0: #define nsCocoaWindow_h_ michael@0: michael@0: #undef DARWIN michael@0: michael@0: #import michael@0: michael@0: #include "nsBaseWidget.h" michael@0: #include "nsPIWidgetCocoa.h" michael@0: #include "nsAutoPtr.h" michael@0: #include "nsCocoaUtils.h" michael@0: michael@0: class nsCocoaWindow; michael@0: class nsChildView; michael@0: class nsMenuBarX; michael@0: @class ChildView; michael@0: michael@0: // Value copied from BITMAP_MAX_AREA, used in nsNativeThemeCocoa.mm michael@0: #define CUIDRAW_MAX_AREA 500000 michael@0: michael@0: // If we are using an SDK older than 10.7, define bits we need that are missing michael@0: // from it. michael@0: #if !defined(MAC_OS_X_VERSION_10_7) || \ michael@0: MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 michael@0: michael@0: enum { michael@0: NSWindowAnimationBehaviorDefault = 0, michael@0: NSWindowAnimationBehaviorNone = 2, michael@0: NSWindowAnimationBehaviorDocumentWindow = 3, michael@0: NSWindowAnimationBehaviorUtilityWindow = 4, michael@0: NSWindowAnimationBehaviorAlertPanel = 5, michael@0: NSWindowCollectionBehaviorFullScreenPrimary = 128, // 1 << 7 michael@0: }; michael@0: michael@0: typedef NSInteger NSWindowAnimationBehavior; michael@0: michael@0: @interface NSWindow (LionWindowFeatures) michael@0: - (void)setAnimationBehavior:(NSWindowAnimationBehavior)newAnimationBehavior; michael@0: - (void)toggleFullScreen:(id)sender; michael@0: @end michael@0: michael@0: #endif michael@0: michael@0: typedef struct _nsCocoaWindowList { michael@0: _nsCocoaWindowList() : prev(nullptr), window(nullptr) {} michael@0: struct _nsCocoaWindowList *prev; michael@0: nsCocoaWindow *window; // Weak michael@0: } nsCocoaWindowList; michael@0: michael@0: // NSWindow subclass that is the base class for all of our own window classes. michael@0: // Among other things, this class handles the storage of those settings that michael@0: // need to be persisted across window destruction and reconstruction, i.e. when michael@0: // switching to and from fullscreen mode. michael@0: // We don't save shadow, transparency mode or background color because it's not michael@0: // worth the hassle - Gecko will reset them anyway as soon as the window is michael@0: // resized. michael@0: @interface BaseWindow : NSWindow michael@0: { michael@0: // Data Storage michael@0: NSMutableDictionary* mState; michael@0: BOOL mDrawsIntoWindowFrame; michael@0: NSColor* mActiveTitlebarColor; michael@0: NSColor* mInactiveTitlebarColor; michael@0: michael@0: // Shadow michael@0: BOOL mScheduledShadowInvalidation; michael@0: michael@0: // Invalidation disabling michael@0: BOOL mDisabledNeedsDisplay; michael@0: michael@0: // DPI cache. Getting the physical screen size (CGDisplayScreenSize) michael@0: // is ridiculously slow, so we cache it in the toplevel window for all michael@0: // descendants to use. michael@0: float mDPI; michael@0: michael@0: NSTrackingArea* mTrackingArea; michael@0: michael@0: BOOL mBeingShown; michael@0: BOOL mDrawTitle; michael@0: } michael@0: michael@0: - (void)importState:(NSDictionary*)aState; michael@0: - (NSMutableDictionary*)exportState; michael@0: - (void)setDrawsContentsIntoWindowFrame:(BOOL)aState; michael@0: - (BOOL)drawsContentsIntoWindowFrame; michael@0: - (void)setTitlebarColor:(NSColor*)aColor forActiveWindow:(BOOL)aActive; michael@0: - (NSColor*)titlebarColorForActiveWindow:(BOOL)aActive; michael@0: michael@0: - (void)deferredInvalidateShadow; michael@0: - (void)invalidateShadow; michael@0: - (float)getDPI; michael@0: michael@0: - (void)mouseEntered:(NSEvent*)aEvent; michael@0: - (void)mouseExited:(NSEvent*)aEvent; michael@0: - (void)mouseMoved:(NSEvent*)aEvent; michael@0: - (void)updateTrackingArea; michael@0: - (NSView*)trackingAreaView; michael@0: michael@0: - (void)setBeingShown:(BOOL)aValue; michael@0: - (BOOL)isBeingShown; michael@0: - (BOOL)isVisibleOrBeingShown; michael@0: michael@0: - (ChildView*)mainChildView; michael@0: michael@0: - (NSArray*)titlebarControls; michael@0: michael@0: - (void)setWantsTitleDrawn:(BOOL)aDrawTitle; michael@0: - (BOOL)wantsTitleDrawn; michael@0: michael@0: - (void)disableSetNeedsDisplay; michael@0: - (void)enableSetNeedsDisplay; michael@0: michael@0: @end michael@0: michael@0: @interface NSWindow (Undocumented) michael@0: michael@0: // If a window has been explicitly removed from the "window cache" (to michael@0: // deactivate it), it's sometimes necessary to "reset" it to reactivate it michael@0: // (and put it back in the "window cache"). One way to do this, which Apple michael@0: // often uses, is to set the "window number" to '-1' and then back to its michael@0: // original value. michael@0: - (void)_setWindowNumber:(NSInteger)aNumber; michael@0: michael@0: // If we set the window's stylemask to be textured, the corners on the bottom of michael@0: // the window are rounded by default. We use this private method to make michael@0: // the corners square again, a la Safari. Starting with 10.7, all windows have michael@0: // rounded bottom corners, so this call doesn't have any effect there. michael@0: - (void)setBottomCornerRounded:(BOOL)rounded; michael@0: - (BOOL)bottomCornerRounded; michael@0: michael@0: // Present in the same form on OS X since at least OS X 10.5. michael@0: - (NSRect)contentRectForFrameRect:(NSRect)windowFrame styleMask:(NSUInteger)windowStyle; michael@0: - (NSRect)frameRectForContentRect:(NSRect)windowContentRect styleMask:(NSUInteger)windowStyle; michael@0: michael@0: // Present since at least OS X 10.5. The OS calls this method on NSWindow michael@0: // (and its subclasses) to find out which NSFrameView subclass to instantiate michael@0: // to create its "frame view". michael@0: + (Class)frameViewClassForStyleMask:(NSUInteger)styleMask; michael@0: michael@0: @end michael@0: michael@0: @interface PopupWindow : BaseWindow michael@0: { michael@0: @private michael@0: BOOL mIsContextMenu; michael@0: } michael@0: michael@0: - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask michael@0: backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation; michael@0: - (BOOL)isContextMenu; michael@0: - (void)setIsContextMenu:(BOOL)flag; michael@0: - (BOOL)canBecomeMainWindow; michael@0: michael@0: @end michael@0: michael@0: @interface BorderlessWindow : BaseWindow michael@0: { michael@0: } michael@0: michael@0: - (BOOL)canBecomeKeyWindow; michael@0: - (BOOL)canBecomeMainWindow; michael@0: michael@0: @end michael@0: michael@0: #if defined( MAC_OS_X_VERSION_10_6 ) && ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 ) michael@0: @interface WindowDelegate : NSObject michael@0: #else michael@0: @interface WindowDelegate : NSObject michael@0: #endif michael@0: { michael@0: nsCocoaWindow* mGeckoWindow; // [WEAK] (we are owned by the window) michael@0: // Used to avoid duplication when we send NS_ACTIVATE and michael@0: // NS_DEACTIVATE to Gecko for toplevel widgets. Starts out michael@0: // false. michael@0: bool mToplevelActiveState; michael@0: BOOL mHasEverBeenZoomed; michael@0: } michael@0: + (void)paintMenubarForWindow:(NSWindow*)aWindow; michael@0: - (id)initWithGeckoWindow:(nsCocoaWindow*)geckoWind; michael@0: - (void)windowDidResize:(NSNotification*)aNotification; michael@0: - (nsCocoaWindow*)geckoWidget; michael@0: - (bool)toplevelActiveState; michael@0: - (void)sendToplevelActivateEvents; michael@0: - (void)sendToplevelDeactivateEvents; michael@0: @end michael@0: michael@0: @class ToolbarWindow; michael@0: michael@0: // NSColor subclass that allows us to draw separate colors both in the titlebar michael@0: // and for background of the window. michael@0: @interface TitlebarAndBackgroundColor : NSColor michael@0: { michael@0: ToolbarWindow *mWindow; // [WEAK] (we are owned by the window) michael@0: } michael@0: michael@0: - (id)initWithWindow:(ToolbarWindow*)aWindow; michael@0: michael@0: @end michael@0: michael@0: // NSWindow subclass for handling windows with toolbars. michael@0: @interface ToolbarWindow : BaseWindow michael@0: { michael@0: TitlebarAndBackgroundColor *mColor; michael@0: CGFloat mUnifiedToolbarHeight; michael@0: NSColor *mBackgroundColor; michael@0: NSView *mTitlebarView; // strong michael@0: NSRect mWindowButtonsRect; michael@0: NSRect mFullScreenButtonRect; michael@0: } michael@0: // Pass nil here to get the default appearance. michael@0: - (void)setTitlebarColor:(NSColor*)aColor forActiveWindow:(BOOL)aActive; michael@0: - (void)setUnifiedToolbarHeight:(CGFloat)aHeight; michael@0: - (CGFloat)unifiedToolbarHeight; michael@0: - (CGFloat)titlebarHeight; michael@0: - (NSRect)titlebarRect; michael@0: - (void)setTitlebarNeedsDisplayInRect:(NSRect)aRect sync:(BOOL)aSync; michael@0: - (void)setTitlebarNeedsDisplayInRect:(NSRect)aRect; michael@0: - (void)setDrawsContentsIntoWindowFrame:(BOOL)aState; michael@0: - (void)placeWindowButtons:(NSRect)aRect; michael@0: - (void)placeFullScreenButton:(NSRect)aRect; michael@0: - (NSPoint)windowButtonsPositionWithDefaultPosition:(NSPoint)aDefaultPosition; michael@0: - (NSPoint)fullScreenButtonPositionWithDefaultPosition:(NSPoint)aDefaultPosition; michael@0: @end michael@0: michael@0: class nsCocoaWindow : public nsBaseWidget, public nsPIWidgetCocoa michael@0: { michael@0: private: michael@0: michael@0: typedef nsBaseWidget Inherited; michael@0: michael@0: public: michael@0: michael@0: nsCocoaWindow(); michael@0: virtual ~nsCocoaWindow(); michael@0: michael@0: NS_DECL_ISUPPORTS_INHERITED michael@0: NS_DECL_NSPIWIDGETCOCOA michael@0: michael@0: NS_IMETHOD Create(nsIWidget* aParent, michael@0: nsNativeWidget aNativeParent, michael@0: const nsIntRect &aRect, michael@0: nsDeviceContext *aContext, michael@0: nsWidgetInitData *aInitData = nullptr); michael@0: michael@0: NS_IMETHOD Destroy(); michael@0: michael@0: NS_IMETHOD Show(bool aState); michael@0: virtual nsIWidget* GetSheetWindowParent(void); michael@0: NS_IMETHOD Enable(bool aState); michael@0: virtual bool IsEnabled() const; michael@0: NS_IMETHOD SetModal(bool aState); michael@0: virtual bool IsVisible() const; michael@0: NS_IMETHOD SetFocus(bool aState=false); michael@0: virtual nsIntPoint WidgetToScreenOffset(); michael@0: virtual nsIntPoint GetClientOffset(); michael@0: virtual nsIntSize ClientToWindowSize(const nsIntSize& aClientSize); michael@0: michael@0: virtual void* GetNativeData(uint32_t aDataType) ; michael@0: michael@0: NS_IMETHOD ConstrainPosition(bool aAllowSlop, michael@0: int32_t *aX, int32_t *aY); michael@0: virtual void SetSizeConstraints(const SizeConstraints& aConstraints); michael@0: NS_IMETHOD Move(double aX, double aY); michael@0: NS_IMETHOD PlaceBehind(nsTopLevelWidgetZPlacement aPlacement, michael@0: nsIWidget *aWidget, bool aActivate); michael@0: NS_IMETHOD SetSizeMode(int32_t aMode); michael@0: NS_IMETHOD HideWindowChrome(bool aShouldHide); michael@0: void EnteredFullScreen(bool aFullScreen); michael@0: NS_IMETHOD MakeFullScreen(bool aFullScreen); michael@0: NS_IMETHOD Resize(double aWidth, double aHeight, bool aRepaint); michael@0: NS_IMETHOD Resize(double aX, double aY, double aWidth, double aHeight, bool aRepaint); michael@0: NS_IMETHOD GetClientBounds(nsIntRect &aRect); michael@0: NS_IMETHOD GetScreenBounds(nsIntRect &aRect); michael@0: void ReportMoveEvent(); michael@0: void ReportSizeEvent(); michael@0: NS_IMETHOD SetCursor(nsCursor aCursor); michael@0: NS_IMETHOD SetCursor(imgIContainer* aCursor, uint32_t aHotspotX, uint32_t aHotspotY); michael@0: michael@0: CGFloat BackingScaleFactor(); michael@0: void BackingScaleFactorChanged(); michael@0: virtual double GetDefaultScaleInternal(); michael@0: virtual int32_t RoundsWidgetCoordinatesTo() MOZ_OVERRIDE; michael@0: michael@0: NS_IMETHOD SetTitle(const nsAString& aTitle); michael@0: michael@0: NS_IMETHOD Invalidate(const nsIntRect &aRect); michael@0: virtual nsresult ConfigureChildren(const nsTArray& aConfigurations); michael@0: virtual LayerManager* GetLayerManager(PLayerTransactionChild* aShadowManager = nullptr, michael@0: LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE, michael@0: LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT, michael@0: bool* aAllowRetaining = nullptr); michael@0: NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent, michael@0: nsEventStatus& aStatus); michael@0: NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, bool aDoCapture); michael@0: NS_IMETHOD GetAttention(int32_t aCycleCount); michael@0: virtual bool HasPendingInputEvent(); michael@0: virtual nsTransparencyMode GetTransparencyMode(); michael@0: virtual void SetTransparencyMode(nsTransparencyMode aMode); michael@0: NS_IMETHOD SetWindowShadowStyle(int32_t aStyle); michael@0: virtual void SetShowsToolbarButton(bool aShow); michael@0: virtual void SetShowsFullScreenButton(bool aShow); michael@0: virtual void SetWindowAnimationType(WindowAnimationType aType); michael@0: virtual void SetDrawsTitle(bool aDrawTitle); michael@0: NS_IMETHOD SetNonClientMargins(nsIntMargin &margins); michael@0: NS_IMETHOD SetWindowTitlebarColor(nscolor aColor, bool aActive); michael@0: virtual void SetDrawsInTitlebar(bool aState); michael@0: virtual nsresult SynthesizeNativeMouseEvent(nsIntPoint aPoint, michael@0: uint32_t aNativeMessage, michael@0: uint32_t aModifierFlags); michael@0: michael@0: void DispatchSizeModeEvent(); michael@0: michael@0: virtual gfxASurface* GetThebesSurface(); michael@0: michael@0: // be notified that a some form of drag event needs to go into Gecko michael@0: virtual bool DragEvent(unsigned int aMessage, Point aMouseGlobal, UInt16 aKeyModifiers); michael@0: michael@0: bool HasModalDescendents() { return mNumModalDescendents > 0; } michael@0: NSWindow *GetCocoaWindow() { return mWindow; } michael@0: michael@0: void SetMenuBar(nsMenuBarX* aMenuBar); michael@0: nsMenuBarX *GetMenuBar(); michael@0: michael@0: NS_IMETHOD NotifyIME(const IMENotification& aIMENotification) MOZ_OVERRIDE; michael@0: NS_IMETHOD_(void) SetInputContext( michael@0: const InputContext& aContext, michael@0: const InputContextAction& aAction) MOZ_OVERRIDE; michael@0: NS_IMETHOD_(InputContext) GetInputContext() michael@0: { michael@0: NSView* view = mWindow ? [mWindow contentView] : nil; michael@0: if (view) { michael@0: mInputContext.mNativeIMEContext = [view inputContext]; michael@0: } michael@0: // If inputContext isn't available on this window, returns this window's michael@0: // pointer since nullptr means the platform has only one context per michael@0: // process. michael@0: if (!mInputContext.mNativeIMEContext) { michael@0: mInputContext.mNativeIMEContext = this; michael@0: } michael@0: return mInputContext; michael@0: } michael@0: NS_IMETHOD_(bool) ExecuteNativeKeyBinding( michael@0: NativeKeyBindingsType aType, michael@0: const mozilla::WidgetKeyboardEvent& aEvent, michael@0: DoCommandCallback aCallback, michael@0: void* aCallbackData) MOZ_OVERRIDE; michael@0: michael@0: void SetPopupWindowLevel(); michael@0: michael@0: NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent); michael@0: protected: michael@0: michael@0: nsresult CreateNativeWindow(const NSRect &aRect, michael@0: nsBorderStyle aBorderStyle, michael@0: bool aRectIsFrameRect); michael@0: nsresult CreatePopupContentView(const nsIntRect &aRect, michael@0: nsDeviceContext *aContext); michael@0: void DestroyNativeWindow(); michael@0: void AdjustWindowShadow(); michael@0: void SetWindowBackgroundBlur(); michael@0: void UpdateBounds(); michael@0: michael@0: nsresult DoResize(double aX, double aY, double aWidth, double aHeight, michael@0: bool aRepaint, bool aConstrainToCurrentScreen); michael@0: michael@0: virtual already_AddRefed michael@0: AllocateChildPopupWidget() michael@0: { michael@0: static NS_DEFINE_IID(kCPopUpCID, NS_POPUP_CID); michael@0: nsCOMPtr widget = do_CreateInstance(kCPopUpCID); michael@0: return widget.forget(); michael@0: } michael@0: michael@0: nsIWidget* mParent; // if we're a popup, this is our parent [WEAK] michael@0: BaseWindow* mWindow; // our cocoa window [STRONG] michael@0: WindowDelegate* mDelegate; // our delegate for processing window msgs [STRONG] michael@0: nsRefPtr mMenuBar; michael@0: NSWindow* mSheetWindowParent; // if this is a sheet, this is the NSWindow it's attached to michael@0: nsChildView* mPopupContentView; // if this is a popup, this is its content widget michael@0: int32_t mShadowStyle; michael@0: michael@0: CGFloat mBackingScaleFactor; michael@0: michael@0: WindowAnimationType mAnimationType; michael@0: michael@0: bool mWindowMadeHere; // true if we created the window, false for embedding michael@0: bool mSheetNeedsShow; // if this is a sheet, are we waiting to be shown? michael@0: // this is used for sibling sheet contention only michael@0: bool mFullScreen; michael@0: bool mInFullScreenTransition; // true from the request to enter/exit fullscreen michael@0: // (MakeFullScreen() call) to EnteredFullScreen() michael@0: bool mModal; michael@0: michael@0: bool mUsesNativeFullScreen; // only true on Lion if SetShowsFullScreenButton(true); michael@0: michael@0: bool mIsAnimationSuppressed; michael@0: michael@0: bool mInReportMoveEvent; // true if in a call to ReportMoveEvent(). michael@0: bool mInResize; // true if in a call to DoResize(). michael@0: michael@0: int32_t mNumModalDescendents; michael@0: InputContext mInputContext; michael@0: }; michael@0: michael@0: #endif // nsCocoaWindow_h_