Files
z-bar-qt/Modules/Polkit/Polkit.qml

356 lines
8.0 KiB
QML

import Quickshell
import Quickshell.Services.Polkit
import Quickshell.Wayland
import Quickshell.Widgets
import ZShell.Components
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import qs.Components
import qs.Modules
import ZShell.Config
import qs.Services
Scope {
id: root
property alias polkitAgent: polkitAgent
property bool shouldShow: false
PanelWindow {
id: panelWindow
property bool detailsOpen: false
WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.namespace: "ZShell-Auth"
color: "transparent"
visible: false
Connections {
function onShouldShowChanged(): void {
if (root.shouldShow) {
panelWindow.visible = true;
openAnim.start();
} else {
closeAnim.start();
}
}
target: root
}
Anim {
id: openAnim
property: "opacity"
target: inputPanel
to: 1
}
Anim {
id: closeAnim
property: "opacity"
target: inputPanel
to: 0
onFinished: {
panelWindow.visible = false;
}
onStarted: {
panelWindow.detailsOpen = false;
}
}
anchors {
bottom: true
left: true
right: true
top: true
}
// mask: Region { item: inputPanel }
CustomRect {
id: inputPanel
anchors.centerIn: parent
color: Colors.tPalette.m3surface
implicitHeight: layout.implicitHeight + layout.anchors.margins * 2
implicitWidth: Math.max(layout.implicitWidth + layout.anchors.margins * 2, 450)
opacity: 0
radius: Tokens.rounding.small * 2
ColumnLayout {
id: layout
anchors.fill: parent
anchors.margins: Tokens.padding.medium
RowLayout {
id: contentRow
spacing: 24
Item {
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
Layout.leftMargin: 16
Layout.preferredHeight: icon.implicitSize
Layout.preferredWidth: icon.implicitSize
IconImage {
id: icon
anchors.fill: parent
implicitSize: 64
mipmap: true
source: Quickshell.iconPath(polkitAgent.flow?.iconName, true) ?? ""
visible: `${source}`.includes("://")
}
MaterialIcon {
anchors.fill: parent
fontStyle: Tokens.font.icon.size(64).build()
horizontalAlignment: Text.AlignHCenter
text: "security"
verticalAlignment: Text.AlignVCenter
visible: !icon.visible
}
}
ColumnLayout {
id: contentColumn
Layout.fillHeight: true
Layout.fillWidth: true
CustomText {
Layout.alignment: Qt.AlignLeft
Layout.preferredWidth: Math.min(600, contentWidth)
font: Tokens.font.title.builders.medium.weight(Font.Bold).build()
text: polkitAgent.flow?.message ?? ""
wrapMode: Text.WordWrap
}
CustomText {
Layout.alignment: Qt.AlignLeft
Layout.preferredWidth: Math.min(600, contentWidth)
color: Colors.tPalette.m3onSurfaceVariant
font: Tokens.font.title.builders.small.weight(Font.Bold).build()
text: polkitAgent.flow?.supplementaryMessage || "No Additional Information"
wrapMode: Text.WordWrap
}
TextField {
id: passInput
Layout.fillWidth: true
Layout.preferredHeight: 40
color: Colors.palette.m3onSurfaceVariant
echoMode: polkitAgent.flow?.responseVisible ? TextInput.Normal : TextInput.Password
placeholderText: polkitAgent.flow?.failed ? " Incorrect Password" : " Input Password"
placeholderTextColor: polkitAgent.flow?.failed ? Colors.palette.m3onError : Colors.tPalette.m3onSurfaceVariant
selectByMouse: true
font: Tokens.font.body.small
background: CustomRect {
color: (polkitAgent.flow?.failed && passInput.text === "") ? Colors.palette.m3error : Colors.tPalette.m3surfaceVariant
implicitHeight: 40
radius: Tokens.rounding.small
}
onAccepted: okButton.clicked()
}
CustomCheckbox {
id: showPassCheckbox
Layout.alignment: Qt.AlignLeft
checked: polkitAgent.flow?.responseVisible ?? false
text: "Show Password"
onCheckedChanged: {
passInput.echoMode = checked ? TextInput.Normal : TextInput.Password;
passInput.forceActiveFocus();
}
}
}
}
CustomRect {
id: detailsPanel
property bool open: panelWindow.detailsOpen
Layout.fillWidth: true
Layout.preferredHeight: implicitHeight
clip: true
color: Colors.tPalette.m3surfaceContainerLow
implicitHeight: 0
implicitWidth: textDetailsColumn.implicitWidth + textDetailsColumn.anchors.margins * 2
radius: Tokens.rounding.medium
visible: true
Behavior on open {
ParallelAnimation {
Anim {
property: "implicitHeight"
target: detailsPanel
to: !detailsPanel.open ? textDetailsColumn.implicitHeight + Tokens.padding.small * 2 : 0
type: Anim.DefaultEffects
}
Anim {
property: "opacity"
target: textDetailsColumn
to: !detailsPanel.open ? 1 : 0
}
}
}
ColumnLayout {
id: textDetailsColumn
anchors.fill: parent
anchors.margins: Tokens.padding.small
opacity: 0
spacing: Tokens.spacing.small
CustomText {
text: `actionId: ${polkitAgent.flow?.actionId}`
wrapMode: Text.WordWrap
}
CustomText {
text: `selectedIdentity: ${polkitAgent.flow?.selectedIdentity}`
wrapMode: Text.WordWrap
}
}
}
RowLayout {
Layout.preferredWidth: contentRow.implicitWidth
spacing: 8
IconButton {
id: detailsButton
Layout.alignment: Qt.AlignLeft
horizontalPadding: Tokens.padding.medium
icon: "info"
inactiveColor: Colors.palette.m3surfaceContainer
inactiveOnColor: Colors.palette.m3onSurface
isRound: true
shapeMorph: true
verticalPadding: Tokens.padding.medium
onClicked: {
panelWindow.detailsOpen = !panelWindow.detailsOpen;
}
}
Item {
id: spacer
Layout.fillWidth: true
}
ButtonRow {
Layout.alignment: Qt.AlignRight
spacing: Tokens.spacing.medium
IconTextButton {
id: okButton
enabled: passInput.text.length > 0 || !!polkitAgent.flow?.isResponseRequired
horizontalPadding: Tokens.padding.large
icon: "check"
inactiveColor: Colors.palette.m3primary
inactiveOnColor: Colors.palette.m3onPrimary
isRound: true
isToggle: false
shapeMorph: true
shapeMorphExpansion: pressed ? 12 : 0
text: "OK"
onClicked: {
polkitAgent.flow.submit(passInput.text);
passInput.text = "";
passInput.forceActiveFocus();
}
}
IconTextButton {
id: cancelButton
enabled: passInput.text.length > 0 || !!polkitAgent.flow?.isResponseRequired
horizontalPadding: Tokens.padding.large
icon: "close"
inactiveColor: Colors.palette.m3surfaceContainer
inactiveOnColor: Colors.palette.m3onSurface
isRound: true
isToggle: false
shapeMorph: true
shapeMorphExpansion: pressed ? 12 : 0
text: "Cancel"
onClicked: {
root.shouldShow = false;
polkitAgent.flow.cancelAuthenticationRequest();
passInput.text = "";
}
}
}
}
}
}
Connections {
function onIsResponseRequiredChanged() {
passInput.text = "";
if (polkitAgent.flow?.isResponseRequired)
root.shouldShow = true;
passInput.forceActiveFocus();
}
function onIsSuccessfulChanged() {
if (polkitAgent.flow?.isSuccessful)
root.shouldShow = false;
passInput.text = "";
}
target: polkitAgent.flow
}
}
PolkitAgent {
id: polkitAgent
}
Variants {
model: Quickshell.screens
PanelWindow {
required property var modelData
color: root.shouldShow ? "#80000000" : "transparent"
exclusionMode: ExclusionMode.Ignore
screen: modelData
visible: panelWindow.visible
Behavior on color {
CAnim {}
}
anchors {
bottom: true
left: true
right: true
top: true
}
}
}
}