From 81ed121cf6e65424227ca191346c0ca0d38a4d48 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Tue, 1 Feb 2022 05:27:55 +0200 Subject: [PATCH 41/41] gtk: Pause audio when the client loses focus See osdn #43750 Signed-off-by: Marko Lindqvist --- client/gui-gtk-3.22/gui_main.c | 37 +++++++++++++++++++++++++++++++++ client/gui-gtk-3.22/gui_main.h | 3 +++ client/gui-gtk-3.22/gui_stuff.c | 4 ++++ client/gui-gtk-4.0/gui_main.c | 37 +++++++++++++++++++++++++++++++++ client/gui-gtk-4.0/gui_main.h | 3 +++ client/gui-gtk-4.0/gui_stuff.c | 4 ++++ 6 files changed, 88 insertions(+) diff --git a/client/gui-gtk-3.22/gui_main.c b/client/gui-gtk-3.22/gui_main.c index b1c3d866ae..c56452a53e 100644 --- a/client/gui-gtk-3.22/gui_main.c +++ b/client/gui-gtk-3.22/gui_main.c @@ -61,6 +61,7 @@ #include "version.h" /* client */ +#include "audio.h" #include "client_main.h" #include "climisc.h" #include "clinet.h" @@ -184,6 +185,9 @@ gint cur_x, cur_y; static bool gui_up = FALSE; +static bool audio_paused = FALSE; +static bool client_focus = TRUE; + static struct video_mode vmode = { -1, -1 }; static gboolean show_info_button_release(GtkWidget *w, GdkEventButton *ev, gpointer data); @@ -237,6 +241,14 @@ static gboolean timer_callback(gpointer data) { double seconds = real_timer_callback(); + if (!audio_paused && !client_focus) { + audio_pause(); + audio_paused = TRUE; + } else if (audio_paused && client_focus) { + audio_resume(); + audio_paused = FALSE; + } + timer_id = g_timeout_add(seconds * 1000, timer_callback, NULL); return FALSE; @@ -762,6 +774,26 @@ static gboolean mouse_scroll_mapcanvas(GtkWidget *w, GdkEventScroll *ev) return TRUE; } +/**********************************************************************//** + Freeciv window has lost focus +**************************************************************************/ +gboolean fc_lost_focus(GtkWidget *w, GdkEventKey *ev, gpointer data) +{ + client_focus = FALSE; + + return TRUE; +} + +/**********************************************************************//** + Freeciv window has gained focus +**************************************************************************/ +gboolean fc_gained_focus(GtkWidget *w, GdkEventKey *ev, gpointer data) +{ + client_focus = TRUE; + + return TRUE; +} + /**********************************************************************//** Reattaches the detached widget when the user destroys it. **************************************************************************/ @@ -1827,6 +1859,11 @@ void ui_main(int argc, char **argv) g_signal_connect(toplevel, "key_press_event", G_CALLBACK(toplevel_handler), NULL); + g_signal_connect(toplevel, "focus_out_event", + G_CALLBACK(fc_lost_focus), NULL); + g_signal_connect(toplevel, "focus_in_event", + G_CALLBACK(fc_gained_focus), NULL); + gtk_window_set_role(GTK_WINDOW(toplevel), "toplevel"); gtk_widget_realize(toplevel); gtk_widget_set_name(toplevel, "Freeciv"); diff --git a/client/gui-gtk-3.22/gui_main.h b/client/gui-gtk-3.22/gui_main.h index 9c107186e7..ebdc8c9205 100644 --- a/client/gui-gtk-3.22/gui_main.h +++ b/client/gui-gtk-3.22/gui_main.h @@ -85,4 +85,7 @@ struct video_mode *resolution_request_get(void); bool is_gui_up(void); +gboolean fc_lost_focus(GtkWidget *w, GdkEventKey *ev, gpointer data); +gboolean fc_gained_focus(GtkWidget *w, GdkEventKey *ev, gpointer data); + #endif /* FC__GUI_MAIN_H */ diff --git a/client/gui-gtk-3.22/gui_stuff.c b/client/gui-gtk-3.22/gui_stuff.c index cf9f38fedf..3abfb4c940 100644 --- a/client/gui-gtk-3.22/gui_stuff.c +++ b/client/gui-gtk-3.22/gui_stuff.c @@ -298,6 +298,10 @@ void setup_dialog(GtkWidget *shell, GtkWidget *parent) /* Close dialog window on Escape keypress. */ if (GTK_IS_DIALOG(shell)) { + g_signal_connect(shell, "focus_out_event", + G_CALLBACK(fc_lost_focus), NULL); + g_signal_connect(shell, "focus_in_event", + G_CALLBACK(fc_gained_focus), NULL); g_signal_connect_after(shell, "close", G_CALLBACK(close_callback), shell); } } diff --git a/client/gui-gtk-4.0/gui_main.c b/client/gui-gtk-4.0/gui_main.c index ec2deaca48..a5356b18e1 100644 --- a/client/gui-gtk-4.0/gui_main.c +++ b/client/gui-gtk-4.0/gui_main.c @@ -61,6 +61,7 @@ #include "version.h" /* client */ +#include "audio.h" #include "client_main.h" #include "climisc.h" #include "clinet.h" @@ -176,6 +177,9 @@ gint cur_x, cur_y; static bool gui_up = FALSE; +static bool audio_paused = FALSE; +static bool client_focus = TRUE; + static GtkApplication *fc_app; static struct video_mode vmode = { -1, -1 }; @@ -230,6 +234,14 @@ static gboolean timer_callback(gpointer data) { double seconds = real_timer_callback(); + if (!audio_paused && !client_focus) { + audio_pause(); + audio_paused = TRUE; + } else if (audio_paused && client_focus) { + audio_resume(); + audio_paused = FALSE; + } + timer_id = g_timeout_add(seconds * 1000, timer_callback, NULL); return FALSE; @@ -753,6 +765,26 @@ static void move_from_container_to_container(GtkWidget *wdg, g_object_unref(wdg); } +/**********************************************************************//** + Freeciv window has lost focus +**************************************************************************/ +gboolean fc_lost_focus(GtkWidget *w, GdkEvent *ev, gpointer data) +{ + client_focus = FALSE; + + return TRUE; +} + +/**********************************************************************//** + Freeciv window has gained focus +**************************************************************************/ +gboolean fc_gained_focus(GtkWidget *w, GdkEvent *ev, gpointer data) +{ + client_focus = TRUE; + + return TRUE; +} + /**********************************************************************//** Reattaches the detached widget when the user destroys it. **************************************************************************/ @@ -1850,6 +1882,11 @@ static void activate_gui(GtkApplication *app, gpointer data) vmode.width, vmode.height); } + g_signal_connect(toplevel, "focus_out_event", + G_CALLBACK(fc_lost_focus), NULL); + g_signal_connect(toplevel, "focus_in_event", + G_CALLBACK(fc_gained_focus), NULL); + gtk_widget_realize(toplevel); gtk_widget_set_name(toplevel, "Freeciv"); diff --git a/client/gui-gtk-4.0/gui_main.h b/client/gui-gtk-4.0/gui_main.h index 5a1db0b3ac..ec3e112f0d 100644 --- a/client/gui-gtk-4.0/gui_main.h +++ b/client/gui-gtk-4.0/gui_main.h @@ -82,4 +82,7 @@ bool is_gui_up(void); bool terminate_signal_processing(void); +gboolean fc_lost_focus(GtkWidget *w, GdkEvent *ev, gpointer data); +gboolean fc_gained_focus(GtkWidget *w, GdkEvent *ev, gpointer data); + #endif /* FC__GUI_MAIN_H */ diff --git a/client/gui-gtk-4.0/gui_stuff.c b/client/gui-gtk-4.0/gui_stuff.c index b3ed48b6f3..8d79b32a74 100644 --- a/client/gui-gtk-4.0/gui_stuff.c +++ b/client/gui-gtk-4.0/gui_stuff.c @@ -278,6 +278,10 @@ void setup_dialog(GtkWidget *shell, GtkWidget *parent) /* Close dialog window on Escape keypress. */ if (GTK_IS_DIALOG(shell)) { + g_signal_connect(shell, "focus_out_event", + G_CALLBACK(fc_lost_focus), NULL); + g_signal_connect(shell, "focus_in_event", + G_CALLBACK(fc_gained_focus), NULL); g_signal_connect_after(shell, "close", G_CALLBACK(close_callback), shell); } } -- 2.34.1