зеркало из https://github.com/mozilla/gecko-dev.git
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
This commit is contained in:
Родитель
89fbad696d
Коммит
6073058701
|
@ -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.
|
||||
|
|
|
@ -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-available)) {
|
||||
--panel-shadow-margin: 0px !important;
|
||||
--panel-border-radius: 0px !important;
|
||||
}
|
||||
|
||||
@media (-moz-platform: macos) {
|
||||
appearance: auto;
|
||||
-moz-default-appearance: menupopup;
|
||||
|
|
|
@ -14,7 +14,8 @@ CompositorWidgetChild::CompositorWidgetChild(
|
|||
RefPtr<CompositorVsyncDispatcher> aVsyncDispatcher,
|
||||
RefPtr<CompositorWidgetVsyncObserver> 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
|
||||
|
|
|
@ -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<CompositorVsyncDispatcher> mVsyncDispatcher;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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<VsyncObserver> mVsyncObserver;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<nsWindow*>(user_data);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -23,7 +23,7 @@ parent:
|
|||
|
||||
async NotifyClientSizeChanged(LayoutDeviceIntSize aClientSize);
|
||||
async CleanupResources();
|
||||
async SetRenderingSurface(uintptr_t aXWindow, bool aShaped);
|
||||
async SetRenderingSurface(uintptr_t aXWindow);
|
||||
|
||||
child:
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ struct GtkCompositorWidgetInitData
|
|||
{
|
||||
uintptr_t XWindow;
|
||||
nsCString XDisplayString;
|
||||
bool Shaped;
|
||||
bool IsX11Display;
|
||||
|
||||
LayoutDeviceIntSize InitialClientSize;
|
||||
|
|
|
@ -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<WindowSurface> 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<WindowSurfaceX11SHM>(DefaultXDisplay(), mXWindow,
|
||||
mXVisual, mXDepth);
|
||||
|
@ -139,7 +136,7 @@ RefPtr<WindowSurface> WindowSurfaceProvider::CreateWindowSurface() {
|
|||
|
||||
LOG(("Drawing to Window 0x%lx will use XPutImage\n", (Window)mXWindow));
|
||||
return MakeRefPtr<WindowSurfaceX11Image>(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<WindowSurfaceX11Image>(
|
||||
DefaultXDisplay(), mXWindow, mXVisual, mXDepth, mIsShaped);
|
||||
DefaultXDisplay(), mXWindow, mXVisual, mXDepth);
|
||||
dt = mWindowSurface->Lock(aInvalidRegion);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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<gfx::DrawTarget> WindowSurfaceX11Image::Lock(
|
||||
const LayoutDeviceIntRegion& aRegion) {
|
||||
|
@ -78,13 +55,6 @@ already_AddRefed<gfx::DrawTarget> 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<gfx::DrawTarget> 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<gfx::DrawTarget> 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());
|
||||
|
|
|
@ -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<gfx::DrawTarget> 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<gfxXlibSurface> mWindowSurface;
|
||||
RefPtr<gfxImageSurface> mImageSurface;
|
||||
|
||||
gchar* mTransparencyBitmap;
|
||||
int32_t mTransparencyBitmapWidth;
|
||||
int32_t mTransparencyBitmapHeight;
|
||||
bool mIsShaped;
|
||||
Window mWindowParent;
|
||||
};
|
||||
|
||||
} // namespace widget
|
||||
|
|
|
@ -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<nsWindow*>(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<DrawTarget> 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<SourceSurface> 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<uint8_t[]>(bufferSize);
|
||||
{
|
||||
RefPtr<DrawTarget> 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.
|
||||
//
|
||||
|
|
|
@ -319,21 +319,11 @@ class nsWindow final : public nsBaseWidget {
|
|||
const mozilla::WidgetKeyboardEvent& aEvent,
|
||||
nsTArray<mozilla::CommandInt>& 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<int, mozilla::Relaxed> 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);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче