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