Per-skärm-inställningar med skärmväljare, kant-i-kant-marginaler
All checks were successful
check / check (push) Successful in 1m39s
All checks were successful
check / check (push) Successful in 1m39s
- outputs{} är nu generiska JSON-överridar: vilket configfält som helst
kan sättas per skärm och deep-mergas över den globala configen
(Config::for_output). Docka, autohide, dodge, beteende, hotspots och
CSS (scopat på window.o-<connector>) läser skärmens effektiva config.
- Settings har skärmväljare överst: klickbar förhandsgranskning av
skärmarna + deras barer, 'Alla skärmar' (standard) eller enskild
skärm. Bara ändrade fält sparas som override (json-diff);
återställ-knapp tar bort skärmens överridar. * = har egna.
- Marginaler: skuggutrymmet läggs inte längre på förankrade sidor så
0 = kant i kant; minusvärden tillåts (A ner till -64, B/C -256).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -109,10 +109,25 @@ thread_local! {
|
||||
/// Bygg om alla hotspot-ytor enligt configen (körs vid start + configbyte).
|
||||
/// Idempotent: oförändrad hotspot-config + skärmuppsättning → ingen ombyggnad.
|
||||
pub fn rebuild(ctx: &Rc<Ctx>) {
|
||||
let n_monitors = gdk::Display::default()
|
||||
.map(|d| d.monitors().n_items())
|
||||
.unwrap_or(0);
|
||||
let signature = format!("{:?}|{n_monitors}", ctx.cfg.borrow().hotspots);
|
||||
let display = gdk::Display::default().expect("ingen display");
|
||||
let monitors = display.monitors();
|
||||
|
||||
// signatur = alla skärmars EFFEKTIVA hotspot-config
|
||||
let mut signature = String::new();
|
||||
let mut mons: Vec<(String, gdk::Monitor)> = Vec::new();
|
||||
for i in 0..monitors.n_items() {
|
||||
let Some(monitor) = monitors.item(i).and_then(|o| o.downcast::<gdk::Monitor>().ok())
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
let connector = monitor
|
||||
.connector()
|
||||
.map(|c| c.to_string())
|
||||
.unwrap_or_else(|| format!("monitor-{i}"));
|
||||
let eff = ctx.cfg.borrow().for_output(&connector);
|
||||
signature += &format!("{connector}:{:?}|", eff.hotspots);
|
||||
mons.push((connector, monitor));
|
||||
}
|
||||
let unchanged = LAST_SIGNATURE.with(|s| *s.borrow() == signature);
|
||||
if unchanged {
|
||||
return;
|
||||
@@ -123,41 +138,33 @@ pub fn rebuild(ctx: &Rc<Ctx>) {
|
||||
win.destroy();
|
||||
}
|
||||
|
||||
let cfg = ctx.cfg.borrow();
|
||||
let dwell = cfg.hotspots.dwell_ms;
|
||||
let c = cfg.hotspots.corners.clone();
|
||||
let e = cfg.hotspots.edges.clone();
|
||||
drop(cfg);
|
||||
|
||||
let corner_defs: [(&Option<HotspotAction>, [Edge; 2]); 4] = [
|
||||
(&c.top_left, [Edge::Top, Edge::Left]),
|
||||
(&c.top_right, [Edge::Top, Edge::Right]),
|
||||
(&c.bottom_left, [Edge::Bottom, Edge::Left]),
|
||||
(&c.bottom_right, [Edge::Bottom, Edge::Right]),
|
||||
];
|
||||
// kanterna lämnar hörnen fria (hörn-ytor ligger ovanpå ändå — overlay
|
||||
// med senare mappade ytor hamnar överst, så det kvittar i praktiken)
|
||||
#[allow(clippy::type_complexity)]
|
||||
let edge_defs: [(&Option<HotspotAction>, [Edge; 3], (i32, i32)); 4] = [
|
||||
(&e.top, [Edge::Top, Edge::Left, Edge::Right], (-1, EDGE_PX)),
|
||||
(&e.bottom, [Edge::Bottom, Edge::Left, Edge::Right], (-1, EDGE_PX)),
|
||||
(&e.left, [Edge::Left, Edge::Top, Edge::Bottom], (EDGE_PX, -1)),
|
||||
(&e.right, [Edge::Right, Edge::Top, Edge::Bottom], (EDGE_PX, -1)),
|
||||
];
|
||||
|
||||
let display = gdk::Display::default().expect("ingen display");
|
||||
let monitors = display.monitors();
|
||||
let mut windows = Vec::new();
|
||||
for i in 0..monitors.n_items() {
|
||||
let Some(monitor) = monitors.item(i).and_then(|o| o.downcast::<gdk::Monitor>().ok())
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
for (connector, monitor) in &mons {
|
||||
let h = ctx.cfg.borrow().for_output(connector).hotspots;
|
||||
let dwell = h.dwell_ms;
|
||||
let c = h.corners.clone();
|
||||
let e = h.edges.clone();
|
||||
|
||||
let corner_defs: [(&Option<HotspotAction>, [Edge; 2]); 4] = [
|
||||
(&c.top_left, [Edge::Top, Edge::Left]),
|
||||
(&c.top_right, [Edge::Top, Edge::Right]),
|
||||
(&c.bottom_left, [Edge::Bottom, Edge::Left]),
|
||||
(&c.bottom_right, [Edge::Bottom, Edge::Right]),
|
||||
];
|
||||
// kanterna lämnar hörnen fria (hörn-ytor ligger ovanpå ändå)
|
||||
#[allow(clippy::type_complexity)]
|
||||
let edge_defs: [(&Option<HotspotAction>, [Edge; 3], (i32, i32)); 4] = [
|
||||
(&e.top, [Edge::Top, Edge::Left, Edge::Right], (-1, EDGE_PX)),
|
||||
(&e.bottom, [Edge::Bottom, Edge::Left, Edge::Right], (-1, EDGE_PX)),
|
||||
(&e.left, [Edge::Left, Edge::Top, Edge::Bottom], (EDGE_PX, -1)),
|
||||
(&e.right, [Edge::Right, Edge::Top, Edge::Bottom], (EDGE_PX, -1)),
|
||||
];
|
||||
|
||||
for (action, edges) in &corner_defs {
|
||||
if let Some(a) = action {
|
||||
windows.push(build_hotspot(
|
||||
ctx,
|
||||
&monitor,
|
||||
monitor,
|
||||
edges,
|
||||
(CORNER_PX, CORNER_PX),
|
||||
a.clone(),
|
||||
@@ -167,7 +174,7 @@ pub fn rebuild(ctx: &Rc<Ctx>) {
|
||||
}
|
||||
for (action, edges, size) in &edge_defs {
|
||||
if let Some(a) = action {
|
||||
windows.push(build_hotspot(ctx, &monitor, edges, *size, a.clone(), dwell));
|
||||
windows.push(build_hotspot(ctx, monitor, edges, *size, a.clone(), dwell));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user