mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
fix(bar): attempt to avoid crash when autohide is used
This commit is contained in:
@@ -85,6 +85,12 @@ Item {
|
||||
property ListModel centerWidgetsModel: ListModel {}
|
||||
property ListModel rightWidgetsModel: ListModel {}
|
||||
|
||||
// Guard: set when Bar is destroyed; prevents Qt.callLater callbacks from running
|
||||
// during/after teardown (avoids SIGSEGV in QV4::Object::insertMember when rapid
|
||||
// workspace switch causes load/unload overlap with async widget incubation)
|
||||
property bool _destroyed: false
|
||||
Component.onDestruction: root._destroyed = true
|
||||
|
||||
// Sync a ListModel with widget data, preserving delegates when only settings change
|
||||
function syncWidgetModel(model, newWidgets) {
|
||||
var validWidgets = filterValidWidgets(newWidgets);
|
||||
@@ -134,6 +140,8 @@ Item {
|
||||
}
|
||||
|
||||
function _syncFromRevision() {
|
||||
if (root._destroyed)
|
||||
return;
|
||||
var widgets = Settings.getBarWidgetsForScreen(screen?.name);
|
||||
if (widgets) {
|
||||
syncWidgetModel(leftWidgetsModel, widgets.left);
|
||||
@@ -152,6 +160,8 @@ Item {
|
||||
}
|
||||
|
||||
function _initModels() {
|
||||
if (root._destroyed)
|
||||
return;
|
||||
var widgets = Settings.getBarWidgetsForScreen(screen?.name);
|
||||
if (widgets) {
|
||||
syncWidgetModel(leftWidgetsModel, widgets.left);
|
||||
|
||||
@@ -91,6 +91,10 @@ Item {
|
||||
onLoaded: {
|
||||
if (!item)
|
||||
return;
|
||||
// Guard: if parent chain is torn down (Bar content unload during rapid workspace
|
||||
// switch), skip registration to avoid SIGSEGV in QV4 during async incubation
|
||||
if (!root.parent || !root.parent.parent || !widgetScreen?.name)
|
||||
return;
|
||||
|
||||
Logger.d("BarWidgetLoader", "Loading widget", widgetId, "on screen:", widgetScreen.name);
|
||||
|
||||
|
||||
@@ -152,10 +152,11 @@ PanelWindow {
|
||||
// start the unload timer), unmapping the Wayland surface mid-animation.
|
||||
property bool contentLoaded: false
|
||||
|
||||
// Timer to delay unload until after fade animation
|
||||
// Timer to delay unload until after fade animation.
|
||||
// Extra buffer (250ms) when auto-hide to reduce race with rapid workspace switch (SIGSEGV in QV4).
|
||||
Timer {
|
||||
id: unloadTimer
|
||||
interval: Style.animationFast + 50
|
||||
interval: Style.animationFast + (barWindow.autoHide ? 250 : 50)
|
||||
onTriggered: {
|
||||
// Only unload if still hidden AND not about to show (prevents unload/reload race)
|
||||
if (barWindow.isHidden && !showTimer.running) {
|
||||
|
||||
@@ -196,6 +196,25 @@ Singleton {
|
||||
// Track last workspace ID to detect actual workspace changes
|
||||
property var lastWorkspaceId: null
|
||||
|
||||
// Debounce rapid workspace switches to reduce load/unload races (SIGSEGV in QV4)
|
||||
property string _pendingWorkspaceScreen: ""
|
||||
|
||||
Timer {
|
||||
id: workspaceDebounceTimer
|
||||
interval: 80
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
var screen = root._pendingWorkspaceScreen;
|
||||
root._pendingWorkspaceScreen = "";
|
||||
if (screen) {
|
||||
setScreenHidden(screen, false);
|
||||
if (!root.isBarHovered(screen)) {
|
||||
barHoverStateChanged(screen, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Workspace switch handler - directly show bar on the focused workspace screen
|
||||
Connections {
|
||||
target: CompositorService
|
||||
@@ -220,13 +239,10 @@ Singleton {
|
||||
var screenName = ws.output || "";
|
||||
Logger.d("BarService", "Workspace switched to:", currentWsId, "on screen:", screenName);
|
||||
|
||||
// Show bar immediately
|
||||
setScreenHidden(screenName, false);
|
||||
|
||||
// Only trigger hideTimer if not already hovered (e.g., mouse on trigger zone)
|
||||
if (!root.isBarHovered(screenName)) {
|
||||
barHoverStateChanged(screenName, false);
|
||||
}
|
||||
// Debounce: rapid switches (e.g. external monitor ↔ laptop) cause overlapping
|
||||
// bar load/unload; 80ms delay coalesces them and reduces QV4 incubation races
|
||||
root._pendingWorkspaceScreen = screenName;
|
||||
workspaceDebounceTimer.restart();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user