Skip to content

Commit

Permalink
feat(vdd): 使vdd不那么脆弱
Browse files Browse the repository at this point in the history
  • Loading branch information
qiin2333 committed Feb 14, 2025
1 parent a858eea commit c5d2f29
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 51 deletions.
2 changes: 1 addition & 1 deletion cmake/packaging/windows.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ set(CPACK_COMPONENT_GAMEPAD_DESCRIPTION "Scripts to install and uninstall Virtua
set(CPACK_COMPONENT_GAMEPAD_GROUP "Scripts")

# Virtual Display Driver
set(CPACK_COMPONENT_VDD_DISPLAY_NAME "IddSampleDriver")
set(CPACK_COMPONENT_VDD_DISPLAY_NAME "Zako Display Driver")
set(CPACK_COMPONENT_VDD_DESCRIPTION "支持HDR的虚拟显示器驱动安装")
set(CPACK_COMPONENT_VDD_REQUIRED OFF)
set(CPACK_COMPONENT_VDD_GROUP "Scripts")
64 changes: 41 additions & 23 deletions src/display_device/session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "src/globals.h"
#include "src/platform/common.h"
#include "src/rtsp.h"
#include "src/system_tray.h"
#include "to_string.h"

namespace display_device {
Expand Down Expand Up @@ -386,7 +387,9 @@ namespace display_device {
BOOST_LOG(error) << "创建虚拟显示器失败";
return false;
}

#if defined SUNSHINE_TRAY && SUNSHINE_TRAY >= 1
system_tray::update_tray_vmonitor_checked(1);
#endif
BOOST_LOG(info) << "创建虚拟显示器完成,响应: " << response;
return true;
}
Expand All @@ -399,6 +402,10 @@ namespace display_device {
return false;
}

#if defined SUNSHINE_TRAY && SUNSHINE_TRAY >= 1
system_tray::update_tray_vmonitor_checked(0);
#endif

BOOST_LOG(info) << "销毁虚拟显示器完成,响应: " << response;
return true;
}
Expand Down Expand Up @@ -435,6 +442,12 @@ namespace display_device {
reload_driver();
}

bool
session_t::is_display_on() {
std::lock_guard lock { mutex };
return !display_device::find_device_by_friendlyname(zako_name).empty();
}

std::chrono::steady_clock::time_point last_toggle_time;
std::chrono::milliseconds debounce_interval { 5000 }; // 5000毫秒防抖间隔

