Fix leds getting unset when closing the program

This commit is contained in:
dec05eba
2025-11-08 13:24:40 +01:00
parent f017f04bdc
commit 2506750243
6 changed files with 105 additions and 18 deletions

7
TODO
View File

@@ -84,9 +84,6 @@ Dont put widget position to int position when scrolling. This makes the UI jitte
Show warning if another instance of gpu screen recorder is already running when starting recording? Show warning if another instance of gpu screen recorder is already running when starting recording?
Keyboard leds get turned off when stopping gsr-global-hotkeys (for example numlock). The numlock key has to be pressed twice again to make it look correct to match its state.
Fix this by writing 0 or 1 to /sys/class/leds/input2::numlock/brightness.
Make gsr-ui flatpak systemd work nicely with non-flatpak gsr-ui. Maybe change ExecStart to do flatpak run ... || gsr-ui, but make it run as a shell command first with /bin/sh -c "". Make gsr-ui flatpak systemd work nicely with non-flatpak gsr-ui. Maybe change ExecStart to do flatpak run ... || gsr-ui, but make it run as a shell command first with /bin/sh -c "".
When enabling X11 global hotkey again only grab lalt, not ralt. When enabling X11 global hotkey again only grab lalt, not ralt.
@@ -245,4 +242,6 @@ Show the currently recorded capture in the ui, to preview if everything looks ok
Show a question mark beside options. When hovering the question mark show a tooltip that explains the options. Show a question mark beside options. When hovering the question mark show a tooltip that explains the options.
Remove all mgl::Clock usage in Overlay. We only need to get the time once per update in Overlay::handle_events. Also get time in other places outside handle_events. Remove all mgl::Clock usage in Overlay. We only need to get the time once per update in Overlay::handle_events. Also get time in other places outside handle_events.
Handle stopping replay/stream when recording is running (show notification that the video is saved and move the video to folder with game name).

View File

