Add option to start replay on fullscreen

This commit is contained in:
dec05eba
2024-11-14 00:25:37 +01:00
parent 4ba1e814b7
commit d2f6b0738b
12 changed files with 218 additions and 41 deletions

6
TODO
View File

@@ -79,3 +79,9 @@ Add profile option. Convert view to profile, add an option at the bottom that sa
Verify monitor/audio when starting recording. Give an error if the options are no longer valid. Verify monitor/audio when starting recording. Give an error if the options are no longer valid.
Add option to record focused monitor. This is less error prone when plugging in monitors, etc. Add option to record focused monitor. This is less error prone when plugging in monitors, etc.
Get focused window when opening gsr-ui and pass that to the save replay script, to ignore gsr-ui when getting game name.
gsr ui window has _NET_WM_STATE _NET_WM_STATE_ABOVE, not _NET_WM_STATE_FULLSCREEN
For replay on fullscreen detect focused fullscreen window by checking if the window size is the same as the monitor size instead of _NET_WM_STATE_FULLSCREEN.

View File

@@ -81,7 +81,7 @@ namespace gsr {
struct ReplayConfig { struct ReplayConfig {
RecordOptions record_options; RecordOptions record_options;
bool start_replay_automatically = false; std::string turn_on_replay_automatically_mode = "dont_turn_on_automatically";
bool save_video_in_game_folder = false; bool save_video_in_game_folder = false;
bool show_replay_started_notifications = true; bool show_replay_started_notifications = true;
bool show_replay_stopped_notifications = true; bool show_replay_stopped_notifications = true;

View File

@@ -59,6 +59,8 @@ namespace gsr {
void update_notification_process_status(); void update_notification_process_status();
void update_gsr_process_status(); void update_gsr_process_status();
void update_focused_fullscreen_status();
void update_ui_recording_paused(); void update_ui_recording_paused();
void update_ui_recording_unpaused(); void update_ui_recording_unpaused();
@@ -115,6 +117,8 @@ namespace gsr {
RecordingStatus recording_status = RecordingStatus::NONE; RecordingStatus recording_status = RecordingStatus::NONE;
bool paused = false; bool paused = false;
mgl::Clock focused_fullscreen_clock;
std::array<KeyBinding, 1> key_bindings; std::array<KeyBinding, 1> key_bindings;
}; };
} }

View File

@@ -5,11 +5,11 @@
namespace gsr { namespace gsr {
class LineSeparator : public Widget { class LineSeparator : public Widget {
public: public:
enum class Type { enum class Orientation {
HORIZONTAL HORIZONTAL
}; };
LineSeparator(Type type, float width); LineSeparator(Orientation orientation, float width);
LineSeparator(const LineSeparator&) = delete; LineSeparator(const LineSeparator&) = delete;
LineSeparator& operator=(const LineSeparator&) = delete; LineSeparator& operator=(const LineSeparator&) = delete;
@@ -18,7 +18,7 @@ namespace gsr {
mgl::vec2f get_size() override; mgl::vec2f get_size() override;
private: private:
Type type; Orientation orientation;
float width; float width;
}; };
} }

View File

@@ -9,7 +9,12 @@
namespace gsr { namespace gsr {
class RadioButton : public Widget { class RadioButton : public Widget {
public: public:
RadioButton(mgl::Font *font); enum class Orientation {
VERTICAL,
HORIZONTAL
};
RadioButton(mgl::Font *font, Orientation orientation);
RadioButton(const RadioButton&) = delete; RadioButton(const RadioButton&) = delete;
RadioButton& operator=(const RadioButton&) = delete; RadioButton& operator=(const RadioButton&) = delete;
@@ -32,6 +37,7 @@ namespace gsr {
}; };
mgl::Font *font; mgl::Font *font;
Orientation orientation;
std::vector<Item> items; std::vector<Item> items;
size_t selected_item = 0; size_t selected_item = 0;
bool dirty = true; bool dirty = true;

View File

@@ -92,7 +92,7 @@ namespace gsr {
std::unique_ptr<List> create_container_section(); std::unique_ptr<List> create_container_section();
std::unique_ptr<Entry> create_replay_time_entry(); std::unique_ptr<Entry> create_replay_time_entry();
std::unique_ptr<List> create_replay_time(); std::unique_ptr<List> create_replay_time();
std::unique_ptr<CheckBox> create_start_replay_on_startup(); std::unique_ptr<RadioButton> create_start_replay_automatically();
std::unique_ptr<CheckBox> create_save_replay_in_game_folder(); std::unique_ptr<CheckBox> create_save_replay_in_game_folder();
std::unique_ptr<Label> create_estimated_file_size(); std::unique_ptr<Label> create_estimated_file_size();
void update_estimated_file_size(); void update_estimated_file_size();
@@ -165,7 +165,6 @@ namespace gsr {
List *stream_key_list_ptr = nullptr; List *stream_key_list_ptr = nullptr;
List *stream_url_list_ptr = nullptr; List *stream_url_list_ptr = nullptr;
List *container_list_ptr = nullptr; List *container_list_ptr = nullptr;
CheckBox *start_replay_automatically_ptr = nullptr;
CheckBox *save_replay_in_game_folder_ptr = nullptr; CheckBox *save_replay_in_game_folder_ptr = nullptr;
Label *estimated_file_size_ptr = nullptr; Label *estimated_file_size_ptr = nullptr;
CheckBox *show_replay_started_notification_checkbox_ptr = nullptr; CheckBox *show_replay_started_notification_checkbox_ptr = nullptr;
@@ -181,6 +180,7 @@ namespace gsr {
Entry *youtube_stream_key_entry_ptr = nullptr; Entry *youtube_stream_key_entry_ptr = nullptr;
Entry *stream_url_entry_ptr = nullptr; Entry *stream_url_entry_ptr = nullptr;
Entry *replay_time_entry_ptr = nullptr; Entry *replay_time_entry_ptr = nullptr;
RadioButton *turn_on_replay_automatically_mode_ptr = nullptr;
PageStack *page_stack = nullptr; PageStack *page_stack = nullptr;

View File

@@ -132,7 +132,7 @@ namespace gsr {
{"replay.record_options.overclock", &config.replay_config.record_options.overclock}, {"replay.record_options.overclock", &config.replay_config.record_options.overclock},
{"replay.record_options.record_cursor", &config.replay_config.record_options.record_cursor}, {"replay.record_options.record_cursor", &config.replay_config.record_options.record_cursor},
{"replay.record_options.restore_portal_session", &config.replay_config.record_options.restore_portal_session}, {"replay.record_options.restore_portal_session", &config.replay_config.record_options.restore_portal_session},
{"replay.start_replay_automatically", &config.replay_config.start_replay_automatically}, {"replay.turn_on_replay_automatically_mode", &config.replay_config.turn_on_replay_automatically_mode},
{"replay.save_video_in_game_folder", &config.replay_config.save_video_in_game_folder}, {"replay.save_video_in_game_folder", &config.replay_config.save_video_in_game_folder},
{"replay.show_replay_started_notifications", &config.replay_config.show_replay_started_notifications}, {"replay.show_replay_started_notifications", &config.replay_config.show_replay_started_notifications},
{"replay.show_replay_stopped_notifications", &config.replay_config.show_replay_stopped_notifications}, {"replay.show_replay_stopped_notifications", &config.replay_config.show_replay_stopped_notifications},

View File

@@ -30,6 +30,66 @@ extern "C" {
namespace gsr { namespace gsr {
static const mgl::Color bg_color(0, 0, 0, 100); static const mgl::Color bg_color(0, 0, 0, 100);
static const double force_window_on_top_timeout_seconds = 1.0; static const double force_window_on_top_timeout_seconds = 1.0;
static const double focused_window_fullscreen_check_timeout_seconds = 1.0;
static bool window_has_atom(Display *dpy, Window window, Atom atom) {
Atom type;
unsigned long len, bytes_left;
int format;
unsigned char *properties = NULL;
if(XGetWindowProperty(dpy, window, atom, 0, 1024, False, AnyPropertyType, &type, &format, &len, &bytes_left, &properties) < Success)
return false;
if(properties)
XFree(properties);
return type != None;
}
static bool window_is_user_program(Display *dpy, Window window) {
const Atom net_wm_state_atom = XInternAtom(dpy, "_NET_WM_STATE", False);
const Atom wm_state_atom = XInternAtom(dpy, "WM_STATE", False);
return window_has_atom(dpy, window, net_wm_state_atom) || window_has_atom(dpy, window, wm_state_atom);
}
static Window get_window_at_cursor_position(Display *dpy) {
Window root_window = None;
Window window = None;
int dummy_i;
unsigned int dummy_u;
int cursor_pos_x = 0;
int cursor_pos_y = 0;
XQueryPointer(dpy, DefaultRootWindow(dpy), &root_window, &window, &dummy_i, &dummy_i, &cursor_pos_x, &cursor_pos_y, &dummy_u);
return window;
}
static Window get_focused_window(Display *dpy) {
const Atom net_active_window_atom = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
Window focused_window = None;
// Atom type = None;
// int format = 0;
// unsigned long num_items = 0;
// unsigned long bytes_left = 0;
// unsigned char *data = NULL;
// XGetWindowProperty(dpy, DefaultRootWindow(dpy), net_active_window_atom, 0, 1, False, XA_WINDOW, &type, &format, &num_items, &bytes_left, &data);
// fprintf(stderr, "focused window: %p\n", (void*)data);
// if(type == XA_WINDOW && num_items == 1 && data)
// return *(Window*)data;
int revert_to = 0;
XGetInputFocus(dpy, &focused_window, &revert_to);
if(focused_window && focused_window != DefaultRootWindow(dpy) && window_is_user_program(dpy, focused_window))
return focused_window;
focused_window = get_window_at_cursor_position(dpy);
if(focused_window && focused_window != DefaultRootWindow(dpy) && window_is_user_program(dpy, focused_window))
return focused_window;
return None;
}
static mgl::Texture texture_from_ximage(XImage *img) { static mgl::Texture texture_from_ximage(XImage *img) {
uint8_t *texture_data = (uint8_t*)malloc(img->width * img->height * 3); uint8_t *texture_data = (uint8_t*)malloc(img->width * img->height * 3);
@@ -82,17 +142,6 @@ namespace gsr {
return result; return result;
} }
static Window get_window_at_cursor_position(Display *display) {
Window root_window = None;
Window window = None;
int dummy_i;
unsigned int dummy_u;
int cursor_pos_x = 0;
int cursor_pos_y = 0;
XQueryPointer(display, DefaultRootWindow(display), &root_window, &window, &dummy_i, &dummy_i, &cursor_pos_x, &cursor_pos_y, &dummy_u);
return window;
}
struct DrawableGeometry { struct DrawableGeometry {
int x, y, width, height; int x, y, width, height;
}; };
@@ -130,6 +179,57 @@ namespace gsr {
&& diff_int(geometry.width, monitor->size.x, margin) && diff_int(geometry.height, monitor->size.y, margin); && diff_int(geometry.width, monitor->size.x, margin) && diff_int(geometry.height, monitor->size.y, margin);
} }
/*static bool is_window_fullscreen_on_monitor(Display *display, Window window, const mgl_monitor *monitors, int num_monitors) {
if(!window)
return false;
DrawableGeometry geometry;
if(!get_drawable_geometry(display, window, &geometry))
return false;
const int margin = 2;
for(int i = 0; i < num_monitors; ++i) {
const mgl_monitor *mon = &monitors[i];
if(diff_int(geometry.x, mon->pos.x, margin) && diff_int(geometry.y, mon->pos.y, margin)
&& diff_int(geometry.width, mon->size.x, margin) && diff_int(geometry.height, mon->size.y, margin))
{
return true;
}
}
return false;
}*/
static bool window_is_fullscreen(Display *display, Window window) {
const Atom wm_state_atom = XInternAtom(display, "_NET_WM_STATE", False);
const Atom wm_state_fullscreen_atom = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", False);
Atom type = None;
int format = 0;
unsigned long num_items = 0;
unsigned long bytes_after = 0;
unsigned char *properties = nullptr;
if(XGetWindowProperty(display, window, wm_state_atom, 0, 1024, False, XA_ATOM, &type, &format, &num_items, &bytes_after, &properties) < Success) {
fprintf(stderr, "Failed to get window wm state property\n");
return false;
}
if(!properties)
return false;
bool is_fullscreen = false;
Atom *atoms = (Atom*)properties;
for(unsigned long i = 0; i < num_items; ++i) {
if(atoms[i] == wm_state_fullscreen_atom) {
is_fullscreen = true;
break;
}
}
XFree(properties);
return is_fullscreen;
}
static void set_focused_window(Display *dpy, Window window) { static void set_focused_window(Display *dpy, Window window) {
XSetInputFocus(dpy, window, RevertToParent, CurrentTime); XSetInputFocus(dpy, window, RevertToParent, CurrentTime);
@@ -220,7 +320,7 @@ namespace gsr {
const std::string notify_bg_color_str = color_to_hex_str(get_color_theme().tint_color); const std::string notify_bg_color_str = color_to_hex_str(get_color_theme().tint_color);
setenv("GSR_NOTIFY_BG_COLOR", notify_bg_color_str.c_str(), true); setenv("GSR_NOTIFY_BG_COLOR", notify_bg_color_str.c_str(), true);
if(config.replay_config.start_replay_automatically) if(config.replay_config.turn_on_replay_automatically_mode == "turn_on_at_system_startup")
on_press_start_replay(true); on_press_start_replay(true);
} }
@@ -289,6 +389,7 @@ namespace gsr {
bool Overlay::draw() { bool Overlay::draw() {
update_notification_process_status(); update_notification_process_status();
update_gsr_process_status(); update_gsr_process_status();
update_focused_fullscreen_status();
if(!visible) if(!visible)
return false; return false;
@@ -753,6 +854,30 @@ namespace gsr {
recording_status = RecordingStatus::NONE; recording_status = RecordingStatus::NONE;
} }
void Overlay::update_focused_fullscreen_status() {
if(focused_fullscreen_clock.get_elapsed_time_seconds() < focused_window_fullscreen_check_timeout_seconds)
return;
focused_fullscreen_clock.restart();
if(config.replay_config.turn_on_replay_automatically_mode != "turn_on_at_fullscreen")
return;
mgl_context *context = mgl_get_context();
Display *display = (Display*)context->connection;
const Window focused_window = get_focused_window(display);
if(window && focused_window == window->get_system_handle())
return;
if(recording_status == RecordingStatus::NONE) {
if(focused_window != 0 && window_is_fullscreen(display, focused_window))
on_press_start_replay(false);
} else if(recording_status == RecordingStatus::REPLAY) {
if(focused_window == 0 || !window_is_fullscreen(display, focused_window))
on_press_start_replay(false);
}
}
void Overlay::update_ui_recording_paused() { void Overlay::update_ui_recording_paused() {
if(!visible || recording_status != RecordingStatus::RECORD) if(!visible || recording_status != RecordingStatus::RECORD)
return; return;

View File

@@ -16,7 +16,7 @@ namespace gsr {
}; };
} }
LineSeparator::LineSeparator(Type type, float width) : type(type), width(width) { LineSeparator::LineSeparator(Orientation orientation, float width) : orientation(orientation), width(width) {
} }

View File

@@ -14,7 +14,7 @@ namespace gsr {
static const float spacing_scale = 0.007f; static const float spacing_scale = 0.007f;
static const float border_scale = 0.0015f; static const float border_scale = 0.0015f;
RadioButton::RadioButton(mgl::Font *font) : font(font) { RadioButton::RadioButton(mgl::Font *font, Orientation orientation) : font(font), orientation(orientation) {
} }
@@ -44,7 +44,14 @@ namespace gsr {
return false; return false;
} }
draw_pos.x += item_size.x + spacing_scale * get_theme().window_height; switch(orientation) {
case Orientation::VERTICAL:
draw_pos.y += item_size.y + spacing_scale * get_theme().window_height;
break;
case Orientation::HORIZONTAL:
draw_pos.x += item_size.x + spacing_scale * get_theme().window_height;
break;
}
} }
} }
return true; return true;
@@ -85,7 +92,14 @@ namespace gsr {
item.text.set_position((draw_pos + item_size * 0.5f - item.text.get_bounds().size * 0.5f).floor()); item.text.set_position((draw_pos + item_size * 0.5f - item.text.get_bounds().size * 0.5f).floor());
window.draw(item.text); window.draw(item.text);
draw_pos.x += item_size.x + spacing_scale * get_theme().window_height; switch(orientation) {
case Orientation::VERTICAL:
draw_pos.y += item_size.y + spacing_scale * get_theme().window_height;
break;
case Orientation::HORIZONTAL:
draw_pos.x += item_size.x + spacing_scale * get_theme().window_height;
break;
}
} }
} }
@@ -98,13 +112,32 @@ namespace gsr {
const int padding_left = padding_left_scale * get_theme().window_height; const int padding_left = padding_left_scale * get_theme().window_height;
const int padding_right = padding_right_scale * get_theme().window_height; const int padding_right = padding_right_scale * get_theme().window_height;
size = { 0.0f, font->get_character_size() + (float)padding_top + (float)padding_bottom }; size = { 0.0f, 0.0f };
for(Item &item : items) { for(Item &item : items) {
const mgl::vec2f bounds = item.text.get_bounds().size; const mgl::vec2f bounds = item.text.get_bounds().size;
size.x += bounds.x + padding_left + padding_right; switch(orientation) {
case Orientation::VERTICAL:
size.x = std::max(size.x, bounds.x + padding_left + padding_right);
size.y += bounds.y + padding_top + padding_bottom;
break;
case Orientation::HORIZONTAL:
size.x += bounds.x + padding_left + padding_right;
size.y = font->get_character_size() + (float)padding_top + (float)padding_bottom;
break;
}
} }
if(items.size() > 1)
size.x += (items.size() - 1) * spacing_scale * get_theme().window_height; if(items.size() > 1) {
switch(orientation) {
case Orientation::VERTICAL:
size.y += (items.size() - 1) * spacing_scale * get_theme().window_height;
break;
case Orientation::HORIZONTAL:
size.x += (items.size() - 1) * spacing_scale * get_theme().window_height;
break;
}
}
dirty = false; dirty = false;
} }

View File

@@ -42,7 +42,7 @@ namespace gsr {
} }
std::unique_ptr<RadioButton> SettingsPage::create_view_radio_button() { std::unique_ptr<RadioButton> SettingsPage::create_view_radio_button() {
auto view_radio_button = std::make_unique<RadioButton>(&get_theme().body_font); auto view_radio_button = std::make_unique<RadioButton>(&get_theme().body_font, RadioButton::Orientation::HORIZONTAL);
view_radio_button->add_item("Simple view", "simple"); view_radio_button->add_item("Simple view", "simple");
view_radio_button->add_item("Advanced view", "advanced"); view_radio_button->add_item("Advanced view", "advanced");
view_radio_button->set_horizontal_alignment(Widget::Alignment::CENTER); view_radio_button->set_horizontal_alignment(Widget::Alignment::CENTER);
@@ -228,7 +228,7 @@ namespace gsr {
} }
std::unique_ptr<RadioButton> SettingsPage::create_audio_type_button() { std::unique_ptr<RadioButton> SettingsPage::create_audio_type_button() {
auto audio_type_radio_button = std::make_unique<RadioButton>(&get_theme().body_font); auto audio_type_radio_button = std::make_unique<RadioButton>(&get_theme().body_font, RadioButton::Orientation::HORIZONTAL);
audio_type_radio_button->add_item("Audio devices", "audio_devices"); audio_type_radio_button->add_item("Audio devices", "audio_devices");
audio_type_radio_button->add_item("Application audio", "app_audio"); audio_type_radio_button->add_item("Application audio", "app_audio");
audio_type_radio_button_ptr = audio_type_radio_button.get(); audio_type_radio_button_ptr = audio_type_radio_button.get();
@@ -321,10 +321,10 @@ namespace gsr {
auto audio_section = std::make_unique<Subsection>("Audio", std::move(audio_device_section_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f)); auto audio_section = std::make_unique<Subsection>("Audio", std::move(audio_device_section_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
audio_device_section_list_ptr->add_widget(create_audio_type_button()); audio_device_section_list_ptr->add_widget(create_audio_type_button());
audio_device_section_list_ptr->add_widget(std::make_unique<LineSeparator>(LineSeparator::Type::HORIZONTAL, audio_section->get_inner_size().x)); audio_device_section_list_ptr->add_widget(std::make_unique<LineSeparator>(LineSeparator::Orientation::HORIZONTAL, audio_section->get_inner_size().x));
audio_device_section_list_ptr->add_widget(create_audio_device_section()); audio_device_section_list_ptr->add_widget(create_audio_device_section());
audio_device_section_list_ptr->add_widget(create_application_audio_section()); audio_device_section_list_ptr->add_widget(create_application_audio_section());
//audio_device_section_list_ptr->add_widget(std::make_unique<LineSeparator>(LineSeparator::Type::HORIZONTAL, audio_section->get_inner_size().x)); //audio_device_section_list_ptr->add_widget(std::make_unique<LineSeparator>(LineSeparator::Orientation::HORIZONTAL, audio_section->get_inner_size().x));
audio_device_section_list_ptr->add_widget(create_merge_audio_tracks_checkbox()); audio_device_section_list_ptr->add_widget(create_merge_audio_tracks_checkbox());
audio_device_section_list_ptr->add_widget(create_audio_codec()); audio_device_section_list_ptr->add_widget(create_audio_codec());
return audio_section; return audio_section;
@@ -646,10 +646,13 @@ namespace gsr {
return replay_time_list; return replay_time_list;
} }
std::unique_ptr<CheckBox> SettingsPage::create_start_replay_on_startup() { std::unique_ptr<RadioButton> SettingsPage::create_start_replay_automatically() {
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Turn on replay automatically"); auto radiobutton = std::make_unique<RadioButton>(&get_theme().body_font, RadioButton::Orientation::VERTICAL);
start_replay_automatically_ptr = checkbox.get(); radiobutton->add_item("Don't turn on replay automatically", "dont_turn_on_automatically");
return checkbox; radiobutton->add_item("Turn on replay at system startup", "turn_on_at_system_startup");
radiobutton->add_item("Turn on replay when starting a fullscreen application", "turn_on_at_fullscreen");
turn_on_replay_automatically_mode_ptr = radiobutton.get();
return radiobutton;
} }
std::unique_ptr<CheckBox> SettingsPage::create_save_replay_in_game_folder() { std::unique_ptr<CheckBox> SettingsPage::create_save_replay_in_game_folder() {
@@ -685,7 +688,7 @@ namespace gsr {
settings_list_ptr->add_widget(std::make_unique<Subsection>("File info", std::move(file_info_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f))); settings_list_ptr->add_widget(std::make_unique<Subsection>("File info", std::move(file_info_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f)));
auto general_list = std::make_unique<List>(List::Orientation::VERTICAL); auto general_list = std::make_unique<List>(List::Orientation::VERTICAL);
general_list->add_widget(create_start_replay_on_startup()); general_list->add_widget(create_start_replay_automatically());
general_list->add_widget(create_save_replay_in_game_folder()); general_list->add_widget(create_save_replay_in_game_folder());
settings_list_ptr->add_widget(std::make_unique<Subsection>("General", std::move(general_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f))); settings_list_ptr->add_widget(std::make_unique<Subsection>("General", std::move(general_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f)));
@@ -1015,7 +1018,7 @@ namespace gsr {
void SettingsPage::load_replay() { void SettingsPage::load_replay() {
load_common(config.replay_config.record_options); load_common(config.replay_config.record_options);
start_replay_automatically_ptr->set_checked(config.replay_config.start_replay_automatically); turn_on_replay_automatically_mode_ptr->set_selected_item(config.replay_config.turn_on_replay_automatically_mode);
save_replay_in_game_folder_ptr->set_checked(config.replay_config.save_video_in_game_folder); save_replay_in_game_folder_ptr->set_checked(config.replay_config.save_video_in_game_folder);
show_replay_started_notification_checkbox_ptr->set_checked(config.replay_config.show_replay_started_notifications); show_replay_started_notification_checkbox_ptr->set_checked(config.replay_config.show_replay_started_notifications);
show_replay_stopped_notification_checkbox_ptr->set_checked(config.replay_config.show_replay_stopped_notifications); show_replay_stopped_notification_checkbox_ptr->set_checked(config.replay_config.show_replay_stopped_notifications);
@@ -1142,7 +1145,7 @@ namespace gsr {
void SettingsPage::save_replay() { void SettingsPage::save_replay() {
save_common(config.replay_config.record_options); save_common(config.replay_config.record_options);
config.replay_config.start_replay_automatically = start_replay_automatically_ptr->is_checked(); config.replay_config.turn_on_replay_automatically_mode = turn_on_replay_automatically_mode_ptr->get_selected_id();
config.replay_config.save_video_in_game_folder = save_replay_in_game_folder_ptr->is_checked(); config.replay_config.save_video_in_game_folder = save_replay_in_game_folder_ptr->is_checked();
config.replay_config.show_replay_started_notifications = show_replay_started_notification_checkbox_ptr->is_checked(); config.replay_config.show_replay_started_notifications = show_replay_started_notification_checkbox_ptr->is_checked();
config.replay_config.show_replay_stopped_notifications = show_replay_stopped_notification_checkbox_ptr->is_checked(); config.replay_config.show_replay_stopped_notifications = show_replay_stopped_notification_checkbox_ptr->is_checked();

View File

@@ -156,7 +156,7 @@ int main(void) {
global_hotkeys.poll_events(); global_hotkeys.poll_events();
overlay->handle_events(); overlay->handle_events();
if(!overlay->draw()) if(!overlay->draw())
std::this_thread::sleep_for(std::chrono::milliseconds(50)); std::this_thread::sleep_for(std::chrono::milliseconds(100));
} }
fprintf(stderr, "info: shutting down!\n"); fprintf(stderr, "info: shutting down!\n");