Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package gpu-screen-recorder-gtk for
openSUSE:Factory checked in at 2024-11-18 20:00:43
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/gpu-screen-recorder-gtk (Old)
and /work/SRC/openSUSE:Factory/.gpu-screen-recorder-gtk.new.2017 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "gpu-screen-recorder-gtk"
Mon Nov 18 20:00:43 2024 rev:9 rq:1224597 version:20241116
Changes:
--------
---
/work/SRC/openSUSE:Factory/gpu-screen-recorder-gtk/gpu-screen-recorder-gtk.changes
2024-11-06 16:53:33.136048734 +0100
+++
/work/SRC/openSUSE:Factory/.gpu-screen-recorder-gtk.new.2017/gpu-screen-recorder-gtk.changes
2024-11-18 20:01:04.716801398 +0100
@@ -1,0 +2,6 @@
+Sat Nov 16 23:02:07 UTC 2024 - [email protected]
+
+- Update to version 20241116:
+ * Add support application audio recording
+
+-------------------------------------------------------------------
Old:
----
gpu-screen-recorder-gtk-20241105.tar.zst
New:
----
gpu-screen-recorder-gtk-20241116.tar.zst
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ gpu-screen-recorder-gtk.spec ++++++
--- /var/tmp/diff_new_pack.Yi5qyn/_old 2024-11-18 20:01:05.376829004 +0100
+++ /var/tmp/diff_new_pack.Yi5qyn/_new 2024-11-18 20:01:05.380829171 +0100
@@ -19,7 +19,7 @@
%bcond_with test
%define appid com.dec05eba.gpu_screen_recorder
Name: gpu-screen-recorder-gtk
-Version: 20241105
+Version: 20241116
Release: 0
Summary: GTK frontend for GPU Screen Recorder
License: GPL-3.0-only
++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.Yi5qyn/_old 2024-11-18 20:01:05.424831011 +0100
+++ /var/tmp/diff_new_pack.Yi5qyn/_new 2024-11-18 20:01:05.432831346 +0100
@@ -1,6 +1,6 @@
<servicedata>
<service name="tar_scm">
<param
name="url">https://repo.dec05eba.com/gpu-screen-recorder-gtk.git</param>
- <param
name="changesrevision">ee137eedf5dd59a96126f02675ffe9553812a044</param></service></servicedata>
+ <param
name="changesrevision">0c2bb1a7a3dfe555619c17748d88e50bd330b80a</param></service></servicedata>
(No newline at EOF)
++++++ gpu-screen-recorder-gtk-20241105.tar.zst ->
gpu-screen-recorder-gtk-20241116.tar.zst ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gpu-screen-recorder-gtk-20241105/README.md
new/gpu-screen-recorder-gtk-20241116/README.md
--- old/gpu-screen-recorder-gtk-20241105/README.md 2024-11-05
10:29:53.000000000 +0100
+++ new/gpu-screen-recorder-gtk-20241116/README.md 2024-11-16
17:40:32.000000000 +0100
@@ -6,7 +6,7 @@
# Installation
This program depends on [GPU Screen
Recorder](https://git.dec05eba.com/gpu-screen-recorder/) which needs to be
installed first.\
-Run `sudo ./install.sh` or if you are running Arch Linux, then you can find
gpu screen recorder gtk on aur under the name gpu-screen-recorder-gtk-git (`yay
-S gpu-screen-recorder-gtk-git`).\
+Run `sudo ./install.sh` or if you are running Arch Linux, then you can find
gpu screen recorder gtk on aur under the name gpu-screen-recorder-gtk (`yay -S
gpu-screen-recorder-gtk`).\
You can also install gpu screen recorder (the gtk gui version) from
[flathub](https://flathub.org/apps/details/com.dec05eba.gpu_screen_recorder).
This flatpak includes gpu-screen-recorder so no need to install that first.
# Dependencies
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gpu-screen-recorder-gtk-20241105/TODO
new/gpu-screen-recorder-gtk-20241116/TODO
--- old/gpu-screen-recorder-gtk-20241105/TODO 2024-11-05 10:29:53.000000000
+0100
+++ new/gpu-screen-recorder-gtk-20241116/TODO 2024-11-16 17:40:32.000000000
+0100
@@ -61,4 +61,12 @@
Use modprobe command. modprobe on system startup in modprobe.d directory is
only available for udev, other systems need to add it to linux kernel boot
parameters (is this also needed for nvidia open kernel module driver?).
-Save gpu screen recorder status in $XDG_RUNTIME_DIR.
\ No newline at end of file
+Save gpu screen recorder status in $XDG_RUNTIME_DIR.
+
+Add option to capture application audio. This should show a popup where you
can use one of the available applications or a custom one and choose to record
that application or all applications except that one.
+
+Add profile option. Convert view to profile, add an option at the bottom that
says "Edit profiles..." which should show a popup where you can create/remove
profiles. New profiles should always be in advanced view.
+
+Move x11 hotkey code to its own file.
+
+Add audio devices/app refresh button.
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gpu-screen-recorder-gtk-20241105/com.dec05eba.gpu_screen_recorder.appdata.xml
new/gpu-screen-recorder-gtk-20241116/com.dec05eba.gpu_screen_recorder.appdata.xml
---
old/gpu-screen-recorder-gtk-20241105/com.dec05eba.gpu_screen_recorder.appdata.xml
2024-11-05 10:29:53.000000000 +0100
+++
new/gpu-screen-recorder-gtk-20241116/com.dec05eba.gpu_screen_recorder.appdata.xml
2024-11-16 17:40:32.000000000 +0100
@@ -80,6 +80,13 @@
</screenshots>
<releases>
+ <release version="4.3.0" date="2024-11-16">
+ <description>
+ <ul>
+ <li>Add option to record audio from applications instead
of audio devices (pipewire only)</li>
+ </ul>
+ </description>
+ </release>
<release version="4.2.6" date="2024-11-05">
<description>
<ul>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gpu-screen-recorder-gtk-20241105/meson.build
new/gpu-screen-recorder-gtk-20241116/meson.build
--- old/gpu-screen-recorder-gtk-20241105/meson.build 2024-11-05
10:29:53.000000000 +0100
+++ new/gpu-screen-recorder-gtk-20241116/meson.build 2024-11-16
17:40:32.000000000 +0100
@@ -1,4 +1,4 @@
-project('gpu-screen-recorder-gtk', ['c', 'cpp'], version : '4.2.6',
default_options : ['warning_level=2'])
+project('gpu-screen-recorder-gtk', ['c', 'cpp'], version : '4.3.0',
default_options : ['warning_level=2'])
add_project_arguments('-Wshadow', language : ['c', 'cpp'])
if get_option('buildtype') == 'debug'
@@ -18,15 +18,23 @@
dependency('ayatana-appindicator3-0.1'),
]
-add_project_arguments('-DGSR_VERSION="' + meson.project_version() + '"',
language: ['c', 'cpp'])
-
-executable('gpu-screen-recorder-gtk', src, dependencies : dep, install : true)
-
prefix = get_option('prefix')
datadir = get_option('datadir')
+icons_path = join_paths(prefix, datadir, 'icons')
+
+executable('gpu-screen-recorder-gtk',
+ src,
+ dependencies : dep,
+ install : true,
+ cpp_args : [
+ '-DGSR_ICONS_PATH="' + icons_path + '"',
+ '-DGSR_VERSION="' + meson.project_version() + '"'
+ ]
+)
+
install_data(files('com.dec05eba.gpu_screen_recorder.desktop'), install_dir :
join_paths(prefix, datadir, 'applications'))
install_data(files('com.dec05eba.gpu_screen_recorder.appdata.xml'),
install_dir : join_paths(prefix, datadir, 'metainfo'))
-install_subdir('icons/hicolor', install_dir : join_paths(prefix, datadir,
'icons'))
+install_subdir('icons/hicolor', install_dir : icons_path)
gnome = import('gnome')
gnome.post_install(gtk_update_icon_cache : true, update_desktop_database :
true)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gpu-screen-recorder-gtk-20241105/project.conf
new/gpu-screen-recorder-gtk-20241116/project.conf
--- old/gpu-screen-recorder-gtk-20241105/project.conf 2024-11-05
10:29:53.000000000 +0100
+++ new/gpu-screen-recorder-gtk-20241116/project.conf 2024-11-16
17:40:32.000000000 +0100
@@ -1,7 +1,7 @@
[package]
name = "gpu-screen-recorder-gtk"
type = "executable"
-version = "4.2.6"
+version = "4.3.0"
platforms = ["posix"]
[config]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gpu-screen-recorder-gtk-20241105/src/config.hpp
new/gpu-screen-recorder-gtk-20241116/src/config.hpp
--- old/gpu-screen-recorder-gtk-20241105/src/config.hpp 2024-11-05
10:29:53.000000000 +0100
+++ new/gpu-screen-recorder-gtk-20241116/src/config.hpp 2024-11-16
17:40:32.000000000 +0100
@@ -28,8 +28,11 @@
int32_t fps = 60;
int32_t video_bitrate = 15000;
bool merge_audio_tracks = true;
+ bool record_app_audio_inverted = false;
bool change_video_resolution = false;
+ std::string audio_type_view = "audio_devices";
std::vector<std::string> audio_input;
+ std::vector<std::string> application_audio;
std::string color_range;
std::string quality;
std::string codec; // Video codec
@@ -313,8 +316,11 @@
{"main.fps", {CONFIG_TYPE_I32, &config.main_config.fps}},
{"main.video_bitrate", {CONFIG_TYPE_I32,
&config.main_config.video_bitrate}},
{"main.merge_audio_tracks", {CONFIG_TYPE_BOOL,
&config.main_config.merge_audio_tracks}},
+ {"main.record_app_audio_inverted", {CONFIG_TYPE_BOOL,
&config.main_config.record_app_audio_inverted}},
{"main.change_video_resolution", {CONFIG_TYPE_BOOL,
&config.main_config.change_video_resolution}},
+ {"main.audio_type_view", {CONFIG_TYPE_STRING,
&config.main_config.audio_type_view}},
{"main.audio_input", {CONFIG_TYPE_STRING_ARRAY,
&config.main_config.audio_input}},
+ {"main.application_audio", {CONFIG_TYPE_STRING_ARRAY,
&config.main_config.application_audio}},
{"main.color_range", {CONFIG_TYPE_STRING,
&config.main_config.color_range}},
{"main.quality", {CONFIG_TYPE_STRING, &config.main_config.quality}},
{"main.codec", {CONFIG_TYPE_STRING, &config.main_config.codec}},
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gpu-screen-recorder-gtk-20241105/src/main.cpp
new/gpu-screen-recorder-gtk-20241116/src/main.cpp
--- old/gpu-screen-recorder-gtk-20241105/src/main.cpp 2024-11-05
10:29:53.000000000 +0100
+++ new/gpu-screen-recorder-gtk-20241116/src/main.cpp 2024-11-16
17:40:32.000000000 +0100
@@ -90,19 +90,26 @@
static GtkEntry *custom_stream_url_entry;
static GtkSpinButton *replay_time_entry;
static GtkButton *select_window_button;
-static GtkWidget *audio_input_used_list;
-static GtkWidget *add_audio_input_button;
+static GtkBox *audio_devices_items_box;
static GtkWidget *record_start_stop_hotkey_button;
static GtkWidget *pause_unpause_hotkey_button;
static GtkWidget *replay_start_stop_hotkey_button;
static GtkWidget *replay_save_hotkey_button;
static GtkWidget *streaming_start_stop_hotkey_button;
+static GtkWidget *record_app_audio_inverted_button;
static GtkWidget *merge_audio_tracks_button;
+static GtkFrame *notifications_frame;
static GtkWidget *show_recording_started_notification_button;
static GtkWidget *show_recording_stopped_notification_button;
static GtkWidget *show_recording_saved_notification_button;
static GtkWidget *record_cursor_button;
static GtkWidget *restore_portal_session_button;
+static GtkBox *audio_type_radio_button_box;
+static GtkWidget *audio_devices_radio_button;
+static GtkWidget *application_audio_radio_button;
+static GtkGrid *audio_devices_grid;
+static GtkGrid *application_audio_grid;
+static GtkBox *application_audio_items_box;
static GtkGrid *video_codec_grid;
static GtkGrid *audio_codec_grid;
static GtkGrid *color_range_grid;
@@ -169,6 +176,7 @@
};
static std::vector<AudioInput> audio_inputs;
+static std::vector<std::string> application_audio;
enum class HotkeyMode {
NoAction,
@@ -249,6 +257,7 @@
struct SystemInfo {
DisplayServer display_server = DisplayServer::UNKNOWN;
+ bool supports_app_audio = false;
bool is_steam_deck = false;
};
@@ -302,11 +311,6 @@
{ "hls", "m3u8" }
};
-struct AudioRow {
- GtkWidget *row;
- GtkComboBoxText *input_list;
-};
-
// Dumb hacks below!! why dont these fking paths work outside flatpak.. except
in kde. TODO: fix this!
static const char* get_tray_idle_icon_name() {
if(flatpak)
@@ -546,65 +550,31 @@
return inputs;
}
-static void used_audio_input_loop_callback(GtkWidget *row, gpointer userdata) {
- const AudioRow *audio_row = (AudioRow*)g_object_get_data(G_OBJECT(row),
"audio-row");
- std::function<void(const AudioRow*)> &callback =
*(std::function<void(const AudioRow*)>*)userdata;
- callback(audio_row);
-}
-
-static void for_each_used_audio_input(GtkListBox *list_box,
std::function<void(const AudioRow*)> callback) {
- gtk_container_foreach(GTK_CONTAINER(list_box),
used_audio_input_loop_callback, &callback);
-}
-
-static void drag_begin (GtkWidget *widget, GdkDragContext *context, gpointer) {
- GtkAllocation alloc;
- int x, y;
- double sx, sy;
-
- GtkWidget *row = gtk_widget_get_ancestor(widget, GTK_TYPE_LIST_BOX_ROW);
- gtk_widget_get_allocation(row, &alloc);
- cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
alloc.width, alloc.height);
- cairo_t *cr = cairo_create(surface);
-
- gtk_style_context_add_class(gtk_widget_get_style_context (row),
"drag-icon");
- gtk_widget_draw(row, cr);
- gtk_style_context_remove_class(gtk_widget_get_style_context (row),
"drag-icon");
-
- gtk_widget_translate_coordinates(widget, row, 0, 0, &x, &y);
- cairo_surface_get_device_scale(surface, &sx, &sy);
- cairo_surface_set_device_offset(surface, -x * sx, -y * sy);
- gtk_drag_set_icon_surface(context, surface);
-
- cairo_destroy(cr);
- cairo_surface_destroy(surface);
-}
-
-static void drag_data_get(GtkWidget *widget, GdkDragContext*, GtkSelectionData
*selection_data, guint, guint, gpointer) {
- gtk_selection_data_set(selection_data,
gdk_atom_intern_static_string("GTK_LIST_BOX_ROW"),
- 32,
- (const guchar *)&widget,
- sizeof(gpointer));
-}
+static std::vector<std::string> get_application_audio() {
+ std::vector<std::string> application_audio;
-static void drag_data_received(GtkWidget *widget, GdkDragContext*,
- gint, gint,
- GtkSelectionData *selection_data,
- guint, guint32, gpointer)
-{
- GtkWidget *target = widget;
+ FILE *f = popen("gpu-screen-recorder --list-application-audio", "r");
+ if(!f) {
+ fprintf(stderr, "error: 'gpu-screen-recorder --list-application-audio'
failed\n");
+ return application_audio;
+ }
- int pos = gtk_list_box_row_get_index(GTK_LIST_BOX_ROW (target));
- GtkWidget *row = *(GtkWidget**)gtk_selection_data_get_data(selection_data);
- GtkWidget *source = gtk_widget_get_ancestor(row, GTK_TYPE_LIST_BOX_ROW);
+ char output[16384];
+ ssize_t bytes_read = fread(output, 1, sizeof(output) - 1, f);
+ if(bytes_read < 0 || ferror(f)) {
+ fprintf(stderr, "error: failed to read 'gpu-screen-recorder
--list-application-audio' output\n");
+ pclose(f);
+ return application_audio;
+ }
+ output[bytes_read] = '\0';
- if (source == target)
- return;
+ string_split_char(output, '\n', [&](StringView line) {
+ std::string line_str(line.str, line.size);
+ application_audio.emplace_back(std::move(line_str));
+ return true;
+ });
- GtkWidget *list_box = gtk_widget_get_parent(source);
- g_object_ref(source);
- gtk_container_remove(GTK_CONTAINER(list_box), source);
- gtk_list_box_insert(GTK_LIST_BOX(list_box), source, pos);
- g_object_unref(source);
+ return application_audio;
}
static bool is_video_capture_option_enabled(const char *str) {
@@ -739,55 +709,8 @@
gtk_widget_set_sensitive(GTK_WIDGET(stream_button), true);
}
-static GtkWidget* create_used_audio_input_row(void) {
- char entry_name[] = "GTK_LIST_BOX_ROW";
- const GtkTargetEntry entries[] = {
- { entry_name, GTK_TARGET_SAME_APP, 0 }
- };
-
- GtkWidget *row = gtk_list_box_row_new();
-
- GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
- gtk_container_add(GTK_CONTAINER(row), box);
-
- GtkWidget *handle = gtk_event_box_new();
- GtkWidget *image = gtk_image_new_from_icon_name("open-menu-symbolic",
GTK_ICON_SIZE_MENU);
- gtk_container_add(GTK_CONTAINER(handle), image);
- gtk_container_add(GTK_CONTAINER(box), handle);
-
- GtkComboBoxText *input_list = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
- for(const auto &audio_input : audio_inputs) {
- gtk_combo_box_text_append(input_list, audio_input.name.c_str(),
audio_input.description.c_str());
- }
- gtk_widget_set_hexpand(GTK_WIDGET(input_list), true);
- gtk_combo_box_set_active(GTK_COMBO_BOX(input_list), 0);
- //gtk_combo_box_set_active_id(GTK_COMBO_BOX(combo), id);
- gtk_container_add(GTK_CONTAINER(box), GTK_WIDGET(input_list));
-
- GtkWidget *remove_button = gtk_button_new_with_label("Remove");
- gtk_widget_set_halign(remove_button, GTK_ALIGN_END);
- gtk_container_add(GTK_CONTAINER(box), remove_button);
-
- gtk_drag_source_set(handle, GDK_BUTTON1_MASK, entries, 1, GDK_ACTION_MOVE);
- g_signal_connect(handle, "drag-begin", G_CALLBACK(drag_begin), NULL);
- g_signal_connect(handle, "drag-data-get", G_CALLBACK(drag_data_get), NULL);
-
- gtk_drag_dest_set(row, GTK_DEST_DEFAULT_ALL, entries, 1, GDK_ACTION_MOVE);
- g_signal_connect(row, "drag-data-received",
G_CALLBACK(drag_data_received), NULL);
-
- AudioRow *audio_row = new AudioRow();
- audio_row->row = row;
- audio_row->input_list = input_list;
- g_object_set_data(G_OBJECT(row), "audio-row", audio_row);
-
- g_signal_connect(remove_button, "clicked", G_CALLBACK(+[](GtkButton*,
gpointer userdata){
- AudioRow *_audio_row = (AudioRow*)userdata;
-
gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(_audio_row->row)),
_audio_row->row);
- delete _audio_row;
- return true;
- }), audio_row);
-
- return row;
+static gboolean scroll_event_ignore(GtkWidget*, GdkEvent*, void*) {
+ return TRUE;
}
// Return true from |callback_func| to continue to the next row
@@ -835,6 +758,96 @@
return found_index;
}
+static GtkWidget* create_audio_device_combo_box_row(const std::string
&selected_row_text) {
+ GtkGrid *grid = GTK_GRID(gtk_grid_new());
+ gtk_grid_set_column_spacing(grid, 10);
+ gtk_widget_set_hexpand(GTK_WIDGET(grid), true);
+
+ GtkComboBoxText *audio_device_combo_box =
GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
+ g_signal_connect(audio_device_combo_box, "scroll-event",
G_CALLBACK(scroll_event_ignore), NULL);
+ for(const auto &audio_input : audio_inputs) {
+ gtk_combo_box_text_append(audio_device_combo_box,
audio_input.name.c_str(), audio_input.description.c_str());
+ }
+
+ if(!audio_inputs.empty() && selected_row_text.empty()) {
+ gtk_combo_box_set_active(GTK_COMBO_BOX(audio_device_combo_box), 0);
+ } else if(!selected_row_text.empty()) {
+ std::string audio_id;
+ const gint target_combo_box_index =
combo_box_text_get_row_by_label(GTK_COMBO_BOX(audio_device_combo_box),
selected_row_text.c_str(), audio_id);
+ if(target_combo_box_index != -1)
+ gtk_combo_box_set_active(GTK_COMBO_BOX(audio_device_combo_box),
target_combo_box_index);
+ else if(!audio_inputs.empty())
+ gtk_combo_box_set_active(GTK_COMBO_BOX(audio_device_combo_box), 0);
+ }
+
+ gtk_widget_set_hexpand(GTK_WIDGET(audio_device_combo_box), true);
+ gtk_grid_attach(grid, GTK_WIDGET(audio_device_combo_box), 0, 0, 1, 1);
+
+ GtkButton *remove_button = GTK_BUTTON(gtk_button_new_with_label("Remove"));
+ gtk_grid_attach(grid, GTK_WIDGET(remove_button), 1, 0, 1, 1);
+
+ g_signal_connect(remove_button, "clicked", G_CALLBACK(+[](GtkButton*,
gpointer userdata){
+ GtkGrid *grid = (GtkGrid*)userdata;
+
gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(GTK_WIDGET(grid))),
GTK_WIDGET(grid));
+ return true;
+ }), grid);
+
+ return GTK_WIDGET(grid);
+}
+
+static GtkWidget* create_application_audio_combo_box_row(const std::string
&selected_row_id) {
+ GtkGrid *grid = GTK_GRID(gtk_grid_new());
+ gtk_grid_set_column_spacing(grid, 10);
+ gtk_widget_set_hexpand(GTK_WIDGET(grid), true);
+
+ GtkComboBoxText *application_audio_combo_box =
GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
+ g_signal_connect(application_audio_combo_box, "scroll-event",
G_CALLBACK(scroll_event_ignore), NULL);
+ for(const std::string &app_audio : application_audio) {
+ gtk_combo_box_text_append(application_audio_combo_box,
app_audio.c_str(), app_audio.c_str());
+ }
+
+ if(!application_audio.empty() && selected_row_id.empty())
+ gtk_combo_box_set_active(GTK_COMBO_BOX(application_audio_combo_box),
0);
+ else if(!selected_row_id.empty())
+
gtk_combo_box_set_active_id(GTK_COMBO_BOX(application_audio_combo_box),
selected_row_id.c_str());
+
+ gtk_widget_set_hexpand(GTK_WIDGET(application_audio_combo_box), true);
+ gtk_grid_attach(grid, GTK_WIDGET(application_audio_combo_box), 0, 0, 1, 1);
+
+ GtkButton *remove_button = GTK_BUTTON(gtk_button_new_with_label("Remove"));
+ gtk_grid_attach(grid, GTK_WIDGET(remove_button), 1, 0, 1, 1);
+
+ g_signal_connect(remove_button, "clicked", G_CALLBACK(+[](GtkButton*,
gpointer userdata){
+ GtkGrid *grid = (GtkGrid*)userdata;
+
gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(GTK_WIDGET(grid))),
GTK_WIDGET(grid));
+ return true;
+ }), grid);
+
+ return GTK_WIDGET(grid);
+}
+
+static GtkWidget* create_application_audio_custom_row(const std::string &text)
{
+ GtkGrid *grid = GTK_GRID(gtk_grid_new());
+ gtk_grid_set_column_spacing(grid, 10);
+ gtk_widget_set_hexpand(GTK_WIDGET(grid), true);
+
+ GtkEntry *application_audio_entry = GTK_ENTRY(gtk_entry_new());
+ gtk_widget_set_hexpand(GTK_WIDGET(application_audio_entry), true);
+ gtk_entry_set_text(application_audio_entry, text.c_str());
+ gtk_grid_attach(grid, GTK_WIDGET(application_audio_entry), 0, 0, 1, 1);
+
+ GtkButton *remove_button = GTK_BUTTON(gtk_button_new_with_label("Remove"));
+ gtk_grid_attach(grid, GTK_WIDGET(remove_button), 1, 0, 1, 1);
+
+ g_signal_connect(remove_button, "clicked", G_CALLBACK(+[](GtkButton*,
gpointer userdata){
+ GtkGrid *grid = (GtkGrid*)userdata;
+
gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(GTK_WIDGET(grid))),
GTK_WIDGET(grid));
+ return true;
+ }), grid);
+
+ return GTK_WIDGET(grid);
+}
+
static bool is_directory(const char *filepath) {
struct stat file_stat;
memset(&file_stat, 0, sizeof(file_stat));
@@ -863,12 +876,33 @@
config.main_config.fps = gtk_spin_button_get_value_as_int(fps_entry);
config.main_config.video_bitrate =
gtk_spin_button_get_value_as_int(video_bitrate_entry);
config.main_config.merge_audio_tracks =
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(merge_audio_tracks_button));
+ config.main_config.record_app_audio_inverted =
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(record_app_audio_inverted_button));
config.main_config.change_video_resolution =
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(change_video_resolution_button));
+ config.main_config.audio_type_view.clear();
+
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(audio_devices_radio_button)))
+ config.main_config.audio_type_view = "audio_devices";
+ else
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(application_audio_radio_button)))
+ config.main_config.audio_type_view = "app_audio";
+
config.main_config.audio_input.clear();
- for_each_used_audio_input(GTK_LIST_BOX(audio_input_used_list), [](const
AudioRow *audio_row) {
-
config.main_config.audio_input.push_back(gtk_combo_box_text_get_active_text(audio_row->input_list));
- });
+ gtk_container_foreach(GTK_CONTAINER(audio_devices_items_box), [](GtkWidget
*widget, gpointer) {
+ GtkWidget *row_item_widget = gtk_grid_get_child_at(GTK_GRID(widget),
0, 0);
+ if(GTK_IS_COMBO_BOX_TEXT(row_item_widget))
+
config.main_config.audio_input.push_back(gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(row_item_widget)));
+ }, nullptr);
+
+ config.main_config.application_audio.clear();
+ gtk_container_foreach(GTK_CONTAINER(application_audio_items_box),
[](GtkWidget *widget, gpointer) {
+ GtkWidget *row_item_widget = gtk_grid_get_child_at(GTK_GRID(widget),
0, 0);
+ const char *text = "";
+ if(GTK_IS_COMBO_BOX_TEXT(row_item_widget))
+ text = gtk_combo_box_get_active_id(GTK_COMBO_BOX(row_item_widget));
+ else if(GTK_IS_ENTRY(row_item_widget))
+ text = gtk_entry_get_text(GTK_ENTRY(row_item_widget));
+ config.main_config.application_audio.push_back(text);
+ }, nullptr);
+
config.main_config.color_range =
gtk_combo_box_get_active_id(GTK_COMBO_BOX(color_range_input_menu));
config.main_config.quality =
gtk_combo_box_get_active_id(GTK_COMBO_BOX(quality_input_menu));
config.main_config.codec = video_codec_selection_menu_get_active_id();
@@ -1445,9 +1479,12 @@
show_bugged_driver_warning();
int num_audio_tracks = 0;
- for_each_used_audio_input(GTK_LIST_BOX(audio_input_used_list),
[&num_audio_tracks](const AudioRow*) {
- ++num_audio_tracks;
- });
+ gtk_container_foreach(GTK_CONTAINER(audio_devices_items_box), [](GtkWidget
*widget, gpointer userdata) {
+ int &num_audio_tracks = *(int*)userdata;
+ GtkWidget *row_item_widget = gtk_grid_get_child_at(GTK_GRID(widget),
0, 0);
+ if(GTK_IS_COMBO_BOX_TEXT(row_item_widget))
+ ++num_audio_tracks;
+ }, &num_audio_tracks);
if(num_audio_tracks > 1 &&
!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(merge_audio_tracks_button))) {
GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(window),
GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
@@ -1536,20 +1573,81 @@
return exit_success;
}
-static void add_audio_command_line_args(std::vector<const char*> &args,
std::string &merge_audio_tracks_arg_value) {
+struct ApplicationAudioCallbackUserdata {
+ const char *arg_option;
+ std::vector<const char*> &args;
+};
+
+static void add_audio_devices_command_line_args(std::vector<const char*>
&args, std::string &merge_audio_tracks_arg_value) {
+
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(merge_audio_tracks_button))) {
+ gtk_container_foreach(GTK_CONTAINER(audio_devices_items_box),
[](GtkWidget *widget, gpointer userdata) {
+ std::string &merge_audio_tracks_arg_value =
*(std::string*)userdata;
+ GtkWidget *row_item_widget =
gtk_grid_get_child_at(GTK_GRID(widget), 0, 0);
+
+ if(GTK_IS_COMBO_BOX_TEXT(row_item_widget)) {
+ if(!merge_audio_tracks_arg_value.empty())
+ merge_audio_tracks_arg_value += '|';
+ merge_audio_tracks_arg_value +=
gtk_combo_box_get_active_id(GTK_COMBO_BOX(row_item_widget));
+ }
+ }, &merge_audio_tracks_arg_value);
+
+ if(!merge_audio_tracks_arg_value.empty())
+ args.insert(args.end(), { "-a",
merge_audio_tracks_arg_value.c_str() });
+ } else {
+ gtk_container_foreach(GTK_CONTAINER(audio_devices_items_box),
[](GtkWidget *widget, gpointer userdata) {
+ std::vector<const char*> &args = *(std::vector<const
char*>*)userdata;
+ GtkWidget *row_item_widget =
gtk_grid_get_child_at(GTK_GRID(widget), 0, 0);
+
+ if(GTK_IS_COMBO_BOX_TEXT(row_item_widget))
+ args.insert(args.end(), { "-a",
gtk_combo_box_get_active_id(GTK_COMBO_BOX(row_item_widget)) });
+ }, &args);
+ }
+}
+
+static void add_application_audio_command_line_args(std::vector<const char*>
&args, std::string &merge_audio_tracks_arg_value) {
+ const char *arg_option =
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(record_app_audio_inverted_button))
? "-aai" : "-aa";
+ ApplicationAudioCallbackUserdata app_audio_callback = {
+ arg_option,
+ args
+ };
+
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(merge_audio_tracks_button))) {
- for_each_used_audio_input(GTK_LIST_BOX(audio_input_used_list),
[&merge_audio_tracks_arg_value](const AudioRow *audio_row) {
+ gtk_container_foreach(GTK_CONTAINER(application_audio_items_box),
[](GtkWidget *widget, gpointer userdata) {
+ std::string &merge_audio_tracks_arg_value =
*(std::string*)userdata;
+ GtkWidget *row_item_widget =
gtk_grid_get_child_at(GTK_GRID(widget), 0, 0);
+
+ const char *text = "";
+ if(GTK_IS_COMBO_BOX_TEXT(row_item_widget))
+ text =
gtk_combo_box_get_active_id(GTK_COMBO_BOX(row_item_widget));
+ else if(GTK_IS_ENTRY(row_item_widget))
+ text = gtk_entry_get_text(GTK_ENTRY(row_item_widget));
+
if(!merge_audio_tracks_arg_value.empty())
merge_audio_tracks_arg_value += '|';
- merge_audio_tracks_arg_value +=
gtk_combo_box_get_active_id(GTK_COMBO_BOX(audio_row->input_list));
- });
+ merge_audio_tracks_arg_value += text;
+ }, &merge_audio_tracks_arg_value);
if(!merge_audio_tracks_arg_value.empty())
- args.insert(args.end(), { "-a",
merge_audio_tracks_arg_value.c_str() });
+ args.insert(args.end(), { arg_option,
merge_audio_tracks_arg_value.c_str() });
} else {
- for_each_used_audio_input(GTK_LIST_BOX(audio_input_used_list),
[&args](const AudioRow *audio_row) {
- args.insert(args.end(), { "-a",
gtk_combo_box_get_active_id(GTK_COMBO_BOX(audio_row->input_list)) });
- });
+ gtk_container_foreach(GTK_CONTAINER(application_audio_items_box),
[](GtkWidget *widget, gpointer userdata) {
+ ApplicationAudioCallbackUserdata *app_audio_callback =
(ApplicationAudioCallbackUserdata*)userdata;
+ GtkWidget *row_item_widget =
gtk_grid_get_child_at(GTK_GRID(widget), 0, 0);
+ const char *text = "";
+ if(GTK_IS_COMBO_BOX_TEXT(row_item_widget))
+ text =
gtk_combo_box_get_active_id(GTK_COMBO_BOX(row_item_widget));
+ else if(GTK_IS_ENTRY(row_item_widget))
+ text = gtk_entry_get_text(GTK_ENTRY(row_item_widget));
+ app_audio_callback->args.insert(app_audio_callback->args.end(), {
app_audio_callback->arg_option, text });
+ }, &app_audio_callback);
+ }
+}
+
+static void add_audio_command_line_args(std::vector<const char*> &args,
std::string &merge_audio_tracks_arg_value) {
+
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(audio_devices_radio_button)))
{
+ add_audio_devices_command_line_args(args,
merge_audio_tracks_arg_value);
+ } else
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(application_audio_radio_button)))
{
+ add_application_audio_command_line_args(args,
merge_audio_tracks_arg_value);
}
}
@@ -2189,9 +2287,7 @@
gtk_widget_set_visible(GTK_WIDGET(audio_codec_grid), advanced_view);
gtk_widget_set_visible(GTK_WIDGET(framerate_mode_grid), advanced_view);
gtk_widget_set_visible(GTK_WIDGET(overclock_grid), advanced_view &&
gsr_info.gpu_info.vendor == GpuVendor::NVIDIA &&
gsr_info.system_info.display_server != DisplayServer::WAYLAND);
-
gtk_widget_set_visible(GTK_WIDGET(show_recording_started_notification_button),
advanced_view);
-
gtk_widget_set_visible(GTK_WIDGET(show_recording_stopped_notification_button),
advanced_view);
-
gtk_widget_set_visible(GTK_WIDGET(show_recording_saved_notification_button),
advanced_view);
+ gtk_widget_set_visible(GTK_WIDGET(notifications_frame), advanced_view);
}
static void quality_combo_box_change_callback(GtkComboBox *widget, gpointer
userdata) {
@@ -2433,6 +2529,8 @@
_gsr_info->system_info.display_server = DisplayServer::WAYLAND;
} else if(attribute_name == "is_steam_deck") {
_gsr_info->system_info.is_steam_deck = attribute_value == "yes";
+ } else if(attribute_name == "supports_app_audio") {
+ _gsr_info->system_info.supports_app_audio = attribute_value == "yes";
}
}
@@ -2609,23 +2707,40 @@
g_free(id);
}
+static void audio_devices_application_audio_radio_toggled(GtkButton *button,
gpointer) {
+ if(!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
+ return;
+
+ if(GTK_WIDGET(button) == audio_devices_radio_button) {
+ gtk_widget_set_visible(GTK_WIDGET(audio_devices_grid), true);
+ gtk_widget_set_visible(GTK_WIDGET(application_audio_grid), false);
+ } else if(GTK_WIDGET(button) == application_audio_radio_button) {
+ gtk_widget_set_visible(GTK_WIDGET(audio_devices_grid), false);
+ gtk_widget_set_visible(GTK_WIDGET(application_audio_grid), true);
+ }
+}
+
static GtkWidget* create_common_settings_page(GtkStack *stack, GtkApplication
*app) {
- GtkGrid *grid = GTK_GRID(gtk_grid_new());
- gtk_stack_add_named(stack, GTK_WIDGET(grid), "common-settings");
- gtk_widget_set_vexpand(GTK_WIDGET(grid), true);
- gtk_widget_set_hexpand(GTK_WIDGET(grid), true);
- gtk_grid_set_row_spacing(grid, 10);
- gtk_grid_set_column_spacing(grid, 10);
- gtk_widget_set_margin(GTK_WIDGET(grid), 10, 10, 10, 10);
+ GtkGrid *main_grid = GTK_GRID(gtk_grid_new());
+ gtk_stack_add_named(stack, GTK_WIDGET(main_grid), "common-settings");
+ gtk_widget_set_vexpand(GTK_WIDGET(main_grid), true);
+ gtk_widget_set_hexpand(GTK_WIDGET(main_grid), true);
+ gtk_grid_set_row_spacing(main_grid, 10);
+ gtk_grid_set_column_spacing(main_grid, 10);
+ gtk_widget_set_margin(GTK_WIDGET(main_grid), 10, 10, 10, 10);
+ int main_grid_row = 0;
int grid_row = 0;
int record_area_row = 0;
int audio_input_area_row = 0;
+ int video_input_area_row = 0;
+ int notifications_area_row = 0;
GtkGrid *simple_advanced_grid = GTK_GRID(gtk_grid_new());
- gtk_grid_attach(grid, GTK_WIDGET(simple_advanced_grid), 0, grid_row++, 2,
1);
+ gtk_grid_attach(main_grid, GTK_WIDGET(simple_advanced_grid), 0,
main_grid_row++, 2, 1);
gtk_grid_attach(simple_advanced_grid, gtk_label_new("View: "), 0, 0, 1, 1);
view_combo_box = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
+ g_signal_connect(view_combo_box, "scroll-event",
G_CALLBACK(scroll_event_ignore), NULL);
gtk_combo_box_text_append(view_combo_box, "simple", "Simple");
gtk_combo_box_text_append(view_combo_box, "advanced", "Advanced");
gtk_widget_set_hexpand(GTK_WIDGET(view_combo_box), true);
@@ -2633,8 +2748,27 @@
gtk_combo_box_set_active(GTK_COMBO_BOX(view_combo_box), 0);
g_signal_connect(view_combo_box, "changed",
G_CALLBACK(view_combo_box_change_callback), view_combo_box);
- GtkFrame *record_area_frame = GTK_FRAME(gtk_frame_new("Record area"));
- gtk_grid_attach(grid, GTK_WIDGET(record_area_frame), 0, grid_row++, 2, 1);
+ GtkScrolledWindow *scrolled_window =
GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL));
+ gtk_scrolled_window_set_min_content_width(scrolled_window, 650);
+ gtk_scrolled_window_set_min_content_height(scrolled_window, 300);
+ gtk_scrolled_window_set_max_content_width(scrolled_window, 650);
+ gtk_scrolled_window_set_max_content_height(scrolled_window, 800);
+ gtk_scrolled_window_set_propagate_natural_width(scrolled_window, true);
+ gtk_scrolled_window_set_propagate_natural_height(scrolled_window, true);
+ gtk_grid_attach(main_grid, GTK_WIDGET(scrolled_window), 0,
main_grid_row++, 2, 1);
+
+ GtkGrid *grid = GTK_GRID(gtk_grid_new());
+ gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(grid));
+ gtk_widget_set_halign(GTK_WIDGET(grid), GTK_ALIGN_CENTER);
+ gtk_widget_set_valign(GTK_WIDGET(grid), GTK_ALIGN_START);
+ gtk_widget_set_vexpand(GTK_WIDGET(grid), true);
+ gtk_widget_set_hexpand(GTK_WIDGET(grid), true);
+ gtk_grid_set_row_spacing(grid, 10);
+ gtk_grid_set_column_spacing(grid, 10);
+ gtk_widget_set_margin(GTK_WIDGET(grid), 10, 10, 10, 10);
+
+ GtkFrame *capture_target_frame = GTK_FRAME(gtk_frame_new("Capture
target"));
+ gtk_grid_attach(grid, GTK_WIDGET(capture_target_frame), 0, grid_row++, 2,
1);
GtkGrid *record_area_grid = GTK_GRID(gtk_grid_new());
gtk_widget_set_vexpand(GTK_WIDGET(record_area_grid), false);
@@ -2642,7 +2776,7 @@
gtk_grid_set_row_spacing(record_area_grid, 10);
gtk_grid_set_column_spacing(record_area_grid, 10);
gtk_widget_set_margin(GTK_WIDGET(record_area_grid), 10, 10, 10, 10);
- gtk_container_add(GTK_CONTAINER(record_area_frame),
GTK_WIDGET(record_area_grid));
+ gtk_container_add(GTK_CONTAINER(capture_target_frame),
GTK_WIDGET(record_area_grid));
GtkListStore *store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
GtkTreeIter iter;
@@ -2717,6 +2851,7 @@
}
record_area_selection_menu =
GTK_COMBO_BOX(gtk_combo_box_new_with_model(record_area_selection_model));
+ g_signal_connect(record_area_selection_menu, "scroll-event",
G_CALLBACK(scroll_event_ignore), NULL);
GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(record_area_selection_menu),
renderer, TRUE);
@@ -2751,6 +2886,7 @@
gtk_grid_attach(area_size_grid, GTK_WIDGET(video_resolution_label), 0,
0, 3, 1);
area_width_entry = GTK_SPIN_BUTTON(gtk_spin_button_new_with_range(5.0,
10000.0, 1.0));
+ g_signal_connect(area_width_entry, "scroll-event",
G_CALLBACK(scroll_event_ignore), NULL);
gtk_spin_button_set_value(area_width_entry, 1920.0);
gtk_widget_set_hexpand(GTK_WIDGET(area_width_entry), true);
gtk_grid_attach(area_size_grid, GTK_WIDGET(area_width_entry), 0, 1, 1,
1);
@@ -2758,6 +2894,7 @@
gtk_grid_attach(area_size_grid, gtk_label_new("x"), 1, 1, 1, 1);
area_height_entry =
GTK_SPIN_BUTTON(gtk_spin_button_new_with_range(5.0, 10000.0, 1.0));
+ g_signal_connect(area_height_entry, "scroll-event",
G_CALLBACK(scroll_event_ignore), NULL);
gtk_spin_button_set_value(area_height_entry, 1080.0);
gtk_widget_set_hexpand(GTK_WIDGET(area_height_entry), true);
gtk_grid_attach(area_size_grid, GTK_WIDGET(area_height_entry), 2, 1,
1, 1);
@@ -2773,6 +2910,7 @@
gtk_grid_attach(video_resolution_grid,
GTK_WIDGET(video_resolution_label), 0, 0, 3, 1);
video_width_entry =
GTK_SPIN_BUTTON(gtk_spin_button_new_with_range(5.0, 10000.0, 1.0));
+ g_signal_connect(video_width_entry, "scroll-event",
G_CALLBACK(scroll_event_ignore), NULL);
gtk_spin_button_set_value(video_width_entry, 1920.0);
gtk_widget_set_hexpand(GTK_WIDGET(video_width_entry), true);
gtk_grid_attach(video_resolution_grid, GTK_WIDGET(video_width_entry),
0, 1, 1, 1);
@@ -2780,6 +2918,7 @@
gtk_grid_attach(video_resolution_grid, gtk_label_new("x"), 1, 1, 1, 1);
video_height_entry =
GTK_SPIN_BUTTON(gtk_spin_button_new_with_range(5.0, 10000.0, 1.0));
+ g_signal_connect(video_height_entry, "scroll-event",
G_CALLBACK(scroll_event_ignore), NULL);
gtk_spin_button_set_value(video_height_entry, 1080.0);
gtk_widget_set_hexpand(GTK_WIDGET(video_height_entry), true);
gtk_grid_attach(video_resolution_grid, GTK_WIDGET(video_height_entry),
2, 1, 1, 1);
@@ -2801,52 +2940,118 @@
gtk_widget_set_margin(GTK_WIDGET(audio_grid), 10, 10, 10, 10);
gtk_container_add(GTK_CONTAINER(audio_input_frame),
GTK_WIDGET(audio_grid));
- GtkGrid *add_audio_grid = GTK_GRID(gtk_grid_new());
- gtk_grid_set_row_spacing(add_audio_grid, 10);
- gtk_grid_set_column_spacing(add_audio_grid, 10);
- gtk_grid_attach(audio_grid, GTK_WIDGET(add_audio_grid), 0,
audio_input_area_row++, 1, 1);
-
- add_audio_input_button = gtk_button_new_with_label("Add audio track");
- gtk_grid_attach(add_audio_grid, add_audio_input_button, 0, 0, 1, 1);
- g_signal_connect(add_audio_input_button, "clicked",
G_CALLBACK(+[](GtkButton*, gpointer){
- GtkWidget *row = create_used_audio_input_row();
- gtk_widget_show_all(row);
- gtk_list_box_insert(GTK_LIST_BOX(audio_input_used_list), row, -1);
- return true;
- }), nullptr);
+ audio_type_radio_button_box =
GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10));
+ gtk_grid_attach(audio_grid, GTK_WIDGET(audio_type_radio_button_box), 0,
audio_input_area_row++, 2, 1);
+
+ audio_devices_radio_button =
gtk_radio_button_new_with_label_from_widget(nullptr, "Audio devices");
+ gtk_box_pack_start(audio_type_radio_button_box,
audio_devices_radio_button, false, false, 0);
+ g_signal_connect(audio_devices_radio_button, "toggled",
G_CALLBACK(audio_devices_application_audio_radio_toggled), nullptr);
+
+ application_audio_radio_button =
gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(audio_devices_radio_button),
"Application audio");
+ gtk_box_pack_start(audio_type_radio_button_box,
GTK_WIDGET(application_audio_radio_button), false, false, 0);
+ g_signal_connect(application_audio_radio_button, "toggled",
G_CALLBACK(audio_devices_application_audio_radio_toggled), nullptr);
+
+
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(audio_devices_radio_button),
true);
+
+ {
+ int audio_devices_row = 0;
+
+ audio_devices_grid = GTK_GRID(gtk_grid_new());
+ gtk_grid_set_row_spacing(audio_devices_grid, 10);
+ gtk_grid_set_column_spacing(audio_devices_grid, 10);
+ gtk_widget_set_margin(GTK_WIDGET(audio_devices_grid), 0, 0, 0, 0);
+ gtk_grid_attach(audio_grid, GTK_WIDGET(audio_devices_grid), 0,
audio_input_area_row++, 2, 1);
+
+ GtkGrid *add_audio_grid = GTK_GRID(gtk_grid_new());
+ gtk_grid_set_row_spacing(add_audio_grid, 10);
+ gtk_grid_set_column_spacing(add_audio_grid, 10);
+ gtk_grid_attach(audio_devices_grid, GTK_WIDGET(add_audio_grid), 0,
audio_devices_row++, 1, 1);
+
+ GtkWidget *add_audio_device_button = gtk_button_new_with_label("Add
audio device");
+ gtk_grid_attach(add_audio_grid, add_audio_device_button, 0, 0, 1, 1);
+ g_signal_connect(add_audio_device_button, "clicked",
G_CALLBACK(+[](GtkButton*, gpointer){
+ GtkWidget *row = create_audio_device_combo_box_row("");
+ gtk_widget_show_all(row);
+ gtk_box_pack_start(audio_devices_items_box, row, false, false, 0);
+ return true;
+ }), nullptr);
+
+ audio_devices_items_box =
GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL, 10));
+ gtk_grid_attach(audio_devices_grid,
GTK_WIDGET(audio_devices_items_box), 0, audio_devices_row++, 2, 1);
+ }
- audio_input_used_list = gtk_list_box_new();
- gtk_widget_set_hexpand (audio_input_used_list, TRUE);
- gtk_list_box_set_selection_mode (GTK_LIST_BOX (audio_input_used_list),
GTK_SELECTION_NONE);
- gtk_grid_attach(audio_grid, audio_input_used_list, 0,
audio_input_area_row++, 2, 1);
+ {
+ int application_audio_row = 0;
+
+ application_audio_grid = GTK_GRID(gtk_grid_new());
+ gtk_grid_set_row_spacing(application_audio_grid, 10);
+ gtk_grid_set_column_spacing(application_audio_grid, 10);
+ gtk_widget_set_margin(GTK_WIDGET(application_audio_grid), 0, 0, 0, 0);
+ gtk_grid_attach(audio_grid, GTK_WIDGET(application_audio_grid), 0,
audio_input_area_row++, 2, 1);
+
+ GtkGrid *add_button_grid = GTK_GRID(gtk_grid_new());
+ gtk_grid_set_column_spacing(add_button_grid, 10);
+ gtk_grid_attach(application_audio_grid, GTK_WIDGET(add_button_grid),
0, application_audio_row++, 2, 1);
+
+ GtkWidget *add_application_audio_button =
gtk_button_new_with_label("Add application audio");
+ gtk_grid_attach(add_button_grid, add_application_audio_button, 0, 0,
1, 1);
+ g_signal_connect(add_application_audio_button, "clicked",
G_CALLBACK(+[](GtkButton*, gpointer){
+ GtkWidget *row = create_application_audio_combo_box_row("");
+ gtk_widget_show_all(row);
+ gtk_box_pack_start(application_audio_items_box, row, false, false,
0);
+ return true;
+ }), nullptr);
+
+ GtkWidget *add_custom_application_audio_button =
gtk_button_new_with_label("Add custom application audio");
+ gtk_grid_attach(add_button_grid, add_custom_application_audio_button,
1, 0, 1, 1);
+ g_signal_connect(add_custom_application_audio_button, "clicked",
G_CALLBACK(+[](GtkButton*, gpointer){
+ GtkWidget *row = create_application_audio_custom_row("");
+ gtk_widget_show_all(row);
+ gtk_box_pack_start(application_audio_items_box, row, false, false,
0);
+ return true;
+ }), nullptr);
+
+ application_audio_items_box =
GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL, 10));
+ gtk_grid_attach(application_audio_grid,
GTK_WIDGET(application_audio_items_box), 0, application_audio_row++, 2, 1);
+
+ record_app_audio_inverted_button =
gtk_check_button_new_with_label("Record audio from all applications except the
selected ones");
+
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(record_app_audio_inverted_button),
false);
+ gtk_widget_set_halign(record_app_audio_inverted_button,
GTK_ALIGN_START);
+ gtk_grid_attach(application_audio_grid,
record_app_audio_inverted_button, 0, application_audio_row++, 2, 1);
+ }
merge_audio_tracks_button = gtk_check_button_new_with_label("Merge audio
tracks");
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(merge_audio_tracks_button),
true);
gtk_widget_set_halign(merge_audio_tracks_button, GTK_ALIGN_START);
gtk_grid_attach(audio_grid, merge_audio_tracks_button, 0,
audio_input_area_row++, 2, 1);
- GtkGrid *fps_grid = GTK_GRID(gtk_grid_new());
- gtk_grid_attach(grid, GTK_WIDGET(fps_grid), 0, grid_row++, 2, 1);
- gtk_grid_attach(fps_grid, gtk_label_new("Frame rate: "), 0, 0, 1, 1);
- fps_entry = GTK_SPIN_BUTTON(gtk_spin_button_new_with_range(1.0, 5000.0,
1.0));
- gtk_spin_button_set_value(fps_entry, 60.0);
- gtk_widget_set_hexpand(GTK_WIDGET(fps_entry), true);
- gtk_grid_attach(fps_grid, GTK_WIDGET(fps_entry), 1, 0, 1, 1);
+ audio_codec_grid = GTK_GRID(gtk_grid_new());
+ gtk_grid_attach(audio_grid, GTK_WIDGET(audio_codec_grid), 0,
audio_input_area_row++, 2, 1);
+ gtk_grid_attach(audio_codec_grid, gtk_label_new("Audio codec: "), 0, 0, 1,
1);
+ audio_codec_input_menu = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
+ g_signal_connect(audio_codec_input_menu, "scroll-event",
G_CALLBACK(scroll_event_ignore), NULL);
+ gtk_combo_box_text_append(audio_codec_input_menu, "opus", "Opus
(Recommended)");
+ gtk_combo_box_text_append(audio_codec_input_menu, "aac", "AAC");
+ gtk_widget_set_hexpand(GTK_WIDGET(audio_codec_input_menu), true);
+ gtk_grid_attach(audio_codec_grid, GTK_WIDGET(audio_codec_input_menu), 1,
0, 1, 1);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(audio_codec_input_menu), 0);
- color_range_grid = GTK_GRID(gtk_grid_new());
- gtk_grid_attach(grid, GTK_WIDGET(color_range_grid), 0, grid_row++, 2, 1);
- gtk_grid_attach(color_range_grid, gtk_label_new("Color range: "), 0, 0, 1,
1);
- color_range_input_menu = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
- gtk_combo_box_text_append(color_range_input_menu, "limited", "Limited");
- gtk_combo_box_text_append(color_range_input_menu, "full", "Full");
- gtk_widget_set_hexpand(GTK_WIDGET(color_range_input_menu), true);
- gtk_grid_attach(color_range_grid, GTK_WIDGET(color_range_input_menu), 1,
0, 1, 1);
- gtk_combo_box_set_active(GTK_COMBO_BOX(color_range_input_menu), 0);
+ GtkFrame *video_input_frame = GTK_FRAME(gtk_frame_new("Video"));
+ gtk_grid_attach(grid, GTK_WIDGET(video_input_frame), 0, grid_row++, 2, 1);
+
+ GtkGrid *video_grid = GTK_GRID(gtk_grid_new());
+ gtk_widget_set_vexpand(GTK_WIDGET(video_grid), false);
+ gtk_widget_set_hexpand(GTK_WIDGET(video_grid), true);
+ gtk_grid_set_row_spacing(video_grid, 10);
+ gtk_grid_set_column_spacing(video_grid, 10);
+ gtk_widget_set_margin(GTK_WIDGET(video_grid), 10, 10, 10, 10);
+ gtk_container_add(GTK_CONTAINER(video_input_frame),
GTK_WIDGET(video_grid));
GtkGrid *video_quality_grid = GTK_GRID(gtk_grid_new());
- gtk_grid_attach(grid, GTK_WIDGET(video_quality_grid), 0, grid_row++, 2, 1);
+ gtk_grid_attach(video_grid, GTK_WIDGET(video_quality_grid), 0,
video_input_area_row++, 2, 1);
gtk_grid_attach(video_quality_grid, gtk_label_new("Video quality: "), 0,
0, 1, 1);
quality_input_menu = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
+ g_signal_connect(quality_input_menu, "scroll-event",
G_CALLBACK(scroll_event_ignore), NULL);
gtk_combo_box_text_append(quality_input_menu, "custom", "Constant bitrate
(Recommended for live streaming and replay)");
gtk_combo_box_text_append(quality_input_menu, "medium", "Medium");
gtk_combo_box_text_append(quality_input_menu, "high", "High");
@@ -2858,15 +3063,16 @@
g_signal_connect(quality_input_menu, "changed",
G_CALLBACK(quality_combo_box_change_callback), quality_input_menu);
video_bitrate_grid = GTK_GRID(gtk_grid_new());
- gtk_grid_attach(grid, GTK_WIDGET(video_bitrate_grid), 0, grid_row++, 2, 1);
+ gtk_grid_attach(video_grid, GTK_WIDGET(video_bitrate_grid), 0,
video_input_area_row++, 2, 1);
gtk_grid_attach(video_bitrate_grid, gtk_label_new("Video bitrate (kbps):
"), 0, 0, 1, 1);
video_bitrate_entry = GTK_SPIN_BUTTON(gtk_spin_button_new_with_range(1.0,
500000.0, 1.0));
+ g_signal_connect(video_bitrate_entry, "scroll-event",
G_CALLBACK(scroll_event_ignore), NULL);
gtk_spin_button_set_value(video_bitrate_entry, 15000.0);
gtk_widget_set_hexpand(GTK_WIDGET(video_bitrate_entry), true);
gtk_grid_attach(video_bitrate_grid, GTK_WIDGET(video_bitrate_entry), 1, 0,
1, 1);
video_codec_grid = GTK_GRID(gtk_grid_new());
- gtk_grid_attach(grid, GTK_WIDGET(video_codec_grid), 0, grid_row++, 2, 1);
+ gtk_grid_attach(video_grid, GTK_WIDGET(video_codec_grid), 0,
video_input_area_row++, 2, 1);
gtk_grid_attach(video_codec_grid, gtk_label_new("Video codec: "), 0, 0, 1,
1);
{
@@ -2928,6 +3134,7 @@
gtk_list_store_set(store, &iter, 1, "h264_software", -1);
video_codec_selection_menu =
GTK_COMBO_BOX(gtk_combo_box_new_with_model(video_codec_selection_model));
+ g_signal_connect(video_codec_selection_menu, "scroll-event",
G_CALLBACK(scroll_event_ignore), NULL);
renderer = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(video_codec_selection_menu),
renderer, TRUE);
@@ -2940,20 +3147,31 @@
gtk_grid_attach(video_codec_grid,
GTK_WIDGET(video_codec_selection_menu), 1, 0, 1, 1);
}
- audio_codec_grid = GTK_GRID(gtk_grid_new());
- gtk_grid_attach(grid, GTK_WIDGET(audio_codec_grid), 0, grid_row++, 2, 1);
- gtk_grid_attach(audio_codec_grid, gtk_label_new("Audio codec: "), 0, 0, 1,
1);
- audio_codec_input_menu = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
- gtk_combo_box_text_append(audio_codec_input_menu, "opus", "Opus
(Recommended)");
- gtk_combo_box_text_append(audio_codec_input_menu, "aac", "AAC");
- gtk_widget_set_hexpand(GTK_WIDGET(audio_codec_input_menu), true);
- gtk_grid_attach(audio_codec_grid, GTK_WIDGET(audio_codec_input_menu), 1,
0, 1, 1);
- gtk_combo_box_set_active(GTK_COMBO_BOX(audio_codec_input_menu), 0);
+ color_range_grid = GTK_GRID(gtk_grid_new());
+ gtk_grid_attach(video_grid, GTK_WIDGET(color_range_grid), 0,
video_input_area_row++, 2, 1);
+ gtk_grid_attach(color_range_grid, gtk_label_new("Color range: "), 0, 0, 1,
1);
+ color_range_input_menu = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
+ g_signal_connect(color_range_input_menu, "scroll-event",
G_CALLBACK(scroll_event_ignore), NULL);
+ gtk_combo_box_text_append(color_range_input_menu, "limited", "Limited");
+ gtk_combo_box_text_append(color_range_input_menu, "full", "Full");
+ gtk_widget_set_hexpand(GTK_WIDGET(color_range_input_menu), true);
+ gtk_grid_attach(color_range_grid, GTK_WIDGET(color_range_input_menu), 1,
0, 1, 1);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(color_range_input_menu), 0);
+
+ GtkGrid *fps_grid = GTK_GRID(gtk_grid_new());
+ gtk_grid_attach(video_grid, GTK_WIDGET(fps_grid), 0,
video_input_area_row++, 2, 1);
+ gtk_grid_attach(fps_grid, gtk_label_new("Frame rate: "), 0, 0, 1, 1);
+ fps_entry = GTK_SPIN_BUTTON(gtk_spin_button_new_with_range(1.0, 5000.0,
1.0));
+ g_signal_connect(fps_entry, "scroll-event",
G_CALLBACK(scroll_event_ignore), NULL);
+ gtk_spin_button_set_value(fps_entry, 60.0);
+ gtk_widget_set_hexpand(GTK_WIDGET(fps_entry), true);
+ gtk_grid_attach(fps_grid, GTK_WIDGET(fps_entry), 1, 0, 1, 1);
framerate_mode_grid = GTK_GRID(gtk_grid_new());
- gtk_grid_attach(grid, GTK_WIDGET(framerate_mode_grid), 0, grid_row++, 2,
1);
+ gtk_grid_attach(video_grid, GTK_WIDGET(framerate_mode_grid), 0,
video_input_area_row++, 2, 1);
gtk_grid_attach(framerate_mode_grid, gtk_label_new("Frame rate mode: "),
0, 0, 1, 1);
framerate_mode_input_menu = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
+ g_signal_connect(framerate_mode_input_menu, "scroll-event",
G_CALLBACK(scroll_event_ignore), NULL);
gtk_combo_box_text_append(framerate_mode_input_menu, "auto", "Auto
(Recommended)");
gtk_combo_box_text_append(framerate_mode_input_menu, "cfr", "Constant");
gtk_combo_box_text_append(framerate_mode_input_menu, "vfr", "Variable");
@@ -2962,7 +3180,7 @@
gtk_combo_box_set_active(GTK_COMBO_BOX(framerate_mode_input_menu), 0);
overclock_grid = GTK_GRID(gtk_grid_new());
- gtk_grid_attach(grid, GTK_WIDGET(overclock_grid), 0, grid_row++, 2, 1);
+ gtk_grid_attach(video_grid, GTK_WIDGET(overclock_grid), 0,
video_input_area_row++, 2, 1);
overclock_button = gtk_check_button_new_with_label("Overclock memory
transfer rate to workaround NVIDIA driver performance bug");
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(overclock_button), false);
gtk_widget_set_halign(overclock_button, GTK_ALIGN_START);
@@ -2991,22 +3209,33 @@
record_cursor_button = gtk_check_button_new_with_label("Record cursor");
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(record_cursor_button),
true);
gtk_widget_set_halign(record_cursor_button, GTK_ALIGN_START);
- gtk_grid_attach(grid, record_cursor_button, 0, grid_row++, 2, 1);
+ gtk_grid_attach(video_grid, record_cursor_button, 0,
video_input_area_row++, 2, 1);
+
+ notifications_frame = GTK_FRAME(gtk_frame_new("Notifications"));
+ gtk_grid_attach(grid, GTK_WIDGET(notifications_frame), 0, grid_row++, 2,
1);
+
+ GtkGrid *notifications_grid = GTK_GRID(gtk_grid_new());
+ gtk_widget_set_vexpand(GTK_WIDGET(notifications_grid), false);
+ gtk_widget_set_hexpand(GTK_WIDGET(notifications_grid), true);
+ gtk_grid_set_row_spacing(notifications_grid, 10);
+ gtk_grid_set_column_spacing(notifications_grid, 10);
+ gtk_widget_set_margin(GTK_WIDGET(notifications_grid), 10, 10, 10, 10);
+ gtk_container_add(GTK_CONTAINER(notifications_frame),
GTK_WIDGET(notifications_grid));
show_recording_started_notification_button =
gtk_check_button_new_with_label("Show recording/streaming/replay started
notification");
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(show_recording_started_notification_button),
false);
gtk_widget_set_halign(show_recording_started_notification_button,
GTK_ALIGN_START);
- gtk_grid_attach(grid, show_recording_started_notification_button, 0,
grid_row++, 2, 1);
+ gtk_grid_attach(notifications_grid,
show_recording_started_notification_button, 0, notifications_area_row++, 2, 1);
show_recording_stopped_notification_button =
gtk_check_button_new_with_label("Show streaming/replay stopped notification");
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(show_recording_stopped_notification_button),
false);
gtk_widget_set_halign(show_recording_stopped_notification_button,
GTK_ALIGN_START);
- gtk_grid_attach(grid, show_recording_stopped_notification_button, 0,
grid_row++, 2, 1);
+ gtk_grid_attach(notifications_grid,
show_recording_stopped_notification_button, 0, notifications_area_row++, 2, 1);
show_recording_saved_notification_button =
gtk_check_button_new_with_label("Show video saved notification");
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(show_recording_saved_notification_button),
true);
gtk_widget_set_halign(show_recording_saved_notification_button,
GTK_ALIGN_START);
- gtk_grid_attach(grid, show_recording_saved_notification_button, 0,
grid_row++, 2, 1);
+ gtk_grid_attach(notifications_grid,
show_recording_saved_notification_button, 0, notifications_area_row++, 2, 1);
GtkGrid *start_button_grid = GTK_GRID(gtk_grid_new());
gtk_grid_attach(grid, GTK_WIDGET(start_button_grid), 0, grid_row++, 2, 1);
@@ -3040,7 +3269,7 @@
gtk_widget_set_sensitive(GTK_WIDGET(record_button), false);
gtk_widget_set_sensitive(GTK_WIDGET(stream_button), false);
- return GTK_WIDGET(grid);
+ return GTK_WIDGET(main_grid);
}
static void replace_meta_with_super(std::string &str) {
@@ -3218,6 +3447,7 @@
gtk_grid_attach(grid, GTK_WIDGET(container_grid), 0, row++, num_columns,
1);
gtk_grid_attach(container_grid, gtk_label_new("Container: "), 0, 0, 1, 1);
replay_container = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
+ g_signal_connect(replay_container, "scroll-event",
G_CALLBACK(scroll_event_ignore), NULL);
for(auto &supported_container : supported_containers) {
gtk_combo_box_text_append(replay_container,
supported_container.container_name, supported_container.file_extension);
}
@@ -3232,6 +3462,7 @@
gtk_grid_attach(grid, GTK_WIDGET(replay_time_grid), 0, row++, num_columns,
1);
gtk_grid_attach(replay_time_grid, gtk_label_new("Replay time in seconds:
"), 0, 0, 1, 1);
replay_time_entry = GTK_SPIN_BUTTON(gtk_spin_button_new_with_range(5.0,
1200.0, 1.0));
+ g_signal_connect(replay_time_entry, "scroll-event",
G_CALLBACK(scroll_event_ignore), NULL);
gtk_spin_button_set_value(replay_time_entry, 30.0);
gtk_widget_set_hexpand(GTK_WIDGET(replay_time_entry), true);
gtk_grid_attach(replay_time_grid, GTK_WIDGET(replay_time_entry), 1, 0, 1,
1);
@@ -3385,6 +3616,7 @@
gtk_grid_attach(grid, GTK_WIDGET(container_grid), 0, row++, num_columns,
1);
gtk_grid_attach(container_grid, gtk_label_new("Container: "), 0, 0, 1, 1);
record_container = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
+ g_signal_connect(record_container, "scroll-event",
G_CALLBACK(scroll_event_ignore), NULL);
for(auto &supported_container : supported_containers) {
gtk_combo_box_text_append(record_container,
supported_container.container_name, supported_container.file_extension);
}
@@ -3520,6 +3752,7 @@
gtk_grid_attach(grid, GTK_WIDGET(stream_service_grid), 0, row++,
num_columns, 1);
gtk_grid_attach(stream_service_grid, gtk_label_new("Stream service: "), 0,
0, 1, 1);
stream_service_input_menu = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
+ g_signal_connect(stream_service_input_menu, "scroll-event",
G_CALLBACK(scroll_event_ignore), NULL);
gtk_combo_box_text_append(stream_service_input_menu, "twitch", "Twitch");
gtk_combo_box_text_append(stream_service_input_menu, "youtube", "Youtube");
gtk_combo_box_text_append(stream_service_input_menu, "custom", "Custom");
@@ -3550,6 +3783,7 @@
gtk_grid_attach(grid, GTK_WIDGET(custom_stream_container_grid), 0, row++,
num_columns, 1);
gtk_grid_attach(custom_stream_container_grid, gtk_label_new("Container:
"), 0, 0, 1, 1);
custom_stream_container = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
+ g_signal_connect(custom_stream_container, "scroll-event",
G_CALLBACK(scroll_event_ignore), NULL);
for(auto &supported_container : supported_containers) {
gtk_combo_box_text_append(custom_stream_container,
supported_container.container_name, supported_container.file_extension);
}
@@ -3692,17 +3926,12 @@
return G_SOURCE_CONTINUE;
}
-static void add_audio_input_track(const char *name) {
- GtkWidget *row = create_used_audio_input_row();
-
- const AudioRow *audio_row = (AudioRow*)g_object_get_data(G_OBJECT(row),
"audio-row");
- std::string audio_id;
- gint target_combo_box_index =
combo_box_text_get_row_by_label(GTK_COMBO_BOX(audio_row->input_list), name,
audio_id);
- if(target_combo_box_index != -1)
- gtk_combo_box_set_active(GTK_COMBO_BOX(audio_row->input_list),
target_combo_box_index);
-
- gtk_widget_show_all(row);
- gtk_list_box_insert (GTK_LIST_BOX(audio_input_used_list), row, -1);
+static const std::string* get_application_audio_by_name_case_insensitive(const
std::vector<std::string> &application_audio, const std::string &name) {
+ for(const auto &app_audio : application_audio) {
+ if(strcasecmp(app_audio.c_str(), name.c_str()) == 0)
+ return &app_audio;
+ }
+ return nullptr;
}
static void load_config() {
@@ -3800,14 +4029,32 @@
gtk_spin_button_set_value(fps_entry, config.main_config.fps);
gtk_spin_button_set_value(video_bitrate_entry,
config.main_config.video_bitrate);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(merge_audio_tracks_button),
config.main_config.merge_audio_tracks);
+
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(record_app_audio_inverted_button),
config.main_config.record_app_audio_inverted);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(change_video_resolution_button),
config.main_config.change_video_resolution);
for(const std::string &audio_input : config.main_config.audio_input) {
- add_audio_input_track(audio_input.c_str());
+ GtkWidget *row = create_audio_device_combo_box_row(audio_input);
+ gtk_widget_show_all(row);
+ gtk_box_pack_start(audio_devices_items_box, row, false, false, 0);
+ }
+
+ if(config_empty && config.main_config.audio_input.empty()) {
+ GtkWidget *row = create_audio_device_combo_box_row("Default output");
+ gtk_widget_show_all(row);
+ gtk_box_pack_start(audio_devices_items_box, row, false, false, 0);
}
- if(config_empty && config.main_config.audio_input.empty())
- add_audio_input_track("Default output");
+ for(const std::string &app_audio : config.main_config.application_audio) {
+ const std::string *app_audio_existing =
get_application_audio_by_name_case_insensitive(application_audio, app_audio);
+ GtkWidget *row = nullptr;
+ if(app_audio_existing)
+ row = create_application_audio_combo_box_row(*app_audio_existing);
+ else
+ row = create_application_audio_custom_row(app_audio);
+
+ gtk_widget_show_all(row);
+ gtk_box_pack_start(application_audio_items_box, row, false, false, 0);
+ }
gtk_combo_box_set_active_id(GTK_COMBO_BOX(color_range_input_menu),
config.main_config.color_range.c_str());
gtk_combo_box_set_active_id(GTK_COMBO_BOX(quality_input_menu),
config.main_config.quality.c_str());
@@ -3858,6 +4105,19 @@
on_change_video_resolution_button_click(GTK_BUTTON(change_video_resolution_button),
nullptr);
+ if(!gsr_info.system_info.supports_app_audio) {
+ gtk_widget_set_visible(GTK_WIDGET(audio_type_radio_button_box), false);
+ gtk_widget_set_visible(GTK_WIDGET(application_audio_grid), false);
+ }
+
+ if(config.main_config.audio_type_view == "app_audio" &&
gsr_info.system_info.supports_app_audio) {
+
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(application_audio_radio_button),
true);
+
audio_devices_application_audio_radio_toggled(GTK_BUTTON(application_audio_radio_button),
nullptr);
+ } else /*if(config.main_config.audio_type_view == "audio_devices") */{
+
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(audio_devices_radio_button),
true);
+
audio_devices_application_audio_radio_toggled(GTK_BUTTON(audio_devices_radio_button),
nullptr);
+ }
+
std::string dummy;
if(!config.main_config.software_encoding_warning_shown &&
!switch_video_codec_to_usable_hardware_encoder(dummy)) {
GtkWidget *dialog =
gtk_message_dialog_new_with_markup(GTK_WINDOW(window), GTK_DIALOG_MODAL,
GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
@@ -4004,8 +4264,24 @@
gtk_window_set_title(GTK_WINDOW(window), window_title.c_str());
gtk_window_set_resizable(GTK_WINDOW(window), false);
+ GtkIconTheme *icon_theme = gtk_icon_theme_get_default();
+#ifdef GSR_ICONS_PATH
+ const char *icon_path = GSR_ICONS_PATH;
+#else
+ const char *icon_path = "/usr/share/icons";
+#endif
+ gtk_icon_theme_set_search_path(icon_theme, &icon_path, 1);
+
+ const char *icon_name = "com.dec05eba.gpu_screen_recorder";
+ if(!gtk_icon_theme_has_icon(icon_theme, icon_name))
+ fprintf(stderr, "Error: failed to find icon %s in %s\n", icon_name,
icon_path);
+
+ gtk_window_set_default_icon_name(icon_name);
+ gtk_window_set_icon_name(GTK_WINDOW(window), icon_name);
+
select_window_userdata.app = app;
audio_inputs = get_audio_devices();
+ application_audio = get_application_audio();
if(gsr_info.system_info.display_server != DisplayServer::WAYLAND)
crosshair_cursor = XCreateFontCursor(gdk_x11_get_default_xdisplay(),
XC_crosshair);
@@ -4092,7 +4368,12 @@
}
}
- GtkApplication *app =
gtk_application_new("com.dec05eba.gpu_screen_recorder",
G_APPLICATION_NON_UNIQUE);
+ char app_id[] = "com.dec05eba.gpu_screen_recorder";
+ // Gtk sets wayland app id / x11 wm class from the binary name, so we
override it here.
+ // This is needed for the correct window icon on wayland (app id needs to
match the desktop file name).
+ argv[0] = app_id;
+
+ GtkApplication *app = gtk_application_new(app_id,
G_APPLICATION_NON_UNIQUE);
g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
int status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);