Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
a29b0f6
feat: rust托盘图标
ShadowLemoon Dec 2, 2025
c79bd1e
perf: 优化子菜单项目的构建方法
ShadowLemoon Dec 2, 2025
5ee6882
rafactor: 把大部分逻辑迁移到rust库
ShadowLemoon Dec 2, 2025
0a8e434
fix: 修复宏与枚举冲突
ShadowLemoon Dec 2, 2025
cfa8b43
fix: 修复构建目标
ShadowLemoon Dec 2, 2025
2b5e784
fix: 静态链接libgcc
ShadowLemoon Dec 2, 2025
18f3265
fix: 修复切换语言
ShadowLemoon Dec 3, 2025
40490f5
fix: Windows下原生加载ico而不是提取图片
ShadowLemoon Dec 3, 2025
1338d62
docs: 更新重构文档
ShadowLemoon Dec 3, 2025
96a3769
fix:再次修复切换语言
ShadowLemoon Dec 3, 2025
8f7c9e9
fix: 修复托盘退出
ShadowLemoon Dec 3, 2025
f6af9ce
fix: 修复托盘菜单死锁问题
ShadowLemoon Dec 3, 2025
55b6e37
feat: 野人办法实现深色托盘
ShadowLemoon Dec 3, 2025
9dda020
fix: 修复配置文件获取
ShadowLemoon Dec 3, 2025
c8bdd30
fix: 分离托盘线程;避免多次调用tray_exit
ShadowLemoon Dec 3, 2025
2d53cd8
feat: DPI感知的托盘图标
ShadowLemoon Dec 3, 2025
d37093e
Merge branch 'master' into feat/rust-tray-icon
ShadowLemoon Dec 4, 2025
ea5f5a3
refactor: 删除托盘的深色模式
ShadowLemoon Dec 4, 2025
67cbb39
Merge branch 'main' into feat/rust-tray-icon
ShadowLemoon Jan 20, 2026
8f96c01
feat: 跟随c++托盘的变化
ShadowLemoon Jan 20, 2026
5d810c0
refactor: 拆分托盘逻辑实现
ShadowLemoon Jan 20, 2026
0dbf3b1
refactor: 项目仅限Windows平台,移除对其他平台的支持
ShadowLemoon Jan 20, 2026
b25b160
feat: 添加安全验证
ShadowLemoon Jan 20, 2026
b51d02b
feat: 实现新版托盘vdd状态逻辑
ShadowLemoon Jan 20, 2026
84e48e1
refactor: 移除旧api
ShadowLemoon Jan 20, 2026
3993895
feat: 添加通知功能
ShadowLemoon Jan 20, 2026
fbbd666
perf: 统一同步原语
ShadowLemoon Jan 20, 2026
aeec553
fix: 修复构建
ShadowLemoon Jan 21, 2026
cd0acbd
refactor: 打开url和配置操作迁移回c++端
ShadowLemoon Jan 22, 2026
f166c19
feat: 模拟用户登录以访问正确文件夹
ShadowLemoon Jan 22, 2026
8bff078
移除配置导入导出
ShadowLemoon Jan 22, 2026
67ae4a0
perf: 清理未使用的代码
ShadowLemoon Jan 23, 2026
43a8f6e
perf: 使用字符串id替代整数
ShadowLemoon Jan 23, 2026
8f5eb5d
perf: rust端不再操作config
ShadowLemoon Jan 23, 2026
d0c2871
fix: 修复Handler返回值问题
ShadowLemoon Jan 23, 2026
d903986
chore: 更新翻译
ShadowLemoon Jan 23, 2026
0206257
style: 移除行尾空格
ShadowLemoon Jan 24, 2026
3af156f
chore: 更改i18n文本
ShadowLemoon Jan 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ jobs:
fi
fi

# Add MinGW target for rust_tray static library
echo "Adding MinGW target for rust_tray..."
rustup target add x86_64-pc-windows-gnu

