From c01ab8aa2a7e2b2deefea34950650daf57030673 Mon Sep 17 00:00:00 2001 From: Filip Wieladek Date: Sat, 17 Jan 2015 15:31:29 +0100 Subject: [PATCH] Fix the infinite event recursion in the klipper popup. Klipper crashes when any modifier key (with the exception of ALT) is pressed. This is because it enters into an infinite recursion. This happens because Klipper popup delegates all events to its input field. The input field does not consume the event, so it is propagated to the parent widget, which is the popup. The popup tries to send the event to the input field again. Since klipper is now part of plasma, this bug kills the entire shell REVIEW: 122106 BUG: 342947 --- klipper/klipperpopup.cpp | 15 +++++++++++++-- klipper/klipperpopup.h | 5 +++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/klipper/klipperpopup.cpp b/klipper/klipperpopup.cpp index 56c6421b3..0b2f11d6d 100644 --- a/klipper/klipperpopup.cpp +++ b/klipper/klipperpopup.cpp @@ -75,7 +75,8 @@ KlipperPopup::KlipperPopup( History* history ) m_filterWidget( 0 ), m_filterWidgetAction( 0 ), m_nHistoryItems( 0 ), - m_showHelp(true) + m_showHelp(true), + m_lastEvent(NULL) { ensurePolished(); KWindowInfo windowInfo( winId(), NET::WMGeometry ); @@ -181,6 +182,15 @@ void KlipperPopup::plugAction( QAction* action ) { /* virtual */ void KlipperPopup::keyPressEvent( QKeyEvent* e ) { + // Most events are send down directly to the m_filterWidget. + // If the m_filterWidget does not handle the event, it will + // come back to this method. Remembering the last event stops + // the infinite event loop + if (m_lastEvent == e) { + m_lastEvent= NULL; + return; + } + m_lastEvent= e; // If alt-something is pressed, select a shortcut // from the menu. Do this by sending a keyPress // without the alt-modifier to the superobject. @@ -240,8 +250,8 @@ void KlipperPopup::keyPressEvent( QKeyEvent* e ) { #endif setActiveAction(actions().at(actions().indexOf(m_filterWidgetAction))); QString lastString = m_filterWidget->text(); - QApplication::sendEvent(m_filterWidget, e); + QApplication::sendEvent(m_filterWidget, e); if (m_filterWidget->text() != lastString) { m_dirty = true; rebuild(m_filterWidget->text()); @@ -250,6 +260,7 @@ void KlipperPopup::keyPressEvent( QKeyEvent* e ) { break; } //default: } //case + m_lastEvent= NULL; } diff --git a/klipper/klipperpopup.h b/klipper/klipperpopup.h index 4e03714fb..6f7b30747 100644 --- a/klipper/klipperpopup.h +++ b/klipper/klipperpopup.h @@ -125,6 +125,11 @@ private: bool m_showHelp; + /** + * The last event which was received. Used to avoid an infinite event loop + */ + QKeyEvent* m_lastEvent; + }; #endif