chore: Polish codebase, fix clippy warnings, correctly mark FFI functions as unsafe

This commit is contained in:
katR 2026-09-01 20:38:40 +05:30
parent ad509c439b
commit 47e4d952ae
10 changed files with 100 additions and 38 deletions

21
scratch/hk.patch Normal file
View file

@ -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(());
+ }
+ }
}
}

32
scratch/ui2.patch Normal file
View file

@ -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();
+ }
+ }
+ }
+ }
}

View file

@ -72,7 +72,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
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<dyn std::error::Error + Send + Sync>> {
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::<Command>(&payload) {
if stream.read_exact(&mut payload).is_ok()
&& let Ok(cmd) = serde_json::from_slice::<Command>(&payload) {
match cmd {
Command::SaveReplay => {
let _ = trigger_tx.try_send(());
@ -122,7 +122,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
_ => {}
}
}
}
}
}
Err(err) => {

View file

@ -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<dyn std::error::Error + Send + Sync>> {
fn send_command(cmd: Command) -> Result<(), Box<dyn std::error::Error>> {
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<dyn std::error::Error + Send + S
fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
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<dyn std::error::Error + Send + Sync>> {
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<dyn std::error::Error + Send + Sync>> {
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();
}
}
}
}
}

View file

@ -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,

View file

@ -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);
}

View file

@ -10,13 +10,10 @@ pub fn run_hotkey_listener(trigger_tx: Sender<()>) -> Result<(), Box<dyn std::er
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()
&& event.id == hotkey.id() && event.state == global_hotkey::HotKeyState::Pressed {
println!("Hotkey triggered! Saving replay...");
let _ = trigger_tx.send(());
}
}
}
}

22
src/hotkey.rs.orig Normal file
View file

@ -0,0 +1,22 @@
use global_hotkey::{GlobalHotKeyManager, hotkey::{HotKey, Modifiers, Code}, GlobalHotKeyEvent};
use crossbeam_channel::Sender;
pub fn run_hotkey_listener(trigger_tx: Sender<()>) -> Result<(), Box<dyn std::error::Error>> {
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(());
}
}
}
}
}

View file

@ -7,7 +7,7 @@ pub struct Muxer {
}
impl Muxer {
pub fn new(path: &str, codec_ctx: *mut AVCodecContext) -> Result<Self, String> {
pub unsafe fn new(path: &str, codec_ctx: *mut AVCodecContext) -> Result<Self, String> {
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);

View file

@ -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
}
}
}