Compare commits

...

2 Commits

Author SHA1 Message Date
yamabush1
9cc65e70ea fix(event_loop): walk error source chain for BrokenPipe in OtherError
Some checks failed
CI / build + test (push) Has been cancelled
CI / cargo audit (push) Has been cancelled
The previous fix checked downcast_ref::<io::Error> directly on the
OtherError payload, but wayland-client wraps the io::Error inside
WaylandError::Io — one level deeper. Downcast failed, is_closed
stayed false, and the panic arm fired anyway.

Replace the single downcast with a source()-chain walk that finds
the io::Error at any depth, matching the same BrokenPipe /
ConnectionReset check already used for the direct IoError arm.
2026-05-18 20:48:35 +02:00
yamabush1
750eae7a93 fix(event_loop): exit cleanly on OtherError(BrokenPipe) from compositor
calloop surfaces the closed-socket condition either as
Error::IoError(BrokenPipe) — already handled — or as
Error::OtherError wrapping an std::io::Error with kind BrokenPipe,
which previously fell through to panic!(). Add a matching arm that
downcasts the inner error and treats both forms the same: log and
set exit_requested so the run loop terminates gracefully instead
of unwinding.
2026-05-17 18:31:12 +02:00

View File

@@ -383,6 +383,36 @@ pub( crate ) fn try_run<A: App>( app: A ) -> Result<(), RunError>
data.exit_requested = true; data.exit_requested = true;
continue; continue;
} }
Err( calloop::Error::OtherError( ref e ) ) =>
{
// wayland-client surfaces the closed-socket condition as an
// OtherError wrapping a WaylandError::Io(BrokenPipe) — one
// level deeper than a direct io::Error. Walk the source()
// chain so we catch it regardless of how many wrapper types
// sit between calloop and the raw io::Error.
let mut src: Option<&dyn std::error::Error> = Some( e.as_ref() );
let mut is_closed = false;
while let Some( err ) = src
{
if let Some( io ) = err.downcast_ref::<std::io::Error>()
{
if matches!( io.kind(),
std::io::ErrorKind::BrokenPipe | std::io::ErrorKind::ConnectionReset )
{
is_closed = true;
break;
}
}
src = err.source();
}
if is_closed
{
eprintln!( "ltk: wayland connection lost; exiting" );
data.exit_requested = true;
continue;
}
panic!( "dispatch: {e:?}" );
}
Err( e ) => panic!( "dispatch: {e:?}" ), Err( e ) => panic!( "dispatch: {e:?}" ),
} }
// Any surface whose press has now crossed `long_press_duration` // Any surface whose press has now crossed `long_press_duration`