xcb: remove confusing indirections for qt selection owner

This makes it more obvious that clipboard and DnD use the
same selection owner (QXcbConnection::qtSelectionOwner()).

This way we can also drop some QT_NO_CLIPBOARD defines.
These defines actually are broken, but that is out-of-scope
for this patch.

And renamed the functions according to Qt guidelines:

getSelectionOwner()   -> selectionOwner()
getQtSelectionOwner() -> qtSelectionOwner()

The previous naming probably was influenced by underlying
C API - xcb_get_selection_owner().

Change-Id: I467f1a3dbe75b4e8fd41c7e66ca9b0e25ef1039c
Reviewed-by: Liang Qi <liang.qi@qt.io>
bb10
Gatis Paeglis 2019-01-03 12:00:48 +01:00 committed by Liang Qi
parent e0938223c4
commit 7f0e227d8a
6 changed files with 40 additions and 76 deletions

View File

@ -83,7 +83,7 @@ public:
bool isEmpty() const
{
return m_clipboard->getSelectionOwner(modeAtom) == XCB_NONE;
return m_clipboard->connection()->selectionOwner(modeAtom) == XCB_NONE;
}
protected:
@ -231,14 +231,15 @@ QXcbClipboard::QXcbClipboard(QXcbConnection *c)
m_clientClipboard[QClipboard::Selection] = nullptr;
m_timestamp[QClipboard::Clipboard] = XCB_CURRENT_TIME;
m_timestamp[QClipboard::Selection] = XCB_CURRENT_TIME;
m_owner = connection()->getQtSelectionOwner();
if (connection()->hasXFixes()) {
const uint32_t mask = XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER |
XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY |
XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE;
xcb_xfixes_select_selection_input_checked(xcb_connection(), m_owner, XCB_ATOM_PRIMARY, mask);
xcb_xfixes_select_selection_input_checked(xcb_connection(), m_owner, atom(QXcbAtom::CLIPBOARD), mask);
xcb_xfixes_select_selection_input_checked(xcb_connection(), connection()->qtSelectionOwner(),
XCB_ATOM_PRIMARY, mask);
xcb_xfixes_select_selection_input_checked(xcb_connection(), connection()->qtSelectionOwner(),
atom(QXcbAtom::CLIPBOARD), mask);
}
// xcb_change_property_request_t and xcb_get_property_request_t are the same size
@ -256,13 +257,16 @@ QXcbClipboard::~QXcbClipboard()
auto reply = Q_XCB_REPLY(xcb_get_selection_owner, xcb_connection(), atom(QXcbAtom::CLIPBOARD_MANAGER));
if (reply && reply->owner != XCB_NONE) {
// we delete the property so the manager saves all TARGETS.
xcb_delete_property(xcb_connection(), m_owner, atom(QXcbAtom::_QT_SELECTION));
xcb_convert_selection(xcb_connection(), m_owner, atom(QXcbAtom::CLIPBOARD_MANAGER), atom(QXcbAtom::SAVE_TARGETS),
xcb_delete_property(xcb_connection(), connection()->qtSelectionOwner(),
atom(QXcbAtom::_QT_SELECTION));
xcb_convert_selection(xcb_connection(), connection()->qtSelectionOwner(),
atom(QXcbAtom::CLIPBOARD_MANAGER), atom(QXcbAtom::SAVE_TARGETS),
atom(QXcbAtom::_QT_SELECTION), connection()->time());
connection()->sync();
// waiting until the clipboard manager fetches the content.
if (auto event = waitForClipboardEvent(m_owner, XCB_SELECTION_NOTIFY, true)) {
if (auto event = waitForClipboardEvent(connection()->qtSelectionOwner(),
XCB_SELECTION_NOTIFY, true)) {
free(event);
} else {
qCWarning(lcQpaClipboard, "QXcbClipboard: Unable to receive an event from the "
@ -289,11 +293,6 @@ bool QXcbClipboard::handlePropertyNotify(const xcb_generic_event_t *event)
return (*it)->updateIncrementalProperty(propertyNotify);
}
xcb_window_t QXcbClipboard::getSelectionOwner(xcb_atom_t atom) const
{
return connection()->getSelectionOwner(atom);
}
xcb_atom_t QXcbClipboard::atomForMode(QClipboard::Mode mode) const
{
if (mode == QClipboard::Clipboard)
@ -319,8 +318,8 @@ QMimeData * QXcbClipboard::mimeData(QClipboard::Mode mode)
if (mode > QClipboard::Selection)
return nullptr;
xcb_window_t clipboardOwner = getSelectionOwner(atomForMode(mode));
if (clipboardOwner == owner()) {
xcb_window_t clipboardOwner = connection()->selectionOwner(atomForMode(mode));
if (clipboardOwner == connection()->qtSelectionOwner()) {
return m_clientClipboard[mode];
} else {
if (!m_xClipboard[mode])
@ -362,7 +361,7 @@ void QXcbClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
connection()->setTime(connection()->getTimestamp());
if (data) {
newOwner = owner();
newOwner = connection()->qtSelectionOwner();
m_clientClipboard[mode] = data;
m_timestamp[mode] = connection()->time();
@ -370,7 +369,7 @@ void QXcbClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
xcb_set_selection_owner(xcb_connection(), newOwner, modeAtom, connection()->time());
if (getSelectionOwner(modeAtom) != newOwner) {
if (connection()->selectionOwner(modeAtom) != newOwner) {
qCWarning(lcQpaClipboard, "QXcbClipboard::setMimeData: Cannot set X11 selection owner");
}
@ -386,10 +385,11 @@ bool QXcbClipboard::supportsMode(QClipboard::Mode mode) const
bool QXcbClipboard::ownsMode(QClipboard::Mode mode) const
{
if (m_owner == XCB_NONE || mode > QClipboard::Selection)
if (connection()->qtSelectionOwner() == XCB_NONE || mode > QClipboard::Selection)
return false;
Q_ASSERT(m_timestamp[mode] == XCB_CURRENT_TIME || getSelectionOwner(atomForMode(mode)) == m_owner);
Q_ASSERT(m_timestamp[mode] == XCB_CURRENT_TIME
|| connection()->selectionOwner(atomForMode(mode)) == connection()->qtSelectionOwner());
return m_timestamp[mode] != XCB_CURRENT_TIME;
}
@ -438,11 +438,6 @@ void QXcbClipboard::setRequestor(xcb_window_t window)
m_requestor = window;
}
xcb_window_t QXcbClipboard::owner() const
{
return m_owner;
}
xcb_atom_t QXcbClipboard::sendTargetsSelection(QMimeData *d, xcb_window_t window, xcb_atom_t property)
{
QList<xcb_atom_t> types;
@ -521,7 +516,7 @@ void QXcbClipboard::handleSelectionClearRequest(xcb_selection_clear_event_t *eve
// XGetSelectionOwner(dpy, XA_PRIMARY),
// xevent->xselectionclear.time, d->timestamp);
xcb_window_t newOwner = getSelectionOwner(event->selection);
xcb_window_t newOwner = connection()->selectionOwner(event->selection);
/* If selection ownership was given up voluntarily from QClipboard::clear(), then we do nothing here
since its already handled in setMimeData. Otherwise, the event must have come from another client
@ -668,7 +663,7 @@ void QXcbClipboard::handleXFixesSelectionRequest(xcb_xfixes_selection_notify_eve
// Note1: Here we care only about the xfixes events that come from other processes.
// Note2: If the QClipboard::clear() is issued, event->owner is XCB_NONE,
// so we check selection_timestamp to not handle our own QClipboard::clear().
if (event->owner != owner() && event->selection_timestamp > m_timestamp[mode]) {
if (event->owner != connection()->qtSelectionOwner() && event->selection_timestamp > m_timestamp[mode]) {
if (!m_xClipboard[mode]) {
m_xClipboard[mode].reset(new QXcbClipboardMime(mode, this));
} else {

View File

@ -97,8 +97,6 @@ public:
xcb_window_t requestor() const;
void setRequestor(xcb_window_t window);
xcb_window_t owner() const;
void handleSelectionRequest(xcb_selection_request_event_t *event);
void handleSelectionClearRequest(xcb_selection_clear_event_t *event);
void handleXFixesSelectionRequest(xcb_xfixes_selection_notify_event_t *event);
@ -110,7 +108,6 @@ public:
bool handlePropertyNotify(const xcb_generic_event_t *event);
xcb_window_t getSelectionOwner(xcb_atom_t atom) const;
QByteArray getSelection(xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property, xcb_timestamp_t t = 0);
int increment() const { return m_maxPropertyRequestDataBytes; }
@ -133,7 +130,6 @@ private:
xcb_timestamp_t m_timestamp[2];
xcb_window_t m_requestor = XCB_NONE;
xcb_window_t m_owner = XCB_NONE;
static const int clipboard_timeout;

View File

@ -868,7 +868,7 @@ xcb_timestamp_t QXcbConnection::getTimestamp()
return timestamp;
}
xcb_window_t QXcbConnection::getSelectionOwner(xcb_atom_t atom) const
xcb_window_t QXcbConnection::selectionOwner(xcb_atom_t atom) const
{
auto reply = Q_XCB_REPLY(xcb_get_selection_owner, xcb_connection(), atom);
if (!reply) {
@ -879,7 +879,7 @@ xcb_window_t QXcbConnection::getSelectionOwner(xcb_atom_t atom) const
return reply->owner;
}
xcb_window_t QXcbConnection::getQtSelectionOwner()
xcb_window_t QXcbConnection::qtSelectionOwner()
{
if (!m_qtSelectionOwner) {
xcb_screen_t *xcbScreen = primaryVirtualDesktop()->screen();

View File

@ -191,8 +191,8 @@ public:
inline void setNetWmUserTime(xcb_timestamp_t t) { if (timeGreaterThan(t, m_netWmUserTime)) m_netWmUserTime = t; }
xcb_timestamp_t getTimestamp();
xcb_window_t getSelectionOwner(xcb_atom_t atom) const;
xcb_window_t getQtSelectionOwner();
xcb_window_t selectionOwner(xcb_atom_t atom) const;
xcb_window_t qtSelectionOwner();
void setButtonState(Qt::MouseButton button, bool down);
Qt::MouseButtons buttonState() const { return m_buttonState; }

View File

@ -174,11 +174,9 @@ void QXcbDrag::startDrag()
{
init();
#ifndef QT_NO_CLIPBOARD
qCDebug(lcQpaXDnd) << "starting drag where source:" << connection()->clipboard()->owner();
xcb_set_selection_owner(xcb_connection(), connection()->clipboard()->owner(),
qCDebug(lcQpaXDnd) << "starting drag where source:" << connection()->qtSelectionOwner();
xcb_set_selection_owner(xcb_connection(), connection()->qtSelectionOwner(),
atom(QXcbAtom::XdndSelection), connection()->time());
#endif
QStringList fmts = QXcbMime::formatsHelper(drag()->mimeData());
for (int i = 0; i < fmts.size(); ++i) {
@ -188,12 +186,11 @@ void QXcbDrag::startDrag()
drag_types.append(atoms.at(j));
}
}
#ifndef QT_NO_CLIPBOARD
if (drag_types.size() > 3)
xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, connection()->clipboard()->owner(),
xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, connection()->qtSelectionOwner(),
atom(QXcbAtom::XdndTypelist),
XCB_ATOM_ATOM, 32, drag_types.size(), (const void *)drag_types.constData());
#endif
setUseCompositing(current_virtual_desktop->compositingActive());
setScreen(current_virtual_desktop->screens().constFirst()->screen());
@ -444,11 +441,7 @@ void QXcbDrag::move(const QPoint &globalPos, Qt::MouseButtons b, Qt::KeyboardMod
enter.window = target;
enter.format = 32;
enter.type = atom(QXcbAtom::XdndEnter);
#ifndef QT_NO_CLIPBOARD
enter.data.data32[0] = connection()->clipboard()->owner();
#else
enter.data.data32[0] = 0;
#endif
enter.data.data32[0] = connection()->qtSelectionOwner();
enter.data.data32[1] = flags;
enter.data.data32[2] = drag_types.size() > 0 ? drag_types.at(0) : 0;
enter.data.data32[3] = drag_types.size() > 1 ? drag_types.at(1) : 0;
@ -479,11 +472,7 @@ void QXcbDrag::move(const QPoint &globalPos, Qt::MouseButtons b, Qt::KeyboardMod
move.window = target;
move.format = 32;
move.type = atom(QXcbAtom::XdndPosition);
#ifndef QT_NO_CLIPBOARD
move.data.data32[0] = connection()->clipboard()->owner();
#else
move.data.data32[0] = 0;
#endif
move.data.data32[0] = connection()->qtSelectionOwner();
move.data.data32[1] = 0; // flags
move.data.data32[2] = (globalPos.x() << 16) + globalPos.y();
move.data.data32[3] = connection()->time();
@ -529,11 +518,7 @@ void QXcbDrag::drop(const QPoint &globalPos, Qt::MouseButtons b, Qt::KeyboardMod
drop.window = current_target;
drop.format = 32;
drop.type = atom(QXcbAtom::XdndDrop);
#ifndef QT_NO_CLIPBOARD
drop.data.data32[0] = connection()->clipboard()->owner();
#else
drop.data.data32[0] = 0;
#endif
drop.data.data32[0] = connection()->qtSelectionOwner();
drop.data.data32[1] = 0; // flags
drop.data.data32[2] = connection()->time();
@ -640,7 +625,7 @@ void QXcbDrag::setActionList(Qt::DropAction requestedAction, Qt::DropActions sup
checkAppend(Qt::LinkAction);
if (current_actions != actions) {
xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, connection()->clipboard()->owner(),
xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, connection()->qtSelectionOwner(),
atom(QXcbAtom::XdndActionList),
XCB_ATOM_ATOM, 32, actions.size(), actions.constData());
current_actions = actions;
@ -861,11 +846,9 @@ void QXcbDrag::handle_xdnd_position(QPlatformWindow *w, const xcb_client_message
qCDebug(lcQpaXDnd) << "sending XdndStatus to source:" << xdnd_dragsource;
#ifndef QT_NO_CLIPBOARD
if (xdnd_dragsource == connection()->clipboard()->owner())
if (xdnd_dragsource == connection()->qtSelectionOwner())
handle_xdnd_status(&response);
else
#endif
xcb_send_event(xcb_connection(), false, current_proxy_target,
XCB_EVENT_MASK_NO_EVENT, (const char *)&response);
}
@ -931,11 +914,7 @@ void QXcbDrag::handle_xdnd_status(const xcb_client_message_event_t *event)
void QXcbDrag::handleStatus(const xcb_client_message_event_t *event)
{
if (
#ifndef QT_NO_CLIPBOARD
event->window != connection()->clipboard()->owner() ||
#endif
!drag())
if (event->window != connection()->qtSelectionOwner() || !drag())
return;
xcb_client_message_event_t *lastEvent = const_cast<xcb_client_message_event_t *>(event);
@ -992,11 +971,7 @@ void QXcbDrag::send_leave()
leave.window = current_target;
leave.format = 32;
leave.type = atom(QXcbAtom::XdndLeave);
#ifndef QT_NO_CLIPBOARD
leave.data.data32[0] = connection()->clipboard()->owner();
#else
leave.data.data32[0] = 0;
#endif
leave.data.data32[0] = connection()->qtSelectionOwner();
leave.data.data32[1] = 0; // flags
leave.data.data32[2] = 0; // x, y
leave.data.data32[3] = 0; // w, h
@ -1091,10 +1066,8 @@ void QXcbDrag::handleFinished(const xcb_client_message_event_t *event)
// Source receives XdndFinished when target is done processing the drop data.
qCDebug(lcQpaXDnd) << "source:" << event->window << "received XdndFinished";
#ifndef QT_NO_CLIPBOARD
if (event->window != connection()->clipboard()->owner())
if (event->window != connection()->qtSelectionOwner())
return;
#endif
const unsigned long *l = (const unsigned long *)event->data.data32;
if (l[0]) {
@ -1369,7 +1342,7 @@ QVariant QXcbDropData::xdndObtainData(const QByteArray &format, QMetaType reques
return result;
#ifndef QT_NO_CLIPBOARD
if (c->clipboard()->getSelectionOwner(drag->atom(QXcbAtom::XdndSelection)) == XCB_NONE)
if (c->selectionOwner(c->atom(QXcbAtom::XdndSelection)) == XCB_NONE)
return result; // should never happen?
xcb_atom_t xdnd_selection = c->atom(QXcbAtom::XdndSelection);

View File

@ -62,7 +62,7 @@ QXcbVirtualDesktop::QXcbVirtualDesktop(QXcbConnection *connection, xcb_screen_t
{
const QByteArray cmAtomName = "_NET_WM_CM_S" + QByteArray::number(m_number);
m_net_wm_cm_atom = connection->internAtom(cmAtomName.constData());
m_compositingActive = connection->getSelectionOwner(m_net_wm_cm_atom);
m_compositingActive = connection->selectionOwner(m_net_wm_cm_atom);
m_workArea = getWorkArea();
@ -177,7 +177,7 @@ bool QXcbVirtualDesktop::compositingActive() const
if (connection()->hasXFixes())
return m_compositingActive;
else
return connection()->getSelectionOwner(m_net_wm_cm_atom);
return connection()->selectionOwner(m_net_wm_cm_atom);
}
void QXcbVirtualDesktop::handleXFixesSelectionNotify(xcb_xfixes_selection_notify_event_t *notify_event)
@ -192,7 +192,7 @@ void QXcbVirtualDesktop::subscribeToXFixesSelectionNotify()
const uint32_t mask = XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER |
XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY |
XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE;
xcb_xfixes_select_selection_input_checked(xcb_connection(), connection()->getQtSelectionOwner(), m_net_wm_cm_atom, mask);
xcb_xfixes_select_selection_input_checked(xcb_connection(), connection()->qtSelectionOwner(), m_net_wm_cm_atom, mask);
}
}