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