fix drag and drop raise with Xwayland windows

They shouldn't be raised immediately. The same strategy as with
Wayland native clients should be used.

BUG: 440534
This commit is contained in:
Xaver Hugl 2021-08-29 17:08:43 +02:00
parent f4d63bb8ed
commit 42b516b567
3 changed files with 15 additions and 16 deletions

View file

@ -1953,6 +1953,20 @@ public:
const auto eventPos = event->globalPos(); const auto eventPos = event->globalPos();
// TODO: use InputDeviceHandler::at() here and check isClient()? // TODO: use InputDeviceHandler::at() here and check isClient()?
Toplevel *t = input()->findManagedToplevel(eventPos); Toplevel *t = input()->findManagedToplevel(eventPos);
const auto dragTarget = qobject_cast<AbstractClient*>(t);
if (dragTarget) {
if (dragTarget != m_dragTarget) {
workspace()->takeActivity(dragTarget, Workspace::ActivityFlag::ActivityFocus);
m_raiseTimer.start();
}
if ((pos - m_lastPos).manhattanLength() > 10) {
m_lastPos = pos;
// reset timer to delay raising the window
m_raiseTimer.start();
}
}
m_dragTarget = dragTarget;
if (auto *xwl = xwayland()) { if (auto *xwl = xwayland()) {
const auto ret = xwl->dragMoveFilter(t, eventPos); const auto ret = xwl->dragMoveFilter(t, eventPos);
if (ret == Xwl::DragEventReply::Ignore) { if (ret == Xwl::DragEventReply::Ignore) {
@ -1965,17 +1979,8 @@ public:
if (t) { if (t) {
// TODO: consider decorations // TODO: consider decorations
if (t->surface() != seat->dragSurface()) { if (t->surface() != seat->dragSurface()) {
if ((m_dragTarget = qobject_cast<AbstractClient*>(t))) {
workspace()->takeActivity(m_dragTarget, Workspace::ActivityFlag::ActivityFocus);
m_raiseTimer.start();
}
seat->setDragTarget(t->surface(), t->inputTransformation()); seat->setDragTarget(t->surface(), t->inputTransformation());
} }
if ((pos - m_lastPos).manhattanLength() > 10) {
m_lastPos = pos;
// reset timer to delay raising the window
m_raiseTimer.start();
}
} else { } else {
// no window at that place, if we have a surface we need to reset // no window at that place, if we have a surface we need to reset
seat->setDragTarget(nullptr); seat->setDragTarget(nullptr);
@ -1989,6 +1994,7 @@ public:
break; break;
case QEvent::MouseButtonRelease: case QEvent::MouseButtonRelease:
raiseDragTarget(); raiseDragTarget();
m_dragTarget = nullptr;
seat->notifyPointerButton(nativeButton, KWaylandServer::PointerButtonState::Released); seat->notifyPointerButton(nativeButton, KWaylandServer::PointerButtonState::Released);
seat->notifyPointerFrame(); seat->notifyPointerFrame();
break; break;

View file

@ -87,7 +87,6 @@ DragEventReply WlToXDrag::moveFilter(Toplevel *target, const QPoint &pos)
return DragEventReply::Wayland; return DragEventReply::Wayland;
} }
// new target // new target
workspace()->activateClient(ac, false);
seat->setDragTarget(DataBridge::self()->dnd()->surfaceIface(), pos, ac->inputTransformation()); seat->setDragTarget(DataBridge::self()->dnd()->surfaceIface(), pos, ac->inputTransformation());
m_visit = new Xvisit(this, ac); m_visit = new Xvisit(this, ac);
return DragEventReply::Take; return DragEventReply::Take;

View file

@ -191,11 +191,6 @@ DragEventReply XToWlDrag::moveFilter(Toplevel *target, const QPoint &pos)
target->surface()->client() == waylandServer()->xWaylandConnection()) { target->surface()->client() == waylandServer()->xWaylandConnection()) {
// currently there is no target or target is an Xwayland window // currently there is no target or target is an Xwayland window
// handled here and by X directly // handled here and by X directly
if (AbstractClient *ac = qobject_cast<AbstractClient*>(target)) {
if (workspace()->activeClient() != ac) {
workspace()->activateClient(ac);
}
}
if (hasCurrent) { if (hasCurrent) {
// last received enter event is now void, // last received enter event is now void,
// wait for the next one // wait for the next one
@ -277,7 +272,6 @@ void XToWlDrag::offerCallback(const QString &mime)
void XToWlDrag::setDragTarget() void XToWlDrag::setDragTarget()
{ {
auto *ac = m_visit->target(); auto *ac = m_visit->target();
workspace()->activateClient(ac);
waylandServer()->seat()->setDragTarget(ac->surface(), ac->inputTransformation()); waylandServer()->seat()->setDragTarget(ac->surface(), ac->inputTransformation());
} }