summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorIlya Fedin <fedin-ilja2010@ya.ru>2022-04-12 08:48:34 +0400
committerIlya Fedin <fedin-ilja2010@ya.ru>2022-07-19 19:15:01 +0400
commitc9f355ebe8d8171c2de265c00780d7f39b580409 (patch)
tree65f30943b16f176154561d5457d8388b7e271398 /src
parent5a288c87e00cdd7224a673eb7ae35b0995d881ba (diff)
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>
Diffstat (limited to 'src')
-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 6d8583480..f2620fc43 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 d05d7c38f..b39d99526 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 a740559b7..d669e8399 100644
--- a/src/client/qwaylandwindow.cpp
+++ b/src/client/qwaylandwindow.cpp
@@ -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));
}
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
index 66d5bdade..d2d4d659f 100644
--- a/src/client/qwaylandwindow_p.h
+++ b/src/client/qwaylandwindow_p.h
@@ -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();