Merge remote-tracking branch 'origin/5.4' into dev
Conflicts: src/compositor/wayland_wrapper/qwlcompositor.cpp Change-Id: Ica26e33eb2b77ed5be0e84e8f4256d2e85abfaf5
This commit is contained in:
commit
03c1b4d4ca
@ -62,7 +62,10 @@ public:
|
||||
|
||||
virtual void initialize(QWaylandDisplay *display) = 0;
|
||||
|
||||
virtual bool isValid() const { return true; }
|
||||
|
||||
virtual bool supportsThreadedOpenGL() const { return false; }
|
||||
virtual bool supportsWindowDecoration() const { return false; }
|
||||
|
||||
virtual QWaylandWindow *createEglWindow(QWindow *window) = 0;
|
||||
virtual QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const = 0;
|
||||
|
@ -45,7 +45,7 @@
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QWaylandHardwareIntegration::QWaylandHardwareIntegration(struct ::wl_registry *registry, int id)
|
||||
: qt_hardware_integration(registry, id)
|
||||
: qt_hardware_integration(registry, id, 1)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,11 @@ QWaylandDataOffer *QWaylandDataDevice::selectionOffer() const
|
||||
return m_selectionOffer.data();
|
||||
}
|
||||
|
||||
void QWaylandDataDevice::invalidateSelectionOffer()
|
||||
{
|
||||
m_selectionOffer.reset();
|
||||
}
|
||||
|
||||
QWaylandDataSource *QWaylandDataDevice::selectionSource() const
|
||||
{
|
||||
return m_selectionSource.data();
|
||||
|
@ -65,6 +65,7 @@ public:
|
||||
~QWaylandDataDevice();
|
||||
|
||||
QWaylandDataOffer *selectionOffer() const;
|
||||
void invalidateSelectionOffer();
|
||||
QWaylandDataSource *selectionSource() const;
|
||||
void setSelectionSource(QWaylandDataSource *source);
|
||||
|
||||
|
@ -51,7 +51,7 @@
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QWaylandDataDeviceManager::QWaylandDataDeviceManager(QWaylandDisplay *display, uint32_t id)
|
||||
: wl_data_device_manager(display->wl_registry(), id)
|
||||
: wl_data_device_manager(display->wl_registry(), id, 1)
|
||||
, m_display(display)
|
||||
{
|
||||
// Create transfer devices for all input devices.
|
||||
|
@ -94,30 +94,18 @@ QWaylandMimeData::~QWaylandMimeData()
|
||||
|
||||
void QWaylandMimeData::appendFormat(const QString &mimeType)
|
||||
{
|
||||
if (m_types.contains(mimeType))
|
||||
close(m_types.take(mimeType)); // Unconsumed data
|
||||
m_types << mimeType;
|
||||
m_data.remove(mimeType); // Clear previous contents
|
||||
|
||||
int pipefd[2];
|
||||
if (::pipe2(pipefd, O_CLOEXEC|O_NONBLOCK) == -1) {
|
||||
qWarning("QWaylandMimeData: pipe2() failed");
|
||||
return;
|
||||
}
|
||||
|
||||
m_dataOffer->receive(mimeType, pipefd[1]);
|
||||
m_display->forceRoundTrip();
|
||||
close(pipefd[1]);
|
||||
m_types.insert(mimeType, pipefd[0]);
|
||||
}
|
||||
|
||||
bool QWaylandMimeData::hasFormat_sys(const QString &mimeType) const
|
||||
{
|
||||
return m_types.contains(mimeType) || m_data.contains(mimeType);
|
||||
return m_types.contains(mimeType);
|
||||
}
|
||||
|
||||
QStringList QWaylandMimeData::formats_sys() const
|
||||
{
|
||||
return m_types.keys() << m_data.keys();
|
||||
return m_types;
|
||||
}
|
||||
|
||||
QVariant QWaylandMimeData::retrieveData_sys(const QString &mimeType, QVariant::Type type) const
|
||||
@ -130,14 +118,24 @@ QVariant QWaylandMimeData::retrieveData_sys(const QString &mimeType, QVariant::T
|
||||
if (!m_types.contains(mimeType))
|
||||
return QVariant();
|
||||
|
||||
int pipefd[2];
|
||||
if (::pipe2(pipefd, O_CLOEXEC|O_NONBLOCK) == -1) {
|
||||
qWarning("QWaylandMimeData: pipe2() failed");
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
m_dataOffer->receive(mimeType, pipefd[1]);
|
||||
m_display->flushRequests();
|
||||
|
||||
close(pipefd[1]);
|
||||
|
||||
QByteArray content;
|
||||
int fd = m_types.take(mimeType);
|
||||
if (readData(fd, content) != 0) {
|
||||
if (readData(pipefd[0], content) != 0) {
|
||||
qWarning("QWaylandDataOffer: error reading data for mimeType %s", qPrintable(mimeType));
|
||||
content = QByteArray();
|
||||
}
|
||||
|
||||
close(fd);
|
||||
close(pipefd[0]);
|
||||
m_data.insert(mimeType, content);
|
||||
return content;
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ private:
|
||||
|
||||
mutable QWaylandDataOffer *m_dataOffer;
|
||||
QWaylandDisplay *m_display;
|
||||
mutable QHash<QString, int> m_types;
|
||||
mutable QStringList m_types;
|
||||
mutable QHash<QString, QByteArray> m_data;
|
||||
};
|
||||
|
||||
|
@ -186,7 +186,7 @@ void QWaylandDecoration::paint(QPaintDevice *device)
|
||||
// Title bar
|
||||
QPoint gradCenter(top.center()+ QPoint(30, 60));
|
||||
QLinearGradient grad(top.topLeft(), top.bottomLeft());
|
||||
QColor base(backgroundColor());
|
||||
QColor base(m_backgroundColor);
|
||||
grad.setColorAt(0, base.lighter(100));
|
||||
grad.setColorAt(1, base.darker(180));
|
||||
QPainterPath roundedRect;
|
||||
@ -335,6 +335,28 @@ bool QWaylandDecoration::handleMouse(QWaylandInputDevice *inputDevice, const QPo
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QWaylandDecoration::handleTouch(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::TouchPointState state, Qt::KeyboardModifiers mods)
|
||||
{
|
||||
Q_UNUSED(inputDevice);
|
||||
Q_UNUSED(global);
|
||||
Q_UNUSED(mods);
|
||||
bool handled = state == Qt::TouchPointPressed;
|
||||
if (handled) {
|
||||
if (closeButtonRect().contains(local))
|
||||
QWindowSystemInterface::handleCloseEvent(m_window);
|
||||
else if (maximizeButtonRect().contains(local))
|
||||
m_window->setWindowState(m_wayland_window->isMaximized() ? Qt::WindowNoState : Qt::WindowMaximized);
|
||||
else if (minimizeButtonRect().contains(local))
|
||||
m_window->setWindowState(Qt::WindowMinimized);
|
||||
else if (local.y() <= m_margins.top())
|
||||
m_wayland_window->shellSurface()->move(inputDevice);
|
||||
else
|
||||
handled = false;
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
bool QWaylandDecoration::inMouseButtonPressedState() const
|
||||
{
|
||||
return m_mouseButtons & Qt::NoButton;
|
||||
@ -446,14 +468,4 @@ QRectF QWaylandDecoration::minimizeButtonRect() const
|
||||
(m_margins.top() - BUTTON_WIDTH) / 2, BUTTON_WIDTH, BUTTON_WIDTH);
|
||||
}
|
||||
|
||||
void QWaylandDecoration::setForegroundColor(const QColor &c)
|
||||
{
|
||||
m_foregroundColor = c;
|
||||
}
|
||||
|
||||
void QWaylandDecoration::setBackgroundColor(const QColor &c)
|
||||
{
|
||||
m_backgroundColor = c;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -75,6 +75,7 @@ public:
|
||||
bool isDirty() const;
|
||||
|
||||
bool handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,Qt::MouseButtons b,Qt::KeyboardModifiers mods);
|
||||
bool handleTouch(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::TouchPointState state, Qt::KeyboardModifiers mods);
|
||||
bool inMouseButtonPressedState() const;
|
||||
|
||||
void startResize(QWaylandInputDevice *inputDevice,enum wl_shell_surface_resize resize, Qt::MouseButtons buttons);
|
||||
@ -84,12 +85,6 @@ public:
|
||||
QWaylandWindow *waylandWindow() const;
|
||||
const QImage &contentImage();
|
||||
|
||||
void setForegroundColor(const QColor &c);
|
||||
inline QColor foregroundColor() const;
|
||||
|
||||
void setBackgroundColor(const QColor &c);
|
||||
inline QColor backgroundColor() const;
|
||||
|
||||
protected:
|
||||
void paint(QPaintDevice *device);
|
||||
|
||||
@ -140,16 +135,6 @@ inline QWaylandWindow *QWaylandDecoration::waylandWindow() const
|
||||
return m_wayland_window;
|
||||
}
|
||||
|
||||
inline QColor QWaylandDecoration::foregroundColor() const
|
||||
{
|
||||
return m_foregroundColor;
|
||||
}
|
||||
|
||||
inline QColor QWaylandDecoration::backgroundColor() const
|
||||
{
|
||||
return m_backgroundColor;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QWAYLANDDECORATION_H
|
||||
|
@ -56,6 +56,7 @@
|
||||
|
||||
#include "qwaylandwindowmanagerintegration_p.h"
|
||||
#include "qwaylandshellintegration_p.h"
|
||||
#include "qwaylandclientbufferintegration_p.h"
|
||||
|
||||
#include "qwaylandextendedoutput_p.h"
|
||||
#include "qwaylandextendedsurface_p.h"
|
||||
@ -126,8 +127,6 @@ void QWaylandDisplay::setLastKeyboardFocusInputDevice(QWaylandInputDevice *devic
|
||||
mLastKeyboardFocusInputDevice = device;
|
||||
}
|
||||
|
||||
static QWaylandDisplay *display = 0;
|
||||
|
||||
QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration)
|
||||
: mWaylandIntegration(waylandIntegration)
|
||||
, mLastKeyboardFocusInputDevice(0)
|
||||
@ -140,7 +139,6 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration)
|
||||
, mTextInputManager(0)
|
||||
, mHardwareIntegration(0)
|
||||
{
|
||||
display = this;
|
||||
qRegisterMetaType<uint32_t>("uint32_t");
|
||||
|
||||
mEventThreadObject = new QWaylandEventThread(0);
|
||||
@ -169,6 +167,8 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration)
|
||||
|
||||
QWaylandDisplay::~QWaylandDisplay(void)
|
||||
{
|
||||
qDeleteAll(mScreens);
|
||||
mScreens.clear();
|
||||
delete mDndSelectionHandler.take();
|
||||
mEventThread->quit();
|
||||
mEventThread->wait();
|
||||
@ -177,20 +177,17 @@ QWaylandDisplay::~QWaylandDisplay(void)
|
||||
|
||||
void QWaylandDisplay::flushRequests()
|
||||
{
|
||||
if (wl_display_dispatch_queue_pending(mDisplay, mEventQueue) == -1 && (errno == EPIPE || errno == ECONNRESET)) {
|
||||
qWarning("The Wayland connection broke. Did the Wayland compositor die?");
|
||||
::exit(1);
|
||||
}
|
||||
if (wl_display_dispatch_queue_pending(mDisplay, mEventQueue) < 0)
|
||||
mEventThreadObject->checkErrorAndExit();
|
||||
|
||||
wl_display_flush(mDisplay);
|
||||
}
|
||||
|
||||
|
||||
void QWaylandDisplay::blockingReadEvents()
|
||||
{
|
||||
if (wl_display_dispatch_queue(mDisplay, mEventQueue) == -1 && (errno == EPIPE || errno == ECONNRESET)) {
|
||||
qWarning("The Wayland connection broke. Did the Wayland compositor die?");
|
||||
::exit(1);
|
||||
}
|
||||
if (wl_display_dispatch_queue(mDisplay, mEventQueue) < 0)
|
||||
mEventThreadObject->checkErrorAndExit();
|
||||
}
|
||||
|
||||
QWaylandScreen *QWaylandDisplay::screenForOutput(struct wl_output *output) const
|
||||
@ -229,37 +226,39 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
|
||||
struct ::wl_registry *registry = object();
|
||||
|
||||
if (interface == QStringLiteral("wl_output")) {
|
||||
mScreens.append(new QWaylandScreen(this, id));
|
||||
QWaylandScreen *screen = new QWaylandScreen(this, id);
|
||||
mScreens.append(screen);
|
||||
// We need to get the output events before creating surfaces
|
||||
forceRoundTrip();
|
||||
mWaylandIntegration->screenAdded(screen);
|
||||
} else if (interface == QStringLiteral("wl_compositor")) {
|
||||
mCompositor.init(registry, id);
|
||||
mCompositor.init(registry, id, 3);
|
||||
} else if (interface == QStringLiteral("wl_shm")) {
|
||||
mShm = static_cast<struct wl_shm *>(wl_registry_bind(registry, id, &wl_shm_interface,1));
|
||||
} else if (interface == QStringLiteral("xdg_shell")
|
||||
&& qEnvironmentVariableIsSet("QT_WAYLAND_USE_XDG_SHELL")) {
|
||||
mShellXdg.reset(new QWaylandXdgShell(registry,id));
|
||||
} else if (interface == QStringLiteral("wl_shell")){
|
||||
mShell.reset(new QtWayland::wl_shell(registry, id));
|
||||
mShell.reset(new QtWayland::wl_shell(registry, id, 1));
|
||||
} else if (interface == QStringLiteral("wl_seat")) {
|
||||
QWaylandInputDevice *inputDevice = new QWaylandInputDevice(this, id);
|
||||
mInputDevices.append(inputDevice);
|
||||
} else if (interface == QStringLiteral("wl_data_device_manager")) {
|
||||
mDndSelectionHandler.reset(new QWaylandDataDeviceManager(this, id));
|
||||
} else if (interface == QStringLiteral("qt_output_extension")) {
|
||||
mOutputExtension.reset(new QtWayland::qt_output_extension(registry, id));
|
||||
mOutputExtension.reset(new QtWayland::qt_output_extension(registry, id, 1));
|
||||
foreach (QPlatformScreen *screen, screens())
|
||||
static_cast<QWaylandScreen *>(screen)->createExtendedOutput();
|
||||
} else if (interface == QStringLiteral("qt_surface_extension")) {
|
||||
mWindowExtension.reset(new QtWayland::qt_surface_extension(registry, id));
|
||||
mWindowExtension.reset(new QtWayland::qt_surface_extension(registry, id, 1));
|
||||
} else if (interface == QStringLiteral("qt_sub_surface_extension")) {
|
||||
mSubSurfaceExtension.reset(new QtWayland::qt_sub_surface_extension(registry, id));
|
||||
mSubSurfaceExtension.reset(new QtWayland::qt_sub_surface_extension(registry, id, 1));
|
||||
} else if (interface == QStringLiteral("qt_touch_extension")) {
|
||||
mTouchExtension.reset(new QWaylandTouchExtension(this, id));
|
||||
} else if (interface == QStringLiteral("qt_key_extension")) {
|
||||
mQtKeyExtension.reset(new QWaylandQtKeyExtension(this, id));
|
||||
} else if (interface == QStringLiteral("wl_text_input_manager")) {
|
||||
mTextInputManager.reset(new QtWayland::wl_text_input_manager(registry, id));
|
||||
mTextInputManager.reset(new QtWayland::wl_text_input_manager(registry, id, 1));
|
||||
} else if (interface == QStringLiteral("qt_hardware_integration")) {
|
||||
mHardwareIntegration.reset(new QWaylandHardwareIntegration(registry, id));
|
||||
// make a roundtrip here since we need to receive the events sent by
|
||||
@ -276,7 +275,17 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
|
||||
void QWaylandDisplay::registry_global_remove(uint32_t id)
|
||||
{
|
||||
for (int i = 0, ie = mGlobals.count(); i != ie; ++i) {
|
||||
if (mGlobals[i].id == id) {
|
||||
RegistryGlobal &global = mGlobals[i];
|
||||
if (global.id == id) {
|
||||
if (global.interface == QStringLiteral("wl_output")) {
|
||||
foreach (QWaylandScreen *screen, mScreens) {
|
||||
if (screen->outputId() == id) {
|
||||
delete screen;
|
||||
mScreens.removeOne(screen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
mGlobals.removeAt(i);
|
||||
break;
|
||||
}
|
||||
@ -337,4 +346,16 @@ QtWayland::xdg_shell *QWaylandDisplay::shellXdg()
|
||||
return mShellXdg.data();
|
||||
}
|
||||
|
||||
bool QWaylandDisplay::supportsWindowDecoration() const
|
||||
{
|
||||
static bool disabled = qgetenv("QT_WAYLAND_DISABLE_WINDOWDECORATION").toInt();
|
||||
// Stop early when disabled via the environment. Do not try to load the integration in
|
||||
// order to play nice with SHM-only, buffer integration-less systems.
|
||||
if (disabled)
|
||||
return false;
|
||||
|
||||
static bool integrationSupport = clientBufferIntegration() && clientBufferIntegration()->supportsWindowDecoration();
|
||||
return integrationSupport;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -97,7 +97,7 @@ public:
|
||||
QWaylandDisplay(QWaylandIntegration *waylandIntegration);
|
||||
~QWaylandDisplay(void);
|
||||
|
||||
QList<QPlatformScreen *> screens() const { return mScreens; }
|
||||
QList<QWaylandScreen *> screens() const { return mScreens; }
|
||||
|
||||
QWaylandScreen *screenForOutput(struct wl_output *output) const;
|
||||
|
||||
@ -157,6 +157,8 @@ public:
|
||||
|
||||
void forceRoundTrip();
|
||||
|
||||
bool supportsWindowDecoration() const;
|
||||
|
||||
public slots:
|
||||
void blockingReadEvents();
|
||||
void flushRequests();
|
||||
@ -177,7 +179,7 @@ private:
|
||||
QWaylandEventThread *mEventThreadObject;
|
||||
QScopedPointer<QtWayland::wl_shell> mShell;
|
||||
QScopedPointer<QWaylandXdgShell> mShellXdg;
|
||||
QList<QPlatformScreen *> mScreens;
|
||||
QList<QWaylandScreen *> mScreens;
|
||||
QList<QWaylandInputDevice *> mInputDevices;
|
||||
QList<Listener> mRegistryListeners;
|
||||
QWaylandIntegration *mWaylandIntegration;
|
||||
|
@ -71,12 +71,25 @@ void QWaylandEventThread::displayConnect()
|
||||
QMetaObject::invokeMethod(this, "waylandDisplayConnect", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
// ### be careful what you do, this function may also be called from other
|
||||
// threads to clean up & exit.
|
||||
void QWaylandEventThread::checkErrorAndExit()
|
||||
{
|
||||
int ecode = wl_display_get_error(m_display);
|
||||
if ((ecode == EPIPE || ecode == ECONNRESET)) {
|
||||
// special case this to provide a nicer error
|
||||
qWarning("The Wayland connection broke. Did the Wayland compositor die?");
|
||||
} else {
|
||||
qErrnoWarning(ecode, "The Wayland connection experienced a fatal error");
|
||||
}
|
||||
::exit(1);
|
||||
}
|
||||
|
||||
void QWaylandEventThread::readWaylandEvents()
|
||||
{
|
||||
if (wl_display_dispatch(m_display) == -1 && (errno == EPIPE || errno == ECONNRESET)) {
|
||||
qWarning("The Wayland connection broke. Did the Wayland compositor die?");
|
||||
::exit(1);
|
||||
}
|
||||
if (wl_display_dispatch(m_display) < 0)
|
||||
checkErrorAndExit();
|
||||
|
||||
emit newEventsRead();
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,8 @@ public:
|
||||
|
||||
wl_display *display() const;
|
||||
|
||||
void checkErrorAndExit();
|
||||
|
||||
private slots:
|
||||
void readWaylandEvents();
|
||||
|
||||
|
@ -220,6 +220,8 @@ public:
|
||||
void touch_frame() Q_DECL_OVERRIDE;
|
||||
void touch_cancel() Q_DECL_OVERRIDE;
|
||||
|
||||
bool allTouchPointsReleased();
|
||||
|
||||
QWaylandInputDevice *mParent;
|
||||
QWaylandWindow *mFocus;
|
||||
QList<QWindowSystemInterface::TouchPoint> mTouchPoints;
|
||||
@ -228,7 +230,7 @@ public:
|
||||
|
||||
QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, uint32_t id)
|
||||
: QObject()
|
||||
, QtWayland::wl_seat(display->wl_registry(), id)
|
||||
, QtWayland::wl_seat(display->wl_registry(), id, 2)
|
||||
, mQDisplay(display)
|
||||
, mDisplay(display->wl_display())
|
||||
, mCaps(0)
|
||||
@ -715,6 +717,11 @@ void QWaylandInputDevice::Keyboard::keyboard_leave(uint32_t time, struct wl_surf
|
||||
Q_UNUSED(time);
|
||||
Q_UNUSED(surface);
|
||||
|
||||
if (surface) {
|
||||
QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface);
|
||||
window->unfocus();
|
||||
}
|
||||
|
||||
mFocus = NULL;
|
||||
|
||||
// Use a callback to set the focus because we may get a leave/enter pair, and
|
||||
@ -851,8 +858,8 @@ void QWaylandInputDevice::Touch::touch_down(uint32_t serial,
|
||||
wl_fixed_t x,
|
||||
wl_fixed_t y)
|
||||
{
|
||||
Q_UNUSED(serial);
|
||||
Q_UNUSED(time);
|
||||
mParent->mTime = time;
|
||||
mParent->mSerial = serial;
|
||||
mFocus = QWaylandWindow::fromWlSurface(surface);
|
||||
mParent->handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointPressed);
|
||||
}
|
||||
@ -863,6 +870,13 @@ void QWaylandInputDevice::Touch::touch_up(uint32_t serial, uint32_t time, int32_
|
||||
Q_UNUSED(time);
|
||||
mFocus = 0;
|
||||
mParent->handleTouchPoint(id, 0, 0, Qt::TouchPointReleased);
|
||||
|
||||
// As of Weston 1.5.90 there is no touch_frame after the last touch_up
|
||||
// (i.e. when the last finger is released). To accommodate for this, issue a
|
||||
// touch_frame. This cannot hurt since it is safe to call the touch_frame
|
||||
// handler multiple times when there are no points left.
|
||||
if (allTouchPointsReleased())
|
||||
touch_frame();
|
||||
}
|
||||
|
||||
void QWaylandInputDevice::Touch::touch_motion(uint32_t time, int32_t id, wl_fixed_t x, wl_fixed_t y)
|
||||
@ -912,7 +926,7 @@ void QWaylandInputDevice::handleTouchPoint(int id, double x, double y, Qt::Touch
|
||||
|
||||
tp.area = QRectF(0, 0, 8, 8);
|
||||
QMargins margins = win->frameMargins();
|
||||
tp.area.moveCenter(win->window()->mapToGlobal(QPoint(x+margins.left(), y+margins.top())));
|
||||
tp.area.moveCenter(win->window()->mapToGlobal(QPoint(x - margins.left(), y - margins.top())));
|
||||
}
|
||||
|
||||
tp.state = state;
|
||||
@ -921,6 +935,15 @@ void QWaylandInputDevice::handleTouchPoint(int id, double x, double y, Qt::Touch
|
||||
mTouch->mTouchPoints.append(tp);
|
||||
}
|
||||
|
||||
bool QWaylandInputDevice::Touch::allTouchPointsReleased()
|
||||
{
|
||||
for (int i = 0; i < mTouchPoints.count(); ++i)
|
||||
if (mTouchPoints.at(i).state != Qt::TouchPointReleased)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QWaylandInputDevice::Touch::touch_frame()
|
||||
{
|
||||
// Copy all points, that are in the previous but not in the current list, as stationary.
|
||||
@ -948,22 +971,24 @@ void QWaylandInputDevice::Touch::touch_frame()
|
||||
|
||||
QWindow *window = mFocus ? mFocus->window() : 0;
|
||||
|
||||
if (mFocus) {
|
||||
const QWindowSystemInterface::TouchPoint &tp = mTouchPoints.last();
|
||||
// When the touch event is received, the global pos is calculated with the margins
|
||||
// in mind. Now we need to adjust again to get the correct local pos back.
|
||||
QMargins margins = window->frameMargins();
|
||||
QPoint p = tp.area.center().toPoint();
|
||||
QPointF localPos(window->mapFromGlobal(QPoint(p.x() + margins.left(), p.y() + margins.top())));
|
||||
if (mFocus->touchDragDecoration(mParent, localPos, tp.area.center(), tp.state, mParent->modifiers()))
|
||||
return;
|
||||
}
|
||||
QWindowSystemInterface::handleTouchEvent(window, mParent->mTouchDevice, mTouchPoints);
|
||||
|
||||
bool allReleased = true;
|
||||
for (int i = 0; i < mTouchPoints.count(); ++i)
|
||||
if (mTouchPoints.at(i).state != Qt::TouchPointReleased) {
|
||||
allReleased = false;
|
||||
break;
|
||||
}
|
||||
|
||||
mPrevTouchPoints = mTouchPoints;
|
||||
mTouchPoints.clear();
|
||||
|
||||
if (allReleased) {
|
||||
QWindowSystemInterface::handleTouchEvent(window, mParent->mTouchDevice, mTouchPoints);
|
||||
if (allTouchPointsReleased())
|
||||
mPrevTouchPoints.clear();
|
||||
}
|
||||
else
|
||||
mPrevTouchPoints = mTouchPoints;
|
||||
|
||||
mTouchPoints.clear();
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -42,13 +42,14 @@
|
||||
#include "qwaylandintegration_p.h"
|
||||
|
||||
#include "qwaylanddisplay_p.h"
|
||||
#include "qwaylandshmwindow_p.h"
|
||||
#include "qwaylandinputcontext_p.h"
|
||||
#include "qwaylandshmbackingstore_p.h"
|
||||
#include "qwaylandshmwindow_p.h"
|
||||
#include "qwaylandnativeinterface_p.h"
|
||||
#include "qwaylandclipboard_p.h"
|
||||
#include "qwaylanddnd_p.h"
|
||||
#include "qwaylandwindowmanagerintegration_p.h"
|
||||
#include "qwaylandscreen_p.h"
|
||||
|
||||
#include "QtPlatformSupport/private/qgenericunixfontdatabase_p.h"
|
||||
#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
|
||||
@ -127,9 +128,6 @@ QWaylandIntegration::QWaylandIntegration()
|
||||
mClipboard = new QWaylandClipboard(mDisplay);
|
||||
mDrag = new QWaylandDrag(mDisplay);
|
||||
|
||||
foreach (QPlatformScreen *screen, mDisplay->screens())
|
||||
screenAdded(screen);
|
||||
|
||||
mInputContext.reset(new QWaylandInputContext(mDisplay));
|
||||
}
|
||||
|
||||
@ -162,14 +160,18 @@ bool QWaylandIntegration::hasCapability(QPlatformIntegration::Capability cap) co
|
||||
case MultipleWindows:
|
||||
case NonFullScreenWindows:
|
||||
return true;
|
||||
case RasterGLSurface:
|
||||
return true;
|
||||
default: return QPlatformIntegration::hasCapability(cap);
|
||||
}
|
||||
}
|
||||
|
||||
QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWindow *window) const
|
||||
{
|
||||
if (window->surfaceType() == QWindow::OpenGLSurface && mDisplay->clientBufferIntegration())
|
||||
if ((window->surfaceType() == QWindow::OpenGLSurface || window->surfaceType() == QWindow::RasterGLSurface)
|
||||
&& mDisplay->clientBufferIntegration())
|
||||
return mDisplay->clientBufferIntegration()->createEglWindow(window);
|
||||
|
||||
return new QWaylandShmWindow(window);
|
||||
}
|
||||
|
||||
@ -255,7 +257,7 @@ QWaylandClientBufferIntegration *QWaylandIntegration::clientBufferIntegration()
|
||||
if (!mClientBufferIntegrationInitialized)
|
||||
const_cast<QWaylandIntegration *>(this)->initializeClientBufferIntegration();
|
||||
|
||||
return mClientBufferIntegration;
|
||||
return mClientBufferIntegration && mClientBufferIntegration->isValid() ? mClientBufferIntegration : 0;
|
||||
}
|
||||
|
||||
QWaylandServerBufferIntegration *QWaylandIntegration::serverBufferIntegration() const
|
||||
@ -291,7 +293,7 @@ void QWaylandIntegration::initializeClientBufferIntegration()
|
||||
}
|
||||
|
||||
if (targetKey.isEmpty()) {
|
||||
qWarning("Failed to determin what client buffer integration to use");
|
||||
qWarning("Failed to determine what client buffer integration to use");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -110,6 +110,8 @@ private:
|
||||
bool mClientBufferIntegrationInitialized;
|
||||
bool mServerBufferIntegrationInitialized;
|
||||
bool mShellIntegrationInitialized;
|
||||
|
||||
friend class QWaylandDisplay;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -68,8 +68,6 @@ public:
|
||||
void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value);
|
||||
|
||||
void emitWindowPropertyChanged(QPlatformWindow *window, const QString &name);
|
||||
private:
|
||||
static QWaylandScreen *qPlatformScreenForWindow(QWindow *window);
|
||||
|
||||
private:
|
||||
QWaylandIntegration *m_integration;
|
||||
|
@ -46,7 +46,7 @@
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QWaylandQtKeyExtension::QWaylandQtKeyExtension(QWaylandDisplay *display, uint32_t id)
|
||||
: QtWayland::qt_key_extension(display->wl_registry(), id)
|
||||
: QtWayland::qt_key_extension(display->wl_registry(), id, 2)
|
||||
, m_display(display)
|
||||
{
|
||||
}
|
||||
|
@ -54,7 +54,9 @@
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, uint32_t id)
|
||||
: QtWayland::wl_output(waylandDisplay->wl_registry(), id)
|
||||
: QPlatformScreen()
|
||||
, QtWayland::wl_output(waylandDisplay->wl_registry(), id, 2)
|
||||
, m_outputId(id)
|
||||
, mWaylandDisplay(waylandDisplay)
|
||||
, mExtendedOutput(0)
|
||||
, mDepth(32)
|
||||
@ -93,6 +95,14 @@ QImage::Format QWaylandScreen::format() const
|
||||
return mFormat;
|
||||
}
|
||||
|
||||
QSizeF QWaylandScreen::physicalSize() const
|
||||
{
|
||||
if (mPhysicalSize.isEmpty())
|
||||
return QPlatformScreen::physicalSize();
|
||||
else
|
||||
return mPhysicalSize;
|
||||
}
|
||||
|
||||
QDpi QWaylandScreen::logicalDpi() const
|
||||
{
|
||||
static int force_dpi = !qgetenv("QT_WAYLAND_FORCE_DPI").isEmpty() ? qgetenv("QT_WAYLAND_FORCE_DPI").toInt() : -1;
|
||||
@ -151,16 +161,11 @@ void QWaylandScreen::output_mode(uint32_t flags, int width, int height, int refr
|
||||
|
||||
QSize size(width, height);
|
||||
|
||||
if (size != mGeometry.size()) {
|
||||
if (size != mGeometry.size())
|
||||
mGeometry.setSize(size);
|
||||
QWindowSystemInterface::handleScreenGeometryChange(screen(), mGeometry);
|
||||
QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), mGeometry);
|
||||
}
|
||||
|
||||
if (refresh != mRefreshRate) {
|
||||
if (refresh != mRefreshRate)
|
||||
mRefreshRate = refresh;
|
||||
QWindowSystemInterface::handleScreenRefreshRateChange(screen(), refreshRate());
|
||||
}
|
||||
}
|
||||
|
||||
void QWaylandScreen::output_geometry(int32_t x, int32_t y,
|
||||
@ -200,14 +205,17 @@ void QWaylandScreen::output_geometry(int32_t x, int32_t y,
|
||||
if (!model.isEmpty())
|
||||
mOutputName = model;
|
||||
|
||||
QRect geom(x, y, width, height);
|
||||
mPhysicalSize = QSize(width, height);
|
||||
mGeometry.moveTopLeft(QPoint(x, y));
|
||||
}
|
||||
|
||||
if (mGeometry == geom)
|
||||
return;
|
||||
|
||||
mGeometry = geom;
|
||||
QWindowSystemInterface::handleScreenGeometryChange(screen(), mGeometry);
|
||||
QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), mGeometry);
|
||||
void QWaylandScreen::output_done()
|
||||
{
|
||||
// the done event is sent after all the geometry and the mode events are sent,
|
||||
// and the last mode event to be sent is the active one, so we can trust the
|
||||
// values of mGeometry and mRefreshRate here
|
||||
QWindowSystemInterface::handleScreenGeometryChange(screen(), mGeometry, mGeometry);
|
||||
QWindowSystemInterface::handleScreenRefreshRateChange(screen(), refreshRate());
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -65,6 +65,8 @@ public:
|
||||
int depth() const;
|
||||
QImage::Format format() const;
|
||||
|
||||
QSizeF physicalSize() const Q_DECL_OVERRIDE;
|
||||
|
||||
QDpi logicalDpi() const Q_DECL_OVERRIDE;
|
||||
|
||||
void setOrientationUpdateMask(Qt::ScreenOrientations mask);
|
||||
@ -77,6 +79,7 @@ public:
|
||||
QPlatformCursor *cursor() const;
|
||||
QWaylandCursor *waylandCursor() const { return mWaylandCursor; };
|
||||
|
||||
uint32_t outputId() const { return m_outputId; }
|
||||
::wl_output *output() { return object(); }
|
||||
|
||||
QWaylandExtendedOutput *extendedOutput() const;
|
||||
@ -92,7 +95,9 @@ private:
|
||||
const QString &make,
|
||||
const QString &model,
|
||||
int32_t transform) Q_DECL_OVERRIDE;
|
||||
void output_done() Q_DECL_OVERRIDE;
|
||||
|
||||
int m_outputId;
|
||||
QWaylandDisplay *mWaylandDisplay;
|
||||
QWaylandExtendedOutput *mExtendedOutput;
|
||||
QRect mGeometry;
|
||||
|
@ -50,6 +50,7 @@ QWaylandShellSurface::QWaylandShellSurface(QWaylandWindow *window)
|
||||
|
||||
void QWaylandShellSurface::setWindowFlags(Qt::WindowFlags flags)
|
||||
{
|
||||
Q_UNUSED(flags);
|
||||
}
|
||||
|
||||
void QWaylandShellSurface::sendProperty(const QString &name, const QVariant &value)
|
||||
|
@ -39,14 +39,12 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "qwaylandshmbackingstore_p.h"
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
#include "qwaylandwindow_p.h"
|
||||
#include "qwaylanddisplay_p.h"
|
||||
#include "qwaylandshmwindow_p.h"
|
||||
#include "qwaylandscreen_p.h"
|
||||
#include "qwaylanddecoration_p.h"
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtGui/QPainter>
|
||||
|
||||
#include <wayland-client.h>
|
||||
@ -156,9 +154,7 @@ QWaylandShmBackingStore::~QWaylandShmBackingStore()
|
||||
|
||||
QPaintDevice *QWaylandShmBackingStore::paintDevice()
|
||||
{
|
||||
if (!windowDecoration())
|
||||
return mBackBuffer->image();
|
||||
return mBackBuffer->imageInsideMargins(windowDecorationMargins());
|
||||
return contentSurface();
|
||||
}
|
||||
|
||||
void QWaylandShmBackingStore::beginPaint(const QRegion &)
|
||||
@ -166,13 +162,11 @@ void QWaylandShmBackingStore::beginPaint(const QRegion &)
|
||||
mPainting = true;
|
||||
ensureSize();
|
||||
|
||||
if (waylandWindow()->attached() && mBackBuffer == waylandWindow()->attached() && mFrameCallback) {
|
||||
QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->handle());
|
||||
Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm);
|
||||
waylandWindow->waitForFrameSync();
|
||||
}
|
||||
QWaylandWindow *window = waylandWindow();
|
||||
if (window->attached() && mBackBuffer == window->attached() && mFrameCallback)
|
||||
window->waitForFrameSync();
|
||||
|
||||
waylandWindow()->setCanResize(false);
|
||||
window->setCanResize(false);
|
||||
}
|
||||
|
||||
void QWaylandShmBackingStore::endPaint()
|
||||
@ -190,9 +184,15 @@ void QWaylandShmBackingStore::ensureSize()
|
||||
|
||||
void QWaylandShmBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset)
|
||||
{
|
||||
// Invoked when the window is of type RasterSurface or when the window is
|
||||
// RasterGLSurface and there are no child widgets requiring OpenGL composition.
|
||||
|
||||
// For the case of RasterGLSurface + having to compose, the composeAndFlush() is
|
||||
// called instead. The default implementation from QPlatformBackingStore is sufficient
|
||||
// however so no need to reimplement that.
|
||||
|
||||
Q_UNUSED(window);
|
||||
Q_UNUSED(offset);
|
||||
Q_ASSERT(waylandWindow()->windowType() == QWaylandWindow::Shm);
|
||||
|
||||
if (windowDecoration() && windowDecoration()->isDirty())
|
||||
updateDecorations();
|
||||
@ -260,6 +260,11 @@ QImage *QWaylandShmBackingStore::entireSurface() const
|
||||
return mBackBuffer->image();
|
||||
}
|
||||
|
||||
QImage *QWaylandShmBackingStore::contentSurface() const
|
||||
{
|
||||
return windowDecoration() ? mBackBuffer->imageInsideMargins(windowDecorationMargins()) : mBackBuffer->image();
|
||||
}
|
||||
|
||||
void QWaylandShmBackingStore::updateDecorations()
|
||||
{
|
||||
QPainter decorationPainter(entireSurface());
|
||||
@ -302,11 +307,19 @@ QMargins QWaylandShmBackingStore::windowDecorationMargins() const
|
||||
return QMargins();
|
||||
}
|
||||
|
||||
QWaylandShmWindow *QWaylandShmBackingStore::waylandWindow() const
|
||||
QWaylandWindow *QWaylandShmBackingStore::waylandWindow() const
|
||||
{
|
||||
return static_cast<QWaylandShmWindow *>(window()->handle());
|
||||
return static_cast<QWaylandWindow *>(window()->handle());
|
||||
}
|
||||
|
||||
QImage QWaylandShmBackingStore::toImage() const
|
||||
{
|
||||
// Invoked from QPlatformBackingStore::composeAndFlush() that is called
|
||||
// instead of flush() for widgets that have renderToTexture children
|
||||
// (QOpenGLWidget, QQuickWidget).
|
||||
|
||||
return *contentSurface();
|
||||
}
|
||||
|
||||
void QWaylandShmBackingStore::done(void *data, wl_callback *callback, uint32_t time)
|
||||
{
|
||||
@ -315,7 +328,7 @@ void QWaylandShmBackingStore::done(void *data, wl_callback *callback, uint32_t t
|
||||
static_cast<QWaylandShmBackingStore *>(data);
|
||||
if (callback != self->mFrameCallback) // others, like QWaylandWindow, may trigger callbacks too
|
||||
return;
|
||||
QWaylandShmWindow *window = self->waylandWindow();
|
||||
QWaylandWindow *window = self->waylandWindow();
|
||||
wl_callback_destroy(self->mFrameCallback);
|
||||
self->mFrameCallback = 0;
|
||||
|
||||
|
@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
class QWaylandDisplay;
|
||||
class QWaylandDecoration;
|
||||
class QWaylandShmWindow;
|
||||
class QWaylandWindow;
|
||||
|
||||
class Q_WAYLAND_CLIENT_EXPORT QWaylandShmBuffer : public QWaylandBuffer {
|
||||
public:
|
||||
@ -87,11 +87,14 @@ public:
|
||||
|
||||
QMargins windowDecorationMargins() const;
|
||||
QImage *entireSurface() const;
|
||||
QImage *contentSurface() const;
|
||||
void ensureSize();
|
||||
|
||||
QWaylandShmWindow *waylandWindow() const;
|
||||
QWaylandWindow *waylandWindow() const;
|
||||
void iterateBuffer();
|
||||
|
||||
QImage toImage() const Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
void updateDecorations();
|
||||
|
||||
|
@ -51,13 +51,11 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
QWaylandShmWindow::QWaylandShmWindow(QWindow *window)
|
||||
: QWaylandWindow(window)
|
||||
, mBackingStore(0)
|
||||
{
|
||||
}
|
||||
|
||||
QWaylandShmWindow::~QWaylandShmWindow()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QWaylandWindow::WindowType QWaylandShmWindow::windowType() const
|
||||
@ -65,9 +63,4 @@ QWaylandWindow::WindowType QWaylandShmWindow::windowType() const
|
||||
return QWaylandWindow::Shm;
|
||||
}
|
||||
|
||||
void QWaylandShmWindow::setBackingStore(QWaylandShmBackingStore *backingStore)
|
||||
{
|
||||
mBackingStore = backingStore;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -47,8 +47,6 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QWaylandShmBackingStore;
|
||||
|
||||
class Q_WAYLAND_CLIENT_EXPORT QWaylandShmWindow : public QWaylandWindow
|
||||
{
|
||||
public:
|
||||
@ -57,19 +55,8 @@ public:
|
||||
|
||||
WindowType windowType() const;
|
||||
QSurfaceFormat format() const { return QSurfaceFormat(); }
|
||||
|
||||
void setBackingStore(QWaylandShmBackingStore *backingStore);
|
||||
QWaylandShmBackingStore *backingStore() const;
|
||||
|
||||
private:
|
||||
QWaylandShmBackingStore *mBackingStore;
|
||||
};
|
||||
|
||||
inline QWaylandShmBackingStore *QWaylandShmWindow::backingStore() const
|
||||
{
|
||||
return mBackingStore;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QWAYLANDSHMWINDOW_H
|
||||
|
@ -46,7 +46,7 @@
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QWaylandTouchExtension::QWaylandTouchExtension(QWaylandDisplay *display, uint32_t id)
|
||||
: QtWayland::qt_touch_extension(display->wl_registry(), id),
|
||||
: QtWayland::qt_touch_extension(display->wl_registry(), id, 1),
|
||||
mDisplay(display),
|
||||
mTouchDevice(0),
|
||||
mPointsLeft(0),
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "qwaylandwindow_p.h"
|
||||
|
||||
#include "qwaylandbuffer_p.h"
|
||||
#include "qwaylanddatadevice_p.h"
|
||||
#include "qwaylanddisplay_p.h"
|
||||
#include "qwaylandinputdevice_p.h"
|
||||
#include "qwaylandscreen_p.h"
|
||||
@ -132,6 +133,8 @@ QWaylandWindow::QWaylandWindow(QWindow *window)
|
||||
|
||||
QWaylandWindow::~QWaylandWindow()
|
||||
{
|
||||
delete mWindowDecoration;
|
||||
|
||||
if (isInitialized()) {
|
||||
delete mShellSurface;
|
||||
destroy();
|
||||
@ -458,6 +461,8 @@ void QWaylandWindow::handleContentOrientationChange(Qt::ScreenOrientation orient
|
||||
case Qt::InvertedPortraitOrientation:
|
||||
transform = isPortrait ? WL_OUTPUT_TRANSFORM_180 : WL_OUTPUT_TRANSFORM_270;
|
||||
break;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
set_buffer_transform(transform);
|
||||
// set_buffer_transform is double buffered, we need to commit.
|
||||
@ -498,8 +503,7 @@ bool QWaylandWindow::createDecoration()
|
||||
}
|
||||
}
|
||||
|
||||
static bool disableWaylandDecorations = !qgetenv("QT_WAYLAND_DISABLE_WINDOWDECORATION").isEmpty();
|
||||
if (disableWaylandDecorations)
|
||||
if (!mDisplay->supportsWindowDecoration())
|
||||
return false;
|
||||
|
||||
bool decoration = false;
|
||||
@ -596,6 +600,13 @@ void QWaylandWindow::handleMouseLeave(QWaylandInputDevice *inputDevice)
|
||||
restoreMouseCursor(inputDevice);
|
||||
}
|
||||
|
||||
bool QWaylandWindow::touchDragDecoration(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::TouchPointState state, Qt::KeyboardModifiers mods)
|
||||
{
|
||||
if (!mWindowDecoration)
|
||||
return false;
|
||||
return mWindowDecoration->handleTouch(inputDevice, local, global, state, mods);
|
||||
}
|
||||
|
||||
void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, ulong timestamp, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
|
||||
{
|
||||
if (mWindowDecoration->handleMouse(inputDevice,local,global,b,mods))
|
||||
@ -648,6 +659,14 @@ void QWaylandWindow::requestActivateWindow()
|
||||
// we rely on compositor setting keyboard focus based on window stacking.
|
||||
}
|
||||
|
||||
void QWaylandWindow::unfocus()
|
||||
{
|
||||
QWaylandInputDevice *inputDevice = mDisplay->currentInputDevice();
|
||||
if (inputDevice && inputDevice->dataDevice()) {
|
||||
inputDevice->dataDevice()->invalidateSelectionOffer();
|
||||
}
|
||||
}
|
||||
|
||||
bool QWaylandWindow::isExposed() const
|
||||
{
|
||||
if (mShellSurface)
|
||||
@ -677,18 +696,21 @@ bool QWaylandWindow::setWindowStateInternal(Qt::WindowState state)
|
||||
// here. We use then this mState variable.
|
||||
mState = state;
|
||||
createDecoration();
|
||||
switch (state) {
|
||||
case Qt::WindowFullScreen:
|
||||
mShellSurface->setFullscreen();
|
||||
break;
|
||||
case Qt::WindowMaximized:
|
||||
mShellSurface->setMaximized();
|
||||
break;
|
||||
case Qt::WindowMinimized:
|
||||
mShellSurface->setMinimized();
|
||||
break;
|
||||
default:
|
||||
mShellSurface->setNormal();
|
||||
|
||||
if (mShellSurface) {
|
||||
switch (state) {
|
||||
case Qt::WindowFullScreen:
|
||||
mShellSurface->setFullscreen();
|
||||
break;
|
||||
case Qt::WindowMaximized:
|
||||
mShellSurface->setMaximized();
|
||||
break;
|
||||
case Qt::WindowMinimized:
|
||||
mShellSurface->setMinimized();
|
||||
break;
|
||||
default:
|
||||
mShellSurface->setNormal();
|
||||
}
|
||||
}
|
||||
|
||||
QWindowSystemInterface::handleWindowStateChanged(window(), mState);
|
||||
|
@ -63,6 +63,7 @@ class QWaylandSubSurface;
|
||||
class QWaylandDecoration;
|
||||
class QWaylandInputDevice;
|
||||
class QWaylandScreen;
|
||||
class QWaylandShmBackingStore;
|
||||
|
||||
class Q_WAYLAND_CLIENT_EXPORT QWaylandWindowConfigure
|
||||
{
|
||||
@ -143,6 +144,7 @@ public:
|
||||
|
||||
void requestActivateWindow() Q_DECL_OVERRIDE;
|
||||
bool isExposed() const Q_DECL_OVERRIDE;
|
||||
void unfocus();
|
||||
|
||||
QWaylandDecoration *decoration() const;
|
||||
void setDecoration(QWaylandDecoration *decoration);
|
||||
@ -157,6 +159,9 @@ public:
|
||||
void handleMouseEnter(QWaylandInputDevice *inputDevice);
|
||||
void handleMouseLeave(QWaylandInputDevice *inputDevice);
|
||||
|
||||
bool touchDragDecoration(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,
|
||||
Qt::TouchPointState state, Qt::KeyboardModifiers mods);
|
||||
|
||||
bool createDecoration();
|
||||
|
||||
inline bool isMaximized() const { return mState == Qt::WindowMaximized; }
|
||||
@ -181,6 +186,12 @@ public:
|
||||
QVariant property(const QString &name);
|
||||
QVariant property(const QString &name, const QVariant &defaultValue);
|
||||
|
||||
void setBackingStore(QWaylandShmBackingStore *backingStore) { mBackingStore = backingStore; }
|
||||
QWaylandShmBackingStore *backingStore() const { return mBackingStore; }
|
||||
|
||||
bool setKeyboardGrabEnabled(bool) Q_DECL_OVERRIDE { return false; }
|
||||
void propagateSizeHints() Q_DECL_OVERRIDE { }
|
||||
|
||||
public slots:
|
||||
void requestResize();
|
||||
|
||||
@ -219,6 +230,8 @@ protected:
|
||||
Qt::WindowState mState;
|
||||
QRegion mMask;
|
||||
|
||||
QWaylandShmBackingStore *mBackingStore;
|
||||
|
||||
private:
|
||||
bool setWindowStateInternal(Qt::WindowState flags);
|
||||
void setGeometry_helper(const QRect &rect);
|
||||
|
@ -95,7 +95,7 @@ void QWaylandWindowManagerIntegration::wlHandleListenerGlobal(void *data, wl_reg
|
||||
{
|
||||
Q_UNUSED(version);
|
||||
if (interface == QStringLiteral("qt_windowmanager"))
|
||||
static_cast<QWaylandWindowManagerIntegration *>(data)->init(registry, id);
|
||||
static_cast<QWaylandWindowManagerIntegration *>(data)->init(registry, id, 1);
|
||||
}
|
||||
|
||||
void QWaylandWindowManagerIntegration::windowmanager_hints(int32_t showIsFullScreen)
|
||||
|
@ -57,7 +57,7 @@ QWaylandXdgShell::QWaylandXdgShell(struct ::xdg_shell *shell)
|
||||
}
|
||||
|
||||
QWaylandXdgShell::QWaylandXdgShell(struct ::wl_registry *registry, uint32_t id)
|
||||
: QtWayland::xdg_shell(registry, id)
|
||||
: QtWayland::xdg_shell(registry, id, 1)
|
||||
{
|
||||
use_unstable_version(QtWayland::xdg_shell::version_current);
|
||||
}
|
||||
|
@ -822,13 +822,13 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr
|
||||
|
||||
printf(" class %s %s\n {\n", clientExport.constData(), interfaceName);
|
||||
printf(" public:\n");
|
||||
printf(" %s(struct ::wl_registry *registry, int id);\n", interfaceName);
|
||||
printf(" %s(struct ::wl_registry *registry, int id, int version);\n", interfaceName);
|
||||
printf(" %s(struct ::%s *object);\n", interfaceName, interfaceName);
|
||||
printf(" %s();\n", interfaceName);
|
||||
printf("\n");
|
||||
printf(" virtual ~%s();\n", interfaceName);
|
||||
printf("\n");
|
||||
printf(" void init(struct ::wl_registry *registry, int id);\n");
|
||||
printf(" void init(struct ::wl_registry *registry, int id, int version);\n");
|
||||
printf(" void init(struct ::%s *object);\n", interfaceName);
|
||||
printf("\n");
|
||||
printf(" struct ::%s *object() { return m_%s; }\n", interfaceName, interfaceName);
|
||||
@ -908,9 +908,9 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr
|
||||
|
||||
bool hasEvents = !interface.events.isEmpty();
|
||||
|
||||
printf(" %s::%s(struct ::wl_registry *registry, int id)\n", interfaceName, interfaceName);
|
||||
printf(" %s::%s(struct ::wl_registry *registry, int id, int version)\n", interfaceName, interfaceName);
|
||||
printf(" {\n");
|
||||
printf(" init(registry, id);\n");
|
||||
printf(" init(registry, id, version);\n");
|
||||
printf(" }\n");
|
||||
printf("\n");
|
||||
|
||||
@ -933,9 +933,9 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr
|
||||
printf(" }\n");
|
||||
printf("\n");
|
||||
|
||||
printf(" void %s::init(struct ::wl_registry *registry, int id)\n", interfaceName);
|
||||
printf(" void %s::init(struct ::wl_registry *registry, int id, int version)\n", interfaceName);
|
||||
printf(" {\n");
|
||||
printf(" m_%s = static_cast<struct ::%s *>(wl_registry_bind(registry, id, &%s_interface, %s_interface.version));\n", interfaceName, interfaceName, interfaceName, interfaceName);
|
||||
printf(" m_%s = static_cast<struct ::%s *>(wl_registry_bind(registry, id, &%s_interface, version));\n", interfaceName, interfaceName, interfaceName);
|
||||
if (hasEvents)
|
||||
printf(" init_listener();\n");
|
||||
printf(" }\n");
|
||||
|
@ -135,8 +135,13 @@ QSharedPointer<MockSurface> MockCompositor::surface()
|
||||
QSharedPointer<MockSurface> result;
|
||||
lock();
|
||||
QVector<Impl::Surface *> surfaces = m_compositor->surfaces();
|
||||
if (!surfaces.isEmpty())
|
||||
result = surfaces.first()->mockSurface();
|
||||
foreach (Impl::Surface *surface, surfaces) {
|
||||
// we don't want to mistake the cursor surface for a window surface
|
||||
if (surface->isMapped()) {
|
||||
result = surface->mockSurface();
|
||||
break;
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
return result;
|
||||
}
|
||||
@ -189,11 +194,6 @@ void *MockCompositor::run(void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MockCompositor::discardSurfaces()
|
||||
{
|
||||
m_compositor->discardSurfaces();
|
||||
}
|
||||
|
||||
namespace Impl {
|
||||
|
||||
Compositor::Compositor()
|
||||
@ -209,6 +209,8 @@ Compositor::Compositor()
|
||||
|
||||
wl_display_add_global(m_display, &wl_compositor_interface, this, bindCompositor);
|
||||
|
||||
m_data_device_manager.reset(new DataDeviceManager(this, m_display));
|
||||
|
||||
wl_display_init_shm(m_display);
|
||||
|
||||
m_seat.reset(new Seat(this, m_display));
|
||||
@ -298,10 +300,5 @@ void Compositor::removeSurface(Surface *surface)
|
||||
m_pointer->setFocus(0, QPoint());
|
||||
}
|
||||
|
||||
void Compositor::discardSurfaces()
|
||||
{
|
||||
m_surfaces.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,7 @@ typedef void (**Implementation)(void);
|
||||
class Keyboard;
|
||||
class Pointer;
|
||||
class Seat;
|
||||
class DataDeviceManager;
|
||||
class Surface;
|
||||
|
||||
class Compositor
|
||||
@ -81,7 +82,6 @@ public:
|
||||
|
||||
void addSurface(Surface *surface);
|
||||
void removeSurface(Surface *surface);
|
||||
void discardSurfaces();
|
||||
|
||||
static void setKeyboardFocus(void *data, const QList<QVariant> ¶meters);
|
||||
static void sendMousePress(void *data, const QList<QVariant> ¶meters);
|
||||
@ -112,6 +112,7 @@ private:
|
||||
QScopedPointer<Seat> m_seat;
|
||||
Pointer *m_pointer;
|
||||
Keyboard *m_keyboard;
|
||||
QScopedPointer<DataDeviceManager> m_data_device_manager;
|
||||
QVector<Surface *> m_surfaces;
|
||||
};
|
||||
|
||||
@ -155,7 +156,6 @@ public:
|
||||
void sendKeyRelease(const QSharedPointer<MockSurface> &surface, uint code);
|
||||
|
||||
QSharedPointer<MockSurface> surface();
|
||||
void discardSurfaces();
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
|
@ -130,6 +130,8 @@ void Seat::seat_get_pointer(Resource *resource, uint32_t id)
|
||||
Keyboard::Keyboard(Compositor *compositor)
|
||||
: wl_keyboard()
|
||||
, m_compositor(compositor)
|
||||
, m_focusResource(Q_NULLPTR)
|
||||
, m_focus(Q_NULLPTR)
|
||||
{
|
||||
}
|
||||
|
||||
@ -174,6 +176,8 @@ void Keyboard::keyboard_destroy_resource(wl_keyboard::Resource *resource)
|
||||
Pointer::Pointer(Compositor *compositor)
|
||||
: wl_pointer()
|
||||
, m_compositor(compositor)
|
||||
, m_focusResource(Q_NULLPTR)
|
||||
, m_focus(Q_NULLPTR)
|
||||
{
|
||||
}
|
||||
|
||||
@ -223,4 +227,35 @@ void Pointer::pointer_destroy_resource(wl_pointer::Resource *resource)
|
||||
m_focusResource = 0;
|
||||
}
|
||||
|
||||
DataDevice::DataDevice(Compositor *compositor)
|
||||
: wl_data_device()
|
||||
, m_compositor(compositor)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DataDevice::~DataDevice()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DataDeviceManager::DataDeviceManager(Compositor *compositor, wl_display *display)
|
||||
: wl_data_device_manager(display)
|
||||
, m_compositor(compositor)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DataDeviceManager::~DataDeviceManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DataDeviceManager::data_device_manager_get_data_device(Resource *resource, uint32_t id, struct ::wl_resource *seat)
|
||||
{
|
||||
if (!m_data_device)
|
||||
m_data_device.reset(new DataDevice(m_compositor));
|
||||
m_data_device->add(resource->client(), id);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -120,6 +120,31 @@ private:
|
||||
Surface *m_focus;
|
||||
};
|
||||
|
||||
class DataDevice : public QtWaylandServer::wl_data_device
|
||||
{
|
||||
public:
|
||||
DataDevice(Compositor *compositor);
|
||||
~DataDevice();
|
||||
|
||||
private:
|
||||
Compositor *m_compositor;
|
||||
};
|
||||
|
||||
class DataDeviceManager : public QtWaylandServer::wl_data_device_manager
|
||||
{
|
||||
public:
|
||||
DataDeviceManager(Compositor *compositor, struct ::wl_display *display);
|
||||
~DataDeviceManager();
|
||||
|
||||
protected:
|
||||
void data_device_manager_get_data_device(Resource *resource, uint32_t id, struct ::wl_resource *seat) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
Compositor *m_compositor;
|
||||
|
||||
QScopedPointer<DataDevice> m_data_device;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // MOCKINPUT_H
|
||||
|
@ -40,6 +40,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "mockcompositor.h"
|
||||
#include "mocksurface.h"
|
||||
|
||||
namespace Impl {
|
||||
|
||||
@ -173,6 +174,8 @@ static void get_shell_surface(wl_client *client, wl_resource *compositorResource
|
||||
|
||||
Q_UNUSED(compositorResource);
|
||||
wl_client_add_object(client, &wl_shell_surface_interface, &shellSurfaceInterface, id, surfaceResource->data);
|
||||
Surface *surf = Surface::fromResource(surfaceResource);
|
||||
surf->map();
|
||||
}
|
||||
|
||||
void Compositor::bindShell(wl_client *client, void *compositorData, uint32_t version, uint32_t id)
|
||||
|
@ -46,10 +46,11 @@ namespace Impl {
|
||||
|
||||
Surface::Surface(wl_client *client, uint32_t id, Compositor *compositor)
|
||||
: QtWaylandServer::wl_surface(client, id)
|
||||
, m_buffer(Q_NULLPTR)
|
||||
, m_compositor(compositor)
|
||||
, m_mockSurface(new MockSurface(this))
|
||||
, m_mapped(false)
|
||||
{
|
||||
wl_list_init(&m_frameCallbackList);
|
||||
}
|
||||
|
||||
Surface::~Surface()
|
||||
@ -57,6 +58,21 @@ Surface::~Surface()
|
||||
m_mockSurface->m_surface = 0;
|
||||
}
|
||||
|
||||
void Surface::map()
|
||||
{
|
||||
m_mapped = true;
|
||||
}
|
||||
|
||||
bool Surface::isMapped() const
|
||||
{
|
||||
return m_mapped;
|
||||
}
|
||||
|
||||
Surface *Surface::fromResource(struct ::wl_resource *resource)
|
||||
{
|
||||
return static_cast<Surface *>(Resource::fromResource(resource)->surface_object);
|
||||
}
|
||||
|
||||
void Surface::surface_destroy_resource(Resource *)
|
||||
{
|
||||
compositor()->removeSurface(this);
|
||||
@ -88,47 +104,44 @@ void Surface::surface_damage(Resource *resource,
|
||||
Q_UNUSED(y);
|
||||
Q_UNUSED(width);
|
||||
Q_UNUSED(height);
|
||||
|
||||
if (!m_buffer)
|
||||
return;
|
||||
|
||||
#if WAYLAND_VERSION_CHECK(1, 2, 0)
|
||||
struct ::wl_shm_buffer *shm_buffer = wl_shm_buffer_get(m_buffer);
|
||||
#else
|
||||
struct ::wl_buffer *shm_buffer = 0;
|
||||
if (wl_buffer_is_shm(static_cast<struct ::wl_buffer*>(m_buffer->data)))
|
||||
shm_buffer = static_cast<struct ::wl_buffer*>(m_buffer->data);
|
||||
#endif
|
||||
|
||||
if (shm_buffer) {
|
||||
int stride = wl_shm_buffer_get_stride(shm_buffer);
|
||||
uint format = wl_shm_buffer_get_format(shm_buffer);
|
||||
Q_UNUSED(format);
|
||||
void *data = wl_shm_buffer_get_data(shm_buffer);
|
||||
const uchar *char_data = static_cast<const uchar *>(data);
|
||||
QImage img(char_data, wl_shm_buffer_get_width(shm_buffer), wl_shm_buffer_get_height(shm_buffer), stride, QImage::Format_ARGB32_Premultiplied);
|
||||
m_mockSurface->image = img;
|
||||
}
|
||||
|
||||
wl_resource *frameCallback;
|
||||
wl_list_for_each(frameCallback, &m_frameCallbackList, link) {
|
||||
wl_callback_send_done(frameCallback, m_compositor->time());
|
||||
wl_resource_destroy(frameCallback);
|
||||
}
|
||||
|
||||
wl_list_init(&m_frameCallbackList);
|
||||
}
|
||||
|
||||
void Surface::surface_frame(Resource *resource,
|
||||
uint32_t callback)
|
||||
{
|
||||
wl_resource *frameCallback = wl_client_add_object(resource->client(), &wl_callback_interface, 0, callback, this);
|
||||
wl_list_insert(&m_frameCallbackList, &frameCallback->link);
|
||||
m_frameCallbackList << frameCallback;
|
||||
}
|
||||
|
||||
void Surface::surface_commit(Resource *resource)
|
||||
{
|
||||
Q_UNUSED(resource);
|
||||
|
||||
if (m_buffer) {
|
||||
#if WAYLAND_VERSION_CHECK(1, 2, 0)
|
||||
struct ::wl_shm_buffer *shm_buffer = wl_shm_buffer_get(m_buffer);
|
||||
#else
|
||||
struct ::wl_buffer *shm_buffer = 0;
|
||||
if (wl_buffer_is_shm(static_cast<struct ::wl_buffer*>(m_buffer->data)))
|
||||
shm_buffer = static_cast<struct ::wl_buffer*>(m_buffer->data);
|
||||
#endif
|
||||
|
||||
if (shm_buffer) {
|
||||
int stride = wl_shm_buffer_get_stride(shm_buffer);
|
||||
uint format = wl_shm_buffer_get_format(shm_buffer);
|
||||
Q_UNUSED(format);
|
||||
void *data = wl_shm_buffer_get_data(shm_buffer);
|
||||
const uchar *char_data = static_cast<const uchar *>(data);
|
||||
QImage img(char_data, wl_shm_buffer_get_width(shm_buffer), wl_shm_buffer_get_height(shm_buffer), stride, QImage::Format_ARGB32_Premultiplied);
|
||||
m_mockSurface->image = img;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (wl_resource *frameCallback, m_frameCallbackList) {
|
||||
wl_callback_send_done(frameCallback, m_compositor->time());
|
||||
wl_resource_destroy(frameCallback);
|
||||
}
|
||||
m_frameCallbackList.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -54,6 +54,9 @@ public:
|
||||
~Surface();
|
||||
|
||||
Compositor *compositor() const { return m_compositor; }
|
||||
static Surface *fromResource(struct ::wl_resource *resource);
|
||||
void map();
|
||||
bool isMapped() const;
|
||||
|
||||
QSharedPointer<MockSurface> mockSurface() const { return m_mockSurface; }
|
||||
|
||||
@ -74,8 +77,8 @@ private:
|
||||
|
||||
Compositor *m_compositor;
|
||||
QSharedPointer<MockSurface> m_mockSurface;
|
||||
|
||||
wl_list m_frameCallbackList;
|
||||
QList<wl_resource *> m_frameCallbackList;
|
||||
bool m_mapped;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -149,11 +149,7 @@ private:
|
||||
|
||||
void tst_WaylandClient::screen()
|
||||
{
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents);
|
||||
|
||||
QTRY_COMPARE(QGuiApplication::primaryScreen()->size(), screenSize);
|
||||
// discard the cursor surface created by the QWaylandInputDevice
|
||||
compositor->discardSurfaces();
|
||||
}
|
||||
|
||||
void tst_WaylandClient::createDestroyWindow()
|
||||
@ -252,6 +248,11 @@ int main(int argc, char **argv)
|
||||
setenv("XDG_RUNTIME_DIR", ".", 1);
|
||||
setenv("QT_QPA_PLATFORM", "wayland", 1); // force QGuiApplication to use wayland plugin
|
||||
|
||||
// wayland-egl hangs in the test setup when we try to initialize. Until it gets
|
||||
// figured out, avoid clientBufferIntegration() from being called in
|
||||
// QWaylandWindow::createDecorations().
|
||||
setenv("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1", 1);
|
||||
|
||||
MockCompositor compositor;
|
||||
compositor.setOutputGeometry(QRect(QPoint(), screenSize));
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user