diff --git a/packages/desktop/Cargo.toml b/packages/desktop/Cargo.toml index 92ee0f43..39a62472 100644 --- a/packages/desktop/Cargo.toml +++ b/packages/desktop/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "desktop" version = "0.0.0" -description = "A Tauri App" +description = "Zebar is a tool for creating customizable and cross-platform taskbars, desktop widgets, and popups." authors = ["you"] license = "" repository = "" diff --git a/packages/desktop/resources/start.bat b/packages/desktop/resources/start.bat new file mode 100644 index 00000000..7c1d1abb --- /dev/null +++ b/packages/desktop/resources/start.bat @@ -0,0 +1,5 @@ +@echo off +@REM Start hidden powershell script, which runs `zebar open bar --args ...` for every monitor. +powershell -WindowStyle hidden -Command ^ + $monitors = zebar monitors; ^ + foreach ($monitor in $monitors) { Start-Process -NoNewWindow -FilePath \"zebar\" -ArgumentList \"open bar --args $monitor\" }; diff --git a/packages/desktop/resources/start.sh b/packages/desktop/resources/start.sh new file mode 100644 index 00000000..ec6e6642 --- /dev/null +++ b/packages/desktop/resources/start.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +# Run `zebar open bar --args ...` for every monitor. +zebar monitors --print0 | xargs -0 -P 99 -I % sh -c 'zebar open bar --args %' diff --git a/packages/desktop/src/cli.rs b/packages/desktop/src/cli.rs index 85923705..342b0dc7 100644 --- a/packages/desktop/src/cli.rs +++ b/packages/desktop/src/cli.rs @@ -4,7 +4,7 @@ use anyhow::Result; use clap::{Parser, Subcommand}; #[derive(Parser, Debug)] -#[clap(author, version, about, long_about = None)] +#[clap(author, version, about, long_about = None, arg_required_else_help = true)] pub struct Cli { #[command(subcommand)] pub command: CliCommand, @@ -12,14 +12,14 @@ pub struct Cli { #[derive(Subcommand, Debug)] pub enum CliCommand { - /// Open a window by its ID (eg. 'zebar open bar'). + /// Open a window by its ID (eg. `zebar open bar`). Open { - /// ID of the window to open (eg. 'bar'). + /// ID of the window to open (eg. `bar`). window_id: String, /// Arguments to pass to the window. /// - /// These become available via the 'self' provider. + /// These become available via the `self` provider. #[clap(short, long, num_args = 1.., value_parser=parse_open_args)] args: Option>, }, @@ -28,13 +28,13 @@ pub enum CliCommand { /// Use ASCII NUL character (character code 0) instead of newlines /// for delimiting monitors. /// - /// Useful for piping to 'xargs -0'. + /// Useful for piping to `xargs -0`. #[clap(short, long)] print0: bool, }, } -/// Print to `stdout`/`stderror` and exit the process. +/// Print to stdout/stderror and exit the process. pub fn print_and_exit(output: Result) { match output { Ok(output) => { diff --git a/packages/desktop/src/main.rs b/packages/desktop/src/main.rs index 5773db28..e0a991b8 100644 --- a/packages/desktop/src/main.rs +++ b/packages/desktop/src/main.rs @@ -1,12 +1,6 @@ -// Prevents additional console window on Windows in release. -#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] #![feature(unix_sigpipe)] -use std::{ - collections::HashMap, - env::{self}, - sync::Arc, -}; +use std::{collections::HashMap, env, sync::Arc}; use anyhow::{Context, Result}; use clap::Parser; diff --git a/packages/desktop/src/user_config.rs b/packages/desktop/src/user_config.rs index a325747a..48175eea 100644 --- a/packages/desktop/src/user_config.rs +++ b/packages/desktop/src/user_config.rs @@ -1,4 +1,4 @@ -use std::{fs, io::Read, path::PathBuf}; +use std::{fs, path::PathBuf}; use anyhow::{Context, Result}; use tauri::{path::BaseDirectory, AppHandle, Manager}; @@ -19,42 +19,51 @@ pub fn read_file( }; // Create new config file from sample if it doesn't exist. - match config_path.exists() { - true => fs::read_to_string(&config_path) - .context("Unable to read config file."), - false => create_from_sample(&config_path, app_handle), + if !config_path.exists() { + create_from_sample(&config_path, app_handle)?; } + + fs::read_to_string(&config_path).context("Unable to read config file.") } /// Initialize config at the given path from the sample config resource. +/// Also adds startup scripts for Windows and Unix. fn create_from_sample( config_path: &PathBuf, app_handle: AppHandle, -) -> Result { - let sample_path = app_handle +) -> Result<()> { + let resources_path = app_handle .path() - .resolve("resources/sample-config.yaml", BaseDirectory::Resource) - .context("Unable to resolve sample config path.")?; - - let mut sample_file = fs::File::open(&sample_path) - .context("Unable to read sample config.")?; + .resolve("resources", BaseDirectory::Resource) + .context("Unable to resolve resources for creating sample config.")?; - // Read the contents of the sample config. - let mut config_string = String::new(); - sample_file.read_to_string(&mut config_string)?; - - let parent_dir = + let dest_dir = config_path.parent().context("Invalid config directory.")?; - // Create the containing directory for the config file. - std::fs::create_dir_all(&parent_dir).with_context(|| { + // Create the destination directory. + std::fs::create_dir_all(&dest_dir).with_context(|| { format!("Unable to create directory {}.", &config_path.display()) })?; - fs::write(&config_path, &config_string) - .context("Unable to write config file.")?; + let sample_filenames = + vec!["sample-config.yaml", "start.sh", "start.bat"]; + + // Copy over sample config and startup scripts. + for sample_filename in sample_filenames { + let dest_filename = match sample_filename { + "sample-config.yaml" => "config.yaml", + other => other, + }; - Ok(config_string) + let src_path = resources_path.join(sample_filename); + let dest_path = dest_dir.join(dest_filename); + + fs::copy(&src_path, &dest_path).with_context(|| { + format!("Unable to write to {}.", dest_path.display()) + })?; + } + + Ok(()) } pub fn open_config_dir(app_handle: AppHandle) -> Result<()> {