@@ -419,8 +419,23 @@ impl WmState { |
| 419 | } | 419 | } |
| 420 | } | 420 | } |
| 421 | | 421 | |
| 422 | - fn workspace_render_geometries(&self, ws_idx: usize, rect: Rect) -> Vec<(WindowId, Rect)> { | 422 | + /// Inflate the user-configured gaps by ers's border width so the |
| | 423 | + /// configured value is the *visible* empty space between tiles, not |
| | 424 | + /// the gross window-rect-to-window-rect distance. Ers draws border |
| | 425 | + /// overlays 4px (or whatever `border_width` is) outside each window's |
| | 426 | + /// frame; with a raw 8px tile gap, two adjacent windows' 4px borders |
| | 427 | + /// fill the entire gap and visually touch. Adding 2 * border_width |
| | 428 | + /// to inner gaps and 1 * border_width to outer gaps reserves space |
| | 429 | + /// for the borders so the configured gap survives as visible empty |
| | 430 | + /// space. |
| | 431 | + pub fn effective_gaps(&self, ws_idx: usize) -> (f64, f64) { |
| 423 | let (gap_inner, gap_outer) = self.workspace_gaps(ws_idx); | 432 | let (gap_inner, gap_outer) = self.workspace_gaps(ws_idx); |
| | 433 | + let bw = self.borders.border_width.max(0.0); |
| | 434 | + (gap_inner + 2.0 * bw, gap_outer + bw) |
| | 435 | + } |
| | 436 | + |
| | 437 | + fn workspace_render_geometries(&self, ws_idx: usize, rect: Rect) -> Vec<(WindowId, Rect)> { |
| | 438 | + let (gap_inner, gap_outer) = self.effective_gaps(ws_idx); |
| 424 | self.workspaces | 439 | self.workspaces |
| 425 | .get(ws_idx) | 440 | .get(ws_idx) |
| 426 | .tree | 441 | .tree |
@@ -428,7 +443,7 @@ impl WmState { |
| 428 | } | 443 | } |
| 429 | | 444 | |
| 430 | fn workspace_focus_geometries(&self, ws_idx: usize, rect: Rect) -> Vec<(WindowId, Rect)> { | 445 | fn workspace_focus_geometries(&self, ws_idx: usize, rect: Rect) -> Vec<(WindowId, Rect)> { |
| 431 | - let (gap_inner, gap_outer) = self.workspace_gaps(ws_idx); | 446 | + let (gap_inner, gap_outer) = self.effective_gaps(ws_idx); |
| 432 | self.workspaces | 447 | self.workspaces |
| 433 | .get(ws_idx) | 448 | .get(ws_idx) |
| 434 | .tree | 449 | .tree |
@@ -572,6 +587,27 @@ impl WmState { |
| 572 | let _ = crate::platform::skylight::set_window_group_system_alpha(wid, 1.0); | 587 | let _ = crate::platform::skylight::set_window_group_system_alpha(wid, 1.0); |
| 573 | let _ = crate::platform::skylight::set_window_group_alpha(wid, 1.0); | 588 | let _ = crate::platform::skylight::set_window_group_alpha(wid, 1.0); |
| 574 | | 589 | |
| | 590 | + if let (Ok((ax, ay)), Ok((aw, ah))) = (ax_get_position(ax_ref), ax_get_size(ax_ref)) { |
| | 591 | + let dx = (ax - rect.x).abs(); |
| | 592 | + let dy = (ay - rect.y).abs(); |
| | 593 | + let dw = (aw - rect.width).abs(); |
| | 594 | + let dh = (ah - rect.height).abs(); |
| | 595 | + if dx > 1.0 || dy > 1.0 || dw > 1.0 || dh > 1.0 { |
| | 596 | + tracing::debug!( |
| | 597 | + wid, |
| | 598 | + req_x = rect.x, |
| | 599 | + req_y = rect.y, |
| | 600 | + req_w = rect.width, |
| | 601 | + req_h = rect.height, |
| | 602 | + got_x = ax, |
| | 603 | + got_y = ay, |
| | 604 | + got_w = aw, |
| | 605 | + got_h = ah, |
| | 606 | + "show_window mismatch" |
| | 607 | + ); |
| | 608 | + } |
| | 609 | + } |
| | 610 | + |
| 575 | // Restore AXEnhancedUserInterface | 611 | // Restore AXEnhancedUserInterface |
| 576 | if was_eui == Some(true) | 612 | if was_eui == Some(true) |
| 577 | && let Some(app) = &app_ref | 613 | && let Some(app) = &app_ref |
@@ -1654,7 +1690,7 @@ impl WmState { |
| 1654 | let window_under = if let Some(special_idx) = special_ws_idx { | 1690 | let window_under = if let Some(special_idx) = special_ws_idx { |
| 1655 | let sr = self.monitor_rect(mi); | 1691 | let sr = self.monitor_rect(mi); |
| 1656 | let ws = self.workspaces.get(special_idx); | 1692 | let ws = self.workspaces.get(special_idx); |
| 1657 | - let (gap_inner, gap_outer) = self.workspace_gaps(special_idx); | 1693 | + let (gap_inner, gap_outer) = self.effective_gaps(special_idx); |
| 1658 | | 1694 | |
| 1659 | // Look up config for this special workspace's overlay rect | 1695 | // Look up config for this special workspace's overlay rect |
| 1660 | let special_name = match &ws.id { | 1696 | let special_name = match &ws.id { |
@@ -2241,7 +2277,7 @@ impl WmState { |
| 2241 | let overlay_rect = Rect::new(overlay_x, overlay_y, overlay_w, overlay_h); | 2277 | let overlay_rect = Rect::new(overlay_x, overlay_y, overlay_w, overlay_h); |
| 2242 | | 2278 | |
| 2243 | // Compute geometries and collect data before calling self methods | 2279 | // Compute geometries and collect data before calling self methods |
| 2244 | - let (gap_inner, gap_outer) = self.workspace_gaps(special_idx); | 2280 | + let (gap_inner, gap_outer) = self.effective_gaps(special_idx); |
| 2245 | let geoms = | 2281 | let geoms = |
| 2246 | ws.tree | 2282 | ws.tree |
| 2247 | .calculate_geometries_with_gaps(overlay_rect, gap_inner, gap_outer, true); | 2283 | .calculate_geometries_with_gaps(overlay_rect, gap_inner, gap_outer, true); |
@@ -2441,7 +2477,7 @@ impl WmState { |
| 2441 | | 2477 | |
| 2442 | // Get target monitor's screen rect for layout | 2478 | // Get target monitor's screen rect for layout |
| 2443 | let target_rect = self.monitor_rect(target_mi); | 2479 | let target_rect = self.monitor_rect(target_mi); |
| 2444 | - let (target_gap_inner, target_gap_outer) = self.workspace_gaps(target_ws_idx); | 2480 | + let (target_gap_inner, target_gap_outer) = self.effective_gaps(target_ws_idx); |
| 2445 | | 2481 | |
| 2446 | // Find which workspace the window is actually on | 2482 | // Find which workspace the window is actually on |
| 2447 | let current_idx = match self.workspaces.find_window(focused) { | 2483 | let current_idx = match self.workspaces.find_window(focused) { |