Codebase list xapp / 367c398
Add XAppGtkWindow, with methods that shadow GtkWindow's icon setting ones. This way, programs only need to change the window class, rather than adding extra code. Michael Webster 6 years ago
6 changed file(s) with 281 addition(s) and 126 deletion(s). Raw diff Collapse all Expand all
1414 dh_autoreconf --as-needed ./autogen.sh
1515
1616 override_dh_auto_configure:
17 dh_auto_configure -- --enable-gtk-doc
17 dh_auto_configure -- --enable-gtk-doc --enable-silent-rules
1818
1919 override_dh_strip:
2020 dh_strip --dbg-package=libxapp-dbg
1616 introspection_sources = \
1717 xapp-monitor-blanker.c \
1818 xapp-kbd-layout-controller.c \
19 xapp-gtk-utils.c
19 xapp-gtk-window.c
2020
2121 libxapp_la_SOURCES = \
2222 $(introspection_sources)
3939 libxapp_HEADERS = \
4040 xapp-monitor-blanker.h \
4141 xapp-kbd-layout-controller.h \
42 xapp-gtk-utils.h
42 xapp-gtk-window.h
4343
4444 -include $(INTROSPECTION_MAKEFILE)
4545 INTROSPECTION_GIRS =
+0
-107
libxapp/xapp-gtk-utils.c less more
0
1 #include <config.h>
2
3 #include <stdlib.h>
4 #include <string.h>
5 #include <math.h>
6 #include <X11/Xlib.h>
7
8 #include <gdk/gdk.h>
9 #include <gdk/gdkx.h>
10 #include "xapp-gtk-utils.h"
11
12 static void
13 set_icon_name (GtkWidget *widget,
14 const gchar *icon_name)
15 {
16 GdkDisplay *display;
17 GdkWindow *window;
18
19 window = gtk_widget_get_window (widget);
20
21 if (gdk_window_get_effective_toplevel (window) != window)
22 {
23 g_warning ("Window is not toplevel");
24 return;
25 }
26
27 display = gdk_window_get_display (window);
28
29 if (icon_name != NULL)
30 {
31 XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
32 GDK_WINDOW_XID (window),
33 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_XAPP_ICON_NAME"),
34 gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
35 PropModeReplace, (guchar *)icon_name, strlen (icon_name));
36 }
37 else
38 {
39 XDeleteProperty (GDK_DISPLAY_XDISPLAY (display),
40 GDK_WINDOW_XID (window),
41 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_XAPP_ICON_NAME"));
42 }
43 }
44
45 static void
46 on_gtk_window_realized (GtkWidget *widget,
47 gpointer user_data)
48 {
49 gchar *int_string;
50
51 g_return_if_fail (GTK_IS_WIDGET (widget));
52
53 int_string = (gchar *) user_data;
54
55 g_signal_handlers_disconnect_by_func (widget, on_gtk_window_realized, int_string);
56 g_object_weak_unref (G_OBJECT (widget), (GWeakNotify) g_free, int_string);
57
58 set_icon_name (widget, int_string);
59
60 g_free (int_string);
61 }
62
63 /**
64 * xapp_gtk_window_set_icon_name:
65 * @window: The #GtkWindow to set the icon name for
66 * @icon_name: (nullable): The icon name or path to set, or %NULL to unset.
67 *
68 * Sets the icon name hint for a window manager (like muffin) to make
69 * available when applications want to change their icons during runtime
70 * without having to resort to the internal low-res pixbufs that GdkWindow
71 * sets on the client side. This string can be either an icon name
72 * corresponding to something in the icon theme, or an absolute path to an
73 * icon, or %NULL to unset.
74 */
75 void
76 xapp_gtk_window_set_icon_name (GtkWindow *window,
77 const gchar *icon_name)
78 {
79 g_return_if_fail (GTK_IS_WINDOW (window));
80
81 /* If the window is realized, set the icon name immediately */
82
83 if (gtk_widget_get_realized (GTK_WIDGET (window)))
84 {
85 set_icon_name (GTK_WIDGET (window), icon_name);
86 }
87 /* Otherwise, hang a callback on window's realize signal and do it then */
88 else
89 {
90 gchar *int_string;
91
92 int_string = g_strdup (icon_name);
93
94 g_signal_connect_after (GTK_WIDGET (window),
95 "realize",
96 G_CALLBACK (on_gtk_window_realized),
97 int_string);
98
99 /* Insurance, in case window gets destroyed without ever being realized */
100 g_object_weak_ref (G_OBJECT (window),
101 (GWeakNotify) g_free,
102 int_string);
103 }
104 }
105
106
+0
-16
libxapp/xapp-gtk-utils.h less more
0 #ifndef __XAPP_GTK_UTILS_H__
1 #define __XAPP_GTK_UTILS_H__
2
3 #include <stdio.h>
4
5 #include <glib-object.h>
6 #include <gtk/gtk.h>
7
8 G_BEGIN_DECLS
9
10 void xapp_gtk_window_set_icon_name (GtkWindow *window,
11 const gchar *icon_name);
12
13 G_END_DECLS
14
15 #endif /* __XAPP_GTK_UTILS_H__ */
0
1 #include <config.h>
2
3 #include <stdlib.h>
4 #include <string.h>
5 #include <math.h>
6 #include <X11/Xlib.h>
7
8 #include <gdk/gdk.h>
9 #include <gdk/gdkx.h>
10 #include "xapp-gtk-window.h"
11
12 struct _XAppGtkWindowPrivate
13 {
14 gchar *icon_name;
15 gchar *icon_path;
16 gboolean need_set_at_realize;
17 };
18
19 G_DEFINE_TYPE (XAppGtkWindow, xapp_gtk_window, GTK_TYPE_WINDOW);
20
21 static void
22 clear_strings (XAppGtkWindow *window)
23 {
24 XAppGtkWindowPrivate *priv = window->priv;
25
26 g_clear_pointer (&priv->icon_name, g_free);
27 g_clear_pointer (&priv->icon_path, g_free);
28 }
29
30 static void
31 set_window_hint (GtkWidget *widget,
32 const gchar *str)
33 {
34 GdkDisplay *display;
35 GdkWindow *window;
36
37 window = gtk_widget_get_window (widget);
38
39 if (gdk_window_get_effective_toplevel (window) != window)
40 {
41 g_warning ("Window is not toplevel");
42 return;
43 }
44
45 display = gdk_window_get_display (window);
46
47 if (str != NULL)
48 {
49 XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
50 GDK_WINDOW_XID (window),
51 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_XAPP_ICON_NAME"),
52 gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
53 PropModeReplace, (guchar *) str, strlen (str));
54 }
55 else
56 {
57 XDeleteProperty (GDK_DISPLAY_XDISPLAY (display),
58 GDK_WINDOW_XID (window),
59 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_XAPP_ICON_NAME"));
60 }
61 }
62
63 static void
64 update_window (XAppGtkWindow *window)
65 {
66 XAppGtkWindowPrivate *priv = window->priv;
67
68 if (priv->icon_name != NULL)
69 {
70 set_window_hint (GTK_WIDGET (window), priv->icon_name);
71 }
72 else if (priv->icon_path != NULL)
73 {
74 set_window_hint (GTK_WIDGET (window), priv->icon_path);
75 }
76 }
77
78 static void
79 xapp_gtk_window_realize (GtkWidget *widget)
80 {
81 XAppGtkWindow *window = XAPP_GTK_WINDOW (widget);
82 XAppGtkWindowPrivate *priv = window->priv;
83
84 GTK_WIDGET_CLASS (xapp_gtk_window_parent_class)->realize (widget);
85
86 if (priv->need_set_at_realize)
87 {
88 update_window (window);
89 priv->need_set_at_realize = FALSE;
90 }
91 }
92
93 static void
94 xapp_gtk_window_unrealize (GtkWidget *widget)
95 {
96 XAppGtkWindow *window = XAPP_GTK_WINDOW (widget);
97 XAppGtkWindowPrivate *priv = window->priv;
98
99 GTK_WIDGET_CLASS (xapp_gtk_window_parent_class)->unrealize (widget);
100
101 if (priv->icon_name != NULL || priv->icon_path != NULL)
102 {
103 priv->need_set_at_realize = TRUE;
104 }
105 }
106
107 static void
108 xapp_gtk_window_finalize (GObject *object)
109 {
110 XAppGtkWindow *window = XAPP_GTK_WINDOW (object);
111 XAppGtkWindowPrivate *priv = window->priv;
112
113 g_clear_pointer (&priv->icon_name, g_free);
114 g_clear_pointer (&priv->icon_path, g_free);
115
116 G_OBJECT_CLASS (xapp_gtk_window_parent_class)->finalize (object);
117 }
118
119 static void
120 xapp_gtk_window_init (XAppGtkWindow *window)
121 {
122 XAppGtkWindowPrivate *priv;
123
124 window->priv = G_TYPE_INSTANCE_GET_PRIVATE (window, XAPP_TYPE_GTK_WINDOW, XAppGtkWindowPrivate);
125
126 priv = window->priv;
127
128 priv->icon_name = NULL;
129 priv->icon_path = NULL;
130 priv->need_set_at_realize = FALSE;
131 }
132
133 static void
134 xapp_gtk_window_class_init (XAppGtkWindowClass *klass)
135 {
136 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
137 GtkWidgetClass *wclass = GTK_WIDGET_CLASS (klass);
138
139 gobject_class->finalize = xapp_gtk_window_finalize;
140 wclass->realize = xapp_gtk_window_realize;
141 wclass->unrealize = xapp_gtk_window_unrealize;
142
143 g_type_class_add_private (gobject_class, sizeof (XAppGtkWindowPrivate));
144 }
145
146 XAppGtkWindow *
147 xapp_gtk_window_new (void)
148 {
149 return g_object_new (XAPP_TYPE_GTK_WINDOW, NULL);
150 }
151
152 /**
153 * xapp_gtk_window_set_icon_name:
154 * @window: The #GtkWindow to set the icon name for
155 * @icon_name: (nullable): The icon name or path to set, or %NULL to unset.
156 *
157 * Sets the icon name hint for a window manager (like muffin) to make
158 * available when applications want to change their icons during runtime
159 * without having to resort to the internal low-res pixbufs that GdkWindow
160 * sets on the client side. This also chains up and calls GtkWindow.set_icon_name
161 * for convenience and compatibility. Set to %NULL to unset.
162 */
163 void
164 xapp_gtk_window_set_icon_name (XAppGtkWindow *window,
165 const gchar *icon_name)
166 {
167 g_return_if_fail (XAPP_IS_GTK_WINDOW (window));
168
169 clear_strings (window);
170
171 if (icon_name != NULL)
172 {
173 window->priv->icon_name = g_strdup (icon_name);
174 }
175
176 /* If the window is realized, set the icon name immediately */
177 if (gtk_widget_get_realized (GTK_WIDGET (window)))
178 {
179 update_window (window);
180 }
181 /* Otherwise, remind ourselves to do it in our realize vfunc */
182 else
183 {
184 window->priv->need_set_at_realize = TRUE;
185 }
186
187 /* Call the GtkWindow method for compatibility */
188 gtk_window_set_icon_name (GTK_WINDOW (window), icon_name);
189 }
190
191
192 /**
193 * xapp_gtk_window_set_icon_from_file:
194 * @window: The #XAppGtkWindow to set the icon name for
195 * @file_name: (nullable): The icon path to set, or %NULL to unset.
196 * @error: (nullable): An error to set if something goes wrong.
197 *
198 * Sets the icon name hint for a window manager (like muffin) to make
199 * available when applications want to change their icons during runtime
200 * without having to resort to the internal low-res pixbufs that GdkWindow
201 * sets on the client side. This also chains up and calls GtkWindow.set_icon_from_file
202 * for convenience and compatibility. Set to %NULL to unset.
203 */
204 void
205 xapp_gtk_window_set_icon_from_file (XAppGtkWindow *window,
206 const gchar *file_name,
207 GError **error)
208 {
209 g_return_if_fail (XAPP_IS_GTK_WINDOW (window));
210
211 clear_strings (window);
212
213 if (file_name != NULL)
214 {
215 window->priv->icon_path = g_strdup (file_name);
216 }
217
218 /* If the window is realized, set the icon path immediately */
219 if (gtk_widget_get_realized (GTK_WIDGET (window)))
220 {
221 update_window (window);
222 }
223 /* Otherwise, remind ourselves to do it later */
224 else
225 {
226 window->priv->need_set_at_realize = TRUE;
227 }
228
229 gtk_window_set_icon_from_file (GTK_WINDOW (window), file_name, error);
230 }
231
0 #ifndef __XAPP_GTK_WINDOW_H__
1 #define __XAPP_GTK_WINDOW_H__
2
3 #include <stdio.h>
4
5 #include <glib-object.h>
6 #include <gtk/gtk.h>
7
8 G_BEGIN_DECLS
9
10 #define XAPP_TYPE_GTK_WINDOW (xapp_gtk_window_get_type ())
11 #define XAPP_GTK_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XAPP_TYPE_GTK_WINDOW, XAppGtkWindow))
12 #define XAPP_GTK_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XAPP_TYPE_GTK_WINDOW, XAppGtkWindowClass))
13 #define XAPP_IS_GTK_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XAPP_TYPE_GTK_WINDOW))
14 #define XAPP_IS_GTK_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XAPP_TYPE_GTK_WINDOW))
15 #define XAPP_GTK_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XAPP_TYPE_GTK_WINDOW, XAppGtkWindowClass))
16
17 typedef struct _XAppGtkWindowPrivate XAppGtkWindowPrivate;
18 typedef struct _XAppGtkWindow XAppGtkWindow;
19 typedef struct _XAppGtkWindowClass XAppGtkWindowClass;
20
21 struct _XAppGtkWindow
22 {
23 GtkWindow parent_object;
24
25 XAppGtkWindowPrivate *priv;
26 };
27
28 struct _XAppGtkWindowClass
29 {
30 GtkWindowClass parent_class;
31 };
32
33 GType xapp_gtk_window_get_type (void);
34 XAppGtkWindow *xapp_gtk_window_new (void);
35
36 void xapp_gtk_window_set_icon_name (XAppGtkWindow *window,
37 const gchar *icon_name);
38
39 void xapp_gtk_window_set_icon_from_file (XAppGtkWindow *window,
40 const gchar *file_name,
41 GError **error);
42
43 G_END_DECLS
44
45 #endif /* __XAPP_GTK_WINDOW_H__ */