diff --git a/README.md b/README.md index 4463f79..7a20587 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,8 @@ These are the dependencies needed to build GPU Screen Recorder UI: * libdrm * libdbus * wayland (wayland-client, wayland-egl, wayland-scanner) -* setcap (libcap) +* libcap +* libpango (pangoft2) ## Runtime dependencies There are also additional dependencies needed at runtime: @@ -52,7 +53,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 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`.\ +This software is licensed under GPL-3.0-only, see the LICENSE file for more information. `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`. diff --git a/TODO b/TODO index 8aa6a46..8edcc8e 100644 --- a/TODO +++ b/TODO @@ -129,8 +129,6 @@ If CursorTrackerWayland fails then fallback to getting focused monitor by window Maybe automatically switch to recording with the device that controls the monitor. In that case also add all monitors available to capture in the capture list and automatically choose the gpu that controls the monitor. -Support cjk font. Use fc-match to find the location of the font. This also works in flatpak, in which case the fonts are in /run/host/..., where it lists system fonts. - Keyboard layout is incorrect on wayland when using kde plasma keyboard settings to setup multiple keyboards, for example when changing to french. Text input is correct, but hotkey is incorrect. Need to use "setxkbmap fr" as well. @@ -164,8 +162,6 @@ Show message that replay/streaming has to be restarted if recording settings are Support vector graphics. Maybe support svg, rendering it to a texture for better performance. -Support freetype for text rendering. Maybe load freetype as runtime (with dlopen) and use that when available and fallback to stb_freetype if not available. - Show .webm container option. It's currently chosen automatically if vp8/vp9 is chosen. The available containers should automatically switch depending on the video codec. In settings show audio levels for each audio. Maybe show audio level image beside the audio name in the dropdown box and switch to a different image (have 3-4 different images for each level) depending on the volume. @@ -260,3 +256,7 @@ Add simple video cutting in the ui. Keep replay turned on when opening a fullscreen application and alt-tabbing. Only stop replay when closing the application (when closing all fullscreen applications). When alt-tabbing check if the previously fullscreen window still exists. + +Show vulkan codec options. + +Use game information to save video under the game title if available, fallback to window title. diff --git a/depends/mglpp b/depends/mglpp index f69b0d3..05ddef2 160000 --- a/depends/mglpp +++ b/depends/mglpp @@ -1 +1 @@ -Subproject commit f69b0d3ee0f6278974470f7f1ff0abdd23398ffe +Subproject commit 05ddef275f9fd8ccb848cd15a4f62e8db61c8d13 diff --git a/fonts/NotoSans-Bold.ttf b/fonts/NotoSans-Bold.ttf deleted file mode 100644 index 785ef8a..0000000 Binary files a/fonts/NotoSans-Bold.ttf and /dev/null differ diff --git a/fonts/NotoSans-Regular.ttf b/fonts/NotoSans-Regular.ttf deleted file mode 100644 index bdc1ffa..0000000 Binary files a/fonts/NotoSans-Regular.ttf and /dev/null differ diff --git a/include/Overlay.hpp b/include/Overlay.hpp index eeda6c7..3599d84 100644 --- a/include/Overlay.hpp +++ b/include/Overlay.hpp @@ -114,7 +114,7 @@ namespace gsr { void handle_keyboard_mapping_event(); void on_event(mgl::Event &event); - void recreate_global_hotkeys(const char *hotkey_option); + void recreate_global_hotkeys(std::string_view hotkey_option); void update_led_indicator_after_settings_change(); void recreate_frontpage_ui_components(); void xi_setup(); @@ -255,6 +255,11 @@ namespace gsr { XEvent x11_xev; Atom net_active_window_atom; bool update_focused_window = true; + std::vector game_windows; + double event_current_time_seconds = 0.0; + double gamescope_running_last_checked_seconds = 0.0; + bool is_gamescope_running = false; + bool is_game_running = false; struct wl_display *wayland_dpy = nullptr; diff --git a/include/Theme.hpp b/include/Theme.hpp index 7760d00..c404484 100644 --- a/include/Theme.hpp +++ b/include/Theme.hpp @@ -2,7 +2,6 @@ #include #include -#include #include #include @@ -19,12 +18,10 @@ namespace gsr { float window_width = 0.0f; float window_height = 0.0f; - mgl::MemoryMappedFile body_font_file; - mgl::MemoryMappedFile title_font_file; - mgl::Font body_font; - mgl::Font title_font; - mgl::Font top_bar_font; - mgl::Font camera_setup_font; + std::string body_font_desc; + std::string title_font_desc; + std::string top_bar_font_desc; + std::string camera_setup_font_desc; mgl::Texture combobox_arrow_texture; mgl::Texture settings_texture; diff --git a/include/Translation.hpp b/include/Translation.hpp index 5128616..5913592 100644 --- a/include/Translation.hpp +++ b/include/Translation.hpp @@ -8,8 +8,8 @@ namespace gsr { public: static Translation& instance(); void init(const char* translations_directory, const char* initial_language = nullptr); - bool load_language(const char* lang); - bool is_language_supported(const char* lang); + bool load_language(std::string_view lang); + bool is_language_supported(std::string_view lang); bool plural_numbers_are_complex(); const char* translate(const char* key); diff --git a/include/gui/Button.hpp b/include/gui/Button.hpp index f412521..9968044 100644 --- a/include/gui/Button.hpp +++ b/include/gui/Button.hpp @@ -12,7 +12,7 @@ namespace gsr { public: // If width is 0 then the width of the text is used instead (with padding). // If height is 0 then the height of the text is used instead (with padding). - Button(mgl::Font *font, const char *text, mgl::vec2f size, mgl::Color bg_color); + Button(const char *font_desc, const char *text, mgl::vec2f size, mgl::Color bg_color); Button(const Button&) = delete; Button& operator=(const Button&) = delete; @@ -25,8 +25,8 @@ namespace gsr { void set_bg_hover_color(mgl::Color color); void set_icon(mgl::Texture *texture); - const std::string& get_text() const; - void set_text(std::string str); + std::string_view get_text() const; + void set_text(std::string_view str); std::function on_click; private: diff --git a/include/gui/CheckBox.hpp b/include/gui/CheckBox.hpp index 0c86c0a..d2dc366 100644 --- a/include/gui/CheckBox.hpp +++ b/include/gui/CheckBox.hpp @@ -11,7 +11,7 @@ namespace gsr { class CheckBox : public Widget { public: - CheckBox(mgl::Font *font, const char *text); + CheckBox(const char *font_desc, const char *text); CheckBox(const CheckBox&) = delete; CheckBox& operator=(const CheckBox&) = delete; diff --git a/include/gui/ComboBox.hpp b/include/gui/ComboBox.hpp index 6c90b81..9cc335c 100644 --- a/include/gui/ComboBox.hpp +++ b/include/gui/ComboBox.hpp @@ -11,24 +11,24 @@ namespace gsr { class ComboBox : public Widget { public: - ComboBox(mgl::Font *font); + ComboBox(const char *font_desc); ComboBox(const ComboBox&) = delete; ComboBox& operator=(const ComboBox&) = delete; bool on_event(mgl::Event &event, mgl::Window &window, mgl::vec2f offset) override; void draw(mgl::Window &window, mgl::vec2f offset) override; - void add_item(const std::string &text, const std::string &id, bool allow_duplicate = true); + void add_item(std::string_view text, const std::string &id, bool allow_duplicate = true); void clear_items(); // The item can only be selected if it's enabled - void set_selected_item(const std::string &id, bool trigger_event = true, bool trigger_event_even_if_selection_not_changed = true); - void set_item_enabled(const std::string &id, bool enabled); - const std::string& get_selected_id() const; + void set_selected_item(std::string_view id, bool trigger_event = true, bool trigger_event_even_if_selection_not_changed = true); + void set_item_enabled(std::string_view id, bool enabled); + std::string_view get_selected_id() const; mgl::vec2f get_size() override; - std::function on_selection_changed; + std::function on_selection_changed; private: void draw_selected(mgl::Window &window, mgl::vec2f draw_pos); void draw_unselected(mgl::Window &window, mgl::vec2f draw_pos); @@ -44,7 +44,8 @@ namespace gsr { }; mgl::vec2f max_size; - mgl::Font *font; + std::string font_desc; + int font_size = 0; std::vector items; mgl::Sprite dropdown_arrow; bool dirty = true; diff --git a/include/gui/DropdownButton.hpp b/include/gui/DropdownButton.hpp index f613d86..ee81291 100644 --- a/include/gui/DropdownButton.hpp +++ b/include/gui/DropdownButton.hpp @@ -10,7 +10,7 @@ namespace gsr { class DropdownButton : public Widget { public: - DropdownButton(mgl::Font *title_font, mgl::Font *description_font, const char *title, const char *description, mgl::Texture *icon_texture, mgl::vec2f size); + DropdownButton(const char *title_font_desc, const char *description_font_desc, const char *title, const char *description, mgl::Texture *icon_texture, mgl::vec2f size); DropdownButton(const DropdownButton&) = delete; DropdownButton& operator=(const DropdownButton&) = delete; @@ -18,10 +18,10 @@ namespace gsr { void draw(mgl::Window &window, mgl::vec2f offset) override; void add_item(const std::string &text, const std::string &id, const std::string &description = ""); - void set_item_label(const std::string &id, const std::string &new_label); - void set_item_icon(const std::string &id, mgl::Texture *texture); - void set_item_description(const std::string &id, const std::string &new_description); - void set_item_enabled(const std::string &id, bool enabled); + void set_item_label(std::string_view id, const std::string &new_label); + void set_item_icon(std::string_view id, mgl::Texture *texture); + void set_item_description(std::string_view id, const std::string &new_description); + void set_item_enabled(std::string_view id, bool enabled); void set_description(std::string description_text); void set_activated(bool activated); @@ -41,8 +41,8 @@ namespace gsr { }; std::vector items; - mgl::Font *title_font; - mgl::Font *description_font; + std::string title_font_desc; + std::string description_font_desc; mgl::vec2f size; bool mouse_inside = false; bool show_dropdown = false; diff --git a/include/gui/Entry.hpp b/include/gui/Entry.hpp index 6960da8..47ca672 100644 --- a/include/gui/Entry.hpp +++ b/include/gui/Entry.hpp @@ -4,32 +4,16 @@ #include #include -#include +#include +#include #include namespace gsr { class Entry; - enum class EntryValidateHandlerResult { - DENY, - ALLOW, - REPLACED - }; - using EntryValidateHandler = std::function; - - struct CaretIndexPos { - int index; - mgl::vec2f pos; - }; - class Entry : public Widget { public: - enum class Direction { - LEFT, - RIGHT - }; - - Entry(mgl::Font *font, const char *text, float max_width); + Entry(const char *font_desc, const char *text, float max_width); Entry(const Entry&) = delete; Entry& operator=(const Entry&) = delete; @@ -38,44 +22,18 @@ namespace gsr { mgl::vec2f get_size() override; - EntryValidateHandlerResult set_text(const std::string &str); - std::string get_text() const; + void set_text(std::string_view str); + std::string_view get_text() const; void set_masked(bool masked); bool is_masked() const; - // Return false to specify that the string should not be accepted. This reverts the string back to its previous value. - // The input can be changed by changing the input parameter and returning true. - EntryValidateHandler validate_handler; + void set_number_mode(bool enabled, int min_val, int max_val); - std::function on_changed; + std::function on_changed; private: - // Also updates the cursor position - void replace_text(size_t index, size_t size, const std::u32string &replacement); - void move_caret_word(Direction direction, size_t max_codepoints); - EntryValidateHandlerResult set_text_internal(std::u32string str); - void draw_caret(mgl::Window &window, mgl::vec2f draw_pos, mgl::vec2f caret_size); - void draw_caret_selection(mgl::Window &window, mgl::vec2f draw_pos, mgl::vec2f caret_size); - CaretIndexPos find_closest_caret_index_by_position(mgl::vec2f position); - private: - struct Caret { - float offset_x = 0.0f; - int index = 0; - }; - mgl::Rectangle background; - mgl::Text32 text; - mgl::Text32 masked_text; - float max_width; - bool selected = false; - bool selecting_text = false; - bool selecting_with_keyboard = false; - bool show_selection = false; - bool masked = false; - Caret caret; - Caret selection_start_caret; - float text_overflow = 0.0f; + mgl::TextEdit text_edit; + float max_width = 0.0f; }; - - EntryValidateHandler create_entry_validator_integer_in_range(int min, int max); -} \ No newline at end of file +} diff --git a/include/gui/FileChooser.hpp b/include/gui/FileChooser.hpp index dbe49bb..2a620e9 100644 --- a/include/gui/FileChooser.hpp +++ b/include/gui/FileChooser.hpp @@ -29,7 +29,7 @@ namespace gsr { mgl::vec2f get_inner_size() override; void set_size(mgl::vec2f size); private: - void set_current_directory(const char *directory); + void set_current_directory(std::string_view directory); private: struct Folder { mgl::Text text; @@ -48,7 +48,7 @@ namespace gsr { class FileChooser : public Widget { public: - FileChooser(const char *start_directory, mgl::vec2f size); + FileChooser(std::string_view start_directory, mgl::vec2f size); FileChooser(const FileChooser&) = delete; FileChooser& operator=(const FileChooser&) = delete; @@ -58,10 +58,10 @@ namespace gsr { mgl::vec2f get_size() override; - void set_current_directory(const char *directory); - void open_subdirectory(const char *name); + void set_current_directory(std::string_view directory); + void open_subdirectory(std::string_view name); void open_parent_directory(); - const std::string& get_current_directory() const; + std::string_view get_current_directory() const; private: struct Folder { mgl::Text text; diff --git a/include/gui/GlobalSettingsPage.hpp b/include/gui/GlobalSettingsPage.hpp index bee8cec..b883f1d 100644 --- a/include/gui/GlobalSettingsPage.hpp +++ b/include/gui/GlobalSettingsPage.hpp @@ -49,9 +49,9 @@ namespace gsr { bool on_event(mgl::Event &event, mgl::Window &window, mgl::vec2f offset) override; std::function on_startup_changed; - std::function on_click_exit_program_button; - std::function on_keyboard_hotkey_changed; - std::function on_joystick_hotkey_changed; + std::function on_click_exit_program_button; + std::function on_keyboard_hotkey_changed; + std::function on_joystick_hotkey_changed; std::function on_page_closed; private: void load_hotkeys(); diff --git a/include/gui/Label.hpp b/include/gui/Label.hpp index f9045e0..c7ec4cf 100644 --- a/include/gui/Label.hpp +++ b/include/gui/Label.hpp @@ -8,8 +8,7 @@ namespace gsr { class Label : public Widget { public: - // TODO: Allow specifying max width, at which either a line-break should occur or elipses should show - Label(mgl::Font *font, const char *text, mgl::Color color); + Label(const char *font_desc, const char *text, mgl::Color color); Label(const Label&) = delete; Label& operator=(const Label&) = delete; @@ -18,8 +17,14 @@ namespace gsr { mgl::vec2f get_size() override; - void set_text(std::string str); - const std::string& get_text() const; + void set_text(std::string_view str); + std::string_view get_text() const; + + // Set to 0 to disable + void set_wrap_width(int width); + + // Set to 0 to disable + void set_max_rows(int max_rows); private: mgl::Text text; }; diff --git a/include/gui/RadioButton.hpp b/include/gui/RadioButton.hpp index e319aa0..085faf5 100644 --- a/include/gui/RadioButton.hpp +++ b/include/gui/RadioButton.hpp @@ -14,7 +14,7 @@ namespace gsr { HORIZONTAL }; - RadioButton(mgl::Font *font, Orientation orientation); + RadioButton(const char *font_desc, Orientation orientation); RadioButton(const RadioButton&) = delete; RadioButton& operator=(const RadioButton&) = delete; @@ -22,14 +22,14 @@ namespace gsr { void draw(mgl::Window &window, mgl::vec2f offset) override; void add_item(const std::string &text, const std::string &id); - void set_selected_item(const std::string &id, bool trigger_event = true, bool trigger_event_even_if_selection_not_changed = true); - const std::string& get_selected_id() const; - const std::string& get_selected_text() const; + void set_selected_item(std::string_view id, bool trigger_event = true, bool trigger_event_even_if_selection_not_changed = true); + std::string_view get_selected_id() const; + std::string_view get_selected_text() const; mgl::vec2f get_size() override; // Return false to revert the change - std::function on_selection_changed; + std::function on_selection_changed; private: void update_if_dirty(); private: @@ -38,7 +38,7 @@ namespace gsr { std::string id; }; - mgl::Font *font; + std::string font_desc; Orientation orientation; std::vector items; size_t selected_item = 0; diff --git a/include/gui/SettingsPage.hpp b/include/gui/SettingsPage.hpp index fcb34e5..2acb45e 100644 --- a/include/gui/SettingsPage.hpp +++ b/include/gui/SettingsPage.hpp @@ -125,7 +125,7 @@ namespace gsr { std::unique_ptr create_save_replay_in_game_folder(); std::unique_ptr create_restart_replay_on_save(); std::unique_ptr