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>
This commit is contained in:
Li Qiu 2014-08-27 18:24:52 +03:00
parent 421b3bb9e1
commit 03e95c8b8c
5 changed files with 21 additions and 0 deletions

View File

@ -77,6 +77,11 @@ QWaylandDataOffer *QWaylandDataDevice::selectionOffer() const
return m_selectionOffer.data(); return m_selectionOffer.data();
} }
void QWaylandDataDevice::invalidateSelectionOffer()
{
m_selectionOffer.reset();
}
QWaylandDataSource *QWaylandDataDevice::selectionSource() const QWaylandDataSource *QWaylandDataDevice::selectionSource() const
{ {
return m_selectionSource.data(); return m_selectionSource.data();

View File

@ -65,6 +65,7 @@ public:
~QWaylandDataDevice(); ~QWaylandDataDevice();
QWaylandDataOffer *selectionOffer() const; QWaylandDataOffer *selectionOffer() const;
void invalidateSelectionOffer();
QWaylandDataSource *selectionSource() const; QWaylandDataSource *selectionSource() const;
void setSelectionSource(QWaylandDataSource *source); void setSelectionSource(QWaylandDataSource *source);

View File

@ -717,6 +717,11 @@ void QWaylandInputDevice::Keyboard::keyboard_leave(uint32_t time, struct wl_surf
Q_UNUSED(time); Q_UNUSED(time);
Q_UNUSED(surface); Q_UNUSED(surface);
if (surface) {
QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface);
window->unfocus();
}
mFocus = NULL; mFocus = NULL;
// Use a callback to set the focus because we may get a leave/enter pair, and // Use a callback to set the focus because we may get a leave/enter pair, and

View File

@ -42,6 +42,7 @@
#include "qwaylandwindow_p.h" #include "qwaylandwindow_p.h"
#include "qwaylandbuffer_p.h" #include "qwaylandbuffer_p.h"
#include "qwaylanddatadevice_p.h"
#include "qwaylanddisplay_p.h" #include "qwaylanddisplay_p.h"
#include "qwaylandinputdevice_p.h" #include "qwaylandinputdevice_p.h"
#include "qwaylandscreen_p.h" #include "qwaylandscreen_p.h"
@ -642,6 +643,14 @@ void QWaylandWindow::requestActivateWindow()
// we rely on compositor setting keyboard focus based on window stacking. // 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 bool QWaylandWindow::isExposed() const
{ {
if (mShellSurface) if (mShellSurface)

View File

@ -142,6 +142,7 @@ public:
void requestActivateWindow() Q_DECL_OVERRIDE; void requestActivateWindow() Q_DECL_OVERRIDE;
bool isExposed() const Q_DECL_OVERRIDE; bool isExposed() const Q_DECL_OVERRIDE;
void unfocus();
QWaylandDecoration *decoration() const; QWaylandDecoration *decoration() const;
void setDecoration(QWaylandDecoration *decoration); void setDecoration(QWaylandDecoration *decoration);