From 2192636d2ba98833230cc5c1f822d62650d97da7 Mon Sep 17 00:00:00 2001 From: Dustin Kaiser <8209087+mrnicegyu11@users.noreply.github.com> Date: Thu, 17 Apr 2025 21:57:47 +0200 Subject: [PATCH] fix(wayland): release portal input capture when EI_EVENT_DISCONNECT is encountered, refactoring Fixes #8005. --- src/lib/platform/EiScreen.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/lib/platform/EiScreen.cpp b/src/lib/platform/EiScreen.cpp index 3a7ad2f8d..c1ea6df50 100644 --- a/src/lib/platform/EiScreen.cpp +++ b/src/lib/platform/EiScreen.cpp @@ -145,7 +145,7 @@ void EiScreen::cleanup_ei() ei_device_set_user_data(ei_abs_, nullptr); ei_abs_ = ei_device_unref(ei_abs_); } - ei_seat_unref(ei_seat_); + ei_seat_ = ei_seat_unref(ei_seat_); for (auto it = ei_devices_.begin(); it != ei_devices_.end(); it++) { free(ei_device_get_user_data(*it)); ei_device_set_user_data(*it, nullptr); @@ -721,7 +721,6 @@ void EiScreen::handle_portal_session_closed(const Event &event, void *) void EiScreen::handleSystemEvent(const Event &sysevent, void *) { std::lock_guard lock(mutex_); - bool disconnected = false; // Only one ei_dispatch per system event, see the comment in // EiEventQueueBuffer::addEvent @@ -767,10 +766,20 @@ void EiScreen::handleSystemEvent(const Event &sysevent, void *) // We're using libei which emulates the various seat/device remove events // so by the time we get here our EiScreen should be in a neutral state. // - // We don't do anything here, we let the portal's Session.Closed signal - // handle the rest. - LOG_WARN("disconnected from eis"); - disconnected = true; + // We must release the xdg-portal InputCapture in case it is still active + // so that the cursor is usable and not stuck on the deskflow server. + LOG_WARN("disconnected from eis, will afterwards commence attempt to reconnect"); + if (is_primary_) { + LOG_DEBUG("re-allocating portal input capture connection and releasing active captures"); + if (portal_input_capture_) { + if (portal_input_capture_->is_active()) { + portal_input_capture_->release(); + } + delete portal_input_capture_; + portal_input_capture_ = new PortalInputCapture(this, this->events_); + } + } + this->handle_portal_session_closed(sysevent, nullptr); break; case EI_EVENT_DEVICE_PAUSED: LOG_DEBUG("device %s is paused", ei_device_get_name(device)); @@ -826,9 +835,6 @@ void EiScreen::handleSystemEvent(const Event &sysevent, void *) } ei_event_unref(event); } - - if (disconnected) - ei_ = ei_unref(ei_); } void EiScreen::updateButtons()