Bug 1869647 - Mark hasStorageAccess.sub.https.window.html as intermittent after wpt...
[gecko.git] / widget / gtk / nsWindow.h
blob02e144a75ad420b74ca4353ebd3ff798071b8c23
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:expandtab:shiftwidth=2:tabstop=2:
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 "VsyncSource.h"
17 #include "mozilla/EventForwards.h"
18 #include "mozilla/Maybe.h"
19 #include "mozilla/RefPtr.h"
20 #include "mozilla/TouchEvents.h"
21 #include "mozilla/UniquePtr.h"
22 #include "mozilla/widget/WindowSurface.h"
23 #include "mozilla/widget/WindowSurfaceProvider.h"
24 #include "nsBaseWidget.h"
25 #include "nsGkAtoms.h"
26 #include "nsIDragService.h"
27 #include "nsRefPtrHashtable.h"
28 #include "IMContextWrapper.h"
30 #ifdef ACCESSIBILITY
31 # include "mozilla/a11y/LocalAccessible.h"
32 #endif
34 #ifdef MOZ_X11
35 # include <gdk/gdkx.h>
36 # include "X11UndefineNone.h"
37 #endif
38 #ifdef MOZ_WAYLAND
39 # include <gdk/gdkwayland.h>
40 # include "base/thread.h"
41 # include "WaylandVsyncSource.h"
42 # include "nsClipboardWayland.h"
43 #endif
45 #ifdef MOZ_LOGGING
47 # include "mozilla/Logging.h"
48 # include "nsTArray.h"
49 # include "Units.h"
51 extern mozilla::LazyLogModule gWidgetLog;
52 extern mozilla::LazyLogModule gWidgetDragLog;
53 extern mozilla::LazyLogModule gWidgetPopupLog;
54 extern mozilla::LazyLogModule gWidgetVsync;
56 # define LOG(str, ...) \
57 MOZ_LOG(IsPopup() ? gWidgetPopupLog : gWidgetLog, \
58 mozilla::LogLevel::Debug, \
59 ("%s: " str, GetDebugTag().get(), ##__VA_ARGS__))
60 # define LOGW(...) MOZ_LOG(gWidgetLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
61 # define LOGDRAG(...) \
62 MOZ_LOG(gWidgetDragLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
63 # define LOG_POPUP(...) \
64 MOZ_LOG(gWidgetPopupLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
65 # define LOG_VSYNC(...) \
66 MOZ_LOG(gWidgetVsync, mozilla::LogLevel::Debug, (__VA_ARGS__))
67 # define LOG_ENABLED() \
68 (MOZ_LOG_TEST(gWidgetPopupLog, mozilla::LogLevel::Debug) || \
69 MOZ_LOG_TEST(gWidgetLog, mozilla::LogLevel::Debug))
71 #else
73 # define LOG(...)
74 # define LOGW(...)
75 # define LOGDRAG(...)
76 # define LOG_POPUP(...)
77 # define LOG_ENABLED() false
79 #endif /* MOZ_LOGGING */
81 #if defined(MOZ_WAYLAND) && !defined(MOZ_X11)
82 typedef uintptr_t Window;
83 #endif
85 class gfxPattern;
86 class nsIFrame;
87 #if !GTK_CHECK_VERSION(3, 18, 0)
88 struct _GdkEventTouchpadPinch;
89 typedef struct _GdkEventTouchpadPinch GdkEventTouchpadPinch;
90 #endif
92 #if !GTK_CHECK_VERSION(3, 22, 0)
93 typedef enum {
94 GDK_ANCHOR_FLIP_X = 1 << 0,
95 GDK_ANCHOR_FLIP_Y = 1 << 1,
96 GDK_ANCHOR_SLIDE_X = 1 << 2,
97 GDK_ANCHOR_SLIDE_Y = 1 << 3,
98 GDK_ANCHOR_RESIZE_X = 1 << 4,
99 GDK_ANCHOR_RESIZE_Y = 1 << 5,
100 GDK_ANCHOR_FLIP = GDK_ANCHOR_FLIP_X | GDK_ANCHOR_FLIP_Y,
101 GDK_ANCHOR_SLIDE = GDK_ANCHOR_SLIDE_X | GDK_ANCHOR_SLIDE_Y,
102 GDK_ANCHOR_RESIZE = GDK_ANCHOR_RESIZE_X | GDK_ANCHOR_RESIZE_Y
103 } GdkAnchorHints;
104 #endif
106 namespace mozilla {
107 enum class NativeKeyBindingsType : uint8_t;
109 class TimeStamp;
110 #ifdef MOZ_X11
111 class CurrentX11TimeGetter;
112 #endif
114 namespace widget {
115 class Screen;
116 } // namespace widget
117 } // namespace mozilla
119 class nsWindow final : public nsBaseWidget {
120 public:
121 typedef mozilla::gfx::DrawTarget DrawTarget;
122 typedef mozilla::WidgetEventTime WidgetEventTime;
123 typedef mozilla::WidgetKeyboardEvent WidgetKeyboardEvent;
124 typedef mozilla::widget::PlatformCompositorWidgetDelegate
125 PlatformCompositorWidgetDelegate;
127 nsWindow();
129 static void ReleaseGlobals();
131 NS_INLINE_DECL_REFCOUNTING_INHERITED(nsWindow, nsBaseWidget)
133 nsresult DispatchEvent(mozilla::WidgetGUIEvent* aEvent,
134 nsEventStatus& aStatus) override;
136 // called when we are destroyed
137 void OnDestroy() override;
139 // called to check and see if a widget's dimensions are sane
140 bool AreBoundsSane(void);
142 // nsIWidget
143 using nsBaseWidget::Create; // for Create signature not overridden here
144 [[nodiscard]] nsresult Create(nsIWidget* aParent,
145 nsNativeWidget aNativeParent,
146 const LayoutDeviceIntRect& aRect,
147 InitData* aInitData) override;
148 void Destroy() override;
149 nsIWidget* GetParent() override;
150 float GetDPI() override;
151 double GetDefaultScaleInternal() override;
152 mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() override;
153 mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScaleByScreen()
154 override;
155 void SetParent(nsIWidget* aNewParent) override;
156 void SetModal(bool aModal) override;
157 bool IsVisible() const override;
158 bool IsMapped() const override;
159 void ConstrainPosition(DesktopIntPoint&) override;
160 void SetSizeConstraints(const SizeConstraints& aConstraints) override;
161 void LockAspectRatio(bool aShouldLock) override;
162 void Move(double aX, double aY) override;
163 void Show(bool aState) override;
164 void Resize(double aWidth, double aHeight, bool aRepaint) override;
165 void Resize(double aX, double aY, double aWidth, double aHeight,
166 bool aRepaint) override;
167 bool IsEnabled() const override;
169 void SetZIndex(int32_t aZIndex) override;
170 nsSizeMode SizeMode() override { return mSizeMode; }
171 void SetSizeMode(nsSizeMode aMode) override;
172 void GetWorkspaceID(nsAString& workspaceID) override;
173 void MoveToWorkspace(const nsAString& workspaceID) override;
174 void Enable(bool aState) override;
175 void SetFocus(Raise, mozilla::dom::CallerType aCallerType) override;
176 LayoutDeviceIntRect GetScreenBounds() override;
177 LayoutDeviceIntRect GetClientBounds() override;
178 LayoutDeviceIntSize GetClientSize() override;
179 LayoutDeviceIntPoint GetClientOffset() override { return mClientOffset; }
180 LayoutDeviceIntPoint GetScreenEdgeSlop() override;
182 // Recomputes the client offset according to our current window position.
183 // If aNotify is true, NotifyWindowMoved will be called on client offset
184 // changes.
186 // NOTE(emilio): It seems that as long any change here update either the size
187 // or the position of the window, we should be doing fine without notifying,
188 // but this is done to preserve existing behavior.
189 void RecomputeClientOffset(bool aNotify);
191 void SetCursor(const Cursor&) override;
192 void Invalidate(const LayoutDeviceIntRect& aRect) override;
193 void* GetNativeData(uint32_t aDataType) override;
194 nsresult SetTitle(const nsAString& aTitle) override;
195 void SetIcon(const nsAString& aIconSpec) override;
196 void SetWindowClass(const nsAString& xulWinType, const nsAString& xulWinClass,
197 const nsAString& xulWinName) override;
198 LayoutDeviceIntPoint WidgetToScreenOffset() override;
199 void CaptureRollupEvents(bool aDoCapture) override;
200 [[nodiscard]] nsresult GetAttention(int32_t aCycleCount) override;
201 bool HasPendingInputEvent() override;
203 bool PrepareForFullscreenTransition(nsISupports** aData) override;
204 void PerformFullscreenTransition(FullscreenTransitionStage aStage,
205 uint16_t aDuration, nsISupports* aData,
206 nsIRunnable* aCallback) override;
207 already_AddRefed<Screen> GetWidgetScreen() override;
208 nsresult MakeFullScreen(bool aFullScreen) override;
209 void HideWindowChrome(bool aShouldHide) override;
212 * GetLastUserInputTime returns a timestamp for the most recent user input
213 * event. This is intended for pointer grab requests (including drags).
215 static guint32 GetLastUserInputTime();
217 // utility method, -1 if no change should be made, otherwise returns a
218 // value that can be passed to gdk_window_set_decorations
219 gint ConvertBorderStyles(BorderStyle aStyle);
221 mozilla::widget::IMContextWrapper* GetIMContext() const { return mIMContext; }
223 bool DispatchCommandEvent(nsAtom* aCommand);
224 bool DispatchContentCommandEvent(mozilla::EventMessage aMsg);
226 // event callbacks
227 gboolean OnExposeEvent(cairo_t* cr);
228 gboolean OnConfigureEvent(GtkWidget* aWidget, GdkEventConfigure* aEvent);
229 void OnMap();
230 void OnUnmap();
231 void OnUnrealize();
232 void OnSizeAllocate(GtkAllocation* aAllocation);
233 void OnDeleteEvent();
234 void OnEnterNotifyEvent(GdkEventCrossing* aEvent);
235 void OnLeaveNotifyEvent(GdkEventCrossing* aEvent);
236 void OnMotionNotifyEvent(GdkEventMotion* aEvent);
237 void OnButtonPressEvent(GdkEventButton* aEvent);
238 void OnButtonReleaseEvent(GdkEventButton* aEvent);
239 void OnContainerFocusInEvent(GdkEventFocus* aEvent);
240 void OnContainerFocusOutEvent(GdkEventFocus* aEvent);
241 gboolean OnKeyPressEvent(GdkEventKey* aEvent);
242 gboolean OnKeyReleaseEvent(GdkEventKey* aEvent);
244 void OnScrollEvent(GdkEventScroll* aEvent);
246 void OnWindowStateEvent(GtkWidget* aWidget, GdkEventWindowState* aEvent);
247 void OnDragDataReceivedEvent(GtkWidget* aWidget, GdkDragContext* aDragContext,
248 gint aX, gint aY,
249 GtkSelectionData* aSelectionData, guint aInfo,
250 guint aTime, gpointer aData);
251 gboolean OnPropertyNotifyEvent(GtkWidget* aWidget, GdkEventProperty* aEvent);
252 gboolean OnTouchEvent(GdkEventTouch* aEvent);
253 gboolean OnTouchpadPinchEvent(GdkEventTouchpadPinch* aEvent);
255 gint GetInputRegionMarginInGdkCoords();
257 void UpdateTopLevelOpaqueRegion();
259 already_AddRefed<mozilla::gfx::DrawTarget> StartRemoteDrawingInRegion(
260 const LayoutDeviceIntRegion& aInvalidRegion,
261 mozilla::layers::BufferMode* aBufferMode) override;
262 void EndRemoteDrawingInRegion(
263 mozilla::gfx::DrawTarget* aDrawTarget,
264 const LayoutDeviceIntRegion& aInvalidRegion) override;
266 void SetProgress(unsigned long progressPercent);
268 RefPtr<mozilla::VsyncDispatcher> GetVsyncDispatcher() override;
269 bool SynchronouslyRepaintOnResize() override;
271 void OnDPIChanged();
272 void OnCheckResize();
273 void OnCompositedChanged();
274 void OnScaleChanged(bool aNotify);
275 void DispatchResized();
277 static guint32 sLastButtonPressTime;
279 MozContainer* GetMozContainer() { return mContainer; }
280 GdkWindow* GetGdkWindow() const { return mGdkWindow; };
281 GdkWindow* GetToplevelGdkWindow() const;
282 GtkWidget* GetGtkWidget() const { return mShell; }
283 nsIFrame* GetFrame() const;
284 nsWindow* GetEffectiveParent();
285 bool IsDestroyed() const { return mIsDestroyed; }
286 bool IsPopup() const;
287 bool IsWaylandPopup() const;
288 bool IsPIPWindow() const { return mIsPIPWindow; };
289 bool IsDragPopup() { return mIsDragPopup; };
291 nsAutoCString GetDebugTag() const;
293 void DispatchDragEvent(mozilla::EventMessage aMsg,
294 const LayoutDeviceIntPoint& aRefPoint, guint aTime);
295 static void UpdateDragStatus(GdkDragContext* aDragContext,
296 nsIDragService* aDragService);
297 void SetDragSource(GdkDragContext* aSourceDragContext);
299 WidgetEventTime GetWidgetEventTime(guint32 aEventTime);
300 mozilla::TimeStamp GetEventTimeStamp(guint32 aEventTime);
301 #ifdef MOZ_X11
302 mozilla::CurrentX11TimeGetter* GetCurrentTimeGetter();
303 #endif
305 void SetInputContext(const InputContext& aContext,
306 const InputContextAction& aAction) override;
307 InputContext GetInputContext() override;
308 TextEventDispatcherListener* GetNativeTextEventDispatcherListener() override;
309 MOZ_CAN_RUN_SCRIPT bool GetEditCommands(
310 mozilla::NativeKeyBindingsType aType,
311 const mozilla::WidgetKeyboardEvent& aEvent,
312 nsTArray<mozilla::CommandInt>& aCommands) override;
314 // These methods are for toplevel windows only.
315 void ResizeTransparencyBitmap();
316 void ApplyTransparencyBitmap();
317 void ClearTransparencyBitmap();
319 void SetTransparencyMode(TransparencyMode aMode) override;
320 TransparencyMode GetTransparencyMode() override;
321 void SetInputRegion(const InputRegion&) override;
322 nsresult UpdateTranslucentWindowAlphaInternal(const nsIntRect& aRect,
323 uint8_t* aAlphas,
324 int32_t aStride);
325 void ReparentNativeWidget(nsIWidget* aNewParent) override;
327 void UpdateTitlebarTransparencyBitmap();
329 nsresult SynthesizeNativeMouseEvent(LayoutDeviceIntPoint aPoint,
330 NativeMouseMessage aNativeMessage,
331 mozilla::MouseButton aButton,
332 nsIWidget::Modifiers aModifierFlags,
333 nsIObserver* aObserver) override;
335 nsresult SynthesizeNativeMouseMove(LayoutDeviceIntPoint aPoint,
336 nsIObserver* aObserver) override {
337 return SynthesizeNativeMouseEvent(
338 aPoint, NativeMouseMessage::Move, mozilla::MouseButton::eNotPressed,
339 nsIWidget::Modifiers::NO_MODIFIERS, aObserver);
342 nsresult SynthesizeNativeMouseScrollEvent(
343 LayoutDeviceIntPoint aPoint, uint32_t aNativeMessage, double aDeltaX,
344 double aDeltaY, double aDeltaZ, uint32_t aModifierFlags,
345 uint32_t aAdditionalFlags, nsIObserver* aObserver) override;
347 nsresult SynthesizeNativeTouchPoint(uint32_t aPointerId,
348 TouchPointerState aPointerState,
349 LayoutDeviceIntPoint aPoint,
350 double aPointerPressure,
351 uint32_t aPointerOrientation,
352 nsIObserver* aObserver) override;
354 nsresult SynthesizeNativeTouchPadPinch(TouchpadGesturePhase aEventPhase,
355 float aScale,
356 LayoutDeviceIntPoint aPoint,
357 int32_t aModifierFlags) override;
359 nsresult SynthesizeNativeTouchpadPan(TouchpadGesturePhase aEventPhase,
360 LayoutDeviceIntPoint aPoint,
361 double aDeltaX, double aDeltaY,
362 int32_t aModifierFlags,
363 nsIObserver* aObserver) override;
365 void GetCompositorWidgetInitData(
366 mozilla::widget::CompositorWidgetInitData* aInitData) override;
368 nsresult SetNonClientMargins(const LayoutDeviceIntMargin&) override;
369 void SetDrawsInTitlebar(bool aState);
370 mozilla::LayoutDeviceIntCoord GetTitlebarRadius();
371 LayoutDeviceIntRect GetTitlebarRect();
372 void UpdateWindowDraggingRegion(
373 const LayoutDeviceIntRegion& aRegion) override;
375 // HiDPI scale conversion
376 gint GdkCeiledScaleFactor();
377 double FractionalScaleFactor();
379 // To GDK
380 gint DevicePixelsToGdkCoordRoundUp(int);
381 gint DevicePixelsToGdkCoordRoundDown(int);
382 GdkPoint DevicePixelsToGdkPointRoundDown(const LayoutDeviceIntPoint&);
383 GdkRectangle DevicePixelsToGdkSizeRoundUp(const LayoutDeviceIntSize&);
384 GdkRectangle DevicePixelsToGdkRectRoundOut(const LayoutDeviceIntRect&);
386 // From GDK
387 int GdkCoordToDevicePixels(gint);
388 LayoutDeviceIntPoint GdkPointToDevicePixels(const GdkPoint&);
389 LayoutDeviceIntPoint GdkEventCoordsToDevicePixels(gdouble aX, gdouble aY);
390 LayoutDeviceIntRect GdkRectToDevicePixels(const GdkRectangle&);
392 bool WidgetTypeSupportsAcceleration() override;
394 nsresult SetSystemFont(const nsCString& aFontName) override;
395 nsresult GetSystemFont(nsCString& aFontName) override;
397 typedef enum {
398 GTK_DECORATION_SYSTEM, // CSD including shadows
399 GTK_DECORATION_CLIENT, // CSD without shadows
400 GTK_DECORATION_NONE, // WM does not support CSD at all
401 } GtkWindowDecoration;
403 * Get the support of Client Side Decoration by checking the desktop
404 * environment.
406 static GtkWindowDecoration GetSystemGtkWindowDecoration();
408 static bool GetTopLevelWindowActiveState(nsIFrame* aFrame);
409 static bool TitlebarUseShapeMask();
410 bool IsRemoteContent() { return HasRemoteContent(); }
411 void NativeMoveResizeWaylandPopupCallback(const GdkRectangle* aFinalSize,
412 bool aFlippedX, bool aFlippedY);
413 static bool IsToplevelWindowTransparent();
415 static nsWindow* GetFocusedWindow();
417 #ifdef MOZ_WAYLAND
418 // Use xdg-activation protocol to transfer focus from gFocusWindow to aWindow.
419 static void TransferFocusToWaylandWindow(nsWindow* aWindow);
420 void FocusWaylandWindow(const char* aTokenID);
422 bool GetCSDDecorationOffset(int* aDx, int* aDy);
423 bool SetEGLNativeWindowSize(const LayoutDeviceIntSize& aEGLWindowSize);
424 void WaylandDragWorkaround(GdkEventButton* aEvent);
426 void CreateCompositorVsyncDispatcher() override;
427 LayoutDeviceIntPoint GetNativePointerLockCenter() {
428 return mNativePointerLockCenter;
430 void SetNativePointerLockCenter(
431 const LayoutDeviceIntPoint& aLockCenter) override;
432 void LockNativePointer() override;
433 void UnlockNativePointer() override;
434 LayoutDeviceIntSize GetMoveToRectPopupSize() const override {
435 return mMoveToRectPopupSize;
437 #endif
439 typedef enum {
440 // WebRender compositor is enabled
441 COMPOSITOR_ENABLED,
442 // WebRender compositor is paused as we're repainting whole window and
443 // we're waiting for content process to update page content.
444 COMPOSITOR_PAUSED_FLICKERING
445 } WindowCompositorState;
447 // Pause compositor to avoid rendering artifacts from content process.
448 void ResumeCompositorImpl();
449 void ResumeCompositorFlickering();
450 void ResumeCompositorFromCompositorThread();
451 void PauseCompositorFlickering();
452 bool IsWaitingForCompositorResume();
454 // Force hide this window, remove compositor etc. to avoid
455 // rendering queue blocking (see Bug 1782948).
456 void ClearRenderingQueue();
458 bool ApplyEnterLeaveMutterWorkaround();
460 void NotifyOcclusionState(mozilla::widget::OcclusionState aState) override;
462 static nsWindow* GetWindow(GdkWindow* window);
464 protected:
465 virtual ~nsWindow();
467 // event handling code
468 void DispatchActivateEvent(void);
469 void DispatchDeactivateEvent(void);
470 void MaybeDispatchResized();
471 void DispatchPanGesture(mozilla::PanGestureInput& aPanInput);
473 void RegisterTouchWindow() override;
475 nsCOMPtr<nsIWidget> mParent;
476 PopupType mPopupHint{};
477 mozilla::Atomic<int, mozilla::Relaxed> mCeiledScaleFactor{1};
478 double mFractionalScaleFactor = 0.0;
480 void UpdateAlpha(mozilla::gfx::SourceSurface* aSourceSurface,
481 nsIntRect aBoundsRect);
483 void NativeMoveResize(bool aMoved, bool aResized);
485 void NativeShow(bool aAction);
486 void SetHasMappedToplevel(bool aState);
487 LayoutDeviceIntSize GetSafeWindowSize(LayoutDeviceIntSize aSize);
489 void DispatchContextMenuEventFromMouseEvent(
490 uint16_t domButton, GdkEventButton* aEvent,
491 const mozilla::LayoutDeviceIntPoint& aRefPoint);
493 void TryToShowNativeWindowMenu(GdkEventButton* aEvent);
495 void WaylandStartVsync();
496 void WaylandStopVsync();
497 void DestroyChildWindows();
498 GtkWidget* GetToplevelWidget() const;
499 nsWindow* GetContainerWindow() const;
500 Window GetX11Window();
501 bool GetShapedState();
502 void EnsureGdkWindow();
503 void SetUrgencyHint(GtkWidget* top_window, bool state);
504 void SetDefaultIcon(void);
505 void SetWindowDecoration(BorderStyle aStyle);
506 void InitButtonEvent(mozilla::WidgetMouseEvent& aEvent,
507 GdkEventButton* aGdkEvent,
508 const mozilla::LayoutDeviceIntPoint& aRefPoint);
509 bool CheckForRollup(gdouble aMouseX, gdouble aMouseY, bool aIsWheel,
510 bool aAlwaysRollup);
511 void RollupAllMenus() { CheckForRollup(0, 0, false, true); }
512 void CheckForRollupDuringGrab() { RollupAllMenus(); }
514 bool GetDragInfo(mozilla::WidgetMouseEvent* aMouseEvent, GdkWindow** aWindow,
515 gint* aButton, gint* aRootX, gint* aRootY);
516 nsIWidgetListener* GetListener();
518 nsWindow* GetTransientForWindowIfPopup();
519 bool IsHandlingTouchSequence(GdkEventSequence* aSequence);
521 void ResizeInt(const mozilla::Maybe<LayoutDeviceIntPoint>& aMove,
522 LayoutDeviceIntSize aSize);
523 void NativeMoveResizeWaylandPopup(bool aMove, bool aResize);
525 // Returns a window edge if the given point (in device pixels) is within a
526 // resizer region of the window.
527 // Only used when drawing decorations client side.
528 mozilla::Maybe<GdkWindowEdge> CheckResizerEdge(const LayoutDeviceIntPoint&);
530 GtkTextDirection GetTextDirection();
532 bool DrawsToCSDTitlebar() const;
533 void AddCSDDecorationSize(int* aWidth, int* aHeight);
535 void CreateAndPutGdkScrollEvent(mozilla::LayoutDeviceIntPoint aPoint,
536 double aDeltaX, double aDeltaY);
538 nsCString mGtkWindowAppClass;
539 nsCString mGtkWindowAppName;
540 nsCString mGtkWindowRoleName;
541 void RefreshWindowClass();
543 GtkWidget* mShell = nullptr;
544 MozContainer* mContainer = nullptr;
545 GdkWindow* mGdkWindow = nullptr;
546 PlatformCompositorWidgetDelegate* mCompositorWidgetDelegate = nullptr;
547 mozilla::Atomic<WindowCompositorState, mozilla::Relaxed> mCompositorState{
548 COMPOSITOR_ENABLED};
549 // This is used in COMPOSITOR_PAUSED_FLICKERING mode only to resume compositor
550 // in some reasonable time when page content is not updated.
551 guint mCompositorPauseTimeoutID = 0;
553 // The actual size mode that's in effect.
554 nsSizeMode mSizeMode = nsSizeMode_Normal;
555 // The last size mode we've requested. This might not match mSizeMode if
556 // there's a request to change the size mode in progress.
557 nsSizeMode mLastSizeModeRequest = nsSizeMode_Normal;
558 nsSizeMode mLastSizeModeBeforeFullscreen = nsSizeMode_Normal;
560 float mAspectRatio = 0.0f;
561 float mAspectRatioSaved = 0.0f;
562 mozilla::Maybe<GtkOrientation> mAspectResizer;
563 LayoutDeviceIntPoint mLastResizePoint;
565 // The size requested, which might not be reflected in mBounds. Used in
566 // WaylandPopupSetDirectPosition() to remember intended size for popup
567 // positioning, in LockAspect() to remember the intended aspect ratio, and
568 // to remember a size requested while waiting for moved-to-rect when
569 // OnSizeAllocate() might change mBounds.Size().
570 LayoutDeviceIntSize mLastSizeRequest;
571 LayoutDeviceIntPoint mClientOffset;
572 // Indicates a new size that still needs to be dispatched.
573 LayoutDeviceIntSize mNeedsDispatchSize = LayoutDeviceIntSize(-1, -1);
575 // This field omits duplicate scroll events caused by GNOME bug 726878.
576 guint32 mLastScrollEventTime = GDK_CURRENT_TIME;
577 mozilla::ScreenCoord mLastPinchEventSpan;
579 struct TouchpadPinchGestureState {
580 // Focus point of the PHASE_BEGIN event
581 ScreenPoint mBeginFocus;
583 // Focus point of the most recent PHASE_UPDATE event
584 ScreenPoint mCurrentFocus;
587 // Used for handling touchpad pinch gestures
588 ScreenPoint mCurrentTouchpadFocus;
590 // Used for synthesizing touchpad pinch gestures
591 TouchpadPinchGestureState mCurrentSynthesizedTouchpadPinch;
593 // Used for synthesizing touchpad pan gestures
594 struct TouchpadPanGestureState {
595 mozilla::Maybe<TouchpadGesturePhase> mTouchpadGesturePhase;
596 uint64_t mSavedObserver = 0;
599 // Used for synthesizing touchpad pan gestures
600 TouchpadPanGestureState mCurrentSynthesizedTouchpadPan;
602 // for touch event handling
603 nsRefPtrHashtable<nsPtrHashKey<GdkEventSequence>, mozilla::dom::Touch>
604 mTouches;
606 // Upper bound on pending ConfigureNotify events to be dispatched to the
607 // window. See bug 1225044.
608 unsigned int mPendingConfigures = 0;
610 // Window titlebar rendering mode, GTK_DECORATION_NONE if it's disabled
611 // for this window.
612 GtkWindowDecoration mGtkWindowDecoration = GTK_DECORATION_NONE;
614 // Draggable titlebar region maintained by UpdateWindowDraggingRegion
615 LayoutDeviceIntRegion mDraggableRegion;
617 // The cursor cache
618 static GdkCursor* gsGtkCursorCache[eCursorCount];
620 // If true, draw our own window titlebar.
622 // Needs to be atomic because GetTitlebarRect() gets called from non-main
623 // threads.
625 // FIXME(emilio): GetTitlebarRect() reads other things that TSAN doesn't
626 // catch because mDrawInTitlebar is false on automation ~always. We should
627 // probably make GetTitlebarRect() simpler / properly thread-safe.
628 mozilla::Atomic<bool, mozilla::Relaxed> mDrawInTitlebar{false};
630 mozilla::Mutex mDestroyMutex;
632 // Has this widget been destroyed yet?
633 bool mIsDestroyed : 1;
634 // mIsShown tracks requested visible status from browser perspective, i.e.
635 // if the window should be visible or now.
636 bool mIsShown : 1;
637 // mNeedsShow is set when browser requested to show this window but we failed
638 // to do so for some reason (wrong window size for instance).
639 // In such case we set mIsShown = true and mNeedsShow = true to indicate
640 // that the window is not actually visible but we report to browser that
641 // it is visible (mIsShown == true).
642 bool mNeedsShow : 1;
643 // This track real window visibility from OS perspective.
644 // It's set by OnMap/OnUnrealize which is based on Gtk events.
645 bool mIsMapped : 1;
646 // is this widget enabled?
647 bool mEnabled : 1;
648 // has the native window for this been created yet?
649 bool mCreated : 1;
650 // whether we handle touch event
651 bool mHandleTouchEvent : 1;
652 // true if this is a drag and drop feedback popup
653 bool mIsDragPopup : 1;
654 bool mCompositedScreen : 1;
655 bool mIsAccelerated : 1;
656 bool mWindowShouldStartDragging : 1;
657 bool mHasMappedToplevel : 1;
658 bool mRetryPointerGrab : 1;
659 bool mPanInProgress : 1;
660 // Draw titlebar with :backdrop css state (inactive/unfocused).
661 bool mTitlebarBackdropState : 1;
662 // It's undecorated popup utility window, without resizers/titlebar,
663 // movable by mouse. Used on Wayland for popups without
664 // parent (for instance WebRTC sharing indicator, notifications).
665 bool mIsWaylandPanelWindow : 1;
666 // It's child window, i.e. window which is nested in parent window.
667 // This is obsoleted and should not be used.
668 // We use GdkWindow hierarchy for such windows.
669 bool mIsChildWindow : 1;
670 bool mAlwaysOnTop : 1;
671 bool mNoAutoHide : 1;
672 bool mIsTransparent : 1;
673 // We can expect at least one size-allocate event after early resizes.
674 bool mHasReceivedSizeAllocate : 1;
675 bool mWidgetCursorLocked : 1;
676 bool mUndecorated : 1;
678 /* Gkt creates popup in two incarnations - wl_subsurface and xdg_popup.
679 * Kind of popup is choosen before GdkWindow is mapped so we can change
680 * it only when GdkWindow is hidden.
682 * Relevant Gtk code is at gdkwindow-wayland.c
683 * in should_map_as_popup() and should_map_as_subsurface()
685 * wl_subsurface:
686 * - can't be positioned by move-to-rect
687 * - can stand outside popup widget hierarchy (has toplevel as parent)
688 * - don't have child popup widgets
690 * xdg_popup:
691 * - can be positioned by move-to-rect
692 * - aligned in popup widget hierarchy, first one is attached to toplevel
693 * - has child (popup) widgets
695 * Thus we need to map Firefox popup type to desired Gtk one:
697 * wl_subsurface:
698 * - pernament panels
700 * xdg_popup:
701 * - menus
702 * - autohide popups (hamburger menu)
703 * - extension popups
704 * - tooltips
706 * We set mPopupTrackInHierarchy = false for pernament panels which
707 * are always mapped to toplevel and painted as wl_surfaces.
709 bool mPopupTrackInHierarchy : 1;
710 bool mPopupTrackInHierarchyConfigured : 1;
712 /* On X11 Gtk tends to ignore window position requests when gtk_window
713 * is hidden. Save the position requests at mPopupPosition and apply
714 * when the widget is shown.
716 bool mHiddenPopupPositioned : 1;
718 // The transparency bitmap is used instead of ARGB visual for toplevel
719 // window to draw titlebar.
720 bool mTransparencyBitmapForTitlebar : 1;
722 // True when we're on compositing window manager and this
723 // window is using visual with alpha channel.
724 bool mHasAlphaVisual : 1;
726 // When popup is anchored, mPopupPosition is relative to its parent popup.
727 bool mPopupAnchored : 1;
729 // When popup is context menu.
730 bool mPopupContextMenu : 1;
732 // Indicates that this popup matches layout setup so we can use parent popup
733 // coordinates reliably.
734 bool mPopupMatchesLayout : 1;
736 /* Indicates that popup setup was changed and
737 * we need to recalculate popup coordinates.
739 bool mPopupChanged : 1;
741 // Popup is hidden only as a part of hierarchy tree update.
742 bool mPopupTemporaryHidden : 1;
744 // Popup is going to be closed and removed.
745 bool mPopupClosed : 1;
747 // Popup is positioned by gdk_window_move_to_rect()
748 bool mPopupUseMoveToRect : 1;
750 /* mWaitingForMoveToRectCallback is set when move-to-rect is called
751 * and we're waiting for move-to-rect callback.
753 * If another position/resize request comes between move-to-rect call and
754 * move-to-rect callback we set mMovedAfterMoveToRect/mResizedAfterMoveToRect.
756 bool mWaitingForMoveToRectCallback : 1;
757 bool mMovedAfterMoveToRect : 1;
758 bool mResizedAfterMoveToRect : 1;
760 // Params used for popup placemend by GdkWindowMoveToRect.
761 // When popup is only resized and not positioned,
762 // we need to reuse last GdkWindowMoveToRect params to avoid
763 // popup movement.
764 struct WaylandPopupMoveToRectParams {
765 LayoutDeviceIntRect mAnchorRect = {0, 0, 0, 0};
766 GdkGravity mAnchorRectType = GDK_GRAVITY_NORTH_WEST;
767 GdkGravity mPopupAnchorType = GDK_GRAVITY_NORTH_WEST;
768 GdkAnchorHints mHints = GDK_ANCHOR_SLIDE;
769 GdkPoint mOffset = {0, 0};
770 bool mAnchorSet = false;
773 WaylandPopupMoveToRectParams mPopupMoveToRectParams;
775 // Whether we've configured default clear color already.
776 bool mConfiguredClearColor : 1;
777 // Whether we've received a non-blank paint in which case we can reset the
778 // clear color to transparent.
779 bool mGotNonBlankPaint : 1;
781 // Whether we need to retry capturing the mouse because we' re not mapped yet.
782 bool mNeedsToRetryCapturingMouse : 1;
784 // This bitmap tracks which pixels are transparent. We don't support
785 // full translucency at this time; each pixel is either fully opaque
786 // or fully transparent.
787 gchar* mTransparencyBitmap = nullptr;
788 int32_t mTransparencyBitmapWidth = 0;
789 int32_t mTransparencyBitmapHeight = 0;
791 // all of our DND stuff
792 void InitDragEvent(mozilla::WidgetDragEvent& aEvent);
794 float mLastMotionPressure = 0.0f;
796 InputRegion mInputRegion;
798 static bool DragInProgress(void);
800 void DispatchMissedButtonReleases(GdkEventCrossing* aGdkEvent);
802 // When window widget gets mapped/unmapped we need to configure
803 // underlying GdkWindow properly. Otherwise we'll end up with
804 // rendering to released window.
805 void ConfigureGdkWindow();
806 void ReleaseGdkWindow();
807 void ConfigureCompositor();
809 bool IsAlwaysUndecoratedWindow() const;
811 // nsBaseWidget
812 WindowRenderer* GetWindowRenderer() override;
813 void DidGetNonBlankPaint() override;
815 void SetCompositorWidgetDelegate(CompositorWidgetDelegate* delegate) override;
817 int32_t RoundsWidgetCoordinatesTo() override;
819 void UpdateMozWindowActive();
821 void ForceTitlebarRedraw();
822 bool DoDrawTilebarCorners();
823 bool IsChromeWindowTitlebar();
825 void SetPopupWindowDecoration(bool aShowOnTaskbar);
827 void ApplySizeConstraints();
829 // Wayland Popup section
830 GdkPoint WaylandGetParentPosition();
831 bool WaylandPopupConfigure();
832 bool WaylandPopupIsAnchored();
833 bool WaylandPopupIsMenu();
834 bool WaylandPopupIsContextMenu();
835 bool WaylandPopupIsPermanent();
836 // First popup means it's attached directly to toplevel window
837 bool WaylandPopupIsFirst();
838 bool IsWidgetOverflowWindow();
839 void RemovePopupFromHierarchyList();
840 void ShowWaylandPopupWindow();
841 void HideWaylandPopupWindow(bool aTemporaryHidden, bool aRemoveFromPopupList);
842 void ShowWaylandToplevelWindow();
843 void HideWaylandToplevelWindow();
844 void WaylandPopupHideTooltips();
845 void WaylandPopupCloseOrphanedPopups();
846 void AppendPopupToHierarchyList(nsWindow* aToplevelWindow);
847 void WaylandPopupHierarchyHideTemporary();
848 void WaylandPopupHierarchyShowTemporaryHidden();
849 void WaylandPopupHierarchyCalculatePositions();
850 bool IsInPopupHierarchy();
851 void AddWindowToPopupHierarchy();
852 void UpdateWaylandPopupHierarchy();
853 void WaylandPopupHierarchyHideByLayout(
854 nsTArray<nsIWidget*>* aLayoutWidgetHierarchy);
855 void WaylandPopupHierarchyValidateByLayout(
856 nsTArray<nsIWidget*>* aLayoutWidgetHierarchy);
857 void CloseAllPopupsBeforeRemotePopup();
858 void WaylandPopupHideClosedPopups();
859 void WaylandPopupPrepareForMove();
860 void WaylandPopupMoveImpl();
861 void WaylandPopupMovePlain(int aX, int aY);
862 bool WaylandPopupRemoveNegativePosition(int* aX = nullptr, int* aY = nullptr);
863 bool WaylandPopupCheckAndGetAnchor(GdkRectangle* aPopupAnchor,
864 GdkPoint* aOffset);
865 bool WaylandPopupAnchorAdjustForParentPopup(GdkRectangle* aPopupAnchor,
866 GdkPoint* aOffset);
867 nsWindow* GetTopmostWindow();
868 bool IsPopupInLayoutPopupChain(nsTArray<nsIWidget*>* aLayoutWidgetHierarchy,
869 bool aMustMatchParent);
870 void WaylandPopupMarkAsClosed();
871 void WaylandPopupRemoveClosedPopups();
872 void WaylandPopupSetDirectPosition();
873 bool WaylandPopupFitsToplevelWindow(bool aMove);
874 const WaylandPopupMoveToRectParams WaylandPopupGetPositionFromLayout();
875 void WaylandPopupPropagateChangesToLayout(bool aMove, bool aResize);
876 nsWindow* WaylandPopupFindLast(nsWindow* aPopup);
877 GtkWindow* GetCurrentTopmostWindow() const;
878 nsAutoCString GetFrameTag() const;
879 nsCString GetPopupTypeName();
880 bool IsPopupDirectionRTL();
882 #ifdef MOZ_LOGGING
883 void LogPopupHierarchy();
884 void LogPopupAnchorHints(int aHints);
885 void LogPopupGravity(GdkGravity aGravity);
886 #endif
888 bool IsTopLevelWindowType() const {
889 return mWindowType == WindowType::TopLevel ||
890 mWindowType == WindowType::Dialog;
893 // mPopupPosition is the original popup position/size from layout, set by
894 // nsWindow::Move() or nsWindow::Resize().
895 // Popup position is relative to main (toplevel) window.
896 GdkPoint mPopupPosition{};
898 // mRelativePopupPosition is popup position calculated against
899 // recent popup parent window.
900 GdkPoint mRelativePopupPosition{};
902 // Toplevel window (first element) of linked list of Wayland popups. It's null
903 // if we're the toplevel.
904 RefPtr<nsWindow> mWaylandToplevel;
906 // Next/Previous popups in Wayland popup hierarchy.
907 RefPtr<nsWindow> mWaylandPopupNext;
908 RefPtr<nsWindow> mWaylandPopupPrev;
910 // When popup is resized by Gtk by move-to-rect callback,
911 // we store final popup size here. Then we use mMoveToRectPopupSize size
912 // in following popup operations unless mLayoutPopupSizeCleared is set.
913 LayoutDeviceIntSize mMoveToRectPopupSize;
916 * |mIMContext| takes all IME related stuff.
918 * This is owned by the top-level nsWindow or the topmost child
919 * nsWindow embedded in a non-Gecko widget.
921 * The instance is created when the top level widget is created. And when
922 * the widget is destroyed, it's released. All child windows refer its
923 * ancestor widget's instance. So, one set of IM contexts is created for
924 * all windows in a hierarchy. If the children are released after the top
925 * level window is released, the children still have a valid pointer,
926 * however, IME doesn't work at that time.
928 RefPtr<mozilla::widget::IMContextWrapper> mIMContext;
930 #ifdef MOZ_X11
931 mozilla::UniquePtr<mozilla::CurrentX11TimeGetter> mCurrentTimeGetter;
932 #endif
933 static GtkWindowDecoration sGtkWindowDecoration;
935 static bool sTransparentMainWindow;
937 #ifdef ACCESSIBILITY
938 RefPtr<mozilla::a11y::LocalAccessible> mRootAccessible;
941 * Request to create the accessible for this window if it is top level.
943 void CreateRootAccessible();
946 * Dispatch accessible event for the top level window accessible.
948 * @param aEventType [in] the accessible event type to dispatch
950 void DispatchEventToRootAccessible(uint32_t aEventType);
953 * Dispatch accessible window activate event for the top level window
954 * accessible.
956 void DispatchActivateEventAccessible();
959 * Dispatch accessible window deactivate event for the top level window
960 * accessible.
962 void DispatchDeactivateEventAccessible();
965 * Dispatch accessible window maximize event for the top level window
966 * accessible.
968 void DispatchMaximizeEventAccessible();
971 * Dispatch accessible window minize event for the top level window
972 * accessible.
974 void DispatchMinimizeEventAccessible();
977 * Dispatch accessible window restore event for the top level window
978 * accessible.
980 void DispatchRestoreEventAccessible();
981 #endif
983 void SetUserTimeAndStartupTokenForActivatedWindow();
985 void KioskLockOnMonitor();
987 void EmulateResizeDrag(GdkEventMotion* aEvent);
989 #ifdef MOZ_X11
990 typedef enum {GTK_WIDGET_COMPOSIDED_DEFAULT = 0,
991 GTK_WIDGET_COMPOSIDED_DISABLED = 1,
992 GTK_WIDGET_COMPOSIDED_ENABLED = 2} WindowComposeRequest;
993 void SetCompositorHint(WindowComposeRequest aState);
994 bool ConfigureX11GLVisual();
995 #endif
996 #ifdef MOZ_WAYLAND
997 RefPtr<mozilla::WaylandVsyncSource> mWaylandVsyncSource;
998 RefPtr<mozilla::VsyncDispatcher> mWaylandVsyncDispatcher;
999 LayoutDeviceIntPoint mNativePointerLockCenter;
1000 zwp_locked_pointer_v1* mLockedPointer = nullptr;
1001 zwp_relative_pointer_v1* mRelativePointer = nullptr;
1002 #endif
1003 // An activation token from our environment (see handling of the
1004 // XDG_ACTIVATION_TOKEN/DESKTOP_STARTUP_ID) env vars.
1005 nsCString mWindowActivationTokenFromEnv;
1006 mozilla::widget::WindowSurfaceProvider mSurfaceProvider;
1007 GdkDragContext* mSourceDragContext = nullptr;
1008 #if MOZ_LOGGING
1009 LayoutDeviceIntRect mLastLoggedBoundSize;
1010 int mLastLoggedScale = -1;
1011 #endif
1012 // Running in kiosk mode and requested to stay on specified monitor.
1013 // If monitor is removed minimize the window.
1014 mozilla::Maybe<int> mKioskMonitor;
1017 #endif /* __nsWindow_h__ */