fix(wayland): release portal input capture when EI_EVENT_DISCONNECT is encountered, refactoring

Fixes #8005.
This commit is contained in:
Dustin Kaiser 2025-04-17 21:57:47 +02:00 committed by Nick Bolton
parent 6194868e89
commit 2192636d2b

View file

@ -145,7 +145,7 @@ void EiScreen::cleanup_ei()
ei_device_set_user_data(ei_abs_, nullptr); ei_device_set_user_data(ei_abs_, nullptr);
ei_abs_ = ei_device_unref(ei_abs_); 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++) { for (auto it = ei_devices_.begin(); it != ei_devices_.end(); it++) {
free(ei_device_get_user_data(*it)); free(ei_device_get_user_data(*it));
ei_device_set_user_data(*it, nullptr); 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 *) void EiScreen::handleSystemEvent(const Event &sysevent, void *)
{ {
std::lock_guard lock(mutex_); std::lock_guard lock(mutex_);
bool disconnected = false;
// Only one ei_dispatch per system event, see the comment in // Only one ei_dispatch per system event, see the comment in
// EiEventQueueBuffer::addEvent // 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 // 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. // 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 // We must release the xdg-portal InputCapture in case it is still active
// handle the rest. // so that the cursor is usable and not stuck on the deskflow server.
LOG_WARN("disconnected from eis"); LOG_WARN("disconnected from eis, will afterwards commence attempt to reconnect");
disconnected = true; 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; break;
case EI_EVENT_DEVICE_PAUSED: case EI_EVENT_DEVICE_PAUSED:
LOG_DEBUG("device %s is paused", ei_device_get_name(device)); 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); ei_event_unref(event);
} }
if (disconnected)
ei_ = ei_unref(ei_);
} }
void EiScreen::updateButtons() void EiScreen::updateButtons()