QWaylandSurface: client support wl_surface version 6
Add QWaylandWindow::updateScale() function to update the window's scale from QWaylandFractionalScale or QWaylandSurface::preferredBufferScale or QWaylandScreen::scale or QWaylandSurface::preferredBufferScale. Add QWaylandWindow::updateBufferTransform() function to update the window's buffer transform from QScreen::primaryOrientation or QWaylandSurface::preferredBufferTransform. Change-Id: I2742701e92c7403a89df97b7fa06b5b0de6917a7 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: David Edmundson <davidedmundson@kde.org>
This commit is contained in:
parent
7666f93b3b
commit
e73979a94f
@ -618,7 +618,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
|
||||
if (interface == QLatin1String(QtWayland::wl_output::interface()->name)) {
|
||||
mWaitingScreens << mWaylandIntegration->createPlatformScreen(this, version, id);
|
||||
} else if (interface == QLatin1String(QtWayland::wl_compositor::interface()->name)) {
|
||||
mCompositor.init(registry, id, qMin((int)version, 4));
|
||||
mCompositor.init(registry, id, qMin((int)version, 6));
|
||||
} else if (interface == QLatin1String(QWaylandShm::interface()->name)) {
|
||||
mShm.reset(new QWaylandShm(this, version, id));
|
||||
} else if (interface == QLatin1String(QWaylandInputDevice::interface()->name)) {
|
||||
|
@ -22,7 +22,7 @@ void QWaylandFractionalScale::wp_fractional_scale_v1_preferred_scale(uint scale)
|
||||
qreal preferredScale = scale / 120.0; // hardcoded denominator determined in the spec
|
||||
if (preferredScale != mPreferredScale) {
|
||||
mPreferredScale = preferredScale;
|
||||
Q_EMIT preferredScaleChanged(preferredScale);
|
||||
Q_EMIT preferredScaleChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,8 +33,10 @@ public:
|
||||
explicit QWaylandFractionalScale(struct ::wp_fractional_scale_v1 *object);
|
||||
~QWaylandFractionalScale();
|
||||
|
||||
std::optional<qreal> preferredScale() const { return mPreferredScale; }
|
||||
|
||||
Q_SIGNALS:
|
||||
void preferredScaleChanged(qreal preferredScale);
|
||||
void preferredScaleChanged();
|
||||
|
||||
protected:
|
||||
void wp_fractional_scale_v1_preferred_scale(uint scale) override;
|
||||
|
@ -205,6 +205,35 @@ QWaylandScreen *QWaylandScreen::fromWlOutput(::wl_output *output)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Qt::ScreenOrientation QWaylandScreen::toScreenOrientation(int wlTransform,
|
||||
Qt::ScreenOrientation fallback) const
|
||||
{
|
||||
auto orientation = fallback;
|
||||
bool isPortrait = mGeometry.height() > mGeometry.width();
|
||||
switch (wlTransform) {
|
||||
case WL_OUTPUT_TRANSFORM_NORMAL:
|
||||
orientation = isPortrait ? Qt::PortraitOrientation : Qt::LandscapeOrientation;
|
||||
break;
|
||||
case WL_OUTPUT_TRANSFORM_90:
|
||||
orientation = isPortrait ? Qt::InvertedLandscapeOrientation : Qt::PortraitOrientation;
|
||||
break;
|
||||
case WL_OUTPUT_TRANSFORM_180:
|
||||
orientation = isPortrait ? Qt::InvertedPortraitOrientation : Qt::InvertedLandscapeOrientation;
|
||||
break;
|
||||
case WL_OUTPUT_TRANSFORM_270:
|
||||
orientation = isPortrait ? Qt::LandscapeOrientation : Qt::InvertedPortraitOrientation;
|
||||
break;
|
||||
// Ignore these ones, at least for now
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED:
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
|
||||
break;
|
||||
}
|
||||
|
||||
return orientation;
|
||||
}
|
||||
|
||||
void QWaylandScreen::output_mode(uint32_t flags, int width, int height, int refresh)
|
||||
{
|
||||
if (!(flags & WL_OUTPUT_MODE_CURRENT))
|
||||
@ -257,29 +286,11 @@ void QWaylandScreen::output_done()
|
||||
void QWaylandScreen::updateOutputProperties()
|
||||
{
|
||||
if (mTransform >= 0) {
|
||||
bool isPortrait = mGeometry.height() > mGeometry.width();
|
||||
switch (mTransform) {
|
||||
case WL_OUTPUT_TRANSFORM_NORMAL:
|
||||
m_orientation = isPortrait ? Qt::PortraitOrientation : Qt::LandscapeOrientation;
|
||||
break;
|
||||
case WL_OUTPUT_TRANSFORM_90:
|
||||
m_orientation = isPortrait ? Qt::InvertedLandscapeOrientation : Qt::PortraitOrientation;
|
||||
break;
|
||||
case WL_OUTPUT_TRANSFORM_180:
|
||||
m_orientation = isPortrait ? Qt::InvertedPortraitOrientation : Qt::InvertedLandscapeOrientation;
|
||||
break;
|
||||
case WL_OUTPUT_TRANSFORM_270:
|
||||
m_orientation = isPortrait ? Qt::LandscapeOrientation : Qt::InvertedPortraitOrientation;
|
||||
break;
|
||||
// Ignore these ones, at least for now
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED:
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
|
||||
break;
|
||||
auto newOrientation = toScreenOrientation(mTransform, m_orientation);
|
||||
if (m_orientation != newOrientation) {
|
||||
m_orientation = newOrientation;
|
||||
QWindowSystemInterface::handleScreenOrientationChange(screen(), m_orientation);
|
||||
}
|
||||
|
||||
QWindowSystemInterface::handleScreenOrientationChange(screen(), m_orientation);
|
||||
mTransform = -1;
|
||||
}
|
||||
|
||||
|
@ -82,6 +82,9 @@ public:
|
||||
static QWaylandScreen *waylandScreenFromWindow(QWindow *window);
|
||||
static QWaylandScreen *fromWlOutput(::wl_output *output);
|
||||
|
||||
Qt::ScreenOrientation toScreenOrientation(int wlTransform,
|
||||
Qt::ScreenOrientation fallback) const;
|
||||
|
||||
protected:
|
||||
enum Event : uint {
|
||||
XdgOutputDoneEvent = 0x1,
|
||||
|
@ -85,6 +85,22 @@ void QWaylandSurface::surface_leave(wl_output *output)
|
||||
emit screensChanged();
|
||||
}
|
||||
|
||||
void QWaylandSurface::surface_preferred_buffer_scale(int32_t scale)
|
||||
{
|
||||
if (m_preferredBufferScale == scale)
|
||||
return;
|
||||
m_preferredBufferScale = scale;
|
||||
Q_EMIT preferredBufferScaleChanged();
|
||||
}
|
||||
|
||||
void QWaylandSurface::surface_preferred_buffer_transform(uint32_t transform)
|
||||
{
|
||||
if (m_preferredBufferTransform == transform)
|
||||
return;
|
||||
m_preferredBufferTransform = static_cast<wl_output_transform>(transform);
|
||||
Q_EMIT preferredBufferTransformChanged();
|
||||
}
|
||||
|
||||
} // namespace QtWaylandClient
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -36,11 +36,15 @@ public:
|
||||
~QWaylandSurface() override;
|
||||
QWaylandScreen *oldestEnteredScreen();
|
||||
QWaylandWindow *waylandWindow() const { return m_window; }
|
||||
std::optional<int32_t> preferredBufferScale() const { return m_preferredBufferScale; }
|
||||
std::optional<wl_output_transform> preferredBufferTransform() const { return m_preferredBufferTransform; }
|
||||
|
||||
static QWaylandSurface *fromWlSurface(::wl_surface *surface);
|
||||
|
||||
signals:
|
||||
void screensChanged();
|
||||
void preferredBufferScaleChanged();
|
||||
void preferredBufferTransformChanged();
|
||||
|
||||
private slots:
|
||||
void handleScreenRemoved(QScreen *qScreen);
|
||||
@ -48,9 +52,13 @@ private slots:
|
||||
protected:
|
||||
void surface_enter(struct ::wl_output *output) override;
|
||||
void surface_leave(struct ::wl_output *output) override;
|
||||
void surface_preferred_buffer_scale(int32_t scale) override;
|
||||
void surface_preferred_buffer_transform(uint32_t transform) override;
|
||||
|
||||
QList<QWaylandScreen *> m_screens; //As seen by wl_surface.enter/leave events. Chronological order.
|
||||
QWaylandWindow *m_window = nullptr;
|
||||
std::optional<int32_t> m_preferredBufferScale;
|
||||
std::optional<wl_output_transform> m_preferredBufferTransform;
|
||||
|
||||
friend class QWaylandWindow; // TODO: shouldn't need to be friends
|
||||
};
|
||||
|
@ -105,11 +105,8 @@ void QWaylandWindow::initWindow()
|
||||
if (mDisplay->fractionalScaleManager() && qApp->highDpiScaleFactorRoundingPolicy() == Qt::HighDpiScaleFactorRoundingPolicy::PassThrough) {
|
||||
mFractionalScale.reset(new QWaylandFractionalScale(mDisplay->fractionalScaleManager()->get_fractional_scale(mSurface->object())));
|
||||
|
||||
connect(mFractionalScale.data(), &QWaylandFractionalScale::preferredScaleChanged, this, [this](qreal preferredScale) {
|
||||
preferredScale = std::max(1.0, preferredScale);
|
||||
Q_ASSERT(mViewport);
|
||||
setScale(preferredScale);
|
||||
});
|
||||
connect(mFractionalScale.data(), &QWaylandFractionalScale::preferredScaleChanged,
|
||||
this, &QWaylandWindow::updateScale);
|
||||
}
|
||||
|
||||
if (shouldCreateSubSurface()) {
|
||||
@ -209,6 +206,10 @@ void QWaylandWindow::initializeWlSurface()
|
||||
mSurface.reset(new QWaylandSurface(mDisplay));
|
||||
connect(mSurface.data(), &QWaylandSurface::screensChanged,
|
||||
this, &QWaylandWindow::handleScreensChanged);
|
||||
connect(mSurface.data(), &QWaylandSurface::preferredBufferScaleChanged,
|
||||
this, &QWaylandWindow::updateScale);
|
||||
connect(mSurface.data(), &QWaylandSurface::preferredBufferTransformChanged,
|
||||
this, &QWaylandWindow::updateBufferTransform);
|
||||
mSurface->m_window = this;
|
||||
}
|
||||
emit wlSurfaceCreated();
|
||||
@ -941,31 +942,49 @@ QWaylandScreen *QWaylandWindow::waylandScreen() const
|
||||
}
|
||||
|
||||
void QWaylandWindow::handleContentOrientationChange(Qt::ScreenOrientation orientation)
|
||||
{
|
||||
mLastReportedContentOrientation = orientation;
|
||||
updateBufferTransform();
|
||||
}
|
||||
|
||||
void QWaylandWindow::updateBufferTransform()
|
||||
{
|
||||
QReadLocker locker(&mSurfaceLock);
|
||||
if (mSurface == nullptr || mSurface->version() < 2)
|
||||
return;
|
||||
|
||||
wl_output_transform transform;
|
||||
bool isPortrait = window()->screen() && window()->screen()->primaryOrientation() == Qt::PortraitOrientation;
|
||||
switch (orientation) {
|
||||
case Qt::PrimaryOrientation:
|
||||
transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
break;
|
||||
case Qt::LandscapeOrientation:
|
||||
transform = isPortrait ? WL_OUTPUT_TRANSFORM_270 : WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
break;
|
||||
case Qt::PortraitOrientation:
|
||||
transform = isPortrait ? WL_OUTPUT_TRANSFORM_NORMAL : WL_OUTPUT_TRANSFORM_90;
|
||||
break;
|
||||
case Qt::InvertedLandscapeOrientation:
|
||||
transform = isPortrait ? WL_OUTPUT_TRANSFORM_90 : WL_OUTPUT_TRANSFORM_180;
|
||||
break;
|
||||
case Qt::InvertedPortraitOrientation:
|
||||
transform = isPortrait ? WL_OUTPUT_TRANSFORM_180 : WL_OUTPUT_TRANSFORM_270;
|
||||
break;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
Qt::ScreenOrientation screenOrientation = Qt::PrimaryOrientation;
|
||||
|
||||
if (mSurface->version() >= 6) {
|
||||
const auto transform = mSurface->preferredBufferTransform().value_or(WL_OUTPUT_TRANSFORM_NORMAL);
|
||||
if (auto screen = waylandScreen())
|
||||
screenOrientation = screen->toScreenOrientation(transform, Qt::PrimaryOrientation);
|
||||
} else {
|
||||
if (auto screen = window()->screen())
|
||||
screenOrientation = screen->primaryOrientation();
|
||||
}
|
||||
|
||||
const bool isPortrait = (screenOrientation == Qt::PortraitOrientation);
|
||||
|
||||
switch (mLastReportedContentOrientation) {
|
||||
case Qt::PrimaryOrientation:
|
||||
transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
break;
|
||||
case Qt::LandscapeOrientation:
|
||||
transform = isPortrait ? WL_OUTPUT_TRANSFORM_270 : WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
break;
|
||||
case Qt::PortraitOrientation:
|
||||
transform = isPortrait ? WL_OUTPUT_TRANSFORM_NORMAL : WL_OUTPUT_TRANSFORM_90;
|
||||
break;
|
||||
case Qt::InvertedLandscapeOrientation:
|
||||
transform = isPortrait ? WL_OUTPUT_TRANSFORM_90 : WL_OUTPUT_TRANSFORM_180;
|
||||
break;
|
||||
case Qt::InvertedPortraitOrientation:
|
||||
transform = isPortrait ? WL_OUTPUT_TRANSFORM_180 : WL_OUTPUT_TRANSFORM_270;
|
||||
break;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
mSurface->set_buffer_transform(transform);
|
||||
}
|
||||
@ -1379,8 +1398,26 @@ void QWaylandWindow::handleScreensChanged()
|
||||
setGeometry(geometry);
|
||||
}
|
||||
|
||||
if (mFractionalScale)
|
||||
updateScale();
|
||||
updateBufferTransform();
|
||||
}
|
||||
|
||||
void QWaylandWindow::updateScale()
|
||||
{
|
||||
if (mFractionalScale) {
|
||||
auto preferredScale = mFractionalScale->preferredScale().value_or(1.0);
|
||||
preferredScale = std::max(1.0, preferredScale);
|
||||
Q_ASSERT(mViewport);
|
||||
setScale(preferredScale);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mSurface && mSurface->version() >= 6) {
|
||||
auto preferredScale = mSurface->preferredBufferScale().value_or(1);
|
||||
preferredScale = std::max(1, preferredScale);
|
||||
setScale(preferredScale);
|
||||
return;
|
||||
}
|
||||
|
||||
int scale = mLastReportedScreen->isPlaceholder() ? 1 : static_cast<QWaylandScreen *>(mLastReportedScreen)->scale();
|
||||
setScale(scale);
|
||||
|
@ -142,6 +142,7 @@ public:
|
||||
QWaylandScreen *waylandScreen() const;
|
||||
|
||||
void handleContentOrientationChange(Qt::ScreenOrientation orientation) override;
|
||||
void updateBufferTransform();
|
||||
void setOrientationMask(Qt::ScreenOrientations mask);
|
||||
|
||||
ToplevelWindowTilingStates toplevelWindowTilingStates() const;
|
||||
@ -331,6 +332,8 @@ protected:
|
||||
QPointer<QWaylandWindow> mTransientParent;
|
||||
QList<QPointer<QWaylandWindow>> mChildPopups;
|
||||
|
||||
Qt::ScreenOrientation mLastReportedContentOrientation = Qt::PrimaryOrientation;
|
||||
|
||||
private slots:
|
||||
void doApplyConfigureFromOtherThread();
|
||||
|
||||
@ -348,6 +351,7 @@ private:
|
||||
|
||||
void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e);
|
||||
void handleScreensChanged();
|
||||
void updateScale();
|
||||
void setScale(qreal newScale);
|
||||
void sendRecursiveExposeEvent();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user