Use QApplication.postEvent again
We had some funny segfaults reported during scrolling (i.e. with QApplication.sendEvent), and some code already had to use postpone=True so there was no segfault... So now we're back to postEvent again, and eliminated the main reason for segfaults with it, which was re-using (and -posting) events which had already been posted. At least during tests this seems to run stable, let's hope it helps for the people having crashes as well.
This commit is contained in:
parent
de03feabfe
commit
fff777404b
@ -595,18 +595,20 @@ class AbstractTab(QWidget):
|
||||
"""Return the widget events should be sent to."""
|
||||
raise NotImplementedError
|
||||
|
||||
def send_event(self, evt, *, postpone=False):
|
||||
def send_event(self, evt):
|
||||
"""Send the given event to the underlying widget.
|
||||
|
||||
Args:
|
||||
postpone: Postpone the event to be handled later instead of
|
||||
immediately. Using this might cause crashes in Qt.
|
||||
The event will be sent via QApplication.postEvent.
|
||||
Note that a posted event may not be re-used in any way!
|
||||
"""
|
||||
# This only gives us some mild protection against re-using events, but
|
||||
# it's certainly better than a segfault.
|
||||
if getattr(evt, 'posted', False):
|
||||
raise AssertionError("Can't re-use an event which was already "
|
||||
"posted!")
|
||||
recipient = self._event_target()
|
||||
if postpone:
|
||||
evt.posted = True
|
||||
QApplication.postEvent(recipient, evt)
|
||||
else:
|
||||
QApplication.sendEvent(recipient, evt)
|
||||
|
||||
@pyqtSlot(QUrl)
|
||||
def _on_link_clicked(self, url):
|
||||
|
@ -1974,8 +1974,8 @@ class CommandDispatcher:
|
||||
window = QApplication.focusWindow()
|
||||
if window is None:
|
||||
raise cmdexc.CommandError("No focused window!")
|
||||
QApplication.sendEvent(window, press_event)
|
||||
QApplication.sendEvent(window, release_event)
|
||||
QApplication.postEvent(window, press_event)
|
||||
QApplication.postEvent(window, release_event)
|
||||
else:
|
||||
try:
|
||||
tab = objreg.get('tab', scope='tab', tab='current')
|
||||
|
@ -376,9 +376,7 @@ class AbstractWebElement(collections.abc.MutableMapping):
|
||||
]
|
||||
|
||||
for evt in events:
|
||||
# For some reason, postpone=True is needed here to *not* cause
|
||||
# segfaults in misc.feature because of :fake-key later...
|
||||
self._tab.send_event(evt, postpone=True)
|
||||
self._tab.send_event(evt)
|
||||
|
||||
def after_click():
|
||||
"""Move cursor to end and reset override_target after clicking."""
|
||||
|
@ -214,9 +214,9 @@ class WebEngineScroller(browsertab.AbstractScroller):
|
||||
|
||||
def _key_press(self, key, count=1):
|
||||
# FIXME:qtwebengine Abort scrolling if the minimum/maximum was reached.
|
||||
for _ in range(count):
|
||||
press_evt = QKeyEvent(QEvent.KeyPress, key, Qt.NoModifier, 0, 0, 0)
|
||||
release_evt = QKeyEvent(QEvent.KeyRelease, key, Qt.NoModifier, 0, 0, 0)
|
||||
for _ in range(count):
|
||||
self._tab.send_event(press_evt)
|
||||
self._tab.send_event(release_evt)
|
||||
|
||||
|
@ -409,14 +409,15 @@ class WebKitScroller(browsertab.AbstractScroller):
|
||||
|
||||
def _key_press(self, key, count=1, getter_name=None, direction=None):
|
||||
frame = self._widget.page().mainFrame()
|
||||
press_evt = QKeyEvent(QEvent.KeyPress, key, Qt.NoModifier, 0, 0, 0)
|
||||
release_evt = QKeyEvent(QEvent.KeyRelease, key, Qt.NoModifier, 0, 0, 0)
|
||||
getter = None if getter_name is None else getattr(frame, getter_name)
|
||||
|
||||
# FIXME:qtwebengine needed?
|
||||
# self._widget.setFocus()
|
||||
|
||||
for _ in range(count):
|
||||
press_evt = QKeyEvent(QEvent.KeyPress, key, Qt.NoModifier, 0, 0, 0)
|
||||
release_evt = QKeyEvent(QEvent.KeyRelease, key, Qt.NoModifier,
|
||||
0, 0, 0)
|
||||
# Abort scrolling if the minimum/maximum was reached.
|
||||
if (getter is not None and
|
||||
frame.scrollBarValue(direction) == getter(direction)):
|
||||
|
@ -84,7 +84,6 @@ Feature: Scrolling
|
||||
And I wait until the scroll position changed to 0/0
|
||||
Then the page should not be scrolled
|
||||
|
||||
# causes segfault with postEvent instead of sendEvent
|
||||
Scenario: Scrolling down with count 10
|
||||
When I run :scroll down with count 10
|
||||
Then no crash should happen
|
||||
|
Loading…
Reference in New Issue
Block a user