update input

This commit is contained in:
Adrian Gunnar Lauterer 2025-02-03 16:54:38 +01:00
parent 20c53ed153
commit f805c7ecd3
Signed by: adriangl
GPG Key ID: D33368A59745C2F0
3 changed files with 92 additions and 60 deletions

View File

@ -19,3 +19,16 @@ See also https://git.pvv.ntnu.no/Grzegorz/grzegorz-clients for frontend alternat
```sh ```sh
RUST_LOG=greg_ng=trace,mpvipc=trace cargo run -- --mpv-socket-path /tmp/mpv.sock RUST_LOG=greg_ng=trace,mpvipc=trace cargo run -- --mpv-socket-path /tmp/mpv.sock
``` ```
Custom api call in curl examples
LOL with input command. (utilizing ydotools)
```sh
curl -X POST -H "Content-Type: application/json" -d '{"keys": "42:1 38:1 38:0 24:1 24:0 38:1 38:0 42:0"}' http://localhost:8008/api/v2/sway/input/keys
```
Launching DEFAULT_BROWSER with url, in --kiosk mode
```sh
curl -X POST -H "Content-Type: application/json" -d '{"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"}' http://localhost:8008/api/v2/sway/browser/launch
```

View File

@ -238,17 +238,11 @@ pub async fn sway_launch_browser(url: &str) -> Fallible<()> {
tokio::task::spawn_blocking(move || -> Fallible<()> { tokio::task::spawn_blocking(move || -> Fallible<()> {
let mut connection = Connection::new()?; let mut connection = Connection::new()?;
// connection.run_command(&format!("exec xdg-open {}", url))?; // connection.run_command(&format!("exec xdg-open {}", url))?;
connection.run_command(&format!("exec firefox --kiosk {}", url))?; //moved to firefox to pin in kiosk mode. potentially add --new-window // connection.run_command(&format!("exec firefox --kiosk {}", url))?; //moved to firefox to pin in kiosk mode. potentially add --new-window
// let browser_output = std::process::Command::new("xdg-settings") //get the DEFAULT_BROWSER env var
// .arg("get") let default_browser = std::env::var("DEFAULT_BROWSER").unwrap_or("firefox".to_string());
// .arg("default-web-browser") connection.run_command(&format!("exec {} --kiosk {}", default_browser, url))?; // set default browser in kiosk mode
// .output()?;
// let default_browser = String::from_utf8(browser_output.stdout)?
// .trim()
// .trim_end_matches(".desktop")
// .to_string();
// connection.run_command(&format!("exec {} --kiosk {}", default_browser, url))?; // set default browser in kiosk mode
Ok(()) Ok(())
}) })
@ -335,12 +329,13 @@ fn validate_keypress_string(input: &str) -> Fallible<String> {
} }
//to simulate keypresses 42:1 38:1 38:0 24:1 24:0 38:1 38:0 42:0 -> LOL //to simulate keypresses 42:1 38:1 38:0 24:1 24:0 38:1 38:0 42:0 -> LOL
pub async fn sway_input(keys: String) -> Fallible<()> { pub async fn input(keys: String) -> Fallible<()> {
let validated_input = validate_keypress_string(&keys)?; let validated_input = validate_keypress_string(&keys)?;
tokio::task::spawn_blocking(move || -> Fallible<()> { tokio::task::spawn_blocking(move || -> Fallible<()> {
let mut connection = Connection::new()?; let mut connection = Connection::new()?;
connection.run_command(&format!("exec ydotool key {}", validated_input))?; connection.run_command(&format!("exec ydotool key {}", validated_input))?;
// instead of running through swaycmf
Ok(()) Ok(())
}) })
.await .await
@ -348,7 +343,7 @@ pub async fn sway_input(keys: String) -> Fallible<()> {
} }
// simulate mouse movement // simulate mouse movement
pub async fn sway_mouse_move(x: i32, y: i32) -> Fallible<()> { pub async fn mouse_move(x: i32, y: i32) -> Fallible<()> {
tokio::task::spawn_blocking(move || -> Fallible<()> { tokio::task::spawn_blocking(move || -> Fallible<()> {
let mut connection = Connection::new()?; let mut connection = Connection::new()?;
connection.run_command(&format!("exec ydotool mousemove -x {} -y {}", x, y))?; connection.run_command(&format!("exec ydotool mousemove -x {} -y {}", x, y))?;
@ -360,7 +355,7 @@ pub async fn sway_mouse_move(x: i32, y: i32) -> Fallible<()> {
//simulate scroll //simulate scroll
pub async fn sway_mouse_scroll(x: i32, y: i32) -> Fallible<()> { pub async fn mouse_scroll(x: i32, y: i32) -> Fallible<()> {
tokio::task::spawn_blocking(move || -> Fallible<()> { tokio::task::spawn_blocking(move || -> Fallible<()> {
let mut connection = Connection::new()?; let mut connection = Connection::new()?;
connection.run_command(&format!("exec ydotool mousemove -w -x {} -y {}", x, y))?; connection.run_command(&format!("exec ydotool mousemove -w -x {} -y {}", x, y))?;
@ -413,7 +408,7 @@ impl MouseButton {
} }
} }
pub async fn sway_mouse_click(button: String) -> Fallible<()> { pub async fn mouse_click(button: String) -> Fallible<()> {
let mouse_button = MouseButton::from_str(&button)?; let mouse_button = MouseButton::from_str(&button)?;
let click_value = mouse_button.click_value(); let click_value = mouse_button.click_value();

View File

@ -38,9 +38,10 @@ pub fn rest_api_routes(mpv: Mpv) -> Router {
.route("/sway/workspace/change", post(sway_change_workspace_handler)) .route("/sway/workspace/change", post(sway_change_workspace_handler))
.route("/sway/workspace/list", get(sway_get_workspace_names_handler)) .route("/sway/workspace/list", get(sway_get_workspace_names_handler))
.route("/sway/browser/launch", post(sway_launch_browser_handler)) .route("/sway/browser/launch", post(sway_launch_browser_handler))
.route("/sway/input/keys", post(sway_input_handler)) .route("/input/keys", post(input_handler))
.route("/sway/input/mouse", post(sway_mouse_move_handler)) .route("/input/mouse", post(mouse_move_handler))
.route("/sway/input/scroll", post(sway_mouse_scroll_handler)) .route("/input/scroll", post(mouse_scroll_handler))
.route("/input/click", post(mouse_click_handler))
.with_state(mpv) .with_state(mpv)
} }
@ -497,9 +498,6 @@ async fn sway_get_workspace_names_handler() -> RestResponse {
#[derive(serde::Deserialize, utoipa::ToSchema)] #[derive(serde::Deserialize, utoipa::ToSchema)]
struct KeyboardInput { struct KeyboardInput {
keys: String, keys: String,
@ -508,64 +506,90 @@ struct KeyboardInput {
#[utoipa::path( #[utoipa::path(
post, post,
path = "/sway/input/keys", path = "/input/keys",
request_body = KeyboardInput, request_body = KeyboardInput,
responses( responses(
(status = 200, description = "Success", body = Vec<String>), (status = 200, description = "Success", body = Vec<String>),
(status = 500, description = "Internal server error", body = ErrorResponse), (status = 500, description = "Internal server error", body = ErrorResponse),
) )
)] )]
async fn sway_input_handler( async fn input_handler(
Json(payload): Json<KeyboardInput> Json(payload): Json<KeyboardInput>
) -> RestResponse { ) -> RestResponse {
base::sway_input(payload.keys) base::input(payload.keys)
.await .await
.map(|_| json!({})) .map(|_| json!({}))
.map_err(anyhow::Error::new) .map_err(anyhow::Error::new)
.into() .into()
} }
#[utoipa::path(
post,
path = "/sway/input/mouse",
request_body = MouseMove,
responses(
(status = 200, description = "Success", body = Vec<String>),
(status = 500, description = "Internal server error", body = ErrorResponse),
)
)]
async fn sway_mouse_move_handler(
Json(payload): Json<MouseMove>
) -> RestResponse {
base::sway_mouse_move(payload.x, payload.y)
.await
.map(|_| json!({}))
.map_err(anyhow::Error::new)
.into()
}
#[utoipa::path(
post,
path = "/sway/input/scroll",
request_body = MouseMove,
responses(
(status = 200, description = "Success", body = Vec<String>),
(status = 500, description = "Internal server error", body = ErrorResponse),
)
)]
async fn sway_mouse_scroll_handler(
Json(payload): Json<MouseMove>
) -> RestResponse {
base::sway_mouse_scroll(payload.x, payload.y)
.await
.map(|_| json!({}))
.map_err(anyhow::Error::new)
.into()
}
#[derive(serde::Deserialize, utoipa::ToSchema)] #[derive(serde::Deserialize, utoipa::ToSchema)]
struct MouseMove { struct MouseMove {
x: i32, x: i32,
y: i32, y: i32,
}
#[utoipa::path(
post,
path = "/input/mouse",
request_body = MouseMove,
responses(
(status = 200, description = "Success", body = Vec<String>),
(status = 500, description = "Internal server error", body = ErrorResponse),
)
)]
async fn mouse_move_handler(
Json(payload): Json<MouseMove>
) -> RestResponse {
base::mouse_move(payload.x, payload.y)
.await
.map(|_| json!({}))
.map_err(anyhow::Error::new)
.into()
}
#[utoipa::path(
post,
path = "/input/scroll",
request_body = MouseMove,
responses(
(status = 200, description = "Success", body = Vec<String>),
(status = 500, description = "Internal server error", body = ErrorResponse),
)
)]
async fn mouse_scroll_handler(
Json(payload): Json<MouseMove>
) -> RestResponse {
base::mouse_scroll(payload.x, payload.y)
.await
.map(|_| json!({}))
.map_err(anyhow::Error::new)
.into()
}
//click
#[derive(serde::Deserialize, utoipa::ToSchema)]
struct MouseClick {
button: String
}
#[utoipa::path(
post,
path = "/input/click",
request_body = MouseClick,
responses(
(status = 200, description = "Success", body = Vec<String>),
(status = 500, description = "Internal server error", body = ErrorResponse),
)
)]
async fn mouse_click_handler(
Json(payload): Json<MouseClick>
) -> RestResponse {
base::mouse_click(payload.button)
.await
.map(|_| json!({}))
.map_err(anyhow::Error::new)
.into()
} }