What caused the crash
A SIGSEGV (segmentation fault) occurs in quickshell's QML engine when the
Wayland compositor reports screen/output changes — specifically during
session wake-up after the screens have been off (e.g., idle/sleep). The
crash happens inside ScriptModel::updateValuesUnique
(src/core/scriptmodel.cpp:61) when QML binding evaluations cascade through
Variants::setModel → repeater item incubation → property access on a
QVariantMap that has become invalid during the model update chain.
Detailed Call Chain
The crash follows this exact path (from the stacktrace and logs):
- Trigger: Wayland compositor signals a screen change. The log shows
"There are no outputs - creating placeholder screen" at both 02:38:08
(session idling) and 12:57:19 (session resuming). The crash occurs on the
second event, when screens come back.
- QWaylandScreen::maybeInitialize() → Qt Wayland client handles the new
screen.
- QuickshellTracked::updateScreens() (qmlglobal.cpp:135) → quickshell
detects screen changes and emits screensChanged().
- screensChanged() signal → triggers QML property bindings that call
Variants::setModel() (variants.cpp:98).
- Variants::updateVariants() (variants.cpp:154) → calls
QQmlComponentPrivate::createWithProperties(), creating new QML component
instances with associated properties.
- During component finalization, a signal handler fires, which triggers a
QML binding that calls ScriptModel::setValues() →
ScriptModel::updateValuesUnique() (scriptmodel.cpp:61).
- QAbstractItemModel::endInsertRows() → notifies
QQmlDelegateModel::_q_itemsInserted() → QQuickRepeater::modelUpdated().
- The Repeater begins incubating new items — during incubation,
QQuickItem::setParentItem() fires, which triggers more QML binding updates.
- One of those bindings attempts to read a property by calling
QV4::ExecutionEngine::fromData() to convert a QVariantMap into a QML
JavaScript object.
- CRASH: The ExecutionEngine::fromData() dereferences invalid/corrupt
memory → SIGSEGV at libc.so.6 (frame #0).
Root Cause Analysis
The crash is fundamentally a use-after-free / dangling reference bug in the
interaction between quickshell's model layer and Qt's QML binding engine:
- ScriptModel::updateValuesUnique() modifies the model (inserts rows) while
there are still active QML bindings that depend on data from the previous
model state.
- When the Repeater responds to model changes by creating new items, those
items' QML bindings evaluate against data (a QVariantMap) that was already
freed or mutated by the ScriptModel::setValues() call earlier in the same
call stack.
- The problem is specifically triggered by screen sleep/wake cycles: when
all outputs disappear (idle/sleep), quickshell creates a placeholder
screen; when outputs return, updateScreens() fires and recreates the entire
screen-dependent model hierarchy while bindings are still referencing the
old data.
Reproduction Conditions
- Desktop: niri (Wayland compositor)
- GPU: Dual GPU (NVIDIA + Intel i915)
- Trigger: Session idle → screens turn off → session resumes (e.g., input
event wakes screens)
- Session duration: The instance had been running ~27 hours before the
crash (started 09:40 May 29, crashed 12:57 May 30)
- Config: DMS v1.4.6 ("Saffron Bloom"), system-level shell at
/usr/share/quickshell/dms/shell.qml
System Info
- quickshell: 0.3.0 (git rev 7d1c9a9), AUR quickshell-git
- Qt: 6.11.1
- Compiler: GCC 16.1.1, RelWithDebInfo
- OS: Arch Linux (rolling)
Report file
report.txt
Log file
log.qslog.log
Configuration
No response
Backtrace
No response
What caused the crash
A SIGSEGV (segmentation fault) occurs in quickshell's QML engine when the
Wayland compositor reports screen/output changes — specifically during
session wake-up after the screens have been off (e.g., idle/sleep). The
crash happens inside ScriptModel::updateValuesUnique
(src/core/scriptmodel.cpp:61) when QML binding evaluations cascade through
Variants::setModel → repeater item incubation → property access on a
QVariantMap that has become invalid during the model update chain.
Detailed Call Chain
The crash follows this exact path (from the stacktrace and logs):
"There are no outputs - creating placeholder screen" at both 02:38:08
(session idling) and 12:57:19 (session resuming). The crash occurs on the
second event, when screens come back.
screen.
detects screen changes and emits screensChanged().
Variants::setModel() (variants.cpp:98).
QQmlComponentPrivate::createWithProperties(), creating new QML component
instances with associated properties.
QML binding that calls ScriptModel::setValues() →
ScriptModel::updateValuesUnique() (scriptmodel.cpp:61).
QQmlDelegateModel::_q_itemsInserted() → QQuickRepeater::modelUpdated().
QQuickItem::setParentItem() fires, which triggers more QML binding updates.
QV4::ExecutionEngine::fromData() to convert a QVariantMap into a QML
JavaScript object.
memory → SIGSEGV at libc.so.6 (frame #0).
Root Cause Analysis
The crash is fundamentally a use-after-free / dangling reference bug in the
interaction between quickshell's model layer and Qt's QML binding engine:
there are still active QML bindings that depend on data from the previous
model state.
items' QML bindings evaluate against data (a QVariantMap) that was already
freed or mutated by the ScriptModel::setValues() call earlier in the same
call stack.
all outputs disappear (idle/sleep), quickshell creates a placeholder
screen; when outputs return, updateScreens() fires and recreates the entire
screen-dependent model hierarchy while bindings are still referencing the
old data.
Reproduction Conditions
event wakes screens)
crash (started 09:40 May 29, crashed 12:57 May 30)
/usr/share/quickshell/dms/shell.qml
System Info
Report file
report.txt
Log file
log.qslog.log
Configuration
No response
Backtrace
No response