Fix TrayMenu crash after display wake. Add checks if screen exists, else set scaling to 1.0
TrayMenu: Replace PopupPanel with NPanel (for better loading & to prevent QS crash) Overview, Background etc: add screen checks, if it doesnt exist set scaling to 1.0
This commit is contained in:
parent
714f6c058f
commit
51f1923e22
9 changed files with 119 additions and 137 deletions
|
|
@ -12,7 +12,7 @@ Variants {
|
||||||
|
|
||||||
required property ShellScreen modelData
|
required property ShellScreen modelData
|
||||||
|
|
||||||
active: Settings.isLoaded
|
active: Settings.isLoaded && modelData
|
||||||
|
|
||||||
sourceComponent: PanelWindow {
|
sourceComponent: PanelWindow {
|
||||||
id: root
|
id: root
|
||||||
|
|
@ -38,7 +38,7 @@ Variants {
|
||||||
property real stripesAngle: 0
|
property real stripesAngle: 0
|
||||||
|
|
||||||
// External state management
|
// External state management
|
||||||
property string servicedWallpaper: WallpaperService.getWallpaper(modelData.name)
|
property string servicedWallpaper: modelData ? WallpaperService.getWallpaper(modelData.name) : ""
|
||||||
property string futureWallpaper: ""
|
property string futureWallpaper: ""
|
||||||
onServicedWallpaperChanged: {
|
onServicedWallpaperChanged: {
|
||||||
// Set wallpaper immediately on startup
|
// Set wallpaper immediately on startup
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,14 @@ Variants {
|
||||||
delegate: Loader {
|
delegate: Loader {
|
||||||
required property ShellScreen modelData
|
required property ShellScreen modelData
|
||||||
|
|
||||||
active: Settings.isLoaded && CompositorService.isNiri
|
active: Settings.isLoaded && CompositorService.isNiri && modelData
|
||||||
|
|
||||||
sourceComponent: PanelWindow {
|
sourceComponent: PanelWindow {
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
|
if (modelData) {
|
||||||
Logger.log("Overview", "Loading Overview component for Niri on", modelData.name)
|
Logger.log("Overview", "Loading Overview component for Niri on", modelData.name)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
color: Color.transparent
|
color: Color.transparent
|
||||||
screen: modelData
|
screen: modelData
|
||||||
|
|
@ -36,7 +38,7 @@ Variants {
|
||||||
id: bgImage
|
id: bgImage
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
fillMode: Image.PreserveAspectCrop
|
fillMode: Image.PreserveAspectCrop
|
||||||
source: WallpaperService.getWallpaper(modelData.name)
|
source: modelData ? WallpaperService.getWallpaper(modelData.name) : ""
|
||||||
smooth: true
|
smooth: true
|
||||||
mipmap: false
|
mipmap: false
|
||||||
cache: false
|
cache: false
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,13 @@ Variants {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
required property ShellScreen modelData
|
required property ShellScreen modelData
|
||||||
readonly property real scaling: ScalingService.scale(modelData)
|
readonly property real scaling: modelData ? ScalingService.scale(modelData) : 1.0
|
||||||
|
|
||||||
active: Settings.isLoaded && modelData ? (Settings.data.bar.monitors.includes(modelData.name)
|
active: Settings.isLoaded && modelData && modelData.name ? (Settings.data.bar.monitors.includes(modelData.name)
|
||||||
|| (Settings.data.bar.monitors.length === 0)) : false
|
|| (Settings.data.bar.monitors.length === 0)) : false
|
||||||
|
|
||||||
sourceComponent: PanelWindow {
|
sourceComponent: PanelWindow {
|
||||||
screen: modelData
|
screen: modelData || null
|
||||||
|
|
||||||
WlrLayershell.namespace: "noctalia-bar"
|
WlrLayershell.namespace: "noctalia-bar"
|
||||||
|
|
||||||
|
|
@ -65,7 +65,7 @@ Variants {
|
||||||
delegate: NWidgetLoader {
|
delegate: NWidgetLoader {
|
||||||
widgetName: modelData
|
widgetName: modelData
|
||||||
widgetProps: {
|
widgetProps: {
|
||||||
"screen": screen
|
"screen": root.modelData || null
|
||||||
}
|
}
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
@ -87,7 +87,7 @@ Variants {
|
||||||
delegate: NWidgetLoader {
|
delegate: NWidgetLoader {
|
||||||
widgetName: modelData
|
widgetName: modelData
|
||||||
widgetProps: {
|
widgetProps: {
|
||||||
"screen": screen
|
"screen": root.modelData || null
|
||||||
}
|
}
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
@ -110,7 +110,7 @@ Variants {
|
||||||
delegate: NWidgetLoader {
|
delegate: NWidgetLoader {
|
||||||
widgetName: modelData
|
widgetName: modelData
|
||||||
widgetProps: {
|
widgetProps: {
|
||||||
"screen": screen
|
"screen": root.modelData || null
|
||||||
}
|
}
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,26 +6,23 @@ import qs.Commons
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
PopupWindow {
|
NPanel {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
objectName: "trayMenu"
|
||||||
|
|
||||||
|
panelWidth: 180 * scaling
|
||||||
|
panelHeight: 220 * scaling
|
||||||
|
panelAnchorRight: true
|
||||||
|
|
||||||
property QsMenuHandle menu
|
property QsMenuHandle menu
|
||||||
property var anchorItem: null
|
property var anchorItem: null
|
||||||
property real anchorX
|
property real anchorX
|
||||||
property real anchorY
|
property real anchorY
|
||||||
property bool isSubMenu: false
|
property bool isSubMenu: false
|
||||||
property bool isHovered: rootMouseArea.containsMouse
|
property bool isHovered: false
|
||||||
|
|
||||||
readonly property int menuWidth: 180
|
|
||||||
|
|
||||||
implicitWidth: menuWidth * scaling
|
|
||||||
|
|
||||||
// Use the content height of the Flickable for implicit height
|
|
||||||
implicitHeight: Math.min(Screen.height * 0.9, flickable.contentHeight + (Style.marginS * 2 * scaling))
|
|
||||||
visible: false
|
|
||||||
color: Color.transparent
|
|
||||||
anchor.item: anchorItem
|
|
||||||
anchor.rect.x: anchorX
|
|
||||||
anchor.rect.y: anchorY - (isSubMenu ? 0 : 4)
|
|
||||||
|
|
||||||
function showAt(item, x, y) {
|
function showAt(item, x, y) {
|
||||||
if (!item) {
|
if (!item) {
|
||||||
|
|
@ -33,27 +30,18 @@ PopupWindow {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!opener.children || opener.children.values.length === 0) {
|
|
||||||
//Logger.warn("TrayMenu", "Menu not ready, delaying show")
|
|
||||||
Qt.callLater(() => showAt(item, x, y))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
anchorItem = item
|
anchorItem = item
|
||||||
anchorX = x
|
anchorX = x
|
||||||
anchorY = y
|
anchorY = y
|
||||||
|
|
||||||
visible = true
|
// Use NPanel's open method instead of PopupWindow's visible
|
||||||
forceActiveFocus()
|
open(screen)
|
||||||
|
|
||||||
|
|
||||||
// Force update after showing.
|
|
||||||
Qt.callLater(() => {
|
|
||||||
root.anchor.updateAnchor()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideMenu() {
|
function hideMenu() {
|
||||||
visible = false
|
close()
|
||||||
|
|
||||||
// Clean up all submenus recursively
|
// Clean up all submenus recursively
|
||||||
for (var i = 0; i < columnLayout.children.length; i++) {
|
for (var i = 0; i < columnLayout.children.length; i++) {
|
||||||
|
|
@ -66,16 +54,18 @@ PopupWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
panelContent: Rectangle {
|
||||||
|
color: Color.transparent
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Style.marginS * scaling
|
||||||
|
|
||||||
// Full-sized, transparent MouseArea to track the mouse.
|
// Full-sized, transparent MouseArea to track the mouse.
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: rootMouseArea
|
id: rootMouseArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
}
|
onEntered: root.isHovered = true
|
||||||
|
onExited: root.isHovered = false
|
||||||
Item {
|
|
||||||
anchors.fill: parent
|
|
||||||
Keys.onEscapePressed: root.hideMenu()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QsMenuOpener {
|
QsMenuOpener {
|
||||||
|
|
@ -83,12 +73,18 @@ PopupWindow {
|
||||||
menu: root.menu
|
menu: root.menu
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Component.onCompleted: {
|
||||||
anchors.fill: parent
|
if (menu && opener.children && opener.children.values.length === 0) {
|
||||||
color: Color.mSurface
|
// Menu not ready, try again later
|
||||||
border.color: Color.mOutline
|
Qt.callLater(() => {
|
||||||
border.width: Math.max(1, Style.borderS * scaling)
|
if (opener.children && opener.children.values.length > 0) {
|
||||||
radius: Style.radiusM * scaling
|
// Menu is now ready
|
||||||
|
root.menuItemCount = opener.children.values.length
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else if (opener.children && opener.children.values.length > 0) {
|
||||||
|
root.menuItemCount = opener.children.values.length
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Flickable {
|
Flickable {
|
||||||
|
|
@ -206,28 +202,17 @@ PopupWindow {
|
||||||
entry.subMenu.destroy()
|
entry.subMenu.destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Need a slight overlap so that menu don't close when moving the mouse to a submenu
|
// Create submenu using the same TrayMenu component
|
||||||
const submenuWidth = menuWidth * scaling // Assuming a similar width as the parent
|
|
||||||
const overlap = 4 * scaling // A small overlap to bridge the mouse path
|
|
||||||
|
|
||||||
// Check if there's enough space on the right
|
|
||||||
const globalPos = entry.mapToGlobal(0, 0)
|
|
||||||
const openLeft = (globalPos.x + entry.width + submenuWidth > Screen.width)
|
|
||||||
|
|
||||||
// Position with overlap
|
|
||||||
const anchorX = openLeft ? -submenuWidth + overlap : entry.width - overlap
|
|
||||||
|
|
||||||
// Create submenu
|
|
||||||
entry.subMenu = Qt.createComponent("TrayMenu.qml").createObject(root, {
|
entry.subMenu = Qt.createComponent("TrayMenu.qml").createObject(root, {
|
||||||
"menu": modelData,
|
"menu": modelData,
|
||||||
"anchorItem": entry,
|
"anchorItem": entry,
|
||||||
"anchorX": anchorX,
|
"anchorX": entry.width,
|
||||||
"anchorY": 0,
|
"anchorY": 0,
|
||||||
"isSubMenu": true
|
"isSubMenu": true
|
||||||
})
|
})
|
||||||
|
|
||||||
if (entry.subMenu) {
|
if (entry.subMenu) {
|
||||||
entry.subMenu.showAt(entry, anchorX, 0)
|
entry.subMenu.open(screen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -254,4 +239,5 @@ PopupWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ Rectangle {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property ShellScreen screen
|
property ShellScreen screen
|
||||||
property real scaling: ScalingService.scale(screen)
|
property real scaling: screen ? ScalingService.scale(screen) : 1.0
|
||||||
readonly property real itemSize: 24 * scaling
|
readonly property real itemSize: 24 * scaling
|
||||||
|
|
||||||
visible: SystemTray.items.values.length > 0
|
visible: SystemTray.items.values.length > 0
|
||||||
|
|
@ -80,35 +80,42 @@ Rectangle {
|
||||||
|
|
||||||
if (mouse.button === Qt.LeftButton) {
|
if (mouse.button === Qt.LeftButton) {
|
||||||
// Close any open menu first
|
// Close any open menu first
|
||||||
trayPanel.close()
|
var trayMenuPanel = PanelService.getPanel("trayMenu")
|
||||||
|
if (trayMenuPanel && trayMenuPanel.active) {
|
||||||
|
trayMenuPanel.close()
|
||||||
|
}
|
||||||
|
|
||||||
if (!modelData.onlyMenu) {
|
if (!modelData.onlyMenu) {
|
||||||
modelData.activate()
|
modelData.activate()
|
||||||
}
|
}
|
||||||
} else if (mouse.button === Qt.MiddleButton) {
|
} else if (mouse.button === Qt.MiddleButton) {
|
||||||
// Close any open menu first
|
// Close any open menu first
|
||||||
trayPanel.close()
|
var trayMenuPanel = PanelService.getPanel("trayMenu")
|
||||||
|
if (trayMenuPanel && trayMenuPanel.active) {
|
||||||
|
trayMenuPanel.close()
|
||||||
|
}
|
||||||
|
|
||||||
modelData.secondaryActivate && modelData.secondaryActivate()
|
modelData.secondaryActivate && modelData.secondaryActivate()
|
||||||
} else if (mouse.button === Qt.RightButton) {
|
} else if (mouse.button === Qt.RightButton) {
|
||||||
trayTooltip.hide()
|
trayTooltip.hide()
|
||||||
|
|
||||||
// Close the menu if it was visible
|
// Don't open menu if screen is invalid
|
||||||
if (trayPanel && trayPanel.visible) {
|
if (!screen || !screen.name) {
|
||||||
trayPanel.close()
|
Logger.warn("Tray", "Cannot open tray menu: invalid screen object")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modelData.hasMenu && modelData.menu && trayMenu.item) {
|
if (modelData.hasMenu && modelData.menu) {
|
||||||
trayPanel.open()
|
// Get the tray menu panel from PanelService
|
||||||
|
var trayMenuPanel = PanelService.getPanel("trayMenu")
|
||||||
// Anchor the menu to the tray icon item (parent) and position it below the icon
|
if (trayMenuPanel) {
|
||||||
const menuX = (width / 2) - (trayMenu.item.width / 2)
|
trayMenuPanel.menu = modelData.menu
|
||||||
const menuY = (Style.barHeight * scaling)
|
trayMenuPanel.toggle(screen, this)
|
||||||
trayMenu.item.menu = modelData.menu
|
|
||||||
trayMenu.item.showAt(parent, menuX, menuY)
|
|
||||||
} else {
|
} else {
|
||||||
Logger.log("Tray", "No menu available for", modelData.id, "or trayMenu not set")
|
Logger.warn("Tray", "Tray menu panel not found")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Logger.log("Tray", "No menu available for", modelData.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -126,36 +133,5 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PanelWindow {
|
|
||||||
id: trayPanel
|
|
||||||
anchors.top: true
|
|
||||||
anchors.left: true
|
|
||||||
anchors.right: true
|
|
||||||
anchors.bottom: true
|
|
||||||
visible: false
|
|
||||||
color: Color.transparent
|
|
||||||
screen: screen
|
|
||||||
|
|
||||||
function open() {
|
|
||||||
visible = true
|
|
||||||
|
|
||||||
PanelService.willOpenPanel(trayPanel)
|
|
||||||
}
|
|
||||||
|
|
||||||
function close() {
|
|
||||||
visible = false
|
|
||||||
trayMenu.item.hideMenu()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clicking outside of the rectangle to close
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: trayPanel.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: trayMenu
|
|
||||||
source: "../Extras/TrayMenu.qml"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ Loader {
|
||||||
id: lockBgImage
|
id: lockBgImage
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
fillMode: Image.PreserveAspectCrop
|
fillMode: Image.PreserveAspectCrop
|
||||||
source: WallpaperService.getWallpaper(screen.name)
|
source: screen ? WallpaperService.getWallpaper(screen.name) : ""
|
||||||
cache: true
|
cache: true
|
||||||
smooth: true
|
smooth: true
|
||||||
mipmap: false
|
mipmap: false
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ ColumnLayout {
|
||||||
NImageRounded {
|
NImageRounded {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Style.marginXS * scaling
|
anchors.margins: Style.marginXS * scaling
|
||||||
imagePath: WallpaperService.getWallpaper(screen.name)
|
imagePath: screen ? WallpaperService.getWallpaper(screen.name) : ""
|
||||||
fallbackIcon: "image"
|
fallbackIcon: "image"
|
||||||
imageRadius: Style.radiusM * scaling
|
imageRadius: Style.radiusM * scaling
|
||||||
}
|
}
|
||||||
|
|
@ -74,7 +74,7 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
property list<string> wallpapersList: WallpaperService.getWallpapersList(screen.name)
|
property list<string> wallpapersList: screen ? WallpaperService.getWallpapersList(screen.name) : []
|
||||||
|
|
||||||
NToggle {
|
NToggle {
|
||||||
label: "Assign selection to all monitors"
|
label: "Assign selection to all monitors"
|
||||||
|
|
@ -115,7 +115,7 @@ ColumnLayout {
|
||||||
id: wallpaperItem
|
id: wallpaperItem
|
||||||
|
|
||||||
property string wallpaperPath: modelData
|
property string wallpaperPath: modelData
|
||||||
property bool isSelected: wallpaperPath === WallpaperService.getWallpaper(screen.name)
|
property bool isSelected: screen ? (wallpaperPath === WallpaperService.getWallpaper(screen.name)) : false
|
||||||
|
|
||||||
width: wallpaperGridView.itemSize
|
width: wallpaperGridView.itemSize
|
||||||
height: Math.floor(wallpaperGridView.itemSize * 0.67)
|
height: Math.floor(wallpaperGridView.itemSize * 0.67)
|
||||||
|
|
@ -183,7 +183,7 @@ ColumnLayout {
|
||||||
onPressed: {
|
onPressed: {
|
||||||
if (Settings.data.wallpaper.setWallpaperOnAllMonitors) {
|
if (Settings.data.wallpaper.setWallpaperOnAllMonitors) {
|
||||||
WallpaperService.changeWallpaper(undefined, wallpaperPath)
|
WallpaperService.changeWallpaper(undefined, wallpaperPath)
|
||||||
} else {
|
} else if (screen) {
|
||||||
WallpaperService.changeWallpaper(screen.name, wallpaperPath)
|
WallpaperService.changeWallpaper(screen.name, wallpaperPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ Loader {
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
|
|
||||||
property ShellScreen screen
|
property ShellScreen screen
|
||||||
readonly property real scaling: ScalingService.scale(screen)
|
readonly property real scaling: screen ? ScalingService.scale(screen) : 1.0
|
||||||
|
|
||||||
property Component panelContent: null
|
property Component panelContent: null
|
||||||
property int panelWidth: 1500
|
property int panelWidth: 1500
|
||||||
|
|
@ -50,6 +50,12 @@ Loader {
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
function toggle(aScreen, buttonItem) {
|
function toggle(aScreen, buttonItem) {
|
||||||
|
// Don't toggle if screen is null or invalid
|
||||||
|
if (!aScreen || !aScreen.name) {
|
||||||
|
Logger.warn("NPanel", "Cannot toggle panel: invalid screen object")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (!active || isClosing) {
|
if (!active || isClosing) {
|
||||||
open(aScreen, buttonItem)
|
open(aScreen, buttonItem)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -59,6 +65,12 @@ Loader {
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
function open(aScreen, buttonItem) {
|
function open(aScreen, buttonItem) {
|
||||||
|
// Don't open if screen is null or invalid
|
||||||
|
if (!aScreen || !aScreen.name) {
|
||||||
|
Logger.warn("NPanel", "Cannot open panel: invalid screen object")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (aScreen !== null) {
|
if (aScreen !== null) {
|
||||||
screen = aScreen
|
screen = aScreen
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import qs.Commons
|
||||||
import qs.Modules.Launcher
|
import qs.Modules.Launcher
|
||||||
import qs.Modules.Background
|
import qs.Modules.Background
|
||||||
import qs.Modules.Bar
|
import qs.Modules.Bar
|
||||||
|
import qs.Modules.Bar.Extras
|
||||||
import qs.Modules.BluetoothPanel
|
import qs.Modules.BluetoothPanel
|
||||||
import qs.Modules.Calendar
|
import qs.Modules.Calendar
|
||||||
import qs.Modules.Dock
|
import qs.Modules.Dock
|
||||||
|
|
@ -99,6 +100,11 @@ ShellRoot {
|
||||||
objectName: "archUpdaterPanel"
|
objectName: "archUpdaterPanel"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TrayMenu {
|
||||||
|
id: trayMenuPanel
|
||||||
|
objectName: "trayMenu"
|
||||||
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
// Save a ref. to our lockScreen so we can access it easily
|
// Save a ref. to our lockScreen so we can access it easily
|
||||||
PanelService.lockScreen = lockScreen
|
PanelService.lockScreen = lockScreen
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue