@@ -6166,9 +6166,7 @@ void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
61666166
61676167 bool restartEvent;
61686168 if (dispatchEntry->eventEntry ->type == EventEntry::Type::KEY) {
6169- KeyEntry& keyEntry = static_cast <KeyEntry&>(*(dispatchEntry->eventEntry ));
6170- restartEvent =
6171- afterKeyEventLockedInterruptable (connection, dispatchEntry, keyEntry, handled);
6169+ restartEvent = afterKeyEventLockedInterruptable (connection, dispatchEntry, handled);
61726170 } else if (dispatchEntry->eventEntry ->type == EventEntry::Type::MOTION) {
61736171 MotionEntry& motionEntry = static_cast <MotionEntry&>(*(dispatchEntry->eventEntry ));
61746172 restartEvent = afterMotionEventLockedInterruptable (connection, dispatchEntry, motionEntry,
@@ -6386,8 +6384,17 @@ void InputDispatcher::processConnectionResponsiveLocked(const Connection& connec
63866384}
63876385
63886386bool InputDispatcher::afterKeyEventLockedInterruptable (
6389- const std::shared_ptr<Connection>& connection, DispatchEntry* dispatchEntry,
6390- KeyEntry& keyEntry, bool handled) {
6387+ const std::shared_ptr<Connection>& connection, DispatchEntry* dispatchEntry, bool handled) {
6388+ // The dispatchEntry is currently valid, but it might point to a deleted object after we release
6389+ // the lock. For simplicity, make copies of the data of interest here and assume that
6390+ // 'dispatchEntry' is not valid after this section.
6391+ // Hold a strong reference to the EventEntry to ensure it's valid for the duration of this
6392+ // function, even if the DispatchEntry gets destroyed and releases its share of the ownership.
6393+ std::shared_ptr<EventEntry> eventEntry = dispatchEntry->eventEntry ;
6394+ const bool hasForegroundTarget = dispatchEntry->hasForegroundTarget ();
6395+ KeyEntry& keyEntry = static_cast <KeyEntry&>(*(eventEntry));
6396+ // To prevent misuse, ensure dispatchEntry is no longer valid.
6397+ dispatchEntry = nullptr ;
63916398 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
63926399 if (!handled) {
63936400 // Report the key as unhandled, since the fallback was not handled.
@@ -6404,7 +6411,7 @@ bool InputDispatcher::afterKeyEventLockedInterruptable(
64046411 connection->inputState .removeFallbackKey (originalKeyCode);
64056412 }
64066413
6407- if (handled || !dispatchEntry-> hasForegroundTarget () ) {
6414+ if (handled || !hasForegroundTarget) {
64086415 // If the application handles the original key for which we previously
64096416 // generated a fallback or if the window is not a foreground window,
64106417 // then cancel the associated fallback key, if any.
0 commit comments