@@ -6100,9 +6100,7 @@ void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
61006100
61016101 bool restartEvent;
61026102 if (dispatchEntry->eventEntry ->type == EventEntry::Type::KEY) {
6103- KeyEntry& keyEntry = static_cast <KeyEntry&>(*(dispatchEntry->eventEntry ));
6104- restartEvent =
6105- afterKeyEventLockedInterruptable (connection, dispatchEntry, keyEntry, handled);
6103+ restartEvent = afterKeyEventLockedInterruptable (connection, dispatchEntry, handled);
61066104 } else if (dispatchEntry->eventEntry ->type == EventEntry::Type::MOTION) {
61076105 MotionEntry& motionEntry = static_cast <MotionEntry&>(*(dispatchEntry->eventEntry ));
61086106 restartEvent = afterMotionEventLockedInterruptable (connection, dispatchEntry, motionEntry,
@@ -6320,8 +6318,17 @@ void InputDispatcher::processConnectionResponsiveLocked(const Connection& connec
63206318}
63216319
63226320bool InputDispatcher::afterKeyEventLockedInterruptable (
6323- const std::shared_ptr<Connection>& connection, DispatchEntry* dispatchEntry,
6324- KeyEntry& keyEntry, bool handled) {
6321+ const std::shared_ptr<Connection>& connection, DispatchEntry* dispatchEntry, bool handled) {
6322+ // The dispatchEntry is currently valid, but it might point to a deleted object after we release
6323+ // the lock. For simplicity, make copies of the data of interest here and assume that
6324+ // 'dispatchEntry' is not valid after this section.
6325+ // Hold a strong reference to the EventEntry to ensure it's valid for the duration of this
6326+ // function, even if the DispatchEntry gets destroyed and releases its share of the ownership.
6327+ std::shared_ptr<EventEntry> eventEntry = dispatchEntry->eventEntry ;
6328+ const bool hasForegroundTarget = dispatchEntry->hasForegroundTarget ();
6329+ KeyEntry& keyEntry = static_cast <KeyEntry&>(*(eventEntry));
6330+ // To prevent misuse, ensure dispatchEntry is no longer valid.
6331+ dispatchEntry = nullptr ;
63256332 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
63266333 if (!handled) {
63276334 // Report the key as unhandled, since the fallback was not handled.
@@ -6338,7 +6345,7 @@ bool InputDispatcher::afterKeyEventLockedInterruptable(
63386345 connection->inputState .removeFallbackKey (originalKeyCode);
63396346 }
63406347
6341- if (handled || !dispatchEntry-> hasForegroundTarget () ) {
6348+ if (handled || !hasForegroundTarget) {
63426349 // If the application handles the original key for which we previously
63436350 // generated a fallback or if the window is not a foreground window,
63446351 // then cancel the associated fallback key, if any.
0 commit comments