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);