Fix unable to change hotkey settings while recording

This commit is contained in:
dec05eba
2025-04-11 21:51:38 +02:00
parent 90a1272a65
commit 38feee9f29
6 changed files with 53 additions and 25 deletions

View File

@@ -40,7 +40,7 @@ There are also additional dependencies needed at runtime:
## Program behavior notes
This program has to grab all keyboards and create a virtual keyboard (`gsr-ui virtual keyboard`) to make global hotkeys work on all Wayland compositors.\
This might cause issues for you if you use keyboard remapping software. To workaround this you can go into settings and select "Only grab virtual devices".\
If you use keyboard remapping software such as keyd then make sure to make it ignore "gsr-ui virtual keyboard" (-dec0:5eba device id), otherwise your keyboard can get locked
If you use keyboard remapping software such as keyd then make sure to make it ignore "gsr-ui virtual keyboard" (dec0:5eba device id), otherwise your keyboard can get locked
as gpu screen recorder tries to grab keys and keyd grabs gpu screen recorder, leading to a lock.\
If you are stuck in such a lock where you cant press and keyboard keys you can press (left) ctrl+shift+alt+esc to close gpu screen recorder and remove it from system startup.

View File

@@ -21,6 +21,8 @@ namespace gsr {
bool bind_key_press(Hotkey hotkey, const std::string &id, GlobalHotkeyCallback callback) override;
void unbind_all_keys() override;
void poll_events() override;
private:
void close_fds();
private:
pid_t process_id = 0;
int read_pipes[2];

View File

@@ -1,5 +1,4 @@
#include "../include/GlobalHotkeysLinux.hpp"
#include <signal.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <limits.h>
@@ -71,22 +70,40 @@ namespace gsr {
}
GlobalHotkeysLinux::~GlobalHotkeysLinux() {
for(int i = 0; i < 2; ++i) {
if(read_pipes[i] > 0)
close(read_pipes[i]);
if(write_pipes[i] > 0)
close(write_pipes[i]);
if(write_pipes[PIPE_WRITE] > 0) {
char command[32];
const int command_size = snprintf(command, sizeof(command), "exit\n");
if(write(write_pipes[PIPE_WRITE], command, command_size) != command_size) {
fprintf(stderr, "Error: GlobalHotkeysLinux::~GlobalHotkeysLinux: failed to write command to gsr-global-hotkeys, error: %s\n", strerror(errno));
close_fds();
}
}
if(read_file)
fclose(read_file);
if(process_id > 0) {
kill(process_id, SIGKILL);
int status;
waitpid(process_id, &status, 0);
}
close_fds();
}
void GlobalHotkeysLinux::close_fds() {
for(int i = 0; i < 2; ++i) {
if(read_pipes[i] > 0) {
close(read_pipes[i]);
read_pipes[i] = -1;
}
if(write_pipes[i] > 0) {
close(write_pipes[i]);
write_pipes[i] = -1;
}
}
if(read_file) {
fclose(read_file);
read_file = nullptr;
}
}
bool GlobalHotkeysLinux::start() {

View File

@@ -1580,9 +1580,9 @@ namespace gsr {
return;
if(is_capture_target_monitor(recording_capture_target.c_str()))
snprintf(msg, sizeof(msg), "Saved recording of this monitor to '%s'", filename.c_str());
snprintf(msg, sizeof(msg), "Saved a recording of this monitor to '%s'", filename.c_str());
else
snprintf(msg, sizeof(msg), "Saved recording of %s to '%s'", recording_capture_target.c_str(), filename.c_str());
snprintf(msg, sizeof(msg), "Saved a recording of %s to '%s'", recording_capture_target.c_str(), filename.c_str());
capture_target = recording_capture_target.c_str();
break;
@@ -1592,9 +1592,9 @@ namespace gsr {
return;
if(is_capture_target_monitor(replay_capture_target.c_str()))
snprintf(msg, sizeof(msg), "Saved replay of this monitor to '%s'", filename.c_str());
snprintf(msg, sizeof(msg), "Saved a replay of this monitor to '%s'", filename.c_str());
else
snprintf(msg, sizeof(msg), "Saved replay of %s to '%s'", replay_capture_target.c_str(), filename.c_str());
snprintf(msg, sizeof(msg), "Saved a replay of %s to '%s'", replay_capture_target.c_str(), filename.c_str());
capture_target = replay_capture_target.c_str();
break;
@@ -1604,9 +1604,9 @@ namespace gsr {
return;
if(is_capture_target_monitor(screenshot_capture_target.c_str()))
snprintf(msg, sizeof(msg), "Saved screenshot of this monitor to '%s'", filename.c_str());
snprintf(msg, sizeof(msg), "Saved a screenshot of this monitor to '%s'", filename.c_str());
else
snprintf(msg, sizeof(msg), "Saved screenshot of %s to '%s'", screenshot_capture_target.c_str(), filename.c_str());
snprintf(msg, sizeof(msg), "Saved a screenshot of %s to '%s'", screenshot_capture_target.c_str(), filename.c_str());
capture_target = screenshot_capture_target.c_str();
break;
@@ -1626,9 +1626,9 @@ namespace gsr {
const std::string filename = filepath_get_filename(replay_saved_filepath);
char msg[512];
if(is_capture_target_monitor(replay_capture_target.c_str()))
snprintf(msg, sizeof(msg), "Saved replay of this monitor to '%s'", filename.c_str());
snprintf(msg, sizeof(msg), "Saved a replay of this monitor to '%s'", filename.c_str());
else
snprintf(msg, sizeof(msg), "Saved replay of %s to '%s'", replay_capture_target.c_str(), filename.c_str());
snprintf(msg, sizeof(msg), "Saved a replay of %s to '%s'", replay_capture_target.c_str(), filename.c_str());
show_notification(msg, notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::REPLAY, replay_capture_target.c_str());
}
}
@@ -1729,9 +1729,9 @@ namespace gsr {
const std::string filename = filepath_get_filename(screenshot_filepath.c_str());
char msg[512];
if(is_capture_target_monitor(screenshot_capture_target.c_str()))
snprintf(msg, sizeof(msg), "Saved screenshot of this monitor to '%s'", filename.c_str());
snprintf(msg, sizeof(msg), "Saved a screenshot of this monitor to '%s'", filename.c_str());
else
snprintf(msg, sizeof(msg), "Saved screenshot of %s to '%s'", screenshot_capture_target.c_str(), filename.c_str());
snprintf(msg, sizeof(msg), "Saved a screenshot of %s to '%s'", screenshot_capture_target.c_str(), filename.c_str());
show_notification(msg, notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::SCREENSHOT, screenshot_capture_target.c_str());
}
} else {
@@ -1835,9 +1835,9 @@ namespace gsr {
const std::string filename = filepath_get_filename(record_filepath.c_str());
char msg[512];
if(is_capture_target_monitor(recording_capture_target.c_str()))
snprintf(msg, sizeof(msg), "Saved recording of this monitor to '%s'", filename.c_str());
snprintf(msg, sizeof(msg), "Saved a recording of this monitor to '%s'", filename.c_str());
else
snprintf(msg, sizeof(msg), "Saved recording of %s to '%s'", recording_capture_target.c_str(), filename.c_str());
snprintf(msg, sizeof(msg), "Saved a recording of %s to '%s'", recording_capture_target.c_str(), filename.c_str());
show_notification(msg, notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::RECORD, recording_capture_target.c_str());
}
} else {

View File

@@ -18,4 +18,10 @@ To unbind all keys send `unbind_all<newline>` to the programs stdin, for example
```
unbind_all
```
## Exit
To close gsr-global-hotkeys send `exit<newline>` to the programs stdin, for example:
```
exit
```

View File

@@ -707,8 +707,11 @@ static void keyboard_event_parse_stdin_command(keyboard_event *self, const char
}
self->num_global_hotkeys = 0;
fprintf(stderr, "Info: unbinded all hotkeys\n");
} else if(strncmp(command, "exit", 4) == 0) {
self->stdin_failed = true;
fprintf(stderr, "Info: received exit command\n");
} else {
fprintf(stderr, "Warning: got invalid command: \"%s\", expected command to start with either \"bind\" or \"unbind_all\"\n", command);
fprintf(stderr, "Warning: got invalid command: \"%s\", expected command to start with either \"bind\", \"unbind_all\" or \"exit\"\n", command);
}
}