summaryrefslogtreecommitdiffstats
path: root/src/client
diff options
context:
space:
mode:
authorDavid Edmundson <davidedmundson@kde.org>2018-06-26 18:45:30 +0100
committerJohan Helsing <johan.helsing@qt.io>2018-08-03 11:28:51 +0000
commitf4527f1581486b99d2699b2675ad5d258bc8a7fc (patch)
tree80991cc655d51764c6459490ca2ed5f2d05b41da /src/client
parent48831347bcdc5e30138db6a6f4d705813afd0cea (diff)
Add XdgOutput client support
XdgOutput is an extension of wl_output with the benefit of having the logical size of a screen as an explicit parameter, instead of clients inferring it from modeSize / scale. This is useful as it allows compositors to implement fractional scaling whilst clients can still fill the screen. In the future XdgOutputV2 will support a more useful name and ID that we can use. [ChangeLog][QPA plugin] Added support for xdg-output-unstable-v1 Change-Id: I2e1e64ad6cb497a1cbb7b7b170f28ac92231c2c4 Reviewed-by: Pier Luigi Fiorini <pierluigi.fiorini@liri.io> Reviewed-by: Johan Helsing <johan.helsing@qt.io>
Diffstat (limited to 'src/client')
-rw-r--r--src/client/client.pro1
-rw-r--r--src/client/qwaylanddisplay.cpp5
-rw-r--r--src/client/qwaylanddisplay_p.h4
-rw-r--r--src/client/qwaylandscreen.cpp47
-rw-r--r--src/client/qwaylandscreen_p.h15
5 files changed, 65 insertions, 7 deletions
diff --git a/src/client/client.pro b/src/client/client.pro
index 593e8daf6..45bbb976b 100644
--- a/src/client/client.pro
+++ b/src/client/client.pro
@@ -28,6 +28,7 @@ WAYLANDCLIENTSOURCES += \
../extensions/qt-key-unstable-v1.xml \
../extensions/qt-windowmanager.xml \
../3rdparty/protocol/text-input-unstable-v2.xml \
+ ../3rdparty/protocol/xdg-output-unstable-v1.xml \
WAYLANDCLIENTSOURCES_SYSTEM += \
../3rdparty/protocol/wayland.xml \
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
index 03e4e3a2c..40ceafd96 100644
--- a/src/client/qwaylanddisplay.cpp
+++ b/src/client/qwaylanddisplay.cpp
@@ -276,6 +276,11 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
// make a roundtrip here since we need to receive the events sent by
// qt_hardware_integration before creating windows
forceRoundTrip();
+ } else if (interface == QLatin1String("zxdg_output_manager_v1")) {
+ mXdgOutputManager.reset(new QtWayland::zxdg_output_manager_v1(registry, id, 1));
+ for (auto *screen : qAsConst(mScreens))
+ screen->initXdgOutput(xdgOutputManager());
+ forceRoundTrip();
}
mGlobals.append(RegistryGlobal(id, interface, version, registry));
diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h
index 8570eba03..aee1ed45f 100644
--- a/src/client/qwaylanddisplay_p.h
+++ b/src/client/qwaylanddisplay_p.h
@@ -76,6 +76,7 @@ class QPlatformScreen;
namespace QtWayland {
class qt_surface_extension;
class zwp_text_input_manager_v2;
+ class zxdg_output_manager_v1;
}
namespace QtWaylandClient {
@@ -143,6 +144,8 @@ public:
QWaylandTouchExtension *touchExtension() const { return mTouchExtension.data(); }
QtWayland::zwp_text_input_manager_v2 *textInputManager() const { return mTextInputManager.data(); }
QWaylandHardwareIntegration *hardwareIntegration() const { return mHardwareIntegration.data(); }
+ QtWayland::zxdg_output_manager_v1 *xdgOutputManager() const { return mXdgOutputManager.data(); }
+
struct RegistryGlobal {
uint32_t id;
@@ -214,6 +217,7 @@ private:
QScopedPointer<QWaylandWindowManagerIntegration> mWindowManagerIntegration;
QScopedPointer<QtWayland::zwp_text_input_manager_v2> mTextInputManager;
QScopedPointer<QWaylandHardwareIntegration> mHardwareIntegration;
+ QScopedPointer<QtWayland::zxdg_output_manager_v1> mXdgOutputManager;
QSocketNotifier *mReadNotifier = nullptr;
int mFd;
int mWritableNotificationFd;
diff --git a/src/client/qwaylandscreen.cpp b/src/client/qwaylandscreen.cpp
index 37fe5f323..892ef974b 100644
--- a/src/client/qwaylandscreen.cpp
+++ b/src/client/qwaylandscreen.cpp
@@ -58,6 +58,23 @@ QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, int version, uin
, mWaylandDisplay(waylandDisplay)
, mOutputName(QStringLiteral("Screen%1").arg(id))
{
+ if (auto *xdgOutputManager = waylandDisplay->xdgOutputManager())
+ initXdgOutput(xdgOutputManager);
+}
+
+QWaylandScreen::~QWaylandScreen()
+{
+ if (zxdg_output_v1::isInitialized())
+ zxdg_output_v1::destroy();
+}
+
+void QWaylandScreen::initXdgOutput(QtWayland::zxdg_output_manager_v1 *xdgOutputManager)
+{
+ Q_ASSERT(xdgOutputManager);
+ if (zxdg_output_v1::isInitialized())
+ return;
+
+ zxdg_output_v1::init(xdgOutputManager->get_xdg_output(wl_output::object()));
}
QWaylandDisplay * QWaylandScreen::display() const
@@ -77,9 +94,13 @@ QString QWaylandScreen::model() const
QRect QWaylandScreen::geometry() const
{
- // Scale geometry for QScreen. This makes window and screen
- // geometry be in the same coordinate system.
- return QRect(mGeometry.topLeft(), mGeometry.size() / mScale);
+ if (zxdg_output_v1::isInitialized()) {
+ return mXdgGeometry;
+ } else {
+ // Scale geometry for QScreen. This makes window and screen
+ // geometry be in the same coordinate system.
+ return QRect(mGeometry.topLeft(), mGeometry.size() / mScale);
+ }
}
int QWaylandScreen::depth() const
@@ -184,7 +205,6 @@ void QWaylandScreen::output_mode(uint32_t flags, int width, int height, int refr
return;
QSize size(width, height);
-
if (size != mGeometry.size())
mGeometry.setSize(size);
@@ -247,8 +267,25 @@ void QWaylandScreen::output_done()
QWindowSystemInterface::handleScreenOrientationChange(screen(), m_orientation);
mTransform = -1;
}
- QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), geometry());
QWindowSystemInterface::handleScreenRefreshRateChange(screen(), refreshRate());
+ if (!zxdg_output_v1::isInitialized())
+ QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), geometry());
+}
+
+
+void QWaylandScreen::zxdg_output_v1_logical_position(int32_t x, int32_t y)
+{
+ mXdgGeometry.moveTopLeft(QPoint(x, y));
+}
+
+void QWaylandScreen::zxdg_output_v1_logical_size(int32_t width, int32_t height)
+{
+ mXdgGeometry.setSize(QSize(width, height));
+}
+
+void QWaylandScreen::zxdg_output_v1_done()
+{
+ QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), geometry());
}
}
diff --git a/src/client/qwaylandscreen_p.h b/src/client/qwaylandscreen_p.h
index 39b72bc24..6e4ed94f7 100644
--- a/src/client/qwaylandscreen_p.h
+++ b/src/client/qwaylandscreen_p.h
@@ -55,6 +55,8 @@
#include <QtWaylandClient/qtwaylandclientglobal.h>
#include <QtWaylandClient/private/qwayland-wayland.h>
+#include <QtWaylandClient/private/qwayland-xdg-output-unstable-v1.h>
+
QT_BEGIN_NAMESPACE
@@ -63,10 +65,13 @@ namespace QtWaylandClient {
class QWaylandDisplay;
class QWaylandCursor;
-class Q_WAYLAND_CLIENT_EXPORT QWaylandScreen : public QPlatformScreen, QtWayland::wl_output
+class Q_WAYLAND_CLIENT_EXPORT QWaylandScreen : public QPlatformScreen, QtWayland::wl_output, QtWayland::zxdg_output_v1
{
public:
QWaylandScreen(QWaylandDisplay *waylandDisplay, int version, uint32_t id);
+ ~QWaylandScreen() override;
+
+ void initXdgOutput(QtWayland::zxdg_output_manager_v1 *xdgOutputManager);
QWaylandDisplay *display() const;
@@ -97,7 +102,7 @@ public:
#endif
uint32_t outputId() const { return m_outputId; }
- ::wl_output *output() { return object(); }
+ ::wl_output *output() { return QtWayland::wl_output::object(); }
static QWaylandScreen *waylandScreenFromWindow(QWindow *window);
static QWaylandScreen *fromWlOutput(::wl_output *output);
@@ -113,11 +118,17 @@ private:
void output_scale(int32_t factor) override;
void output_done() override;
+ // XdgOutput
+ void zxdg_output_v1_logical_position(int32_t x, int32_t y) override;
+ void zxdg_output_v1_logical_size(int32_t width, int32_t height) override;
+ void zxdg_output_v1_done() override;
+
int m_outputId;
QWaylandDisplay *mWaylandDisplay = nullptr;
QString mManufacturer;
QString mModel;
QRect mGeometry;
+ QRect mXdgGeometry;
int mScale = 1;
int mDepth = 32;
int mRefreshRate = 60000;