diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 6cec890..668c947 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,6 +4,7 @@ on: push: branches: - release + workflow_dispatch: jobs: publish-tauri: diff --git a/package.json b/package.json index bfb3158..1acdfa5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "opendeck", "version": "2.1.1", - "description": "OpenDeck is a cross-platform desktop application that provides functionality for stream controller devices.", + "description": "A cross-platform desktop application for stream controller devices", "author": "ninjadev64", "license": "GPL-3.0-or-later", "repository": "https://github.com/ninjadev64/OpenDeck", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 5a9d29c..689e6c7 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "opendeck" version = "2.1.1" -description = "A cross-platform desktop application for ProntoKey and Stream Deck." +description = "A cross-platform desktop application for stream controller devices" authors = [ "ninjadev64" ] license = "GPL-3.0-or-later" repository = "https://github.com/ninjadev64/OpenDeck" diff --git a/src-tauri/40-streamdeck.rules b/src-tauri/bundle/40-streamdeck.rules similarity index 100% rename from src-tauri/40-streamdeck.rules rename to src-tauri/bundle/40-streamdeck.rules diff --git a/src-tauri/bundle/me.amankhanna.opendeck.metainfo.xml b/src-tauri/bundle/me.amankhanna.opendeck.metainfo.xml new file mode 100644 index 0000000..cf4e4d1 --- /dev/null +++ b/src-tauri/bundle/me.amankhanna.opendeck.metainfo.xml @@ -0,0 +1,72 @@ + + + + me.amankhanna.opendeck + + OpenDeck + A cross-platform desktop application for stream controller devices + Aman Khanna + + https://github.com/ninjadev64/OpenDeck + https://github.com/ninjadev64/OpenDeck + https://github.com/ninjadev64/OpenDeck/issues + https://github.com/ninjadev64/OpenDeck?tab=readme-ov-file#support + https://github.com/ninjadev64/OpenDeck?tab=readme-ov-file#building-from-source--contributing + https://github.com/sponsors/ninjadev64 + https://matrix.to/#/#opendeck:amankhanna.me + + CC-BY-SA-4.0 + GPL-3.0-or-later + + + +

OpenDeck is a desktop application for using stream controller devices like the Elgato Stream Deck. OpenDeck conforms to the OpenAction API, which is cross-compatible with the Stream Deck SDK, allowing a wide range of pre-existing plugins to be used.

+

OpenDeck supports ProntoKey, Elgato Stream Deck and some Ajazz hardware on all three major desktop platforms. If you would like to contribute support for additional hardware (e.g. Loupedeck) feel free to reach out on any of the support forums and make a pull request!

+

Please note that you may need to install udev subsystem rules for your device to be detected. For more information, see the Installation section of the project README on GitHub.

+
+ + opendeck.desktop + + + https://github.com/ninjadev64/OpenDeck/raw/2daaf68/.github/readme/mainmenu.png + + + https://github.com/ninjadev64/OpenDeck/raw/2daaf68/.github/readme/multiaction.png + + + https://github.com/ninjadev64/OpenDeck/raw/2daaf68/.github/readme/plugins.png + + + + + + https://github.com/ninjadev64/OpenDeck/releases/tag/v2.2.0 + +
    +
  • Preparations for Flatpak release
  • +
  • Removal of unnecessary dependencies
  • +
  • Internal build system and formatting improvements
  • +
+
+
+ + https://github.com/ninjadev64/OpenDeck/release/tag/v2.1.1 + Bug fix for blank screens + + + https://github.com/ninjadev64/OpenDeck/releases/tag/v2.1.0 + +
    +
  • Changed license to the GNU GPL version 3 or later
  • +
  • Changed the config directory location
  • +
  • Migrated to Tauri v2 to reduce app size, prevent dependency issues, and fix bugs and performance issues
  • +
  • Minor bug fixes
  • +
