diff --git a/libxapp/xapp-gtk-window.c b/libxapp/xapp-gtk-window.c index 413f779..ff0593d 100644 --- a/libxapp/xapp-gtk-window.c +++ b/libxapp/xapp-gtk-window.c @@ -230,3 +230,127 @@ gtk_window_set_icon_from_file (GTK_WINDOW (window), file_name, error); } +/* Wrappers (for GtkWindow subclasses like GtkDialog) + * window must be a GtkWindow or descendant */ + +static void +on_gtk_window_realized (GtkWidget *widget, + gpointer user_data) +{ + gchar *int_string; + + g_return_if_fail (GTK_IS_WIDGET (widget)); + + int_string = (gchar *) user_data; + + g_signal_handlers_disconnect_by_func (widget, on_gtk_window_realized, int_string); + g_object_weak_unref (G_OBJECT (widget), (GWeakNotify) g_free, int_string); + + set_window_hint (widget, int_string); + + g_free (int_string); +} + +/** + * xapp_set_window_icon_name: + * @window: The #GtkWindow to set the icon name for + * @icon_name: (nullable): The icon name to set, or %NULL to unset. + * + * Sets the icon name hint for a window manager (like muffin) to make + * available when applications want to change their icons during runtime + * without having to resort to the internal low-res pixbufs that GdkWindow + * sets on the client side. This is a function, not a method, for taking + * advantage of this feature with descendants of GtkWindows, such as + * GtkDialogs. Sets gtk_window_set_icon_name as well, to avoid needing + * to have two calls each time. Set to %NULL to unset. + */ + +void +xapp_set_window_icon_name (XAppGtkWindow *window, + const gchar *icon_name) +{ + g_return_if_fail (GTK_IS_WINDOW (window)); + + if (XAPP_IS_GTK_WINDOW (window)) + { + g_warning("Window is an instance of XAppGtkWindow. Use the instance set_icon_name method instead."); + } + + /* If the window is realized, set the icon name immediately */ + if (gtk_widget_get_realized (GTK_WIDGET (window))) + { + set_window_hint (GTK_WIDGET (window), icon_name); + } + /* Otherwise, hang a callback on window's realize signal and do it then */ + else + { + gchar *int_string; + + int_string = g_strdup (icon_name); + + g_signal_connect_after (GTK_WIDGET (window), + "realize", + G_CALLBACK (on_gtk_window_realized), + int_string); + + /* Insurance, in case window gets destroyed without ever being realized */ + g_object_weak_ref (G_OBJECT (window), + (GWeakNotify) g_free, + int_string); + } + + /* Call the GtkWindow method for compatibility */ + gtk_window_set_icon_name (GTK_WINDOW (window), icon_name); +} + + +/** + * xapp_set_window_icon_from_file: + * @window: The #GtkWindow to set the icon name for + * @file_name: (nullable): The icon path to set, or %NULL to unset. + * @error: (nullable): An error to set if something goes wrong. + * + * Sets the icon name hint for a window manager (like muffin) to make + * available when applications want to change their icons during runtime + * without having to resort to the internal low-res pixbufs that GdkWindow + * sets on the client side. This also chains up and calls GtkWindow.set_icon_from_file + * for convenience and compatibility. Set to %NULL to unset. + */ +void +xapp_set_window_icon_from_file (GtkWindow *window, + const gchar *file_name, + GError **error) +{ + g_return_if_fail (GTK_IS_WINDOW (window)); + + if (XAPP_IS_GTK_WINDOW (window)) + { + g_warning("Window is an instance of XAppGtkWindow. Use the instance set_icon_from_file method instead."); + } + + /* If the window is realized, set the icon name immediately */ + if (gtk_widget_get_realized (GTK_WIDGET (window))) + { + set_window_hint (GTK_WIDGET (window), file_name); + } + /* Otherwise, hang a callback on window's realize signal and do it then */ + else + { + gchar *int_string; + + int_string = g_strdup (file_name); + + g_signal_connect_after (GTK_WIDGET (window), + "realize", + G_CALLBACK (on_gtk_window_realized), + int_string); + + /* Insurance, in case window gets destroyed without ever being realized */ + g_object_weak_ref (G_OBJECT (window), + (GWeakNotify) g_free, + int_string); + } + + /* Call the GtkWindow method for compatibility */ + gtk_window_set_icon_from_file (GTK_WINDOW (window), file_name, error); +} diff --git a/libxapp/xapp-gtk-window.h b/libxapp/xapp-gtk-window.h index de7ee7b..45ea7df 100644 --- a/libxapp/xapp-gtk-window.h +++ b/libxapp/xapp-gtk-window.h @@ -31,6 +31,7 @@ GtkWindowClass parent_class; }; +/* Class */ GType xapp_gtk_window_get_type (void); XAppGtkWindow *xapp_gtk_window_new (void); @@ -41,6 +42,15 @@ const gchar *file_name, GError **error); +/* Wrappers (for GtkWindow subclasses like GtkDialog)*/ + +void xapp_set_window_icon_name (XAppGtkWindow *window, + const gchar *icon_name); + +void xapp_set_window_icon_from_file (GtkWindow *window, + const gchar *file_name, + GError **error); + G_END_DECLS #endif /* __XAPP_GTK_WINDOW_H__ */