diff options
author | Li Qiu <li.qiu@yahoo.com> | 2014-08-27 18:24:52 +0300 |
---|---|---|
committer | Li Qiu <li.qiu@yahoo.com> | 2014-09-04 10:13:01 +0200 |
commit | a34716370185d98ab0de25903913d8f2c7c821fa (patch) | |
tree | 3c0c1f2389d192abf20c5273a1172f5882d40728 | |
parent | 1e052dd2de91506f71443e50bf225756d5ad69b1 (diff) | |
download | qtwayland-a34716370185d98ab0de25903913d8f2c7c821fa.tar.gz |
DataOffer not invalidated when client loses keyboard focus
The data_offer object should be invalidated when client loses keyboard focus.
Otherwise in following scenario, it will become zombie object: start app1 ->
copy text -> start app2 -> paste text -> close app1 -> paste again in app2 ->
seg fault in qtwayland.
The root cause is that when app2 takes focus the first time, data_device.data_offer
event was sent to it from DataDevice::setFocus. When app1 is closed, the data source
reference in data offer becomes invalid. so when trying to paste again in app2,
segmentation faults
Change-Id: I16a584e80fddaadd269b00cdf39eb405dd95b622
Task-number: QTBUG-41005
Reviewed-by: Giulio Camuffo <giulio.camuffo@jollamobile.com>
-rw-r--r-- | src/client/qwaylanddatadevice.cpp | 5 | ||||
-rw-r--r-- | src/client/qwaylanddatadevice_p.h | 1 | ||||
-rw-r--r-- | src/client/qwaylandinputdevice.cpp | 5 | ||||
-rw-r--r-- | src/client/qwaylandwindow.cpp | 9 | ||||
-rw-r--r-- | src/client/qwaylandwindow_p.h | 1 |
5 files changed, 21 insertions, 0 deletions
diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp index 8f690aae..74f879f9 100644 --- a/src/client/qwaylanddatadevice.cpp +++ b/src/client/qwaylanddatadevice.cpp @@ -77,6 +77,11 @@ QWaylandDataOffer *QWaylandDataDevice::selectionOffer() const return m_selectionOffer.data(); } +void QWaylandDataDevice::invalidateSelectionOffer() +{ + m_selectionOffer.reset(); +} + QWaylandDataSource *QWaylandDataDevice::selectionSource() const { return m_selectionSource.data(); diff --git a/src/client/qwaylanddatadevice_p.h b/src/client/qwaylanddatadevice_p.h index f5fad177..dae91290 100644 --- a/src/client/qwaylanddatadevice_p.h +++ b/src/client/qwaylanddatadevice_p.h @@ -65,6 +65,7 @@ public: ~QWaylandDataDevice(); QWaylandDataOffer *selectionOffer() const; + void invalidateSelectionOffer(); QWaylandDataSource *selectionSource() const; void setSelectionSource(QWaylandDataSource *source); diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp index 5be76d90..c0406768 100644 --- a/src/client/qwaylandinputdevice.cpp +++ b/src/client/qwaylandinputdevice.cpp @@ -717,6 +717,11 @@ void QWaylandInputDevice::Keyboard::keyboard_leave(uint32_t time, struct wl_surf Q_UNUSED(time); Q_UNUSED(surface); + if (surface) { + QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); + window->unfocus(); + } + mFocus = NULL; // Use a callback to set the focus because we may get a leave/enter pair, and diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index 278825e8..0905cb3a 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -42,6 +42,7 @@ #include "qwaylandwindow_p.h" #include "qwaylandbuffer_p.h" +#include "qwaylanddatadevice_p.h" #include "qwaylanddisplay_p.h" #include "qwaylandinputdevice_p.h" #include "qwaylandscreen_p.h" @@ -642,6 +643,14 @@ void QWaylandWindow::requestActivateWindow() // we rely on compositor setting keyboard focus based on window stacking. } +void QWaylandWindow::unfocus() +{ + QWaylandInputDevice *inputDevice = mDisplay->currentInputDevice(); + if (inputDevice && inputDevice->dataDevice()) { + inputDevice->dataDevice()->invalidateSelectionOffer(); + } +} + bool QWaylandWindow::isExposed() const { if (mShellSurface) diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h index db0b5945..a69af9c0 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -142,6 +142,7 @@ public: void requestActivateWindow() Q_DECL_OVERRIDE; bool isExposed() const Q_DECL_OVERRIDE; + void unfocus(); QWaylandDecoration *decoration() const; void setDecoration(QWaylandDecoration *decoration); |