summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Fedin <fedin-ilja2010@ya.ru>2022-04-12 08:48:34 +0400
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-07-19 15:59:27 +0000
commitb4119fd680c667d73cab95d2cb0f962618f00688 (patch)
tree156e872a8fd95ecc72b90cd99b4ec8a0c82d5557
parentb4102dd2068b5bc72514a22b7b9e0e475b96ea90 (diff)
downloadqtwayland-b4119fd680c667d73cab95d2cb0f962618f00688.tar.gz
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. Change-Id: Iaf498469843b5cac5c458049164065c4ef15877d Reviewed-by: David Edmundson <davidedmundson@kde.org> (cherry picked from commit c9f355ebe8d8171c2de265c00780d7f39b580409) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/client/qwaylandnativeinterface.cpp17
-rw-r--r--src/client/qwaylandnativeinterface_p.h5
-rw-r--r--src/client/qwaylandwindow.cpp17
-rw-r--r--src/client/qwaylandwindow_p.h3
4 files changed, 40 insertions, 2 deletions
diff --git a/src/client/qwaylandnativeinterface.cpp b/src/client/qwaylandnativeinterface.cpp
index 6d858348..f2620fc4 100644
--- a/src/client/qwaylandnativeinterface.cpp
+++ b/src/client/qwaylandnativeinterface.cpp
@@ -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
diff --git a/src/client/qwaylandnativeinterface_p.h b/src/client/qwaylandnativeinterface_p.h
index d05d7c38..b39d9952 100644
--- a/src/client/qwaylandnativeinterface_p.h
+++ b/src/client/qwaylandnativeinterface_p.h
@@ -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;
};
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
index 5a8dd0aa..e8b50939 100644
--- a/src/client/qwaylandwindow.cpp
+++ b/src/client/qwaylandwindow.cpp
@@ -397,8 +397,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);
@@ -735,6 +739,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
*/
@@ -754,6 +764,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));
}
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
index e3f59a1d..e1280268 100644
--- a/src/client/qwaylandwindow_p.h
+++ b/src/client/qwaylandwindow_p.h
@@ -109,6 +109,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;
@@ -286,6 +287,8 @@ protected:
QWaylandBuffer *mQueuedBuffer = nullptr;
QRegion mQueuedBufferDamage;
+ QMargins mCustomMargins;
+
private:
void setGeometry_helper(const QRect &rect);
void initWindow();