new tray
This commit is contained in:
parent
900d0e8be9
commit
f7643077d3
670
Cargo.lock
generated
670
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
13
Cargo.toml
13
Cargo.toml
@ -86,7 +86,6 @@ arboard = "2.0"
|
|||||||
system_shutdown = "3.0.0"
|
system_shutdown = "3.0.0"
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
#systray = { git = "https://github.com/open-trade/systray-rs" }
|
|
||||||
trayicon = { git = "https://github.com/open-trade/trayicon-rs", features = ["winit"] }
|
trayicon = { git = "https://github.com/open-trade/trayicon-rs", features = ["winit"] }
|
||||||
winit = "0.26"
|
winit = "0.26"
|
||||||
winapi = { version = "0.3", features = ["winuser"] }
|
winapi = { version = "0.3", features = ["winuser"] }
|
||||||
@ -104,11 +103,15 @@ dispatch = "0.2"
|
|||||||
core-foundation = "0.9"
|
core-foundation = "0.9"
|
||||||
core-graphics = "0.22"
|
core-graphics = "0.22"
|
||||||
include_dir = "0.7.2"
|
include_dir = "0.7.2"
|
||||||
tray-item = "0.7" # looks better than trayicon
|
dark-light = "1.0"
|
||||||
dark-light = "0.2"
|
|
||||||
fruitbasket = "0.10.0"
|
fruitbasket = "0.10.0"
|
||||||
objc_id = "0.1.1"
|
objc_id = "0.1.1"
|
||||||
|
|
||||||
|
[target.'cfg(any(target_os = "macos", target_os = "linux"))'.dependencies]
|
||||||
|
tray-icon = "0.4"
|
||||||
|
tao = { git = "https://github.com/tauri-apps/tao", branch = "muda" }
|
||||||
|
image = "0.24"
|
||||||
|
|
||||||
[target.'cfg(target_os = "linux")'.dependencies]
|
[target.'cfg(target_os = "linux")'.dependencies]
|
||||||
psimple = { package = "libpulse-simple-binding", version = "2.25" }
|
psimple = { package = "libpulse-simple-binding", version = "2.25" }
|
||||||
pulse = { package = "libpulse-binding", version = "2.26" }
|
pulse = { package = "libpulse-binding", version = "2.26" }
|
||||||
@ -118,9 +121,6 @@ mouce = { git="https://github.com/fufesou/mouce.git" }
|
|||||||
evdev = { git="https://github.com/fufesou/evdev" }
|
evdev = { git="https://github.com/fufesou/evdev" }
|
||||||
dbus = "0.9"
|
dbus = "0.9"
|
||||||
dbus-crossroads = "0.5"
|
dbus-crossroads = "0.5"
|
||||||
gtk = "0.15"
|
|
||||||
libappindicator = "0.7"
|
|
||||||
glib = "0.16.5"
|
|
||||||
backtrace = "0.3"
|
backtrace = "0.3"
|
||||||
|
|
||||||
[target.'cfg(target_os = "android")'.dependencies]
|
[target.'cfg(target_os = "android")'.dependencies]
|
||||||
@ -157,7 +157,6 @@ identifier = "com.carriez.rustdesk"
|
|||||||
icon = ["res/32x32.png", "res/128x128.png", "res/128x128@2x.png"]
|
icon = ["res/32x32.png", "res/128x128.png", "res/128x128@2x.png"]
|
||||||
deb_depends = ["libgtk-3-0", "libxcb-randr0", "libxdo3", "libxfixes3", "libxcb-shape0", "libxcb-xfixes0", "libasound2", "libsystemd0", "curl", "libvdpau1", "libva2"]
|
deb_depends = ["libgtk-3-0", "libxcb-randr0", "libxdo3", "libxfixes3", "libxcb-shape0", "libxcb-xfixes0", "libasound2", "libsystemd0", "curl", "libvdpau1", "libva2"]
|
||||||
osx_minimum_system_version = "10.14"
|
osx_minimum_system_version = "10.14"
|
||||||
resources = ["res/mac-tray-light.png","res/mac-tray-dark.png", "res/mac-tray-light-x2.png","res/mac-tray-dark-x2.png"]
|
|
||||||
|
|
||||||
#https://github.com/johnthagen/min-sized-rust
|
#https://github.com/johnthagen/min-sized-rust
|
||||||
[profile.release]
|
[profile.release]
|
||||||
|
@ -26,10 +26,6 @@
|
|||||||
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
|
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
|
||||||
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
|
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
|
||||||
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
|
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
|
||||||
7E4BCD762966B0EC006D24E2 /* mac-tray-light.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E4BCD742966B0EC006D24E2 /* mac-tray-light.png */; };
|
|
||||||
7E4BCD772966B0EC006D24E2 /* mac-tray-dark.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E4BCD752966B0EC006D24E2 /* mac-tray-dark.png */; };
|
|
||||||
7E881462296E98EE00A0C54F /* mac-tray-light-x2.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E881461296E98ED00A0C54F /* mac-tray-light-x2.png */; };
|
|
||||||
7E881464296E991200A0C54F /* mac-tray-dark-x2.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E881463296E991200A0C54F /* mac-tray-dark-x2.png */; };
|
|
||||||
84010BA8292CF66600152837 /* liblibrustdesk.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 84010BA7292CF66600152837 /* liblibrustdesk.dylib */; settings = {ATTRIBUTES = (Weak, ); }; };
|
84010BA8292CF66600152837 /* liblibrustdesk.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 84010BA7292CF66600152837 /* liblibrustdesk.dylib */; settings = {ATTRIBUTES = (Weak, ); }; };
|
||||||
84010BA9292CF68300152837 /* liblibrustdesk.dylib in Embed Libraries */ = {isa = PBXBuildFile; fileRef = 84010BA7292CF66600152837 /* liblibrustdesk.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
84010BA9292CF68300152837 /* liblibrustdesk.dylib in Embed Libraries */ = {isa = PBXBuildFile; fileRef = 84010BA7292CF66600152837 /* liblibrustdesk.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
C5E54335B73C89F72DB1B606 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26C84465887F29AE938039CB /* Pods_Runner.framework */; };
|
C5E54335B73C89F72DB1B606 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26C84465887F29AE938039CB /* Pods_Runner.framework */; };
|
||||||
@ -78,10 +74,6 @@
|
|||||||
33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
|
33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
|
||||||
7436B85D94E8F7B5A9324869 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
7436B85D94E8F7B5A9324869 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
|
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
|
||||||
7E4BCD742966B0EC006D24E2 /* mac-tray-light.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "mac-tray-light.png"; path = "../../res/mac-tray-light.png"; sourceTree = "<group>"; };
|
|
||||||
7E4BCD752966B0EC006D24E2 /* mac-tray-dark.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "mac-tray-dark.png"; path = "../../res/mac-tray-dark.png"; sourceTree = "<group>"; };
|
|
||||||
7E881461296E98ED00A0C54F /* mac-tray-light-x2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "mac-tray-light-x2.png"; path = "../../res/mac-tray-light-x2.png"; sourceTree = "<group>"; };
|
|
||||||
7E881463296E991200A0C54F /* mac-tray-dark-x2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "mac-tray-dark-x2.png"; path = "../../res/mac-tray-dark-x2.png"; sourceTree = "<group>"; };
|
|
||||||
84010BA7292CF66600152837 /* liblibrustdesk.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = liblibrustdesk.dylib; path = ../../target/release/liblibrustdesk.dylib; sourceTree = "<group>"; };
|
84010BA7292CF66600152837 /* liblibrustdesk.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = liblibrustdesk.dylib; path = ../../target/release/liblibrustdesk.dylib; sourceTree = "<group>"; };
|
||||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
|
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
|
||||||
C3BB669FF6190AE1B11BCAEA /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
C3BB669FF6190AE1B11BCAEA /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||||
@ -135,10 +127,6 @@
|
|||||||
33CC11242044D66E0003C045 /* Resources */ = {
|
33CC11242044D66E0003C045 /* Resources */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
7E881463296E991200A0C54F /* mac-tray-dark-x2.png */,
|
|
||||||
7E881461296E98ED00A0C54F /* mac-tray-light-x2.png */,
|
|
||||||
7E4BCD752966B0EC006D24E2 /* mac-tray-dark.png */,
|
|
||||||
7E4BCD742966B0EC006D24E2 /* mac-tray-light.png */,
|
|
||||||
33CC10F22044A3C60003C045 /* Assets.xcassets */,
|
33CC10F22044A3C60003C045 /* Assets.xcassets */,
|
||||||
33CC10F42044A3C60003C045 /* MainMenu.xib */,
|
33CC10F42044A3C60003C045 /* MainMenu.xib */,
|
||||||
33CC10F72044A3C60003C045 /* Info.plist */,
|
33CC10F72044A3C60003C045 /* Info.plist */,
|
||||||
@ -265,12 +253,8 @@
|
|||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
7E881462296E98EE00A0C54F /* mac-tray-light-x2.png in Resources */,
|
|
||||||
7E4BCD762966B0EC006D24E2 /* mac-tray-light.png in Resources */,
|
|
||||||
7E4BCD772966B0EC006D24E2 /* mac-tray-dark.png in Resources */,
|
|
||||||
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */,
|
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */,
|
||||||
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */,
|
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */,
|
||||||
7E881464296E991200A0C54F /* mac-tray-dark-x2.png in Resources */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 703 B |
Binary file not shown.
Before Width: | Height: | Size: 535 B |
Binary file not shown.
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 728 B |
Binary file not shown.
Before Width: | Height: | Size: 415 B |
@ -164,9 +164,6 @@ pub fn core_main() -> Option<Vec<String>> {
|
|||||||
#[cfg(feature = "with_rc")]
|
#[cfg(feature = "with_rc")]
|
||||||
hbb_common::allow_err!(crate::rc::extract_resources(&args[1]));
|
hbb_common::allow_err!(crate::rc::extract_resources(&args[1]));
|
||||||
return None;
|
return None;
|
||||||
} else if args[0] == "--tray" {
|
|
||||||
crate::tray::start_tray();
|
|
||||||
return None;
|
|
||||||
} else if args[0] == "--portable-service" {
|
} else if args[0] == "--portable-service" {
|
||||||
crate::platform::elevate_or_run_as_system(
|
crate::platform::elevate_or_run_as_system(
|
||||||
click_setup,
|
click_setup,
|
||||||
@ -183,34 +180,24 @@ pub fn core_main() -> Option<Vec<String>> {
|
|||||||
std::fs::remove_file(&args[1]).ok();
|
std::fs::remove_file(&args[1]).ok();
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
} else if args[0] == "--tray" {
|
||||||
|
crate::tray::start_tray();
|
||||||
|
return None;
|
||||||
} else if args[0] == "--service" {
|
} else if args[0] == "--service" {
|
||||||
log::info!("start --service");
|
log::info!("start --service");
|
||||||
crate::start_os_service();
|
crate::start_os_service();
|
||||||
return None;
|
return None;
|
||||||
} else if args[0] == "--server" {
|
} else if args[0] == "--server" {
|
||||||
log::info!("start --server with user {}", crate::username());
|
log::info!("start --server with user {}", crate::username());
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(any(target_os = "linux", target_os = "windows"))]
|
||||||
{
|
{
|
||||||
crate::start_server(true);
|
crate::start_server(true);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
{
|
|
||||||
std::thread::spawn(move || crate::start_server(true));
|
|
||||||
crate::platform::macos::hide_dock();
|
|
||||||
crate::ui::macos::make_tray();
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
{
|
{
|
||||||
let handler = std::thread::spawn(move || crate::start_server(true));
|
let handler = std::thread::spawn(move || crate::start_server(true));
|
||||||
// Show the tray in linux only when current user is a normal user
|
crate::tray::start_tray();
|
||||||
// [Note]
|
|
||||||
// As for GNOME, the tray cannot be shown in user's status bar.
|
|
||||||
// As for KDE, the tray can be shown without user's theme.
|
|
||||||
if !crate::platform::is_root() {
|
|
||||||
crate::tray::start_tray();
|
|
||||||
}
|
|
||||||
// prevent server exit when encountering errors from tray
|
// prevent server exit when encountering errors from tray
|
||||||
hbb_common::allow_err!(handler.join());
|
hbb_common::allow_err!(handler.join());
|
||||||
}
|
}
|
||||||
@ -349,6 +336,6 @@ fn core_main_invoke_new_connection(mut args: std::env::Args) -> Option<Vec<Strin
|
|||||||
Some(Vec::new())
|
Some(Vec::new())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ pub extern "C" fn rustdesk_core_main() -> bool {
|
|||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn handle_applicationShouldOpenUntitledFile() {
|
pub extern "C" fn handle_applicationShouldOpenUntitledFile() {
|
||||||
crate::platform::macos::handle_applicationShouldOpenUntitledFile();
|
crate::platform::macos::handle_application_should_open_untitled_file();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
|
@ -17,7 +17,7 @@ use core_graphics::{
|
|||||||
display::{kCGNullWindowID, kCGWindowListOptionOnScreenOnly, CGWindowListCopyWindowInfo},
|
display::{kCGNullWindowID, kCGWindowListOptionOnScreenOnly, CGWindowListCopyWindowInfo},
|
||||||
window::{kCGWindowName, kCGWindowOwnerPID},
|
window::{kCGWindowName, kCGWindowOwnerPID},
|
||||||
};
|
};
|
||||||
use hbb_common::{bail, log};
|
use hbb_common::{allow_err, bail, log};
|
||||||
use include_dir::{include_dir, Dir};
|
use include_dir::{include_dir, Dir};
|
||||||
use objc::{class, msg_send, sel, sel_impl};
|
use objc::{class, msg_send, sel, sel_impl};
|
||||||
use scrap::{libc::c_void, quartz::ffi::*};
|
use scrap::{libc::c_void, quartz::ffi::*};
|
||||||
@ -578,12 +578,12 @@ fn check_main_window() -> bool {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_applicationShouldOpenUntitledFile() {
|
pub fn handle_application_should_open_untitled_file() {
|
||||||
hbb_common::log::debug!("icon clicked on finder");
|
hbb_common::log::debug!("icon clicked on finder");
|
||||||
let x = std::env::args().nth(1).unwrap_or_default();
|
let x = std::env::args().nth(1).unwrap_or_default();
|
||||||
if x == "--server" || x == "--cm" {
|
if x == "--server" || x == "--cm" || x == "--tray" {
|
||||||
if crate::platform::macos::check_main_window() {
|
if crate::platform::macos::check_main_window() {
|
||||||
crate::ipc::send_url_scheme("rustdesk:".into());
|
allow_err!(crate::ipc::send_url_scheme("rustdesk:".into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
224
src/tray.rs
224
src/tray.rs
@ -1,11 +1,5 @@
|
|||||||
#[cfg(any(target_os = "linux", target_os = "windows"))]
|
#[cfg(any(target_os = "windows"))]
|
||||||
use super::ui_interface::get_option_opt;
|
use super::ui_interface::get_option_opt;
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
use hbb_common::log::{debug, error, info};
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
use libappindicator::AppIndicator;
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
use std::env::temp_dir;
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
@ -83,119 +77,10 @@ pub fn start_tray() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start a tray icon in Linux
|
|
||||||
///
|
|
||||||
/// [Block]
|
|
||||||
/// This function will block current execution, show the tray icon and handle events.
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
pub fn start_tray() {
|
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use glib::{clone, Continue};
|
|
||||||
use gtk::traits::{GtkMenuItemExt, MenuShellExt, WidgetExt};
|
|
||||||
|
|
||||||
info!("configuring tray");
|
|
||||||
// init gtk context
|
|
||||||
if let Err(err) = gtk::init() {
|
|
||||||
error!("Error when starting the tray: {}", err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if let Some(mut appindicator) = get_default_app_indicator() {
|
|
||||||
let mut menu = gtk::Menu::new();
|
|
||||||
let stoped = is_service_stopped();
|
|
||||||
// start/stop service
|
|
||||||
let label = if stoped {
|
|
||||||
crate::client::translate("Start Service".to_owned())
|
|
||||||
} else {
|
|
||||||
crate::client::translate("Stop service".to_owned())
|
|
||||||
};
|
|
||||||
let menu_item_service = gtk::MenuItem::with_label(label.as_str());
|
|
||||||
menu_item_service.connect_activate(move |_| {
|
|
||||||
let _lock = crate::ui_interface::SENDER.lock().unwrap();
|
|
||||||
change_service_state();
|
|
||||||
});
|
|
||||||
menu.append(&menu_item_service);
|
|
||||||
// show tray item
|
|
||||||
menu.show_all();
|
|
||||||
appindicator.set_menu(&mut menu);
|
|
||||||
// start event loop
|
|
||||||
info!("Setting tray event loop");
|
|
||||||
// check the connection status for every second
|
|
||||||
glib::timeout_add_local(
|
|
||||||
Duration::from_secs(1),
|
|
||||||
clone!(@strong menu_item_service as item => move || {
|
|
||||||
let _lock = crate::ui_interface::SENDER.lock().unwrap();
|
|
||||||
update_tray_service_item(&item);
|
|
||||||
// continue to trigger the next status check
|
|
||||||
Continue(true)
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
gtk::main();
|
|
||||||
} else {
|
|
||||||
error!("Tray process exit now");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
fn change_service_state() {
|
|
||||||
if is_service_stopped() {
|
|
||||||
debug!("Now try to start service");
|
|
||||||
crate::ipc::set_option("stop-service", "");
|
|
||||||
} else {
|
|
||||||
debug!("Now try to stop service");
|
|
||||||
crate::ipc::set_option("stop-service", "Y");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
#[inline]
|
|
||||||
fn update_tray_service_item(item: >k::MenuItem) {
|
|
||||||
use gtk::traits::GtkMenuItemExt;
|
|
||||||
|
|
||||||
if is_service_stopped() {
|
|
||||||
item.set_label(&crate::client::translate("Start Service".to_owned()));
|
|
||||||
} else {
|
|
||||||
item.set_label(&crate::client::translate("Stop service".to_owned()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
fn get_default_app_indicator() -> Option<AppIndicator> {
|
|
||||||
use libappindicator::AppIndicatorStatus;
|
|
||||||
use std::io::Write;
|
|
||||||
|
|
||||||
let icon = include_bytes!("../res/icon.png");
|
|
||||||
// appindicator does not support icon buffer, so we write it to tmp folder
|
|
||||||
let mut icon_path = temp_dir();
|
|
||||||
icon_path.push("RustDesk");
|
|
||||||
icon_path.push("rustdesk.png");
|
|
||||||
match std::fs::File::create(icon_path.clone()) {
|
|
||||||
Ok(mut f) => {
|
|
||||||
f.write_all(icon).unwrap();
|
|
||||||
// set .png icon file to be writable
|
|
||||||
// this ensures successful file rewrite when switching between x11 and wayland.
|
|
||||||
let mut perm = f.metadata().unwrap().permissions();
|
|
||||||
if perm.readonly() {
|
|
||||||
perm.set_readonly(false);
|
|
||||||
f.set_permissions(perm).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
error!("Error when writing icon to {:?}: {}", icon_path, err);
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
debug!("write temp icon complete");
|
|
||||||
let mut appindicator = AppIndicator::new("RustDesk", icon_path.to_str().unwrap_or("rustdesk"));
|
|
||||||
appindicator.set_label("RustDesk", "A remote control software.");
|
|
||||||
appindicator.set_status(AppIndicatorStatus::Active);
|
|
||||||
Some(appindicator)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check if service is stoped.
|
/// Check if service is stoped.
|
||||||
/// Return [`true`] if service is stoped, [`false`] otherwise.
|
/// Return [`true`] if service is stoped, [`false`] otherwise.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(any(target_os = "linux", target_os = "windows"))]
|
#[cfg(any(target_os = "windows"))]
|
||||||
fn is_service_stopped() -> bool {
|
fn is_service_stopped() -> bool {
|
||||||
if let Some(v) = get_option_opt("stop-service") {
|
if let Some(v) = get_option_opt("stop-service") {
|
||||||
v == "Y"
|
v == "Y"
|
||||||
@ -204,47 +89,68 @@ fn is_service_stopped() -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
/// Start a tray icon in Linux
|
||||||
pub fn make_tray() {
|
///
|
||||||
extern "C" {
|
/// [Block]
|
||||||
fn BackingScaleFactor() -> f32;
|
/// This function will block current execution, show the tray icon and handle events.
|
||||||
}
|
#[cfg(target_os = "linux")]
|
||||||
let f = unsafe { BackingScaleFactor() };
|
pub fn start_tray() {}
|
||||||
use tray_item::TrayItem;
|
|
||||||
let mode = dark_light::detect();
|
|
||||||
let icon_path = match mode {
|
|
||||||
dark_light::Mode::Dark => {
|
|
||||||
// still show big overflow icon in my test, so still use x1 png.
|
|
||||||
// let's do it with objc with svg support later.
|
|
||||||
// or use another tray crate, or find out in tauri (it has tray support)
|
|
||||||
if f > 2. {
|
|
||||||
"mac-tray-light-x2.png"
|
|
||||||
} else {
|
|
||||||
"mac-tray-light.png"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dark_light::Mode::Light => {
|
|
||||||
if f > 2. {
|
|
||||||
"mac-tray-dark-x2.png"
|
|
||||||
} else {
|
|
||||||
"mac-tray-dark.png"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if let Ok(mut tray) = TrayItem::new(&crate::get_app_name(), icon_path) {
|
|
||||||
tray.add_label(&format!(
|
|
||||||
"{} {}",
|
|
||||||
crate::get_app_name(),
|
|
||||||
crate::lang::translate("Service is running".to_owned())
|
|
||||||
))
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
let inner = tray.inner_mut();
|
#[cfg(target_os = "macos")]
|
||||||
inner.add_quit_item(&crate::lang::translate("Quit".to_owned()));
|
pub fn start_tray() {
|
||||||
inner.display();
|
use hbb_common::{allow_err, log};
|
||||||
} else {
|
allow_err!(make_tray());
|
||||||
loop {
|
}
|
||||||
std::thread::sleep(std::time::Duration::from_secs(3));
|
|
||||||
}
|
#[cfg(target_os = "macos")]
|
||||||
}
|
pub fn make_tray() -> hbb_common::ResultType<()> {
|
||||||
|
// https://github.com/tauri-apps/tray-icon/blob/dev/examples/tao.rs
|
||||||
|
use hbb_common::anyhow::Context;
|
||||||
|
use tao::event_loop::{ControlFlow, EventLoopBuilder};
|
||||||
|
use tray_icon::{TrayEvent, TrayIconBuilder};
|
||||||
|
let mode = dark_light::detect();
|
||||||
|
const LIGHT: &[u8] = include_bytes!("../res/mac-tray-light-x2.png");
|
||||||
|
const DARK: &[u8] = include_bytes!("../res/mac-tray-dark-x2.png");
|
||||||
|
let icon = match mode {
|
||||||
|
dark_light::Mode::Dark => DARK,
|
||||||
|
_ => LIGHT,
|
||||||
|
};
|
||||||
|
let (icon_rgba, icon_width, icon_height) = {
|
||||||
|
let image = image::load_from_memory(icon)
|
||||||
|
.context("Failed to open icon path")?
|
||||||
|
.into_rgba8();
|
||||||
|
let (width, height) = image.dimensions();
|
||||||
|
let rgba = image.into_raw();
|
||||||
|
(rgba, width, height)
|
||||||
|
};
|
||||||
|
let icon = tray_icon::icon::Icon::from_rgba(icon_rgba, icon_width, icon_height)
|
||||||
|
.context("Failed to open icon")?;
|
||||||
|
|
||||||
|
let event_loop = EventLoopBuilder::new().build();
|
||||||
|
|
||||||
|
let _tray_icon = Some(
|
||||||
|
TrayIconBuilder::new()
|
||||||
|
.with_tooltip(format!(
|
||||||
|
"{} {}",
|
||||||
|
crate::get_app_name(),
|
||||||
|
crate::lang::translate("Service is running".to_owned())
|
||||||
|
))
|
||||||
|
.with_icon(icon)
|
||||||
|
.build()?,
|
||||||
|
);
|
||||||
|
|
||||||
|
let tray_channel = TrayEvent::receiver();
|
||||||
|
let mut docker_hiden = false;
|
||||||
|
|
||||||
|
event_loop.run(move |_event, _, control_flow| {
|
||||||
|
if !docker_hiden {
|
||||||
|
crate::platform::macos::hide_dock();
|
||||||
|
docker_hiden = true;
|
||||||
|
}
|
||||||
|
*control_flow = ControlFlow::Poll;
|
||||||
|
|
||||||
|
if tray_channel.try_recv().is_ok() {
|
||||||
|
crate::platform::macos::handle_application_should_open_untitled_file();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -141,7 +141,7 @@ extern "C" fn application_should_handle_open_untitled_file(
|
|||||||
if !LAUNCHED {
|
if !LAUNCHED {
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
crate::platform::macos::handle_applicationShouldOpenUntitledFile();
|
crate::platform::macos::handle_application_should_open_untitled_file();
|
||||||
let inner: *mut c_void = *this.get_ivar(APP_HANDLER_IVAR);
|
let inner: *mut c_void = *this.get_ivar(APP_HANDLER_IVAR);
|
||||||
let inner = &mut *(inner as *mut DelegateState);
|
let inner = &mut *(inner as *mut DelegateState);
|
||||||
(*inner).command(AWAKE);
|
(*inner).command(AWAKE);
|
||||||
@ -258,10 +258,3 @@ pub fn show_dock() {
|
|||||||
NSApp().setActivationPolicy_(NSApplicationActivationPolicyRegular);
|
NSApp().setActivationPolicy_(NSApplicationActivationPolicyRegular);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_tray() {
|
|
||||||
unsafe {
|
|
||||||
set_delegate(None);
|
|
||||||
}
|
|
||||||
crate::tray::make_tray();
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user