Fix some remaining issues with DnD

Do not set the event mask of the window
we drop onto to NO_EVENT. Always use the
clipboards requestor window to convert
selections.

Reviewed-by: Samuel
This commit is contained in:
Lars Knoll 2011-06-07 13:35:12 +02:00
parent ff53b1dcec
commit 1928e633a5
4 changed files with 10 additions and 93 deletions

View File

@ -261,6 +261,9 @@ xcb_window_t QXcbClipboard::requestor() const
0, // value mask
0)); // value list
uint32_t mask = XCB_EVENT_MASK_PROPERTY_CHANGE;
xcb_change_window_attributes(m_connection->xcb_connection(), window, XCB_CW_EVENT_MASK, &mask);
that->setRequestor(window);
}
return m_requestor;
@ -731,23 +734,16 @@ QByteArray QXcbClipboard::clipboardReadIncrementalProperty(xcb_window_t win, xcb
QByteArray QXcbClipboard::getDataInFormat(xcb_atom_t modeAtom, xcb_atom_t fmtAtom)
{
QByteArray buf;
xcb_window_t win = requestor();
// qDebug() << "getDataInFormat" << m_connection->atomName(modeAtom) << m_connection->atomName(fmtAtom) << win;
return getSelection(win, modeAtom, fmtAtom, m_connection->atom(QXcbAtom::_QT_SELECTION));
return getSelection(modeAtom, fmtAtom, m_connection->atom(QXcbAtom::_QT_SELECTION));
}
QByteArray QXcbClipboard::getSelection(xcb_window_t win, xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property)
QByteArray QXcbClipboard::getSelection(xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property)
{
QByteArray buf;
uint32_t mask = XCB_EVENT_MASK_NO_EVENT;
xcb_change_window_attributes(m_connection->xcb_connection(), win, XCB_CW_EVENT_MASK, &mask);
xcb_window_t win = requestor();
xcb_delete_property(m_connection->xcb_connection(), win, property);
xcb_convert_selection(m_connection->xcb_connection(), win, selection, target, property, XCB_CURRENT_TIME);
xcb_convert_selection(m_connection->xcb_connection(), win, selection, target, property, m_connection->time());
m_connection->sync();
@ -758,21 +754,14 @@ QByteArray QXcbClipboard::getSelection(xcb_window_t win, xcb_atom_t selection, x
if (no_selection)
return buf;
mask = XCB_EVENT_MASK_PROPERTY_CHANGE;
xcb_change_window_attributes(m_connection->xcb_connection(), win, XCB_CW_EVENT_MASK, &mask);
xcb_atom_t type;
if (clipboardReadProperty(win, property, true, &buf, 0, &type, 0)) {
if (type == m_connection->atom(QXcbAtom::INCR)) {
qDebug() << "INCR";
int nbytes = buf.size() >= 4 ? *((int*)buf.data()) : 0;
buf = clipboardReadIncrementalProperty(win, property, nbytes, false);
}
}
mask = XCB_EVENT_MASK_NO_EVENT;
xcb_change_window_attributes(m_connection->xcb_connection(), win, XCB_CW_EVENT_MASK, &mask);
return buf;
}

View File

@ -75,7 +75,7 @@ public:
QByteArray getDataInFormat(xcb_atom_t modeAtom, xcb_atom_t fmtatom);
xcb_window_t getSelectionOwner(xcb_atom_t atom) const;
QByteArray getSelection(xcb_window_t win, xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property);
QByteArray getSelection(xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property);
private:
void setOwner(xcb_window_t window);

View File

@ -55,7 +55,7 @@
QT_BEGIN_NAMESPACE
#define DND_DEBUG
//#define DND_DEBUG
#ifdef DND_DEBUG
#define DEBUG qDebug
#else
@ -733,8 +733,6 @@ void QXcbDrag::handle_xdnd_position(QWindow *w, const xcb_client_message_event_t
p -= geometry.topLeft();
qDebug() << "handle_xdnd_position" << p;
// ####
// if (!passive && checkEmbedded(w, e))
// return;
@ -772,7 +770,6 @@ void QXcbDrag::handle_xdnd_position(QWindow *w, const xcb_client_message_event_t
manager->possible_actions = manager->dragPrivate()->possible_actions;
} else {
manager->possible_actions = Qt::DropActions(toDropAction(e->data.data32[4]));
// possible_actions |= Qt::CopyAction;
}
QDragMoveEvent me(p, manager->possible_actions, dropData,
QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
@ -1226,66 +1223,6 @@ Window findRealWindow(const QPoint & pos, Window w, int md)
return 0;
}
void QDragManager::drop()
{
endDrag();
if (!current_target)
return;
qDeleteInEventHandler(xdnd_data.deco);
xdnd_data.deco = 0;
XClientMessageEvent drop;
drop.type = ClientMessage;
drop.window = current_target;
drop.format = 32;
drop.message_type = ATOM(XdndDrop);
drop.data.l[0] = dragPrivate()->source->effectiveWinId();
drop.data.l[1] = 0; // flags
drop.data.l[2] = connection()->time();
drop.data.l[3] = 0;
drop.data.l[4] = 0;
QWidget * w = QWidget::find(current_proxy_target);
if (w && (w->windowType() == Qt::Desktop) && !w->acceptDrops())
w = 0;
QXdndDropTransaction t = {
connection()->time(),
current_target,
current_proxy_target,
w,
current_embedding_widget,
object
};
X11->dndDropTransactions.append(t);
restartXdndDropExpiryTimer();
if (w)
X11->xdndHandleDrop(w, (const XEvent *)&drop, false);
else
XSendEvent(X11->display, current_proxy_target, False,
NoEventMask, (XEvent*)&drop);
current_target = 0;
current_proxy_target = 0;
source_time = 0;
current_embedding_widget = 0;
object = 0;
#ifndef QT_NO_CURSOR
if (restoreCursor) {
QApplication::restoreOverrideCursor();
restoreCursor = false;
}
#endif
}
bool QX11Data::xdndHandleBadwindow()
{
if (current_target) {
@ -1480,16 +1417,8 @@ QVariant QDropData::xdndObtainData(const QByteArray &format, QVariant::Type requ
if (c->clipboard()->getSelectionOwner(drag->connection()->atom(QXcbAtom::XdndSelection)) == XCB_NONE)
return result; // should never happen?
QWindow* tw = drag->currentWindow.data();
if (!drag->currentWindow || (drag->currentWindow.data()->windowType() == Qt::Desktop))
tw = new QWindow;
xcb_window_t win = ::xcb_window(tw);
xcb_atom_t xdnd_selection = c->atom(QXcbAtom::XdndSelection);
result = c->clipboard()->getSelection(win, xdnd_selection, a, xdnd_selection);
if (!drag->currentWindow || (drag->currentWindow.data()->windowType() == Qt::Desktop))
delete tw;
result = c->clipboard()->getSelection(xdnd_selection, a, xdnd_selection);
return mimeConvertToFormat(c, a, result, QLatin1String(format), requestedType, encoding);
}

View File

@ -981,7 +981,6 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
return;
if (event->type == atom(QXcbAtom::WM_PROTOCOLS)) {
qDebug() << "WM_PROTO" << m_window << connection()->atomName(event->data.data32[0]);
if (event->data.data32[0] == atom(QXcbAtom::WM_DELETE_WINDOW)) {
QWindowSystemInterface::handleCloseEvent(window());
} else if (event->data.data32[0] == atom(QXcbAtom::WM_TAKE_FOCUS)) {