diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index bfee1933..05c07e65 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -1560,12 +1560,46 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "libappindicator" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2d3cb96d092b4824cb306c9e544c856a4cb6210c1081945187f7f1924b47e8" +dependencies = [ + "glib", + "gtk", + "gtk-sys", + "libappindicator-sys", + "log", +] + +[[package]] +name = "libappindicator-sys" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1b3b6681973cea8cc3bce7391e6d7d5502720b80a581c9a95c9cbaf592826aa" +dependencies = [ + "gtk-sys", + "libloading", + "once_cell", +] + [[package]] name = "libc" version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + [[package]] name = "line-wrap" version = "0.1.1" @@ -2936,6 +2970,7 @@ dependencies = [ "core-foundation", "core-graphics 0.22.3", "crossbeam-channel", + "dirs-next", "dispatch", "gdk", "gdk-pixbuf", @@ -2950,6 +2985,7 @@ dependencies = [ "instant", "jni", "lazy_static", + "libappindicator", "libc", "log", "ndk", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 6f994f30..d6e71dd4 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -13,7 +13,7 @@ edition = "2021" tauri-build = { version = "1.5", features = [] } [dependencies] -tauri = { version = "1.5", features = [ "window-set-size", "window-set-always-on-top", "window-start-dragging", "macos-private-api", "devtools", "http-all"] } +tauri = { version = "1.5", features = [ "system-tray", "window-set-size", "window-set-always-on-top", "window-start-dragging", "macos-private-api", "devtools", "http-all"] } serde = { version = "1.0", features = ["derive"] } tauri-plugin-websocket = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" } serde_json = "1.0" diff --git a/src-tauri/icons/32x32.png b/src-tauri/icons/32x32.png new file mode 100644 index 00000000..ce677181 Binary files /dev/null and b/src-tauri/icons/32x32.png differ diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 02ec8829..c84da27b 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -1,9 +1,63 @@ -// Prevents additional console window on Windows in release, DO NOT REMOVE!! -#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] +#![cfg_attr( + all(not(debug_assertions), target_os = "windows"), + windows_subsystem = "windows" +)] + +#[cfg(target_os = "macos")] +#[macro_use] +extern crate objc; + +mod window_custom; + +use tauri::{ + CustomMenuItem, Manager, RunEvent, SystemTray, SystemTrayEvent, + SystemTrayMenu, +}; +use window_custom::WindowExt as _; fn main() { - tauri::Builder::default() + // System tray configuration + let tray = SystemTray::new().with_menu( + SystemTrayMenu::new() + .add_item(CustomMenuItem::new("show_overlayed", "Show Overlayed")) + .add_item(CustomMenuItem::new("quit", "Quit")) + ); + + let app = tauri::Builder::default() .plugin(tauri_plugin_websocket::init()) - .run(tauri::generate_context!()) - .expect("error while running tauri application"); + .setup(|app| { + let window = app.get_window("main").unwrap(); + #[cfg(target_os = "macos")] + window.set_transparent_titlebar(true, true); + // Move the window to the center of the screen + window.center().expect("Cannot move window!"); + + // Open dev tools + #[cfg(debug_assertions)] + window.open_devtools(); + Ok(()) + }) + // Add the system tray + .system_tray(tray) + // Handle system tray events + .on_system_tray_event(|app, event| match event { + SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() { + "quit" => std::process::exit(0), + "show_overlayed" => { + let window = app.get_window("main").unwrap(); + window.show().unwrap(); + window.set_focus().unwrap(); + } + _ => {} + }, + _ => {} + }) + .build(tauri::generate_context!()) + .expect("An error occured while running the app!"); + + app.run(|_app_handle, e| match e { + RunEvent::Ready => { + } + _ => {} + }) } diff --git a/src-tauri/src/window_custom.rs b/src-tauri/src/window_custom.rs new file mode 100644 index 00000000..cf43c5d9 --- /dev/null +++ b/src-tauri/src/window_custom.rs @@ -0,0 +1,46 @@ +#[cfg(target_os = "macos")] +use cocoa::appkit::{NSWindow, NSWindowButton, NSWindowStyleMask, NSWindowTitleVisibility}; + +#[cfg(target_os = "macos")] +use objc::runtime::YES; +use tauri::{Runtime, Window}; + +pub trait WindowExt { + #[cfg(target_os = "macos")] + fn set_transparent_titlebar(&self, title_transparent: bool, remove_toolbar: bool); +} + +impl WindowExt for Window { + #[cfg(target_os = "macos")] + fn set_transparent_titlebar(&self, title_transparent: bool, remove_tool_bar: bool) { + unsafe { + let id = self.ns_window().unwrap() as cocoa::base::id; + NSWindow::setTitlebarAppearsTransparent_(id, cocoa::base::YES); + let mut style_mask = id.styleMask(); + style_mask.set( + NSWindowStyleMask::NSFullSizeContentViewWindowMask, + title_transparent, + ); + id.setStyleMask_(style_mask); + if remove_tool_bar { + let close_button = id.standardWindowButton_(NSWindowButton::NSWindowCloseButton); + let _: () = msg_send![close_button, setHidden: YES]; + let min_button = + id.standardWindowButton_(NSWindowButton::NSWindowMiniaturizeButton); + let _: () = msg_send![min_button, setHidden: YES]; + let zoom_button = id.standardWindowButton_(NSWindowButton::NSWindowZoomButton); + let _: () = msg_send![zoom_button, setHidden: YES]; + } + id.setTitleVisibility_(if title_transparent { + NSWindowTitleVisibility::NSWindowTitleHidden + } else { + NSWindowTitleVisibility::NSWindowTitleVisible + }); + id.setTitlebarAppearsTransparent_(if title_transparent { + cocoa::base::YES + } else { + cocoa::base::NO + }); + } + } +} diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index d469cf5a..c07f6f51 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -11,6 +11,10 @@ "version": "0.0.0" }, "tauri": { + "systemTray": { + "iconPath": "icons/32x32.png", + "iconAsTemplate": true + }, "allowlist": { "all": false, "http": { @@ -44,7 +48,6 @@ "fullscreen": false, "resizable": true, "transparent": true, - "decorations": false, "title": "overlayed-rust-test", "width": 420, "height": 600 diff --git a/src/components/nav-bar.tsx b/src/components/nav-bar.tsx index a927eccf..9a0468bf 100644 --- a/src/components/nav-bar.tsx +++ b/src/components/nav-bar.tsx @@ -28,7 +28,7 @@ export const NavBar = () => { return (
overlayed
{getNavLink()}
diff --git a/src/components/user.tsx b/src/components/user.tsx index 7d1c664b..24d9f756 100644 --- a/src/components/user.tsx +++ b/src/components/user.tsx @@ -17,7 +17,7 @@ export const User = ({ item }: { item: OverlayedUser }) => { avatar
-
{item.username}
+
{item.username}
); }; diff --git a/src/views/settings.tsx b/src/views/settings.tsx index 782014ae..44fca140 100644 --- a/src/views/settings.tsx +++ b/src/views/settings.tsx @@ -2,6 +2,17 @@ export const Settings = () => { return (

Settings

+
+ +
); };