I did a bit of research to understand why I could not use my mouse to drag to select text to copy to the clipboard in iTerm. Apparently https://github.com/openai/codex/pull/641 to enable mousewheel scrolling broke this functionality. It seems that, unless we put in a bit of effort, we can have drag-to-select or scrolling, but not both. Though if you know the trick to hold down `Option` will dragging with the mouse in iTerm, you can probably get by with this. (I did not know about this option prior to researching this issue.) Nevertheless, users may still prefer to disable mouse capture altogether, so this PR introduces: * the ability to set `tui.disable_mouse_capture = true` in `config.toml` to disable mouse capture * a new command, `/toggle-mouse-mode` to toggle mouse capture
70 lines
1.7 KiB
Rust
70 lines
1.7 KiB
Rust
use crossterm::event::DisableMouseCapture;
|
|
use crossterm::event::EnableMouseCapture;
|
|
use ratatui::crossterm::execute;
|
|
use std::io::Result;
|
|
use std::io::stdout;
|
|
|
|
pub(crate) struct MouseCapture {
|
|
mouse_capture_is_active: bool,
|
|
}
|
|
|
|
impl MouseCapture {
|
|
pub(crate) fn new_with_capture(mouse_capture_is_active: bool) -> Result<Self> {
|
|
if mouse_capture_is_active {
|
|
enable_capture()?;
|
|
}
|
|
|
|
Ok(Self {
|
|
mouse_capture_is_active,
|
|
})
|
|
}
|
|
}
|
|
|
|
impl MouseCapture {
|
|
/// Idempotent method to set the mouse capture state.
|
|
pub fn set_active(&mut self, is_active: bool) -> Result<()> {
|
|
match (self.mouse_capture_is_active, is_active) {
|
|
(true, true) => {}
|
|
(false, false) => {}
|
|
(true, false) => {
|
|
disable_capture()?;
|
|
self.mouse_capture_is_active = false;
|
|
}
|
|
(false, true) => {
|
|
enable_capture()?;
|
|
self.mouse_capture_is_active = true;
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub(crate) fn toggle(&mut self) -> Result<()> {
|
|
self.set_active(!self.mouse_capture_is_active)
|
|
}
|
|
|
|
pub(crate) fn disable(&mut self) -> Result<()> {
|
|
if self.mouse_capture_is_active {
|
|
disable_capture()?;
|
|
self.mouse_capture_is_active = false;
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl Drop for MouseCapture {
|
|
fn drop(&mut self) {
|
|
if self.disable().is_err() {
|
|
// The user is likely shutting down, so ignore any errors so the
|
|
// shutdown process can complete.
|
|
}
|
|
}
|
|
}
|
|
|
|
fn enable_capture() -> Result<()> {
|
|
execute!(stdout(), EnableMouseCapture)
|
|
}
|
|
|
|
fn disable_capture() -> Result<()> {
|
|
execute!(stdout(), DisableMouseCapture)
|
|
}
|