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