← luna

Commit 8623b3c

3
files
+54
added
-19
deleted
@@ -351,7 +351,7 @@ fn build_scene(
351 351 current_ws: usize,
352 352 ws_count: usize,
353 353 overview: bool,
354 - is_primary: bool,
354 + _is_primary: bool,
355 355 cursor: Option<Point>,
356 356 ) {
357 357 let sh = |r: Rect| r.offset(-ox, -oy);
@@ -431,9 +431,9 @@ fn build_scene(
431 431 }
432 432 }
433 433
434 - // Podgląd okien i przestrzeni (Super+Tab) — rysowany na głównym monitorze.
435 - if overview && is_primary {
436 - draw_overview(scene, size, model, current_ws, ws_count);
434 + // Podgląd okien i przestrzeni (Super+Tab) — na każdym monitorze (jego okna).
435 + if overview {
436 + draw_overview(scene, size, ox, oy, model, current_ws, ws_count);
437 437 }
438 438
439 439 // Kursor rysuje ten monitor, na którym leży (tryb DRM — nikt go za nas nie narysuje).
@@ -463,6 +463,8 @@ fn fill_vgradient(scene: &mut Scene, rect: Rect, top: Color, bottom: Color) {
463 463 fn draw_overview(
464 464 scene: &mut Scene,
465 465 size: Size,
466 + ox: f64,
467 + _oy: f64,
466 468 model: &WindowModel,
467 469 current_ws: usize,
468 470 ws_count: usize,
@@ -474,7 +476,7 @@ fn draw_overview(
474 476 );
475 477 let slots = {
476 478 let w = model.lock_or_recover();
477 - crate::state::overview_slots(&w, current_ws)
479 + crate::state::overview_slots_on(&w, current_ws, ox, size.width)
478 480 };
479 481 let tiles = crate::state::overview_tiles(slots.len(), (size.width, size.height));
480 482 let windows = model.lock_or_recover();
@@ -983,25 +983,25 @@ fn move_window_to_workspace(state: &mut State, slot: usize, ws: usize) {
983 983 crate::workspace::broadcast_workspace_states(state);
984 984 }
985 985
986 -/// Rozmiar głównego monitora — obszar układu podglądu.
987 -fn primary_size(state: &State) -> (f64, f64) {
988 - state
989 - .outputs
990 - .lock_or_recover()
991 - .first()
992 - .map(|o| (o.width as f64, o.height as f64))
993 - .unwrap_or((1280.0, 800.0))
994 -}
995 -
996 986 /// Klik w trybie podglądu: kafelek → fokus okna, chip → przestrzeń, poza → zamknij.
997 987 fn overview_click(state: &mut State, pos: Point) {
998 - let size = primary_size(state);
988 + // Znajdź monitor pod kursorem i lokalny układ podglądu na nim.
989 + let (ox, oy, size) = {
990 + let outs = state.outputs.lock_or_recover();
991 + let idx = crate::monitors::output_at(&outs, pos.x, pos.y);
992 + match outs.get(idx) {
993 + Some(o) => (o.x as f64, o.y as f64, (o.width as f64, o.height as f64)),
994 + None => (0.0, 0.0, (1280.0, 800.0)),
995 + }
996 + };
997 + let local = Point::new(pos.x - ox, pos.y - oy);
998 + let cur_ws = *state.ws_current.lock_or_recover();
999 999 let slots = {
1000 1000 let w = state.windows.lock_or_recover();
1001 - crate::state::overview_slots(&w, *state.ws_current.lock_or_recover())
1001 + crate::state::overview_slots_on(&w, cur_ws, ox, size.0)
1002 1002 };
1003 1003 let tiles = crate::state::overview_tiles(slots.len(), size);
1004 - if let Some(k) = tiles.iter().position(|r| r.contains(pos)) {
1004 + if let Some(k) = tiles.iter().position(|r| r.contains(local)) {
1005 1005 if let Some(&slot) = slots.get(k) {
1006 1006 state.set_overview(false);
1007 1007 raise_and_focus(state, slot);
@@ -1009,7 +1009,7 @@ fn overview_click(state: &mut State, pos: Point) {
1009 1009 }
1010 1010 }
1011 1011 let chips = crate::state::overview_ws_chips(state.ws_count, size);
1012 - if let Some(i) = chips.iter().position(|r| r.contains(pos)) {
1012 + if let Some(i) = chips.iter().position(|r| r.contains(local)) {
1013 1013 state.set_overview(false);
1014 1014 switch_workspace(state, i);
1015 1015 return;
@@ -187,6 +187,7 @@ pub const OVERVIEW_STRIP_H: f64 = 56.0;
187 187 pub const OVERVIEW_TITLE: f64 = 26.0;
188 188
189 189 /// Sloty okien bieżącej przestrzeni (bez paneli/popupów), w kolejności z-order.
190 +#[allow(dead_code)]
190 191 pub fn overview_slots(windows: &[Window], current_ws: usize) -> Vec<usize> {
191 192 let mut v: Vec<(usize, i32)> = windows
192 193 .iter()
@@ -200,6 +201,24 @@ pub fn overview_slots(windows: &[Window], current_ws: usize) -> Vec<usize> {
200 201 v.into_iter().map(|(i, _)| i).collect()
201 202 }
202 203
204 +/// Sloty okien bieżącej przestrzeni, których **środek** leży na wyjściu `[ox, ox+w)`.
205 +pub fn overview_slots_on(windows: &[Window], current_ws: usize, ox: f64, w: f64) -> Vec<usize> {
206 + let mut v: Vec<(usize, i32)> = windows
207 + .iter()
208 + .enumerate()
209 + .filter(|(_, win)| {
210 + win.mapped && !win.minimized && !win.popup && !win.layer && win.workspace == current_ws
211 + })
212 + .filter(|(_, win)| {
213 + let cx = win.x + win.width as f64 / 2.0;
214 + cx >= ox && cx < ox + w
215 + })
216 + .map(|(i, w)| (i, w.z))
217 + .collect();
218 + v.sort_by_key(|&(_, z)| z);
219 + v.into_iter().map(|(i, _)| i).collect()
220 +}
221 +
203 222 /// Prostokąty kafelków w siatce na obszarze `size` (zostawiając pas u dołu).
204 223 pub fn overview_tiles(count: usize, size: (f64, f64)) -> Vec<Rect> {
205 224 if count == 0 {
@@ -443,6 +462,20 @@ mod tests {
443 462 assert_eq!(overview_slots(&ws, 1), vec![1]);
444 463 }
445 464
465 + #[test]
466 + fn overview_slots_split_by_output() {
467 + let mut a = window_at_ws(0, 1);
468 + a.x = 100.0;
469 + a.width = 200; // środek 200 → monitor 0
470 + let mut b = window_at_ws(0, 2);
471 + b.x = 2000.0;
472 + b.width = 100; // środek 2050 → monitor 1
473 + let ws = vec![a, b];
474 + assert_eq!(overview_slots_on(&ws, 0, 0.0, 1920.0), vec![0]);
475 + assert_eq!(overview_slots_on(&ws, 0, 1920.0, 1280.0), vec![1]);
476 + assert!(overview_slots_on(&ws, 1, 0.0, 1920.0).is_empty());
477 + }
478 +
446 479 #[test]
447 480 fn overview_tiles_and_chips_layout() {
448 481 let size = (1920.0, 1080.0);