+
+
+ + https://github.com/ninjadev64/OpenDeck/release/tag/v2.0.0 + This is the first stable release of the completely rewritten version of OpenDeck + +
+
diff --git a/src-tauri/opendeck.desktop b/src-tauri/bundle/opendeck.desktop similarity index 100% rename from src-tauri/opendeck.desktop rename to src-tauri/bundle/opendeck.desktop diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 34a377c..1049906 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -100,7 +100,7 @@ async fn main() { .filter(|v| { !matches!( v.target(), - "tungstenite::handshake::server" | "tungstenite::protocol" | "tracing::span" | "zbus::object_server" | "zbus::handshake" | "zbus::connection" + "tungstenite::handshake::server" | "tungstenite::protocol" | "tracing::span" | "zbus::object_server" | "zbus::handshake" | "zbus::connection" | "os_info::imp::lsb_release" ) }) .build(), @@ -108,9 +108,16 @@ async fn main() { .plugin(tauri_plugin_autostart::init(tauri_plugin_autostart::MacosLauncher::LaunchAgent, Some(vec!["--hide"]))) .plugin(tauri_plugin_single_instance::init(|app, _, _| app.get_webview_window("main").unwrap().show().unwrap())) .on_window_event(|window, event| { + if window.label() != "main" { + return; + } if let WindowEvent::CloseRequested { api, .. } = event { - window.hide().unwrap(); - api.prevent_close(); + if let Ok(true) = store::get_settings().map(|store| store.value.background) { + window.hide().unwrap(); + api.prevent_close(); + } else { + window.app_handle().exit(0); + } } }) .run(tauri::generate_context!()) diff --git a/src-tauri/src/plugins/mod.rs b/src-tauri/src/plugins/mod.rs index bfea423..25d6d4d 100644 --- a/src-tauri/src/plugins/mod.rs +++ b/src-tauri/src/plugins/mod.rs @@ -142,6 +142,7 @@ pub async fn initialise_plugin(path: &path::PathBuf) -> anyhow::Result<()> { } let code_path = code_path.unwrap(); + let args = ["-port", "57116", "-pluginUUID", plugin_uuid, "-registerEvent", "registerPlugin", "-info"]; if code_path.to_lowercase().ends_with(".html") || code_path.to_lowercase().ends_with(".htm") || code_path.to_lowercase().ends_with(".xhtml") { // Create a webview window for the plugin and call its registration function. @@ -177,7 +178,9 @@ pub async fn initialise_plugin(path: &path::PathBuf) -> anyhow::Result<()> { INSTANCES.lock().await.insert(plugin_uuid.to_owned(), PluginInstance::Webview); } else if code_path.to_lowercase().ends_with(".js") || code_path.to_lowercase().ends_with(".mjs") || code_path.to_lowercase().ends_with(".cjs") { // Check for Node.js installation and version in one go. - let version_output = Command::new("node").arg("--version").output(); + let command = if std::env::var("container").is_ok() { "flatpak-spawn" } else { "node" }; + let extra_args = if std::env::var("container").is_ok() { vec!["--host", "node"] } else { vec![] }; + let version_output = Command::new(command).args(&extra_args).arg("--version").output(); if version_output.is_err() || String::from_utf8(version_output.unwrap().stdout).unwrap().trim() < "v20.0.0" { return Err(anyhow!("Node version 20.0.0 or higher is required, or Node is not installed")); } @@ -185,45 +188,33 @@ pub async fn initialise_plugin(path: &path::PathBuf) -> anyhow::Result<()> { let info = info_param::make_info(plugin_uuid.to_owned(), manifest.version, true).await; let log_file = fs::File::create(path.parent().unwrap().parent().unwrap().join("logs").join("plugins").join(format!("{plugin_uuid}.log")))?; // Start Node with the appropriate arguments. - let child = Command::new("node") + let child = Command::new(command) .current_dir(path) - .args([ - code_path, - String::from("-port"), - 57116.to_string(), - String::from("-pluginUUID"), - plugin_uuid.to_owned(), - String::from("-registerEvent"), - String::from("registerPlugin"), - String::from("-info"), - serde_json::to_string(&info)?, - ]) + .args(extra_args) + .arg(code_path) + .args(args) + .arg(serde_json::to_string(&info)?) .stdout(Stdio::from(log_file.try_clone()?)) .stderr(Stdio::from(log_file)) .spawn()?; INSTANCES.lock().await.insert(plugin_uuid.to_owned(), PluginInstance::Node(child)); } else if use_wine { - if Command::new("wine").stdout(Stdio::null()).stderr(Stdio::null()).spawn().is_err() { + let command = if std::env::var("container").is_ok() { "flatpak-spawn" } else { "wine" }; + let extra_args = if std::env::var("container").is_ok() { vec!["--host", "wine"] } else { vec![] }; + if Command::new(command).stdout(Stdio::null()).stderr(Stdio::null()).spawn().is_err() { return Err(anyhow!("failed to detect an installation of Wine")); } let info = info_param::make_info(plugin_uuid.to_owned(), manifest.version, true).await; let log_file = fs::File::create(path.parent().unwrap().parent().unwrap().join("logs").join("plugins").join(format!("{plugin_uuid}.log")))?; // Start Wine with the appropriate arguments. - let child = Command::new("wine") + let child = Command::new(command) .current_dir(path) - .args([ - &code_path, - "-port", - "57116", - "-pluginUUID", - plugin_uuid, - "-registerEvent", - "registerPlugin", - "-info", - &serde_json::to_string(&info)?, - ]) + .args(extra_args) + .arg(code_path) + .args(args) + .arg(serde_json::to_string(&info)?) .stdout(Stdio::from(log_file.try_clone()?)) .stderr(Stdio::from(log_file)) .spawn()?; @@ -236,16 +227,8 @@ pub async fn initialise_plugin(path: &path::PathBuf) -> anyhow::Result<()> { #[cfg(target_os = "windows")] let child = Command::new(path.join(code_path)) .current_dir(path) - .args([ - "-port", - "57116", - "-pluginUUID", - plugin_uuid, - "-registerEvent", - "registerPlugin", - "-info", - &serde_json::to_string(&info)?, - ]) + .args(args) + .arg(serde_json::to_string(&info)?) .stdout(Stdio::from(log_file.try_clone()?)) .stderr(Stdio::from(log_file)) .creation_flags(0x08000000) @@ -253,16 +236,8 @@ pub async fn initialise_plugin(path: &path::PathBuf) -> anyhow::Result<()> { #[cfg(not(target_os = "windows"))] let child = Command::new(path.join(code_path)) .current_dir(path) - .args([ - "-port", - "57116", - "-pluginUUID", - plugin_uuid, - "-registerEvent", - "registerPlugin", - "-info", - &serde_json::to_string(&info)?, - ]) + .args(args) + .arg(serde_json::to_string(&info)?) .stdout(Stdio::from(log_file.try_clone()?)) .stderr(Stdio::from(log_file)) .spawn()?; diff --git a/src-tauri/src/store/mod.rs b/src-tauri/src/store/mod.rs index 9990d7a..0a7961b 100644 --- a/src-tauri/src/store/mod.rs +++ b/src-tauri/src/store/mod.rs @@ -68,6 +68,7 @@ where #[serde(default)] pub struct Settings { pub language: String, + pub background: bool, pub autolaunch: bool, pub darktheme: bool, pub brightness: u8, @@ -78,6 +79,7 @@ impl Default for Settings { fn default() -> Self { Self { language: "en".to_owned(), + background: std::env::var("container").is_err(), autolaunch: false, darktheme: true, brightness: 50, diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index d472bb4..65809b5 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -10,21 +10,23 @@ "targets": "all", "linux": { "deb": { - "desktopTemplate": "opendeck.desktop", + "desktopTemplate": "bundle/opendeck.desktop", "files": { - "/etc/udev/rules.d/40-streamdeck.rules": "40-streamdeck.rules" + "/etc/udev/rules.d/40-streamdeck.rules": "bundle/40-streamdeck.rules", + "/app/share/metainfo/me.amankhanna.opendeck.metainfo.xml": "bundle/me.amankhanna.opendeck.metainfo.xml" } }, "rpm": { - "desktopTemplate": "opendeck.desktop", + "desktopTemplate": "bundle/opendeck.desktop", "files": { - "/etc/udev/rules.d/40-streamdeck.rules": "40-streamdeck.rules" + "/etc/udev/rules.d/40-streamdeck.rules": "bundle/40-streamdeck.rules", + "/app/share/metainfo/me.amankhanna.opendeck.metainfo.xml": "bundle/me.amankhanna.opendeck.metainfo.xml" } } }, "publisher": "ninjadev64", - "shortDescription": "A cross-platform desktop application for ProntoKey and Stream Deck.", - "longDescription": "OpenDeck is a cross-platform desktop application that provides functionality for stream controller devices.", + "shortDescription": "A cross-platform desktop application for stream controller devices", + "longDescription": "OpenDeck is a desktop application for using stream controller devices like the Elgato Stream Deck. OpenDeck conforms to the OpenAction API, which is cross-compatible with the Stream Deck SDK, allowing a wide range of pre-existing plugins to be used.", "category": "Productivity", "icon": [ "icons/icon.png", diff --git a/src/components/SettingsView.svelte b/src/components/SettingsView.svelte index e3f7430..1ac0e42 100644 --- a/src/components/SettingsView.svelte +++ b/src/components/SettingsView.svelte @@ -51,6 +51,12 @@ +
+ Run in background: + + If this option is enabled, OpenDeck will minimise to the tray and run in the background. +
+
Autolaunch: diff --git a/src/lib/settings.ts b/src/lib/settings.ts index 88f7799..9234f5b 100644 --- a/src/lib/settings.ts +++ b/src/lib/settings.ts @@ -1,5 +1,6 @@ export type Settings = { language: string; + background: boolean; autolaunch: boolean; darktheme: boolean; brightness: number;