From b0608ef1b9f28da51a80ef01dc8bd70c405619ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 16 Aug 2024 12:48:28 +0000 Subject: [PATCH] Bug 1913104 - Remove X11 mask code. r=stransky,desktop-theme-reviewers,dao It's only used in non-compositing WMs, to implement popup transparency, and it's completely untested. Instead, do not draw shadows and rounded corners on those WMs. Differential Revision: https://phabricator.services.mozilla.com/D219141 --- .../test/chrome/chrome-only-media-queries.js | 1 + modules/libpref/init/all.js | 1 - .../components/style/gecko/media_features.rs | 3 +- toolkit/themes/shared/popup.css | 6 + widget/LookAndFeel.h | 6 + widget/gtk/CompositorWidgetChild.cpp | 8 +- widget/gtk/CompositorWidgetChild.h | 3 +- widget/gtk/CompositorWidgetParent.cpp | 4 +- widget/gtk/CompositorWidgetParent.h | 4 +- widget/gtk/GtkCompositorWidget.cpp | 15 +- widget/gtk/GtkCompositorWidget.h | 8 +- widget/gtk/MozContainer.cpp | 9 +- widget/gtk/MozContainer.h | 2 - widget/gtk/PCompositorWidget.ipdl | 2 +- widget/gtk/PlatformWidgetTypes.ipdlh | 1 - widget/gtk/WindowSurfaceProvider.cpp | 11 +- widget/gtk/WindowSurfaceProvider.h | 3 +- widget/gtk/WindowSurfaceX11Image.cpp | 156 +------ widget/gtk/WindowSurfaceX11Image.h | 11 +- widget/gtk/nsLookAndFeel.cpp | 6 + widget/gtk/nsWindow.cpp | 416 +----------------- widget/gtk/nsWindow.h | 28 +- widget/nsXPLookAndFeel.cpp | 1 + xpcom/ds/StaticAtoms.py | 1 + 24 files changed, 61 insertions(+), 645 deletions(-) diff --git a/layout/style/test/chrome/chrome-only-media-queries.js b/layout/style/test/chrome/chrome-only-media-queries.js index d17976149bc3..f0be01ce75de 100644 --- a/layout/style/test/chrome/chrome-only-media-queries.js +++ b/layout/style/test/chrome/chrome-only-media-queries.js @@ -11,6 +11,7 @@ const CHROME_ONLY_TOGGLES = [ "-moz-windows-accent-color-in-titlebar", "-moz-swipe-animation-enabled", "-moz-gtk-csd-available", + "-moz-gtk-csd-transparency-available", "-moz-gtk-csd-minimize-button", "-moz-gtk-csd-maximize-button", "-moz-gtk-csd-close-button", diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index b38747dcdc47..bff811243e54 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -3187,7 +3187,6 @@ pref("network.psl.onUpdate_notify", false); #ifdef MOZ_WIDGET_GTK pref("widget.disable-workspace-management", false); - pref("widget.titlebar-x11-use-shape-mask", false); #endif // All the Geolocation preferences are here. diff --git a/servo/components/style/gecko/media_features.rs b/servo/components/style/gecko/media_features.rs index df1c5e464b84..ff6a291b7360 100644 --- a/servo/components/style/gecko/media_features.rs +++ b/servo/components/style/gecko/media_features.rs @@ -698,7 +698,7 @@ macro_rules! lnf_int_feature { /// to support new types in these entries and (2) ensuring that either /// nsPresContext::MediaFeatureValuesChanged is called when the value that /// would be returned by the evaluator function could change. -pub static MEDIA_FEATURES: [QueryFeatureDescription; 59] = [ +pub static MEDIA_FEATURES: [QueryFeatureDescription; 60] = [ feature!( atom!("width"), AllowsRanges::Yes, @@ -1003,6 +1003,7 @@ pub static MEDIA_FEATURES: [QueryFeatureDescription; 59] = [ ), lnf_int_feature!(atom!("-moz-swipe-animation-enabled"), SwipeAnimationEnabled), lnf_int_feature!(atom!("-moz-gtk-csd-available"), GTKCSDAvailable), + lnf_int_feature!(atom!("-moz-gtk-csd-transparency-available"), GTKCSDTransparencyAvailable), lnf_int_feature!(atom!("-moz-gtk-csd-minimize-button"), GTKCSDMinimizeButton), lnf_int_feature!(atom!("-moz-gtk-csd-maximize-button"), GTKCSDMaximizeButton), lnf_int_feature!(atom!("-moz-gtk-csd-close-button"), GTKCSDCloseButton), diff --git a/toolkit/themes/shared/popup.css b/toolkit/themes/shared/popup.css index ed230860215c..a86b2e0e0476 100644 --- a/toolkit/themes/shared/popup.css +++ b/toolkit/themes/shared/popup.css @@ -43,6 +43,12 @@ panel { --panel-shadow-margin: 4px; } + /* On some linux WMs we need to draw square menus because alpha is not available */ + @media (-moz-platform: linux) and (not (-moz-gtk-csd-transparency-available)) { + --panel-shadow-margin: 0px !important; + --panel-border-radius: 0px !important; + } + @media (-moz-platform: macos) { appearance: auto; -moz-default-appearance: menupopup; diff --git a/widget/LookAndFeel.h b/widget/LookAndFeel.h index ca605d62cd69..1b269714a4a3 100644 --- a/widget/LookAndFeel.h +++ b/widget/LookAndFeel.h @@ -193,6 +193,12 @@ class LookAndFeel { */ GTKCSDAvailable, + /* + * A boolean value indicating whether semi-transparent + * windows are available. + */ + GTKCSDTransparencyAvailable, + /* * A boolean value indicating whether client-side decorations should * contain a minimize button. diff --git a/widget/gtk/CompositorWidgetChild.cpp b/widget/gtk/CompositorWidgetChild.cpp index 3b6af872ed68..302276c70d63 100644 --- a/widget/gtk/CompositorWidgetChild.cpp +++ b/widget/gtk/CompositorWidgetChild.cpp @@ -14,7 +14,8 @@ CompositorWidgetChild::CompositorWidgetChild( RefPtr aVsyncDispatcher, RefPtr aVsyncObserver, const CompositorWidgetInitData&) - : mVsyncDispatcher(aVsyncDispatcher), mVsyncObserver(aVsyncObserver) { + : mVsyncDispatcher(std::move(aVsyncDispatcher)), + mVsyncObserver(std::move(aVsyncObserver)) { MOZ_ASSERT(XRE_IsParentProcess()); MOZ_ASSERT(!gfxPlatform::IsHeadless()); } @@ -42,9 +43,8 @@ void CompositorWidgetChild::CleanupResources() { Unused << SendCleanupResources(); } -void CompositorWidgetChild::SetRenderingSurface(const uintptr_t aXWindow, - const bool aShaped) { - Unused << SendSetRenderingSurface(aXWindow, aShaped); +void CompositorWidgetChild::SetRenderingSurface(const uintptr_t aXWindow) { + Unused << SendSetRenderingSurface(aXWindow); } } // namespace widget diff --git a/widget/gtk/CompositorWidgetChild.h b/widget/gtk/CompositorWidgetChild.h index f46cf63bfbb2..fb2d834afc17 100644 --- a/widget/gtk/CompositorWidgetChild.h +++ b/widget/gtk/CompositorWidgetChild.h @@ -28,8 +28,7 @@ class CompositorWidgetChild final : public PCompositorWidgetChild, void NotifyClientSizeChanged(const LayoutDeviceIntSize& aClientSize) override; void CleanupResources() override; - void SetRenderingSurface(const uintptr_t aXWindow, - const bool aShaped) override; + void SetRenderingSurface(const uintptr_t aXWindow) override; private: RefPtr mVsyncDispatcher; diff --git a/widget/gtk/CompositorWidgetParent.cpp b/widget/gtk/CompositorWidgetParent.cpp index 7f576f35e7b7..8356c45ffe79 100644 --- a/widget/gtk/CompositorWidgetParent.cpp +++ b/widget/gtk/CompositorWidgetParent.cpp @@ -46,8 +46,8 @@ mozilla::ipc::IPCResult CompositorWidgetParent::RecvCleanupResources() { } mozilla::ipc::IPCResult CompositorWidgetParent::RecvSetRenderingSurface( - const uintptr_t& aXWindow, const bool& aShaped) { - SetRenderingSurface(aXWindow, aShaped); + const uintptr_t& aXWindow) { + SetRenderingSurface(aXWindow); return IPC_OK(); } diff --git a/widget/gtk/CompositorWidgetParent.h b/widget/gtk/CompositorWidgetParent.h index 8c0a6e8c267b..b76776c46b19 100644 --- a/widget/gtk/CompositorWidgetParent.h +++ b/widget/gtk/CompositorWidgetParent.h @@ -29,8 +29,8 @@ class CompositorWidgetParent final : public PCompositorWidgetParent, const LayoutDeviceIntSize& aClientSize) override; mozilla::ipc::IPCResult RecvCleanupResources() override; - mozilla::ipc::IPCResult RecvSetRenderingSurface(const uintptr_t& aXWindow, - const bool& aShaped) override; + mozilla::ipc::IPCResult RecvSetRenderingSurface( + const uintptr_t& aXWindow) override; private: RefPtr mVsyncObserver; diff --git a/widget/gtk/GtkCompositorWidget.cpp b/widget/gtk/GtkCompositorWidget.cpp index cd8ab7166eb2..bfd90cd642e4 100644 --- a/widget/gtk/GtkCompositorWidget.cpp +++ b/widget/gtk/GtkCompositorWidget.cpp @@ -6,9 +6,7 @@ #include "GtkCompositorWidget.h" #include "mozilla/gfx/gfxVars.h" -#include "mozilla/layers/CompositorThread.h" #include "mozilla/WidgetUtilsGtk.h" -#include "mozilla/widget/InProcessCompositorWidget.h" #include "mozilla/widget/PlatformWidgetTypes.h" #include "nsWindow.h" @@ -40,7 +38,7 @@ GtkCompositorWidget::GtkCompositorWidget( "GtkCompositorWidget::mClientSize") { #if defined(MOZ_X11) if (GdkIsX11Display()) { - ConfigureX11Backend((Window)aInitData.XWindow(), aInitData.Shaped()); + ConfigureX11Backend((Window)aInitData.XWindow()); LOG("GtkCompositorWidget::GtkCompositorWidget() [%p] mXWindow %p\n", (void*)mWidget.get(), (void*)aInitData.XWindow()); } @@ -176,19 +174,18 @@ void GtkCompositorWidget::ConfigureWaylandBackend() { #endif #if defined(MOZ_X11) -void GtkCompositorWidget::ConfigureX11Backend(Window aXWindow, bool aShaped) { +void GtkCompositorWidget::ConfigureX11Backend(Window aXWindow) { // We don't have X window yet. if (!aXWindow) { mProvider.CleanupResources(); return; } // Initialize the window surface provider - mProvider.Initialize(aXWindow, aShaped); + mProvider.Initialize(aXWindow); } #endif -void GtkCompositorWidget::SetRenderingSurface(const uintptr_t aXWindow, - const bool aShaped) { +void GtkCompositorWidget::SetRenderingSurface(const uintptr_t aXWindow) { LOG("GtkCompositorWidget::SetRenderingSurface() [%p]\n", mWidget.get()); #if defined(MOZ_WAYLAND) @@ -199,8 +196,8 @@ void GtkCompositorWidget::SetRenderingSurface(const uintptr_t aXWindow, #endif #if defined(MOZ_X11) if (GdkIsX11Display()) { - LOG(" configure XWindow %p shaped %d\n", (void*)aXWindow, aShaped); - ConfigureX11Backend((Window)aXWindow, aShaped); + LOG(" configure XWindow %p\n", (void*)aXWindow); + ConfigureX11Backend((Window)aXWindow); } #endif } diff --git a/widget/gtk/GtkCompositorWidget.h b/widget/gtk/GtkCompositorWidget.h index 8d56f35a561c..91bdcb463452 100644 --- a/widget/gtk/GtkCompositorWidget.h +++ b/widget/gtk/GtkCompositorWidget.h @@ -31,8 +31,7 @@ class PlatformCompositorWidgetDelegate : public CompositorWidgetDelegate { virtual GtkCompositorWidget* AsGtkCompositorWidget() { return nullptr; }; virtual void CleanupResources() = 0; - virtual void SetRenderingSurface(const uintptr_t aXWindow, - const bool aShaped) = 0; + virtual void SetRenderingSurface(const uintptr_t aXWindow) = 0; // CompositorWidgetDelegate Overrides @@ -79,8 +78,7 @@ class GtkCompositorWidget : public CompositorWidget, void CleanupResources() override; // Resume rendering with to given aXWindow (X11) or nsWindow (Wayland). - void SetRenderingSurface(const uintptr_t aXWindow, - const bool aShaped) override; + void SetRenderingSurface(const uintptr_t aXWindow) override; // If we fail to set window size (due to different screen scale or so) // we can't paint the frame by compositor. @@ -105,7 +103,7 @@ class GtkCompositorWidget : public CompositorWidget, void ConfigureWaylandBackend(); #endif #if defined(MOZ_X11) - void ConfigureX11Backend(Window aXWindow, bool aShaped); + void ConfigureX11Backend(Window aXWindow); #endif #ifdef MOZ_LOGGING bool IsPopup(); diff --git a/widget/gtk/MozContainer.cpp b/widget/gtk/MozContainer.cpp index 446dc97a66f6..fd0d9693f62d 100644 --- a/widget/gtk/MozContainer.cpp +++ b/widget/gtk/MozContainer.cpp @@ -171,10 +171,7 @@ void moz_container_realize(GtkWidget* widget) { attributes.wclass = GDK_INPUT_OUTPUT; attributes.window_type = GDK_WINDOW_CHILD; MozContainer* container = MOZ_CONTAINER(widget); - attributes.visual = - container->data.force_default_visual - ? gdk_screen_get_system_visual(gtk_widget_get_screen(widget)) - : gtk_widget_get_visual(widget); + attributes.visual = gtk_widget_get_visual(widget); window = gdk_window_new(parent, &attributes, attributes_mask); @@ -228,10 +225,6 @@ void moz_container_size_allocate(GtkWidget* widget, GtkAllocation* allocation) { } } -void moz_container_force_default_visual(MozContainer* container) { - container->data.force_default_visual = true; -} - nsWindow* moz_container_get_nsWindow(MozContainer* container) { gpointer user_data = g_object_get_data(G_OBJECT(container), "nsWindow"); return static_cast(user_data); diff --git a/widget/gtk/MozContainer.h b/widget/gtk/MozContainer.h index e6f9b4e99238..d3688569ec53 100644 --- a/widget/gtk/MozContainer.h +++ b/widget/gtk/MozContainer.h @@ -48,7 +48,6 @@ struct _MozContainer { GtkContainer container; gboolean destroyed; struct Data { - gboolean force_default_visual = false; #ifdef MOZ_WAYLAND MozContainerWayland wl_container; #endif @@ -64,7 +63,6 @@ GtkWidget* moz_container_new(void); void moz_container_unmap(GtkWidget* widget); void moz_container_put(MozContainer* container, GtkWidget* child_widget, gint x, gint y); -void moz_container_force_default_visual(MozContainer* container); void moz_container_class_init(MozContainerClass* klass); class nsWindow; diff --git a/widget/gtk/PCompositorWidget.ipdl b/widget/gtk/PCompositorWidget.ipdl index e083e8d4ef7a..2bd363e65cc5 100644 --- a/widget/gtk/PCompositorWidget.ipdl +++ b/widget/gtk/PCompositorWidget.ipdl @@ -23,7 +23,7 @@ parent: async NotifyClientSizeChanged(LayoutDeviceIntSize aClientSize); async CleanupResources(); - async SetRenderingSurface(uintptr_t aXWindow, bool aShaped); + async SetRenderingSurface(uintptr_t aXWindow); child: diff --git a/widget/gtk/PlatformWidgetTypes.ipdlh b/widget/gtk/PlatformWidgetTypes.ipdlh index c85da1711e92..bb7425f26012 100644 --- a/widget/gtk/PlatformWidgetTypes.ipdlh +++ b/widget/gtk/PlatformWidgetTypes.ipdlh @@ -17,7 +17,6 @@ struct GtkCompositorWidgetInitData { uintptr_t XWindow; nsCString XDisplayString; - bool Shaped; bool IsX11Display; LayoutDeviceIntSize InitialClientSize; diff --git a/widget/gtk/WindowSurfaceProvider.cpp b/widget/gtk/WindowSurfaceProvider.cpp index 204718bd4940..89f7ec8eabe8 100644 --- a/widget/gtk/WindowSurfaceProvider.cpp +++ b/widget/gtk/WindowSurfaceProvider.cpp @@ -46,7 +46,6 @@ WindowSurfaceProvider::WindowSurfaceProvider() mWindowSurfaceValid(false) #ifdef MOZ_X11 , - mIsShaped(false), mXDepth(0), mXWindow(0), mXVisual(nullptr) @@ -78,7 +77,7 @@ bool WindowSurfaceProvider::Initialize(GtkCompositorWidget* aCompositorWidget) { } #endif #ifdef MOZ_X11 -bool WindowSurfaceProvider::Initialize(Window aWindow, bool aIsShaped) { +bool WindowSurfaceProvider::Initialize(Window aWindow) { mWindowSurfaceValid = false; // Grab the window's visual and depth @@ -91,7 +90,6 @@ bool WindowSurfaceProvider::Initialize(Window aWindow, bool aIsShaped) { mXWindow = aWindow; mXVisual = windowAttrs.visual; mXDepth = windowAttrs.depth; - mIsShaped = aIsShaped; return true; } #endif @@ -106,7 +104,6 @@ void WindowSurfaceProvider::CleanupResources() { mXWindow = 0; mXVisual = 0; mXDepth = 0; - mIsShaped = false; #endif } @@ -130,7 +127,7 @@ RefPtr WindowSurfaceProvider::CreateWindowSurface() { // 1. MIT-SHM // 2. XPutImage # ifdef MOZ_HAVE_SHMIMAGE - if (!mIsShaped && nsShmImage::UseShm()) { + if (nsShmImage::UseShm()) { LOG(("Drawing to Window 0x%lx will use MIT-SHM\n", (Window)mXWindow)); return MakeRefPtr(DefaultXDisplay(), mXWindow, mXVisual, mXDepth); @@ -139,7 +136,7 @@ RefPtr WindowSurfaceProvider::CreateWindowSurface() { LOG(("Drawing to Window 0x%lx will use XPutImage\n", (Window)mXWindow)); return MakeRefPtr(DefaultXDisplay(), mXWindow, - mXVisual, mXDepth, mIsShaped); + mXVisual, mXDepth); } #endif MOZ_RELEASE_ASSERT(false); @@ -187,7 +184,7 @@ WindowSurfaceProvider::StartRemoteDrawingInRegion( gfxWarningOnce() << "Failed to lock WindowSurface, falling back to XPutImage backend."; mWindowSurface = MakeRefPtr( - DefaultXDisplay(), mXWindow, mXVisual, mXDepth, mIsShaped); + DefaultXDisplay(), mXWindow, mXVisual, mXDepth); dt = mWindowSurface->Lock(aInvalidRegion); } #endif diff --git a/widget/gtk/WindowSurfaceProvider.h b/widget/gtk/WindowSurfaceProvider.h index 44a0d78ec6f1..54d537657bf8 100644 --- a/widget/gtk/WindowSurfaceProvider.h +++ b/widget/gtk/WindowSurfaceProvider.h @@ -49,7 +49,7 @@ class WindowSurfaceProvider final { bool Initialize(GtkCompositorWidget* aCompositorWidget); #endif #ifdef MOZ_X11 - bool Initialize(Window aWindow, bool aIsShaped); + bool Initialize(Window aWindow); Window GetXWindow() const { return mXWindow; } #endif @@ -89,7 +89,6 @@ class WindowSurfaceProvider final { GtkCompositorWidget* mCompositorWidget = nullptr; #endif #ifdef MOZ_X11 - bool mIsShaped; int mXDepth; // Make mXWindow atomic to allow it read from different threads // and make tsan happy. diff --git a/widget/gtk/WindowSurfaceX11Image.cpp b/widget/gtk/WindowSurfaceX11Image.cpp index f797bfafad27..c32fe50e1bcf 100644 --- a/widget/gtk/WindowSurfaceX11Image.cpp +++ b/widget/gtk/WindowSurfaceX11Image.cpp @@ -29,33 +29,10 @@ using namespace mozilla::gfx; WindowSurfaceX11Image::WindowSurfaceX11Image(Display* aDisplay, Window aWindow, Visual* aVisual, - unsigned int aDepth, - bool aIsShaped) - : WindowSurfaceX11(aDisplay, aWindow, aVisual, aDepth), - mTransparencyBitmap(nullptr), - mTransparencyBitmapWidth(0), - mTransparencyBitmapHeight(0), - mIsShaped(aIsShaped), - mWindowParent(0) { - if (!mIsShaped) { - return; - } + unsigned int aDepth) + : WindowSurfaceX11(aDisplay, aWindow, aVisual, aDepth) {} - Window root, *children = nullptr; - unsigned int childrenNum; - if (XQueryTree(mDisplay, mWindow, &root, &mWindowParent, &children, - &childrenNum)) { - if (children) { - XFree((char*)children); - } - } -} - -WindowSurfaceX11Image::~WindowSurfaceX11Image() { - if (mTransparencyBitmap) { - delete[] mTransparencyBitmap; - } -} +WindowSurfaceX11Image::~WindowSurfaceX11Image() {} already_AddRefed WindowSurfaceX11Image::Lock( const LayoutDeviceIntRegion& aRegion) { @@ -78,13 +55,6 @@ already_AddRefed WindowSurfaceX11Image::Lock( : gfx::SurfaceFormat::X8R8G8B8_UINT32; } - // Use alpha image format for shaped window as we derive - // the shape bitmap from alpha channel. Must match SHAPED_IMAGE_SURFACE_BPP - // and SHAPED_IMAGE_SURFACE_ALPHA_INDEX. - if (mIsShaped) { - format = gfx::SurfaceFormat::A8R8G8B8_UINT32; - } - mImageSurface = new gfxImageSurface(size, format); if (mImageSurface->CairoStatus()) { return nullptr; @@ -112,122 +82,6 @@ already_AddRefed WindowSurfaceX11Image::Lock( ImageFormatToSurfaceFormat(format)); } -// The transparency bitmap routines are derived form the ones at nsWindow.cpp. -// The difference here is that we compose to RGBA image and then create -// the shape mask from final image alpha channel. -static inline int32_t GetBitmapStride(int32_t width) { return (width + 7) / 8; } - -static bool ChangedMaskBits(gchar* aMaskBits, int32_t aMaskWidth, - int32_t aMaskHeight, const nsIntRect& aRect, - uint8_t* aImageData) { - int32_t stride = aMaskWidth * SHAPED_IMAGE_SURFACE_BPP; - int32_t x, y, xMax = aRect.XMost(), yMax = aRect.YMost(); - int32_t maskBytesPerRow = GetBitmapStride(aMaskWidth); - for (y = aRect.y; y < yMax; y++) { - gchar* maskBytes = aMaskBits + y * maskBytesPerRow; - uint8_t* alphas = aImageData; - for (x = aRect.x; x < xMax; x++) { - bool newBit = *(alphas + SHAPED_IMAGE_SURFACE_ALPHA_INDEX) > 0x7f; - alphas += SHAPED_IMAGE_SURFACE_BPP; - - gchar maskByte = maskBytes[x >> 3]; - bool maskBit = (maskByte & (1 << (x & 7))) != 0; - - if (maskBit != newBit) { - return true; - } - } - aImageData += stride; - } - - return false; -} - -static void UpdateMaskBits(gchar* aMaskBits, int32_t aMaskWidth, - int32_t aMaskHeight, const nsIntRect& aRect, - uint8_t* aImageData) { - int32_t stride = aMaskWidth * SHAPED_IMAGE_SURFACE_BPP; - int32_t x, y, xMax = aRect.XMost(), yMax = aRect.YMost(); - int32_t maskBytesPerRow = GetBitmapStride(aMaskWidth); - for (y = aRect.y; y < yMax; y++) { - gchar* maskBytes = aMaskBits + y * maskBytesPerRow; - uint8_t* alphas = aImageData; - for (x = aRect.x; x < xMax; x++) { - bool newBit = *(alphas + SHAPED_IMAGE_SURFACE_ALPHA_INDEX) > 0x7f; - alphas += SHAPED_IMAGE_SURFACE_BPP; - - gchar mask = 1 << (x & 7); - gchar maskByte = maskBytes[x >> 3]; - // Note: '-newBit' turns 0 into 00...00 and 1 into 11...11 - maskBytes[x >> 3] = (maskByte & ~mask) | (-newBit & mask); - } - aImageData += stride; - } -} - -void WindowSurfaceX11Image::ResizeTransparencyBitmap(int aWidth, int aHeight) { - int32_t actualSize = - GetBitmapStride(mTransparencyBitmapWidth) * mTransparencyBitmapHeight; - int32_t newSize = GetBitmapStride(aWidth) * aHeight; - - if (actualSize < newSize) { - delete[] mTransparencyBitmap; - mTransparencyBitmap = new gchar[newSize]; - } - - mTransparencyBitmapWidth = aWidth; - mTransparencyBitmapHeight = aHeight; -} - -void WindowSurfaceX11Image::ApplyTransparencyBitmap() { - gfx::IntSize size = mWindowSurface->GetSize(); - bool maskChanged = true; - - if (!mTransparencyBitmap) { - mTransparencyBitmapWidth = size.width; - mTransparencyBitmapHeight = size.height; - - int32_t byteSize = - GetBitmapStride(mTransparencyBitmapWidth) * mTransparencyBitmapHeight; - mTransparencyBitmap = new gchar[byteSize]; - } else { - bool sizeChanged = (size.width != mTransparencyBitmapWidth || - size.height != mTransparencyBitmapHeight); - - if (sizeChanged) { - ResizeTransparencyBitmap(size.width, size.height); - } else { - maskChanged = ChangedMaskBits( - mTransparencyBitmap, mTransparencyBitmapWidth, - mTransparencyBitmapHeight, nsIntRect(0, 0, size.width, size.height), - (uint8_t*)mImageSurface->Data()); - } - } - - if (maskChanged) { - UpdateMaskBits(mTransparencyBitmap, mTransparencyBitmapWidth, - mTransparencyBitmapHeight, - nsIntRect(0, 0, size.width, size.height), - (uint8_t*)mImageSurface->Data()); - - // We use X11 calls where possible, because GDK handles expose events - // for shaped windows in a way that's incompatible with us (Bug 635903). - // It doesn't occur when the shapes are set through X. - Display* xDisplay = mWindowSurface->XDisplay(); - Window xDrawable = mWindowSurface->XDrawable(); - Pixmap maskPixmap = XCreateBitmapFromData( - xDisplay, xDrawable, mTransparencyBitmap, mTransparencyBitmapWidth, - mTransparencyBitmapHeight); - XShapeCombineMask(xDisplay, xDrawable, ShapeBounding, 0, 0, maskPixmap, - ShapeSet); - if (mWindowParent) { - XShapeCombineMask(mDisplay, mWindowParent, ShapeBounding, 0, 0, - maskPixmap, ShapeSet); - } - XFreePixmap(xDisplay, maskPixmap); - } -} - void WindowSurfaceX11Image::Commit( const LayoutDeviceIntRegion& aInvalidRegion) { RefPtr dt = gfx::Factory::CreateDrawTargetForCairoSurface( @@ -245,10 +99,6 @@ void WindowSurfaceX11Image::Commit( return; } - if (mIsShaped) { - ApplyTransparencyBitmap(); - } - uint32_t numRects = aInvalidRegion.GetNumRects(); if (numRects == 1) { dt->CopySurface(surf, bounds, bounds.TopLeft()); diff --git a/widget/gtk/WindowSurfaceX11Image.h b/widget/gtk/WindowSurfaceX11Image.h index 281199b5dd57..84ceb2d33afb 100644 --- a/widget/gtk/WindowSurfaceX11Image.h +++ b/widget/gtk/WindowSurfaceX11Image.h @@ -20,7 +20,7 @@ namespace widget { class WindowSurfaceX11Image : public WindowSurfaceX11 { public: WindowSurfaceX11Image(Display* aDisplay, Window aWindow, Visual* aVisual, - unsigned int aDepth, bool aIsShaped); + unsigned int aDepth); ~WindowSurfaceX11Image(); already_AddRefed Lock( @@ -29,17 +29,8 @@ class WindowSurfaceX11Image : public WindowSurfaceX11 { bool IsFallback() const override { return true; } private: - void ResizeTransparencyBitmap(int aWidth, int aHeight); - void ApplyTransparencyBitmap(); - RefPtr mWindowSurface; RefPtr mImageSurface; - - gchar* mTransparencyBitmap; - int32_t mTransparencyBitmapWidth; - int32_t mTransparencyBitmapHeight; - bool mIsShaped; - Window mWindowParent; }; } // namespace widget diff --git a/widget/gtk/nsLookAndFeel.cpp b/widget/gtk/nsLookAndFeel.cpp index 1e73b09a2530..8a2ff98a6f7d 100644 --- a/widget/gtk/nsLookAndFeel.cpp +++ b/widget/gtk/nsLookAndFeel.cpp @@ -978,6 +978,12 @@ nsresult nsLookAndFeel::NativeGetInt(IntID aID, int32_t& aResult) { case IntID::GTKCSDAvailable: aResult = sCSDAvailable; break; + case IntID::GTKCSDTransparencyAvailable: { + auto* screen = gdk_screen_get_default(); + aResult = gdk_screen_get_rgba_visual(screen) && + gdk_screen_is_composited(screen); + break; + } case IntID::GTKCSDMaximizeButton: EnsureInit(); aResult = mCSDMaximizeButton; diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 770ba273c61c..7cf7d95d5c86 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -343,14 +343,6 @@ static GdkCursor* gCursorCache[eCursorCount]; // only the button state bits are used. static guint gButtonState; -static inline int32_t GetBitmapStride(int32_t width) { -#if defined(MOZ_X11) - return (width + 7) / 8; -#else - return cairo_format_stride_for_width(CAIRO_FORMAT_A1, width); -#endif -} - static inline bool TimestampIsNewerThan(guint32 a, guint32 b) { // Timestamps are just the least significant bits of a monotonically // increasing function, and so the use of unsigned overflow arithmetic. @@ -415,7 +407,6 @@ nsWindow::nsWindow() mPopupTrackInHierarchy(false), mPopupTrackInHierarchyConfigured(false), mHiddenPopupPositioned(false), - mTransparencyBitmapForTitlebar(false), mHasAlphaVisual(false), mPopupAnchored(false), mPopupContextMenu(false), @@ -611,8 +602,6 @@ void nsWindow::Destroy() { MOZ_ASSERT(!gtk_widget_get_mapped(mShell)); MOZ_ASSERT(!gtk_widget_get_mapped(GTK_WIDGET(mContainer))); - ClearTransparencyBitmap(); - DestroyLayerManager(); // mSurfaceProvider holds reference to this nsWindow so we need to explicitly @@ -3888,27 +3877,6 @@ gboolean nsWindow::OnExposeEvent(cairo_t* cr) { // to the new bounds here. The region is relative to this // window. region.And(region, LayoutDeviceIntRect(0, 0, mBounds.width, mBounds.height)); - - bool shaped = false; - if (TransparencyMode::Transparent == GetTransparencyMode()) { - auto* window = static_cast(GetTopLevelWidget()); - if (mTransparencyBitmapForTitlebar) { - if (mSizeMode == nsSizeMode_Normal) { - window->UpdateTitlebarTransparencyBitmap(); - } else { - window->ClearTransparencyBitmap(); - } - } else { - if (mHasAlphaVisual) { - // Remove possible shape mask from when window manger was not - // previously compositing. - window->ClearTransparencyBitmap(); - } else { - shaped = true; - } - } - } - if (region.IsEmpty()) { LOG("quit, region.IsEmpty()"); return TRUE; @@ -3944,28 +3912,8 @@ gboolean nsWindow::OnExposeEvent(cairo_t* cr) { } #ifdef MOZ_X11 - if (shaped) { - // Collapse update area to the bounding box. This is so we only have to - // call UpdateTranslucentWindowAlpha once. After we have dropped - // support for non-Thebes graphics, UpdateTranslucentWindowAlpha will be - // our private interface so we can rework things to avoid this. - dt->PushClipRect(Rect(boundsRect)); - - // The double buffering is done here to extract the shape mask. - // (The shape mask won't be necessary when a visual with an alpha - // channel is used on compositing window managers.) - layerBuffering = BufferMode::BUFFER_NONE; - RefPtr destDT = - dt->CreateSimilarDrawTarget(boundsRect.Size(), SurfaceFormat::B8G8R8A8); - if (!destDT || !destDT->IsValid()) { - return FALSE; - } - destDT->SetTransform(Matrix::Translation(-boundsRect.TopLeft())); - ctx.emplace(destDT, /* aPreserveTransform */ true); - } else { - gfxUtils::ClipToRegion(dt, region.ToUnknownRegion()); - ctx.emplace(dt, /* aPreserveTransform */ true); - } + gfxUtils::ClipToRegion(dt, region.ToUnknownRegion()); + ctx.emplace(dt, /* aPreserveTransform */ true); # if 0 // NOTE: Paint flashing region would be wrong for cairo, since @@ -3980,7 +3928,6 @@ gboolean nsWindow::OnExposeEvent(cairo_t* cr) { #endif // MOZ_X11 - bool painted = false; { if (renderer->GetBackendType() == LayersBackend::LAYERS_NONE) { if (GetTransparencyMode() == TransparencyMode::Transparent && @@ -3992,7 +3939,7 @@ gboolean nsWindow::OnExposeEvent(cairo_t* cr) { } AutoLayerManagerSetup setupLayerManager( this, ctx.isNothing() ? nullptr : &ctx.ref(), layerBuffering); - painted = listener->PaintWindow(this, region); + listener->PaintWindow(this, region); // Re-get the listener since the will paint notification might have // killed it. @@ -4004,26 +3951,8 @@ gboolean nsWindow::OnExposeEvent(cairo_t* cr) { } #ifdef MOZ_X11 - // PaintWindow can Destroy us (bug 378273), avoid doing any paint - // operations below if that happened - it will lead to XError and exit(). - if (shaped) { - if (MOZ_LIKELY(!mIsDestroyed)) { - if (painted) { - RefPtr surf = ctx->GetDrawTarget()->Snapshot(); - - UpdateAlpha(surf, boundsRect); - - dt->DrawSurface(surf, Rect(boundsRect), - Rect(0, 0, boundsRect.width, boundsRect.height), - DrawSurfaceOptions(SamplingFilter::POINT), - DrawOptions(1.0f, CompositionOp::OP_SOURCE)); - } - } - } - ctx.reset(); dt->PopClip(); - #endif // MOZ_X11 EndRemoteDrawingInRegion(dt, region); @@ -4043,33 +3972,6 @@ gboolean nsWindow::OnExposeEvent(cairo_t* cr) { return TRUE; } -void nsWindow::UpdateAlpha(SourceSurface* aSourceSurface, - nsIntRect aBoundsRect) { - // We need to create our own buffer to force the stride to match the - // expected stride. - int32_t stride = - GetAlignedStride<4>(aBoundsRect.width, BytesPerPixel(SurfaceFormat::A8)); - if (stride == 0) { - return; - } - int32_t bufferSize = stride * aBoundsRect.height; - auto imageBuffer = MakeUniqueFallible(bufferSize); - { - RefPtr drawTarget = gfxPlatform::CreateDrawTargetForData( - imageBuffer.get(), aBoundsRect.Size(), stride, SurfaceFormat::A8); - - if (drawTarget) { - drawTarget->DrawSurface(aSourceSurface, - Rect(0, 0, aBoundsRect.width, aBoundsRect.height), - Rect(0, 0, aSourceSurface->GetSize().width, - aSourceSurface->GetSize().height), - DrawSurfaceOptions(SamplingFilter::POINT), - DrawOptions(1.0f, CompositionOp::OP_SOURCE)); - } - } - UpdateTranslucentWindowAlphaInternal(aBoundsRect, imageBuffer.get(), stride); -} - gboolean nsWindow::OnConfigureEvent(GtkWidget* aWidget, GdkEventConfigure* aEvent) { // These events are only received on toplevel windows. @@ -5400,14 +5302,6 @@ void nsWindow::OnWindowStateEvent(GtkWidget* aWidget, if (mWidgetListener && mSizeMode != oldSizeMode) { mWidgetListener->SizeModeChanged(mSizeMode); } - - if (mDrawInTitlebar && mTransparencyBitmapForTitlebar) { - if (mSizeMode == nsSizeMode_Normal && !mIsTiled) { - UpdateTitlebarTransparencyBitmap(); - } else { - ClearTransparencyBitmap(); - } - } } void nsWindow::OnDPIChanged() { @@ -5850,10 +5744,6 @@ void nsWindow::EnsureGdkWindow() { } } -bool nsWindow::GetShapedState() { - return mIsTransparent && !mHasAlphaVisual && !mTransparencyBitmapForTitlebar; -} - void nsWindow::ConfigureCompositor() { MOZ_DIAGNOSTIC_ASSERT(mIsMapped); MOZ_DIAGNOSTIC_ASSERT(mCompositorState == COMPOSITOR_ENABLED); @@ -6049,21 +5939,11 @@ nsresult nsWindow::Create(nsIWidget* aParent, nsNativeWidget aNativeParent, } } - // Use X shape mask to draw round corners of Firefox titlebar. - // We don't use shape masks any more as we switched to ARGB visual - // by default and non-compositing screens use solid-csd decorations - // without round corners. - // Leave the shape mask code here as it can be used to draw round - // corners on EGL (https://gitlab.freedesktop.org/mesa/mesa/-/issues/149) - // or when custom titlebar theme is used. - mTransparencyBitmapForTitlebar = TitlebarUseShapeMask(); - // We have a toplevel window with transparency. // Calls to UpdateTitlebarTransparencyBitmap() from OnExposeEvent() // occur before SetTransparencyMode() receives TransparencyMode::Transparent // from layout, so set mIsTransparent here. - if (mWindowType == WindowType::TopLevel && - (mHasAlphaVisual || mTransparencyBitmapForTitlebar)) { + if (mWindowType == WindowType::TopLevel && mHasAlphaVisual) { mIsTransparent = true; } @@ -6207,10 +6087,6 @@ nsresult nsWindow::Create(nsIWidget* aParent, nsNativeWidget aNativeParent, gtk_widget_set_app_paintable( mShell, StaticPrefs::widget_transparent_windows_AtStartup()); - if (mTransparencyBitmapForTitlebar) { - moz_container_force_default_visual(mContainer); - } - // If we draw to mContainer window then configure it now because // gtk_container_add() realizes the child widget. gtk_widget_set_has_window(container, true); @@ -6671,8 +6547,7 @@ void nsWindow::ResumeCompositorImpl() { LOG("nsWindow::ResumeCompositorImpl()\n"); MOZ_DIAGNOSTIC_ASSERT(mCompositorWidgetDelegate); - mCompositorWidgetDelegate->SetRenderingSurface(GetX11Window(), - GetShapedState()); + mCompositorWidgetDelegate->SetRenderingSurface(GetX11Window()); // As WaylandStartVsync needs mCompositorWidgetDelegate this is the right // time to start it. @@ -6817,8 +6692,6 @@ void nsWindow::NativeShow(bool aAction) { mPendingConfigures = 0; } gtk_widget_hide(mShell); - - ClearTransparencyBitmap(); // Release some resources } } } @@ -6861,7 +6734,7 @@ LayoutDeviceIntSize nsWindow::GetSafeWindowSize(LayoutDeviceIntSize aSize) { } void nsWindow::SetTransparencyMode(TransparencyMode aMode) { - bool isTransparent = aMode == TransparencyMode::Transparent; + const bool isTransparent = aMode == TransparencyMode::Transparent; if (mIsTransparent == isTransparent) { return; @@ -6878,11 +6751,6 @@ void nsWindow::SetTransparencyMode(TransparencyMode aMode) { return; } - if (!isTransparent) { - ClearTransparencyBitmap(); - } // else the new default alpha values are "all 1", so we don't - // need to change anything yet - mIsTransparent = isTransparent; if (!mHasAlphaVisual) { @@ -7068,247 +6936,6 @@ bool nsWindow::DoDrawTilebarCorners() { !mIsTiled; } -void nsWindow::ResizeTransparencyBitmap() { - if (!mTransparencyBitmap) { - return; - } - - if (mBounds.width == mTransparencyBitmapWidth && - mBounds.height == mTransparencyBitmapHeight) { - return; - } - - int32_t newRowBytes = GetBitmapStride(mBounds.width); - int32_t newSize = newRowBytes * mBounds.height; - auto* newBits = new gchar[newSize]; - // fill new mask with "transparent", first - memset(newBits, 0, newSize); - - // Now copy the intersection of the old and new areas into the new mask - int32_t copyWidth = std::min(mBounds.width, mTransparencyBitmapWidth); - int32_t copyHeight = std::min(mBounds.height, mTransparencyBitmapHeight); - int32_t oldRowBytes = GetBitmapStride(mTransparencyBitmapWidth); - int32_t copyBytes = GetBitmapStride(copyWidth); - - int32_t i; - gchar* fromPtr = mTransparencyBitmap; - gchar* toPtr = newBits; - for (i = 0; i < copyHeight; i++) { - memcpy(toPtr, fromPtr, copyBytes); - fromPtr += oldRowBytes; - toPtr += newRowBytes; - } - - delete[] mTransparencyBitmap; - mTransparencyBitmap = newBits; - mTransparencyBitmapWidth = mBounds.width; - mTransparencyBitmapHeight = mBounds.height; -} - -static bool ChangedMaskBits(gchar* aMaskBits, int32_t aMaskWidth, - int32_t aMaskHeight, const nsIntRect& aRect, - uint8_t* aAlphas, int32_t aStride) { - int32_t x, y, xMax = aRect.XMost(), yMax = aRect.YMost(); - int32_t maskBytesPerRow = GetBitmapStride(aMaskWidth); - for (y = aRect.y; y < yMax; y++) { - gchar* maskBytes = aMaskBits + y * maskBytesPerRow; - uint8_t* alphas = aAlphas; - for (x = aRect.x; x < xMax; x++) { - bool newBit = *alphas > 0x7f; - alphas++; - - gchar maskByte = maskBytes[x >> 3]; - bool maskBit = (maskByte & (1 << (x & 7))) != 0; - - if (maskBit != newBit) { - return true; - } - } - aAlphas += aStride; - } - - return false; -} - -static void UpdateMaskBits(gchar* aMaskBits, int32_t aMaskWidth, - int32_t aMaskHeight, const nsIntRect& aRect, - uint8_t* aAlphas, int32_t aStride) { - int32_t x, y, xMax = aRect.XMost(), yMax = aRect.YMost(); - int32_t maskBytesPerRow = GetBitmapStride(aMaskWidth); - for (y = aRect.y; y < yMax; y++) { - gchar* maskBytes = aMaskBits + y * maskBytesPerRow; - uint8_t* alphas = aAlphas; - for (x = aRect.x; x < xMax; x++) { - bool newBit = *alphas > 0x7f; - alphas++; - - gchar mask = 1 << (x & 7); - gchar maskByte = maskBytes[x >> 3]; - // Note: '-newBit' turns 0 into 00...00 and 1 into 11...11 - maskBytes[x >> 3] = (maskByte & ~mask) | (-newBit & mask); - } - aAlphas += aStride; - } -} - -void nsWindow::ApplyTransparencyBitmap() { -#ifdef MOZ_X11 - // We use X11 calls where possible, because GDK handles expose events - // for shaped windows in a way that's incompatible with us (Bug 635903). - // It doesn't occur when the shapes are set through X. - Display* xDisplay = GDK_WINDOW_XDISPLAY(mGdkWindow); - Window xDrawable = GDK_WINDOW_XID(mGdkWindow); - Pixmap maskPixmap = XCreateBitmapFromData( - xDisplay, xDrawable, mTransparencyBitmap, mTransparencyBitmapWidth, - mTransparencyBitmapHeight); - XShapeCombineMask(xDisplay, xDrawable, ShapeBounding, 0, 0, maskPixmap, - ShapeSet); - XFreePixmap(xDisplay, maskPixmap); -#endif // MOZ_X11 -} - -void nsWindow::ClearTransparencyBitmap() { - if (!mTransparencyBitmap) { - return; - } - - delete[] mTransparencyBitmap; - mTransparencyBitmap = nullptr; - mTransparencyBitmapWidth = 0; - mTransparencyBitmapHeight = 0; - - if (!mShell) { - return; - } - -#ifdef MOZ_X11 - if (MOZ_UNLIKELY(!mGdkWindow)) { - return; - } - - Display* xDisplay = GDK_WINDOW_XDISPLAY(mGdkWindow); - Window xWindow = gdk_x11_window_get_xid(mGdkWindow); - - XShapeCombineMask(xDisplay, xWindow, ShapeBounding, 0, 0, X11None, ShapeSet); -#endif -} - -nsresult nsWindow::UpdateTranslucentWindowAlphaInternal(const nsIntRect& aRect, - uint8_t* aAlphas, - int32_t aStride) { - NS_ASSERTION(mIsTransparent, "Window is not transparent"); - NS_ASSERTION(!mTransparencyBitmapForTitlebar, - "Transparency bitmap is already used for titlebar rendering"); - - if (mTransparencyBitmap == nullptr) { - int32_t size = GetBitmapStride(mBounds.width) * mBounds.height; - mTransparencyBitmap = new gchar[size]; - memset(mTransparencyBitmap, 255, size); - mTransparencyBitmapWidth = mBounds.width; - mTransparencyBitmapHeight = mBounds.height; - } else { - ResizeTransparencyBitmap(); - } - - nsIntRect rect; - rect.IntersectRect(aRect, nsIntRect(0, 0, mBounds.width, mBounds.height)); - - if (!ChangedMaskBits(mTransparencyBitmap, mBounds.width, mBounds.height, rect, - aAlphas, aStride)) { - // skip the expensive stuff if the mask bits haven't changed; hopefully - // this is the common case - return NS_OK; - } - - UpdateMaskBits(mTransparencyBitmap, mBounds.width, mBounds.height, rect, - aAlphas, aStride); - - if (!mNeedsShow) { - ApplyTransparencyBitmap(); - } - return NS_OK; -} - -void nsWindow::UpdateTitlebarTransparencyBitmap() { - NS_ASSERTION(mTransparencyBitmapForTitlebar, - "Transparency bitmap is already used to draw window shape"); - - if (!mGdkWindow || !mDrawInTitlebar || - (mBounds.width == mTransparencyBitmapWidth && - mBounds.height == mTransparencyBitmapHeight)) { - return; - } - - bool maskCreate = - !mTransparencyBitmap || mBounds.width > mTransparencyBitmapWidth; - - bool maskUpdate = - !mTransparencyBitmap || mBounds.width != mTransparencyBitmapWidth; - - LayoutDeviceIntCoord radius = GetTitlebarRadius(); - if (maskCreate) { - delete[] mTransparencyBitmap; - int32_t size = GetBitmapStride(mBounds.width) * radius; - mTransparencyBitmap = new gchar[size]; - mTransparencyBitmapWidth = mBounds.width; - } else { - mTransparencyBitmapWidth = mBounds.width; - } - mTransparencyBitmapHeight = mBounds.height; - - if (maskUpdate) { - cairo_surface_t* surface = cairo_image_surface_create( - CAIRO_FORMAT_A8, mTransparencyBitmapWidth, radius); - if (!surface) { - return; - } - - cairo_t* cr = cairo_create(surface); - - GtkWidgetState state; - memset((void*)&state, 0, sizeof(state)); - GdkRectangle rect = {0, 0, mTransparencyBitmapWidth, radius}; - - moz_gtk_widget_paint(MOZ_GTK_HEADER_BAR, cr, &rect, &state, 0, - GTK_TEXT_DIR_NONE); - - cairo_destroy(cr); - cairo_surface_mark_dirty(surface); - cairo_surface_flush(surface); - - UpdateMaskBits(mTransparencyBitmap, mTransparencyBitmapWidth, radius, - nsIntRect(0, 0, mTransparencyBitmapWidth, radius), - cairo_image_surface_get_data(surface), - cairo_format_stride_for_width(CAIRO_FORMAT_A8, - mTransparencyBitmapWidth)); - - cairo_surface_destroy(surface); - } - -#ifdef MOZ_X11 - if (!mNeedsShow) { - Display* xDisplay = GDK_WINDOW_XDISPLAY(mGdkWindow); - Window xDrawable = GDK_WINDOW_XID(mGdkWindow); - - Pixmap maskPixmap = - XCreateBitmapFromData(xDisplay, xDrawable, mTransparencyBitmap, - mTransparencyBitmapWidth, radius); - - XShapeCombineMask(xDisplay, xDrawable, ShapeBounding, 0, 0, maskPixmap, - ShapeSet); - - if (mTransparencyBitmapHeight > radius) { - XRectangle rect = {0, 0, (unsigned short)mTransparencyBitmapWidth, - (unsigned short)(mTransparencyBitmapHeight - radius)}; - XShapeCombineRectangles(xDisplay, xDrawable, ShapeBounding, 0, radius, - &rect, 1, ShapeUnion, 0); - } - - XFreePixmap(xDisplay, maskPixmap); - } -#endif -} - GtkWidget* nsWindow::GetToplevelWidget() const { return mShell; } GdkWindow* nsWindow::GetToplevelGdkWindow() const { @@ -9215,14 +8842,6 @@ void nsWindow::SetDrawsInTitlebar(bool aState) { gtk_widget_destroy(tmpWindow); } - if (mTransparencyBitmapForTitlebar) { - if (mDrawInTitlebar && mSizeMode == nsSizeMode_Normal && !mIsTiled) { - UpdateTitlebarTransparencyBitmap(); - } else { - ClearTransparencyBitmap(); - } - } - // Recompute the input region (which should generally be null, but this is // enough to work around bug 1844497, which is probably a gtk bug). SetInputRegion(mInputRegion); @@ -9685,24 +9304,6 @@ nsWindow::GtkWindowDecoration nsWindow::GetSystemGtkWindowDecoration() { return sGtkWindowDecoration; } -bool nsWindow::TitlebarUseShapeMask() { - static int useShapeMask = []() { - // Don't use titlebar shape mask on Wayland - if (!GdkIsX11Display()) { - return false; - } - - // We can't use shape masks on Mutter/X.org as we can't resize Firefox - // window there (Bug 1530252). - if (IsGnomeDesktopEnvironment()) { - return false; - } - - return Preferences::GetBool("widget.titlebar-x11-use-shape-mask", false); - }(); - return useShapeMask; -} - int32_t nsWindow::RoundsWidgetCoordinatesTo() { return GdkCeiledScaleFactor(); } void nsWindow::GetCompositorWidgetInitData( @@ -9723,8 +9324,7 @@ void nsWindow::GetCompositorWidgetInitData( } #endif *aInitData = mozilla::widget::GtkCompositorWidgetInitData( - window, displayName, GetShapedState(), GdkIsX11Display(), - GetClientSize()); + window, displayName, GdkIsX11Display(), GetClientSize()); #ifdef MOZ_X11 if (GdkIsX11Display()) { @@ -10083,7 +9683,7 @@ void nsWindow::OnMap() { #ifdef MOZ_X11 if (GdkIsX11Display()) { - mSurfaceProvider.Initialize(GetX11Window(), GetShapedState()); + mSurfaceProvider.Initialize(GetX11Window()); // Set window manager hint to keep fullscreen windows composited. // diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h index d3526eebf66a..a0de5a1dbd4f 100644 --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -319,21 +319,11 @@ class nsWindow final : public nsBaseWidget { const mozilla::WidgetKeyboardEvent& aEvent, nsTArray& aCommands) override; - // These methods are for toplevel windows only. - void ResizeTransparencyBitmap(); - void ApplyTransparencyBitmap(); - void ClearTransparencyBitmap(); - void SetTransparencyMode(TransparencyMode aMode) override; TransparencyMode GetTransparencyMode() override; void SetInputRegion(const InputRegion&) override; - nsresult UpdateTranslucentWindowAlphaInternal(const nsIntRect& aRect, - uint8_t* aAlphas, - int32_t aStride); void ReparentNativeWidget(nsIWidget* aNewParent) override; - void UpdateTitlebarTransparencyBitmap(); - nsresult SynthesizeNativeMouseEvent(LayoutDeviceIntPoint aPoint, NativeMouseMessage aNativeMessage, mozilla::MouseButton aButton, @@ -417,8 +407,7 @@ class nsWindow final : public nsBaseWidget { */ static GtkWindowDecoration GetSystemGtkWindowDecoration(); - static bool TitlebarUseShapeMask(); - bool IsRemoteContent() { return HasRemoteContent(); } + bool IsRemoteContent() const { return HasRemoteContent(); } void NativeMoveResizeWaylandPopupCallback(const GdkRectangle* aFinalSize, bool aFlippedX, bool aFlippedY); static bool IsToplevelWindowTransparent(); @@ -495,9 +484,6 @@ class nsWindow final : public nsBaseWidget { mozilla::Atomic mCeiledScaleFactor{1}; double mFractionalScaleFactor = 0.0; - void UpdateAlpha(mozilla::gfx::SourceSurface* aSourceSurface, - nsIntRect aBoundsRect); - void NativeMoveResize(bool aMoved, bool aResized); void NativeShow(bool aAction); @@ -519,7 +505,6 @@ class nsWindow final : public nsBaseWidget { GtkWidget* GetToplevelWidget() const; nsWindow* GetContainerWindow() const; Window GetX11Window(); - bool GetShapedState(); void EnsureGdkWindow(); void SetUrgencyHint(GtkWidget* top_window, bool state); void SetDefaultIcon(void); @@ -729,10 +714,6 @@ class nsWindow final : public nsBaseWidget { */ bool mHiddenPopupPositioned : 1; - // The transparency bitmap is used instead of ARGB visual for toplevel - // window to draw titlebar. - bool mTransparencyBitmapForTitlebar : 1; - // True when we're on compositing window manager and this // window is using visual with alpha channel. bool mHasAlphaVisual : 1; @@ -795,13 +776,6 @@ class nsWindow final : public nsBaseWidget { // Whether we need to retry capturing the mouse because we' re not mapped yet. bool mNeedsToRetryCapturingMouse : 1; - // This bitmap tracks which pixels are transparent. We don't support - // full translucency at this time; each pixel is either fully opaque - // or fully transparent. - gchar* mTransparencyBitmap = nullptr; - int32_t mTransparencyBitmapWidth = 0; - int32_t mTransparencyBitmapHeight = 0; - // all of our DND stuff void InitDragEvent(mozilla::WidgetDragEvent& aEvent); diff --git a/widget/nsXPLookAndFeel.cpp b/widget/nsXPLookAndFeel.cpp index 8f36a5e8c23f..41663c5d755b 100644 --- a/widget/nsXPLookAndFeel.cpp +++ b/widget/nsXPLookAndFeel.cpp @@ -168,6 +168,7 @@ static const char sIntPrefs[][45] = { "ui.contextMenuOffsetHorizontal", "ui.tooltipOffsetVertical", "ui.GtkCSDAvailable", + "ui.GtkCSDTransparencyAvailable", "ui.GtkCSDMinimizeButton", "ui.GtkCSDMaximizeButton", "ui.GtkCSDCloseButton", diff --git a/xpcom/ds/StaticAtoms.py b/xpcom/ds/StaticAtoms.py index 3dd62646a885..27f3e9cf3ff2 100644 --- a/xpcom/ds/StaticAtoms.py +++ b/xpcom/ds/StaticAtoms.py @@ -2277,6 +2277,7 @@ STATIC_ATOMS = [ Atom("_moz_is_resource_document", "-moz-is-resource-document"), Atom("_moz_swipe_animation_enabled", "-moz-swipe-animation-enabled"), Atom("_moz_gtk_csd_available", "-moz-gtk-csd-available"), + Atom("_moz_gtk_csd_transparency_available", "-moz-gtk-csd-transparency-available"), Atom("_moz_gtk_csd_titlebar_radius", "-moz-gtk-csd-titlebar-radius"), Atom("_moz_gtk_csd_titlebar_button_spacing", "-moz-gtk-csd-titlebar-button-spacing"), Atom("_moz_gtk_csd_minimize_button", "-moz-gtk-csd-minimize-button"),