Details
-
Bug
-
Resolution: Fixed
-
P1: Critical
-
6.3.1
-
None
-
-
441993a9a (dev), ff2dcd861 (6.5), 6116f9591 (tqtc/lts-6.2), 00e1ff6b3 (tqtc/lts-5.15)
Description
A crash can occur when closing a modal window with macOS' built-in on-screen keyboard activated, as the keyboard's callbacks are executed on a still-existing QNSView without a QPlatformWindow.
The on-screen keyboard executes `-[IMKInputSession stringFromRange:completionHandler:] ()` on a window focus change, which is handled by `-[QNSView(ComplexText) attributedSubstringForProposedRange:actualRange:]`. Inside this function, `QObject *focusObject = m_platformWindow->window()->focusObject();` is called to fetch the current object that is in focus for the current platform window.
For a modal window this can happen while the modal window is being destroyed, leading to a null pointer access (as `m_platformWindow` is already a null pointer), but the event callback is still executed on an orphaned (but not destroyed) `QNSView`:
Here is some verbose debug logging by Qt for the sequence of events before the crash - `OBSBasicSettingsWindow` is the modal window that is being closed:
2022-09-06 00:40:47.650723+0200 OBS[93991:14349212] [qt.qpa.window] QCocoaWindow::setVisible QWidgetWindow(0x600000bf59e0, name="OBSBasicSettingsWindow") false 2022-09-06 00:40:47.651921+0200 OBS[93991:14349212] [qt.qpa.cocoa.notifications] Forwarding NSWindowDidResignKeyNotification to QList(QCocoaWindow(0x60000193dc30, window=QWidgetWindow(0x600000bf59e0, name="OBSBasicSettingsWindow"))) 2022-09-06 00:40:47.652288+0200 OBS[93991:14349212] [qt.qpa.input.methods] Focus object changed to QObject(0x0) 2022-09-06 00:40:47.709009+0200 OBS[93991:14349212] [qt.qpa.cocoa.notifications] Forwarding NSWindowDidOrderOffScreenNotification to QList(QCocoaWindow(0x60000193dc30, window=QWidgetWindow(0x600000bf59e0, name="OBSBasicSettingsWindow"))) 2022-09-06 00:40:47.709069+0200 OBS[93991:14349212] [qt.qpa.drawing] QCocoaWindow::handleExposeEvent QWidgetWindow(0x600000bf59e0, name="OBSBasicSettingsWindow") QRegion(null) isExposed false 2022-09-06 00:40:47.712391+0200 OBS[93991:14349212] [qt.qpa.window] QCocoaWindow::~QCocoaWindow QWidgetWindow(0x600000bf59e0, name="OBSBasicSettingsWindow") 2022-09-06 00:40:47.713137+0200 OBS[93991:14349212] [qt.qpa.window] Re-parenting <QNSView: 0x2ac98a0e0; QCocoaWindow(0x60000193dc30, window=QWidgetWindow(0x600000bf59e0, name="OBSBasicSettingsWindow"))> from <NSThemeFrame: 0x2ac98a910> to NSObject(0x0) 2022-09-06 00:40:47.713195+0200 OBS[93991:14349212] [qt.qpa.window] Done re-parenting <QNSView: 0x2ac98a0e0; QCocoaWindow(0x60000193dc30, window=QWidgetWindow(0x600000bf59e0, name="OBSBasicSettingsWindow"))> into NSObject(0x0) 2022-09-06 00:40:47.713243+0200 OBS[93991:14349212] [qt.qpa.window] Moving <QNSView: 0x2ac98a0e0; QCocoaWindow(0x60000193dc30, window=QWidgetWindow(0x600000bf59e0, name="OBSBasicSettingsWindow"))> from <QNSPanel: 0x2ac98a3a0; contentView=<QNSView: 0x2ac98a0e0; QCocoaWindow(0x60000193dc30, window=QWidgetWindow(0x600000bf59e0, name="OBSBasicSettingsWindow"))>> to NSObject(0x0) 2022-09-06 00:40:47.713296+0200 OBS[93991:14349212] [qt.qpa.window] Done moving <QNSView: 0x2ac98a0e0; QCocoaWindow(0x60000193dc30, window=QWidgetWindow(0x600000bf59e0, name="OBSBasicSettingsWindow"))> to NSObject(0x0)
Right after this, the crash occurs in the next iteration of `[NSApp runModalSession:session]` inside `QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>)`, as this is where the callback hook of the on-screen keyboard is executed again.