progress save

This commit is contained in:
kossLAN 2025-08-10 01:41:30 -04:00
parent fa7d012416
commit d32bedda31
Signed by: kossLAN
SSH key fingerprint: SHA256:bdV0x+wdQHGJ6LgmstH3KV8OpWY+OOFmJcPcB0wQPV8
9 changed files with 293 additions and 249 deletions

View file

@ -7,13 +7,26 @@ import Quickshell.Io
Singleton { Singleton {
property alias settings: jsonAdapter.settings property alias settings: jsonAdapter.settings
property alias sizing: jsonAdapter.sizing property alias sizing: jsonAdapter.sizing
property alias colors: jsonAdapter.colors
property QtObject colors: QtObject {
property color surface: Qt.rgba(1.0, 1.0, 1.0, 1.0)
property color surface_translucent: Qt.rgba(0.0, 0.0, 0.0, 0.15)
property color surface_container: Qt.rgba(0.25, 0.25, 0.25, 1.0)
property color surface_container_translucent: Qt.rgba(0.25, 0.25, 0.25, 0.25)
property color highlight: Qt.rgba(1.0, 1.0, 1.0, 0.85)
// property color primary: "#2EADC6"
property color active: Qt.rgba(1.0, 1.0, 1.0, 1.0)
property color active_translucent: Qt.rgba(1.0, 1.0, 1.0, 0.15)
property color border_translucent: Qt.rgba(1.0, 1.0, 1.0, 0.05)
property color inactive: Qt.rgba(0.25, 0.25, 0.25, 1.0)
property color inactive_translucent: Qt.rgba(0.25, 0.25, 0.25, 0.15)
}
FileView { FileView {
path: `${Quickshell.dataPath("settings")}/quickshell/settings.json` path: `${Quickshell.dataPath("settings")}/quickshell/settings.json`
watchChanges: true watchChanges: true
// onFileChanged: reload() onFileChanged: reload()
// onAdapterUpdated: writeAdapter() onAdapterUpdated: writeAdapter()
blockLoading: true blockLoading: true
JsonAdapter { JsonAdapter {
@ -28,20 +41,6 @@ Singleton {
property JsonObject sizing: JsonObject { property JsonObject sizing: JsonObject {
property int barHeight: 25 property int barHeight: 25
} }
property JsonObject colors: JsonObject {
property color surface: Qt.rgba(1.0, 1.0, 1.0, 1.0)
property color surface_translucent: Qt.rgba(0.0, 0.0, 0.0, 0.15)
property color surface_container: Qt.rgba(0.25, 0.25, 0.25, 1.0)
property color surface_container_translucent: Qt.rgba(0.25, 0.25, 0.25, 0.25)
property color highlight: Qt.rgba(1.0, 1.0, 1.0, 0.85)
// property color primary: "#2EADC6"
property color active: Qt.rgba(1.0, 1.0, 1.0, 1.0)
property color active_translucent: Qt.rgba(1.0, 1.0, 1.0, 0.15)
property color border_translucent: Qt.rgba(1.0, 1.0, 1.0, 0.05)
property color inactive: Qt.rgba(0.25, 0.25, 0.25, 1.0)
property color inactive_translucent: Qt.rgba(0.25, 0.25, 0.25, 0.15)
}
} }
} }
} }

View file

@ -7,11 +7,16 @@ import "systray"
// import qs.widgets // import qs.widgets
import qs import qs
PanelWindow { Variants {
model: Quickshell.screens
delegate: PanelWindow {
id: root id: root
color: "transparent" color: ShellSettings.colors.surface_translucent
implicitHeight: ShellSettings.sizing.barHeight implicitHeight: ShellSettings.sizing.barHeight
property alias popup: popupHandler screen: modelData
required property var modelData
anchors { anchors {
top: true top: true
@ -19,11 +24,6 @@ PanelWindow {
right: true right: true
} }
Rectangle {
color: ShellSettings.colors.surface_translucent
anchors.fill: parent
}
PopupHandler { PopupHandler {
id: popupHandler id: popupHandler
bar: root bar: root
@ -64,11 +64,40 @@ PanelWindow {
SysTray { SysTray {
id: sysTray id: sysTray
popup: root.popup popup: popupHandler
// bar: root
Layout.fillHeight: true Layout.fillHeight: true
} }
PopupItem {
id: test
Layout.preferredWidth: 20
Layout.fillHeight: true
onClicked: {
popupHandler.set(test);
}
menu: Rectangle {
implicitWidth: 100
implicitHeight: 100
}
}
PopupItem {
id: test2
Layout.preferredWidth: 20
Layout.fillHeight: true
onClicked: {
popupHandler.set(test2);
}
menu: Rectangle {
implicitWidth: 200
implicitHeight: 200
}
}
// VolumeIndicator { // VolumeIndicator {
// id: volumeIndicator // id: volumeIndicator
// popup: root.popup // popup: root.popup
@ -80,7 +109,6 @@ PanelWindow {
// BatteryIndicator { // BatteryIndicator {
// id: batteryIndicator // id: batteryIndicator
// popup: root.popup
// Layout.fillHeight: true // Layout.fillHeight: true
// } // }
@ -96,3 +124,4 @@ PanelWindow {
} }
} }
} }
}

View file

@ -1,10 +0,0 @@
import Quickshell
Variants {
model: Quickshell.screens
Bar {
required property var modelData
screen: modelData
}
}

View file

@ -1,17 +1,19 @@
pragma ComponentBehavior: Bound
import Quickshell import Quickshell
import Quickshell.Hyprland
import Quickshell.Widgets import Quickshell.Widgets
import Quickshell.Hyprland
import QtQuick import QtQuick
import qs import qs
PopupWindow { PopupWindow {
id: root id: root
visible: false
color: "transparent" color: "transparent"
implicitWidth: bar.width implicitWidth: bar.width
implicitHeight: Math.max(popupContainer.height, 800) + 20 implicitHeight: Math.max(1000, bar.height)
mask: Region { mask: Region {
item: popupContainer item: surface
} }
anchor { anchor {
@ -23,103 +25,126 @@ PopupWindow {
} }
required property var bar required property var bar
property var isOpen: false property var currentMenu
property var padding: 5 property real padding: 5
property var item
property var content
function set(item, content) { function set(item) {
root.item = item;
root.content = content;
popupContent.data = content;
let itemPos = item.mapToItem(root.bar.contentItem, 0, root.bar.height, item.width, 0).x; // Clear surface
position(itemPos); if (content.children.includes(item.menu)) {
console.log("Clearing popup surface.");
popupContainer.visible = false; root.currentMenu = undefined;
content.children = [];
// surface.implicitHeight = 0;
surface.opacity = 0;
contentOpacity.restart();
grab.active = false;
return;
} }
function position(itemPos) { // Set surface
if (itemPos === undefined) console.log("Setting popup surface.");
return; root.visible = true;
root.currentMenu = item.menu
content.children = [item.menu];
// content.implicitWidth = item.menu.implicitWidth;
// content.implicitHeight = item.menu.implicitHeight;
let rightEdge = itemPos + popupContainer.implicitWidth; let itemPos = item.mapToItem(root.bar.contentItem, 0, root.bar.height, item.width, 0).x;
// Check right edge
let rightEdge = itemPos + surface.implicitWidth;
let maxRightEdge = root.width - padding; let maxRightEdge = root.width - padding;
let isTouchingRightEdge = rightEdge > maxRightEdge; let isTouchingRightEdge = rightEdge > maxRightEdge;
if (isTouchingRightEdge) { if (isTouchingRightEdge) {
// touching right edge, reposition // touching right edge, reposition
// console.log("touching right edge"); surface.x = maxRightEdge - surface.implicitWidth;
popupContainer.x = maxRightEdge - popupContainer.implicitWidth; surface.y = padding;
popupContainer.y = padding;
} else { } else {
// not touching right edge // not touching right edge
popupContainer.x = itemPos; surface.x = itemPos;
popupContainer.y = padding; surface.y = padding;
}
} }
function show() { surface.opacity = 1;
contentOpacity.restart();
grab.active = true; grab.active = true;
isOpen = true;
root.visible = true; // set and leave open
root.content.visible = true;
popupContainer.visible = true;
}
function hide() {
grab.active = false;
isOpen = false;
popupContainer.visible = false;
root.item = undefined;
root.content = undefined;
popupContent.data = [];
}
function toggle() {
if (isOpen) {
hide();
} else {
show();
}
}
Rectangle {
color: ShellSettings.colors.surface_translucent
opacity: 0.15
radius: 12
anchors.fill: popupContainer
border.color: ShellSettings.colors.active
}
WrapperItem {
id: popupContainer
margin: 8
clip: true
x: root.bar.width
onVisibleChanged: root.visible = visible
// needed to handle occurences where items are resized while open
onImplicitWidthChanged: {
if (root.isOpen && popupContent.data !== []) {
// console.log("repositioning popup");
let itemPos = root.item.mapToItem(root.bar.contentItem, 0, root.bar.height, root.item.width, 0).x;
root.position(itemPos);
}
}
Item {
id: popupContent
implicitWidth: Math.max(root.content?.width, 60)
implicitHeight: Math.max(childrenRect.height, 60)
} }
HyprlandFocusGrab { HyprlandFocusGrab {
id: grab id: grab
windows: [root, root.bar] windows: [root, root.bar]
onCleared: { onCleared: {
root.hide(); surface.opacity = 0;
contentOpacity.restart();
root.currentMenu = undefined;
content.children = [];
}
}
WrapperRectangle {
id: surface
opacity: 0
visible: opacity > 0
color: ShellSettings.colors.surface_translucent
clip: true
margin: 5
radius: 12
border {
width: 1
color: ShellSettings.colors.active_translucent
}
// Animating implicit widht/height causes issues, this works but
// is kind of cursed, but fuck it. Better solutions welcome.
width: implicitWidth
height: implicitHeight
Item {
id: content
implicitWidth: Math.max(root.currentMenu?.width, 60)
implicitHeight: root.currentMenu?.height ?? 0
NumberAnimation {
id: contentOpacity
target: content
property: "opacity"
from: 0
to: 1
duration: 300
easing.type: Easing.InOutQuad
}
}
Behavior on opacity {
NumberAnimation {
duration: 250
easing.type: Easing.InOutQuad
}
}
Behavior on width {
enabled: root.visible
SmoothedAnimation {
duration: 250
easing.type: Easing.InOutQuad
}
}
Behavior on height {
SmoothedAnimation {
duration: 250
easing.type: Easing.InOutQuad
}
}
Behavior on x {
enabled: root.visible
SmoothedAnimation {
duration: 250
easing.type: Easing.InOutQuad
} }
} }
} }

8
shell/bar/PopupItem.qml Normal file
View file

@ -0,0 +1,8 @@
import QtQuick
import qs.widgets
StyledMouseArea {
id: root
property QtObject menu
}

View file

@ -26,7 +26,6 @@ Item {
} }
root.popup.set(this, powerMenu); root.popup.set(this, powerMenu);
root.popup.show();
} }
anchors { anchors {

View file

@ -2,95 +2,27 @@ pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import Quickshell
import Quickshell.Widgets
import Quickshell.Services.SystemTray import Quickshell.Services.SystemTray
import qs.widgets import ".."
RowLayout { RowLayout {
id: root id: root
spacing: 5 spacing: 5
visible: SystemTray.items.values.length > 0 visible: SystemTray.items.values.length > 0
required property var popup required property PopupHandler popup
Repeater { Repeater {
id: repeater
model: SystemTray.items model: SystemTray.items
delegate: Item { delegate: TrayMenuLauncher {
id: trayField id: trayItem
required property SystemTrayItem modelData
trayItem: modelData
popup: root.popup
Layout.preferredWidth: parent.height Layout.preferredWidth: parent.height
Layout.fillHeight: true Layout.fillHeight: true
required property SystemTrayItem modelData
StyledMouseArea {
id: trayButton
hoverEnabled: true
onClicked: {
menuOpener.menu = trayField.modelData.menu;
if (root.popup.content == trayMenu) {
root.popup.hide();
return;
}
root.popup.set(this, trayMenu);
root.popup.show();
}
anchors {
fill: parent
margins: 2
}
IconImage {
id: trayIcon
anchors.fill: parent
source: {
// console.log(trayField.modelData.id);
switch (trayField.modelData.id) {
case "obs":
return "image://icon/obs-tray";
default:
return trayField.modelData.icon;
}
}
}
}
QsMenuOpener {
id: menuOpener
}
WrapperItem {
id: trayMenu
visible: false
property var leftItem: false
property var rightItem: false
ColumnLayout {
id: menuContainer
spacing: 2
Repeater {
model: menuOpener.children
delegate: TrayMenuItem {
id: sysTrayContent
Layout.fillWidth: true
Layout.fillHeight: true
rootMenu: trayMenu
onInteracted: {
root.popup.hide();
menuOpener.menu = null;
}
}
}
}
}
} }
} }
} }

View file

@ -0,0 +1,62 @@
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Layouts
import Quickshell
import Quickshell.Widgets
import Quickshell.Services.SystemTray
import ".."
PopupItem {
id: root
onClicked: {
menuOpener.menu = trayItem.menu;
popup.set(menu);
}
required property PopupHandler popup
required property SystemTrayItem trayItem
menu: ColumnLayout {
id: trayMenu
spacing: 2
// visible: false
property var leftItem: false
property var rightItem: false
Repeater {
model: menuOpener.children
delegate: TrayMenuItem {
id: sysTrayContent
Layout.fillWidth: true
Layout.fillHeight: true
rootMenu: trayMenu
onInteracted: {
menuOpener.menu = null;
}
}
}
}
QsMenuOpener {
id: menuOpener
}
IconImage {
id: trayIcon
anchors.fill: parent
source: {
// console.log(trayField.modelData.id);
switch (root.trayItem.id) {
case "obs":
return "image://icon/obs-tray";
default:
return root.trayItem.icon;
}
}
}
}

View file

@ -3,7 +3,7 @@
import Quickshell import Quickshell
import QtQuick import QtQuick
import "bar" as Bar import "bar"
import "notifications" as Notifications import "notifications" as Notifications
import "mpris" as Mpris import "mpris" as Mpris
import "volume-osd" as VolumeOSD import "volume-osd" as VolumeOSD
@ -14,7 +14,7 @@ import "wallpaper" as Wallpaper
import "screencapture" as ScreenCapture import "screencapture" as ScreenCapture
ShellRoot { ShellRoot {
Bar.Controller {} Bar {}
Wallpaper.Controller {} Wallpaper.Controller {}
Notifications.Controller {} Notifications.Controller {}
VolumeOSD.Controller {} VolumeOSD.Controller {}