Files
noctalia-shell/Services/PanelService.qml
T
ItsLemmy 101b27fcc7 New windowing system
Large commit that totally refactor of the way we handle the bar and
panels.

Testing should focus on Panels, Bar, Keyboard Focus, IPC calls.

Changes brief:
- One NFullScreenWindow per screen which handle it's bar and dedicated
panels.
- Added shadows
- Reintroduced dimming
- New panels animations
- Proper Z ordering
- Panels on overlay laywer is not reimplemented, if we do it then the
bar will be on the Overlay too
- Panel dragging was not reimplemented, to be discussed before
reimplementing
- Still a WIP, need to work more on shadows and polishing + debugging.
2025-11-03 00:53:02 -05:00

112 lines
2.9 KiB
QML

pragma Singleton
import Quickshell
import qs.Commons
Singleton {
id: root
// A ref. to the lockScreen, so it's accessible from anywhere
// This is not a panel...
property var lockScreen: null
// Panels
property var registeredPanels: ({})
property var openedPanel: null
signal willOpen
signal didClose
// Currently opened popups, can have more than one.
// ex: when opening an NIconPicker from a widget setting.
property var openedPopups: []
property bool hasOpenedPopup: false
signal popupChanged
// Registered panel loaders (before they're loaded)
property var registeredPanelLoaders: ({})
// Register a panel loader (called before panel is loaded)
function registerPanelLoader(panelLoader, objectName) {
registeredPanelLoaders[objectName] = panelLoader
Logger.d("PanelService", "Registered panel loader:", objectName)
}
// Register this panel (called after panel is loaded)
function registerPanel(panel) {
registeredPanels[panel.objectName] = panel
Logger.i("PanelService", "Registered panel:", panel.objectName)
}
// Returns a panel (loads it on-demand if not yet loaded)
function getPanel(name, screen) {
if (!screen) {
Logger.w("PanelService", "missing screen for getPanel:", name)
Logger.callStack()
// If no screen specified, return the first matching panel
for (var key in registeredPanels) {
if (key.startsWith(name + "-")) {
return registeredPanels[key]
}
}
return null
}
var panelKey = `${name}-${screen.name}`
// Check if panel is already loaded
if (registeredPanels[panelKey]) {
return registeredPanels[panelKey]
}
// Panel not loaded yet - try to load it via the loader
if (registeredPanelLoaders[panelKey]) {
Logger.d("PanelService", "Loading panel on-demand:", panelKey)
registeredPanelLoaders[panelKey].ensureLoaded()
// After ensureLoaded(), the panel should register itself via registerPanel()
// Return it if it registered synchronously
return registeredPanels[panelKey] || null
}
Logger.w("PanelService", "Panel not found:", panelKey)
return null
}
// Check if a panel exists
function hasPanel(name) {
return name in registeredPanels
}
// Helper to keep only one panel open at any time
function willOpenPanel(panel) {
if (openedPanel && openedPanel !== panel) {
openedPanel.close()
}
openedPanel = panel
// emit signal
willOpen()
}
function closedPanel(panel) {
if (openedPanel && openedPanel === panel) {
openedPanel = null
}
// emit signal
didClose()
}
// Popups
function willOpenPopup(popup) {
openedPopups.push(popup)
hasOpenedPopup = (openedPopups.length !== 0)
popupChanged()
}
function willClosePopup(popup) {
openedPopups = openedPopups.filter(p => p !== popup)
hasOpenedPopup = (openedPopups.length !== 0)
popupChanged()
}
}