From 0769229419d002ad7fcb976dd4f6283767f54642 Mon Sep 17 00:00:00 2001 From: Adrian Gunnar Lauterer Date: Fri, 24 Jan 2025 21:42:31 +0100 Subject: [PATCH] added api for swaymsg to greg-ng (untested) --- Cargo.lock | 23 +++++++++++++++++++++++ Cargo.toml | 1 + module.nix | 11 +++++++++++ src/api/base.rs | 12 ++++++++++++ src/api/rest_wrapper_v1.rs | 21 +++++++++++++++++++++ src/api/websocket_v1.rs | 7 +++++++ 6 files changed, 75 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 4a01d38..3a12ab6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -625,6 +625,7 @@ dependencies = [ "sd-notify", "serde", "serde_json", + "swayipc", "systemd-journal-logger", "tempfile", "tokio", @@ -1501,6 +1502,28 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "swayipc" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b8c50cb2e98e88b52066a35ef791fffd8f6fa631c3a4983de18ba41f718c736" +dependencies = [ + "serde", + "serde_json", + "swayipc-types", +] + +[[package]] +name = "swayipc-types" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "551233c60323e87cfb8194c21cc44577ab848d00bb7fa2d324a2c7f52609eaff" +dependencies = [ + "serde", + "serde_json", + "thiserror 1.0.69", +] + [[package]] name = "syn" version = "2.0.90" diff --git a/Cargo.toml b/Cargo.toml index 5760878..7ae2593 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ readme = "README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +swayipc = "3.0" anyhow = "1.0.82" axum = { version = "0.7.7", features = ["macros", "ws"] } clap = { version = "4.4.1", features = ["derive"] } diff --git a/module.nix b/module.nix index e03bc3c..f2e8c33 100644 --- a/module.nix +++ b/module.nix @@ -11,6 +11,8 @@ in mpvPackage = lib.mkPackageOption pkgs "mpv" { }; enableSway = lib.mkEnableOption "sway as the main window manager"; + + enableFirefox = lib.mkEnableOption "include fiorefox browser for external urls"; enablePipewire = lib.mkEnableOption "pipewire" // { default = true; }; @@ -166,6 +168,14 @@ in wrapperFeatures.gtk = true; }; + (lib.mkIf (cfg.enable && cfg.enableFirefox) { + programs.firefox = { + enable = true; + preferences = { + media.autoplay.default = "0"; + }; + }; + xdg.portal = { enable = true; wlr.enable = true; @@ -176,6 +186,7 @@ in users.greg = { isNormalUser = true; group = "greg"; + extraGroups [ "audio" "video" "input" ]; uid = 2000; description = "loud gym bro"; }; diff --git a/src/api/base.rs b/src/api/base.rs index 8f0833e..2b36dd4 100644 --- a/src/api/base.rs +++ b/src/api/base.rs @@ -170,3 +170,15 @@ pub async fn playlist_set_looping(mpv: Mpv, r#loop: bool) -> anyhow::Result<()> .await .map_err(|e| e.into()) } + +use swayipc::{Connection, Fallible}; + +pub async fn run_sway_command(command: String) -> Fallible<()> { + tokio::task::spawn_blocking(move || -> Fallible<()> { + let mut connection = Connection::new()?; + connection.run_command(&command)?; + Ok(()) + }) + .await + .map_err(|e| swayipc::Error::CommandFailed(e.to_string()))? +} \ No newline at end of file diff --git a/src/api/rest_wrapper_v1.rs b/src/api/rest_wrapper_v1.rs index db639b5..edb5ef1 100644 --- a/src/api/rest_wrapper_v1.rs +++ b/src/api/rest_wrapper_v1.rs @@ -32,6 +32,7 @@ pub fn rest_api_routes(mpv: Mpv) -> Router { .route("/playlist/shuffle", post(shuffle)) .route("/playlist/loop", get(playlist_get_looping)) .route("/playlist/loop", post(playlist_set_looping)) + .route("/sway/command", post(sway_command)) .with_state(mpv) } @@ -401,3 +402,23 @@ async fn playlist_set_looping( ) -> RestResponse { base::playlist_set_looping(mpv, query.r#loop).await.into() } + + +#[derive(serde::Deserialize, utoipa::IntoParams)] +struct SwayCommandArgs { + command: String, +} + +/// Execute a sway command +#[utoipa::path( + post, + path = "/sway/command", + params(SwayCommandArgs), + responses( + (status = 200, description = "Success", body = EmptySuccessResponse), + (status = 500, description = "Internal server error", body = ErrorResponse), + ) +)] +async fn sway_command(Query(query): Query) -> RestResponse { + base::run_sway_command(query.command).await.map_err(anyhow::Error::new).into() +} diff --git a/src/api/websocket_v1.rs b/src/api/websocket_v1.rs index 8436e4f..721d263 100644 --- a/src/api/websocket_v1.rs +++ b/src/api/websocket_v1.rs @@ -25,6 +25,8 @@ use tokio::{select, sync::watch}; use crate::util::IdPool; +use super::base; + #[derive(Debug, Clone)] struct WebsocketState { mpv: Mpv, @@ -355,6 +357,7 @@ pub enum WSCommand { Shuffle, SetSubtitleTrack { track: Option }, SetLooping { value: bool }, + SwayCommand { command: String }, } async fn handle_message( @@ -445,5 +448,9 @@ async fn handle_message( .await?; Ok(None) } + WSCommand::SwayCommand { command } => { + base::run_sway_command(command).await?; + Ok(None) + } } }