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:
parent
ff53b1dcec
commit
1928e633a5
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
Loading…
Reference in New Issue
Block a user