Merge "Merge remote-tracking branch 'origin/5.12' into 5.13"

This commit is contained in:
Johan Klokkhammer Helsing 2019-08-28 07:37:19 +02:00
commit 75ff7d01c5
13 changed files with 118 additions and 66 deletions

View File

@ -154,9 +154,13 @@ void QWaylandDataDevice::data_device_drop()
void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface, wl_fixed_t x, wl_fixed_t y, wl_data_offer *id)
{
m_enterSerial = serial;
m_dragWindow = QWaylandWindow::fromWlSurface(surface)->window();
auto *dragWaylandWindow = QWaylandWindow::fromWlSurface(surface);
if (!dragWaylandWindow)
return; // Ignore foreign surfaces
m_dragWindow = dragWaylandWindow->window();
m_dragPoint = calculateDragPosition(x, y, m_dragWindow);
m_enterSerial = serial;
QMimeData *dragData = nullptr;
Qt::DropActions supportedActions;

View File

@ -135,7 +135,7 @@ QVariant QWaylandMimeData::retrieveData_sys(const QString &mimeType, QVariant::T
}
int pipefd[2];
if (qt_safe_pipe(pipefd, O_NONBLOCK) == -1) {
if (qt_safe_pipe(pipefd) == -1) {
qWarning("QWaylandMimeData: pipe2() failed");
return QVariant();
}
@ -158,23 +158,32 @@ QVariant QWaylandMimeData::retrieveData_sys(const QString &mimeType, QVariant::T
int QWaylandMimeData::readData(int fd, QByteArray &data) const
{
char buf[4096];
int retryCount = 0;
int n;
while (true) {
n = QT_READ(fd, buf, sizeof buf);
if (n == -1 && (errno == EAGAIN || errno == EWOULDBLOCK) && ++retryCount < 1000)
usleep(1000);
else
break;
}
if (retryCount >= 1000)
fd_set readset;
FD_ZERO(&readset);
FD_SET(fd, &readset);
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
int ready = select(FD_SETSIZE, &readset, nullptr, nullptr, &timeout);
if (ready < 0) {
qWarning() << "QWaylandDataOffer: select() failed";
return -1;
} else if (ready == 0) {
qWarning("QWaylandDataOffer: timeout reading from pipe");
if (n > 0) {
data.append(buf, n);
n = readData(fd, data);
return -1;
} else {
char buf[4096];
int n = QT_READ(fd, buf, sizeof buf);
if (n > 0) {
data.append(buf, n);
n = readData(fd, data);
} else if (n < 0) {
qWarning("QWaylandDataOffer: read() failed");
}
return n;
}
return n;
}
}

View File

@ -186,9 +186,9 @@ void QWaylandDisplay::checkError() const
int ecode = wl_display_get_error(mDisplay);
if ((ecode == EPIPE || ecode == ECONNRESET)) {
// special case this to provide a nicer error
qWarning("The Wayland connection broke. Did the Wayland compositor die?");
qFatal("The Wayland connection broke. Did the Wayland compositor die?");
} else {
qErrnoWarning(ecode, "The Wayland connection experienced a fatal error");
qFatal("The Wayland connection experienced a fatal error: %s", strerror(ecode));
}
}
@ -198,25 +198,16 @@ void QWaylandDisplay::flushRequests()
wl_display_read_events(mDisplay);
}
if (wl_display_dispatch_pending(mDisplay) < 0) {
if (wl_display_dispatch_pending(mDisplay) < 0)
checkError();
exitWithError();
}
wl_display_flush(mDisplay);
}
void QWaylandDisplay::blockingReadEvents()
{
if (wl_display_dispatch(mDisplay) < 0) {
if (wl_display_dispatch(mDisplay) < 0)
checkError();
exitWithError();
}
}
void QWaylandDisplay::exitWithError()
{
::exit(1);
}
wl_event_queue *QWaylandDisplay::createEventQueue()
@ -245,10 +236,9 @@ void QWaylandDisplay::dispatchQueueWhile(wl_event_queue *queue, std::function<bo
else
wl_display_cancel_read(mDisplay);
if (wl_display_dispatch_queue_pending(mDisplay, queue) < 0) {
if (wl_display_dispatch_queue_pending(mDisplay, queue) < 0)
checkError();
exitWithError();
}
if (!condition())
break;
}

View File

@ -201,7 +201,6 @@ public slots:
private:
void waitForScreens();
void exitWithError();
void checkError() const;
void handleWaylandSync();

View File

