Merge remote-tracking branch 'origin/5.4' into dev
Conflicts: src/client/qwaylanddataoffer.cpp src/client/qwaylanddisplay.cpp src/client/qwaylandinputdevice.cpp src/client/qwaylandwindow.cpp src/compositor/compositor_api/qwaylandsurfaceitem.cpp Change-Id: I2eae0fd43a71fbfd7c907ca715707a26f3c134c5
This commit is contained in:
commit
d1de454093
@ -88,6 +88,10 @@ void QWaylandClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
|
||||
if (!inputDevice || !inputDevice->dataDevice())
|
||||
return;
|
||||
|
||||
static const QString plain = QStringLiteral("text/plain");
|
||||
static const QString utf8 = QStringLiteral("text/plain;charset=utf-8");
|
||||
if (data && data->hasFormat(plain) && !data->hasFormat(utf8))
|
||||
data->setData(utf8, data->data(plain));
|
||||
inputDevice->dataDevice()->setSelectionSource(data ? new QWaylandDataSource(mDisplay->dndSelectionHandler(), data) : 0);
|
||||
|
||||
emitChanged(mode);
|
||||
|
@ -53,6 +53,11 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QtWaylandClient {
|
||||
|
||||
static QString utf8Text()
|
||||
{
|
||||
return QStringLiteral("text/plain;charset=utf-8");
|
||||
}
|
||||
|
||||
QWaylandDataOffer::QWaylandDataOffer(QWaylandDisplay *display, struct ::wl_data_offer *offer)
|
||||
: QtWayland::wl_data_offer(offer)
|
||||
, m_mimeData(new QWaylandMimeData(this, display))
|
||||
@ -102,7 +107,13 @@ void QWaylandMimeData::appendFormat(const QString &mimeType)
|
||||
|
||||
bool QWaylandMimeData::hasFormat_sys(const QString &mimeType) const
|
||||
{
|
||||
return m_types.contains(mimeType);
|
||||
if (m_types.contains(mimeType))
|
||||
return true;
|
||||
|
||||
if (mimeType == QStringLiteral("text/plain") && m_types.contains(utf8Text()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList QWaylandMimeData::formats_sys() const
|
||||
@ -117,8 +128,14 @@ QVariant QWaylandMimeData::retrieveData_sys(const QString &mimeType, QVariant::T
|
||||
if (m_data.contains(mimeType))
|
||||
return m_data.value(mimeType);
|
||||
|
||||
if (!m_types.contains(mimeType))
|
||||
return QVariant();
|
||||
QString mime = mimeType;
|
||||
|
||||
if (!m_types.contains(mimeType)) {
|
||||
if (mimeType == QStringLiteral("text/plain") && m_types.contains(utf8Text()))
|
||||
mime = utf8Text();
|
||||
else
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
int pipefd[2];
|
||||
if (::pipe2(pipefd, O_CLOEXEC|O_NONBLOCK) == -1) {
|
||||
@ -126,7 +143,7 @@ QVariant QWaylandMimeData::retrieveData_sys(const QString &mimeType, QVariant::T
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
m_dataOffer->receive(mimeType, pipefd[1]);
|
||||
m_dataOffer->receive(mime, pipefd[1]);
|
||||
m_display->flushRequests();
|
||||
|
||||
close(pipefd[1]);
|
||||
|
@ -140,6 +140,9 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration)
|
||||
, mQtKeyExtension(0)
|
||||
, mTextInputManager(0)
|
||||
, mHardwareIntegration(0)
|
||||
, mLastInputSerial(0)
|
||||
, mLastInputDevice(0)
|
||||
, mLastInputWindow(0)
|
||||
{
|
||||
qRegisterMetaType<uint32_t>("uint32_t");
|
||||
|
||||
@ -373,6 +376,11 @@ bool QWaylandDisplay::supportsWindowDecoration() const
|
||||
return integrationSupport;
|
||||
}
|
||||
|
||||
void QWaylandDisplay::setLastInputDevice(QWaylandInputDevice *device, uint32_t serial, QWaylandWindow *win)
|
||||
{
|
||||
mLastInputDevice = device;
|
||||
mLastInputSerial = serial;
|
||||
mLastInputWindow = win;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -163,6 +163,11 @@ public:
|
||||
|
||||
bool supportsWindowDecoration() const;
|
||||
|
||||
uint32_t lastInputSerial() const { return mLastInputSerial; }
|
||||
QWaylandInputDevice *lastInputDevice() const { return mLastInputDevice; }
|
||||
QWaylandWindow *lastInputWindow() const { return mLastInputWindow; }
|
||||
void setLastInputDevice(QWaylandInputDevice *device, uint32_t serial, QWaylandWindow *window);
|
||||
|
||||
public slots:
|
||||
void blockingReadEvents();
|
||||
void flushRequests();
|
||||
@ -204,6 +209,9 @@ private:
|
||||
bool mScreensInitialized;
|
||||
QList<RegistryGlobal> mGlobals;
|
||||
int mCompositorVersion;
|
||||
uint32_t mLastInputSerial;
|
||||
QWaylandInputDevice *mLastInputDevice;
|
||||
QWaylandWindow *mLastInputWindow;
|
||||
|
||||
void registry_global(uint32_t id, const QString &interface, uint32_t version) Q_DECL_OVERRIDE;
|
||||
void registry_global_remove(uint32_t id) Q_DECL_OVERRIDE;
|
||||
|
@ -73,13 +73,20 @@ QMimeData * QWaylandDrag::platformDropData()
|
||||
|
||||
void QWaylandDrag::startDrag()
|
||||
{
|
||||
bool cancel = false;
|
||||
if (!shapedPixmapWindow()) {
|
||||
QBasicDrag::startDrag();
|
||||
QBasicDrag::cancel();
|
||||
// Don't call cancel() here, since that will hide 'shapedPixmapWindow()', and
|
||||
// QWaylandWindow::setVisible(false) will flush the window system queue,
|
||||
// ending up trying to render the window, which doesn't have a role yet,
|
||||
// and so blocking waiting for a frame callback.
|
||||
cancel = true;
|
||||
}
|
||||
|
||||
QWaylandWindow *icon = static_cast<QWaylandWindow *>(shapedPixmapWindow()->handle());
|
||||
m_display->currentInputDevice()->dataDevice()->startDrag(drag()->mimeData(), icon);
|
||||
if (cancel)
|
||||
QBasicDrag::cancel();
|
||||
QBasicDrag::startDrag();
|
||||
}
|
||||
|
||||
|
@ -439,10 +439,10 @@ void QWaylandInputDevice::Pointer::pointer_motion(uint32_t time, wl_fixed_t surf
|
||||
// so we just set it outside of the window boundaries.
|
||||
pos = QPointF(-1, -1);
|
||||
global = grab->window()->mapToGlobal(pos.toPoint());
|
||||
MotionEvent e(time, pos, global, mButtons, Qt::NoModifier);
|
||||
MotionEvent e(time, pos, global, mButtons, mParent->modifiers());
|
||||
grab->handleMouse(mParent, e);
|
||||
} else {
|
||||
MotionEvent e(time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier);
|
||||
MotionEvent e(time, mSurfacePos, mGlobalPos, mButtons, mParent->modifiers());
|
||||
window->handleMouse(mParent, e);
|
||||
}
|
||||
}
|
||||
@ -450,7 +450,6 @@ void QWaylandInputDevice::Pointer::pointer_motion(uint32_t time, wl_fixed_t surf
|
||||
void QWaylandInputDevice::Pointer::pointer_button(uint32_t serial, uint32_t time,
|
||||
uint32_t button, uint32_t state)
|
||||
{
|
||||
Q_UNUSED(serial);
|
||||
QWaylandWindow *window = mFocus;
|
||||
Qt::MouseButton qt_button;
|
||||
|
||||
@ -483,15 +482,17 @@ void QWaylandInputDevice::Pointer::pointer_button(uint32_t serial, uint32_t time
|
||||
|
||||
mParent->mTime = time;
|
||||
mParent->mSerial = serial;
|
||||
if (state)
|
||||
mParent->mQDisplay->setLastInputDevice(mParent, serial, window);
|
||||
|
||||
QWaylandWindow *grab = QWaylandWindow::mouseGrab();
|
||||
if (grab && grab != mFocus) {
|
||||
QPointF pos = QPointF(-1, -1);
|
||||
QPointF global = grab->window()->mapToGlobal(pos.toPoint());
|
||||
MotionEvent e(time, pos, global, mButtons, Qt::NoModifier);
|
||||
MotionEvent e(time, pos, global, mButtons, mParent->modifiers());
|
||||
grab->handleMouse(mParent, e);
|
||||
} else if (window) {
|
||||
MotionEvent e(time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier);
|
||||
MotionEvent e(time, mSurfacePos, mGlobalPos, mButtons, mParent->modifiers());
|
||||
window->handleMouse(mParent, e);
|
||||
}
|
||||
}
|
||||
@ -736,13 +737,13 @@ void QWaylandInputDevice::Keyboard::focusCallback(void *data, struct wl_callback
|
||||
|
||||
void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
|
||||
{
|
||||
Q_UNUSED(serial);
|
||||
QWaylandWindow *window = mFocus;
|
||||
uint32_t code = key + 8;
|
||||
bool isDown = state != 0;
|
||||
QEvent::Type type = isDown ? QEvent::KeyPress : QEvent::KeyRelease;
|
||||
QString text;
|
||||
int qtkey = key + 8; // qt-compositor substracts 8 for some reason
|
||||
mParent->mSerial = serial;
|
||||
|
||||
if (!window) {
|
||||
// We destroyed the keyboard focus surface, but the server
|
||||
@ -750,6 +751,9 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time,
|
||||
return;
|
||||
}
|
||||
|
||||
if (isDown)
|
||||
mParent->mQDisplay->setLastInputDevice(mParent, serial, window);
|
||||
|
||||
#ifndef QT_NO_WAYLAND_XKB
|
||||
if (!createDefaultKeyMap()) {
|
||||
return;
|
||||
@ -761,7 +765,8 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time,
|
||||
Qt::KeyboardModifiers modifiers = mParent->modifiers();
|
||||
|
||||
uint utf32 = xkb_keysym_to_utf32(sym);
|
||||
text = QString::fromUcs4(&utf32, 1);
|
||||
if (utf32)
|
||||
text = QString::fromUcs4(&utf32, 1);
|
||||
|
||||
qtkey = keysymToQtKey(sym, modifiers, text);
|
||||
|
||||
@ -855,6 +860,7 @@ void QWaylandInputDevice::Touch::touch_down(uint32_t serial,
|
||||
mParent->mTime = time;
|
||||
mParent->mSerial = serial;
|
||||
mFocus = QWaylandWindow::fromWlSurface(surface);
|
||||
mParent->mQDisplay->setLastInputDevice(mParent, serial, mFocus);
|
||||
mParent->handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointPressed);
|
||||
}
|
||||
|
||||
|
@ -118,6 +118,14 @@ QDpi QWaylandScreen::logicalDpi() const
|
||||
return QPlatformScreen::logicalDpi();
|
||||
}
|
||||
|
||||
QList<QPlatformScreen *> QWaylandScreen::virtualSiblings() const
|
||||
{
|
||||
QList<QPlatformScreen *> list;
|
||||
foreach (QWaylandScreen *screen, mWaylandDisplay->screens())
|
||||
list << screen;
|
||||
return list;
|
||||
}
|
||||
|
||||
void QWaylandScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask)
|
||||
{
|
||||
foreach (QWindow *window, QGuiApplication::allWindows()) {
|
||||
|
@ -70,6 +70,7 @@ public:
|
||||
QSizeF physicalSize() const Q_DECL_OVERRIDE;
|
||||
|
||||
QDpi logicalDpi() const Q_DECL_OVERRIDE;
|
||||
QList<QPlatformScreen *> virtualSiblings() const Q_DECL_OVERRIDE;
|
||||
|
||||
void setOrientationUpdateMask(Qt::ScreenOrientations mask);
|
||||
|
||||
|
@ -90,8 +90,6 @@ QWaylandWindow::QWaylandWindow(QWindow *window)
|
||||
, mResizeDirty(false)
|
||||
, mResizeAfterSwap(qEnvironmentVariableIsSet("QT_WAYLAND_RESIZE_AFTER_SWAP"))
|
||||
, mSentInitialResize(false)
|
||||
, mMouseDevice(0)
|
||||
, mMouseSerial(0)
|
||||
, mState(Qt::WindowNoState)
|
||||
, mMask()
|
||||
, mBackingStore(Q_NULLPTR)
|
||||
@ -218,7 +216,7 @@ void QWaylandWindow::setGeometry(const QRect &rect)
|
||||
{
|
||||
setGeometry_helper(rect);
|
||||
|
||||
if (window()->isVisible()) {
|
||||
if (window()->isVisible() && rect.isValid()) {
|
||||
if (mWindowDecoration)
|
||||
mWindowDecoration->update();
|
||||
|
||||
@ -236,14 +234,17 @@ void QWaylandWindow::setGeometry(const QRect &rect)
|
||||
void QWaylandWindow::setVisible(bool visible)
|
||||
{
|
||||
if (visible) {
|
||||
if (window()->type() == Qt::Popup && transientParent()) {
|
||||
if (window()->type() == Qt::Popup) {
|
||||
QWaylandWindow *parent = transientParent();
|
||||
mMouseDevice = parent->mMouseDevice;
|
||||
mMouseSerial = parent->mMouseSerial;
|
||||
|
||||
QWaylandWlShellSurface *wlshellSurface = dynamic_cast<QWaylandWlShellSurface*>(mShellSurface);
|
||||
if (mMouseDevice && wlshellSurface) {
|
||||
wlshellSurface->setPopup(transientParent(), mMouseDevice, mMouseSerial);
|
||||
if (!parent) {
|
||||
// Try with the current focus window. It should be the right one and anyway
|
||||
// better than having no parent at all.
|
||||
parent = mDisplay->lastInputWindow();
|
||||
}
|
||||
if (parent) {
|
||||
QWaylandWlShellSurface *wlshellSurface = dynamic_cast<QWaylandWlShellSurface*>(mShellSurface);
|
||||
if (wlshellSurface)
|
||||
wlshellSurface->setPopup(parent, mDisplay->lastInputDevice(), mDisplay->lastInputSerial());
|
||||
}
|
||||
}
|
||||
|
||||
@ -364,7 +365,7 @@ void QWaylandWindow::requestResize()
|
||||
{
|
||||
QMutexLocker lock(&mResizeLock);
|
||||
|
||||
if (mCanResize) {
|
||||
if (mCanResize || !mSentInitialResize) {
|
||||
doResize();
|
||||
}
|
||||
|
||||
@ -599,7 +600,7 @@ QWaylandWindow *QWaylandWindow::transientParent() const
|
||||
if (window()->transientParent()) {
|
||||
// Take the top level window here, since the transient parent may be a QWidgetWindow
|
||||
// or some other window without a shell surface, which is then not able to get mouse
|
||||
// events, nor set mMouseSerial and mMouseDevice.
|
||||
// events.
|
||||
return static_cast<QWaylandWindow *>(topLevelWindow(window()->transientParent())->handle());
|
||||
}
|
||||
return 0;
|
||||
@ -607,10 +608,6 @@ QWaylandWindow *QWaylandWindow::transientParent() const
|
||||
|
||||
void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e)
|
||||
{
|
||||
if (e.buttons != Qt::NoButton) {
|
||||
mMouseSerial = inputDevice->serial();
|
||||
mMouseDevice = inputDevice;
|
||||
}
|
||||
|
||||
if (mWindowDecoration) {
|
||||
handleMouseEventWithDecoration(inputDevice, e);
|
||||
|
@ -222,8 +222,6 @@ protected:
|
||||
QPoint mOffset;
|
||||
|
||||
QIcon mWindowIcon;
|
||||
QWaylandInputDevice *mMouseDevice;
|
||||
int mMouseSerial;
|
||||
|
||||
Qt::WindowState mState;
|
||||
QRegion mMask;
|
||||
|
@ -189,8 +189,14 @@ void QWaylandWlShellSurface::updateTransientParent(QWindow *parent)
|
||||
void QWaylandWlShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial)
|
||||
{
|
||||
QWaylandWindow *parent_wayland_window = parent;
|
||||
if (!parent_wayland_window)
|
||||
if (!parent_wayland_window) {
|
||||
qWarning("setPopup called without parent window");
|
||||
return;
|
||||
}
|
||||
if (!device) {
|
||||
qWarning("setPopup called without input device");
|
||||
return;
|
||||
}
|
||||
|
||||
// set_popup expects a position relative to the parent
|
||||
QPoint transientPos = m_window->geometry().topLeft(); // this is absolute
|
||||
|
Loading…
x
Reference in New Issue
Block a user