feat: no console in windows

This commit is contained in:
Gabor Körber 2024-06-09 14:25:18 +02:00
parent 090bea5805
commit 36d7a64148
3 changed files with 37 additions and 15 deletions

View File

@ -46,6 +46,7 @@ features = [
"Win32_UI_Controls", "Win32_UI_Controls",
"Win32_Graphics_Dwm", "Win32_Graphics_Dwm",
"Win32_UI_Shell", "Win32_UI_Shell",
"Win32_System_Console", # attaching to console
] ]
#[target.'cfg(windows)'.dependencies.windows-sys] #[target.'cfg(windows)'.dependencies.windows-sys]

View File

@ -1,3 +1,5 @@
#![cfg_attr(not(test), windows_subsystem = "windows")] // not(debug_assertions) would hide the console only on release builds.
use axum_template::engine::Engine; use axum_template::engine::Engine;
use minijinja::{path_loader, Environment}; use minijinja::{path_loader, Environment};
use state::AppState; use state::AppState;
@ -19,6 +21,16 @@ mod vbplay;
fn main() { fn main() {
dotenv().ok(); dotenv().ok();
#[cfg(target_os = "windows")]
{
// if you run this from a windows console, we attach to the parent process.
use windows::Win32::System::Console::{AttachConsole, ATTACH_PARENT_PROCESS};
unsafe {
AttachConsole(ATTACH_PARENT_PROCESS).unwrap_or_default();
}
}
let rt = tokio::runtime::Runtime::new().unwrap(); let rt = tokio::runtime::Runtime::new().unwrap();
let device_pattern = env::var("DEVICE_PATTERN").expect("Need a device pattern"); let device_pattern = env::var("DEVICE_PATTERN").expect("Need a device pattern");
@ -32,6 +44,7 @@ fn main() {
DeviceSelection::FindByPattern(device_pattern), DeviceSelection::FindByPattern(device_pattern),
SoundDecoder::Detect, SoundDecoder::Detect,
); );
let event_handler = Box::new(example_handler::PressMouseForward::new()); let event_handler = Box::new(example_handler::PressMouseForward::new());
audio.on_playback(event_handler); audio.on_playback(event_handler);
let audio = Arc::new(Mutex::new(audio)); let audio = Arc::new(Mutex::new(audio));
@ -52,6 +65,7 @@ fn main() {
}; };
let (ui_to_server_tx, ui_to_server_rx) = mpsc::channel(32); let (ui_to_server_tx, ui_to_server_rx) = mpsc::channel(32);
//let (server_to_ui_tx, server_to_ui_rx) = mpsc::channel(32);
let server_handle = rt.spawn(async move { let server_handle = rt.spawn(async move {
server::run_server(app_state, ui_to_server_rx).await; server::run_server(app_state, ui_to_server_rx).await;
@ -72,5 +86,5 @@ fn main() {
drop(audio); drop(audio);
eprintln!("Reached end of program."); eprintln!("Reached end of program.");
std::process::exit(0); //std::process::exit(0);
} }

View File

@ -1,19 +1,26 @@
use eframe::egui; use eframe::egui;
use raw_window_handle::{HasWindowHandle, RawWindowHandle}; use raw_window_handle::{HasWindowHandle, RawWindowHandle};
use std::sync::{Arc, Mutex}; use std::sync::Mutex;
use std::sync::{
atomic::{AtomicBool, Ordering},
Arc,
};
use tokio::sync::mpsc; use tokio::sync::mpsc;
use tray_item::TrayItem; use tray_item::TrayItem;
use crate::server::{ServerMessage, ServerSettings}; use crate::server::{ServerMessage, ServerSettings};
pub enum UIMessage {
ServerHasQuit,
}
pub fn run_ui( pub fn run_ui(
settings: Arc<Mutex<ServerSettings>>, settings: Arc<Mutex<ServerSettings>>,
should_run: Arc<Mutex<bool>>, should_run: Arc<Mutex<bool>>,
tx: mpsc::Sender<ServerMessage>, tx: mpsc::Sender<ServerMessage>,
) { ) {
// Create an atomic bool to track window visibility // Initialize visibility as AtomicBool
static VISIBLE: once_cell::sync::Lazy<Mutex<bool>> = let visible = Arc::new(AtomicBool::new(true));
once_cell::sync::Lazy::new(|| Mutex::new(true));
let icon = crate::icon::load_app_icon("icon-soundboard"); let icon = crate::icon::load_app_icon("icon-soundboard");
@ -22,11 +29,12 @@ pub fn run_ui(
..Default::default() ..Default::default()
}; };
let visible_for_tray = Arc::clone(&visible);
eframe::run_native( eframe::run_native(
"App", "App",
native_options, native_options,
Box::new(|cc| { Box::new(|cc| {
// Set up the tray icon event handler
let window_handle = cc.window_handle().unwrap(); let window_handle = cc.window_handle().unwrap();
let window_handle = window_handle.as_raw(); let window_handle = window_handle.as_raw();
let mut tray = TrayItem::new( let mut tray = TrayItem::new(
@ -34,34 +42,33 @@ pub fn run_ui(
tray_item::IconSource::Resource("icon-soundboard"), tray_item::IconSource::Resource("icon-soundboard"),
) )
.unwrap(); .unwrap();
if let RawWindowHandle::Win32(handle) = window_handle { if let RawWindowHandle::Win32(handle) = window_handle {
#[cfg(windows)] #[cfg(windows)]
{ {
// Windows Only.
use windows::Win32::Foundation::HWND; use windows::Win32::Foundation::HWND;
use windows::Win32::UI::WindowsAndMessaging::{ use windows::Win32::UI::WindowsAndMessaging::{
ShowWindow, ShowWindow, SW_HIDE, SW_RESTORE,
SW_HIDE,
SW_RESTORE, // SW_SHOWDEFAULT, SW_SHOWNORMAL,
}; };
tray.add_label("Server Control").unwrap(); tray.add_label("Server Control").unwrap();
tray.add_menu_item("Show/Hide", {
move || {
let mut visible_lock = VISIBLE.lock().unwrap();
let window_handle = HWND(handle.hwnd.into()); let window_handle = HWND(handle.hwnd.into());
tray.add_menu_item("Show/Hide", {
//let visible_for_tray = Arc::clone(&visible_for_tray);
move || {
let is_visible = visible_for_tray.load(Ordering::SeqCst);
if *visible_lock { if is_visible {
unsafe { unsafe {
_ = ShowWindow(window_handle, SW_HIDE); _ = ShowWindow(window_handle, SW_HIDE);
} }
*visible_lock = false; visible_for_tray.store(false, Ordering::SeqCst);
} else { } else {
unsafe { unsafe {
_ = ShowWindow(window_handle, SW_RESTORE); _ = ShowWindow(window_handle, SW_RESTORE);
} }
*visible_lock = true; visible_for_tray.store(true, Ordering::SeqCst);
} }
} }
}) })