forked from Shinonome/dots-hyprland
Merge branch 'end-4:main' into main
This commit is contained in:
@@ -27,6 +27,23 @@ Singleton {
|
|||||||
property bool superReleaseMightTrigger: true
|
property bool superReleaseMightTrigger: true
|
||||||
property bool workspaceShowNumbers: false
|
property bool workspaceShowNumbers: false
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: Config
|
||||||
|
function onReadyChanged() {
|
||||||
|
if (Config.options.lock.launchOnStartup && Config.ready && Persistent.ready && Persistent.isNewHyprlandInstance) {
|
||||||
|
GlobalStates.screenLocked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Connections {
|
||||||
|
target: Persistent
|
||||||
|
function onReadyChanged() {
|
||||||
|
if (Config.options.lock.launchOnStartup && Config.ready && Persistent.ready && Persistent.isNewHyprlandInstance) {
|
||||||
|
GlobalStates.screenLocked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
property real screenZoom: 1
|
property real screenZoom: 1
|
||||||
onScreenZoomChanged: {
|
onScreenZoomChanged: {
|
||||||
Quickshell.execDetached(["hyprctl", "keyword", "cursor:zoom_factor", root.screenZoom.toString()]);
|
Quickshell.execDetached(["hyprctl", "keyword", "cursor:zoom_factor", root.screenZoom.toString()]);
|
||||||
|
|||||||
@@ -175,16 +175,10 @@ Variants {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
Image {
|
StyledImage {
|
||||||
id: wallpaper
|
id: wallpaper
|
||||||
visible: opacity > 0 && !blurLoader.active
|
visible: opacity > 0 && !blurLoader.active
|
||||||
opacity: (status === Image.Ready && !bgRoot.wallpaperIsVideo) ? 1 : 0
|
|
||||||
Behavior on opacity {
|
|
||||||
animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this)
|
|
||||||
}
|
|
||||||
cache: false
|
cache: false
|
||||||
asynchronous: true
|
|
||||||
retainWhileLoading: true
|
|
||||||
smooth: false
|
smooth: false
|
||||||
// Range = groups that workspaces span on
|
// Range = groups that workspaces span on
|
||||||
property int chunkSize: Config?.options.bar.workspaces.shown ?? 10
|
property int chunkSize: Config?.options.bar.workspaces.shown ?? 10
|
||||||
@@ -300,9 +294,7 @@ Variants {
|
|||||||
easing.bezierCurve: Appearance.animation.elementMove.bezierCurve
|
easing.bezierCurve: Appearance.animation.elementMove.bezierCurve
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sourceComponent: ColumnLayout {
|
sourceComponent: Column {
|
||||||
spacing: 8
|
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: digitalClockLoader
|
id: digitalClockLoader
|
||||||
visible: root.clockStyle === "digital"
|
visible: root.clockStyle === "digital"
|
||||||
@@ -340,7 +332,6 @@ Variants {
|
|||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: cookieClockLoader
|
id: cookieClockLoader
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
visible: root.clockStyle === "cookie"
|
visible: root.clockStyle === "cookie"
|
||||||
active: visible
|
active: visible
|
||||||
sourceComponent: CookieClock {}
|
sourceComponent: CookieClock {}
|
||||||
@@ -432,7 +423,7 @@ Variants {
|
|||||||
styleColor: Appearance.colors.colShadow
|
styleColor: Appearance.colors.colShadow
|
||||||
animateChange: true
|
animateChange: true
|
||||||
}
|
}
|
||||||
component ClockStatusText: RowLayout {
|
component ClockStatusText: Row {
|
||||||
id: statusTextRow
|
id: statusTextRow
|
||||||
property alias statusIcon: statusIconWidget.text
|
property alias statusIcon: statusIconWidget.text
|
||||||
property alias statusText: statusTextWidget.text
|
property alias statusText: statusTextWidget.text
|
||||||
@@ -443,10 +434,10 @@ Variants {
|
|||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||||
}
|
}
|
||||||
Layout.fillWidth: false
|
spacing: 4
|
||||||
MaterialSymbol {
|
MaterialSymbol {
|
||||||
id: statusIconWidget
|
id: statusIconWidget
|
||||||
Layout.fillWidth: false
|
anchors.verticalCenter: statusTextRow.verticalCenter
|
||||||
iconSize: Appearance.font.pixelSize.huge
|
iconSize: Appearance.font.pixelSize.huge
|
||||||
color: statusTextRow.textColor
|
color: statusTextRow.textColor
|
||||||
style: Text.Raised
|
style: Text.Raised
|
||||||
@@ -454,8 +445,8 @@ Variants {
|
|||||||
}
|
}
|
||||||
ClockText {
|
ClockText {
|
||||||
id: statusTextWidget
|
id: statusTextWidget
|
||||||
Layout.fillWidth: false
|
|
||||||
color: statusTextRow.textColor
|
color: statusTextRow.textColor
|
||||||
|
anchors.verticalCenter: statusTextRow.verticalCenter
|
||||||
font {
|
font {
|
||||||
family: Appearance.font.family.main
|
family: Appearance.font.family.main
|
||||||
pixelSize: Appearance.font.pixelSize.large
|
pixelSize: Appearance.font.pixelSize.large
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ Item { // Bar content region
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout { // Middle section
|
Row { // Middle section
|
||||||
id: middleSection
|
id: middleSection
|
||||||
anchors {
|
anchors {
|
||||||
top: parent.top
|
top: parent.top
|
||||||
@@ -108,8 +108,8 @@ Item { // Bar content region
|
|||||||
|
|
||||||
BarGroup {
|
BarGroup {
|
||||||
id: leftCenterGroup
|
id: leftCenterGroup
|
||||||
Layout.preferredWidth: root.centerSideModuleWidth
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
Layout.fillHeight: false
|
implicitWidth: root.centerSideModuleWidth
|
||||||
|
|
||||||
Resources {
|
Resources {
|
||||||
alwaysShowAllResources: root.useShortenedForm === 2
|
alwaysShowAllResources: root.useShortenedForm === 2
|
||||||
@@ -128,6 +128,7 @@ Item { // Bar content region
|
|||||||
|
|
||||||
BarGroup {
|
BarGroup {
|
||||||
id: middleCenterGroup
|
id: middleCenterGroup
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
padding: workspacesWidget.widgetPadding
|
padding: workspacesWidget.widgetPadding
|
||||||
|
|
||||||
Workspaces {
|
Workspaces {
|
||||||
@@ -153,9 +154,9 @@ Item { // Bar content region
|
|||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: rightCenterGroup
|
id: rightCenterGroup
|
||||||
implicitWidth: rightCenterGroupContent.implicitWidth
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
implicitWidth: root.centerSideModuleWidth
|
||||||
implicitHeight: rightCenterGroupContent.implicitHeight
|
implicitHeight: rightCenterGroupContent.implicitHeight
|
||||||
Layout.preferredWidth: root.centerSideModuleWidth
|
|
||||||
|
|
||||||
onPressed: {
|
onPressed: {
|
||||||
GlobalStates.sidebarRightOpen = !GlobalStates.sidebarRightOpen;
|
GlobalStates.sidebarRightOpen = !GlobalStates.sidebarRightOpen;
|
||||||
|
|||||||
@@ -14,11 +14,12 @@ StyledPopup {
|
|||||||
spacing: 4
|
spacing: 4
|
||||||
|
|
||||||
// Header
|
// Header
|
||||||
RowLayout {
|
Row {
|
||||||
id: header
|
id: header
|
||||||
spacing: 5
|
spacing: 5
|
||||||
|
|
||||||
MaterialSymbol {
|
MaterialSymbol {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
fill: 0
|
fill: 0
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
text: "battery_android_full"
|
text: "battery_android_full"
|
||||||
@@ -27,6 +28,7 @@ StyledPopup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: "Battery"
|
text: "Battery"
|
||||||
font {
|
font {
|
||||||
weight: Font.Medium
|
weight: Font.Medium
|
||||||
|
|||||||
@@ -39,10 +39,11 @@ StyledPopup {
|
|||||||
spacing: 4
|
spacing: 4
|
||||||
|
|
||||||
// Date + Time row
|
// Date + Time row
|
||||||
RowLayout {
|
Row {
|
||||||
spacing: 5
|
spacing: 5
|
||||||
|
|
||||||
MaterialSymbol {
|
MaterialSymbol {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
fill: 0
|
fill: 0
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
text: "calendar_month"
|
text: "calendar_month"
|
||||||
@@ -50,6 +51,7 @@ StyledPopup {
|
|||||||
color: Appearance.colors.colOnSurfaceVariant
|
color: Appearance.colors.colOnSurfaceVariant
|
||||||
}
|
}
|
||||||
StyledText {
|
StyledText {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
color: Appearance.colors.colOnSurfaceVariant
|
color: Appearance.colors.colOnSurfaceVariant
|
||||||
text: `${root.formattedDate}`
|
text: `${root.formattedDate}`
|
||||||
@@ -79,26 +81,26 @@ StyledPopup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Tasks
|
// Tasks
|
||||||
ColumnLayout {
|
Column {
|
||||||
spacing: 0
|
spacing: 0
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
RowLayout {
|
Row {
|
||||||
spacing: 4
|
spacing: 4
|
||||||
Layout.fillWidth: true
|
|
||||||
MaterialSymbol {
|
MaterialSymbol {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: "checklist"
|
text: "checklist"
|
||||||
color: Appearance.colors.colOnSurfaceVariant
|
color: Appearance.colors.colOnSurfaceVariant
|
||||||
font.pixelSize: Appearance.font.pixelSize.large
|
font.pixelSize: Appearance.font.pixelSize.large
|
||||||
}
|
}
|
||||||
StyledText {
|
StyledText {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: Translation.tr("To Do:")
|
text: Translation.tr("To Do:")
|
||||||
color: Appearance.colors.colOnSurfaceVariant
|
color: Appearance.colors.colOnSurfaceVariant
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.fillWidth: true
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
color: Appearance.colors.colOnSurfaceVariant
|
color: Appearance.colors.colOnSurfaceVariant
|
||||||
|
|||||||
@@ -6,10 +6,16 @@ import qs.modules.common.widgets
|
|||||||
Loader {
|
Loader {
|
||||||
id: root
|
id: root
|
||||||
property bool vertical: false
|
property bool vertical: false
|
||||||
|
|
||||||
active: HyprlandXkb.layoutCodes.length > 1
|
active: HyprlandXkb.layoutCodes.length > 1
|
||||||
visible: active
|
visible: active
|
||||||
|
|
||||||
|
function abbreviateLayoutCode(fullCode) {
|
||||||
|
return fullCode.split(':').map(layout => {
|
||||||
|
const baseLayout = layout.split('-')[0];
|
||||||
|
return baseLayout.slice(0, 4);
|
||||||
|
}).join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
sourceComponent: Item {
|
sourceComponent: Item {
|
||||||
implicitWidth: root.vertical ? null : layoutCodeText.implicitWidth
|
implicitWidth: root.vertical ? null : layoutCodeText.implicitWidth
|
||||||
implicitHeight: root.vertical ? layoutCodeText.implicitHeight : null
|
implicitHeight: root.vertical ? layoutCodeText.implicitHeight : null
|
||||||
@@ -18,7 +24,7 @@ Loader {
|
|||||||
id: layoutCodeText
|
id: layoutCodeText
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
text: HyprlandXkb.currentLayoutCode.split(":").join("\n")
|
text: abbreviateLayoutCode(HyprlandXkb.currentLayoutCode)
|
||||||
font.pixelSize: text.includes("\n") ? Appearance.font.pixelSize.smallie : Appearance.font.pixelSize.small
|
font.pixelSize: text.includes("\n") ? Appearance.font.pixelSize.smallie : Appearance.font.pixelSize.small
|
||||||
color: rightSidebarButton.colText
|
color: rightSidebarButton.colText
|
||||||
animateChange: true
|
animateChange: true
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ StyledPopup {
|
|||||||
required property string label
|
required property string label
|
||||||
required property string value
|
required property string value
|
||||||
spacing: 4
|
spacing: 4
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
MaterialSymbol {
|
MaterialSymbol {
|
||||||
text: resourceItem.icon
|
text: resourceItem.icon
|
||||||
@@ -40,13 +39,14 @@ StyledPopup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
component ResourceHeaderItem: RowLayout {
|
component ResourceHeaderItem: Row {
|
||||||
id: headerItem
|
id: headerItem
|
||||||
required property var icon
|
required property var icon
|
||||||
required property var label
|
required property var label
|
||||||
spacing: 5
|
spacing: 5
|
||||||
|
|
||||||
MaterialSymbol {
|
MaterialSymbol {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
fill: 0
|
fill: 0
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
text: headerItem.icon
|
text: headerItem.icon
|
||||||
@@ -55,6 +55,7 @@ StyledPopup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: headerItem.label
|
text: headerItem.label
|
||||||
font {
|
font {
|
||||||
weight: Font.Medium
|
weight: Font.Medium
|
||||||
@@ -64,19 +65,20 @@ StyledPopup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
Row {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: 12
|
spacing: 12
|
||||||
|
|
||||||
ColumnLayout {
|
Column {
|
||||||
Layout.alignment: Qt.AlignTop
|
anchors.top: parent.top
|
||||||
spacing: 8
|
spacing: 8
|
||||||
|
|
||||||
ResourceHeaderItem {
|
ResourceHeaderItem {
|
||||||
icon: "memory"
|
icon: "memory"
|
||||||
label: "RAM"
|
label: "RAM"
|
||||||
}
|
}
|
||||||
ColumnLayout {
|
Column {
|
||||||
|
spacing: 4
|
||||||
ResourceItem {
|
ResourceItem {
|
||||||
icon: "clock_loader_60"
|
icon: "clock_loader_60"
|
||||||
label: Translation.tr("Used:")
|
label: Translation.tr("Used:")
|
||||||
@@ -95,16 +97,17 @@ StyledPopup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
Column {
|
||||||
visible: ResourceUsage.swapTotal > 0
|
visible: ResourceUsage.swapTotal > 0
|
||||||
Layout.alignment: Qt.AlignTop
|
anchors.top: parent.top
|
||||||
spacing: 8
|
spacing: 8
|
||||||
|
|
||||||
ResourceHeaderItem {
|
ResourceHeaderItem {
|
||||||
icon: "swap_horiz"
|
icon: "swap_horiz"
|
||||||
label: "Swap"
|
label: "Swap"
|
||||||
}
|
}
|
||||||
ColumnLayout {
|
Column {
|
||||||
|
spacing: 4
|
||||||
ResourceItem {
|
ResourceItem {
|
||||||
icon: "clock_loader_60"
|
icon: "clock_loader_60"
|
||||||
label: Translation.tr("Used:")
|
label: Translation.tr("Used:")
|
||||||
@@ -123,15 +126,16 @@ StyledPopup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
Column {
|
||||||
Layout.alignment: Qt.AlignTop
|
anchors.top: parent.top
|
||||||
spacing: 8
|
spacing: 8
|
||||||
|
|
||||||
ResourceHeaderItem {
|
ResourceHeaderItem {
|
||||||
icon: "planner_review"
|
icon: "planner_review"
|
||||||
label: "CPU"
|
label: "CPU"
|
||||||
}
|
}
|
||||||
ColumnLayout {
|
Column {
|
||||||
|
spacing: 4
|
||||||
ResourceItem {
|
ResourceItem {
|
||||||
icon: "bolt"
|
icon: "bolt"
|
||||||
label: Translation.tr("Load:")
|
label: Translation.tr("Load:")
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import qs
|
|||||||
import qs.modules.common
|
import qs.modules.common
|
||||||
import qs.modules.common.widgets
|
import qs.modules.common.widgets
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
|
||||||
|
|
||||||
Revealer { // Scroll hint
|
Revealer { // Scroll hint
|
||||||
id: root
|
id: root
|
||||||
@@ -11,10 +10,11 @@ Revealer { // Scroll hint
|
|||||||
property string tooltipText: ""
|
property string tooltipText: ""
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
anchors.right: root.side === "left" ? parent.right : undefined
|
anchors.right: root.side === "left" ? parent.right : undefined
|
||||||
anchors.left: root.side === "right" ? parent.left : undefined
|
anchors.left: root.side === "right" ? parent.left : undefined
|
||||||
implicitWidth: contentColumnLayout.implicitWidth
|
implicitWidth: contentColumn.implicitWidth
|
||||||
implicitHeight: contentColumnLayout.implicitHeight
|
implicitHeight: contentColumn.implicitHeight
|
||||||
property bool hovered: false
|
property bool hovered: false
|
||||||
|
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
@@ -22,32 +22,36 @@ Revealer { // Scroll hint
|
|||||||
onExited: hovered = false
|
onExited: hovered = false
|
||||||
acceptedButtons: Qt.NoButton
|
acceptedButtons: Qt.NoButton
|
||||||
|
|
||||||
// StyledToolTip {
|
property bool showHintTimedOut: false
|
||||||
// extraVisibleCondition: tooltipText.length > 0
|
onHoveredChanged: showHintTimedOut = false
|
||||||
// text: tooltipText
|
Timer {
|
||||||
// }
|
running: mouseArea.hovered
|
||||||
|
interval: 500
|
||||||
|
onTriggered: mouseArea.showHintTimedOut = true
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
PopupToolTip {
|
||||||
id: contentColumnLayout
|
extraVisibleCondition: (tooltipText.length > 0 && mouseArea.showHintTimedOut)
|
||||||
anchors.centerIn: parent
|
text: tooltipText
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: contentColumn
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
}
|
||||||
spacing: -5
|
spacing: -5
|
||||||
MaterialSymbol {
|
MaterialSymbol {
|
||||||
Layout.leftMargin: 5
|
|
||||||
Layout.rightMargin: 5
|
|
||||||
text: "keyboard_arrow_up"
|
text: "keyboard_arrow_up"
|
||||||
iconSize: 14
|
iconSize: 14
|
||||||
color: Appearance.colors.colSubtext
|
color: Appearance.colors.colSubtext
|
||||||
}
|
}
|
||||||
MaterialSymbol {
|
MaterialSymbol {
|
||||||
Layout.leftMargin: 5
|
|
||||||
Layout.rightMargin: 5
|
|
||||||
text: root.icon
|
text: root.icon
|
||||||
iconSize: 14
|
iconSize: 14
|
||||||
color: Appearance.colors.colSubtext
|
color: Appearance.colors.colSubtext
|
||||||
}
|
}
|
||||||
MaterialSymbol {
|
MaterialSymbol {
|
||||||
Layout.leftMargin: 5
|
|
||||||
Layout.rightMargin: 5
|
|
||||||
text: "keyboard_arrow_down"
|
text: "keyboard_arrow_down"
|
||||||
iconSize: 14
|
iconSize: 14
|
||||||
color: Appearance.colors.colSubtext
|
color: Appearance.colors.colSubtext
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ LazyLoader {
|
|||||||
anchors.top: Config.options.bar.vertical || (!Config.options.bar.vertical && !Config.options.bar.bottom)
|
anchors.top: Config.options.bar.vertical || (!Config.options.bar.vertical && !Config.options.bar.bottom)
|
||||||
anchors.bottom: !Config.options.bar.vertical && Config.options.bar.bottom
|
anchors.bottom: !Config.options.bar.vertical && Config.options.bar.bottom
|
||||||
|
|
||||||
implicitWidth: popupBackground.implicitWidth + Appearance.sizes.hyprlandGapsOut * 2 + root.popupBackgroundMargin
|
implicitWidth: popupBackground.implicitWidth + Appearance.sizes.elevationMargin * 2 + root.popupBackgroundMargin
|
||||||
implicitHeight: popupBackground.implicitHeight + Appearance.sizes.hyprlandGapsOut * 2 + root.popupBackgroundMargin
|
implicitHeight: popupBackground.implicitHeight + Appearance.sizes.elevationMargin * 2 + root.popupBackgroundMargin
|
||||||
|
|
||||||
mask: Region {
|
mask: Region {
|
||||||
item: popupBackground
|
item: popupBackground
|
||||||
@@ -63,10 +63,10 @@ LazyLoader {
|
|||||||
readonly property real margin: 10
|
readonly property real margin: 10
|
||||||
anchors {
|
anchors {
|
||||||
fill: parent
|
fill: parent
|
||||||
leftMargin: Appearance.sizes.hyprlandGapsOut + root.popupBackgroundMargin * (!popupWindow.anchors.left)
|
leftMargin: Appearance.sizes.elevationMargin + root.popupBackgroundMargin * (!popupWindow.anchors.left)
|
||||||
rightMargin: Appearance.sizes.hyprlandGapsOut + root.popupBackgroundMargin * (!popupWindow.anchors.right)
|
rightMargin: Appearance.sizes.elevationMargin + root.popupBackgroundMargin * (!popupWindow.anchors.right)
|
||||||
topMargin: Appearance.sizes.hyprlandGapsOut + root.popupBackgroundMargin * (!popupWindow.anchors.top)
|
topMargin: Appearance.sizes.elevationMargin + root.popupBackgroundMargin * (!popupWindow.anchors.top)
|
||||||
bottomMargin: Appearance.sizes.hyprlandGapsOut + root.popupBackgroundMargin * (!popupWindow.anchors.bottom)
|
bottomMargin: Appearance.sizes.elevationMargin + root.popupBackgroundMargin * (!popupWindow.anchors.bottom)
|
||||||
}
|
}
|
||||||
implicitWidth: root.contentItem.implicitWidth + margin * 2
|
implicitWidth: root.contentItem.implicitWidth + margin * 2
|
||||||
implicitHeight: root.contentItem.implicitHeight + margin * 2
|
implicitHeight: root.contentItem.implicitHeight + margin * 2
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import qs.modules.common.widgets
|
|||||||
import qs.modules.common.functions
|
import qs.modules.common.functions
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
import Quickshell.Hyprland
|
import Quickshell.Hyprland
|
||||||
@@ -19,7 +18,8 @@ Item {
|
|||||||
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(root.QsWindow.window?.screen)
|
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(root.QsWindow.window?.screen)
|
||||||
readonly property Toplevel activeWindow: ToplevelManager.activeToplevel
|
readonly property Toplevel activeWindow: ToplevelManager.activeToplevel
|
||||||
|
|
||||||
readonly property int workspaceGroup: Math.floor((monitor?.activeWorkspace?.id - 1) / Config.options.bar.workspaces.shown)
|
readonly property int workspacesShown: Config.options.bar.workspaces.shown
|
||||||
|
readonly property int workspaceGroup: Math.floor((monitor?.activeWorkspace?.id - 1) / root.workspacesShown)
|
||||||
property list<bool> workspaceOccupied: []
|
property list<bool> workspaceOccupied: []
|
||||||
property int widgetPadding: 4
|
property int widgetPadding: 4
|
||||||
property int workspaceButtonWidth: 26
|
property int workspaceButtonWidth: 26
|
||||||
@@ -28,7 +28,7 @@ Item {
|
|||||||
property real workspaceIconSizeShrinked: workspaceButtonWidth * 0.55
|
property real workspaceIconSizeShrinked: workspaceButtonWidth * 0.55
|
||||||
property real workspaceIconOpacityShrinked: 1
|
property real workspaceIconOpacityShrinked: 1
|
||||||
property real workspaceIconMarginShrinked: -4
|
property real workspaceIconMarginShrinked: -4
|
||||||
property int workspaceIndexInGroup: (monitor?.activeWorkspace?.id - 1) % Config.options.bar.workspaces.shown
|
property int workspaceIndexInGroup: (monitor?.activeWorkspace?.id - 1) % root.workspacesShown
|
||||||
|
|
||||||
property bool showNumbers: false
|
property bool showNumbers: false
|
||||||
Timer {
|
Timer {
|
||||||
@@ -56,8 +56,8 @@ Item {
|
|||||||
|
|
||||||
// Function to update workspaceOccupied
|
// Function to update workspaceOccupied
|
||||||
function updateWorkspaceOccupied() {
|
function updateWorkspaceOccupied() {
|
||||||
workspaceOccupied = Array.from({ length: Config.options.bar.workspaces.shown }, (_, i) => {
|
workspaceOccupied = Array.from({ length: root.workspacesShown }, (_, i) => {
|
||||||
return Hyprland.workspaces.values.some(ws => ws.id === workspaceGroup * Config.options.bar.workspaces.shown + i + 1);
|
return Hyprland.workspaces.values.some(ws => ws.id === workspaceGroup * root.workspacesShown + i + 1);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,8 +79,8 @@ Item {
|
|||||||
updateWorkspaceOccupied();
|
updateWorkspaceOccupied();
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitWidth: root.vertical ? Appearance.sizes.verticalBarWidth : backgroundLayout.implicitWidth
|
implicitWidth: root.vertical ? Appearance.sizes.verticalBarWidth : (root.workspaceButtonWidth * root.workspacesShown)
|
||||||
implicitHeight: root.vertical ? backgroundLayout.implicitHeight : Appearance.sizes.barHeight
|
implicitHeight: root.vertical ? (root.workspaceButtonWidth * root.workspacesShown) : Appearance.sizes.barHeight
|
||||||
|
|
||||||
// Scroll to switch workspaces
|
// Scroll to switch workspaces
|
||||||
WheelHandler {
|
WheelHandler {
|
||||||
@@ -104,24 +104,20 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Workspaces - background
|
// Workspaces - background
|
||||||
GridLayout {
|
Grid {
|
||||||
id: backgroundLayout
|
|
||||||
z: 1
|
z: 1
|
||||||
anchors.fill: parent
|
anchors.centerIn: parent
|
||||||
implicitHeight: root.vertical ? root.workspaceButtonWidth : Appearance.sizes.barHeight
|
|
||||||
implicitWidth: root.vertical ? Appearance.sizes.verticalBarWidth : root.workspaceButtonWidth
|
|
||||||
|
|
||||||
rowSpacing: 0
|
rowSpacing: 0
|
||||||
columnSpacing: 0
|
columnSpacing: 0
|
||||||
columns: root.vertical ? 1 : -1
|
columns: root.vertical ? 1 : root.workspacesShown
|
||||||
|
rows: root.vertical ? root.workspacesShown : 1
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: Config.options.bar.workspaces.shown
|
model: root.workspacesShown
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
z: 1
|
z: 1
|
||||||
Layout.alignment: root.vertical ? Qt.AlignHCenter : Qt.AlignVCenter
|
|
||||||
|
|
||||||
implicitWidth: workspaceButtonWidth
|
implicitWidth: workspaceButtonWidth
|
||||||
implicitHeight: workspaceButtonWidth
|
implicitHeight: workspaceButtonWidth
|
||||||
radius: (width / 2)
|
radius: (width / 2)
|
||||||
@@ -195,26 +191,24 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Workspaces - numbers
|
// Workspaces - numbers
|
||||||
GridLayout {
|
Grid {
|
||||||
id: rowLayoutNumbers
|
|
||||||
z: 3
|
z: 3
|
||||||
|
|
||||||
columns: vertical ? 1 : -1
|
columns: root.vertical ? 1 : root.workspacesShown
|
||||||
|
rows: root.vertical ? root.workspacesShown : 1
|
||||||
columnSpacing: 0
|
columnSpacing: 0
|
||||||
rowSpacing: 0
|
rowSpacing: 0
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
implicitHeight: vertical ? Appearance.sizes.verticalBarWidth : Appearance.sizes.barHeight
|
|
||||||
implicitWidth: vertical ? Appearance.sizes.verticalBarWidth : Appearance.sizes.verticalBarWidth
|
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: Config.options.bar.workspaces.shown
|
model: root.workspacesShown
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
id: button
|
id: button
|
||||||
property int workspaceValue: workspaceGroup * Config.options.bar.workspaces.shown + index + 1
|
property int workspaceValue: workspaceGroup * root.workspacesShown + index + 1
|
||||||
Layout.fillHeight: !root.vertical
|
implicitHeight: vertical ? Appearance.sizes.verticalBarWidth : Appearance.sizes.barHeight
|
||||||
Layout.fillWidth: root.vertical
|
implicitWidth: vertical ? Appearance.sizes.verticalBarWidth : Appearance.sizes.verticalBarWidth
|
||||||
onPressed: Hyprland.dispatch(`workspace ${workspaceValue}`)
|
onPressed: Hyprland.dispatch(`workspace ${workspaceValue}`)
|
||||||
width: vertical ? undefined : workspaceButtonWidth
|
width: vertical ? undefined : workspaceButtonWidth
|
||||||
height: vertical ? workspaceButtonWidth : undefined
|
height: vertical ? workspaceButtonWidth : undefined
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
import qs
|
import qs
|
||||||
import qs.services
|
import qs.services
|
||||||
import qs.modules.common
|
import qs.modules.common
|
||||||
@@ -11,8 +12,9 @@ Item {
|
|||||||
readonly property var keybinds: HyprlandKeybinds.keybinds
|
readonly property var keybinds: HyprlandKeybinds.keybinds
|
||||||
property real spacing: 20
|
property real spacing: 20
|
||||||
property real titleSpacing: 7
|
property real titleSpacing: 7
|
||||||
implicitWidth: rowLayout.implicitWidth
|
property real padding: 4
|
||||||
implicitHeight: rowLayout.implicitHeight
|
implicitWidth: row.implicitWidth + padding * 2
|
||||||
|
implicitHeight: row.implicitHeight + padding * 2
|
||||||
|
|
||||||
property var keyBlacklist: ["Super_L"]
|
property var keyBlacklist: ["Super_L"]
|
||||||
property var keySubstitutions: ({
|
property var keySubstitutions: ({
|
||||||
@@ -28,43 +30,51 @@ Item {
|
|||||||
// "Shift": "",
|
// "Shift": "",
|
||||||
})
|
})
|
||||||
|
|
||||||
RowLayout { // Keybind columns
|
Row { // Keybind columns
|
||||||
id: rowLayout
|
id: row
|
||||||
spacing: root.spacing
|
spacing: root.spacing
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: keybinds.children
|
model: keybinds.children
|
||||||
|
|
||||||
delegate: ColumnLayout { // Keybind sections
|
delegate: Column { // Keybind sections
|
||||||
spacing: root.spacing
|
spacing: root.spacing
|
||||||
required property var modelData
|
required property var modelData
|
||||||
Layout.alignment: Qt.AlignTop
|
anchors.top: row.top
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: modelData.children
|
model: modelData.children
|
||||||
|
|
||||||
delegate: Item { // Section with real keybinds
|
delegate: Item { // Section with real keybinds
|
||||||
|
id: keybindSection
|
||||||
required property var modelData
|
required property var modelData
|
||||||
implicitWidth: sectionColumnLayout.implicitWidth
|
implicitWidth: sectionColumn.implicitWidth
|
||||||
implicitHeight: sectionColumnLayout.implicitHeight
|
implicitHeight: sectionColumn.implicitHeight
|
||||||
ColumnLayout {
|
|
||||||
id: sectionColumnLayout
|
Column {
|
||||||
|
id: sectionColumn
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: root.titleSpacing
|
spacing: root.titleSpacing
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: sectionTitle
|
id: sectionTitle
|
||||||
font.family: Appearance.font.family.title
|
font.family: Appearance.font.family.title
|
||||||
font.pixelSize: Appearance.font.pixelSize.huge
|
font.pixelSize: Appearance.font.pixelSize.huge
|
||||||
color: Appearance.colors.colOnLayer0
|
color: Appearance.colors.colOnLayer0
|
||||||
text: modelData.name
|
text: keybindSection.modelData.name
|
||||||
}
|
}
|
||||||
|
|
||||||
GridLayout {
|
Grid {
|
||||||
id: keybindGrid
|
id: keybindGrid
|
||||||
columns: 2
|
columns: 2
|
||||||
|
columnSpacing: 4
|
||||||
|
rowSpacing: 4
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: {
|
model: {
|
||||||
var result = [];
|
var result = [];
|
||||||
for (var i = 0; i < modelData.keybinds.length; i++) {
|
for (var i = 0; i < keybindSection.modelData.keybinds.length; i++) {
|
||||||
const keybind = modelData.keybinds[i];
|
const keybind = keybindSection.modelData.keybinds[i];
|
||||||
result.push({
|
result.push({
|
||||||
"type": "keys",
|
"type": "keys",
|
||||||
"mods": keybind.mods,
|
"mods": keybind.mods,
|
||||||
@@ -89,7 +99,7 @@ Item {
|
|||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: keysComponent
|
id: keysComponent
|
||||||
RowLayout {
|
Row {
|
||||||
spacing: 4
|
spacing: 4
|
||||||
Repeater {
|
Repeater {
|
||||||
model: modelData.mods
|
model: modelData.mods
|
||||||
@@ -101,7 +111,6 @@ Item {
|
|||||||
StyledText {
|
StyledText {
|
||||||
id: keybindPlus
|
id: keybindPlus
|
||||||
visible: !keyBlacklist.includes(modelData.key) && modelData.mods.length > 0
|
visible: !keyBlacklist.includes(modelData.key) && modelData.mods.length > 0
|
||||||
Layout.alignment: Qt.AlignVCenter
|
|
||||||
text: "+"
|
text: "+"
|
||||||
}
|
}
|
||||||
KeyboardKey {
|
KeyboardKey {
|
||||||
|
|||||||
@@ -15,14 +15,14 @@ Item {
|
|||||||
implicitWidth: mainLayout.implicitWidth
|
implicitWidth: mainLayout.implicitWidth
|
||||||
implicitHeight: mainLayout.implicitHeight
|
implicitHeight: mainLayout.implicitHeight
|
||||||
|
|
||||||
ColumnLayout {
|
Column {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
spacing: root.spacing
|
spacing: root.spacing
|
||||||
|
|
||||||
Repeater { // Main table rows
|
Repeater { // Main table rows
|
||||||
model: root.elements
|
model: root.elements
|
||||||
|
|
||||||
delegate: RowLayout { // Table cells
|
delegate: Row { // Table cells
|
||||||
id: tableRow
|
id: tableRow
|
||||||
spacing: root.spacing
|
spacing: root.spacing
|
||||||
required property var modelData
|
required property var modelData
|
||||||
@@ -47,7 +47,7 @@ Item {
|
|||||||
Repeater { // Main table rows
|
Repeater { // Main table rows
|
||||||
model: root.series
|
model: root.series
|
||||||
|
|
||||||
delegate: RowLayout { // Table cells
|
delegate: Row { // Table cells
|
||||||
id: seriesTableRow
|
id: seriesTableRow
|
||||||
spacing: root.spacing
|
spacing: root.spacing
|
||||||
required property var modelData
|
required property var modelData
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import qs.modules.common
|
import qs.modules.common
|
||||||
|
import qs.modules.common.functions
|
||||||
import qs.modules.common.widgets
|
import qs.modules.common.widgets
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
|
||||||
@@ -18,7 +19,7 @@ RippleButton {
|
|||||||
topMargin: 4
|
topMargin: 4
|
||||||
leftMargin: 4
|
leftMargin: 4
|
||||||
}
|
}
|
||||||
color: Appearance.colors.colLayer2
|
color: ColorUtils.transparentize(Appearance.colors.colLayer2)
|
||||||
radius: Appearance.rounding.full
|
radius: Appearance.rounding.full
|
||||||
implicitWidth: Math.max(20, elementNumber.implicitWidth)
|
implicitWidth: Math.max(20, elementNumber.implicitWidth)
|
||||||
implicitHeight: Math.max(20, elementNumber.implicitHeight)
|
implicitHeight: Math.max(20, elementNumber.implicitHeight)
|
||||||
@@ -26,13 +27,35 @@ RippleButton {
|
|||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: elementNumber
|
id: elementNumber
|
||||||
anchors.centerIn: parent
|
anchors.left: parent.left
|
||||||
color: Appearance.colors.colOnLayer2
|
color: Appearance.colors.colOnLayer2
|
||||||
text: root.element.number
|
text: root.element.number
|
||||||
font.pixelSize: Appearance.font.pixelSize.smallest
|
font.pixelSize: Appearance.font.pixelSize.smallest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
right: parent.right
|
||||||
|
topMargin: 4
|
||||||
|
rightMargin: 4
|
||||||
|
}
|
||||||
|
color: ColorUtils.transparentize(Appearance.colors.colLayer2)
|
||||||
|
radius: Appearance.rounding.full
|
||||||
|
implicitWidth: Math.max(20, elementWeight.implicitWidth)
|
||||||
|
implicitHeight: Math.max(20, elementWeight.implicitHeight)
|
||||||
|
width: height
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: elementWeight
|
||||||
|
anchors.right: parent.right
|
||||||
|
color: Appearance.colors.colOnLayer2
|
||||||
|
text: root.element.weight
|
||||||
|
font.pixelSize: Appearance.font.pixelSize.smallest
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: elementSymbol
|
id: elementSymbol
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|||||||
@@ -356,7 +356,7 @@ Singleton {
|
|||||||
property real mediaControlsWidth: 440
|
property real mediaControlsWidth: 440
|
||||||
property real mediaControlsHeight: 160
|
property real mediaControlsHeight: 160
|
||||||
property real notificationPopupWidth: 410
|
property real notificationPopupWidth: 410
|
||||||
property real osdWidth: 200
|
property real osdWidth: 180
|
||||||
property real searchWidthCollapsed: 260
|
property real searchWidthCollapsed: 260
|
||||||
property real searchWidth: 450
|
property real searchWidth: 450
|
||||||
property real sidebarWidth: 460
|
property real sidebarWidth: 460
|
||||||
|
|||||||
@@ -260,6 +260,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
property JsonObject lock: JsonObject {
|
property JsonObject lock: JsonObject {
|
||||||
|
property bool launchOnStartup: false
|
||||||
property JsonObject blur: JsonObject {
|
property JsonObject blur: JsonObject {
|
||||||
property bool enable: false
|
property bool enable: false
|
||||||
property real radius: 100
|
property real radius: 100
|
||||||
@@ -267,6 +268,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
property bool centerClock: true
|
property bool centerClock: true
|
||||||
property bool showLockedText: true
|
property bool showLockedText: true
|
||||||
|
property bool unlockKeyring: true
|
||||||
}
|
}
|
||||||
|
|
||||||
property JsonObject media: JsonObject {
|
property JsonObject media: JsonObject {
|
||||||
|
|||||||
@@ -11,6 +11,15 @@ Singleton {
|
|||||||
property string fileName: "states.json"
|
property string fileName: "states.json"
|
||||||
property string filePath: `${root.fileDir}/${root.fileName}`
|
property string filePath: `${root.fileDir}/${root.fileName}`
|
||||||
|
|
||||||
|
property bool ready: false
|
||||||
|
property string previousHyprlandInstanceSignature: ""
|
||||||
|
property bool isNewHyprlandInstance: previousHyprlandInstanceSignature !== states.hyprlandInstanceSignature
|
||||||
|
|
||||||
|
onReadyChanged: {
|
||||||
|
root.previousHyprlandInstanceSignature = root.states.hyprlandInstanceSignature
|
||||||
|
root.states.hyprlandInstanceSignature = Quickshell.env("HYPRLAND_INSTANCE_SIGNATURE") || ""
|
||||||
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: fileReloadTimer
|
id: fileReloadTimer
|
||||||
interval: 100
|
interval: 100
|
||||||
@@ -36,6 +45,7 @@ Singleton {
|
|||||||
watchChanges: true
|
watchChanges: true
|
||||||
onFileChanged: fileReloadTimer.restart()
|
onFileChanged: fileReloadTimer.restart()
|
||||||
onAdapterUpdated: fileWriteTimer.restart()
|
onAdapterUpdated: fileWriteTimer.restart()
|
||||||
|
onLoaded: root.ready = true
|
||||||
onLoadFailed: error => {
|
onLoadFailed: error => {
|
||||||
console.log("Failed to load persistent states file:", error);
|
console.log("Failed to load persistent states file:", error);
|
||||||
if (error == FileViewError.FileNotFound) {
|
if (error == FileViewError.FileNotFound) {
|
||||||
@@ -45,6 +55,9 @@ Singleton {
|
|||||||
|
|
||||||
adapter: JsonAdapter {
|
adapter: JsonAdapter {
|
||||||
id: persistentStatesJsonAdapter
|
id: persistentStatesJsonAdapter
|
||||||
|
|
||||||
|
property string hyprlandInstanceSignature: ""
|
||||||
|
|
||||||
property JsonObject ai: JsonObject {
|
property JsonObject ai: JsonObject {
|
||||||
property string model
|
property string model
|
||||||
property real temperature: 0.5
|
property real temperature: 0.5
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Image {
|
StyledImage {
|
||||||
id: image
|
id: image
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
|||||||
@@ -72,8 +72,8 @@ RippleButton {
|
|||||||
Layout.bottomMargin: 5
|
Layout.bottomMargin: 5
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
value: 0.7
|
value: 0.7
|
||||||
sperm: true
|
wavy: true
|
||||||
animateSperm: lightDarkButtonRoot.toggled
|
animateWave: lightDarkButtonRoot.toggled
|
||||||
highlightColor: lightDarkButtonRoot.toggled ? Appearance.m3colors.m3primary : lightDarkButtonRoot.previewFg
|
highlightColor: lightDarkButtonRoot.toggled ? Appearance.m3colors.m3primary : lightDarkButtonRoot.previewFg
|
||||||
trackColor: ColorUtils.mix(lightDarkButtonRoot.previewBg, lightDarkButtonRoot.previewFg, 0.5)
|
trackColor: ColorUtils.mix(lightDarkButtonRoot.previewBg, lightDarkButtonRoot.previewFg, 0.5)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ Item { // Notification item area
|
|||||||
implicitHeight: summaryText.implicitHeight
|
implicitHeight: summaryText.implicitHeight
|
||||||
StyledText {
|
StyledText {
|
||||||
id: summaryText
|
id: summaryText
|
||||||
Layout.fillWidth: summaryTextMetrics.width >= summaryRow.width * root.summaryElideRatio
|
Layout.fillWidth: summaryTextMetrics.width >= summaryRow.implicitWidth * root.summaryElideRatio
|
||||||
visible: !root.onlyNotification
|
visible: !root.onlyNotification
|
||||||
font.pixelSize: root.fontSize
|
font.pixelSize: root.fontSize
|
||||||
color: Appearance.colors.colOnLayer3
|
color: Appearance.colors.colOnLayer3
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
import qs.services
|
pragma ComponentBehavior: Bound
|
||||||
import qs.modules.common
|
import qs.modules.common
|
||||||
import qs.modules.common.widgets
|
import qs.modules.common.widgets
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Widgets
|
|
||||||
import Qt5Compat.GraphicalEffects
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Material 3 progress bar. See https://m3.material.io/components/progress-indicators/overview
|
* Material 3 progress bar. See https://m3.material.io/components/progress-indicators/overview
|
||||||
@@ -18,13 +15,13 @@ ProgressBar {
|
|||||||
property real valueBarGap: 4
|
property real valueBarGap: 4
|
||||||
property color highlightColor: Appearance?.colors.colPrimary ?? "#685496"
|
property color highlightColor: Appearance?.colors.colPrimary ?? "#685496"
|
||||||
property color trackColor: Appearance?.m3colors.m3secondaryContainer ?? "#F1D3F9"
|
property color trackColor: Appearance?.m3colors.m3secondaryContainer ?? "#F1D3F9"
|
||||||
property bool sperm: false // If true, the progress bar will have a wavy fill effect
|
property bool wavy: false // If true, the progress bar will have a wavy fill effect
|
||||||
property bool animateSperm: true
|
property bool animateWave: true
|
||||||
property real spermAmplitudeMultiplier: sperm ? 0.5 : 0
|
property real waveAmplitudeMultiplier: wavy ? 0.5 : 0
|
||||||
property real spermFrequency: 6
|
property real waveFrequency: 6
|
||||||
property real spermFps: 60
|
property real waveFps: 60
|
||||||
|
|
||||||
Behavior on spermAmplitudeMultiplier {
|
Behavior on waveAmplitudeMultiplier {
|
||||||
animation: Appearance?.animation.elementMoveFast.numberAnimation.createObject(this)
|
animation: Appearance?.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,64 +35,62 @@ ProgressBar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
contentItem: Item {
|
contentItem: Item {
|
||||||
|
id: contentItem
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
Canvas {
|
Loader {
|
||||||
id: wavyFill
|
|
||||||
anchors {
|
anchors {
|
||||||
left: parent.left
|
left: parent.left
|
||||||
right: parent.right
|
|
||||||
verticalCenter: parent.verticalCenter
|
verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
height: parent.height * 6
|
active: root.wavy
|
||||||
onPaint: {
|
sourceComponent: WavyLine {
|
||||||
var ctx = getContext("2d");
|
id: wavyFill
|
||||||
ctx.clearRect(0, 0, width, height);
|
frequency: root.waveFrequency
|
||||||
|
color: root.highlightColor
|
||||||
var progress = root.visualPosition;
|
amplitudeMultiplier: root.wavy ? 0.5 : 0
|
||||||
var fillWidth = progress * width;
|
height: contentItem.height * 6
|
||||||
var amplitude = parent.height * root.spermAmplitudeMultiplier;
|
width: contentItem.width * root.visualPosition
|
||||||
var frequency = root.spermFrequency;
|
lineWidth: contentItem.height
|
||||||
var phase = Date.now() / 400.0;
|
fullLength: root.width
|
||||||
var centerY = height / 2;
|
Connections {
|
||||||
|
target: root
|
||||||
ctx.strokeStyle = root.highlightColor;
|
function onValueChanged() { wavyFill.requestPaint(); }
|
||||||
ctx.lineWidth = parent.height;
|
function onHighlightColorChanged() { wavyFill.requestPaint(); }
|
||||||
ctx.lineCap = "round";
|
}
|
||||||
ctx.beginPath();
|
FrameAnimation {
|
||||||
for (var x = ctx.lineWidth / 2; x <= fillWidth; x += 1) {
|
running: root.animateWave
|
||||||
var waveY = centerY + amplitude * Math.sin(frequency * 2 * Math.PI * x / width + phase);
|
onTriggered: {
|
||||||
if (x === 0)
|
wavyFill.requestPaint()
|
||||||
ctx.moveTo(x, waveY);
|
}
|
||||||
else
|
|
||||||
ctx.lineTo(x, waveY);
|
|
||||||
}
|
}
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
Connections {
|
|
||||||
target: root
|
|
||||||
function onValueChanged() { wavyFill.requestPaint(); }
|
|
||||||
function onHighlightColorChanged() { wavyFill.requestPaint(); }
|
|
||||||
}
|
|
||||||
Timer {
|
|
||||||
interval: 1000 / root.spermFps
|
|
||||||
running: root.animateSperm
|
|
||||||
repeat: root.sperm
|
|
||||||
onTriggered: wavyFill.requestPaint()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
active: !root.wavy
|
||||||
|
sourceComponent: Rectangle {
|
||||||
|
anchors.left: parent.left
|
||||||
|
width: contentItem.width * root.visualPosition
|
||||||
|
height: contentItem.height
|
||||||
|
radius: height / 2
|
||||||
|
color: root.highlightColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle { // Right remaining part fill
|
Rectangle { // Right remaining part fill
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
width: (1 - root.visualPosition) * parent.width - valueBarGap
|
width: (1 - root.visualPosition) * parent.width - valueBarGap
|
||||||
height: parent.height
|
height: parent.height
|
||||||
radius: Appearance?.rounding.full ?? 9999
|
radius: height / 2
|
||||||
color: root.trackColor
|
color: root.trackColor
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle { // Stop point
|
Rectangle { // Stop point
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
width: valueBarGap
|
width: valueBarGap
|
||||||
height: valueBarGap
|
height: valueBarGap
|
||||||
radius: Appearance?.rounding.full ?? 9999
|
radius: height / 2
|
||||||
color: root.highlightColor
|
color: root.highlightColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import qs.modules.common
|
|||||||
RectangularShadow {
|
RectangularShadow {
|
||||||
required property var target
|
required property var target
|
||||||
anchors.fill: target
|
anchors.fill: target
|
||||||
radius: 20
|
radius: target.radius
|
||||||
blur: 0.9 * Appearance.sizes.elevationMargin
|
blur: 0.9 * Appearance.sizes.elevationMargin
|
||||||
offset: Qt.vector2d(0.0, 1.0)
|
offset: Qt.vector2d(0.0, 1.0)
|
||||||
spread: 1
|
spread: 1
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
import qs.modules.common
|
import qs.modules.common
|
||||||
import qs.modules.common.widgets
|
import qs.modules.common.widgets
|
||||||
import qs.services
|
import qs.services
|
||||||
@@ -17,6 +18,7 @@ Slider {
|
|||||||
|
|
||||||
property list<real> stopIndicatorValues: [1]
|
property list<real> stopIndicatorValues: [1]
|
||||||
enum Configuration {
|
enum Configuration {
|
||||||
|
Wavy = 4,
|
||||||
XS = 12,
|
XS = 12,
|
||||||
S = 18,
|
S = 18,
|
||||||
M = 30,
|
M = 30,
|
||||||
@@ -28,10 +30,9 @@ Slider {
|
|||||||
|
|
||||||
property real handleDefaultWidth: 3
|
property real handleDefaultWidth: 3
|
||||||
property real handlePressedWidth: 1.5
|
property real handlePressedWidth: 1.5
|
||||||
|
|
||||||
property color highlightColor: Appearance.colors.colPrimary
|
property color highlightColor: Appearance.colors.colPrimary
|
||||||
property color trackColor: Appearance.colors.colSecondaryContainer
|
property color trackColor: Appearance.colors.colSecondaryContainer
|
||||||
property color handleColor: Appearance.m3colors.m3onSecondaryContainer
|
property color handleColor: Appearance.colors.colPrimary
|
||||||
property color dotColor: Appearance.m3colors.m3onSecondaryContainer
|
property color dotColor: Appearance.m3colors.m3onSecondaryContainer
|
||||||
property color dotColorHighlighted: Appearance.m3colors.m3onPrimary
|
property color dotColorHighlighted: Appearance.m3colors.m3onPrimary
|
||||||
property real unsharpenRadius: Appearance.rounding.unsharpen
|
property real unsharpenRadius: Appearance.rounding.unsharpen
|
||||||
@@ -39,15 +40,18 @@ Slider {
|
|||||||
property real trackRadius: trackWidth >= StyledSlider.Configuration.XL ? 21
|
property real trackRadius: trackWidth >= StyledSlider.Configuration.XL ? 21
|
||||||
: trackWidth >= StyledSlider.Configuration.L ? 12
|
: trackWidth >= StyledSlider.Configuration.L ? 12
|
||||||
: trackWidth >= StyledSlider.Configuration.M ? 9
|
: trackWidth >= StyledSlider.Configuration.M ? 9
|
||||||
: 6
|
: trackWidth >= StyledSlider.Configuration.S ? 6
|
||||||
property real handleHeight: Math.max(33, trackWidth + 9)
|
: height / 2
|
||||||
|
property real handleHeight: (configuration === StyledSlider.Configuration.Wavy) ? 24 : Math.max(33, trackWidth + 9)
|
||||||
property real handleWidth: root.pressed ? handlePressedWidth : handleDefaultWidth
|
property real handleWidth: root.pressed ? handlePressedWidth : handleDefaultWidth
|
||||||
property real handleMargins: 4
|
property real handleMargins: 4
|
||||||
onHandleMarginsChanged: {
|
|
||||||
console.log("Handle margins changed to", handleMargins);
|
|
||||||
}
|
|
||||||
property real trackDotSize: 3
|
property real trackDotSize: 3
|
||||||
property string tooltipContent: `${Math.round(value * 100)}%`
|
property string tooltipContent: `${Math.round(value * 100)}%`
|
||||||
|
property bool wavy: configuration === StyledSlider.Configuration.Wavy // If true, the progress bar will have a wavy fill effect
|
||||||
|
property bool animateWave: true
|
||||||
|
property real waveAmplitudeMultiplier: wavy ? 0.5 : 0
|
||||||
|
property real waveFrequency: 6
|
||||||
|
property real waveFps: 60
|
||||||
|
|
||||||
leftPadding: handleMargins
|
leftPadding: handleMargins
|
||||||
rightPadding: handleMargins
|
rightPadding: handleMargins
|
||||||
@@ -93,18 +97,51 @@ Slider {
|
|||||||
implicitHeight: trackWidth
|
implicitHeight: trackWidth
|
||||||
|
|
||||||
// Fill left
|
// Fill left
|
||||||
Rectangle {
|
Loader {
|
||||||
anchors {
|
anchors {
|
||||||
verticalCenter: parent.verticalCenter
|
verticalCenter: parent.verticalCenter
|
||||||
left: parent.left
|
left: parent.left
|
||||||
}
|
}
|
||||||
width: root.handleMargins + (root.visualPosition * root.effectiveDraggingWidth) - (root.handleWidth / 2 + root.handleMargins)
|
width: root.handleMargins + (root.visualPosition * root.effectiveDraggingWidth) - (root.handleWidth / 2 + root.handleMargins)
|
||||||
height: trackWidth
|
height: root.trackWidth
|
||||||
color: root.highlightColor
|
active: !root.wavy
|
||||||
topLeftRadius: root.trackRadius
|
sourceComponent: Rectangle {
|
||||||
bottomLeftRadius: root.trackRadius
|
color: root.highlightColor
|
||||||
topRightRadius: root.unsharpenRadius
|
topLeftRadius: root.trackRadius
|
||||||
bottomRightRadius: root.unsharpenRadius
|
bottomLeftRadius: root.trackRadius
|
||||||
|
topRightRadius: root.unsharpenRadius
|
||||||
|
bottomRightRadius: root.unsharpenRadius
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
anchors {
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
left: parent.left
|
||||||
|
}
|
||||||
|
width: root.handleMargins + (root.visualPosition * root.effectiveDraggingWidth) - (root.handleWidth / 2 + root.handleMargins)
|
||||||
|
height: root.height
|
||||||
|
active: root.wavy
|
||||||
|
sourceComponent: WavyLine {
|
||||||
|
id: wavyFill
|
||||||
|
frequency: root.waveFrequency
|
||||||
|
fullLength: root.width
|
||||||
|
color: root.highlightColor
|
||||||
|
amplitudeMultiplier: root.wavy ? 0.5 : 0
|
||||||
|
width: root.handleMargins + (root.visualPosition * root.effectiveDraggingWidth) - (root.handleWidth / 2 + root.handleMargins)
|
||||||
|
height: root.trackWidth
|
||||||
|
Connections {
|
||||||
|
target: root
|
||||||
|
function onValueChanged() { wavyFill.requestPaint(); }
|
||||||
|
function onHighlightColorChanged() { wavyFill.requestPaint(); }
|
||||||
|
}
|
||||||
|
FrameAnimation {
|
||||||
|
running: root.animateWave
|
||||||
|
onTriggered: {
|
||||||
|
wavyFill.requestPaint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill right
|
// Fill right
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ Item {
|
|||||||
default property alias data: toolbarLayout.data
|
default property alias data: toolbarLayout.data
|
||||||
implicitWidth: background.implicitWidth
|
implicitWidth: background.implicitWidth
|
||||||
implicitHeight: background.implicitHeight
|
implicitHeight: background.implicitHeight
|
||||||
|
property alias radius: background.radius
|
||||||
|
|
||||||
StyledRectangularShadow {
|
StyledRectangularShadow {
|
||||||
target: background
|
target: background
|
||||||
@@ -23,11 +24,11 @@ Item {
|
|||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: background
|
id: background
|
||||||
anchors.centerIn: parent
|
anchors.fill: parent
|
||||||
color: Appearance.m3colors.m3surfaceContainer // Needs to be opaque
|
color: Appearance.m3colors.m3surfaceContainer // Needs to be opaque
|
||||||
implicitHeight: Math.max(toolbarLayout.implicitHeight + root.padding * 2, 56)
|
implicitHeight: Math.max(toolbarLayout.implicitHeight + root.padding * 2, 56)
|
||||||
implicitWidth: toolbarLayout.implicitWidth + root.padding * 2
|
implicitWidth: toolbarLayout.implicitWidth + root.padding * 2
|
||||||
radius: Appearance.rounding.full
|
radius: height / 2
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: toolbarLayout
|
id: toolbarLayout
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import qs.modules.common
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Canvas {
|
||||||
|
id: root
|
||||||
|
property real amplitudeMultiplier: 0.5
|
||||||
|
property real frequency: 6
|
||||||
|
property color color: Appearance?.colors.colPrimary ?? "#685496"
|
||||||
|
property real lineWidth: 4
|
||||||
|
property real fullLength: width
|
||||||
|
|
||||||
|
onPaint: {
|
||||||
|
var ctx = getContext("2d");
|
||||||
|
ctx.clearRect(0, 0, width, height);
|
||||||
|
|
||||||
|
var amplitude = root.lineWidth * root.amplitudeMultiplier;
|
||||||
|
var frequency = root.frequency;
|
||||||
|
var phase = Date.now() / 400.0;
|
||||||
|
var centerY = height / 2;
|
||||||
|
|
||||||
|
ctx.strokeStyle = root.color;
|
||||||
|
ctx.lineWidth = root.lineWidth;
|
||||||
|
ctx.lineCap = "round";
|
||||||
|
ctx.beginPath();
|
||||||
|
for (var x = ctx.lineWidth / 2; x <= root.width - ctx.lineWidth / 2; x += 1) {
|
||||||
|
var waveY = centerY + amplitude * Math.sin(frequency * 2 * Math.PI * x / root.fullLength + phase);
|
||||||
|
if (x === 0)
|
||||||
|
ctx.moveTo(x, waveY);
|
||||||
|
else
|
||||||
|
ctx.lineTo(x, waveY);
|
||||||
|
}
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import qs
|
import qs
|
||||||
|
import qs.modules.common
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Services.Pam
|
import Quickshell.Services.Pam
|
||||||
@@ -55,6 +56,7 @@ Scope {
|
|||||||
onCompleted: result => {
|
onCompleted: result => {
|
||||||
if (result == PamResult.Success) {
|
if (result == PamResult.Success) {
|
||||||
root.unlocked();
|
root.unlocked();
|
||||||
|
if (Config.options.lock.unlockKeyring) root.unlockKeyring();
|
||||||
} else {
|
} else {
|
||||||
root.showFailure = true;
|
root.showFailure = true;
|
||||||
GlobalStates.screenUnlockFailed = true;
|
GlobalStates.screenUnlockFailed = true;
|
||||||
@@ -64,4 +66,13 @@ Scope {
|
|||||||
root.unlockInProgress = false;
|
root.unlockInProgress = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function unlockKeyring() {
|
||||||
|
Quickshell.execDetached({
|
||||||
|
environment: ({
|
||||||
|
UNLOCK_PASSWORD: root.currentText
|
||||||
|
}),
|
||||||
|
command: ["bash", "-c", Quickshell.shellPath("scripts/keyring/unlock.sh")]
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,21 +155,21 @@ MouseArea {
|
|||||||
opacity: root.toolbarOpacity
|
opacity: root.toolbarOpacity
|
||||||
|
|
||||||
// Username
|
// Username
|
||||||
RowLayout {
|
Row {
|
||||||
spacing: 6
|
spacing: 6
|
||||||
Layout.leftMargin: 8
|
Layout.leftMargin: 8
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
|
||||||
MaterialSymbol {
|
MaterialSymbol {
|
||||||
id: userIcon
|
id: userIcon
|
||||||
Layout.alignment: Qt.AlignVCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
fill: 1
|
fill: 1
|
||||||
text: "account_circle"
|
text: "account_circle"
|
||||||
iconSize: Appearance.font.pixelSize.huge
|
iconSize: Appearance.font.pixelSize.huge
|
||||||
color: Appearance.colors.colOnSurfaceVariant
|
color: Appearance.colors.colOnSurfaceVariant
|
||||||
}
|
}
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.alignment: Qt.AlignVCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: SystemInfo.username
|
text: SystemInfo.username
|
||||||
color: Appearance.colors.colOnSurfaceVariant
|
color: Appearance.colors.colOnSurfaceVariant
|
||||||
}
|
}
|
||||||
@@ -184,18 +184,19 @@ MouseArea {
|
|||||||
active: true
|
active: true
|
||||||
visible: active
|
visible: active
|
||||||
|
|
||||||
sourceComponent: RowLayout {
|
sourceComponent: Row {
|
||||||
spacing: 8
|
spacing: 8
|
||||||
|
|
||||||
MaterialSymbol {
|
MaterialSymbol {
|
||||||
id: keyboardIcon
|
id: keyboardIcon
|
||||||
Layout.alignment: Qt.AlignVCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
fill: 1
|
fill: 1
|
||||||
text: "keyboard_alt"
|
text: "keyboard_alt"
|
||||||
iconSize: Appearance.font.pixelSize.huge
|
iconSize: Appearance.font.pixelSize.huge
|
||||||
color: Appearance.colors.colOnSurfaceVariant
|
color: Appearance.colors.colOnSurfaceVariant
|
||||||
}
|
}
|
||||||
Loader {
|
Loader {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
sourceComponent: StyledText {
|
sourceComponent: StyledText {
|
||||||
text: HyprlandXkb.currentLayoutCode
|
text: HyprlandXkb.currentLayoutCode
|
||||||
color: Appearance.colors.colOnSurfaceVariant
|
color: Appearance.colors.colOnSurfaceVariant
|
||||||
@@ -229,18 +230,18 @@ MouseArea {
|
|||||||
scale: root.toolbarScale
|
scale: root.toolbarScale
|
||||||
opacity: root.toolbarOpacity
|
opacity: root.toolbarOpacity
|
||||||
|
|
||||||
RowLayout {
|
Row {
|
||||||
visible: UPower.displayDevice.isLaptopBattery
|
visible: UPower.displayDevice.isLaptopBattery
|
||||||
spacing: 6
|
spacing: 4
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.leftMargin: 10
|
Layout.leftMargin: 10
|
||||||
Layout.rightMargin: 10
|
Layout.rightMargin: 10
|
||||||
|
|
||||||
MaterialSymbol {
|
MaterialSymbol {
|
||||||
id: boltIcon
|
id: boltIcon
|
||||||
Layout.alignment: Qt.AlignVCenter
|
anchors {
|
||||||
Layout.leftMargin: -2
|
verticalCenter: parent.verticalCenter
|
||||||
Layout.rightMargin: -2
|
}
|
||||||
fill: 1
|
fill: 1
|
||||||
text: Battery.isCharging ? "bolt" : "battery_android_full"
|
text: Battery.isCharging ? "bolt" : "battery_android_full"
|
||||||
iconSize: Appearance.font.pixelSize.huge
|
iconSize: Appearance.font.pixelSize.huge
|
||||||
@@ -248,7 +249,7 @@ MouseArea {
|
|||||||
color: (Battery.isLow && !Battery.isCharging) ? Appearance.colors.colError : Appearance.colors.colOnSurfaceVariant
|
color: (Battery.isLow && !Battery.isCharging) ? Appearance.colors.colError : Appearance.colors.colOnSurfaceVariant
|
||||||
}
|
}
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.alignment: Qt.AlignVCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: Math.round(Battery.percentage * 100)
|
text: Math.round(Battery.percentage * 100)
|
||||||
color: (Battery.isLow && !Battery.isCharging) ? Appearance.colors.colError : Appearance.colors.colOnSurfaceVariant
|
color: (Battery.isLow && !Battery.isCharging) ? Appearance.colors.colError : Appearance.colors.colOnSurfaceVariant
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
import qs.modules.common
|
import qs.modules.common
|
||||||
import qs.modules.common.widgets
|
import qs.modules.common.widgets
|
||||||
import qs.services
|
import qs.services
|
||||||
@@ -153,8 +154,8 @@ Scope {
|
|||||||
required property MprisPlayer modelData
|
required property MprisPlayer modelData
|
||||||
player: modelData
|
player: modelData
|
||||||
visualizerPoints: root.visualizerPoints
|
visualizerPoints: root.visualizerPoints
|
||||||
implicitWidth: widgetWidth
|
implicitWidth: root.widgetWidth
|
||||||
implicitHeight: widgetHeight
|
implicitHeight: root.widgetHeight
|
||||||
radius: root.popupRounding
|
radius: root.popupRounding
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
import qs.modules.common
|
import qs.modules.common
|
||||||
import qs.modules.common.models
|
import qs.modules.common.models
|
||||||
import qs.modules.common.widgets
|
import qs.modules.common.widgets
|
||||||
@@ -160,7 +161,7 @@ Item { // Player instance
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Image { // Art image
|
StyledImage { // Art image
|
||||||
id: mediaArt
|
id: mediaArt
|
||||||
property int size: parent.height
|
property int size: parent.height
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -169,7 +170,6 @@ Item { // Player instance
|
|||||||
fillMode: Image.PreserveAspectCrop
|
fillMode: Image.PreserveAspectCrop
|
||||||
cache: false
|
cache: false
|
||||||
antialiasing: true
|
antialiasing: true
|
||||||
asynchronous: true
|
|
||||||
|
|
||||||
width: size
|
width: size
|
||||||
height: size
|
height: size
|
||||||
@@ -233,16 +233,41 @@ Item { // Player instance
|
|||||||
Item {
|
Item {
|
||||||
id: progressBarContainer
|
id: progressBarContainer
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
implicitHeight: progressBar.implicitHeight
|
implicitHeight: Math.max(sliderLoader.implicitHeight, progressBarLoader.implicitHeight)
|
||||||
|
|
||||||
StyledProgressBar {
|
Loader {
|
||||||
id: progressBar
|
id: sliderLoader
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
highlightColor: blendedColors.colPrimary
|
active: playerController.player?.canSeek ?? false
|
||||||
trackColor: blendedColors.colSecondaryContainer
|
sourceComponent: StyledSlider {
|
||||||
value: playerController.player?.position / playerController.player?.length
|
configuration: StyledSlider.Configuration.Wavy
|
||||||
sperm: playerController.player?.isPlaying
|
highlightColor: blendedColors.colPrimary
|
||||||
|
trackColor: blendedColors.colSecondaryContainer
|
||||||
|
handleColor: blendedColors.colPrimary
|
||||||
|
value: playerController.player?.position / playerController.player?.length
|
||||||
|
onMoved: {
|
||||||
|
playerController.player.position = value * playerController.player.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: progressBarLoader
|
||||||
|
anchors {
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
active: !(playerController.player?.canSeek ?? false)
|
||||||
|
sourceComponent: StyledProgressBar {
|
||||||
|
wavy: playerController.player?.isPlaying
|
||||||
|
highlightColor: blendedColors.colPrimary
|
||||||
|
trackColor: blendedColors.colSecondaryContainer
|
||||||
|
value: playerController.player?.position / playerController.player?.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
TrackChangeButton {
|
TrackChangeButton {
|
||||||
iconName: "skip_next"
|
iconName: "skip_next"
|
||||||
|
|||||||
+49
-33
@@ -15,9 +15,21 @@ Scope {
|
|||||||
property string protectionMessage: ""
|
property string protectionMessage: ""
|
||||||
property var focusedScreen: Quickshell.screens.find(s => s.name === Hyprland.focusedMonitor?.name)
|
property var focusedScreen: Quickshell.screens.find(s => s.name === Hyprland.focusedMonitor?.name)
|
||||||
|
|
||||||
|
property string currentIndicator: "volume"
|
||||||
|
property var indicators: [
|
||||||
|
{
|
||||||
|
id: "volume",
|
||||||
|
sourceUrl: "indicators/VolumeIndicator.qml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "brightness",
|
||||||
|
sourceUrl: "indicators/BrightnessIndicator.qml"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
function triggerOsd() {
|
function triggerOsd() {
|
||||||
GlobalStates.osdVolumeOpen = true
|
GlobalStates.osdVolumeOpen = true;
|
||||||
osdTimeout.restart()
|
osdTimeout.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
@@ -26,35 +38,44 @@ Scope {
|
|||||||
repeat: false
|
repeat: false
|
||||||
running: false
|
running: false
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
GlobalStates.osdVolumeOpen = false
|
GlobalStates.osdVolumeOpen = false;
|
||||||
root.protectionMessage = ""
|
root.protectionMessage = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: Brightness
|
target: Brightness
|
||||||
function onBrightnessChanged() {
|
function onBrightnessChanged() {
|
||||||
GlobalStates.osdVolumeOpen = false
|
root.protectionMessage = "";
|
||||||
|
root.currentIndicator = "brightness";
|
||||||
|
root.triggerOsd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections { // Listen to volume changes
|
Connections {
|
||||||
|
// Listen to volume changes
|
||||||
target: Audio.sink?.audio ?? null
|
target: Audio.sink?.audio ?? null
|
||||||
function onVolumeChanged() {
|
function onVolumeChanged() {
|
||||||
if (!Audio.ready) return
|
if (!Audio.ready)
|
||||||
root.triggerOsd()
|
return;
|
||||||
|
root.currentIndicator = "volume";
|
||||||
|
root.triggerOsd();
|
||||||
}
|
}
|
||||||
function onMutedChanged() {
|
function onMutedChanged() {
|
||||||
if (!Audio.ready) return
|
if (!Audio.ready)
|
||||||
root.triggerOsd()
|
return;
|
||||||
|
root.currentIndicator = "volume";
|
||||||
|
root.triggerOsd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections { // Listen to protection triggers
|
Connections {
|
||||||
|
// Listen to protection triggers
|
||||||
target: Audio
|
target: Audio
|
||||||
function onSinkProtectionTriggered(reason) {
|
function onSinkProtectionTriggered(reason) {
|
||||||
root.protectionMessage = reason;
|
root.protectionMessage = reason;
|
||||||
root.triggerOsd()
|
root.currentIndicator = "volume";
|
||||||
|
root.triggerOsd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +90,7 @@ Scope {
|
|||||||
Connections {
|
Connections {
|
||||||
target: root
|
target: root
|
||||||
function onFocusedScreenChanged() {
|
function onFocusedScreenChanged() {
|
||||||
osdRoot.screen = root.focusedScreen
|
osdRoot.screen = root.focusedScreen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,10 +118,11 @@ Scope {
|
|||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: columnLayout
|
id: columnLayout
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: osdValuesWrapper
|
id: osdValuesWrapper
|
||||||
// Extra space for shadow
|
// Extra space for shadow
|
||||||
implicitHeight: contentColumnLayout.implicitHeight + Appearance.sizes.elevationMargin * 2
|
implicitHeight: contentColumnLayout.implicitHeight
|
||||||
implicitWidth: contentColumnLayout.implicitWidth
|
implicitWidth: contentColumnLayout.implicitWidth
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
@@ -110,30 +132,25 @@ Scope {
|
|||||||
onEntered: GlobalStates.osdVolumeOpen = false
|
onEntered: GlobalStates.osdVolumeOpen = false
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
Column {
|
||||||
id: contentColumnLayout
|
id: contentColumnLayout
|
||||||
anchors {
|
anchors {
|
||||||
top: parent.top
|
top: parent.top
|
||||||
left: parent.left
|
left: parent.left
|
||||||
right: parent.right
|
right: parent.right
|
||||||
leftMargin: Appearance.sizes.elevationMargin
|
|
||||||
rightMargin: Appearance.sizes.elevationMargin
|
|
||||||
}
|
}
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
OsdValueIndicator {
|
Loader {
|
||||||
id: osdValues
|
id: osdIndicatorLoader
|
||||||
Layout.fillWidth: true
|
source: root.indicators.find(i => i.id === root.currentIndicator)?.sourceUrl
|
||||||
value: Audio.sink?.audio.volume ?? 0
|
|
||||||
icon: Audio.sink?.audio.muted ? "volume_off" : "volume_up"
|
|
||||||
name: Translation.tr("Volume")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: protectionMessageWrapper
|
id: protectionMessageWrapper
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
implicitHeight: protectionMessageBackground.implicitHeight
|
implicitHeight: protectionMessageBackground.implicitHeight
|
||||||
implicitWidth: protectionMessageBackground.implicitWidth
|
implicitWidth: protectionMessageBackground.implicitWidth
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
opacity: root.protectionMessage !== "" ? 1 : 0
|
opacity: root.protectionMessage !== "" ? 1 : 0
|
||||||
|
|
||||||
StyledRectangularShadow {
|
StyledRectangularShadow {
|
||||||
@@ -174,26 +191,26 @@ Scope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IpcHandler {
|
IpcHandler {
|
||||||
target: "osdVolume"
|
target: "osdVolume"
|
||||||
|
|
||||||
function trigger() {
|
function trigger() {
|
||||||
root.triggerOsd()
|
root.triggerOsd();
|
||||||
}
|
}
|
||||||
|
|
||||||
function hide() {
|
function hide() {
|
||||||
GlobalStates.osdVolumeOpen = false
|
GlobalStates.osdVolumeOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggle() {
|
function toggle() {
|
||||||
GlobalStates.osdVolumeOpen = !GlobalStates.osdVolumeOpen
|
GlobalStates.osdVolumeOpen = !GlobalStates.osdVolumeOpen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GlobalShortcut {
|
GlobalShortcut {
|
||||||
name: "osdVolumeTrigger"
|
name: "osdVolumeTrigger"
|
||||||
description: "Triggers volume OSD on press"
|
description: "Triggers volume OSD on press"
|
||||||
|
|
||||||
onPressed: {
|
onPressed: {
|
||||||
root.triggerOsd()
|
root.triggerOsd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GlobalShortcut {
|
GlobalShortcut {
|
||||||
@@ -201,8 +218,7 @@ Scope {
|
|||||||
description: "Hides volume OSD on press"
|
description: "Hides volume OSD on press"
|
||||||
|
|
||||||
onPressed: {
|
onPressed: {
|
||||||
GlobalStates.osdVolumeOpen = false
|
GlobalStates.osdVolumeOpen = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,157 +0,0 @@
|
|||||||
import qs
|
|
||||||
import qs.services
|
|
||||||
import qs.modules.common
|
|
||||||
import qs.modules.common.widgets
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Io
|
|
||||||
import Quickshell.Hyprland
|
|
||||||
import Quickshell.Wayland
|
|
||||||
|
|
||||||
Scope {
|
|
||||||
id: root
|
|
||||||
property var focusedScreen: Quickshell.screens.find(s => s.name === Hyprland.focusedMonitor?.name)
|
|
||||||
property var brightnessMonitor: Brightness.getMonitorForScreen(focusedScreen)
|
|
||||||
|
|
||||||
function triggerOsd() {
|
|
||||||
GlobalStates.osdBrightnessOpen = true
|
|
||||||
osdTimeout.restart()
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: osdTimeout
|
|
||||||
interval: Config.options.osd.timeout
|
|
||||||
repeat: false
|
|
||||||
running: false
|
|
||||||
onTriggered: {
|
|
||||||
GlobalStates.osdBrightnessOpen = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: Audio.sink?.audio ?? null
|
|
||||||
function onVolumeChanged() {
|
|
||||||
if (!Audio.ready) return
|
|
||||||
GlobalStates.osdBrightnessOpen = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: Brightness
|
|
||||||
function onBrightnessChanged() {
|
|
||||||
if (!root.brightnessMonitor.ready) return
|
|
||||||
root.triggerOsd()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: osdLoader
|
|
||||||
active: GlobalStates.osdBrightnessOpen
|
|
||||||
|
|
||||||
sourceComponent: PanelWindow {
|
|
||||||
id: osdRoot
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: root
|
|
||||||
function onFocusedScreenChanged() {
|
|
||||||
osdRoot.screen = root.focusedScreen
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WlrLayershell.namespace: "quickshell:onScreenDisplay"
|
|
||||||
WlrLayershell.layer: WlrLayer.Overlay
|
|
||||||
anchors {
|
|
||||||
top: !Config.options.bar.bottom
|
|
||||||
bottom: Config.options.bar.bottom
|
|
||||||
}
|
|
||||||
mask: Region {
|
|
||||||
item: osdValuesWrapper
|
|
||||||
}
|
|
||||||
|
|
||||||
exclusionMode: ExclusionMode.Ignore
|
|
||||||
exclusiveZone: 0
|
|
||||||
margins {
|
|
||||||
top: Appearance.sizes.barHeight
|
|
||||||
bottom: Appearance.sizes.barHeight
|
|
||||||
}
|
|
||||||
|
|
||||||
implicitWidth: columnLayout.implicitWidth
|
|
||||||
implicitHeight: columnLayout.implicitHeight
|
|
||||||
visible: osdLoader.active
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: columnLayout
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
Item {
|
|
||||||
id: osdValuesWrapper
|
|
||||||
// Extra space for shadow
|
|
||||||
implicitHeight: osdValues.implicitHeight + Appearance.sizes.elevationMargin * 2
|
|
||||||
implicitWidth: osdValues.implicitWidth
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
onEntered: GlobalStates.osdBrightnessOpen = false
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on implicitHeight {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Appearance.animation.menuDecel.duration
|
|
||||||
easing.type: Appearance.animation.menuDecel.type
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OsdValueIndicator {
|
|
||||||
id: osdValues
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Appearance.sizes.elevationMargin
|
|
||||||
value: root.brightnessMonitor?.brightness ?? 50
|
|
||||||
icon: "light_mode"
|
|
||||||
rotateIcon: true
|
|
||||||
scaleIcon: true
|
|
||||||
name: Translation.tr("Brightness")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IpcHandler {
|
|
||||||
target: "osdBrightness"
|
|
||||||
|
|
||||||
function trigger() {
|
|
||||||
root.triggerOsd()
|
|
||||||
}
|
|
||||||
|
|
||||||
function hide() {
|
|
||||||
GlobalStates.osdBrightnessOpen = false
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggle() {
|
|
||||||
GlobalStates.osdBrightnessOpen = !GlobalStates.osdBrightnessOpen
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GlobalShortcut {
|
|
||||||
name: "osdBrightnessTrigger"
|
|
||||||
description: "Triggers brightness OSD on press"
|
|
||||||
|
|
||||||
onPressed: {
|
|
||||||
root.triggerOsd()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GlobalShortcut {
|
|
||||||
name: "osdBrightnessHide"
|
|
||||||
description: "Hides brightness OSD on press"
|
|
||||||
|
|
||||||
onPressed: {
|
|
||||||
GlobalStates.osdBrightnessOpen = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,8 @@
|
|||||||
import qs.services
|
|
||||||
import qs.modules.common
|
import qs.modules.common
|
||||||
import qs.modules.common.widgets
|
import qs.modules.common.widgets
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
|
||||||
import QtQuick.Effects
|
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Widgets
|
import Quickshell.Widgets
|
||||||
// import Qt5Compat.GraphicalEffects
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
@@ -21,19 +16,23 @@ Item {
|
|||||||
property real valueIndicatorLeftPadding: 10
|
property real valueIndicatorLeftPadding: 10
|
||||||
property real valueIndicatorRightPadding: 20 // An icon is circle ish, a column isn't, hence the extra padding
|
property real valueIndicatorRightPadding: 20 // An icon is circle ish, a column isn't, hence the extra padding
|
||||||
|
|
||||||
Layout.margins: Appearance.sizes.elevationMargin
|
implicitWidth: Appearance.sizes.osdWidth + 2 * Appearance.sizes.elevationMargin
|
||||||
implicitWidth: Appearance.sizes.osdWidth
|
implicitHeight: valueIndicator.implicitHeight + 2 * Appearance.sizes.elevationMargin
|
||||||
implicitHeight: valueIndicator.implicitHeight
|
|
||||||
|
|
||||||
StyledRectangularShadow {
|
StyledRectangularShadow {
|
||||||
target: valueIndicator
|
target: valueIndicator
|
||||||
}
|
}
|
||||||
WrapperRectangle {
|
Rectangle {
|
||||||
id: valueIndicator
|
id: valueIndicator
|
||||||
anchors.fill: parent
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
margins: Appearance.sizes.elevationMargin
|
||||||
|
}
|
||||||
radius: Appearance.rounding.full
|
radius: Appearance.rounding.full
|
||||||
color: Appearance.colors.colLayer0
|
color: Appearance.colors.colLayer0
|
||||||
|
|
||||||
implicitWidth: valueRow.implicitWidth
|
implicitWidth: valueRow.implicitWidth
|
||||||
|
implicitHeight: valueRow.implicitHeight
|
||||||
|
|
||||||
RowLayout { // Icon on the left, stuff on the right
|
RowLayout { // Icon on the left, stuff on the right
|
||||||
id: valueRow
|
id: valueRow
|
||||||
@@ -48,6 +47,7 @@ Item {
|
|||||||
Layout.leftMargin: valueIndicatorLeftPadding
|
Layout.leftMargin: valueIndicatorLeftPadding
|
||||||
Layout.topMargin: valueIndicatorVerticalPadding
|
Layout.topMargin: valueIndicatorVerticalPadding
|
||||||
Layout.bottomMargin: valueIndicatorVerticalPadding
|
Layout.bottomMargin: valueIndicatorVerticalPadding
|
||||||
|
|
||||||
MaterialSymbol { // Icon
|
MaterialSymbol { // Icon
|
||||||
anchors {
|
anchors {
|
||||||
centerIn: parent
|
centerIn: parent
|
||||||
@@ -101,4 +101,4 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import qs
|
||||||
|
import qs.services
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
import "../"
|
||||||
|
|
||||||
|
OsdValueIndicator {
|
||||||
|
id: root
|
||||||
|
property var focusedScreen: Quickshell.screens.find(s => s.name === Hyprland.focusedMonitor?.name)
|
||||||
|
property var brightnessMonitor: Brightness.getMonitorForScreen(focusedScreen)
|
||||||
|
|
||||||
|
value: root.brightnessMonitor?.brightness ?? 50
|
||||||
|
icon: "light_mode"
|
||||||
|
rotateIcon: true
|
||||||
|
scaleIcon: true
|
||||||
|
name: Translation.tr("Brightness")
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import qs
|
||||||
|
import qs.services
|
||||||
|
import QtQuick
|
||||||
|
import "../"
|
||||||
|
|
||||||
|
OsdValueIndicator {
|
||||||
|
id: osdValues
|
||||||
|
value: Audio.sink?.audio.volume ?? 0
|
||||||
|
icon: Audio.sink?.audio.muted ? "volume_off" : "volume_up"
|
||||||
|
name: Translation.tr("Volume")
|
||||||
|
}
|
||||||
@@ -63,7 +63,7 @@ Item {
|
|||||||
border.width: 1
|
border.width: 1
|
||||||
border.color: Appearance.colors.colLayer0Border
|
border.color: Appearance.colors.colLayer0Border
|
||||||
|
|
||||||
ColumnLayout { // Workspaces
|
Column { // Workspaces
|
||||||
id: workspaceColumnLayout
|
id: workspaceColumnLayout
|
||||||
|
|
||||||
z: root.workspaceZ
|
z: root.workspaceZ
|
||||||
@@ -71,7 +71,7 @@ Item {
|
|||||||
spacing: workspaceSpacing
|
spacing: workspaceSpacing
|
||||||
Repeater {
|
Repeater {
|
||||||
model: Config.options.overview.rows
|
model: Config.options.overview.rows
|
||||||
delegate: RowLayout {
|
delegate: Row {
|
||||||
id: row
|
id: row
|
||||||
property int rowIndex: index
|
property int rowIndex: index
|
||||||
spacing: workspaceSpacing
|
spacing: workspaceSpacing
|
||||||
@@ -148,27 +148,27 @@ Item {
|
|||||||
model: ScriptModel {
|
model: ScriptModel {
|
||||||
values: {
|
values: {
|
||||||
// console.log(JSON.stringify(ToplevelManager.toplevels.values.map(t => t), null, 2))
|
// console.log(JSON.stringify(ToplevelManager.toplevels.values.map(t => t), null, 2))
|
||||||
return ToplevelManager.toplevels.values.filter((toplevel) => {
|
return [...ToplevelManager.toplevels.values.filter((toplevel) => {
|
||||||
const address = `0x${toplevel.HyprlandToplevel?.address}`
|
const address = `0x${toplevel.HyprlandToplevel?.address}`
|
||||||
var win = windowByAddress[address]
|
var win = windowByAddress[address]
|
||||||
const inWorkspaceGroup = (root.workspaceGroup * root.workspacesShown < win?.workspace?.id && win?.workspace?.id <= (root.workspaceGroup + 1) * root.workspacesShown)
|
const inWorkspaceGroup = (root.workspaceGroup * root.workspacesShown < win?.workspace?.id && win?.workspace?.id <= (root.workspaceGroup + 1) * root.workspacesShown)
|
||||||
return inWorkspaceGroup;
|
return inWorkspaceGroup;
|
||||||
})
|
})].reverse()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delegate: OverviewWindow {
|
delegate: OverviewWindow {
|
||||||
id: window
|
id: window
|
||||||
required property var modelData
|
required property var modelData
|
||||||
property int monitorId: windowData?.monitor
|
property int monitorId: windowData?.monitor
|
||||||
property var monitor: HyprlandData.monitors[monitorId]
|
property var monitor: HyprlandData.monitors.find(m => m.id == monitorId)
|
||||||
property var address: `0x${modelData.HyprlandToplevel.address}`
|
property var address: `0x${modelData.HyprlandToplevel.address}`
|
||||||
windowData: windowByAddress[address]
|
|
||||||
toplevel: modelData
|
toplevel: modelData
|
||||||
monitorData: HyprlandData.monitors[monitorId]
|
monitorData: this.monitor
|
||||||
scale: root.scale
|
scale: root.scale
|
||||||
availableWorkspaceWidth: root.workspaceImplicitWidth
|
availableWorkspaceWidth: root.workspaceImplicitWidth
|
||||||
availableWorkspaceHeight: root.workspaceImplicitHeight
|
availableWorkspaceHeight: root.workspaceImplicitHeight
|
||||||
widgetMonitorId: root.monitor.id
|
widgetMonitorId: root.monitor.id
|
||||||
|
windowData: windowByAddress[address]
|
||||||
|
|
||||||
property bool atInitPosition: (initX == x && initY == y)
|
property bool atInitPosition: (initX == x && initY == y)
|
||||||
|
|
||||||
@@ -188,7 +188,7 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
z: atInitPosition ? root.windowZ : root.windowDraggingZ
|
z: atInitPosition ? (root.windowZ + windowData?.floating) : root.windowDraggingZ
|
||||||
Drag.hotSpot.x: targetWindowWidth / 2
|
Drag.hotSpot.x: targetWindowWidth / 2
|
||||||
Drag.hotSpot.y: targetWindowHeight / 2
|
Drag.hotSpot.y: targetWindowHeight / 2
|
||||||
MouseArea {
|
MouseArea {
|
||||||
@@ -218,8 +218,13 @@ Item {
|
|||||||
updateWindowPosition.restart()
|
updateWindowPosition.restart()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
window.x = window.initX
|
if (!window.windowData.floating) {
|
||||||
window.y = window.initY
|
updateWindowPosition.restart()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const percentageX = Math.round((window.x - xOffset) / root.workspaceImplicitWidth * 100)
|
||||||
|
const percentageY = Math.round((window.y - yOffset) / root.workspaceImplicitHeight * 100)
|
||||||
|
Hyprland.dispatch(`movewindowpixel exact ${percentageX}% ${percentageY}%, address:${window.windowData?.address}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onClicked: (event) => {
|
onClicked: (event) => {
|
||||||
|
|||||||
@@ -81,35 +81,29 @@ Item { // Window
|
|||||||
border.width : 1
|
border.width : 1
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
Image {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
id: windowIcon
|
||||||
anchors.left: parent.left
|
anchors.centerIn: parent
|
||||||
anchors.right: parent.right
|
property var iconSize: {
|
||||||
spacing: Appearance.font.pixelSize.smaller * 0.5
|
// console.log("-=-=-", root.toplevel.title, "-=-=-")
|
||||||
|
// console.log("Target window size:", targetWindowWidth, targetWindowHeight)
|
||||||
|
// console.log("Icon ratio:", root.compactMode ? root.iconToWindowRatioCompact : root.iconToWindowRatio)
|
||||||
|
// console.log("Scale:", root.monitorData.scale)
|
||||||
|
// console.log("Final:", Math.min(targetWindowWidth, targetWindowHeight) * (root.compactMode ? root.iconToWindowRatioCompact : root.iconToWindowRatio) / root.monitorData.scale)
|
||||||
|
return Math.min(targetWindowWidth, targetWindowHeight) * (root.compactMode ? root.iconToWindowRatioCompact : root.iconToWindowRatio) / root.monitorData.scale;
|
||||||
|
}
|
||||||
|
// mipmap: true
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
source: root.iconPath
|
||||||
|
width: iconSize
|
||||||
|
height: iconSize
|
||||||
|
sourceSize: Qt.size(iconSize, iconSize)
|
||||||
|
|
||||||
Image {
|
Behavior on width {
|
||||||
id: windowIcon
|
animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this)
|
||||||
property var iconSize: {
|
}
|
||||||
// console.log("-=-=-", root.toplevel.title, "-=-=-")
|
Behavior on height {
|
||||||
// console.log("Target window size:", targetWindowWidth, targetWindowHeight)
|
animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this)
|
||||||
// console.log("Icon ratio:", root.compactMode ? root.iconToWindowRatioCompact : root.iconToWindowRatio)
|
|
||||||
// console.log("Scale:", root.monitorData.scale)
|
|
||||||
// console.log("Final:", Math.min(targetWindowWidth, targetWindowHeight) * (root.compactMode ? root.iconToWindowRatioCompact : root.iconToWindowRatio) / root.monitorData.scale)
|
|
||||||
return Math.min(targetWindowWidth, targetWindowHeight) * (root.compactMode ? root.iconToWindowRatioCompact : root.iconToWindowRatio) / root.monitorData.scale;
|
|
||||||
}
|
|
||||||
// mipmap: true
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
source: root.iconPath
|
|
||||||
width: iconSize
|
|
||||||
height: iconSize
|
|
||||||
sourceSize: Qt.size(iconSize, iconSize)
|
|
||||||
|
|
||||||
Behavior on width {
|
|
||||||
animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this)
|
|
||||||
}
|
|
||||||
Behavior on height {
|
|
||||||
animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ Item { // Wrapper
|
|||||||
{
|
{
|
||||||
action: "konachanwallpaper",
|
action: "konachanwallpaper",
|
||||||
execute: () => {
|
execute: () => {
|
||||||
Quickshell.execDetached([Quickshell.shellPath("scripts/colors/random_konachan_wall.sh")]);
|
Quickshell.execDetached([Quickshell.shellPath("scripts/colors/random/random_konachan_wall.sh")]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -81,6 +81,12 @@ Item { // Wrapper
|
|||||||
GlobalStates.wallpaperSelectorOpen = true;
|
GlobalStates.wallpaperSelectorOpen = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
action: "wipeclipboard",
|
||||||
|
execute: () => {
|
||||||
|
Cliphist.wipe();
|
||||||
|
}
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
function focusFirstItem() {
|
function focusFirstItem() {
|
||||||
|
|||||||
@@ -167,6 +167,14 @@ ContentPage {
|
|||||||
icon: "lock"
|
icon: "lock"
|
||||||
title: Translation.tr("Lock screen")
|
title: Translation.tr("Lock screen")
|
||||||
|
|
||||||
|
ConfigSwitch {
|
||||||
|
text: Translation.tr('Launch on startup')
|
||||||
|
checked: Config.options.lock.launchOnStartup
|
||||||
|
onCheckedChanged: {
|
||||||
|
Config.options.lock.launchOnStartup = checked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ContentSubsection {
|
ContentSubsection {
|
||||||
title: Translation.tr("Blurred style")
|
title: Translation.tr("Blurred style")
|
||||||
|
|
||||||
|
|||||||
@@ -14,12 +14,13 @@ ContentPage {
|
|||||||
forceWidth: true
|
forceWidth: true
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: konachanWallProc
|
id: randomWallProc
|
||||||
property string status: ""
|
property string status: ""
|
||||||
command: ["bash", "-c", FileUtils.trimFileProtocol(`${Directories.scriptPath}/colors/random_konachan_wall.sh`)]
|
property string scriptPath: `${Directories.scriptPath}/colors/random/random_konachan_wall.sh`
|
||||||
|
command: ["bash", "-c", FileUtils.trimFileProtocol(randomWallProc.scriptPath)]
|
||||||
stdout: SplitParser {
|
stdout: SplitParser {
|
||||||
onRead: data => {
|
onRead: data => {
|
||||||
konachanWallProc.status = data.trim();
|
randomWallProc.status = data.trim();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,19 +91,35 @@ ContentPage {
|
|||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
RippleButtonWithIcon {
|
RippleButtonWithIcon {
|
||||||
id: rndWallBtn
|
enabled: !randomWallProc.running
|
||||||
visible: Config.options.policies.weeb === 1
|
visible: Config.options.policies.weeb === 1
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
buttonRadius: Appearance.rounding.small
|
buttonRadius: Appearance.rounding.small
|
||||||
materialIcon: "ifl"
|
materialIcon: "ifl"
|
||||||
mainText: konachanWallProc.running ? Translation.tr("Be patient...") : Translation.tr("Random: Konachan")
|
mainText: randomWallProc.running ? Translation.tr("Be patient...") : Translation.tr("Random: Konachan")
|
||||||
onClicked: {
|
onClicked: {
|
||||||
konachanWallProc.running = true;
|
randomWallProc.scriptPath = `${Directories.scriptPath}/colors/random/random_konachan_wall.sh`;
|
||||||
|
randomWallProc.running = true;
|
||||||
}
|
}
|
||||||
StyledToolTip {
|
StyledToolTip {
|
||||||
text: Translation.tr("Random SFW Anime wallpaper from Konachan\nImage is saved to ~/Pictures/Wallpapers")
|
text: Translation.tr("Random SFW Anime wallpaper from Konachan\nImage is saved to ~/Pictures/Wallpapers")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
RippleButtonWithIcon {
|
||||||
|
enabled: !randomWallProc.running
|
||||||
|
visible: Config.options.policies.weeb === 1
|
||||||
|
Layout.fillWidth: true
|
||||||
|
buttonRadius: Appearance.rounding.small
|
||||||
|
materialIcon: "ifl"
|
||||||
|
mainText: randomWallProc.running ? Translation.tr("Be patient...") : Translation.tr("Random: osu! seasonal")
|
||||||
|
onClicked: {
|
||||||
|
randomWallProc.scriptPath = `${Directories.scriptPath}/colors/random/random_osu_wall.sh`;
|
||||||
|
randomWallProc.running = true;
|
||||||
|
}
|
||||||
|
StyledToolTip {
|
||||||
|
text: Translation.tr("Random osu! seasonal background\nImage is saved to ~/Pictures/Wallpapers")
|
||||||
|
}
|
||||||
|
}
|
||||||
RippleButtonWithIcon {
|
RippleButtonWithIcon {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
materialIcon: "wallpaper"
|
materialIcon: "wallpaper"
|
||||||
@@ -154,17 +171,6 @@ ContentPage {
|
|||||||
dark: true
|
dark: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigSwitch {
|
|
||||||
text: Translation.tr("Transparency")
|
|
||||||
checked: Config.options.appearance.transparency.enable
|
|
||||||
onCheckedChanged: {
|
|
||||||
Config.options.appearance.transparency.enable = checked;
|
|
||||||
}
|
|
||||||
StyledToolTip {
|
|
||||||
text: Translation.tr("Might look ass. Unsupported.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,6 +219,17 @@ ContentPage {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConfigSwitch {
|
||||||
|
text: Translation.tr("Transparency")
|
||||||
|
checked: Config.options.appearance.transparency.enable
|
||||||
|
onCheckedChanged: {
|
||||||
|
Config.options.appearance.transparency.enable = checked;
|
||||||
|
}
|
||||||
|
StyledToolTip {
|
||||||
|
text: Translation.tr("Might look ass. Unsupported.")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentSection {
|
ContentSection {
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ Item {
|
|||||||
event.accepted = true
|
event.accepted = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((event.modifiers & Qt.ControlModifier) && (event.modifiers & Qt.ShiftModifier) && event.key === Qt.Key_O) {
|
||||||
|
Ai.clearMessages();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
property var allCommands: [
|
property var allCommands: [
|
||||||
@@ -332,14 +335,11 @@ Inline w/ backslash and round brackets \\(e^{i\\pi} + 1 = 0\\)
|
|||||||
mouseScrollFactor: Config.options.interactions.scrolling.mouseScrollFactor * 1.4
|
mouseScrollFactor: Config.options.interactions.scrolling.mouseScrollFactor * 1.4
|
||||||
|
|
||||||
property int lastResponseLength: 0
|
property int lastResponseLength: 0
|
||||||
property bool shouldAutoScroll: true
|
|
||||||
|
|
||||||
onContentYChanged: shouldAutoScroll = atYEnd
|
|
||||||
onContentHeightChanged: {
|
onContentHeightChanged: {
|
||||||
if (shouldAutoScroll) positionViewAtEnd();
|
if (atYEnd) positionViewAtEnd();
|
||||||
}
|
}
|
||||||
onCountChanged: { // Auto-scroll when new messages are added
|
onCountChanged: { // Auto-scroll when new messages are added
|
||||||
if (shouldAutoScroll) positionViewAtEnd();
|
if (atYEnd) positionViewAtEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
add: null // Prevent function calls from being janky
|
add: null // Prevent function calls from being janky
|
||||||
@@ -647,13 +647,24 @@ Inline w/ backslash and round brackets \\(e^{i\\pi} + 1 = 0\\)
|
|||||||
root.handleInput(inputText)
|
root.handleInput(inputText)
|
||||||
event.accepted = true
|
event.accepted = true
|
||||||
}
|
}
|
||||||
} else if ((event.modifiers & Qt.ControlModifier) && event.key === Qt.Key_V) { // Intercept Ctrl+V to handle image pasting
|
} else if ((event.modifiers & Qt.ControlModifier) && event.key === Qt.Key_V) { // Intercept Ctrl+V to handle image/file pasting
|
||||||
|
if (event.modifiers & Qt.ShiftModifier) { // Let Shift+Ctrl+V = plain paste
|
||||||
|
messageInputField.text += Quickshell.clipboardText
|
||||||
|
event.accepted = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Try image paste first
|
// Try image paste first
|
||||||
const currentClipboardEntry = Cliphist.entries[0]
|
const currentClipboardEntry = Cliphist.entries[0]
|
||||||
|
const cleanCliphistEntry = StringUtils.cleanCliphistEntry(currentClipboardEntry)
|
||||||
if (/^\d+\t\[\[.*binary data.*\d+x\d+.*\]\]$/.test(currentClipboardEntry)) { // First entry = currently copied entry = image?
|
if (/^\d+\t\[\[.*binary data.*\d+x\d+.*\]\]$/.test(currentClipboardEntry)) { // First entry = currently copied entry = image?
|
||||||
decodeImageAndAttachProc.handleEntry(currentClipboardEntry)
|
decodeImageAndAttachProc.handleEntry(currentClipboardEntry)
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
return;
|
return;
|
||||||
|
} else if (cleanCliphistEntry.startsWith("file://")) { // First entry = currently copied entry = image?
|
||||||
|
const fileName = decodeURIComponent(cleanCliphistEntry)
|
||||||
|
Ai.attachFile(fileName);
|
||||||
|
event.accepted = true;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
event.accepted = false; // No image, let text pasting proceed
|
event.accepted = false; // No image, let text pasting proceed
|
||||||
} else if (event.key === Qt.Key_Escape) { // Esc to detach file
|
} else if (event.key === Qt.Key_Escape) { // Esc to detach file
|
||||||
|
|||||||
@@ -127,8 +127,12 @@ Scope { // Scope
|
|||||||
|
|
||||||
sourceComponent: FloatingWindow {
|
sourceComponent: FloatingWindow {
|
||||||
id: detachedSidebarRoot
|
id: detachedSidebarRoot
|
||||||
visible: GlobalStates.sidebarLeftOpen
|
|
||||||
property var contentParent: detachedSidebarBackground
|
property var contentParent: detachedSidebarBackground
|
||||||
|
|
||||||
|
visible: GlobalStates.sidebarLeftOpen
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (!visible) GlobalStates.sidebarLeftOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: detachedSidebarBackground
|
id: detachedSidebarBackground
|
||||||
|
|||||||
@@ -125,13 +125,12 @@ Rectangle {
|
|||||||
sourceComponent: Item {
|
sourceComponent: Item {
|
||||||
implicitHeight: root.imageHeight * root.scale
|
implicitHeight: root.imageHeight * root.scale
|
||||||
implicitWidth: imagePreview.implicitWidth
|
implicitWidth: imagePreview.implicitWidth
|
||||||
Image {
|
StyledImage {
|
||||||
id: imagePreview
|
id: imagePreview
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
source: Qt.resolvedUrl(root.filePath)
|
source: Qt.resolvedUrl(root.filePath)
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
antialiasing: true
|
antialiasing: true
|
||||||
asynchronous: true
|
|
||||||
width: root.imageWidth * root.scale
|
width: root.imageWidth * root.scale
|
||||||
height: root.imageHeight * root.scale
|
height: root.imageHeight * root.scale
|
||||||
sourceSize.width: root.imageWidth * root.scale
|
sourceSize.width: root.imageWidth * root.scale
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ Button {
|
|||||||
contentItem: Item {
|
contentItem: Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
Image {
|
StyledImage {
|
||||||
id: imageObject
|
id: imageObject
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
width: root.rowHeight * modelData.aspect_ratio
|
width: root.rowHeight * modelData.aspect_ratio
|
||||||
@@ -68,12 +68,6 @@ Button {
|
|||||||
sourceSize.width: root.rowHeight * modelData.aspect_ratio
|
sourceSize.width: root.rowHeight * modelData.aspect_ratio
|
||||||
sourceSize.height: root.rowHeight
|
sourceSize.height: root.rowHeight
|
||||||
|
|
||||||
visible: opacity > 0
|
|
||||||
opacity: status === Image.Ready ? 1 : 0
|
|
||||||
Behavior on opacity {
|
|
||||||
animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
layer.effect: OpacityMask {
|
layer.effect: OpacityMask {
|
||||||
maskSource: Rectangle {
|
maskSource: Rectangle {
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ Item {
|
|||||||
StyledSlider {
|
StyledSlider {
|
||||||
id: slider
|
id: slider
|
||||||
value: root.node.audio.volume
|
value: root.node.audio.volume
|
||||||
onValueChanged: root.node.audio.volume = value
|
onMoved: root.node.audio.volume = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ Item { // Bar content region
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout { // Middle section
|
Column { // Middle section
|
||||||
id: middleSection
|
id: middleSection
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: 4
|
spacing: 4
|
||||||
@@ -156,8 +156,6 @@ Item { // Bar content region
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: false
|
Layout.fillHeight: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,12 +70,15 @@ MouseArea {
|
|||||||
hoverTarget: root
|
hoverTarget: root
|
||||||
active: GlobalStates.mediaControlsOpen ? false : root.containsMouse
|
active: GlobalStates.mediaControlsOpen ? false : root.containsMouse
|
||||||
|
|
||||||
ColumnLayout {
|
Column {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
RowLayout {
|
spacing: 4
|
||||||
spacing: 5
|
|
||||||
|
Row {
|
||||||
|
spacing: 4
|
||||||
|
|
||||||
MaterialSymbol {
|
MaterialSymbol {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
fill: 0
|
fill: 0
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
text: "music_note"
|
text: "music_note"
|
||||||
@@ -84,6 +87,7 @@ MouseArea {
|
|||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: "Media"
|
text: "Media"
|
||||||
font {
|
font {
|
||||||
weight: Font.Medium
|
weight: Font.Medium
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import qs.modules.common.functions
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
import Qt5Compat.GraphicalEffects
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
import Quickshell.Widgets
|
import Quickshell.Widgets
|
||||||
@@ -35,7 +36,11 @@ ShellRoot {
|
|||||||
property color imageFillColor: "#33f1d1ff"
|
property color imageFillColor: "#33f1d1ff"
|
||||||
property color onBorderColor: "#ff000000"
|
property color onBorderColor: "#ff000000"
|
||||||
property real standardRounding: 4
|
property real standardRounding: 4
|
||||||
readonly property var windows: HyprlandData.windowList
|
readonly property var windows: [...HyprlandData.windowList].sort((a, b) => {
|
||||||
|
// Sort floating=true windows before others
|
||||||
|
if (a.floating === b.floating) return 0;
|
||||||
|
return a.floating ? -1 : 1;
|
||||||
|
})
|
||||||
readonly property var layers: HyprlandData.layers
|
readonly property var layers: HyprlandData.layers
|
||||||
readonly property real falsePositivePreventionRatio: 0.5
|
readonly property real falsePositivePreventionRatio: 0.5
|
||||||
|
|
||||||
@@ -74,10 +79,10 @@ ShellRoot {
|
|||||||
}
|
}
|
||||||
implicitWidth: regionInfoRow.implicitWidth + horizontalPadding * 2
|
implicitWidth: regionInfoRow.implicitWidth + horizontalPadding * 2
|
||||||
implicitHeight: regionInfoRow.implicitHeight + verticalPadding * 2
|
implicitHeight: regionInfoRow.implicitHeight + verticalPadding * 2
|
||||||
RowLayout {
|
Row {
|
||||||
id: regionInfoRow
|
id: regionInfoRow
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: 8
|
spacing: 4
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: regionIconLoader
|
id: regionIconLoader
|
||||||
@@ -133,7 +138,8 @@ ShellRoot {
|
|||||||
})
|
})
|
||||||
readonly property list<var> layerRegions: {
|
readonly property list<var> layerRegions: {
|
||||||
const layersOfThisMonitor = root.layers[panelWindow.hyprlandMonitor.name]
|
const layersOfThisMonitor = root.layers[panelWindow.hyprlandMonitor.name]
|
||||||
const topLayers = layersOfThisMonitor.levels["2"]
|
const topLayers = layersOfThisMonitor?.levels["2"]
|
||||||
|
if (!topLayers) return [];
|
||||||
const nonBarTopLayers = topLayers
|
const nonBarTopLayers = topLayers
|
||||||
.filter(layer => !(layer.namespace.includes(":bar") || layer.namespace.includes(":verticalBar") || layer.namespace.includes(":dock")))
|
.filter(layer => !(layer.namespace.includes(":bar") || layer.namespace.includes(":verticalBar") || layer.namespace.includes(":dock")))
|
||||||
.map(layer => {
|
.map(layer => {
|
||||||
@@ -386,14 +392,24 @@ ShellRoot {
|
|||||||
|
|
||||||
// Overlay to darken screen
|
// Overlay to darken screen
|
||||||
Rectangle { // Base
|
Rectangle { // Base
|
||||||
id: overlayRect
|
id: darkenOverlay
|
||||||
z: 0
|
z: 1
|
||||||
anchors.fill: parent
|
anchors {
|
||||||
color: root.overlayColor
|
left: parent.left
|
||||||
layer.enabled: true
|
top: parent.top
|
||||||
|
leftMargin: panelWindow.regionX - darkenOverlay.border.width
|
||||||
|
topMargin: panelWindow.regionY - darkenOverlay.border.width
|
||||||
|
}
|
||||||
|
width: panelWindow.regionWidth + darkenOverlay.border.width * 2
|
||||||
|
height: panelWindow.regionHeight + darkenOverlay.border.width * 2
|
||||||
|
color: "transparent"
|
||||||
|
// border.color: root.selectionBorderColor
|
||||||
|
border.color: root.overlayColor
|
||||||
|
border.width: Math.max(panelWindow.width, panelWindow.height)
|
||||||
|
radius: root.standardRounding
|
||||||
}
|
}
|
||||||
Rectangle {
|
Rectangle {
|
||||||
// TODO: Make this mask the base instead of just overlaying a border
|
id: selectionBorder
|
||||||
z: 1
|
z: 1
|
||||||
anchors {
|
anchors {
|
||||||
left: parent.left
|
left: parent.left
|
||||||
@@ -406,11 +422,21 @@ ShellRoot {
|
|||||||
color: "transparent"
|
color: "transparent"
|
||||||
border.color: root.selectionBorderColor
|
border.color: root.selectionBorderColor
|
||||||
border.width: 2
|
border.width: 2
|
||||||
radius: root.standardRounding
|
// radius: root.standardRounding
|
||||||
|
radius: 0 // TODO: figure out how to make the overlay thing work with rounding
|
||||||
|
}
|
||||||
|
StyledText {
|
||||||
|
anchors {
|
||||||
|
bottom: selectionBorder.bottom
|
||||||
|
right: selectionBorder.right
|
||||||
|
margins: 8
|
||||||
|
}
|
||||||
|
text: `${Math.round(panelWindow.regionWidth)} x ${Math.round(panelWindow.regionHeight)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instructions
|
// Instructions
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
z: 9999
|
||||||
anchors {
|
anchors {
|
||||||
top: parent.top
|
top: parent.top
|
||||||
horizontalCenter: parent.horizontalCenter
|
horizontalCenter: parent.horizontalCenter
|
||||||
@@ -430,21 +456,19 @@ ShellRoot {
|
|||||||
implicitWidth: instructionsRow.implicitWidth + 10 * 2
|
implicitWidth: instructionsRow.implicitWidth + 10 * 2
|
||||||
implicitHeight: instructionsRow.implicitHeight + 5 * 2
|
implicitHeight: instructionsRow.implicitHeight + 5 * 2
|
||||||
|
|
||||||
RowLayout {
|
Row {
|
||||||
id: instructionsRow
|
id: instructionsRow
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
Item {
|
spacing: 4
|
||||||
Layout.fillHeight: true
|
MaterialSymbol {
|
||||||
implicitWidth: screenshotRegionIcon.implicitWidth
|
id: screenshotRegionIcon
|
||||||
MaterialSymbol {
|
// anchors.centerIn: parent
|
||||||
id: screenshotRegionIcon
|
iconSize: Appearance.font.pixelSize.larger
|
||||||
anchors.centerIn: parent
|
text: "screenshot_region"
|
||||||
iconSize: Appearance.font.pixelSize.larger
|
color: root.genericContentForeground
|
||||||
text: "screenshot_region"
|
|
||||||
color: root.genericContentForeground
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
StyledText {
|
StyledText {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: Translation.tr("Drag or click a region • LMB: Copy • RMB: Edit")
|
text: Translation.tr("Drag or click a region • LMB: Copy • RMB: Edit")
|
||||||
color: root.genericContentForeground
|
color: root.genericContentForeground
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -32,11 +32,11 @@ page=$((1 + RANDOM % 1000));
|
|||||||
response=$(curl "https://konachan.net/post.json?tags=rating%3Asafe&limit=1&page=$page")
|
response=$(curl "https://konachan.net/post.json?tags=rating%3Asafe&limit=1&page=$page")
|
||||||
link=$(echo "$response" | jq '.[0].file_url' -r);
|
link=$(echo "$response" | jq '.[0].file_url' -r);
|
||||||
ext=$(echo "$link" | awk -F. '{print $NF}')
|
ext=$(echo "$link" | awk -F. '{print $NF}')
|
||||||
downloadPath="$PICTURES_DIR/Wallpapers/konachan_random_image.$ext"
|
downloadPath="$PICTURES_DIR/Wallpapers/random_wallpaper.$ext"
|
||||||
illogicalImpulseConfigPath="$HOME/.config/illogical-impulse/config.json"
|
illogicalImpulseConfigPath="$HOME/.config/illogical-impulse/config.json"
|
||||||
currentWallpaperPath=$(jq -r '.background.wallpaperPath' $illogicalImpulseConfigPath)
|
currentWallpaperPath=$(jq -r '.background.wallpaperPath' $illogicalImpulseConfigPath)
|
||||||
if [ "$downloadPath" == "$currentWallpaperPath" ]; then
|
if [ "$downloadPath" == "$currentWallpaperPath" ]; then
|
||||||
downloadPath="$PICTURES_DIR/Wallpapers/konachan_random_image-1.$ext"
|
downloadPath="$PICTURES_DIR/Wallpapers/random_wallpaper-1.$ext"
|
||||||
fi
|
fi
|
||||||
curl "$link" -o "$downloadPath"
|
curl "$link" -o "$downloadPath"
|
||||||
"$SCRIPT_DIR/switchwall.sh" --image "$downloadPath"
|
"$SCRIPT_DIR/../switchwall.sh" --image "$downloadPath"
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
get_pictures_dir() {
|
||||||
|
if command -v xdg-user-dir &> /dev/null; then
|
||||||
|
xdg-user-dir PICTURES
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
local config_file="${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs"
|
||||||
|
if [ -f "$config_file" ]; then
|
||||||
|
local pictures_path
|
||||||
|
pictures_path=$(source "$config_file" >/dev/null 2>&1; echo "$XDG_PICTURES_DIR")
|
||||||
|
echo "${pictures_path/#\$HOME/$HOME}"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$HOME/Pictures"
|
||||||
|
}
|
||||||
|
|
||||||
|
QUICKSHELL_CONFIG_NAME="ii"
|
||||||
|
XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
|
||||||
|
XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}"
|
||||||
|
XDG_STATE_HOME="${XDG_STATE_HOME:-$HOME/.local/state}"
|
||||||
|
PICTURES_DIR=$(get_pictures_dir)
|
||||||
|
CONFIG_DIR="$XDG_CONFIG_HOME/quickshell/$QUICKSHELL_CONFIG_NAME"
|
||||||
|
CACHE_DIR="$XDG_CACHE_HOME/quickshell"
|
||||||
|
STATE_DIR="$XDG_STATE_HOME/quickshell"
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
mkdir -p "$PICTURES_DIR/Wallpapers"
|
||||||
|
|
||||||
|
response=$(curl "https://osu.ppy.sh/api/v2/seasonal-backgrounds")
|
||||||
|
images=$(echo "$response" | jq '.backgrounds | length' -r);
|
||||||
|
randomIndex=$((RANDOM % images));
|
||||||
|
link=$(echo "$response" | jq ".backgrounds[$randomIndex].url" -r)
|
||||||
|
ext=$(echo "$link" | awk -F. '{print $NF}')
|
||||||
|
downloadPath="$PICTURES_DIR/Wallpapers/random_wallpaper.$ext"
|
||||||
|
illogicalImpulseConfigPath="$HOME/.config/illogical-impulse/config.json"
|
||||||
|
currentWallpaperPath=$(jq -r '.background.wallpaperPath' $illogicalImpulseConfigPath)
|
||||||
|
if [ "$downloadPath" == "$currentWallpaperPath" ]; then
|
||||||
|
downloadPath="$PICTURES_DIR/Wallpapers/random_wallpaper-1.$ext"
|
||||||
|
fi
|
||||||
|
curl "$link" -o "$downloadPath"
|
||||||
|
"$SCRIPT_DIR/../switchwall.sh" --image "$downloadPath"
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Based on https://unix.stackexchange.com/a/602935
|
||||||
|
|
||||||
|
# Skip if already unlocked
|
||||||
|
locked_state=$(busctl --user get-property org.freedesktop.secrets \
|
||||||
|
/org/freedesktop/secrets/collection/login \
|
||||||
|
org.freedesktop.Secret.Collection Locked)
|
||||||
|
if [[ "${locked_state}" == "b false" ]]; then
|
||||||
|
echo 'Keyring is already unlocked.' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Prompt for password if not provided
|
||||||
|
if [[ -z "${UNLOCK_PASSWORD}" ]]; then
|
||||||
|
echo -n 'Login password: ' >&2
|
||||||
|
read -s UNLOCK_PASSWORD || return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Unlock
|
||||||
|
killall -q -u "$(whoami)" gnome-keyring-daemon
|
||||||
|
eval $(echo -n "${UNLOCK_PASSWORD}" \
|
||||||
|
| gnome-keyring-daemon --daemonize --login \
|
||||||
|
| sed -e 's/^/export /')
|
||||||
|
unset UNLOCK_PASSWORD
|
||||||
|
echo '' >&2
|
||||||
@@ -74,8 +74,14 @@ Singleton {
|
|||||||
id: monitor
|
id: monitor
|
||||||
|
|
||||||
required property ShellScreen screen
|
required property ShellScreen screen
|
||||||
readonly property bool isDdc: root.ddcMonitors.some(m => m.model === screen.model)
|
readonly property bool isDdc: {
|
||||||
readonly property string busNum: root.ddcMonitors.find(m => m.model === screen.model)?.busNum ?? ""
|
const match = root.ddcMonitors.find(m => m.model === screen.model && !root.monitors.slice(0, root.monitors.indexOf(this)).some(mon => mon.busNum === m.busNum));
|
||||||
|
return !!match;
|
||||||
|
}
|
||||||
|
readonly property string busNum: {
|
||||||
|
const match = root.ddcMonitors.find(m => m.model === screen.model && !root.monitors.slice(0, root.monitors.indexOf(this)).some(mon => mon.busNum === m.busNum));
|
||||||
|
return match?.busNum ?? "";
|
||||||
|
}
|
||||||
property int rawMaxBrightness: 100
|
property int rawMaxBrightness: 100
|
||||||
property real brightness
|
property real brightness
|
||||||
property bool ready: false
|
property bool ready: false
|
||||||
|
|||||||
@@ -95,6 +95,18 @@ Singleton {
|
|||||||
deleteProc.deleteEntry(entry);
|
deleteProc.deleteEntry(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: wipeProc
|
||||||
|
command: [root.cliphistBinary, "wipe"]
|
||||||
|
onExited: (exitCode, exitStatus) => {
|
||||||
|
root.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function wipe() {
|
||||||
|
wipeProc.running = true;
|
||||||
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: Quickshell
|
target: Quickshell
|
||||||
function onClipboardTextChanged() {
|
function onClipboardTextChanged() {
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import Quickshell.Io
|
|||||||
*/
|
*/
|
||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
property var manualActive
|
|
||||||
property string from: Config.options?.light?.night?.from ?? "19:00"
|
property string from: Config.options?.light?.night?.from ?? "19:00"
|
||||||
property string to: Config.options?.light?.night?.to ?? "06:30"
|
property string to: Config.options?.light?.night?.to ?? "06:30"
|
||||||
property bool automatic: Config.options?.light?.night?.automatic && (Config?.ready ?? true)
|
property bool automatic: Config.options?.light?.night?.automatic && (Config?.ready ?? true)
|
||||||
@@ -29,6 +28,9 @@ Singleton {
|
|||||||
property int clockHour: DateTime.clock.hours
|
property int clockHour: DateTime.clock.hours
|
||||||
property int clockMinute: DateTime.clock.minutes
|
property int clockMinute: DateTime.clock.minutes
|
||||||
|
|
||||||
|
property var manualActive
|
||||||
|
property int manualActiveHour
|
||||||
|
property int manualActiveMinute
|
||||||
|
|
||||||
onClockMinuteChanged: reEvaluate()
|
onClockMinuteChanged: reEvaluate()
|
||||||
onAutomaticChanged: {
|
onAutomaticChanged: {
|
||||||
@@ -36,17 +38,26 @@ Singleton {
|
|||||||
root.firstEvaluation = true;
|
root.firstEvaluation = true;
|
||||||
reEvaluate();
|
reEvaluate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function inBetween(t, from, to) {
|
||||||
|
if (from < to) {
|
||||||
|
return (t >= from && t <= to);
|
||||||
|
} else {
|
||||||
|
// Wrapped around midnight
|
||||||
|
return (t >= from || t <= to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function reEvaluate() {
|
function reEvaluate() {
|
||||||
const t = clockHour * 60 + clockMinute;
|
const t = clockHour * 60 + clockMinute;
|
||||||
const from = fromHour * 60 + fromMinute;
|
const from = fromHour * 60 + fromMinute;
|
||||||
const to = toHour * 60 + toMinute;
|
const to = toHour * 60 + toMinute;
|
||||||
|
const manualActive = manualActiveHour * 60 + manualActiveMinute;
|
||||||
|
|
||||||
if (from < to) {
|
if (root.manualActive !== undefined && (inBetween(from, manualActive, t) || inBetween(to, manualActive, t))) {
|
||||||
root.shouldBeOn = t >= from && t <= to;
|
root.manualActive = undefined;
|
||||||
} else {
|
|
||||||
// Wrapped around midnight
|
|
||||||
root.shouldBeOn = t >= from || t <= to;
|
|
||||||
}
|
}
|
||||||
|
root.shouldBeOn = inBetween(t, from, to);
|
||||||
if (firstEvaluation) {
|
if (firstEvaluation) {
|
||||||
firstEvaluation = false;
|
firstEvaluation = false;
|
||||||
root.ensureState();
|
root.ensureState();
|
||||||
@@ -94,15 +105,18 @@ Singleton {
|
|||||||
if (output.length == 0 || output.startsWith("Couldn't"))
|
if (output.length == 0 || output.startsWith("Couldn't"))
|
||||||
root.active = false;
|
root.active = false;
|
||||||
else
|
else
|
||||||
root.active = (output != "6500");
|
root.active = (output != "6500"); // 6500 is the default when off
|
||||||
// console.log("[Hyprsunset] Fetched state:", output, "->", root.active);
|
// console.log("[Hyprsunset] Fetched state:", output, "->", root.active);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggle() {
|
function toggle() {
|
||||||
if (root.manualActive === undefined)
|
if (root.manualActive === undefined) {
|
||||||
root.manualActive = root.active;
|
root.manualActive = root.active;
|
||||||
|
root.manualActiveHour = root.clockHour;
|
||||||
|
root.manualActiveMinute = root.clockMinute;
|
||||||
|
}
|
||||||
|
|
||||||
root.manualActive = !root.manualActive;
|
root.manualActive = !root.manualActive;
|
||||||
if (root.manualActive) {
|
if (root.manualActive) {
|
||||||
|
|||||||
@@ -12,10 +12,22 @@ Singleton {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
property alias inhibit: idleInhibitor.enabled
|
property alias inhibit: idleInhibitor.enabled
|
||||||
inhibit: Persistent.states.idle.inhibit
|
inhibit: false
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: Persistent
|
||||||
|
function onReadyChanged() {
|
||||||
|
if (!Persistent.isNewHyprlandInstance) {
|
||||||
|
root.inhibit = Persistent.states.idle.inhibit
|
||||||
|
} else {
|
||||||
|
Persistent.states.idle.inhibit = root.inhibit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function toggleInhibit() {
|
function toggleInhibit() {
|
||||||
Persistent.states.idle.inhibit = !Persistent.states.idle.inhibit
|
root.inhibit = !root.inhibit
|
||||||
|
Persistent.states.idle.inhibit = root.inhibit
|
||||||
}
|
}
|
||||||
|
|
||||||
IdleInhibitor {
|
IdleInhibitor {
|
||||||
|
|||||||
@@ -224,10 +224,8 @@ ApplicationWindow {
|
|||||||
Connections {
|
Connections {
|
||||||
target: root
|
target: root
|
||||||
function onCurrentPageChanged() {
|
function onCurrentPageChanged() {
|
||||||
if (pageLoader.sourceComponent !== root.pages[root.currentPage].component) {
|
switchAnim.complete();
|
||||||
switchAnim.complete();
|
switchAnim.start();
|
||||||
switchAnim.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,8 +42,7 @@ ShellRoot {
|
|||||||
property bool enableLock: true
|
property bool enableLock: true
|
||||||
property bool enableMediaControls: true
|
property bool enableMediaControls: true
|
||||||
property bool enableNotificationPopup: true
|
property bool enableNotificationPopup: true
|
||||||
property bool enableOnScreenDisplayBrightness: true
|
property bool enableOnScreenDisplay: true
|
||||||
property bool enableOnScreenDisplayVolume: true
|
|
||||||
property bool enableOnScreenKeyboard: true
|
property bool enableOnScreenKeyboard: true
|
||||||
property bool enableOverview: true
|
property bool enableOverview: true
|
||||||
property bool enableReloadPopup: true
|
property bool enableReloadPopup: true
|
||||||
@@ -72,8 +71,7 @@ ShellRoot {
|
|||||||
LazyLoader { active: enableLock; component: Lock {} }
|
LazyLoader { active: enableLock; component: Lock {} }
|
||||||
LazyLoader { active: enableMediaControls; component: MediaControls {} }
|
LazyLoader { active: enableMediaControls; component: MediaControls {} }
|
||||||
LazyLoader { active: enableNotificationPopup; component: NotificationPopup {} }
|
LazyLoader { active: enableNotificationPopup; component: NotificationPopup {} }
|
||||||
LazyLoader { active: enableOnScreenDisplayBrightness; component: OnScreenDisplayBrightness {} }
|
LazyLoader { active: enableOnScreenDisplay; component: OnScreenDisplay {} }
|
||||||
LazyLoader { active: enableOnScreenDisplayVolume; component: OnScreenDisplayVolume {} }
|
|
||||||
LazyLoader { active: enableOnScreenKeyboard; component: OnScreenKeyboard {} }
|
LazyLoader { active: enableOnScreenKeyboard; component: OnScreenKeyboard {} }
|
||||||
LazyLoader { active: enableOverview; component: Overview {} }
|
LazyLoader { active: enableOverview; component: Overview {} }
|
||||||
LazyLoader { active: enableReloadPopup; component: ReloadPopup {} }
|
LazyLoader { active: enableReloadPopup; component: ReloadPopup {} }
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ ApplicationWindow {
|
|||||||
Process {
|
Process {
|
||||||
id: konachanWallProc
|
id: konachanWallProc
|
||||||
property string status: ""
|
property string status: ""
|
||||||
command: ["bash", "-c", Quickshell.shellPath("scripts/colors/random_konachan_wall.sh")]
|
command: ["bash", "-c", Quickshell.shellPath("scripts/colors/random/random_konachan_wall.sh")]
|
||||||
stdout: SplitParser {
|
stdout: SplitParser {
|
||||||
onRead: data => {
|
onRead: data => {
|
||||||
console.log(`Konachan wall proc output: ${data}`);
|
console.log(`Konachan wall proc output: ${data}`);
|
||||||
|
|||||||
Reference in New Issue
Block a user