Expand All @@ -443,34 +456,39 @@ namespace display_device {
auto now = std::chrono::steady_clock::now();

if (now - last_toggle_time < debounce_interval) {
BOOST_LOG(debug) << "忽略快速重复的显示器开关请求";
return;
BOOST_LOG(debug) << "忽略快速重复的显示器开关请求";
return;
}

last_toggle_time = now;

if (display_device::find_device_by_friendlyname(zako_name).empty()) {
if (create_vdd_monitor()) {
// 启动新线程处理确认弹窗和超时
std::thread([this]() {
// Windows弹窗确认
auto future = std::async(std::launch::async, []() {
return MessageBoxW(nullptr,
L"已创建虚拟显示器,是否继续使用?",
L"显示器确认",
MB_YESNO | MB_ICONQUESTION) == IDYES;
});

// 等待20秒超时
if (future.wait_for(20s) != std::future_status::ready || !future.get()) {
BOOST_LOG(info) << "用户未确认或超时,自动销毁虚拟显示器";
destroy_vdd_monitor();
}
}).detach(); // 分离线程自动管理
}
if (!is_display_on()) {
if (create_vdd_monitor()) {
// 启动新线程处理确认弹窗和超时
std::thread([this]() {
// Windows弹窗确认
auto future = std::async(std::launch::async, []() {
return MessageBoxW(nullptr,
L"已创建虚拟显示器,是否继续使用?",
L"显示器确认",
MB_YESNO | MB_ICONQUESTION) == IDYES;
});

// 等待20秒超时
if (future.wait_for(20s) != std::future_status::ready || !future.get()) {
BOOST_LOG(info) << "用户未确认或超时,自动销毁虚拟显示器";
// 强制关闭消息框
HWND hwnd = GetActiveWindow();
if (hwnd && IsWindow(hwnd)) {
PostMessage(hwnd, WM_CLOSE, 0, 0);
}
destroy_vdd_monitor();
}
}).detach(); // 分离线程自动管理
}
}
else {
destroy_vdd_monitor();
destroy_vdd_monitor();
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/display_device/session.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ namespace display_device {
void
disable_enable_vdd();

bool
is_display_on();

void
toggle_display_power();

Expand Down
74 changes: 47 additions & 27 deletions src/system_tray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@
// local includes
#include "confighttp.h"
#include "display_device/session.h"
#include "src/display_device/display_device.h"
#include "logging.h"
#include "platform/common.h"
#include "process.h"
#include "src/display_device/display_device.h"
#include "src/entry_handler.h"
#include "version.h"

Expand All @@ -52,6 +52,14 @@ using namespace std::literals;
namespace system_tray {
static std::atomic<bool> tray_initialized = false;

static struct tray tray = {
.icon = TRAY_ICON,
.tooltip = PROJECT_NAME,
.menu = nullptr, // 先初始化为空指针,后续再赋值
.iconPathCount = 4,
.allIconPaths = { TRAY_ICON, TRAY_ICON_LOCKED, TRAY_ICON_PLAYING, TRAY_ICON_PAUSING },
};

void
tray_open_ui_cb(struct tray_menu *item) {
BOOST_LOG(info) << "Opening UI from system tray"sv;
Expand Down Expand Up @@ -95,7 +103,7 @@ namespace system_tray {
int msgboxID = MessageBoxW(
NULL,
L"你不能退出!\n那么想退吗? 真拿你没办法呢, 继续点一下吧~",
L"真的要退出吗",
L" 真的要退出吗",
MB_ICONWARNING | MB_OKCANCEL);

if (msgboxID == IDOK) {
Expand All @@ -117,35 +125,33 @@ namespace system_tray {
display_device::session_t::get().toggle_display_power();
}

// Tray menu
static struct tray tray = {
.icon = TRAY_ICON,
.tooltip = PROJECT_NAME,
.menu =
(struct tray_menu[]) {
// todo - use boost/locale to translate menu strings
{ .text = "Open Sunshine", .cb = tray_open_ui_cb },
{ .text = "-" },
{ .text = "Toggle Display Power", .cb = tray_toggle_display_cb },
// { .text = "Donate",
// .submenu =
// (struct tray_menu[]) {
// { .text = "GitHub Sponsors", .cb = tray_donate_github_cb },
// { .text = "Patreon", .cb = tray_donate_patreon_cb },
// { .text = "PayPal", .cb = tray_donate_paypal_cb },
// { .text = nullptr } } },
{ .text = "-" },
// Currently display device settings are only supported on Windows
// 将菜单数组声明为静态变量
static struct tray_menu tray_menus[] = {
{ .text = "Open Sunshine", .cb = tray_open_ui_cb },
{ .text = "-" },
{ .text = "VDD Monitor Toggle", .checked = 0, .cb = tray_toggle_display_cb },
// { .text = "Donate",
// .submenu =
// (struct tray_menu[]) {
// { .text = "GitHub Sponsors", .cb = tray_donate_github_cb },
// { .text = "Patreon", .cb = tray_donate_patreon_cb },
// { .text = "PayPal", .cb = tray_donate_paypal_cb },
// { .text = nullptr } } },
{ .text = "-" },
#ifdef _WIN32
{ .text = "Reset Display Device Config", .cb = tray_reset_display_device_config_cb },
{ .text = "Reset Display Device Config", .cb = tray_reset_display_device_config_cb },
#endif
{ .text = "Restart", .cb = tray_restart_cb },
{ .text = "Quit", .cb = tray_quit_cb },
{ .text = nullptr } },
.iconPathCount = 4,
.allIconPaths = { TRAY_ICON, TRAY_ICON_LOCKED, TRAY_ICON_PLAYING, TRAY_ICON_PAUSING },
{ .text = "Restart", .cb = tray_restart_cb },
{ .text = "Quit", .cb = tray_quit_cb },
{ .text = nullptr }
};

// 在菜单数组初始化后设置 tray.menu
__attribute__((constructor)) static void
init_tray_menu() {
tray.menu = tray_menus;
}

int
system_tray() {
#ifdef _WIN32
Expand Down Expand Up @@ -231,6 +237,10 @@ namespace system_tray {
BOOST_LOG(info) << "System tray created"sv;
}

// 初始化时获取实际显示器状态
tray_menus[2].checked = display_device::session_t::get().is_display_on() ? 1 : 0;
tray_update(&tray);

tray_initialized = true;
while (tray_loop(1) == 0) {
BOOST_LOG(debug) << "System tray loop"sv;
Expand Down Expand Up @@ -355,5 +365,15 @@ namespace system_tray {
tray_update(&tray);
}

void
update_tray_vmonitor_checked(int checked) {
if (!tray_initialized) {
return;
}
// 更新显示器切换菜单项的勾选状态
tray_menus[2].checked = checked;
tray_update(&tray);
}

} // namespace system_tray
#endif
3 changes: 3 additions & 0 deletions src/system_tray.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,7 @@ namespace system_tray {
*/
void
update_tray_require_pin(std::string pin_name);

void
update_tray_vmonitor_checked(int checked);
} // namespace system_tray
Binary file modified src_assets/windows/misc/vdd/driver/MttVDD.inf
Binary file not shown.
Binary file modified src_assets/windows/misc/vdd/driver/mttvdd.cat
Binary file not shown.

0 comments on commit c5d2f29

Please sign in to comment.