Compare commits

...

14 Commits
1.9.0 ... 1.9.3

Author SHA1 Message Date
dec05eba
fed47000ce 1.9.3 - Only use led indicator if it's enabled 2026-01-08 20:40:11 +01:00
dec05eba
7f43adfbd5 1.9.3 2026-01-08 20:23:39 +01:00
dec05eba
1f6251baf3 Fix high cpu usage when running global hotkeys without grab and then connecting a secondary keyboard 2026-01-08 20:23:21 +01:00
dec05eba
d1220b013e Update flatpak version reference 2026-01-08 01:25:08 +01:00
dec05eba
93a55b6bdf 1.9.2 2026-01-06 22:17:54 +01:00
dec05eba
974e760136 Fix clipboard save to disk option not working correctly 2026-01-06 22:17:38 +01:00
dec05eba
387141d36f Update flatpak version reference 2026-01-06 19:36:57 +01:00
dec05eba
3713d3d59e Add -Ddesktop-files option 2026-01-01 04:53:26 +01:00
dec05eba
2bb6754523 Update usage text 2025-12-31 16:32:31 +01:00
dec05eba
df1610431d Add application icon, show gsr icon in notification 2025-12-31 16:29:11 +01:00
dec05eba
1ea9615584 Add option to not save screenshot to disk (only clipboard), refactor webcam ui code 2025-12-27 22:57:09 +01:00
dec05eba
45ae7c95cf 1.9.1 2025-12-27 13:04:19 +01:00
dec05eba
f1b6df4d56 Dont turn on led when using replay/streaming and then recording if not enabled 2025-12-27 13:03:30 +01:00
dec05eba
202c0b2415 Correct license identifier 2025-12-26 16:17:05 +01:00
22 changed files with 289 additions and 184 deletions

View File

