Merge remote-tracking branch 'origin/5.6' into 5.7
Change-Id: I75a8ddc0652f3c6f438ef98e940c9357450d29c6
This commit is contained in:
commit
d04de01e80
@ -137,6 +137,8 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration)
|
|||||||
, mLastInputSerial(0)
|
, mLastInputSerial(0)
|
||||||
, mLastInputDevice(0)
|
, mLastInputDevice(0)
|
||||||
, mLastInputWindow(0)
|
, mLastInputWindow(0)
|
||||||
|
, mLastKeyboardFocus(Q_NULLPTR)
|
||||||
|
, mSyncCallback(Q_NULLPTR)
|
||||||
{
|
{
|
||||||
qRegisterMetaType<uint32_t>("uint32_t");
|
qRegisterMetaType<uint32_t>("uint32_t");
|
||||||
|
|
||||||
@ -393,6 +395,73 @@ void QWaylandDisplay::setLastInputDevice(QWaylandInputDevice *device, uint32_t s
|
|||||||
mLastInputWindow = win;
|
mLastInputWindow = win;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QWaylandDisplay::shellManagesActiveState() const
|
||||||
|
{
|
||||||
|
//TODO: This should be part of a shell interface used by the shell protocol implementations
|
||||||
|
return mShellXdg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWaylandDisplay::handleWindowActivated(QWaylandWindow *window)
|
||||||
|
{
|
||||||
|
if (mActiveWindows.contains(window))
|
||||||
|
return;
|
||||||
|
|
||||||
|
mActiveWindows.append(window);
|
||||||
|
requestWaylandSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWaylandDisplay::handleWindowDeactivated(QWaylandWindow *window)
|
||||||
|
{
|
||||||
|
Q_ASSERT(!mActiveWindows.empty());
|
||||||
|
|
||||||
|
if (mActiveWindows.last() == window)
|
||||||
|
requestWaylandSync();
|
||||||
|
|
||||||
|
mActiveWindows.removeOne(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWaylandDisplay::handleKeyboardFocusChanged(QWaylandInputDevice *inputDevice)
|
||||||
|
{
|
||||||
|
QWaylandWindow *keyboardFocus = inputDevice->keyboardFocus();
|
||||||
|
|
||||||
|
if (!shellManagesActiveState() && mLastKeyboardFocus != keyboardFocus) {
|
||||||
|
if (keyboardFocus)
|
||||||
|
handleWindowActivated(keyboardFocus);
|
||||||
|
if (mLastKeyboardFocus)
|
||||||
|
handleWindowDeactivated(mLastKeyboardFocus);
|
||||||
|
}
|
||||||
|
mLastKeyboardFocus = inputDevice->keyboardFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWaylandDisplay::handleWaylandSync()
|
||||||
|
{
|
||||||
|
// This callback is used to set the window activation because we may get an activate/deactivate
|
||||||
|
// pair, and the latter one would be lost in the QWindowSystemInterface queue, if we issue the
|
||||||
|
// handleWindowActivated() calls immediately.
|
||||||
|
QWindow *activeWindow = mActiveWindows.empty() ? Q_NULLPTR : mActiveWindows.last()->window();
|
||||||
|
if (activeWindow != QGuiApplication::focusWindow())
|
||||||
|
QWindowSystemInterface::handleWindowActivated(activeWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
const wl_callback_listener QWaylandDisplay::syncCallbackListener = {
|
||||||
|
[](void *data, struct wl_callback *callback, uint32_t time){
|
||||||
|
Q_UNUSED(time);
|
||||||
|
wl_callback_destroy(callback);
|
||||||
|
QWaylandDisplay *display = static_cast<QWaylandDisplay *>(data);
|
||||||
|
display->mSyncCallback = Q_NULLPTR;
|
||||||
|
display->handleWaylandSync();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void QWaylandDisplay::requestWaylandSync()
|
||||||
|
{
|
||||||
|
if (mSyncCallback)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mSyncCallback = wl_display_sync(mDisplay);
|
||||||
|
wl_callback_add_listener(mSyncCallback, &syncCallbackListener, this);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
#include <QtCore/QRect>
|
#include <QtCore/QRect>
|
||||||
#include <QtCore/QPointer>
|
#include <QtCore/QPointer>
|
||||||
|
#include <QtCore/QVector>
|
||||||
|
|
||||||
#include <QtCore/QWaitCondition>
|
#include <QtCore/QWaitCondition>
|
||||||
|
|
||||||
@ -174,6 +175,11 @@ public:
|
|||||||
QWaylandWindow *lastInputWindow() const;
|
QWaylandWindow *lastInputWindow() const;
|
||||||
void setLastInputDevice(QWaylandInputDevice *device, uint32_t serial, QWaylandWindow *window);
|
void setLastInputDevice(QWaylandInputDevice *device, uint32_t serial, QWaylandWindow *window);
|
||||||
|
|
||||||
|
bool shellManagesActiveState() const;
|
||||||
|
void handleWindowActivated(QWaylandWindow *window);
|
||||||
|
void handleWindowDeactivated(QWaylandWindow *window);
|
||||||
|
void handleKeyboardFocusChanged(QWaylandInputDevice *inputDevice);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void blockingReadEvents();
|
void blockingReadEvents();
|
||||||
void flushRequests();
|
void flushRequests();
|
||||||
@ -183,6 +189,9 @@ private:
|
|||||||
void exitWithError();
|
void exitWithError();
|
||||||
void checkError() const;
|
void checkError() const;
|
||||||
|
|
||||||
|
void handleWaylandSync();
|
||||||
|
void requestWaylandSync();
|
||||||
|
|
||||||
struct Listener {
|
struct Listener {
|
||||||
RegistryListener listener;
|
RegistryListener listener;
|
||||||
void *data;
|
void *data;
|
||||||
@ -213,6 +222,10 @@ private:
|
|||||||
uint32_t mLastInputSerial;
|
uint32_t mLastInputSerial;
|
||||||
QWaylandInputDevice *mLastInputDevice;
|
QWaylandInputDevice *mLastInputDevice;
|
||||||
QPointer<QWaylandWindow> mLastInputWindow;
|
QPointer<QWaylandWindow> mLastInputWindow;
|
||||||
|
QWaylandWindow *mLastKeyboardFocus;
|
||||||
|
QVector<QWaylandWindow *> mActiveWindows;
|
||||||
|
struct wl_callback *mSyncCallback;
|
||||||
|
static const wl_callback_listener syncCallbackListener;
|
||||||
|
|
||||||
void registry_global(uint32_t id, const QString &interface, uint32_t version) Q_DECL_OVERRIDE;
|
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;
|
void registry_global_remove(uint32_t id) Q_DECL_OVERRIDE;
|
||||||
|
@ -78,7 +78,6 @@ QWaylandInputDevice::Keyboard::Keyboard(QWaylandInputDevice *p)
|
|||||||
, mXkbMap(0)
|
, mXkbMap(0)
|
||||||
, mXkbState(0)
|
, mXkbState(0)
|
||||||
#endif
|
#endif
|
||||||
, mFocusCallback(0)
|
|
||||||
, mNativeModifiers(0)
|
, mNativeModifiers(0)
|
||||||
{
|
{
|
||||||
connect(&mRepeatTimer, SIGNAL(timeout()), this, SLOT(repeatKey()));
|
connect(&mRepeatTimer, SIGNAL(timeout()), this, SLOT(repeatKey()));
|
||||||
@ -131,8 +130,6 @@ QWaylandInputDevice::Keyboard::~Keyboard()
|
|||||||
#endif
|
#endif
|
||||||
if (mFocus)
|
if (mFocus)
|
||||||
QWindowSystemInterface::handleWindowActivated(0);
|
QWindowSystemInterface::handleWindowActivated(0);
|
||||||
if (mFocusCallback)
|
|
||||||
wl_callback_destroy(mFocusCallback);
|
|
||||||
if (mParent->mVersion >= 3)
|
if (mParent->mVersion >= 3)
|
||||||
wl_keyboard_release(object());
|
wl_keyboard_release(object());
|
||||||
else
|
else
|
||||||
@ -614,10 +611,7 @@ void QWaylandInputDevice::Keyboard::keyboard_enter(uint32_t time, struct wl_surf
|
|||||||
QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface);
|
QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface);
|
||||||
mFocus = window;
|
mFocus = window;
|
||||||
|
|
||||||
if (!mFocusCallback) {
|
mParent->mQDisplay->handleKeyboardFocusChanged(mParent);
|
||||||
mFocusCallback = wl_display_sync(mParent->mDisplay);
|
|
||||||
wl_callback_add_listener(mFocusCallback, &QWaylandInputDevice::Keyboard::callback, this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWaylandInputDevice::Keyboard::keyboard_leave(uint32_t time, struct wl_surface *surface)
|
void QWaylandInputDevice::Keyboard::keyboard_leave(uint32_t time, struct wl_surface *surface)
|
||||||
@ -632,33 +626,11 @@ void QWaylandInputDevice::Keyboard::keyboard_leave(uint32_t time, struct wl_surf
|
|||||||
|
|
||||||
mFocus = NULL;
|
mFocus = NULL;
|
||||||
|
|
||||||
// Use a callback to set the focus because we may get a leave/enter pair, and
|
mParent->mQDisplay->handleKeyboardFocusChanged(mParent);
|
||||||
// the latter one would be lost in the QWindowSystemInterface queue, if
|
|
||||||
// we issue the handleWindowActivated() calls immediately.
|
|
||||||
if (!mFocusCallback) {
|
|
||||||
mFocusCallback = wl_display_sync(mParent->mDisplay);
|
|
||||||
wl_callback_add_listener(mFocusCallback, &QWaylandInputDevice::Keyboard::callback, this);
|
|
||||||
}
|
|
||||||
mRepeatTimer.stop();
|
mRepeatTimer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
const wl_callback_listener QWaylandInputDevice::Keyboard::callback = {
|
|
||||||
QWaylandInputDevice::Keyboard::focusCallback
|
|
||||||
};
|
|
||||||
|
|
||||||
void QWaylandInputDevice::Keyboard::focusCallback(void *data, struct wl_callback *callback, uint32_t time)
|
|
||||||
{
|
|
||||||
Q_UNUSED(time);
|
|
||||||
Q_UNUSED(callback);
|
|
||||||
QWaylandInputDevice::Keyboard *self = static_cast<QWaylandInputDevice::Keyboard *>(data);
|
|
||||||
if (self->mFocusCallback) {
|
|
||||||
wl_callback_destroy(self->mFocusCallback);
|
|
||||||
self->mFocusCallback = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
QWindowSystemInterface::handleWindowActivated(self->mFocus ? self->mFocus->window() : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sendKey(QWindow *tlw, ulong timestamp, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
|
static void sendKey(QWindow *tlw, ulong timestamp, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
|
||||||
quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers,
|
quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers,
|
||||||
const QString& text = QString(), bool autorep = false, ushort count = 1)
|
const QString& text = QString(), bool autorep = false, ushort count = 1)
|
||||||
|
@ -197,7 +197,6 @@ public:
|
|||||||
xkb_keymap *mXkbMap;
|
xkb_keymap *mXkbMap;
|
||||||
xkb_state *mXkbState;
|
xkb_state *mXkbState;
|
||||||
#endif
|
#endif
|
||||||
struct wl_callback *mFocusCallback;
|
|
||||||
uint32_t mNativeModifiers;
|
uint32_t mNativeModifiers;
|
||||||
|
|
||||||
int mRepeatKey;
|
int mRepeatKey;
|
||||||
@ -209,9 +208,6 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
QTimer mRepeatTimer;
|
QTimer mRepeatTimer;
|
||||||
|
|
||||||
static const wl_callback_listener callback;
|
|
||||||
static void focusCallback(void *data, struct wl_callback *callback, uint32_t time);
|
|
||||||
|
|
||||||
Qt::KeyboardModifiers modifiers() const;
|
Qt::KeyboardModifiers modifiers() const;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
@ -308,29 +308,37 @@ void QWaylandShmBackingStore::updateDecorations()
|
|||||||
QPainter decorationPainter(entireSurface());
|
QPainter decorationPainter(entireSurface());
|
||||||
decorationPainter.setCompositionMode(QPainter::CompositionMode_Source);
|
decorationPainter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
QImage sourceImage = windowDecoration()->contentImage();
|
QImage sourceImage = windowDecoration()->contentImage();
|
||||||
QRect target;
|
|
||||||
|
qreal dp = sourceImage.devicePixelRatio();
|
||||||
|
int dpWidth = int(sourceImage.width() / dp);
|
||||||
|
int dpHeight = int(sourceImage.height() / dp);
|
||||||
|
QMatrix sourceMatrix;
|
||||||
|
sourceMatrix.scale(dp, dp);
|
||||||
|
QRect target; // needs to be in device independent pixels
|
||||||
|
|
||||||
//Top
|
//Top
|
||||||
target.setX(0);
|
target.setX(0);
|
||||||
target.setY(0);
|
target.setY(0);
|
||||||
target.setWidth(sourceImage.width());
|
target.setWidth(dpWidth);
|
||||||
target.setHeight(windowDecorationMargins().top());
|
target.setHeight(windowDecorationMargins().top());
|
||||||
decorationPainter.drawImage(target, sourceImage, target);
|
decorationPainter.drawImage(target, sourceImage, sourceMatrix.mapRect(target));
|
||||||
|
|
||||||
//Left
|
//Left
|
||||||
target.setWidth(windowDecorationMargins().left());
|
target.setWidth(windowDecorationMargins().left());
|
||||||
target.setHeight(sourceImage.height());
|
target.setHeight(dpHeight);
|
||||||
decorationPainter.drawImage(target, sourceImage, target);
|
decorationPainter.drawImage(target, sourceImage, sourceMatrix.mapRect(target));
|
||||||
|
|
||||||
//Right
|
//Right
|
||||||
target.setX(sourceImage.width() - windowDecorationMargins().right());
|
target.setX(dpWidth - windowDecorationMargins().right());
|
||||||
decorationPainter.drawImage(target, sourceImage, target);
|
target.setWidth(windowDecorationMargins().right());
|
||||||
|
decorationPainter.drawImage(target, sourceImage, sourceMatrix.mapRect(target));
|
||||||
|
|
||||||
//Bottom
|
//Bottom
|
||||||
target.setX(0);
|
target.setX(0);
|
||||||
target.setY(sourceImage.height() - windowDecorationMargins().bottom());
|
target.setY(dpHeight - windowDecorationMargins().bottom());
|
||||||
target.setWidth(sourceImage.width());
|
target.setWidth(dpWidth);
|
||||||
target.setHeight(windowDecorationMargins().bottom());
|
target.setHeight(windowDecorationMargins().bottom());
|
||||||
decorationPainter.drawImage(target, sourceImage, target);
|
decorationPainter.drawImage(target, sourceImage, sourceMatrix.mapRect(target));
|
||||||
}
|
}
|
||||||
|
|
||||||
QWaylandAbstractDecoration *QWaylandShmBackingStore::windowDecoration() const
|
QWaylandAbstractDecoration *QWaylandShmBackingStore::windowDecoration() const
|
||||||
|
@ -58,6 +58,7 @@ QWaylandXdgSurface::QWaylandXdgSurface(struct ::xdg_surface *xdg_surface, QWayla
|
|||||||
, m_maximized(false)
|
, m_maximized(false)
|
||||||
, m_minimized(false)
|
, m_minimized(false)
|
||||||
, m_fullscreen(false)
|
, m_fullscreen(false)
|
||||||
|
, m_active(false)
|
||||||
, m_extendedWindow(Q_NULLPTR)
|
, m_extendedWindow(Q_NULLPTR)
|
||||||
{
|
{
|
||||||
if (window->display()->windowExtension())
|
if (window->display()->windowExtension())
|
||||||
@ -66,6 +67,9 @@ QWaylandXdgSurface::QWaylandXdgSurface(struct ::xdg_surface *xdg_surface, QWayla
|
|||||||
|
|
||||||
QWaylandXdgSurface::~QWaylandXdgSurface()
|
QWaylandXdgSurface::~QWaylandXdgSurface()
|
||||||
{
|
{
|
||||||
|
if (m_active)
|
||||||
|
window()->display()->handleWindowDeactivated(m_window);
|
||||||
|
|
||||||
xdg_surface_destroy(object());
|
xdg_surface_destroy(object());
|
||||||
delete m_extendedWindow;
|
delete m_extendedWindow;
|
||||||
}
|
}
|
||||||
@ -182,6 +186,7 @@ void QWaylandXdgSurface::xdg_surface_configure(int32_t width, int32_t height, st
|
|||||||
size_t numStates = states->size / sizeof(uint32_t);
|
size_t numStates = states->size / sizeof(uint32_t);
|
||||||
bool aboutToMaximize = false;
|
bool aboutToMaximize = false;
|
||||||
bool aboutToFullScreen = false;
|
bool aboutToFullScreen = false;
|
||||||
|
bool aboutToActivate = false;
|
||||||
|
|
||||||
for (size_t i = 0; i < numStates; i++) {
|
for (size_t i = 0; i < numStates; i++) {
|
||||||
switch (state[i]) {
|
switch (state[i]) {
|
||||||
@ -195,13 +200,21 @@ void QWaylandXdgSurface::xdg_surface_configure(int32_t width, int32_t height, st
|
|||||||
m_normalSize = QSize(width, height);
|
m_normalSize = QSize(width, height);
|
||||||
break;
|
break;
|
||||||
case XDG_SURFACE_STATE_ACTIVATED:
|
case XDG_SURFACE_STATE_ACTIVATED:
|
||||||
// TODO: here about the missing window activation
|
aboutToActivate = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_active && aboutToActivate) {
|
||||||
|
m_active = true;
|
||||||
|
window()->display()->handleWindowActivated(m_window);
|
||||||
|
} else if (m_active && !aboutToActivate) {
|
||||||
|
m_active = false;
|
||||||
|
window()->display()->handleWindowDeactivated(m_window);
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_fullscreen && aboutToFullScreen) {
|
if (!m_fullscreen && aboutToFullScreen) {
|
||||||
if (!m_maximized)
|
if (!m_maximized)
|
||||||
m_normalSize = m_window->window()->frameGeometry().size();
|
m_normalSize = m_window->window()->frameGeometry().size();
|
||||||
|
@ -112,6 +112,7 @@ private:
|
|||||||
bool m_maximized;
|
bool m_maximized;
|
||||||
bool m_minimized;
|
bool m_minimized;
|
||||||
bool m_fullscreen;
|
bool m_fullscreen;
|
||||||
|
bool m_active;
|
||||||
QSize m_normalSize;
|
QSize m_normalSize;
|
||||||
QMargins m_margins;
|
QMargins m_margins;
|
||||||
QWaylandExtendedSurface *m_extendedWindow;
|
QWaylandExtendedSurface *m_extendedWindow;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user