@@ -1,4 +1,4 @@
project('gsr-ui', ['c', 'cpp'], version : '1.7.9', default_options : ['warning_level=2', 'cpp_std=c++17'], subproject_dir : 'depends') project('gsr-ui', ['c', 'cpp'], version : '1.8.0', default_options : ['warning_level=2', 'cpp_std=c++17'], subproject_dir : 'depends')
add_project_arguments('-D_FILE_OFFSET_BITS=64', language : ['c', 'cpp']) add_project_arguments('-D_FILE_OFFSET_BITS=64', language : ['c', 'cpp'])
@@ -66,7 +66,7 @@ datadir = get_option('datadir')
gsr_ui_resources_path = join_paths(prefix, datadir, 'gsr-ui') gsr_ui_resources_path = join_paths(prefix, datadir, 'gsr-ui')
add_project_arguments('-DGSR_UI_VERSION="' + meson.project_version() + '"', language: ['c', 'cpp']) add_project_arguments('-DGSR_UI_VERSION="' + meson.project_version() + '"', language: ['c', 'cpp'])
add_project_arguments('-DGSR_FLATPAK_VERSION="5.8.4"', language: ['c', 'cpp']) add_project_arguments('-DGSR_FLATPAK_VERSION="5.8.5"', language: ['c', 'cpp'])
executable( executable(
meson.project_name(), meson.project_name(),

View File

@@ -1,7 +1,7 @@
[package] [package]
name = "gsr-ui" name = "gsr-ui"
type = "executable" type = "executable"
version = "1.7.9" version = "1.8.0"
platforms = ["posix"] platforms = ["posix"]
[lang.cpp] [lang.cpp]

View File

@@ -1,5 +1,6 @@
#include "keyboard_event.h" #include "keyboard_event.h"
#include "keys.h" #include "keys.h"
#include "leds.h"
/* C stdlib */ /* C stdlib */
#include <stdio.h> #include <stdio.h>
@@ -716,6 +717,41 @@ bool keyboard_event_init(keyboard_event *self, bool exclusive_grab, keyboard_gra
return true; return true;
} }
static void write_led_data_to_device(int fd, uint16_t led, int value) {
struct input_event led_data = {
.type = EV_LED,
.code = led,
.value = value
};
write(fd, &led_data, sizeof(led_data));
struct input_event syn_data = {
.type = EV_SYN,
.code = 0,
.value = 0
};
write(fd, &syn_data, sizeof(syn_data));
}
/* When the device is ungrabbed the leds are unset for some reason. Set them back to their previous brightness */
static void keyboard_event_device_deinit(int fd, event_extra_data *extra_data) {
ggh_leds leds;
const bool got_leds = get_leds(extra_data->dev_input_id, &leds);
ioctl(fd, EVIOCGRAB, 0);
if(got_leds) {
if(leds.scroll_lock_brightness >= 0)
write_led_data_to_device(fd, LED_SCROLLL, leds.scroll_lock_brightness);
if(leds.num_lock_brightness >= 0)
write_led_data_to_device(fd, LED_NUML, leds.num_lock_brightness);
if(leds.caps_lock_brightness >= 0)
write_led_data_to_device(fd, LED_CAPSL, leds.caps_lock_brightness);
}
close(fd);
}
void keyboard_event_deinit(keyboard_event *self) { void keyboard_event_deinit(keyboard_event *self) {
self->running = false; self->running = false;
@@ -732,8 +768,10 @@ void keyboard_event_deinit(keyboard_event *self) {
for(int i = 0; i < self->num_event_polls; ++i) { for(int i = 0; i < self->num_event_polls; ++i) {
if(self->event_polls[i].fd > 0) { if(self->event_polls[i].fd > 0) {
ioctl(self->event_polls[i].fd, EVIOCGRAB, 0); if(self->event_extra_data[i].dev_input_id > 0 && !self->event_extra_data[i].gsr_ui_virtual_keyboard)
close(self->event_polls[i].fd); keyboard_event_device_deinit(self->event_polls[i].fd, &self->event_extra_data[i]);
else
close(self->event_polls[i].fd);
} }
free(self->event_extra_data[i].key_states); free(self->event_extra_data[i].key_states);
free(self->event_extra_data[i].key_presses_grabbed); free(self->event_extra_data[i].key_presses_grabbed);

View File

@@ -15,27 +15,37 @@
/* LINUX */ /* LINUX */
#include <linux/input.h> #include <linux/input.h>
static int get_max_brightness(const char *sys_class_path, const char *filename) { /* Returns -1 on error */
char path[PATH_MAX]; static int read_int_from_file(const char *filepath) {
snprintf(path, sizeof(path), "%s/%s/max_brightness", sys_class_path, filename); const int fd = open(filepath, O_RDONLY);
const int fd = open(path, O_RDONLY);
if(fd == -1) { if(fd == -1) {
fprintf(stderr, "Warning: get_max_brightness open error: %s\n", strerror(errno)); fprintf(stderr, "Warning: get_max_brightness open error: %s\n", strerror(errno));
return false; return -1;
} }
bool success = false; bool success = false;
int max_brightness = 0; int value = 0;
char buffer[32]; char buffer[32];
const ssize_t num_bytes_read = read(fd, buffer, sizeof(buffer)); const ssize_t num_bytes_read = read(fd, buffer, sizeof(buffer));
if(num_bytes_read > 0) { if(num_bytes_read > 0) {
buffer[num_bytes_read] = '\0'; buffer[num_bytes_read] = '\0';
success = sscanf(buffer, "%d", &max_brightness) == 1; success = sscanf(buffer, "%d", &value) == 1;
} }
close(fd); close(fd);
return success; return success ? value : -1;
}
static int get_max_brightness(const char *sys_class_path, const char *filename) {
char path[PATH_MAX];
snprintf(path, sizeof(path), "%s/%s/max_brightness", sys_class_path, filename);
return read_int_from_file(path);
}
static int get_brightness(const char *sys_class_path, const char *filename) {
char path[PATH_MAX];
snprintf(path, sizeof(path), "%s/%s/brightness", sys_class_path, filename);
return read_int_from_file(path);
} }
static bool string_starts_with(const char *str, const char *sub) { static bool string_starts_with(const char *str, const char *sub) {
@@ -137,3 +147,35 @@ bool set_leds(const char *led_name, bool enabled) {
return false; return false;
} }
} }
bool get_leds(int event_number, ggh_leds *leds) {
leds->scroll_lock_brightness = -1;
leds->num_lock_brightness = -1;
leds->caps_lock_brightness = -1;
char path[PATH_MAX];
snprintf(path, sizeof(path), "/sys/class/input/event%d/device", event_number);
DIR *dir = opendir(path);
if(!dir)
return false;
struct dirent *entry;
while((entry = readdir(dir)) != NULL) {
if(entry->d_name[0] == '.')
continue;
if(!string_starts_with(entry->d_name, "input"))
continue;
if(string_ends_with(entry->d_name, "::scrolllock"))
leds->scroll_lock_brightness = get_brightness(path, entry->d_name);
else if(string_ends_with(entry->d_name, "::numlock"))
leds->num_lock_brightness = get_brightness(path, entry->d_name);
else if(string_ends_with(entry->d_name, "::capslock"))
leds->caps_lock_brightness = get_brightness(path, entry->d_name);
}
closedir(dir);
return true;
}

View File

@@ -4,6 +4,14 @@
/* C stdlib */ /* C stdlib */
#include <stdbool.h> #include <stdbool.h>
typedef struct {
/* These are set to -1 if not supported */
int scroll_lock_brightness;
int num_lock_brightness;
int caps_lock_brightness;
} ggh_leds;
bool set_leds(const char *led_name, bool enabled); bool set_leds(const char *led_name, bool enabled);
bool get_leds(int event_number, ggh_leds *leds);
#endif /* LEDS_H */ #endif /* LEDS_H */