diff --git a/src/xstate/mod.rs b/src/xstate/mod.rs index 2e0b78a..37c39e5 100644 --- a/src/xstate/mod.rs +++ b/src/xstate/mod.rs @@ -485,85 +485,7 @@ impl XState { )); } xcb::Event::X(x::Event::ClientMessage(e)) => { - match e.r#type() { - x if x == self.atoms.wl_surface_id => { - panic!(concat!( - "Xserver should be using WL_SURFACE_SERIAL, not WL_SURFACE_ID\n", - "Your Xwayland is likely too old, it should be version 23.1 or greater." - )); - } - x if x == self.atoms.wl_surface_serial => { - let x::ClientMessageData::Data32(data) = e.data() else { - unreachable!(); - }; - server_state.set_window_serial(e.window(), [data[0], data[1]]); - } - x if x == self.atoms.net_wm_state => { - let x::ClientMessageData::Data32(data) = e.data() else { - unreachable!(); - }; - let Ok(action) = SetState::try_from(data[0]) else { - warn!("unknown action for _NET_WM_STATE: {}", data[0]); - continue; - }; - let prop1 = unsafe { x::Atom::new(data[1]) }; - let prop2 = unsafe { x::Atom::new(data[2]) }; - - trace!("_NET_WM_STATE ({action:?}) props: {prop1:?} {prop2:?}"); - - for prop in [prop1, prop2] { - match prop { - x if x == self.atoms.wm_fullscreen => { - server_state.set_fullscreen(e.window(), action); - } - _ => {} - } - } - } - x if x == self.atoms.active_win => { - server_state.activate_window(e.window()); - } - x if x == self.atoms.moveresize => { - let x::ClientMessageData::Data32(data) = e.data() else { - unreachable!(); - }; - - let (_x_root, _y_root) = (data[0], data[1]); - let Ok(direction) = MoveResizeDirection::try_from(data[2]) else { - warn!("unknown direction for _NET_WM_MOVERESIZE: {}", data[2]); - continue; - }; - let button = data[3]; - // XXX: This can technically be driven by keyboard events and other mouse buttons as well, - // but I haven't found an application that does this yet. We'll cross that bridge when we get to it. - if button != 1 { - warn!("Attempted move/resize of {:?} with non left click button ({button})", e.window()); - continue; - } - - match direction { - MoveResizeDirection::Move => { - server_state.move_window(e.window()); - } - MoveResizeDirection::SizeTopLeft - | MoveResizeDirection::SizeTop - | MoveResizeDirection::SizeTopRight - | MoveResizeDirection::SizeRight - | MoveResizeDirection::SizeBottomRight - | MoveResizeDirection::SizeBottom - | MoveResizeDirection::SizeBottomLeft - | MoveResizeDirection::SizeLeft => { - server_state.resize_window(e.window(), direction); - } - MoveResizeDirection::SizeKeyboard - | MoveResizeDirection::MoveKeyboard - | MoveResizeDirection::Cancel => { - warn!("Unimplemented window move/resize action: {direction:?} ({:?})", e.window()); - } - } - } - t => warn!("unrecognized message: {t:?}"), - } + self.handle_client_message(e, server_state); } xcb::Event::X(x::Event::MappingNotify(_)) => {} xcb::Event::RandR(xcb::randr::Event::Notify(e)) @@ -580,6 +502,98 @@ impl XState { } } + fn handle_client_message( + &self, + e: x::ClientMessageEvent, + server_state: &mut super::RealServerState, + ) { + match e.r#type() { + x if x == self.atoms.wl_surface_id => { + panic!(concat!( + "Xserver should be using WL_SURFACE_SERIAL, not WL_SURFACE_ID\n", + "Your Xwayland is likely too old, it should be version 23.1 or greater." + )); + } + x if x == self.atoms.wl_surface_serial => { + let x::ClientMessageData::Data32(data) = e.data() else { + unreachable!(); + }; + server_state.set_window_serial(e.window(), [data[0], data[1]]); + } + x if x == self.atoms.net_wm_state => { + let x::ClientMessageData::Data32(data) = e.data() else { + unreachable!(); + }; + let Ok(action) = SetState::try_from(data[0]) else { + warn!("unknown action for _NET_WM_STATE: {}", data[0]); + return; + }; + let prop1 = unsafe { x::Atom::new(data[1]) }; + let prop2 = unsafe { x::Atom::new(data[2]) }; + + trace!("_NET_WM_STATE ({action:?}) props: {prop1:?} {prop2:?}"); + + for prop in [prop1, prop2] { + match prop { + x if x == self.atoms.wm_fullscreen => { + server_state.set_fullscreen(e.window(), action); + } + _ => {} + } + } + } + x if x == self.atoms.active_win => { + server_state.activate_window(e.window()); + } + x if x == self.atoms.moveresize => { + let x::ClientMessageData::Data32(data) = e.data() else { + unreachable!(); + }; + + let (_x_root, _y_root) = (data[0], data[1]); + let Ok(direction) = MoveResizeDirection::try_from(data[2]) else { + warn!("unknown direction for _NET_WM_MOVERESIZE: {}", data[2]); + return; + }; + let button = data[3]; + // XXX: This can technically be driven by keyboard events and other mouse buttons as well, + // but I haven't found an application that does this yet. We'll cross that bridge when we get to it. + if button != 1 { + warn!( + "Attempted move/resize of {:?} with non left click button ({button})", + e.window() + ); + return; + } + + match direction { + MoveResizeDirection::Move => { + server_state.move_window(e.window()); + } + MoveResizeDirection::SizeTopLeft + | MoveResizeDirection::SizeTop + | MoveResizeDirection::SizeTopRight + | MoveResizeDirection::SizeRight + | MoveResizeDirection::SizeBottomRight + | MoveResizeDirection::SizeBottom + | MoveResizeDirection::SizeBottomLeft + | MoveResizeDirection::SizeLeft => { + server_state.resize_window(e.window(), direction); + } + MoveResizeDirection::SizeKeyboard + | MoveResizeDirection::MoveKeyboard + | MoveResizeDirection::Cancel => { + warn!( + "Unimplemented window move/resize action: {direction:?} ({:?})", + e.window() + ); + } + } + } + t => warn!("unrecognized message: {t:?}"), + } + } + fn handle_window_properties( &self, server_state: &mut super::RealServerState,