Remove lazy_static dependency (#530)
This commit is contained in:
parent
df0c2358fd
commit
1418580fed
@ -34,7 +34,6 @@ event-stream = ["futures-core"]
|
|||||||
#
|
#
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags = "1.2"
|
bitflags = "1.2"
|
||||||
lazy_static = "1.4"
|
|
||||||
parking_lot = "0.11"
|
parking_lot = "0.11"
|
||||||
|
|
||||||
# optional deps only added when requested
|
# optional deps only added when requested
|
||||||
|
@ -144,8 +144,7 @@ features = ["event-stream"]
|
|||||||
| Dependency | Used for | Included |
|
| Dependency | Used for | Included |
|
||||||
| :----- | :----- | :-----
|
| :----- | :----- | :-----
|
||||||
| `bitflags` | `KeyModifiers`, those are differ based on input.| always
|
| `bitflags` | `KeyModifiers`, those are differ based on input.| always
|
||||||
| `lazy_static` | original console color, original terminal mode, saved cursor position, supports ANSI on windows, single event reader per application.| always
|
| `parking_lot` | locking `RwLock`s with a timeout, const mutexes. | always
|
||||||
| `parking_lot` | used for an RW LOCK. | always
|
|
||||||
| `libc` | UNIX terminal_size/raw modes/set_title and several other lowlevel functionality. | UNIX only
|
| `libc` | UNIX terminal_size/raw modes/set_title and several other lowlevel functionality. | UNIX only
|
||||||
| `Mio` | event readiness polling, waking up poller | UNIX only
|
| `Mio` | event readiness polling, waking up poller | UNIX only
|
||||||
| `signal-hook`| signalhook is used to handle terminal resize SIGNAL with Mio. | UNIX only
|
| `signal-hook`| signalhook is used to handle terminal resize SIGNAL with Mio. | UNIX only
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
use crossterm_winapi::{ConsoleMode, Handle};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use winapi::um::wincon::ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
|
||||||
|
|
||||||
use lazy_static::lazy_static;
|
use crossterm_winapi::{ConsoleMode, Handle};
|
||||||
|
use parking_lot::Once;
|
||||||
|
use winapi::um::wincon::ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||||
|
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
@ -27,17 +28,21 @@ fn enable_vt_processing() -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
static SUPPORTS_ANSI_ESCAPE_CODES: AtomicBool = AtomicBool::new(false);
|
||||||
static ref SUPPORTS_ANSI_ESCAPE_CODES: bool = {
|
static INITIALIZER: Once = Once::new();
|
||||||
|
|
||||||
|
/// Checks if the current terminal supports ansi escape sequences
|
||||||
|
pub fn supports_ansi() -> bool {
|
||||||
|
INITIALIZER.call_once(|| {
|
||||||
// Some terminals on Windows like GitBash can't use WinAPI calls directly
|
// Some terminals on Windows like GitBash can't use WinAPI calls directly
|
||||||
// so when we try to enable the ANSI-flag for Windows this won't work.
|
// so when we try to enable the ANSI-flag for Windows this won't work.
|
||||||
// Because of that we should check first if the TERM-variable is set
|
// Because of that we should check first if the TERM-variable is set
|
||||||
// and see if the current terminal is a terminal who does support ANSI.
|
// and see if the current terminal is a terminal who does support ANSI.
|
||||||
std::env::var("TERM").map_or(false, |term| term != "dumb") || enable_vt_processing().is_ok()
|
let supported = std::env::var("TERM").map_or(false, |term| term != "dumb")
|
||||||
};
|
|| enable_vt_processing().is_ok();
|
||||||
}
|
|
||||||
|
|
||||||
/// Checks if the current terminal supports ansi escape sequences
|
SUPPORTS_ANSI_ESCAPE_CODES.store(supported, Ordering::SeqCst);
|
||||||
pub fn supports_ansi() -> bool {
|
});
|
||||||
*SUPPORTS_ANSI_ESCAPE_CODES
|
|
||||||
|
SUPPORTS_ANSI_ESCAPE_CODES.load(Ordering::SeqCst)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
//! WinAPI related logic to cursor manipulation.
|
//! WinAPI related logic to cursor manipulation.
|
||||||
|
|
||||||
use std::{io, sync::Mutex};
|
use std::convert::TryFrom;
|
||||||
|
use std::io;
|
||||||
|
use std::sync::atomic::{AtomicU64, Ordering};
|
||||||
|
|
||||||
use crossterm_winapi::{is_true, Coord, Handle, HandleType, ScreenBuffer};
|
use crossterm_winapi::{is_true, Coord, Handle, HandleType, ScreenBuffer};
|
||||||
use winapi::{
|
use winapi::{
|
||||||
@ -8,13 +10,13 @@ use winapi::{
|
|||||||
um::wincon::{SetConsoleCursorInfo, SetConsoleCursorPosition, CONSOLE_CURSOR_INFO, COORD},
|
um::wincon::{SetConsoleCursorInfo, SetConsoleCursorPosition, CONSOLE_CURSOR_INFO, COORD},
|
||||||
};
|
};
|
||||||
|
|
||||||
use lazy_static::lazy_static;
|
|
||||||
|
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
lazy_static! {
|
/// The position of the cursor, written when you save the cursor's position.
|
||||||
static ref SAVED_CURSOR_POS: Mutex<Option<(i16, i16)>> = Mutex::new(None);
|
///
|
||||||
}
|
/// This is `u64::MAX` initially. Otherwise, it stores the cursor's x position bit-shifted left 16
|
||||||
|
/// times or-ed with the cursor's y position, where both are `i16`s.
|
||||||
|
static SAVED_CURSOR_POS: AtomicU64 = AtomicU64::new(u64::MAX);
|
||||||
|
|
||||||
// The 'y' position of the cursor is not relative to the window but absolute to screen buffer.
|
// The 'y' position of the cursor is not relative to the window but absolute to screen buffer.
|
||||||
// We can calculate the relative cursor position by subtracting the top position of the terminal window from the y position.
|
// We can calculate the relative cursor position by subtracting the top position of the terminal window from the y position.
|
||||||
@ -176,7 +178,9 @@ impl ScreenBufferCursor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn restore_position(&self) -> Result<()> {
|
fn restore_position(&self) -> Result<()> {
|
||||||
if let Some((x, y)) = *SAVED_CURSOR_POS.lock().unwrap() {
|
if let Ok(val) = u32::try_from(SAVED_CURSOR_POS.load(Ordering::Relaxed)) {
|
||||||
|
let x = (val >> 16) as i16;
|
||||||
|
let y = val as i16;
|
||||||
self.move_to(x, y)?;
|
self.move_to(x, y)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,8 +190,8 @@ impl ScreenBufferCursor {
|
|||||||
fn save_position(&self) -> Result<()> {
|
fn save_position(&self) -> Result<()> {
|
||||||
let position = self.position()?;
|
let position = self.position()?;
|
||||||
|
|
||||||
let mut locked_pos = SAVED_CURSOR_POS.lock().unwrap();
|
let bits = u64::from(u32::from(position.x as u16) << 16 | u32::from(position.y as u16));
|
||||||
*locked_pos = Some((position.x, position.y));
|
SAVED_CURSOR_POS.store(bits, Ordering::Relaxed);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
33
src/event.rs
33
src/event.rs
@ -75,16 +75,17 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use parking_lot::RwLock;
|
use bitflags::bitflags;
|
||||||
|
use parking_lot::{MappedMutexGuard, Mutex, MutexGuard};
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{Command, Result};
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
use crate::{csi, Command, Result};
|
|
||||||
|
|
||||||
use filter::{EventFilter, Filter};
|
use filter::{EventFilter, Filter};
|
||||||
|
use read::InternalEventReader;
|
||||||
#[cfg(feature = "event-stream")]
|
#[cfg(feature = "event-stream")]
|
||||||
pub use stream::EventStream;
|
pub use stream::EventStream;
|
||||||
use timeout::PollTimeout;
|
use timeout::PollTimeout;
|
||||||
@ -97,10 +98,22 @@ mod stream;
|
|||||||
pub(crate) mod sys;
|
pub(crate) mod sys;
|
||||||
mod timeout;
|
mod timeout;
|
||||||
|
|
||||||
lazy_static! {
|
/// Static instance of `InternalEventReader`.
|
||||||
/// Static instance of `InternalEventReader`.
|
/// This needs to be static because there can be one event reader.
|
||||||
/// This needs to be static because there can be one event reader.
|
static INTERNAL_EVENT_READER: Mutex<Option<InternalEventReader>> = parking_lot::const_mutex(None);
|
||||||
static ref INTERNAL_EVENT_READER: RwLock<read::InternalEventReader> = RwLock::new(read::InternalEventReader::default());
|
|
||||||
|
fn lock_internal_event_reader() -> MappedMutexGuard<'static, InternalEventReader> {
|
||||||
|
MutexGuard::map(INTERNAL_EVENT_READER.lock(), |reader| {
|
||||||
|
reader.get_or_insert_with(InternalEventReader::default)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fn try_lock_internal_event_reader_for(
|
||||||
|
duration: Duration,
|
||||||
|
) -> Option<MappedMutexGuard<'static, InternalEventReader>> {
|
||||||
|
Some(MutexGuard::map(
|
||||||
|
INTERNAL_EVENT_READER.try_lock_for(duration)?,
|
||||||
|
|reader| reader.get_or_insert_with(InternalEventReader::default),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if there is an [`Event`](enum.Event.html) available.
|
/// Checks if there is an [`Event`](enum.Event.html) available.
|
||||||
@ -201,13 +214,13 @@ where
|
|||||||
{
|
{
|
||||||
let (mut reader, timeout) = if let Some(timeout) = timeout {
|
let (mut reader, timeout) = if let Some(timeout) = timeout {
|
||||||
let poll_timeout = PollTimeout::new(Some(timeout));
|
let poll_timeout = PollTimeout::new(Some(timeout));
|
||||||
if let Some(reader) = INTERNAL_EVENT_READER.try_write_for(timeout) {
|
if let Some(reader) = try_lock_internal_event_reader_for(timeout) {
|
||||||
(reader, poll_timeout.leftover())
|
(reader, poll_timeout.leftover())
|
||||||
} else {
|
} else {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
(INTERNAL_EVENT_READER.write(), None)
|
(lock_internal_event_reader(), None)
|
||||||
};
|
};
|
||||||
reader.poll(timeout, filter)
|
reader.poll(timeout, filter)
|
||||||
}
|
}
|
||||||
@ -217,7 +230,7 @@ pub(crate) fn read_internal<F>(filter: &F) -> Result<InternalEvent>
|
|||||||
where
|
where
|
||||||
F: Filter,
|
F: Filter,
|
||||||
{
|
{
|
||||||
let mut reader = INTERNAL_EVENT_READER.write();
|
let mut reader = lock_internal_event_reader();
|
||||||
reader.read(filter)
|
reader.read(filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,8 @@ use futures_core::stream::Stream;
|
|||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
filter::EventFilter, poll_internal, read_internal, sys::Waker, Event, InternalEvent,
|
filter::EventFilter, lock_internal_event_reader, poll_internal, read_internal, sys::Waker,
|
||||||
INTERNAL_EVENT_READER,
|
Event, InternalEvent,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A stream of `Result<Event>`.
|
/// A stream of `Result<Event>`.
|
||||||
@ -60,7 +60,7 @@ impl Default for EventStream {
|
|||||||
});
|
});
|
||||||
|
|
||||||
EventStream {
|
EventStream {
|
||||||
poll_internal_waker: INTERNAL_EVENT_READER.write().waker(),
|
poll_internal_waker: lock_internal_event_reader().waker(),
|
||||||
stream_wake_task_executed: Arc::new(AtomicBool::new(false)),
|
stream_wake_task_executed: Arc::new(AtomicBool::new(false)),
|
||||||
stream_wake_task_should_shutdown: Arc::new(AtomicBool::new(false)),
|
stream_wake_task_should_shutdown: Arc::new(AtomicBool::new(false)),
|
||||||
task_sender,
|
task_sender,
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
//! This is a WINDOWS specific implementation for input related action.
|
//! This is a WINDOWS specific implementation for input related action.
|
||||||
|
|
||||||
use std::sync::Mutex;
|
use std::convert::TryFrom;
|
||||||
|
use std::sync::atomic::{AtomicU64, Ordering};
|
||||||
|
|
||||||
use crossterm_winapi::{ConsoleMode, Handle};
|
use crossterm_winapi::{ConsoleMode, Handle};
|
||||||
use lazy_static::lazy_static;
|
|
||||||
|
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
@ -15,25 +15,24 @@ pub(crate) mod poll;
|
|||||||
|
|
||||||
const ENABLE_MOUSE_MODE: u32 = 0x0010 | 0x0080 | 0x0008;
|
const ENABLE_MOUSE_MODE: u32 = 0x0010 | 0x0080 | 0x0008;
|
||||||
|
|
||||||
lazy_static! {
|
/// This is a either `u64::MAX` if it's uninitialized or a valid `u32` that stores the original
|
||||||
static ref ORIGINAL_CONSOLE_MODE: Mutex<Option<u32>> = Mutex::new(None);
|
/// console mode if it's initialized.
|
||||||
}
|
static ORIGINAL_CONSOLE_MODE: AtomicU64 = AtomicU64::new(u64::MAX);
|
||||||
|
|
||||||
/// Initializes the default console color. It will will be skipped if it has already been initialized.
|
/// Initializes the default console color. It will will be skipped if it has already been initialized.
|
||||||
fn init_original_console_mode(original_mode: u32) {
|
fn init_original_console_mode(original_mode: u32) {
|
||||||
let mut lock = ORIGINAL_CONSOLE_MODE.lock().unwrap();
|
let _ = ORIGINAL_CONSOLE_MODE.compare_exchange(
|
||||||
|
u64::MAX,
|
||||||
if lock.is_none() {
|
u64::from(original_mode),
|
||||||
*lock = Some(original_mode);
|
Ordering::Relaxed,
|
||||||
}
|
Ordering::Relaxed,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the original console color, make sure to call `init_console_color` before calling this function. Otherwise this function will panic.
|
/// Returns the original console color, make sure to call `init_console_color` before calling this function. Otherwise this function will panic.
|
||||||
fn original_console_mode() -> u32 {
|
fn original_console_mode() -> u32 {
|
||||||
|
u32::try_from(ORIGINAL_CONSOLE_MODE.load(Ordering::Relaxed))
|
||||||
// safe unwrap, initial console color was set with `init_console_color` in `WinApiColor::new()`
|
// safe unwrap, initial console color was set with `init_console_color` in `WinApiColor::new()`
|
||||||
ORIGINAL_CONSOLE_MODE
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.expect("Original console mode not set")
|
.expect("Original console mode not set")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
use std::sync::Mutex;
|
use std::convert::TryFrom;
|
||||||
|
use std::sync::atomic::{AtomicU32, Ordering};
|
||||||
|
|
||||||
use crossterm_winapi::{Console, Handle, HandleType, ScreenBuffer};
|
use crossterm_winapi::{Console, Handle, HandleType, ScreenBuffer};
|
||||||
use winapi::um::wincon;
|
use winapi::um::wincon;
|
||||||
|
|
||||||
use lazy_static::lazy_static;
|
|
||||||
|
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
use super::super::{Color, Colored};
|
use super::super::{Color, Colored};
|
||||||
@ -70,7 +69,7 @@ pub(crate) fn set_background_color(bg_color: Color) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn reset() -> Result<()> {
|
pub(crate) fn reset() -> Result<()> {
|
||||||
if let Some(original_color) = *ORIGINAL_CONSOLE_COLOR.lock().unwrap() {
|
if let Ok(original_color) = u16::try_from(ORIGINAL_CONSOLE_COLOR.load(Ordering::Relaxed)) {
|
||||||
Console::from(Handle::new(HandleType::CurrentOutputHandle)?)
|
Console::from(Handle::new(HandleType::CurrentOutputHandle)?)
|
||||||
.set_text_attribute(original_color)?;
|
.set_text_attribute(original_color)?;
|
||||||
}
|
}
|
||||||
@ -80,12 +79,10 @@ pub(crate) fn reset() -> Result<()> {
|
|||||||
|
|
||||||
/// Initializes the default console color. It will will be skipped if it has already been initialized.
|
/// Initializes the default console color. It will will be skipped if it has already been initialized.
|
||||||
pub(crate) fn init_console_color() -> Result<()> {
|
pub(crate) fn init_console_color() -> Result<()> {
|
||||||
let mut locked_pos = ORIGINAL_CONSOLE_COLOR.lock().unwrap();
|
if ORIGINAL_CONSOLE_COLOR.load(Ordering::Relaxed) == u32::MAX {
|
||||||
|
|
||||||
if locked_pos.is_none() {
|
|
||||||
let screen_buffer = ScreenBuffer::current()?;
|
let screen_buffer = ScreenBuffer::current()?;
|
||||||
let attr = screen_buffer.info()?.attributes();
|
let attr = screen_buffer.info()?.attributes();
|
||||||
*locked_pos = Some(attr);
|
ORIGINAL_CONSOLE_COLOR.store(u32::from(attr), Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -93,16 +90,14 @@ pub(crate) fn init_console_color() -> Result<()> {
|
|||||||
|
|
||||||
/// Returns the original console color, make sure to call `init_console_color` before calling this function. Otherwise this function will panic.
|
/// Returns the original console color, make sure to call `init_console_color` before calling this function. Otherwise this function will panic.
|
||||||
pub(crate) fn original_console_color() -> u16 {
|
pub(crate) fn original_console_color() -> u16 {
|
||||||
|
u16::try_from(ORIGINAL_CONSOLE_COLOR.load(Ordering::Relaxed))
|
||||||
// safe unwrap, initial console color was set with `init_console_color` in `WinApiColor::new()`
|
// safe unwrap, initial console color was set with `init_console_color` in `WinApiColor::new()`
|
||||||
ORIGINAL_CONSOLE_COLOR
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.expect("Initial console color not set")
|
.expect("Initial console color not set")
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
// This is either a valid u16 in which case it stores the original console color or it is u32::MAX
|
||||||
static ref ORIGINAL_CONSOLE_COLOR: Mutex<Option<u16>> = Mutex::new(None);
|
// in which case it is uninitialized.
|
||||||
}
|
static ORIGINAL_CONSOLE_COLOR: AtomicU32 = AtomicU32::new(u32::MAX);
|
||||||
|
|
||||||
impl From<Colored> for u16 {
|
impl From<Colored> for u16 {
|
||||||
/// Returns the WinAPI color value (u16) from the `Colored` struct.
|
/// Returns the WinAPI color value (u16) from the `Colored` struct.
|
||||||
@ -180,6 +175,8 @@ impl From<Colored> for u16 {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
use crate::style::sys::windows::set_foreground_color;
|
use crate::style::sys::windows::set_foreground_color;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@ -200,11 +197,11 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_original_console_color_is_set() {
|
fn test_original_console_color_is_set() {
|
||||||
assert!(ORIGINAL_CONSOLE_COLOR.lock().unwrap().is_none());
|
assert_eq!(ORIGINAL_CONSOLE_COLOR.load(Ordering::Relaxed), u32::MAX);
|
||||||
|
|
||||||
// will call `init_console_color`
|
// will call `init_console_color`
|
||||||
set_foreground_color(Color::Blue).unwrap();
|
set_foreground_color(Color::Blue).unwrap();
|
||||||
|
|
||||||
assert!(ORIGINAL_CONSOLE_COLOR.lock().unwrap().is_some());
|
assert_ne!(ORIGINAL_CONSOLE_COLOR.load(Ordering::Relaxed), u32::MAX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,25 +2,23 @@
|
|||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::os::unix::io::{IntoRawFd, RawFd};
|
use std::os::unix::io::{IntoRawFd, RawFd};
|
||||||
use std::{io, mem, process, sync::Mutex};
|
use std::{io, mem, process};
|
||||||
|
|
||||||
use lazy_static::lazy_static;
|
|
||||||
use libc::{
|
use libc::{
|
||||||
cfmakeraw, ioctl, tcgetattr, tcsetattr, termios as Termios, winsize, STDOUT_FILENO, TCSANOW,
|
cfmakeraw, ioctl, tcgetattr, tcsetattr, termios as Termios, winsize, STDOUT_FILENO, TCSANOW,
|
||||||
TIOCGWINSZ,
|
TIOCGWINSZ,
|
||||||
};
|
};
|
||||||
|
use parking_lot::Mutex;
|
||||||
|
|
||||||
use crate::error::{ErrorKind, Result};
|
use crate::error::{ErrorKind, Result};
|
||||||
use crate::event::sys::unix::file_descriptor::{tty_fd, FileDesc};
|
use crate::event::sys::unix::file_descriptor::{tty_fd, FileDesc};
|
||||||
|
|
||||||
lazy_static! {
|
// Some(Termios) -> we're in the raw mode and this is the previous mode
|
||||||
// Some(Termios) -> we're in the raw mode and this is the previous mode
|
// None -> we're not in the raw mode
|
||||||
// None -> we're not in the raw mode
|
static TERMINAL_MODE_PRIOR_RAW_MODE: Mutex<Option<Termios>> = parking_lot::const_mutex(None);
|
||||||
static ref TERMINAL_MODE_PRIOR_RAW_MODE: Mutex<Option<Termios>> = Mutex::new(None);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn is_raw_mode_enabled() -> bool {
|
pub(crate) fn is_raw_mode_enabled() -> bool {
|
||||||
TERMINAL_MODE_PRIOR_RAW_MODE.lock().unwrap().is_some()
|
TERMINAL_MODE_PRIOR_RAW_MODE.lock().is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::useless_conversion)]
|
#[allow(clippy::useless_conversion)]
|
||||||
@ -49,7 +47,7 @@ pub(crate) fn size() -> Result<(u16, u16)> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn enable_raw_mode() -> Result<()> {
|
pub(crate) fn enable_raw_mode() -> Result<()> {
|
||||||
let mut original_mode = TERMINAL_MODE_PRIOR_RAW_MODE.lock().unwrap();
|
let mut original_mode = TERMINAL_MODE_PRIOR_RAW_MODE.lock();
|
||||||
|
|
||||||
if original_mode.is_some() {
|
if original_mode.is_some() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@ -70,7 +68,7 @@ pub(crate) fn enable_raw_mode() -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn disable_raw_mode() -> Result<()> {
|
pub(crate) fn disable_raw_mode() -> Result<()> {
|
||||||
let mut original_mode = TERMINAL_MODE_PRIOR_RAW_MODE.lock().unwrap();
|
let mut original_mode = TERMINAL_MODE_PRIOR_RAW_MODE.lock();
|
||||||
|
|
||||||
if let Some(original_mode_ios) = original_mode.as_ref() {
|
if let Some(original_mode_ios) = original_mode.as_ref() {
|
||||||
let tty = tty_fd()?;
|
let tty = tty_fd()?;
|
||||||
|
Loading…
Reference in New Issue
Block a user