@ -562,6 +562,8 @@ void QWaylandInputDevice::Pointer::pointer_enter(uint32_t serial, struct wl_surf
return;
QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface);
if (!window)
return; // Ignore foreign surfaces
if (mFocus) {
qCWarning(lcQpaWayland) << "The compositor sent a wl_pointer.enter event before sending a"
@ -569,6 +571,7 @@ void QWaylandInputDevice::Pointer::pointer_enter(uint32_t serial, struct wl_surf
<< "attempting to work around it by invalidating the current focus";
invalidateFocus();
}
mFocus = window;
connect(mFocus.data(), &QWaylandWindow::wlSurfaceDestroyed, this, &Pointer::handleFocusDestroyed);
@ -597,6 +600,10 @@ void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surfac
if (!surface)
return;
auto *window = QWaylandWindow::fromWlSurface(surface);
if (!window)
return; // Ignore foreign surfaces
if (!QWaylandWindow::mouseGrab()) {
QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface);
window->handleMouseLeave(mParent);
@ -972,9 +979,13 @@ void QWaylandInputDevice::Touch::touch_down(uint32_t serial,
if (!surface)
return;
auto *window = QWaylandWindow::fromWlSurface(surface);
if (!window)
return; // Ignore foreign surfaces
mParent->mTime = time;
mParent->mSerial = serial;
mFocus = QWaylandWindow::fromWlSurface(surface);
mFocus = window;
mParent->mQDisplay->setLastInputDevice(mParent, serial, mFocus);
mParent->handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointPressed);
}

View File

@ -310,11 +310,14 @@ QPlatformTheme *QWaylandIntegration::createPlatformTheme(const QString &name) co
return GenericWaylandTheme::createUnixTheme(name);
}
// May be called from non-GUI threads
QWaylandClientBufferIntegration *QWaylandIntegration::clientBufferIntegration() const
{
if (!mClientBufferIntegrationInitialized)
// Do an inexpensive check first to avoid locking whenever possible
if (Q_UNLIKELY(!mClientBufferIntegrationInitialized))
const_cast<QWaylandIntegration *>(this)->initializeClientBufferIntegration();
Q_ASSERT(mClientBufferIntegrationInitialized);
return mClientBufferIntegration && mClientBufferIntegration->isValid() ? mClientBufferIntegration.data() : nullptr;
}
@ -334,9 +337,12 @@ QWaylandShellIntegration *QWaylandIntegration::shellIntegration() const
return mShellIntegration.data();
}
// May be called from non-GUI threads
void QWaylandIntegration::initializeClientBufferIntegration()
{
mClientBufferIntegrationInitialized = true;
QMutexLocker lock(&mClientBufferInitLock);
if (mClientBufferIntegrationInitialized)
return;
QString targetKey = QString::fromLocal8Bit(qgetenv("QT_WAYLAND_CLIENT_BUFFER_INTEGRATION"));
@ -352,22 +358,25 @@ void QWaylandIntegration::initializeClientBufferIntegration()
if (targetKey.isEmpty()) {
qWarning("Failed to determine what client buffer integration to use");
return;
}
QStringList keys = QWaylandClientBufferIntegrationFactory::keys();
qCDebug(lcQpaWayland) << "Available client buffer integrations:" << keys;
if (keys.contains(targetKey))
mClientBufferIntegration.reset(QWaylandClientBufferIntegrationFactory::create(targetKey, QStringList()));
if (mClientBufferIntegration) {
qCDebug(lcQpaWayland) << "Initializing client buffer integration" << targetKey;
mClientBufferIntegration->initialize(mDisplay.data());
} else {
qCWarning(lcQpaWayland) << "Failed to load client buffer integration:" << targetKey;
qCWarning(lcQpaWayland) << "Available client buffer integrations:" << keys;
QStringList keys = QWaylandClientBufferIntegrationFactory::keys();
qCDebug(lcQpaWayland) << "Available client buffer integrations:" << keys;
if (keys.contains(targetKey))
mClientBufferIntegration.reset(QWaylandClientBufferIntegrationFactory::create(targetKey, QStringList()));
if (mClientBufferIntegration) {
qCDebug(lcQpaWayland) << "Initializing client buffer integration" << targetKey;
mClientBufferIntegration->initialize(mDisplay.data());
} else {
qCWarning(lcQpaWayland) << "Failed to load client buffer integration:" << targetKey;
qCWarning(lcQpaWayland) << "Available client buffer integrations:" << keys;
}
}
// This must be set last to make sure other threads don't use the
// integration before initialization is complete.
mClientBufferIntegrationInitialized = true;
}
void QWaylandIntegration::initializeServerBufferIntegration()

View File

@ -54,6 +54,7 @@
#include <QtWaylandClient/qtwaylandclientglobal.h>
#include <qpa/qplatformintegration.h>
#include <QtCore/QScopedPointer>
#include <QtCore/QMutex>
QT_BEGIN_NAMESPACE
@ -152,6 +153,7 @@ private:
mutable QScopedPointer<QPlatformAccessibility> mAccessibility;
#endif
bool mFailed = false;
QMutex mClientBufferInitLock;
bool mClientBufferIntegrationInitialized = false;
bool mServerBufferIntegrationInitialized = false;
bool mShellIntegrationInitialized = false;

View File

