diff --git a/.gitmodules b/.gitmodules index b909e7c..8560d1b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "subprojects/april-asr"] path = subprojects/april-asr - url = https://github.com/abb128/april-asr.git + url = https://github.com/Techlm77/april-asr.git diff --git a/meson.build b/meson.build index 8dfd7b3..89ac5de 100644 --- a/meson.build +++ b/meson.build @@ -1,9 +1,10 @@ -project('livecaptions', 'c', +project('livecaptions', 'c', 'cpp', version: '0.1.0', meson_version: '>= 0.59.0', default_options: [ 'warning_level=2', 'werror=false', 'c_std=gnu11', + 'cpp_std=c++17', ], ) diff --git a/src/asrproc.c b/src/asrproc.c index 5548f38..489fd9e 100644 --- a/src/asrproc.c +++ b/src/asrproc.c @@ -121,6 +121,9 @@ static void april_result_handler(void* userdata, AprilResultType result, size_t if((data->window == NULL) || (data->pause)) return; switch(result) { + case APRIL_RESULT_UNKNOWN: + break; + case APRIL_RESULT_RECOGNITION_PARTIAL: case APRIL_RESULT_RECOGNITION_FINAL: { @@ -257,7 +260,7 @@ bool asr_thread_update_model(asr_thread data, const char *model_path) { AprilConfig config = { .handler = april_result_handler, - .flags = APRIL_CONFIG_FLAG_ASYNC_RT_BIT, + .flags = APRIL_CONFIG_FLAG_ASYNC_NO_RT_BIT, .userdata = data }; diff --git a/src/audiocap-pa.c b/src/audiocap-pa.c index 14a7bfe..7d8da93 100644 --- a/src/audiocap-pa.c +++ b/src/audiocap-pa.c @@ -55,6 +55,7 @@ static void stream_success_cb(pa_stream *stream, int success, void *userdata); static void stream_read_cb(pa_stream *stream, size_t nbytes, void *userdata); static void server_info_callback(pa_context *c, const pa_server_info *i, void *userdata){ + (void)c; audio_thread_pa data = (audio_thread_pa)userdata; data->source_name = (char *)calloc(1, strlen(i->default_source_name) + 1); @@ -154,11 +155,13 @@ void *run_audio_thread_pa(void *userdata) { } static void context_state_cb(pa_context* context, void* userdata) { + (void)context; audio_thread_pa data = userdata; pa_threaded_mainloop_signal(data->mainloop, 0); } static void stream_state_cb(pa_stream *s, void *userdata) { + (void)s; audio_thread_pa data = userdata; pa_threaded_mainloop_signal(data->mainloop, 0); } @@ -196,6 +199,8 @@ static void stream_read_cb(pa_stream *stream, size_t nbytes, void *userdata) { } static void stream_success_cb(pa_stream *stream, int success, void *userdata) { + (void)stream; + (void)success; audio_thread_pa data = userdata; pa_threaded_mainloop_signal(data->mainloop, 0); } diff --git a/src/audiocap.c b/src/audiocap.c index 675f502..ab3f283 100644 --- a/src/audiocap.c +++ b/src/audiocap.c @@ -41,12 +41,6 @@ struct audio_thread_i { }; -static void *run_audio_thread(void *userdata) { - audio_thread data = (audio_thread)userdata; - - return NULL; -} - audio_thread create_audio_thread(bool microphone, asr_thread asr){ audio_thread data = calloc(1, sizeof(struct audio_thread_i)); diff --git a/src/history.c b/src/history.c index 5ca722a..7c21765 100644 --- a/src/history.c +++ b/src/history.c @@ -77,7 +77,7 @@ void commit_tokens_to_current_history(const AprilToken *tokens, struct history_token *token = &entry->tokens[i]; if(strlen(tokens[i].token) >= HISTORY_TOKEN_MAX_CHARS){ - printf("Token %s is too long! (%d)\n", tokens[i].token, strlen(tokens[i].token)); + printf("Token %s is too long! (%zu)\n", tokens[i].token, strlen(tokens[i].token)); g_assert(false); } diff --git a/src/line-gen.c b/src/line-gen.c index ddca228..4b26743 100644 --- a/src/line-gen.c +++ b/src/line-gen.c @@ -240,7 +240,7 @@ void line_generator_update(struct line_generator *lg, size_t num_tokens, const A // break line if too long if(i == lg->current_line){ curr->len += line_generator_get_text_width(lg, token); - if(curr->len >= lg->max_text_width) { + if (lg->max_text_width > 0 && curr->len >= (size_t)lg->max_text_width) { size_t tgt_brk = j; // find previous word boundary while((!(tokens[tgt_brk].flags & APRIL_TOKEN_FLAG_WORD_BOUNDARY_BIT)) && (tgt_brk > start_of_line)) tgt_brk--; @@ -342,7 +342,7 @@ const char *line_generator_get_plaintext(struct line_generator *lg) { } else { // HACK: We need to remove the tags bool inside_markup = false; - for(int j=0; jhead; j++) { + for(size_t j=0; jhead; j++) { if(curr->text[j] == '<') { inside_markup = true; continue; diff --git a/src/livecaptions-application.c b/src/livecaptions-application.c index 2517f2c..3428493 100644 --- a/src/livecaptions-application.c +++ b/src/livecaptions-application.c @@ -119,7 +119,7 @@ static gboolean on_handle_allow_keep_above(DBLCapNetSapplesLiveCaptionsExternal GDBusMethodInvocation *invocation, gpointer user_data) { - LiveCaptionsApplication *self = LIVECAPTIONS_APPLICATION(user_data); + (void)user_data; override_keep_above_system(true); @@ -130,7 +130,7 @@ static gboolean on_handle_allow_keep_above(DBLCapNetSapplesLiveCaptionsExternal static gboolean livecaptions_application_dbus_register(GApplication *app, GDBusConnection *connection, - const gchar *object_path, + G_GNUC_UNUSED const gchar *object_path, GError **error) { LiveCaptionsApplication *self = LIVECAPTIONS_APPLICATION(app); @@ -172,6 +172,8 @@ livecaptions_application_dbus_unregister(GApplication *app, GDBusConnection *connection, const gchar *object_path) { + (void)connection; + (void)object_path; LiveCaptionsApplication *self = LIVECAPTIONS_APPLICATION(app); g_dbus_interface_skeleton_unexport(G_DBUS_INTERFACE_SKELETON(self->dbus_external)); @@ -242,12 +244,11 @@ livecaptions_application_show_preferences(G_GNUC_UNUSED GSimpleAction *action, LiveCaptionsApplication *self = LIVECAPTIONS_APPLICATION(user_data); if(self->welcome != NULL) return; - GtkApplication *app = GTK_APPLICATION(user_data); - GtkWindow *window = gtk_application_get_active_window (app); - LiveCaptionsSettings *preferences = g_object_new(LIVECAPTIONS_TYPE_SETTINGS, "application", GTK_APPLICATION(self), NULL); + LiveCaptionsSettings *preferences = g_object_new(LIVECAPTIONS_TYPE_SETTINGS, NULL); preferences->application = self; - gtk_window_present (GTK_WINDOW (preferences)); + // No parent, so the preferences open in their own window instead of inside the captions bar + adw_dialog_present(ADW_DIALOG(preferences), NULL); } diff --git a/src/livecaptions-history-window.c b/src/livecaptions-history-window.c index 3f4edbd..275937a 100644 --- a/src/livecaptions-history-window.c +++ b/src/livecaptions-history-window.c @@ -39,7 +39,8 @@ static gboolean close_self_window(gpointer userdata) { return G_SOURCE_REMOVE; } -static void message_cb(AdwMessageDialog *dialog, gchar *response, gpointer userdata){ +static void message_cb(AdwAlertDialog *dialog, gchar *response, gpointer userdata){ + (void)dialog; if(g_str_equal(response, "delete")){ erase_all_history(); @@ -48,26 +49,24 @@ static void message_cb(AdwMessageDialog *dialog, gchar *response, gpointer userd } static void warn_deletion_cb(LiveCaptionsHistoryWindow *self){ - GtkWindow *parent = GTK_WINDOW(gtk_widget_get_root(GTK_WIDGET(self))); - GtkWidget *dialog; + AdwDialog *dialog; - dialog = adw_message_dialog_new(parent, - _("Erase History?"), - _("Everything in history will be erased. You may wish to export your history before erasing!")); + dialog = adw_alert_dialog_new(_("Erase History?"), + _("Everything in history will be erased. You may wish to export your history before erasing!")); - adw_message_dialog_add_responses(ADW_MESSAGE_DIALOG(dialog), - "cancel", _("_Cancel"), - "delete", _("_Erase Everything"), - NULL); + adw_alert_dialog_add_responses(ADW_ALERT_DIALOG(dialog), + "cancel", _("_Cancel"), + "delete", _("_Erase Everything"), + NULL); - adw_message_dialog_set_response_appearance(ADW_MESSAGE_DIALOG(dialog), "delete", ADW_RESPONSE_DESTRUCTIVE); + adw_alert_dialog_set_response_appearance(ADW_ALERT_DIALOG(dialog), "delete", ADW_RESPONSE_DESTRUCTIVE); - adw_message_dialog_set_default_response(ADW_MESSAGE_DIALOG(dialog), "cancel"); - adw_message_dialog_set_close_response(ADW_MESSAGE_DIALOG(dialog), "cancel"); + adw_alert_dialog_set_default_response(ADW_ALERT_DIALOG(dialog), "cancel"); + adw_alert_dialog_set_close_response(ADW_ALERT_DIALOG(dialog), "cancel"); - g_signal_connect(ADW_MESSAGE_DIALOG(dialog), "response", G_CALLBACK(message_cb), self); + g_signal_connect(ADW_ALERT_DIALOG(dialog), "response", G_CALLBACK(message_cb), self); - gtk_window_present(GTK_WINDOW(dialog)); + adw_dialog_present(dialog, GTK_WIDGET(self)); } @@ -232,50 +231,35 @@ static void load_more_cb(LiveCaptionsHistoryWindow *self) { } -static void on_save_response(GtkNativeDialog *native, - int response, - LiveCaptionsHistoryWindow *self) +static void on_save_response(GObject *source, + GAsyncResult *result, + gpointer user_data) { - if(response == GTK_RESPONSE_ACCEPT){ - GtkFileChooser *chooser = GTK_FILE_CHOOSER(native); + LiveCaptionsHistoryWindow *self = LIVECAPTIONS_HISTORY_WINDOW(user_data); - g_autoptr(GFile) file = gtk_file_chooser_get_file(chooser); - + g_autoptr(GFile) file = gtk_file_dialog_save_finish(GTK_FILE_DIALOG(source), result, NULL); + if(file != NULL){ char *path = g_file_get_path(file); export_history_as_text(path); - char *uri = g_file_get_uri(file); - - gtk_show_uri(GTK_WINDOW(self), uri, GDK_CURRENT_TIME); + g_autoptr(GtkFileLauncher) launcher = gtk_file_launcher_new(file); + gtk_file_launcher_launch(launcher, GTK_WINDOW(self), NULL, NULL, NULL); g_free(path); - g_free(uri); } - g_object_unref(native); + g_object_unref(self); } static void export_cb(LiveCaptionsHistoryWindow *self) { - GtkFileChooserNative *native; - GtkFileChooser *chooser; - GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_SAVE; - - native = gtk_file_chooser_native_new("Export History", - GTK_WINDOW(self), - action, - _("_Export"), - _("_Cancel")); - - chooser = GTK_FILE_CHOOSER(native); - - gtk_file_chooser_set_current_name(chooser, _("Live Captions History.txt")); + g_autoptr(GtkFileDialog) dialog = gtk_file_dialog_new(); - gtk_native_dialog_show(GTK_NATIVE_DIALOG(native)); + gtk_file_dialog_set_title(dialog, "Export History"); + gtk_file_dialog_set_accept_label(dialog, _("_Export")); + gtk_file_dialog_set_initial_name(dialog, _("Live Captions History.txt")); - g_signal_connect(native, "response", - G_CALLBACK (on_save_response), - self); + gtk_file_dialog_save(dialog, GTK_WINDOW(self), NULL, on_save_response, g_object_ref(self)); } // The window needs to be kept on top if the main window is kept on top, diff --git a/src/livecaptions-settings.c b/src/livecaptions-settings.c index d23a8ab..627f240 100644 --- a/src/livecaptions-settings.c +++ b/src/livecaptions-settings.c @@ -27,19 +27,16 @@ #include "livecaptions-history-window.h" #include "asrproc.h" -G_DEFINE_TYPE(LiveCaptionsSettings, livecaptions_settings, ADW_TYPE_PREFERENCES_WINDOW) +G_DEFINE_TYPE(LiveCaptionsSettings, livecaptions_settings, ADW_TYPE_PREFERENCES_DIALOG) static void rerun_benchmark_cb (LiveCaptionsSettings *self) { - gtk_window_close(GTK_WINDOW(self)); + g_action_group_activate_action(G_ACTION_GROUP(self->application), "setup", NULL); - gtk_widget_activate_action(GTK_WIDGET(self), "app.setup", NULL); - - gtk_window_destroy(GTK_WINDOW(self)); + adw_dialog_close(ADW_DIALOG(self)); } static void about_cb(LiveCaptionsSettings *self) { - GtkRoot *root = gtk_widget_get_root (GTK_WIDGET (self)); - GtkWidget *about; + AdwDialog *about; const char *developers[] = { "abb128", @@ -52,8 +49,7 @@ static void about_cb(LiveCaptionsSettings *self) { }; about = - g_object_new(ADW_TYPE_ABOUT_WINDOW, - "transient-for", root, + g_object_new(ADW_TYPE_ABOUT_DIALOG, "application-icon", "net.sapples.LiveCaptions", "application-name", _("Live Captions"), "developer-name", _("abb128"), @@ -67,69 +63,67 @@ static void about_cb(LiveCaptionsSettings *self) { "translator-credits", _("translator-credits"), NULL); - adw_about_window_add_legal_section(ADW_ABOUT_WINDOW(about), + adw_about_dialog_add_legal_section(ADW_ABOUT_DIALOG(about), _("Model"), NULL, GTK_LICENSE_CUSTOM, "The ASR model was originally trained by Fangjun Kuang (@csukuangfj), and has been finetuned on extra data."); - adw_about_window_add_legal_section(ADW_ABOUT_WINDOW(about), + adw_about_dialog_add_legal_section(ADW_ABOUT_DIALOG(about), "april-asr", "Copyright © 2022 abb128", GTK_LICENSE_GPL_3_0_ONLY, NULL); - adw_about_window_add_legal_section(ADW_ABOUT_WINDOW(about), + adw_about_dialog_add_legal_section(ADW_ABOUT_DIALOG(about), "ONNXRuntime", "Copyright © 2021 Microsoft Corporation", GTK_LICENSE_MIT_X11, NULL); - adw_about_window_add_legal_section(ADW_ABOUT_WINDOW(about), + adw_about_dialog_add_legal_section(ADW_ABOUT_DIALOG(about), "pocketfft", "Copyright © 2010-2019 Max-Planck-Society", GTK_LICENSE_BSD_3, NULL); - adw_about_window_add_legal_section(ADW_ABOUT_WINDOW(about), + adw_about_dialog_add_legal_section(ADW_ABOUT_DIALOG(about), "sonic", "Copyright © 2010 Bill Cox", GTK_LICENSE_APACHE_2_0, NULL); - adw_about_window_add_acknowledgement_section(ADW_ABOUT_WINDOW(about), + adw_about_dialog_add_acknowledgement_section(ADW_ABOUT_DIALOG(about), _("Special thanks to"), special_thanks); - gtk_window_present(GTK_WINDOW(about)); + adw_dialog_present(about, GTK_WIDGET(self)); +} + + +static GtkWindow *get_parent_window(LiveCaptionsSettings *self) { + return GTK_WINDOW(gtk_widget_get_root(GTK_WIDGET(self))); } +static void launch_uri(LiveCaptionsSettings *self, const char *uri) { + g_autoptr(GtkUriLauncher) launcher = gtk_uri_launcher_new(uri); + gtk_uri_launcher_launch(launcher, get_parent_window(self), NULL, NULL, NULL); +} static void report_cb(LiveCaptionsSettings *self) { - gtk_show_uri( - GTK_WINDOW(self), - "https://github.com/abb128/LiveCaptions/issues/48", - GDK_CURRENT_TIME - ); + launch_uri(self, "https://github.com/abb128/LiveCaptions/issues/48"); } static void download_models_cb(LiveCaptionsSettings *self) { - gtk_show_uri( - GTK_WINDOW(self), - "https://abb128.github.io/april-asr/models.html", - GDK_CURRENT_TIME - ); + launch_uri(self, "https://abb128.github.io/april-asr/models.html"); } static void open_history(LiveCaptionsSettings *self) { - GtkRoot *root = gtk_widget_get_root(GTK_WIDGET(self)); - - LiveCaptionsHistoryWindow *window = g_object_new(LIVECAPTIONS_TYPE_HISTORY_WINDOW, "transient-for", root, NULL); + LiveCaptionsHistoryWindow *window = g_object_new(LIVECAPTIONS_TYPE_HISTORY_WINDOW, "application", self->application, NULL); gtk_window_present(GTK_WINDOW(window)); - gtk_window_close(GTK_WINDOW(self)); - gtk_window_destroy(GTK_WINDOW(self)); + adw_dialog_close(ADW_DIALOG(self)); } static const char *get_always_on_top_tip_text(){ @@ -146,29 +140,18 @@ static const char *get_always_on_top_tip_text(){ } -static void on_add_model_response(GtkNativeDialog *native, - int response, - LiveCaptionsSettings *self); +static void on_add_model_response(GObject *source, + GAsyncResult *result, + gpointer user_data); static void add_model_cb(LiveCaptionsSettings *self) { - GtkFileChooserNative *native; - GtkFileChooser *chooser; - GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN; + g_autoptr(GtkFileDialog) dialog = gtk_file_dialog_new(); - native = gtk_file_chooser_native_new("Load Model", - GTK_WINDOW(self), - action, - _("_Load"), - _("_Cancel")); + gtk_file_dialog_set_title(dialog, "Load Model"); + gtk_file_dialog_set_accept_label(dialog, _("_Load")); + gtk_file_dialog_set_default_filter(dialog, self->file_filter); - chooser = GTK_FILE_CHOOSER(native); - gtk_file_chooser_add_filter(chooser, self->file_filter); - - gtk_native_dialog_show(GTK_NATIVE_DIALOG(native)); - - g_signal_connect(native, "response", - G_CALLBACK (on_add_model_response), - self); + gtk_file_dialog_open(dialog, get_parent_window(self), NULL, on_add_model_response, g_object_ref(self)); } static void on_builtin_toggled(LiveCaptionsSettings *self); @@ -217,7 +200,7 @@ static void livecaptions_settings_class_init(LiveCaptionsSettingsClass *klass) { static gboolean deferred_update_keep_above(void *userdata) { LiveCaptionsSettings *self = userdata; - set_window_keep_above(GTK_WINDOW(self), g_settings_get_boolean(self->settings, "keep-on-top")); + set_window_keep_above(get_parent_window(self), g_settings_get_boolean(self->settings, "keep-on-top")); return G_SOURCE_REMOVE; } @@ -226,7 +209,7 @@ static void model_load_failsafe(LiveCaptionsSettings *self, bool load_default); static void on_model_selected(GtkCheckButton* button, LiveCaptionsSettings *self){ if(!gtk_check_button_get_active(button)) return; - const char *model = g_quark_to_string((GQuark)g_object_get_data(G_OBJECT(button), "lcap-model-path")); + const char *model = g_quark_to_string(GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(button), "lcap-model-path"))); if(!asr_thread_update_model(self->application->asr, model)) { model_load_failsafe(self, false); return; @@ -244,7 +227,7 @@ static void on_builtin_toggled(LiveCaptionsSettings *self) { } static void on_model_deleted(GtkButton *button, LiveCaptionsSettings *self) { - const char *model = g_quark_to_string((GQuark)g_object_get_data(G_OBJECT(button), "lcap-model-path")); + const char *model = g_quark_to_string(GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(button), "lcap-model-path"))); if(g_str_equal(model, "/app/LiveCaptions/models/aprilv0_en-us.april")) return; char *active_model = g_settings_get_string(self->settings, "active-model"); @@ -306,7 +289,7 @@ static void insert_model_to_list(LiveCaptionsSettings *self, gchar *model) { g_free(active_model); - gpointer quark = (gpointer)g_quark_from_string(model); + gpointer quark = GUINT_TO_POINTER(g_quark_from_string(model)); g_object_set_data(G_OBJECT(button), "lcap-model-path", quark); g_signal_connect(button, "toggled", G_CALLBACK(on_model_selected), self); @@ -344,18 +327,10 @@ static void add_new_model(LiveCaptionsSettings *self, gchar *model) { } static void model_load_failsafe(LiveCaptionsSettings *self, bool load_default) { - GtkDialogFlags flags = GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL; - GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(self), - flags, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "Failed to load model!"); - - gtk_window_present(GTK_WINDOW(dialog)); + AdwDialog *dialog = adw_alert_dialog_new("Failed to load model!", NULL); + adw_alert_dialog_add_response(ADW_ALERT_DIALOG(dialog), "close", _("_Close")); - g_signal_connect(dialog, "response", - G_CALLBACK (gtk_window_destroy), - NULL); + adw_dialog_present(dialog, GTK_WIDGET(self)); char *prev_model; if(load_default) { @@ -369,15 +344,14 @@ static void model_load_failsafe(LiveCaptionsSettings *self, bool load_default) { if(load_default) gtk_check_button_set_active(self->radio_button_1, true); } -static void on_add_model_response(GtkNativeDialog *native, - int response, - LiveCaptionsSettings *self) +static void on_add_model_response(GObject *source, + GAsyncResult *result, + gpointer user_data) { - if(response == GTK_RESPONSE_ACCEPT){ - GtkFileChooser *chooser = GTK_FILE_CHOOSER(native); + LiveCaptionsSettings *self = LIVECAPTIONS_SETTINGS(user_data); - g_autoptr(GFile) file = gtk_file_chooser_get_file(chooser); - + g_autoptr(GFile) file = gtk_file_dialog_open_finish(GTK_FILE_DIALOG(source), result, NULL); + if(file != NULL){ char *model = g_file_get_path(file); @@ -385,7 +359,7 @@ static void on_add_model_response(GtkNativeDialog *native, model_load_failsafe(self, false); g_free(model); - g_object_unref(native); + g_object_unref(self); return; } @@ -398,7 +372,7 @@ static void on_add_model_response(GtkNativeDialog *native, g_free(model); } - g_object_unref(native); + g_object_unref(self); } static void livecaptions_settings_init(LiveCaptionsSettings *self) { @@ -427,7 +401,7 @@ static void livecaptions_settings_init(LiveCaptionsSettings *self) { sprintf(benchmark_result, "%.2f", (float)benchmark_result_v); gtk_label_set_text(self->benchmark_label, benchmark_result); - if(is_keep_above_supported(GTK_WINDOW(self))) { + if(is_keep_above_supported(GTK_WIDGET(self))) { g_settings_bind(self->settings, "keep-on-top", self->keep_above_switch, "active", G_SETTINGS_BIND_DEFAULT); gtk_widget_set_sensitive(GTK_WIDGET(self->keep_above_switch), true); diff --git a/src/livecaptions-settings.h b/src/livecaptions-settings.h index 0c68318..9ec5a74 100644 --- a/src/livecaptions-settings.h +++ b/src/livecaptions-settings.h @@ -22,7 +22,7 @@ #include "livecaptions-application.h" struct _LiveCaptionsSettings { - AdwPreferencesWindow parent_instance; + AdwPreferencesDialog parent_instance; LiveCaptionsApplication *application; @@ -59,6 +59,6 @@ G_BEGIN_DECLS #define LIVECAPTIONS_TYPE_SETTINGS (livecaptions_settings_get_type()) -G_DECLARE_FINAL_TYPE(LiveCaptionsSettings, livecaptions_settings, LIVECAPTIONS, SETTINGS, AdwPreferencesWindow) +G_DECLARE_FINAL_TYPE(LiveCaptionsSettings, livecaptions_settings, LIVECAPTIONS, SETTINGS, AdwPreferencesDialog) G_END_DECLS diff --git a/src/livecaptions-settings.ui b/src/livecaptions-settings.ui index 9f3ac91..d36e1ac 100644 --- a/src/livecaptions-settings.ui +++ b/src/livecaptions-settings.ui @@ -1,9 +1,8 @@ - -