- name: Verify Build Tools
shell: msys2 {0}
run: |
Expand Down
2 changes: 1 addition & 1 deletion cmake/compile_definitions/common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ set(SUNSHINE_TARGET_FILES
"${CMAKE_SOURCE_DIR}/src/network.cpp"
"${CMAKE_SOURCE_DIR}/src/network.h"
"${CMAKE_SOURCE_DIR}/src/move_by_copy.h"
"${CMAKE_SOURCE_DIR}/src/system_tray.cpp"
"${CMAKE_SOURCE_DIR}/src/system_tray_rust.cpp"
"${CMAKE_SOURCE_DIR}/src/system_tray.h"
"${CMAKE_SOURCE_DIR}/src/system_tray_i18n.cpp"
"${CMAKE_SOURCE_DIR}/src/system_tray_i18n.h"
Expand Down
5 changes: 3 additions & 2 deletions cmake/compile_definitions/windows.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ list(PREPEND PLATFORM_LIBRARIES
)

if(SUNSHINE_ENABLE_TRAY)
list(APPEND PLATFORM_TARGET_FILES
"${CMAKE_SOURCE_DIR}/third-party/tray/src/tray_windows.c")
# Rust tray implementation
include(${CMAKE_MODULE_PATH}/targets/rust_tray.cmake)
list(APPEND PLATFORM_LIBRARIES ${RUST_TRAY_LIBRARY} ${RUST_TRAY_PLATFORM_LIBS})
endif()
121 changes: 121 additions & 0 deletions cmake/targets/rust_tray.cmake
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
Comment on lines +63 to +69
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

DEPENDS 列表不完整,可能导致增量构建失效

根据 lib.rs 中声明的模块,src/ 目录下还有 dialogs.rsmenu.rsmenu_items.rsnotification.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
Verify each finding against the current code and only fix it if needed.

In `@cmake/targets/rust_tray.cmake` around lines 63 - 69, The DEPENDS list for the
rust tray target is incomplete: files referenced by lib.rs (dialogs.rs, menu.rs,
menu_items.rs, notification.rs) are missing so CMake won't re-run when they
change; update the DEPENDS block that references
${RUST_TRAY_SOURCE_DIR}/Cargo.toml, build.rs, src/lib.rs, src/i18n.rs,
src/actions.rs to also include ${RUST_TRAY_SOURCE_DIR}/src/dialogs.rs,
${RUST_TRAY_SOURCE_DIR}/src/menu.rs, ${RUST_TRAY_SOURCE_DIR}/src/menu_items.rs
and ${RUST_TRAY_SOURCE_DIR}/src/notification.rs (or replace the explicit list by
a file(GLOB ...) over ${RUST_TRAY_SOURCE_DIR}/src/*.rs if you prefer
auto-collecting files, noting GLOB caveats) so changes to those modules trigger
incremental rebuilds.

)

# 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}")
5 changes: 5 additions & 0 deletions rust_tray/.cargo/config.toml
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"]
2 changes: 2 additions & 0 deletions rust_tray/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/target/
/Cargo.lock
35 changes: 35 additions & 0 deletions rust_tray/Cargo.toml
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"
68 changes: 68 additions & 0 deletions rust_tray/README.md
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
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

README 仍把当前实现写成跨平台。

rust_tray/src/dialogs.rsrust_tray/src/notification.rs 已经直接依赖 Windows API / WinRT,rust_tray/Cargo.toml 也只在 cfg(windows) 下声明了这部分依赖,但这里仍写着 Linux/macOS 支持并列出对应产物路径。建议改成明确的 Windows-only 说明,或者把尚未实现的前提条件写清楚,避免误导手动构建和集成。

Also applies to: 28-31

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rust_tray/README.md` around lines 7 - 10, The README currently claims
cross-platform support but the implementation files rust_tray/src/dialogs.rs and
rust_tray/src/notification.rs and the Cargo.toml only enable Windows-specific
APIs/dependencies; update README.md to explicitly state this crate is
Windows-only (or clearly document that Linux/macOS are not yet implemented and
list required preconditions for those platforms), remove or mark as Windows-only
any Linux/macOS artifact paths, and update the corresponding lines referenced
(including lines 28-31) to avoid implying full cross-platform support; reference
rust_tray/src/dialogs.rs, rust_tray/src/notification.rs, and
rust_tray/Cargo.toml when making the README changes.


## 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
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

架构章节已经落后于当前实现。

目录树没有列出这次新增的 actions.rsmenu.rsnotification.rsdialogs.rs,下面还写着“不需要修改 src/system_tray.cpp”,但当前接入点已经是 src/system_tray_rust.cpp。另外这个代码块缺少语言标记,也会继续触发 markdownlint MD040。

🧰 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
Verify each finding against the current code and only fix it if needed.

In `@rust_tray/README.md` around lines 54 - 68, The README's architecture section
is outdated: update the directory tree to list the new Rust files (actions.rs,
menu.rs, notification.rs, dialogs.rs) under src and replace the note that
mentions src/system_tray.cpp with the current entry point
src/system_tray_rust.cpp; also add a language tag to the code fence (e.g.,
```text or ```bash) to satisfy markdownlint MD040 so the tree block is properly
marked. Ensure the paragraph referencing compatibility/third-party headers still
applies or update it if the integration changed, and keep all edits inside
README.md to reflect the new filenames and entry point.

23 changes: 23 additions & 0 deletions rust_tray/build.rs
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
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 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.rs

Repository: AlkaidLab/foundation-sunshine

Length of output: 1734


build.rs 中的 Windows 库链接不完整且存在重复

build.rs 中声明的 Windows 库集合与 CMake 配置不一致。虽然 build.rs 中的 5 个库(user32、gdi32、shell32、ole32、comctl32)确实在 CMake 中也被链接,形成重复,但更重要的问题是 build.rs 缺少 CMake 中指定的 7 个库:oleaut32、uuid、bcrypt、ntdll、userenv、ws2_32、pthread。

当通过 cargo 独立构建此 Rust 库时,将缺少这些关键依赖,可能导致链接或运行时失败。建议:

  • 更新 build.rs 以包含 CMake 中定义的所有库,或
  • 明确记录两者适用的场景(如果设计上有意区分)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rust_tray/build.rs` around lines 14 - 22, 在 build.rs 的 Windows
平台块(#[cfg(target_os = "windows")] 内使用 println!("cargo:rustc-link-lib=...")
的地方,补上 CMake 中缺失的库:添加 println! 行分别为 oleaut32、uuid、bcrypt、ntdll、userenv、ws2_32 和
pthread(同时保留已存在的
user32、gdi32、shell32、ole32、comctl32,避免重复新增相同项);如果这些差异是有意为之,请改为在该模块或仓库 README
中明确记录何时使用 build.rs 链接而何时依赖 CMake,以避免构建时缺少依赖。

}
Loading