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
|
||||
|
||||
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
|
||||
{
|
||||
QWaylandWindow *waylandWindow = static_cast<QWaylandWindow *>(window);
|
||||
@ -158,6 +169,12 @@ void QWaylandNativeInterface::emitWindowPropertyChanged(QPlatformWindow *window,
|
||||
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
|
||||
|
@ -24,6 +24,8 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QMargins;
|
||||
|
||||
namespace QtWaylandClient {
|
||||
|
||||
class QWaylandIntegration;
|
||||
@ -41,6 +43,7 @@ public:
|
||||
#if QT_CONFIG(opengl)
|
||||
void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) override;
|
||||
#endif
|
||||
NativeResourceForWindowFunction nativeResourceFunctionForWindow(const QByteArray &resource) override;
|
||||
QVariantMap windowProperties(QPlatformWindow *window) const override;
|
||||
QVariant windowProperty(QPlatformWindow *window, const QString &name) 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);
|
||||
|
||||
private:
|
||||
static void setWindowMargins(QWindow *window, const QMargins &margins);
|
||||
|
||||
QWaylandIntegration *m_integration = nullptr;
|
||||
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
|
||||
// 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.
|
||||
if (mWindowDecorationEnabled && (sizeWithMargins != surfaceSize()))
|
||||
margins = mWindowDecoration->margins(QWaylandAbstractDecoration::ShadowsExcluded);
|
||||
if (sizeWithMargins != surfaceSize()) {
|
||||
if (mWindowDecorationEnabled)
|
||||
margins = mWindowDecoration->margins(QWaylandAbstractDecoration::ShadowsExcluded);
|
||||
if (!mCustomMargins.isNull())
|
||||
margins -= mCustomMargins;
|
||||
}
|
||||
|
||||
int widthWithoutMargins = qMax(sizeWithMargins.width() - (margins.left() + margins.right()), 1);
|
||||
int heightWithoutMargins = qMax(sizeWithMargins.height() - (margins.top() + margins.bottom()), 1);
|
||||
@ -740,6 +744,12 @@ QMargins QWaylandWindow::clientSideMargins() const
|
||||
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
|
||||
*/
|
||||
@ -759,6 +769,9 @@ QRect QWaylandWindow::windowContentGeometry() const
|
||||
if (mWindowDecorationEnabled)
|
||||
shadowMargins = mWindowDecoration->margins(QWaylandAbstractDecoration::ShadowsOnly);
|
||||
|
||||
if (!mCustomMargins.isNull())
|
||||
shadowMargins += mCustomMargins;
|
||||
|
||||
return QRect(QPoint(shadowMargins.left(), shadowMargins.top()), surfaceSize().shrunkBy(shadowMargins));
|
||||
}
|
||||
|
||||
|
@ -112,6 +112,7 @@ public:
|
||||
bool waitForFrameSync(int timeout);
|
||||
|
||||
QMargins frameMargins() const override;
|
||||
void setCustomMargins(const QMargins &margins);
|
||||
QSize surfaceSize() const;
|
||||
QRect windowContentGeometry() const;
|
||||
QPointF mapFromWlSurface(const QPointF &surfacePosition) const;
|
||||
@ -289,6 +290,8 @@ protected:
|
||||
QWaylandBuffer *mQueuedBuffer = nullptr;
|
||||
QRegion mQueuedBufferDamage;
|
||||
|
||||
QMargins mCustomMargins;
|
||||
|
||||
private:
|
||||
void setGeometry_helper(const QRect &rect);
|
||||
void initWindow();
|
||||
|
Loading…
x
Reference in New Issue
Block a user