Peeks start where the part is: no dip when the bar hides

Switching from a workspace with the bar shown to a fullscreen one slid
the bar away while the workspace peek slid in from hidden, so the pill
dipped and came back. A peek now starts from the part's current
position, so a shown pill stays still for the peek and then leaves.
The tray, which peeks don't show, slides away on its own.

Tested on DP-2 (2 -> 3 and back), frame by frame.
This commit is contained in:
server2
2026-10-15 01:14:55 +02:00
parent 200aff97ae
commit dfe3867529
3 changed files with 16 additions and 8 deletions
+1 -1
View File
@@ -30,7 +30,7 @@ Handoff for agents continuing work on the Magic Island shell (Hermes, Claude Cod
- **Control centre** (top right): a status pill (Wi-Fi or hotspot, VPN, Bluetooth, Ethernet, battery; icons of stopped services hidden) that opens a panel: tiles for Wi-Fi, Bluetooth, VPN, Hotspot, Ethernet; volume with the output, brightness, keyboard light, performance mode, external-GPU programs. The panel morphs into its menus as one shape: Wi-Fi and Bluetooth maps (devices floating round this computer, click to join/pair, right-click a saved network for its password, click the centre to search again), VPN list, sound outputs, Ethernet details with copyable addresses. The maps reach from the right edge to the island's pill, less 16 px. Popups (`magic-prompt`) ask for passwords, PINs and passkeys and say why something failed.
- **System tray** right of the workspace pill.
- **Bar hiding:** only on monitors showing a fullscreen window; the pointer resting on the top edge brings it back. Events bring one part in for a moment (a peek): the workspace pill alone on a workspace change, the island on a song change or a new player.
- **Bar hiding:** only on monitors showing a fullscreen window; the pointer resting on the top edge brings it back. Events bring one part in for a moment (a peek): the workspace pill alone on a workspace change, the island on a song change or a new player. A peek starts from where the part is, so switching from a shown bar to a fullscreen workspace keeps the workspace pill still (no dip) while the tray leaves on its own.
- **Reserved space:** windows that aren't fullscreen stay below the bar (44 px at the top of every monitor).
On 2026-10-13 the user was asked to try the mouse-only parts (tray clicks, top-edge hover reveal, Copy buttons, PIN pairing) and answered "All works"; the agent itself only drove them over IPC.
+8 -1
View File
@@ -238,7 +238,14 @@ fn peek(edge: &mut Edge, part: Part, monitor: &str) {
let key = (part, monitor.to_string());
let began = Instant::now();
let entry = edge.peeks.entry(key.clone()).or_insert_with(|| (sliding(0.0), began));
// from wherever the part is now: one already showing (the bar on its way out after a switch to a fullscreen workspace) stays put instead of dipping
let now = edge.part(part, monitor);
let entry = edge.peeks.entry(key.clone()).or_insert_with(|| (sliding(now), began));
if entry.0.value() < now {
entry.0 = sliding(now);
}
entry.0.to(1.0);
entry.1 = began;
+7 -6
View File
@@ -46,11 +46,12 @@ pub fn view(monitor: &Monitor) -> LayerWindow {
let workspaces = Workspaces::read();
let hover = Hover::read();
// hidden on a fullscreen monitor until wanted, or for a moment on a workspace change (edge.rs)
let (slide, switched, peeking) = {
// hidden on a fullscreen monitor until wanted, or for a moment on a workspace change (edge.rs); the tray only goes with the whole bar
let (slide, tray_slide, switched, peeking) = {
let edge = Edge::read();
let shown = edge.shown(&monitor.name);
(edge::hidden_by(edge.part(Part::Workspaces, &monitor.name), 0.0, HIDE_H), edge.switched(&monitor.name), edge.shown(&monitor.name) == 0.0)
(edge::hidden_by(edge.part(Part::Workspaces, &monitor.name), 0.0, HIDE_H), edge::hidden_by(shown, 0.0, HIDE_H), edge.switched(&monitor.name), shown == 0.0)
};
// special workspaces (scratchpads) aren't places to switch to
@@ -180,11 +181,12 @@ pub fn view(monitor: &Monitor) -> LayerWindow {
// clicks next to the pills reach the windows underneath
let mut regions = vec![InputArea { x: LEFT as i32, y: TOP_GAP as i32, width: width.ceil() as i32, height: COMPACT_H as i32 }];
let mut pills: Vec<Box<dyn Widget>> = vec![Box::new(pill)];
let mut pills: Vec<Box<dyn Widget>> = vec![Box::new(pill.translate(0.0, slide))];
// a peek keeps the workspaces in while the bar leaves: the tray slides away on its own
if let Some((tray, tray_pill_w)) = tray {
regions.push(InputArea { x: (LEFT + width + TRAY_GAP) as i32, y: TOP_GAP as i32, width: tray_pill_w.ceil() as i32, height: COMPACT_H as i32 });
pills.push(Box::new(tray));
pills.push(Box::new(tray.translate(0.0, tray_slide)));
}
window.input_region(regions).child(
@@ -193,7 +195,6 @@ 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(Row::new(pills).gap(TRAY_GAP).align(Start)),
)
}