fixed notifications font rendering
This commit is contained in:
@@ -5,24 +5,15 @@ import Quickshell.Wayland
|
||||
import Quickshell.Services.UPower
|
||||
|
||||
import "../../config" as Cfg
|
||||
import "../../components"
|
||||
|
||||
Rectangle {
|
||||
ModuleChip {
|
||||
id: root
|
||||
|
||||
property real panelRadius: Cfg.Config.radius / 2
|
||||
property int borderWidth: Cfg.Config.panelBorderWidth
|
||||
|
||||
property bool isTop: true
|
||||
property var targetScreen: null
|
||||
property int barHeight: Cfg.Config.barHeight
|
||||
property int barMargin: Cfg.Config.margin
|
||||
|
||||
readonly property var t: Cfg.Config.theme
|
||||
|
||||
readonly property var bat: UPower.displayDevice
|
||||
readonly property bool batReady: bat && bat.ready && bat.isLaptopBattery
|
||||
|
||||
readonly property bool moduleEnabled: batReady
|
||||
readonly property bool moduleEnabled: false
|
||||
|
||||
readonly property real pct: batReady ? bat.percentage * 100 : 72
|
||||
readonly property int state: batReady ? bat.state : UPowerDeviceState.Unknown
|
||||
@@ -163,53 +154,11 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
PanelWindow {
|
||||
PopupPanel {
|
||||
id: batteryPopup
|
||||
screen: root.targetScreen
|
||||
visible: false
|
||||
color: "transparent"
|
||||
|
||||
property bool popupOpen: false
|
||||
|
||||
function open() { hideTimer.stop(); visible = true; popupOpen = true }
|
||||
function close() { popupOpen = false; hideTimer.restart() }
|
||||
function toggle() { popupOpen ? close() : open() }
|
||||
|
||||
Timer {
|
||||
id: hideTimer
|
||||
interval: Cfg.Config.popupAnimDuration + 70
|
||||
onTriggered: batteryPopup.visible = false
|
||||
}
|
||||
|
||||
anchors { top: true; bottom: true; left: true; right: true }
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
WlrLayershell.namespace: "main-shell-battery"
|
||||
WlrLayershell.exclusiveZone: -1
|
||||
mask: popupOpen ? null : _noInput
|
||||
Region { id: _noInput }
|
||||
|
||||
TapHandler { onTapped: batteryPopup.close() }
|
||||
|
||||
Item {
|
||||
id: popupClipContainer
|
||||
readonly property int cardW: 260
|
||||
readonly property int screenPad: root.barMargin + 10
|
||||
|
||||
x: {
|
||||
let centerX = root.mapToItem(null, 0, 0).x + root.width / 2
|
||||
let desiredX = centerX - cardW / 2
|
||||
return Math.max(screenPad,
|
||||
Math.min(desiredX, parent.width - cardW - screenPad))
|
||||
}
|
||||
width: cardW
|
||||
|
||||
anchors.top: root.isTop ? parent.top : undefined
|
||||
anchors.bottom: root.isTop ? undefined : parent.bottom
|
||||
anchors.topMargin: root.isTop ? (root.barHeight + 10) : 0
|
||||
anchors.bottomMargin: root.isTop ? 0 : (root.barHeight + 10)
|
||||
height: parent.height - root.barHeight - 10
|
||||
|
||||
clip: true
|
||||
ns: "battery"
|
||||
chipRoot: root
|
||||
cardWidth: 260
|
||||
|
||||
Rectangle {
|
||||
id: cardShadow
|
||||
@@ -584,6 +533,5 @@ Rectangle {
|
||||
Item { height: 2 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,19 +6,9 @@ import Quickshell.Wayland
|
||||
import "../../config" as Cfg
|
||||
import "../../components"
|
||||
|
||||
Rectangle {
|
||||
ModuleChip {
|
||||
id: root
|
||||
|
||||
property real panelRadius: Cfg.Config.radius / 2
|
||||
property int borderWidth: Cfg.Config.panelBorderWidth
|
||||
|
||||
property bool isTop: true
|
||||
property var targetScreen: null
|
||||
property int barHeight: Cfg.Config.barHeight
|
||||
property int barMargin: Cfg.Config.margin
|
||||
|
||||
readonly property var t: Cfg.Config.theme
|
||||
|
||||
TimezoneProvider { id: timezone }
|
||||
|
||||
width: clockLayout.implicitWidth + 24
|
||||
@@ -92,52 +82,11 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
PanelWindow {
|
||||
PopupPanel {
|
||||
id: calendarPopup
|
||||
screen: root.targetScreen
|
||||
visible: false
|
||||
color: "transparent"
|
||||
|
||||
property bool popupOpen: false
|
||||
|
||||
function open() { hideTimer.stop(); visible = true; popupOpen = true }
|
||||
function close() { popupOpen = false; hideTimer.restart() }
|
||||
function toggle() { popupOpen ? close() : open() }
|
||||
|
||||
Timer {
|
||||
id: hideTimer
|
||||
interval: Cfg.Config.popupAnimDuration + 70
|
||||
onTriggered: calendarPopup.visible = false
|
||||
}
|
||||
|
||||
anchors { top: true; bottom: true; left: true; right: true }
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
WlrLayershell.namespace: "main-shell-calendar"
|
||||
WlrLayershell.exclusiveZone: -1
|
||||
mask: popupOpen ? null : _noInput
|
||||
Region { id: _noInput }
|
||||
|
||||
TapHandler { onTapped: calendarPopup.close() }
|
||||
|
||||
Item {
|
||||
id: calClipContainer
|
||||
readonly property int cardW: 284
|
||||
readonly property int screenPad: root.barMargin + 10
|
||||
|
||||
x: {
|
||||
let centerX = root.mapToItem(null, 0, 0).x + root.width / 2
|
||||
let desiredX = centerX - cardW / 2
|
||||
return Math.max(screenPad, Math.min(desiredX, parent.width - cardW - screenPad))
|
||||
}
|
||||
width: cardW
|
||||
|
||||
anchors.top: root.isTop ? parent.top : undefined
|
||||
anchors.bottom: root.isTop ? undefined : parent.bottom
|
||||
anchors.topMargin: root.isTop ? (root.barHeight + 10) : 0
|
||||
anchors.bottomMargin: root.isTop ? 0 : (root.barHeight + 10)
|
||||
height: parent.height - root.barHeight - 10
|
||||
|
||||
clip: true
|
||||
ns: "calendar"
|
||||
chipRoot: root
|
||||
cardWidth: 284
|
||||
|
||||
Rectangle {
|
||||
id: card
|
||||
@@ -407,6 +356,5 @@ Rectangle {
|
||||
Item { height: 4 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,18 +5,11 @@ import Quickshell.Wayland
|
||||
import Quickshell.Io
|
||||
|
||||
import "../../config" as Cfg
|
||||
import "../../components"
|
||||
|
||||
Rectangle {
|
||||
ModuleChip {
|
||||
id: root
|
||||
|
||||
property real panelRadius: Cfg.Config.radius / 2
|
||||
property int borderWidth: Cfg.Config.panelBorderWidth
|
||||
property bool isTop: true
|
||||
property var targetScreen: null
|
||||
property int barHeight: Cfg.Config.barHeight
|
||||
property int barMargin: Cfg.Config.margin
|
||||
|
||||
readonly property var t: Cfg.Config.theme
|
||||
readonly property var cfg: Cfg.Config
|
||||
|
||||
readonly property string configPath:
|
||||
@@ -43,36 +36,24 @@ Rectangle {
|
||||
Behavior on color { ColorAnimation { duration: 150 } }
|
||||
Behavior on border.color { ColorAnimation { duration: 150 } }
|
||||
|
||||
property var localPairs: [{ coin: cfg.cryptoCoinId ?? "bitcoin", currency: cfg.cryptoVsCurrency ?? "usd" }]
|
||||
property var localPairs: [{ coin: "bitcoin", currency: "usd" }]
|
||||
property int activeCoinIndex: 0
|
||||
readonly property string localCoinId: localPairs.length > 0
|
||||
? localPairs[activeCoinIndex % localPairs.length].coin
|
||||
: (cfg.cryptoCoinId ?? "bitcoin")
|
||||
: "bitcoin"
|
||||
readonly property string localActiveCurrency: localPairs.length > 0
|
||||
? localPairs[activeCoinIndex % localPairs.length].currency
|
||||
: (cfg.cryptoVsCurrency ?? "usd")
|
||||
: "usd"
|
||||
|
||||
property string localVsCur: cfg.cryptoVsCurrency ?? "usd"
|
||||
property string localVsCur: "usd"
|
||||
property int localDecimals: cfg.cryptoDecimals ?? 1
|
||||
property int localRefreshSec: cfg.cryptoRefreshSec ?? 60
|
||||
property bool localShowIcon: cfg.cryptoShowIcon ?? true
|
||||
|
||||
function resolveWithPersistence() {
|
||||
const cfgCoin = cfg.cryptoCoinId ?? "bitcoin"
|
||||
const cfgCur = cfg.cryptoVsCurrency ?? "usd"
|
||||
|
||||
let cfgPairs
|
||||
if (typeof cfg.cryptoPairs !== "undefined" && Array.isArray(cfg.cryptoPairs) && cfg.cryptoPairs.length > 0) {
|
||||
cfgPairs = cfg.cryptoPairs
|
||||
} else if (typeof cfg.cryptoCoinIds !== "undefined" && Array.isArray(cfg.cryptoCoinIds) && cfg.cryptoCoinIds.length > 0) {
|
||||
cfgPairs = cfg.cryptoCoinIds.map(c => ({ coin: c, currency: cfgCur }))
|
||||
} else {
|
||||
cfgPairs = [{ coin: cfgCoin, currency: cfgCur }]
|
||||
}
|
||||
|
||||
root.localPairs = cfgPairs
|
||||
root.localVsCur = cfgPairs.length > 0 ? cfgPairs[0].currency : cfgCur
|
||||
root.displayCurrency = cfgPairs.length > 0 ? cfgPairs[0].currency : cfgCur
|
||||
root.localPairs = Array.isArray(cfg.cryptoPairs) && cfg.cryptoPairs.length > 0 ? cfg.cryptoPairs : [{ coin: "bitcoin", currency: "usd" }]
|
||||
root.localVsCur = root.localPairs[0].currency
|
||||
root.displayCurrency = root.localPairs[0].currency
|
||||
root.activeCoinIndex = 0
|
||||
root.localDecimals = cfg.cryptoDecimals ?? 1
|
||||
root.localRefreshSec = cfg.cryptoRefreshSec ?? 60
|
||||
@@ -123,7 +104,7 @@ Rectangle {
|
||||
property string coinSymbol: localCoinId.toUpperCase().slice(0, 4)
|
||||
property string coinName: ""
|
||||
property string lastUpdated: ""
|
||||
property string displayCurrency: cfg.cryptoVsCurrency ?? "usd"
|
||||
property string displayCurrency: "usd"
|
||||
property bool loading: false
|
||||
property bool loadingVisible: false
|
||||
property bool hasError: false
|
||||
@@ -289,54 +270,18 @@ Rectangle {
|
||||
|
||||
}
|
||||
|
||||
PanelWindow {
|
||||
PopupPanel {
|
||||
id: cryptoPopup
|
||||
screen: root.targetScreen
|
||||
visible: false
|
||||
color: "transparent"
|
||||
ns: "crypto"
|
||||
chipRoot: root
|
||||
cardWidth: 300
|
||||
hasKeyboardFocus: true
|
||||
|
||||
property bool popupOpen: false
|
||||
property real popupCenterX: 0
|
||||
|
||||
function open() { popupCenterX = root.mapToItem(null, 0, 0).x + root.width / 2; hideTimer.stop(); visible = true; popupOpen = true }
|
||||
function close() { popupOpen = false; hideTimer.restart() }
|
||||
function toggle() { popupOpen ? close() : open() }
|
||||
|
||||
Timer {
|
||||
id: hideTimer
|
||||
interval: Cfg.Config.popupAnimDuration + 70
|
||||
onTriggered: cryptoPopup.visible = false
|
||||
function open() {
|
||||
popupCenterX = root.mapToItem(null, 0, 0).x + root.width / 2
|
||||
_doOpen()
|
||||
}
|
||||
|
||||
anchors { top: true; bottom: true; left: true; right: true }
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
WlrLayershell.namespace: "main-shell-crypto"
|
||||
WlrLayershell.exclusiveZone: -1
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
|
||||
mask: popupOpen ? null : _noInput
|
||||
Region { id: _noInput }
|
||||
|
||||
TapHandler { onTapped: cryptoPopup.close() }
|
||||
|
||||
Item {
|
||||
id: popClip
|
||||
readonly property int cardW: 300
|
||||
readonly property int screenPad: root.barMargin + 10
|
||||
|
||||
x: {
|
||||
let cx = cryptoPopup.popupCenterX
|
||||
return Math.max(screenPad,
|
||||
Math.min(cx - cardW / 2, parent.width - cardW - screenPad))
|
||||
}
|
||||
width: cardW
|
||||
|
||||
anchors.top: root.isTop ? parent.top : undefined
|
||||
anchors.bottom: root.isTop ? undefined : parent.bottom
|
||||
anchors.topMargin: root.isTop ? (root.barHeight + 10) : 0
|
||||
anchors.bottomMargin: root.isTop ? 0 : (root.barHeight + 10)
|
||||
height: parent.height - root.barHeight - 10
|
||||
clip: true
|
||||
|
||||
Rectangle {
|
||||
id: card
|
||||
width: parent.width
|
||||
@@ -1166,19 +1111,9 @@ Rectangle {
|
||||
MouseArea {
|
||||
anchors.fill: parent; cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
const cfgCoin = cfg.cryptoCoinId ?? "bitcoin"
|
||||
const cfgCur = cfg.cryptoVsCurrency ?? "usd"
|
||||
let cfgPairs
|
||||
if (typeof cfg.cryptoPairs !== "undefined" && Array.isArray(cfg.cryptoPairs) && cfg.cryptoPairs.length > 0) {
|
||||
cfgPairs = cfg.cryptoPairs
|
||||
} else if (typeof cfg.cryptoCoinIds !== "undefined" && Array.isArray(cfg.cryptoCoinIds) && cfg.cryptoCoinIds.length > 0) {
|
||||
cfgPairs = cfg.cryptoCoinIds.map(c => ({ coin: c, currency: cfgCur }))
|
||||
} else {
|
||||
cfgPairs = [{ coin: cfgCoin, currency: cfgCur }]
|
||||
}
|
||||
root.localPairs = cfgPairs
|
||||
root.localVsCur = cfgCur
|
||||
root.displayCurrency = cfgPairs.length > 0 ? cfgPairs[0].currency : cfgCur
|
||||
root.localPairs = Array.isArray(cfg.cryptoPairs) && cfg.cryptoPairs.length > 0 ? cfg.cryptoPairs : [{ coin: "bitcoin", currency: "usd" }]
|
||||
root.localVsCur = "usd"
|
||||
root.displayCurrency = root.localPairs.length > 0 ? root.localPairs[0].currency : "usd"
|
||||
root.activeCoinIndex = 0
|
||||
root.localDecimals = cfg.cryptoDecimals ?? 1
|
||||
root.localRefreshSec = cfg.cryptoRefreshSec ?? 60
|
||||
@@ -1195,6 +1130,5 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,11 @@
|
||||
import QtQuick
|
||||
|
||||
import "../../config" as Cfg
|
||||
import "../../components"
|
||||
|
||||
Rectangle {
|
||||
ModuleChip {
|
||||
id: root
|
||||
|
||||
property real panelRadius: Cfg.Config.radius / 2
|
||||
property int borderWidth: Cfg.Config.panelBorderWidth
|
||||
|
||||
property bool isTop: true
|
||||
property var targetScreen: null
|
||||
property int barHeight: Cfg.Config.barHeight
|
||||
property int barMargin: Cfg.Config.margin
|
||||
|
||||
readonly property var t: Cfg.Config.theme
|
||||
|
||||
property var launcher: null
|
||||
|
||||
readonly property bool launcherActive: !!launcher && launcher.isOpen
|
||||
|
||||
@@ -3,22 +3,13 @@ import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
import Quickshell.Networking
|
||||
import Quickshell.Services.Polkit
|
||||
|
||||
import "../../config" as Cfg
|
||||
import "../../components"
|
||||
|
||||
Rectangle {
|
||||
ModuleChip {
|
||||
id: root
|
||||
|
||||
property real panelRadius: Cfg.Config.radius / 2
|
||||
property int borderWidth: Cfg.Config.panelBorderWidth
|
||||
property bool isTop: true
|
||||
property var targetScreen: null
|
||||
property int barHeight: Cfg.Config.barHeight
|
||||
property int barMargin: Cfg.Config.margin
|
||||
|
||||
readonly property var t: Cfg.Config.theme
|
||||
|
||||
readonly property var wifiDevice: {
|
||||
for (const dev of (Networking.devices?.values ?? []))
|
||||
if (dev.type === DeviceType.Wifi) return dev
|
||||
@@ -159,58 +150,18 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
PanelWindow {
|
||||
PopupPanel {
|
||||
id: netPopup
|
||||
screen: root.targetScreen
|
||||
visible: false
|
||||
color: "transparent"
|
||||
|
||||
property bool popupOpen: false
|
||||
ns: "network"
|
||||
chipRoot: root
|
||||
cardWidth: 310
|
||||
|
||||
function open() {
|
||||
root.cancelConnect()
|
||||
hideTimer.stop()
|
||||
visible = true
|
||||
popupOpen = true
|
||||
_doOpen()
|
||||
if (root.hasWifi && root.wifiDevice)
|
||||
root.wifiDevice.scannerEnabled = true
|
||||
}
|
||||
function close() { popupOpen = false; hideTimer.restart() }
|
||||
function toggle() { popupOpen ? close() : open() }
|
||||
|
||||
Timer {
|
||||
id: hideTimer
|
||||
interval: Cfg.Config.popupAnimDuration + 70
|
||||
onTriggered: netPopup.visible = false
|
||||
}
|
||||
|
||||
anchors { top: true; bottom: true; left: true; right: true }
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
WlrLayershell.namespace: "main-shell-network"
|
||||
WlrLayershell.exclusiveZone: -1
|
||||
mask: netPopup.popupOpen ? null : _noInput
|
||||
Region { id: _noInput }
|
||||
|
||||
TapHandler { onTapped: netPopup.close() }
|
||||
|
||||
Item {
|
||||
id: popupClip
|
||||
readonly property int cardW: 310
|
||||
readonly property int screenPad: root.barMargin + 10
|
||||
|
||||
x: {
|
||||
var cx = root.mapToItem(null, 0, 0).x + root.width / 2
|
||||
var dx = cx - cardW / 2
|
||||
return Math.max(screenPad, Math.min(dx, parent.width - cardW - screenPad))
|
||||
}
|
||||
width: cardW
|
||||
|
||||
anchors.top: root.isTop ? parent.top : undefined
|
||||
anchors.bottom: root.isTop ? undefined : parent.bottom
|
||||
anchors.topMargin: root.isTop ? (root.barHeight + 10) : 0
|
||||
anchors.bottomMargin: root.isTop ? 0 : (root.barHeight + 10)
|
||||
height: parent.height - root.barHeight - 10
|
||||
clip: true
|
||||
|
||||
Rectangle {
|
||||
id: card
|
||||
@@ -723,6 +674,5 @@ Rectangle {
|
||||
Item { height: 4 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,18 +6,11 @@ import Quickshell.Wayland
|
||||
import Quickshell.Services.Notifications
|
||||
|
||||
import "../../config" as Cfg
|
||||
import "../../components"
|
||||
|
||||
Rectangle {
|
||||
ModuleChip {
|
||||
id: root
|
||||
|
||||
property real panelRadius: Cfg.Config.radius / 2
|
||||
property int borderWidth: Cfg.Config.panelBorderWidth
|
||||
property bool isTop: true
|
||||
property var targetScreen: null
|
||||
property int barHeight: Cfg.Config.barHeight
|
||||
property int barMargin: Cfg.Config.margin
|
||||
readonly property var t: Cfg.Config.theme
|
||||
|
||||
property int unreadCount: 0
|
||||
property bool doNotDisturb: false
|
||||
property bool historyOpen: historyPopup.popupOpen
|
||||
@@ -111,7 +104,6 @@ Rectangle {
|
||||
? toastRoot.t.notifUrgencyCritical
|
||||
: (cardHover.hovered ? toastRoot.t.notifBorderActive : toastRoot.t.notifToastBorder)
|
||||
border.width: Cfg.Config.popupBorderWidth
|
||||
layer.enabled: true
|
||||
|
||||
Behavior on color { ColorAnimation { duration: 150; easing.type: Easing.OutCubic } }
|
||||
Behavior on border.color { ColorAnimation { duration: 150 } }
|
||||
@@ -152,22 +144,26 @@ Rectangle {
|
||||
color: toastRoot.urgencyColor(toastRoot.urgency)
|
||||
font.pixelSize: 12
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
Text {
|
||||
text: toastRoot.appName
|
||||
color: toastRoot.t.notifToastAppName
|
||||
font.pixelSize: 11
|
||||
font.pixelSize: 12
|
||||
font.bold: true
|
||||
font.capitalization: Font.AllUppercase
|
||||
font.letterSpacing: 0.4
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
Text {
|
||||
text: toastRoot.timeStr
|
||||
color: toastRoot.t.notifToastDim
|
||||
font.pixelSize: 10
|
||||
font.pixelSize: 11
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
@@ -181,6 +177,7 @@ Rectangle {
|
||||
text: "✕"
|
||||
color: closeHover.hovered ? toastRoot.t.notifToastText : toastRoot.t.notifToastDim
|
||||
font.pixelSize: 10
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
HoverHandler { id: closeHover; cursorShape: Qt.PointingHandCursor }
|
||||
TapHandler { onTapped: toastRoot.triggerDismiss() }
|
||||
@@ -196,6 +193,7 @@ Rectangle {
|
||||
elide: Text.ElideRight
|
||||
textFormat: Text.PlainText
|
||||
visible: toastRoot.summary !== ""
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
Text {
|
||||
@@ -209,7 +207,8 @@ Rectangle {
|
||||
textFormat: Text.PlainText
|
||||
visible: toastRoot.body !== ""
|
||||
Layout.bottomMargin: toastRoot.urgency === NotificationUrgency.Low ? 6 : 0
|
||||
lineHeight: 1.15
|
||||
lineHeight: 1.2
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,7 +285,7 @@ Rectangle {
|
||||
Behavior on opacity { NumberAnimation { duration: 150 } }
|
||||
Behavior on color { ColorAnimation { duration: 150 } }
|
||||
|
||||
Text { anchors.centerIn: parent; text: "✕"; color: histRoot.t.notifToastText; font.pixelSize: 10 }
|
||||
Text { anchors.centerIn: parent; text: "✕"; color: histRoot.t.notifToastText; font.pixelSize: 10; renderType: Text.NativeRendering }
|
||||
HoverHandler { id: histCloseHover; cursorShape: Qt.PointingHandCursor }
|
||||
TapHandler { onTapped: dismissAnim.start() }
|
||||
}
|
||||
@@ -298,21 +297,24 @@ Rectangle {
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true; spacing: 5
|
||||
Text { text: histRoot.urgencyIcon(histRoot.urgency); color: histRoot.urgencyColor(histRoot.urgency); font.pixelSize: 11; Layout.alignment: Qt.AlignVCenter }
|
||||
Text { text: histRoot.urgencyIcon(histRoot.urgency); color: histRoot.urgencyColor(histRoot.urgency); font.pixelSize: 11; Layout.alignment: Qt.AlignVCenter; renderType: Text.NativeRendering }
|
||||
Text {
|
||||
text: histRoot.appName; color: histRoot.t.notifToastAppName; font.pixelSize: 11; font.bold: true
|
||||
font.capitalization: Font.AllUppercase; Layout.fillWidth: true; elide: Text.ElideRight; verticalAlignment: Text.AlignVCenter
|
||||
text: histRoot.appName; color: histRoot.t.notifToastAppName; font.pixelSize: 12; font.bold: true
|
||||
font.capitalization: Font.AllUppercase; font.letterSpacing: 0.4; Layout.fillWidth: true; elide: Text.ElideRight; verticalAlignment: Text.AlignVCenter
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
Text { text: histRoot.timeStr; color: histRoot.t.notifToastDim; font.pixelSize: 11; verticalAlignment: Text.AlignVCenter }
|
||||
Text { text: histRoot.timeStr; color: histRoot.t.notifToastDim; font.pixelSize: 11; verticalAlignment: Text.AlignVCenter; renderType: Text.NativeRendering }
|
||||
}
|
||||
|
||||
Text {
|
||||
text: histRoot.summary; color: histRoot.t.notifToastText; font.pixelSize: 13; font.bold: true
|
||||
Layout.fillWidth: true; elide: Text.ElideRight; textFormat: Text.PlainText; visible: histRoot.summary !== ""
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
Text {
|
||||
text: histRoot.body; color: histRoot.t.notifToastDim; font.pixelSize: 12; Layout.fillWidth: true
|
||||
wrapMode: Text.WordWrap; maximumLineCount: 2; elide: Text.ElideRight; textFormat: Text.PlainText; visible: histRoot.body !== ""; lineHeight: 1.15
|
||||
wrapMode: Text.WordWrap; maximumLineCount: 2; elide: Text.ElideRight; textFormat: Text.PlainText; visible: histRoot.body !== ""; lineHeight: 1.2
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -375,6 +377,7 @@ Rectangle {
|
||||
color: t.notifBadgeText
|
||||
font.pixelSize: 8
|
||||
font.bold: true
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -574,7 +577,6 @@ Rectangle {
|
||||
radius: Cfg.Config.popupRadius
|
||||
border.color: t.notifHistoryBorder
|
||||
border.width: Cfg.Config.popupBorderWidth
|
||||
layer.enabled: true
|
||||
|
||||
MouseArea { anchors.fill: parent; propagateComposedEvents: false }
|
||||
|
||||
@@ -584,10 +586,10 @@ Rectangle {
|
||||
anchors.topMargin: 20; anchors.leftMargin: 20; anchors.rightMargin: 20
|
||||
spacing: 10
|
||||
|
||||
Text { text: ""; color: t.notifToastAppName; font.pixelSize: 18; Layout.alignment: Qt.AlignVCenter }
|
||||
Text { text: ""; color: t.notifToastAppName; font.pixelSize: 18; Layout.alignment: Qt.AlignVCenter; renderType: Text.NativeRendering }
|
||||
Text {
|
||||
text: "Notifications"; color: t.notifToastAppName; font.pixelSize: 15; font.bold: true
|
||||
Layout.fillWidth: true; Layout.alignment: Qt.AlignVCenter
|
||||
Layout.fillWidth: true; Layout.alignment: Qt.AlignVCenter; renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
@@ -613,6 +615,7 @@ Rectangle {
|
||||
font.pixelSize: 12
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Behavior on color { ColorAnimation { duration: 150 } }
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
Text {
|
||||
text: root.doNotDisturb ? "On" : "Off"
|
||||
@@ -621,6 +624,7 @@ Rectangle {
|
||||
font.bold: root.doNotDisturb
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Behavior on color { ColorAnimation { duration: 150 } }
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
}
|
||||
|
||||
@@ -637,7 +641,7 @@ Rectangle {
|
||||
color: clearHover.hovered ? t.notifHistoryHover : "transparent"
|
||||
Behavior on color { ColorAnimation { duration: 150 } }
|
||||
|
||||
Text { id: clearText; anchors.centerIn: parent; text: "Clear all"; color: t.notifToastDim; font.pixelSize: 11 }
|
||||
Text { id: clearText; anchors.centerIn: parent; text: "Clear all"; color: t.notifToastDim; font.pixelSize: 11; renderType: Text.NativeRendering }
|
||||
HoverHandler { id: clearHover; cursorShape: Qt.PointingHandCursor }
|
||||
TapHandler { onTapped: clearAllAnim.start() }
|
||||
}
|
||||
@@ -689,8 +693,8 @@ Rectangle {
|
||||
width: histCol.width - 16; height: 90; visible: notifHistory.count === 0
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent; spacing: 8
|
||||
Text { text: ""; color: t.notifHistoryEmpty; font.pixelSize: 30; Layout.alignment: Qt.AlignHCenter }
|
||||
Text { text: "No notifications"; color: t.notifHistoryEmpty; font.pixelSize: 12; Layout.alignment: Qt.AlignHCenter }
|
||||
Text { text: ""; color: t.notifHistoryEmpty; font.pixelSize: 30; Layout.alignment: Qt.AlignHCenter; renderType: Text.NativeRendering }
|
||||
Text { text: "No notifications"; color: t.notifHistoryEmpty; font.pixelSize: 12; Layout.alignment: Qt.AlignHCenter; renderType: Text.NativeRendering }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,16 +3,11 @@ import QtQuick.Layouts
|
||||
import Quickshell.Io
|
||||
|
||||
import "../../config" as Cfg
|
||||
import "../../components"
|
||||
|
||||
Rectangle {
|
||||
ModuleChip {
|
||||
id: root
|
||||
|
||||
property real panelRadius: Cfg.Config.radius / 2
|
||||
property int borderWidth: Cfg.Config.panelBorderWidth
|
||||
property int barHeight: Cfg.Config.barHeight
|
||||
property int barMargin: Cfg.Config.margin
|
||||
readonly property var t: Cfg.Config.theme
|
||||
|
||||
width: statsLayout.implicitWidth + 20
|
||||
height: Cfg.Config.moduleHeight
|
||||
color: t.statsBg
|
||||
|
||||
@@ -239,6 +239,130 @@ Item {
|
||||
|
||||
QsMenuOpener { id: rootMenuOpener }
|
||||
|
||||
Component {
|
||||
id: trayMenuItemComponent
|
||||
|
||||
Item {
|
||||
id: menuItem
|
||||
required property var modelData
|
||||
readonly property bool isSep: modelData.isSeparator
|
||||
|
||||
width: parent.width
|
||||
height: isSep ? 5 : 32
|
||||
|
||||
Rectangle {
|
||||
visible: isSep
|
||||
anchors {
|
||||
left: parent.left; right: parent.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
anchors.leftMargin: 8; anchors.rightMargin: 8
|
||||
height: 1
|
||||
color: root.tmSeparator
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
visible: !isSep
|
||||
anchors.fill: parent
|
||||
anchors.margins: 2
|
||||
radius: 10
|
||||
readonly property bool active: menuMouse.containsMouse
|
||||
|| (submenuCard.visible
|
||||
&& trayMenuPopup._submenuParentRef === menuItem)
|
||||
color: active ? root.tmHover : "transparent"
|
||||
Behavior on color { ColorAnimation { duration: 120 } }
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 8; anchors.rightMargin: 8
|
||||
spacing: 8
|
||||
|
||||
Item {
|
||||
Layout.preferredWidth: 16
|
||||
Layout.preferredHeight: 16
|
||||
visible: !isSep
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
visible: modelData.buttonType === QsMenuButtonType.CheckBox
|
||||
&& modelData.checkState === Qt.Checked
|
||||
text: "✓"; color: root.tmCheck
|
||||
font.pixelSize: 14
|
||||
}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
visible: modelData.buttonType === QsMenuButtonType.RadioButton
|
||||
&& modelData.checkState === Qt.Checked
|
||||
text: "●"; color: root.tmCheck
|
||||
font.pixelSize: 9
|
||||
}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
visible: modelData.buttonType === QsMenuButtonType.RadioButton
|
||||
&& modelData.checkState !== Qt.Checked
|
||||
text: "○"; color: root.tmDim
|
||||
font.pixelSize: 11
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
visible: !isSep && modelData.icon !== ""
|
||||
source: modelData.icon
|
||||
width: 16; height: 16
|
||||
sourceSize: Qt.size(16, 16)
|
||||
fillMode: Image.PreserveAspectFit
|
||||
}
|
||||
|
||||
Text {
|
||||
text: modelData.text
|
||||
color: modelData.enabled ? root.tmText : root.tmDim
|
||||
font.pixelSize: 13
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
Text {
|
||||
visible: !isSep && modelData.hasChildren
|
||||
text: "▶"
|
||||
color: root.tmDim
|
||||
font.pixelSize: 9
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: menuMouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
enabled: !isSep && modelData.enabled
|
||||
|
||||
onClicked: {
|
||||
if (modelData.hasChildren) {
|
||||
closeSubmenuTimer.stop()
|
||||
submenuDelayTimer.itemRef = menuItem
|
||||
submenuDelayTimer.restart()
|
||||
} else {
|
||||
modelData.triggered()
|
||||
trayMenuPopup.close()
|
||||
}
|
||||
}
|
||||
onEntered: {
|
||||
if (modelData.hasChildren) {
|
||||
closeSubmenuTimer.stop()
|
||||
submenuDelayTimer.itemRef = menuItem
|
||||
submenuDelayTimer.restart()
|
||||
} else {
|
||||
closeSubmenuTimer.stop()
|
||||
submenuCard.visible = false
|
||||
}
|
||||
}
|
||||
onExited: {
|
||||
if (modelData.hasChildren)
|
||||
closeSubmenuTimer.restart()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: menuCardWrapper
|
||||
@@ -301,133 +425,7 @@ Item {
|
||||
|
||||
Repeater {
|
||||
model: rootMenuOpener.children
|
||||
|
||||
delegate: Item {
|
||||
id: menuDelegate
|
||||
required property var modelData
|
||||
property bool isSep: modelData.isSeparator
|
||||
|
||||
width: menuCol.width
|
||||
height: isSep ? 5 : 32
|
||||
|
||||
Rectangle {
|
||||
visible: isSep
|
||||
anchors {
|
||||
left: parent.left; right: parent.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
anchors.leftMargin: 8
|
||||
anchors.rightMargin: 8
|
||||
height: 1
|
||||
color: root.tmSeparator
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: itemBg
|
||||
visible: !isSep
|
||||
anchors.fill: parent
|
||||
anchors.margins: 2
|
||||
radius: 10
|
||||
property bool active: itemMouse.containsMouse
|
||||
|| (submenuCard.visible
|
||||
&& trayMenuPopup._submenuParentRef === menuDelegate)
|
||||
color: active ? root.tmHover : "transparent"
|
||||
Behavior on color { ColorAnimation { duration: 120 } }
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 8
|
||||
anchors.rightMargin: 8
|
||||
spacing: 8
|
||||
|
||||
Item {
|
||||
Layout.preferredWidth: 16
|
||||
Layout.preferredHeight: 16
|
||||
visible: !isSep
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
visible: modelData.buttonType === QsMenuButtonType.CheckBox
|
||||
&& modelData.checkState === Qt.Checked
|
||||
text: "✓"
|
||||
color: root.tmCheck
|
||||
font.pixelSize: 14
|
||||
}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
visible: modelData.buttonType === QsMenuButtonType.RadioButton
|
||||
&& modelData.checkState === Qt.Checked
|
||||
text: "●"
|
||||
color: root.tmCheck
|
||||
font.pixelSize: 9
|
||||
}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
visible: modelData.buttonType === QsMenuButtonType.RadioButton
|
||||
&& modelData.checkState !== Qt.Checked
|
||||
text: "○"
|
||||
color: root.tmDim
|
||||
font.pixelSize: 11
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
visible: !isSep && modelData.icon !== ""
|
||||
source: modelData.icon
|
||||
width: 16; height: 16
|
||||
sourceSize: Qt.size(16, 16)
|
||||
fillMode: Image.PreserveAspectFit
|
||||
}
|
||||
|
||||
Text {
|
||||
text: modelData.text
|
||||
color: modelData.enabled ? root.tmText : root.tmDim
|
||||
font.pixelSize: 13
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
Text {
|
||||
visible: !isSep && modelData.hasChildren
|
||||
text: "▶"
|
||||
color: root.tmDim
|
||||
font.pixelSize: 9
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: itemMouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
enabled: !isSep && modelData.enabled
|
||||
|
||||
onClicked: {
|
||||
if (modelData.hasChildren) {
|
||||
closeSubmenuTimer.stop()
|
||||
submenuDelayTimer.itemRef = menuDelegate
|
||||
submenuDelayTimer.restart()
|
||||
} else {
|
||||
modelData.triggered()
|
||||
trayMenuPopup.close()
|
||||
}
|
||||
}
|
||||
onEntered: {
|
||||
if (modelData.hasChildren) {
|
||||
closeSubmenuTimer.stop()
|
||||
submenuDelayTimer.itemRef = menuDelegate
|
||||
submenuDelayTimer.restart()
|
||||
} else {
|
||||
closeSubmenuTimer.stop()
|
||||
submenuCard.visible = false
|
||||
}
|
||||
}
|
||||
onExited: {
|
||||
if (modelData.hasChildren)
|
||||
closeSubmenuTimer.restart()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delegate: trayMenuItemComponent
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -515,96 +513,7 @@ Item {
|
||||
|
||||
Repeater {
|
||||
model: subMenuOpener.children
|
||||
|
||||
delegate: Item {
|
||||
required property var modelData
|
||||
property bool isSep: modelData.isSeparator
|
||||
|
||||
width: submenuCol.width
|
||||
height: isSep ? 5 : 32
|
||||
|
||||
Rectangle {
|
||||
visible: isSep
|
||||
anchors {
|
||||
left: parent.left; right: parent.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
anchors.leftMargin: 8; anchors.rightMargin: 8
|
||||
height: 1
|
||||
color: root.tmSeparator
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: subBg
|
||||
visible: !isSep
|
||||
anchors.fill: parent
|
||||
anchors.margins: 2
|
||||
radius: 10
|
||||
color: subMouse.containsMouse ? root.tmHover : "transparent"
|
||||
Behavior on color { ColorAnimation { duration: 120 } }
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 8; anchors.rightMargin: 8
|
||||
spacing: 8
|
||||
|
||||
Item {
|
||||
Layout.preferredWidth: 16
|
||||
Layout.preferredHeight: 16
|
||||
visible: !isSep
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
visible: modelData.buttonType === QsMenuButtonType.CheckBox
|
||||
&& modelData.checkState === Qt.Checked
|
||||
text: "✓"; color: root.tmCheck
|
||||
font.pixelSize: 14
|
||||
}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
visible: modelData.buttonType === QsMenuButtonType.RadioButton
|
||||
&& modelData.checkState === Qt.Checked
|
||||
text: "●"; color: root.tmCheck
|
||||
font.pixelSize: 9
|
||||
}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
visible: modelData.buttonType === QsMenuButtonType.RadioButton
|
||||
&& modelData.checkState !== Qt.Checked
|
||||
text: "○"; color: root.tmDim
|
||||
font.pixelSize: 11
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
visible: !isSep && modelData.icon !== ""
|
||||
source: modelData.icon
|
||||
width: 16; height: 16
|
||||
sourceSize: Qt.size(16, 16)
|
||||
fillMode: Image.PreserveAspectFit
|
||||
}
|
||||
|
||||
Text {
|
||||
text: modelData.text
|
||||
color: modelData.enabled ? root.tmText : root.tmDim
|
||||
font.pixelSize: 13
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: subMouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
enabled: !isSep && modelData.enabled
|
||||
onClicked: {
|
||||
modelData.triggered()
|
||||
trayMenuPopup.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delegate: trayMenuItemComponent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,19 +6,11 @@ import Quickshell.Wayland
|
||||
import Quickshell.Services.Pipewire
|
||||
|
||||
import "../../config" as Cfg
|
||||
import "../../components"
|
||||
|
||||
Rectangle {
|
||||
ModuleChip {
|
||||
id: root
|
||||
|
||||
property real panelRadius: Cfg.Config.radius / 2
|
||||
property int borderWidth: Cfg.Config.panelBorderWidth
|
||||
property bool isTop: true
|
||||
property var targetScreen: null
|
||||
property int barHeight: Cfg.Config.barHeight
|
||||
property int barMargin: Cfg.Config.margin
|
||||
|
||||
readonly property var t: Cfg.Config.theme
|
||||
|
||||
property int outputMaxVolume: Cfg.Config.volumeOutputMax
|
||||
property int inputMaxVolume: Cfg.Config.volumeInputMax
|
||||
|
||||
@@ -165,54 +157,11 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
PanelWindow {
|
||||
PopupPanel {
|
||||
id: volumePopup
|
||||
screen: root.targetScreen
|
||||
visible: false
|
||||
color: "transparent"
|
||||
|
||||
property bool popupOpen: false
|
||||
|
||||
function open() { hideTimer.stop(); visible = true; popupOpen = true }
|
||||
function close() { popupOpen = false; hideTimer.restart() }
|
||||
function toggle() { popupOpen ? close() : open() }
|
||||
|
||||
Timer {
|
||||
id: hideTimer
|
||||
interval: Cfg.Config.popupAnimDuration + 70
|
||||
onTriggered: volumePopup.visible = false
|
||||
}
|
||||
|
||||
anchors { top: true; bottom: true; left: true; right: true }
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
WlrLayershell.namespace: "main-shell-volume"
|
||||
WlrLayershell.exclusiveZone: -1
|
||||
mask: popupOpen ? null : _noInput
|
||||
Region { id: _noInput }
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: volumePopup.close()
|
||||
}
|
||||
|
||||
Item {
|
||||
id: volClipContainer
|
||||
readonly property int cardW: Cfg.Config.volumePopupWidth
|
||||
readonly property int screenPad: root.barMargin + 10
|
||||
|
||||
x: {
|
||||
let cx = root.mapToItem(null, 0, 0).x + root.width / 2
|
||||
return Math.max(screenPad, Math.min(cx - cardW / 2, parent.width - cardW - screenPad))
|
||||
}
|
||||
width: cardW
|
||||
|
||||
anchors.top: root.isTop ? parent.top : undefined
|
||||
anchors.bottom: root.isTop ? undefined : parent.bottom
|
||||
anchors.topMargin: root.isTop ? (root.barHeight + 10) : 0
|
||||
anchors.bottomMargin: root.isTop ? 0 : (root.barHeight + 10)
|
||||
height: parent.height - root.barHeight - 10
|
||||
|
||||
clip: true
|
||||
ns: "volume"
|
||||
chipRoot: root
|
||||
cardWidth: Cfg.Config.volumePopupWidth
|
||||
|
||||
Rectangle {
|
||||
id: volCard
|
||||
@@ -340,7 +289,6 @@ Rectangle {
|
||||
Item { height: 2 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component VolumeSection: ColumnLayout {
|
||||
|
||||
@@ -3,15 +3,11 @@ import QtQuick.Layouts
|
||||
import Quickshell.Hyprland
|
||||
|
||||
import "../../config" as Cfg
|
||||
import "../../components"
|
||||
|
||||
Rectangle {
|
||||
ModuleChip {
|
||||
id: root
|
||||
|
||||
property real panelRadius: Cfg.Config.radius / 2
|
||||
property int borderWidth: Cfg.Config.panelBorderWidth
|
||||
|
||||
readonly property var t: Cfg.Config.theme
|
||||
|
||||
width: workspaceLayout.implicitWidth + 24
|
||||
height: Cfg.Config.moduleHeight
|
||||
color: t.wsPanelBg
|
||||
|
||||
16
components/ModuleChip.qml
Normal file
16
components/ModuleChip.qml
Normal file
@@ -0,0 +1,16 @@
|
||||
import QtQuick
|
||||
import "../config" as Cfg
|
||||
|
||||
Rectangle {
|
||||
id: chip
|
||||
|
||||
property real panelRadius: Cfg.Config.radius / 2
|
||||
property int borderWidth: Cfg.Config.panelBorderWidth
|
||||
property bool isTop: true
|
||||
property var targetScreen: null
|
||||
property int barHeight: Cfg.Config.barHeight
|
||||
property int barMargin: Cfg.Config.margin
|
||||
readonly property var t: Cfg.Config.theme
|
||||
|
||||
property bool moduleEnabled: true
|
||||
}
|
||||
68
components/PopupPanel.qml
Normal file
68
components/PopupPanel.qml
Normal file
@@ -0,0 +1,68 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
import "../config" as Cfg
|
||||
|
||||
PanelWindow {
|
||||
id: popup
|
||||
|
||||
property string ns: ""
|
||||
property var chipRoot: null
|
||||
property int cardWidth: 260
|
||||
property bool hasKeyboardFocus: false
|
||||
|
||||
property alias clipItem: popupClip
|
||||
default property alias content: popupClip.data
|
||||
|
||||
screen: chipRoot ? chipRoot.targetScreen : null
|
||||
visible: false
|
||||
color: "transparent"
|
||||
|
||||
property bool popupOpen: false
|
||||
property real popupCenterX: -1
|
||||
|
||||
function _doOpen() { hideTimer.stop(); visible = true; popupOpen = true }
|
||||
function open() {
|
||||
if (popupCenterX < 0 && chipRoot)
|
||||
popupCenterX = chipRoot.mapToItem(null, 0, 0).x + chipRoot.width / 2
|
||||
_doOpen()
|
||||
}
|
||||
function close() { popupOpen = false; hideTimer.restart() }
|
||||
function toggle() { popupOpen ? close() : open() }
|
||||
|
||||
Timer {
|
||||
id: hideTimer
|
||||
interval: Cfg.Config.popupAnimDuration + 70
|
||||
onTriggered: popup.visible = false
|
||||
}
|
||||
|
||||
anchors { top: true; bottom: true; left: true; right: true }
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
WlrLayershell.namespace: "main-shell-" + ns
|
||||
WlrLayershell.exclusiveZone: -1
|
||||
WlrLayershell.keyboardFocus: hasKeyboardFocus ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
||||
mask: popupOpen ? null : _noInput
|
||||
Region { id: _noInput }
|
||||
|
||||
TapHandler { onTapped: popup.close() }
|
||||
|
||||
Item {
|
||||
id: popupClip
|
||||
property int screenPad: chipRoot ? chipRoot.barMargin + 10 : 30
|
||||
|
||||
x: {
|
||||
if (!chipRoot && popupCenterX < 0) return 0
|
||||
let cx = popupCenterX >= 0 ? popupCenterX : chipRoot.mapToItem(null, 0, 0).x + chipRoot.width / 2
|
||||
return Math.max(screenPad, Math.min(cx - cardWidth / 2, parent.width - cardWidth - screenPad))
|
||||
}
|
||||
width: cardWidth
|
||||
|
||||
anchors.top: chipRoot && chipRoot.isTop ? parent.top : undefined
|
||||
anchors.bottom: chipRoot && chipRoot.isTop ? undefined : parent.bottom
|
||||
anchors.topMargin: chipRoot && chipRoot.isTop ? (chipRoot.barHeight + 10) : 0
|
||||
anchors.bottomMargin: chipRoot && chipRoot.isTop ? 0 : (chipRoot.barHeight + 10)
|
||||
height: chipRoot ? parent.height - chipRoot.barHeight - 10 : parent.height
|
||||
|
||||
clip: true
|
||||
}
|
||||
}
|
||||
@@ -129,11 +129,6 @@ QtObject {
|
||||
// Settings popup and those changes are persisted across restarts.
|
||||
property var cryptoPairs: [{ coin: "bitcoin", currency: "usd" }, { coin: "ethereum", currency: "eur" }, { coin: "monero", currency: "usd" }, { coin: "solana", currency: "brl" }]
|
||||
|
||||
// Legacy fallbacks – used by Crypto.qml when cryptoPairs is absent.
|
||||
// You can leave these as-is; they are derived from the first pair above.
|
||||
property string cryptoCoinId: cryptoPairs[0].coin ?? "bitcoin"
|
||||
property string cryptoVsCurrency: cryptoPairs[0].currency ?? "usd"
|
||||
|
||||
// ── Compact label decimals ────────────────────────────────────────────────
|
||||
// 0 → "80k"
|
||||
// 1 → "80.0k" (default)
|
||||
|
||||
@@ -430,3 +430,4 @@ PanelWindow {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
import Quickshell.Services.Polkit
|
||||
|
||||
Reference in New Issue
Block a user