mirror of
https://github.com/danbulant/dots-hyprland
synced 2026-05-24 12:22:09 +00:00
vertical bar
This commit is contained in:
parent
25a0c88670
commit
9fc0d26eb5
17 changed files with 1334 additions and 80 deletions
|
|
@ -4,19 +4,18 @@ import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import Quickshell.Services.SystemTray
|
import Quickshell.Services.SystemTray
|
||||||
|
|
||||||
// TODO: More fancy animation
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
implicitWidth: gridLayout.implicitWidth
|
||||||
|
implicitHeight: gridLayout.implicitHeight
|
||||||
|
property bool vertical: false
|
||||||
|
|
||||||
height: parent.height
|
GridLayout {
|
||||||
implicitWidth: rowLayout.implicitWidth
|
id: gridLayout
|
||||||
Layout.leftMargin: Appearance.rounding.screenRounding
|
columns: root.vertical ? 1 : -1
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: rowLayout
|
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
spacing: 15
|
rowSpacing: 10
|
||||||
|
columnSpacing: 15
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: SystemTray.items
|
model: SystemTray.items
|
||||||
|
|
@ -24,12 +23,14 @@ Item {
|
||||||
SysTrayItem {
|
SysTrayItem {
|
||||||
required property SystemTrayItem modelData
|
required property SystemTrayItem modelData
|
||||||
item: modelData
|
item: modelData
|
||||||
|
Layout.fillHeight: !root.vertical
|
||||||
|
Layout.fillWidth: root.vertical
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||||
font.pixelSize: Appearance.font.pixelSize.larger
|
font.pixelSize: Appearance.font.pixelSize.larger
|
||||||
color: Appearance.colors.colSubtext
|
color: Appearance.colors.colSubtext
|
||||||
text: "•"
|
text: "•"
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,10 @@ MouseArea {
|
||||||
property var bar: root.QsWindow.window
|
property var bar: root.QsWindow.window
|
||||||
required property SystemTrayItem item
|
required property SystemTrayItem item
|
||||||
property bool targetMenuOpen: false
|
property bool targetMenuOpen: false
|
||||||
property int trayItemWidth: Appearance.font.pixelSize.larger
|
|
||||||
|
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
Layout.fillHeight: true
|
implicitWidth: 20
|
||||||
implicitWidth: trayItemWidth
|
implicitHeight: 20
|
||||||
onClicked: (event) => {
|
onClicked: (event) => {
|
||||||
switch (event.button) {
|
switch (event.button) {
|
||||||
case Qt.LeftButton:
|
case Qt.LeftButton:
|
||||||
|
|
@ -35,10 +34,11 @@ MouseArea {
|
||||||
|
|
||||||
menu: root.item.menu
|
menu: root.item.menu
|
||||||
anchor.window: bar
|
anchor.window: bar
|
||||||
anchor.rect.x: root.x + bar.width
|
anchor.rect.x: root.x + (Config.options.bar.vertical ? 0 : bar.width)
|
||||||
anchor.rect.y: root.y
|
anchor.rect.y: root.y + (Config.options.bar.vertical ? bar.height : 0)
|
||||||
anchor.rect.height: root.height
|
anchor.rect.height: root.height
|
||||||
anchor.edges: Edges.Bottom
|
anchor.rect.width: root.width
|
||||||
|
anchor.edges: Config.options.bar.bottom ? (Edges.Top | Edges.Left) : (Edges.Bottom | Edges.Right)
|
||||||
}
|
}
|
||||||
|
|
||||||
IconImage {
|
IconImage {
|
||||||
|
|
|
||||||
|
|
@ -329,19 +329,23 @@ Singleton {
|
||||||
property real barCenterSideModuleWidthHellaShortened: 190
|
property real barCenterSideModuleWidthHellaShortened: 190
|
||||||
property real barShortenScreenWidthThreshold: 1200 // Shorten if screen width is at most this value
|
property real barShortenScreenWidthThreshold: 1200 // Shorten if screen width is at most this value
|
||||||
property real barHellaShortenScreenWidthThreshold: 1000 // Shorten even more...
|
property real barHellaShortenScreenWidthThreshold: 1000 // Shorten even more...
|
||||||
property real sidebarWidth: 460
|
|
||||||
property real sidebarWidthExtended: 750
|
|
||||||
property real osdWidth: 200
|
|
||||||
property real mediaControlsWidth: 440
|
|
||||||
property real mediaControlsHeight: 160
|
|
||||||
property real notificationPopupWidth: 410
|
|
||||||
property real searchWidthCollapsed: 260
|
|
||||||
property real searchWidth: 450
|
|
||||||
property real hyprlandGapsOut: 5
|
|
||||||
property real elevationMargin: 10
|
property real elevationMargin: 10
|
||||||
property real fabShadowRadius: 5
|
property real fabShadowRadius: 5
|
||||||
property real fabHoveredShadowRadius: 7
|
property real fabHoveredShadowRadius: 7
|
||||||
|
property real hyprlandGapsOut: 5
|
||||||
|
property real mediaControlsWidth: 440
|
||||||
|
property real mediaControlsHeight: 160
|
||||||
|
property real notificationPopupWidth: 410
|
||||||
|
property real osdWidth: 200
|
||||||
|
property real searchWidthCollapsed: 260
|
||||||
|
property real searchWidth: 450
|
||||||
|
property real sidebarWidth: 460
|
||||||
|
property real sidebarWidthExtended: 750
|
||||||
|
property real baseVerticalBarWidth: 46
|
||||||
|
property real verticalBarWidth: Config.options.bar.cornerStyle === 1 ?
|
||||||
|
(baseVerticalBarWidth + root.sizes.hyprlandGapsOut * 2) : baseVerticalBarWidth
|
||||||
|
property real verticalBarGroupWidth: 38
|
||||||
}
|
}
|
||||||
|
|
||||||
syntaxHighlightingTheme: Appearance.m3colors.darkmode ? "Monokai" : "ayu Light"
|
syntaxHighlightingTheme: root.m3colors.darkmode ? "Monokai" : "ayu Light"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,7 @@ Singleton {
|
||||||
property string topLeftIcon: "spark" // Options: "distro" or any icon name in ~/.config/quickshell/ii/assets/icons
|
property string topLeftIcon: "spark" // Options: "distro" or any icon name in ~/.config/quickshell/ii/assets/icons
|
||||||
property bool showBackground: true
|
property bool showBackground: true
|
||||||
property bool verbose: true
|
property bool verbose: true
|
||||||
|
property bool vertical: false
|
||||||
property JsonObject resources: JsonObject {
|
property JsonObject resources: JsonObject {
|
||||||
property bool alwaysShowSwap: true
|
property bool alwaysShowSwap: true
|
||||||
property bool alwaysShowCpu: false
|
property bool alwaysShowCpu: false
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import Qt5Compat.GraphicalEffects
|
||||||
*/
|
*/
|
||||||
ProgressBar {
|
ProgressBar {
|
||||||
id: root
|
id: root
|
||||||
|
property bool vertical: false
|
||||||
property real valueBarWidth: 30
|
property real valueBarWidth: 30
|
||||||
property real valueBarHeight: 18
|
property real valueBarHeight: 18
|
||||||
property color highlightColor: Appearance?.colors.colOnSecondaryContainer ?? "#685496"
|
property color highlightColor: Appearance?.colors.colOnSecondaryContainer ?? "#685496"
|
||||||
|
|
@ -45,13 +46,36 @@ ProgressBar {
|
||||||
visible: false
|
visible: false
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
id: progressFill
|
||||||
anchors {
|
anchors {
|
||||||
left: parent.left
|
|
||||||
top: parent.top
|
top: parent.top
|
||||||
bottom: parent.bottom
|
bottom: parent.bottom
|
||||||
|
left: parent.left
|
||||||
|
right: undefined
|
||||||
}
|
}
|
||||||
radius: Appearance.rounding.unsharpen
|
|
||||||
width: parent.width * root.visualPosition
|
width: parent.width * root.visualPosition
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
states: State {
|
||||||
|
name: "vertical"
|
||||||
|
when: root.vertical
|
||||||
|
AnchorChanges {
|
||||||
|
target: progressFill
|
||||||
|
anchors {
|
||||||
|
top: undefined
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: progressFill
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height * root.visualPosition
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
radius: Appearance.rounding.unsharpen
|
||||||
color: root.highlightColor
|
color: root.highlightColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,10 @@ LazyLoader {
|
||||||
id: popupWindow
|
id: popupWindow
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
anchors.left: true
|
anchors.left: !Config.options.bar.vertical || (Config.options.bar.vertical && !Config.options.bar.bottom)
|
||||||
anchors.top: !Config.options.bar.bottom
|
anchors.right: Config.options.bar.vertical && Config.options.bar.bottom
|
||||||
anchors.bottom: 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
|
||||||
|
|
||||||
implicitWidth: popupBackground.implicitWidth + Appearance.sizes.hyprlandGapsOut * 2
|
implicitWidth: popupBackground.implicitWidth + Appearance.sizes.hyprlandGapsOut * 2
|
||||||
implicitHeight: popupBackground.implicitHeight + Appearance.sizes.hyprlandGapsOut * 2
|
implicitHeight: popupBackground.implicitHeight + Appearance.sizes.hyprlandGapsOut * 2
|
||||||
|
|
@ -27,12 +28,22 @@ LazyLoader {
|
||||||
exclusionMode: ExclusionMode.Ignore
|
exclusionMode: ExclusionMode.Ignore
|
||||||
exclusiveZone: 0
|
exclusiveZone: 0
|
||||||
margins {
|
margins {
|
||||||
left: root.QsWindow?.mapFromItem(
|
left: {
|
||||||
root.hoverTarget,
|
if (!Config.options.bar.vertical) return root.QsWindow?.mapFromItem(
|
||||||
(root.hoverTarget.width - popupBackground.implicitWidth) / 2, 0
|
root.hoverTarget,
|
||||||
).x
|
(root.hoverTarget.width - popupBackground.implicitWidth) / 2, 0
|
||||||
top: Config?.options.bar.bottom ? 0 : Appearance.sizes.barHeight
|
).x;
|
||||||
bottom: Config?.options.bar.bottom ? Appearance.sizes.barHeight : 0
|
return Appearance.sizes.barHeight
|
||||||
|
}
|
||||||
|
top: {
|
||||||
|
if (!Config.options.bar.vertical) return Appearance.sizes.barHeight;
|
||||||
|
return root.QsWindow?.mapFromItem(
|
||||||
|
root.hoverTarget,
|
||||||
|
(root.hoverTarget.height - popupBackground.implicitHeight) / 2, 0
|
||||||
|
).y;
|
||||||
|
}
|
||||||
|
right: Appearance.sizes.barHeight
|
||||||
|
bottom: Appearance.sizes.barHeight
|
||||||
}
|
}
|
||||||
WlrLayershell.namespace: "quickshell:popup"
|
WlrLayershell.namespace: "quickshell:popup"
|
||||||
WlrLayershell.layer: WlrLayer.Overlay
|
WlrLayershell.layer: WlrLayer.Overlay
|
||||||
|
|
|
||||||
|
|
@ -72,26 +72,53 @@ ContentPage {
|
||||||
ContentSection {
|
ContentSection {
|
||||||
title: Translation.tr("Bar")
|
title: Translation.tr("Bar")
|
||||||
|
|
||||||
ConfigSelectionArray {
|
ConfigRow {
|
||||||
currentValue: Config.options.bar.cornerStyle
|
ContentSubsection {
|
||||||
configOptionName: "bar.cornerStyle"
|
title: "Corner style"
|
||||||
onSelected: newValue => {
|
|
||||||
Config.options.bar.cornerStyle = newValue;
|
ConfigSelectionArray {
|
||||||
}
|
currentValue: Config.options.bar.cornerStyle
|
||||||
options: [
|
configOptionName: "bar.cornerStyle"
|
||||||
{
|
onSelected: newValue => {
|
||||||
displayName: Translation.tr("Hug"),
|
Config.options.bar.cornerStyle = newValue; // Update local copy
|
||||||
value: 0
|
}
|
||||||
},
|
options: [
|
||||||
{
|
{
|
||||||
displayName: Translation.tr("Float"),
|
displayName: Translation.tr("Hug"),
|
||||||
value: 1
|
value: 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: Translation.tr("Plain rectangle"),
|
displayName: Translation.tr("Float"),
|
||||||
value: 2
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: Translation.tr("Plain rectangle"),
|
||||||
|
value: 2
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
|
|
||||||
|
ContentSubsection {
|
||||||
|
title: "Bar layout"
|
||||||
|
ConfigSelectionArray {
|
||||||
|
currentValue: Config.options.bar.vertical
|
||||||
|
configOptionName: "bar.vertical"
|
||||||
|
onSelected: newValue => {
|
||||||
|
Config.options.bar.vertical = newValue;
|
||||||
|
}
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: Translation.tr("Horizontal"),
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: Translation.tr("Vertical"),
|
||||||
|
value: true
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentSubsection {
|
ContentSubsection {
|
||||||
|
|
@ -106,7 +133,7 @@ ContentPage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ConfigSwitch {
|
ConfigSwitch {
|
||||||
text: Translation.tr("Place at the bottom")
|
text: Translation.tr("Place at the bottom/right")
|
||||||
checked: Config.options.bar.bottom
|
checked: Config.options.bar.bottom
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
Config.options.bar.bottom = checked;
|
Config.options.bar.bottom = checked;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.widgets
|
||||||
|
import qs.services
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import "./../bar" as Bar
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: root
|
||||||
|
property bool borderless: Config.options.bar.borderless
|
||||||
|
readonly property var chargeState: Battery.chargeState
|
||||||
|
readonly property bool isCharging: Battery.isCharging
|
||||||
|
readonly property bool isPluggedIn: Battery.isPluggedIn
|
||||||
|
readonly property real percentage: Battery.percentage
|
||||||
|
readonly property bool isLow: percentage <= Config.options.battery.low / 100
|
||||||
|
|
||||||
|
implicitHeight: batteryProgress.implicitHeight
|
||||||
|
implicitWidth: Appearance.sizes.verticalBarGroupWidth
|
||||||
|
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
ClippedProgressBar {
|
||||||
|
id: batteryProgress
|
||||||
|
anchors.centerIn: parent
|
||||||
|
vertical: true
|
||||||
|
valueBarWidth: 21
|
||||||
|
valueBarHeight: 40
|
||||||
|
value: percentage
|
||||||
|
highlightColor: (isLow && !isCharging) ? Appearance.m3colors.m3error : Appearance.colors.colOnSecondaryContainer
|
||||||
|
|
||||||
|
font {
|
||||||
|
pixelSize: text.length > 2 ? 11 : 13
|
||||||
|
weight: text.length > 2 ? Font.Medium : Font.DemiBold
|
||||||
|
}
|
||||||
|
|
||||||
|
textMask: Item {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: batteryProgress.valueBarWidth
|
||||||
|
height: batteryProgress.valueBarHeight
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
MaterialSymbol {
|
||||||
|
id: boltIcon
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
fill: 1
|
||||||
|
text: isCharging ? "bolt" : "battery_android_full"
|
||||||
|
iconSize: Appearance.font.pixelSize.normal
|
||||||
|
visible: percentage < 1
|
||||||
|
}
|
||||||
|
StyledText {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
font: batteryProgress.font
|
||||||
|
text: batteryProgress.text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bar.BatteryPopup {
|
||||||
|
id: batteryPopup
|
||||||
|
hoverTarget: root
|
||||||
|
}
|
||||||
|
}
|
||||||
43
.config/quickshell/ii/modules/verticalBar/Resource.qml
Normal file
43
.config/quickshell/ii/modules/verticalBar/Resource.qml
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
import qs
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.widgets
|
||||||
|
import qs.services
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
required property string iconName
|
||||||
|
required property double percentage
|
||||||
|
implicitHeight: resourceProgress.implicitHeight
|
||||||
|
implicitWidth: Appearance.sizes.verticalBarWidth
|
||||||
|
|
||||||
|
// Helper function to format KB to GB
|
||||||
|
function formatKB(kb) {
|
||||||
|
return (kb / (1024 * 1024)).toFixed(1) + " GB";
|
||||||
|
}
|
||||||
|
|
||||||
|
ClippedFilledCircularProgress {
|
||||||
|
id: resourceProgress
|
||||||
|
anchors.centerIn: parent
|
||||||
|
value: percentage
|
||||||
|
|
||||||
|
MaterialSymbol {
|
||||||
|
font.weight: Font.Medium
|
||||||
|
fill: 1
|
||||||
|
text: root.iconName
|
||||||
|
iconSize: 13
|
||||||
|
color: Appearance.colors.colOnSecondaryContainer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
acceptedButtons: Qt.NoButton
|
||||||
|
enabled: root.visible
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
41
.config/quickshell/ii/modules/verticalBar/Resources.qml
Normal file
41
.config/quickshell/ii/modules/verticalBar/Resources.qml
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
import qs.services
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import "../bar" as Bar
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: root
|
||||||
|
property bool alwaysShowAllResources: false
|
||||||
|
implicitHeight: columnLayout.implicitHeight
|
||||||
|
implicitWidth: columnLayout.implicitWidth
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: columnLayout
|
||||||
|
spacing: 10
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Resource {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
iconName: "memory"
|
||||||
|
percentage: ResourceUsage.memoryUsedPercentage
|
||||||
|
}
|
||||||
|
|
||||||
|
Resource {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
iconName: "swap_horiz"
|
||||||
|
percentage: ResourceUsage.swapUsedPercentage
|
||||||
|
}
|
||||||
|
|
||||||
|
Resource {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
iconName: "planner_review"
|
||||||
|
percentage: ResourceUsage.cpuUsage
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Bar.ResourcesPopup {
|
||||||
|
hoverTarget: root
|
||||||
|
}
|
||||||
|
}
|
||||||
248
.config/quickshell/ii/modules/verticalBar/VerticalBar.qml
Normal file
248
.config/quickshell/ii/modules/verticalBar/VerticalBar.qml
Normal file
|
|
@ -0,0 +1,248 @@
|
||||||
|
import "./weather"
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
import Quickshell.Services.UPower
|
||||||
|
import qs
|
||||||
|
import qs.services
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.widgets
|
||||||
|
import qs.modules.common.functions
|
||||||
|
|
||||||
|
Scope {
|
||||||
|
id: bar
|
||||||
|
|
||||||
|
readonly property int osdHideMouseMoveThreshold: 20
|
||||||
|
property bool showBarBackground: Config.options.bar.showBackground
|
||||||
|
|
||||||
|
Variants {
|
||||||
|
// For each monitor
|
||||||
|
model: {
|
||||||
|
const screens = Quickshell.screens;
|
||||||
|
const list = Config.options.bar.screenList;
|
||||||
|
if (!list || list.length === 0)
|
||||||
|
return screens;
|
||||||
|
return screens.filter(screen => list.includes(screen.name));
|
||||||
|
}
|
||||||
|
LazyLoader {
|
||||||
|
id: barLoader
|
||||||
|
active: GlobalStates.barOpen && !GlobalStates.screenLocked
|
||||||
|
required property ShellScreen modelData
|
||||||
|
component: PanelWindow { // Bar window
|
||||||
|
id: barRoot
|
||||||
|
screen: barLoader.modelData
|
||||||
|
|
||||||
|
property var brightnessMonitor: Brightness.getMonitorForScreen(barLoader.modelData)
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: showBarTimer
|
||||||
|
interval: (Config?.options.bar.autoHide.showWhenPressingSuper.delay ?? 100)
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
barRoot.superShow = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Connections {
|
||||||
|
target: GlobalStates
|
||||||
|
function onSuperDownChanged() {
|
||||||
|
if (!Config?.options.bar.autoHide.showWhenPressingSuper.enable) return;
|
||||||
|
if (GlobalStates.superDown) showBarTimer.restart();
|
||||||
|
else {
|
||||||
|
showBarTimer.stop();
|
||||||
|
barRoot.superShow = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
property bool superShow: false
|
||||||
|
property bool mustShow: hoverRegion.containsMouse || superShow
|
||||||
|
exclusionMode: ExclusionMode.Ignore
|
||||||
|
exclusiveZone: (Config?.options.bar.autoHide.enable && (!mustShow || !Config?.options.bar.autoHide.pushWindows)) ? 0 :
|
||||||
|
Appearance.sizes.baseVerticalBarWidth + (Config.options.bar.cornerStyle === 1 ? Appearance.sizes.hyprlandGapsOut : 0)
|
||||||
|
WlrLayershell.namespace: "quickshell:verticalBar"
|
||||||
|
// WlrLayershell.layer: WlrLayer.Overlay // TODO enable this when bar can hide when fullscreen
|
||||||
|
implicitWidth: Appearance.sizes.verticalBarWidth + Appearance.rounding.screenRounding
|
||||||
|
mask: Region {
|
||||||
|
item: hoverMaskRegion
|
||||||
|
}
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
left: !Config.options.bar.bottom
|
||||||
|
right: Config.options.bar.bottom
|
||||||
|
top: true
|
||||||
|
bottom: true
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: hoverRegion
|
||||||
|
hoverEnabled: true
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: hoverMaskRegion
|
||||||
|
anchors {
|
||||||
|
fill: barContent
|
||||||
|
leftMargin: -1
|
||||||
|
rightMargin: -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VerticalBarContent {
|
||||||
|
id: barContent
|
||||||
|
|
||||||
|
implicitWidth: Appearance.sizes.verticalBarWidth
|
||||||
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: parent.left
|
||||||
|
right: undefined
|
||||||
|
leftMargin: (Config?.options.bar.autoHide.enable && !mustShow) ? -Appearance.sizes.verticalBarWidth : 0
|
||||||
|
rightMargin: 0
|
||||||
|
}
|
||||||
|
Behavior on anchors.leftMargin {
|
||||||
|
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
Behavior on anchors.rightMargin {
|
||||||
|
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
states: State {
|
||||||
|
name: "right"
|
||||||
|
when: Config.options.bar.bottom
|
||||||
|
AnchorChanges {
|
||||||
|
target: barContent
|
||||||
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: undefined
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: barContent
|
||||||
|
anchors.topMargin: 0
|
||||||
|
anchors.rightMargin: (Config?.options.bar.autoHide.enable && !mustShow) ? -Appearance.sizes.barHeight : 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Round decorators
|
||||||
|
Loader {
|
||||||
|
id: roundDecorators
|
||||||
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: barContent.right
|
||||||
|
right: undefined
|
||||||
|
}
|
||||||
|
width: Appearance.rounding.screenRounding
|
||||||
|
active: showBarBackground && Config.options.bar.cornerStyle === 0 // Hug
|
||||||
|
|
||||||
|
states: State {
|
||||||
|
name: "right"
|
||||||
|
when: Config.options.bar.bottom
|
||||||
|
AnchorChanges {
|
||||||
|
target: roundDecorators
|
||||||
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: undefined
|
||||||
|
right: barContent.left
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceComponent: Item {
|
||||||
|
implicitHeight: Appearance.rounding.screenRounding
|
||||||
|
RoundCorner {
|
||||||
|
id: topCorner
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
top: parent.top
|
||||||
|
}
|
||||||
|
|
||||||
|
implicitSize: Appearance.rounding.screenRounding
|
||||||
|
color: showBarBackground ? Appearance.colors.colLayer0 : "transparent"
|
||||||
|
|
||||||
|
corner: RoundCorner.CornerEnum.TopLeft
|
||||||
|
states: State {
|
||||||
|
name: "bottom"
|
||||||
|
when: Config.options.bar.bottom
|
||||||
|
PropertyChanges {
|
||||||
|
topCorner.corner: RoundCorner.CornerEnum.TopRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RoundCorner {
|
||||||
|
id: bottomCorner
|
||||||
|
anchors {
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: !Config.options.bar.bottom ? parent.left : undefined
|
||||||
|
right: Config.options.bar.bottom ? parent.right : undefined
|
||||||
|
}
|
||||||
|
implicitSize: Appearance.rounding.screenRounding
|
||||||
|
color: showBarBackground ? Appearance.colors.colLayer0 : "transparent"
|
||||||
|
|
||||||
|
corner: RoundCorner.CornerEnum.BottomLeft
|
||||||
|
states: State {
|
||||||
|
name: "bottom"
|
||||||
|
when: Config.options.bar.bottom
|
||||||
|
PropertyChanges {
|
||||||
|
bottomCorner.corner: RoundCorner.CornerEnum.BottomRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IpcHandler {
|
||||||
|
target: "bar"
|
||||||
|
|
||||||
|
function toggle(): void {
|
||||||
|
GlobalStates.barOpen = !GlobalStates.barOpen
|
||||||
|
}
|
||||||
|
|
||||||
|
function close(): void {
|
||||||
|
GlobalStates.barOpen = false
|
||||||
|
}
|
||||||
|
|
||||||
|
function open(): void {
|
||||||
|
GlobalStates.barOpen = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalShortcut {
|
||||||
|
name: "barToggle"
|
||||||
|
description: "Toggles bar on press"
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
GlobalStates.barOpen = !GlobalStates.barOpen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalShortcut {
|
||||||
|
name: "barOpen"
|
||||||
|
description: "Opens bar on press"
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
GlobalStates.barOpen = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalShortcut {
|
||||||
|
name: "barClose"
|
||||||
|
description: "Closes bar on press"
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
GlobalStates.barOpen = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
369
.config/quickshell/ii/modules/verticalBar/VerticalBarContent.qml
Normal file
369
.config/quickshell/ii/modules/verticalBar/VerticalBarContent.qml
Normal file
|
|
@ -0,0 +1,369 @@
|
||||||
|
import "./weather"
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
import Quickshell.Services.UPower
|
||||||
|
import qs
|
||||||
|
import qs.services
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.widgets
|
||||||
|
import qs.modules.common.functions
|
||||||
|
import "../bar" as Bar
|
||||||
|
|
||||||
|
Item { // Bar content region
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property var screen: root.QsWindow.window?.screen
|
||||||
|
property var brightnessMonitor: Brightness.getMonitorForScreen(screen)
|
||||||
|
|
||||||
|
component HorizontalBarSeparator: Rectangle {
|
||||||
|
Layout.leftMargin: Appearance.sizes.baseBarHeight / 3
|
||||||
|
Layout.rightMargin: Appearance.sizes.baseBarHeight / 3
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: 1
|
||||||
|
color: Appearance.colors.colOutlineVariant
|
||||||
|
}
|
||||||
|
|
||||||
|
// Background shadow
|
||||||
|
Loader {
|
||||||
|
active: Config.options.bar.showBackground && Config.options.bar.cornerStyle === 1
|
||||||
|
anchors.fill: barBackground
|
||||||
|
sourceComponent: StyledRectangularShadow {
|
||||||
|
anchors.fill: undefined // The loader's anchors act on this, and this should not have any anchor
|
||||||
|
target: barBackground
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Background
|
||||||
|
Rectangle {
|
||||||
|
id: barBackground
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
margins: Config.options.bar.cornerStyle === 1 ? (Appearance.sizes.hyprlandGapsOut) : 0 // idk why but +1 is needed
|
||||||
|
}
|
||||||
|
color: Config.options.bar.showBackground ? Appearance.colors.colLayer0 : "transparent"
|
||||||
|
radius: Config.options.bar.cornerStyle === 1 ? Appearance.rounding.windowRounding : 0
|
||||||
|
border.width: Config.options.bar.cornerStyle === 1 ? 1 : 0
|
||||||
|
border.color: Appearance.colors.colLayer0Border
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea { // Top section | scroll to change brightness
|
||||||
|
id: barTopSectionMouseArea
|
||||||
|
anchors.top: parent.top
|
||||||
|
implicitHeight: topSectionColumnLayout.implicitHeight
|
||||||
|
implicitWidth: Appearance.sizes.baseVerticalBarWidth
|
||||||
|
height: (root.height - middleSection.height) / 2
|
||||||
|
width: Appearance.sizes.verticalBarWidth
|
||||||
|
property bool hovered: false
|
||||||
|
property real lastScrollX: 0
|
||||||
|
property real lastScrollY: 0
|
||||||
|
property bool trackingScroll: false
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
|
hoverEnabled: true
|
||||||
|
propagateComposedEvents: true
|
||||||
|
onEntered: event => {
|
||||||
|
barTopSectionMouseArea.hovered = true;
|
||||||
|
}
|
||||||
|
onExited: event => {
|
||||||
|
barTopSectionMouseArea.hovered = false;
|
||||||
|
barTopSectionMouseArea.trackingScroll = false;
|
||||||
|
}
|
||||||
|
onPressed: event => {
|
||||||
|
if (event.button === Qt.LeftButton) {
|
||||||
|
GlobalStates.sidebarLeftOpen = !GlobalStates.sidebarLeftOpen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Scroll to change brightness
|
||||||
|
WheelHandler {
|
||||||
|
onWheel: event => {
|
||||||
|
if (event.angleDelta.y < 0)
|
||||||
|
root.brightnessMonitor.setBrightness(root.brightnessMonitor.brightness - 0.05);
|
||||||
|
else if (event.angleDelta.y > 0)
|
||||||
|
root.brightnessMonitor.setBrightness(root.brightnessMonitor.brightness + 0.05);
|
||||||
|
// Store the mouse position and start tracking
|
||||||
|
barTopSectionMouseArea.lastScrollX = event.x;
|
||||||
|
barTopSectionMouseArea.lastScrollY = event.y;
|
||||||
|
barTopSectionMouseArea.trackingScroll = true;
|
||||||
|
}
|
||||||
|
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
||||||
|
}
|
||||||
|
onPositionChanged: mouse => {
|
||||||
|
if (barTopSectionMouseArea.trackingScroll) {
|
||||||
|
const dx = mouse.x - barTopSectionMouseArea.lastScrollX;
|
||||||
|
const dy = mouse.y - barTopSectionMouseArea.lastScrollY;
|
||||||
|
if (Math.sqrt(dx * dx + dy * dy) > osdHideMouseMoveThreshold) {
|
||||||
|
GlobalStates.osdBrightnessOpen = false;
|
||||||
|
barTopSectionMouseArea.trackingScroll = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout { // Content
|
||||||
|
id: topSectionColumnLayout
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
RippleButton { // Left sidebar button
|
||||||
|
Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
|
||||||
|
Layout.topMargin: (Appearance.sizes.baseVerticalBarWidth - implicitWidth) / 2 + Appearance.sizes.hyprlandGapsOut
|
||||||
|
Layout.fillHeight: false
|
||||||
|
property real buttonPadding: 5
|
||||||
|
implicitWidth: distroIcon.width + buttonPadding * 2
|
||||||
|
implicitHeight: distroIcon.height + buttonPadding * 2
|
||||||
|
|
||||||
|
buttonRadius: Appearance.rounding.full
|
||||||
|
colBackground: barTopSectionMouseArea.hovered ? Appearance.colors.colLayer1Hover : ColorUtils.transparentize(Appearance.colors.colLayer1Hover, 1)
|
||||||
|
colBackgroundHover: Appearance.colors.colLayer1Hover
|
||||||
|
colRipple: Appearance.colors.colLayer1Active
|
||||||
|
colBackgroundToggled: Appearance.colors.colSecondaryContainer
|
||||||
|
colBackgroundToggledHover: Appearance.colors.colSecondaryContainerHover
|
||||||
|
colRippleToggled: Appearance.colors.colSecondaryContainerActive
|
||||||
|
toggled: GlobalStates.sidebarLeftOpen
|
||||||
|
property color colText: toggled ? Appearance.m3colors.m3onSecondaryContainer : Appearance.colors.colOnLayer0
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
GlobalStates.sidebarLeftOpen = !GlobalStates.sidebarLeftOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomIcon {
|
||||||
|
id: distroIcon
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: 19.5
|
||||||
|
height: 19.5
|
||||||
|
source: Config.options.bar.topLeftIcon == 'distro' ? SystemInfo.distroIcon : `${Config.options.bar.topLeftIcon}-symbolic`
|
||||||
|
colorize: true
|
||||||
|
color: Appearance.colors.colOnLayer0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout { // Middle section
|
||||||
|
id: middleSection
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 4
|
||||||
|
|
||||||
|
VerticalBarGroup {
|
||||||
|
padding: 8
|
||||||
|
Resources {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HorizontalBarSeparator {
|
||||||
|
visible: Config.options?.bar.borderless
|
||||||
|
}
|
||||||
|
|
||||||
|
VerticalBarGroup {
|
||||||
|
id: middleCenterGroup
|
||||||
|
padding: 6
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
Workspaces {
|
||||||
|
id: workspacesWidget
|
||||||
|
MouseArea {
|
||||||
|
// Right-click to toggle overview
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.RightButton
|
||||||
|
|
||||||
|
onPressed: event => {
|
||||||
|
if (event.button === Qt.RightButton) {
|
||||||
|
GlobalStates.overviewOpen = !GlobalStates.overviewOpen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HorizontalBarSeparator {
|
||||||
|
visible: Config.options?.bar.borderless
|
||||||
|
}
|
||||||
|
|
||||||
|
VerticalBarGroup {
|
||||||
|
padding: 8
|
||||||
|
|
||||||
|
VerticalClockWidget {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: false
|
||||||
|
}
|
||||||
|
|
||||||
|
BatteryIndicator {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea { // Bottom section | scroll to change volume
|
||||||
|
id: barBottomSectionMouseArea
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
bottom: parent.bottom
|
||||||
|
}
|
||||||
|
implicitWidth: Appearance.sizes.baseVerticalBarWidth
|
||||||
|
implicitHeight: bottomSectionColumnLayout.implicitHeight
|
||||||
|
width: Appearance.sizes.verticalBarWidth
|
||||||
|
|
||||||
|
property bool hovered: false
|
||||||
|
property real lastScrollX: 0
|
||||||
|
property real lastScrollY: 0
|
||||||
|
property bool trackingScroll: false
|
||||||
|
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
|
hoverEnabled: true
|
||||||
|
propagateComposedEvents: true
|
||||||
|
onEntered: event => {
|
||||||
|
barBottomSectionMouseArea.hovered = true;
|
||||||
|
}
|
||||||
|
onExited: event => {
|
||||||
|
barBottomSectionMouseArea.hovered = false;
|
||||||
|
barBottomSectionMouseArea.trackingScroll = false;
|
||||||
|
}
|
||||||
|
onPressed: event => {
|
||||||
|
if (event.button === Qt.LeftButton) {
|
||||||
|
GlobalStates.sidebarRightOpen = !GlobalStates.sidebarRightOpen;
|
||||||
|
} else if (event.button === Qt.RightButton) {
|
||||||
|
MprisController.activePlayer.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Scroll to change volume
|
||||||
|
WheelHandler {
|
||||||
|
onWheel: event => {
|
||||||
|
const currentVolume = Audio.value;
|
||||||
|
const step = currentVolume < 0.1 ? 0.01 : 0.02 || 0.2;
|
||||||
|
if (event.angleDelta.y < 0)
|
||||||
|
Audio.sink.audio.volume -= step;
|
||||||
|
else if (event.angleDelta.y > 0)
|
||||||
|
Audio.sink.audio.volume = Math.min(1, Audio.sink.audio.volume + step);
|
||||||
|
// Store the mouse position and start tracking
|
||||||
|
barBottomSectionMouseArea.lastScrollX = event.x;
|
||||||
|
barBottomSectionMouseArea.lastScrollY = event.y;
|
||||||
|
barBottomSectionMouseArea.trackingScroll = true;
|
||||||
|
}
|
||||||
|
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
||||||
|
}
|
||||||
|
onPositionChanged: mouse => {
|
||||||
|
if (barBottomSectionMouseArea.trackingScroll) {
|
||||||
|
const dx = mouse.x - barBottomSectionMouseArea.lastScrollX;
|
||||||
|
const dy = mouse.y - barBottomSectionMouseArea.lastScrollY;
|
||||||
|
if (Math.sqrt(dx * dx + dy * dy) > osdHideMouseMoveThreshold) {
|
||||||
|
GlobalStates.osdVolumeOpen = false;
|
||||||
|
barBottomSectionMouseArea.trackingScroll = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: bottomSectionColumnLayout
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: 4
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Bar.SysTray {
|
||||||
|
vertical: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: false
|
||||||
|
}
|
||||||
|
|
||||||
|
RippleButton { // Right sidebar button
|
||||||
|
id: rightSidebarButton
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignBottom | Qt.AlignHCenter
|
||||||
|
Layout.bottomMargin: Appearance.rounding.screenRounding
|
||||||
|
Layout.fillHeight: false
|
||||||
|
|
||||||
|
implicitHeight: indicatorsColumnLayout.implicitHeight + 4 * 2
|
||||||
|
implicitWidth: indicatorsColumnLayout.implicitWidth + 6 * 2
|
||||||
|
|
||||||
|
buttonRadius: Appearance.rounding.full
|
||||||
|
colBackground: barBottomSectionMouseArea.hovered ? Appearance.colors.colLayer1Hover : ColorUtils.transparentize(Appearance.colors.colLayer1Hover, 1)
|
||||||
|
colBackgroundHover: Appearance.colors.colLayer1Hover
|
||||||
|
colRipple: Appearance.colors.colLayer1Active
|
||||||
|
colBackgroundToggled: Appearance.colors.colSecondaryContainer
|
||||||
|
colBackgroundToggledHover: Appearance.colors.colSecondaryContainerHover
|
||||||
|
colRippleToggled: Appearance.colors.colSecondaryContainerActive
|
||||||
|
toggled: GlobalStates.sidebarRightOpen
|
||||||
|
property color colText: toggled ? Appearance.m3colors.m3onSecondaryContainer : Appearance.colors.colOnLayer0
|
||||||
|
|
||||||
|
Behavior on colText {
|
||||||
|
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
GlobalStates.sidebarRightOpen = !GlobalStates.sidebarRightOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: indicatorsColumnLayout
|
||||||
|
anchors.centerIn: parent
|
||||||
|
property real realSpacing: 6
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Revealer {
|
||||||
|
vertical: true
|
||||||
|
reveal: Audio.sink?.audio?.muted ?? false
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.bottomMargin: reveal ? indicatorsColumnLayout.realSpacing : 0
|
||||||
|
Behavior on Layout.bottomMargin {
|
||||||
|
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
MaterialSymbol {
|
||||||
|
text: "volume_off"
|
||||||
|
iconSize: Appearance.font.pixelSize.larger
|
||||||
|
color: rightSidebarButton.colText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Revealer {
|
||||||
|
vertical: true
|
||||||
|
reveal: Audio.source?.audio?.muted ?? false
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.bottomMargin: reveal ? indicatorsColumnLayout.realSpacing : 0
|
||||||
|
Behavior on Layout.topMargin {
|
||||||
|
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
MaterialSymbol {
|
||||||
|
text: "mic_off"
|
||||||
|
iconSize: Appearance.font.pixelSize.larger
|
||||||
|
color: rightSidebarButton.colText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loader {
|
||||||
|
active: HyprlandXkb.layoutCodes.length > 1
|
||||||
|
visible: active
|
||||||
|
Layout.bottomMargin: indicatorsColumnLayout.realSpacing
|
||||||
|
sourceComponent: StyledText {
|
||||||
|
text: HyprlandXkb.currentLayoutCode
|
||||||
|
font.pixelSize: Appearance.font.pixelSize.small
|
||||||
|
color: rightSidebarButton.colText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MaterialSymbol {
|
||||||
|
Layout.bottomMargin: indicatorsColumnLayout.realSpacing
|
||||||
|
text: Network.materialSymbol
|
||||||
|
iconSize: Appearance.font.pixelSize.larger
|
||||||
|
color: rightSidebarButton.colText
|
||||||
|
}
|
||||||
|
MaterialSymbol {
|
||||||
|
text: Bluetooth.bluetoothConnected ? "bluetooth_connected" : Bluetooth.bluetoothEnabled ? "bluetooth" : "bluetooth_disabled"
|
||||||
|
iconSize: Appearance.font.pixelSize.larger
|
||||||
|
color: rightSidebarButton.colText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
import qs.modules.common
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
property real padding: 5
|
||||||
|
implicitWidth: Appearance.sizes.baseVerticalBarWidth
|
||||||
|
width: Appearance.sizes.verticalBarWidth
|
||||||
|
implicitHeight: columnLayout.implicitHeight + padding * 2
|
||||||
|
default property alias items: columnLayout.children
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: background
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
leftMargin: 4
|
||||||
|
rightMargin: 4
|
||||||
|
}
|
||||||
|
color: Config.options?.bar.borderless ? "transparent" : Appearance.colors.colLayer1
|
||||||
|
radius: Appearance.rounding.small
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: columnLayout
|
||||||
|
anchors {
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
|
topMargin: root.padding
|
||||||
|
bottomMargin: root.padding
|
||||||
|
}
|
||||||
|
spacing: 12
|
||||||
|
|
||||||
|
// Children defined by `items` prop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.widgets
|
||||||
|
import qs.services
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import "../bar" as Bar
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
property bool borderless: Config.options.bar.borderless
|
||||||
|
implicitHeight: clockColumn.implicitHeight
|
||||||
|
implicitWidth: Appearance.sizes.verticalBarWidth
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: clockColumn
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: DateTime.time.split(/[: ]/)
|
||||||
|
delegate: StyledText {
|
||||||
|
required property string modelData
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
font.pixelSize: modelData.match(/am|pm/i) ?
|
||||||
|
Appearance.font.pixelSize.smaller // Smaller "am"/"pm" text
|
||||||
|
: Appearance.font.pixelSize.large
|
||||||
|
color: Appearance.colors.colOnLayer1
|
||||||
|
text: modelData.padStart(2, "0")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
acceptedButtons: Qt.NoButton
|
||||||
|
|
||||||
|
Bar.ClockWidgetTooltip {
|
||||||
|
hoverTarget: mouseArea
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
313
.config/quickshell/ii/modules/verticalBar/Workspaces.qml
Normal file
313
.config/quickshell/ii/modules/verticalBar/Workspaces.qml
Normal file
|
|
@ -0,0 +1,313 @@
|
||||||
|
import qs
|
||||||
|
import qs.services
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.widgets
|
||||||
|
import qs.modules.common.functions
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
import Quickshell.Widgets
|
||||||
|
import Qt5Compat.GraphicalEffects
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
property bool borderless: Config.options.bar.borderless
|
||||||
|
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(root.QsWindow.window?.screen)
|
||||||
|
readonly property Toplevel activeWindow: ToplevelManager.activeToplevel
|
||||||
|
|
||||||
|
readonly property int workspaceGroup: Math.floor((monitor?.activeWorkspace?.id - 1) / Config.options.bar.workspaces.shown)
|
||||||
|
property list<bool> workspaceOccupied: []
|
||||||
|
property int workspaceButtonWidth: 26
|
||||||
|
property real workspaceIconSize: workspaceButtonWidth * 0.69
|
||||||
|
property real workspaceIconSizeShrinked: workspaceButtonWidth * 0.55
|
||||||
|
property real workspaceIconOpacityShrinked: 1
|
||||||
|
property real workspaceIconMarginShrinked: -4
|
||||||
|
property int workspaceIndexInGroup: (monitor?.activeWorkspace?.id - 1) % Config.options.bar.workspaces.shown
|
||||||
|
|
||||||
|
implicitHeight: columnLayout.implicitHeight + columnLayout.spacing * 2
|
||||||
|
implicitWidth: Appearance.sizes.verticalBarWidth
|
||||||
|
|
||||||
|
property bool showNumbers: false
|
||||||
|
Timer {
|
||||||
|
id: showNumbersTimer
|
||||||
|
interval: (Config?.options.bar.autoHide.showWhenPressingSuper.delay ?? 100)
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
root.showNumbers = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Connections {
|
||||||
|
target: GlobalStates
|
||||||
|
function onSuperDownChanged() {
|
||||||
|
if (!Config?.options.bar.autoHide.showWhenPressingSuper.enable) return;
|
||||||
|
if (GlobalStates.superDown) showNumbersTimer.restart();
|
||||||
|
else {
|
||||||
|
showNumbersTimer.stop();
|
||||||
|
root.showNumbers = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function onSuperReleaseMightTriggerChanged() {
|
||||||
|
showNumbersTimer.stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to update workspaceOccupied
|
||||||
|
function updateWorkspaceOccupied() {
|
||||||
|
workspaceOccupied = Array.from({ length: Config.options.bar.workspaces.shown }, (_, i) => {
|
||||||
|
return Hyprland.workspaces.values.some(ws => ws.id === workspaceGroup * Config.options.bar.workspaces.shown + i + 1);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Occupied workspace updates
|
||||||
|
Component.onCompleted: updateWorkspaceOccupied()
|
||||||
|
Connections {
|
||||||
|
target: Hyprland.workspaces
|
||||||
|
function onValuesChanged() {
|
||||||
|
updateWorkspaceOccupied();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Connections {
|
||||||
|
target: Hyprland
|
||||||
|
function onFocusedWorkspaceChanged() {
|
||||||
|
updateWorkspaceOccupied();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onWorkspaceGroupChanged: {
|
||||||
|
updateWorkspaceOccupied();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scroll to switch workspaces
|
||||||
|
WheelHandler {
|
||||||
|
onWheel: (event) => {
|
||||||
|
if (event.angleDelta.y < 0)
|
||||||
|
Hyprland.dispatch(`workspace r+1`);
|
||||||
|
else if (event.angleDelta.y > 0)
|
||||||
|
Hyprland.dispatch(`workspace r-1`);
|
||||||
|
}
|
||||||
|
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.BackButton
|
||||||
|
onPressed: (event) => {
|
||||||
|
if (event.button === Qt.BackButton) {
|
||||||
|
Hyprland.dispatch(`togglespecialworkspace`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Workspaces - background
|
||||||
|
ColumnLayout {
|
||||||
|
id: columnLayout
|
||||||
|
z: 1
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
implicitWidth: Appearance.sizes.verticalBarWidth
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: Config.options.bar.workspaces.shown
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
z: 1
|
||||||
|
implicitWidth: workspaceButtonWidth
|
||||||
|
implicitHeight: workspaceButtonWidth
|
||||||
|
radius: (width / 2)
|
||||||
|
property var previousOccupied: (workspaceOccupied[index-1] && !(!activeWindow?.activated && monitor?.activeWorkspace?.id === index))
|
||||||
|
property var nextOccupied: (workspaceOccupied[index+1] && !(!activeWindow?.activated && monitor?.activeWorkspace?.id === index+2))
|
||||||
|
property var radiusTop: previousOccupied ? 0 : (width / 2)
|
||||||
|
property var radiusBottom: nextOccupied ? 0 : (width / 2)
|
||||||
|
|
||||||
|
topLeftRadius: radiusTop
|
||||||
|
topRightRadius: radiusTop
|
||||||
|
bottomLeftRadius: radiusBottom
|
||||||
|
bottomRightRadius: radiusBottom
|
||||||
|
|
||||||
|
color: ColorUtils.transparentize(Appearance.m3colors.m3secondaryContainer, 0.4)
|
||||||
|
opacity: (workspaceOccupied[index] && !(!activeWindow?.activated && monitor?.activeWorkspace?.id === index+1)) ? 1 : 0
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
Behavior on radiusTop {
|
||||||
|
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
Behavior on radiusBottom {
|
||||||
|
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Active workspace
|
||||||
|
Rectangle {
|
||||||
|
z: 2
|
||||||
|
// Make active ws indicator, which has a brighter color, smaller to look like it is of the same size as ws occupied highlight
|
||||||
|
property real activeWorkspaceMargin: 2
|
||||||
|
implicitWidth: workspaceButtonWidth - activeWorkspaceMargin * 2
|
||||||
|
radius: Appearance.rounding.full
|
||||||
|
color: Appearance.colors.colPrimary
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
property real idx1: workspaceIndexInGroup
|
||||||
|
property real idx2: workspaceIndexInGroup
|
||||||
|
y: Math.min(idx1, idx2) * workspaceButtonWidth + activeWorkspaceMargin
|
||||||
|
implicitHeight: Math.abs(idx1 - idx2) * workspaceButtonWidth + workspaceButtonWidth - activeWorkspaceMargin * 2
|
||||||
|
|
||||||
|
Behavior on activeWorkspaceMargin {
|
||||||
|
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
Behavior on idx1 { // Leading anim
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 100
|
||||||
|
easing.type: Easing.OutSine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Behavior on idx2 { // Following anim
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 300
|
||||||
|
easing.type: Easing.OutSine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Workspaces - numbers
|
||||||
|
ColumnLayout {
|
||||||
|
id: columnLayoutNumbers
|
||||||
|
z: 3
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
anchors.fill: parent
|
||||||
|
implicitWidth: Appearance.sizes.verticalBarWidth
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: Config.options.bar.workspaces.shown
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: button
|
||||||
|
property int workspaceValue: workspaceGroup * Config.options.bar.workspaces.shown + index + 1
|
||||||
|
Layout.fillWidth: true
|
||||||
|
onPressed: Hyprland.dispatch(`workspace ${workspaceValue}`)
|
||||||
|
height: workspaceButtonWidth
|
||||||
|
|
||||||
|
background: Item {
|
||||||
|
id: workspaceButtonBackground
|
||||||
|
implicitWidth: workspaceButtonWidth
|
||||||
|
implicitHeight: workspaceButtonWidth
|
||||||
|
property var biggestWindow: HyprlandData.biggestWindowForWorkspace(button.workspaceValue)
|
||||||
|
property var mainAppIconSource: Quickshell.iconPath(AppSearch.guessIcon(biggestWindow?.class), "image-missing")
|
||||||
|
|
||||||
|
StyledText { // Workspace number text
|
||||||
|
opacity: root.showNumbers
|
||||||
|
|| ((Config.options?.bar.workspaces.alwaysShowNumbers && (!Config.options?.bar.workspaces.showAppIcons || !workspaceButtonBackground.biggestWindow || root.showNumbers))
|
||||||
|
|| (root.showNumbers && !Config.options?.bar.workspaces.showAppIcons)
|
||||||
|
) ? 1 : 0
|
||||||
|
z: 3
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
font.pixelSize: Appearance.font.pixelSize.small - ((text.length - 1) * (text !== "10") * 2)
|
||||||
|
text: `${button.workspaceValue}`
|
||||||
|
elide: Text.ElideRight
|
||||||
|
color: (monitor?.activeWorkspace?.id == button.workspaceValue) ?
|
||||||
|
Appearance.m3colors.m3onPrimary :
|
||||||
|
(workspaceOccupied[index] ? Appearance.m3colors.m3onSecondaryContainer :
|
||||||
|
Appearance.colors.colOnLayer1Inactive)
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rectangle { // Dot instead of ws number
|
||||||
|
id: wsDot
|
||||||
|
opacity: (Config.options?.bar.workspaces.alwaysShowNumbers
|
||||||
|
|| root.showNumbers
|
||||||
|
|| (Config.options?.bar.workspaces.showAppIcons && workspaceButtonBackground.biggestWindow)
|
||||||
|
) ? 0 : 1
|
||||||
|
visible: opacity > 0
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: workspaceButtonWidth * 0.18
|
||||||
|
height: width
|
||||||
|
radius: width / 2
|
||||||
|
color: (monitor?.activeWorkspace?.id == button.workspaceValue) ?
|
||||||
|
Appearance.m3colors.m3onPrimary :
|
||||||
|
(workspaceOccupied[index] ? Appearance.m3colors.m3onSecondaryContainer :
|
||||||
|
Appearance.colors.colOnLayer1Inactive)
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item { // Main app icon
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: workspaceButtonWidth
|
||||||
|
height: workspaceButtonWidth
|
||||||
|
opacity: !Config.options?.bar.workspaces.showAppIcons ? 0 :
|
||||||
|
(workspaceButtonBackground.biggestWindow && !root.showNumbers && Config.options?.bar.workspaces.showAppIcons) ?
|
||||||
|
1 : workspaceButtonBackground.biggestWindow ? workspaceIconOpacityShrinked : 0
|
||||||
|
visible: opacity > 0
|
||||||
|
IconImage {
|
||||||
|
id: mainAppIcon
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottomMargin: (!root.showNumbers && Config.options?.bar.workspaces.showAppIcons) ?
|
||||||
|
(workspaceButtonWidth - workspaceIconSize) / 2 : workspaceIconMarginShrinked
|
||||||
|
anchors.rightMargin: (!root.showNumbers && Config.options?.bar.workspaces.showAppIcons) ?
|
||||||
|
(workspaceButtonWidth - workspaceIconSize) / 2 : workspaceIconMarginShrinked
|
||||||
|
|
||||||
|
source: workspaceButtonBackground.mainAppIconSource
|
||||||
|
implicitSize: (!root.showNumbers && Config.options?.bar.workspaces.showAppIcons) ? workspaceIconSize : workspaceIconSizeShrinked
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
Behavior on anchors.bottomMargin {
|
||||||
|
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
Behavior on anchors.rightMargin {
|
||||||
|
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
Behavior on implicitSize {
|
||||||
|
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
active: Config.options.bar.workspaces.monochromeIcons
|
||||||
|
anchors.fill: mainAppIcon
|
||||||
|
sourceComponent: Item {
|
||||||
|
Desaturate {
|
||||||
|
id: desaturatedIcon
|
||||||
|
visible: false // There's already color overlay
|
||||||
|
anchors.fill: parent
|
||||||
|
source: mainAppIcon
|
||||||
|
desaturation: 0.8
|
||||||
|
}
|
||||||
|
ColorOverlay {
|
||||||
|
anchors.fill: desaturatedIcon
|
||||||
|
source: desaturatedIcon
|
||||||
|
color: ColorUtils.transparentize(wsDot.color, 0.9)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -22,6 +22,7 @@ import "./modules/screenCorners/"
|
||||||
import "./modules/session/"
|
import "./modules/session/"
|
||||||
import "./modules/sidebarLeft/"
|
import "./modules/sidebarLeft/"
|
||||||
import "./modules/sidebarRight/"
|
import "./modules/sidebarRight/"
|
||||||
|
import "./modules/verticalBar/"
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Window
|
import QtQuick.Window
|
||||||
|
|
@ -47,6 +48,7 @@ ShellRoot {
|
||||||
property bool enableSession: true
|
property bool enableSession: true
|
||||||
property bool enableSidebarLeft: true
|
property bool enableSidebarLeft: true
|
||||||
property bool enableSidebarRight: true
|
property bool enableSidebarRight: true
|
||||||
|
property bool enableVerticalBar: true
|
||||||
|
|
||||||
// Force initialization of some singletons
|
// Force initialization of some singletons
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
|
|
@ -56,7 +58,7 @@ ShellRoot {
|
||||||
MaterialThemeLoader.reapplyTheme()
|
MaterialThemeLoader.reapplyTheme()
|
||||||
}
|
}
|
||||||
|
|
||||||
LazyLoader { active: enableBar; component: Bar {} }
|
LazyLoader { active: enableBar && Config.ready && !Config.options.bar.vertical; component: Bar {} }
|
||||||
LazyLoader { active: enableBackground; component: Background {} }
|
LazyLoader { active: enableBackground; component: Background {} }
|
||||||
LazyLoader { active: enableCheatsheet; component: Cheatsheet {} }
|
LazyLoader { active: enableCheatsheet; component: Cheatsheet {} }
|
||||||
LazyLoader { active: enableDock && Config.options.dock.enable; component: Dock {} }
|
LazyLoader { active: enableDock && Config.options.dock.enable; component: Dock {} }
|
||||||
|
|
@ -72,5 +74,6 @@ ShellRoot {
|
||||||
LazyLoader { active: enableSession; component: Session {} }
|
LazyLoader { active: enableSession; component: Session {} }
|
||||||
LazyLoader { active: enableSidebarLeft; component: SidebarLeft {} }
|
LazyLoader { active: enableSidebarLeft; component: SidebarLeft {} }
|
||||||
LazyLoader { active: enableSidebarRight; component: SidebarRight {} }
|
LazyLoader { active: enableSidebarRight; component: SidebarRight {} }
|
||||||
|
LazyLoader { active: enableVerticalBar && Config.ready && Config.options.bar.vertical; component: VerticalBar {} }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -134,29 +134,52 @@ ApplicationWindow {
|
||||||
ContentSection {
|
ContentSection {
|
||||||
title: Translation.tr("Bar")
|
title: Translation.tr("Bar")
|
||||||
|
|
||||||
ContentSubsection {
|
ConfigRow {
|
||||||
title: "Corner style"
|
ContentSubsection {
|
||||||
|
title: "Corner style"
|
||||||
|
|
||||||
ConfigSelectionArray {
|
ConfigSelectionArray {
|
||||||
currentValue: Config.options.bar.cornerStyle
|
currentValue: Config.options.bar.cornerStyle
|
||||||
configOptionName: "bar.cornerStyle"
|
configOptionName: "bar.cornerStyle"
|
||||||
onSelected: newValue => {
|
onSelected: newValue => {
|
||||||
Config.options.bar.cornerStyle = newValue; // Update local copy
|
Config.options.bar.cornerStyle = newValue; // Update local copy
|
||||||
}
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
displayName: Translation.tr("Hug"),
|
|
||||||
value: 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: Translation.tr("Float"),
|
|
||||||
value: 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: Translation.tr("Plain rectangle"),
|
|
||||||
value: 2
|
|
||||||
}
|
}
|
||||||
]
|
options: [
|
||||||
|
{
|
||||||
|
displayName: Translation.tr("Hug"),
|
||||||
|
value: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: Translation.tr("Float"),
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: Translation.tr("Plain rectangle"),
|
||||||
|
value: 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ContentSubsection {
|
||||||
|
title: "Bar layout"
|
||||||
|
ConfigSelectionArray {
|
||||||
|
currentValue: Config.options.bar.vertical
|
||||||
|
configOptionName: "bar.vertical"
|
||||||
|
onSelected: newValue => {
|
||||||
|
Config.options.bar.vertical = newValue;
|
||||||
|
}
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: Translation.tr("Horizontal"),
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: Translation.tr("Vertical"),
|
||||||
|
value: true
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -169,7 +192,7 @@ ApplicationWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ConfigSwitch {
|
ConfigSwitch {
|
||||||
text: Translation.tr("Place at the bottom")
|
text: Translation.tr("Place at the bottom/right")
|
||||||
checked: Config.options.bar.bottom
|
checked: Config.options.bar.bottom
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
Config.options.bar.bottom = checked;
|
Config.options.bar.bottom = checked;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue