1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-05 21:15:38 -05:00
Files
DankMaterialShell/Modules/TopBar/TopBar.qml
bbedward 21867c842f modules cleanup and qmlfmt everywhere
- throw in 24H clock fix and app drawer fix too
2025-09-03 23:26:07 -04:00

969 lines
47 KiB
QML

import QtQuick
import QtQuick.Controls
import QtQuick.Effects
import Quickshell
import Quickshell.Io
import Quickshell.Services.Mpris
import Quickshell.Services.Notifications
import Quickshell.Services.SystemTray
import Quickshell.Wayland
import Quickshell.Widgets
import qs.Common
import qs.Modules
import qs.Modules.TopBar
import qs.Services
import qs.Widgets
PanelWindow {
id: root
property var modelData
property string screenName: modelData.name
readonly property int notificationCount: NotificationService.notifications.length
readonly property real effectiveBarHeight: Math.max(root.widgetHeight + SettingsData.topBarInnerPadding + 4, Theme.barHeight - 4 - (8 - SettingsData.topBarInnerPadding))
readonly property real widgetHeight: Math.max(20, 26 + SettingsData.topBarInnerPadding * 0.6)
screen: modelData
implicitHeight: effectiveBarHeight + SettingsData.topBarSpacing
color: "transparent"
Component.onCompleted: {
const fonts = Qt.fontFamilies()
if (fonts.indexOf("Material Symbols Rounded") === -1) {
ToastService.showError("Please install Material Symbols Rounded and Restart your Shell. See README.md for instructions")
}
SettingsData.forceTopBarLayoutRefresh.connect(() => {
Qt.callLater(() => {
leftSection.visible = false
centerSection.visible = false
rightSection.visible = false
Qt.callLater(() => {
leftSection.visible = true
centerSection.visible = true
rightSection.visible = true
})
})
})
updateGpuTempConfig()
Qt.callLater(() => Qt.callLater(forceWidgetRefresh))
}
function forceWidgetRefresh() {
const sections = [leftSection, centerSection, rightSection]
sections.forEach(section => section && (section.visible = false))
Qt.callLater(() => sections.forEach(section => section && (section.visible = true)))
}
function updateGpuTempConfig() {
const allWidgets = [...(SettingsData.topBarLeftWidgets || []), ...(SettingsData.topBarCenterWidgets || []), ...(SettingsData.topBarRightWidgets || [])]
const hasGpuTempWidget = allWidgets.some(widget => {
const widgetId = typeof widget === "string" ? widget : widget.id
const widgetEnabled = typeof widget === "string" ? true : (widget.enabled !== false)
return widgetId === "gpuTemp" && widgetEnabled
})
DgopService.gpuTempEnabled = hasGpuTempWidget || SessionData.nvidiaGpuTempEnabled || SessionData.nonNvidiaGpuTempEnabled
DgopService.nvidiaGpuTempEnabled = hasGpuTempWidget || SessionData.nvidiaGpuTempEnabled
DgopService.nonNvidiaGpuTempEnabled = hasGpuTempWidget || SessionData.nonNvidiaGpuTempEnabled
}
Connections {
function onTopBarLeftWidgetsChanged() {
root.updateGpuTempConfig()
}
function onTopBarCenterWidgetsChanged() {
root.updateGpuTempConfig()
}
function onTopBarRightWidgetsChanged() {
root.updateGpuTempConfig()
}
target: SettingsData
}
Connections {
function onNvidiaGpuTempEnabledChanged() {
root.updateGpuTempConfig()
}
function onNonNvidiaGpuTempEnabledChanged() {
root.updateGpuTempConfig()
}
target: SessionData
}
Connections {
target: root.screen
function onGeometryChanged() {
if (centerSection?.width > 0) {
Qt.callLater(centerSection.updateLayout)
}
}
}
anchors {
top: true
left: true
right: true
}
exclusiveZone: topBarCore.autoHide ? -1 : root.effectiveBarHeight + SettingsData.topBarSpacing - 2 + SettingsData.topBarBottomGap
mask: Region {
item: topBarMouseArea
}
Item {
id: topBarCore
anchors.fill: parent
property real backgroundTransparency: SettingsData.topBarTransparency
property bool autoHide: SettingsData.topBarAutoHide
property bool reveal: SettingsData.topBarVisible && (!autoHide || topBarMouseArea.containsMouse || hasActivePopout)
readonly property bool hasActivePopout: {
const loaders = [{
"loader": appDrawerLoader,
"prop": "shouldBeVisible"
}, {
"loader": centcomPopoutLoader,
"prop": "shouldBeVisible"
}, {
"loader": processListPopoutLoader,
"prop": "shouldBeVisible"
}, {
"loader": notificationCenterLoader,
"prop": "shouldBeVisible"
}, {
"loader": batteryPopoutLoader,
"prop": "shouldBeVisible"
}, {
"loader": vpnPopoutLoader,
"prop": "shouldBeVisible"
}, {
"loader": controlCenterLoader,
"prop": "shouldBeVisible"
}, {
"loader": notepadSlideoutLoader,
"prop": "notepadVisible"
}, {
"loader": clipboardHistoryModalPopup,
"prop": "visible"
}]
return loaders.some(item => item.loader?.item[item.prop])
}
Connections {
function onTopBarTransparencyChanged() {
topBarCore.backgroundTransparency = SettingsData.topBarTransparency
}
target: SettingsData
}
MouseArea {
id: topBarMouseArea
height: parent.reveal ? root.effectiveBarHeight + SettingsData.topBarSpacing : 4
anchors {
top: parent.top
left: parent.left
right: parent.right
}
hoverEnabled: true
Behavior on height {
NumberAnimation {
duration: 200
easing.type: Easing.OutCubic
}
}
Item {
id: topBarContainer
anchors.fill: parent
transform: Translate {
id: topBarSlide
y: topBarCore.reveal ? 0 : -(root.effectiveBarHeight - 4)
Behavior on y {
NumberAnimation {
duration: 200
easing.type: Easing.OutCubic
}
}
}
Item {
anchors.fill: parent
anchors.topMargin: SettingsData.topBarSpacing
anchors.bottomMargin: 0
anchors.leftMargin: SettingsData.topBarSpacing
anchors.rightMargin: SettingsData.topBarSpacing
Rectangle {
anchors.fill: parent
radius: SettingsData.topBarSquareCorners ? 0 : Theme.cornerRadius
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, topBarCore.backgroundTransparency)
layer.enabled: true
Rectangle {
anchors.fill: parent
color: "transparent"
border.color: Theme.outlineMedium
border.width: 1
radius: parent.radius
}
Rectangle {
anchors.fill: parent
color: Qt.rgba(Theme.surfaceTint.r, Theme.surfaceTint.g, Theme.surfaceTint.b, 0.04)
radius: parent.radius
SequentialAnimation on opacity {
running: false
loops: Animation.Infinite
NumberAnimation {
to: 0.08
duration: Theme.extraLongDuration
easing.type: Theme.standardEasing
}
NumberAnimation {
to: 0.02
duration: Theme.extraLongDuration
easing.type: Theme.standardEasing
}
}
}
layer.effect: MultiEffect {
shadowEnabled: true
shadowHorizontalOffset: 0
shadowVerticalOffset: 4
shadowBlur: 0.5 // radius/32, adjusted for visual match
shadowColor: Qt.rgba(0, 0, 0, 0.15)
shadowOpacity: 0.15
}
}
Item {
id: topBarContent
readonly property int availableWidth: width
readonly property int launcherButtonWidth: 40
readonly property int workspaceSwitcherWidth: 120 // Approximate
readonly property int focusedAppMaxWidth: 456 // Fixed width since we don't have focusedApp reference
readonly property int estimatedLeftSectionWidth: launcherButtonWidth + workspaceSwitcherWidth + focusedAppMaxWidth + (Theme.spacingXS * 2)
readonly property int rightSectionWidth: rightSection.width
readonly property int clockWidth: 120 // Approximate clock width
readonly property int mediaMaxWidth: 280 // Normal max width
readonly property int weatherWidth: 80 // Approximate weather width
readonly property bool validLayout: availableWidth > 100 && estimatedLeftSectionWidth > 0 && rightSectionWidth > 0
readonly property int clockLeftEdge: (availableWidth - clockWidth) / 2
readonly property int clockRightEdge: clockLeftEdge + clockWidth
readonly property int leftSectionRightEdge: estimatedLeftSectionWidth
readonly property int mediaLeftEdge: clockLeftEdge - mediaMaxWidth - Theme.spacingS
readonly property int rightSectionLeftEdge: availableWidth - rightSectionWidth
readonly property int leftToClockGap: Math.max(0, clockLeftEdge - leftSectionRightEdge)
readonly property int leftToMediaGap: mediaMaxWidth > 0 ? Math.max(0, mediaLeftEdge - leftSectionRightEdge) : leftToClockGap
readonly property int mediaToClockGap: mediaMaxWidth > 0 ? Theme.spacingS : 0
readonly property int clockToRightGap: validLayout ? Math.max(0, rightSectionLeftEdge - clockRightEdge) : 1000
readonly property bool spacingTight: validLayout && (leftToMediaGap < 150 || clockToRightGap < 100)
readonly property bool overlapping: validLayout && (leftToMediaGap < 100 || clockToRightGap < 50)
function getWidgetEnabled(enabled) {
return enabled !== false
}
function getWidgetSection(parentItem) {
if (!parentItem?.parent) {
return "left"
}
if (parentItem.parent === leftSection) {
return "left"
}
if (parentItem.parent === rightSection) {
return "right"
}
if (parentItem.parent === centerSection) {
return "center"
}
return "left"
}
readonly property var widgetVisibility: ({
"cpuUsage": DgopService.dgopAvailable,
"memUsage": DgopService.dgopAvailable,
"cpuTemp": DgopService.dgopAvailable,
"gpuTemp": DgopService.dgopAvailable,
"network_speed_monitor": DgopService.dgopAvailable
})
function getWidgetVisible(widgetId) {
return widgetVisibility[widgetId] ?? true
}
readonly property var componentMap: ({
"launcherButton": launcherButtonComponent,
"workspaceSwitcher": workspaceSwitcherComponent,
"focusedWindow": focusedWindowComponent,
"runningApps": runningAppsComponent,
"clock": clockComponent,
"music": mediaComponent,
"weather": weatherComponent,
"systemTray": systemTrayComponent,
"privacyIndicator": privacyIndicatorComponent,
"clipboard": clipboardComponent,
"cpuUsage": cpuUsageComponent,
"memUsage": memUsageComponent,
"cpuTemp": cpuTempComponent,
"gpuTemp": gpuTempComponent,
"notificationButton": notificationButtonComponent,
"battery": batteryComponent,
"controlCenterButton": controlCenterButtonComponent,
"idleInhibitor": idleInhibitorComponent,
"spacer": spacerComponent,
"separator": separatorComponent,
"network_speed_monitor": networkComponent,
"keyboard_layout_name": keyboardLayoutNameComponent,
"vpn": vpnComponent,
"notepadButton": notepadButtonComponent
})
function getWidgetComponent(widgetId) {
return componentMap[widgetId] || null
}
anchors.fill: parent
anchors.leftMargin: Math.max(Theme.spacingXS, SettingsData.topBarInnerPadding * 0.8)
anchors.rightMargin: Math.max(Theme.spacingXS, SettingsData.topBarInnerPadding * 0.8)
anchors.topMargin: SettingsData.topBarInnerPadding / 2
anchors.bottomMargin: SettingsData.topBarInnerPadding / 2
clip: true
Row {
id: leftSection
height: parent.height
spacing: SettingsData.topBarNoBackground ? 2 : Theme.spacingXS
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
Repeater {
model: SettingsData.topBarLeftWidgetsModel
Loader {
property string widgetId: model.widgetId
property var widgetData: model
property int spacerSize: model.size || 20
anchors.verticalCenter: parent ? parent.verticalCenter : undefined
active: topBarContent.getWidgetVisible(model.widgetId)
sourceComponent: topBarContent.getWidgetComponent(model.widgetId)
opacity: topBarContent.getWidgetEnabled(model.enabled) ? 1 : 0
asynchronous: false
}
}
}
Item {
id: centerSection
property var centerWidgets: []
property int totalWidgets: 0
property real totalWidth: 0
property real spacing: SettingsData.topBarNoBackground ? 2 : Theme.spacingS
function updateLayout() {
if (width <= 0 || height <= 0 || !visible) {
Qt.callLater(updateLayout)
return
}
centerWidgets = []
totalWidgets = 0
totalWidth = 0
for (var i = 0; i < centerRepeater.count; i++) {
const item = centerRepeater.itemAt(i)
if (item?.active && item.item) {
centerWidgets.push(item.item)
totalWidgets++
totalWidth += item.item.width
}
}
if (totalWidgets > 1) {
totalWidth += spacing * (totalWidgets - 1)
}
positionWidgets()
}
function positionWidgets() {
if (totalWidgets === 0 || width <= 0) {
return
}
const parentCenterX = width / 2
const isOdd = totalWidgets % 2 === 1
centerWidgets.forEach(widget => widget.anchors.horizontalCenter = undefined)
if (isOdd) {
const middleIndex = Math.floor(totalWidgets / 2)
const middleWidget = centerWidgets[middleIndex]
middleWidget.x = parentCenterX - (middleWidget.width / 2)
let currentX = middleWidget.x
for (var i = middleIndex - 1; i >= 0; i--) {
currentX -= (spacing + centerWidgets[i].width)
centerWidgets[i].x = currentX
}
currentX = middleWidget.x + middleWidget.width
for (var i = middleIndex + 1; i < totalWidgets; i++) {
currentX += spacing
centerWidgets[i].x = currentX
currentX += centerWidgets[i].width
}
} else {
const leftIndex = (totalWidgets / 2) - 1
const rightIndex = totalWidgets / 2
const halfSpacing = spacing / 2
centerWidgets[leftIndex].x = parentCenterX - halfSpacing - centerWidgets[leftIndex].width
centerWidgets[rightIndex].x = parentCenterX + halfSpacing
let currentX = centerWidgets[leftIndex].x
for (var i = leftIndex - 1; i >= 0; i--) {
currentX -= (spacing + centerWidgets[i].width)
centerWidgets[i].x = currentX
}
currentX = centerWidgets[rightIndex].x + centerWidgets[rightIndex].width
for (var i = rightIndex + 1; i < totalWidgets; i++) {
currentX += spacing
centerWidgets[i].x = currentX
currentX += centerWidgets[i].width
}
}
}
height: parent.height
width: parent.width
anchors.centerIn: parent
Component.onCompleted: {
Qt.callLater(() => {
Qt.callLater(updateLayout)
})
}
onWidthChanged: {
if (width > 0) {
Qt.callLater(updateLayout)
}
}
onVisibleChanged: {
if (visible && width > 0) {
Qt.callLater(updateLayout)
}
}
Repeater {
id: centerRepeater
model: SettingsData.topBarCenterWidgetsModel
Loader {
property string widgetId: model.widgetId
property var widgetData: model
property int spacerSize: model.size || 20
anchors.verticalCenter: parent ? parent.verticalCenter : undefined
active: topBarContent.getWidgetVisible(model.widgetId)
sourceComponent: topBarContent.getWidgetComponent(model.widgetId)
opacity: topBarContent.getWidgetEnabled(model.enabled) ? 1 : 0
asynchronous: false
onLoaded: {
if (!item) {
return
}
item.onWidthChanged.connect(centerSection.updateLayout)
if (model.widgetId === "spacer") {
item.spacerSize = Qt.binding(() => model.size || 20)
}
Qt.callLater(centerSection.updateLayout)
}
onActiveChanged: {
Qt.callLater(centerSection.updateLayout)
}
}
}
Connections {
function onCountChanged() {
Qt.callLater(centerSection.updateLayout)
}
target: SettingsData.topBarCenterWidgetsModel
}
}
Row {
id: rightSection
height: parent.height
spacing: SettingsData.topBarNoBackground ? 2 : Theme.spacingXS
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
Repeater {
model: SettingsData.topBarRightWidgetsModel
Loader {
property string widgetId: model.widgetId
property var widgetData: model
property int spacerSize: model.size || 20
anchors.verticalCenter: parent ? parent.verticalCenter : undefined
active: topBarContent.getWidgetVisible(model.widgetId)
sourceComponent: topBarContent.getWidgetComponent(model.widgetId)
opacity: topBarContent.getWidgetEnabled(model.enabled) ? 1 : 0
asynchronous: false
}
}
}
Component {
id: clipboardComponent
Rectangle {
readonly property real horizontalPadding: SettingsData.topBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (root.widgetHeight / 30))
width: clipboardIcon.width + horizontalPadding * 2
height: root.widgetHeight
radius: SettingsData.topBarNoBackground ? 0 : Theme.cornerRadius
color: {
if (SettingsData.topBarNoBackground) {
return "transparent"
}
const baseColor = clipboardArea.containsMouse ? Theme.primaryHover : Theme.secondaryHover
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency)
}
DankIcon {
id: clipboardIcon
anchors.centerIn: parent
name: "content_paste"
size: Theme.iconSize - 6
color: Theme.surfaceText
}
MouseArea {
id: clipboardArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
clipboardHistoryModalPopup.toggle()
}
}
Behavior on color {
ColorAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
}
Component {
id: launcherButtonComponent
LauncherButton {
isActive: false
widgetHeight: root.widgetHeight
barHeight: root.effectiveBarHeight
section: topBarContent.getWidgetSection(parent)
popupTarget: appDrawerLoader.item
parentScreen: root.screen
onClicked: {
appDrawerLoader.active = true
appDrawerLoader.item?.toggle()
}
}
}
Component {
id: workspaceSwitcherComponent
WorkspaceSwitcher {
screenName: root.screenName
widgetHeight: root.widgetHeight
}
}
Component {
id: focusedWindowComponent
FocusedApp {
availableWidth: topBarContent.leftToMediaGap
widgetHeight: root.widgetHeight
}
}
Component {
id: runningAppsComponent
RunningApps {
widgetHeight: root.widgetHeight
section: topBarContent.getWidgetSection(parent)
parentScreen: root.screen
topBar: topBarContent
}
}
Component {
id: clockComponent
Clock {
compactMode: topBarContent.overlapping
barHeight: root.effectiveBarHeight
widgetHeight: root.widgetHeight
section: topBarContent.getWidgetSection(parent) || "center"
popupTarget: {
centcomPopoutLoader.active = true
return centcomPopoutLoader.item
}
parentScreen: root.screen
onClockClicked: {
centcomPopoutLoader.active = true
if (centcomPopoutLoader.item) {
centcomPopoutLoader.item.calendarVisible = !centcomPopoutLoader.item.calendarVisible
}
}
}
}
Component {
id: mediaComponent
Media {
compactMode: topBarContent.spacingTight || topBarContent.overlapping
barHeight: root.effectiveBarHeight
widgetHeight: root.widgetHeight
section: topBarContent.getWidgetSection(parent) || "center"
popupTarget: {
centcomPopoutLoader.active = true
return centcomPopoutLoader.item
}
parentScreen: root.screen
onClicked: {
centcomPopoutLoader.active = true
if (centcomPopoutLoader.item) {
centcomPopoutLoader.item.calendarVisible = !centcomPopoutLoader.item.calendarVisible
}
}
}
}
Component {
id: weatherComponent
Weather {
barHeight: root.effectiveBarHeight
widgetHeight: root.widgetHeight
section: topBarContent.getWidgetSection(parent) || "center"
popupTarget: {
centcomPopoutLoader.active = true
return centcomPopoutLoader.item
}
parentScreen: root.screen
onClicked: {
centcomPopoutLoader.active = true
if (centcomPopoutLoader.item) {
centcomPopoutLoader.item.calendarVisible = !centcomPopoutLoader.item.calendarVisible
}
}
}
}
Component {
id: systemTrayComponent
SystemTrayBar {
parentWindow: root
parentScreen: root.screen
widgetHeight: root.widgetHeight
}
}
Component {
id: privacyIndicatorComponent
PrivacyIndicator {
widgetHeight: root.widgetHeight
section: topBarContent.getWidgetSection(parent) || "right"
parentScreen: root.screen
}
}
Component {
id: cpuUsageComponent
CpuMonitor {
barHeight: root.effectiveBarHeight
widgetHeight: root.widgetHeight
section: topBarContent.getWidgetSection(parent) || "right"
popupTarget: {
processListPopoutLoader.active = true
return processListPopoutLoader.item
}
parentScreen: root.screen
toggleProcessList: () => {
processListPopoutLoader.active = true
return processListPopoutLoader.item?.toggle()
}
}
}
Component {
id: memUsageComponent
RamMonitor {
barHeight: root.effectiveBarHeight
widgetHeight: root.widgetHeight
section: topBarContent.getWidgetSection(parent) || "right"
popupTarget: {
processListPopoutLoader.active = true
return processListPopoutLoader.item
}
parentScreen: root.screen
toggleProcessList: () => {
processListPopoutLoader.active = true
return processListPopoutLoader.item?.toggle()
}
}
}
Component {
id: cpuTempComponent
CpuTemperature {
barHeight: root.effectiveBarHeight
widgetHeight: root.widgetHeight
section: topBarContent.getWidgetSection(parent) || "right"
popupTarget: {
processListPopoutLoader.active = true
return processListPopoutLoader.item
}
parentScreen: root.screen
toggleProcessList: () => {
processListPopoutLoader.active = true
return processListPopoutLoader.item?.toggle()
}
}
}
Component {
id: gpuTempComponent
GpuTemperature {
barHeight: root.effectiveBarHeight
widgetHeight: root.widgetHeight
section: topBarContent.getWidgetSection(parent) || "right"
popupTarget: {
processListPopoutLoader.active = true
return processListPopoutLoader.item
}
parentScreen: root.screen
widgetData: parent.widgetData
toggleProcessList: () => {
processListPopoutLoader.active = true
return processListPopoutLoader.item?.toggle()
}
}
}
Component {
id: networkComponent
NetworkMonitor {}
}
Component {
id: notificationButtonComponent
NotificationCenterButton {
hasUnread: root.notificationCount > 0
isActive: notificationCenterLoader.item ? notificationCenterLoader.item.shouldBeVisible : false
widgetHeight: root.widgetHeight
barHeight: root.effectiveBarHeight
section: topBarContent.getWidgetSection(parent) || "right"
popupTarget: {
notificationCenterLoader.active = true
return notificationCenterLoader.item
}
parentScreen: root.screen
onClicked: {
notificationCenterLoader.active = true
notificationCenterLoader.item?.toggle()
}
}
}
Component {
id: batteryComponent
Battery {
batteryPopupVisible: batteryPopoutLoader.item ? batteryPopoutLoader.item.shouldBeVisible : false
widgetHeight: root.widgetHeight
barHeight: root.effectiveBarHeight
section: topBarContent.getWidgetSection(parent) || "right"
popupTarget: {
batteryPopoutLoader.active = true
return batteryPopoutLoader.item
}
parentScreen: root.screen
onToggleBatteryPopup: {
batteryPopoutLoader.active = true
batteryPopoutLoader.item?.toggle()
}
}
}
Component {
id: vpnComponent
Vpn {
widgetHeight: root.widgetHeight
barHeight: root.effectiveBarHeight
section: topBarContent.getWidgetSection(parent) || "right"
popupTarget: {
vpnPopoutLoader.active = true
return vpnPopoutLoader.item
}
parentScreen: root.screen
onToggleVpnPopup: {
vpnPopoutLoader.active = true
vpnPopoutLoader.item?.toggle()
}
}
}
Component {
id: controlCenterButtonComponent
ControlCenterButton {
isActive: controlCenterLoader.item ? controlCenterLoader.item.shouldBeVisible : false
widgetHeight: root.widgetHeight
barHeight: root.effectiveBarHeight
section: topBarContent.getWidgetSection(parent) || "right"
popupTarget: {
controlCenterLoader.active = true
return controlCenterLoader.item
}
parentScreen: root.screen
widgetData: parent.widgetData
onClicked: {
controlCenterLoader.active = true
if (!controlCenterLoader.item) {
return
}
controlCenterLoader.item.triggerScreen = root.screen
controlCenterLoader.item.toggle()
if (controlCenterLoader.item.shouldBeVisible && NetworkService.wifiEnabled) {
NetworkService.scanWifi()
}
}
}
}
Component {
id: idleInhibitorComponent
IdleInhibitor {
widgetHeight: root.widgetHeight
section: topBarContent.getWidgetSection(parent) || "right"
parentScreen: root.screen
}
}
Component {
id: spacerComponent
Item {
width: parent.spacerSize || 20
height: root.widgetHeight
Rectangle {
anchors.fill: parent
color: "transparent"
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.1)
border.width: 1
radius: 2
visible: false
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: parent.visible = true
onExited: parent.visible = false
}
}
}
}
Component {
id: separatorComponent
Rectangle {
width: 1
height: root.widgetHeight * 0.67
color: Theme.outline
opacity: 0.3
}
}
Component {
id: keyboardLayoutNameComponent
KeyboardLayoutName {}
}
Component {
id: notepadButtonComponent
NotepadButton {
isActive: notepadSlideoutLoader.item ? notepadSlideoutLoader.item.notepadVisible : false
widgetHeight: root.widgetHeight
barHeight: root.effectiveBarHeight
section: topBarContent.getWidgetSection(parent) || "right"
popupTarget: {
notepadSlideoutLoader.active = true
return notepadSlideoutLoader.item
}
parentScreen: root.screen
onClicked: {
notepadSlideoutLoader.active = true
notepadSlideoutLoader.item?.toggle()
}
}
}
}
}
}
}
}
}