mirror of
https://github.com/end-4/dots-hyprland.git
synced 2026-06-05 14:59:27 -05:00
hefty: bar: window info
This commit is contained in:
@@ -159,8 +159,8 @@ Singleton {
|
||||
property JsonObject apps: JsonObject {
|
||||
property string bluetooth: "kcmshell6 kcm_bluetooth"
|
||||
property string changePassword: "kitty -1 --hold=yes fish -i -c 'passwd'"
|
||||
property string network: "kcmshell6 kcm_networkmanagement"
|
||||
property string manageUser: "kcmshell6 kcm_users"
|
||||
property string network: "kcmshell6 kcm_networkmanagement"
|
||||
property string networkEthernet: "kcmshell6 kcm_networkmanagement"
|
||||
property string taskManager: "plasma-systemmonitor --page-name Processes"
|
||||
property string terminal: "kitty -1" // This is only for shell actions
|
||||
|
||||
@@ -4,7 +4,7 @@ import Quickshell.Io
|
||||
|
||||
JsonObject {
|
||||
property JsonObject bar: JsonObject {
|
||||
property list<var> leftWidgets: ["HLeftSidebarButton"]
|
||||
property list<var> leftWidgets: ["HLeftSidebarButton", "HWindowInfo"]
|
||||
property list<var> centerLeftWidgets: ["HTime"]
|
||||
property list<var> centerWidgets: ["HWorkspaces"]
|
||||
property list<var> centerRightWidgets: ["HResources"]
|
||||
|
||||
@@ -11,6 +11,9 @@ Item {
|
||||
property alias verticalAlignment: textWidget.verticalAlignment
|
||||
property alias font: textWidget.font
|
||||
property alias color: textWidget.color
|
||||
property alias elide: textWidget.elide
|
||||
property alias wrapMode: textWidget.wrapMode
|
||||
property alias animateChange: textWidget.animateChange
|
||||
|
||||
// In many cases the baseline is a bit high to accomodate the dangling parts of "g" and "y",
|
||||
// making most text (especiall number-only text) not well-balanced.
|
||||
|
||||
@@ -2,6 +2,7 @@ pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import qs.modules.common as C
|
||||
import qs.modules.common.widgets as W
|
||||
|
||||
Item {
|
||||
id: root
|
||||
@@ -19,10 +20,17 @@ Item {
|
||||
id: leftSide
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
anchors.right: !root.vertical ? centerLeftSide.left : parent.right
|
||||
anchors.bottom: !root.vertical ? parent.bottom : centerLeftSide.top
|
||||
|
||||
HBarUserFallbackComponentRepeater {
|
||||
componentNames: root.leftWidgets
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
|
||||
Side {
|
||||
@@ -56,12 +64,20 @@ Item {
|
||||
id: rightSide
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: !root.vertical ? centerRightSide.right : parent.left
|
||||
anchors.top: !root.vertical ? parent.top : centerRightSide.bottom
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
HBarUserFallbackComponentRepeater {
|
||||
componentNames: root.rightWidgets
|
||||
}
|
||||
}
|
||||
|
||||
component Side: GridLayout {
|
||||
component Side: W.BoxLayout {
|
||||
anchors {
|
||||
top: !root.vertical ? parent.top : undefined
|
||||
bottom: !root.vertical ? parent.bottom : undefined
|
||||
@@ -73,9 +89,7 @@ Item {
|
||||
rightMargin: root.spacing * !root.vertical
|
||||
}
|
||||
|
||||
columns: C.Config.options.bar.vertical ? 1 : -1
|
||||
property real spacing: root.spacing
|
||||
columnSpacing: spacing
|
||||
rowSpacing: spacing
|
||||
vertical: C.Config.options.bar.vertical
|
||||
spacing: root.spacing
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -1,5 +1,6 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.modules.common as C
|
||||
import qs.modules.common.widgets as W
|
||||
@@ -48,6 +49,11 @@ Repeater {
|
||||
context: root.context
|
||||
property bool startSide: index === 0
|
||||
property bool endSide: index === root.model.length - 1
|
||||
|
||||
Layout.fillWidth: item.Layout.fillWidth
|
||||
Layout.fillHeight: item.Layout.fillHeight
|
||||
Layout.maximumWidth: item.Layout.maximumWidth
|
||||
Layout.maximumHeight: item.Layout.maximumHeight
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,4 +80,4 @@ Repeater {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,282 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
import Quickshell.Hyprland
|
||||
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import ".."
|
||||
|
||||
HBarWidgetWithPopout {
|
||||
id: root
|
||||
|
||||
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(root.QsWindow.window?.screen)
|
||||
readonly property Toplevel activeWindow: ToplevelManager.activeToplevel
|
||||
readonly property var activeHyprlandClient: HyprlandData.clientForToplevel(activeWindow)
|
||||
readonly property bool focusingThisMonitor: HyprlandData.activeWorkspace?.monitor == monitor?.name
|
||||
readonly property var biggestWindow: HyprlandData.biggestWindowForWorkspace(HyprlandData.monitors[root.monitor?.id]?.activeWorkspace.id)
|
||||
readonly property bool hasFocusedWindow: (focusingThisMonitor && activeWindow?.activated && biggestWindow) ?? false
|
||||
|
||||
readonly property string primaryText: {
|
||||
if (root.hasFocusedWindow)
|
||||
return root.activeWindow?.title;
|
||||
return (root.biggestWindow?.title) ?? `${Translation.tr("Workspace")} ${root.monitor?.activeWorkspace?.id ?? 1}`;
|
||||
}
|
||||
readonly property string secondaryText: {
|
||||
if (root.hasFocusedWindow && root.activeWindow?.appId != "" && root.activeWindow?.appId != primaryText)
|
||||
return root.activeWindow?.appId;
|
||||
return Translation.tr("Options")
|
||||
}
|
||||
|
||||
property real fontPixelSize: Appearance.font.pixelSize.smaller
|
||||
|
||||
Layout.maximumWidth: implicitWidth
|
||||
Layout.fillWidth: true
|
||||
|
||||
popupContentWidth: popupContent.implicitWidth
|
||||
popupContentHeight: popupContent.implicitHeight
|
||||
|
||||
HBarWidgetContent {
|
||||
id: contentRoot
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
vertical: root.vertical
|
||||
atBottom: root.atBottom
|
||||
contentImplicitWidth: winTitleContent.implicitWidth
|
||||
contentImplicitHeight: winTitleContent.implicitHeight
|
||||
showPopup: false
|
||||
onClicked: root.showPopup = !root.showPopup;
|
||||
|
||||
WinTitleContent {
|
||||
id: winTitleContent
|
||||
}
|
||||
|
||||
WinOptionsPopup {
|
||||
id: popupContent
|
||||
anchors {
|
||||
top: parent.top
|
||||
topMargin: root.popupContentOffsetY
|
||||
left: parent.left
|
||||
leftMargin: root.popupContentOffsetX
|
||||
}
|
||||
shown: root.showPopup
|
||||
}
|
||||
}
|
||||
|
||||
component WinTitleContent: BoxLayout {
|
||||
anchors.fill: parent
|
||||
vertical: root.vertical
|
||||
spacing: 4
|
||||
|
||||
Item {
|
||||
Layout.leftMargin: 4 * !root.vertical
|
||||
Layout.topMargin: 3 * root.vertical
|
||||
Layout.bottomMargin: 4 * root.vertical
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
implicitWidth: appIcon.implicitWidth
|
||||
implicitHeight: appIcon.implicitHeight
|
||||
|
||||
AppIcon {
|
||||
id: appIcon
|
||||
anchors.centerIn: parent
|
||||
opacity: 0
|
||||
source: Quickshell.iconPath(AppSearch.guessIcon(root.activeWindow?.appId), "image-missing")
|
||||
implicitSize: 16
|
||||
animated: false
|
||||
}
|
||||
Circle {
|
||||
id: iconMask
|
||||
visible: false
|
||||
layer.enabled: true
|
||||
diameter: appIcon.implicitSize
|
||||
}
|
||||
Loader {
|
||||
anchors.fill: appIcon
|
||||
Colorizer {
|
||||
id: renderedIcon
|
||||
implicitWidth: appIcon.implicitWidth
|
||||
implicitHeight: appIcon.implicitHeight
|
||||
colorizationColor: Appearance.colors.colOnLayer0
|
||||
// colorization: Config.options.bar.workspaces.monochromeIcons ? 0.8 : 0.5
|
||||
colorization: 1
|
||||
brightness: 0
|
||||
source: appIcon
|
||||
|
||||
maskEnabled: true
|
||||
maskSource: iconMask
|
||||
maskThresholdMin: 0.5
|
||||
maskSpreadAtMin: 1
|
||||
|
||||
visible: root.activeWindow
|
||||
}
|
||||
}
|
||||
|
||||
MaterialSymbol {
|
||||
anchors.centerIn: parent
|
||||
visible: !renderedIcon.visible
|
||||
text: "overview_key"
|
||||
iconSize: 16
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
visible: !root.vertical
|
||||
Layout.rightMargin: 4
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.fillHeight: true
|
||||
// No overflow
|
||||
Layout.maximumWidth: implicitWidth
|
||||
Layout.fillWidth: true
|
||||
// Size
|
||||
implicitWidth: winText.implicitWidth
|
||||
implicitHeight: winText.implicitHeight
|
||||
|
||||
FlyFadeEnterChoreographable {
|
||||
anchors.fill: parent
|
||||
progress: contentRoot.containsMouse ? 0 : 1
|
||||
reverseDirection: true
|
||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||
VisuallyCenteredStyledText {
|
||||
id: winText
|
||||
height: parent.height
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
// Styles & text
|
||||
font.pixelSize: root.fontPixelSize
|
||||
text: root.primaryText
|
||||
}
|
||||
}
|
||||
FlyFadeEnterChoreographable {
|
||||
anchors.fill: parent
|
||||
progress: contentRoot.containsMouse ? 1 : 0
|
||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||
VisuallyCenteredStyledText {
|
||||
height: parent.height
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
// Styles & text
|
||||
font.pixelSize: root.fontPixelSize
|
||||
text: root.secondaryText
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component WinOptionsPopup: ChoreographerLoader {
|
||||
sourceComponent: ChoreographerGridLayout {
|
||||
id: popupRoot
|
||||
|
||||
columns: 3
|
||||
rowSpacing: 8
|
||||
columnSpacing: 6
|
||||
|
||||
FlyFadeEnterChoreographable {
|
||||
Layout.fillWidth: true
|
||||
Layout.columnSpan: 3
|
||||
StyledText {
|
||||
width: parent.width
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.Wrap
|
||||
text: root.hasFocusedWindow ? Translation.tr("Window options") : Translation.tr("Launch")
|
||||
// font.pixelSize: Appearance.font.pixelSize.title
|
||||
}
|
||||
}
|
||||
|
||||
FlyFadeEnterChoreographable {
|
||||
visible: !root.hasFocusedWindow
|
||||
PopupLabeledIconButton {
|
||||
materialSymbol: "terminal"
|
||||
text: Translation.tr("Terminal")
|
||||
onClicked: Quickshell.execDetached(["bash", "-c", Config.options.apps.terminal]);
|
||||
}
|
||||
}
|
||||
|
||||
FlyFadeEnterChoreographable {
|
||||
visible: !root.hasFocusedWindow
|
||||
PopupLabeledIconButton {
|
||||
materialSymbol: "files"
|
||||
text: Translation.tr("Files")
|
||||
onClicked: Qt.openUrlExternally(Directories.home);
|
||||
}
|
||||
}
|
||||
|
||||
FlyFadeEnterChoreographable {
|
||||
visible: !root.hasFocusedWindow
|
||||
PopupLabeledIconButton {
|
||||
materialSymbol: "language"
|
||||
text: Translation.tr("Browser")
|
||||
// Kinda hacky. Works with Google and DDG at least
|
||||
onClicked: Qt.openUrlExternally(Config.options.search.engineBaseUrl);
|
||||
}
|
||||
}
|
||||
|
||||
FlyFadeEnterChoreographable {
|
||||
visible: root.hasFocusedWindow
|
||||
PopupLabeledIconButton {
|
||||
materialSymbol: "content_copy"
|
||||
text: Translation.tr("Address")
|
||||
onClicked: Quickshell.clipboardText = root.activeHyprlandClient.address
|
||||
}
|
||||
}
|
||||
|
||||
FlyFadeEnterChoreographable {
|
||||
visible: root.hasFocusedWindow
|
||||
PopupLabeledIconButton {
|
||||
property bool toFloat: !(root.activeHyprlandClient?.floating ?? false)
|
||||
materialSymbol: toFloat ? "picture_in_picture_center" : "side_navigation"
|
||||
text: toFloat ? Translation.tr("Float") : Translation.tr("Tile")
|
||||
onClicked: {
|
||||
Hyprland.dispatch(`togglefloating address:${root.activeHyprlandClient.address}`)
|
||||
HyprlandData.updateWindowList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FlyFadeEnterChoreographable {
|
||||
visible: root.hasFocusedWindow
|
||||
PopupLabeledIconButton {
|
||||
materialSymbol: "warning"
|
||||
text: Translation.tr("Kill")
|
||||
colBackground: Appearance.colors.colError
|
||||
colForeground: Appearance.colors.colOnError
|
||||
onClicked: {
|
||||
Hyprland.dispatch(`killwindow address:${root.activeHyprlandClient.address}`)
|
||||
HyprlandData.updateWindowList()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component PopupLabeledIconButton: Column {
|
||||
id: licobtn
|
||||
property string materialSymbol: "circle"
|
||||
property string text: "Label"
|
||||
property alias colBackground: btn.colBackground
|
||||
property alias colForeground: btn.colForeground
|
||||
spacing: 4
|
||||
|
||||
signal clicked()
|
||||
onClicked: root.showPopup = false
|
||||
|
||||
StyledIconButton {
|
||||
id: btn
|
||||
implicitWidth: 70
|
||||
implicitHeight: 50
|
||||
text: licobtn.materialSymbol
|
||||
iconSize: 24
|
||||
colBackground: Appearance.colors.colLayer4
|
||||
colForeground: Appearance.colors.colOnLayer4
|
||||
onClicked: licobtn.clicked()
|
||||
}
|
||||
|
||||
StyledText {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: licobtn.text
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user