various key handling fixes

- key presses while a webview is focused no longer make it to the
main window's keyPressEvent() routine, so AnkiWebView now uses its
event filter to pass the key events to the main window
- move the shared key handling out of keyPressEvent into
globalKeyHandler()
- make sure all key handling routines return true or false to
indicate if an event was handled or not
- remove focus when esc hit in the main window, to retain old
behaviour of allowing esc to clear focus from the type answer box
This commit is contained in:
Damien Elmes 2017-06-06 15:56:21 +10:00
parent c24f122d6e
commit 76e508e25d
5 changed files with 35 additions and 9 deletions

View file

@ -64,8 +64,7 @@ class DeckBrowser:
return False return False
def _keyHandler(self, evt): def _keyHandler(self, evt):
# currently does nothing return False
key = str(evt.text())
def _selDeck(self, did): def _selDeck(self, did):
self.mw.col.decks.select(did) self.mw.col.decks.select(did)

View file

@ -512,6 +512,7 @@ title="%s" %s>%s</button>''' % (
tweb = self.toolbarWeb = aqt.webview.AnkiWebView() tweb = self.toolbarWeb = aqt.webview.AnkiWebView()
tweb.title = "top toolbar" tweb.title = "top toolbar"
tweb.setFocusPolicy(Qt.WheelFocus) tweb.setFocusPolicy(Qt.WheelFocus)
tweb.keyEventDelegate = self.globalKeyHandler
self.toolbar = aqt.toolbar.Toolbar(self, tweb) self.toolbar = aqt.toolbar.Toolbar(self, tweb)
self.toolbar.draw() self.toolbar.draw()
# main area # main area
@ -519,10 +520,12 @@ title="%s" %s>%s</button>''' % (
self.web.title = "main webview" self.web.title = "main webview"
self.web.setFocusPolicy(Qt.WheelFocus) self.web.setFocusPolicy(Qt.WheelFocus)
self.web.setMinimumWidth(400) self.web.setMinimumWidth(400)
self.web.keyEventDelegate = self.globalKeyHandler
# bottom area # bottom area
sweb = self.bottomWeb = aqt.webview.AnkiWebView() sweb = self.bottomWeb = aqt.webview.AnkiWebView()
sweb.title = "bottom toolbar" sweb.title = "bottom toolbar"
sweb.setFocusPolicy(Qt.WheelFocus) sweb.setFocusPolicy(Qt.WheelFocus)
sweb.keyEventDelegate = self.globalKeyHandler
# add in a layout # add in a layout
self.mainLayout = QVBoxLayout() self.mainLayout = QVBoxLayout()
self.mainLayout.setContentsMargins(0,0,0,0) self.mainLayout.setContentsMargins(0,0,0,0)
@ -622,13 +625,17 @@ title="%s" %s>%s</button>''' % (
self.debugShortcut.activated.connect(self.onDebug) self.debugShortcut.activated.connect(self.onDebug)
def keyPressEvent(self, evt): def keyPressEvent(self, evt):
if not self.globalKeyHandler(evt):
QMainWindow.keyPressEvent(self, evt)
# true if we handled key
# called via mw's keyPressEvent() or a webview's event filter
def globalKeyHandler(self, evt):
# do we have a delegate? # do we have a delegate?
if self.keyHandler: if self.keyHandler:
# did it eat the key? # did it eat the key?
if self.keyHandler(evt): if self.keyHandler(evt):
return return True
# run standard handler
QMainWindow.keyPressEvent(self, evt)
# check global keys # check global keys
key = str(evt.text()) key = str(evt.text())
if key == "d": if key == "d":
@ -647,6 +654,9 @@ title="%s" %s>%s</button>''' % (
self.onStats() self.onStats()
elif key == "y": elif key == "y":
self.onSync() self.onSync()
else:
return False
return True
# App exit # App exit
########################################################################## ##########################################################################

View file

@ -68,17 +68,20 @@ class Overview:
key = str(evt.text()) key = str(evt.text())
if key == "o": if key == "o":
self.mw.onDeckConf() self.mw.onDeckConf()
if key == "r" and cram: elif key == "r" and cram:
self.mw.col.sched.rebuildDyn() self.mw.col.sched.rebuildDyn()
self.mw.reset() self.mw.reset()
if key == "e" and cram: elif key == "e" and cram:
self.mw.col.sched.emptyDyn(self.mw.col.decks.selected()) self.mw.col.sched.emptyDyn(self.mw.col.decks.selected())
self.mw.reset() self.mw.reset()
if key == "c" and not cram: elif key == "c" and not cram:
self.onStudyMore() self.onStudyMore()
if key == "u": elif key == "u":
self.mw.col.sched.unburyCardsForDeck() self.mw.col.sched.unburyCardsForDeck()
self.mw.reset() self.mw.reset()
else:
return False
return True
# HTML # HTML
############################################################ ############################################################

View file

@ -319,6 +319,9 @@ The front of this card is empty. Please run Tools>Empty Cards.""")
self._answerCard(int(key)) self._answerCard(int(key))
elif key == "v": elif key == "v":
self.onReplayRecorded() self.onReplayRecorded()
else:
return False
return True
def _linkHandler(self, url): def _linkHandler(self, url):
if url == "ans": if url == "ans":

View file

@ -75,6 +75,8 @@ class AnkiWebView(QWebEngineView):
self._loadFinishedCB = None self._loadFinishedCB = None
self.setPage(self._page) self.setPage(self._page)
self.keyEventDelegate = None
self._page.profile().setHttpCacheType(QWebEngineProfile.MemoryHttpCache) self._page.profile().setHttpCacheType(QWebEngineProfile.MemoryHttpCache)
self.resetHandlers() self.resetHandlers()
self.allowDrops = False self.allowDrops = False
@ -105,9 +107,18 @@ class AnkiWebView(QWebEngineView):
from aqt import mw from aqt import mw
if w != mw: if w != mw:
w.close() w.close()
else:
self.clearFocus()
break break
w = w.parent() w = w.parent()
return True return True
if self.keyEventDelegate:
ret = self.keyEventDelegate(evt)
if ret is None:
raise Exception("add-ons that modify key handlers should make sure true/false is returned")
return ret
return False return False
def onCopy(self): def onCopy(self):