summaryrefslogtreecommitdiffstats
path: root/src/client
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-08-02 10:44:58 +0200
committerLiang Qi <liang.qi@qt.io>2016-08-02 10:44:58 +0200
commita4d68e7d78a28225c23931431f0db6ebf75f5e41 (patch)
treeea04abea84bfa53aa4212cade81df780f4a5d89b /src/client
parent5ce1c2a3bf9546171d2913c76330bc6d1b6a4789 (diff)
parent6260c4376e598031e467416027703bd11012621d (diff)
Merge remote-tracking branch 'origin/5.7' into dev
Conflicts: .qmake.conf examples/wayland/minimal-qml/main.qml Change-Id: Ic34029a6aa77f2b359f40258a05421d82efd5b37
Diffstat (limited to 'src/client')
-rw-r--r--src/client/global/qwaylandclientextension.h4
-rw-r--r--src/client/qwaylanddisplay.cpp69
-rw-r--r--src/client/qwaylanddisplay_p.h13
-rw-r--r--src/client/qwaylandinputcontext.cpp5
-rw-r--r--src/client/qwaylandinputdevice.cpp37
-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
9 files changed, 125 insertions, 51 deletions
diff --git a/src/client/global/qwaylandclientextension.h b/src/client/global/qwaylandclientextension.h
index a39f32b7f..d1610c271 100644
--- a/src/client/global/qwaylandclientextension.h
+++ b/src/client/global/qwaylandclientextension.h
@@ -39,7 +39,9 @@
#include <QObject>
#include <QtWaylandClient/qwaylandclientexport.h>
-#include <QtWaylandClient/private/qwayland-wayland.h>
+
+struct wl_registry;
+
QT_BEGIN_NAMESPACE
namespace QtWaylandClient {
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
index 9ed76d2ce..7b3ff7bbb 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 1c0b46bfb..b040d69a0 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/qwaylandinputcontext.cpp b/src/client/qwaylandinputcontext.cpp
index 509965d2f..5a58d6d75 100644
--- a/src/client/qwaylandinputcontext.cpp
+++ b/src/client/qwaylandinputcontext.cpp
@@ -335,8 +335,9 @@ void QWaylandTextInput::zwp_text_input_v2_keysym(uint32_t time, uint32_t sym, ui
Qt::KeyboardModifiers qtModifiers = modifiersToQtModifiers(modifiers);
QEvent::Type type = QWaylandXkb::toQtEventType(state);
- const QString &text = QWaylandXkb::textFromKeysym(sym, qtModifiers);
- int qtkey = QWaylandXkb::keysymToQtKey(sym, qtModifiers, text);
+ QString text;
+ int qtkey;
+ std::tie(qtkey, text) = QWaylandXkb::keysymToQtKey(sym, qtModifiers);
QWindowSystemInterface::handleKeyEvent(QGuiApplication::focusWindow(),
time, type, qtkey, qtModifiers, text);
diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp
index 613d517a3..f490f07ff 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,
@@ -707,8 +679,7 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time,
Qt::KeyboardModifiers modifiers = mParent->modifiers();
- text = QWaylandXkb::textFromKeysym(sym, modifiers);
- qtkey = QWaylandXkb::keysymToQtKey(sym, modifiers, text);
+ std::tie(qtkey, text) = QWaylandXkb::keysymToQtKey(sym, modifiers);
sendKey(window->window(), time, type, qtkey, modifiers, code, sym, mNativeModifiers, text);
#else
diff --git a/src/client/qwaylandinputdevice_p.h b/src/client/qwaylandinputdevice_p.h
index 3954328f1..ea685223d 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 ea1fe7baa..13f823edf 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 69532b514..93263e0aa 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 24eb86519..e98aa41e9 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;