From cc090b1d0ffab5102e6741caa7c80121332c3468 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Sat, 7 May 2022 00:11:08 +0200 Subject: [PATCH] xwayland: fix mapping of windows whose size is already correct at map time IntelliJ in particular opens new windows with the exact same size as the existing window. In a mono layout, this is the resulting window size. For some reason, IntelliJ will not draw itself properly if it doesn't get resized after mapping. So send a dummy 1x1 configure at map time. --- src/ifs/wl_surface/xwindow.rs | 12 +++--- src/xwayland/xwm.rs | 74 ++++++++++++++++++++--------------- 2 files changed, 50 insertions(+), 36 deletions(-) diff --git a/src/ifs/wl_surface/xwindow.rs b/src/ifs/wl_surface/xwindow.rs index 5562a7d9..3be3d619 100644 --- a/src/ifs/wl_surface/xwindow.rs +++ b/src/ifs/wl_surface/xwindow.rs @@ -198,17 +198,19 @@ pub enum Change { impl Xwindow { pub fn new(data: &Rc, surface: &Rc) -> Self { + let tld = ToplevelData::new( + &data.state, + data.info.title.borrow_mut().clone().unwrap_or_default(), + Some(surface.client.clone()), + ); + tld.pos.set(surface.extents.get()); Self { id: data.state.node_ids.next(), seat_state: Default::default(), data: data.clone(), surface: surface.clone(), display_link: Default::default(), - toplevel_data: ToplevelData::new( - &data.state, - data.info.title.borrow_mut().clone().unwrap_or_default(), - Some(surface.client.clone()), - ), + toplevel_data: tld, } } diff --git a/src/xwayland/xwm.rs b/src/xwayland/xwm.rs index 090d4f89..636ace91 100644 --- a/src/xwayland/xwm.rs +++ b/src/xwayland/xwm.rs @@ -1063,7 +1063,8 @@ impl Wm { self.set_net_active_window(window).await; self.focus_window(window).await; if let Some(w) = window { - self.stack_window(w, None, true).await; + self.move_to_top_of_stack(w); + self.configure_stack_position(w).await; } } @@ -1263,14 +1264,15 @@ impl Wm { async fn handle_map_notify(&mut self, event: &Event) -> Result<(), XWaylandError> { let event: MapNotify = event.parse()?; let data = match self.windows.get(&event.window) { - Some(d) => d, + Some(d) => d.clone(), _ => return Ok(()), }; - self.update_override_redirect(data, event.override_redirect); + self.update_override_redirect(&data, event.override_redirect); data.info.mapped.set(true); if let Some(win) = data.window.get() { win.map_status_changed(); } + self.configure_stack_position(&data).await; Ok(()) } @@ -1290,7 +1292,24 @@ impl Wm { self.num_mapped += 1; } self.set_net_client_list().await; - self.stack_window(&data, None, true).await; + let pending = data.info.pending_extents.get(); + if pending.width() > 0 && pending.height() > 0 { + let dummy = Rect::new_sized(0, 0, 1, 1).unwrap(); + for rect in [dummy, pending] { + let cw = ConfigureWindow { + window: data.window_id, + values: ConfigureWindowValues { + x: Some(rect.x1()), + y: Some(rect.y1()), + width: Some(rect.width() as _), + height: Some(rect.height() as _), + ..Default::default() + }, + }; + let _ = self.c.call(&cw).await; + } + } + self.move_to_top_of_stack(&data); let mw = MapWindow { window: event.window, }; @@ -1300,44 +1319,37 @@ impl Wm { Ok(()) } - async fn stack_window( + fn move_to_top_of_stack( &mut self, window: &Rc, - sibling: Option<&Rc>, - above: bool, ) { - let link = 'link: { - if let Some(s) = sibling { - if s.window_id == window.window_id { - log::warn!("trying to stack window above itself"); - } else { - let sl = s.stack_link.borrow_mut(); - if let Some(sl) = sl.deref() { - break 'link if above { - sl.append(window.clone()) - } else { - sl.prepend(window.clone()) - }; - } - } - } - if above { - self.stack_list.add_last(window.clone()) - } else { - self.stack_list.add_first(window.clone()) + let link = self.stack_list.add_last(window.clone()); + *window.stack_link.borrow_mut() = Some(link); + } + + async fn configure_stack_position( + &mut self, + window: &Rc, + ) { + let sl = window.stack_link.borrow_mut(); + let sl = match sl.deref() { + Some(sl) => sl, + _ => return, + }; + let (sibling, stack_mode) = match sl.prev() { + Some(n) => (Some(n), STACK_MODE_ABOVE), + _ => match sl.next() { + Some(n) => (Some(n), STACK_MODE_BELOW), + _ => (None, STACK_MODE_ABOVE), } }; - *window.stack_link.borrow_mut() = Some(link); let res = self .c .call(&ConfigureWindow { window: window.window_id, values: ConfigureWindowValues { sibling: sibling.map(|s| s.window_id), - stack_mode: Some(match above { - true => STACK_MODE_ABOVE, - false => STACK_MODE_BELOW, - }), + stack_mode: Some(stack_mode), ..Default::default() }, })