From 6aece1b8d2dfb68acc9096ba956576e17aea5f0d Mon Sep 17 00:00:00 2001
From: Dave Lane <42013603+ReenigneArcher@users.noreply.github.com>
Date: Mon, 17 Aug 2026 14:50:19 -0400
Subject: [PATCH] fix(virtual-hid): remove license expiration (#5517)
---
src/confighttp.cpp | 1 -
src/system_tray.cpp | 20 +++++------
.../assets/web/public/assets/locale/en.json | 1 -
.../common/assets/web/troubleshooting.html | 5 ---
tests/unit/test_confighttp.cpp | 3 +-
tests/unit/test_system_tray.cpp | 35 +++++++++----------
third-party/libvirtualhid | 2 +-
7 files changed, 27 insertions(+), 40 deletions(-)
diff --git a/src/confighttp.cpp b/src/confighttp.cpp
index eae0b1083..ef9f710a9 100644
--- a/src/confighttp.cpp
+++ b/src/confighttp.cpp
@@ -304,7 +304,6 @@ namespace confighttp {
output_tree["activation_usage"] = license.activation_usage;
output_tree["plan_name"] = license.plan_name;
output_tree["customer_email"] = license.customer_email;
- output_tree["expires_at"] = license.expires_at;
output_tree["message"] = license.message;
output_tree["purchase_url"] = license.purchase_url;
output_tree["manage_account_url"] = license.manage_account_url;
diff --git a/src/system_tray.cpp b/src/system_tray.cpp
index eda356c90..47a739dc1 100644
--- a/src/system_tray.cpp
+++ b/src/system_tray.cpp
@@ -410,6 +410,7 @@ namespace system_tray {
virtualhid_license_menu_text_storage() = {};
set_virtualhid_license_menu_item(0, std::format("Status: {}", virtualhid_license_state_label(license.state)), true);
+ auto separator_index = 5U;
if (license.licensed()) {
set_virtualhid_license_menu_item(
1,
@@ -423,18 +424,14 @@ namespace system_tray {
);
set_virtualhid_license_menu_item(
3,
- license.expires_at.empty() ? "Expiration: Not reported" : std::format("Expires: {}", license.expires_at),
- true
- );
- set_virtualhid_license_menu_item(
- 4,
license.activation_limit == 0 ?
"Machine activations: Not reported" :
std::format("Machine activations: {} / {}", license.activation_usage, license.activation_limit),
true
);
- set_virtualhid_license_menu_item(6, "View License Details", false, tray_virtualhid_license_cb);
- set_virtualhid_license_menu_item(7, "Manage License", false, tray_virtualhid_license_cb);
+ separator_index = 4U;
+ set_virtualhid_license_menu_item(5, "View License Details", false, tray_virtualhid_license_cb);
+ set_virtualhid_license_menu_item(6, "Manage License", false, tray_virtualhid_license_cb);
} else {
set_virtualhid_license_menu_item(1, std::string {virtualhid_license_state_detail(license.state)}, true);
set_virtualhid_license_menu_item(2, "Full virtual gamepad support is locked", true);
@@ -447,10 +444,11 @@ namespace system_tray {
set_virtualhid_license_menu_item(6, "Activate License", false, tray_virtualhid_license_cb);
set_virtualhid_license_menu_item(7, "Buy License", false, tray_virtualhid_license_cb);
}
- virtualhid_license_menu[5] = {.text = "-"};
- set_virtualhid_license_menu_item(8, "Benefits over ViGEmBus", false);
- virtualhid_license_menu[8].submenu = virtualhid_benefits_menu.data();
- set_virtualhid_license_menu_item(9, "Download Virtual HID Driver", false, tray_virtualhid_download_cb);
+ virtualhid_license_menu[separator_index] = {.text = "-"};
+ const auto benefits_index = separator_index + 3U;
+ set_virtualhid_license_menu_item(benefits_index, "Benefits over ViGEmBus", false);
+ virtualhid_license_menu[benefits_index].submenu = virtualhid_benefits_menu.data();
+ set_virtualhid_license_menu_item(benefits_index + 1U, "Download Virtual HID Driver", false, tray_virtualhid_download_cb);
}
/**
diff --git a/src_assets/common/assets/web/public/assets/locale/en.json b/src_assets/common/assets/web/public/assets/locale/en.json
index 1ececcdba..4735edada 100644
--- a/src_assets/common/assets/web/public/assets/locale/en.json
+++ b/src_assets/common/assets/web/public/assets/locale/en.json
@@ -594,7 +594,6 @@
"virtualhid_license_customer": "Customer",
"virtualhid_license_deactivate": "Deactivate This Machine",
"virtualhid_license_desc": "An active license is required before Sunshine can create libvirtualhid gamepads. Activation is handled by the local libvirtualhid service; Sunshine does not save your license key.",
- "virtualhid_license_expires": "Expires",
"virtualhid_license_key": "License Key",
"virtualhid_license_key_desc": "The key is sent only to the local libvirtualhid service and is cleared from this page after successful activation.",
"virtualhid_license_key_placeholder": "Enter your product key",
diff --git a/src_assets/common/assets/web/troubleshooting.html b/src_assets/common/assets/web/troubleshooting.html
index 9ecf98d81..dde2cc0d4 100644
--- a/src_assets/common/assets/web/troubleshooting.html
+++ b/src_assets/common/assets/web/troubleshooting.html
@@ -193,10 +193,6 @@
{{ $t('troubleshooting.virtualhid_license_customer') }}
{{ virtualhidLicense.customer_email }}
-
- - {{ $t('troubleshooting.virtualhid_license_expires') }}
- - {{ virtualhidLicense.expires_at }}
-
(), 3U);
EXPECT_EQ(output["plan_name"].get(), "Yearly");
EXPECT_EQ(output["customer_email"].get(), "customer@example.com");
- EXPECT_EQ(output["expires_at"].get(), "2027-08-10T00:00:00Z");
+ EXPECT_FALSE(output.contains("expires_at"));
EXPECT_EQ(output["message"].get(), "License is active");
EXPECT_EQ(output["purchase_url"].get(), "https://example.com/buy");
EXPECT_EQ(output["manage_account_url"].get(), "https://example.com/manage");
diff --git a/tests/unit/test_system_tray.cpp b/tests/unit/test_system_tray.cpp
index 84fba4a97..7961786db 100644
--- a/tests/unit/test_system_tray.cpp
+++ b/tests/unit/test_system_tray.cpp
@@ -98,15 +98,16 @@ namespace {
* @brief Verify the shared action entries in a populated Virtual HID Driver menu.
*
* @param license_menu License submenu to verify.
+ * @param benefits_index Index of the shared benefits action.
*/
- void verify_virtualhid_actions_menu(const struct tray_menu *license_menu) {
+ void verify_virtualhid_actions_menu(const struct tray_menu *license_menu, std::size_t benefits_index) {
ASSERT_NE(license_menu, nullptr);
- EXPECT_STREQ(license_menu[8].text, "Benefits over ViGEmBus");
- EXPECT_EQ(license_menu[8].cb, nullptr);
- verify_virtualhid_benefits_menu(license_menu[8].submenu);
- EXPECT_STREQ(license_menu[9].text, "Download Virtual HID Driver");
- EXPECT_NE(license_menu[9].cb, nullptr);
- EXPECT_EQ(license_menu[10].text, nullptr);
+ EXPECT_STREQ(license_menu[benefits_index].text, "Benefits over ViGEmBus");
+ EXPECT_EQ(license_menu[benefits_index].cb, nullptr);
+ verify_virtualhid_benefits_menu(license_menu[benefits_index].submenu);
+ EXPECT_STREQ(license_menu[benefits_index + 1U].text, "Download Virtual HID Driver");
+ EXPECT_NE(license_menu[benefits_index + 1U].cb, nullptr);
+ EXPECT_EQ(license_menu[benefits_index + 2U].text, nullptr);
}
#endif
@@ -328,7 +329,6 @@ TEST_F(SystemTrayTest, PreparesLicensedVirtualHidMenuBeforeInitialization) {
license.state = lvh::LicenseState::licensed;
license.plan_name = "Yearly";
license.customer_email = "customer@example.com";
- license.expires_at = "2027-08-10T00:00:00Z";
license.activation_usage = 2;
license.activation_limit = 5;
@@ -340,29 +340,26 @@ TEST_F(SystemTrayTest, PreparesLicensedVirtualHidMenuBeforeInitialization) {
EXPECT_STREQ(license_menu[0].text, "Status: Licensed");
EXPECT_STREQ(license_menu[1].text, "Plan: Yearly");
EXPECT_STREQ(license_menu[2].text, "Customer: customer@example.com");
- EXPECT_STREQ(license_menu[3].text, "Expires: 2027-08-10T00:00:00Z");
- EXPECT_STREQ(license_menu[4].text, "Machine activations: 2 / 5");
- EXPECT_STREQ(license_menu[5].text, "-");
- EXPECT_STREQ(license_menu[6].text, "View License Details");
+ EXPECT_STREQ(license_menu[3].text, "Machine activations: 2 / 5");
+ EXPECT_STREQ(license_menu[4].text, "-");
+ EXPECT_STREQ(license_menu[5].text, "View License Details");
+ EXPECT_NE(license_menu[5].cb, nullptr);
+ EXPECT_STREQ(license_menu[6].text, "Manage License");
EXPECT_NE(license_menu[6].cb, nullptr);
- EXPECT_STREQ(license_menu[7].text, "Manage License");
- EXPECT_NE(license_menu[7].cb, nullptr);
- verify_virtualhid_actions_menu(license_menu);
+ verify_virtualhid_actions_menu(license_menu, 7U);
EXPECT_EQ(tray_data.notification_title, nullptr);
EXPECT_EQ(tray_data.notification_text, nullptr);
EXPECT_EQ(tray_data.notification_cb, nullptr);
license.plan_name.clear();
license.customer_email.clear();
- license.expires_at.clear();
license.activation_usage = 0;
license.activation_limit = 0;
system_tray::update_tray_virtualhid_license(license, false);
EXPECT_STREQ(license_menu[1].text, "This machine is activated");
EXPECT_STREQ(license_menu[2].text, "Customer: Not reported");
- EXPECT_STREQ(license_menu[3].text, "Expiration: Not reported");
- EXPECT_STREQ(license_menu[4].text, "Machine activations: Not reported");
+ EXPECT_STREQ(license_menu[3].text, "Machine activations: Not reported");
}
/**
@@ -393,7 +390,7 @@ TEST_P(UnlicensedVirtualHidTrayTest, PreparesMenuAndStartupNotification) {
EXPECT_NE(license_menu[6].cb, nullptr);
EXPECT_STREQ(license_menu[7].text, "Buy License");
EXPECT_NE(license_menu[7].cb, nullptr);
- verify_virtualhid_actions_menu(license_menu);
+ verify_virtualhid_actions_menu(license_menu, 8U);
EXPECT_STREQ(tray_data.notification_title, "Activate Virtual HID Driver");
EXPECT_STREQ(
tray_data.notification_text,
diff --git a/third-party/libvirtualhid b/third-party/libvirtualhid
index 6b06ea99f..0cab07331 160000
--- a/third-party/libvirtualhid
+++ b/third-party/libvirtualhid
@@ -1 +1 @@
-Subproject commit 6b06ea99f0d96ff54dbd4f4d7adf0588aa154a66
+Subproject commit 0cab07331f819aad358d0b5b979ad923a05805d3