1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef nsCocoaWindow_h_
7 #define nsCocoaWindow_h_
11 #import <Cocoa/Cocoa.h>
13 #include "mozilla/RefPtr.h"
14 #include "nsBaseWidget.h"
15 #include "nsPIWidgetCocoa.h"
16 #include "nsCocoaUtils.h"
17 #include "nsTouchBar.h"
25 typedef struct _nsCocoaWindowList
{
26 _nsCocoaWindowList() : prev(nullptr), window(nullptr) {}
27 struct _nsCocoaWindowList
* prev
;
28 nsCocoaWindow
* window
; // Weak
31 // NSWindow subclass that is the base class for all of our own window classes.
32 // Among other things, this class handles the storage of those settings that
33 // need to be persisted across window destruction and reconstruction, i.e. when
34 // switching to and from fullscreen mode.
35 // We don't save shadow, transparency mode or background color because it's not
36 // worth the hassle - Gecko will reset them anyway as soon as the window is
38 @interface BaseWindow
: NSWindow
{
40 NSMutableDictionary
* mState
;
41 BOOL mDrawsIntoWindowFrame
;
43 // Invalidation disabling
44 BOOL mDisabledNeedsDisplay
;
46 NSTrackingArea
* mTrackingArea
;
52 BOOL mBrightTitlebarForeground
;
54 BOOL mIsAnimationSuppressed
;
56 nsTouchBar
* mTouchBar
;
59 - (void)importState
:(NSDictionary
*)aState
;
60 - (NSMutableDictionary
*)exportState
;
61 - (void)setDrawsContentsIntoWindowFrame
:(BOOL
)aState
;
62 - (BOOL
)drawsContentsIntoWindowFrame
;
64 // These two methods are like contentRectForFrameRect and frameRectForContentRect,
65 // but they deal with the rect of the window's "main ChildView" instead of the
66 // rect of the window's content view. The two are sometimes sized differently: The
67 // window's content view always covers the entire window, whereas the ChildView
68 // only covers the full window when drawsContentsIntoWindowFrame is YES. When
69 // drawsContentsIntoWindowFrame is NO, there's a titlebar-sized gap above the
70 // ChildView within the content view.
71 - (NSRect
)childViewRectForFrameRect
:(NSRect
)aFrameRect
;
72 - (NSRect
)frameRectForChildViewRect
:(NSRect
)aChildViewRect
;
74 - (void)mouseEntered
:(NSEvent
*)aEvent
;
75 - (void)mouseExited
:(NSEvent
*)aEvent
;
76 - (void)mouseMoved
:(NSEvent
*)aEvent
;
77 - (void)updateTrackingArea
;
78 - (NSView
*)trackingAreaView
;
80 - (void)setBeingShown
:(BOOL
)aValue
;
82 - (BOOL
)isVisibleOrBeingShown
;
84 - (void)setIsAnimationSuppressed
:(BOOL
)aValue
;
85 - (BOOL
)isAnimationSuppressed
;
87 // Returns an autoreleased NSArray containing the NSViews that we consider the
88 // "contents" of this window. All views in the returned array are subviews of
89 // this window's content view. However, the array may not include all of the
90 // content view's subviews; concretely, the ToolbarWindow implementation will
91 // exclude its TitlebarGradientView from the array that is returned here.
92 // In the vast majority of cases, the array will only have a single element:
93 // this window's mainChildView.
94 - (NSArray
<NSView
*>*)contentViewContents
;
96 - (ChildView
*)mainChildView
;
98 - (void)setWantsTitleDrawn
:(BOOL
)aDrawTitle
;
99 - (BOOL
)wantsTitleDrawn
;
101 - (void)setUseBrightTitlebarForeground
:(BOOL
)aBrightForeground
;
102 - (BOOL
)useBrightTitlebarForeground
;
104 - (void)disableSetNeedsDisplay
;
105 - (void)enableSetNeedsDisplay
;
107 - (NSRect
)getAndResetNativeDirtyRect
;
109 - (void)setUseMenuStyle
:(BOOL
)aValue
;
111 - (void)releaseJSObjects
;
115 @interface
NSWindow (Undocumented
)
117 // If a window has been explicitly removed from the "window cache" (to
118 // deactivate it), it's sometimes necessary to "reset" it to reactivate it
119 // (and put it back in the "window cache"). One way to do this, which Apple
120 // often uses, is to set the "window number" to '-1' and then back to its
122 - (void)_setWindowNumber
:(NSInteger
)aNumber
;
124 - (BOOL
)bottomCornerRounded
;
126 // Present in the same form on OS X since at least OS X 10.5.
127 - (NSRect
)contentRectForFrameRect
:(NSRect
)windowFrame styleMask
:(NSUInteger
)windowStyle
;
128 - (NSRect
)frameRectForContentRect
:(NSRect
)windowContentRect styleMask
:(NSUInteger
)windowStyle
;
130 // Present since at least OS X 10.5. The OS calls this method on NSWindow
131 // (and its subclasses) to find out which NSFrameView subclass to instantiate
132 // to create its "frame view".
133 + (Class
)frameViewClassForStyleMask
:(NSUInteger
)styleMask
;
137 @interface PopupWindow
: BaseWindow
{
142 - (id
)initWithContentRect
:(NSRect
)contentRect
143 styleMask
:(NSUInteger
)styleMask
144 backing
:(NSBackingStoreType
)bufferingType
145 defer
:(BOOL
)deferCreation
;
146 - (BOOL
)isContextMenu
;
147 - (void)setIsContextMenu
:(BOOL
)flag
;
148 - (BOOL
)canBecomeMainWindow
;
152 @interface BorderlessWindow
: BaseWindow
{
155 - (BOOL
)canBecomeKeyWindow
;
156 - (BOOL
)canBecomeMainWindow
;
160 @interface WindowDelegate
: NSObject
<NSWindowDelegate
> {
161 nsCocoaWindow
* mGeckoWindow
; // [WEAK] (we are owned by the window)
162 // Used to avoid duplication when we send NS_ACTIVATE and
163 // NS_DEACTIVATE to Gecko for toplevel widgets. Starts out
165 bool mToplevelActiveState
;
166 BOOL mHasEverBeenZoomed
;
168 + (void)paintMenubarForWindow
:(NSWindow
*)aWindow
;
169 - (id
)initWithGeckoWindow
:(nsCocoaWindow
*)geckoWind
;
170 - (void)windowDidResize
:(NSNotification
*)aNotification
;
171 - (nsCocoaWindow
*)geckoWidget
;
172 - (bool)toplevelActiveState
;
173 - (void)sendToplevelActivateEvents
;
174 - (void)sendToplevelDeactivateEvents
;
177 @interface TitlebarGradientView
: NSView
180 // NSWindow subclass for handling windows with toolbars.
181 @interface ToolbarWindow
: BaseWindow
{
182 // This window's titlebar gradient view, if present.
183 // Will be nil if drawsContentsIntoWindowFrame is YES.
184 // This view is a subview of the window's content view and gets created and
185 // destroyed by updateTitlebarGradientViewPresence.
186 TitlebarGradientView
* mTitlebarGradientView
; // [STRONG]
188 CGFloat mUnifiedToolbarHeight
;
189 CGFloat mSheetAttachmentPosition
;
190 NSRect mWindowButtonsRect
;
191 NSRect mFullScreenButtonRect
;
193 - (void)setUnifiedToolbarHeight
:(CGFloat
)aHeight
;
194 - (CGFloat
)unifiedToolbarHeight
;
195 - (CGFloat
)titlebarHeight
;
196 - (NSRect
)titlebarRect
;
197 - (void)setTitlebarNeedsDisplay
;
198 - (void)setDrawsContentsIntoWindowFrame
:(BOOL
)aState
;
199 - (void)setSheetAttachmentPosition
:(CGFloat
)aY
;
200 - (CGFloat
)sheetAttachmentPosition
;
201 - (void)placeWindowButtons
:(NSRect
)aRect
;
202 - (void)placeFullScreenButton
:(NSRect
)aRect
;
203 - (NSPoint
)windowButtonsPositionWithDefaultPosition
:(NSPoint
)aDefaultPosition
;
204 - (NSPoint
)fullScreenButtonPositionWithDefaultPosition
:(NSPoint
)aDefaultPosition
;
205 - (void)windowMainStateChanged
;
208 class nsCocoaWindow final
: public nsBaseWidget
, public nsPIWidgetCocoa
{
210 typedef nsBaseWidget Inherited
;
215 NS_DECL_ISUPPORTS_INHERITED
216 NS_DECL_NSPIWIDGETCOCOA
; // semicolon for clang-format bug 1629756
218 [[nodiscard
]] virtual nsresult
Create(nsIWidget
* aParent
, nsNativeWidget aNativeParent
,
219 const DesktopIntRect
& aRect
,
220 nsWidgetInitData
* aInitData
= nullptr) override
;
222 [[nodiscard
]] virtual nsresult
Create(nsIWidget
* aParent
, nsNativeWidget aNativeParent
,
223 const LayoutDeviceIntRect
& aRect
,
224 nsWidgetInitData
* aInitData
= nullptr) override
;
226 virtual void Destroy() override
;
228 virtual void Show(bool aState
) override
;
229 virtual bool NeedsRecreateToReshow() override
;
231 virtual nsIWidget
* GetSheetWindowParent(void) override
;
232 virtual void Enable(bool aState
) override
;
233 virtual bool IsEnabled() const override
;
234 virtual void SetModal(bool aState
) override
;
235 virtual void SetFakeModal(bool aState
) override
;
236 virtual bool IsRunningAppModal() override
;
237 virtual bool IsVisible() const override
;
238 virtual void SetFocus(Raise
, mozilla::dom::CallerType aCallerType
) override
;
239 virtual LayoutDeviceIntPoint
WidgetToScreenOffset() override
;
240 virtual LayoutDeviceIntPoint
GetClientOffset() override
;
241 virtual LayoutDeviceIntSize
ClientToWindowSize(const LayoutDeviceIntSize
& aClientSize
) override
;
243 virtual void* GetNativeData(uint32_t aDataType
) override
;
245 virtual void ConstrainPosition(bool aAllowSlop
, int32_t* aX
, int32_t* aY
) override
;
246 virtual void SetSizeConstraints(const SizeConstraints
& aConstraints
) override
;
247 virtual void Move(double aX
, double aY
) override
;
248 virtual void SetSizeMode(nsSizeMode aMode
) override
;
249 virtual void GetWorkspaceID(nsAString
& workspaceID
) override
;
250 virtual void MoveToWorkspace(const nsAString
& workspaceID
) override
;
251 virtual void SuppressAnimation(bool aSuppress
) override
;
252 virtual void HideWindowChrome(bool aShouldHide
) override
;
254 void WillEnterFullScreen(bool aFullScreen
);
255 void EnteredFullScreen(bool aFullScreen
, bool aNativeMode
= true);
256 virtual bool PrepareForFullscreenTransition(nsISupports
** aData
) override
;
257 virtual void PerformFullscreenTransition(FullscreenTransitionStage aStage
, uint16_t aDuration
,
258 nsISupports
* aData
, nsIRunnable
* aCallback
) override
;
259 nsresult
MakeFullScreen(bool aFullScreen
, nsIScreen
* aTargetScreen
= nullptr) final
;
260 nsresult
MakeFullScreenWithNativeTransition(bool aFullScreen
,
261 nsIScreen
* aTargetScreen
= nullptr) final
;
262 NSAnimation
* FullscreenTransitionAnimation() const { return mFullscreenTransitionAnimation
; }
263 void ReleaseFullscreenTransitionAnimation() {
264 MOZ_ASSERT(mFullscreenTransitionAnimation
, "Should only be called when there is animation");
265 [mFullscreenTransitionAnimation release
];
266 mFullscreenTransitionAnimation
= nil
;
269 virtual void Resize(double aWidth
, double aHeight
, bool aRepaint
) override
;
270 virtual void Resize(double aX
, double aY
, double aWidth
, double aHeight
, bool aRepaint
) override
;
271 NSRect
GetClientCocoaRect();
272 virtual LayoutDeviceIntRect
GetClientBounds() override
;
273 virtual LayoutDeviceIntRect
GetScreenBounds() override
;
274 void ReportMoveEvent();
275 void ReportSizeEvent();
276 virtual void SetCursor(nsCursor aDefaultCursor
, imgIContainer
* aCursorImage
, uint32_t aHotspotX
,
277 uint32_t aHotspotY
) override
;
279 CGFloat
BackingScaleFactor();
280 void BackingScaleFactorChanged();
281 virtual double GetDefaultScaleInternal() override
;
282 virtual int32_t RoundsWidgetCoordinatesTo() override
;
284 mozilla::DesktopToLayoutDeviceScale
GetDesktopToDeviceScale() final
{
285 return mozilla::DesktopToLayoutDeviceScale(BackingScaleFactor());
288 virtual nsresult
SetTitle(const nsAString
& aTitle
) override
;
290 virtual void Invalidate(const LayoutDeviceIntRect
& aRect
) override
;
291 virtual nsresult
ConfigureChildren(const nsTArray
<Configuration
>& aConfigurations
) override
;
292 virtual LayerManager
* GetLayerManager(
293 PLayerTransactionChild
* aShadowManager
= nullptr,
294 LayersBackend aBackendHint
= mozilla::layers::LayersBackend::LAYERS_NONE
,
295 LayerManagerPersistence aPersistence
= LAYER_MANAGER_CURRENT
) override
;
296 virtual nsresult
DispatchEvent(mozilla::WidgetGUIEvent
* aEvent
, nsEventStatus
& aStatus
) override
;
297 virtual void CaptureRollupEvents(nsIRollupListener
* aListener
, bool aDoCapture
) override
;
298 [[nodiscard
]] virtual nsresult
GetAttention(int32_t aCycleCount
) override
;
299 virtual bool HasPendingInputEvent() override
;
300 virtual nsTransparencyMode
GetTransparencyMode() override
;
301 virtual void SetTransparencyMode(nsTransparencyMode aMode
) override
;
302 virtual void SetWindowShadowStyle(mozilla::StyleWindowShadow aStyle
) override
;
303 virtual void SetWindowOpacity(float aOpacity
) override
;
304 virtual void SetWindowTransform(const mozilla::gfx::Matrix
& aTransform
) override
;
305 virtual void SetWindowMouseTransparent(bool aIsTransparent
) override
;
306 virtual void SetShowsToolbarButton(bool aShow
) override
;
307 virtual void SetSupportsNativeFullscreen(bool aShow
) override
;
308 virtual void SetWindowAnimationType(WindowAnimationType aType
) override
;
309 virtual void SetDrawsTitle(bool aDrawTitle
) override
;
310 virtual void SetUseBrightTitlebarForeground(bool aBrightForeground
) override
;
311 virtual nsresult
SetNonClientMargins(LayoutDeviceIntMargin
& aMargins
) override
;
312 virtual void SetDrawsInTitlebar(bool aState
) override
;
313 virtual void UpdateThemeGeometries(const nsTArray
<ThemeGeometry
>& aThemeGeometries
) override
;
314 virtual nsresult
SynthesizeNativeMouseEvent(LayoutDeviceIntPoint aPoint
, uint32_t aNativeMessage
,
315 uint32_t aModifierFlags
,
316 nsIObserver
* aObserver
) override
;
317 virtual nsresult
SynthesizeNativeMouseScrollEvent(LayoutDeviceIntPoint aPoint
,
318 uint32_t aNativeMessage
, double aDeltaX
,
319 double aDeltaY
, double aDeltaZ
,
320 uint32_t aModifierFlags
,
321 uint32_t aAdditionalFlags
,
322 nsIObserver
* aObserver
) override
;
323 virtual void LockAspectRatio(bool aShouldLock
) override
;
325 void DispatchSizeModeEvent();
326 void DispatchOcclusionEvent();
328 // be notified that a some form of drag event needs to go into Gecko
329 virtual bool DragEvent(unsigned int aMessage
, mozilla::gfx::Point aMouseGlobal
,
330 UInt16 aKeyModifiers
);
332 bool HasModalDescendents() { return mNumModalDescendents
> 0; }
333 NSWindow
* GetCocoaWindow() { return mWindow
; }
335 void SetMenuBar(nsMenuBarX
* aMenuBar
);
336 nsMenuBarX
* GetMenuBar();
338 virtual void SetInputContext(const InputContext
& aContext
,
339 const InputContextAction
& aAction
) override
;
340 virtual InputContext
GetInputContext() override
{ return mInputContext
; }
341 virtual bool GetEditCommands(NativeKeyBindingsType aType
,
342 const mozilla::WidgetKeyboardEvent
& aEvent
,
343 nsTArray
<mozilla::CommandInt
>& aCommands
) override
;
345 void SetPopupWindowLevel();
347 bool InFullScreenMode() const { return mInFullScreenMode
; }
349 void PauseCompositor();
350 void ResumeCompositor();
353 virtual ~nsCocoaWindow();
355 nsresult
CreateNativeWindow(const NSRect
& aRect
, nsBorderStyle aBorderStyle
,
356 bool aRectIsFrameRect
);
357 nsresult
CreatePopupContentView(const LayoutDeviceIntRect
& aRect
, nsWidgetInitData
* aInitData
);
358 void DestroyNativeWindow();
359 void AdjustWindowShadow();
360 void SetWindowBackgroundBlur();
362 int32_t GetWorkspaceID();
364 void DoResize(double aX
, double aY
, double aWidth
, double aHeight
, bool aRepaint
,
365 bool aConstrainToCurrentScreen
);
367 inline bool ShouldToggleNativeFullscreen(bool aFullScreen
, bool aUseSystemTransition
);
368 void UpdateFullscreenState(bool aFullScreen
, bool aNativeMode
);
369 nsresult
DoMakeFullScreen(bool aFullScreen
, bool aUseSystemTransition
);
371 virtual already_AddRefed
<nsIWidget
> AllocateChildPopupWidget() override
{
372 return nsIWidget::CreateTopLevelWindow();
375 nsIWidget
* mParent
; // if we're a popup, this is our parent [WEAK]
376 nsIWidget
* mAncestorLink
; // link to traverse ancestors [WEAK]
377 BaseWindow
* mWindow
; // our cocoa window [STRONG]
378 WindowDelegate
* mDelegate
; // our delegate for processing window msgs [STRONG]
379 RefPtr
<nsMenuBarX
> mMenuBar
;
380 NSWindow
* mSheetWindowParent
; // if this is a sheet, this is the NSWindow it's attached to
381 nsChildView
* mPopupContentView
; // if this is a popup, this is its content widget
382 // if this is a toplevel window, and there is any ongoing fullscreen
383 // transition, it is the animation object.
384 NSAnimation
* mFullscreenTransitionAnimation
;
385 mozilla::StyleWindowShadow mShadowStyle
;
387 CGFloat mBackingScaleFactor
;
388 CGFloat mAspectRatio
;
390 WindowAnimationType mAnimationType
;
392 bool mWindowMadeHere
; // true if we created the window, false for embedding
393 bool mSheetNeedsShow
; // if this is a sheet, are we waiting to be shown?
394 // this is used for sibling sheet contention only
395 bool mInFullScreenMode
;
396 bool mInFullScreenTransition
; // true from the request to enter/exit fullscreen
397 // (MakeFullScreen() call) to EnteredFullScreen()
401 // Whether we are currently using native fullscreen. It could be false because
402 // we are in the DOM fullscreen where we do not use the native fullscreen.
403 bool mInNativeFullScreenMode
;
405 bool mIsAnimationSuppressed
;
407 bool mInReportMoveEvent
; // true if in a call to ReportMoveEvent().
408 bool mInResize
; // true if in a call to DoResize().
409 bool mWindowTransformIsIdentity
;
411 bool mAspectRatioLocked
;
413 int32_t mNumModalDescendents
;
414 InputContext mInputContext
;
415 NSWindowAnimationBehavior mWindowAnimationBehavior
;
418 // true if Show() has been called.
422 #endif // nsCocoaWindow_h_