diff --git a/depends/mglpp b/depends/mglpp index cdd4014..f69b0d3 160000 --- a/depends/mglpp +++ b/depends/mglpp @@ -1 +1 @@ -Subproject commit cdd401478d8e70a895e06415e95c077f3fdd0ba5 +Subproject commit f69b0d3ee0f6278974470f7f1ff0abdd23398ffe diff --git a/gpu-screen-recorder.desktop b/gpu-screen-recorder.desktop new file mode 100644 index 0000000..078911a --- /dev/null +++ b/gpu-screen-recorder.desktop @@ -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; diff --git a/icons/hicolor/128x128/apps/gpu-screen-recorder.png b/icons/hicolor/128x128/apps/gpu-screen-recorder.png new file mode 100644 index 0000000..f2b99a1 Binary files /dev/null and b/icons/hicolor/128x128/apps/gpu-screen-recorder.png differ diff --git a/icons/hicolor/32x32/apps/gpu-screen-recorder.png b/icons/hicolor/32x32/apps/gpu-screen-recorder.png new file mode 100644 index 0000000..431162b Binary files /dev/null and b/icons/hicolor/32x32/apps/gpu-screen-recorder.png differ diff --git a/icons/hicolor/64x64/apps/gpu-screen-recorder.png b/icons/hicolor/64x64/apps/gpu-screen-recorder.png new file mode 100644 index 0000000..f66332b Binary files /dev/null and b/icons/hicolor/64x64/apps/gpu-screen-recorder.png differ diff --git a/include/Overlay.hpp b/include/Overlay.hpp index 284dd70..e39765b 100644 --- a/include/Overlay.hpp +++ b/include/Overlay.hpp @@ -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(); @@ -171,6 +173,8 @@ namespace gsr { Config config; Config current_recording_config; + std::string gsr_icon_path; + bool visible = false; mgl::Texture window_texture_texture; diff --git a/meson.build b/meson.build index 584a35a..2dfbd96 100644 --- a/meson.build +++ b/meson.build @@ -64,6 +64,7 @@ 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']) @@ -112,6 +113,12 @@ executable( install_subdir('images', install_dir : gsr_ui_resources_path) install_subdir('fonts', install_dir : gsr_ui_resources_path) +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) + if get_option('systemd') == true install_data(files('extra/gpu-screen-recorder-ui.service'), install_dir : 'lib/systemd/user') endif diff --git a/src/Overlay.cpp b/src/Overlay.cpp index cb20682..dbf7aab 100644 --- a/src/Overlay.cpp +++ b/src/Overlay.cpp @@ -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,7 +521,7 @@ 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); } } @@ -735,7 +737,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 +776,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 +827,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 +836,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; } } @@ -1321,12 +1323,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); } }; @@ -1576,13 +1578,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 +1975,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 +2074,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"; diff --git a/src/main.cpp b/src/main.cpp index 24939ec..14d9185 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,6 +3,7 @@ #include "../include/gui/Utils.hpp" #include "../include/Process.hpp" #include "../include/Rpc.hpp" +#include "../include/Theme.hpp" #include #include @@ -174,6 +175,7 @@ static void usage() { enum class LaunchAction { LAUNCH_SHOW, LAUNCH_HIDE, + LAUNCH_HIDE_ANNOUNCE, LAUNCH_DAEMON }; @@ -197,6 +199,8 @@ 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 { @@ -209,6 +213,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(); const gsr::RpcOpenResult rpc_open_result = rpc->open("gsr-ui"); @@ -220,7 +237,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 +250,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 +307,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 +325,8 @@ int main(int argc, char **argv) { auto overlay = std::make_unique(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());