Skip to content

Commit

Permalink
xwayland: improve dnd and cleanup (#9405)
Browse files Browse the repository at this point in the history
Minor changes to xwayland dnd / regular dnd to fix various issues

---------

Co-authored-by: Vaxry <vaxry@vaxry.net>
  • Loading branch information
nnyyxxxx and vaxerski authored Feb 24, 2025
1 parent e594646 commit 3458d7a
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 95 deletions.
62 changes: 37 additions & 25 deletions src/protocols/core/DataDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "../../managers/HookSystemManager.hpp"
#include "../../helpers/Monitor.hpp"
#include "../../render/Renderer.hpp"
#include "../../xwayland/Dnd.hpp"
using namespace Hyprutils::OS;

CWLDataOfferResource::CWLDataOfferResource(SP<CWlDataOffer> resource_, SP<IDataSource> source_) : source(source_), resource(resource_) {
Expand Down Expand Up @@ -689,14 +690,24 @@ void CWLDataDeviceProtocol::updateDrag() {
g_pSeatManager->state.dndPointerFocus->current.size / 2.F, offer);
}

void CWLDataDeviceProtocol::resetDndState() {
void CWLDataDeviceProtocol::cleanupDndState(bool resetDevice, bool resetSource, bool simulateInput) {
dnd.dndSurface.reset();
dnd.dndSurfaceCommit.reset();
dnd.dndSurfaceDestroy.reset();
dnd.mouseButton.reset();
dnd.mouseMove.reset();
dnd.touchUp.reset();
dnd.touchMove.reset();

if (resetDevice)
dnd.focusedDevice.reset();
if (resetSource)
dnd.currentSource.reset();

if (simulateInput) {
g_pInputManager->simulateMouseMovement();
g_pSeatManager->resendEnterEvents();
}
}

void CWLDataDeviceProtocol::dropDrag() {
Expand All @@ -712,47 +723,46 @@ void CWLDataDeviceProtocol::dropDrag() {
}

dnd.focusedDevice->sendDrop();
dnd.focusedDevice->sendLeave();

resetDndState();
#ifndef NO_XWAYLAND
if (dnd.focusedDevice->getX11()) {
dnd.focusedDevice->sendLeave();
if (dnd.overriddenCursor)
g_pInputManager->unsetCursorImage();
dnd.overriddenCursor = false;
cleanupDndState(true, true, true);
return;
}
#endif

dnd.focusedDevice->sendLeave();
if (dnd.overriddenCursor)
g_pInputManager->unsetCursorImage();
dnd.overriddenCursor = false;
cleanupDndState(false, false, false);
}

bool CWLDataDeviceProtocol::wasDragSuccessful() {
if (!dnd.focusedDevice || !dnd.currentSource)
if (!dnd.currentSource)
return false;

for (auto const& o : m_vOffers) {
if (o->dead || !o->source || !o->source->hasDnd())
if (o->dead || o->source != dnd.currentSource)
continue;

if (o->recvd || o->accepted)
return true;
}

#ifndef NO_XWAYLAND
if (g_pXWayland->pWM) {
for (auto const& o : g_pXWayland->pWM->dndDataOffers) {
if (o->dead || !o->source || !o->source->hasDnd())
continue;

if (o->source != dnd.currentSource)
continue;

return true;
}
}
if (dnd.focusedDevice->getX11())
return true;
#endif

return false;
}

void CWLDataDeviceProtocol::completeDrag() {
resetDndState();

if (!dnd.focusedDevice && !dnd.currentSource)
return;

Expand All @@ -761,15 +771,11 @@ void CWLDataDeviceProtocol::completeDrag() {
dnd.currentSource->sendDndFinished();
}

dnd.focusedDevice.reset();
dnd.currentSource.reset();

g_pInputManager->simulateMouseMovement();
g_pSeatManager->resendEnterEvents();
cleanupDndState(true, true, true);
}

void CWLDataDeviceProtocol::abortDrag() {
resetDndState();
cleanupDndState(false, false, false);

if (dnd.overriddenCursor)
g_pInputManager->unsetCursorImage();
Expand All @@ -778,8 +784,14 @@ void CWLDataDeviceProtocol::abortDrag() {
if (!dnd.focusedDevice && !dnd.currentSource)
return;

if (dnd.focusedDevice)
if (dnd.focusedDevice) {
#ifndef NO_XWAYLAND
if (auto x11Device = dnd.focusedDevice->getX11(); x11Device)
x11Device->forceCleanupDnd();
#endif
dnd.focusedDevice->sendLeave();
}

if (dnd.currentSource)
dnd.currentSource->cancelled();

Expand Down
2 changes: 1 addition & 1 deletion src/protocols/core/DataDevice.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ class CWLDataDeviceProtocol : public IWaylandProtocol {
void updateDrag();
void dropDrag();
void completeDrag();
void resetDndState();
void cleanupDndState(bool resetDevice, bool resetSource, bool simulateInput);
bool wasDragSuccessful();

//
Expand Down
Loading

0 comments on commit 3458d7a

Please sign in to comment.