- hypr/apps.lua - hypr/autostart.lua - hypr/envs.lua - hypr/hyprland.lua - hypr/hyprsunset.conf - hypr/input.lua - hypr/looknfeel.lua - hypr/omasettings.lua - hypr/xdph.conf - omarchy/branding/about.txt - omarchy/branding/screensaver.txt - omarchy/extensions/omarchy-menu.jsonc - omarchy/hooks/battery-low.d/play-warning-sound.sample - omarchy/hooks/font-set.d/show-font-notification.sample - omarchy/hooks/post-boot.d/weather.sample - omarchy/hooks/post-update.d/install-voxtype.hook - omarchy/hooks/post-update.d/setup-agent.hook - omarchy/hooks/post-update.d/setup-fingerprint.hook - omarchy/hooks/post-update.d/show-update-notification.sample - omarchy/hooks/pre-refresh-pacman.d/add-custom-repo.sample - omarchy/hooks/theme-set.d/show-theme-notification.sample - omarchy/shell.json - omarchy/shell.toml - omarchy/theme.name - omarchy/themes/azure-glow/README.md - omarchy/themes/azure-glow/alacritty.toml - omarchy/themes/azure-glow/btop.theme - omarchy/themes/azure-glow/hyprland.conf - omarchy/themes/azure-glow/hyprlock.conf - omarchy/themes/azure-glow/icons.theme - … 269 more
164 lines
4.6 KiB
QML
164 lines
4.6 KiB
QML
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Wayland
|
|
import qs.Commons
|
|
import qs.Ui
|
|
|
|
// A transient, centered SSH authorization surface. The full-screen layer
|
|
// window supplies the scrim, outside-click denial, and keyboard focus; only
|
|
// the compact card is visible. It is tied to the bar widget's screen but not
|
|
// positioned relative to the bar, so the plugin otherwise stays out of sight.
|
|
PanelWindow {
|
|
id: popup
|
|
|
|
required property var panel
|
|
required property Item anchorItem
|
|
|
|
readonly property bool open: panel.sshAgentApprovalPopup && (panel.sshPrompt !== null || panel.sshUnlockRequest !== null)
|
|
property bool focusPrimed: false
|
|
readonly property var anchorWindow: anchorItem ? anchorItem.QsWindow.window : null
|
|
readonly property int cardWidth: Math.max(1, Math.min(Style.space(460), width - Style.gapsOut * 2))
|
|
readonly property int cardHeight: Math.max(1, Math.min(
|
|
content.implicitHeight + card.contentTopInset + card.contentBottomInset,
|
|
height - Style.gapsOut * 2))
|
|
|
|
function beginFocusPrime() {
|
|
if (open && backingWindowVisible) focusPrimeTimer.restart()
|
|
}
|
|
|
|
function refocus() {
|
|
if (!open) return
|
|
Qt.callLater(function() {
|
|
if (!popup.open) return
|
|
if (popup.panel.sshPrompt) approvalScreen.focusDefault()
|
|
else unlockScreen.focusDefault()
|
|
})
|
|
}
|
|
|
|
screen: anchorItem && anchorItem.QsWindow.window ? anchorItem.QsWindow.window.screen : null
|
|
visible: open
|
|
color: "transparent"
|
|
exclusionMode: ExclusionMode.Ignore
|
|
|
|
WlrLayershell.namespace: "qs-bitwarden-ssh-approval"
|
|
WlrLayershell.layer: WlrLayer.Overlay
|
|
// Prime focus briefly so keyboard-summoned requests reliably receive it,
|
|
// then settle to OnDemand so another monitor is not pointer-blocked.
|
|
WlrLayershell.keyboardFocus: open
|
|
? (focusPrimed ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.Exclusive)
|
|
: WlrKeyboardFocus.None
|
|
|
|
anchors {
|
|
top: true
|
|
bottom: true
|
|
left: true
|
|
right: true
|
|
}
|
|
|
|
onBackingWindowVisibleChanged: beginFocusPrime()
|
|
onOpenChanged: {
|
|
if (open) {
|
|
focusPrimed = false
|
|
beginFocusPrime()
|
|
refocus()
|
|
} else {
|
|
focusPrimeTimer.stop()
|
|
focusPrimed = false
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: popup.panel
|
|
function onSshPromptChanged() { popup.refocus() }
|
|
function onSshUnlockRequestChanged() { popup.refocus() }
|
|
function onStatusChanged() { popup.refocus() }
|
|
}
|
|
|
|
Timer {
|
|
id: focusPrimeTimer
|
|
interval: 75
|
|
repeat: false
|
|
onTriggered: {
|
|
popup.focusPrimed = true
|
|
popup.refocus()
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
color: Color.menu.scrim
|
|
}
|
|
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
onClicked: popup.panel.denySshRequest()
|
|
}
|
|
|
|
BorderSurface {
|
|
id: card
|
|
width: popup.cardWidth
|
|
height: popup.cardHeight
|
|
anchors.centerIn: parent
|
|
radius: Style.cornerRadius
|
|
color: Color.popups.background
|
|
borderSpec: Border.surfaceSpec("popups", "border", Color.popups.border,
|
|
Math.max(1, Style.space(2)))
|
|
padding: Style.spacing.panelPadding
|
|
|
|
// Swallow clicks on unused card space; only a click outside the card is a
|
|
// denial. Interactive children declared below remain above this catcher.
|
|
MouseArea { anchors.fill: parent; onClicked: {} }
|
|
|
|
Item {
|
|
id: keyScope
|
|
anchors.fill: parent
|
|
anchors.topMargin: card.contentTopInset
|
|
anchors.rightMargin: card.contentRightInset
|
|
anchors.bottomMargin: card.contentBottomInset
|
|
anchors.leftMargin: card.contentLeftInset
|
|
focus: popup.open
|
|
|
|
Keys.priority: Keys.BeforeItem
|
|
Keys.onPressed: function(event) {
|
|
if (event.key === Qt.Key_Escape) {
|
|
if (!(event.modifiers & ~Qt.KeypadModifier)) {
|
|
popup.panel.denySshRequest()
|
|
event.accepted = true
|
|
} else if (event.modifiers & Qt.ShiftModifier) {
|
|
popup.panel.denyAllSshRequests()
|
|
event.accepted = true
|
|
}
|
|
}
|
|
}
|
|
|
|
Flickable {
|
|
id: scroller
|
|
anchors.fill: parent
|
|
contentWidth: width
|
|
contentHeight: content.implicitHeight
|
|
clip: true
|
|
flickableDirection: Flickable.VerticalFlick
|
|
boundsBehavior: Flickable.StopAtBounds
|
|
interactive: contentHeight > height
|
|
|
|
Column {
|
|
id: content
|
|
width: scroller.width
|
|
|
|
SshUnlockScreen {
|
|
id: unlockScreen
|
|
panel: popup.panel
|
|
active: popup.open && popup.panel.sshPrompt === null
|
|
}
|
|
|
|
SshApprovalScreen {
|
|
id: approvalScreen
|
|
panel: popup.panel
|
|
active: popup.open && popup.panel.sshPrompt !== null
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|