@ -70,7 +70,11 @@ void QWaylandQtKeyExtension::zqt_key_v1_key(struct wl_surface *surface,
}
QWaylandInputDevice *dev = inputDevices.first();
QWaylandWindow *win = surface ? QWaylandWindow::fromWlSurface(surface) : dev->keyboardFocus();
auto *win = surface ? QWaylandWindow::fromWlSurface(surface) : nullptr;
if (!win)
win = dev->keyboardFocus();
if (!win || !win->window()) {
qWarning("qt_key_extension: handle_qtkey: No keyboard focus");

View File

@ -217,8 +217,9 @@ QWaylandScreen * QWaylandScreen::waylandScreenFromWindow(QWindow *window)
QWaylandScreen *QWaylandScreen::fromWlOutput(::wl_output *output)
{
auto wlOutput = static_cast<QtWayland::wl_output *>(wl_output_get_user_data(output));
return static_cast<QWaylandScreen *>(wlOutput);
if (auto *o = QtWayland::wl_output::fromObject(output))
return static_cast<QWaylandScreen *>(o);
return nullptr;
}
void QWaylandScreen::output_mode(uint32_t flags, int width, int height, int refresh)

View File

@ -199,7 +199,9 @@ void QWaylandWindow::initWindow()
void QWaylandWindow::initializeWlSurface()
{
Q_ASSERT(!isInitialized());
init(mDisplay->createSurface(static_cast<QtWayland::wl_surface *>(this)));
emit wlSurfaceCreated();
}
bool QWaylandWindow::shouldCreateShellSurface() const

View File

@ -203,6 +203,7 @@ public slots:
void applyConfigure();
signals:
void wlSurfaceCreated();
void wlSurfaceDestroyed();
protected:

View File

@ -51,7 +51,26 @@ class QWaylandSharedMemoryFormatHelper
{
public:
static inline wl_shm_format fromQImageFormat(QImage::Format format);
static inline QImage::Format fromWaylandShmFormat(wl_shm_format format);
static inline QImage::Format fromWaylandShmFormat(wl_shm_format format)
{
switch (format) {
case WL_SHM_FORMAT_XRGB8888: return QImage::Format_RGB32;
case WL_SHM_FORMAT_ARGB8888: return QImage::Format_ARGB32_Premultiplied;
case WL_SHM_FORMAT_RGB565: return QImage::Format_RGB16;
case WL_SHM_FORMAT_XRGB1555: return QImage::Format_RGB555;
case WL_SHM_FORMAT_RGB888: return QImage::Format_RGB888;
case WL_SHM_FORMAT_XRGB4444: return QImage::Format_RGB444;
case WL_SHM_FORMAT_ARGB4444: return QImage::Format_ARGB4444_Premultiplied;
case WL_SHM_FORMAT_XBGR8888: return QImage::Format_RGBX8888;
case WL_SHM_FORMAT_ABGR8888: return QImage::Format_RGBA8888_Premultiplied;
case WL_SHM_FORMAT_XBGR2101010: return QImage::Format_BGR30;
case WL_SHM_FORMAT_ABGR2101010: return QImage::Format_A2BGR30_Premultiplied;
case WL_SHM_FORMAT_XRGB2101010: return QImage::Format_RGB30;
case WL_SHM_FORMAT_ARGB2101010: return QImage::Format_A2RGB30_Premultiplied;
case WL_SHM_FORMAT_C8: return QImage::Format_Alpha8;
default: return QImage::Format_Invalid;
}
}
static inline QVector<wl_shm_format> supportedWaylandFormats();
private:
@ -108,16 +127,6 @@ wl_shm_format QWaylandSharedMemoryFormatHelper::fromQImageFormat(QImage::Format
return array.data[format];
}
QImage::Format QWaylandSharedMemoryFormatHelper::fromWaylandShmFormat(wl_shm_format format)
{
Array array = getData();
for (size_t i = 0; i < array.size; i++) {
if (array.data[i] == format)
return QImage::Format(i);
}
return QImage::Format_Invalid;
}
QVector<wl_shm_format> QWaylandSharedMemoryFormatHelper::supportedWaylandFormats()
{
QVector<wl_shm_format> retFormats;

View File

@ -986,6 +986,7 @@ bool Scanner::process()
printf("\n");
printf(" struct ::%s *object() { return m_%s; }\n", interfaceName, interfaceName);
printf(" const struct ::%s *object() const { return m_%s; }\n", interfaceName, interfaceName);
printf(" static %s *fromObject(struct ::%s *object);\n", interfaceName, interfaceName);
printf("\n");
printf(" bool isInitialized() const;\n");
printf("\n");
@ -1130,6 +1131,16 @@ bool Scanner::process()
printf(" }\n");
printf("\n");
printf(" %s *%s::fromObject(struct ::%s *object)\n", interfaceName, interfaceName, interfaceName);
printf(" {\n");
if (hasEvents) {
printf(" if (wl_proxy_get_listener((struct ::wl_proxy *)object) != (void *)&m_%s_listener)\n", interfaceName);
printf(" return nullptr;\n");
}
printf(" return static_cast<%s *>(%s_get_user_data(object));\n", interfaceName, interfaceName);
printf(" }\n");
printf("\n");
printf(" bool %s::isInitialized() const\n", interfaceName);
printf(" {\n");
printf(" return m_%s != nullptr;\n", interfaceName);