Skip to content

Commit 4b3c068

Browse files
committed
fix: handle proper placement of unattached floating windows.
This has been a minor disturbance for a while for GTK floating windows, they kept popping up on the wrong monitor (furthest left). Regardless of which monitor was focused when the popup spawned. This turned out to be caused by a double-bug. On first render, dimensions on the float weren't rewritten to absolute from 'assumed monitor relative'. I.E. a window spawned on mon 1 with x=0 is assumed to be x=0 on mon 1, and should therefore be transposed to absolute x = [mon 1].x + 0. The second was that relative placements were allowed to be negative, going out of bounds of the monitor it was supposed to be placed on, which could place it on the wrong monitor.
1 parent 39444cc commit 4b3c068

2 files changed

Lines changed: 30 additions & 25 deletions

File tree

pgwm-app/src/manager/draw.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ impl<'a> Drawer<'a> {
3535
dimensions: Dimensions,
3636
state: &mut State,
3737
) -> Result<()> {
38-
pgwm_utils::debug!("Drawing floating {window} at {dimensions:?}");
3938
call_wrapper.configure_window(window, dimensions, state.window_border_width, state)?;
4039
call_wrapper.send_map(window, state)?;
4140
Ok(())
@@ -86,16 +85,26 @@ impl<'a> Drawer<'a> {
8685
for (win, arrange) in floating {
8786
if let ArrangeKind::FloatingInactive(rel_x, rel_y) = arrange {
8887
let dimensions = state.monitors[mon_ind].dimensions;
89-
let x = (dimensions.x as f32 + dimensions.width as f32 * rel_x) as i32;
90-
let y = (dimensions.y as f32
91-
+ STATUS_BAR_HEIGHT as f32
92-
+ dimensions.height as f32 * rel_y) as i32;
88+
let (x, y) = Self::absolute_floating_x_y(dimensions, rel_x, rel_y);
9389
Self::move_floating(call_wrapper, win, x, y, state)?;
9490
}
9591
}
9692
Ok(())
9793
}
9894

95+
pub(crate) fn absolute_floating_x_y(
96+
monitor_dimensions: Dimensions,
97+
float_rel_x: f32,
98+
float_rel_y: f32,
99+
) -> (i32, i32) {
100+
let x =
101+
(monitor_dimensions.x as f32 + monitor_dimensions.width as f32 * float_rel_x) as i32;
102+
let y = (monitor_dimensions.y as f32
103+
+ STATUS_BAR_HEIGHT as f32
104+
+ monitor_dimensions.height as f32 * float_rel_y) as i32;
105+
(x, y)
106+
}
107+
99108
fn draw(
100109
&self,
101110
call_wrapper: &mut CallWrapper,

pgwm-app/src/manager/mod.rs

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,6 @@ impl<'a> Manager<'a> {
449449
call_wrapper.set_base_client_properties(win)?;
450450
let dimensions_cookie = call_wrapper.get_dimensions(win)?;
451451
let properties = window_properties_cookie.await_properties(call_wrapper)?;
452-
pgwm_utils::debug!("Managing window {:?}", win);
453452
let ws_ind = if let Some(ws_ind) =
454453
Self::map_window_class_to_workspace(call_wrapper, win, &state.workspaces)?
455454
{
@@ -586,9 +585,7 @@ impl<'a> Manager<'a> {
586585
dimensions: Dimensions,
587586
state: &mut State,
588587
) -> Result<()> {
589-
pgwm_utils::debug!("Managing floating {win} attached to {attached_to:?}");
590588
let attached_to = if attached_to == Some(state.screen.root) {
591-
pgwm_utils::debug!("Parent was root, assigning floating to currently focused monitor");
592589
let mon_ind = state.focused_mon;
593590
let new_parent = if let Some(last_focus) = state.monitors[mon_ind].last_focus {
594591
last_focus
@@ -598,7 +595,6 @@ impl<'a> Manager<'a> {
598595
{
599596
first_tiled
600597
} else {
601-
pgwm_utils::debug!("Promoting window");
602598
let ws_ind = state.monitors[mon_ind].hosted_workspace;
603599
self.manage_tiled(
604600
call_wrapper,
@@ -611,21 +607,14 @@ impl<'a> Manager<'a> {
611607
)?;
612608
return Ok(());
613609
};
614-
pgwm_utils::debug!("Assigned to new parent {new_parent}");
615610
Some(new_parent)
616611
} else {
617612
attached_to
618613
};
619614
let focus_style = Self::deduce_focus_style(&properties);
620-
if let Some(attached_to) = attached_to {
615+
let placement_dimensions = if let Some(attached_to) = attached_to {
621616
let parent_dimensions = call_wrapper.get_dimensions(attached_to)?;
622-
pgwm_utils::debug!("Found attached {} to parent {}", win, attached_to);
623617
let parent_dimensions = parent_dimensions.await_dimensions(call_wrapper)?;
624-
pgwm_utils::debug!(
625-
"Attached geometry {:?}\nParent geometry {:?}",
626-
dimensions,
627-
parent_dimensions
628-
);
629618
let dimensions = if (dimensions.x < parent_dimensions.x
630619
|| dimensions.x + (dimensions.width) < parent_dimensions.x)
631620
|| (dimensions.y > parent_dimensions.y
@@ -637,7 +626,6 @@ impl<'a> Manager<'a> {
637626
(parent_dimensions.height - dimensions.height) as f32 / 2f32;
638627
let x = parent_dimensions.x as i32 + parent_relative_x_offset as i32;
639628
let y = parent_dimensions.y as i32 + parent_relative_y_offset as i32;
640-
pgwm_utils::debug!("Remapping attached to ({x}, {y})");
641629
call_wrapper.move_window(win, x, y, state)?;
642630

643631
Dimensions::new(dimensions.width, dimensions.height, x as i16, y as i16)
@@ -656,6 +644,7 @@ impl<'a> Manager<'a> {
656644
focus_style,
657645
&properties,
658646
)?;
647+
dimensions
659648
} else {
660649
let (rel_x, rel_y) = calculate_relative_placement(
661650
state.monitors[mon_ind].dimensions,
@@ -669,12 +658,19 @@ impl<'a> Manager<'a> {
669658
focus_style,
670659
&properties,
671660
)?;
672-
}
661+
let (abs_x, abs_y) =
662+
Drawer::absolute_floating_x_y(state.monitors[mon_ind].dimensions, rel_x, rel_y);
663+
Dimensions::new(
664+
dimensions.width,
665+
dimensions.height,
666+
abs_x as i16,
667+
abs_y as i16,
668+
)
669+
};
673670
call_wrapper.push_to_client_list(state.screen.root, win)?;
674671

675-
Drawer::draw_floating(call_wrapper, win, dimensions, state)?;
672+
Drawer::draw_floating(call_wrapper, win, placement_dimensions, state)?;
676673
self.focus_window(call_wrapper, state.focused_mon, win, state)?;
677-
crate::debug!("Drew window");
678674
Ok(())
679675
}
680676

@@ -1396,7 +1392,6 @@ impl<'a> Manager<'a> {
13961392
state: &mut State,
13971393
) -> Result<()> {
13981394
if let Some(focus_candidate) = state.find_first_focus_candidate(mon_ind)? {
1399-
pgwm_utils::debug!("Found focus candidate {focus_candidate:?}");
14001395
self.focus_window(call_wrapper, mon_ind, focus_candidate, state)
14011396
} else {
14021397
self.focus_root_on_mon(call_wrapper, mon_ind, state)
@@ -1475,7 +1470,6 @@ impl<'a> Manager<'a> {
14751470
self.make_window_not_urgent(call_wrapper, win, state)?;
14761471
Self::highlight_border(call_wrapper, win, state)?; // Highlighting the base window even if a top level transient is focused
14771472
if let Some(old_focused_mon) = state.update_focused_mon(mon_ind) {
1478-
pgwm_utils::debug!("Switched focus from {} to {}", old_focused_mon, mon_ind);
14791473
self.bar_manager.set_workspace_selected_not_focused(
14801474
call_wrapper,
14811475
old_focused_mon,
@@ -2207,8 +2201,10 @@ fn calculate_relative_placement(
22072201
placement_x: i16,
22082202
placement_y: i16,
22092203
) -> (f32, f32) {
2210-
let rel_x = (placement_x - container_dimensions.x) as f32 / container_dimensions.width as f32;
2211-
let rel_y = (placement_y - container_dimensions.y) as f32 / container_dimensions.height as f32;
2204+
let rel_x =
2205+
(placement_x - container_dimensions.x).max(0) as f32 / container_dimensions.width as f32;
2206+
let rel_y =
2207+
(placement_y - container_dimensions.y).max(0) as f32 / container_dimensions.height as f32;
22122208
(rel_x, rel_y)
22132209
}
22142210

0 commit comments

Comments
 (0)