server: make state's client and connection mandatory

The goal of the previous commits being to remove these unwraps. The `unwrap_or_skip_bad_window` changes needed to make a singular debug conditional
This commit is contained in:
En-En 2025-08-03 12:30:55 +00:00 committed by Supreeeme
parent 4280639df8
commit be9d573fd6
5 changed files with 90 additions and 112 deletions

View file

@ -16,7 +16,7 @@ use xcb::x;
pub trait XConnection: Sized + 'static { pub trait XConnection: Sized + 'static {
type X11Selection: X11Selection; type X11Selection: X11Selection;
fn set_window_dims(&mut self, window: x::Window, dims: PendingSurfaceState); fn set_window_dims(&mut self, window: x::Window, dims: PendingSurfaceState) -> bool;
fn set_fullscreen(&mut self, window: x::Window, fullscreen: bool); fn set_fullscreen(&mut self, window: x::Window, fullscreen: bool);
fn focus_window(&mut self, window: x::Window, output_name: Option<String>); fn focus_window(&mut self, window: x::Window, output_name: Option<String>);
fn close_window(&mut self, window: x::Window); fn close_window(&mut self, window: x::Window);
@ -134,8 +134,7 @@ pub fn main(mut data: impl RunData) -> Option<()> {
} }
}; };
let mut server_state = EarlyServerState::new(dh, data.server()); let mut server_state = EarlyServerState::new(dh, data.server(), connection);
server_state.connect(connection);
server_state.run(); server_state.run();
// Remove the lifetimes on our fds to avoid borrowing issues, since we know they will exist for // Remove the lifetimes on our fds to avoid borrowing issues, since we know they will exist for
@ -177,8 +176,7 @@ pub fn main(mut data: impl RunData) -> Option<()> {
display.flush_clients().unwrap(); display.flush_clients().unwrap();
} }
let mut xstate: Option<XState> = None; let mut xstate = XState::new(xsock_wl.as_fd());
let xstate = xstate.insert(XState::new(xsock_wl.as_fd()));
let mut reader = BufReader::new(&ready_rx); let mut reader = BufReader::new(&ready_rx);
{ {
let mut display = String::new(); let mut display = String::new();

View file

@ -157,9 +157,8 @@ impl SurfaceEvents {
); );
if state.last_focused_toplevel == Some(*window) { if state.last_focused_toplevel == Some(*window) {
let output = get_output_name(Some(&on_output), &state.world); let output = get_output_name(Some(&on_output), &state.world);
let conn = connection.as_mut().unwrap();
debug!("focused window changed outputs - resetting primary output"); debug!("focused window changed outputs - resetting primary output");
conn.focus_window(*window, output); connection.focus_window(*window, output);
} }
if state.fractional_scale.is_none() { if state.fractional_scale.is_none() {
@ -205,7 +204,7 @@ impl SurfaceEvents {
target: Entity, target: Entity,
state: &mut ServerState<C>, state: &mut ServerState<C>,
) { ) {
let connection = state.connection.as_mut().unwrap(); let connection = &mut state.connection;
let state = &mut state.inner; let state = &mut state.inner;
let xdg_surface::Event::Configure { serial } = event else { let xdg_surface::Event::Configure { serial } = event else {
unreachable!(); unreachable!();
@ -308,7 +307,7 @@ impl SurfaceEvents {
toplevel.fullscreen = toplevel.fullscreen =
states.contains(&(u32::from(xdg_toplevel::State::Fullscreen) as u8)); states.contains(&(u32::from(xdg_toplevel::State::Fullscreen) as u8));
if toplevel.fullscreen != prev_fs { if toplevel.fullscreen != prev_fs {
state.connection.as_mut().unwrap().set_fullscreen( state.connection.set_fullscreen(
*data.get::<&x::Window>().unwrap(), *data.get::<&x::Window>().unwrap(),
toplevel.fullscreen, toplevel.fullscreen,
); );
@ -364,8 +363,6 @@ impl SurfaceEvents {
xdg_popup::Event::PopupDone => { xdg_popup::Event::PopupDone => {
state state
.connection .connection
.as_mut()
.unwrap()
.unmap_window(*data.get::<&x::Window>().unwrap()); .unmap_window(*data.get::<&x::Window>().unwrap());
} }
other => todo!("{other:?}"), other => todo!("{other:?}"),
@ -482,7 +479,7 @@ impl Event for client::wl_pointer::Event {
let mut do_enter = || { let mut do_enter = || {
debug!("pointer entering {} ({serial} {})", surface.id(), scale.0); debug!("pointer entering {} ({serial} {})", surface.id(), scale.0);
server.enter(serial, surface, surface_x * scale.0, surface_y * scale.0); server.enter(serial, surface, surface_x * scale.0, surface_y * scale.0);
state.connection.as_mut().unwrap().raise_to_top(*window); state.connection.raise_to_top(*window);
if !surface_is_popup { if !surface_is_popup {
state.inner.last_hovered = Some(*window); state.inner.last_hovered = Some(*window);
} }
@ -916,7 +913,7 @@ fn update_window_output_offsets(
output: Entity, output: Entity,
global_output_offset: &GlobalOutputOffset, global_output_offset: &GlobalOutputOffset,
world: &World, world: &World,
connection: &mut Option<impl XConnection>, connection: &mut impl XConnection,
) { ) {
let dimensions = world.get::<&OutputDimensions>(output).unwrap(); let dimensions = world.get::<&OutputDimensions>(output).unwrap();
let mut query = world.query::<(&x::Window, &mut WindowData, &OnOutput)>(); let mut query = world.query::<(&x::Window, &mut WindowData, &OnOutput)>();
@ -940,7 +937,7 @@ pub(super) fn update_global_output_offset(
output: Entity, output: Entity,
global_output_offset: &GlobalOutputOffset, global_output_offset: &GlobalOutputOffset,
world: &World, world: &World,
connection: &mut Option<impl XConnection>, connection: &mut impl XConnection,
) { ) {
let entity = world.entity(output).unwrap(); let entity = world.entity(output).unwrap();
let mut query = entity.query::<(&OutputDimensions, &WlOutput)>(); let mut query = entity.query::<(&OutputDimensions, &WlOutput)>();
@ -1459,8 +1456,6 @@ where
let entity = state.world.reserve_entity(); let entity = state.world.reserve_entity();
let server = state let server = state
.client .client
.as_ref()
.unwrap()
.create_resource::<_, _, InnerServerState<S>>(&state.dh, 1, entity) .create_resource::<_, _, InnerServerState<S>>(&state.dh, 1, entity)
.unwrap(); .unwrap();
let obj_key: &LateInitObjectKey<Client> = client.data().unwrap(); let obj_key: &LateInitObjectKey<Client> = client.data().unwrap();

View file

@ -138,7 +138,7 @@ impl WindowData {
&mut self, &mut self,
window: x::Window, window: x::Window,
offset: WindowOutputOffset, offset: WindowOutputOffset,
connection: &mut Option<C>, connection: &mut C,
) { ) {
log::trace!("offset: {offset:?}"); log::trace!("offset: {offset:?}");
if offset == self.output_offset { if offset == self.output_offset {
@ -150,19 +150,17 @@ impl WindowData {
dims.y += (offset.y - self.output_offset.y) as i16; dims.y += (offset.y - self.output_offset.y) as i16;
self.output_offset = offset; self.output_offset = offset;
if let Some(connection) = connection.as_mut() { if connection.set_window_dims(
connection.set_window_dims( window,
window, PendingSurfaceState {
PendingSurfaceState { x: dims.x as i32,
x: dims.x as i32, y: dims.y as i32,
y: dims.y as i32, width: self.attrs.dims.width as _,
width: self.attrs.dims.width as _, height: self.attrs.dims.height as _,
height: self.attrs.dims.height as _, },
}, ) {
); debug!("set {:?} offset to {:?}", window, self.output_offset);
} }
debug!("set {:?} offset to {:?}", window, self.output_offset);
} }
} }
@ -415,14 +413,15 @@ impl<S: X11Selection> XConnection for EarlyConnection<S> {
fn set_fullscreen(&mut self, _: x::Window, _: bool) { fn set_fullscreen(&mut self, _: x::Window, _: bool) {
debug!("could not toggle fullscreen without XWayland initialized"); debug!("could not toggle fullscreen without XWayland initialized");
} }
fn set_window_dims(&mut self, _: x::Window, _: crate::server::PendingSurfaceState) { fn set_window_dims(&mut self, _: x::Window, _: crate::server::PendingSurfaceState) -> bool {
debug!("could not set window dimensions without XWayland initialized"); debug!("could not set window dimensions without XWayland initialized");
false
} }
} }
pub struct ServerState<C: XConnection> { pub struct ServerState<C: XConnection> {
inner: InnerServerState<C::X11Selection>, inner: InnerServerState<C::X11Selection>,
pub connection: Option<C>, pub connection: C,
} }
pub struct InnerServerState<S: X11Selection> { pub struct InnerServerState<S: X11Selection> {
@ -433,7 +432,7 @@ pub struct InnerServerState<S: X11Selection> {
world: MyWorld, world: MyWorld,
queue: EventQueue<MyWorld>, queue: EventQueue<MyWorld>,
qh: QueueHandle<MyWorld>, qh: QueueHandle<MyWorld>,
client: Option<Client>, client: Client,
to_focus: Option<FocusData>, to_focus: Option<FocusData>,
unfocus: bool, unfocus: bool,
last_focused_toplevel: Option<x::Window>, last_focused_toplevel: Option<x::Window>,
@ -453,7 +452,11 @@ pub struct InnerServerState<S: X11Selection> {
} }
impl<S: X11Selection> ServerState<EarlyConnection<S>> { impl<S: X11Selection> ServerState<EarlyConnection<S>> {
pub fn new(dh: DisplayHandle, server_connection: Option<UnixStream>) -> Self { pub fn new(
mut dh: DisplayHandle,
server_connection: Option<UnixStream>,
client: UnixStream,
) -> Self {
let connection = if let Some(stream) = server_connection { let connection = if let Some(stream) = server_connection {
Connection::from_socket(stream).unwrap() Connection::from_socket(stream).unwrap()
} else { } else {
@ -508,10 +511,12 @@ impl<S: X11Selection> ServerState<EarlyConnection<S>> {
.contents() .contents()
.with_list(|globals| handle_globals::<S>(&dh, globals)); .with_list(|globals| handle_globals::<S>(&dh, globals));
let client = dh.insert_client(client, std::sync::Arc::new(())).unwrap();
let inner = InnerServerState { let inner = InnerServerState {
windows: HashMap::new(), windows: HashMap::new(),
pids: HashSet::new(), pids: HashSet::new(),
client: None, client,
queue, queue,
qh, qh,
dh, dh,
@ -543,9 +548,9 @@ impl<S: X11Selection> ServerState<EarlyConnection<S>> {
}; };
Self { Self {
inner, inner,
connection: Some(EarlyConnection { connection: EarlyConnection {
_p: std::marker::PhantomData, _p: std::marker::PhantomData,
}), },
} }
} }
@ -555,7 +560,7 @@ impl<S: X11Selection> ServerState<EarlyConnection<S>> {
{ {
ServerState { ServerState {
inner: self.inner, inner: self.inner,
connection: Some(connection), connection,
} }
} }
} }
@ -569,18 +574,10 @@ impl<C: XConnection> ServerState<C> {
self.inner.clientside_fd() self.inner.clientside_fd()
} }
pub fn connect(&mut self, connection: UnixStream) {
self.inner.connect(connection)
}
fn handle_new_globals(&mut self) { fn handle_new_globals(&mut self) {
self.inner.handle_new_globals() self.inner.handle_new_globals()
} }
pub fn set_x_connection(&mut self, connection: C) {
self.connection = Some(connection);
}
pub fn new_window( pub fn new_window(
&mut self, &mut self,
window: x::Window, window: x::Window,
@ -761,13 +758,11 @@ impl<C: XConnection> ServerState<C> {
output_name, output_name,
}) = self.inner.to_focus.take() }) = self.inner.to_focus.take()
{ {
let conn = self.connection.as_mut().unwrap();
debug!("focusing window {window:?}"); debug!("focusing window {window:?}");
conn.focus_window(window, output_name); self.connection.focus_window(window, output_name);
self.inner.last_focused_toplevel = Some(window); self.inner.last_focused_toplevel = Some(window);
} else if self.inner.unfocus { } else if self.inner.unfocus {
let conn = self.connection.as_mut().unwrap(); self.connection.focus_window(x::WINDOW_NONE, None);
conn.focus_window(x::WINDOW_NONE, None);
} }
self.inner.unfocus = false; self.inner.unfocus = false;
} }
@ -806,7 +801,7 @@ impl<C: XConnection> ServerState<C> {
fn close_x_window(&mut self, window: x::Window) { fn close_x_window(&mut self, window: x::Window) {
debug!("sending close request to {window:?}"); debug!("sending close request to {window:?}");
self.connection.as_mut().unwrap().close_window(window); self.connection.close_window(window);
if self.inner.last_focused_toplevel == Some(window) { if self.inner.last_focused_toplevel == Some(window) {
self.inner.last_focused_toplevel.take(); self.inner.last_focused_toplevel.take();
} }
@ -821,14 +816,6 @@ impl<S: X11Selection + 'static> InnerServerState<S> {
self.queue.as_fd() self.queue.as_fd()
} }
fn connect(&mut self, connection: UnixStream) {
self.client = Some(
self.dh
.insert_client(connection, std::sync::Arc::new(()))
.unwrap(),
);
}
fn handle_new_globals(&mut self) { fn handle_new_globals(&mut self) {
let globals = std::mem::take(&mut self.world.new_globals); let globals = std::mem::take(&mut self.world.new_globals);
handle_globals::<S>(&self.dh, globals.iter()); handle_globals::<S>(&self.dh, globals.iter());

View file

@ -209,13 +209,14 @@ impl super::XConnection for FakeXConnection {
} }
#[track_caller] #[track_caller]
fn set_window_dims(&mut self, window: Window, state: super::PendingSurfaceState) { fn set_window_dims(&mut self, window: Window, state: super::PendingSurfaceState) -> bool {
self.window_mut(window).dims = WindowDims { self.window_mut(window).dims = WindowDims {
x: state.x as _, x: state.x as _,
y: state.y as _, y: state.y as _,
width: state.width as _, width: state.width as _,
height: state.height as _, height: state.height as _,
}; };
true
} }
#[track_caller] #[track_caller]
@ -367,9 +368,8 @@ impl EarlyTestFixture {
}); });
let (fake_client, xwls_server) = UnixStream::pair().unwrap(); let (fake_client, xwls_server) = UnixStream::pair().unwrap();
let mut satellite = EarlyServerState::new(display.handle(), Some(client_s)); let satellite = EarlyServerState::new(display.handle(), Some(client_s), xwls_server);
let testwl = thread.join().unwrap(); let testwl = thread.join().unwrap();
satellite.connect(xwls_server);
let xwls_connection = Connection::from_socket(fake_client).unwrap(); let xwls_connection = Connection::from_socket(fake_client).unwrap();
let registry = TestObject::<WlRegistry>::from_request( let registry = TestObject::<WlRegistry>::from_request(
@ -549,7 +549,7 @@ impl TestFixture<FakeXConnection> {
} }
fn connection(&self) -> &FakeXConnection { fn connection(&self) -> &FakeXConnection {
self.satellite.connection.as_ref().unwrap() &self.satellite.connection
} }
fn object_data<P>(&self, obj: &P) -> Arc<TestObjectData<P>> fn object_data<P>(&self, obj: &P) -> Arc<TestObjectData<P>>
@ -612,12 +612,7 @@ impl TestFixture<FakeXConnection> {
} }
fn register_window(&mut self, window: Window, data: WindowData) { fn register_window(&mut self, window: Window, data: WindowData) {
self.satellite self.satellite.connection.windows.insert(window, data);
.connection
.as_mut()
.unwrap()
.windows
.insert(window, data);
} }
fn new_window(&mut self, window: Window, override_redirect: bool, data: WindowData) { fn new_window(&mut self, window: Window, override_redirect: bool, data: WindowData) {
@ -940,7 +935,7 @@ fn toplevel_flow() {
f.testwl.close_toplevel(testwl_id); f.testwl.close_toplevel(testwl_id);
f.run(); f.run();
assert!(!f.satellite.connection.as_ref().unwrap().windows[&window].mapped); assert!(!f.satellite.connection.windows[&window].mapped);
assert!( assert!(
f.testwl.get_surface_data(testwl_id).is_some(), f.testwl.get_surface_data(testwl_id).is_some(),

View file

@ -44,19 +44,24 @@ impl From<xcb::ProtocolError> for MaybeBadWindow {
type XResult<T> = Result<T, MaybeBadWindow>; type XResult<T> = Result<T, MaybeBadWindow>;
macro_rules! unwrap_or_skip_bad_window { macro_rules! unwrap_or_skip_bad_window {
($err:expr) => { ($err:expr, $skip:expr) => {
match $err { match $err {
Ok(v) => v, Ok(v) => v,
Err(e) => { Err(e) => {
let err = MaybeBadWindow::from(e); let err = MaybeBadWindow::from(e);
match err { match err {
MaybeBadWindow::BadWindow => return, MaybeBadWindow::BadWindow => $skip,
MaybeBadWindow::Other(other) => panic!("X11 protocol error: {other:?}"), MaybeBadWindow::Other(other) => panic!("X11 protocol error: {other:?}"),
} }
} }
} }
}; };
} }
macro_rules! unwrap_or_skip_bad_window_ret {
($err:expr) => {
unwrap_or_skip_bad_window!($err, return)
};
}
/// Essentially a trait alias. /// Essentially a trait alias.
trait PropertyResolver { trait PropertyResolver {
@ -310,16 +315,7 @@ impl XState {
pub fn handle_events(&mut self, server_state: &mut super::RealServerState) { pub fn handle_events(&mut self, server_state: &mut super::RealServerState) {
macro_rules! unwrap_or_skip_bad_window_cont { macro_rules! unwrap_or_skip_bad_window_cont {
($err:expr) => { ($err:expr) => {
match $err { unwrap_or_skip_bad_window!($err, continue)
Ok(v) => v,
Err(e) => {
let err = MaybeBadWindow::from(e);
match err {
MaybeBadWindow::BadWindow => continue,
MaybeBadWindow::Other(other) => panic!("X11 protocol error: {other:?}"),
}
}
}
}; };
} }
@ -412,8 +408,6 @@ impl XState {
// The connection on the server state stores state. // The connection on the server state stores state.
server_state server_state
.connection .connection
.as_mut()
.unwrap()
.focus_window(x::Window::none(), None); .focus_window(x::Window::none(), None);
} }
@ -506,11 +500,7 @@ impl XState {
xcb::Event::RandR(xcb::randr::Event::Notify(e)) xcb::Event::RandR(xcb::randr::Event::Notify(e))
if matches!(e.u(), xcb::randr::NotifyData::Rc(_)) => if matches!(e.u(), xcb::randr::NotifyData::Rc(_)) =>
{ {
server_state server_state.connection.update_outputs(self.root);
.connection
.as_mut()
.unwrap()
.update_outputs(self.root);
} }
other => { other => {
warn!("unhandled event: {other:?}"); warn!("unhandled event: {other:?}");
@ -850,31 +840,34 @@ impl XState {
match event.atom() { match event.atom() {
x if x == x::ATOM_WM_HINTS => { x if x == x::ATOM_WM_HINTS => {
let hints = let hints =
unwrap_or_skip_bad_window!(self.get_wm_hints(window).resolve()).unwrap(); unwrap_or_skip_bad_window_ret!(self.get_wm_hints(window).resolve()).unwrap();
server_state.set_win_hints(window, hints); server_state.set_win_hints(window, hints);
} }
x if x == x::ATOM_WM_NORMAL_HINTS => { x if x == x::ATOM_WM_NORMAL_HINTS => {
let hints = let hints =
unwrap_or_skip_bad_window!(self.get_wm_size_hints(window).resolve()).unwrap(); unwrap_or_skip_bad_window_ret!(self.get_wm_size_hints(window).resolve())
.unwrap();
server_state.set_size_hints(window, hints); server_state.set_size_hints(window, hints);
} }
x if x == x::ATOM_WM_NAME => { x if x == x::ATOM_WM_NAME => {
let name = unwrap_or_skip_bad_window!(self.get_wm_name(window).resolve()).unwrap(); let name =
unwrap_or_skip_bad_window_ret!(self.get_wm_name(window).resolve()).unwrap();
server_state.set_win_title(window, name); server_state.set_win_title(window, name);
} }
x if x == self.atoms.net_wm_name => { x if x == self.atoms.net_wm_name => {
let name = let name =
unwrap_or_skip_bad_window!(self.get_net_wm_name(window).resolve()).unwrap(); unwrap_or_skip_bad_window_ret!(self.get_net_wm_name(window).resolve()).unwrap();
server_state.set_win_title(window, name); server_state.set_win_title(window, name);
} }
x if x == x::ATOM_WM_CLASS => { x if x == x::ATOM_WM_CLASS => {
let class = let class =
unwrap_or_skip_bad_window!(self.get_wm_class(window).resolve()).unwrap(); unwrap_or_skip_bad_window_ret!(self.get_wm_class(window).resolve()).unwrap();
server_state.set_win_class(window, class); server_state.set_win_class(window, class);
} }
x if x == self.atoms.motif_wm_hints => { x if x == self.atoms.motif_wm_hints => {
let motif_hints = let motif_hints =
unwrap_or_skip_bad_window!(self.get_motif_wm_hints(window).resolve()).unwrap(); unwrap_or_skip_bad_window_ret!(self.get_motif_wm_hints(window).resolve())
.unwrap();
if let Some(decorations) = motif_hints.decorations { if let Some(decorations) = motif_hints.decorations {
server_state.set_win_decorations(window, decorations); server_state.set_win_decorations(window, decorations);
} }
@ -1197,17 +1190,25 @@ impl RealConnection {
impl XConnection for RealConnection { impl XConnection for RealConnection {
type X11Selection = Selection; type X11Selection = Selection;
fn set_window_dims(&mut self, window: x::Window, dims: crate::server::PendingSurfaceState) { fn set_window_dims(
&mut self,
window: x::Window,
dims: crate::server::PendingSurfaceState,
) -> bool {
trace!("set window dimensions {window:?} {dims:?}"); trace!("set window dimensions {window:?} {dims:?}");
unwrap_or_skip_bad_window!(self.connection.send_and_check_request(&x::ConfigureWindow { unwrap_or_skip_bad_window!(
window, self.connection.send_and_check_request(&x::ConfigureWindow {
value_list: &[ window,
x::ConfigWindow::X(dims.x), value_list: &[
x::ConfigWindow::Y(dims.y), x::ConfigWindow::X(dims.x),
x::ConfigWindow::Width(dims.width as _), x::ConfigWindow::Y(dims.y),
x::ConfigWindow::Height(dims.height as _), x::ConfigWindow::Width(dims.width as _),
] x::ConfigWindow::Height(dims.height as _),
})); ]
}),
return false
);
true
} }
fn set_fullscreen(&mut self, window: x::Window, fullscreen: bool) { fn set_fullscreen(&mut self, window: x::Window, fullscreen: bool) {
@ -1299,7 +1300,7 @@ impl XConnection for RealConnection {
long_offset: 0, long_offset: 0,
long_length: 10, long_length: 10,
}); });
let reply = unwrap_or_skip_bad_window!(self.connection.wait_for_reply(cookie)); let reply = unwrap_or_skip_bad_window_ret!(self.connection.wait_for_reply(cookie));
if reply if reply
.value::<x::Atom>() .value::<x::Atom>()
@ -1312,30 +1313,32 @@ impl XConnection for RealConnection {
x::ClientMessageData::Data32(data), x::ClientMessageData::Data32(data),
); );
unwrap_or_skip_bad_window!(self.connection.send_and_check_request(&x::SendEvent { unwrap_or_skip_bad_window_ret!(self.connection.send_and_check_request(&x::SendEvent {
destination: x::SendEventDest::Window(window), destination: x::SendEventDest::Window(window),
propagate: false, propagate: false,
event_mask: x::EventMask::empty(), event_mask: x::EventMask::empty(),
event, event,
})); }));
} else { } else {
unwrap_or_skip_bad_window!(self.connection.send_and_check_request(&x::KillClient { unwrap_or_skip_bad_window_ret!(self.connection.send_and_check_request(&x::KillClient {
resource: window.resource_id() resource: window.resource_id()
})) }))
} }
} }
fn unmap_window(&mut self, window: x::Window) { fn unmap_window(&mut self, window: x::Window) {
unwrap_or_skip_bad_window!(self unwrap_or_skip_bad_window_ret!(self
.connection .connection
.send_and_check_request(&x::UnmapWindow { window })); .send_and_check_request(&x::UnmapWindow { window }));
} }
fn raise_to_top(&mut self, window: x::Window) { fn raise_to_top(&mut self, window: x::Window) {
unwrap_or_skip_bad_window!(self.connection.send_and_check_request(&x::ConfigureWindow { unwrap_or_skip_bad_window_ret!(self.connection.send_and_check_request(
window, &x::ConfigureWindow {
value_list: &[x::ConfigWindow::StackMode(x::StackMode::Above)], window,
})); value_list: &[x::ConfigWindow::StackMode(x::StackMode::Above)],
}
));
} }
} }