Lots of uncommitted changes
This commit is contained in:
		
							parent
							
								
									daace49bfc
								
							
						
					
					
						commit
						497ca48ada
					
				
					 27 changed files with 909 additions and 134 deletions
				
			
		| 
						 | 
				
			
			@ -5,4 +5,5 @@ Image {
 | 
			
		|||
	required property ShellScreen screen;
 | 
			
		||||
	source: Qt.resolvedUrl(screen.name == "DP-1" ? "5120x1440.png" : "1920x1080.png")
 | 
			
		||||
	asynchronous: false
 | 
			
		||||
	cache: false
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,18 +6,17 @@ Item {
 | 
			
		|||
 | 
			
		||||
	Item {
 | 
			
		||||
		anchors.centerIn: parent
 | 
			
		||||
		scale: 2
 | 
			
		||||
 | 
			
		||||
		Text {
 | 
			
		||||
			id: timeText
 | 
			
		||||
			anchors {
 | 
			
		||||
				bottom: entryBox.top
 | 
			
		||||
				bottomMargin: 50
 | 
			
		||||
				bottomMargin: 100
 | 
			
		||||
				horizontalCenter: parent.horizontalCenter
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			font {
 | 
			
		||||
				pointSize: 60
 | 
			
		||||
				pointSize: 120
 | 
			
		||||
				hintingPreference: Font.PreferFullHinting
 | 
			
		||||
				family: "Noto Sans"
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -34,13 +33,11 @@ Item {
 | 
			
		|||
		Text {
 | 
			
		||||
			anchors {
 | 
			
		||||
				top: timeText.bottom
 | 
			
		||||
				topMargin: -10
 | 
			
		||||
				topMargin: -20
 | 
			
		||||
				horizontalCenter: parent.horizontalCenter
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			font {
 | 
			
		||||
				pointSize: 20
 | 
			
		||||
			}
 | 
			
		||||
			font.pointSize: 40
 | 
			
		||||
 | 
			
		||||
			color: "#50ffffff"
 | 
			
		||||
			text: "Locked"
 | 
			
		||||
| 
						 | 
				
			
			@ -49,7 +46,8 @@ Item {
 | 
			
		|||
		TextField {
 | 
			
		||||
			id: entryBox
 | 
			
		||||
			anchors.centerIn: parent
 | 
			
		||||
			width: 300
 | 
			
		||||
			width: 600
 | 
			
		||||
			font.pointSize: 24
 | 
			
		||||
 | 
			
		||||
			enabled: context.status != AuthContext.Status.Authenticating
 | 
			
		||||
			focus: true
 | 
			
		||||
| 
						 | 
				
			
			@ -86,11 +84,12 @@ Item {
 | 
			
		|||
		Text {
 | 
			
		||||
			id: status
 | 
			
		||||
			color: "white"
 | 
			
		||||
			font.pointSize: 24
 | 
			
		||||
 | 
			
		||||
			anchors {
 | 
			
		||||
				horizontalCenter: entryBox.horizontalCenter
 | 
			
		||||
				top: entryBox.bottom
 | 
			
		||||
				topMargin: 20
 | 
			
		||||
				topMargin: 40
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			text: {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,5 @@
 | 
			
		|||
//@ pragma NativeTextRendering
 | 
			
		||||
 | 
			
		||||
import QtQuick
 | 
			
		||||
import Quickshell
 | 
			
		||||
import Quickshell.Wayland
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
import QtQuick
 | 
			
		||||
import Quickshell
 | 
			
		||||
import ".."
 | 
			
		||||
 | 
			
		||||
ShellRoot {
 | 
			
		||||
	AuthContext {
 | 
			
		||||
| 
						 | 
				
			
			@ -8,10 +9,30 @@ ShellRoot {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	FloatingWindow {
 | 
			
		||||
		color: "#303030"
 | 
			
		||||
		BackgroundImage {
 | 
			
		||||
			anchors.fill: parent
 | 
			
		||||
			screen: Quickshell.screens.filter(s => s.name == "eDP-1")[0]
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Lockscreen {
 | 
			
		||||
			anchors.fill: parent
 | 
			
		||||
			anchors {
 | 
			
		||||
				left: parent.left
 | 
			
		||||
				top: parent.top
 | 
			
		||||
				bottom: parent.bottom
 | 
			
		||||
				right: parent.horizontalCenter
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			context: authContext
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Lockscreen {
 | 
			
		||||
			anchors {
 | 
			
		||||
				left: parent.horizontalCenter
 | 
			
		||||
				top: parent.top
 | 
			
		||||
				bottom: parent.bottom
 | 
			
		||||
				right: parent.right
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			context: authContext
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,73 +0,0 @@
 | 
			
		|||
import QtQuick
 | 
			
		||||
import QtQuick.Layouts
 | 
			
		||||
import Quickshell
 | 
			
		||||
import Quickshell.Wayland
 | 
			
		||||
 | 
			
		||||
PanelWindow {
 | 
			
		||||
	id: root
 | 
			
		||||
 | 
			
		||||
	PersistentProperties {
 | 
			
		||||
		id: persist
 | 
			
		||||
		reloadableId: "persist"
 | 
			
		||||
 | 
			
		||||
		property bool barVisible: false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	PopupSurface {
 | 
			
		||||
		id: popupSurface
 | 
			
		||||
		reloadableId: "popupSurface"
 | 
			
		||||
 | 
			
		||||
		screen: root.screen
 | 
			
		||||
		bar: barRect
 | 
			
		||||
		visible: persist.barVisible
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	onBackingWindowVisibleChanged: {
 | 
			
		||||
		persist.barVisible = Qt.binding(() => backingWindowVisible);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	anchors {
 | 
			
		||||
		left: true
 | 
			
		||||
		top: true
 | 
			
		||||
		bottom: true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	width: 70
 | 
			
		||||
	color: "transparent"
 | 
			
		||||
	WlrLayershell.namespace: "shell:bar"
 | 
			
		||||
 | 
			
		||||
	Rectangle {
 | 
			
		||||
		id: barRect
 | 
			
		||||
		anchors {
 | 
			
		||||
			fill: parent
 | 
			
		||||
			margins: 10
 | 
			
		||||
			rightMargin: 5
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		color: ShellGlobals.colors.bar
 | 
			
		||||
		radius: 5
 | 
			
		||||
		border.color: ShellGlobals.colors.barOutline
 | 
			
		||||
		border.width: 1
 | 
			
		||||
 | 
			
		||||
		Item {
 | 
			
		||||
			anchors {
 | 
			
		||||
				fill: parent
 | 
			
		||||
				margins: 5
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			ColumnLayout {
 | 
			
		||||
				anchors {
 | 
			
		||||
					bottom: parent.bottom
 | 
			
		||||
					left: parent.left
 | 
			
		||||
					right: parent.right
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				ClockWidget {
 | 
			
		||||
					Layout.fillWidth: true
 | 
			
		||||
					popupSurface: popupSurface
 | 
			
		||||
					barWindow: root
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -11,6 +11,7 @@ Singleton {
 | 
			
		|||
		readonly property var barOutline: "#50ffffff";
 | 
			
		||||
		readonly property var widget: "#40ceffff";
 | 
			
		||||
		readonly property var widgetOutline: "#60ffffff";
 | 
			
		||||
		readonly property var separator: "#60ffffff";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	readonly property var popoutXCurve: EasingCurve {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,35 +1,19 @@
 | 
			
		|||
pragma Singleton
 | 
			
		||||
 | 
			
		||||
import Quickshell
 | 
			
		||||
import Quickshell.Io
 | 
			
		||||
import Quickshell.Hyprland
 | 
			
		||||
 | 
			
		||||
Singleton {
 | 
			
		||||
	property bool termSelect: false;
 | 
			
		||||
	readonly property alias termSelect: termSelectBind.pressed;
 | 
			
		||||
	signal screenshot();
 | 
			
		||||
 | 
			
		||||
	SocketServer {
 | 
			
		||||
		active: true
 | 
			
		||||
		path: "/run/user/1000/quickshell.sock"
 | 
			
		||||
	Shortcut {
 | 
			
		||||
		name: "screenshot"
 | 
			
		||||
		onPressed: screenshot()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
		handler: Socket {
 | 
			
		||||
			parser: SplitParser {
 | 
			
		||||
				onRead: message => {
 | 
			
		||||
					console.log(message)
 | 
			
		||||
					switch (message) {
 | 
			
		||||
					case "screenshot":
 | 
			
		||||
						screenshot();
 | 
			
		||||
						break;
 | 
			
		||||
					case "termselect:start":
 | 
			
		||||
						termSelect = true;
 | 
			
		||||
						break;
 | 
			
		||||
					case "termselect:stop":
 | 
			
		||||
						termSelect = false;
 | 
			
		||||
						break;
 | 
			
		||||
					default:
 | 
			
		||||
						console.log(`socket received unknown message: ${message}`)
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	Shortcut {
 | 
			
		||||
		id: termSelectBind
 | 
			
		||||
		name: "termselect"
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										33
									
								
								modules/user/modules/quickshell/shell/bar/Bar.qml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								modules/user/modules/quickshell/shell/bar/Bar.qml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,33 @@
 | 
			
		|||
import QtQuick
 | 
			
		||||
import QtQuick.Layouts
 | 
			
		||||
import QtQuick.Controls
 | 
			
		||||
import "systray" as SysTray
 | 
			
		||||
 | 
			
		||||
BarContainment {
 | 
			
		||||
	id: root
 | 
			
		||||
	ColumnLayout {
 | 
			
		||||
		anchors {
 | 
			
		||||
			left: parent.left
 | 
			
		||||
			right: parent.right
 | 
			
		||||
			top: parent.top
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ColumnLayout {
 | 
			
		||||
		anchors {
 | 
			
		||||
			left: parent.left
 | 
			
		||||
			right: parent.right
 | 
			
		||||
			bottom: parent.bottom
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		SysTray.SysTray {
 | 
			
		||||
			bar: root
 | 
			
		||||
			Layout.fillWidth: true
 | 
			
		||||
			//width: 24
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ClockWidget {
 | 
			
		||||
			Layout.fillWidth: true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										114
									
								
								modules/user/modules/quickshell/shell/bar/BarContainment.qml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								modules/user/modules/quickshell/shell/bar/BarContainment.qml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,114 @@
 | 
			
		|||
import QtQuick
 | 
			
		||||
import Quickshell
 | 
			
		||||
import Quickshell.Wayland
 | 
			
		||||
import ".."
 | 
			
		||||
 | 
			
		||||
PanelWindow {
 | 
			
		||||
	id: root
 | 
			
		||||
 | 
			
		||||
	default property list<QtObject> widgetSurfaceData;
 | 
			
		||||
	readonly property var widgetSurface: widgetSurface;
 | 
			
		||||
	property list<var> overlays: [];
 | 
			
		||||
 | 
			
		||||
	anchors {
 | 
			
		||||
		left: true
 | 
			
		||||
		top: true
 | 
			
		||||
		bottom: true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	width: 70
 | 
			
		||||
	color: "transparent"
 | 
			
		||||
	WlrLayershell.namespace: "shell:bar"
 | 
			
		||||
 | 
			
		||||
	Rectangle {
 | 
			
		||||
		id: barRect
 | 
			
		||||
 | 
			
		||||
		anchors {
 | 
			
		||||
			fill: parent
 | 
			
		||||
			margins: 10
 | 
			
		||||
			rightMargin: 5
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		color: ShellGlobals.colors.bar
 | 
			
		||||
		radius: 5
 | 
			
		||||
		border.color: ShellGlobals.colors.barOutline
 | 
			
		||||
		border.width: 1
 | 
			
		||||
 | 
			
		||||
		Item {
 | 
			
		||||
			id: containment
 | 
			
		||||
 | 
			
		||||
			anchors {
 | 
			
		||||
				fill: parent
 | 
			
		||||
				margins: 5
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// note: must be above the widgetSurface due to reload order
 | 
			
		||||
	PersistentProperties {
 | 
			
		||||
		id: persist
 | 
			
		||||
		reloadableId: "persist"
 | 
			
		||||
 | 
			
		||||
		property bool visible: false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	onBackingWindowVisibleChanged: {
 | 
			
		||||
		persist.visible = Qt.binding(() => backingWindowVisible);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	PanelWindow {
 | 
			
		||||
		id: widgetSurface
 | 
			
		||||
		reloadableId: "widgetSurface"
 | 
			
		||||
 | 
			
		||||
		visible: persist.visible
 | 
			
		||||
		anchors: root.anchors
 | 
			
		||||
		screen: root.screen
 | 
			
		||||
		exclusionMode: ExclusionMode.Ignore
 | 
			
		||||
		WlrLayershell.namespace: "shell:bar"
 | 
			
		||||
		WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
 | 
			
		||||
		color: "transparent"
 | 
			
		||||
 | 
			
		||||
		width: {
 | 
			
		||||
			const extents = overlays
 | 
			
		||||
				.filter(overlay => !overlay.fullyCollapsed)
 | 
			
		||||
				.map(overlay => overlayXOffset + overlay.expandedWidth);
 | 
			
		||||
 | 
			
		||||
			return Math.max(root.width, ...extents);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		readonly property real overlayXOffset: root.width + 10;
 | 
			
		||||
		readonly property real tooltipXOffset: root.width + 2;
 | 
			
		||||
 | 
			
		||||
		function overlayRect(targetY: real, size: rect): rect {
 | 
			
		||||
			const y = Math.max(barRect.y, Math.min((barRect.y + barRect.height) - size.height, targetY));
 | 
			
		||||
			return Qt.rect(overlayXOffset, y, size.width, size.height);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		function boundedY(targetY: real, height: real): real {
 | 
			
		||||
			return Math.max(0, Math.min(barRect.height - height, targetY))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Item {
 | 
			
		||||
			id: contentArea
 | 
			
		||||
			data: widgetSurfaceData
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		readonly property var tooltip: tooltip;
 | 
			
		||||
		Tooltip {
 | 
			
		||||
			id: tooltip
 | 
			
		||||
			bar: root
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		function repositionContentArea() {
 | 
			
		||||
			// abusing the knowledge that both bars are in the same position onscreen
 | 
			
		||||
			const contentRect = containment.mapToItem(root.contentItem, 0, 0, containment.width, containment.height)
 | 
			
		||||
 | 
			
		||||
			contentArea.x = contentRect.x
 | 
			
		||||
			contentArea.y = contentRect.y
 | 
			
		||||
			contentArea.width = contentRect.width
 | 
			
		||||
			contentArea.height = contentRect.height
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	onWindowTransformChanged: widgetSurface.repositionContentArea()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +1,5 @@
 | 
			
		|||
import QtQuick
 | 
			
		||||
import ".."
 | 
			
		||||
 | 
			
		||||
Rectangle {
 | 
			
		||||
	color: ShellGlobals.colors.widget
 | 
			
		||||
							
								
								
									
										31
									
								
								modules/user/modules/quickshell/shell/bar/BugTester.qml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								modules/user/modules/quickshell/shell/bar/BugTester.qml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,31 @@
 | 
			
		|||
import QtQuick
 | 
			
		||||
 | 
			
		||||
BarWidgetInner {
 | 
			
		||||
	implicitHeight: 50
 | 
			
		||||
 | 
			
		||||
	SequentialAnimation on implicitHeight {
 | 
			
		||||
		loops: Animation.Infinite
 | 
			
		||||
		PropertyAnimation { to: 70; duration: 1000 }
 | 
			
		||||
		PropertyAnimation { to: 40; duration: 1000 }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	property int len: 1
 | 
			
		||||
 | 
			
		||||
	Text {
 | 
			
		||||
		anchors.centerIn: parent
 | 
			
		||||
		text: `8${'='.repeat(len)}D`
 | 
			
		||||
		font.pointSize: 16
 | 
			
		||||
		color: "white"
 | 
			
		||||
 | 
			
		||||
		PropertyAnimation on rotation {
 | 
			
		||||
			loops: Animation.Infinite
 | 
			
		||||
			to: 365
 | 
			
		||||
			duration: 1000
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	MouseArea {
 | 
			
		||||
		anchors.fill: parent
 | 
			
		||||
		onClicked: len += 1;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
import QtQuick
 | 
			
		||||
import QtQuick.Layouts
 | 
			
		||||
import ".."
 | 
			
		||||
 | 
			
		||||
OverlayWidget {
 | 
			
		||||
	expandedWidth: 600
 | 
			
		||||
| 
						 | 
				
			
			@ -1,14 +1,13 @@
 | 
			
		|||
import QtQuick
 | 
			
		||||
import Quickshell
 | 
			
		||||
import ".."
 | 
			
		||||
 | 
			
		||||
Item {
 | 
			
		||||
	required property PopupSurface popupSurface;
 | 
			
		||||
	required property var bar;
 | 
			
		||||
	required property real expandedWidth;
 | 
			
		||||
	required property real expandedHeight;
 | 
			
		||||
	required default property Item widget;
 | 
			
		||||
 | 
			
		||||
	required property var barWindow;
 | 
			
		||||
 | 
			
		||||
	property bool expanded: false;
 | 
			
		||||
 | 
			
		||||
	onExpandedChanged: {
 | 
			
		||||
| 
						 | 
				
			
			@ -22,14 +21,22 @@ Item {
 | 
			
		|||
		if (fullyCollapsed && popupSurface.activeOverlay == this) {
 | 
			
		||||
			popupSurface.activeOverlay = null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/*if (fullyCollapsed) {
 | 
			
		||||
			widget.x = Qt.binding(() => this.x)
 | 
			
		||||
		}*/
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	readonly property rect collapsedLayerRect: {
 | 
			
		||||
		void [barWindow.windowTransform, popupSurface.windowTransform];
 | 
			
		||||
		void [barWindow.windowTransform, popupSurface.windowTransform, y, parent.y];
 | 
			
		||||
		return this.mapToItem(popupSurface.contentItem, 0, 0, width, height);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	readonly property rect expandedLayerRect: popupSurface.expandedPosition(this)
 | 
			
		||||
	onCollapsedLayerRectChanged: console.log(`clr: ${collapsedLayerRect}`)
 | 
			
		||||
	onLayerRectChanged: console.log(`lr: ${layerRect}`)
 | 
			
		||||
	onYChanged: console.log(`y: ${y}`)
 | 
			
		||||
 | 
			
		||||
	readonly property rect expandedLayerRect: bar.widgetSurface.expandedPosition(this)
 | 
			
		||||
 | 
			
		||||
	readonly property rect layerRect: {
 | 
			
		||||
		const [p, xCurve, yCurve] = [animationProgress, ShellGlobals.popoutXCurve, ShellGlobals.popoutYCurve];
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +53,7 @@ Item {
 | 
			
		|||
	implicitHeight: widget.implicitHeight
 | 
			
		||||
 | 
			
		||||
	Component.onCompleted: {
 | 
			
		||||
		popupSurface.connectOverlay(this)
 | 
			
		||||
		popupSurface.connectOverlay(this);
 | 
			
		||||
		widget.x = Qt.binding(() => layerRect.x);
 | 
			
		||||
		widget.y = Qt.binding(() => layerRect.y);
 | 
			
		||||
		widget.width = Qt.binding(() => layerRect.width);
 | 
			
		||||
							
								
								
									
										17
									
								
								modules/user/modules/quickshell/shell/bar/OverlayWidget.qml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								modules/user/modules/quickshell/shell/bar/OverlayWidget.qml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
import QtQuick
 | 
			
		||||
 | 
			
		||||
Item {
 | 
			
		||||
	default property Item item;
 | 
			
		||||
	property int expandedWidth;
 | 
			
		||||
	property int expandedHeight;
 | 
			
		||||
 | 
			
		||||
	implicitHeight: item.implicitHeight
 | 
			
		||||
	implicitWidth: item.implicitWidth
 | 
			
		||||
 | 
			
		||||
	Component.onCompleted: {
 | 
			
		||||
		item.width = Qt.binding(() => this.width)
 | 
			
		||||
		item.height = Qt.binding(() => this.height)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	children: [ item ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										127
									
								
								modules/user/modules/quickshell/shell/bar/Tooltip.qml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								modules/user/modules/quickshell/shell/bar/Tooltip.qml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,127 @@
 | 
			
		|||
import QtQuick
 | 
			
		||||
import Quickshell
 | 
			
		||||
import Quickshell.Hyprland
 | 
			
		||||
 | 
			
		||||
Scope {
 | 
			
		||||
	id: root
 | 
			
		||||
	required property var bar;
 | 
			
		||||
 | 
			
		||||
	property TooltipItem activeTooltip: null;
 | 
			
		||||
	property TooltipItem activeMenu: null;
 | 
			
		||||
 | 
			
		||||
	readonly property TooltipItem activeItem: activeMenu ?? activeTooltip;
 | 
			
		||||
	property TooltipItem lastActiveItem: null;
 | 
			
		||||
 | 
			
		||||
	onActiveItemChanged: {
 | 
			
		||||
		if (activeItem != null) activeItem.visible = true;
 | 
			
		||||
		if (lastActiveItem != null) lastActiveItem.visible = false;
 | 
			
		||||
		lastActiveItem = activeItem;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function setItem(item: TooltipItem) {
 | 
			
		||||
		if (item.isMenu) {
 | 
			
		||||
			activeMenu = item;
 | 
			
		||||
		} else {
 | 
			
		||||
			activeTooltip = item;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function removeItem(item: TooltipItem) {
 | 
			
		||||
		if (item.isMenu && activeMenu == item) {
 | 
			
		||||
			activeMenu = null
 | 
			
		||||
		} else if (!item.isMenu && activeTooltip == item) {
 | 
			
		||||
			activeTooltip = null
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	LazyLoader {
 | 
			
		||||
		id: popupLoader
 | 
			
		||||
		activeAsync: activeItem != null
 | 
			
		||||
 | 
			
		||||
		PopupWindow {
 | 
			
		||||
			id: popup
 | 
			
		||||
			parentWindow: bar.widgetSurface
 | 
			
		||||
			relativeX: bar.widgetSurface.tooltipXOffset
 | 
			
		||||
			relativeY: 0
 | 
			
		||||
			height: bar.widgetSurface.height
 | 
			
		||||
			width: tooltipItem.width
 | 
			
		||||
			visible: true
 | 
			
		||||
			color: "transparent"
 | 
			
		||||
 | 
			
		||||
			mask: Region {
 | 
			
		||||
				item: (activeItem?.isMenu ?? false) ? tooltipItem : null
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			HyprlandFocusGrab {
 | 
			
		||||
				active: activeItem?.isMenu ?? false
 | 
			
		||||
				windows: [ popup, bar.widgetSurface ]
 | 
			
		||||
				onActiveChanged: {
 | 
			
		||||
					if (!active && activeItem?.isMenu) {
 | 
			
		||||
						activeMenu.close()
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			BarWidgetInner {
 | 
			
		||||
				id: tooltipItem
 | 
			
		||||
 | 
			
		||||
				readonly property var targetWidth: activeItem?.implicitWidth ?? 10;
 | 
			
		||||
				readonly property var targetHeight: (activeItem?.implicitHeight ?? 0) + 10;
 | 
			
		||||
 | 
			
		||||
				readonly property real targetY: {
 | 
			
		||||
					if (activeItem == null) return 0;
 | 
			
		||||
					const target = bar.widgetSurface.contentItem.mapFromItem(activeItem.owner, 0, activeItem.targetRelativeY).y;
 | 
			
		||||
					return bar.widgetSurface.boundedY(target, activeItem.implicitHeight / 2);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				width: targetWidth + 10
 | 
			
		||||
 | 
			
		||||
				property var y1: -1
 | 
			
		||||
				property var y2: -1
 | 
			
		||||
 | 
			
		||||
				y: y1
 | 
			
		||||
				height: y2 - y1
 | 
			
		||||
 | 
			
		||||
				SmoothedAnimation {
 | 
			
		||||
					target: tooltipItem;
 | 
			
		||||
					property: "y1";
 | 
			
		||||
					to: tooltipItem.targetY - tooltipItem.targetHeight / 2;
 | 
			
		||||
					onToChanged: {
 | 
			
		||||
						if (tooltipItem.y1 == -1 || !(activeItem?.animateSize ?? true)) {
 | 
			
		||||
							stop();
 | 
			
		||||
							tooltipItem.y1 = to;
 | 
			
		||||
						} else {
 | 
			
		||||
							velocity = (Math.max(tooltipItem.y1, to) - Math.min(tooltipItem.y1, to)) * 5;
 | 
			
		||||
							restart();
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				SmoothedAnimation {
 | 
			
		||||
					target: tooltipItem
 | 
			
		||||
					property: "y2"
 | 
			
		||||
					to: tooltipItem.targetY + tooltipItem.targetHeight / 2;
 | 
			
		||||
					onToChanged: {
 | 
			
		||||
						if (tooltipItem.y2 == -1 || !(activeItem?.animateSize ?? true)) {
 | 
			
		||||
							stop();
 | 
			
		||||
							tooltipItem.y2 = to;
 | 
			
		||||
						} else {
 | 
			
		||||
							velocity = (Math.max(tooltipItem.y2, to) - Math.min(tooltipItem.y2, to)) * 5;
 | 
			
		||||
							restart();
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				Item {
 | 
			
		||||
					clip: true
 | 
			
		||||
					children: [ activeItem ]
 | 
			
		||||
 | 
			
		||||
					anchors {
 | 
			
		||||
						fill: parent
 | 
			
		||||
						margins: 5
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								modules/user/modules/quickshell/shell/bar/TooltipItem.qml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								modules/user/modules/quickshell/shell/bar/TooltipItem.qml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,31 @@
 | 
			
		|||
import QtQuick
 | 
			
		||||
import Quickshell
 | 
			
		||||
 | 
			
		||||
Item {
 | 
			
		||||
	id: root
 | 
			
		||||
	required property var tooltip;
 | 
			
		||||
	required property Item owner;
 | 
			
		||||
	property bool isMenu: false;
 | 
			
		||||
	property bool animateSize: true;
 | 
			
		||||
	property bool show: false;
 | 
			
		||||
 | 
			
		||||
	property real targetRelativeY: owner.height / 2;
 | 
			
		||||
	property real hangTime: isMenu ? 0 : 200;
 | 
			
		||||
 | 
			
		||||
	signal close();
 | 
			
		||||
 | 
			
		||||
	onShowChanged: {
 | 
			
		||||
		if (show) {
 | 
			
		||||
			hangTimer.stop();
 | 
			
		||||
			tooltip.setItem(this);
 | 
			
		||||
		} else if (hangTime == 0) {
 | 
			
		||||
			tooltip.removeItem(this);
 | 
			
		||||
		} else hangTimer.start();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Timer {
 | 
			
		||||
		id: hangTimer
 | 
			
		||||
		interval: hangTime
 | 
			
		||||
		onTriggered: tooltip.removeItem(root);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,44 @@
 | 
			
		|||
import QtQuick
 | 
			
		||||
import QtQuick.Shapes
 | 
			
		||||
import "../.."
 | 
			
		||||
 | 
			
		||||
Rectangle {
 | 
			
		||||
	property var checkState: Qt.Unchecked;
 | 
			
		||||
	implicitHeight: 18
 | 
			
		||||
	implicitWidth: 18
 | 
			
		||||
	radius: 3
 | 
			
		||||
	color: ShellGlobals.colors.widget
 | 
			
		||||
 | 
			
		||||
	Shape {
 | 
			
		||||
		visible: checkState == Qt.Checked
 | 
			
		||||
		anchors.fill: parent
 | 
			
		||||
		layer.enabled: true
 | 
			
		||||
		layer.samples: 10
 | 
			
		||||
 | 
			
		||||
		ShapePath {
 | 
			
		||||
			strokeWidth: 2
 | 
			
		||||
			capStyle: ShapePath.RoundCap
 | 
			
		||||
			joinStyle: ShapePath.RoundJoin
 | 
			
		||||
			fillColor: "transparent"
 | 
			
		||||
 | 
			
		||||
			startX: start.x
 | 
			
		||||
			startY: start.y
 | 
			
		||||
 | 
			
		||||
			PathLine {
 | 
			
		||||
				id: start
 | 
			
		||||
				x: width * 0.8
 | 
			
		||||
				y: height * 0.2
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			PathLine {
 | 
			
		||||
				x: width * 0.35
 | 
			
		||||
				y: height * 0.8
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			PathLine {
 | 
			
		||||
				x: width * 0.2
 | 
			
		||||
				y: height * 0.6
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,56 @@
 | 
			
		|||
import QtQuick
 | 
			
		||||
import QtQuick.Shapes
 | 
			
		||||
import Quickshell
 | 
			
		||||
 | 
			
		||||
Item {
 | 
			
		||||
	property bool expanded: false;
 | 
			
		||||
 | 
			
		||||
	readonly property bool open: progress != 0;
 | 
			
		||||
	readonly property bool animating: internalProgress != -1 && internalProgress != 101;
 | 
			
		||||
 | 
			
		||||
	implicitHeight: 16
 | 
			
		||||
	implicitWidth: 16
 | 
			
		||||
	property var xStart: Math.round(width * 0.3)
 | 
			
		||||
	property var yStart: Math.round(height * 0.1)
 | 
			
		||||
	property var xEnd: Math.round(width * 0.7)
 | 
			
		||||
	property var yEnd: Math.round(height * 0.9)
 | 
			
		||||
 | 
			
		||||
	property real internalProgress: expanded ? 101 : -1;
 | 
			
		||||
	Behavior on internalProgress { SmoothedAnimation { velocity: 300 } }
 | 
			
		||||
 | 
			
		||||
	EasingCurve {
 | 
			
		||||
		id: curve
 | 
			
		||||
		curve.type: Easing.InOutQuad
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	readonly property real progress: curve.valueAt(Math.min(100, Math.max(internalProgress, 0)) * 0.01)
 | 
			
		||||
 | 
			
		||||
	rotation: progress * 90;
 | 
			
		||||
 | 
			
		||||
	Shape {
 | 
			
		||||
		anchors.fill: parent
 | 
			
		||||
 | 
			
		||||
		layer.enabled: true
 | 
			
		||||
		layer.samples: 3
 | 
			
		||||
 | 
			
		||||
		ShapePath {
 | 
			
		||||
			strokeWidth: 2
 | 
			
		||||
			capStyle: ShapePath.RoundCap
 | 
			
		||||
			joinStyle: ShapePath.MiterJoin
 | 
			
		||||
			fillColor: "transparent"
 | 
			
		||||
 | 
			
		||||
			startX: xStart
 | 
			
		||||
			startY: yStart
 | 
			
		||||
 | 
			
		||||
			PathLine {
 | 
			
		||||
				x: xEnd
 | 
			
		||||
				y: height / 2
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			PathLine {
 | 
			
		||||
				y: yEnd
 | 
			
		||||
				x: xStart
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										110
									
								
								modules/user/modules/quickshell/shell/bar/systray/MenuItem.qml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								modules/user/modules/quickshell/shell/bar/systray/MenuItem.qml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,110 @@
 | 
			
		|||
import QtQuick
 | 
			
		||||
import QtQuick.Layouts
 | 
			
		||||
import Quickshell
 | 
			
		||||
import Quickshell.DBusMenu
 | 
			
		||||
import "../.."
 | 
			
		||||
 | 
			
		||||
MouseArea {
 | 
			
		||||
	id: root
 | 
			
		||||
	required property var entry;
 | 
			
		||||
	property alias expanded: childrenRevealer.expanded;
 | 
			
		||||
	property bool animating: childrenRevealer.animating || childrenList.animating;
 | 
			
		||||
	// appears it won't actually create the handler when only used from MenuItemList.
 | 
			
		||||
	onExpandedChanged: {}
 | 
			
		||||
	onAnimatingChanged: {}
 | 
			
		||||
 | 
			
		||||
	signal close();
 | 
			
		||||
 | 
			
		||||
	implicitWidth: row.implicitWidth + 4
 | 
			
		||||
	implicitHeight: row.implicitHeight + 4
 | 
			
		||||
 | 
			
		||||
	hoverEnabled: true
 | 
			
		||||
	onClicked: {
 | 
			
		||||
		if (entry.hasChildren) childrenRevealer.expanded = !childrenRevealer.expanded
 | 
			
		||||
		else {
 | 
			
		||||
			entry.click();
 | 
			
		||||
			if (entry.toggleType == ToggleButtonType.None) close();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ColumnLayout {
 | 
			
		||||
		id: row
 | 
			
		||||
		anchors.fill: parent
 | 
			
		||||
		anchors.margins: 2
 | 
			
		||||
		spacing: 0
 | 
			
		||||
 | 
			
		||||
		RowLayout {
 | 
			
		||||
			Item {
 | 
			
		||||
				implicitWidth: 22
 | 
			
		||||
				implicitHeight: 22
 | 
			
		||||
 | 
			
		||||
				MenuCheckBox {
 | 
			
		||||
					anchors.centerIn: parent
 | 
			
		||||
					visible: entry.toggleType == ToggleButtonType.CheckBox
 | 
			
		||||
					checkState: entry.checkState
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				MenuRadioButton {
 | 
			
		||||
					anchors.centerIn: parent
 | 
			
		||||
					visible: entry.toggleType == ToggleButtonType.RadioButton
 | 
			
		||||
					checkState: entry.checkState
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				MenuChildrenRevealer {
 | 
			
		||||
					id: childrenRevealer
 | 
			
		||||
					anchors.centerIn: parent
 | 
			
		||||
					visible: entry.hasChildren
 | 
			
		||||
					onOpenChanged: entry.showChildren = open
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			Text {
 | 
			
		||||
				text: entry.cleanLabel
 | 
			
		||||
				color: entry.enabled ? "white" : "#bbbbbb"
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			Item {
 | 
			
		||||
				Layout.fillWidth: true
 | 
			
		||||
				implicitWidth: 22
 | 
			
		||||
				implicitHeight: 22
 | 
			
		||||
 | 
			
		||||
				Image {
 | 
			
		||||
					anchors.right: parent.right
 | 
			
		||||
					anchors.verticalCenter: parent.verticalCenter
 | 
			
		||||
					visible: entry.icon != ""
 | 
			
		||||
					source: entry.icon
 | 
			
		||||
					sourceSize.height: parent.height
 | 
			
		||||
					sourceSize.width: parent.height
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Item {
 | 
			
		||||
			Layout.fillWidth: true
 | 
			
		||||
			implicitHeight: childrenList.implicitHeight * childrenRevealer.progress
 | 
			
		||||
			clip: true
 | 
			
		||||
 | 
			
		||||
			MenuItemList {
 | 
			
		||||
				id: childrenList
 | 
			
		||||
				items: entry.children
 | 
			
		||||
				onClose: root.close()
 | 
			
		||||
 | 
			
		||||
				anchors {
 | 
			
		||||
					top: parent.top
 | 
			
		||||
					left: parent.left
 | 
			
		||||
					right: parent.right
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Rectangle {
 | 
			
		||||
		anchors.fill: parent
 | 
			
		||||
		visible: root.containsMouse || childrenRevealer.expanded
 | 
			
		||||
 | 
			
		||||
		color: ShellGlobals.colors.widget
 | 
			
		||||
		border.width: 1
 | 
			
		||||
		border.color: ShellGlobals.colors.widgetOutline
 | 
			
		||||
		radius: 5
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,80 @@
 | 
			
		|||
import QtQuick
 | 
			
		||||
import QtQuick.Layouts
 | 
			
		||||
import Quickshell
 | 
			
		||||
import Quickshell.DBusMenu
 | 
			
		||||
import "../.."
 | 
			
		||||
 | 
			
		||||
ColumnLayout {
 | 
			
		||||
	id: root
 | 
			
		||||
	required property var items;
 | 
			
		||||
	property Item animatingItem: null;
 | 
			
		||||
	property bool animating: animatingItem != null;
 | 
			
		||||
 | 
			
		||||
	signal close();
 | 
			
		||||
	signal submenuExpanded(item: var);
 | 
			
		||||
 | 
			
		||||
	spacing: 0
 | 
			
		||||
 | 
			
		||||
	Repeater {
 | 
			
		||||
		model: items
 | 
			
		||||
 | 
			
		||||
		Loader {
 | 
			
		||||
			required property var modelData;
 | 
			
		||||
 | 
			
		||||
			property var item: Component {
 | 
			
		||||
				BoundComponent {
 | 
			
		||||
					id: itemComponent
 | 
			
		||||
					source: "MenuItem.qml"
 | 
			
		||||
 | 
			
		||||
					property var entry: modelData
 | 
			
		||||
 | 
			
		||||
					function onClose() {
 | 
			
		||||
						root.close()
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					function onExpandedChanged() {
 | 
			
		||||
						if (item.expanded) root.submenuExpanded(item);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					function onAnimatingChanged() {
 | 
			
		||||
						if (item.animating) {
 | 
			
		||||
							root.animatingItem = this;
 | 
			
		||||
						} else if (root.animatingItem == this) {
 | 
			
		||||
							root.animatingItem = null;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					Connections {
 | 
			
		||||
						target: root
 | 
			
		||||
 | 
			
		||||
						function onSubmenuExpanded(expandedItem) {
 | 
			
		||||
							if (item != expandedItem) item.expanded = false;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			property var separator: Component {
 | 
			
		||||
				Item {
 | 
			
		||||
					implicitHeight: seprect.height + 6
 | 
			
		||||
 | 
			
		||||
					Rectangle {
 | 
			
		||||
						id: seprect
 | 
			
		||||
 | 
			
		||||
						anchors {
 | 
			
		||||
							verticalCenter: parent.verticalCenter
 | 
			
		||||
							left: parent.left
 | 
			
		||||
							right: parent.right
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						color: ShellGlobals.colors.separator
 | 
			
		||||
						height: 1
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			sourceComponent: modelData.isSeparator ? separator : item
 | 
			
		||||
			Layout.fillWidth: true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,19 @@
 | 
			
		|||
import QtQuick
 | 
			
		||||
import "../.."
 | 
			
		||||
 | 
			
		||||
Rectangle {
 | 
			
		||||
	property var checkState: Qt.Unchecked;
 | 
			
		||||
	implicitHeight: 18
 | 
			
		||||
	implicitWidth: 18
 | 
			
		||||
	radius: width / 2
 | 
			
		||||
	color: ShellGlobals.colors.widget
 | 
			
		||||
 | 
			
		||||
	Rectangle {
 | 
			
		||||
		x: parent.width * 0.25
 | 
			
		||||
		y: parent.height * 0.25
 | 
			
		||||
		visible: checkState == Qt.Checked
 | 
			
		||||
		width: parent.width * 0.5
 | 
			
		||||
		height: width
 | 
			
		||||
		radius: width / 2
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										147
									
								
								modules/user/modules/quickshell/shell/bar/systray/SysTray.qml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								modules/user/modules/quickshell/shell/bar/systray/SysTray.qml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,147 @@
 | 
			
		|||
import QtQuick
 | 
			
		||||
import QtQuick.Layouts
 | 
			
		||||
import QtQuick.Effects
 | 
			
		||||
import Quickshell
 | 
			
		||||
import Quickshell.Services.SystemTray
 | 
			
		||||
import ".."
 | 
			
		||||
 | 
			
		||||
OverlayWidget {
 | 
			
		||||
	id: root
 | 
			
		||||
	expandedWidth: 600
 | 
			
		||||
	expandedHeight: 800
 | 
			
		||||
	required property var bar;
 | 
			
		||||
 | 
			
		||||
	BarWidgetInner {
 | 
			
		||||
		implicitHeight: column.implicitHeight + 10
 | 
			
		||||
 | 
			
		||||
		ColumnLayout {
 | 
			
		||||
			id: column
 | 
			
		||||
			implicitHeight: childrenRect.height
 | 
			
		||||
			spacing: 5
 | 
			
		||||
 | 
			
		||||
			anchors {
 | 
			
		||||
				fill: parent
 | 
			
		||||
				margins: 5
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			Repeater {
 | 
			
		||||
				model: SystemTray.items;
 | 
			
		||||
 | 
			
		||||
				Item {
 | 
			
		||||
					required property var modelData;
 | 
			
		||||
					readonly property alias menu: menuWatcher.menu;
 | 
			
		||||
 | 
			
		||||
					SystemTrayMenuWatcher {
 | 
			
		||||
						id: menuWatcher;
 | 
			
		||||
						trayItem: modelData;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					property bool targetMenuOpen: false;
 | 
			
		||||
					onTargetMenuOpenChanged: menu.showChildren = targetMenuOpen
 | 
			
		||||
 | 
			
		||||
					Layout.fillWidth: true
 | 
			
		||||
					implicitHeight: width
 | 
			
		||||
					Behavior on implicitHeight {
 | 
			
		||||
						SmoothedAnimation { velocity: 50 }
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					MouseArea {
 | 
			
		||||
						id: mouseArea
 | 
			
		||||
						anchors {
 | 
			
		||||
							top: parent.top
 | 
			
		||||
							bottom: parent.bottom
 | 
			
		||||
							horizontalCenter: parent.horizontalCenter
 | 
			
		||||
						}
 | 
			
		||||
						width: height
 | 
			
		||||
 | 
			
		||||
						hoverEnabled: true
 | 
			
		||||
						acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
 | 
			
		||||
 | 
			
		||||
						Image {
 | 
			
		||||
							id: image
 | 
			
		||||
							anchors.fill: parent
 | 
			
		||||
 | 
			
		||||
							anchors.margins: mouseArea.pressed || targetMenuOpen ? 3 : 0
 | 
			
		||||
							Behavior on anchors.margins { SmoothedAnimation { velocity: 30 } }
 | 
			
		||||
 | 
			
		||||
							source: modelData.icon
 | 
			
		||||
							sourceSize.width: width
 | 
			
		||||
							sourceSize.height: height
 | 
			
		||||
							cache: false
 | 
			
		||||
							visible: false
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						MultiEffect {
 | 
			
		||||
							anchors.fill: image
 | 
			
		||||
							source: image
 | 
			
		||||
 | 
			
		||||
							property real targetBrightness: mouseArea.pressed || targetMenuOpen ? -25 : mouseArea.containsMouse ? 75 : 0
 | 
			
		||||
							Behavior on targetBrightness { SmoothedAnimation { velocity: 600 } }
 | 
			
		||||
							brightness: targetBrightness / 1000
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						onClicked: event => {
 | 
			
		||||
							event.accepted = true;
 | 
			
		||||
 | 
			
		||||
							if (event.button == Qt.LeftButton) {
 | 
			
		||||
								modelData.activate();
 | 
			
		||||
							} else if (event.button == Qt.MiddleButton) {
 | 
			
		||||
								modelData.secondaryActivate();
 | 
			
		||||
							} else if (event.button == Qt.RightButton && menu != null) {
 | 
			
		||||
								targetMenuOpen = !targetMenuOpen;
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						onWheel: event => {
 | 
			
		||||
							event.accepted = true;
 | 
			
		||||
							const points = event.angleDelta.y / 120
 | 
			
		||||
							modelData.scroll(points, false);
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						property var tooltip: TooltipItem {
 | 
			
		||||
							anchors.fill: parent
 | 
			
		||||
							tooltip: bar.widgetSurface.tooltip
 | 
			
		||||
							owner: image
 | 
			
		||||
 | 
			
		||||
							show: mouseArea.containsMouse
 | 
			
		||||
							implicitWidth: tooltipText.implicitWidth
 | 
			
		||||
							implicitHeight: tooltipText.implicitHeight
 | 
			
		||||
 | 
			
		||||
							Text {
 | 
			
		||||
								id: tooltipText
 | 
			
		||||
								anchors.fill: parent
 | 
			
		||||
								text: modelData.tooltipTitle != "" ? modelData.tooltipTitle : modelData.id
 | 
			
		||||
								color: "white"
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						property var rightclickMenu: TooltipItem {
 | 
			
		||||
							anchors.fill: parent
 | 
			
		||||
							tooltip: bar.widgetSurface.tooltip
 | 
			
		||||
							owner: image
 | 
			
		||||
 | 
			
		||||
							isMenu: true
 | 
			
		||||
							show: targetMenuOpen && menu.showChildren
 | 
			
		||||
							animateSize: !rightclickItems.animating
 | 
			
		||||
							implicitHeight: rightclickItems.implicitHeight
 | 
			
		||||
							implicitWidth: rightclickItems.implicitWidth
 | 
			
		||||
 | 
			
		||||
							onVisibleChanged: {
 | 
			
		||||
								if (!visible) targetMenuOpen = false;
 | 
			
		||||
							}
 | 
			
		||||
 | 
			
		||||
							onClose: targetMenuOpen = false;
 | 
			
		||||
 | 
			
		||||
							MenuItemList {
 | 
			
		||||
								id: rightclickItems
 | 
			
		||||
								anchors.fill: parent
 | 
			
		||||
								items: menu == null ? [] : menu.children
 | 
			
		||||
								onClose: targetMenuOpen = false;
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -79,8 +79,6 @@ Scope {
 | 
			
		|||
	LazyLoader {
 | 
			
		||||
		loading: root.shooting
 | 
			
		||||
		active: root.visible
 | 
			
		||||
		onLoadingChanged: console.log(`loading set to ${loading} at ${new Date()}`)
 | 
			
		||||
		onActiveChanged: console.log(`active set to ${active} at ${new Date()}`)
 | 
			
		||||
 | 
			
		||||
		Variants {
 | 
			
		||||
			model: Quickshell.screens
 | 
			
		||||
| 
						 | 
				
			
			@ -128,8 +126,6 @@ Scope {
 | 
			
		|||
					}
 | 
			
		||||
 | 
			
		||||
					onReleased: {
 | 
			
		||||
						console.log(`area: ${selection.x} ${selection.y} ${selection.w} ${selection.h}`)
 | 
			
		||||
 | 
			
		||||
						if (selection.w > 0 && selection.h > 0) {
 | 
			
		||||
							magickProc.running = true
 | 
			
		||||
							selectionComplete = true
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
import Quickshell
 | 
			
		||||
import Quickshell.Wayland
 | 
			
		||||
 | 
			
		||||
PanelWindow {
 | 
			
		||||
	visible: false
 | 
			
		||||
 | 
			
		||||
	anchors {
 | 
			
		||||
		left: true
 | 
			
		||||
		right: true
 | 
			
		||||
		top: true
 | 
			
		||||
		bottom: true
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -5,6 +5,7 @@ import QtQuick
 | 
			
		|||
import QtQuick.Layouts
 | 
			
		||||
import ".."
 | 
			
		||||
import "screenshot" as Screenshot
 | 
			
		||||
import "bar" as Bar
 | 
			
		||||
 | 
			
		||||
ShellRoot {
 | 
			
		||||
	Process {
 | 
			
		||||
| 
						 | 
				
			
			@ -34,7 +35,10 @@ ShellRoot {
 | 
			
		|||
		Scope {
 | 
			
		||||
			property var modelData
 | 
			
		||||
 | 
			
		||||
			Bar {
 | 
			
		||||
			/*Bar {
 | 
			
		||||
				screen: modelData
 | 
			
		||||
			}*/
 | 
			
		||||
			Bar.Bar {
 | 
			
		||||
				screen: modelData
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -52,8 +56,6 @@ ShellRoot {
 | 
			
		|||
					right: true
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				color: "#111111"
 | 
			
		||||
 | 
			
		||||
				BackgroundImage {
 | 
			
		||||
					anchors.fill: parent
 | 
			
		||||
					screen: window.screen
 | 
			
		||||
| 
						 | 
				
			
			@ -118,6 +120,7 @@ ShellRoot {
 | 
			
		|||
			}
 | 
			
		||||
 | 
			
		||||
			PanelWindow {
 | 
			
		||||
				visible: false
 | 
			
		||||
				screen: modelData
 | 
			
		||||
				WlrLayershell.layer: WlrLayer.Overlay
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,11 +6,16 @@
 | 
			
		|||
    runAsService = true;
 | 
			
		||||
 | 
			
		||||
    config = {
 | 
			
		||||
      show_initial_entries = true;
 | 
			
		||||
      fullscreen = true;
 | 
			
		||||
      scrollbar_policy = "external";
 | 
			
		||||
      search.hide_spinner = true;
 | 
			
		||||
      activation_mode.use_alt = true;
 | 
			
		||||
 | 
			
		||||
      search = {
 | 
			
		||||
        hide_icons = false;
 | 
			
		||||
        hide_spinner = true;
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      align = {
 | 
			
		||||
        width = 500;
 | 
			
		||||
        horizontal = "center";
 | 
			
		||||
| 
						 | 
				
			
			@ -21,8 +26,11 @@
 | 
			
		|||
      list = {
 | 
			
		||||
        height = 500;
 | 
			
		||||
        fixed_height = true;
 | 
			
		||||
        always_show = true;
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      icons.hide = false;
 | 
			
		||||
 | 
			
		||||
      modules = [
 | 
			
		||||
        {
 | 
			
		||||
          name = "applications";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue