Support mulitple data devices on a single client
Summary: Firefox has two wl_data_devices. One in firefox code one in GTK code. Both need to get data offers. I've left handling the case for multiple data devices and drags to make this patch feasible to put into 5.19 and I didn't want to make this patch invasive. Test Plan: Firefox in wayland WAYLAND_DEBUG=1 firefox |& grep data Shows now both created devices get offers Also I can paste Reviewers: #kwin, zzag Reviewed By: #kwin, zzag Subscribers: ngraham, zzag Differential Revision: https://phabricator.kde.org/D29720
This commit is contained in:
parent
7c7d9a117b
commit
9454421ff7
2 changed files with 31 additions and 23 deletions
|
@ -236,9 +236,9 @@ QVector<TouchInterface *> SeatInterface::Private::touchsForSurface(SurfaceInterf
|
|||
return interfacesForSurface(surface, touchs);
|
||||
}
|
||||
|
||||
DataDeviceInterface *SeatInterface::Private::dataDeviceForSurface(SurfaceInterface *surface) const
|
||||
QVector<DataDeviceInterface *> SeatInterface::Private::dataDevicesForSurface(SurfaceInterface *surface) const
|
||||
{
|
||||
return interfaceForSurface(surface, dataDevices);
|
||||
return interfacesForSurface(surface, dataDevices);
|
||||
}
|
||||
|
||||
TextInputInterface *SeatInterface::Private::textInputForSurface(SurfaceInterface *surface) const
|
||||
|
@ -252,15 +252,14 @@ void SeatInterface::Private::registerDataDevice(DataDeviceInterface *dataDevice)
|
|||
dataDevices << dataDevice;
|
||||
auto dataDeviceCleanup = [this, dataDevice] {
|
||||
dataDevices.removeOne(dataDevice);
|
||||
if (keys.focus.selection == dataDevice) {
|
||||
keys.focus.selection = nullptr;
|
||||
}
|
||||
keys.focus.selections.removeOne(dataDevice);
|
||||
|
||||
if (currentSelection == dataDevice) {
|
||||
// current selection is cleared
|
||||
currentSelection = nullptr;
|
||||
emit q->selectionChanged(nullptr);
|
||||
if (keys.focus.selection) {
|
||||
keys.focus.selection->sendClearSelection();
|
||||
for (auto selection: keys.focus.selections) {
|
||||
selection->sendClearSelection();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -328,10 +327,10 @@ void SeatInterface::Private::registerDataDevice(DataDeviceInterface *dataDevice)
|
|||
}
|
||||
);
|
||||
// is the new DataDevice for the current keyoard focus?
|
||||
if (keys.focus.surface && !keys.focus.selection) {
|
||||
if (keys.focus.surface) {
|
||||
// same client?
|
||||
if (keys.focus.surface->client() == dataDevice->client()) {
|
||||
keys.focus.selection = dataDevice;
|
||||
keys.focus.selections.append(dataDevice);
|
||||
if (currentSelection && currentSelection->selection()) {
|
||||
dataDevice->sendSelection(currentSelection);
|
||||
}
|
||||
|
@ -408,11 +407,11 @@ void SeatInterface::Private::updateSelection(DataDeviceInterface *dataDevice, bo
|
|||
}
|
||||
if (dataDevice == currentSelection) {
|
||||
// need to send out the selection
|
||||
if (keys.focus.selection) {
|
||||
for (auto focussedDevice: qAsConst(keys.focus.selections)) {
|
||||
if (set) {
|
||||
keys.focus.selection->sendSelection(dataDevice);
|
||||
focussedDevice->sendSelection(dataDevice);
|
||||
} else {
|
||||
keys.focus.selection->sendClearSelection();
|
||||
focussedDevice->sendClearSelection();
|
||||
currentSelection = nullptr;
|
||||
selChanged = true;
|
||||
}
|
||||
|
@ -648,7 +647,15 @@ void SeatInterface::setDragTarget(SurfaceInterface *surface, const QPointF &glob
|
|||
if (d->drag.target) {
|
||||
d->drag.target->updateDragTarget(nullptr, serial);
|
||||
}
|
||||
d->drag.target = d->dataDeviceForSurface(surface);
|
||||
|
||||
// technically we can have mulitple data devices
|
||||
// and we should send the drag to all of them, but that seems overly complicated
|
||||
// in practice so far the only case for mulitple data devices is for clipboard overriding
|
||||
d->drag.target = nullptr;
|
||||
if (d->dataDevicesForSurface(surface).size() > 0) {
|
||||
d->drag.target = d->dataDevicesForSurface(surface).first();
|
||||
}
|
||||
|
||||
if (d->drag.mode == Private::Drag::Mode::Pointer) {
|
||||
setPointerPos(globalPosition);
|
||||
} else if (d->drag.mode == Private::Drag::Mode::Touch &&
|
||||
|
@ -1128,12 +1135,13 @@ void SeatInterface::setFocusedKeyboardSurface(SurfaceInterface *surface)
|
|||
);
|
||||
d->keys.focus.serial = serial;
|
||||
// selection?
|
||||
d->keys.focus.selection = d->dataDeviceForSurface(surface);
|
||||
if (d->keys.focus.selection) {
|
||||
if (d->currentSelection && d->currentSelection->selection()) {
|
||||
d->keys.focus.selection->sendSelection(d->currentSelection);
|
||||
const QVector<DataDeviceInterface *> dataDevices = d->dataDevicesForSurface(surface);
|
||||
d->keys.focus.selections = dataDevices;
|
||||
for (auto dataDevice : dataDevices) {
|
||||
if (d->currentSelection) {
|
||||
dataDevice->sendSelection(d->currentSelection);
|
||||
} else {
|
||||
d->keys.focus.selection->sendClearSelection();
|
||||
dataDevice->sendClearSelection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1602,11 +1610,11 @@ void SeatInterface::setSelection(DataDeviceInterface *dataDevice)
|
|||
// cancel the previous selection
|
||||
d->cancelPreviousSelection(dataDevice);
|
||||
d->currentSelection = dataDevice;
|
||||
if (d->keys.focus.selection) {
|
||||
for (auto focussedDevice: qAsConst(d->keys.focus.selections)) {
|
||||
if (dataDevice && dataDevice->selection()) {
|
||||
d->keys.focus.selection->sendSelection(dataDevice);
|
||||
focussedDevice->sendSelection(dataDevice);
|
||||
} else {
|
||||
d->keys.focus.selection->sendClearSelection();
|
||||
focussedDevice->sendClearSelection();
|
||||
}
|
||||
}
|
||||
emit selectionChanged(dataDevice);
|
||||
|
|
|
@ -32,7 +32,7 @@ public:
|
|||
QVector<PointerInterface *> pointersForSurface(SurfaceInterface *surface) const;
|
||||
QVector<KeyboardInterface *> keyboardsForSurface(SurfaceInterface *surface) const;
|
||||
QVector<TouchInterface *> touchsForSurface(SurfaceInterface *surface) const;
|
||||
DataDeviceInterface *dataDeviceForSurface(SurfaceInterface *surface) const;
|
||||
QVector<DataDeviceInterface *> dataDevicesForSurface(SurfaceInterface *surface) const;
|
||||
TextInputInterface *textInputForSurface(SurfaceInterface *surface) const;
|
||||
void registerDataDevice(DataDeviceInterface *dataDevice);
|
||||
void registerTextInput(TextInputInterface *textInput);
|
||||
|
@ -101,7 +101,7 @@ public:
|
|||
QVector<KeyboardInterface*> keyboards;
|
||||
QMetaObject::Connection destroyConnection;
|
||||
quint32 serial = 0;
|
||||
DataDeviceInterface *selection = nullptr;
|
||||
QVector<DataDeviceInterface *> selections;
|
||||
};
|
||||
Focus focus;
|
||||
quint32 lastStateSerial = 0;
|
||||
|
|
Loading…
Reference in a new issue