mirror of
https://github.com/Nexoniarz/nexoniarz-config-nixos.git
synced 2026-11-03 20:44:27 +00:00
nixos config
This commit is contained in:
commit
5dc9fb020e
46 changed files with 6194 additions and 0 deletions
218
dotfiles/quickshell/RightBar.qml
Normal file
218
dotfiles/quickshell/RightBar.qml
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Services.Pipewire
|
||||
import Quickshell.Services.SystemTray
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Wayland
|
||||
|
||||
PanelWindow {
|
||||
id: root
|
||||
required property var screen
|
||||
property string activePanel: ""
|
||||
property bool expanded: false
|
||||
|
||||
// Keeps the default sink's PwNode subscribed so audio properties
|
||||
// (volume/muted) actually receive live updates.
|
||||
PwObjectTracker {
|
||||
objects: Pipewire.defaultAudioSink ? [Pipewire.defaultAudioSink] : []
|
||||
}
|
||||
|
||||
anchors { top: true; right: true; bottom: true }
|
||||
// Collapsed = zero reserved space; expand/collapse is triggered from
|
||||
// the taskbar (BottomBar), not a button on this bar itself.
|
||||
implicitWidth: expanded ? 220 : 0
|
||||
exclusiveZone: expanded ? 220 : 0
|
||||
color: Theme.bg
|
||||
// Never take keyboard focus — this bar has no text input, and leaving
|
||||
// it focusable was stealing the keyboard grab from things like slurp's
|
||||
// screenshot selection overlay.
|
||||
focusable: false
|
||||
|
||||
// Only "network" needs the popup's keyboard grab (hotspot/wifi
|
||||
// password fields).
|
||||
function needsGrab(panel) { return panel === "network"; }
|
||||
|
||||
function toggle(panel) {
|
||||
if (root.activePanel === panel) {
|
||||
root.activePanel = "";
|
||||
return;
|
||||
}
|
||||
if (root.activePanel !== "" && root.needsGrab(root.activePanel) !== root.needsGrab(panel)) {
|
||||
// See LeftBar.qml's toggle() for why: an xdg_popup's grab
|
||||
// can't be toggled on an already-mapped surface, only
|
||||
// established fresh — so force a close+reopen when crossing
|
||||
// that boundary instead of just changing the panel in place.
|
||||
root.activePanel = "";
|
||||
Qt.callLater(function () { root.activePanel = panel; });
|
||||
return;
|
||||
}
|
||||
root.activePanel = panel;
|
||||
}
|
||||
|
||||
Column {
|
||||
visible: root.expanded
|
||||
anchors.top: parent.top
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.topMargin: 14
|
||||
spacing: 14
|
||||
width: parent.width - 24
|
||||
|
||||
DigitalClock {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
// System tray (StatusNotifierItem) — background/status apps like
|
||||
// Steam, Discord, KDE Connect that register a tray icon. Sits
|
||||
// right under the clock, separate from the categorized sections
|
||||
// below the divider.
|
||||
Row {
|
||||
id: trayRow
|
||||
visible: SystemTray.items.values.length > 0
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
spacing: 12
|
||||
|
||||
Repeater {
|
||||
model: SystemTray.items.values
|
||||
delegate: IconImage {
|
||||
id: trayIcon
|
||||
implicitSize: 18
|
||||
source: Quickshell.iconPath(modelData.icon, "")
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: (mouse) => {
|
||||
if (mouse.button === Qt.RightButton) {
|
||||
if (modelData.hasMenu) {
|
||||
var pos = trayIcon.mapToItem(null, 0, trayIcon.height);
|
||||
modelData.display(root, pos.x, pos.y);
|
||||
} else {
|
||||
modelData.secondaryActivate();
|
||||
}
|
||||
} else {
|
||||
modelData.activate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle { width: parent.width; height: 1; color: Theme.borderDim }
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
spacing: 6
|
||||
|
||||
Text {
|
||||
text: "CONNECTIVITY"
|
||||
color: Theme.fgDim
|
||||
font.family: "JetBrainsMono Nerd Font"
|
||||
font.pixelSize: 9
|
||||
font.bold: true
|
||||
}
|
||||
SidebarRow {
|
||||
label: "Wi-Fi & Network"
|
||||
active: root.activePanel === "network"
|
||||
onClicked: root.toggle("network")
|
||||
}
|
||||
SidebarRow {
|
||||
label: "Bluetooth"
|
||||
active: root.activePanel === "bluetooth"
|
||||
onClicked: root.toggle("bluetooth")
|
||||
}
|
||||
SidebarRow {
|
||||
label: "Messages"
|
||||
active: root.activePanel === "messages"
|
||||
onClicked: root.toggle("messages")
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
spacing: 6
|
||||
|
||||
Text {
|
||||
text: "SYSTEM"
|
||||
color: Theme.fgDim
|
||||
font.family: "JetBrainsMono Nerd Font"
|
||||
font.pixelSize: 9
|
||||
font.bold: true
|
||||
}
|
||||
SidebarRow {
|
||||
label: "Screenshot"
|
||||
active: root.activePanel === "screenshot"
|
||||
onClicked: root.toggle("screenshot")
|
||||
}
|
||||
SidebarRow {
|
||||
label: (Pipewire.defaultAudioSink && Pipewire.defaultAudioSink.audio && Pipewire.defaultAudioSink.audio.muted)
|
||||
? "Volume (muted)" : "Volume"
|
||||
active: root.activePanel === "volume"
|
||||
onClicked: root.toggle("volume")
|
||||
}
|
||||
SidebarRow {
|
||||
label: "Brightness"
|
||||
active: root.activePanel === "brightness"
|
||||
onClicked: root.toggle("brightness")
|
||||
}
|
||||
SidebarRow {
|
||||
label: "Devices"
|
||||
active: root.activePanel === "devices"
|
||||
onClicked: root.toggle("devices")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SidebarRow {
|
||||
visible: root.expanded
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 14
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: parent.width - 24
|
||||
label: "Power"
|
||||
fg: Theme.danger
|
||||
active: root.activePanel === "power"
|
||||
onClicked: root.toggle("power")
|
||||
}
|
||||
|
||||
PanelWindow {
|
||||
id: flyout
|
||||
screen: root.screen
|
||||
anchors { top: true; right: true }
|
||||
// No margin here on purpose: Hyprland already insets layer-shell
|
||||
// surfaces past other surfaces' exclusive zones on the same edge
|
||||
// (confirmed via `hyprctl layers` — BottomBar gets the same
|
||||
// treatment for free, spanning right up to x=1700 with zero
|
||||
// margin of its own). A margin of 220 here was stacking on top
|
||||
// of that automatic inset, pushing the flyout 220px further left
|
||||
// than intended and leaving a ~220px gap between it and the
|
||||
// sidebar.
|
||||
visible: root.activePanel !== ""
|
||||
implicitWidth: 320
|
||||
implicitHeight: content.implicitHeight
|
||||
exclusiveZone: 0
|
||||
color: "transparent"
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
// On-demand layer-shell focus, not an xdg_popup grab: this used to
|
||||
// be a PopupWindow with grabFocus, but an xdg_popup grab gets
|
||||
// dismissed by the compositor the instant anything else so much as
|
||||
// touches focus/surface state elsewhere (confirmed: even an
|
||||
// unrelated hyprpaper/mpvpaper surface change was enough), which
|
||||
// silently closed the whole flyout AND dropped keyboard input —
|
||||
// that's what let keystrokes fall through to whatever window was
|
||||
// focused before the flyout opened instead of reaching the text
|
||||
// field. OnDemand only claims focus when something inside is
|
||||
// actually clicked, and isn't torn down by unrelated surfaces.
|
||||
// Panels with no text input don't need it at all.
|
||||
WlrLayershell.keyboardFocus: root.needsGrab(root.activePanel)
|
||||
? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
||||
|
||||
RightFlyout {
|
||||
id: content
|
||||
anchors.fill: parent
|
||||
activePanel: root.activePanel
|
||||
onRequestClose: root.activePanel = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue