popout positioning fixes
This commit is contained in:
@@ -9,14 +9,14 @@ Shape {
|
||||
required property Item bar
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.margins: 8
|
||||
// anchors.margins: 8
|
||||
anchors.topMargin: bar.implicitHeight
|
||||
preferredRendererType: Shape.CurveRenderer
|
||||
|
||||
Modules.Background {
|
||||
wrapper: root.panels.popouts
|
||||
|
||||
startX: wrapper.x - rounding
|
||||
startX: wrapper.x - 8
|
||||
startY: wrapper.y
|
||||
}
|
||||
}
|
||||
|
||||
+4
-5
@@ -13,7 +13,7 @@ Item {
|
||||
readonly property alias popouts: popouts
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.margins: 8
|
||||
// anchors.margins: 8
|
||||
anchors.topMargin: bar.implicitHeight
|
||||
|
||||
Modules.Wrapper {
|
||||
@@ -21,13 +21,12 @@ Item {
|
||||
|
||||
screen: root.screen
|
||||
|
||||
anchors.top: parent.top
|
||||
x: {
|
||||
const off = currentCenter - 8 - nonAnimWidth / 2;
|
||||
const off = currentCenter - nonAnimWidth / 2;
|
||||
const diff = root.width - Math.floor(off + nonAnimWidth);
|
||||
if (diff < 0)
|
||||
if ( diff < 0 )
|
||||
return off + diff;
|
||||
return Math.floor(Math.max(off, 0));
|
||||
return Math.floor( Math.max( off, 0 ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+41
-1
@@ -14,11 +14,15 @@ Singleton {
|
||||
readonly property var workspaces: Hyprland.workspaces
|
||||
readonly property var monitors: Hyprland.monitors
|
||||
|
||||
readonly property HyprlandToplevel activeToplevel: Hyprland.activeToplevel?.wayland?.activated ? Hyprland.activeToplevel : null
|
||||
readonly property HyprlandToplevel activeToplevel: Hyprland.activeToplevel
|
||||
readonly property HyprlandWorkspace focusedWorkspace: Hyprland.focusedWorkspace
|
||||
readonly property HyprlandMonitor focusedMonitor: Hyprland.focusedMonitor
|
||||
readonly property int activeWsId: focusedWorkspace?.id ?? 1
|
||||
|
||||
property string activeName
|
||||
property string applicationDir: "/usr/share/applications/"
|
||||
property string desktopName: ""
|
||||
|
||||
readonly property HyprKeyboard keyboard: extras.devices.keyboards.find(kb => kb.main) ?? null
|
||||
readonly property bool capsLock: keyboard?.capsLock ?? false
|
||||
readonly property bool numLock: keyboard?.numLock ?? false
|
||||
@@ -49,6 +53,19 @@ Singleton {
|
||||
|
||||
Component.onCompleted: reloadDynamicConfs()
|
||||
|
||||
function updateActiveWindow(): void {
|
||||
root.desktopName = root.applicationDir + root.activeToplevel?.lastIpcObject.class + ".desktop";
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Hyprland
|
||||
|
||||
function onRawEvent( event: HyprlandEvent ): void {
|
||||
if ( event.name === "activewindow" ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Hyprland
|
||||
|
||||
@@ -63,15 +80,38 @@ Singleton {
|
||||
} else if (["workspace", "moveworkspace", "activespecial", "focusedmon"].includes(n)) {
|
||||
Hyprland.refreshWorkspaces();
|
||||
Hyprland.refreshMonitors();
|
||||
Qt.callLater( root.updateActiveWindow );
|
||||
} else if (["openwindow", "closewindow", "movewindow"].includes(n)) {
|
||||
Hyprland.refreshToplevels();
|
||||
Hyprland.refreshWorkspaces();
|
||||
Qt.callLater( root.updateActiveWindow );
|
||||
} else if (n.includes("mon")) {
|
||||
Hyprland.refreshMonitors();
|
||||
Qt.callLater( root.updateActiveWindow );
|
||||
} else if (n.includes("workspace")) {
|
||||
Hyprland.refreshWorkspaces();
|
||||
Qt.callLater( root.updateActiveWindow );
|
||||
} else if (n.includes("window") || n.includes("group") || ["pin", "fullscreen", "changefloatingmode", "minimize"].includes(n)) {
|
||||
Hyprland.refreshToplevels();
|
||||
Qt.callLater( root.updateActiveWindow );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FileView {
|
||||
id: desktopEntryName
|
||||
|
||||
path: root.desktopName
|
||||
|
||||
onLoaded: {
|
||||
const lines = text().split( "\n" );
|
||||
for ( const line of lines ) {
|
||||
if ( line.startsWith( "Name=" )) {
|
||||
let name = line.replace( "Name=", "" );
|
||||
let caseFix = name[ 0 ].toUpperCase() + name.slice( 1 );
|
||||
root.activeName = caseFix;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-14
@@ -1,22 +1,18 @@
|
||||
pragma Singleton
|
||||
import Quickshell.Io
|
||||
|
||||
import Quickshell
|
||||
import Quickshell.Hyprland
|
||||
import qs.Helpers
|
||||
|
||||
Singleton {
|
||||
|
||||
function getInitialTitle(callback) {
|
||||
initialTitleProc.running = true
|
||||
initialTitleProc.stdout.streamFinished.connect( function() {
|
||||
let cleaned = initialTitleProc.stdout.text.trim().replace(/\"/g, "")
|
||||
callback(cleaned === "null" ? "" : cleaned)
|
||||
})
|
||||
}
|
||||
let activeWindow = Hypr.activeToplevel.title
|
||||
let activeClass = Hypr.activeToplevel.lastIpcObject.class.toString()
|
||||
let regex = new RegExp(activeClass, "i")
|
||||
|
||||
Process {
|
||||
id: initialTitleProc
|
||||
command: ["./scripts/initialTitle.sh"]
|
||||
running: false
|
||||
stdout: StdioCollector {
|
||||
}
|
||||
console.log("ActiveWindow", activeWindow, "ActiveClass", activeClass, "Regex", regex)
|
||||
|
||||
const evalTitle = activeWindow.match(regex)
|
||||
callback(evalTitle)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ import qs.Components
|
||||
Item {
|
||||
id: root
|
||||
implicitWidth: expanded ? 300 : 150
|
||||
implicitHeight: 34
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
property bool expanded: false
|
||||
property color textColor: Config.useDynamicColors ? DynamicColors.palette.m3tertiaryFixed : "#ffffff"
|
||||
|
||||
@@ -48,7 +48,7 @@ ShapePath {
|
||||
|
||||
PathLine {
|
||||
relativeX: 0
|
||||
relativeY: -(root.wrapper.height - root.roundingY * 2)
|
||||
relativeY: -( root.wrapper.height - root.roundingY * 2 )
|
||||
}
|
||||
|
||||
PathArc {
|
||||
|
||||
+15
-25
@@ -11,8 +11,6 @@ import qs.Daemons
|
||||
RowLayout {
|
||||
id: root
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 5
|
||||
anchors.rightMargin: 5
|
||||
|
||||
readonly property int vPadding: 6
|
||||
required property Wrapper popouts
|
||||
@@ -34,26 +32,22 @@ RowLayout {
|
||||
|
||||
if (id === "audio" && Config.barConfig.popouts.audio) {
|
||||
popouts.currentName = "audio";
|
||||
popouts.currentCenter = Qt.binding(() => item.mapToItem(root, itemWidth / 2, 0).x);
|
||||
popouts.currentCenter = Qt.binding( () => item.mapToItem(root, itemWidth / 2, 0 ).x );
|
||||
popouts.hasCurrent = true;
|
||||
} else if ( id === "resources" && Config.barConfig.popouts.resources ) {
|
||||
popouts.currentName = "resources";
|
||||
popouts.currentCenter = Qt.binding(() => item.mapToItem(root, itemWidth / 2 + 5, 0).x);
|
||||
popouts.currentCenter = Qt.binding( () => item.mapToItem( root, itemWidth / 2, 0 ).x );
|
||||
popouts.hasCurrent = true;
|
||||
} else if (id === "tray" && Config.barConfig.popouts.tray) {
|
||||
const index = Math.floor(((x - top - 6) / item.implicitWidth) * item.items.count);
|
||||
const trayItem = item.items.itemAt(index);
|
||||
if (trayItem) {
|
||||
popouts.currentName = `traymenu${index}`;
|
||||
popouts.currentCenter = Qt.binding(() => trayItem.mapToItem(root, trayItem.implicitWidth / 2 + 4, 0).x);
|
||||
} else if ( id === "tray" && Config.barConfig.popouts.tray ) {
|
||||
const index = Math.floor((( x - top ) / item.implicitWidth ) * item.items.count );
|
||||
const trayItem = item.items.itemAt( index );
|
||||
if ( trayItem ) {
|
||||
popouts.currentName = `traymenu${ index }`;
|
||||
popouts.currentCenter = Qt.binding( () => trayItem.mapToItem( root, trayItem.implicitWidth / 2, 0 ).x );
|
||||
popouts.hasCurrent = true;
|
||||
} else {
|
||||
popouts.hasCurrent = false;
|
||||
}
|
||||
} else if (id === "activeWindow" && Config.barConfig.popouts.activeWindow) {
|
||||
popouts.currentName = id.toLowerCase();
|
||||
popouts.currentCenter = item.mapToItem(root, 0, itemHeight / 2).y;
|
||||
popouts.hasCurrent = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,17 +101,13 @@ RowLayout {
|
||||
DelegateChoice {
|
||||
roleValue: "notifBell"
|
||||
delegate: WrappedLoader {
|
||||
sourceComponent: NotifBell {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
sourceComponent: NotifBell {}
|
||||
}
|
||||
}
|
||||
DelegateChoice {
|
||||
roleValue: "clock"
|
||||
delegate: WrappedLoader {
|
||||
sourceComponent: Clock {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
sourceComponent: Clock {}
|
||||
}
|
||||
}
|
||||
DelegateChoice {
|
||||
@@ -134,6 +124,9 @@ RowLayout {
|
||||
required property string id
|
||||
required property int index
|
||||
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.fillHeight: true
|
||||
|
||||
function findFirstEnabled(): Item {
|
||||
const count = repeater.count;
|
||||
for (let i = 0; i < count; i++) {
|
||||
@@ -153,11 +146,8 @@ RowLayout {
|
||||
return null;
|
||||
}
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
// Cursed ahh thing to add padding to first and last enabled components
|
||||
Layout.topMargin: findFirstEnabled() === this ? root.vPadding : 0
|
||||
Layout.bottomMargin: findLastEnabled() === this ? root.vPadding : 0
|
||||
Layout.leftMargin: findFirstEnabled() === this ? root.vPadding : 0
|
||||
Layout.rightMargin: findLastEnabled() === this ? root.vPadding : 0
|
||||
|
||||
visible: enabled
|
||||
active: enabled
|
||||
|
||||
+8
-1
@@ -4,9 +4,16 @@ import qs.Modules
|
||||
|
||||
Item {
|
||||
implicitWidth: timeText.contentWidth
|
||||
implicitHeight: timeText.contentHeight
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
Text {
|
||||
id: timeText
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
text: Time.time
|
||||
color: Config.useDynamicColors ? DynamicColors.palette.m3tertiary : "white"
|
||||
|
||||
|
||||
+3
-7
@@ -12,16 +12,13 @@ Item {
|
||||
readonly property Popout currentPopout: content.children.find(c => c.shouldBeActive) ?? null
|
||||
readonly property Item current: currentPopout?.item ?? null
|
||||
|
||||
anchors.centerIn: parent
|
||||
|
||||
implicitWidth: (currentPopout?.implicitWidth ?? 0) + 10 * 2
|
||||
implicitHeight: (currentPopout?.implicitHeight ?? 0) + 10 * 2
|
||||
implicitWidth: (currentPopout?.implicitWidth ?? 0) + 5 * 2
|
||||
implicitHeight: (currentPopout?.implicitHeight ?? 0) + 5 * 2
|
||||
|
||||
Item {
|
||||
id: content
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.margins: 10
|
||||
|
||||
Popout {
|
||||
name: "audio"
|
||||
@@ -80,8 +77,7 @@ Item {
|
||||
required property string name
|
||||
readonly property bool shouldBeActive: root.wrapper.currentName === name
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.centerIn: parent
|
||||
|
||||
opacity: 0
|
||||
scale: 0.8
|
||||
|
||||
+11
-1
@@ -4,11 +4,21 @@ import qs.Helpers
|
||||
import qs.Components
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
implicitWidth: 20
|
||||
implicitHeight: 18
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
MaterialIcon {
|
||||
id: notificationCenterIcon
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
property color iconColor: Config.useDynamicColors ? DynamicColors.palette.m3tertiaryFixed : "white"
|
||||
|
||||
text: HasNotifications.hasNotifications ? "\uf4fe" : "\ue7f4"
|
||||
font.family: "Material Symbols Rounded"
|
||||
font.pixelSize: 20
|
||||
|
||||
@@ -14,8 +14,10 @@ Item {
|
||||
implicitWidth: rowLayout.implicitWidth + rowLayout.anchors.leftMargin + rowLayout.anchors.rightMargin
|
||||
implicitHeight: 34
|
||||
property color textColor: Config.useDynamicColors ? DynamicColors.palette.m3tertiaryFixed : "#ffffff"
|
||||
clip: true
|
||||
|
||||
Rectangle {
|
||||
id: backgroundRect
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
|
||||
@@ -7,9 +7,15 @@ import Quickshell.Services.SystemTray
|
||||
|
||||
Row {
|
||||
id: root
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
required property PanelWindow bar
|
||||
readonly property alias items: repeater
|
||||
|
||||
spacing: 0
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
model: SystemTray.items
|
||||
|
||||
@@ -6,12 +6,16 @@ import qs.Config
|
||||
Item {
|
||||
id: root
|
||||
property int countUpdates: Updates.availableUpdates
|
||||
implicitWidth: contentRow.childrenRect.width + 10
|
||||
implicitHeight: 22
|
||||
implicitWidth: textMetrics.width + contentRow.spacing + 30
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
property color textColor: Config.useDynamicColors ? DynamicColors.palette.m3tertiaryFixed : "#ffffff"
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
implicitHeight: 22
|
||||
radius: height / 2
|
||||
color: Config.useDynamicColors ? DynamicColors.tPalette.m3surfaceContainer : "#40000000"
|
||||
Behavior on color {
|
||||
|
||||
+13
-21
@@ -3,10 +3,11 @@ import QtQuick.Layouts
|
||||
import Quickshell.Hyprland
|
||||
import qs.Helpers
|
||||
import qs.Config
|
||||
import qs.Components
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property string currentTitle
|
||||
property string currentTitle: Hypr.activeName
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredWidth: Math.max( titleText1.implicitWidth, titleText2.implicitWidth ) + 10
|
||||
clip: true
|
||||
@@ -14,15 +15,15 @@ Item {
|
||||
property bool showFirst: true
|
||||
property color textColor: Config.useDynamicColors ? DynamicColors.palette.m3primary : "white"
|
||||
|
||||
Component.onCompleted: {
|
||||
Hyprland.rawEvent.connect(( event ) => {
|
||||
if (event.name === "activewindow") {
|
||||
InitialTitle.getInitialTitle( function( initialTitle ) {
|
||||
root.currentTitle = initialTitle
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
// Component.onCompleted: {
|
||||
// Hyprland.rawEvent.connect(( event ) => {
|
||||
// if (event.name === "activewindow") {
|
||||
// InitialTitle.getInitialTitle( function( initialTitle ) {
|
||||
// root.currentTitle = initialTitle
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
onCurrentTitleChanged: {
|
||||
if (showFirst) {
|
||||
@@ -34,14 +35,13 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
CustomText {
|
||||
id: titleText1
|
||||
anchors.fill: parent
|
||||
anchors.margins: 5
|
||||
text: root.currentTitle
|
||||
color: root.textColor
|
||||
elide: Text.ElideRight
|
||||
font.family: "Rubik"
|
||||
font.pixelSize: 16
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
@@ -49,13 +49,9 @@ Item {
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
|
||||
}
|
||||
|
||||
Behavior on color {
|
||||
CAnim {}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
CustomText {
|
||||
id: titleText2
|
||||
anchors.fill: parent
|
||||
anchors.margins: 5
|
||||
@@ -68,9 +64,5 @@ Item {
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
|
||||
}
|
||||
|
||||
Behavior on color {
|
||||
CAnim {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,14 +12,17 @@ import qs.Components
|
||||
Item {
|
||||
id: itemRoot
|
||||
required property PanelWindow bar
|
||||
implicitHeight: 28
|
||||
implicitWidth: root.implicitWidth
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
implicitWidth: workspacesRow.implicitWidth + 10
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
property HyprlandMonitor monitor: Hyprland.monitorFor( itemRoot.bar?.screen )
|
||||
|
||||
implicitWidth: workspacesRow.implicitWidth + 10
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
implicitHeight: 22
|
||||
|
||||
function shouldShow(monitor) {
|
||||
|
||||
@@ -71,8 +71,6 @@ Item {
|
||||
|
||||
shouldBeActive: root.hasCurrent
|
||||
asynchronous: true
|
||||
anchors.top: parent.top
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
sourceComponent: Content {
|
||||
wrapper: root
|
||||
|
||||
+70
-6
@@ -1,14 +1,78 @@
|
||||
import Quickshell
|
||||
import QtQuick
|
||||
import Quickshell.Hyprland
|
||||
|
||||
FloatingWindow {
|
||||
id: root
|
||||
|
||||
title: "terminal"
|
||||
minimumSize: Qt.size(400, 300)
|
||||
Component.onCompleted: {
|
||||
Hyprland.refreshToplevels()
|
||||
console.log(Hyprland.toplevels.values)
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
width: 480
|
||||
height: 320
|
||||
|
||||
property int callsToUpdateMinimumWidth: 0
|
||||
property bool optimize: true
|
||||
|
||||
property int currentTextModel: 0
|
||||
property var columnTexts: [
|
||||
["Click on either", "rectangle above", "and note how the counter", "below updates", "significantly faster using the", "regular (non-optimized)", "implementation"],
|
||||
["The width", "of this column", "is", "no wider than the", "widest item"],
|
||||
["Note how using Qt.callLater()", "the minimum width is", "calculated a bare-minimum", "number", "of times"]
|
||||
]
|
||||
|
||||
Text {
|
||||
x: 20; y: 280
|
||||
text: "Times minimum width has been calculated: " + root.callsToUpdateMinimumWidth
|
||||
}
|
||||
|
||||
Row {
|
||||
y: 25; spacing: 30; anchors.horizontalCenter: parent.horizontalCenter
|
||||
Rectangle {
|
||||
width: 200; height: 50; color: "lightgreen"
|
||||
Text { text: "Optimized behavior\nusing Qt.callLater()"; anchors.centerIn: parent }
|
||||
MouseArea { anchors.fill: parent; onClicked: { root.optimize = true; root.currentTextModel++ } }
|
||||
}
|
||||
Rectangle {
|
||||
width: 200; height: 50; color: "lightblue"
|
||||
Text { text: "Regular behavior"; anchors.centerIn: parent}
|
||||
MouseArea { anchors.fill: parent; onClicked: { root.optimize = false; root.currentTextModel++ } }
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
id: column
|
||||
anchors.centerIn: parent
|
||||
|
||||
onChildrenChanged: root.optimize ? Qt.callLater(updateMinimumWidth) : updateMinimumWidth()
|
||||
|
||||
property int widestChild
|
||||
function updateMinimumWidth() {
|
||||
root.callsToUpdateMinimumWidth++
|
||||
var w = 0;
|
||||
for (var i in children) {
|
||||
var child = children[i];
|
||||
if (child.implicitWidth > w) {
|
||||
w = child.implicitWidth;
|
||||
}
|
||||
}
|
||||
|
||||
widestChild = w;
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
model: root.columnTexts[root.currentTextModel%3]
|
||||
delegate: Text {
|
||||
id: text
|
||||
required property string modelData
|
||||
required property int index
|
||||
color: "white"
|
||||
text: modelData
|
||||
width: column.widestChild
|
||||
horizontalAlignment: Text.Center
|
||||
Rectangle { anchors.fill: parent; z: -1; color: text.index%2 ? "gray" : "darkgray" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user