Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 82181545a6 | |||
| e3f823045c |
Generated
+1
-1
@@ -2224,7 +2224,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mouth"
|
name = "mouth"
|
||||||
version = "0.2.1"
|
version = "0.2.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"arboard",
|
"arboard",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "mouth"
|
name = "mouth"
|
||||||
version = "0.2.2"
|
version = "0.2.3"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
description = "Offline speech-to-text with global hotkey and paste"
|
description = "Offline speech-to-text with global hotkey and paste"
|
||||||
license-file = "LICENSE"
|
license-file = "LICENSE"
|
||||||
|
|||||||
@@ -170,7 +170,13 @@ if [ ${#BUILT[@]} -eq 0 ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
|
if [ -t 0 ]; then
|
||||||
read -rp "Publish release ${TAG} to ${FORGE}? [y/N] " confirm
|
read -rp "Publish release ${TAG} to ${FORGE}? [y/N] " confirm
|
||||||
|
else
|
||||||
|
# Non-interactive (piped/scripted) — default to yes
|
||||||
|
confirm="y"
|
||||||
|
echo "Non-interactive mode: auto-publishing release ${TAG} to ${FORGE}"
|
||||||
|
fi
|
||||||
if [[ ! "${confirm}" =~ ^[Yy]$ ]]; then
|
if [[ ! "${confirm}" =~ ^[Yy]$ ]]; then
|
||||||
echo "Skipped. Artifacts are in ${RELEASE_DIR}/"
|
echo "Skipped. Artifacts are in ${RELEASE_DIR}/"
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
@@ -22,10 +22,6 @@ pub fn run() -> Result<()> {
|
|||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide Windows console window
|
|
||||||
#[cfg(windows)]
|
|
||||||
hide_console();
|
|
||||||
|
|
||||||
info!("Mouth v{} starting", env!("CARGO_PKG_VERSION"));
|
info!("Mouth v{} starting", env!("CARGO_PKG_VERSION"));
|
||||||
info!("Mode: {:?}", config.mode);
|
info!("Mode: {:?}", config.mode);
|
||||||
info!("Hotkey: {}", config.hotkey);
|
info!("Hotkey: {}", config.hotkey);
|
||||||
@@ -146,15 +142,3 @@ pub fn run() -> Result<()> {
|
|||||||
ipc::cleanup();
|
ipc::cleanup();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
fn hide_console() {
|
|
||||||
use windows_sys::Win32::System::Console::GetConsoleWindow;
|
|
||||||
use windows_sys::Win32::UI::WindowsAndMessaging::{ShowWindow, SW_HIDE};
|
|
||||||
unsafe {
|
|
||||||
let console = GetConsoleWindow();
|
|
||||||
if !console.is_null() {
|
|
||||||
ShowWindow(console, SW_HIDE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+2
-2
@@ -2,7 +2,7 @@ use anyhow::{Context, Result};
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tracing::{debug, info, warn};
|
use tracing::{debug, info};
|
||||||
|
|
||||||
use crate::shared_state::SharedState;
|
use crate::shared_state::SharedState;
|
||||||
|
|
||||||
@@ -116,7 +116,7 @@ fn unix_listener(path: &str, shared_state: Arc<SharedState>) -> Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!("Failed to serialize status: {e}");
|
tracing::warn!("Failed to serialize status: {e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+41
-2
@@ -1,3 +1,5 @@
|
|||||||
|
#![cfg_attr(windows, windows_subsystem = "windows")]
|
||||||
|
|
||||||
mod audio_feedback;
|
mod audio_feedback;
|
||||||
mod cli;
|
mod cli;
|
||||||
mod config;
|
mod config;
|
||||||
@@ -48,7 +50,16 @@ enum Commands {
|
|||||||
Status,
|
Status,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> anyhow::Result<()> {
|
fn main() {
|
||||||
|
// Attach to parent console when launched from a terminal so CLI subcommands
|
||||||
|
// can write output. Silently fails when double-clicked (no parent console).
|
||||||
|
#[cfg(windows)]
|
||||||
|
unsafe {
|
||||||
|
windows_sys::Win32::System::Console::AttachConsole(
|
||||||
|
windows_sys::Win32::System::Console::ATTACH_PARENT_PROCESS,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
tracing_subscriber::fmt()
|
tracing_subscriber::fmt()
|
||||||
.with_env_filter(
|
.with_env_filter(
|
||||||
tracing_subscriber::EnvFilter::try_from_default_env()
|
tracing_subscriber::EnvFilter::try_from_default_env()
|
||||||
@@ -57,8 +68,9 @@ fn main() -> anyhow::Result<()> {
|
|||||||
.init();
|
.init();
|
||||||
|
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
|
let is_daemon = matches!(cli.command, None | Some(Commands::Run));
|
||||||
|
|
||||||
match cli.command {
|
let result = match cli.command {
|
||||||
None | Some(Commands::Run) => cli::run_cmd::run(),
|
None | Some(Commands::Run) => cli::run_cmd::run(),
|
||||||
|
|
||||||
Some(Commands::Config { show, reset }) => {
|
Some(Commands::Config { show, reset }) => {
|
||||||
@@ -80,5 +92,32 @@ fn main() -> anyhow::Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Some(Commands::Status) => cli::status_cmd::status(),
|
Some(Commands::Status) => cli::status_cmd::status(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Err(e) = result {
|
||||||
|
if is_daemon {
|
||||||
|
#[cfg(windows)]
|
||||||
|
show_error_dialog(&format!("Mouth failed to start:\n\n{e:#}"));
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
eprintln!("Error: {e:#}");
|
||||||
|
} else {
|
||||||
|
eprintln!("Error: {e:#}");
|
||||||
|
}
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn show_error_dialog(message: &str) {
|
||||||
|
use windows_sys::Win32::UI::WindowsAndMessaging::{MessageBoxW, MB_ICONERROR, MB_OK};
|
||||||
|
let title: Vec<u16> = "Mouth".encode_utf16().chain(Some(0)).collect();
|
||||||
|
let msg: Vec<u16> = message.encode_utf16().chain(Some(0)).collect();
|
||||||
|
unsafe {
|
||||||
|
MessageBoxW(
|
||||||
|
std::ptr::null_mut(),
|
||||||
|
msg.as_ptr(),
|
||||||
|
title.as_ptr(),
|
||||||
|
MB_OK | MB_ICONERROR,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user