Support keyboard led indicator on wayland as well

This commit is contained in:
dec05eba
2025-11-08 03:28:18 +01:00
parent 0995e86e89
commit d1f8db3760
12 changed files with 282 additions and 47 deletions

View File

@@ -231,8 +231,8 @@ namespace gsr {
{"record.record_options.overclock", &config.record_config.record_options.overclock},
{"record.record_options.record_cursor", &config.record_config.record_options.record_cursor},
{"record.record_options.restore_portal_session", &config.record_config.record_options.restore_portal_session},
{"record.record_options.show_notifications", &config.replay_config.record_options.show_notifications},
{"record.record_options.use_led_indicator", &config.replay_config.record_options.use_led_indicator},
{"record.record_options.show_notifications", &config.record_config.record_options.show_notifications},
{"record.record_options.use_led_indicator", &config.record_config.record_options.use_led_indicator},
{"record.save_video_in_game_folder", &config.record_config.save_video_in_game_folder},
{"record.save_directory", &config.record_config.save_directory},
{"record.container", &config.record_config.container},

View File

@@ -1,15 +1,21 @@
#include "../include/LedIndicator.hpp"
#include <X11/XKBlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
namespace gsr {
LedIndicator::LedIndicator(Display *dpy) : dpy(dpy) {
scroll_lock_atom = XInternAtom(dpy, "Scroll Lock", False);
XkbSetNamedIndicator(dpy, scroll_lock_atom, True, False, False, NULL);
LedIndicator::LedIndicator() {
run_gsr_global_hotkeys_set_leds(false);
}
LedIndicator::~LedIndicator() {
XkbSetNamedIndicator(dpy, scroll_lock_atom, True, False, False, NULL);
run_gsr_global_hotkeys_set_leds(false);
if(gsr_global_hotkeys_pid > 0) {
int status;
waitpid(gsr_global_hotkeys_pid, &status, 0);
}
}
void LedIndicator::set_led(bool enabled) {
@@ -22,12 +28,48 @@ namespace gsr {
blink_timer.restart();
}
bool LedIndicator::run_gsr_global_hotkeys_set_leds(bool enabled) {
if(gsr_global_hotkeys_pid > 0) {
int status;
if(waitpid(gsr_global_hotkeys_pid, &status, WNOHANG) == 0) {
// Still running
return false;
}
gsr_global_hotkeys_pid = -1;
}
const bool inside_flatpak = getenv("FLATPAK_ID") != NULL;
const char *user_homepath = getenv("HOME");
if(!user_homepath)
user_homepath = "/tmp";
gsr_global_hotkeys_pid = vfork();
if(gsr_global_hotkeys_pid == -1) {
fprintf(stderr, "Error: LedIndicator::run_gsr_global_hotkeys_set_leds: failed to fork\n");
return false;
} else if(gsr_global_hotkeys_pid == 0) { // Child
if(inside_flatpak) {
const char *args[] = { "flatpak-spawn", "--host", "/var/lib/flatpak/app/com.dec05eba.gpu_screen_recorder/current/active/files/bin/kms-server-proxy", "launch-gsr-global-hotkeys", user_homepath, "--set-led", "Scroll Lock", enabled ? "on" : "off", nullptr };
execvp(args[0], (char* const*)args);
} else {
const char *args[] = { "gsr-global-hotkeys", "--set-led", "Scroll Lock", enabled ? "on" : "off", nullptr };
execvp(args[0], (char* const*)args);
}
perror("gsr-global-hotkeys");
_exit(127);
return true;
} else { // Parent
return true;
}
}
void LedIndicator::update_led(bool new_state) {
if(new_state == led_indicator_on)
return;
led_indicator_on = new_state;
XkbSetNamedIndicator(dpy, scroll_lock_atom, True, new_state, False, NULL);
if(run_gsr_global_hotkeys_set_leds(new_state))
led_indicator_on = new_state;
}
void LedIndicator::update() {

View File

@@ -522,8 +522,8 @@ namespace gsr {
}
}
if(x11_dpy)
led_indicator = std::make_unique<LedIndicator>(x11_dpy);
// TODO: Only do this if led indicator is enabled (at startup or when changing recording/screenshot settings to enabled it)
led_indicator = std::make_unique<LedIndicator>();
}
Overlay::~Overlay() {

View File

@@ -229,7 +229,7 @@ namespace gsr {
}
std::unique_ptr<Widget> ScreenshotSettingsPage::create_led_indicator() {
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, gsr_info->system_info.display_server == DisplayServer::X11 ? "Blink scroll lock led when taking a screenshot" : "Blink scroll lock led when taking a screenshot (not supported by Wayland)");
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Blink scroll lock led when taking a screenshot");
checkbox->set_checked(true);
led_indicator_checkbox_ptr = checkbox.get();
return checkbox;

View File

@@ -832,10 +832,7 @@ namespace gsr {
std::unique_ptr<CheckBox> SettingsPage::create_led_indicator(const char *type) {
char label_str[256];
if(gsr_info->system_info.display_server == DisplayServer::X11)
snprintf(label_str, sizeof(label_str), "Show %s status with scroll lock led", type);
else
snprintf(label_str, sizeof(label_str), "Show %s status with scroll lock led (not supported by Wayland)", type);
snprintf(label_str, sizeof(label_str), "Show %s status with scroll lock led", type);
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, label_str);
checkbox->set_checked(false);