-
-
Notifications
You must be signed in to change notification settings - Fork 110
feat: rust托盘图标 #338
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
feat: rust托盘图标 #338
Changes from all commits
a29b0f6
c79bd1e
5ee6882
0a8e434
cfa8b43
2b5e784
18f3265
40490f5
1338d62
96a3769
8f7c9e9
f6af9ce
55b6e37
9dda020
c8bdd30
2d53cd8
d37093e
ea5f5a3
67cbb39
8f96c01
5d810c0
0dbf3b1
b25b160
b51d02b
84e48e1
3993895
fbbd666
aeec553
cd0acbd
f166c19
8bff078
67ae4a0
43a8f6e
8f5eb5d
d0c2871
d903986
0206257
3af156f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,121 @@ | ||
| # rust_tray.cmake | ||
| # CMake configuration for building and linking the Rust tray library | ||
|
|
||
| set(RUST_TRAY_SOURCE_DIR "${CMAKE_SOURCE_DIR}/rust_tray") | ||
| set(RUST_TARGET_DIR "${CMAKE_BINARY_DIR}/rust_tray") | ||
|
|
||
| # Determine the Rust target and output filename based on platform | ||
| if(WIN32) | ||
| # Windows uses MinGW/UCRT toolchain - must use gnu target | ||
| set(RUST_TARGET "x86_64-pc-windows-gnu") | ||
| set(RUST_LIB_NAME "libtray.a") | ||
| elseif(APPLE) | ||
| set(RUST_LIB_NAME "libtray.a") | ||
| # Check for ARM64 | ||
| if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64" OR CMAKE_OSX_ARCHITECTURES MATCHES "arm64") | ||
| set(RUST_TARGET "aarch64-apple-darwin") | ||
| else() | ||
| set(RUST_TARGET "x86_64-apple-darwin") | ||
| endif() | ||
| else() | ||
| set(RUST_LIB_NAME "libtray.a") | ||
| # Check for ARM64 | ||
| if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64") | ||
| set(RUST_TARGET "aarch64-unknown-linux-gnu") | ||
| else() | ||
| set(RUST_TARGET "x86_64-unknown-linux-gnu") | ||
| endif() | ||
| endif() | ||
|
|
||
| # Set the output path based on build type | ||
| if(CMAKE_BUILD_TYPE STREQUAL "Debug") | ||
| set(RUST_BUILD_TYPE "debug") | ||
| set(CARGO_BUILD_FLAGS "") | ||
| else() | ||
| set(RUST_BUILD_TYPE "release") | ||
| set(CARGO_BUILD_FLAGS "--release") | ||
| endif() | ||
|
|
||
| # Output path: target/<target>/<profile>/ | ||
| set(RUST_OUTPUT_LIB "${RUST_TARGET_DIR}/${RUST_TARGET}/${RUST_BUILD_TYPE}/${RUST_LIB_NAME}") | ||
|
|
||
| # Find cargo | ||
| find_program(CARGO_EXECUTABLE cargo HINTS $ENV{HOME}/.cargo/bin $ENV{USERPROFILE}/.cargo/bin) | ||
| if(NOT CARGO_EXECUTABLE) | ||
| message(FATAL_ERROR "Cargo (Rust package manager) not found. Please install Rust: https://rustup.rs/") | ||
| endif() | ||
|
|
||
| message(STATUS "Found Cargo: ${CARGO_EXECUTABLE}") | ||
| message(STATUS "Rust target: ${RUST_TARGET}") | ||
| message(STATUS "Rust tray library will be built at: ${RUST_OUTPUT_LIB}") | ||
|
|
||
| # Custom command to build the Rust library | ||
| add_custom_command( | ||
| OUTPUT ${RUST_OUTPUT_LIB} | ||
| COMMAND ${CMAKE_COMMAND} -E env | ||
| CARGO_TARGET_DIR=${RUST_TARGET_DIR} | ||
| ${CARGO_EXECUTABLE} build | ||
| --manifest-path ${RUST_TRAY_SOURCE_DIR}/Cargo.toml | ||
| --target ${RUST_TARGET} | ||
| ${CARGO_BUILD_FLAGS} | ||
| WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} | ||
| COMMENT "Building Rust tray library (${RUST_BUILD_TYPE})" | ||
| DEPENDS | ||
| ${RUST_TRAY_SOURCE_DIR}/Cargo.toml | ||
| ${RUST_TRAY_SOURCE_DIR}/build.rs | ||
| ${RUST_TRAY_SOURCE_DIR}/src/lib.rs | ||
| ${RUST_TRAY_SOURCE_DIR}/src/i18n.rs | ||
| ${RUST_TRAY_SOURCE_DIR}/src/actions.rs | ||
| VERBATIM | ||
| ) | ||
|
|
||
| # Create a custom target for the Rust library | ||
| add_custom_target(rust_tray ALL DEPENDS ${RUST_OUTPUT_LIB}) | ||
|
|
||
| # Create an imported static library target | ||
| add_library(rust_tray_lib STATIC IMPORTED GLOBAL) | ||
| set_target_properties(rust_tray_lib PROPERTIES | ||
| IMPORTED_LOCATION ${RUST_OUTPUT_LIB} | ||
| ) | ||
| add_dependencies(rust_tray_lib rust_tray) | ||
|
|
||
| # Export the library path for use in other CMake files | ||
| set(RUST_TRAY_LIBRARY ${RUST_OUTPUT_LIB} CACHE FILEPATH "Path to the Rust tray library") | ||
|
|
||
| # Platform-specific dependencies for the Rust library | ||
| if(WIN32) | ||
| # MinGW/UCRT dependencies for Rust static library | ||
| set(RUST_TRAY_PLATFORM_LIBS | ||
| user32 | ||
| gdi32 | ||
| shell32 | ||
| ole32 | ||
| oleaut32 | ||
| uuid | ||
| comctl32 | ||
| bcrypt | ||
| ntdll | ||
| userenv | ||
| ws2_32 | ||
| pthread | ||
| ) | ||
| elseif(APPLE) | ||
| # macOS dependencies for tray-icon crate | ||
| set(RUST_TRAY_PLATFORM_LIBS | ||
| "-framework Cocoa" | ||
| "-framework AppKit" | ||
| "-framework Foundation" | ||
| ) | ||
| else() | ||
| # Linux dependencies for tray-icon crate | ||
| find_package(PkgConfig REQUIRED) | ||
| pkg_check_modules(GTK3 REQUIRED gtk+-3.0) | ||
| pkg_check_modules(GLIB REQUIRED glib-2.0) | ||
|
|
||
| set(RUST_TRAY_PLATFORM_LIBS | ||
| ${GTK3_LIBRARIES} | ||
| ${GLIB_LIBRARIES} | ||
| ) | ||
| endif() | ||
|
|
||
| message(STATUS "Rust tray platform libraries: ${RUST_TRAY_PLATFORM_LIBS}") | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| # Cargo configuration for MinGW builds | ||
|
|
||
| [target.x86_64-pc-windows-gnu] | ||
| # Static link libgcc to avoid runtime DLL dependency | ||
| rustflags = ["-C", "link-arg=-static-libgcc"] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| /target/ | ||
| /Cargo.lock |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| [package] | ||
| name = "sunshine_tray" | ||
| version = "0.1.0" | ||
| edition = "2021" | ||
| build = "build.rs" | ||
| description = "Windows-only system tray implementation for Sunshine" | ||
|
|
||
| [lib] | ||
| name = "tray" | ||
| crate-type = ["staticlib"] | ||
|
|
||
| [dependencies] | ||
| tray-icon = "0.19" | ||
| muda = "0.15" | ||
| once_cell = "1.19" | ||
| parking_lot = "0.12" | ||
| log = "0.4" | ||
|
|
||
| # Windows-only dependencies | ||
| [target.'cfg(windows)'.dependencies] | ||
| winit = { version = "0.30", default-features = false, features = ["rwh_06"] } | ||
| windows-sys = { version = "0.59", features = [ | ||
| "Win32_Foundation", | ||
| "Win32_UI_WindowsAndMessaging", | ||
| "Win32_UI_Shell", | ||
| "Win32_UI_Controls_Dialogs", | ||
| ] } | ||
| winrt-notification = "0.5" | ||
|
|
||
| [build-dependencies] | ||
| # bindgen = "0.71" # Disabled: requires LLVM/Clang installation | ||
|
|
||
| [profile.release] | ||
| lto = true | ||
| opt-level = "s" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| # Rust Tray Library | ||
|
|
||
| This directory contains a Rust implementation of the system tray library, designed to replace the original C `tray` library. | ||
|
|
||
| ## Features | ||
|
|
||
| - Cross-platform support (Windows, Linux, macOS) | ||
| - Compatible C API matching the original `tray.h` header | ||
| - Uses the `tray-icon` Rust crate for the underlying implementation | ||
| - Better maintainability and reduced cross-platform adaptation code | ||
|
Comment on lines
+7
to
+10
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. README 仍把当前实现写成跨平台。
Also applies to: 28-31 🤖 Prompt for AI Agents |
||
|
|
||
| ## Prerequisites | ||
|
|
||
| - [Rust](https://rustup.rs/) (latest stable version recommended) | ||
| - Cargo (comes with Rust) | ||
|
|
||
| ## Building | ||
|
|
||
| The library is automatically built by CMake when `SUNSHINE_USE_RUST_TRAY=ON` is set. | ||
|
|
||
| ### Manual Build | ||
|
|
||
| ```bash | ||
| cd rust_tray | ||
| cargo build --release | ||
| ``` | ||
|
|
||
| The static library will be generated at: | ||
| - Windows (MSVC): `target/release/tray.lib` | ||
| - Windows (MinGW): `target/release/libtray.a` | ||
| - Linux/macOS: `target/release/libtray.a` | ||
|
|
||
| ## CMake Integration | ||
|
|
||
| To enable the Rust tray library, configure CMake with: | ||
|
|
||
| ```bash | ||
| cmake -DSUNSHINE_USE_RUST_TRAY=ON .. | ||
| ``` | ||
|
|
||
| ## API | ||
|
|
||
| The library provides the following C-compatible functions: | ||
|
|
||
| - `tray_init(struct tray *tray)` - Initialize the tray icon | ||
| - `tray_update(struct tray *tray)` - Update the tray icon and menu | ||
| - `tray_loop(int blocking)` - Run one iteration of the UI loop | ||
| - `tray_exit(void)` - Terminate the UI loop | ||
|
|
||
| See `../third-party/tray/src/tray.h` for the complete API definition. | ||
|
|
||
| ## Architecture | ||
|
|
||
| ``` | ||
| rust_tray/ | ||
| ├── Cargo.toml # Rust package manifest | ||
| ├── build.rs # Build script (platform-specific setup) | ||
| ├── src/ | ||
| │ ├── lib.rs # Main library implementation | ||
| │ └── ffi.rs # FFI type definitions | ||
| └── README.md # This file | ||
| ``` | ||
|
|
||
| ## Notes | ||
|
|
||
| - The Rust implementation maintains full API compatibility with the original C library | ||
| - No changes are required to `src/system_tray.cpp` | ||
| - The original `third-party/tray/src/tray.h` header is still used for the C++ code | ||
|
Comment on lines
+54
to
+68
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 架构章节已经落后于当前实现。 目录树没有列出这次新增的 🧰 Tools🪛 markdownlint-cli2 (0.22.0)[warning] 54-54: Fenced code blocks should have a language specified (MD040, fenced-code-language) 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| //! Build script for sunshine_tray | ||
| //! | ||
| //! Note: We manually define the C structures in lib.rs instead of using bindgen | ||
| //! to avoid requiring LLVM/Clang installation on all build machines. | ||
|
|
||
| fn main() { | ||
| // Tell cargo to rerun this script if the header file changes | ||
| println!("cargo:rerun-if-changed=../third-party/tray/src/tray.h"); | ||
| println!("cargo:rerun-if-changed=build.rs"); | ||
|
|
||
| // Note: We manually define the FFI structures in src/ffi.rs | ||
| // to match the original tray.h header file. | ||
|
|
||
| // Platform-specific linker flags | ||
| #[cfg(target_os = "windows")] | ||
| { | ||
| println!("cargo:rustc-link-lib=user32"); | ||
| println!("cargo:rustc-link-lib=gdi32"); | ||
| println!("cargo:rustc-link-lib=shell32"); | ||
| println!("cargo:rustc-link-lib=ole32"); | ||
| println!("cargo:rustc-link-lib=comctl32"); | ||
| } | ||
|
Comment on lines
+14
to
+22
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# 验证 CMake 中定义的平台库是否与 build.rs 重复
echo "=== CMake RUST_TRAY_PLATFORM_LIBS ==="
rg -A 20 'RUST_TRAY_PLATFORM_LIBS' cmake/targets/rust_tray.cmake
echo ""
echo "=== build.rs link-lib ==="
cat rust_tray/build.rsRepository: AlkaidLab/foundation-sunshine Length of output: 1734 build.rs 中的 Windows 库链接不完整且存在重复
当通过 cargo 独立构建此 Rust 库时,将缺少这些关键依赖,可能导致链接或运行时失败。建议:
🤖 Prompt for AI Agents |
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DEPENDS 列表不完整,可能导致增量构建失效
根据
lib.rs中声明的模块,src/目录下还有dialogs.rs、menu.rs、menu_items.rs和notification.rs,但这些文件未包含在依赖列表中。当这些文件修改时,CMake 不会触发重新构建。🔧 建议的修复方案
DEPENDS ${RUST_TRAY_SOURCE_DIR}/Cargo.toml ${RUST_TRAY_SOURCE_DIR}/build.rs ${RUST_TRAY_SOURCE_DIR}/src/lib.rs ${RUST_TRAY_SOURCE_DIR}/src/i18n.rs ${RUST_TRAY_SOURCE_DIR}/src/actions.rs + ${RUST_TRAY_SOURCE_DIR}/src/dialogs.rs + ${RUST_TRAY_SOURCE_DIR}/src/menu.rs + ${RUST_TRAY_SOURCE_DIR}/src/menu_items.rs + ${RUST_TRAY_SOURCE_DIR}/src/notification.rs VERBATIM或者使用
file(GLOB ...)自动收集所有.rs文件(但需注意 GLOB 在新增文件时的限制)。🤖 Prompt for AI Agents