diff --git a/scratch/hk.patch b/scratch/hk.patch new file mode 100644 index 0000000..357749f --- /dev/null +++ b/scratch/hk.patch @@ -0,0 +1,21 @@ +--- src/hotkey.rs ++++ src/hotkey.rs +@@ -11,10 +11,6 @@ + let receiver = GlobalHotKeyEvent::receiver(); + loop { +- if let Ok(event) = receiver.recv() { +- if event.id == hotkey.id() { +- if event.state == global_hotkey::HotKeyState::Pressed { +- println!("Hotkey triggered! Saving replay..."); +- let _ = trigger_tx.send(()); +- } +- } +- } ++ if let Ok(event) = receiver.recv() { ++ if event.id == hotkey.id() && event.state == global_hotkey::HotKeyState::Pressed { ++ println!("Hotkey triggered! Saving replay..."); ++ let _ = trigger_tx.send(()); ++ } ++ } + } + } diff --git a/scratch/ui2.patch b/scratch/ui2.patch new file mode 100644 index 0000000..3a98140 --- /dev/null +++ b/scratch/ui2.patch @@ -0,0 +1,32 @@ +--- src/bin/vrec-ui.rs ++++ src/bin/vrec-ui.rs +@@ -40,14 +40,10 @@ + let receiver = GlobalHotKeyEvent::receiver(); + loop { +- if let Ok(event) = receiver.recv() { +- if event.id == hotkey.id() { +- if event.state == global_hotkey::HotKeyState::Pressed { +- println!("Hotkey triggered! Sending SaveReplay command to daemon..."); +- if let Err(e) = send_command(Command::SaveReplay) { +- eprintln!("Failed to communicate with daemon: {}", e); +- } else { +- if env::var("XDG_SESSION_TYPE").unwrap_or_else(|_| "x11".to_string()).to_lowercase() != "wayland" { +- vrec::overlay::show_saved_overlay(); +- } +- } +- } +- } +- } ++ if let Ok(event) = receiver.recv() { ++ if event.id == hotkey.id() && event.state == global_hotkey::HotKeyState::Pressed { ++ println!("Hotkey triggered! Sending SaveReplay command to daemon..."); ++ if let Err(e) = send_command(Command::SaveReplay) { ++ eprintln!("Failed to communicate with daemon: {}", e); ++ } else { ++ if env::var("XDG_SESSION_TYPE").unwrap_or_else(|_| "x11".to_string()).to_lowercase() != "wayland" { ++ vrec::overlay::show_saved_overlay(); ++ } ++ } ++ } ++ } + } diff --git a/src/bin/vrec-daemon.rs b/src/bin/vrec-daemon.rs index 6430575..f74481f 100644 --- a/src/bin/vrec-daemon.rs +++ b/src/bin/vrec-daemon.rs @@ -72,7 +72,7 @@ async fn main() -> Result<(), Box> { if start_idx < drain.len() { let codec_ctx = codec_ctx_ptr as *mut ffmpeg_next::ffi::AVCodecContext; - let mut muxer = Muxer::new("output.mp4", codec_ctx).unwrap(); + let mut muxer = unsafe { Muxer::new("output.mp4", codec_ctx).unwrap() }; for p in drain.into_iter().skip(start_idx) { let _ = muxer.write_packet(&p); } @@ -110,8 +110,8 @@ async fn main() -> Result<(), Box> { if stream.read_exact(&mut len_buf).is_ok() { let len = u32::from_le_bytes(len_buf) as usize; let mut payload = vec![0u8; len]; - if stream.read_exact(&mut payload).is_ok() { - if let Ok(cmd) = serde_json::from_slice::(&payload) { + if stream.read_exact(&mut payload).is_ok() + && let Ok(cmd) = serde_json::from_slice::(&payload) { match cmd { Command::SaveReplay => { let _ = trigger_tx.try_send(()); @@ -122,7 +122,6 @@ async fn main() -> Result<(), Box> { _ => {} } } - } } } Err(err) => { diff --git a/src/bin/vrec-ui.rs b/src/bin/vrec-ui.rs index dbdca63..df4df24 100644 --- a/src/bin/vrec-ui.rs +++ b/src/bin/vrec-ui.rs @@ -4,7 +4,7 @@ use std::io::Write; use std::env; use global_hotkey::{GlobalHotKeyManager, hotkey::{HotKey, Modifiers, Code}, GlobalHotKeyEvent}; -fn send_command(cmd: Command) -> Result<(), Box> { +fn send_command(cmd: Command) -> Result<(), Box> { let socket_path = format!("{}/vrec.sock", env::var("XDG_RUNTIME_DIR").unwrap_or_else(|_| "/tmp".to_string())); let mut stream = UnixStream::connect(&socket_path)?; let payload = serde_json::to_vec(&cmd)?; @@ -17,7 +17,6 @@ fn send_command(cmd: Command) -> Result<(), Box Result<(), Box> { println!("Starting vrec UI/Hotkey process..."); - // Check session type let session_type = env::var("XDG_SESSION_TYPE").unwrap_or_else(|_| "x11".to_string()); let desktop = env::var("XDG_CURRENT_DESKTOP").unwrap_or_else(|_| "".to_string()).to_lowercase(); @@ -35,7 +34,7 @@ fn main() -> Result<(), Box> { println!("X11 session detected. (X11 override-redirect overlay would be spawned here)."); } - let manager = GlobalHotKeyManager::new()?; + let manager = GlobalHotKeyManager::new().unwrap(); let hotkey = HotKey::new(Some(Modifiers::CONTROL | Modifiers::SHIFT), Code::KeyR); if let Err(e) = manager.register(hotkey) { @@ -47,19 +46,14 @@ fn main() -> Result<(), Box> { let receiver = GlobalHotKeyEvent::receiver(); loop { - if let Ok(event) = receiver.recv() { - if event.id == hotkey.id() { - if event.state == global_hotkey::HotKeyState::Pressed { - println!("Hotkey triggered! Sending SaveReplay command to daemon..."); - if let Err(e) = send_command(Command::SaveReplay) { - eprintln!("Failed to communicate with daemon: {}", e); - } else { - if env::var("XDG_SESSION_TYPE").unwrap_or_else(|_| "x11".to_string()).to_lowercase() != "wayland" { - vrec::overlay::show_saved_overlay(); - } - } + if let Ok(event) = receiver.recv() + && event.id == hotkey.id() && event.state == global_hotkey::HotKeyState::Pressed { + println!("Hotkey triggered! Sending SaveReplay command to daemon..."); + if let Err(e) = send_command(Command::SaveReplay) { + eprintln!("Failed to communicate with daemon: {}", e); + } else if env::var("XDG_SESSION_TYPE").unwrap_or_else(|_| "x11".to_string()).to_lowercase() != "wayland" { + vrec::overlay::show_saved_overlay(); } } - } } } diff --git a/src/capture/wayland.rs b/src/capture/wayland.rs index 3e26732..bd16b2c 100644 --- a/src/capture/wayland.rs +++ b/src/capture/wayland.rs @@ -1,7 +1,6 @@ use crate::capture::{Frame, FrameSource}; use ashpd::desktop::screencast::{CursorMode, Screencast, SourceType}; use ashpd::desktop::PersistMode; -use std::os::unix::io::{RawFd, IntoRawFd}; pub struct WaylandCapture { stream: crate::capture::wayland_stream::PipeWireStream, diff --git a/src/capture/wayland_stream.rs b/src/capture/wayland_stream.rs index 3e52c31..0a36800 100644 --- a/src/capture/wayland_stream.rs +++ b/src/capture/wayland_stream.rs @@ -76,12 +76,12 @@ impl PipeWireStream { // To properly handle DMA-BUFs, we would read the spa_data chunk and extract the fd // For this MVP skeleton, we will push a mock DmaBuf to satisfy the pipeline let frame = Frame::DmaBuf { - width: user_data.format.size().width as u32, - height: user_data.format.size().height as u32, + width: user_data.format.size().width, + height: user_data.format.size().height, format: 0, - fd: data.fd() as i32, + fd: data.fd(), stride: data.chunk().stride() as u32, - offset: data.chunk().offset() as u32, + offset: data.chunk().offset(), }; let _ = user_data.tx.try_send(frame); } diff --git a/src/hotkey.rs b/src/hotkey.rs index febde6b..4a75231 100644 --- a/src/hotkey.rs +++ b/src/hotkey.rs @@ -10,13 +10,10 @@ pub fn run_hotkey_listener(trigger_tx: Sender<()>) -> Result<(), Box) -> Result<(), Box> { + let manager = GlobalHotKeyManager::new()?; + let hotkey = HotKey::new(Some(Modifiers::CONTROL | Modifiers::SHIFT), Code::KeyR); + manager.register(hotkey)?; + + println!("Registered global hotkey Ctrl+Shift+R to trigger replay save."); + + let receiver = GlobalHotKeyEvent::receiver(); + loop { + if let Ok(event) = receiver.recv() { + if event.id == hotkey.id() { + if event.state == global_hotkey::HotKeyState::Pressed { + println!("Hotkey triggered! Saving replay..."); + let _ = trigger_tx.send(()); + } + } + } + } +} diff --git a/src/muxer.rs b/src/muxer.rs index a13754b..7d687ae 100644 --- a/src/muxer.rs +++ b/src/muxer.rs @@ -7,7 +7,7 @@ pub struct Muxer { } impl Muxer { - pub fn new(path: &str, codec_ctx: *mut AVCodecContext) -> Result { + pub unsafe fn new(path: &str, codec_ctx: *mut AVCodecContext) -> Result { unsafe { let path_cstr = CString::new(path).unwrap(); let mut fmt_ctx: *mut AVFormatContext = std::ptr::null_mut(); @@ -27,8 +27,8 @@ impl Muxer { return Err("Failed to copy codec parameters".into()); } - if ((*(*fmt_ctx).oformat).flags & AVFMT_NOFILE as i32) == 0 { - let ret = avio_open(&mut (*fmt_ctx).pb, path_cstr.as_ptr(), AVIO_FLAG_WRITE as i32); + if ((*(*fmt_ctx).oformat).flags & AVFMT_NOFILE) == 0 { + let ret = avio_open(&mut (*fmt_ctx).pb, path_cstr.as_ptr(), AVIO_FLAG_WRITE); if ret < 0 { return Err("Failed to open file".into()); } @@ -73,7 +73,7 @@ impl Muxer { impl Drop for Muxer { fn drop(&mut self) { unsafe { - if ((*(*self.fmt_ctx).oformat).flags & AVFMT_NOFILE as i32) == 0 { + if ((*(*self.fmt_ctx).oformat).flags & AVFMT_NOFILE) == 0 { avio_closep(&mut (*self.fmt_ctx).pb); } avformat_free_context(self.fmt_ctx); diff --git a/src/ring.rs b/src/ring.rs index 9a4eea0..384c69a 100644 --- a/src/ring.rs +++ b/src/ring.rs @@ -1,5 +1,3 @@ -use ringbuf::traits::{Producer, Consumer, Split}; -use ringbuf::HeapRb; use ffmpeg_next::ffi::*; pub struct Packet { @@ -16,7 +14,7 @@ impl Packet { pub fn is_keyframe(&self) -> bool { unsafe { - ((*self.ptr).flags & AV_PKT_FLAG_KEY as i32) != 0 + ((*self.ptr).flags & AV_PKT_FLAG_KEY) != 0 } } }