Package: meli I hope to update rust-termion to version 4 soon, I was able to patch meli to build with the new version, but the patches were quite involved so you might want to run things by upstream and/or test that the package still works correctly.
Debdiff is attatched.
diff -Nru meli-0.8.12+dfsg/debian/changelog meli-0.8.12+dfsg/debian/changelog --- meli-0.8.12+dfsg/debian/changelog 2025-12-05 19:17:31.000000000 +0000 +++ meli-0.8.12+dfsg/debian/changelog 2025-12-16 22:46:37.000000000 +0000 @@ -1,3 +1,10 @@ +meli (0.8.12+dfsg-9.1) UNRELEASED; urgency=medium + + * Non-maintainer upload. + * Add patches for termion 4. + + -- Peter Michael Green <[email protected]> Tue, 16 Dec 2025 22:46:37 +0000 + meli (0.8.12+dfsg-9) unstable; urgency=medium * add patch 1001_async-fn-stream diff -Nru meli-0.8.12+dfsg/debian/control meli-0.8.12+dfsg/debian/control --- meli-0.8.12+dfsg/debian/control 2025-12-05 13:41:53.000000000 +0000 +++ meli-0.8.12+dfsg/debian/control 2025-12-16 22:46:37.000000000 +0000 @@ -65,7 +65,7 @@ librust-structopt-0.3-dev, librust-syn-1+default-dev, librust-tempfile-3+default-dev, - librust-termion-1+default-dev, + librust-termion-4+default-dev, librust-toml-0.8+display-dev, librust-toml-0.8+parse-dev, librust-toml-0.8+preserve-order-dev, diff -Nru meli-0.8.12+dfsg/debian/patches/2005_termion_2.patch meli-0.8.12+dfsg/debian/patches/2005_termion_2.patch --- meli-0.8.12+dfsg/debian/patches/2005_termion_2.patch 1970-01-01 00:00:00.000000000 +0000 +++ meli-0.8.12+dfsg/debian/patches/2005_termion_2.patch 2025-12-16 22:34:26.000000000 +0000 @@ -0,0 +1,35 @@ +Description: Support termion 2 + Replaces AlternateScreen::from with into_alternate_screen per the + upstream migration guide. +Author: Peter Michael Green <[email protected]> + +--- meli-0.8.12+dfsg.orig/meli/Cargo.toml ++++ meli-0.8.12+dfsg/meli/Cargo.toml +@@ -44,7 +44,7 @@ signal-hook-registry = { version = "1.2. + smallvec = { version = "^1.5.0", features = ["serde"] } + structopt = { version = "0.3.26", default-features = false } + # svg_crate = { version = "^0.13", optional = true, package = "svg" } +-termion = { version = "1.5.1", default-features = false } ++termion = { version = "2", default-features = false } + toml = { version = "0.8", default-features = false, features = ["display","preserve_order","parse"] } + xdg = { version = "2.1.0" } + +--- meli-0.8.12+dfsg.orig/meli/src/terminal/screen.rs ++++ meli-0.8.12+dfsg/meli/src/terminal/screen.rs +@@ -375,6 +375,7 @@ impl Screen<Tty> { + } + + pub fn switch_to_alternate_screen(&mut self, context: &crate::Context) { ++ use crate::termion::screen::IntoAlternateScreen; + let mut stdout = BufWriter::with_capacity( + 240 * 80, + Box::new(std::io::stdout()) as Box<dyn std::io::Write>, +@@ -414,7 +415,7 @@ impl Screen<Tty> { + ) + .unwrap(); + +- self.display.stdout = Some(AlternateScreen::from(stdout.into_raw_mode().unwrap())); ++ self.display.stdout = Some(stdout.into_raw_mode().unwrap().into_alternate_screen().unwrap()); + self.flush(); + } + diff -Nru meli-0.8.12+dfsg/debian/patches/2006_termion_3.patch meli-0.8.12+dfsg/debian/patches/2006_termion_3.patch --- meli-0.8.12+dfsg/debian/patches/2006_termion_3.patch 1970-01-01 00:00:00.000000000 +0000 +++ meli-0.8.12+dfsg/debian/patches/2006_termion_3.patch 2025-12-16 22:43:44.000000000 +0000 @@ -0,0 +1,96 @@ +Description: Support termion 3 + Termion 3 was tricky, "RawTerminal" now requires AsFd in addition to + Write. To accomodate this we create a Wrapper around BufWriter that + implements AsFd. +Author: Peter Michael Green <[email protected]> + +Index: meli-0.8.12+dfsg/meli/src/terminal/screen.rs +=================================================================== +--- meli-0.8.12+dfsg.orig/meli/src/terminal/screen.rs ++++ meli-0.8.12+dfsg/meli/src/terminal/screen.rs +@@ -36,8 +36,59 @@ use crate::{ + Attr, Context, ThemeAttribute, + }; + ++use std::os::fd::AsFd; ++use std::os::fd::BorrowedFd; ++use std::cell::RefCell; ++use std::os::fd::AsRawFd; ++ ++// by implementing this trait one asserts that writing ++// to the writer will not close the underlying Fd. ++pub (crate) unsafe trait WriteAsFd: std::io::Write + AsFd {} ++ ++unsafe impl WriteAsFd for Box<(dyn WriteAsFd)> {} ++unsafe impl WriteAsFd for std::io::Stdout {} ++ ++pub (crate) struct BufWriterWithFd<W: WriteAsFd> { ++ inner: RefCell<BufWriter<W>> ++} ++ ++// a buffered writer that allows access to the FD of the inner writer. ++// requesting the FD will flush the buffered writer. ++impl <W: WriteAsFd> BufWriterWithFd<W> { ++ pub fn with_capacity(capacity: usize, inner: W) -> BufWriterWithFd<W> { ++ Self { inner: BufWriter::with_capacity(capacity, inner).into() } ++ } ++} ++ ++impl <W: WriteAsFd> std::io::Write for BufWriterWithFd<W> { ++ fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> { ++ self.inner.get_mut().write(buf) ++ } ++ fn flush(&mut self) -> std::io::Result<()> { ++ self.inner.get_mut().flush() ++ } ++ fn write_vectored(&mut self, bufs: &[std::io::IoSlice<'_>]) -> std::io::Result<usize> { ++ self.inner.get_mut().write_vectored(bufs) ++ } ++ fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> { ++ self.inner.get_mut().write_all(buf) ++ } ++ fn write_fmt(&mut self, args: std::fmt::Arguments<'_>) -> std::io::Result<()> { ++ self.inner.get_mut().write_fmt(args) ++ } ++} ++ ++impl <W: WriteAsFd> AsFd for BufWriterWithFd<W> { ++ fn as_fd(&self) -> BorrowedFd<'_> { ++ self.inner.borrow_mut().flush(); ++ // Safety: we only use interior mutability to flush the bufwriter, and we have asserted ++ // that writing to the underlying writer does not close the underlying fd. ++ unsafe { BorrowedFd::borrow_raw(self.inner.borrow_mut().get_ref().as_fd().as_raw_fd()) } ++ } ++} ++ + pub type StateStdout = termion::screen::AlternateScreen< +- termion::raw::RawTerminal<BufWriter<Box<dyn Write + 'static>>>, ++ termion::raw::RawTerminal<BufWriterWithFd<Box<dyn WriteAsFd + 'static>>>, + >; + + type DrawHorizontalSegmentFn = +@@ -376,9 +427,9 @@ impl Screen<Tty> { + + pub fn switch_to_alternate_screen(&mut self, context: &crate::Context) { + use crate::termion::screen::IntoAlternateScreen; +- let mut stdout = BufWriter::with_capacity( ++ let mut stdout = BufWriterWithFd::with_capacity( + 240 * 80, +- Box::new(std::io::stdout()) as Box<dyn std::io::Write>, ++ Box::new(std::io::stdout()) as Box<dyn WriteAsFd>, + ); + + write!( +Index: meli-0.8.12+dfsg/meli/Cargo.toml +=================================================================== +--- meli-0.8.12+dfsg.orig/meli/Cargo.toml ++++ meli-0.8.12+dfsg/meli/Cargo.toml +@@ -44,7 +44,7 @@ signal-hook-registry = { version = "1.2. + smallvec = { version = "^1.5.0", features = ["serde"] } + structopt = { version = "0.3.26", default-features = false } + # svg_crate = { version = "^0.13", optional = true, package = "svg" } +-termion = { version = "2", default-features = false } ++termion = { version = "3", default-features = false } + toml = { version = "0.8", default-features = false, features = ["display","preserve_order","parse"] } + xdg = { version = "2.1.0" } + diff -Nru meli-0.8.12+dfsg/debian/patches/2007_termion_4.patch meli-0.8.12+dfsg/debian/patches/2007_termion_4.patch --- meli-0.8.12+dfsg/debian/patches/2007_termion_4.patch 1970-01-01 00:00:00.000000000 +0000 +++ meli-0.8.12+dfsg/debian/patches/2007_termion_4.patch 2025-12-16 22:46:37.000000000 +0000 @@ -0,0 +1,88 @@ +Description: Support termion 3 + Termion 4 added "WheelLeft" and "WheelRight" buttons, this patch makes + the conversion from a termion mouse event to a meli one falible and + ignores events that cannot be converted. +Author: Peter Michael Green <[email protected]> +Index: meli-0.8.12+dfsg/meli/Cargo.toml +=================================================================== +--- meli-0.8.12+dfsg.orig/meli/Cargo.toml ++++ meli-0.8.12+dfsg/meli/Cargo.toml +@@ -44,7 +44,7 @@ signal-hook-registry = { version = "1.2. + smallvec = { version = "^1.5.0", features = ["serde"] } + structopt = { version = "0.3.26", default-features = false } + # svg_crate = { version = "^0.13", optional = true, package = "svg" } +-termion = { version = "3", default-features = false } ++termion = { version = "4", default-features = false } + toml = { version = "0.8", default-features = false, features = ["display","preserve_order","parse"] } + xdg = { version = "2.1.0" } + +Index: meli-0.8.12+dfsg/meli/src/terminal/keys.rs +=================================================================== +--- meli-0.8.12+dfsg.orig/meli/src/terminal/keys.rs ++++ meli-0.8.12+dfsg/meli/src/terminal/keys.rs +@@ -98,13 +98,14 @@ pub enum MouseEvent { + Hold(u16, u16), + } + +-impl From<TermionMouseEvent> for MouseEvent { +- fn from(val: TermionMouseEvent) -> Self { ++impl TryFrom<TermionMouseEvent> for MouseEvent { ++ type Error = &'static str; ++ fn try_from(val: TermionMouseEvent) -> Result<Self, Self::Error> { + use TermionMouseEvent::*; + match val { +- Press(btn, a, b) => Self::Press(btn.into(), a, b), +- Release(a, b) => Self::Release(a, b), +- Hold(a, b) => Self::Hold(a, b), ++ Press(btn, a, b) => Ok(Self::Press(btn.try_into()?, a, b)), ++ Release(a, b) => Ok(Self::Release(a, b)), ++ Hold(a, b) => Ok(Self::Hold(a, b)), + } + } + } +@@ -127,17 +128,27 @@ pub enum MouseButton { + /// + /// This event is typically only used with [`MouseEvent::Press`]. + WheelDown, ++ /// Mouse wheel is going up. ++ /// ++ /// This event is typically only used with [`MouseEvent::Press`]. ++ WheelLeft, ++ /// Mouse wheel is going down. ++ /// ++ /// This event is typically only used with [`MouseEvent::Press`]. ++ WheelRight, + } + +-impl From<TermionMouseButton> for MouseButton { +- fn from(val: TermionMouseButton) -> Self { ++impl TryFrom<TermionMouseButton> for MouseButton { ++ type Error = &'static str; ++ fn try_from(val: TermionMouseButton) -> Result<Self, Self::Error> { + use TermionMouseButton::*; + match val { +- Left => Self::Left, +- Right => Self::Right, +- Middle => Self::Middle, +- WheelUp => Self::WheelUp, +- WheelDown => Self::WheelDown, ++ Left => Ok(Self::Left), ++ Right => Ok(Self::Right), ++ Middle => Ok(Self::Middle), ++ WheelUp => Ok(Self::WheelUp), ++ WheelDown => Ok(Self::WheelDown), ++ _ => Err("unknown mouse button"), + } + } + } +@@ -364,7 +375,9 @@ pub fn get_events( + continue 'poll_while; + } + (Ok((TEvent::Mouse(mev), bytes)), InputMode::Normal) => { +- closure((Key::Mouse(mev.into()), bytes)); ++ if let Ok(mev) = mev.try_into() { //ignore mouse events that cannot be converted. ++ closure((Key::Mouse(mev), bytes)); ++ } + continue 'poll_while; + } + (Ok((TEvent::Unsupported(ref k,), _)), InputMode::Normal) if k.as_slice() == [27, 91, 63] => { diff -Nru meli-0.8.12+dfsg/debian/patches/series meli-0.8.12+dfsg/debian/patches/series --- meli-0.8.12+dfsg/debian/patches/series 2025-12-05 13:37:11.000000000 +0000 +++ meli-0.8.12+dfsg/debian/patches/series 2025-12-16 22:13:06.000000000 +0000 @@ -9,3 +9,6 @@ 2003_unicode.patch 2004_no_hardcode_defaults.patch 2004_no_jmap_server_test.patch +2005_termion_2.patch +2006_termion_3.patch +2007_termion_4.patch

