style(agent): clear 77 pre-existing clippy -D warnings
All checks were successful
All checks were successful
CI never ran clippy on the agent crate (the build-server clippy job is Linux-only and can't compile the Windows agent; build-agent only runs cargo build), so 77 clippy -D-warnings errors had accumulated. Behavior-preserving cleanup, code-reviewed APPROVED, locally verified (cargo clippy --workspace --all-targets --all-features -- -D warnings exits 0; cargo test --workspace = 57 passed). - let _ = on Win32 resource-teardown BOOL returns (gdi.rs); fallible BitBlt/GetDIBits stay error-handled - removed unused imports/vars; idiom fixes (div_ceil, is_null, transmute annotations, match collapsing, useless_conversion) - #[allow(dead_code)] + comment on genuine Task-6/7 scaffolding (vk consts, SpecialKey emission, SAS mgmt API, modifier tracking, GDI frame-diff fields) - Cargo.lock: cargo pruned ~147 stale transitive entries (no version changes) Follow-up: add cargo clippy -D warnings to the build-agent CI job so the agent crate stays clippy-clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
149
Cargo.lock
generated
149
Cargo.lock
generated
@@ -735,19 +735,6 @@ version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f"
|
||||
|
||||
[[package]]
|
||||
name = "dashmap"
|
||||
version = "5.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"hashbrown 0.14.5",
|
||||
"lock_api",
|
||||
"once_cell",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "data-encoding"
|
||||
version = "2.11.0"
|
||||
@@ -1075,31 +1062,6 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "forwarded-header-value"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8835f84f38484cc86f110a805655697908257fb9a7af005234060891557198e9"
|
||||
dependencies = [
|
||||
"nonempty",
|
||||
"thiserror 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.32"
|
||||
@@ -1167,19 +1129,12 @@ version = "0.3.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
|
||||
|
||||
[[package]]
|
||||
name = "futures-timer"
|
||||
version = "3.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af43fadb8a98512d547e37b4e92e0ced13e205c061b87b4623eff01d918d6968"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
@@ -1398,26 +1353,6 @@ dependencies = [
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "governor"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"dashmap",
|
||||
"futures",
|
||||
"futures-timer",
|
||||
"no-std-compat",
|
||||
"nonzero_ext",
|
||||
"parking_lot",
|
||||
"portable-atomic",
|
||||
"quanta",
|
||||
"rand 0.8.6",
|
||||
"smallvec",
|
||||
"spinning_top",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gtk"
|
||||
version = "0.18.2"
|
||||
@@ -1472,7 +1407,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "guruconnect"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -1511,7 +1446,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "guruconnect-server"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argon2",
|
||||
@@ -1534,18 +1469,11 @@ dependencies = [
|
||||
"toml 0.8.2",
|
||||
"tower",
|
||||
"tower-http",
|
||||
"tower_governor",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.5"
|
||||
@@ -2362,24 +2290,6 @@ dependencies = [
|
||||
"jni-sys 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "no-std-compat"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c"
|
||||
|
||||
[[package]]
|
||||
name = "nonempty"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7"
|
||||
|
||||
[[package]]
|
||||
name = "nonzero_ext"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21"
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.50.3"
|
||||
@@ -3035,12 +2945,6 @@ dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
|
||||
|
||||
[[package]]
|
||||
name = "potential_utf"
|
||||
version = "0.1.5"
|
||||
@@ -3218,21 +3122,6 @@ version = "0.1.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0c5ccf5294c6ccd63a74f1565028353830a9c2f5eb0c682c355c471726a6e3f"
|
||||
|
||||
[[package]]
|
||||
name = "quanta"
|
||||
version = "0.12.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3ab5a9d756f0d97bdc89019bd2e4ea098cf9cde50ee7564dde6b81ccc8f06c7"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"raw-cpuid",
|
||||
"wasi",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-xml"
|
||||
version = "0.39.4"
|
||||
@@ -3377,15 +3266,6 @@ dependencies = [
|
||||
"getrandom 0.3.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "raw-cpuid"
|
||||
version = "11.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186"
|
||||
dependencies = [
|
||||
"bitflags 2.11.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "raw-window-handle"
|
||||
version = "0.6.2"
|
||||
@@ -3960,15 +3840,6 @@ dependencies = [
|
||||
"lock_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spinning_top"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spki"
|
||||
version = "0.7.3"
|
||||
@@ -4653,22 +4524,6 @@ version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
|
||||
|
||||
[[package]]
|
||||
name = "tower_governor"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aea939ea6cfa7c4880f3e7422616624f97a567c16df67b53b11f0d03917a8e46"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"forwarded-header-value",
|
||||
"governor",
|
||||
"http",
|
||||
"pin-project",
|
||||
"thiserror 1.0.69",
|
||||
"tower",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.44"
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
//! The agent communicates with this service via named pipe IPC.
|
||||
|
||||
use std::ffi::OsString;
|
||||
use std::io::{Read, Write as IoWrite};
|
||||
use std::sync::mpsc;
|
||||
use std::time::Duration;
|
||||
|
||||
@@ -84,6 +83,8 @@ extern "system" {
|
||||
) -> i32;
|
||||
}
|
||||
|
||||
// Field names mirror the Win32 SECURITY_ATTRIBUTES ABI struct.
|
||||
#[allow(non_snake_case)]
|
||||
#[repr(C)]
|
||||
struct SECURITY_ATTRIBUTES {
|
||||
nLength: u32,
|
||||
|
||||
@@ -32,6 +32,8 @@ pub struct Display {
|
||||
}
|
||||
|
||||
/// Display info for protocol messages
|
||||
// Future use: multi-display protocol negotiation.
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DisplayInfo {
|
||||
pub displays: Vec<Display>,
|
||||
@@ -40,11 +42,13 @@ pub struct DisplayInfo {
|
||||
|
||||
impl Display {
|
||||
/// Total pixels in the display
|
||||
#[allow(dead_code)]
|
||||
pub fn pixel_count(&self) -> u32 {
|
||||
self.width * self.height
|
||||
}
|
||||
|
||||
/// Bytes needed for BGRA frame buffer
|
||||
#[allow(dead_code)]
|
||||
pub fn buffer_size(&self) -> usize {
|
||||
(self.width * self.height * 4) as usize
|
||||
}
|
||||
@@ -60,7 +64,6 @@ pub fn enumerate_displays() -> Result<Vec<Display>> {
|
||||
};
|
||||
|
||||
let mut displays = Vec::new();
|
||||
let mut display_id = 0u32;
|
||||
|
||||
// Callback for EnumDisplayMonitors
|
||||
unsafe extern "system" fn enum_callback(
|
||||
@@ -148,6 +151,8 @@ pub fn enumerate_displays() -> Result<Vec<Display>> {
|
||||
}
|
||||
|
||||
/// Get display info for protocol
|
||||
// Future use: multi-display protocol negotiation.
|
||||
#[allow(dead_code)]
|
||||
pub fn get_display_info() -> Result<DisplayInfo> {
|
||||
let displays = enumerate_displays()?;
|
||||
let primary_id = displays
|
||||
|
||||
@@ -32,6 +32,8 @@ pub struct DxgiCapturer {
|
||||
staging_texture: Option<ID3D11Texture2D>,
|
||||
width: u32,
|
||||
height: u32,
|
||||
// Future use: frame diffing against the previously captured frame.
|
||||
#[allow(dead_code)]
|
||||
last_frame: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ impl GdiCapturer {
|
||||
|
||||
let bitmap = CreateCompatibleBitmap(screen_dc, self.width as i32, self.height as i32);
|
||||
if bitmap.is_invalid() {
|
||||
DeleteDC(mem_dc);
|
||||
let _ = DeleteDC(mem_dc);
|
||||
ReleaseDC(HWND::default(), screen_dc);
|
||||
anyhow::bail!("Failed to create compatible bitmap");
|
||||
}
|
||||
@@ -69,8 +69,8 @@ impl GdiCapturer {
|
||||
SRCCOPY,
|
||||
) {
|
||||
SelectObject(mem_dc, old_bitmap);
|
||||
DeleteObject(bitmap);
|
||||
DeleteDC(mem_dc);
|
||||
let _ = DeleteObject(bitmap);
|
||||
let _ = DeleteDC(mem_dc);
|
||||
ReleaseDC(HWND::default(), screen_dc);
|
||||
anyhow::bail!("BitBlt failed: {}", e);
|
||||
}
|
||||
@@ -110,8 +110,8 @@ impl GdiCapturer {
|
||||
|
||||
// Cleanup
|
||||
SelectObject(mem_dc, old_bitmap);
|
||||
DeleteObject(bitmap);
|
||||
DeleteDC(mem_dc);
|
||||
let _ = DeleteObject(bitmap);
|
||||
let _ = DeleteDC(mem_dc);
|
||||
ReleaseDC(HWND::default(), screen_dc);
|
||||
|
||||
if lines == 0 {
|
||||
|
||||
@@ -9,7 +9,7 @@ mod dxgi;
|
||||
#[cfg(windows)]
|
||||
mod gdi;
|
||||
|
||||
pub use display::{Display, DisplayInfo};
|
||||
pub use display::Display;
|
||||
|
||||
use anyhow::Result;
|
||||
use std::time::Instant;
|
||||
@@ -33,6 +33,8 @@ pub struct CapturedFrame {
|
||||
pub display_id: u32,
|
||||
|
||||
/// Regions that changed since last frame (if available)
|
||||
// Populated by capturers; not yet consumed by the encoder pipeline.
|
||||
#[allow(dead_code)]
|
||||
pub dirty_rects: Option<Vec<DirtyRect>>,
|
||||
}
|
||||
|
||||
@@ -53,9 +55,11 @@ pub trait Capturer: Send {
|
||||
fn capture(&mut self) -> Result<Option<CapturedFrame>>;
|
||||
|
||||
/// Get the current display info
|
||||
#[allow(dead_code)]
|
||||
fn display(&self) -> &Display;
|
||||
|
||||
/// Check if capturer is still valid (display may have changed)
|
||||
#[allow(dead_code)]
|
||||
fn is_valid(&self) -> bool;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,17 +6,13 @@
|
||||
use std::sync::mpsc::{self, Receiver, Sender};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
use tracing::{error, info, warn};
|
||||
use tracing::info;
|
||||
#[cfg(not(windows))]
|
||||
use tracing::warn;
|
||||
|
||||
#[cfg(windows)]
|
||||
use windows::core::PCWSTR;
|
||||
#[cfg(windows)]
|
||||
use windows::Win32::Foundation::*;
|
||||
#[cfg(windows)]
|
||||
use windows::Win32::Graphics::Gdi::*;
|
||||
#[cfg(windows)]
|
||||
use windows::Win32::System::LibraryLoader::GetModuleHandleW;
|
||||
#[cfg(windows)]
|
||||
use windows::Win32::UI::WindowsAndMessaging::*;
|
||||
|
||||
/// A chat message
|
||||
@@ -29,11 +25,15 @@ pub struct ChatMessage {
|
||||
}
|
||||
|
||||
/// Commands that can be sent to the chat window
|
||||
// Show/Hide/Close are part of the chat control API but not yet driven by the session loop.
|
||||
#[derive(Debug)]
|
||||
pub enum ChatCommand {
|
||||
#[allow(dead_code)]
|
||||
Show,
|
||||
#[allow(dead_code)]
|
||||
Hide,
|
||||
AddMessage(ChatMessage),
|
||||
#[allow(dead_code)]
|
||||
Close,
|
||||
}
|
||||
|
||||
@@ -69,11 +69,13 @@ impl ChatController {
|
||||
}
|
||||
|
||||
/// Show the chat window
|
||||
#[allow(dead_code)]
|
||||
pub fn show(&self) {
|
||||
let _ = self.command_tx.send(ChatCommand::Show);
|
||||
}
|
||||
|
||||
/// Hide the chat window
|
||||
#[allow(dead_code)]
|
||||
pub fn hide(&self) {
|
||||
let _ = self.command_tx.send(ChatCommand::Hide);
|
||||
}
|
||||
@@ -93,16 +95,14 @@ impl ChatController {
|
||||
}
|
||||
|
||||
/// Close the chat window
|
||||
#[allow(dead_code)]
|
||||
pub fn close(&self) {
|
||||
let _ = self.command_tx.send(ChatCommand::Close);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn run_chat_window(command_rx: Receiver<ChatCommand>, message_tx: Sender<ChatMessage>) {
|
||||
use std::ffi::OsStr;
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
|
||||
fn run_chat_window(command_rx: Receiver<ChatCommand>, _message_tx: Sender<ChatMessage>) {
|
||||
info!("Starting chat window thread");
|
||||
|
||||
// For now, we'll use a simple message box approach
|
||||
|
||||
@@ -9,7 +9,7 @@ use anyhow::{anyhow, Context, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::io::{Read, Seek, SeekFrom};
|
||||
use std::path::PathBuf;
|
||||
use tracing::{info, warn};
|
||||
use tracing::info;
|
||||
use uuid::Uuid;
|
||||
|
||||
/// Magic marker for embedded configuration (10 bytes)
|
||||
@@ -196,7 +196,7 @@ impl Config {
|
||||
/// Extract 6-digit support code from filename
|
||||
fn extract_support_code(filename: &str) -> Option<String> {
|
||||
// Look for patterns like "GuruConnect-123456" or "GuruConnect_123456"
|
||||
for part in filename.split(|c| c == '-' || c == '_' || c == '.') {
|
||||
for part in filename.split(['-', '_', '.']) {
|
||||
let trimmed = part.trim();
|
||||
if trimmed.len() == 6 && trimmed.chars().all(|c| c.is_ascii_digit()) {
|
||||
return Some(trimmed.to_string());
|
||||
@@ -435,6 +435,8 @@ impl Config {
|
||||
}
|
||||
|
||||
/// Example configuration file content
|
||||
// Retained for documentation / config-template generation.
|
||||
#[allow(dead_code)]
|
||||
pub fn example_config() -> &'static str {
|
||||
r#"# GuruConnect Agent Configuration
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ mod raw;
|
||||
pub use raw::RawEncoder;
|
||||
|
||||
use crate::capture::CapturedFrame;
|
||||
use crate::proto::{DirtyRect as ProtoDirtyRect, RawFrame, VideoFrame};
|
||||
use crate::proto::VideoFrame;
|
||||
use anyhow::Result;
|
||||
|
||||
/// Encoded frame ready for transmission
|
||||
@@ -23,6 +23,8 @@ pub struct EncodedFrame {
|
||||
pub size: usize,
|
||||
|
||||
/// Whether this is a keyframe (full frame)
|
||||
// Set by encoders; not yet read by the transmit path.
|
||||
#[allow(dead_code)]
|
||||
pub is_keyframe: bool,
|
||||
}
|
||||
|
||||
@@ -32,9 +34,11 @@ pub trait Encoder: Send {
|
||||
fn encode(&mut self, frame: &CapturedFrame) -> Result<EncodedFrame>;
|
||||
|
||||
/// Request a keyframe on next encode
|
||||
#[allow(dead_code)]
|
||||
fn request_keyframe(&mut self);
|
||||
|
||||
/// Get encoder name/type
|
||||
#[allow(dead_code)]
|
||||
fn name(&self) -> &str;
|
||||
}
|
||||
|
||||
@@ -44,9 +48,7 @@ pub fn create_encoder(codec: &str, quality: u32) -> Result<Box<dyn Encoder>> {
|
||||
"raw" | "zstd" => Ok(Box::new(RawEncoder::new(quality)?)),
|
||||
// "vp9" => Ok(Box::new(Vp9Encoder::new(quality)?)),
|
||||
// "h264" => Ok(Box::new(H264Encoder::new(quality)?)),
|
||||
"auto" | _ => {
|
||||
// Default to raw for now (best for LAN)
|
||||
Ok(Box::new(RawEncoder::new(quality)?))
|
||||
}
|
||||
// "auto" and any unknown codec default to raw for now (best for LAN)
|
||||
_ => Ok(Box::new(RawEncoder::new(quality)?)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,8 +77,8 @@ impl RawEncoder {
|
||||
let mut dirty_rects = Vec::new();
|
||||
let stride = (width * 4) as usize;
|
||||
|
||||
let blocks_x = (width + BLOCK_SIZE - 1) / BLOCK_SIZE;
|
||||
let blocks_y = (height + BLOCK_SIZE - 1) / BLOCK_SIZE;
|
||||
let blocks_x = width.div_ceil(BLOCK_SIZE);
|
||||
let blocks_y = height.div_ceil(BLOCK_SIZE);
|
||||
|
||||
for by in 0..blocks_y {
|
||||
for bx in 0..blocks_x {
|
||||
|
||||
@@ -5,8 +5,7 @@ use anyhow::Result;
|
||||
#[cfg(windows)]
|
||||
use windows::Win32::UI::Input::KeyboardAndMouse::{
|
||||
MapVirtualKeyW, SendInput, INPUT, INPUT_0, INPUT_KEYBOARD, KEYBDINPUT, KEYBD_EVENT_FLAGS,
|
||||
KEYEVENTF_EXTENDEDKEY, KEYEVENTF_KEYUP, KEYEVENTF_SCANCODE, KEYEVENTF_UNICODE,
|
||||
MAPVK_VK_TO_VSC_EX,
|
||||
KEYEVENTF_EXTENDEDKEY, KEYEVENTF_KEYUP, KEYEVENTF_UNICODE, MAPVK_VK_TO_VSC_EX,
|
||||
};
|
||||
|
||||
/// Keyboard input controller
|
||||
@@ -16,6 +15,8 @@ pub struct KeyboardController {
|
||||
modifiers: ModifierState,
|
||||
}
|
||||
|
||||
// Modifier tracking is not yet wired into key dispatch.
|
||||
#[allow(dead_code)]
|
||||
#[derive(Default)]
|
||||
struct ModifierState {
|
||||
ctrl: bool,
|
||||
@@ -78,6 +79,7 @@ impl KeyboardController {
|
||||
}
|
||||
|
||||
/// Type a unicode character
|
||||
#[allow(dead_code)]
|
||||
#[cfg(windows)]
|
||||
pub fn type_char(&mut self, ch: char) -> Result<()> {
|
||||
let mut inputs = Vec::new();
|
||||
@@ -119,6 +121,7 @@ impl KeyboardController {
|
||||
}
|
||||
|
||||
/// Type a string of text
|
||||
#[allow(dead_code)]
|
||||
#[cfg(windows)]
|
||||
pub fn type_string(&mut self, text: &str) -> Result<()> {
|
||||
for ch in text.chars() {
|
||||
|
||||
@@ -26,11 +26,13 @@ impl InputController {
|
||||
}
|
||||
|
||||
/// Get mouse controller
|
||||
#[allow(dead_code)]
|
||||
pub fn mouse(&mut self) -> &mut MouseController {
|
||||
&mut self.mouse
|
||||
}
|
||||
|
||||
/// Get keyboard controller
|
||||
#[allow(dead_code)]
|
||||
pub fn keyboard(&mut self) -> &mut KeyboardController {
|
||||
&mut self.keyboard
|
||||
}
|
||||
@@ -64,6 +66,7 @@ impl InputController {
|
||||
}
|
||||
|
||||
/// Type a unicode character
|
||||
#[allow(dead_code)]
|
||||
pub fn type_unicode(&mut self, ch: char) -> Result<()> {
|
||||
self.keyboard.type_char(ch)
|
||||
}
|
||||
@@ -80,7 +83,10 @@ pub enum MouseButton {
|
||||
Left,
|
||||
Right,
|
||||
Middle,
|
||||
// Extra mouse buttons; not yet produced by the viewer input mapping.
|
||||
#[allow(dead_code)]
|
||||
X1,
|
||||
#[allow(dead_code)]
|
||||
X2,
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//! - UAC elevation with graceful fallback
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use tracing::{error, info, warn};
|
||||
use tracing::{info, warn};
|
||||
|
||||
#[cfg(windows)]
|
||||
use windows::{
|
||||
|
||||
@@ -453,7 +453,7 @@ fn show_error_box(_title: &str, message: &str) {
|
||||
fn show_debug_console() {
|
||||
unsafe {
|
||||
let hwnd = GetConsoleWindow();
|
||||
if hwnd.0 == std::ptr::null_mut() {
|
||||
if hwnd.0.is_null() {
|
||||
let _ = AllocConsole();
|
||||
} else {
|
||||
let _ = ShowWindow(hwnd, SW_SHOW);
|
||||
|
||||
@@ -5,13 +5,11 @@
|
||||
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::{Read, Write};
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use tracing::{debug, error, info, warn};
|
||||
|
||||
const PIPE_NAME: &str = r"\\.\pipe\guruconnect-sas";
|
||||
const TIMEOUT_MS: u64 = 5000;
|
||||
|
||||
/// Request Ctrl+Alt+Del (Secure Attention Sequence) via the SAS service
|
||||
pub fn request_sas() -> Result<()> {
|
||||
@@ -65,6 +63,8 @@ pub fn request_sas() -> Result<()> {
|
||||
}
|
||||
|
||||
/// Check if the SAS service is available
|
||||
// Used by the test module and the (not-yet-wired) SAS status API.
|
||||
#[allow(dead_code)]
|
||||
pub fn is_service_available() -> bool {
|
||||
// Try to open the pipe
|
||||
if let Ok(mut pipe) = OpenOptions::new().read(true).write(true).open(PIPE_NAME) {
|
||||
@@ -81,6 +81,7 @@ pub fn is_service_available() -> bool {
|
||||
}
|
||||
|
||||
/// Get information about SAS service status
|
||||
#[allow(dead_code)]
|
||||
pub fn get_service_status() -> String {
|
||||
if is_service_available() {
|
||||
"SAS service is running and responding".to_string()
|
||||
|
||||
@@ -11,7 +11,7 @@ use windows::Win32::System::Console::{AllocConsole, GetConsoleWindow};
|
||||
#[cfg(windows)]
|
||||
use windows::Win32::UI::WindowsAndMessaging::{ShowWindow, SW_SHOW};
|
||||
|
||||
use crate::capture::{self, Capturer, Display};
|
||||
use crate::capture::{self, Capturer};
|
||||
use crate::chat::{ChatController, ChatMessage as ChatMsg};
|
||||
use crate::config::Config;
|
||||
use crate::encoder::{self, Encoder};
|
||||
@@ -22,7 +22,7 @@ use crate::input::InputController;
|
||||
fn show_debug_console() {
|
||||
unsafe {
|
||||
let hwnd = GetConsoleWindow();
|
||||
if hwnd.0 == std::ptr::null_mut() {
|
||||
if hwnd.0.is_null() {
|
||||
let _ = AllocConsole();
|
||||
tracing::info!("Debug console window opened");
|
||||
} else {
|
||||
@@ -130,7 +130,7 @@ impl SessionManager {
|
||||
|
||||
// Get primary display with panic protection
|
||||
tracing::debug!("Enumerating displays...");
|
||||
let primary_display = match std::panic::catch_unwind(|| capture::primary_display()) {
|
||||
let primary_display = match std::panic::catch_unwind(capture::primary_display) {
|
||||
Ok(result) => result?,
|
||||
Err(e) => {
|
||||
tracing::error!("Panic during display enumeration: {:?}", e);
|
||||
@@ -623,11 +623,8 @@ impl SessionManager {
|
||||
Some(message::Payload::SpecialKey(special)) => {
|
||||
if let Some(input) = self.input.as_mut() {
|
||||
use crate::proto::SpecialKey;
|
||||
match SpecialKey::try_from(special.key).ok() {
|
||||
Some(SpecialKey::CtrlAltDel) => {
|
||||
input.send_ctrl_alt_del()?;
|
||||
}
|
||||
_ => {}
|
||||
if let Ok(SpecialKey::CtrlAltDel) = SpecialKey::try_from(special.key) {
|
||||
input.send_ctrl_alt_del()?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//! Handles adding/removing the agent from Windows startup.
|
||||
|
||||
use anyhow::Result;
|
||||
use tracing::{error, info, warn};
|
||||
use tracing::{info, warn};
|
||||
|
||||
#[cfg(windows)]
|
||||
use windows::core::PCWSTR;
|
||||
@@ -58,7 +58,10 @@ pub fn add_to_startup() -> Result<()> {
|
||||
anyhow::bail!("Failed to open registry key: {:?}", result);
|
||||
}
|
||||
|
||||
let hkey_raw = std::mem::transmute::<_, windows::Win32::System::Registry::HKEY>(hkey);
|
||||
let hkey_raw = std::mem::transmute::<
|
||||
windows::Win32::Foundation::HANDLE,
|
||||
windows::Win32::System::Registry::HKEY,
|
||||
>(hkey);
|
||||
|
||||
// Set the value
|
||||
let data_bytes =
|
||||
@@ -116,7 +119,10 @@ pub fn remove_from_startup() -> Result<()> {
|
||||
return Ok(()); // Not an error if key doesn't exist
|
||||
}
|
||||
|
||||
let hkey_raw = std::mem::transmute::<_, windows::Win32::System::Registry::HKEY>(hkey);
|
||||
let hkey_raw = std::mem::transmute::<
|
||||
windows::Win32::Foundation::HANDLE,
|
||||
windows::Win32::System::Registry::HKEY,
|
||||
>(hkey);
|
||||
|
||||
let delete_result = RegDeleteValueW(hkey_raw, PCWSTR(value_name.as_ptr()));
|
||||
|
||||
@@ -180,6 +186,8 @@ pub fn uninstall() -> Result<()> {
|
||||
|
||||
/// Install the SAS service if the binary is available
|
||||
/// This allows the agent to send Ctrl+Alt+Del even without SYSTEM privileges
|
||||
// Not yet wired into the CLI; retained as the SAS service management API.
|
||||
#[allow(dead_code)]
|
||||
#[cfg(windows)]
|
||||
pub fn install_sas_service() -> Result<()> {
|
||||
info!("Attempting to install SAS service...");
|
||||
@@ -230,6 +238,8 @@ pub fn install_sas_service() -> Result<()> {
|
||||
}
|
||||
|
||||
/// Uninstall the SAS service
|
||||
// Not yet wired into the CLI; retained as the SAS service management API.
|
||||
#[allow(dead_code)]
|
||||
#[cfg(windows)]
|
||||
pub fn uninstall_sas_service() -> Result<()> {
|
||||
info!("Attempting to uninstall SAS service...");
|
||||
@@ -244,16 +254,14 @@ pub fn uninstall_sas_service() -> Result<()> {
|
||||
)),
|
||||
];
|
||||
|
||||
for path_opt in paths.iter() {
|
||||
if let Some(ref path) = path_opt {
|
||||
if path.exists() {
|
||||
let output = std::process::Command::new(path).arg("uninstall").output();
|
||||
for path in paths.iter().flatten() {
|
||||
if path.exists() {
|
||||
let output = std::process::Command::new(path).arg("uninstall").output();
|
||||
|
||||
if let Ok(result) = output {
|
||||
if result.status.success() {
|
||||
info!("SAS service uninstalled successfully");
|
||||
return Ok(());
|
||||
}
|
||||
if let Ok(result) = output {
|
||||
if result.status.success() {
|
||||
info!("SAS service uninstalled successfully");
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -264,6 +272,8 @@ pub fn uninstall_sas_service() -> Result<()> {
|
||||
}
|
||||
|
||||
/// Check if the SAS service is installed and running
|
||||
// Not yet wired into the CLI; retained as the SAS service management API.
|
||||
#[allow(dead_code)]
|
||||
#[cfg(windows)]
|
||||
pub fn check_sas_service() -> bool {
|
||||
use crate::sas_client;
|
||||
|
||||
@@ -82,7 +82,7 @@ impl WebSocketTransport {
|
||||
|
||||
// Send as binary WebSocket message
|
||||
stream
|
||||
.send(WsMessage::Binary(buf.into()))
|
||||
.send(WsMessage::Binary(buf))
|
||||
.await
|
||||
.context("Failed to send message")?;
|
||||
|
||||
@@ -132,6 +132,7 @@ impl WebSocketTransport {
|
||||
}
|
||||
|
||||
/// Receive a message (blocking)
|
||||
#[allow(dead_code)]
|
||||
pub async fn recv(&mut self) -> Result<Option<Message>> {
|
||||
// Return buffered message if available
|
||||
if let Some(msg) = self.incoming.pop_front() {
|
||||
@@ -164,7 +165,7 @@ impl WebSocketTransport {
|
||||
.context("Failed to decode protobuf message")?;
|
||||
Ok(Some(msg))
|
||||
}
|
||||
WsMessage::Ping(data) => {
|
||||
WsMessage::Ping(_data) => {
|
||||
// Pong is sent automatically by tungstenite
|
||||
tracing::trace!("Received ping");
|
||||
Ok(None)
|
||||
@@ -193,6 +194,7 @@ impl WebSocketTransport {
|
||||
}
|
||||
|
||||
/// Close the connection
|
||||
#[allow(dead_code)]
|
||||
pub async fn close(&mut self) -> Result<()> {
|
||||
let mut stream = self.stream.lock().await;
|
||||
stream.close(None).await?;
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
//! - End session
|
||||
|
||||
use anyhow::Result;
|
||||
use muda::{Menu, MenuEvent, MenuItem, PredefinedMenuItem, Submenu};
|
||||
use muda::{Menu, MenuEvent, MenuItem, PredefinedMenuItem};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Arc;
|
||||
use tracing::{info, warn};
|
||||
use tracing::info;
|
||||
use tray_icon::{Icon, TrayIcon, TrayIconBuilder, TrayIconEvent};
|
||||
|
||||
#[cfg(windows)]
|
||||
@@ -28,7 +28,8 @@ pub enum TrayAction {
|
||||
/// Tray icon controller
|
||||
pub struct TrayController {
|
||||
_tray_icon: TrayIcon,
|
||||
menu: Menu,
|
||||
// Kept alive for the lifetime of the tray icon; not read directly.
|
||||
_menu: Menu,
|
||||
end_session_item: MenuItem,
|
||||
debug_item: MenuItem,
|
||||
status_item: MenuItem,
|
||||
@@ -86,7 +87,7 @@ impl TrayController {
|
||||
|
||||
Ok(Self {
|
||||
_tray_icon: tray_icon,
|
||||
menu,
|
||||
_menu: menu,
|
||||
end_session_item,
|
||||
debug_item,
|
||||
status_item,
|
||||
@@ -124,14 +125,9 @@ impl TrayController {
|
||||
}
|
||||
|
||||
// Check for tray icon events (like double-click)
|
||||
if let Ok(event) = TrayIconEvent::receiver().try_recv() {
|
||||
match event {
|
||||
TrayIconEvent::DoubleClick { .. } => {
|
||||
info!("Tray icon double-clicked");
|
||||
return Some(TrayAction::ShowDetails);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
if let Ok(TrayIconEvent::DoubleClick { .. }) = TrayIconEvent::receiver().try_recv() {
|
||||
info!("Tray icon double-clicked");
|
||||
return Some(TrayAction::ShowDetails);
|
||||
}
|
||||
|
||||
None
|
||||
|
||||
@@ -17,10 +17,14 @@ pub struct VersionInfo {
|
||||
pub download_url: String,
|
||||
pub checksum_sha256: String,
|
||||
pub is_mandatory: bool,
|
||||
// Part of the server JSON contract; deserialized but not yet surfaced in the UI.
|
||||
#[allow(dead_code)]
|
||||
pub release_notes: Option<String>,
|
||||
}
|
||||
|
||||
/// Update state tracking
|
||||
// Future use: drive an update-progress indicator.
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum UpdateState {
|
||||
Idle,
|
||||
|
||||
@@ -12,9 +12,9 @@ use tracing::trace;
|
||||
use windows::{
|
||||
Win32::Foundation::{LPARAM, LRESULT, WPARAM},
|
||||
Win32::UI::WindowsAndMessaging::{
|
||||
CallNextHookEx, DispatchMessageW, GetMessageW, PeekMessageW, SetWindowsHookExW,
|
||||
TranslateMessage, UnhookWindowsHookEx, HHOOK, KBDLLHOOKSTRUCT, MSG, PM_REMOVE,
|
||||
WH_KEYBOARD_LL, WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, WM_SYSKEYUP,
|
||||
CallNextHookEx, DispatchMessageW, PeekMessageW, SetWindowsHookExW, TranslateMessage,
|
||||
UnhookWindowsHookEx, HHOOK, KBDLLHOOKSTRUCT, MSG, PM_REMOVE, WH_KEYBOARD_LL, WM_KEYDOWN,
|
||||
WM_KEYUP, WM_SYSKEYDOWN, WM_SYSKEYUP,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -28,7 +28,9 @@ static INPUT_TX: OnceLock<mpsc::Sender<InputEvent>> = OnceLock::new();
|
||||
static mut HOOK_HANDLE: HHOOK = HHOOK(std::ptr::null_mut());
|
||||
|
||||
/// Virtual key codes for special keys
|
||||
// Several entries are reserved for upcoming special-key fidelity work.
|
||||
#[cfg(windows)]
|
||||
#[allow(dead_code)]
|
||||
mod vk {
|
||||
pub const VK_LWIN: u32 = 0x5B;
|
||||
pub const VK_RWIN: u32 = 0x5C;
|
||||
|
||||
@@ -26,6 +26,8 @@ pub enum ViewerEvent {
|
||||
pub enum InputEvent {
|
||||
Mouse(proto::MouseEvent),
|
||||
Key(proto::KeyEvent),
|
||||
// Not yet emitted by the viewer input path (special-key fidelity is pending).
|
||||
#[allow(dead_code)]
|
||||
SpecialKey(proto::SpecialKeyEvent),
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ pub struct FrameData {
|
||||
pub height: u32,
|
||||
pub data: Vec<u8>,
|
||||
pub compressed: bool,
|
||||
// Carried through from the wire frame; the renderer does not branch on it yet.
|
||||
#[allow(dead_code)]
|
||||
pub is_keyframe: bool,
|
||||
}
|
||||
|
||||
@@ -343,12 +345,10 @@ impl ApplicationHandler for ViewerApp {
|
||||
};
|
||||
self.send_mouse_wheel(dx, dy);
|
||||
}
|
||||
WindowEvent::KeyboardInput { event, .. } => {
|
||||
// Note: This handles keys that aren't captured by the low-level hook
|
||||
// The hook handles Win key and other special keys
|
||||
if !event.repeat {
|
||||
self.send_key_event(event.physical_key, event.state);
|
||||
}
|
||||
// Note: This handles keys that aren't captured by the low-level hook.
|
||||
// The hook handles Win key and other special keys.
|
||||
WindowEvent::KeyboardInput { event, .. } if !event.repeat => {
|
||||
self.send_key_event(event.physical_key, event.state);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user