Control centre: popups via iwctl/bluetoothctl, one-shape menus, search rings, Ethernet and link speeds, auto-hiding bar

- prompt.rs: popup for Wi-Fi passwords, Bluetooth PINs/passkeys/codes, saved
  passwords (Copy through wl-copy on stdin) and failure reasons; joins through
  iwctl, pairs through a bluetoothctl session; only popups with a field take
  the keyboard (an exclusive grab let stray keystrokes close failure popups)
- menus: the panel is the only shape; the menu window fades its content in
  once the panel has taken the menu's size
- maps: clicking the bubble searches again (iwctl scan, bluetoothctl scan)
  with rings running out from the click
- Ethernet tile and pill icon from sysfs; link speed badges (Ethernet speed,
  Wi-Fi RxBitrate from iwd diagnostics, at most once a minute)
- edge.rs: bar hidden until the pointer rests on the top edge; nothing is
  read or drawn while hidden
- IPC: control wifi join|password|search, bluetooth pair|connect|search,
  prompt answer|cancel, status prompt=
This commit is contained in:
server2
2026-10-13 02:59:22 +02:00
parent afe963dfea
commit b14df3a435
11 changed files with 1550 additions and 174 deletions
+7 -1
View File
@@ -8,6 +8,7 @@ use amane::{
Rectangle, Row, Service, Shadow, Start, Text, Vertical, Weight, Widget, Workspace, Workspaces, Zone,
};
use crate::edge::{self, Edge, HIDE_H};
use crate::island::{CHIP_HOVER, CLEAR, COMPACT_H, HOVER_MS, SHADOW, TOP_GAP, backdrop, faded};
use crate::theme;
@@ -42,6 +43,9 @@ pub fn view(monitor: &Monitor) -> LayerWindow {
let workspaces = Workspaces::read();
let hover = Hover::read();
// hidden until the pointer rests on the top edge (edge.rs)
let slide = edge::hidden_by(Edge::read().shown(&monitor.name), 0.0, HIDE_H);
// special workspaces (scratchpads) aren't places to switch to
let here: Vec<&Workspace> = workspaces
.list()
@@ -64,7 +68,7 @@ pub fn view(monitor: &Monitor) -> LayerWindow {
.namespace("magic-workspaces");
// empty and click-through rather than hidden: see the island's view for why
if here.is_empty() {
if here.is_empty() || slide <= -HIDE_H {
return window.click_through().child(Rectangle::new().width(0.0).height(0.0));
}
@@ -118,6 +122,7 @@ pub fn view(monitor: &Monitor) -> LayerWindow {
.shadow(Shadow::drop(theme.accent).opacity(0.3).blur(22.0))
.padding(INSET)
.align_child(Start, Center)
.on_hover(edge::over_bar)
.child(Row::new(slots).gap(SLOT_GAP).align(Center));
// clicks next to the pill reach the windows underneath
@@ -134,6 +139,7 @@ pub fn view(monitor: &Monitor) -> LayerWindow {
.height(Parent)
.padding(Padding { top: TOP_GAP, right: 0.0, bottom: 0.0, left: LEFT })
.align_child(Start, Start)
.translate(0.0, slide)
.child(pill),
)
}