summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-08-01 11:03:33 +0200
committerLiang Qi <liang.qi@qt.io>2016-08-01 11:03:38 +0200
commit6260c4376e598031e467416027703bd11012621d (patch)
tree993f83d4105f228f4cb6bed1da600dc671be2ed4
parent45d43ca1d9c4edca378f21530f184433cc629431 (diff)
parentd8b4bef3ddff327598027c8f94a61e3d0b61a2dd (diff)
downloadqtwayland-6260c4376e598031e467416027703bd11012621d.tar.gz
Merge remote-tracking branch 'origin/5.6' into 5.7
Change-Id: I75a8ddc0652f3c6f438ef98e940c9357450d29c6
-rw-r--r--src/client/qwaylanddisplay.cpp69
-rw-r--r--src/client/qwaylanddisplay_p.h13
-rw-r--r--src/client/qwaylandinputdevice.cpp34
-rw-r--r--src/client/qwaylandinputdevice_p.h4
-rw-r--r--src/client/qwaylandshmbackingstore.cpp28
-rw-r--r--src/client/qwaylandxdgsurface.cpp15
-rw-r--r--src/client/qwaylandxdgsurface_p.h1
7 files changed, 118 insertions, 46 deletions
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
index 9ed76d2c..7b3ff7bb 100644
--- a/src/client/qwaylanddisplay.cpp
+++ b/src/client/qwaylanddisplay.cpp
@@ -137,6 +137,8 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration)
, mLastInputSerial(0)
, mLastInputDevice(0)
, mLastInputWindow(0)
+ , mLastKeyboardFocus(Q_NULLPTR)
+ , mSyncCallback(Q_NULLPTR)
{
qRegisterMetaType<uint32_t>("uint32_t");
@@ -393,6 +395,73 @@ void QWaylandDisplay::setLastInputDevice(QWaylandInputDevice *device, uint32_t s
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
diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h
index 1c0b46bf..b040d69a 100644
--- a/src/client/qwaylanddisplay_p.h
+++ b/src/client/qwaylanddisplay_p.h
@@ -54,6 +54,7 @@
#include <QtCore/QObject>
#include <QtCore/QRect>
#include <QtCore/QPointer>
+#include <QtCore/QVector>
#include <QtCore/QWaitCondition>
@@ -174,6 +175,11 @@ public:
QWaylandWindow *lastInputWindow() const;
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:
void blockingReadEvents();
void flushRequests();
@@ -183,6 +189,9 @@ private:
void exitWithError();
void checkError() const;
+ void handleWaylandSync();
+ void requestWaylandSync();
+
struct Listener {
RegistryListener listener;
void *data;
@@ -213,6 +222,10 @@ private:
uint32_t mLastInputSerial;
QWaylandInputDevice *mLastInputDevice;
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_remove(uint32_t id) Q_DECL_OVERRIDE;
diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp
index 13ab5efe..f490f07f 100644
--- a/src/client/qwaylandinputdevice.cpp
+++ b/src/client/qwaylandinputdevice.cpp
@@ -78,7 +78,6 @@ QWaylandInputDevice::Keyboard::Keyboard(QWaylandInputDevice *p)
, mXkbMap(0)
, mXkbState(0)
#endif
- , mFocusCallback(0)
, mNativeModifiers(0)
{
connect(&mRepeatTimer, SIGNAL(timeout()), this, SLOT(repeatKey()));
@@ -131,8 +130,6 @@ QWaylandInputDevice::Keyboard::~Keyboard()
#endif
if (mFocus)
QWindowSystemInterface::handleWindowActivated(0);
- if (mFocusCallback)
- wl_callback_destroy(mFocusCallback);
if (mParent->mVersion >= 3)
wl_keyboard_release(object());
else
@@ -614,10 +611,7 @@ void QWaylandInputDevice::Keyboard::keyboard_enter(uint32_t time, struct wl_surf
QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface);
mFocus = window;
- if (!mFocusCallback) {
- mFocusCallback = wl_display_sync(mParent->mDisplay);
- wl_callback_add_listener(mFocusCallback, &QWaylandInputDevice::Keyboard::callback, this);
- }
+ mParent->mQDisplay->handleKeyboardFocusChanged(mParent);
}
void QWaylandInputDevice::Keyboard::keyboard_leave(uint32_t time, struct wl_surface *surface)
@@ -632,31 +626,9 @@ void QWaylandInputDevice::Keyboard::keyboard_leave(uint32_t time, struct wl_surf
mFocus = NULL;
- // Use a callback to set the focus because we may get a leave/enter pair, and
- // 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();
-}
-
-const wl_callback_listener QWaylandInputDevice::Keyboard::callback = {
- QWaylandInputDevice::Keyboard::focusCallback
-};
+ mParent->mQDisplay->handleKeyboardFocusChanged(mParent);
-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);
+ mRepeatTimer.stop();
}
static void sendKey(QWindow *tlw, ulong timestamp, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
diff --git a/src/client/qwaylandinputdevice_p.h b/src/client/qwaylandinputdevice_p.h
index 3954328f..ea685223 100644
--- a/src/client/qwaylandinputdevice_p.h
+++ b/src/client/qwaylandinputdevice_p.h
@@ -197,7 +197,6 @@ public:
xkb_keymap *mXkbMap;
xkb_state *mXkbState;
#endif
- struct wl_callback *mFocusCallback;
uint32_t mNativeModifiers;
int mRepeatKey;
@@ -209,9 +208,6 @@ public:
#endif
QTimer mRepeatTimer;
- static const wl_callback_listener callback;
- static void focusCallback(void *data, struct wl_callback *callback, uint32_t time);
-
Qt::KeyboardModifiers modifiers() const;
private slots:
diff --git a/src/client/qwaylandshmbackingstore.cpp b/src/client/qwaylandshmbackingstore.cpp
index ea1fe7ba..13f823ed 100644
--- a/src/client/qwaylandshmbackingstore.cpp
+++ b/src/client/qwaylandshmbackingstore.cpp
@@ -308,29 +308,37 @@ void QWaylandShmBackingStore::updateDecorations()
QPainter decorationPainter(entireSurface());
decorationPainter.setCompositionMode(QPainter::CompositionMode_Source);
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
target.setX(0);
target.setY(0);
- target.setWidth(sourceImage.width());
+ target.setWidth(dpWidth);
target.setHeight(windowDecorationMargins().top());
- decorationPainter.drawImage(target, sourceImage, target);
+ decorationPainter.drawImage(target, sourceImage, sourceMatrix.mapRect(target));
//Left
target.setWidth(windowDecorationMargins().left());
- target.setHeight(sourceImage.height());
- decorationPainter.drawImage(target, sourceImage, target);
+ target.setHeight(dpHeight);
+ decorationPainter.drawImage(target, sourceImage, sourceMatrix.mapRect(target));
//Right
- target.setX(sourceImage.width() - windowDecorationMargins().right());
- decorationPainter.drawImage(target, sourceImage, target);
+ target.setX(dpWidth - windowDecorationMargins().right());
+ target.setWidth(windowDecorationMargins().right());
+ decorationPainter.drawImage(target, sourceImage, sourceMatrix.mapRect(target));
//Bottom
target.setX(0);
- target.setY(sourceImage.height() - windowDecorationMargins().bottom());
- target.setWidth(sourceImage.width());
+ target.setY(dpHeight - windowDecorationMargins().bottom());
+ target.setWidth(dpWidth);
target.setHeight(windowDecorationMargins().bottom());
- decorationPainter.drawImage(target, sourceImage, target);
+ decorationPainter.drawImage(target, sourceImage, sourceMatrix.mapRect(target));
}
QWaylandAbstractDecoration *QWaylandShmBackingStore::windowDecoration() const
diff --git a/src/client/qwaylandxdgsurface.cpp b/src/client/qwaylandxdgsurface.cpp
index 69532b51..93263e0a 100644
--- a/src/client/qwaylandxdgsurface.cpp
+++ b/src/client/qwaylandxdgsurface.cpp
@@ -58,6 +58,7 @@ QWaylandXdgSurface::QWaylandXdgSurface(struct ::xdg_surface *xdg_surface, QWayla
, m_maximized(false)
, m_minimized(false)
, m_fullscreen(false)
+ , m_active(false)
, m_extendedWindow(Q_NULLPTR)
{
if (window->display()->windowExtension())
@@ -66,6 +67,9 @@ QWaylandXdgSurface::QWaylandXdgSurface(struct ::xdg_surface *xdg_surface, QWayla
QWaylandXdgSurface::~QWaylandXdgSurface()
{
+ if (m_active)
+ window()->display()->handleWindowDeactivated(m_window);
+
xdg_surface_destroy(object());
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);
bool aboutToMaximize = false;
bool aboutToFullScreen = false;
+ bool aboutToActivate = false;
for (size_t i = 0; i < numStates; 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);
break;
case XDG_SURFACE_STATE_ACTIVATED:
- // TODO: here about the missing window activation
+ aboutToActivate = true;
break;
default:
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_maximized)
m_normalSize = m_window->window()->frameGeometry().size();
diff --git a/src/client/qwaylandxdgsurface_p.h b/src/client/qwaylandxdgsurface_p.h
index 24eb8651..e98aa41e 100644
--- a/src/client/qwaylandxdgsurface_p.h
+++ b/src/client/qwaylandxdgsurface_p.h
@@ -112,6 +112,7 @@ private:
bool m_maximized;
bool m_minimized;
bool m_fullscreen;
+ bool m_active;
QSize m_normalSize;
QMargins m_margins;
QWaylandExtendedSurface *m_extendedWindow;