1
0
Fork 0
forked from wry/wry

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.
This commit is contained in:
Julian Orth 2022-05-07 00:11:08 +02:00
parent 5e21e00059
commit cc090b1d0f
2 changed files with 50 additions and 36 deletions

View file

@ -198,17 +198,19 @@ pub enum Change {
impl Xwindow { impl Xwindow {
pub fn new(data: &Rc<XwindowData>, surface: &Rc<WlSurface>) -> Self { pub fn new(data: &Rc<XwindowData>, surface: &Rc<WlSurface>) -> 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 { Self {
id: data.state.node_ids.next(), id: data.state.node_ids.next(),
seat_state: Default::default(), seat_state: Default::default(),
data: data.clone(), data: data.clone(),
surface: surface.clone(), surface: surface.clone(),
display_link: Default::default(), display_link: Default::default(),
toplevel_data: ToplevelData::new( toplevel_data: tld,
&data.state,
data.info.title.borrow_mut().clone().unwrap_or_default(),
Some(surface.client.clone()),
),
} }
} }

View file

@ -1063,7 +1063,8 @@ impl Wm {
self.set_net_active_window(window).await; self.set_net_active_window(window).await;
self.focus_window(window).await; self.focus_window(window).await;
if let Some(w) = window { 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> { async fn handle_map_notify(&mut self, event: &Event) -> Result<(), XWaylandError> {
let event: MapNotify = event.parse()?; let event: MapNotify = event.parse()?;
let data = match self.windows.get(&event.window) { let data = match self.windows.get(&event.window) {
Some(d) => d, Some(d) => d.clone(),
_ => return Ok(()), _ => return Ok(()),
}; };
self.update_override_redirect(data, event.override_redirect); self.update_override_redirect(&data, event.override_redirect);
data.info.mapped.set(true); data.info.mapped.set(true);
if let Some(win) = data.window.get() { if let Some(win) = data.window.get() {
win.map_status_changed(); win.map_status_changed();
} }
self.configure_stack_position(&data).await;
Ok(()) Ok(())
} }
@ -1290,7 +1292,24 @@ impl Wm {
self.num_mapped += 1; self.num_mapped += 1;
} }
self.set_net_client_list().await; 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 { let mw = MapWindow {
window: event.window, window: event.window,
}; };
@ -1300,44 +1319,37 @@ impl Wm {
Ok(()) Ok(())
} }
async fn stack_window( fn move_to_top_of_stack(
&mut self, &mut self,
window: &Rc<XwindowData>, window: &Rc<XwindowData>,
sibling: Option<&Rc<XwindowData>>,
above: bool,
) { ) {
let link = 'link: { let link = self.stack_list.add_last(window.clone());
if let Some(s) = sibling { *window.stack_link.borrow_mut() = Some(link);
if s.window_id == window.window_id { }
log::warn!("trying to stack window above itself");
} else { async fn configure_stack_position(
let sl = s.stack_link.borrow_mut(); &mut self,
if let Some(sl) = sl.deref() { window: &Rc<XwindowData>,
break 'link if above { ) {
sl.append(window.clone()) let sl = window.stack_link.borrow_mut();
} else { let sl = match sl.deref() {
sl.prepend(window.clone()) Some(sl) => sl,
}; _ => return,
} };
} let (sibling, stack_mode) = match sl.prev() {
} Some(n) => (Some(n), STACK_MODE_ABOVE),
if above { _ => match sl.next() {
self.stack_list.add_last(window.clone()) Some(n) => (Some(n), STACK_MODE_BELOW),
} else { _ => (None, STACK_MODE_ABOVE),
self.stack_list.add_first(window.clone())
} }
}; };
*window.stack_link.borrow_mut() = Some(link);
let res = self let res = self
.c .c
.call(&ConfigureWindow { .call(&ConfigureWindow {
window: window.window_id, window: window.window_id,
values: ConfigureWindowValues { values: ConfigureWindowValues {
sibling: sibling.map(|s| s.window_id), sibling: sibling.map(|s| s.window_id),
stack_mode: Some(match above { stack_mode: Some(stack_mode),
true => STACK_MODE_ABOVE,
false => STACK_MODE_BELOW,
}),
..Default::default() ..Default::default()
}, },
}) })