style: cargo fmt --all — make codebase rustfmt-clean
Some checks failed
Build and Test / Build Server (Linux) (push) Failing after 2m59s
Build and Test / Build Agent (Windows) (push) Has started running
Build and Test / Security Audit (push) Has been cancelled
Build and Test / Build Summary (push) Has been cancelled
Run Tests / Test Server (push) Has been cancelled
Run Tests / Test Agent (push) Has been cancelled
Run Tests / Code Coverage (push) Has been cancelled
Run Tests / Lint and Format Check (push) Has been cancelled

First run of the build-and-test CI gate (cargo fmt --all -- --check) surfaced
pre-existing formatting drift across the agent and server crates. Apply rustfmt
across the workspace so the codebase meets its own CI gate. Pure formatting; no
logic changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-29 15:02:12 +00:00
parent f2e0456f8d
commit 1c5c1e78e7
48 changed files with 1174 additions and 797 deletions

View File

@@ -37,11 +37,11 @@ mod vk {
pub const VK_RSHIFT: u32 = 0xA1;
pub const VK_LCONTROL: u32 = 0xA2;
pub const VK_RCONTROL: u32 = 0xA3;
pub const VK_LMENU: u32 = 0xA4; // Left Alt
pub const VK_RMENU: u32 = 0xA5; // Right Alt
pub const VK_LMENU: u32 = 0xA4; // Left Alt
pub const VK_RMENU: u32 = 0xA5; // Right Alt
pub const VK_TAB: u32 = 0x09;
pub const VK_ESCAPE: u32 = 0x1B;
pub const VK_SNAPSHOT: u32 = 0x2C; // Print Screen
pub const VK_SNAPSHOT: u32 = 0x2C; // Print Screen
}
#[cfg(windows)]
@@ -53,15 +53,12 @@ pub struct KeyboardHook {
impl KeyboardHook {
pub fn new(input_tx: mpsc::Sender<InputEvent>) -> Result<Self> {
// Store the sender globally for the hook callback
INPUT_TX.set(input_tx).map_err(|_| anyhow::anyhow!("Input TX already set"))?;
INPUT_TX
.set(input_tx)
.map_err(|_| anyhow::anyhow!("Input TX already set"))?;
unsafe {
let hook = SetWindowsHookExW(
WH_KEYBOARD_LL,
Some(keyboard_hook_proc),
None,
0,
)?;
let hook = SetWindowsHookExW(WH_KEYBOARD_LL, Some(keyboard_hook_proc), None, 0)?;
HOOK_HANDLE = hook;
Ok(Self { _hook: hook })
@@ -82,11 +79,7 @@ impl Drop for KeyboardHook {
}
#[cfg(windows)]
unsafe extern "system" fn keyboard_hook_proc(
code: i32,
wparam: WPARAM,
lparam: LPARAM,
) -> LRESULT {
unsafe extern "system" fn keyboard_hook_proc(code: i32, wparam: WPARAM, lparam: LPARAM) -> LRESULT {
if code >= 0 {
let kb_struct = &*(lparam.0 as *const KBDLLHOOKSTRUCT);
let vk_code = kb_struct.vkCode;
@@ -97,10 +90,7 @@ unsafe extern "system" fn keyboard_hook_proc(
if is_down || is_up {
// Check if this is a key we want to intercept (Win key, Alt+Tab, etc.)
let should_intercept = matches!(
vk_code,
vk::VK_LWIN | vk::VK_RWIN | vk::VK_APPS
);
let should_intercept = matches!(vk_code, vk::VK_LWIN | vk::VK_RWIN | vk::VK_APPS);
// Send the key event to the remote
if let Some(tx) = INPUT_TX.get() {
@@ -114,7 +104,12 @@ unsafe extern "system" fn keyboard_hook_proc(
};
let _ = tx.try_send(InputEvent::Key(event));
trace!("Key hook: vk={:#x} scan={} down={}", vk_code, scan_code, is_down);
trace!(
"Key hook: vk={:#x} scan={} down={}",
vk_code,
scan_code,
is_down
);
}
// For Win key, consume the event so it doesn't open Start menu locally
@@ -133,12 +128,12 @@ fn get_current_modifiers() -> proto::Modifiers {
unsafe {
proto::Modifiers {
ctrl: GetAsyncKeyState(0x11) < 0, // VK_CONTROL
alt: GetAsyncKeyState(0x12) < 0, // VK_MENU
shift: GetAsyncKeyState(0x10) < 0, // VK_SHIFT
ctrl: GetAsyncKeyState(0x11) < 0, // VK_CONTROL
alt: GetAsyncKeyState(0x12) < 0, // VK_MENU
shift: GetAsyncKeyState(0x10) < 0, // VK_SHIFT
meta: GetAsyncKeyState(0x5B) < 0 || GetAsyncKeyState(0x5C) < 0, // VK_LWIN/RWIN
caps_lock: GetAsyncKeyState(0x14) & 1 != 0, // VK_CAPITAL
num_lock: GetAsyncKeyState(0x90) & 1 != 0, // VK_NUMLOCK
num_lock: GetAsyncKeyState(0x90) & 1 != 0, // VK_NUMLOCK
}
}
}

View File

@@ -11,7 +11,7 @@ use crate::proto;
use anyhow::Result;
use std::sync::Arc;
use tokio::sync::{mpsc, Mutex};
use tracing::{info, error, warn};
use tracing::{error, info, warn};
#[derive(Debug, Clone)]
pub enum ViewerEvent {
@@ -93,16 +93,18 @@ pub async fn run(server_url: &str, session_id: &str, api_key: &str) -> Result<()
}
}
Some(proto::message::Payload::CursorPosition(pos)) => {
let _ = viewer_tx_recv.send(ViewerEvent::CursorPosition(
pos.x, pos.y, pos.visible
)).await;
let _ = viewer_tx_recv
.send(ViewerEvent::CursorPosition(pos.x, pos.y, pos.visible))
.await;
}
Some(proto::message::Payload::CursorShape(shape)) => {
let _ = viewer_tx_recv.send(ViewerEvent::CursorShape(shape)).await;
}
Some(proto::message::Payload::Disconnect(d)) => {
warn!("Server disconnected: {}", d.reason);
let _ = viewer_tx_recv.send(ViewerEvent::Disconnected(d.reason)).await;
let _ = viewer_tx_recv
.send(ViewerEvent::Disconnected(d.reason))
.await;
break;
}
_ => {}

View File

@@ -1,9 +1,9 @@
//! Window rendering and frame display
use super::{ViewerEvent, InputEvent};
use crate::proto;
#[cfg(windows)]
use super::input;
use super::{InputEvent, ViewerEvent};
use crate::proto;
use anyhow::Result;
use std::num::NonZeroU32;
use std::sync::Arc;
@@ -43,10 +43,7 @@ struct ViewerApp {
}
impl ViewerApp {
fn new(
viewer_rx: mpsc::Receiver<ViewerEvent>,
input_tx: mpsc::Sender<InputEvent>,
) -> Self {
fn new(viewer_rx: mpsc::Receiver<ViewerEvent>, input_tx: mpsc::Sender<InputEvent>) -> Self {
Self {
window: None,
surface: None,
@@ -112,7 +109,9 @@ impl ViewerApp {
}
fn render(&mut self) {
let Some(surface) = &mut self.surface else { return };
let Some(surface) = &mut self.surface else {
return;
};
let Some(window) = &self.window else { return };
if self.frame_buffer.is_empty() || self.frame_width == 0 || self.frame_height == 0 {

View File

@@ -6,23 +6,17 @@ use bytes::Bytes;
use futures_util::{SinkExt, StreamExt};
use prost::Message as ProstMessage;
use std::sync::Arc;
use tokio::net::TcpStream;
use tokio::sync::Mutex;
use tokio_tungstenite::{
connect_async,
tungstenite::protocol::Message as WsMessage,
MaybeTlsStream, WebSocketStream,
connect_async, tungstenite::protocol::Message as WsMessage, MaybeTlsStream, WebSocketStream,
};
use tokio::net::TcpStream;
use tracing::{debug, error, trace};
pub type WsSender = futures_util::stream::SplitSink<
WebSocketStream<MaybeTlsStream<TcpStream>>,
WsMessage,
>;
pub type WsSender =
futures_util::stream::SplitSink<WebSocketStream<MaybeTlsStream<TcpStream>>, WsMessage>;
pub type WsReceiver = futures_util::stream::SplitStream<
WebSocketStream<MaybeTlsStream<TcpStream>>,
>;
pub type WsReceiver = futures_util::stream::SplitStream<WebSocketStream<MaybeTlsStream<TcpStream>>>;
/// Receiver wrapper that parses protobuf messages
pub struct MessageReceiver {
@@ -88,10 +82,7 @@ pub async fn connect(url: &str, token: &str) -> Result<(WsSender, MessageReceive
}
/// Send a protobuf message over the WebSocket
pub async fn send_message(
sender: &Arc<Mutex<WsSender>>,
msg: &proto::Message,
) -> Result<()> {
pub async fn send_message(sender: &Arc<Mutex<WsSender>>, msg: &proto::Message) -> Result<()> {
let mut buf = Vec::with_capacity(msg.encoded_len());
msg.encode(&mut buf)?;