diff --git a/wayvr-ipc/src/client.rs b/wayvr-ipc/src/client.rs index b1c4c598..19a8dcca 100644 --- a/wayvr-ipc/src/client.rs +++ b/wayvr-ipc/src/client.rs @@ -429,6 +429,14 @@ impl WayVRClient { send_only!(client, &PacketClient::WlxModifyPanel(params)); Ok(()) } + + pub async fn fn_wlx_screen_focus_toggle( + client: WayVRClientMutex, + params: packet_client::WlxScreenFocusToggleParams, + ) -> anyhow::Result<()> { + send_only!(client, &PacketClient::WlxScreenFocusToggle(params)); + Ok(()) + } } impl Drop for WayVRClient { diff --git a/wayvr-ipc/src/packet_client.rs b/wayvr-ipc/src/packet_client.rs index 6f8649bb..f53cc46f 100644 --- a/wayvr-ipc/src/packet_client.rs +++ b/wayvr-ipc/src/packet_client.rs @@ -55,11 +55,21 @@ pub struct WlxModifyPanelParams { pub command: WlxModifyPanelCommand, } +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct WlxScreenFocusToggleParams { + pub screen_name: String, + pub target_x: f32, + pub target_y: f32, + pub crop_rect: Option<[f32; 4]>, + pub refresh_only: bool, +} + #[derive(Debug, Serialize, Deserialize)] pub enum PacketClient { Handshake(Handshake), WvrWindowList(Serial), WvrWindowSetVisible(packet_server::WvrWindowHandle, bool), + WlxScreenFocusToggle(WlxScreenFocusToggleParams), WvrProcessGet(Serial, packet_server::WvrProcessHandle), WvrProcessLaunch(Serial, WvrProcessLaunchParams), WvrProcessList(Serial), diff --git a/wayvrctl/src/helper.rs b/wayvrctl/src/helper.rs index 60fb91e3..9fad216a 100644 --- a/wayvrctl/src/helper.rs +++ b/wayvrctl/src/helper.rs @@ -204,3 +204,27 @@ pub async fn wlx_input_state(state: &mut WayVRClientState) { .context("failed to get input state"), ) } + +pub async fn wlx_screen_focus_toggle( + state: &mut WayVRClientState, + screen_name: String, + target_x: f32, + target_y: f32, + crop_rect: Option<[f32; 4]>, + refresh_only: bool, +) { + handle_empty_result( + WayVRClient::fn_wlx_screen_focus_toggle( + state.wayvr_client.clone(), + packet_client::WlxScreenFocusToggleParams { + screen_name, + target_x, + target_y, + crop_rect, + refresh_only, + }, + ) + .await + .context("failed to toggle screen focus"), + ) +} diff --git a/wayvrctl/src/main.rs b/wayvrctl/src/main.rs index 6df69149..683dd98f 100644 --- a/wayvrctl/src/main.rs +++ b/wayvrctl/src/main.rs @@ -14,9 +14,9 @@ use wayvr_ipc::{ }; use crate::helper::{ - WayVRClientState, wlx_device_haptics, wlx_input_state, wlx_panel_modify, wlx_show_hide, - wlx_switch_set, wvr_process_get, wvr_process_launch, wvr_process_list, wvr_process_terminate, - wvr_window_list, wvr_window_set_visible, + WayVRClientState, wlx_device_haptics, wlx_input_state, wlx_panel_modify, + wlx_screen_focus_toggle, wlx_show_hide, wlx_switch_set, wvr_process_get, wvr_process_launch, + wvr_process_list, wvr_process_terminate, wvr_window_list, wvr_window_set_visible, }; mod helper; @@ -195,6 +195,34 @@ async fn run_once(state: &mut WayVRClientState, args: Args) -> anyhow::Result<() let set = if set == 0 { None } else { Some((set - 1) as _) }; wlx_switch_set(state, set).await; } + Subcommands::ScreenFocusToggle { screen_name } => { + wlx_screen_focus_toggle(state, screen_name, 0.5, 0.5, None, false).await; + } + Subcommands::ScreenFocusAt { + screen_name, + target_x, + target_y, + crop_x, + crop_y, + crop_w, + crop_h, + refresh_only, + } => { + let crop_rect = crop_x + .zip(crop_y) + .zip(crop_w) + .zip(crop_h) + .map(|(((x, y), w), h)| [x, y, w, h]); + wlx_screen_focus_toggle( + state, + screen_name, + target_x, + target_y, + crop_rect, + refresh_only, + ) + .await; + } } Ok(()) } @@ -291,6 +319,24 @@ enum Subcommands { /// Set number to switch to, 0 to hide all sets set_or_0: usize, }, + ScreenFocusToggle { + screen_name: String, + }, + ScreenFocusAt { + screen_name: String, + target_x: f32, + target_y: f32, + #[arg(long)] + crop_x: Option, + #[arg(long)] + crop_y: Option, + #[arg(long)] + crop_w: Option, + #[arg(long)] + crop_h: Option, + #[arg(long)] + refresh_only: bool, + }, } #[derive(Debug, Clone, Copy, clap::ValueEnum)]