@@ -44,7 +44,7 @@ as gpu screen recorder tries to grab keys and keyd grabs gpu screen recorder, le
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.
# License
This software is licensed under GPL3.0-only. Files under `fonts/` directory belong to the Noto Sans Google fonts project and they are licensed under `SIL Open Font License`.\
This software is licensed under GPL-3.0-only, see the LICENSE file for more information. Files under `fonts/` directory belong to the Noto Sans Google fonts project and they are licensed under `SIL Open Font License`.\
`images/default.cur` it part of the [Adwaita icon theme](https://gitlab.gnome.org/GNOME/adwaita-icon-theme/-/tree/master) which is licensed under `CC BY-SA 3.0`.\
The controller buttons under `images/` were created by [Julio Cacko](https://juliocacko.itch.io/free-input-prompts) and they are licensed under `CC0 1.0 Universal`.\
The PlayStation logo under `images/` was created by [ArksDigital](https://arks.itch.io/ps4-buttons) and it's licensed under `CC BY 4.0`.

2
TODO
View File

@@ -127,8 +127,6 @@ Add option to do screen-direct recording. But make it clear that it should not b
Add systray for recording status.
Add a desktop icon when gsr-ui has a window mode option (which should be the default launch option).
Verify if cursor tracker monitor name is always correct. It uses the wayland monitor name for recording, but gpu screen recorder uses a custom name created from the drm connector name.
Notification with the focused monitor (with CursorTrackerWayland) assumes that the x11 monitor name is the same as the drm monitor name. Same for find_monitor_by_name.

View File

@@ -0,0 +1,10 @@
[Desktop Entry]
Type=Application
Name=GPU Screen Recorder
GenericName=Screen recorder
Comment=A ShadowPlay-like screen recorder for Linux
Icon=gpu-screen-recorder
Exec=gsr-ui launch-hide-announce
Terminal=false
Keywords=gpu-screen-recorder;gsr-ui;screen recorder;streaming;twitch;replay;shadowplay;
Categories=AudioVideo;Recorder;

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -148,6 +148,7 @@ namespace gsr {
bool save_screenshot_in_game_folder = false;
bool save_screenshot_to_clipboard = false;
bool save_screenshot_to_disk = true;
bool show_notifications = true;
bool use_led_indicator = false;
std::string save_directory;

View File

@@ -40,7 +40,8 @@ namespace gsr {
RECORD,
REPLAY,
STREAM,
SCREENSHOT
SCREENSHOT,
NOTICE
};
enum class NotificationLevel {
@@ -98,6 +99,7 @@ namespace gsr {
bool global_hotkeys_ungrab_keyboard = false;
private:
const char* notification_type_to_string(NotificationType notification_type);
void update_upause_status();
void hide();
@@ -106,6 +108,7 @@ namespace gsr {
void on_event(mgl::Event &event);
void recreate_global_hotkeys(const char *hotkey_option);
void update_led_indicator_after_settings_change();
void create_frontpage_ui_components();
void xi_setup();
void handle_xi_events();
@@ -171,6 +174,8 @@ namespace gsr {
Config config;
Config current_recording_config;
std::string gsr_icon_path;
bool visible = false;
mgl::Texture window_texture_texture;

View File

@@ -23,6 +23,8 @@ namespace gsr {
void load();
void save();
void on_navigate_away_from_page() override;
std::function<void()> on_config_changed;
private:
std::unique_ptr<ComboBox> create_record_area_box();
std::unique_ptr<Widget> create_record_area();
@@ -43,6 +45,7 @@ namespace gsr {
std::unique_ptr<Widget> create_file_info_section();
std::unique_ptr<CheckBox> create_save_screenshot_in_game_folder();
std::unique_ptr<CheckBox> create_save_screenshot_to_clipboard();
std::unique_ptr<CheckBox> create_save_screenshot_to_disk();
std::unique_ptr<Widget> create_notifications();
std::unique_ptr<Widget> create_led_indicator();
std::unique_ptr<Widget> create_general_section();
@@ -76,6 +79,7 @@ namespace gsr {
Button *save_directory_button_ptr = nullptr;
CheckBox *save_screenshot_in_game_folder_checkbox_ptr = nullptr;
CheckBox *save_screenshot_to_clipboard_checkbox_ptr = nullptr;
CheckBox *save_screenshot_to_disk_checkbox_ptr = nullptr;
CheckBox *show_notification_checkbox_ptr = nullptr;
CheckBox *led_indicator_checkbox_ptr = nullptr;
Entry *create_custom_script_screenshot_entry_ptr = nullptr;

View File

@@ -68,6 +68,9 @@ namespace gsr {
std::unique_ptr<Widget> create_capture_target_section();
std::unique_ptr<List> create_webcam_sources();
std::unique_ptr<List> create_webcam_video_format();
std::unique_ptr<Widget> create_webcam_location_widget();
std::unique_ptr<CheckBox> create_flip_camera_checkbox();
std::unique_ptr<List> create_webcam_body();
std::unique_ptr<Widget> create_webcam_section();
std::unique_ptr<ComboBox> create_audio_device_selection_combobox(AudioDeviceType device_type);
std::unique_ptr<Button> create_remove_audio_device_button(List *audio_input_list_ptr, List *audio_device_list_ptr);

View File

@@ -1,4 +1,4 @@
project('gsr-ui', ['c', 'cpp'], version : '1.9.0', default_options : ['warning_level=2', 'cpp_std=c++17'], subproject_dir : 'depends')
project('gsr-ui', ['c', 'cpp'], version : '1.9.3', default_options : ['warning_level=2', 'cpp_std=c++17'], subproject_dir : 'depends')
add_project_arguments('-D_FILE_OFFSET_BITS=64', language : ['c', 'cpp'])
@@ -64,9 +64,10 @@ mglpp_dep = mglpp_proj.get_variable('mglpp_dep')
prefix = get_option('prefix')
datadir = get_option('datadir')
gsr_ui_resources_path = join_paths(prefix, datadir, 'gsr-ui')
icons_path = join_paths(prefix, datadir, 'icons')
add_project_arguments('-DGSR_UI_VERSION="' + meson.project_version() + '"', language: ['c', 'cpp'])
add_project_arguments('-DGSR_FLATPAK_VERSION="5.11.1"', language: ['c', 'cpp'])
add_project_arguments('-DGSR_FLATPAK_VERSION="5.11.5"', language: ['c', 'cpp'])
executable(
meson.project_name(),
@@ -112,6 +113,14 @@ executable(
install_subdir('images', install_dir : gsr_ui_resources_path)
install_subdir('fonts', install_dir : gsr_ui_resources_path)
if get_option('desktop-files') == true
install_data(files('gpu-screen-recorder.desktop'), install_dir : join_paths(prefix, datadir, 'applications'))
install_subdir('icons/hicolor', install_dir : icons_path)
gnome = import('gnome')
gnome.post_install(update_desktop_database : true)
endif
if get_option('systemd') == true
install_data(files('extra/gpu-screen-recorder-ui.service'), install_dir : 'lib/systemd/user')
endif

View File

@@ -1,2 +1,3 @@
option('systemd', type : 'boolean', value : true, description : 'Install systemd service file')
option('capabilities', type : 'boolean', value : true, description : 'Set binary setuid capability on gsr-global-hotkeys binary to allow global hotkeys')
option('capabilities', type : 'boolean', value : true, description : 'Set binary setuid capability on gsr-global-hotkeys binary to allow global hotkeys')
option('desktop-files', type : 'boolean', value : true, description : 'Install desktop files')

View File

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

View File

@@ -48,11 +48,18 @@ namespace gsr {
XNextEvent(dpy, &xev);
switch(xev.type) {
case SelectionClear: {
should_clear_selection = true;
if(clipboard_copies.empty()) {
should_clear_selection = false;
set_current_file("", file_type);
bool clear_current_file = false;
{
std::lock_guard<std::mutex> lock(mutex);
should_clear_selection = true;
if(clipboard_copies.empty()) {
should_clear_selection = false;
clear_current_file = true;
}
}
if(clear_current_file)
set_current_file("", file_type);
break;
}
case SelectionRequest:
@@ -205,6 +212,9 @@ namespace gsr {
uint8_t file_buffer[1<<16];
ssize_t file_bytes_read = 0;
if(file_fd <= 0)
return;
if(lseek(file_fd, clipboard_copy->file_offset, SEEK_SET) == -1) {
fprintf(stderr, "gsr ui: error: ClipboardFile::send_clipboard: failed to seek in clipboard file to offset " FORMAT_U64 " for requestor window " FORMAT_I64 ", error: %s\n", (uint64_t)clipboard_copy->file_offset, (int64_t)xselectionrequest->requestor, strerror(errno));
clipboard_copy->file_offset = 0;
@@ -262,7 +272,13 @@ namespace gsr {
}
clipboard_copies.clear();
if(XGetSelectionOwner(dpy, clipboard_atom) == clipboard_window) {
XSetSelectionOwner(dpy, clipboard_atom, None, CurrentTime);
XFlush(dpy);
}
if(filepath.empty()) {
// TODO: Cancel transfer
if(file_fd > 0) {
close(file_fd);
file_fd = -1;

View File

@@ -305,6 +305,7 @@ namespace gsr {
{"screenshot.restore_portal_session", &config.screenshot_config.restore_portal_session},
{"screenshot.save_screenshot_in_game_folder", &config.screenshot_config.save_screenshot_in_game_folder},
{"screenshot.save_screenshot_to_clipboard", &config.screenshot_config.save_screenshot_to_clipboard},
{"screenshot.save_screenshot_to_disk", &config.screenshot_config.save_screenshot_to_disk},
{"screenshot.show_notifications", &config.screenshot_config.show_notifications},
{"screenshot.use_led_indicator", &config.screenshot_config.use_led_indicator},
{"screenshot.save_directory", &config.screenshot_config.save_directory},

View File

@@ -152,19 +152,24 @@ namespace gsr {
if(read_led_brightness_timer.get_elapsed_time_seconds() > 0.2) {
read_led_brightness_timer.restart();
bool led_status_outdated = false;
bool any_keyboard_with_led_enabled = false;
bool any_keyboard_with_led_disabled = false;
char buffer[32];
for(int led_brightness_file_fd : led_brightness_files) {
const ssize_t bytes_read = read(led_brightness_file_fd, buffer, sizeof(buffer));
if(bytes_read > 0) {
if(buffer[0] == '0')
led_status_outdated = true;
any_keyboard_with_led_disabled = true;
else
any_keyboard_with_led_enabled = true;
lseek(led_brightness_file_fd, 0, SEEK_SET);
}
}
if(led_status_outdated && led_enabled)
if(led_enabled && any_keyboard_with_led_disabled)
run_gsr_global_hotkeys_set_leds(true);
else if(!led_enabled && any_keyboard_with_led_enabled)
run_gsr_global_hotkeys_set_leds(false);
}
}
}

View File

@@ -473,6 +473,8 @@ namespace gsr {
top_bar_background({0.0f, 0.0f}),
close_button_widget({0.0f, 0.0f})
{
gsr_icon_path = this->resources_path + "images/gpu_screen_recorder_logo.png";
key_bindings[0].key_event.code = mgl::Keyboard::Escape;
key_bindings[0].key_event.alt = false;
key_bindings[0].key_event.control = false;
@@ -519,12 +521,11 @@ namespace gsr {
if(!config.main_config.wayland_warning_shown) {
config.main_config.wayland_warning_shown = true;
save_config(config);
show_notification("Wayland doesn't support GPU Screen Recorder UI properly,\nthings may not work as expected. Use X11 if you experience issues.", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::NONE, nullptr, NotificationLevel::ERROR);
show_notification("Wayland doesn't support GPU Screen Recorder UI properly,\nthings may not work as expected. Use X11 if you experience issues.", notification_error_timeout_seconds, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
}
}
// 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>();
update_led_indicator_after_settings_change();
}
Overlay::~Overlay() {
@@ -735,7 +736,7 @@ namespace gsr {
show_notification(
"Some keyboard remapping software conflicts with GPU Screen Recorder on your system.\n"
"Keyboards have been ungrabbed, applications will now receive the hotkeys you press."
, 7.0, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::NONE, nullptr, NotificationLevel::ERROR);
, 7.0, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
config.main_config.hotkeys_enable_option = "enable_hotkeys_no_grab";
save_config(config);
@@ -774,7 +775,7 @@ namespace gsr {
if(selected_window && selected_window != DefaultRootWindow(display)) {
on_window_selected();
} else {
show_notification("No window selected", notification_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::NONE, nullptr, NotificationLevel::ERROR);
show_notification("No window selected", notification_timeout_seconds, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
}
on_window_selected = nullptr;
}
@@ -825,7 +826,7 @@ namespace gsr {
start_region_capture = false;
hide();
if(!region_selector.start(get_color_theme().tint_color)) {
show_notification("Failed to start region capture", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::NONE, nullptr, NotificationLevel::ERROR);
show_notification("Failed to start region capture", notification_error_timeout_seconds, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
on_region_selected = nullptr;
}
}
@@ -834,7 +835,7 @@ namespace gsr {
start_window_capture = false;
hide();
if(!window_selector.start(get_color_theme().tint_color)) {
show_notification("Failed to start window capture", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::NONE, nullptr, NotificationLevel::ERROR);
show_notification("Failed to start window capture", notification_error_timeout_seconds, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
on_window_selected = nullptr;
}
}
@@ -1177,6 +1178,15 @@ namespace gsr {
global_hotkeys.reset();
}
void Overlay::update_led_indicator_after_settings_change() {
if(config.record_config.record_options.use_led_indicator || config.replay_config.record_options.use_led_indicator || config.streaming_config.record_options.use_led_indicator || config.screenshot_config.use_led_indicator) {
if(!led_indicator)
led_indicator = std::make_unique<LedIndicator>();
} else {
led_indicator.reset();
}
}
void Overlay::create_frontpage_ui_components() {
bg_screenshot_overlay = mgl::Rectangle(mgl::vec2f(get_theme().window_width, get_theme().window_height));
top_bar_background = mgl::Rectangle(mgl::vec2f(get_theme().window_width, get_theme().window_height*0.06f).floor());
@@ -1267,6 +1277,8 @@ namespace gsr {
record_settings_page->on_config_changed = [this]() {
if(recording_status == RecordingStatus::RECORD)
show_notification("Recording settings have been modified.\nYou may need to restart recording to apply the changes.", notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::RECORD);
update_led_indicator_after_settings_change();
};
page_stack.push(std::move(record_settings_page));
} else if(id == "pause") {
@@ -1292,6 +1304,8 @@ namespace gsr {
stream_settings_page->on_config_changed = [this]() {
if(recording_status == RecordingStatus::STREAM)
show_notification("Streaming settings have been modified.\nYou may need to restart streaming to apply the changes.", notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::STREAM);
update_led_indicator_after_settings_change();
};
page_stack.push(std::move(stream_settings_page));
} else if(id == "start") {
@@ -1321,12 +1335,12 @@ namespace gsr {
if(exit_status == 127) {
if(enable)
show_notification("Failed to add GPU Screen Recorder to system startup.\nThis option only works on systems that use systemd.\nYou have to manually add \"gsr-ui\" to system startup on systems that uses another init system.", 7.0, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::NONE, nullptr, NotificationLevel::ERROR);
show_notification("Failed to add GPU Screen Recorder to system startup.\nThis option only works on systems that use systemd.\nYou have to manually add \"gsr-ui\" to system startup on systems that uses another init system.", 7.0, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
} else {
if(enable)
show_notification("Failed to add GPU Screen Recorder to system startup", notification_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::NONE, nullptr, NotificationLevel::ERROR);
show_notification("Failed to add GPU Screen Recorder to system startup", notification_timeout_seconds, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
else
show_notification("Failed to remove GPU Screen Recorder from system startup", notification_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::NONE, nullptr, NotificationLevel::ERROR);
show_notification("Failed to remove GPU Screen Recorder from system startup", notification_timeout_seconds, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
}
};
@@ -1374,6 +1388,9 @@ namespace gsr {
button->set_icon_padding_scale(1.2f);
button->on_click = [&]() {
auto screenshot_settings_page = std::make_unique<ScreenshotSettingsPage>(&gsr_info, config, &page_stack);
screenshot_settings_page->on_config_changed = [this]() {
update_led_indicator_after_settings_change();
};
page_stack.push(std::move(screenshot_settings_page));
};
front_page_ptr->add_widget(std::move(button));
@@ -1576,13 +1593,14 @@ namespace gsr {
on_press_take_screenshot(false, ScreenshotForceType::WINDOW);
}
static const char* notification_type_to_string(NotificationType notification_type) {
const char* Overlay::notification_type_to_string(NotificationType notification_type) {
switch(notification_type) {
case NotificationType::NONE: return nullptr;
case NotificationType::RECORD: return "record";
case NotificationType::REPLAY: return "replay";
case NotificationType::STREAM: return "stream";
case NotificationType::SCREENSHOT: return "screenshot";
case NotificationType::NOTICE: return gsr_icon_path.c_str();
}
return nullptr;
}
@@ -1972,6 +1990,7 @@ namespace gsr {
}
case NotificationType::NONE:
case NotificationType::STREAM:
case NotificationType::NOTICE:
break;
}
show_notification(msg, notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, notification_type, capture_target);
@@ -2070,6 +2089,7 @@ namespace gsr {
const char *prefix = "";
switch(notification_type) {
case NotificationType::NONE:
case NotificationType::NOTICE:
break;
case NotificationType::SCREENSHOT:
prefix = "Failed to take a screenshot";
@@ -2167,7 +2187,7 @@ namespace gsr {
exit_code = WEXITSTATUS(status);
if(exit_code == 0) {
if(config.screenshot_config.save_screenshot_in_game_folder) {
if(config.screenshot_config.save_screenshot_in_game_folder && config.screenshot_config.save_screenshot_to_disk) {
save_video_in_current_game_directory(screenshot_filepath, NotificationType::SCREENSHOT);
} else if(config.screenshot_config.show_notifications) {
char msg[512];
@@ -2936,10 +2956,12 @@ namespace gsr {
update_upause_status();
if(led_indicator) {
if(!current_recording_config.replay_config.record_options.use_led_indicator)
led_indicator->set_led(true);
else if(config.record_config.record_options.use_led_indicator)
led_indicator->blink();
if(config.record_config.record_options.use_led_indicator) {
if(!current_recording_config.replay_config.record_options.use_led_indicator)
led_indicator->set_led(true);
else
led_indicator->blink();
}
}
}
@@ -2966,10 +2988,12 @@ namespace gsr {
update_upause_status();
if(led_indicator) {
if(!current_recording_config.streaming_config.record_options.use_led_indicator)
led_indicator->set_led(true);
else if(config.record_config.record_options.use_led_indicator)
led_indicator->blink();
if(config.record_config.record_options.use_led_indicator) {
if(!current_recording_config.streaming_config.record_options.use_led_indicator)
led_indicator->set_led(true);
else
led_indicator->blink();
}
}
}
@@ -3355,7 +3379,12 @@ namespace gsr {
}
// TODO: Validate input, fallback to valid values
const std::string output_file = config.screenshot_config.save_directory + "/Screenshot_" + get_date_str() + "." + config.screenshot_config.image_format; // TODO: Validate image format
std::string output_file;
if(config.screenshot_config.save_screenshot_to_disk)
output_file = config.screenshot_config.save_directory + "/Screenshot_" + get_date_str() + "." + config.screenshot_config.image_format; // TODO: Validate image format
else
output_file = "/tmp/gsr_ui_clipboard_screenshot." + config.screenshot_config.image_format;
const bool capture_cursor = force_type == ScreenshotForceType::NONE && config.screenshot_config.record_cursor;
std::vector<const char*> args = {
@@ -3394,6 +3423,8 @@ namespace gsr {
args.push_back(nullptr);
clipboard_file.set_current_file("", ClipboardFile::FileType::JPG);
screenshot_filepath = output_file;
gpu_screen_recorder_screenshot_process = exec_program(args.data(), nullptr);
if(gpu_screen_recorder_screenshot_process == -1) {

View File

@@ -221,6 +221,13 @@ namespace gsr {
return checkbox;
}
std::unique_ptr<CheckBox> ScreenshotSettingsPage::create_save_screenshot_to_disk() {
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Save screenshot to disk");
save_screenshot_to_disk_checkbox_ptr = checkbox.get();
checkbox->set_checked(true);
return checkbox;
}
std::unique_ptr<Widget> ScreenshotSettingsPage::create_notifications() {
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Show screenshot notifications");
checkbox->set_checked(true);
@@ -239,6 +246,7 @@ namespace gsr {
auto list = std::make_unique<List>(List::Orientation::VERTICAL);
list->add_widget(create_save_screenshot_in_game_folder());
list->add_widget(create_save_screenshot_to_clipboard());
list->add_widget(create_save_screenshot_to_disk());
return std::make_unique<Subsection>("General", std::move(list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
}
@@ -273,7 +281,7 @@ namespace gsr {
std::unique_ptr<Widget> ScreenshotSettingsPage::create_settings() {
auto page_list = std::make_unique<List>(List::Orientation::VERTICAL);
page_list->set_spacing(0.018f);
auto scrollable_page = std::make_unique<ScrollablePage>(content_page_ptr->get_inner_size() - mgl::vec2f(0.0f, page_list->get_size().y + 0.018f * get_theme().window_height));
auto scrollable_page = std::make_unique<ScrollablePage>(content_page_ptr->get_inner_size() - mgl::vec2f(0.0f, page_list->get_size().y));
settings_scrollable_page_ptr = scrollable_page.get();
page_list->add_widget(std::move(scrollable_page));
@@ -327,6 +335,7 @@ namespace gsr {
save_directory_button_ptr->set_text(config.screenshot_config.save_directory);
save_screenshot_in_game_folder_checkbox_ptr->set_checked(config.screenshot_config.save_screenshot_in_game_folder);
save_screenshot_to_clipboard_checkbox_ptr->set_checked(config.screenshot_config.save_screenshot_to_clipboard);
save_screenshot_to_disk_checkbox_ptr->set_checked(config.screenshot_config.save_screenshot_to_disk);
show_notification_checkbox_ptr->set_checked(config.screenshot_config.show_notifications);
led_indicator_checkbox_ptr->set_checked(config.screenshot_config.use_led_indicator);
@@ -348,6 +357,8 @@ namespace gsr {
}
void ScreenshotSettingsPage::save() {
Config prev_config = config;
config.screenshot_config.record_area_option = record_area_box_ptr->get_selected_id();
config.screenshot_config.image_width = atoi(image_width_entry_ptr->get_text().c_str());
config.screenshot_config.image_height = atoi(image_height_entry_ptr->get_text().c_str());
@@ -359,6 +370,7 @@ namespace gsr {
config.screenshot_config.save_directory = save_directory_button_ptr->get_text();
config.screenshot_config.save_screenshot_in_game_folder = save_screenshot_in_game_folder_checkbox_ptr->is_checked();
config.screenshot_config.save_screenshot_to_clipboard = save_screenshot_to_clipboard_checkbox_ptr->is_checked();
config.screenshot_config.save_screenshot_to_disk = save_screenshot_to_disk_checkbox_ptr->is_checked();
config.screenshot_config.show_notifications = show_notification_checkbox_ptr->is_checked();
config.screenshot_config.use_led_indicator = led_indicator_checkbox_ptr->is_checked();
config.screenshot_config.custom_script = create_custom_script_screenshot_entry_ptr->get_text();
@@ -380,5 +392,8 @@ namespace gsr {
}
save_config(config);
if(on_config_changed && config != prev_config)
on_config_changed();
}
}

View File

@@ -249,154 +249,156 @@ namespace gsr {
return ll;
}
std::unique_ptr<Widget> SettingsPage::create_webcam_section() {
auto ll = std::make_unique<List>(List::Orientation::VERTICAL);
std::unique_ptr<Widget> SettingsPage::create_webcam_location_widget() {
const float camera_screen_width = std::min(400.0f, (float)settings_scrollable_page_ptr->get_inner_size().x * 0.90f);
camera_screen_size = mgl::vec2f(camera_screen_width, camera_screen_width * 0.5625);
ll->add_widget(create_webcam_sources());
const float screen_border = 2.0f;
const mgl::vec2f screen_border_size(screen_border, screen_border);
screen_inner_size = mgl::vec2f(camera_screen_size - screen_border_size*2.0f);
auto body_list = std::make_unique<List>(List::Orientation::VERTICAL);
body_list->set_visible(false);
webcam_body_list_ptr = body_list.get();
{
const float camera_screen_width = std::min(400.0f, (float)settings_scrollable_page_ptr->get_inner_size().x * 0.90f);
camera_screen_size = mgl::vec2f(camera_screen_width, camera_screen_width * 0.5625);
const mgl::vec2f bounding_box_size(30.0f, 30.0f);
const float screen_border = 2.0f;
const mgl::vec2f screen_border_size(screen_border, screen_border);
screen_inner_size = mgl::vec2f(camera_screen_size - screen_border_size*2.0f);
auto camera_location_widget = std::make_unique<CustomRendererWidget>(camera_screen_size);
camera_location_widget->draw_handler = [this, screen_border_size, screen_border](mgl::Window &window, mgl::vec2f pos, mgl::vec2f size) {
if(!selected_camera.has_value())
return;
const mgl::vec2f bounding_box_size(30.0f, 30.0f);
pos = pos.floor();
size = size.floor();
const mgl::vec2i mouse_pos = window.get_mouse_position();
const mgl::vec2f webcam_box_min_size = clamp_keep_aspect_ratio(selected_camera->size.to_vec2f(), screen_inner_size * 0.2f);
auto camera_location_widget = std::make_unique<CustomRendererWidget>(camera_screen_size);
camera_location_widget->draw_handler = [this, screen_border_size, screen_border](mgl::Window &window, mgl::vec2f pos, mgl::vec2f size) {
if(!selected_camera.has_value())
return;
if(moving_webcam_box) {
webcam_box_pos = mouse_pos.to_vec2f() - screen_border_size - webcam_box_grab_offset - pos;
} else if(webcam_resize_corner == WebcamBoxResizeCorner::BOTTOM_RIGHT) {
const mgl::vec2f mouse_diff = mouse_pos.to_vec2f() - webcam_resize_start_pos;
webcam_box_size = webcam_box_size_resize_start + mouse_diff;
}
pos = pos.floor();
size = size.floor();
const mgl::vec2i mouse_pos = window.get_mouse_position();
const mgl::vec2f webcam_box_min_size = clamp_keep_aspect_ratio(selected_camera->size.to_vec2f(), screen_inner_size * 0.2f);
webcam_box_size = clamp_keep_aspect_ratio(selected_camera->size.to_vec2f(), webcam_box_size);
if(moving_webcam_box) {
webcam_box_pos = mouse_pos.to_vec2f() - screen_border_size - webcam_box_grab_offset - pos;
} else if(webcam_resize_corner == WebcamBoxResizeCorner::BOTTOM_RIGHT) {
const mgl::vec2f mouse_diff = mouse_pos.to_vec2f() - webcam_resize_start_pos;
webcam_box_size = webcam_box_size_resize_start + mouse_diff;
}
if(webcam_box_pos.x < 0.0f)
webcam_box_pos.x = 0.0f;
else if(webcam_box_pos.x + webcam_box_size.x > screen_inner_size.x)
webcam_box_pos.x = screen_inner_size.x - webcam_box_size.x;
webcam_box_size = clamp_keep_aspect_ratio(selected_camera->size.to_vec2f(), webcam_box_size);
if(webcam_box_pos.y < 0.0f)
webcam_box_pos.y = 0.0f;
else if(webcam_box_pos.y + webcam_box_size.y > screen_inner_size.y)
webcam_box_pos.y = screen_inner_size.y - webcam_box_size.y;
if(webcam_box_pos.x < 0.0f)
webcam_box_pos.x = 0.0f;
else if(webcam_box_pos.x + webcam_box_size.x > screen_inner_size.x)
webcam_box_pos.x = screen_inner_size.x - webcam_box_size.x;
if(webcam_box_size.x < webcam_box_min_size.x)
webcam_box_size.x = webcam_box_min_size.x;
else if(webcam_box_pos.x + webcam_box_size.x > screen_inner_size.x)
webcam_box_size.x = screen_inner_size.x - webcam_box_pos.x;
if(webcam_box_pos.y < 0.0f)
webcam_box_pos.y = 0.0f;
else if(webcam_box_pos.y + webcam_box_size.y > screen_inner_size.y)
webcam_box_pos.y = screen_inner_size.y - webcam_box_size.y;
//webcam_box_size = clamp_keep_aspect_ratio(selected_camera->size.to_vec2f(), webcam_box_size);
if(webcam_box_size.x < webcam_box_min_size.x)
webcam_box_size.x = webcam_box_min_size.x;
else if(webcam_box_pos.x + webcam_box_size.x > screen_inner_size.x)
webcam_box_size.x = screen_inner_size.x - webcam_box_pos.x;
if(webcam_box_size.y < webcam_box_min_size.y)
webcam_box_size.y = webcam_box_min_size.y;
else if(webcam_box_pos.y + webcam_box_size.y > screen_inner_size.y)
webcam_box_size.y = screen_inner_size.y - webcam_box_pos.y;
//webcam_box_size = clamp_keep_aspect_ratio(selected_camera->size.to_vec2f(), webcam_box_size);
webcam_box_size = clamp_keep_aspect_ratio(selected_camera->size.to_vec2f(), webcam_box_size);
if(webcam_box_size.y < webcam_box_min_size.y)
webcam_box_size.y = webcam_box_min_size.y;
else if(webcam_box_pos.y + webcam_box_size.y > screen_inner_size.y)
webcam_box_size.y = screen_inner_size.y - webcam_box_pos.y;
{
draw_rectangle_outline(window, pos, size, mgl::Color(255, 0, 0, 255), screen_border);
mgl::Text screen_text("Screen", get_theme().camera_setup_font);
screen_text.set_position((pos + size * 0.5f - screen_text.get_bounds().size * 0.5f).floor());
window.draw(screen_text);
}
webcam_box_size = clamp_keep_aspect_ratio(selected_camera->size.to_vec2f(), webcam_box_size);
{
webcam_box_drawn_size = clamp_keep_aspect_ratio(selected_camera->size.to_vec2f(), webcam_box_size);
webcam_box_drawn_pos = (pos + screen_border_size + webcam_box_pos).floor();
{
draw_rectangle_outline(window, pos, size, mgl::Color(255, 0, 0, 255), screen_border);
mgl::Text screen_text("Screen", get_theme().camera_setup_font);
screen_text.set_position((pos + size * 0.5f - screen_text.get_bounds().size * 0.5f).floor());
window.draw(screen_text);
}
draw_rectangle_outline(window, webcam_box_drawn_pos, webcam_box_drawn_size, mgl::Color(0, 255, 0, 255), screen_border);
{
webcam_box_drawn_size = clamp_keep_aspect_ratio(selected_camera->size.to_vec2f(), webcam_box_size);
webcam_box_drawn_pos = (pos + screen_border_size + webcam_box_pos).floor();
// mgl::Rectangle resize_area(webcam_box_drawn_pos + webcam_box_drawn_size - bounding_box_size*0.5f - screen_border_size*0.5f, bounding_box_size);
// resize_area.set_color(mgl::Color(0, 0, 255, 255));
// window.draw(resize_area);
draw_rectangle_outline(window, webcam_box_drawn_pos, webcam_box_drawn_size, mgl::Color(0, 255, 0, 255), screen_border);
mgl::Text webcam_text("Webcam", get_theme().camera_setup_font);
webcam_text.set_position((webcam_box_drawn_pos + webcam_box_drawn_size * 0.5f - webcam_text.get_bounds().size * 0.5f).floor());
window.draw(webcam_text);
}
};
// mgl::Rectangle resize_area(webcam_box_drawn_pos + webcam_box_drawn_size - bounding_box_size*0.5f - screen_border_size*0.5f, bounding_box_size);
// resize_area.set_color(mgl::Color(0, 0, 255, 255));
// window.draw(resize_area);
mgl::Text webcam_text("Webcam", get_theme().camera_setup_font);
webcam_text.set_position((webcam_box_drawn_pos + webcam_box_drawn_size * 0.5f - webcam_text.get_bounds().size * 0.5f).floor());
window.draw(webcam_text);
}
};
camera_location_widget->event_handler = [this, screen_border_size, bounding_box_size](mgl::Event &event, mgl::Window&, mgl::vec2f, mgl::vec2f) {
switch(event.type) {
case mgl::Event::MouseButtonPressed: {
if(event.mouse_button.button == mgl::Mouse::Left && webcam_resize_corner == WebcamBoxResizeCorner::NONE) {
const mgl::vec2f mouse_button_pos(event.mouse_button.x, event.mouse_button.y);
if(mgl::FloatRect(webcam_box_drawn_pos, webcam_box_drawn_size).contains(mouse_button_pos)) {
moving_webcam_box = true;
webcam_box_grab_offset = mouse_button_pos - webcam_box_drawn_pos;
} else {
moving_webcam_box = false;
}
} else if(event.mouse_button.button == mgl::Mouse::Right && !moving_webcam_box) {
const mgl::vec2f mouse_button_pos(event.mouse_button.x, event.mouse_button.y);
webcam_resize_start_pos = mouse_button_pos;
webcam_box_pos_resize_start = webcam_box_pos;
webcam_box_size_resize_start = webcam_box_size;
camera_location_widget->event_handler = [this, screen_border_size, bounding_box_size](mgl::Event &event, mgl::Window&, mgl::vec2f, mgl::vec2f) {
switch(event.type) {
case mgl::Event::MouseButtonPressed: {
if(event.mouse_button.button == mgl::Mouse::Left && webcam_resize_corner == WebcamBoxResizeCorner::NONE) {
const mgl::vec2f mouse_button_pos(event.mouse_button.x, event.mouse_button.y);
if(mgl::FloatRect(webcam_box_drawn_pos, webcam_box_drawn_size).contains(mouse_button_pos)) {
moving_webcam_box = true;
webcam_box_grab_offset = mouse_button_pos - webcam_box_drawn_pos;
/*if(mgl::FloatRect(webcam_box_drawn_pos - bounding_box_size*0.5f, bounding_box_size).contains(mouse_button_pos)) {
webcam_resize_corner = WebcamBoxResizeCorner::TOP_LEFT;
fprintf(stderr, "top left\n");
} else if(mgl::FloatRect(webcam_box_drawn_pos + mgl::vec2f(webcam_box_drawn_size.x, 0.0f) - bounding_box_size*0.5f, bounding_box_size).contains(mouse_button_pos)) {
webcam_resize_corner = WebcamBoxResizeCorner::TOP_RIGHT;
fprintf(stderr, "top right\n");
} else if(mgl::FloatRect(webcam_box_drawn_pos + mgl::vec2f(0.0f, webcam_box_drawn_size.y) - bounding_box_size*0.5f, bounding_box_size).contains(mouse_button_pos)) {
webcam_resize_corner = WebcamBoxResizeCorner::BOTTOM_LEFT;
fprintf(stderr, "bottom left\n");
} else */if(mgl::FloatRect(webcam_box_drawn_pos + webcam_box_drawn_size - bounding_box_size*0.5f - screen_border_size*0.5f, bounding_box_size).contains(mouse_button_pos)) {
webcam_resize_corner = WebcamBoxResizeCorner::BOTTOM_RIGHT;
} else {
webcam_resize_corner = WebcamBoxResizeCorner::NONE;
}
}
break;
}
case mgl::Event::MouseButtonReleased: {
if(event.mouse_button.button == mgl::Mouse::Left && webcam_resize_corner == WebcamBoxResizeCorner::NONE) {
} else {
moving_webcam_box = false;
} else if(event.mouse_button.button == mgl::Mouse::Right && !moving_webcam_box) {
}
} else if(event.mouse_button.button == mgl::Mouse::Right && !moving_webcam_box) {
const mgl::vec2f mouse_button_pos(event.mouse_button.x, event.mouse_button.y);
webcam_resize_start_pos = mouse_button_pos;
webcam_box_pos_resize_start = webcam_box_pos;
webcam_box_size_resize_start = webcam_box_size;
webcam_box_grab_offset = mouse_button_pos - webcam_box_drawn_pos;
/*if(mgl::FloatRect(webcam_box_drawn_pos - bounding_box_size*0.5f, bounding_box_size).contains(mouse_button_pos)) {
webcam_resize_corner = WebcamBoxResizeCorner::TOP_LEFT;
fprintf(stderr, "top left\n");
} else if(mgl::FloatRect(webcam_box_drawn_pos + mgl::vec2f(webcam_box_drawn_size.x, 0.0f) - bounding_box_size*0.5f, bounding_box_size).contains(mouse_button_pos)) {
webcam_resize_corner = WebcamBoxResizeCorner::TOP_RIGHT;
fprintf(stderr, "top right\n");
} else if(mgl::FloatRect(webcam_box_drawn_pos + mgl::vec2f(0.0f, webcam_box_drawn_size.y) - bounding_box_size*0.5f, bounding_box_size).contains(mouse_button_pos)) {
webcam_resize_corner = WebcamBoxResizeCorner::BOTTOM_LEFT;
fprintf(stderr, "bottom left\n");
} else */if(mgl::FloatRect(webcam_box_drawn_pos + webcam_box_drawn_size - bounding_box_size*0.5f - screen_border_size*0.5f, bounding_box_size).contains(mouse_button_pos)) {
webcam_resize_corner = WebcamBoxResizeCorner::BOTTOM_RIGHT;
} else {
webcam_resize_corner = WebcamBoxResizeCorner::NONE;
}
break;
}
default: {
break;
}
break;
}
return true;
};
body_list->add_widget(std::move(camera_location_widget));
}
case mgl::Event::MouseButtonReleased: {
if(event.mouse_button.button == mgl::Mouse::Left && webcam_resize_corner == WebcamBoxResizeCorner::NONE) {
moving_webcam_box = false;
} else if(event.mouse_button.button == mgl::Mouse::Right && !moving_webcam_box) {
webcam_resize_corner = WebcamBoxResizeCorner::NONE;
}
break;
}
default: {
break;
}
}
return true;
};
return camera_location_widget;
}
std::unique_ptr<CheckBox> SettingsPage::create_flip_camera_checkbox() {
auto flip_camera_horizontally_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Flip camera horizontally");
flip_camera_horizontally_checkbox_ptr = flip_camera_horizontally_checkbox.get();
return flip_camera_horizontally_checkbox;
}
std::unique_ptr<List> SettingsPage::create_webcam_body() {
auto body_list = std::make_unique<List>(List::Orientation::VERTICAL);
webcam_body_list_ptr = body_list.get();
body_list->set_visible(false);
body_list->add_widget(create_webcam_location_widget());
body_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "* Right click in the bottom right corner to resize the webcam", get_color_theme().text_color));
{
auto flip_camera_horizontally_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Flip camera horizontally");
flip_camera_horizontally_checkbox_ptr = flip_camera_horizontally_checkbox.get();
body_list->add_widget(std::move(flip_camera_horizontally_checkbox));
}
body_list->add_widget(create_flip_camera_checkbox());
body_list->add_widget(create_webcam_video_format());
ll->add_widget(std::move(body_list));
return body_list;
}
std::unique_ptr<Widget> SettingsPage::create_webcam_section() {
auto ll = std::make_unique<List>(List::Orientation::VERTICAL);
ll->add_widget(create_webcam_sources());
ll->add_widget(create_webcam_body());
return std::make_unique<Subsection>("Webcam", std::move(ll), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
}

View File

@@ -3,6 +3,7 @@
#include "../include/gui/Utils.hpp"
#include "../include/Process.hpp"
#include "../include/Rpc.hpp"
#include "../include/Theme.hpp"
#include <signal.h>
#include <string.h>
@@ -164,9 +165,10 @@ static void set_display_server_environment_variables() {
static void usage() {
printf("usage: gsr-ui [action]\n");
printf("OPTIONS:\n");
printf(" action The launch action. Should be either \"launch-show\", \"launch-hide\" or \"launch-daemon\". Optional, defaults to \"launch-hide\".\n");
printf(" action The launch action. Should be either \"launch-show\", \"launch-hide\", \"launch-hide-announce\" or \"launch-daemon\". Optional, defaults to \"launch-hide\".\n");
printf(" If \"launch-show\" is used then the program starts and the UI is immediately opened and can be shown/hidden with Alt+Z.\n");
printf(" If \"launch-hide\" is used then the program starts but the UI is not opened until Alt+Z is pressed. The UI will be opened if the program is already running in another process.\n");
printf(" If \"launch-hide-announce\" is used then the program starts but the UI is not opened until Alt+Z is pressed and a notification tells the user to press Alt+Z. The UI will be opened if the program is already running in another process.\n");
printf(" If \"launch-daemon\" is used then the program starts but the UI is not opened until Alt+Z is pressed. The UI will not be opened if the program is already running in another process.\n");
exit(1);
}
@@ -174,6 +176,7 @@ static void usage() {
enum class LaunchAction {
LAUNCH_SHOW,
LAUNCH_HIDE,
LAUNCH_HIDE_ANNOUNCE,
LAUNCH_DAEMON
};
@@ -197,10 +200,12 @@ int main(int argc, char **argv) {
launch_action = LaunchAction::LAUNCH_SHOW;
} else if(strcmp(launch_action_opt, "launch-hide") == 0) {
launch_action = LaunchAction::LAUNCH_HIDE;
} else if(strcmp(launch_action_opt, "launch-hide-announce") == 0) {
launch_action = LaunchAction::LAUNCH_HIDE_ANNOUNCE;
} else if(strcmp(launch_action_opt, "launch-daemon") == 0) {
launch_action = LaunchAction::LAUNCH_DAEMON;
} else {
printf("error: invalid action \"%s\", expected \"launch-show\", \"launch-hide\" or \"launch-daemon\".\n", launch_action_opt);
printf("error: invalid action \"%s\", expected \"launch-show\", \"launch-hide\", \"launch-hide-announce\" or \"launch-daemon\".\n", launch_action_opt);
usage();
}
} else {
@@ -209,6 +214,19 @@ int main(int argc, char **argv) {
set_display_server_environment_variables();
std::string resources_path;
if(access("sibs-build/linux_x86_64/debug/gsr-ui", F_OK) == 0) {
resources_path = "./";
} else {
#ifdef GSR_UI_RESOURCES_PATH
resources_path = GSR_UI_RESOURCES_PATH "/";
#else
resources_path = "/usr/share/gsr-ui/";
#endif
}
const std::string gsr_icon_path = resources_path + "images/gpu_screen_recorder_logo.png";
auto rpc = std::make_unique<gsr::Rpc>();
const gsr::RpcOpenResult rpc_open_result = rpc->open("gsr-ui");
@@ -220,7 +238,10 @@ int main(int argc, char **argv) {
fprintf(stderr, "Error: another instance of gsr-ui is already running, opening that one instead\n");
} else {
fprintf(stderr, "Error: failed to send command to running gsr-ui instance, user will have to open the UI manually with Alt+Z\n");
const char *args[] = { "gsr-notify", "--text", "Another instance of GPU Screen Recorder UI is already running.\nPress Alt+Z to open the UI.", "--timeout", "5.0", "--icon-color", "ff0000", "--bg-color", "ff0000", nullptr };
const char *args[] = {
"gsr-notify", "--text", "Another instance of GPU Screen Recorder UI is already running.\nPress Alt+Z to open the UI.", "--timeout", "5.0",
"--icon-color", "ffffff", "--icon", gsr_icon_path.c_str(), "--bg-color", "ff0000", nullptr
};
gsr::exec_program_daemonized(args);
}
return 1;
@@ -230,7 +251,10 @@ int main(int argc, char **argv) {
fprintf(stderr, "Error: Failed to create rpc\n");
if(gsr::pidof("gpu-screen-recorder", -1) != -1) {
const char *args[] = { "gsr-notify", "--text", "GPU Screen Recorder is already running in another process.\nPlease close it before using GPU Screen Recorder UI.", "--timeout", "5.0", "--icon-color", "ff0000", "--bg-color", "ff0000", nullptr };
const char *args[] = {
"gsr-notify", "--text", "GPU Screen Recorder is already running in another process.\nPlease close it before using GPU Screen Recorder UI.",
"--timeout", "5.0", "--icon-color", "ffffff", "--icon", gsr_icon_path.c_str(), "--bg-color", "ff0000", nullptr
};
gsr::exec_program_daemonized(args);
}
@@ -284,17 +308,6 @@ int main(int argc, char **argv) {
gsr::SupportedCaptureOptions capture_options = gsr::get_supported_capture_options(gsr_info);
std::string resources_path;
if(access("sibs-build/linux_x86_64/debug/gsr-ui", F_OK) == 0) {
resources_path = "./";
} else {
#ifdef GSR_UI_RESOURCES_PATH
resources_path = GSR_UI_RESOURCES_PATH "/";
#else
resources_path = "/usr/share/gsr-ui/";
#endif
}
mgl_context *context = mgl_get_context();
egl_functions egl_funcs;
@@ -313,6 +326,8 @@ int main(int argc, char **argv) {
auto overlay = std::make_unique<gsr::Overlay>(resources_path, std::move(gsr_info), std::move(capture_options), egl_funcs);
if(launch_action == LaunchAction::LAUNCH_SHOW)
overlay->show();
else if(launch_action == LaunchAction::LAUNCH_HIDE_ANNOUNCE)
overlay->show_notification("Press Alt+Z to open the GPU Screen Recorder UI", 5.0, mgl::Color(255, 255, 255), gsr::get_color_theme().tint_color, gsr::NotificationType::NOTICE, nullptr, gsr::NotificationLevel::ERROR);
rpc_add_commands(rpc.get(), overlay.get());

View File

@@ -243,17 +243,6 @@ static void keyboard_event_process_input_event_data(keyboard_event *self, event_
fprintf(stderr, "Error: failed to write event data to virtual keyboard for exclusively grabbed device\n");
}
if(event.type == EV_LED) {
write(fd, &event, sizeof(event));
const struct input_event syn_event = {
.type = EV_SYN,
.code = 0,
.value = 0
};
write(fd, &syn_event, sizeof(syn_event));
}
if(!extra_data->is_possibly_non_keyboard_device)
return;