nosignal-shell/services/NsShell.qml
28allday e42538896f fix(nosignal): hardware-test round 4 — Wi-Fi join, multi-monitor popouts, sudo focus
From the 2026-06-20 Acer muxless-Optimus hardware test:

- F-wifi (NsNetwork.qml): the Wi-Fi panel was display-only — no onClicked,
  no password field — so a secured network could not be joined from the GUI.
  Wire the existing Network service: click to connect; open/saved networks
  connect directly; secured-without-profile expands an inline password field
  (StyledTextField, echoMode Password). Also strip a stray NUL byte that the
  on-box edit left at the `?? " "` sentinel. HW-verified on the test laptop.
- F-multimon (NsShell.qml + NsBar.qml + NsOverlay.qml): bar popouts mirrored
  on every monitor. Add a `screen` identity to NsShell; pills pass their
  output name; each NsOverlay only renders when it owns the open panel ("" =
  unscoped, for the global power modal). HW-verified dual-monitor.
- F-sudo (SudoToggleRow.qml): the passwordless-sudo prompt used the shared
  TUI.float class with no focus rule, so keystrokes missed it and three blank
  tries tripped pam_faillock with no feedback. Use a dedicated `nosignal-sudo`
  class (builder ships float/center/pin/stayfocused rules) and call the new
  `nosignal-sudo-toggle enable-tui` wrapper, which keeps the terminal open on
  failure so the reason is visible.

Add .gitattributes (*.qml/*.conf/*.json text) for clean diffs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 18:49:18 +01:00

43 lines
1.3 KiB
QML

pragma Singleton
pragma ComponentBehavior: Bound
// NoSignal shell-level popup state. "One panel open at a time" — `open` is the
// id of the active panel ("" = none). `anchorX` is the scene x of the trigger
// (a bar pill) center, used to position under-trigger / right-anchored popups.
// `screen` is the name of the output that owns the open panel, so a per-screen
// NsOverlay shows it on ONLY that monitor instead of mirroring on all of them
// (multi-monitor fix, 2026-06-20). "" = no owner → show on all screens (used by
// the full-screen power modal opened from a global keybind, which has no screen).
// The NsBar pills call toggle() with their screen; NsOverlay matches on `screen`.
import QtQuick
import Quickshell
Singleton {
id: root
property string open: ""
property real anchorX: 0
property string screen: ""
function toggle(id: string, x: real, screen: string): void {
const scr = screen ?? "";
if (root.open === id && root.screen === scr) {
root.open = "";
} else {
root.open = id;
root.anchorX = x;
root.screen = scr;
}
}
function show(id: string, x: real, screen: string): void {
root.open = id;
root.anchorX = x;
root.screen = screen ?? "";
}
function close(): void {
root.open = "";
}
}