From faaf2009b6a272da5489a19cb33a29be2856fbf1 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Sat, 26 Jul 2025 01:44:09 -0500 Subject: [PATCH] Add keepalive thread for Razer Blade 14 2021 and 2022 that sends a get device request to keep lighting active --- .../RazerController/RazerController.cpp | 55 +++++++++++++++++++ .../RazerController/RazerController.h | 9 +++ 2 files changed, 64 insertions(+) diff --git a/Controllers/RazerController/RazerController/RazerController.cpp b/Controllers/RazerController/RazerController/RazerController.cpp index f964ede3..731d29fc 100644 --- a/Controllers/RazerController/RazerController/RazerController.cpp +++ b/Controllers/RazerController/RazerController/RazerController.cpp @@ -173,10 +173,34 @@ RazerController::RazerController(hid_device* dev_handle, hid_device* dev_argb_ha | Determine matrix type for device | \*-----------------------------------------------------------------*/ matrix_type = device_list[device_index]->matrix_type; + + /*-----------------------------------------------------------------*\ + | Start keepalive thread for devices that need it to prevent RGB | + | from timing out | + \*-----------------------------------------------------------------*/ + switch(dev_pid) + { + case RAZER_BLADE_14_2021_PID: + case RAZER_BLADE_14_2022_PID: + keepalive_thread_run = true; + keepalive_thread = new std::thread(&RazerController::KeepaliveThreadFunction, this); + break; + + default: + keepalive_thread_run = false; + keepalive_thread = NULL; + break; + } } RazerController::~RazerController() { + if(keepalive_thread != NULL) + { + keepalive_thread_run = false; + keepalive_thread->join(); + } + hid_close(dev); delete guard_manager_ptr; } @@ -211,6 +235,23 @@ std::string RazerController::GetSerialString() return(razer_get_serial()); } +void RazerController::KeepaliveThreadFunction() +{ + /*-----------------------------------------------------------------*\ + | Performing a get device mode request seems to be enough to keep | + | the lighting active on devices with the lighting timeout, so | + | periodically send a device mode request every 2.5s. | + \*-----------------------------------------------------------------*/ + while(keepalive_thread_run.load()) + { + if((std::chrono::steady_clock::now() - last_update_time) > 2500ms) + { + razer_get_device_mode(); + } + std::this_thread::sleep_for(1s); + } +} + void RazerController::SetAddressableZoneSizes(unsigned char zone_1_size, unsigned char zone_2_size, unsigned char zone_3_size, unsigned char zone_4_size, unsigned char zone_5_size, unsigned char zone_6_size) { razer_report report = razer_create_addressable_size_report(zone_1_size, zone_2_size, zone_3_size, zone_4_size, zone_5_size, zone_6_size); @@ -996,6 +1037,20 @@ razer_report RazerController::razer_create_set_led_effect_report(unsigned char v | Get functions (request information from device) | \*---------------------------------------------------------------------------------*/ +unsigned char RazerController::razer_get_device_mode() +{ + std::string firmware_string = ""; + struct razer_report report = razer_create_report(0x00, RAZER_COMMAND_ID_GET_DEVICE_MODE, 0x02); + struct razer_report response_report = razer_create_response(); + + std::this_thread::sleep_for(2ms); + razer_usb_send(&report); + std::this_thread::sleep_for(5ms); + razer_usb_receive(&response_report); + + return(response_report.arguments[0]); +} + std::string RazerController::razer_get_firmware() { std::string firmware_string = ""; diff --git a/Controllers/RazerController/RazerController/RazerController.h b/Controllers/RazerController/RazerController/RazerController.h index 20d9cb1a..ce6a528f 100644 --- a/Controllers/RazerController/RazerController/RazerController.h +++ b/Controllers/RazerController/RazerController/RazerController.h @@ -11,7 +11,10 @@ #pragma once +#include +#include #include +#include #include #include "RGBController.h" #include "DeviceGuardManager.h" @@ -323,6 +326,7 @@ private: razer_report razer_create_set_led_effect_report(unsigned char variable_storage, unsigned char led_id, unsigned char effect); razer_report razer_create_set_led_rgb_report(unsigned char variable_storage, unsigned char led_id, unsigned char* rgb_data); + unsigned char razer_get_device_mode(); std::string razer_get_firmware(); std::string razer_get_serial(); void razer_get_keyboard_info(unsigned char* layout, unsigned char* variant); @@ -345,4 +349,9 @@ private: int razer_usb_send(razer_report* report); int razer_usb_send_argb(razer_argb_report* report); + std::chrono::time_point last_update_time; + std::atomic keepalive_thread_run; + std::thread * keepalive_thread; + + void KeepaliveThreadFunction(); };