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