Introduce new qt-shell and an API for custom shells
Adds a new API for writing custom shell extensions. This API is supported, but semi-public. Binary compatibility is not guaranteed. Also adds qt-shell, a new shell that maps directly to the QWindow API, and provides functionality that Qt provides on other window systems, such as absolute window positions and window activation. This shell is not intended for use on the desktop. This is a squashed commit of a development branch consisting of approximately 60 changes. Contributors: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> Paul Olav Tvete <paul.tvete@qt.io> Task-number: QTBUG-94330 Task-number: QTBUG-91542 Change-Id: I419b6bd8179fe03e4da47d328c7ff4b4795b8a91 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> Reviewed-by: David Edmundson <davidedmundson@kde.org> Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
This commit is contained in:
parent
0a8d63ea67
commit
a7bb7210ac
@ -48,7 +48,8 @@ qt_internal_add_module(WaylandClient
|
||||
qwaylandtouch.cpp qwaylandtouch_p.h
|
||||
qwaylandwindow.cpp qwaylandwindow_p.h
|
||||
qwaylandwindowmanagerintegration.cpp qwaylandwindowmanagerintegration_p.h
|
||||
shellintegration/qwaylandshellintegration_p.h
|
||||
shellintegration/qwaylandclientshellapi_p.h
|
||||
shellintegration/qwaylandshellintegration_p.h shellintegration/qwaylandshellintegration.cpp
|
||||
shellintegration/qwaylandshellintegrationfactory.cpp shellintegration/qwaylandshellintegrationfactory_p.h
|
||||
shellintegration/qwaylandshellintegrationplugin.cpp shellintegration/qwaylandshellintegrationplugin_p.h
|
||||
INCLUDE_DIRECTORIES
|
||||
|
@ -37,6 +37,10 @@ qt_feature("wayland-client-xdg-shell" PRIVATE
|
||||
LABEL "xdg-shell"
|
||||
CONDITION QT_FEATURE_wayland_client
|
||||
)
|
||||
qt_feature("wayland-client-qt-shell" PRIVATE
|
||||
LABEL "qt-shell"
|
||||
CONDITION QT_FEATURE_wayland_client
|
||||
)
|
||||
qt_feature("egl-extension-platform-wayland" PRIVATE
|
||||
LABEL "EGL wayland platform extension"
|
||||
CONDITION QT_FEATURE_wayland_client AND QT_FEATURE_opengl AND QT_FEATURE_egl AND TEST_egl_1_5_wayland
|
||||
@ -45,4 +49,5 @@ qt_configure_add_summary_section(NAME "Qt Wayland Client Shell Integrations")
|
||||
qt_configure_add_summary_entry(ARGS "wayland-client-xdg-shell")
|
||||
qt_configure_add_summary_entry(ARGS "wayland-client-ivi-shell")
|
||||
qt_configure_add_summary_entry(ARGS "wayland-client-wl-shell")
|
||||
qt_configure_add_summary_entry(ARGS "wayland-client-qt-shell")
|
||||
qt_configure_end_summary_section() # end of "Qt Wayland Client Shell Integrations" section
|
||||
|
@ -12,3 +12,7 @@ endif()
|
||||
if(QT_FEATURE_wayland_client_xdg_shell)
|
||||
add_subdirectory(xdg-shell)
|
||||
endif()
|
||||
|
||||
if(QT_FEATURE_wayland_client_qt_shell)
|
||||
add_subdirectory(qt-shell)
|
||||
endif()
|
||||
|
@ -44,23 +44,22 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QtWaylandClient {
|
||||
|
||||
bool QWaylandFullScreenShellV1Integration::initialize(QWaylandDisplay *display)
|
||||
bool QWaylandFullScreenShellV1Integration::initialize()
|
||||
{
|
||||
for (const QWaylandDisplay::RegistryGlobal &global : display->globals()) {
|
||||
if (global.interface == QLatin1String("zwp_fullscreen_shell_v1") && !m_shell) {
|
||||
m_shell.reset(new QtWayland::zwp_fullscreen_shell_v1(display->wl_registry(), global.id, global.version));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_shell)
|
||||
return true;
|
||||
wl_registry *registry;
|
||||
uint32_t id;
|
||||
uint32_t version;
|
||||
bool found = findGlobal(QLatin1String("zwp_fullscreen_shell_v1"), ®istry, &id, &version);
|
||||
if (found)
|
||||
m_shell.reset(new QtWayland::zwp_fullscreen_shell_v1(registry, id, version));
|
||||
if (!m_shell) {
|
||||
qCDebug(lcQpaWayland) << "Couldn't find global zwp_fullscreen_shell_v1 for fullscreen-shell";
|
||||
return false;
|
||||
}
|
||||
|
||||
return QWaylandShellIntegration::initialize(display);
|
||||
return true;
|
||||
}
|
||||
|
||||
QWaylandShellSurface *QWaylandFullScreenShellV1Integration::createShellSurface(QWaylandWindow *window)
|
||||
{
|
||||
return new QWaylandFullScreenShellV1Surface(m_shell.data(), window);
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include <wayland-client.h>
|
||||
#include <QtWaylandClient/private/qwayland-wayland.h>
|
||||
#include <QtWaylandClient/private/qwaylandshellintegration_p.h>
|
||||
#include <QScopedPointer>
|
||||
|
||||
#include "qwayland-fullscreen-shell-unstable-v1.h"
|
||||
|
||||
@ -53,7 +54,7 @@ namespace QtWaylandClient {
|
||||
class Q_WAYLAND_CLIENT_EXPORT QWaylandFullScreenShellV1Integration : public QWaylandShellIntegration
|
||||
{
|
||||
public:
|
||||
bool initialize(QWaylandDisplay *display) override;
|
||||
bool initialize() override;
|
||||
QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
|
||||
|
||||
private:
|
||||
|
@ -47,15 +47,16 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QtWaylandClient {
|
||||
|
||||
bool QWaylandWlShellIntegration::initialize(QWaylandDisplay *display)
|
||||
bool QWaylandWlShellIntegration::initialize()
|
||||
{
|
||||
const auto globals = display->globals();
|
||||
for (QWaylandDisplay::RegistryGlobal global : globals) {
|
||||
if (global.interface == QLatin1String("wl_shell")) {
|
||||
m_wlShell = new QtWayland::wl_shell(display->wl_registry(), global.id, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (m_wlShell)
|
||||
return true;
|
||||
wl_registry *registry;
|
||||
uint32_t id;
|
||||
uint32_t version;
|
||||
bool found = findGlobal(QLatin1String("wl_shell"), ®istry, &id, &version);
|
||||
if (found)
|
||||
m_wlShell = new QtWayland::wl_shell(registry, id, 1);
|
||||
|
||||
if (!m_wlShell) {
|
||||
qCDebug(lcQpaWayland) << "Couldn't find global wl_shell";
|
||||
@ -66,7 +67,7 @@ bool QWaylandWlShellIntegration::initialize(QWaylandDisplay *display)
|
||||
<< "\"xdg-shell\" if supported by the compositor"
|
||||
<< "by setting the environment variable QT_WAYLAND_SHELL_INTEGRATION";
|
||||
|
||||
return QWaylandShellIntegration::initialize(display);
|
||||
return true;
|
||||
}
|
||||
|
||||
QWaylandShellSurface *QWaylandWlShellIntegration::createShellSurface(QWaylandWindow *window)
|
||||
|
@ -63,7 +63,7 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandWlShellIntegration : public QWaylandShellI
|
||||
{
|
||||
public:
|
||||
QWaylandWlShellIntegration() {}
|
||||
bool initialize(QWaylandDisplay *) override;
|
||||
bool initialize() override;
|
||||
QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
|
||||
void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) override;
|
||||
|
||||
|
@ -47,21 +47,21 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QtWaylandClient {
|
||||
|
||||
bool QWaylandXdgShellIntegration::initialize(QWaylandDisplay *display)
|
||||
bool QWaylandXdgShellIntegration::initialize()
|
||||
{
|
||||
for (QWaylandDisplay::RegistryGlobal global : display->globals()) {
|
||||
if (global.interface == QLatin1String("xdg_wm_base")) {
|
||||
m_xdgShell.reset(new QWaylandXdgShell(display, global.id, global.version));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_xdgShell)
|
||||
return true;
|
||||
wl_registry *registry;
|
||||
uint32_t id;
|
||||
uint32_t version;
|
||||
bool found = findGlobal(QLatin1String("xdg_wm_base"), ®istry, &id, &version);
|
||||
if (found)
|
||||
m_xdgShell.reset(new QWaylandXdgShell(m_display, id, version));
|
||||
if (!m_xdgShell) {
|
||||
qCDebug(lcQpaWayland) << "Couldn't find global xdg_wm_base for xdg-shell stable";
|
||||
return false;
|
||||
}
|
||||
|
||||
return QWaylandShellIntegration::initialize(display);
|
||||
return true;
|
||||
}
|
||||
|
||||
QWaylandShellSurface *QWaylandXdgShellIntegration::createShellSurface(QWaylandWindow *window)
|
||||
|
@ -63,7 +63,7 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandXdgShellIntegration : public QWaylandShell
|
||||
{
|
||||
public:
|
||||
QWaylandXdgShellIntegration() {}
|
||||
bool initialize(QWaylandDisplay *display) override;
|
||||
bool initialize() override;
|
||||
QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override;
|
||||
void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) override;
|
||||
|
||||
|
@ -40,17 +40,6 @@
|
||||
#ifndef QWAYLANDCLIENTGLOBAL_H
|
||||
#define QWAYLANDCLIENTGLOBAL_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtGui/qtguiglobal.h>
|
||||
#include <QtWaylandClient/qtwaylandclient-config.h>
|
||||
|
||||
|
@ -217,6 +217,7 @@ public:
|
||||
bool isKeyboardAvailable() const;
|
||||
|
||||
void initEventThread();
|
||||
|
||||
public slots:
|
||||
void blockingReadEvents();
|
||||
void flushRequests();
|
||||
|
@ -83,12 +83,14 @@
|
||||
|
||||
#include "qwaylandserverbufferintegration_p.h"
|
||||
#include "qwaylandserverbufferintegrationfactory_p.h"
|
||||
#include "qwaylandshellsurface_p.h"
|
||||
|
||||
#include "qwaylandshellintegration_p.h"
|
||||
#include "qwaylandshellintegrationfactory_p.h"
|
||||
|
||||
#include "qwaylandinputdeviceintegration_p.h"
|
||||
#include "qwaylandinputdeviceintegrationfactory_p.h"
|
||||
#include "qwaylandwindow_p.h"
|
||||
|
||||
#if QT_CONFIG(accessibility_atspi_bridge)
|
||||
#include <QtGui/private/qspiaccessiblebridge_p.h>
|
||||
@ -119,6 +121,19 @@ QWaylandIntegration::QWaylandIntegration()
|
||||
mFailed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// ### Not ideal...
|
||||
// We don't want to use QPlatformWindow::requestActivate here, since that gives a warning
|
||||
// for most shells. Also, we don't want to put this into the specific shells that can use
|
||||
// it, since we want to support more than one shell in one client.
|
||||
// In addition, this will send a new requestActivate when the focus object changes, even if
|
||||
// the focus window stays the same.
|
||||
QObject::connect(qApp, &QGuiApplication::focusObjectChanged, qApp, [](){
|
||||
QWindow *fw = QGuiApplication::focusWindow();
|
||||
auto *w = fw ? static_cast<QWaylandWindow*>(fw->handle()) : nullptr;
|
||||
if (w && w->shellSurface())
|
||||
w->shellSurface()->requestActivate();
|
||||
});
|
||||
}
|
||||
|
||||
QWaylandIntegration::~QWaylandIntegration()
|
||||
@ -435,6 +450,7 @@ void QWaylandIntegration::initializeShellIntegration()
|
||||
} else {
|
||||
preferredShells << QLatin1String("xdg-shell");
|
||||
preferredShells << QLatin1String("wl-shell") << QLatin1String("ivi-shell");
|
||||
preferredShells << QLatin1String("qt-shell");
|
||||
}
|
||||
|
||||
for (const QString &preferredShell : qAsConst(preferredShells)) {
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "qwaylandshellsurface_p.h"
|
||||
#include "qwaylandwindow_p.h"
|
||||
#include "qwaylandextendedsurface_p.h"
|
||||
#include "qwaylandinputdevice_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -61,6 +62,49 @@ void QWaylandShellSurface::sendProperty(const QString &name, const QVariant &val
|
||||
Q_UNUSED(value);
|
||||
}
|
||||
|
||||
QPlatformWindow *QWaylandShellSurface::platformWindow()
|
||||
{
|
||||
return m_window;
|
||||
}
|
||||
|
||||
wl_surface *QWaylandShellSurface::wlSurface()
|
||||
{
|
||||
return m_window ? m_window->wlSurface() : nullptr;
|
||||
}
|
||||
|
||||
void QWaylandShellSurface::resizeFromApplyConfigure(const QSize &sizeWithMargins, const QPoint &offset)
|
||||
{
|
||||
m_window->resizeFromApplyConfigure(sizeWithMargins, offset);
|
||||
}
|
||||
|
||||
void QWaylandShellSurface::repositionFromApplyConfigure(const QPoint &position)
|
||||
{
|
||||
m_window->repositionFromApplyConfigure(position);
|
||||
}
|
||||
|
||||
void QWaylandShellSurface::setGeometryFromApplyConfigure(const QPoint &globalPosition, const QSize &sizeWithMargins)
|
||||
{
|
||||
m_window->setGeometryFromApplyConfigure(globalPosition, sizeWithMargins);
|
||||
}
|
||||
|
||||
void QWaylandShellSurface::applyConfigureWhenPossible()
|
||||
{
|
||||
m_window->applyConfigureWhenPossible();
|
||||
}
|
||||
|
||||
void QWaylandShellSurface::handleActivationChanged(bool activated)
|
||||
{
|
||||
if (activated)
|
||||
m_window->display()->handleWindowActivated(m_window);
|
||||
else
|
||||
m_window->display()->handleWindowDeactivated(m_window);
|
||||
}
|
||||
|
||||
uint32_t QWaylandShellSurface::getSerial(QWaylandInputDevice *inputDevice)
|
||||
{
|
||||
return inputDevice->serial();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -53,14 +53,16 @@
|
||||
|
||||
#include <QtCore/QSize>
|
||||
#include <QObject>
|
||||
|
||||
#include <QtWaylandClient/private/qwayland-wayland.h>
|
||||
#include <QPoint>
|
||||
#include <QtWaylandClient/qtwaylandclientglobal.h>
|
||||
|
||||
struct wl_surface;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QVariant;
|
||||
class QWindow;
|
||||
class QPlatformWindow;
|
||||
|
||||
namespace QtWaylandClient {
|
||||
|
||||
@ -90,15 +92,30 @@ public:
|
||||
|
||||
virtual void sendProperty(const QString &name, const QVariant &value);
|
||||
|
||||
inline QWaylandWindow *window() { return m_window; }
|
||||
|
||||
virtual void applyConfigure() {}
|
||||
virtual void requestWindowStates(Qt::WindowStates states) {Q_UNUSED(states);}
|
||||
virtual bool wantsDecorations() const { return false; }
|
||||
virtual QMargins serverSideFrameMargins() const { return QMargins(); }
|
||||
|
||||
virtual void propagateSizeHints() {}
|
||||
|
||||
virtual void setWindowGeometry(const QRect &rect) { Q_UNUSED(rect); }
|
||||
virtual void setWindowPosition(const QPoint &position) { Q_UNUSED(position); }
|
||||
|
||||
virtual bool requestActivate() { return false; }
|
||||
|
||||
inline QWaylandWindow *window() { return m_window; }
|
||||
QPlatformWindow *platformWindow();
|
||||
struct wl_surface *wlSurface();
|
||||
|
||||
protected:
|
||||
void resizeFromApplyConfigure(const QSize &sizeWithMargins, const QPoint &offset = {0, 0});
|
||||
void repositionFromApplyConfigure(const QPoint &position);
|
||||
void setGeometryFromApplyConfigure(const QPoint &globalPosition, const QSize &sizeWithMargins);
|
||||
void applyConfigureWhenPossible();
|
||||
void handleActivationChanged(bool activated);
|
||||
|
||||
static uint32_t getSerial(QWaylandInputDevice *inputDevice);
|
||||
|
||||
private:
|
||||
QWaylandWindow *m_window = nullptr;
|
||||
|
@ -342,7 +342,7 @@ void QWaylandWindow::setGeometry_helper(const QRect &rect)
|
||||
qBound(minimum.height(), rect.height(), maximum.height())));
|
||||
|
||||
if (mSubSurfaceWindow) {
|
||||
QMargins m = QPlatformWindow::parent()->frameMargins();
|
||||
QMargins m = static_cast<QWaylandWindow *>(QPlatformWindow::parent())->clientSideMargins();
|
||||
mSubSurfaceWindow->set_position(rect.x() + m.left(), rect.y() + m.top());
|
||||
|
||||
QWaylandWindow *parentWindow = mSubSurfaceWindow->parent();
|
||||
@ -372,16 +372,45 @@ void QWaylandWindow::setGeometry(const QRect &rect)
|
||||
if (isExposed() && !mInResizeFromApplyConfigure && exposeGeometry != mLastExposeGeometry)
|
||||
sendExposeEvent(exposeGeometry);
|
||||
|
||||
if (mShellSurface && isExposed())
|
||||
if (mShellSurface && isExposed()) {
|
||||
mShellSurface->setWindowGeometry(windowContentGeometry());
|
||||
if (!qt_window_private(window())->positionAutomatic)
|
||||
mShellSurface->setWindowPosition(windowGeometry().topLeft());
|
||||
}
|
||||
|
||||
if (isOpaque() && mMask.isEmpty())
|
||||
setOpaqueArea(rect);
|
||||
}
|
||||
|
||||
void QWaylandWindow::setGeometryFromApplyConfigure(const QPoint &globalPosition, const QSize &sizeWithMargins)
|
||||
{
|
||||
QMargins margins = clientSideMargins();
|
||||
|
||||
QPoint positionWithoutMargins = globalPosition + QPoint(margins.left(), margins.top());
|
||||
int widthWithoutMargins = qMax(sizeWithMargins.width() - (margins.left() + margins.right()), 1);
|
||||
int heightWithoutMargins = qMax(sizeWithMargins.height() - (margins.top() + margins.bottom()), 1);
|
||||
|
||||
QRect geometry(positionWithoutMargins, QSize(widthWithoutMargins, heightWithoutMargins));
|
||||
|
||||
mInResizeFromApplyConfigure = true;
|
||||
setGeometry(geometry);
|
||||
mInResizeFromApplyConfigure = false;
|
||||
}
|
||||
|
||||
void QWaylandWindow::repositionFromApplyConfigure(const QPoint &globalPosition)
|
||||
{
|
||||
QMargins margins = clientSideMargins();
|
||||
QPoint positionWithoutMargins = globalPosition + QPoint(margins.left(), margins.top());
|
||||
|
||||
QRect geometry(positionWithoutMargins, windowGeometry().size());
|
||||
mInResizeFromApplyConfigure = true;
|
||||
setGeometry(geometry);
|
||||
mInResizeFromApplyConfigure = false;
|
||||
}
|
||||
|
||||
void QWaylandWindow::resizeFromApplyConfigure(const QSize &sizeWithMargins, const QPoint &offset)
|
||||
{
|
||||
QMargins margins = frameMargins();
|
||||
QMargins margins = clientSideMargins();
|
||||
|
||||
// Exclude shadows from margins once they are excluded from window geometry
|
||||
// 1) First resizeFromApplyConfigure() call will have sizeWithMargins equal to surfaceSize()
|
||||
@ -394,7 +423,8 @@ void QWaylandWindow::resizeFromApplyConfigure(const QSize &sizeWithMargins, cons
|
||||
|
||||
int widthWithoutMargins = qMax(sizeWithMargins.width() - (margins.left() + margins.right()), 1);
|
||||
int heightWithoutMargins = qMax(sizeWithMargins.height() - (margins.top() + margins.bottom()), 1);
|
||||
QRect geometry(windowGeometry().topLeft(), QSize(widthWithoutMargins, heightWithoutMargins));
|
||||
QRect geometry(windowGeometry().topLeft() + QPoint(margins.left(), margins.top()),
|
||||
QSize(widthWithoutMargins, heightWithoutMargins));
|
||||
|
||||
mOffset += offset;
|
||||
mInResizeFromApplyConfigure = true;
|
||||
@ -411,7 +441,6 @@ void QWaylandWindow::sendExposeEvent(const QRect &rect)
|
||||
mLastExposeGeometry = rect;
|
||||
}
|
||||
|
||||
|
||||
static QList<QPointer<QWaylandWindow>> activePopups;
|
||||
|
||||
void QWaylandWindow::closePopups(QWaylandWindow *parent)
|
||||
@ -719,7 +748,15 @@ QMargins QWaylandWindow::frameMargins() const
|
||||
{
|
||||
if (mWindowDecoration)
|
||||
return mWindowDecoration->margins();
|
||||
return QPlatformWindow::frameMargins();
|
||||
else if (mShellSurface)
|
||||
return mShellSurface->serverSideFrameMargins();
|
||||
else
|
||||
return QPlatformWindow::frameMargins();
|
||||
}
|
||||
|
||||
QMargins QWaylandWindow::clientSideMargins() const
|
||||
{
|
||||
return mWindowDecoration ? mWindowDecoration->margins() : QMargins{};
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -727,7 +764,7 @@ QMargins QWaylandWindow::frameMargins() const
|
||||
*/
|
||||
QSize QWaylandWindow::surfaceSize() const
|
||||
{
|
||||
return geometry().marginsAdded(frameMargins()).size();
|
||||
return geometry().marginsAdded(clientSideMargins()).size();
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -753,7 +790,7 @@ QRect QWaylandWindow::windowContentGeometry() const
|
||||
*/
|
||||
QPointF QWaylandWindow::mapFromWlSurface(const QPointF &surfacePosition) const
|
||||
{
|
||||
const QMargins margins = frameMargins();
|
||||
const QMargins margins = clientSideMargins();
|
||||
return QPointF(surfacePosition.x() - margins.left(), surfacePosition.y() - margins.top());
|
||||
}
|
||||
|
||||
@ -980,7 +1017,7 @@ void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, const QWaylan
|
||||
|
||||
#if QT_CONFIG(cursor)
|
||||
if (e.type == QEvent::Enter) {
|
||||
QRect contentGeometry = windowContentGeometry().marginsRemoved(frameMargins());
|
||||
QRect contentGeometry = windowContentGeometry().marginsRemoved(clientSideMargins());
|
||||
if (contentGeometry.contains(e.local.toPoint()))
|
||||
restoreMouseCursor(inputDevice);
|
||||
}
|
||||
@ -1213,7 +1250,8 @@ void QWaylandWindow::restoreMouseCursor(QWaylandInputDevice *device)
|
||||
|
||||
void QWaylandWindow::requestActivateWindow()
|
||||
{
|
||||
qCWarning(lcQpaWayland) << "Wayland does not support QWindow::requestActivate()";
|
||||
if (mShellSurface == nullptr || !mShellSurface->requestActivate())
|
||||
qCWarning(lcQpaWayland) << "Wayland does not support QWindow::requestActivate()";
|
||||
}
|
||||
|
||||
bool QWaylandWindow::isExposed() const
|
||||
@ -1448,7 +1486,7 @@ bool QWaylandWindow::isOpaque() const
|
||||
|
||||
void QWaylandWindow::setOpaqueArea(const QRegion &opaqueArea)
|
||||
{
|
||||
const QRegion translatedOpaqueArea = opaqueArea.translated(frameMargins().left(), frameMargins().top());
|
||||
const QRegion translatedOpaqueArea = opaqueArea.translated(clientSideMargins().left(), clientSideMargins().top());
|
||||
|
||||
if (translatedOpaqueArea == mOpaqueArea || !mSurface)
|
||||
return;
|
||||
|
@ -123,6 +123,8 @@ public:
|
||||
|
||||
void setGeometry(const QRect &rect) override;
|
||||
void resizeFromApplyConfigure(const QSize &sizeWithMargins, const QPoint &offset = {0, 0});
|
||||
void repositionFromApplyConfigure(const QPoint &position);
|
||||
void setGeometryFromApplyConfigure(const QPoint &globalPosition, const QSize &sizeWithMargins);
|
||||
|
||||
void applyConfigureWhenPossible(); //rename to possible?
|
||||
|
||||
@ -239,6 +241,7 @@ protected:
|
||||
virtual void doHandleFrameCallback();
|
||||
virtual QRect defaultGeometry() const;
|
||||
void sendExposeEvent(const QRect &rect);
|
||||
QMargins clientSideMargins() const;
|
||||
|
||||
QWaylandDisplay *mDisplay = nullptr;
|
||||
QScopedPointer<QWaylandSurface> mSurface;
|
||||
|
@ -0,0 +1,60 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtWaylandClient module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QWAYLANDCLIENTSHELLAPI_P_H
|
||||
#define QWAYLANDCLIENTSHELLAPI_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
// N O T E
|
||||
// -------
|
||||
// This file provides a supported API for creating client-side shell
|
||||
// extensions. Source compatibility will be preserved, but we may break
|
||||
// forward and backward binary compatibility, even in patch releases.
|
||||
//
|
||||
// The supported API contains these classes:
|
||||
//
|
||||
// QtWaylandClient::QWaylandShellSurface
|
||||
// QtWaylandClient::QWaylandShellIntegration
|
||||
// QtWaylandClient::QWaylandShellIntegrationPlugin
|
||||
|
||||
#include "QtWaylandClient/private/qwaylandshellsurface_p.h"
|
||||
#include "QtWaylandClient/private/qwaylandshellintegration_p.h"
|
||||
#include "QtWaylandClient/private/qwaylandshellintegrationplugin_p.h"
|
||||
|
||||
#endif // QWAYLANDCLIENTSHELLAPI_P_H
|
@ -0,0 +1,57 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtWaylandClient module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "qwaylandshellintegration_p.h"
|
||||
#include <QtWaylandClient/private/qwaylanddisplay_p.h>
|
||||
#include <QtWaylandClient/private/qwaylandwindow_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QtWaylandClient {
|
||||
|
||||
wl_surface *QWaylandShellIntegration::wlSurfaceForWindow(QWaylandWindow *window)
|
||||
{
|
||||
return window->wlSurface();
|
||||
}
|
||||
|
||||
bool QWaylandShellIntegration::findGlobal(const QString &interface, wl_registry **registry, uint32_t *id, uint32_t *version)
|
||||
{
|
||||
for (QWaylandDisplay::RegistryGlobal &global : m_display->globals()) {
|
||||
if (global.interface == interface) {
|
||||
*registry = m_display->wl_registry();
|
||||
*id = global.id;
|
||||
*version = global.version;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
@ -52,10 +52,19 @@
|
||||
//
|
||||
|
||||
#include <QtWaylandClient/qtwaylandclientglobal.h>
|
||||
#include <QtWaylandClient/private/qwaylanddisplay_p.h>
|
||||
#include <QtWaylandClient/qwaylandclientextension.h>
|
||||
|
||||
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
struct wl_surface;
|
||||
struct wl_registry;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QWindow;
|
||||
|
||||
namespace QtWaylandClient {
|
||||
|
||||
class QWaylandWindow;
|
||||
@ -68,9 +77,12 @@ public:
|
||||
QWaylandShellIntegration() {}
|
||||
virtual ~QWaylandShellIntegration() {}
|
||||
|
||||
virtual bool initialize(QWaylandDisplay *display) {
|
||||
bool initialize(QWaylandDisplay *display) {
|
||||
m_display = display;
|
||||
return true;
|
||||
return initialize();
|
||||
}
|
||||
virtual bool initialize() {
|
||||
return false;
|
||||
}
|
||||
virtual QWaylandShellSurface *createShellSurface(QWaylandWindow *window) = 0;
|
||||
virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) {
|
||||
@ -79,10 +91,49 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static wl_surface *wlSurfaceForWindow(QWaylandWindow *window);
|
||||
bool findGlobal(const QString &interface, wl_registry **registry, uint32_t *id, uint32_t *version);
|
||||
|
||||
protected:
|
||||
QWaylandDisplay *m_display = nullptr;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Q_WAYLAND_CLIENT_EXPORT QWaylandShellIntegrationTemplate : public QWaylandShellIntegration, public QWaylandClientExtension
|
||||
{
|
||||
public:
|
||||
QWaylandShellIntegrationTemplate(const int ver) :
|
||||
QWaylandClientExtension(ver)
|
||||
{
|
||||
}
|
||||
|
||||
bool initialize() override
|
||||
{
|
||||
QWaylandClientExtension::initialize();
|
||||
return isActive();
|
||||
}
|
||||
|
||||
const struct wl_interface *extensionInterface() const override
|
||||
{
|
||||
return T::interface();
|
||||
}
|
||||
|
||||
void bind(struct ::wl_registry *registry, int id, int ver) override
|
||||
{
|
||||
T* instance = static_cast<T *>(this);
|
||||
// Make sure lowest version is used of the supplied version from the
|
||||
// developer and the version specified in the protocol and also the
|
||||
// compositor version.
|
||||
if (this->version() > T::interface()->version) {
|
||||
qWarning("Supplied protocol version to QWaylandClientExtensionTemplate is higher than the version of the protocol, using protocol version instead.");
|
||||
}
|
||||
int minVersion = qMin(ver, qMin(T::interface()->version, this->version()));
|
||||
setVersion(minVersion);
|
||||
instance->init(registry, id, minVersion);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
Loading…
x
Reference in New Issue
Block a user