diff options
author | dec05eba <dec05eba@protonmail.com> | 2025-03-21 23:47:24 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2025-03-21 23:47:24 +0100 |
commit | 2ec59c6812ef2112dde2a7ce8c068d0c8155ed06 (patch) | |
tree | 67e217d1c507879362882ab4ddc59f6bfd30da18 | |
parent | a0d8af9d372ac3847cbae9dc9c647abf57227e3c (diff) |
Add alt+f2 to take a screenshot of a region
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | include/Config.hpp | 1 | ||||
-rw-r--r-- | include/Overlay.hpp | 3 | ||||
-rw-r--r-- | include/gui/GlobalSettingsPage.hpp | 3 | ||||
-rw-r--r-- | src/Config.cpp | 4 | ||||
-rw-r--r-- | src/Overlay.cpp | 31 | ||||
-rw-r--r-- | src/gui/GlobalSettingsPage.cpp | 26 | ||||
-rw-r--r-- | src/gui/SettingsPage.cpp | 2 | ||||
-rw-r--r-- | src/main.cpp | 5 | ||||
-rw-r--r-- | tools/gsr-ui-cli/main.c | 24 |
10 files changed, 81 insertions, 20 deletions
@@ -141,7 +141,7 @@ Allow using a hotkey such as printscreen or any other non-alphanumeric key witho Use x11 shm instead of XGetImage (https://stackoverflow.com/questions/43442675/how-to-use-xshmgetimage-and-xshmputimage). -Add a hotkey to record/stream/replay/screenshot region. +Add a hotkey to record/stream/replay region. Do xi grab for keys as well. Otherwise the ui cant be used for keyboard input if a program has grabbed the keyboard, and there could possibly be a game that grabs the keyboard as well. diff --git a/include/Config.hpp b/include/Config.hpp index 1e2e9cb..0e8e4eb 100644 --- a/include/Config.hpp +++ b/include/Config.hpp @@ -126,6 +126,7 @@ namespace gsr { bool show_screenshot_saved_notifications = true; std::string save_directory; ConfigHotkey take_screenshot_hotkey; + ConfigHotkey take_screenshot_region_hotkey; }; struct Config { diff --git a/include/Overlay.hpp b/include/Overlay.hpp index 5ed7f51..d7b8af1 100644 --- a/include/Overlay.hpp +++ b/include/Overlay.hpp @@ -59,6 +59,7 @@ namespace gsr { void toggle_replay(); void save_replay(); void take_screenshot(); + void take_screenshot_region(); void show_notification(const char *str, double timeout_seconds, mgl::Color icon_color, mgl::Color bg_color, NotificationType notification_type); bool is_open() const; bool should_exit(std::string &reason) const; @@ -111,7 +112,7 @@ namespace gsr { bool on_press_start_replay(bool disable_notification, bool finished_region_selection); void on_press_start_record(bool finished_region_selection); void on_press_start_stream(bool finished_region_selection); - void on_press_take_screenshot(bool finished_region_selection); + void on_press_take_screenshot(bool finished_region_selection, bool force_region_capture); bool update_compositor_texture(const Monitor &monitor); void force_window_on_top(); diff --git a/include/gui/GlobalSettingsPage.hpp b/include/gui/GlobalSettingsPage.hpp index c261ab6..5df5b9c 100644 --- a/include/gui/GlobalSettingsPage.hpp +++ b/include/gui/GlobalSettingsPage.hpp @@ -26,6 +26,7 @@ namespace gsr { RECORD_PAUSE_UNPAUSE, STREAM_START_STOP, TAKE_SCREENSHOT, + TAKE_SCREENSHOT_REGION, SHOW_HIDE }; @@ -58,6 +59,7 @@ namespace gsr { std::unique_ptr<List> create_record_hotkey_options(); std::unique_ptr<List> create_stream_hotkey_options(); std::unique_ptr<List> create_screenshot_hotkey_options(); + std::unique_ptr<List> create_screenshot_region_hotkey_options(); std::unique_ptr<List> create_hotkey_control_buttons(); std::unique_ptr<Subsection> create_keyboard_hotkey_subsection(ScrollablePage *parent_page); std::unique_ptr<Subsection> create_controller_hotkey_subsection(ScrollablePage *parent_page); @@ -91,6 +93,7 @@ namespace gsr { Button *pause_unpause_recording_button_ptr = nullptr; Button *start_stop_streaming_button_ptr = nullptr; Button *take_screenshot_button_ptr = nullptr; + Button *take_screenshot_region_button_ptr = nullptr; Button *show_hide_button_ptr = nullptr; ConfigHotkey configure_config_hotkey; diff --git a/src/Config.cpp b/src/Config.cpp index 734f827..6f33359 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -140,6 +140,7 @@ namespace gsr { replay_config.save_hotkey = {mgl::Keyboard::F10, HOTKEY_MOD_LALT}; screenshot_config.take_screenshot_hotkey = {mgl::Keyboard::F1, HOTKEY_MOD_LALT}; + screenshot_config.take_screenshot_region_hotkey = {mgl::Keyboard::F2, HOTKEY_MOD_LALT}; main_config.show_hide_hotkey = {mgl::Keyboard::Z, HOTKEY_MOD_LALT}; } @@ -262,7 +263,8 @@ namespace gsr { {"screenshot.save_screenshot_in_game_folder", &config.screenshot_config.save_screenshot_in_game_folder}, {"screenshot.show_screenshot_saved_notifications", &config.screenshot_config.show_screenshot_saved_notifications}, {"screenshot.save_directory", &config.screenshot_config.save_directory}, - {"screenshot.take_screenshot_hotkey", &config.screenshot_config.take_screenshot_hotkey} + {"screenshot.take_screenshot_hotkey", &config.screenshot_config.take_screenshot_hotkey}, + {"screenshot.take_screenshot_region_hotkey", &config.screenshot_config.take_screenshot_region_hotkey} }; } diff --git a/src/Overlay.cpp b/src/Overlay.cpp index 0be7375..dabeeaa 100644 --- a/src/Overlay.cpp +++ b/src/Overlay.cpp @@ -318,6 +318,13 @@ namespace gsr { fprintf(stderr, "pressed %s\n", id.c_str()); overlay->take_screenshot(); }); + + global_hotkeys->bind_key_press( + config_hotkey_to_hotkey(overlay->get_config().screenshot_config.take_screenshot_region_hotkey), + "take_screenshot_region", [overlay](const std::string &id) { + fprintf(stderr, "pressed %s\n", id.c_str()); + overlay->take_screenshot_region(); + }); } static std::unique_ptr<GlobalHotkeysLinux> register_linux_hotkeys(Overlay *overlay, GlobalHotkeysLinux::GrabType grab_type) { @@ -1311,7 +1318,11 @@ namespace gsr { } void Overlay::take_screenshot() { - on_press_take_screenshot(false); + on_press_take_screenshot(false, false); + } + + void Overlay::take_screenshot_region() { + on_press_take_screenshot(false, true); } static const char* notification_type_to_string(NotificationType notification_type) { @@ -2300,7 +2311,7 @@ namespace gsr { show_notification("Streaming has started", notification_timeout_seconds, get_color_theme().tint_color, get_color_theme().tint_color, NotificationType::STREAM); } - void Overlay::on_press_take_screenshot(bool finished_region_selection) { + void Overlay::on_press_take_screenshot(bool finished_region_selection, bool force_region_capture) { if(region_selector.is_started()) return; @@ -2309,18 +2320,20 @@ namespace gsr { return; } - if(!validate_capture_target(gsr_info, config.screenshot_config.record_area_option)) { + const bool region_capture = config.screenshot_config.record_area_option == "region" || force_region_capture; + const char *record_area_option = region_capture ? "region" : config.screenshot_config.record_area_option.c_str(); + if(!validate_capture_target(gsr_info, record_area_option)) { char err_msg[256]; - snprintf(err_msg, sizeof(err_msg), "Failed to take a screenshot, capture target \"%s\" is invalid. Please change capture target in settings", config.screenshot_config.record_area_option.c_str()); + snprintf(err_msg, sizeof(err_msg), "Failed to take a screenshot, capture target \"%s\" is invalid. Please change capture target in settings", record_area_option); show_notification(err_msg, notification_error_timeout_seconds, mgl::Color(255, 0, 0, 0), mgl::Color(255, 0, 0, 0), NotificationType::SCREENSHOT); return; } - if(config.screenshot_config.record_area_option == "region" && !finished_region_selection) { + if(region_capture && !finished_region_selection) { start_region_capture = true; - on_region_selected = [this]() { + on_region_selected = [this, force_region_capture]() { usleep(200 * 1000); // Hack: wait 0.2 seconds before taking a screenshot to allow user to move cursor away. TODO: Remove this - on_press_take_screenshot(true); + on_press_take_screenshot(true, force_region_capture); }; return; } @@ -2329,7 +2342,7 @@ namespace gsr { const std::string output_file = config.screenshot_config.save_directory + "/Screenshot_" + get_date_str() + "." + config.screenshot_config.image_format; // TODO: Validate image format std::vector<const char*> args = { - "gpu-screen-recorder", "-w", config.screenshot_config.record_area_option.c_str(), + "gpu-screen-recorder", "-w", record_area_option, "-cursor", config.screenshot_config.record_cursor ? "yes" : "no", "-v", "no", "-q", config.screenshot_config.image_quality.c_str(), @@ -2350,7 +2363,7 @@ namespace gsr { } char region_str[128]; - if(config.screenshot_config.record_area_option == "region") + if(region_capture) add_region_command(args, region_str, sizeof(region_str), region_selector); args.push_back(nullptr); diff --git a/src/gui/GlobalSettingsPage.cpp b/src/gui/GlobalSettingsPage.cpp index f8cdf20..defd710 100644 --- a/src/gui/GlobalSettingsPage.cpp +++ b/src/gui/GlobalSettingsPage.cpp @@ -300,6 +300,21 @@ namespace gsr { return list; } + std::unique_ptr<List> GlobalSettingsPage::create_screenshot_region_hotkey_options() { + auto list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER); + + list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Take a screenshot of a region:", get_color_theme().text_color)); + auto take_screenshot_region_button = std::make_unique<Button>(&get_theme().body_font, "", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120)); + take_screenshot_region_button_ptr = take_screenshot_region_button.get(); + list->add_widget(std::move(take_screenshot_region_button)); + + take_screenshot_region_button_ptr->on_click = [this] { + configure_hotkey_start(ConfigureHotkeyType::TAKE_SCREENSHOT_REGION); + }; + + return list; + } + std::unique_ptr<List> GlobalSettingsPage::create_hotkey_control_buttons() { auto list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER); @@ -311,6 +326,7 @@ namespace gsr { config.replay_config.start_stop_hotkey = {mgl::Keyboard::Unknown, 0}; config.replay_config.save_hotkey = {mgl::Keyboard::Unknown, 0}; config.screenshot_config.take_screenshot_hotkey = {mgl::Keyboard::Unknown, 0}; + config.screenshot_config.take_screenshot_region_hotkey = {mgl::Keyboard::Unknown, 0}; config.main_config.show_hide_hotkey = {mgl::Keyboard::Unknown, 0}; load_hotkeys(); overlay->rebind_all_keyboard_hotkeys(); @@ -351,6 +367,7 @@ namespace gsr { list_ptr->add_widget(create_record_hotkey_options()); list_ptr->add_widget(create_stream_hotkey_options()); list_ptr->add_widget(create_screenshot_hotkey_options()); + list_ptr->add_widget(create_screenshot_region_hotkey_options()); list_ptr->add_widget(create_hotkey_control_buttons()); return subsection; } @@ -470,6 +487,7 @@ namespace gsr { start_stop_streaming_button_ptr->set_text(config.streaming_config.start_stop_hotkey.to_string()); take_screenshot_button_ptr->set_text(config.screenshot_config.take_screenshot_hotkey.to_string()); + take_screenshot_region_button_ptr->set_text(config.screenshot_config.take_screenshot_region_hotkey.to_string()); show_hide_button_ptr->set_text(config.main_config.show_hide_hotkey.to_string()); } @@ -547,6 +565,8 @@ namespace gsr { return start_stop_streaming_button_ptr; case ConfigureHotkeyType::TAKE_SCREENSHOT: return take_screenshot_button_ptr; + case ConfigureHotkeyType::TAKE_SCREENSHOT_REGION: + return take_screenshot_region_button_ptr; case ConfigureHotkeyType::SHOW_HIDE: return show_hide_button_ptr; } @@ -569,6 +589,8 @@ namespace gsr { return &config.streaming_config.start_stop_hotkey; case ConfigureHotkeyType::TAKE_SCREENSHOT: return &config.screenshot_config.take_screenshot_hotkey; + case ConfigureHotkeyType::TAKE_SCREENSHOT_REGION: + return &config.screenshot_config.take_screenshot_region_hotkey; case ConfigureHotkeyType::SHOW_HIDE: return &config.main_config.show_hide_hotkey; } @@ -583,6 +605,7 @@ namespace gsr { &config.record_config.pause_unpause_hotkey, &config.streaming_config.start_stop_hotkey, &config.screenshot_config.take_screenshot_hotkey, + &config.screenshot_config.take_screenshot_region_hotkey, &config.main_config.show_hide_hotkey }; for(ConfigHotkey *config_hotkey : config_hotkeys) { @@ -622,6 +645,9 @@ namespace gsr { case ConfigureHotkeyType::TAKE_SCREENSHOT: hotkey_configure_action_name = "Take a screenshot"; break; + case ConfigureHotkeyType::TAKE_SCREENSHOT_REGION: + hotkey_configure_action_name = "Take a screenshot of a region"; + break; case ConfigureHotkeyType::SHOW_HIDE: hotkey_configure_action_name = "Show/hide UI"; break; diff --git a/src/gui/SettingsPage.cpp b/src/gui/SettingsPage.cpp index be09f54..79b4525 100644 --- a/src/gui/SettingsPage.cpp +++ b/src/gui/SettingsPage.cpp @@ -370,7 +370,7 @@ namespace gsr { std::unique_ptr<List> SettingsPage::create_video_bitrate() { auto video_bitrate_list = std::make_unique<List>(List::Orientation::VERTICAL); - video_bitrate_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Video bitrate (kbps):", get_color_theme().text_color)); + video_bitrate_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Video bitrate (Kbps):", get_color_theme().text_color)); video_bitrate_list->add_widget(create_video_bitrate_entry()); video_bitrate_list_ptr = video_bitrate_list.get(); return video_bitrate_list; diff --git a/src/main.cpp b/src/main.cpp index 169721e..7c10a6e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -78,6 +78,11 @@ static void rpc_add_commands(gsr::Rpc *rpc, gsr::Overlay *overlay) { fprintf(stderr, "rpc command executed: %s\n", name.c_str()); overlay->take_screenshot(); }); + + rpc->add_handler("take-screenshot-region", [overlay](const std::string &name) { + fprintf(stderr, "rpc command executed: %s\n", name.c_str()); + overlay->take_screenshot_region(); + }); } static bool is_gsr_ui_virtual_keyboard_running() { diff --git a/tools/gsr-ui-cli/main.c b/tools/gsr-ui-cli/main.c index 9f1eb03..c34888c 100644 --- a/tools/gsr-ui-cli/main.c +++ b/tools/gsr-ui-cli/main.c @@ -44,13 +44,22 @@ static void usage(void) { printf("Run commands on the running gsr-ui instance.\n"); printf("\n"); printf("COMMANDS:\n"); - printf(" toggle-show Show/hide the UI.\n"); - printf(" toggle-record Start/stop recording.\n"); - printf(" toggle-pause Pause/unpause recording. Only applies to regular recording.\n"); - printf(" toggle-stream Start/stop streaming.\n"); - printf(" toggle-replay Start/stop replay.\n"); - printf(" replay-save Save replay.\n"); - printf(" take-screenshot Take a screenshot.\n"); + printf(" toggle-show\n"); + printf(" Show/hide the UI.\n"); + printf(" toggle-record\n"); + printf(" Start/stop recording.\n"); + printf(" toggle-pause\n"); + printf(" Pause/unpause recording. Only applies to regular recording.\n"); + printf(" toggle-stream\n"); + printf(" Start/stop streaming.\n"); + printf(" toggle-replay\n"); + printf(" Start/stop replay.\n"); + printf(" replay-save\n"); + printf(" Save replay.\n"); + printf(" take-screenshot\n"); + printf(" Take a screenshot.\n"); + printf(" take-screenshot-region\n"); + printf(" Take a screenshot of a region.\n"); printf("\n"); printf("EXAMPLES:\n"); printf(" gsr-ui-cli toggle-show\n"); @@ -67,6 +76,7 @@ static bool is_valid_command(const char *command) { "toggle-replay", "replay-save", "take-screenshot", + "take-screenshot-region", NULL }; |