Bug 1751217 Part 3: Make HDR-capable macOS screens report 30 pixelDepth. r=mstange
[gecko.git] / widget / gtk / nsWindow.h
blob44ab67a6290a6cf3e3555d24b67fa28e20be8696
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:expandtab:shiftwidth=4:tabstop=4:
3 */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #ifndef __nsWindow_h__
9 #define __nsWindow_h__
11 #include <gdk/gdk.h>
12 #include <gtk/gtk.h>
14 #include "CompositorWidget.h"
15 #include "MozContainer.h"
16 #include "mozilla/EventForwards.h"
17 #include "mozilla/Maybe.h"
18 #include "mozilla/RefPtr.h"
19 #include "mozilla/TouchEvents.h"
20 #include "mozilla/UniquePtr.h"
21 #include "mozilla/widget/WindowSurface.h"
22 #include "mozilla/widget/WindowSurfaceProvider.h"
23 #include "nsBaseWidget.h"
24 #include "nsGkAtoms.h"
25 #include "nsIDragService.h"
26 #include "nsRefPtrHashtable.h"
27 #include "IMContextWrapper.h"
29 #ifdef ACCESSIBILITY
30 # include "mozilla/a11y/LocalAccessible.h"
31 #endif
33 #ifdef MOZ_X11
34 # include <gdk/gdkx.h>
35 # include "X11UndefineNone.h"
36 #endif
37 #ifdef MOZ_WAYLAND
38 # include <gdk/gdkwayland.h>
39 # include "base/thread.h"
40 # include "WaylandVsyncSource.h"
41 # include "nsClipboardWayland.h"
42 #endif
44 #ifdef MOZ_LOGGING
46 # include "mozilla/Logging.h"
47 # include "nsTArray.h"
48 # include "Units.h"
50 extern mozilla::LazyLogModule gWidgetLog;
51 extern mozilla::LazyLogModule gWidgetDragLog;
52 extern mozilla::LazyLogModule gWidgetPopupLog;
53 extern mozilla::LazyLogModule gWidgetVsync;
55 # define LOG(str, ...) \
56 MOZ_LOG(IsPopup() ? gWidgetPopupLog : gWidgetLog, \
57 mozilla::LogLevel::Debug, \
58 ("%s: " str, GetDebugTag().get(), ##__VA_ARGS__))
59 # define LOGW(...) MOZ_LOG(gWidgetLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
60 # define LOGDRAG(...) \
61 MOZ_LOG(gWidgetDragLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
62 # define LOG_POPUP(...) \
63 MOZ_LOG(gWidgetPopupLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
64 # define LOG_VSYNC(...) \
65 MOZ_LOG(gWidgetVsync, mozilla::LogLevel::Debug, (__VA_ARGS__))
66 # define LOG_ENABLED() \
67 (MOZ_LOG_TEST(gWidgetPopupLog, mozilla::LogLevel::Debug) || \
68 MOZ_LOG_TEST(gWidgetLog, mozilla::LogLevel::Debug))
70 #else
72 # define LOG(...)
73 # define LOGW(...)
74 # define LOGDRAG(...)
75 # define LOG_POPUP(...)
76 # define LOG_ENABLED() false
78 #endif /* MOZ_LOGGING */
80 class gfxPattern;
81 class nsIFrame;
82 #if !GTK_CHECK_VERSION(3, 18, 0)
83 struct _GdkEventTouchpadPinch;
84 typedef struct _GdkEventTouchpadPinch GdkEventTouchpadPinch;
85 #endif
87 #if !GTK_CHECK_VERSION(3, 22, 0)
88 typedef enum {
89 GDK_ANCHOR_FLIP_X = 1 << 0,
90 GDK_ANCHOR_FLIP_Y = 1 << 1,
91 GDK_ANCHOR_SLIDE_X = 1 << 2,
92 GDK_ANCHOR_SLIDE_Y = 1 << 3,
93 GDK_ANCHOR_RESIZE_X = 1 << 4,
94 GDK_ANCHOR_RESIZE_Y = 1 << 5,
95 GDK_ANCHOR_FLIP = GDK_ANCHOR_FLIP_X | GDK_ANCHOR_FLIP_Y,
96 GDK_ANCHOR_SLIDE = GDK_ANCHOR_SLIDE_X | GDK_ANCHOR_SLIDE_Y,
97 GDK_ANCHOR_RESIZE = GDK_ANCHOR_RESIZE_X | GDK_ANCHOR_RESIZE_Y
98 } GdkAnchorHints;
99 #endif
101 namespace mozilla {
102 enum class NativeKeyBindingsType : uint8_t;
104 class TimeStamp;
105 class CurrentX11TimeGetter;
106 } // namespace mozilla
108 class nsWindow final : public nsBaseWidget {
109 public:
110 typedef mozilla::gfx::DrawTarget DrawTarget;
111 typedef mozilla::WidgetEventTime WidgetEventTime;
112 typedef mozilla::WidgetKeyboardEvent WidgetKeyboardEvent;
113 typedef mozilla::widget::PlatformCompositorWidgetDelegate
114 PlatformCompositorWidgetDelegate;
116 nsWindow();
118 static void ReleaseGlobals();
120 NS_INLINE_DECL_REFCOUNTING_INHERITED(nsWindow, nsBaseWidget)
122 nsresult DispatchEvent(mozilla::WidgetGUIEvent* aEvent,
123 nsEventStatus& aStatus) override;
125 // called when we are destroyed
126 void OnDestroy() override;
128 // called to check and see if a widget's dimensions are sane
129 bool AreBoundsSane(void);
131 // nsIWidget
132 using nsBaseWidget::Create; // for Create signature not overridden here
133 [[nodiscard]] nsresult Create(nsIWidget* aParent,
134 nsNativeWidget aNativeParent,
135 const LayoutDeviceIntRect& aRect,
136 nsWidgetInitData* aInitData) override;
137 void Destroy() override;
138 nsIWidget* GetParent() override;
139 float GetDPI() override;
140 double GetDefaultScaleInternal() override;
141 mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() override;
142 mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScaleByScreen()
143 override;
144 void SetParent(nsIWidget* aNewParent) override;
145 void SetModal(bool aModal) override;
146 bool IsVisible() const override;
147 void ConstrainPosition(bool aAllowSlop, int32_t* aX, int32_t* aY) override;
148 void SetSizeConstraints(const SizeConstraints& aConstraints) override;
149 void LockAspectRatio(bool aShouldLock) override;
150 void Move(double aX, double aY) override;
151 void Show(bool aState) override;
152 void Resize(double aWidth, double aHeight, bool aRepaint) override;
153 void Resize(double aX, double aY, double aWidth, double aHeight,
154 bool aRepaint) override;
155 bool IsEnabled() const override;
157 void SetZIndex(int32_t aZIndex) override;
158 void SetSizeMode(nsSizeMode aMode) override;
159 void GetWorkspaceID(nsAString& workspaceID) override;
160 void MoveToWorkspace(const nsAString& workspaceID) override;
161 void Enable(bool aState) override;
162 void SetFocus(Raise, mozilla::dom::CallerType aCallerType) override;
163 LayoutDeviceIntRect GetScreenBounds() override;
164 LayoutDeviceIntRect GetClientBounds() override;
165 LayoutDeviceIntSize GetClientSize() override;
166 LayoutDeviceIntPoint GetClientOffset() override;
167 void SetCursor(const Cursor&) override;
168 void Invalidate(const LayoutDeviceIntRect& aRect) override;
169 void* GetNativeData(uint32_t aDataType) override;
170 nsresult SetTitle(const nsAString& aTitle) override;
171 void SetIcon(const nsAString& aIconSpec) override;
172 void SetWindowClass(const nsAString& xulWinType) override;
173 LayoutDeviceIntPoint WidgetToScreenOffset() override;
174 void CaptureMouse(bool aCapture) override;
175 void CaptureRollupEvents(nsIRollupListener* aListener,
176 bool aDoCapture) override;
177 [[nodiscard]] nsresult GetAttention(int32_t aCycleCount) override;
178 bool HasPendingInputEvent() override;
180 bool PrepareForFullscreenTransition(nsISupports** aData) override;
181 void PerformFullscreenTransition(FullscreenTransitionStage aStage,
182 uint16_t aDuration, nsISupports* aData,
183 nsIRunnable* aCallback) override;
184 already_AddRefed<nsIScreen> GetWidgetScreen() override;
185 nsresult MakeFullScreen(bool aFullScreen) override;
186 void HideWindowChrome(bool aShouldHide) override;
189 * GetLastUserInputTime returns a timestamp for the most recent user input
190 * event. This is intended for pointer grab requests (including drags).
192 static guint32 GetLastUserInputTime();
194 // utility method, -1 if no change should be made, otherwise returns a
195 // value that can be passed to gdk_window_set_decorations
196 gint ConvertBorderStyles(nsBorderStyle aStyle);
198 GdkRectangle DevicePixelsToGdkRectRoundOut(LayoutDeviceIntRect aRect);
200 mozilla::widget::IMContextWrapper* GetIMContext() const { return mIMContext; }
202 bool DispatchCommandEvent(nsAtom* aCommand);
203 bool DispatchContentCommandEvent(mozilla::EventMessage aMsg);
205 // event callbacks
206 gboolean OnExposeEvent(cairo_t* cr);
207 gboolean OnConfigureEvent(GtkWidget* aWidget, GdkEventConfigure* aEvent);
208 void OnMap();
209 void OnUnrealize();
210 void OnSizeAllocate(GtkAllocation* aAllocation);
211 void OnDeleteEvent();
212 void OnEnterNotifyEvent(GdkEventCrossing* aEvent);
213 void OnLeaveNotifyEvent(GdkEventCrossing* aEvent);
214 void OnMotionNotifyEvent(GdkEventMotion* aEvent);
215 void OnButtonPressEvent(GdkEventButton* aEvent);
216 void OnButtonReleaseEvent(GdkEventButton* aEvent);
217 void OnContainerFocusInEvent(GdkEventFocus* aEvent);
218 void OnContainerFocusOutEvent(GdkEventFocus* aEvent);
219 gboolean OnKeyPressEvent(GdkEventKey* aEvent);
220 gboolean OnKeyReleaseEvent(GdkEventKey* aEvent);
222 void OnScrollEvent(GdkEventScroll* aEvent);
224 void OnWindowStateEvent(GtkWidget* aWidget, GdkEventWindowState* aEvent);
225 void OnDragDataReceivedEvent(GtkWidget* aWidget, GdkDragContext* aDragContext,
226 gint aX, gint aY,
227 GtkSelectionData* aSelectionData, guint aInfo,
228 guint aTime, gpointer aData);
229 gboolean OnPropertyNotifyEvent(GtkWidget* aWidget, GdkEventProperty* aEvent);
230 gboolean OnTouchEvent(GdkEventTouch* aEvent);
231 gboolean OnTouchpadPinchEvent(GdkEventTouchpadPinch* aEvent);
233 void UpdateTopLevelOpaqueRegion();
235 already_AddRefed<mozilla::gfx::DrawTarget> StartRemoteDrawingInRegion(
236 const LayoutDeviceIntRegion& aInvalidRegion,
237 mozilla::layers::BufferMode* aBufferMode) override;
238 void EndRemoteDrawingInRegion(
239 mozilla::gfx::DrawTarget* aDrawTarget,
240 const LayoutDeviceIntRegion& aInvalidRegion) override;
242 void SetProgress(unsigned long progressPercent);
244 RefPtr<mozilla::gfx::VsyncSource> GetVsyncSource() override;
245 bool SynchronouslyRepaintOnResize() override;
247 void OnDPIChanged(void);
248 void OnCheckResize(void);
249 void OnCompositedChanged(void);
250 void OnScaleChanged();
251 void DispatchResized();
253 static guint32 sLastButtonPressTime;
255 [[nodiscard]] nsresult BeginResizeDrag(mozilla::WidgetGUIEvent* aEvent,
256 int32_t aHorizontal,
257 int32_t aVertical) override;
259 MozContainer* GetMozContainer() { return mContainer; }
260 LayoutDeviceIntSize GetMozContainerSize();
261 // GetMozContainerWidget returns the MozContainer even for undestroyed
262 // descendant windows
263 GtkWidget* GetMozContainerWidget();
264 GdkWindow* GetGdkWindow() { return mGdkWindow; };
265 GdkWindow* GetToplevelGdkWindow();
266 GtkWidget* GetGtkWidget() { return mShell; }
267 nsIFrame* GetFrame() const;
268 bool IsDestroyed() const { return mIsDestroyed; }
269 bool IsPopup() const;
270 bool IsWaylandPopup() const;
271 bool IsPIPWindow() const { return mIsPIPWindow; };
272 bool IsDragPopup() { return mIsDragPopup; };
274 nsAutoCString GetDebugTag() const;
276 void DispatchDragEvent(mozilla::EventMessage aMsg,
277 const LayoutDeviceIntPoint& aRefPoint, guint aTime);
278 static void UpdateDragStatus(GdkDragContext* aDragContext,
279 nsIDragService* aDragService);
281 WidgetEventTime GetWidgetEventTime(guint32 aEventTime);
282 mozilla::TimeStamp GetEventTimeStamp(guint32 aEventTime);
283 mozilla::CurrentX11TimeGetter* GetCurrentTimeGetter();
285 void SetInputContext(const InputContext& aContext,
286 const InputContextAction& aAction) override;
287 InputContext GetInputContext() override;
288 TextEventDispatcherListener* GetNativeTextEventDispatcherListener() override;
289 MOZ_CAN_RUN_SCRIPT bool GetEditCommands(
290 mozilla::NativeKeyBindingsType aType,
291 const mozilla::WidgetKeyboardEvent& aEvent,
292 nsTArray<mozilla::CommandInt>& aCommands) override;
294 // These methods are for toplevel windows only.
295 void ResizeTransparencyBitmap();
296 void ApplyTransparencyBitmap();
297 void ClearTransparencyBitmap();
299 void SetTransparencyMode(nsTransparencyMode aMode) override;
300 nsTransparencyMode GetTransparencyMode() override;
301 void SetWindowMouseTransparent(bool aIsTransparent) override;
302 nsresult UpdateTranslucentWindowAlphaInternal(const nsIntRect& aRect,
303 uint8_t* aAlphas,
304 int32_t aStride);
305 void ReparentNativeWidget(nsIWidget* aNewParent) override;
307 void UpdateTitlebarTransparencyBitmap();
309 nsresult SynthesizeNativeMouseEvent(LayoutDeviceIntPoint aPoint,
310 NativeMouseMessage aNativeMessage,
311 mozilla::MouseButton aButton,
312 nsIWidget::Modifiers aModifierFlags,
313 nsIObserver* aObserver) override;
315 nsresult SynthesizeNativeMouseMove(LayoutDeviceIntPoint aPoint,
316 nsIObserver* aObserver) override {
317 return SynthesizeNativeMouseEvent(
318 aPoint, NativeMouseMessage::Move, mozilla::MouseButton::eNotPressed,
319 nsIWidget::Modifiers::NO_MODIFIERS, aObserver);
322 nsresult SynthesizeNativeMouseScrollEvent(
323 LayoutDeviceIntPoint aPoint, uint32_t aNativeMessage, double aDeltaX,
324 double aDeltaY, double aDeltaZ, uint32_t aModifierFlags,
325 uint32_t aAdditionalFlags, nsIObserver* aObserver) override;
327 nsresult SynthesizeNativeTouchPoint(uint32_t aPointerId,
328 TouchPointerState aPointerState,
329 LayoutDeviceIntPoint aPoint,
330 double aPointerPressure,
331 uint32_t aPointerOrientation,
332 nsIObserver* aObserver) override;
334 nsresult SynthesizeNativeTouchPadPinch(TouchpadGesturePhase aEventPhase,
335 float aScale,
336 LayoutDeviceIntPoint aPoint,
337 int32_t aModifierFlags) override;
339 void GetCompositorWidgetInitData(
340 mozilla::widget::CompositorWidgetInitData* aInitData) override;
342 nsresult SetNonClientMargins(LayoutDeviceIntMargin& aMargins) override;
343 void SetDrawsInTitlebar(bool aState) override;
344 mozilla::LayoutDeviceIntCoord GetTitlebarRadius();
345 LayoutDeviceIntRect GetTitlebarRect();
346 void UpdateWindowDraggingRegion(
347 const LayoutDeviceIntRegion& aRegion) override;
349 // HiDPI scale conversion
350 gint GdkCeiledScaleFactor();
351 bool UseFractionalScale();
352 double FractionalScaleFactor();
354 // To GDK
355 gint DevicePixelsToGdkCoordRoundUp(int pixels);
356 gint DevicePixelsToGdkCoordRoundDown(int pixels);
357 GdkPoint DevicePixelsToGdkPointRoundDown(LayoutDeviceIntPoint point);
358 GdkRectangle DevicePixelsToGdkSizeRoundUp(LayoutDeviceIntSize pixelSize);
360 // From GDK
361 int GdkCoordToDevicePixels(gint coord);
362 LayoutDeviceIntPoint GdkPointToDevicePixels(GdkPoint point);
363 LayoutDeviceIntPoint GdkEventCoordsToDevicePixels(gdouble x, gdouble y);
364 LayoutDeviceIntRect GdkRectToDevicePixels(GdkRectangle rect);
366 bool WidgetTypeSupportsAcceleration() override;
368 nsresult SetSystemFont(const nsCString& aFontName) override;
369 nsresult GetSystemFont(nsCString& aFontName) override;
371 typedef enum {
372 GTK_DECORATION_SYSTEM, // CSD including shadows
373 GTK_DECORATION_CLIENT, // CSD without shadows
374 GTK_DECORATION_NONE, // WM does not support CSD at all
375 } GtkWindowDecoration;
377 * Get the support of Client Side Decoration by checking
378 * the XDG_CURRENT_DESKTOP environment variable.
380 static GtkWindowDecoration GetSystemGtkWindowDecoration();
382 static bool GetTopLevelWindowActiveState(nsIFrame* aFrame);
383 static bool TitlebarUseShapeMask();
384 bool IsRemoteContent() { return HasRemoteContent(); }
385 void NativeMoveResizeWaylandPopupCallback(const GdkRectangle* aFinalSize,
386 bool aFlippedX, bool aFlippedY);
387 static bool IsToplevelWindowTransparent();
389 static nsWindow* GetFocusedWindow();
391 #ifdef MOZ_WAYLAND
392 // Use xdg-activation protocol to transfer focus from gFocusWindow to aWindow.
393 static void RequestFocusWaylandWindow(RefPtr<nsWindow> aWindow);
394 void FocusWaylandWindow(const char* aTokenID);
396 bool GetCSDDecorationOffset(int* aDx, int* aDy);
397 void SetEGLNativeWindowSize(const LayoutDeviceIntSize& aEGLWindowSize);
398 void WaylandDragWorkaround(GdkEventButton* aEvent);
400 wl_display* GetWaylandDisplay();
401 void CreateCompositorVsyncDispatcher() override;
402 LayoutDeviceIntPoint GetNativePointerLockCenter() {
403 return mNativePointerLockCenter;
405 void SetNativePointerLockCenter(
406 const LayoutDeviceIntPoint& aLockCenter) override;
407 void LockNativePointer() override;
408 void UnlockNativePointer() override;
409 LayoutDeviceIntRect GetMoveToRectPopupRect() const override {
410 return mMoveToRectPopupRect;
412 void MoveToRectPopupRectClear() override {
413 mMoveToRectPopupRect = LayoutDeviceIntRect();
415 #endif
417 typedef enum {
418 // WebRender compositor is enabled
419 COMPOSITOR_ENABLED,
420 // WebRender compositor is paused after window creation.
421 COMPOSITOR_PAUSED_INITIALLY,
422 // WebRender compositor is paused because GtkWindow is hidden,
423 // we can't draw into GL context.
424 COMPOSITOR_PAUSED_MISSING_WINDOW,
425 // WebRender compositor is paused as we're repainting whole window and
426 // we're waiting for content process to update page content.
427 COMPOSITOR_PAUSED_FLICKERING
428 } WindowCompositorState;
430 // Pause compositor to avoid rendering artifacts from content process.
431 void ResumeCompositor();
432 void ResumeCompositorFromCompositorThread();
433 void PauseCompositor();
434 bool IsWaitingForCompositorResume();
436 protected:
437 virtual ~nsWindow();
439 // event handling code
440 void DispatchActivateEvent(void);
441 void DispatchDeactivateEvent(void);
442 void MaybeDispatchResized();
444 void RegisterTouchWindow() override;
445 bool CompositorInitiallyPaused() override {
446 return mCompositorState == COMPOSITOR_PAUSED_INITIALLY;
448 nsCOMPtr<nsIWidget> mParent;
449 nsPopupType mPopupHint{};
450 int mWindowScaleFactor = 1;
452 void UpdateAlpha(mozilla::gfx::SourceSurface* aSourceSurface,
453 nsIntRect aBoundsRect);
455 void NativeMoveResize(bool aMoved, bool aResized);
457 void NativeShow(bool aAction);
458 void SetHasMappedToplevel(bool aState);
459 LayoutDeviceIntSize GetSafeWindowSize(LayoutDeviceIntSize aSize);
461 void EnsureGrabs(void);
462 void GrabPointer(guint32 aTime);
463 void ReleaseGrabs(void);
465 void UpdateClientOffsetFromFrameExtents();
466 void UpdateClientOffsetFromCSDWindow();
468 void DispatchContextMenuEventFromMouseEvent(uint16_t domButton,
469 GdkEventButton* aEvent);
471 void EnableRenderingToWindow();
472 void DisableRenderingToWindow();
473 void ResumeCompositorHiddenWindow();
474 void PauseCompositorHiddenWindow();
475 void WaylandStartVsync();
476 void WaylandStopVsync();
477 void DestroyChildWindows();
478 GtkWidget* GetToplevelWidget();
479 nsWindow* GetContainerWindow();
480 Window GetX11Window();
481 bool GetShapedState();
482 void EnsureGdkWindow();
483 void SetUrgencyHint(GtkWidget* top_window, bool state);
484 void SetDefaultIcon(void);
485 void SetWindowDecoration(nsBorderStyle aStyle);
486 void InitButtonEvent(mozilla::WidgetMouseEvent& aEvent,
487 GdkEventButton* aGdkEvent);
488 bool CheckForRollup(gdouble aMouseX, gdouble aMouseY, bool aIsWheel,
489 bool aAlwaysRollup);
490 void CheckForRollupDuringGrab() { CheckForRollup(0, 0, false, true); }
492 bool GetDragInfo(mozilla::WidgetMouseEvent* aMouseEvent, GdkWindow** aWindow,
493 gint* aButton, gint* aRootX, gint* aRootY);
494 nsIWidgetListener* GetListener();
496 nsWindow* GetTransientForWindowIfPopup();
497 bool IsHandlingTouchSequence(GdkEventSequence* aSequence);
499 void ResizeInt(int aX, int aY, int aWidth, int aHeight, bool aMove);
500 void NativeMoveResizeWaylandPopup(bool aMove, bool aResize);
502 // Returns true if the given point (in device pixels) is within a resizer
503 // region of the window. Only used when drawing decorations client side.
504 bool CheckResizerEdge(LayoutDeviceIntPoint aPoint, GdkWindowEdge& aOutEdge);
506 GtkTextDirection GetTextDirection();
508 void AddCSDDecorationSize(int* aWidth, int* aHeight);
510 nsCString mGtkWindowAppName;
511 nsCString mGtkWindowRoleName;
512 void RefreshWindowClass();
514 GtkWidget* mShell = nullptr;
515 MozContainer* mContainer = nullptr;
516 GdkWindow* mGdkWindow = nullptr;
517 PlatformCompositorWidgetDelegate* mCompositorWidgetDelegate = nullptr;
518 mozilla::Atomic<WindowCompositorState, mozilla::Relaxed> mCompositorState{
519 COMPOSITOR_ENABLED};
520 // This is used in COMPOSITOR_PAUSED_FLICKERING mode only to resume compositor
521 // in some reasonable time when page content is not updated.
522 int mCompositorPauseTimeoutID = 0;
524 nsSizeMode mSizeState = nsSizeMode_Normal;
525 float mAspectRatio = 0.0f;
526 float mAspectRatioSaved = 0.0f;
527 nsIntPoint mClientOffset;
529 // This field omits duplicate scroll events caused by GNOME bug 726878.
530 guint32 mLastScrollEventTime = GDK_CURRENT_TIME;
531 mozilla::ScreenCoord mLastPinchEventSpan;
533 // for touch event handling
534 nsRefPtrHashtable<nsPtrHashKey<GdkEventSequence>, mozilla::dom::Touch>
535 mTouches;
537 // Upper bound on pending ConfigureNotify events to be dispatched to the
538 // window. See bug 1225044.
539 unsigned int mPendingConfigures = 0;
541 // Window titlebar rendering mode, GTK_DECORATION_NONE if it's disabled
542 // for this window.
543 GtkWindowDecoration mGtkWindowDecoration = GTK_DECORATION_NONE;
545 // Draggable titlebar region maintained by UpdateWindowDraggingRegion
546 LayoutDeviceIntRegion mDraggableRegion;
548 // The cursor cache
549 static GdkCursor* gsGtkCursorCache[eCursorCount];
551 // If true, draw our own window titlebar.
553 // Needs to be atomic because GetTitlebarRect() gets called from non-main
554 // threads.
556 // FIXME(emilio): GetTitlebarRect() reads other things that TSAN doesn't
557 // catch because mDrawInTitlebar is false on automation ~always. We should
558 // probably make GetTitlebarRect() simpler / properly thread-safe.
559 mozilla::Atomic<bool, mozilla::Relaxed> mDrawInTitlebar{false};
561 // Has this widget been destroyed yet?
562 bool mIsDestroyed : 1;
563 // Does WindowResized need to be called on listeners?
564 bool mNeedsDispatchResized : 1;
565 // mIsShown tracks requested visible status from browser perspective, i.e.
566 // if the window should be visible or now.
567 bool mIsShown : 1;
568 // mNeedsShow is set when browser requested to show this window but we failed
569 // to do so for some reason (wrong window size for instance).
570 // In such case we set mIsShown = true and mNeedsShow = true to indicate
571 // that the window is not actually visible but we report to browser that
572 // it is visible (mIsShown == true).
573 bool mNeedsShow : 1;
574 // This track real window visibility from OS perspective.
575 // It's set by OnMap/OnUnrealize which is based on Gtk events.
576 bool mIsMapped : 1;
577 // is this widget enabled?
578 bool mEnabled : 1;
579 // has the native window for this been created yet?
580 bool mCreated : 1;
581 // whether we handle touch event
582 bool mHandleTouchEvent : 1;
583 // true if this is a drag and drop feedback popup
584 bool mIsDragPopup : 1;
585 bool mWindowScaleFactorChanged : 1;
586 bool mCompositedScreen : 1;
587 bool mIsAccelerated : 1;
588 bool mWindowShouldStartDragging : 1;
589 bool mHasMappedToplevel : 1;
590 bool mRetryPointerGrab : 1;
591 bool mPanInProgress : 1;
592 // Use dedicated GdkWindow for mContainer
593 bool mDrawToContainer : 1;
594 // Draw titlebar with :backdrop css state (inactive/unfocused).
595 bool mTitlebarBackdropState : 1;
596 // It's PictureInPicture window.
597 bool mIsPIPWindow : 1;
598 // It's undecorated popup utility window, without resizers/titlebar,
599 // movable by mouse. Used on Wayland for popups without
600 // parent (for instance WebRTC sharing indicator, notifications).
601 bool mIsWaylandPanelWindow : 1;
602 // It's child window, i.e. window which is nested in parent window.
603 // This is obsoleted and should not be used.
604 // We use GdkWindow hierarchy for such windows.
605 bool mIsChildWindow : 1;
606 bool mAlwaysOnTop : 1;
607 bool mNoAutoHide : 1;
608 bool mMouseTransparent : 1;
609 bool mIsTransparent : 1;
610 // We can't detect size state changes correctly so set this flag
611 // to force update mBounds after a size state change from a configure
612 // event.
613 bool mBoundsAreValid : 1;
615 /* Gkt creates popup in two incarnations - wl_subsurface and xdg_popup.
616 * Kind of popup is choosen before GdkWindow is mapped so we can change
617 * it only when GdkWindow is hidden.
619 * Relevant Gtk code is at gdkwindow-wayland.c
620 * in should_map_as_popup() and should_map_as_subsurface()
622 * wl_subsurface:
623 * - can't be positioned by move-to-rect
624 * - can stand outside popup widget hierarchy (has toplevel as parent)
625 * - don't have child popup widgets
627 * xdg_popup:
628 * - can be positioned by move-to-rect
629 * - aligned in popup widget hierarchy, first one is attached to toplevel
630 * - has child (popup) widgets
632 * Thus we need to map Firefox popup type to desired Gtk one:
634 * wl_subsurface:
635 * - pernament panels
637 * xdg_popup:
638 * - menus
639 * - autohide popups (hamburger menu)
640 * - extension popups
641 * - tooltips
643 * We set mPopupTrackInHierarchy = false for pernament panels which
644 * are always mapped to toplevel and painted as wl_surfaces.
646 bool mPopupTrackInHierarchy : 1;
647 bool mPopupTrackInHierarchyConfigured : 1;
649 /* On X11 Gtk tends to ignore window position requests when gtk_window
650 * is hidden. Save the position requests at mPopupPosition and apply
651 * when the widget is shown.
653 bool mHiddenPopupPositioned : 1;
655 // The transparency bitmap is used instead of ARGB visual for toplevel
656 // window to draw titlebar.
657 bool mTransparencyBitmapForTitlebar : 1;
659 // True when we're on compositing window manager and this
660 // window is using visual with alpha channel.
661 bool mHasAlphaVisual : 1;
663 // When popup is anchored, mPopupPosition is relative to its parent popup.
664 bool mPopupAnchored : 1;
666 // When popup is context menu.
667 bool mPopupContextMenu : 1;
669 // Indicates that this popup matches layout setup so we can use parent popup
670 // coordinates reliably.
671 bool mPopupMatchesLayout : 1;
673 /* Indicates that popup setup was changed and
674 * we need to recalculate popup coordinates.
676 bool mPopupChanged : 1;
678 // Popup is hidden only as a part of hierarchy tree update.
679 bool mPopupTemporaryHidden : 1;
681 // Popup is going to be closed and removed.
682 bool mPopupClosed : 1;
684 // Popup is positioned by gdk_window_move_to_rect()
685 bool mPopupUseMoveToRect : 1;
687 /* mWaitingForMoveToRectCallback is set when move-to-rect is called
688 * and we're waiting for move-to-rect callback.
690 * If another position/resize request comes between move-to-rect call and
691 * move-to-rect callback we set mNewBoundsAfterMoveToRect.
693 bool mWaitingForMoveToRectCallback : 1;
695 // Params used for popup placemend by GdkWindowMoveToRect.
696 // When popup is only resized and not positioned,
697 // we need to reuse last GdkWindowMoveToRect params to avoid
698 // popup movement.
699 struct WaylandPopupMoveToRectParams {
700 LayoutDeviceIntRect mAnchorRect;
701 GdkGravity mAnchorRectType;
702 GdkGravity mPopupAnchorType;
703 GdkAnchorHints mHints;
704 GdkPoint mOffset;
707 WaylandPopupMoveToRectParams mPopupMoveToRectParams;
709 // Whether we've configured default clear color already.
710 bool mConfiguredClearColor : 1;
711 // Whether we've received a non-blank paint in which case we can reset the
712 // clear color to transparent.
713 bool mGotNonBlankPaint : 1;
715 // This bitmap tracks which pixels are transparent. We don't support
716 // full translucency at this time; each pixel is either fully opaque
717 // or fully transparent.
718 gchar* mTransparencyBitmap = nullptr;
719 int32_t mTransparencyBitmapWidth = 0;
720 int32_t mTransparencyBitmapHeight = 0;
722 // all of our DND stuff
723 void InitDragEvent(mozilla::WidgetDragEvent& aEvent);
725 float mLastMotionPressure = 0.0f;
727 // Remember the last sizemode so that we can restore it when
728 // leaving fullscreen
729 nsSizeMode mLastSizeMode = nsSizeMode_Normal;
731 static bool DragInProgress(void);
733 void DispatchMissedButtonReleases(GdkEventCrossing* aGdkEvent);
735 // When window widget gets mapped/unmapped we need to configure
736 // underlying GdkWindow properly. Otherwise we'll end up with
737 // rendering to released window.
738 void ConfigureGdkWindow();
739 void ReleaseGdkWindow();
741 // nsBaseWidget
742 WindowRenderer* GetWindowRenderer() override;
743 void DidGetNonBlankPaint() override;
745 void SetCompositorWidgetDelegate(CompositorWidgetDelegate* delegate) override;
747 void CleanLayerManagerRecursive();
749 int32_t RoundsWidgetCoordinatesTo() override;
751 void UpdateMozWindowActive();
753 void ForceTitlebarRedraw();
754 bool DoDrawTilebarCorners();
755 bool IsChromeWindowTitlebar();
757 void SetPopupWindowDecoration(bool aShowOnTaskbar);
759 void ApplySizeConstraints(void);
761 // Wayland Popup section
762 GdkPoint WaylandGetParentPosition();
763 bool WaylandPopupConfigure();
764 bool WaylandPopupIsAnchored();
765 bool WaylandPopupIsMenu();
766 bool WaylandPopupIsContextMenu();
767 bool WaylandPopupIsPermanent();
768 bool IsWidgetOverflowWindow();
769 void RemovePopupFromHierarchyList();
770 void ShowWaylandWindow();
771 void HideWaylandWindow();
772 void HideWaylandPopupWindow(bool aTemporaryHidden, bool aRemoveFromPopupList);
773 void HideWaylandToplevelWindow();
774 void WaylandPopupHideTooltips();
775 void AppendPopupToHierarchyList(nsWindow* aToplevelWindow);
776 void WaylandPopupHierarchyHideTemporary();
777 void WaylandPopupHierarchyShowTemporaryHidden();
778 void WaylandPopupHierarchyCalculatePositions();
779 bool IsInPopupHierarchy();
780 void AddWindowToPopupHierarchy();
781 void UpdateWaylandPopupHierarchy();
782 void WaylandPopupHierarchyHideByLayout(
783 nsTArray<nsIWidget*>* aLayoutWidgetHierarchy);
784 void WaylandPopupHierarchyValidateByLayout(
785 nsTArray<nsIWidget*>* aLayoutWidgetHierarchy);
786 void CloseAllPopupsBeforeRemotePopup();
787 void WaylandPopupHideClosedPopups();
788 void WaylandPopupMove();
789 bool WaylandPopupRemoveNegativePosition(int* aX = nullptr, int* aY = nullptr);
790 nsWindow* WaylandPopupGetTopmostWindow();
791 bool IsPopupInLayoutPopupChain(nsTArray<nsIWidget*>* aLayoutWidgetHierarchy,
792 bool aMustMatchParent);
793 void WaylandPopupMarkAsClosed();
794 void WaylandPopupRemoveClosedPopups();
795 void WaylandPopupSetDirectPosition();
796 bool WaylandPopupFitsParentWindow(const GdkRectangle& aSize);
797 const WaylandPopupMoveToRectParams WaylandPopupGetPositionFromLayout();
798 nsWindow* WaylandPopupFindLast(nsWindow* aPopup);
799 GtkWindow* GetCurrentTopmostWindow();
800 nsAutoCString GetFrameTag() const;
801 nsCString GetPopupTypeName();
802 bool IsPopupDirectionRTL();
804 #ifdef MOZ_LOGGING
805 void LogPopupHierarchy();
806 #endif
808 // mPopupPosition is the original popup position from layout, set by
809 // nsWindow::Move() or nsWindow::Resize().
810 GdkPoint mPopupPosition{};
812 // mRelativePopupPosition is popup position calculated against parent window.
813 GdkPoint mRelativePopupPosition{};
815 // Toplevel window (first element) of linked list of Wayland popups. It's null
816 // if we're the toplevel.
817 RefPtr<nsWindow> mWaylandToplevel;
819 // Next/Previous popups in Wayland popup hierarchy.
820 RefPtr<nsWindow> mWaylandPopupNext;
821 RefPtr<nsWindow> mWaylandPopupPrev;
823 // When popup is resized by Gtk by move-to-rect callback,
824 // we store final popup size here. Then we use mMoveToRectPopupRect size
825 // in following popup operations unless mLayoutPopupSizeCleared is set.
826 LayoutDeviceIntRect mMoveToRectPopupRect;
828 LayoutDeviceIntRect mNewBoundsAfterMoveToRect;
831 * |mIMContext| takes all IME related stuff.
833 * This is owned by the top-level nsWindow or the topmost child
834 * nsWindow embedded in a non-Gecko widget.
836 * The instance is created when the top level widget is created. And when
837 * the widget is destroyed, it's released. All child windows refer its
838 * ancestor widget's instance. So, one set of IM contexts is created for
839 * all windows in a hierarchy. If the children are released after the top
840 * level window is released, the children still have a valid pointer,
841 * however, IME doesn't work at that time.
843 RefPtr<mozilla::widget::IMContextWrapper> mIMContext;
845 mozilla::UniquePtr<mozilla::CurrentX11TimeGetter> mCurrentTimeGetter;
846 static GtkWindowDecoration sGtkWindowDecoration;
848 static bool sTransparentMainWindow;
850 #ifdef ACCESSIBILITY
851 RefPtr<mozilla::a11y::LocalAccessible> mRootAccessible;
854 * Request to create the accessible for this window if it is top level.
856 void CreateRootAccessible();
859 * Dispatch accessible event for the top level window accessible.
861 * @param aEventType [in] the accessible event type to dispatch
863 void DispatchEventToRootAccessible(uint32_t aEventType);
866 * Dispatch accessible window activate event for the top level window
867 * accessible.
869 void DispatchActivateEventAccessible();
872 * Dispatch accessible window deactivate event for the top level window
873 * accessible.
875 void DispatchDeactivateEventAccessible();
878 * Dispatch accessible window maximize event for the top level window
879 * accessible.
881 void DispatchMaximizeEventAccessible();
884 * Dispatch accessible window minize event for the top level window
885 * accessible.
887 void DispatchMinimizeEventAccessible();
890 * Dispatch accessible window restore event for the top level window
891 * accessible.
893 void DispatchRestoreEventAccessible();
894 #endif
896 #ifdef MOZ_X11
897 typedef enum {GTK_WIDGET_COMPOSIDED_DEFAULT = 0,
898 GTK_WIDGET_COMPOSIDED_DISABLED = 1,
899 GTK_WIDGET_COMPOSIDED_ENABLED = 2} WindowComposeRequest;
900 void SetCompositorHint(WindowComposeRequest aState);
901 bool ConfigureX11GLVisual();
902 #endif
903 #ifdef MOZ_WAYLAND
904 RefPtr<mozilla::WaylandVsyncSource> mWaylandVsyncSource;
905 LayoutDeviceIntPoint mNativePointerLockCenter;
906 zwp_locked_pointer_v1* mLockedPointer = nullptr;
907 zwp_relative_pointer_v1* mRelativePointer = nullptr;
908 xdg_activation_token_v1* mXdgToken = nullptr;
909 #endif
910 mozilla::widget::WindowSurfaceProvider mSurfaceProvider;
913 #endif /* __nsWindow_h__ */