island: follow the pointer across monitors (experiment)

- one island window per monitor (window_per_monitor), shown only on the
  monitor of the focused workspace; hyprland focuses the monitor under
  the mouse (input:follow_mouse = 1), so the island follows the pointer
- hidden windows return before reading any other service, so music and
  animations only wake the shown one: still 60 frames a second in total
- the Workspaces service re-reads j/workspaces and j/monitors on every
  hyprland event
- without a workspace list (other compositors) every monitor shows it
This commit is contained in:
server2
2026-10-06 16:41:25 +02:00
parent fc90260d5d
commit dd597c8c70
2 changed files with 25 additions and 11 deletions
+24 -10
View File
@@ -5,9 +5,9 @@ use std::time::{Duration, Instant};
use amane::{
Animation, Arc, Argument, Blend, Bus, Canvas, Cap, Center, Color, Column, Easing, End, Full, Gradient,
Image, InputArea, Layer, LayerWindow, Line, Media, MediaPlayer, Padding, Palette, Parent, Path,
Image, InputArea, Layer, LayerWindow, Line, Media, MediaPlayer, Monitor, Padding, Palette, Parent, Path,
Pointer, Rectangle, Row, Scroll, ScrollArea, Service, Shadow, Shape, SpaceBetween, Stack,
Start, Text, Vertical, Weight, Widget, Zone, children, shapes,
Start, Text, Vertical, Weight, Widget, Workspaces, Zone, children, shapes,
};
use crate::art::Art;
@@ -226,14 +226,7 @@ struct Scene<'a> {
levels: &'a [f32],
}
pub fn view() -> LayerWindow {
let media = Media::read();
let island = Island::read();
let sound = Sound::read();
let art = Art::read();
let palette = Palette::read();
let spectrum = Spectrum::read();
pub fn view(monitor: &Monitor) -> LayerWindow {
let window_w = WIDE_W + 2.0 * SHADOW;
let window = LayerWindow::new()
@@ -245,6 +238,27 @@ pub fn view() -> LayerWindow {
.space(Zone::Ignore)
.namespace("magic-island");
/*
* one island window per monitor, shown only on the focused one: hyprland focuses
* the monitor under the mouse (input:follow_mouse), so the island follows the
* pointer. the hidden ones return before reading anything else, so music and
* animations only wake the shown one. no workspace list (another compositor):
* every monitor shows it
*/
let workspaces = Workspaces::read();
let focused = workspaces.list().iter().find(|workspace| workspace.focused()).and_then(|workspace| workspace.output());
if focused.is_some_and(|name| name != monitor.name) {
return window.visible(false);
}
let media = Media::read();
let island = Island::read();
let sound = Sound::read();
let art = Art::read();
let palette = Palette::read();
let spectrum = Spectrum::read();
let Some(player) = shown(&media, island.selected.as_deref()) else {
return window.visible(false);
};
+1 -1
View File
@@ -10,5 +10,5 @@ fn main() {
// the card's glow follows the cover art, which art::Art copies to this one path
Palette::write().open(&art::palette_file(), 8);
App::new().font("Fira Code").ipc("island", island::command).window(island::view).run();
App::new().font("Fira Code").ipc("island", island::command).window_per_monitor(island::view).run();
}