Add unwrap warning, deal with some unwraps

This commit is contained in:
Seaotatop 2023-06-29 17:41:08 -05:00
parent d6504b0b82
commit 2b50e7d31a
11 changed files with 210 additions and 140 deletions

View file

@ -54,14 +54,17 @@ use self::msg::{Msg, OutgoingMsg};
const SOCKET_PATH: &str = "/tmp/pinnacle_socket"; const SOCKET_PATH: &str = "/tmp/pinnacle_socket";
fn handle_client(mut stream: UnixStream, sender: Sender<Msg>) { fn handle_client(
mut stream: UnixStream,
sender: Sender<Msg>,
) -> Result<(), Box<dyn std::error::Error>> {
loop { loop {
let mut len_marker_bytes = [0u8; 4]; let mut len_marker_bytes = [0u8; 4];
if let Err(err) = stream.read_exact(&mut len_marker_bytes) { if let Err(err) = stream.read_exact(&mut len_marker_bytes) {
if err.kind() == io::ErrorKind::UnexpectedEof { if err.kind() == io::ErrorKind::UnexpectedEof {
tracing::warn!("stream closed: {}", err); tracing::warn!("stream closed: {}", err);
stream.shutdown(std::net::Shutdown::Both).unwrap(); stream.shutdown(std::net::Shutdown::Both)?;
break; break Ok(());
} }
}; };
@ -71,15 +74,14 @@ fn handle_client(mut stream: UnixStream, sender: Sender<Msg>) {
if let Err(err) = stream.read_exact(msg_bytes.as_mut_slice()) { if let Err(err) = stream.read_exact(msg_bytes.as_mut_slice()) {
if err.kind() == io::ErrorKind::UnexpectedEof { if err.kind() == io::ErrorKind::UnexpectedEof {
tracing::warn!("stream closed: {}", err); tracing::warn!("stream closed: {}", err);
stream.shutdown(std::net::Shutdown::Both).unwrap(); stream.shutdown(std::net::Shutdown::Both)?;
break; break Ok(());
} }
}; };
let msg: Msg = rmp_serde::from_slice(msg_bytes.as_slice()).unwrap(); // TODO: handle error let msg: Msg = rmp_serde::from_slice(msg_bytes.as_slice())?; // TODO: handle error
sender.send(msg).unwrap(); sender.send(msg)?;
} }
tracing::info!("end of handle_client");
} }
pub struct PinnacleSocketSource { pub struct PinnacleSocketSource {
@ -151,10 +153,15 @@ impl EventSource for PinnacleSocketSource {
.process_events(readiness, token, |_readiness, listener| { .process_events(readiness, token, |_readiness, listener| {
while let Ok((stream, _sock_addr)) = listener.accept() { while let Ok((stream, _sock_addr)) = listener.accept() {
let sender = self.sender.clone(); let sender = self.sender.clone();
let callback_stream = stream.try_clone().unwrap(); // TODO: error let callback_stream = match stream.try_clone() {
Ok(callback_stream) => callback_stream,
Err(err) => return Err(err),
};
callback(callback_stream, &mut ()); callback(callback_stream, &mut ());
std::thread::spawn(move || { std::thread::spawn(move || {
handle_client(stream, sender); if let Err(err) = handle_client(stream, sender) {
tracing::error!("handle_client errored: {err}");
}
}); });
} }

View file

@ -52,14 +52,6 @@ pub enum Msg {
callback_id: Option<CallbackId>, callback_id: Option<CallbackId>,
}, },
/// Run a command using the optionally specified shell and callback.
SpawnShell {
shell: Option<String>,
command: Vec<String>,
#[serde(default)]
callback_id: Option<CallbackId>,
},
// Pinnacle management // Pinnacle management
/// Quit the compositor. /// Quit the compositor.
Quit, Quit,

View file

@ -7,6 +7,7 @@
// from anvil // from anvil
// TODO: figure out what this stuff does // TODO: figure out what this stuff does
#![allow(clippy::unwrap_used)] // I don't know what this stuff does yet
use std::{ use std::{
collections::{HashMap, HashSet}, collections::{HashMap, HashSet},
error::Error, error::Error,

View file

@ -142,7 +142,7 @@ pub fn run_winit() -> Result<(), Box<dyn Error>> {
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let dmabuf_default_feedback = DmabufFeedbackBuilder::new(node.dev_id(), dmabuf_formats) let dmabuf_default_feedback = DmabufFeedbackBuilder::new(node.dev_id(), dmabuf_formats)
.build() .build()
.unwrap(); .expect("DmabufFeedbackBuilder error");
Some(dmabuf_default_feedback) Some(dmabuf_default_feedback)
} }
Ok(None) => { Ok(None) => {
@ -260,9 +260,9 @@ pub fn run_winit() -> Result<(), Box<dyn Error>> {
states states
.data_map .data_map
.get::<Mutex<CursorImageAttributes>>() .get::<Mutex<CursorImageAttributes>>()
.unwrap() .expect("Mutex<CursorImageAttributes> wasn't in the data map")
.lock() .lock()
.unwrap() .expect("Failed to lock Mutex<CursorImageAttributes>")
.hotspot .hotspot
}) })
} else { } else {
@ -291,7 +291,8 @@ pub fn run_winit() -> Result<(), Box<dyn Error>> {
// render_output() // render_output()
let space_render_elements = let space_render_elements =
space::space_render_elements(renderer, [&state.space], &output, 1.0).unwrap(); space::space_render_elements(renderer, [&state.space], &output, 1.0)
.expect("Failed to get render elements");
let mut output_render_elements = Vec::< let mut output_render_elements = Vec::<
OutputRenderElements<GlesRenderer, WaylandSurfaceRenderElement<GlesRenderer>>, OutputRenderElements<GlesRenderer, WaylandSurfaceRenderElement<GlesRenderer>>,

View file

@ -77,7 +77,9 @@ impl<B: Backend> CompositorHandler for State<B> {
}); });
if let Some(dmabuf) = maybe_dmabuf { if let Some(dmabuf) = maybe_dmabuf {
if let Ok((blocker, source)) = dmabuf.generate_blocker(Interest::READ) { if let Ok((blocker, source)) = dmabuf.generate_blocker(Interest::READ) {
let client = surface.client().unwrap(); let client = surface
.client()
.expect("Surface has no client/is no longer alive");
let res = state.loop_handle.insert_source(source, move |_, _, data| { let res = state.loop_handle.insert_source(source, move |_, _, data| {
data.state data.state
.client_compositor_state(&client) .client_compositor_state(&client)
@ -124,7 +126,10 @@ impl<B: Backend> CompositorHandler for State<B> {
} }
fn client_compositor_state<'a>(&self, client: &'a Client) -> &'a CompositorClientState { fn client_compositor_state<'a>(&self, client: &'a Client) -> &'a CompositorClientState {
&client.get_data::<ClientState>().unwrap().compositor_state &client
.get_data::<ClientState>()
.expect("ClientState wasn't in client's data map")
.compositor_state
} }
} }
delegate_compositor!(@<B: Backend> State<B>); delegate_compositor!(@<B: Backend> State<B>);
@ -135,9 +140,9 @@ fn ensure_initial_configure<B: Backend>(surface: &WlSurface, state: &mut State<B
states states
.data_map .data_map
.get::<XdgToplevelSurfaceData>() .get::<XdgToplevelSurfaceData>()
.unwrap() .expect("XdgToplevelSurfaceData wasn't in surface's data map")
.lock() .lock()
.unwrap() .expect("Failed to lock Mutex<XdgToplevelSurfaceData>")
.initial_configure_sent .initial_configure_sent
}); });
// println!("initial_configure_sent is {}", initial_configure_sent); // println!("initial_configure_sent is {}", initial_configure_sent);
@ -155,9 +160,9 @@ fn ensure_initial_configure<B: Backend>(surface: &WlSurface, state: &mut State<B
states states
.data_map .data_map
.get::<XdgPopupSurfaceData>() .get::<XdgPopupSurfaceData>()
.unwrap() .expect("XdgPopupSurfaceData wasn't in popup's data map")
.lock() .lock()
.unwrap() .expect("Failed to lock Mutex<XdgPopupSurfaceData>")
.initial_configure_sent .initial_configure_sent
}); });
if !initial_configure_sent { if !initial_configure_sent {
@ -221,11 +226,15 @@ impl<B: Backend> XdgShellHandler for State<B> {
self.space.map_element(window.clone(), (0, 0), true); self.space.map_element(window.clone(), (0, 0), true);
self.loop_handle.insert_idle(move |data| { self.loop_handle.insert_idle(move |data| {
data.state.seat.get_keyboard().unwrap().set_focus( data.state
&mut data.state, .seat
Some(window.toplevel().wl_surface().clone()), .get_keyboard()
SERIAL_COUNTER.next_serial(), .expect("Seat had no keyboard") // FIXME: actually handle error
); .set_focus(
&mut data.state,
Some(window.toplevel().wl_surface().clone()),
SERIAL_COUNTER.next_serial(),
);
}); });
let windows: Vec<Window> = self.space.elements().cloned().collect(); let windows: Vec<Window> = self.space.elements().cloned().collect();
@ -245,11 +254,11 @@ impl<B: Backend> XdgShellHandler for State<B> {
.map(|win| win.toplevel().wl_surface().clone()); .map(|win| win.toplevel().wl_surface().clone());
self.seat self.seat
.get_keyboard() .get_keyboard()
.unwrap() .expect("Seat had no keyboard")
.set_focus(self, focus, SERIAL_COUNTER.next_serial()); .set_focus(self, focus, SERIAL_COUNTER.next_serial());
} }
fn new_popup(&mut self, surface: PopupSurface, positioner: PositionerState) { fn new_popup(&mut self, surface: PopupSurface, _positioner: PositionerState) {
if let Err(err) = self.popup_manager.track_popup(PopupKind::from(surface)) { if let Err(err) = self.popup_manager.track_popup(PopupKind::from(surface)) {
tracing::warn!("failed to track popup: {}", err); tracing::warn!("failed to track popup: {}", err);
} }
@ -259,7 +268,7 @@ impl<B: Backend> XdgShellHandler for State<B> {
crate::xdg::request::move_request( crate::xdg::request::move_request(
self, self,
&surface, &surface,
&Seat::from_resource(&seat).unwrap(), &Seat::from_resource(&seat).expect("Couldn't get seat from WlSeat"),
serial, serial,
); );
} }
@ -275,7 +284,7 @@ impl<B: Backend> XdgShellHandler for State<B> {
crate::xdg::request::resize_request( crate::xdg::request::resize_request(
self, self,
&surface, &surface,
&Seat::from_resource(&seat).unwrap(), &Seat::from_resource(&seat).expect("Couldn't get seat from WlSeat"),
serial, serial,
edges, edges,
BUTTON_LEFT, BUTTON_LEFT,
@ -296,7 +305,7 @@ impl<B: Backend> XdgShellHandler for State<B> {
} }
fn grab(&mut self, surface: PopupSurface, seat: WlSeat, serial: Serial) { fn grab(&mut self, surface: PopupSurface, seat: WlSeat, serial: Serial) {
let seat: Seat<Self> = Seat::from_resource(&seat).unwrap(); let seat: Seat<Self> = Seat::from_resource(&seat).expect("Couldn't get seat from WlSeat");
let popup_kind = PopupKind::Xdg(surface); let popup_kind = PopupKind::Xdg(surface);
if let Some(root) = find_popup_root_surface(&popup_kind) if let Some(root) = find_popup_root_surface(&popup_kind)
.ok() .ok()

View file

@ -53,8 +53,8 @@ impl<B: Backend> State<B> {
} }
fn pointer_button<I: InputBackend>(&mut self, event: I::PointerButtonEvent) { fn pointer_button<I: InputBackend>(&mut self, event: I::PointerButtonEvent) {
let pointer = self.seat.get_pointer().unwrap(); let pointer = self.seat.get_pointer().expect("Seat has no pointer"); // FIXME: handle err
let keyboard = self.seat.get_keyboard().unwrap(); let keyboard = self.seat.get_keyboard().expect("Seat has no keyboard"); // FIXME: handle err
// A serial is a number sent with a event that is sent back to the // A serial is a number sent with a event that is sent back to the
// server by the clients in further requests. This allows the server to // server by the clients in further requests. This allows the server to
@ -198,7 +198,10 @@ impl<B: Backend> State<B> {
frame = frame.stop(Axis::Vertical); frame = frame.stop(Axis::Vertical);
} }
self.seat.get_pointer().unwrap().axis(self, frame); self.seat
.get_pointer()
.expect("Seat has no pointer")
.axis(self, frame); // FIXME: handle err
} }
fn keyboard<I: InputBackend>(&mut self, event: I::KeyboardKeyEvent) { fn keyboard<I: InputBackend>(&mut self, event: I::KeyboardKeyEvent) {
@ -206,58 +209,62 @@ impl<B: Backend> State<B> {
let time = event.time_msec(); let time = event.time_msec();
let press_state = event.state(); let press_state = event.state();
let mut move_mode = false; let mut move_mode = false;
let action = self.seat.get_keyboard().unwrap().input( let action = self
self, .seat
event.key_code(), .get_keyboard()
press_state, .expect("Seat has no keyboard") // FIXME: handle err
serial, .input(
time, self,
|state, modifiers, keysym| { event.key_code(),
if press_state == KeyState::Pressed { press_state,
let mut modifier_mask = Vec::<Modifiers>::new(); serial,
if modifiers.alt { time,
modifier_mask.push(Modifiers::Alt); |state, modifiers, keysym| {
if press_state == KeyState::Pressed {
let mut modifier_mask = Vec::<Modifiers>::new();
if modifiers.alt {
modifier_mask.push(Modifiers::Alt);
}
if modifiers.shift {
modifier_mask.push(Modifiers::Shift);
}
if modifiers.ctrl {
modifier_mask.push(Modifiers::Ctrl);
}
if modifiers.logo {
modifier_mask.push(Modifiers::Super);
}
if let Some(callback_id) = state
.input_state
.keybinds
.get(&(modifier_mask.into(), keysym.modified_sym()))
{
return FilterResult::Intercept(*callback_id);
}
} }
if modifiers.shift {
modifier_mask.push(Modifiers::Shift);
}
if modifiers.ctrl {
modifier_mask.push(Modifiers::Ctrl);
}
if modifiers.logo {
modifier_mask.push(Modifiers::Super);
}
if let Some(callback_id) = state
.input_state
.keybinds
.get(&(modifier_mask.into(), keysym.modified_sym()))
{
return FilterResult::Intercept(*callback_id);
}
}
if keysym.modified_sym() == keysyms::KEY_Control_L { if keysym.modified_sym() == keysyms::KEY_Control_L {
match press_state { match press_state {
KeyState::Pressed => { KeyState::Pressed => {
move_mode = true; move_mode = true;
} }
KeyState::Released => { KeyState::Released => {
move_mode = false; move_mode = false;
}
} }
FilterResult::Forward
} else {
FilterResult::Forward
} }
FilterResult::Forward },
} else { );
FilterResult::Forward
}
},
);
self.move_mode = move_mode; self.move_mode = move_mode;
if let Some(callback_id) = action { if let Some(callback_id) = action {
if let Some(stream) = self.api_state.stream.as_ref() { if let Some(stream) = self.api_state.stream.as_ref() {
if let Err(err) = crate::api::send_to_client( if let Err(err) = crate::api::send_to_client(
&mut stream.lock().unwrap(), &mut stream.lock().expect("Could not lock stream mutex"),
&OutgoingMsg::CallCallback { &OutgoingMsg::CallCallback {
callback_id, callback_id,
args: None, args: None,
@ -288,11 +295,14 @@ impl State<WinitData> {
} }
fn pointer_motion_absolute<I: InputBackend>(&mut self, event: I::PointerMotionAbsoluteEvent) { fn pointer_motion_absolute<I: InputBackend>(&mut self, event: I::PointerMotionAbsoluteEvent) {
let output = self.space.outputs().next().unwrap(); let Some(output) = self.space.outputs().next() else { return; };
let output_geo = self.space.output_geometry(output).unwrap(); let output_geo = self
.space
.output_geometry(output)
.expect("Output geometry doesn't exist");
let pointer_loc = event.position_transformed(output_geo.size) + output_geo.loc.to_f64(); let pointer_loc = event.position_transformed(output_geo.size) + output_geo.loc.to_f64();
let serial = SERIAL_COUNTER.next_serial(); let serial = SERIAL_COUNTER.next_serial();
let pointer = self.seat.get_pointer().unwrap(); let pointer = self.seat.get_pointer().expect("Seat has no pointer"); // FIXME: handle err
// tracing::info!("pointer_loc: {:?}", pointer_loc); // tracing::info!("pointer_loc: {:?}", pointer_loc);
@ -407,16 +417,35 @@ impl State<UdevData> {
let serial = SERIAL_COUNTER.next_serial(); let serial = SERIAL_COUNTER.next_serial();
let max_x = self.space.outputs().fold(0, |acc, o| { let max_x = self.space.outputs().fold(0, |acc, o| {
acc + self.space.output_geometry(o).unwrap().size.w acc + self
.space
.output_geometry(o)
.expect("Output geometry doesn't exist")
.size
.w
}); });
let max_h_output = self let Some(max_h_output) = self
.space .space
.outputs() .outputs()
.max_by_key(|o| self.space.output_geometry(o).unwrap().size.h) .max_by_key(|o| {
.unwrap(); self.space
.output_geometry(o)
.expect("Output geometry doesn't exist")
.size
.h
})
else {
tracing::warn!("Pointer moved, but there was no output");
return;
};
let max_y = self.space.output_geometry(max_h_output).unwrap().size.h; let max_y = self
.space
.output_geometry(max_h_output)
.expect("Output geometry doesn't exist")
.size
.h;
self.pointer_location.x = event.x_transformed(max_x); self.pointer_location.x = event.x_transformed(max_x);
self.pointer_location.y = event.y_transformed(max_y); self.pointer_location.y = event.y_transformed(max_y);
@ -447,17 +476,31 @@ impl State<UdevData> {
let (pos_x, pos_y) = pos.into(); let (pos_x, pos_y) = pos.into();
let max_x = self.space.outputs().fold(0, |acc, o| { let max_x = self.space.outputs().fold(0, |acc, o| {
acc + self.space.output_geometry(o).unwrap().size.w acc + self
.space
.output_geometry(o)
.expect("Output geometry doesn't exist")
.size
.w
}); });
let clamped_x = pos_x.clamp(0.0, max_x as f64); let clamped_x = pos_x.clamp(0.0, max_x as f64);
let max_y = self let max_y = self
.space .space
.outputs() .outputs()
.find(|o| { .find(|o| {
let geo = self.space.output_geometry(o).unwrap(); let geo = self
.space
.output_geometry(o)
.expect("Output geometry doesn't exist");
geo.contains((clamped_x as i32, 0)) geo.contains((clamped_x as i32, 0))
}) })
.map(|o| self.space.output_geometry(o).unwrap().size.h); .map(|o| {
self.space
.output_geometry(o)
.expect("Output geometry doesn't exist")
.size
.h
});
if let Some(max_y) = max_y { if let Some(max_y) = max_y {
let clamped_y = pos_y.clamp(0.0, max_y as f64); let clamped_y = pos_y.clamp(0.0, max_y as f64);

View file

@ -13,6 +13,7 @@
//! contribute or learn how building something like this works. //! contribute or learn how building something like this works.
#![deny(unused_imports)] // gonna force myself to keep stuff clean #![deny(unused_imports)] // gonna force myself to keep stuff clean
#![warn(clippy::unwrap_used)]
mod api; mod api;
mod backend; mod backend;

View file

@ -24,7 +24,10 @@ impl OutputState {
.user_data() .user_data()
.insert_if_missing(|| RefCell::<Self>::default); .insert_if_missing(|| RefCell::<Self>::default);
let state = output.user_data().get::<RefCell<Self>>().unwrap(); let state = output
.user_data()
.get::<RefCell<Self>>()
.expect("RefCell doesn't exist in data map (This should NEVER happen. If you see this, something oofed big-time.)");
func(&mut state.borrow_mut()) func(&mut state.borrow_mut())
} }

View file

@ -115,18 +115,19 @@ impl<B: Backend> State<B> {
// //
// To fix this, I just set the limit to be higher. As Pinnacle is the whole graphical // To fix this, I just set the limit to be higher. As Pinnacle is the whole graphical
// environment, I *think* this is ok. // environment, I *think* this is ok.
smithay::reexports::nix::sys::resource::setrlimit( if let Err(err) = smithay::reexports::nix::sys::resource::setrlimit(
smithay::reexports::nix::sys::resource::Resource::RLIMIT_NOFILE, smithay::reexports::nix::sys::resource::Resource::RLIMIT_NOFILE,
65536, 65536,
65536 * 2, 65536 * 2,
) ) {
.unwrap(); tracing::error!("Could not raise fd limit: errno {err}");
}
loop_handle.insert_source(socket, |stream, _metadata, data| { loop_handle.insert_source(socket, |stream, _metadata, data| {
data.display data.display
.handle() .handle()
.insert_client(stream, Arc::new(ClientState::default())) .insert_client(stream, Arc::new(ClientState::default()))
.unwrap(); .expect("Could not insert client into loop handle");
})?; })?;
loop_handle.insert_source( loop_handle.insert_source(
@ -180,11 +181,6 @@ impl<B: Backend> State<B> {
} => { } => {
data.state.handle_spawn(command, callback_id); data.state.handle_spawn(command, callback_id);
} }
Msg::SpawnShell {
shell,
command,
callback_id,
} => todo!(),
Msg::MoveToTag { tag } => todo!(), Msg::MoveToTag { tag } => todo!(),
Msg::ToggleTag { tag } => todo!(), Msg::ToggleTag { tag } => todo!(),
@ -215,9 +211,9 @@ impl<B: Backend> State<B> {
let lock = states. let lock = states.
data_map data_map
.get::<XdgToplevelSurfaceData>() .get::<XdgToplevelSurfaceData>()
.unwrap() .expect("XdgToplevelSurfaceData doesn't exist")
.lock() .lock()
.unwrap(); .expect("Couldn't lock XdgToplevelSurfaceData");
(lock.app_id.clone(), lock.title.clone()) (lock.app_id.clone(), lock.title.clone())
} }
); );
@ -234,8 +230,8 @@ impl<B: Backend> State<B> {
location: location.into(), location: location.into(),
floating, floating,
}; };
let stream = data.state.api_state.stream.as_ref().unwrap(); let stream = data.state.api_state.stream.as_ref().expect("Stream doesn't exist");
let mut stream = stream.lock().unwrap(); let mut stream = stream.lock().expect("Couldn't lock stream");
crate::api::send_to_client( crate::api::send_to_client(
&mut stream, &mut stream,
&OutgoingMsg::RequestResponse { &OutgoingMsg::RequestResponse {
@ -243,7 +239,7 @@ impl<B: Backend> State<B> {
response: RequestResponse::Window { window: props } response: RequestResponse::Window { window: props }
} }
) )
.unwrap(); .expect("Send to client failed");
}, },
Request::GetAllWindows { id } => { Request::GetAllWindows { id } => {
let window_props = data.state.space.elements().map(|win| { let window_props = data.state.space.elements().map(|win| {
@ -254,9 +250,9 @@ impl<B: Backend> State<B> {
let lock = states. let lock = states.
data_map data_map
.get::<XdgToplevelSurfaceData>() .get::<XdgToplevelSurfaceData>()
.unwrap() .expect("XdgToplevelSurfaceData doesn't exist")
.lock() .lock()
.unwrap(); .expect("Couldn't lock XdgToplevelSurfaceData");
(lock.app_id.clone(), lock.title.clone()) (lock.app_id.clone(), lock.title.clone())
} }
); );
@ -264,7 +260,7 @@ impl<B: Backend> State<B> {
(state.id, state.floating.is_floating()) (state.id, state.floating.is_floating())
}); });
// TODO: unwrap // TODO: unwrap
let location = data.state.space.element_location(win).unwrap(); let location = data.state.space.element_location(win).expect("Window location doesn't exist");
WindowProperties { WindowProperties {
id: window_id, id: window_id,
app_id, app_id,
@ -275,8 +271,9 @@ impl<B: Backend> State<B> {
} }
}).collect::<Vec<_>>(); }).collect::<Vec<_>>();
let stream = data.state.api_state.stream.as_ref().unwrap(); // FIXME: figure out what to do if error
let mut stream = stream.lock().unwrap(); let stream = data.state.api_state.stream.as_ref().expect("Stream doesn't exist");
let mut stream = stream.lock().expect("Couldn't lock stream");
crate::api::send_to_client( crate::api::send_to_client(
&mut stream, &mut stream,
&OutgoingMsg::RequestResponse { &OutgoingMsg::RequestResponse {
@ -284,7 +281,7 @@ impl<B: Backend> State<B> {
response: RequestResponse::GetAllWindows { windows: window_props }, response: RequestResponse::GetAllWindows { windows: window_props },
} }
) )
.unwrap(); .expect("Couldn't send to client");
} }
}, },
}; };
@ -305,13 +302,13 @@ impl<B: Backend> State<B> {
{ {
old_stream old_stream
.lock() .lock()
.unwrap() .expect("Couldn't lock old stream")
.shutdown(std::net::Shutdown::Both) .shutdown(std::net::Shutdown::Both)
.unwrap(); .expect("Couldn't shutdown old stream");
} }
})?; })?;
let (executor, sched) = calloop::futures::executor::<()>().unwrap(); let (executor, sched) = calloop::futures::executor::<()>().expect("Couldn't create executor");
loop_handle.insert_source(executor, |_, _, _| {})?; loop_handle.insert_source(executor, |_, _, _| {})?;
// TODO: move all this into the lua api // TODO: move all this into the lua api
@ -324,7 +321,7 @@ impl<B: Backend> State<B> {
let lua_path = std::env::var("LUA_PATH").expect("Lua is not installed!"); let lua_path = std::env::var("LUA_PATH").expect("Lua is not installed!");
let mut local_lua_path = std::env::current_dir() let mut local_lua_path = std::env::current_dir()
.unwrap() .expect("Couldn't get current dir")
.to_string_lossy() .to_string_lossy()
.to_string(); .to_string();
local_lua_path.push_str("/api/lua"); // TODO: get from crate root and do dynamically local_lua_path.push_str("/api/lua"); // TODO: get from crate root and do dynamically
@ -339,7 +336,7 @@ impl<B: Backend> State<B> {
.env("LUA_PATH", new_lua_path) .env("LUA_PATH", new_lua_path)
.env("LUA_CPATH", new_lua_cpath) .env("LUA_CPATH", new_lua_cpath)
.spawn() .spawn()
.unwrap(); .expect("Could not start config process");
let display_handle = display.handle(); let display_handle = display.handle();
let mut seat_state = SeatState::new(); let mut seat_state = SeatState::new();
@ -381,13 +378,14 @@ impl<B: Backend> State<B> {
} }
pub fn handle_spawn(&self, command: Vec<String>, callback_id: Option<CallbackId>) { pub fn handle_spawn(&self, command: Vec<String>, callback_id: Option<CallbackId>) {
let mut command = command.into_iter().peekable(); let mut command = command.into_iter();
if command.peek().is_none() { let Some(program) = command.next() else {
// TODO: notify that command was nothing // TODO: notify that command was nothing
return; return;
} };
let mut child = async_process::Command::new(OsString::from(command.next().unwrap())) let program = OsString::from(program);
let Ok(mut child) = async_process::Command::new(&program)
.env("WAYLAND_DISPLAY", self.socket_name.clone()) .env("WAYLAND_DISPLAY", self.socket_name.clone())
.stdin(if callback_id.is_some() { .stdin(if callback_id.is_some() {
Stdio::piped() Stdio::piped()
@ -408,13 +406,17 @@ impl<B: Backend> State<B> {
}) })
.args(command) .args(command)
.spawn() .spawn()
.unwrap(); // TODO: handle unwrap else {
// TODO: notify user that program doesn't exist
tracing::warn!("tried to run {}, but it doesn't exist", program.to_string_lossy());
return;
};
// TODO: find a way to make this hellish code look better, deal with unwraps // TODO: find a way to make this hellish code look better, deal with unwraps
if let Some(callback_id) = callback_id { if let Some(callback_id) = callback_id {
let stdout = child.stdout.take(); let stdout = child.stdout.take();
let stderr = child.stderr.take(); let stderr = child.stderr.take();
let stream_out = self.api_state.stream.as_ref().unwrap().clone(); let stream_out = self.api_state.stream.as_ref().expect("Stream doesn't exist").clone();
let stream_err = stream_out.clone(); let stream_err = stream_out.clone();
let stream_exit = stream_out.clone(); let stream_exit = stream_out.clone();
@ -427,7 +429,7 @@ impl<B: Backend> State<B> {
match reader.read_line(&mut buf).await { match reader.read_line(&mut buf).await {
Ok(0) => break, Ok(0) => break,
Ok(_) => { Ok(_) => {
let mut stream = stream_out.lock().unwrap(); let mut stream = stream_out.lock().expect("Couldn't lock stream");
crate::api::send_to_client( crate::api::send_to_client(
&mut stream, &mut stream,
&OutgoingMsg::CallCallback { &OutgoingMsg::CallCallback {
@ -440,7 +442,7 @@ impl<B: Backend> State<B> {
}), }),
}, },
) )
.unwrap(); .expect("Send to client failed"); // TODO: notify instead of crash
} }
Err(err) => { Err(err) => {
tracing::warn!("child read err: {err}"); tracing::warn!("child read err: {err}");
@ -449,7 +451,11 @@ impl<B: Backend> State<B> {
} }
} }
}; };
self.async_scheduler.schedule(future).unwrap();
// This is not important enough to crash on error, so just print the error instead
if let Err(err) = self.async_scheduler.schedule(future) {
tracing::error!("Failed to schedule future: {err}");
}
} }
if let Some(stderr) = stderr { if let Some(stderr) = stderr {
let future = async move { let future = async move {
@ -459,7 +465,7 @@ impl<B: Backend> State<B> {
match reader.read_line(&mut buf).await { match reader.read_line(&mut buf).await {
Ok(0) => break, Ok(0) => break,
Ok(_) => { Ok(_) => {
let mut stream = stream_err.lock().unwrap(); let mut stream = stream_err.lock().expect("Couldn't lock stream");
crate::api::send_to_client( crate::api::send_to_client(
&mut stream, &mut stream,
&OutgoingMsg::CallCallback { &OutgoingMsg::CallCallback {
@ -472,7 +478,7 @@ impl<B: Backend> State<B> {
}), }),
}, },
) )
.unwrap(); .expect("Send to client failed"); // TODO: notify instead of crash
} }
Err(err) => { Err(err) => {
tracing::warn!("child read err: {err}"); tracing::warn!("child read err: {err}");
@ -481,13 +487,15 @@ impl<B: Backend> State<B> {
} }
} }
}; };
self.async_scheduler.schedule(future).unwrap(); if let Err(err) = self.async_scheduler.schedule(future) {
tracing::error!("Failed to schedule future: {err}");
}
} }
let future = async move { let future = async move {
match child.status().await { match child.status().await {
Ok(exit_status) => { Ok(exit_status) => {
let mut stream = stream_exit.lock().unwrap(); let mut stream = stream_exit.lock().expect("Couldn't lock stream");
crate::api::send_to_client( crate::api::send_to_client(
&mut stream, &mut stream,
&OutgoingMsg::CallCallback { &OutgoingMsg::CallCallback {
@ -500,14 +508,16 @@ impl<B: Backend> State<B> {
}), }),
}, },
) )
.unwrap() .expect("Send to client failed"); // TODO: notify instead of crash
} }
Err(err) => { Err(err) => {
tracing::warn!("child wait() err: {err}"); tracing::warn!("child wait() err: {err}");
} }
} }
}; };
self.async_scheduler.schedule(future).unwrap(); if let Err(err) = self.async_scheduler.schedule(future) {
tracing::error!("Failed to schedule future: {err}");
}
} }
} }
} }

View file

@ -34,7 +34,10 @@ pub trait SurfaceState: Default + 'static {
{ {
compositor::with_states(wl_surface, |states| { compositor::with_states(wl_surface, |states| {
states.data_map.insert_if_missing(RefCell::<Self>::default); states.data_map.insert_if_missing(RefCell::<Self>::default);
let state = states.data_map.get::<RefCell<Self>>().unwrap(); let state = states
.data_map
.get::<RefCell<Self>>()
.expect("This should never happen");
function(&mut state.borrow_mut()) function(&mut state.borrow_mut())
}) })

View file

@ -119,7 +119,7 @@ impl WindowState {
let mut state = window let mut state = window
.user_data() .user_data()
.get::<RefCell<Self>>() .get::<RefCell<Self>>()
.unwrap() .expect("This should never happen")
.borrow_mut(); .borrow_mut();
func(&mut state) func(&mut state)
} }