Skip to content

Commit

Permalink
inputhook: improve CTRL+C handling
Browse files Browse the repository at this point in the history
Allow a first CTRL+C to interrupt the qt4 event loop
and a second to trigger a KeyboardInterrupt.
  • Loading branch information
cboos committed Sep 23, 2011
1 parent 6d5890c commit 0dd489f
Showing 1 changed file with 21 additions and 4 deletions.
25 changes: 21 additions & 4 deletions IPython/lib/inputhook.py
Expand Up @@ -198,18 +198,35 @@ def enable_qt4(self, app=None):
app = QtGui.QApplication(sys.argv)
"""
from IPython.external.qt_for_kernel import QtCore, QtGui
from IPython.core import ipapi

if app is None:
app = QtCore.QCoreApplication.instance()
if app is None:
app = QtGui.QApplication([" "])

# Always use the following input hook instead of PyQt4's
# default one, as it interacts better with readline packages
# (issue #481)
# Always use a custom input hook instead of PyQt4's default
# one, as it interacts better with readline packages (issue
# #481).

# Note that we can't let KeyboardInterrupt escape from that
# hook, (no exception can't be raised from within a ctypes
# python callback). We need to make a compromise: a trapped
# KeyboardInterrupt will prevent the input hook to re-enter
# the exec loop, until we start over with a new prompt line.
# This means one needs a double CTRL+C to get back to the
# prompt.

got_kbdint = [False]

def preprompthook_qt4(self):
got_kbdint[0] = False
ipapi.get().set_hook('pre_prompt_hook', preprompthook_qt4)

def inputhook_qt4():
try:
if got_kbdint[0]:
return 0
app.processEvents(QtCore.QEventLoop.AllEvents, 300)
if not stdin_ready():
timer = QtCore.QTimer()
Expand All @@ -219,7 +236,7 @@ def inputhook_qt4():
app.exec_()
timer.stop()
except KeyboardInterrupt:
pass
got_kbdint[0] = True
return 0
self.set_inputhook(inputhook_qt4)

Expand Down

0 comments on commit 0dd489f

Please sign in to comment.