Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / widget / cocoa / nsCocoaWindow.h
blob96e117ba26608011db076c133286b19a309e7fac
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_
9 #undef DARWIN
11 #import <Cocoa/Cocoa.h>
13 #include "mozilla/RefPtr.h"
14 #include "nsBaseWidget.h"
15 #include "nsCocoaUtils.h"
16 #include "nsTouchBar.h"
17 #include <dlfcn.h>
18 #include <queue>
20 class nsCocoaWindow;
21 class nsChildView;
22 class nsMenuBarX;
23 @class ChildView;
25 namespace mozilla {
26 enum class NativeKeyBindingsType : uint8_t;
27 } // namespace mozilla
29 // NSWindow subclass that is the base class for all of our own window classes.
30 // Among other things, this class handles the storage of those settings that
31 // need to be persisted across window destruction and reconstruction, i.e. when
32 // switching to and from fullscreen mode.
33 // We don't save shadow, transparency mode or background color because it's not
34 // worth the hassle - Gecko will reset them anyway as soon as the window is
35 // resized.
36 @interface BaseWindow : NSWindow {
37 // Data Storage
38 NSMutableDictionary* mState;
39 BOOL mDrawsIntoWindowFrame;
41 // Invalidation disabling
42 BOOL mDisabledNeedsDisplay;
44 NSTrackingArea* mTrackingArea;
46 NSRect mDirtyRect;
48 BOOL mBeingShown;
49 BOOL mDrawTitle;
50 BOOL mIsAnimationSuppressed;
52 nsTouchBar* mTouchBar;
55 - (void)importState:(NSDictionary*)aState;
56 - (NSMutableDictionary*)exportState;
57 - (void)setDrawsContentsIntoWindowFrame:(BOOL)aState;
58 - (BOOL)drawsContentsIntoWindowFrame;
60 // These two methods are like contentRectForFrameRect and
61 // frameRectForContentRect, but they deal with the rect of the window's "main
62 // ChildView" instead of the rect of the window's content view. The two are
63 // sometimes sized differently: The window's content view always covers the
64 // entire window, whereas the ChildView only covers the full window when
65 // drawsContentsIntoWindowFrame is YES. When drawsContentsIntoWindowFrame is NO,
66 // there's a titlebar-sized gap above the ChildView within the content view.
67 - (NSRect)childViewRectForFrameRect:(NSRect)aFrameRect;
68 - (NSRect)frameRectForChildViewRect:(NSRect)aChildViewRect;
70 - (void)mouseEntered:(NSEvent*)aEvent;
71 - (void)mouseExited:(NSEvent*)aEvent;
72 - (void)mouseMoved:(NSEvent*)aEvent;
73 - (void)updateTrackingArea;
74 - (NSView*)trackingAreaView;
76 - (void)setBeingShown:(BOOL)aValue;
77 - (BOOL)isBeingShown;
78 - (BOOL)isVisibleOrBeingShown;
80 - (void)setIsAnimationSuppressed:(BOOL)aValue;
81 - (BOOL)isAnimationSuppressed;
83 // Returns an autoreleased NSArray containing the NSViews that we consider the
84 // "contents" of this window. All views in the returned array are subviews of
85 // this window's content view. However, the array may not include all of the
86 // content view's subviews; concretely, the ToolbarWindow implementation will
87 // exclude its MOZTitlebarView from the array that is returned here.
88 // In the vast majority of cases, the array will only have a single element:
89 // this window's mainChildView.
90 - (NSArray<NSView*>*)contentViewContents;
92 - (ChildView*)mainChildView;
94 - (void)setWantsTitleDrawn:(BOOL)aDrawTitle;
95 - (BOOL)wantsTitleDrawn;
97 - (void)disableSetNeedsDisplay;
98 - (void)enableSetNeedsDisplay;
100 - (NSRect)getAndResetNativeDirtyRect;
102 - (void)setEffectViewWrapperForStyle:(mozilla::WindowShadow)aStyle;
103 @property(nonatomic) mozilla::WindowShadow shadowStyle;
105 - (void)releaseJSObjects;
107 @end
109 @interface NSWindow (Undocumented)
110 - (NSDictionary*)shadowParameters;
112 // Present in the same form on OS X since at least OS X 10.5.
113 - (NSRect)contentRectForFrameRect:(NSRect)windowFrame
114 styleMask:(NSUInteger)windowStyle;
115 - (NSRect)frameRectForContentRect:(NSRect)windowContentRect
116 styleMask:(NSUInteger)windowStyle;
118 // Present since at least OS X 10.5. The OS calls this method on NSWindow
119 // (and its subclasses) to find out which NSFrameView subclass to instantiate
120 // to create its "frame view".
121 + (Class)frameViewClassForStyleMask:(NSUInteger)styleMask;
123 @end
125 @interface PopupWindow : BaseWindow {
126 @private
127 BOOL mIsContextMenu;
130 - (id)initWithContentRect:(NSRect)contentRect
131 styleMask:(NSUInteger)styleMask
132 backing:(NSBackingStoreType)bufferingType
133 defer:(BOOL)deferCreation;
134 - (BOOL)isContextMenu;
135 - (void)setIsContextMenu:(BOOL)flag;
136 - (BOOL)canBecomeMainWindow;
138 @end
140 @interface BorderlessWindow : BaseWindow {
143 - (BOOL)canBecomeKeyWindow;
144 - (BOOL)canBecomeMainWindow;
146 @end
148 @interface WindowDelegate : NSObject <NSWindowDelegate> {
149 nsCocoaWindow* mGeckoWindow; // [WEAK] (we are owned by the window)
150 // Used to avoid duplication when we send NS_ACTIVATE and
151 // NS_DEACTIVATE to Gecko for toplevel widgets. Starts out
152 // false.
153 bool mToplevelActiveState;
154 BOOL mHasEverBeenZoomed;
156 + (void)paintMenubarForWindow:(NSWindow*)aWindow;
157 - (id)initWithGeckoWindow:(nsCocoaWindow*)geckoWind;
158 - (void)windowDidResize:(NSNotification*)aNotification;
159 - (nsCocoaWindow*)geckoWidget;
160 - (bool)toplevelActiveState;
161 - (void)sendToplevelActivateEvents;
162 - (void)sendToplevelDeactivateEvents;
163 @end
165 @interface FullscreenTitlebarTracker : NSTitlebarAccessoryViewController
166 - (FullscreenTitlebarTracker*)init;
167 @end
169 // NSWindow subclass for handling windows with toolbars.
170 @interface ToolbarWindow : BaseWindow {
171 // mFullscreenTitlebarTracker attaches an invisible rectangle to the system
172 // title bar. This allows us to detect when the title bar is showing in
173 // fullscreen.
174 FullscreenTitlebarTracker* mFullscreenTitlebarTracker;
176 CGFloat mMenuBarHeight;
177 NSRect mWindowButtonsRect;
179 - (void)setDrawsContentsIntoWindowFrame:(BOOL)aState;
180 - (void)placeWindowButtons:(NSRect)aRect;
181 - (NSRect)windowButtonsRect;
182 - (void)windowMainStateChanged;
183 @end
185 class nsCocoaWindow final : public nsBaseWidget {
186 private:
187 typedef nsBaseWidget Inherited;
189 public:
190 nsCocoaWindow();
192 [[nodiscard]] nsresult Create(nsIWidget* aParent,
193 nsNativeWidget aNativeParent,
194 const DesktopIntRect& aRect,
195 InitData* = nullptr) override;
197 [[nodiscard]] nsresult Create(nsIWidget* aParent,
198 nsNativeWidget aNativeParent,
199 const LayoutDeviceIntRect& aRect,
200 InitData* = nullptr) override;
202 void Destroy() override;
204 void Show(bool aState) override;
205 bool NeedsRecreateToReshow() override;
207 void Enable(bool aState) override;
208 bool IsEnabled() const override;
209 void SetModal(bool aState) override;
210 bool IsRunningAppModal() override;
211 bool IsVisible() const override;
212 void SetFocus(Raise, mozilla::dom::CallerType aCallerType) override;
213 LayoutDeviceIntPoint WidgetToScreenOffset() override;
214 LayoutDeviceIntPoint GetClientOffset() override;
215 LayoutDeviceIntMargin ClientToWindowMargin() override;
217 void* GetNativeData(uint32_t aDataType) override;
219 void ConstrainPosition(DesktopIntPoint&) override;
220 void SetSizeConstraints(const SizeConstraints& aConstraints) override;
221 void Move(double aX, double aY) override;
222 nsSizeMode SizeMode() override { return mSizeMode; }
223 void SetSizeMode(nsSizeMode aMode) override;
224 void GetWorkspaceID(nsAString& workspaceID) override;
225 void MoveToWorkspace(const nsAString& workspaceID) override;
226 void SuppressAnimation(bool aSuppress) override;
227 void HideWindowChrome(bool aShouldHide) override;
229 bool PrepareForFullscreenTransition(nsISupports** aData) override;
230 void PerformFullscreenTransition(FullscreenTransitionStage aStage,
231 uint16_t aDuration, nsISupports* aData,
232 nsIRunnable* aCallback) override;
233 void CleanupFullscreenTransition() override;
234 nsresult MakeFullScreen(bool aFullScreen) final;
235 nsresult MakeFullScreenWithNativeTransition(bool aFullScreen) final;
236 NSAnimation* FullscreenTransitionAnimation() const {
237 return mFullscreenTransitionAnimation;
239 void ReleaseFullscreenTransitionAnimation() {
240 MOZ_ASSERT(mFullscreenTransitionAnimation,
241 "Should only be called when there is animation");
242 [mFullscreenTransitionAnimation release];
243 mFullscreenTransitionAnimation = nil;
246 void Resize(double aWidth, double aHeight, bool aRepaint) override;
247 void Resize(double aX, double aY, double aWidth, double aHeight,
248 bool aRepaint) override;
249 NSRect GetClientCocoaRect();
250 LayoutDeviceIntRect GetClientBounds() override;
251 LayoutDeviceIntRect GetScreenBounds() override;
252 void ReportMoveEvent();
253 void ReportSizeEvent();
254 void SetCursor(const Cursor&) override;
256 CGFloat BackingScaleFactor();
257 void BackingScaleFactorChanged();
258 double GetDefaultScaleInternal() override;
259 int32_t RoundsWidgetCoordinatesTo() override;
261 mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() final {
262 return mozilla::DesktopToLayoutDeviceScale(BackingScaleFactor());
265 nsresult SetTitle(const nsAString& aTitle) override;
267 void Invalidate(const LayoutDeviceIntRect& aRect) override;
268 WindowRenderer* GetWindowRenderer() override;
269 nsresult DispatchEvent(mozilla::WidgetGUIEvent* aEvent,
270 nsEventStatus& aStatus) override;
271 void CaptureRollupEvents(bool aDoCapture) override;
272 [[nodiscard]] nsresult GetAttention(int32_t aCycleCount) override;
273 bool HasPendingInputEvent() override;
274 TransparencyMode GetTransparencyMode() override;
275 void SetTransparencyMode(TransparencyMode aMode) override;
276 void SetWindowShadowStyle(mozilla::WindowShadow aStyle) override;
277 void SetWindowOpacity(float aOpacity) override;
278 void SetWindowTransform(const mozilla::gfx::Matrix& aTransform) override;
279 void SetInputRegion(const InputRegion&) override;
280 void SetColorScheme(const mozilla::Maybe<mozilla::ColorScheme>&) override;
281 void SetShowsToolbarButton(bool aShow) override;
282 void SetSupportsNativeFullscreen(bool aShow) override;
283 void SetWindowAnimationType(WindowAnimationType aType) override;
284 void SetDrawsTitle(bool aDrawTitle) override;
285 nsresult SetNonClientMargins(const LayoutDeviceIntMargin&) override;
286 void SetDrawsInTitlebar(bool aState);
287 void UpdateThemeGeometries(
288 const nsTArray<ThemeGeometry>& aThemeGeometries) override;
289 nsresult SynthesizeNativeMouseEvent(LayoutDeviceIntPoint aPoint,
290 NativeMouseMessage aNativeMessage,
291 mozilla::MouseButton aButton,
292 nsIWidget::Modifiers aModifierFlags,
293 nsIObserver* aObserver) override;
294 nsresult SynthesizeNativeMouseScrollEvent(
295 LayoutDeviceIntPoint aPoint, uint32_t aNativeMessage, double aDeltaX,
296 double aDeltaY, double aDeltaZ, uint32_t aModifierFlags,
297 uint32_t aAdditionalFlags, nsIObserver* aObserver) override;
298 void LockAspectRatio(bool aShouldLock) override;
300 void DispatchSizeModeEvent();
301 void DispatchOcclusionEvent();
303 // be notified that a some form of drag event needs to go into Gecko
304 bool DragEvent(unsigned int aMessage, mozilla::gfx::Point aMouseGlobal,
305 UInt16 aKeyModifiers);
307 bool HasModalDescendants() const { return mNumModalDescendants > 0; }
308 bool IsModal() const { return mModal; }
310 NSWindow* GetCocoaWindow() { return mWindow; }
312 void SetMenuBar(RefPtr<nsMenuBarX>&& aMenuBar);
313 nsMenuBarX* GetMenuBar();
315 void SetInputContext(const InputContext& aContext,
316 const InputContextAction& aAction) override;
317 InputContext GetInputContext() override { return mInputContext; }
318 MOZ_CAN_RUN_SCRIPT bool GetEditCommands(
319 mozilla::NativeKeyBindingsType aType,
320 const mozilla::WidgetKeyboardEvent& aEvent,
321 nsTArray<mozilla::CommandInt>& aCommands) override;
323 void SetPopupWindowLevel();
325 bool InFullScreenMode() const { return mInFullScreenMode; }
327 void PauseOrResumeCompositor(bool aPause) override;
329 bool AsyncPanZoomEnabled() const override;
331 bool StartAsyncAutoscroll(const ScreenPoint& aAnchorLocation,
332 const ScrollableLayerGuid& aGuid) override;
333 void StopAsyncAutoscroll(const ScrollableLayerGuid& aGuid) override;
335 // Class method versions of NSWindow/Delegate callbacks which need to
336 // access object state.
337 void CocoaWindowWillEnterFullscreen(bool aFullscreen);
338 void CocoaWindowDidEnterFullscreen(bool aFullscreen);
339 void CocoaWindowDidResize();
340 void CocoaSendToplevelActivateEvents();
341 void CocoaSendToplevelDeactivateEvents();
343 enum class TransitionType {
344 Windowed,
345 Fullscreen,
346 EmulatedFullscreen,
347 Miniaturize,
348 Deminiaturize,
349 Zoom,
351 void FinishCurrentTransitionIfMatching(const TransitionType& aTransition);
353 // Called when something has happened that might cause us to update our
354 // fullscreen state. Returns true if we updated state. We'll call this
355 // on window resize, and we'll call it when we enter or exit fullscreen,
356 // since fullscreen to-and-from zoomed windows won't necessarily trigger
357 // a resize.
358 bool HandleUpdateFullscreenOnResize();
360 protected:
361 virtual ~nsCocoaWindow();
363 nsresult CreateNativeWindow(const NSRect& aRect, BorderStyle aBorderStyle,
364 bool aRectIsFrameRect, bool aIsPrivateBrowsing);
365 nsresult CreatePopupContentView(const LayoutDeviceIntRect& aRect, InitData*);
366 void DestroyNativeWindow();
367 void UpdateBounds();
368 int32_t GetWorkspaceID();
369 void SendSetZLevelEvent();
371 void DoResize(double aX, double aY, double aWidth, double aHeight,
372 bool aRepaint, bool aConstrainToCurrentScreen);
374 void UpdateFullscreenState(bool aFullScreen, bool aNativeMode);
375 nsresult DoMakeFullScreen(bool aFullScreen, bool aUseSystemTransition);
377 already_AddRefed<nsIWidget> AllocateChildPopupWidget() override {
378 return nsIWidget::CreateTopLevelWindow();
381 nsIWidget* mParent; // if we're a popup, this is our parent [WEAK]
382 nsIWidget* mAncestorLink; // link to traverse ancestors [WEAK]
383 BaseWindow* mWindow; // our cocoa window [STRONG]
384 WindowDelegate*
385 mDelegate; // our delegate for processing window msgs [STRONG]
386 RefPtr<nsMenuBarX> mMenuBar;
387 nsChildView*
388 mPopupContentView; // if this is a popup, this is its content widget
389 // if this is a toplevel window, and there is any ongoing fullscreen
390 // transition, it is the animation object.
391 NSAnimation* mFullscreenTransitionAnimation;
392 mozilla::WindowShadow mShadowStyle;
394 CGFloat mBackingScaleFactor;
395 CGFloat mAspectRatio;
397 WindowAnimationType mAnimationType;
399 bool mWindowMadeHere; // true if we created the window, false for embedding
400 nsSizeMode mSizeMode;
401 bool mInFullScreenMode;
402 // Whether we are currently using native fullscreen. It could be false because
403 // we are in the emulated fullscreen where we do not use the native
404 // fullscreen.
405 bool mInNativeFullScreenMode;
407 mozilla::Maybe<TransitionType> mTransitionCurrent;
408 std::queue<TransitionType> mTransitionsPending;
410 // Sometimes we add a transition that wasn't requested by a caller. We do this
411 // to manage transitions between states that otherwise would be rejected by
412 // Cocoa. When we do this, it's useful to know when we are handling an added
413 // transition because we don't want to send size mode events when they
414 // execute.
415 bool mIsTransitionCurrentAdded = false;
417 // Whether we are treating the next resize as the start of a fullscreen
418 // transition. If we are, which direction are we going: Fullscreen or
419 // Windowed.
420 mozilla::Maybe<TransitionType> mUpdateFullscreenOnResize;
422 bool IsInTransition() { return mTransitionCurrent.isSome(); }
423 void QueueTransition(const TransitionType& aTransition);
424 void ProcessTransitions();
426 // Call this to stop all transition processing, which is useful during
427 // window closing and shutdown.
428 void CancelAllTransitions();
430 bool mInProcessTransitions = false;
432 // While running an emulated fullscreen transition, we want to suppress
433 // sending size mode events due to window resizing. We fix it up at the end
434 // when the transition is complete.
435 bool mSuppressSizeModeEvents = false;
437 // Ignore occlusion events caused by displaying the temporary fullscreen
438 // window during the fullscreen transition animation because only focused
439 // contexts are permitted to enter DOM fullscreen.
440 int mIgnoreOcclusionCount;
442 // Set to true when a native fullscreen transition is initiated -- either to
443 // or from fullscreen -- and set to false when it is complete. During this
444 // period, we presume the window is visible, which prevents us from sending
445 // unnecessary OcclusionStateChanged events.
446 bool mHasStartedNativeFullscreen;
448 bool mModal = false;
449 bool mIsAnimationSuppressed = false;
451 bool mInReportMoveEvent = false; // true if in a call to ReportMoveEvent().
452 bool mInResize = false; // true if in a call to DoResize().
453 bool mWindowTransformIsIdentity = true;
454 bool mAlwaysOnTop = false;
455 bool mAspectRatioLocked = false;
456 bool mIsAlert = false; // True if this is an non-native alert window.
457 bool mWasShown = false;
459 int32_t mNumModalDescendants = 0;
460 InputContext mInputContext;
461 NSWindowAnimationBehavior mWindowAnimationBehavior;
463 private:
464 // This is class state for tracking which nsCocoaWindow, if any, is in the
465 // middle of a native fullscreen transition.
466 static nsCocoaWindow* sWindowInNativeTransition;
468 // This function returns true if the caller has been able to claim the sole
469 // permission to start a native transition. It must be followed by a call
470 // to EndOurNativeTransition() when the native transition is complete.
471 bool CanStartNativeTransition();
472 void EndOurNativeTransition();
475 #endif // nsCocoaWindow_h_