add noctalia and fuzzel
This commit is contained in:
@@ -0,0 +1,668 @@
|
||||
pragma Singleton
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services.Compositor
|
||||
import qs.Services.UI
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
property bool isVisible: true
|
||||
|
||||
// Computed visibility that factors in compositor overview state
|
||||
readonly property bool effectivelyVisible: {
|
||||
if (!isVisible) {
|
||||
return false;
|
||||
}
|
||||
if (Settings.data.bar.hideOnOverview && CompositorService.overviewActive) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
property var readyBars: ({})
|
||||
|
||||
// Revision counter - increment when widget list structure changes (add/remove/reorder)
|
||||
// This triggers Bar.qml to re-sync its ListModels
|
||||
property int widgetsRevision: 0
|
||||
|
||||
// Registry to store actual widget instances
|
||||
// Key format: "screenName|section|widgetId|index"
|
||||
property var widgetInstances: ({})
|
||||
|
||||
signal activeWidgetsChanged
|
||||
signal barReadyChanged(string screenName)
|
||||
signal barAutoHideStateChanged(string screenName, bool hidden)
|
||||
signal barHoverStateChanged(string screenName, bool hovered)
|
||||
|
||||
// Track if a popup menu is open from the bar (prevents auto-hide)
|
||||
property bool popupOpen: false
|
||||
|
||||
// Auto-hide state per screen: { screenName: { hovered: bool, hidden: bool } }
|
||||
property var screenAutoHideState: ({})
|
||||
|
||||
// Get or create auto-hide state for a screen
|
||||
function getOrCreateAutoHideState(screenName) {
|
||||
if (!screenAutoHideState[screenName]) {
|
||||
screenAutoHideState[screenName] = {
|
||||
"hovered": false,
|
||||
"hidden": Settings.getBarDisplayModeForScreen(screenName) === "auto_hide"
|
||||
};
|
||||
}
|
||||
return screenAutoHideState[screenName];
|
||||
}
|
||||
|
||||
// Set hover state for a screen
|
||||
function setScreenHovered(screenName, hovered) {
|
||||
var state = getOrCreateAutoHideState(screenName);
|
||||
if (state.hovered !== hovered) {
|
||||
state.hovered = hovered;
|
||||
screenAutoHideState = Object.assign({}, screenAutoHideState);
|
||||
barHoverStateChanged(screenName, hovered);
|
||||
}
|
||||
}
|
||||
|
||||
// Set hidden state for a screen
|
||||
function setScreenHidden(screenName, hidden) {
|
||||
var state = getOrCreateAutoHideState(screenName);
|
||||
if (state.hidden !== hidden) {
|
||||
state.hidden = hidden;
|
||||
screenAutoHideState = Object.assign({}, screenAutoHideState);
|
||||
barAutoHideStateChanged(screenName, hidden);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if bar is hidden on a screen
|
||||
function isBarHidden(screenName) {
|
||||
var state = screenAutoHideState[screenName];
|
||||
return state ? state.hidden : false;
|
||||
}
|
||||
|
||||
// Check if bar is hovered on a screen
|
||||
function isBarHovered(screenName) {
|
||||
var state = screenAutoHideState[screenName];
|
||||
return state ? state.hovered : false;
|
||||
}
|
||||
|
||||
// Toggle bar visibility. In auto-hide mode, toggles the per-screen hidden
|
||||
// state without touching isVisible (so hover-to-show still works).
|
||||
// For non-auto-hide screens, toggles the global isVisible flag.
|
||||
function toggleVisibility() {
|
||||
// Check if any auto-hide screen is currently visible
|
||||
var anyAutoHideVisible = false;
|
||||
var hasAutoHideScreens = false;
|
||||
for (var screenName in screenAutoHideState) {
|
||||
if (Settings.getBarDisplayModeForScreen(screenName) === "auto_hide") {
|
||||
hasAutoHideScreens = true;
|
||||
if (!screenAutoHideState[screenName].hidden) {
|
||||
anyAutoHideVisible = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle auto-hide screens (per-screen hidden state only)
|
||||
if (hasAutoHideScreens) {
|
||||
for (var screenName in screenAutoHideState) {
|
||||
if (Settings.getBarDisplayModeForScreen(screenName) === "auto_hide") {
|
||||
setScreenHidden(screenName, anyAutoHideVisible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only toggle global visibility when no auto-hide screens exist,
|
||||
// otherwise it would permanently disable hover-to-show
|
||||
if (!hasAutoHideScreens) {
|
||||
isVisible = !isVisible;
|
||||
}
|
||||
}
|
||||
|
||||
// Show bar. In auto-hide mode, un-hides on screens with auto-hide enabled.
|
||||
// The bar stays visible until the user hovers and moves away.
|
||||
function show() {
|
||||
// Show auto-hide screens
|
||||
for (var screenName in screenAutoHideState) {
|
||||
if (Settings.getBarDisplayModeForScreen(screenName) === "auto_hide") {
|
||||
setScreenHidden(screenName, false);
|
||||
}
|
||||
}
|
||||
// Set global visibility (affects non-auto-hide screens)
|
||||
isVisible = true;
|
||||
}
|
||||
|
||||
// Hide bar. In auto-hide mode, sets per-screen hidden state without touching
|
||||
// isVisible so hover-to-show still works. For non-auto-hide screens, sets
|
||||
// global visibility to false.
|
||||
function hide() {
|
||||
var hasAutoHideScreens = false;
|
||||
for (var screenName in screenAutoHideState) {
|
||||
if (Settings.getBarDisplayModeForScreen(screenName) === "auto_hide") {
|
||||
setScreenHidden(screenName, true);
|
||||
hasAutoHideScreens = true;
|
||||
}
|
||||
}
|
||||
// Only set global visibility off when no auto-hide screens exist,
|
||||
// otherwise it would permanently disable hover-to-show
|
||||
if (!hasAutoHideScreens) {
|
||||
isVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Temporarily show the bar, then auto-hide after the configured delay.
|
||||
// Uses the same pattern as workspace switch: show, then emit unhover
|
||||
// to start the hide timer.
|
||||
function peek() {
|
||||
for (var screenName in screenAutoHideState) {
|
||||
if (Settings.getBarDisplayModeForScreen(screenName) === "auto_hide") {
|
||||
setScreenHidden(screenName, false);
|
||||
if (!isBarHovered(screenName)) {
|
||||
barHoverStateChanged(screenName, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
Logger.i("BarService", "Service started");
|
||||
}
|
||||
|
||||
// Bump widgetsRevision when settings are reloaded from an external file change
|
||||
// so Bar.qml re-syncs its widget ListModels with the updated widget configuration
|
||||
Connections {
|
||||
target: Settings
|
||||
function onSettingsReloaded() {
|
||||
Logger.d("BarService", "Settings reloaded externally, bumping widgetsRevision");
|
||||
root.widgetsRevision++;
|
||||
}
|
||||
}
|
||||
|
||||
// update bar's hidden state when mode changes
|
||||
Connections {
|
||||
target: Settings.data.bar
|
||||
function onDisplayModeChanged() {
|
||||
Logger.d("BarService", "Display mode changed to:", Settings.data.bar.displayMode);
|
||||
|
||||
// Only affect screens without displayMode overrides
|
||||
for (let screenName in screenAutoHideState) {
|
||||
if (!Settings.hasScreenOverride(screenName, "displayMode")) {
|
||||
var displayMode = Settings.getBarDisplayModeForScreen(screenName);
|
||||
if (displayMode === "auto_hide") {
|
||||
setScreenHidden(screenName, true);
|
||||
} else {
|
||||
if (screenAutoHideState[screenName].hidden) {
|
||||
setScreenHidden(screenName, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onScreenOverridesChanged() {
|
||||
Logger.d("BarService", "Screen overrides changed, re-evaluating auto-hide states");
|
||||
|
||||
// Re-evaluate auto-hide state for all screens
|
||||
for (let screenName in screenAutoHideState) {
|
||||
var displayMode = Settings.getBarDisplayModeForScreen(screenName);
|
||||
if (displayMode === "auto_hide") {
|
||||
if (!screenAutoHideState[screenName].hidden) {
|
||||
setScreenHidden(screenName, true);
|
||||
}
|
||||
} else {
|
||||
if (screenAutoHideState[screenName].hidden) {
|
||||
setScreenHidden(screenName, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
function onWorkspaceChanged() {
|
||||
if (!Settings.data.bar.showOnWorkspaceSwitch)
|
||||
return;
|
||||
if (Settings.data.bar.displayMode !== "auto_hide")
|
||||
return;
|
||||
|
||||
var ws = CompositorService.getCurrentWorkspace();
|
||||
if (!ws || !ws.output) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only trigger if workspace actually changed
|
||||
var currentWsId = ws.id;
|
||||
if (currentWsId === root.lastWorkspaceId) {
|
||||
return;
|
||||
}
|
||||
root.lastWorkspaceId = currentWsId;
|
||||
|
||||
var screenName = ws.output || "";
|
||||
Logger.d("BarService", "Workspace switched to:", currentWsId, "on screen:", screenName);
|
||||
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
||||
// Function for the Bar to call when it's ready
|
||||
function registerBar(screenName) {
|
||||
if (!readyBars[screenName]) {
|
||||
readyBars[screenName] = true;
|
||||
Logger.d("BarService", "Bar is ready on screen:", screenName);
|
||||
barReadyChanged(screenName);
|
||||
}
|
||||
}
|
||||
|
||||
// Function for the Dock to check if the bar is ready
|
||||
function isBarReady(screenName) {
|
||||
return readyBars[screenName] || false;
|
||||
}
|
||||
|
||||
// Register a widget instance
|
||||
function registerWidget(screenName, section, widgetId, index, instance) {
|
||||
const key = [screenName, section, widgetId, index].join("|");
|
||||
widgetInstances[key] = {
|
||||
"key": key,
|
||||
"screenName": screenName,
|
||||
"section": section,
|
||||
"widgetId": widgetId,
|
||||
"index": index,
|
||||
"instance": instance
|
||||
};
|
||||
|
||||
Logger.d("BarService", "Registered widget:", key);
|
||||
root.activeWidgetsChanged();
|
||||
}
|
||||
|
||||
// Unregister a widget instance
|
||||
function unregisterWidget(screenName, section, widgetId, index) {
|
||||
const key = [screenName, section, widgetId, index].join("|");
|
||||
delete widgetInstances[key];
|
||||
Logger.d("BarService", "Unregistered widget:", key);
|
||||
root.activeWidgetsChanged();
|
||||
}
|
||||
|
||||
// Lookup a specific widget instance (returns the actual QML instance)
|
||||
function lookupWidget(widgetId, screenName = null, section = null, index = null) {
|
||||
// If looking for a specific instance
|
||||
if (screenName && section !== null) {
|
||||
for (var key in widgetInstances) {
|
||||
var widget = widgetInstances[key];
|
||||
if (!widget)
|
||||
continue;
|
||||
if (widget.widgetId === widgetId && widget.screenName === screenName && widget.section === section) {
|
||||
if (index === null) {
|
||||
return widget.instance;
|
||||
} else if (widget.index == index) {
|
||||
return widget.instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return first match if no specific screen/section specified
|
||||
for (var key in widgetInstances) {
|
||||
var widget = widgetInstances[key];
|
||||
if (!widget)
|
||||
continue;
|
||||
if (widget.widgetId === widgetId) {
|
||||
if (!screenName || widget.screenName === screenName) {
|
||||
if (section === null || widget.section === section) {
|
||||
return widget.instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Get all instances of a widget type
|
||||
function getAllWidgetInstances(widgetId = null, screenName = null, section = null) {
|
||||
var instances = [];
|
||||
|
||||
for (var key in widgetInstances) {
|
||||
var widget = widgetInstances[key];
|
||||
if (!widget)
|
||||
continue;
|
||||
|
||||
var matches = true;
|
||||
if (widgetId && widget.widgetId !== widgetId)
|
||||
matches = false;
|
||||
if (screenName && widget.screenName !== screenName)
|
||||
matches = false;
|
||||
if (section !== null && widget.section !== section)
|
||||
matches = false;
|
||||
|
||||
if (matches) {
|
||||
instances.push(widget.instance);
|
||||
}
|
||||
}
|
||||
|
||||
return instances;
|
||||
}
|
||||
|
||||
// Get widget with full metadata
|
||||
function getWidgetWithMetadata(widgetId, screenName = null, section = null) {
|
||||
for (var key in widgetInstances) {
|
||||
var widget = widgetInstances[key];
|
||||
if (!widget)
|
||||
continue;
|
||||
if (widget.widgetId === widgetId) {
|
||||
if (!screenName || widget.screenName === screenName) {
|
||||
if (section === null || widget.section === section) {
|
||||
return widget;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Get all widgets in a specific section
|
||||
function getWidgetsBySection(section, screenName = null) {
|
||||
var widgetEntries = [];
|
||||
|
||||
for (var key in widgetInstances) {
|
||||
var widget = widgetInstances[key];
|
||||
if (!widget)
|
||||
continue;
|
||||
if (widget.section === section) {
|
||||
if (!screenName || widget.screenName === screenName) {
|
||||
widgetEntries.push(widget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by index to maintain order
|
||||
widgetEntries.sort(function (a, b) {
|
||||
return (a.index || 0) - (b.index || 0);
|
||||
});
|
||||
|
||||
// Return just the instances
|
||||
return widgetEntries.map(function (w) {
|
||||
return w.instance;
|
||||
});
|
||||
}
|
||||
|
||||
// Get all registered widgets (for debugging)
|
||||
function getAllRegisteredWidgets() {
|
||||
var result = [];
|
||||
for (var key in widgetInstances) {
|
||||
var widget = widgetInstances[key];
|
||||
if (!widget)
|
||||
continue;
|
||||
result.push({
|
||||
"key": key,
|
||||
"widgetId": widget.widgetId,
|
||||
"section": widget.section,
|
||||
"screenName": widget.screenName,
|
||||
"index": widget.index
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Check if a widget type exists in a section
|
||||
function hasWidget(widgetId, section = null, screenName = null) {
|
||||
for (var key in widgetInstances) {
|
||||
var widget = widgetInstances[key];
|
||||
if (!widget)
|
||||
continue;
|
||||
if (widget.widgetId === widgetId) {
|
||||
if (section === null || widget.section === section) {
|
||||
if (!screenName || widget.screenName === screenName) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Unregister all widget instances for a plugin (used during hot reload)
|
||||
// Note: We don't destroy instances here - the Loader manages that when the component is unregistered
|
||||
function destroyPluginWidgetInstances(pluginId) {
|
||||
var widgetId = "plugin:" + pluginId;
|
||||
var keysToRemove = [];
|
||||
|
||||
// Find all instances of this plugin's widget
|
||||
for (var key in widgetInstances) {
|
||||
var widget = widgetInstances[key];
|
||||
if (widget && widget.widgetId === widgetId) {
|
||||
keysToRemove.push(key);
|
||||
Logger.d("BarService", "Unregistering plugin widget instance:", key);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove from registry
|
||||
for (var i = 0; i < keysToRemove.length; i++) {
|
||||
delete widgetInstances[keysToRemove[i]];
|
||||
}
|
||||
|
||||
if (keysToRemove.length > 0) {
|
||||
Logger.i("BarService", "Unregistered", keysToRemove.length, "instance(s) of plugin widget:", widgetId);
|
||||
root.activeWidgetsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
// Get pill direction for a widget instance
|
||||
function getPillDirection(widgetInstance) {
|
||||
try {
|
||||
if (widgetInstance.section === "left") {
|
||||
return false;
|
||||
} else if (widgetInstance.section === "right") {
|
||||
return true;
|
||||
} else {
|
||||
// middle section
|
||||
if (widgetInstance.sectionWidgetIndex < widgetInstance.sectionWidgetsCount / 2) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
Logger.e(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function getTooltipDirection(screenName) {
|
||||
const position = Settings.getBarPositionForScreen(screenName);
|
||||
switch (position) {
|
||||
case "right":
|
||||
return "left";
|
||||
case "left":
|
||||
return "right";
|
||||
case "bottom":
|
||||
return "top";
|
||||
default:
|
||||
return "bottom";
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to close any existing dialogs in a popup menu window
|
||||
function closeExistingDialogs(popupMenuWindow) {
|
||||
if (!popupMenuWindow || !popupMenuWindow.dialogParent)
|
||||
return;
|
||||
|
||||
var dialogParent = popupMenuWindow.dialogParent;
|
||||
for (var i = dialogParent.children.length - 1; i >= 0; i--) {
|
||||
var child = dialogParent.children[i];
|
||||
if (child && typeof child.close === "function") {
|
||||
child.close();
|
||||
}
|
||||
}
|
||||
popupMenuWindow.hasDialog = false;
|
||||
}
|
||||
|
||||
// Open widget settings dialog for a bar widget
|
||||
// Parameters:
|
||||
// screen: The screen to show the dialog on
|
||||
// section: Section id ("left", "center", "right")
|
||||
// index: Widget index in section
|
||||
// widgetId: Widget type id (e.g., "Volume")
|
||||
// widgetData: Current widget settings object
|
||||
function openWidgetSettings(screen, section, index, widgetId, widgetData) {
|
||||
// Get the popup menu window to use as parent (avoids clipping issues with bar height)
|
||||
var popupMenuWindow = PanelService.getPopupMenuWindow(screen);
|
||||
if (!popupMenuWindow) {
|
||||
Logger.e("BarService", "No popup menu window found for screen");
|
||||
return;
|
||||
}
|
||||
|
||||
// Close any existing dialogs first to prevent stacking
|
||||
closeExistingDialogs(popupMenuWindow);
|
||||
|
||||
if (PanelService.openedPanel) {
|
||||
PanelService.openedPanel.close();
|
||||
}
|
||||
|
||||
var component = Qt.createComponent(Quickshell.shellDir + "/Modules/Panels/Settings/Bar/BarWidgetSettingsDialog.qml");
|
||||
|
||||
function instantiateAndOpen() {
|
||||
// Use dialogParent (Item) instead of window directly for proper Popup anchoring
|
||||
var dialog = component.createObject(popupMenuWindow.dialogParent, {
|
||||
"widgetIndex": index,
|
||||
"widgetData": widgetData,
|
||||
"widgetId": widgetId,
|
||||
"sectionId": section,
|
||||
"screen": screen
|
||||
});
|
||||
|
||||
if (dialog) {
|
||||
dialog.updateWidgetSettings.connect((sec, idx, settings) => {
|
||||
var screenName = screen?.name || "";
|
||||
if (Settings.hasScreenOverride(screenName, "widgets")) {
|
||||
var overrideWidgets = Settings.getBarWidgetsForScreen(screenName);
|
||||
if (overrideWidgets && overrideWidgets[sec] && idx < overrideWidgets[sec].length) {
|
||||
overrideWidgets[sec][idx] = Object.assign({}, overrideWidgets[sec][idx], settings);
|
||||
Settings.setScreenOverride(screenName, "widgets", overrideWidgets);
|
||||
}
|
||||
} else {
|
||||
var widgets = Settings.data.bar.widgets[sec];
|
||||
if (widgets && idx < widgets.length) {
|
||||
widgets[idx] = Object.assign({}, widgets[idx], settings);
|
||||
Settings.data.bar.widgets[sec] = widgets;
|
||||
Settings.saveImmediate();
|
||||
}
|
||||
}
|
||||
});
|
||||
// Enable keyboard focus for the popup menu window when dialog is open
|
||||
popupMenuWindow.hasDialog = true;
|
||||
// Close the popup menu window when dialog closes
|
||||
dialog.closed.connect(() => {
|
||||
popupMenuWindow.hasDialog = false;
|
||||
popupMenuWindow.close();
|
||||
dialog.destroy();
|
||||
});
|
||||
// Show the popup menu window and open the dialog
|
||||
popupMenuWindow.open();
|
||||
dialog.open();
|
||||
} else {
|
||||
Logger.e("BarService", "Failed to create widget settings dialog");
|
||||
}
|
||||
}
|
||||
|
||||
if (component.status === Component.Ready) {
|
||||
instantiateAndOpen();
|
||||
} else if (component.status === Component.Error) {
|
||||
Logger.e("BarService", "Error loading widget settings dialog:", component.errorString());
|
||||
} else {
|
||||
component.statusChanged.connect(function () {
|
||||
if (component.status === Component.Ready) {
|
||||
instantiateAndOpen();
|
||||
} else if (component.status === Component.Error) {
|
||||
Logger.e("BarService", "Error loading widget settings dialog:", component.errorString());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Open plugin settings dialog
|
||||
// Parameters:
|
||||
// screen: The screen to show the dialog on
|
||||
// pluginManifest: The plugin's manifest object (must have entryPoints.settings)
|
||||
function openPluginSettings(screen, pluginManifest) {
|
||||
if (!pluginManifest || !pluginManifest.entryPoints || !pluginManifest.entryPoints.settings) {
|
||||
Logger.e("BarService", "Cannot open plugin settings: no settings entry point");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the popup menu window to use as parent
|
||||
var popupMenuWindow = PanelService.getPopupMenuWindow(screen);
|
||||
if (!popupMenuWindow) {
|
||||
Logger.e("BarService", "No popup menu window found for screen");
|
||||
return;
|
||||
}
|
||||
|
||||
// Close any existing dialogs first to prevent stacking
|
||||
closeExistingDialogs(popupMenuWindow);
|
||||
|
||||
var component = Qt.createComponent(Quickshell.shellDir + "/Widgets/NPluginSettingsPopup.qml");
|
||||
|
||||
function instantiateAndOpen() {
|
||||
var dialog = component.createObject(popupMenuWindow.dialogParent, {
|
||||
"showToastOnSave": true,
|
||||
"screen": screen
|
||||
});
|
||||
|
||||
if (dialog) {
|
||||
// Enable keyboard focus for the popup menu window when dialog is open
|
||||
popupMenuWindow.hasDialog = true;
|
||||
// Close the popup menu window when dialog closes
|
||||
dialog.closed.connect(() => {
|
||||
popupMenuWindow.hasDialog = false;
|
||||
popupMenuWindow.close();
|
||||
dialog.destroy();
|
||||
});
|
||||
// Show the popup menu window and open the dialog
|
||||
popupMenuWindow.open();
|
||||
dialog.openPluginSettings(pluginManifest);
|
||||
} else {
|
||||
Logger.e("BarService", "Failed to create plugin settings dialog");
|
||||
}
|
||||
}
|
||||
|
||||
if (component.status === Component.Ready) {
|
||||
instantiateAndOpen();
|
||||
} else if (component.status === Component.Error) {
|
||||
Logger.e("BarService", "Error loading plugin settings dialog:", component.errorString());
|
||||
} else {
|
||||
component.statusChanged.connect(function () {
|
||||
if (component.status === Component.Ready) {
|
||||
instantiateAndOpen();
|
||||
} else if (component.status === Component.Error) {
|
||||
Logger.e("BarService", "Error loading plugin settings dialog:", component.errorString());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user