Client: Expose a way to set window margins via native interface
The lack of such API is a big hassle to me since a long time. All that time I was forced to have my own fork of the xdg-shell plugin in the application code in order to have shadows on Wayland with custom client-side decorations. I hope I won't have to maintain the fork anymore. Pick-to: 6.4 Change-Id: Iaf498469843b5cac5c458049164065c4ef15877d Reviewed-by: David Edmundson <davidedmundson@kde.org>
This commit is contained in:
parent
e43b382fb3
commit
6939f52984
@ -129,6 +129,17 @@ void *QWaylandNativeInterface::nativeResourceForContext(const QByteArray &resour
|
|||||||
}
|
}
|
||||||
#endif // opengl
|
#endif // opengl
|
||||||
|
|
||||||
|
QPlatformNativeInterface::NativeResourceForWindowFunction QWaylandNativeInterface::nativeResourceFunctionForWindow(const QByteArray &resource)
|
||||||
|
{
|
||||||
|
QByteArray lowerCaseResource = resource.toLower();
|
||||||
|
|
||||||
|
if (lowerCaseResource == "setmargins") {
|
||||||
|
return NativeResourceForWindowFunction(reinterpret_cast<void *>(setWindowMargins));
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
QVariantMap QWaylandNativeInterface::windowProperties(QPlatformWindow *window) const
|
QVariantMap QWaylandNativeInterface::windowProperties(QPlatformWindow *window) const
|
||||||
{
|
{
|
||||||
QWaylandWindow *waylandWindow = static_cast<QWaylandWindow *>(window);
|
QWaylandWindow *waylandWindow = static_cast<QWaylandWindow *>(window);
|
||||||
@ -158,6 +169,12 @@ void QWaylandNativeInterface::emitWindowPropertyChanged(QPlatformWindow *window,
|
|||||||
emit windowPropertyChanged(window,name);
|
emit windowPropertyChanged(window,name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QWaylandNativeInterface::setWindowMargins(QWindow *window, const QMargins &margins)
|
||||||
|
{
|
||||||
|
QWaylandWindow *wlWindow = static_cast<QWaylandWindow*>(window->handle());
|
||||||
|
wlWindow->setCustomMargins(margins);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QMargins;
|
||||||
|
|
||||||
namespace QtWaylandClient {
|
namespace QtWaylandClient {
|
||||||
|
|
||||||
class QWaylandIntegration;
|
class QWaylandIntegration;
|
||||||
@ -41,6 +43,7 @@ public:
|
|||||||
#if QT_CONFIG(opengl)
|
#if QT_CONFIG(opengl)
|
||||||
void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) override;
|
void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) override;
|
||||||
#endif
|
#endif
|
||||||
|
NativeResourceForWindowFunction nativeResourceFunctionForWindow(const QByteArray &resource) override;
|
||||||
QVariantMap windowProperties(QPlatformWindow *window) const override;
|
QVariantMap windowProperties(QPlatformWindow *window) const override;
|
||||||
QVariant windowProperty(QPlatformWindow *window, const QString &name) const override;
|
QVariant windowProperty(QPlatformWindow *window, const QString &name) const override;
|
||||||
QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const override;
|
QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const override;
|
||||||
@ -49,6 +52,8 @@ public:
|
|||||||
void emitWindowPropertyChanged(QPlatformWindow *window, const QString &name);
|
void emitWindowPropertyChanged(QPlatformWindow *window, const QString &name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static void setWindowMargins(QWindow *window, const QMargins &margins);
|
||||||
|
|
||||||
QWaylandIntegration *m_integration = nullptr;
|
QWaylandIntegration *m_integration = nullptr;
|
||||||
QHash<QPlatformWindow*, QVariantMap> m_windowProperties;
|
QHash<QPlatformWindow*, QVariantMap> m_windowProperties;
|
||||||
};
|
};
|
||||||
|
@ -402,8 +402,12 @@ void QWaylandWindow::resizeFromApplyConfigure(const QSize &sizeWithMargins, cons
|
|||||||
// 2) Following resizeFromApplyConfigure() calls should have sizeWithMargins equal to
|
// 2) Following resizeFromApplyConfigure() calls should have sizeWithMargins equal to
|
||||||
// windowContentGeometry() which excludes shadows, therefore in this case we have to
|
// windowContentGeometry() which excludes shadows, therefore in this case we have to
|
||||||
// exclude them too in order not to accidentally apply smaller size to the window.
|
// exclude them too in order not to accidentally apply smaller size to the window.
|
||||||
if (mWindowDecorationEnabled && (sizeWithMargins != surfaceSize()))
|
if (sizeWithMargins != surfaceSize()) {
|
||||||
margins = mWindowDecoration->margins(QWaylandAbstractDecoration::ShadowsExcluded);
|
if (mWindowDecorationEnabled)
|
||||||
|
margins = mWindowDecoration->margins(QWaylandAbstractDecoration::ShadowsExcluded);
|
||||||
|
if (!mCustomMargins.isNull())
|
||||||
|
margins -= mCustomMargins;
|
||||||
|
}
|
||||||
|
|
||||||
int widthWithoutMargins = qMax(sizeWithMargins.width() - (margins.left() + margins.right()), 1);
|
int widthWithoutMargins = qMax(sizeWithMargins.width() - (margins.left() + margins.right()), 1);
|
||||||
int heightWithoutMargins = qMax(sizeWithMargins.height() - (margins.top() + margins.bottom()), 1);
|
int heightWithoutMargins = qMax(sizeWithMargins.height() - (margins.top() + margins.bottom()), 1);
|
||||||
@ -740,6 +744,12 @@ QMargins QWaylandWindow::clientSideMargins() const
|
|||||||
return mWindowDecorationEnabled ? mWindowDecoration->margins() : QMargins{};
|
return mWindowDecorationEnabled ? mWindowDecoration->margins() : QMargins{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QWaylandWindow::setCustomMargins(const QMargins &margins) {
|
||||||
|
const QMargins oldMargins = mCustomMargins;
|
||||||
|
mCustomMargins = margins;
|
||||||
|
setGeometry(geometry().marginsRemoved(oldMargins).marginsAdded(margins));
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Size, with decorations (including including eventual shadows) in wl_surface coordinates
|
* Size, with decorations (including including eventual shadows) in wl_surface coordinates
|
||||||
*/
|
*/
|
||||||
@ -759,6 +769,9 @@ QRect QWaylandWindow::windowContentGeometry() const
|
|||||||
if (mWindowDecorationEnabled)
|
if (mWindowDecorationEnabled)
|
||||||
shadowMargins = mWindowDecoration->margins(QWaylandAbstractDecoration::ShadowsOnly);
|
shadowMargins = mWindowDecoration->margins(QWaylandAbstractDecoration::ShadowsOnly);
|
||||||
|
|
||||||
|
if (!mCustomMargins.isNull())
|
||||||
|
shadowMargins += mCustomMargins;
|
||||||
|
|
||||||
return QRect(QPoint(shadowMargins.left(), shadowMargins.top()), surfaceSize().shrunkBy(shadowMargins));
|
return QRect(QPoint(shadowMargins.left(), shadowMargins.top()), surfaceSize().shrunkBy(shadowMargins));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,6 +112,7 @@ public:
|
|||||||
bool waitForFrameSync(int timeout);
|
bool waitForFrameSync(int timeout);
|
||||||
|
|
||||||
QMargins frameMargins() const override;
|
QMargins frameMargins() const override;
|
||||||
|
void setCustomMargins(const QMargins &margins);
|
||||||
QSize surfaceSize() const;
|
QSize surfaceSize() const;
|
||||||
QRect windowContentGeometry() const;
|
QRect windowContentGeometry() const;
|
||||||
QPointF mapFromWlSurface(const QPointF &surfacePosition) const;
|
QPointF mapFromWlSurface(const QPointF &surfacePosition) const;
|
||||||
@ -289,6 +290,8 @@ protected:
|
|||||||
QWaylandBuffer *mQueuedBuffer = nullptr;
|
QWaylandBuffer *mQueuedBuffer = nullptr;
|
||||||
QRegion mQueuedBufferDamage;
|
QRegion mQueuedBufferDamage;
|
||||||
|
|
||||||
|
QMargins mCustomMargins;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setGeometry_helper(const QRect &rect);
|
void setGeometry_helper(const QRect &rect);
|
||||||
void initWindow();
|
void initWindow();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user