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