diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /widget/gtk/GtkCompositorWidget.cpp | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'widget/gtk/GtkCompositorWidget.cpp')
-rw-r--r-- | widget/gtk/GtkCompositorWidget.cpp | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/widget/gtk/GtkCompositorWidget.cpp b/widget/gtk/GtkCompositorWidget.cpp new file mode 100644 index 0000000000..bfb970ec47 --- /dev/null +++ b/widget/gtk/GtkCompositorWidget.cpp @@ -0,0 +1,147 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "GtkCompositorWidget.h" + +#include "gfxPlatformGtk.h" +#include "mozilla/layers/CompositorThread.h" +#include "mozilla/widget/InProcessCompositorWidget.h" +#include "mozilla/widget/PlatformWidgetTypes.h" +#include "nsWindow.h" + +namespace mozilla { +namespace widget { + +GtkCompositorWidget::GtkCompositorWidget( + const GtkCompositorWidgetInitData& aInitData, + const layers::CompositorOptions& aOptions, nsWindow* aWindow) + : CompositorWidget(aOptions), + mWidget(aWindow), + mClientSize("GtkCompositorWidget::mClientSize") { +#if defined(MOZ_WAYLAND) + if (!aInitData.IsX11Display()) { + if (!aWindow) { + NS_WARNING("GtkCompositorWidget: We're missing nsWindow!"); + } + mProvider.Initialize(aWindow); + } +#endif +#if defined(MOZ_X11) + if (aInitData.IsX11Display()) { + // If we have a nsWindow, then grab the already existing display connection + // If we don't, then use the init data to connect to the display + if (aWindow) { + mXDisplay = aWindow->XDisplay(); + } else { + mXDisplay = XOpenDisplay(aInitData.XDisplayString().get()); + } + mXWindow = (Window)aInitData.XWindow(); + + // Grab the window's visual and depth + XWindowAttributes windowAttrs; + if (!XGetWindowAttributes(mXDisplay, mXWindow, &windowAttrs)) { + NS_WARNING("GtkCompositorWidget(): XGetWindowAttributes() failed!"); + } + + Visual* visual = windowAttrs.visual; + mDepth = windowAttrs.depth; + + // Initialize the window surface provider + mProvider.Initialize(mXDisplay, mXWindow, visual, mDepth, + aInitData.Shaped()); + } +#endif + auto size = mClientSize.Lock(); + *size = aInitData.InitialClientSize(); +} + +GtkCompositorWidget::~GtkCompositorWidget() { + mProvider.CleanupResources(); + +#if defined(MOZ_X11) + // If we created our own display connection, we need to destroy it + if (!mWidget && mXDisplay) { + XCloseDisplay(mXDisplay); + mXDisplay = nullptr; + } +#endif +} + +already_AddRefed<gfx::DrawTarget> GtkCompositorWidget::StartRemoteDrawing() { + return nullptr; +} +void GtkCompositorWidget::EndRemoteDrawing() {} + +already_AddRefed<gfx::DrawTarget> +GtkCompositorWidget::StartRemoteDrawingInRegion( + LayoutDeviceIntRegion& aInvalidRegion, layers::BufferMode* aBufferMode) { + return mProvider.StartRemoteDrawingInRegion(aInvalidRegion, aBufferMode); +} + +void GtkCompositorWidget::EndRemoteDrawingInRegion( + gfx::DrawTarget* aDrawTarget, const LayoutDeviceIntRegion& aInvalidRegion) { + mProvider.EndRemoteDrawingInRegion(aDrawTarget, aInvalidRegion); +} + +nsIWidget* GtkCompositorWidget::RealWidget() { return mWidget; } + +void GtkCompositorWidget::NotifyClientSizeChanged( + const LayoutDeviceIntSize& aClientSize) { + auto size = mClientSize.Lock(); + *size = aClientSize; +} + +LayoutDeviceIntSize GtkCompositorWidget::GetClientSize() { + auto size = mClientSize.Lock(); + return *size; +} + +uintptr_t GtkCompositorWidget::GetWidgetKey() { + return reinterpret_cast<uintptr_t>(mWidget); +} + +EGLNativeWindowType GtkCompositorWidget::GetEGLNativeWindow() { + if (mWidget) { + return (EGLNativeWindowType)mWidget->GetNativeData(NS_NATIVE_EGL_WINDOW); + } +#if defined(MOZ_X11) + if (mXWindow) { + return (EGLNativeWindowType)mXWindow; + } +#endif + return nullptr; +} + +int32_t GtkCompositorWidget::GetDepth() { return mDepth; } + +#if defined(MOZ_WAYLAND) +void GtkCompositorWidget::SetEGLNativeWindowSize( + const LayoutDeviceIntSize& aEGLWindowSize) { + if (mWidget) { + mWidget->SetEGLNativeWindowSize(aEGLWindowSize); + } +} +#endif + +void GtkCompositorWidget::ClearBeforePaint( + RefPtr<gfx::DrawTarget> aTarget, const LayoutDeviceIntRegion& aRegion) { + // We need to clear target buffer alpha values of popup windows as + // SW-WR paints with alpha blending (see Bug 1674473). + if (mWidget->IsPopup()) { + for (auto iter = aRegion.RectIter(); !iter.Done(); iter.Next()) { + aTarget->ClearRect(gfx::Rect(iter.Get().ToUnknownRect())); + } + } + + // Clear background of titlebar area to render titlebar + // transparent corners correctly. + gfx::Rect rect; + if (mWidget->GetTitlebarRect(rect)) { + aTarget->ClearRect(rect); + } +} + +} // namespace widget +} // namespace mozilla |