use kwayland for shadows and dialog positioning
use plasmashell interface for moving the dialog, use kwayland as well for shadows. this is supposed to replace the waylanddialogfilter hack in plasmashell. REVIEW:129148
This commit is contained in:
parent
ba9a8a16ab
commit
b0a5bc09ef
@ -66,6 +66,14 @@ find_package(KF5XmlGui ${KF5_DEP_VERSION} REQUIRED)
|
|||||||
find_package(KF5Notifications ${KF5_DEP_VERSION} REQUIRED)
|
find_package(KF5Notifications ${KF5_DEP_VERSION} REQUIRED)
|
||||||
find_package(KF5Package ${KF5_DEP_VERSION} REQUIRED)
|
find_package(KF5Package ${KF5_DEP_VERSION} REQUIRED)
|
||||||
|
|
||||||
|
find_package(KF5Wayland ${KF5_DEP_VERSION})
|
||||||
|
set_package_properties(KF5Wayland PROPERTIES DESCRIPTION "Integration with the Wayland compositor"
|
||||||
|
TYPE OPTIONAL
|
||||||
|
)
|
||||||
|
if(KF5Wayland_FOUND)
|
||||||
|
set(HAVE_KWAYLAND 1)
|
||||||
|
endif()
|
||||||
|
|
||||||
find_package(KF5DocTools ${KF5_DEP_VERSION})
|
find_package(KF5DocTools ${KF5_DEP_VERSION})
|
||||||
set_package_properties(KF5DocTools PROPERTIES DESCRIPTION "Tools to generate documentation"
|
set_package_properties(KF5DocTools PROPERTIES DESCRIPTION "Tools to generate documentation"
|
||||||
TYPE OPTIONAL
|
TYPE OPTIONAL
|
||||||
|
@ -4,5 +4,6 @@
|
|||||||
#cmakedefine01 HAVE_X11
|
#cmakedefine01 HAVE_X11
|
||||||
#cmakedefine01 HAVE_GLX
|
#cmakedefine01 HAVE_GLX
|
||||||
#cmakedefine01 HAVE_EGL
|
#cmakedefine01 HAVE_EGL
|
||||||
|
#cmakedefine01 HAVE_KWAYLAND
|
||||||
|
|
||||||
#define PLASMA_RELATIVE_DATA_INSTALL_DIR "@PLASMA_RELATIVE_DATA_INSTALL_DIR@"
|
#define PLASMA_RELATIVE_DATA_INSTALL_DIR "@PLASMA_RELATIVE_DATA_INSTALL_DIR@"
|
||||||
|
@ -42,6 +42,13 @@ target_link_libraries(KF5PlasmaQuick
|
|||||||
KF5::QuickAddons
|
KF5::QuickAddons
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(HAVE_KWAYLAND)
|
||||||
|
target_link_libraries(KF5PlasmaQuick
|
||||||
|
PRIVATE
|
||||||
|
KF5::WaylandClient
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(HAVE_X11)
|
if(HAVE_X11)
|
||||||
target_link_libraries(KF5PlasmaQuick
|
target_link_libraries(KF5PlasmaQuick
|
||||||
PRIVATE
|
PRIVATE
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "dialog.h"
|
#include "dialog.h"
|
||||||
|
#include "config-plasma.h"
|
||||||
#include "../declarativeimports/core/framesvgitem.h"
|
#include "../declarativeimports/core/framesvgitem.h"
|
||||||
#include "dialogshadows_p.h"
|
#include "dialogshadows_p.h"
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
@ -47,6 +48,11 @@
|
|||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
#if HAVE_KWAYLAND
|
||||||
|
#include <KWayland/Client/plasmashell.h>
|
||||||
|
#include <KWayland/Client/surface.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <config-plasma.h>
|
#include <config-plasma.h>
|
||||||
#if HAVE_XCB_SHAPE
|
#if HAVE_XCB_SHAPE
|
||||||
#include <QX11Info>
|
#include <QX11Info>
|
||||||
@ -128,12 +134,18 @@ public:
|
|||||||
bool mainItemContainsPosition(const QPointF &point) const;
|
bool mainItemContainsPosition(const QPointF &point) const;
|
||||||
QPointF positionAdjustedForMainItem(const QPointF &point) const;
|
QPointF positionAdjustedForMainItem(const QPointF &point) const;
|
||||||
|
|
||||||
|
void setupWaylandIntegration();
|
||||||
|
|
||||||
|
|
||||||
Dialog *q;
|
Dialog *q;
|
||||||
Plasma::Types::Location location;
|
Plasma::Types::Location location;
|
||||||
Plasma::FrameSvgItem *frameSvgItem;
|
Plasma::FrameSvgItem *frameSvgItem;
|
||||||
QPointer<QQuickItem> mainItem;
|
QPointer<QQuickItem> mainItem;
|
||||||
QPointer<QQuickItem> visualParent;
|
QPointer<QQuickItem> visualParent;
|
||||||
QTimer hintsCommitTimer;
|
QTimer hintsCommitTimer;
|
||||||
|
#if HAVE_KWAYLAND
|
||||||
|
QPointer<KWayland::Client::PlasmaShellSurface> shellSurface;
|
||||||
|
#endif
|
||||||
|
|
||||||
QRect cachedGeometry;
|
QRect cachedGeometry;
|
||||||
bool hasMask;
|
bool hasMask;
|
||||||
@ -664,6 +676,28 @@ QPointF DialogPrivate::positionAdjustedForMainItem(const QPointF &point) const
|
|||||||
qBound(itemRect.top(), point.y(), itemRect.bottom()));
|
qBound(itemRect.top(), point.y(), itemRect.bottom()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogPrivate::setupWaylandIntegration()
|
||||||
|
{
|
||||||
|
#if HAVE_KWAYLAND
|
||||||
|
if (shellSurface) {
|
||||||
|
// already setup
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace KWayland::Client;
|
||||||
|
PlasmaShell *interface = DialogShadows::self()->waylandPlasmaShellInterface();
|
||||||
|
if (!interface) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Surface *s = Surface::fromWindow(q);
|
||||||
|
if (!s) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
shellSurface = interface->createSurface(s, q);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Dialog::Dialog(QQuickItem *parent)
|
Dialog::Dialog(QQuickItem *parent)
|
||||||
: QQuickWindow(parent ? parent->window() : 0),
|
: QQuickWindow(parent ? parent->window() : 0),
|
||||||
d(new DialogPrivate(this))
|
d(new DialogPrivate(this))
|
||||||
@ -722,7 +756,6 @@ void Dialog::setMainItem(QQuickItem *mainItem)
|
|||||||
disconnect(d->mainItemLayout, 0, this, 0);
|
disconnect(d->mainItemLayout, 0, this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
d->mainItem = mainItem;
|
d->mainItem = mainItem;
|
||||||
|
|
||||||
if (mainItem) {
|
if (mainItem) {
|
||||||
@ -1089,12 +1122,23 @@ bool Dialog::event(QEvent *event)
|
|||||||
|
|
||||||
if (pSEvent->surfaceEventType() == QPlatformSurfaceEvent::SurfaceCreated) {
|
if (pSEvent->surfaceEventType() == QPlatformSurfaceEvent::SurfaceCreated) {
|
||||||
KWindowSystem::setState(winId(), NET::SkipTaskbar | NET::SkipPager);
|
KWindowSystem::setState(winId(), NET::SkipTaskbar | NET::SkipPager);
|
||||||
|
d->setupWaylandIntegration();
|
||||||
|
} else if (pSEvent->surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed) {
|
||||||
|
#if HAVE_KWAYLAND
|
||||||
|
delete d->shellSurface;
|
||||||
|
d->shellSurface = nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else if (event->type() == QEvent::Show) {
|
} else if (event->type() == QEvent::Show) {
|
||||||
d->updateVisibility(true);
|
d->updateVisibility(true);
|
||||||
} else if (event->type() == QEvent::Hide) {
|
} else if (event->type() == QEvent::Hide) {
|
||||||
d->updateVisibility(false);
|
d->updateVisibility(false);
|
||||||
|
} else if (event->type() == QEvent::Move) {
|
||||||
|
QMoveEvent *me = static_cast<QMoveEvent *>(event);
|
||||||
|
if (d->shellSurface) {
|
||||||
|
d->shellSurface->setPosition(me->pos());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Fitt's law: if the containment has margins, and the mouse cursor clicked
|
/*Fitt's law: if the containment has margins, and the mouse cursor clicked
|
||||||
|
@ -18,11 +18,11 @@
|
|||||||
|
|
||||||
#include "dialogshadows_p.h"
|
#include "dialogshadows_p.h"
|
||||||
|
|
||||||
#include <QGlobalStatic>
|
|
||||||
#include <QWindow>
|
#include <QWindow>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <config-plasma.h>
|
#include <config-plasma.h>
|
||||||
|
|
||||||
|
#include <KWindowSystem>
|
||||||
#if HAVE_X11
|
#if HAVE_X11
|
||||||
#include <QX11Info>
|
#include <QX11Info>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
@ -31,6 +31,15 @@
|
|||||||
#include <fixx11h.h>
|
#include <fixx11h.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_KWAYLAND
|
||||||
|
#include <KWayland/Client/connection_thread.h>
|
||||||
|
#include <KWayland/Client/registry.h>
|
||||||
|
#include <KWayland/Client/shadow.h>
|
||||||
|
#include <KWayland/Client/shm_pool.h>
|
||||||
|
#include <KWayland/Client/surface.h>
|
||||||
|
#include <KWayland/Client/plasmashell.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <qdebug.h>
|
#include <qdebug.h>
|
||||||
|
|
||||||
class DialogShadows::Private
|
class DialogShadows::Private
|
||||||
@ -39,11 +48,12 @@ public:
|
|||||||
Private(DialogShadows *shadows)
|
Private(DialogShadows *shadows)
|
||||||
: q(shadows)
|
: q(shadows)
|
||||||
#if HAVE_X11
|
#if HAVE_X11
|
||||||
, _connection(0x0),
|
,_connection(0x0),
|
||||||
_gc(0x0)
|
_gc(0x0)
|
||||||
, m_isX11(QX11Info::isPlatformX11())
|
, m_isX11(KWindowSystem::isPlatformX11())
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
setupWaylandIntegration();
|
||||||
}
|
}
|
||||||
|
|
||||||
~Private()
|
~Private()
|
||||||
@ -54,17 +64,24 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void freeX11Pixmaps();
|
void freeX11Pixmaps();
|
||||||
|
void freeWaylandBuffers();
|
||||||
void clearPixmaps();
|
void clearPixmaps();
|
||||||
void setupPixmaps();
|
void setupPixmaps();
|
||||||
Qt::HANDLE createPixmap(const QPixmap &source);
|
Qt::HANDLE createPixmap(const QPixmap &source);
|
||||||
void initPixmap(const QString &element);
|
void initPixmap(const QString &element);
|
||||||
QPixmap initEmptyPixmap(const QSize &size);
|
QPixmap initEmptyPixmap(const QSize &size);
|
||||||
void updateShadow(const QWindow *window, Plasma::FrameSvg::EnabledBorders);
|
void updateShadow(const QWindow *window, Plasma::FrameSvg::EnabledBorders);
|
||||||
|
void updateShadowX11(const QWindow *window, Plasma::FrameSvg::EnabledBorders);
|
||||||
|
void updateShadowWayland(const QWindow *window, Plasma::FrameSvg::EnabledBorders);
|
||||||
void clearShadow(const QWindow *window);
|
void clearShadow(const QWindow *window);
|
||||||
|
void clearShadowX11(const QWindow *window);
|
||||||
|
void clearShadowWayland(const QWindow *window);
|
||||||
void updateShadows();
|
void updateShadows();
|
||||||
void windowDestroyed(QObject *deletedObject);
|
void windowDestroyed(QObject *deletedObject);
|
||||||
void setupData(Plasma::FrameSvg::EnabledBorders enabledBorders);
|
void setupData(Plasma::FrameSvg::EnabledBorders enabledBorders);
|
||||||
|
|
||||||
|
void setupWaylandIntegration();
|
||||||
|
|
||||||
DialogShadows *q;
|
DialogShadows *q;
|
||||||
QList<QPixmap> m_shadowPixmaps;
|
QList<QPixmap> m_shadowPixmaps;
|
||||||
|
|
||||||
@ -85,6 +102,17 @@ public:
|
|||||||
bool m_isX11;
|
bool m_isX11;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_KWAYLAND
|
||||||
|
struct Wayland {
|
||||||
|
KWayland::Client::ShadowManager *manager = nullptr;
|
||||||
|
KWayland::Client::ShmPool *shmPool = nullptr;
|
||||||
|
KWayland::Client::PlasmaShell *plasmaShell = nullptr;
|
||||||
|
|
||||||
|
QList<KWayland::Client::Buffer::Ptr> shadowBuffers;
|
||||||
|
};
|
||||||
|
Wayland m_wayland;
|
||||||
|
#endif
|
||||||
|
|
||||||
QHash<Plasma::FrameSvg::EnabledBorders, QVector<unsigned long> > data;
|
QHash<Plasma::FrameSvg::EnabledBorders, QVector<unsigned long> > data;
|
||||||
QHash<const QWindow *, Plasma::FrameSvg::EnabledBorders> m_windows;
|
QHash<const QWindow *, Plasma::FrameSvg::EnabledBorders> m_windows;
|
||||||
};
|
};
|
||||||
@ -146,6 +174,16 @@ void DialogShadows::removeWindow(const QWindow *window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogShadows::setEnabledBorders(const QWindow *window, Plasma::FrameSvg::EnabledBorders enabledBorders)
|
||||||
|
{
|
||||||
|
if (!window || !d->m_windows.contains(window)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
d->updateShadow(window, enabledBorders);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DialogShadows::Private::windowDestroyed(QObject *deletedObject)
|
void DialogShadows::Private::windowDestroyed(QObject *deletedObject)
|
||||||
{
|
{
|
||||||
m_windows.remove(static_cast<QWindow *>(deletedObject));
|
m_windows.remove(static_cast<QWindow *>(deletedObject));
|
||||||
@ -269,6 +307,13 @@ void DialogShadows::Private::setupPixmaps()
|
|||||||
m_emptyVerticalPix = initEmptyPixmap(QSize(1, q->elementSize(QStringLiteral("shadow-left")).height()));
|
m_emptyVerticalPix = initEmptyPixmap(QSize(1, q->elementSize(QStringLiteral("shadow-left")).height()));
|
||||||
m_emptyHorizontalPix = initEmptyPixmap(QSize(q->elementSize(QStringLiteral("shadow-top")).width(), 1));
|
m_emptyHorizontalPix = initEmptyPixmap(QSize(q->elementSize(QStringLiteral("shadow-top")).width(), 1));
|
||||||
|
|
||||||
|
#if HAVE_KWAYLAND
|
||||||
|
if (m_wayland.shmPool) {
|
||||||
|
for (auto it = m_shadowPixmaps.constBegin(); it != m_shadowPixmaps.constEnd(); ++it) {
|
||||||
|
m_wayland.shadowBuffers << m_wayland.shmPool->createBuffer(it->toImage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogShadows::Private::setupData(Plasma::FrameSvg::EnabledBorders enabledBorders)
|
void DialogShadows::Private::setupData(Plasma::FrameSvg::EnabledBorders enabledBorders)
|
||||||
@ -459,16 +504,35 @@ void DialogShadows::Private::clearPixmaps()
|
|||||||
m_emptyVerticalPix = QPixmap();
|
m_emptyVerticalPix = QPixmap();
|
||||||
m_emptyHorizontalPix = QPixmap();
|
m_emptyHorizontalPix = QPixmap();
|
||||||
#endif
|
#endif
|
||||||
|
freeWaylandBuffers();
|
||||||
m_shadowPixmaps.clear();
|
m_shadowPixmaps.clear();
|
||||||
data.clear();
|
data.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogShadows::Private::freeWaylandBuffers()
|
||||||
|
{
|
||||||
|
#if HAVE_KWAYLAND
|
||||||
|
m_wayland.shadowBuffers.clear();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void DialogShadows::Private::updateShadow(const QWindow *window, Plasma::FrameSvg::EnabledBorders enabledBorders)
|
void DialogShadows::Private::updateShadow(const QWindow *window, Plasma::FrameSvg::EnabledBorders enabledBorders)
|
||||||
{
|
{
|
||||||
#if HAVE_X11
|
#if HAVE_X11
|
||||||
if (!m_isX11) {
|
if (m_isX11) {
|
||||||
return;
|
updateShadowX11(window, enabledBorders);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#if HAVE_KWAYLAND
|
||||||
|
if (m_wayland.manager) {
|
||||||
|
updateShadowWayland(window, enabledBorders);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogShadows::Private::updateShadowX11(const QWindow *window, Plasma::FrameSvg::EnabledBorders enabledBorders)
|
||||||
|
{
|
||||||
|
#if HAVE_X11
|
||||||
if (m_shadowPixmaps.isEmpty()) {
|
if (m_shadowPixmaps.isEmpty()) {
|
||||||
setupPixmaps();
|
setupPixmaps();
|
||||||
}
|
}
|
||||||
@ -483,23 +547,149 @@ void DialogShadows::Private::updateShadow(const QWindow *window, Plasma::FrameSv
|
|||||||
//qDebug() << "going to set the shadow of" << window->winId() << "to" << data;
|
//qDebug() << "going to set the shadow of" << window->winId() << "to" << data;
|
||||||
XChangeProperty(dpy, window->winId(), atom, XA_CARDINAL, 32, PropModeReplace,
|
XChangeProperty(dpy, window->winId(), atom, XA_CARDINAL, 32, PropModeReplace,
|
||||||
reinterpret_cast<const unsigned char *>(data[enabledBorders].constData()), data[enabledBorders].size());
|
reinterpret_cast<const unsigned char *>(data[enabledBorders].constData()), data[enabledBorders].size());
|
||||||
#else
|
#endif
|
||||||
Q_UNUSED(window)
|
}
|
||||||
Q_UNUSED(enabledBorders)
|
|
||||||
|
void DialogShadows::Private::updateShadowWayland(const QWindow *window, Plasma::FrameSvg::EnabledBorders enabledBorders)
|
||||||
|
{
|
||||||
|
#if HAVE_KWAYLAND
|
||||||
|
if (!m_wayland.shmPool) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (m_wayland.shadowBuffers.isEmpty()) {
|
||||||
|
setupPixmaps();
|
||||||
|
}
|
||||||
|
// TODO: check whether the surface already has a shadow
|
||||||
|
KWayland::Client::Surface *surface = KWayland::Client::Surface::fromWindow(const_cast<QWindow*>(window));
|
||||||
|
if (!surface) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto shadow = m_wayland.manager->createShadow(surface, surface);
|
||||||
|
|
||||||
|
//shadow-top
|
||||||
|
if (enabledBorders & Plasma::FrameSvg::TopBorder) {
|
||||||
|
shadow->attachTop(m_wayland.shadowBuffers.at(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
//shadow-topright
|
||||||
|
if (enabledBorders & Plasma::FrameSvg::TopBorder &&
|
||||||
|
enabledBorders & Plasma::FrameSvg::RightBorder) {
|
||||||
|
shadow->attachTopRight(m_wayland.shadowBuffers.at(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
//shadow-right
|
||||||
|
if (enabledBorders & Plasma::FrameSvg::RightBorder) {
|
||||||
|
shadow->attachRight(m_wayland.shadowBuffers.at(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
//shadow-bottomright
|
||||||
|
if (enabledBorders & Plasma::FrameSvg::BottomBorder &&
|
||||||
|
enabledBorders & Plasma::FrameSvg::RightBorder) {
|
||||||
|
shadow->attachBottomRight(m_wayland.shadowBuffers.at(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
//shadow-bottom
|
||||||
|
if (enabledBorders & Plasma::FrameSvg::BottomBorder) {
|
||||||
|
shadow->attachBottom(m_wayland.shadowBuffers.at(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
//shadow-bottomleft
|
||||||
|
if (enabledBorders & Plasma::FrameSvg::BottomBorder &&
|
||||||
|
enabledBorders & Plasma::FrameSvg::LeftBorder) {
|
||||||
|
shadow->attachBottomLeft(m_wayland.shadowBuffers.at(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
//shadow-left
|
||||||
|
if (enabledBorders & Plasma::FrameSvg::LeftBorder) {
|
||||||
|
shadow->attachLeft(m_wayland.shadowBuffers.at(6));
|
||||||
|
}
|
||||||
|
|
||||||
|
//shadow-topleft
|
||||||
|
if (enabledBorders & Plasma::FrameSvg::TopBorder &&
|
||||||
|
enabledBorders & Plasma::FrameSvg::LeftBorder) {
|
||||||
|
shadow->attachTopLeft(m_wayland.shadowBuffers.at(7));
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize marginHint;
|
||||||
|
QMarginsF margins = QMarginsF(1, 1, 1, 1);
|
||||||
|
if (enabledBorders & Plasma::FrameSvg::TopBorder) {
|
||||||
|
marginHint = q->elementSize(QStringLiteral("shadow-hint-top-margin"));
|
||||||
|
if (marginHint.isValid()) {
|
||||||
|
margins.setTop(marginHint.height());
|
||||||
|
} else {
|
||||||
|
margins.setTop(m_shadowPixmaps[0].height());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enabledBorders & Plasma::FrameSvg::RightBorder) {
|
||||||
|
marginHint = q->elementSize(QStringLiteral("shadow-hint-right-margin"));
|
||||||
|
if (marginHint.isValid()) {
|
||||||
|
margins.setRight(marginHint.width());
|
||||||
|
} else {
|
||||||
|
margins.setRight(m_shadowPixmaps[2].width());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enabledBorders & Plasma::FrameSvg::BottomBorder) {
|
||||||
|
marginHint = q->elementSize(QStringLiteral("shadow-hint-bottom-margin"));
|
||||||
|
if (marginHint.isValid()) {
|
||||||
|
margins.setBottom(marginHint.height());
|
||||||
|
} else {
|
||||||
|
margins.setBottom(m_shadowPixmaps[4].height());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enabledBorders & Plasma::FrameSvg::LeftBorder) {
|
||||||
|
marginHint = q->elementSize(QStringLiteral("shadow-hint-left-margin"));
|
||||||
|
if (marginHint.isValid()) {
|
||||||
|
margins.setLeft(marginHint.width());
|
||||||
|
} else {
|
||||||
|
margins.setLeft(m_shadowPixmaps[6].width());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shadow->setOffsets(margins);
|
||||||
|
shadow->commit();
|
||||||
|
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogShadows::Private::clearShadow(const QWindow *window)
|
void DialogShadows::Private::clearShadow(const QWindow *window)
|
||||||
{
|
{
|
||||||
#if HAVE_X11
|
if (!static_cast<const QSurface*>(window)->surfaceHandle()) {
|
||||||
if (!m_isX11) {
|
qWarning() << "Cannot clear shadow from window without native surface!";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#if HAVE_X11
|
||||||
|
if (m_isX11) {
|
||||||
|
clearShadowX11(window);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if HAVE_KWAYLAND
|
||||||
|
if (m_wayland.manager) {
|
||||||
|
clearShadowWayland(window);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogShadows::Private::clearShadowX11(const QWindow* window)
|
||||||
|
{
|
||||||
|
#if HAVE_X11
|
||||||
Display *dpy = QX11Info::display();
|
Display *dpy = QX11Info::display();
|
||||||
Atom atom = XInternAtom(dpy, "_KDE_NET_WM_SHADOW", False);
|
Atom atom = XInternAtom(dpy, "_KDE_NET_WM_SHADOW", False);
|
||||||
XDeleteProperty(dpy, window->winId(), atom);
|
XDeleteProperty(dpy, window->winId(), atom);
|
||||||
#else
|
#endif
|
||||||
Q_UNUSED(window)
|
}
|
||||||
|
|
||||||
|
void DialogShadows::Private::clearShadowWayland(const QWindow *window)
|
||||||
|
{
|
||||||
|
#if HAVE_KWAYLAND
|
||||||
|
KWayland::Client::Surface *surface = KWayland::Client::Surface::fromWindow(const_cast<QWindow*>(window));
|
||||||
|
if (!surface) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_wayland.manager->removeShadow(surface);
|
||||||
|
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,5 +698,47 @@ bool DialogShadows::enabled() const
|
|||||||
return hasElement(QStringLiteral("shadow-left"));
|
return hasElement(QStringLiteral("shadow-left"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KWayland::Client::PlasmaShell *DialogShadows::waylandPlasmaShellInterface() const
|
||||||
|
{
|
||||||
|
#if HAVE_KWAYLAND
|
||||||
|
return d->m_wayland.plasmaShell;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogShadows::Private::setupWaylandIntegration()
|
||||||
|
{
|
||||||
|
#if HAVE_KWAYLAND
|
||||||
|
if (!KWindowSystem::isPlatformWayland()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
using namespace KWayland::Client;
|
||||||
|
ConnectionThread *connection = ConnectionThread::fromApplication(q);
|
||||||
|
if (!connection) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Registry *registry = new Registry(q);
|
||||||
|
registry->create(connection);
|
||||||
|
connect(registry, &Registry::shadowAnnounced, q,
|
||||||
|
[this, registry] (quint32 name, quint32 version) {
|
||||||
|
m_wayland.manager = registry->createShadowManager(name, version, q);
|
||||||
|
updateShadows();
|
||||||
|
}, Qt::QueuedConnection
|
||||||
|
);
|
||||||
|
connect(registry, &Registry::shmAnnounced, q,
|
||||||
|
[this, registry] (quint32 name, quint32 version) {
|
||||||
|
m_wayland.shmPool = registry->createShmPool(name, version, q);
|
||||||
|
updateShadows();
|
||||||
|
}, Qt::QueuedConnection
|
||||||
|
);
|
||||||
|
connect(registry, &Registry::plasmaShellAnnounced, q,
|
||||||
|
[this, registry] (quint32 name, quint32 version) {
|
||||||
|
m_wayland.plasmaShell = registry->createPlasmaShell(name, version, q);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
registry->setup();
|
||||||
|
connection->roundtrip();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#include "moc_dialogshadows_p.cpp"
|
#include "moc_dialogshadows_p.cpp"
|
||||||
|
|
||||||
|
@ -24,6 +24,14 @@
|
|||||||
#include "plasma/framesvg.h"
|
#include "plasma/framesvg.h"
|
||||||
#include "plasma/svg.h"
|
#include "plasma/svg.h"
|
||||||
|
|
||||||
|
namespace KWayland
|
||||||
|
{
|
||||||
|
namespace Client
|
||||||
|
{
|
||||||
|
class PlasmaShell;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class DialogShadows : public Plasma::Svg
|
class DialogShadows : public Plasma::Svg
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -37,8 +45,12 @@ public:
|
|||||||
void addWindow(const QWindow *window, Plasma::FrameSvg::EnabledBorders enabledBorders = Plasma::FrameSvg::AllBorders);
|
void addWindow(const QWindow *window, Plasma::FrameSvg::EnabledBorders enabledBorders = Plasma::FrameSvg::AllBorders);
|
||||||
void removeWindow(const QWindow *window);
|
void removeWindow(const QWindow *window);
|
||||||
|
|
||||||
|
void setEnabledBorders(const QWindow *window, Plasma::FrameSvg::EnabledBorders enabledBorders = Plasma::FrameSvg::AllBorders);
|
||||||
|
|
||||||
bool enabled() const;
|
bool enabled() const;
|
||||||
|
|
||||||
|
KWayland::Client::PlasmaShell *waylandPlasmaShellInterface() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Private;
|
class Private;
|
||||||
Private *const d;
|
Private *const d;
|
||||||
|
Loading…
Reference in New Issue
Block a user