Package list xapp / fb6670e
xapp-gtk-window.c: Add xid-based functions Michael Webster 4 years ago
2 changed file(s) with 183 addition(s) and 56 deletion(s). Raw diff Collapse all Expand all
33 #include <stdlib.h>
44 #include <string.h>
55 #include <math.h>
6 #include <X11/Xlib.h>
76 #include <X11/Xatom.h>
87
98 #include <gdk/gdk.h>
5251 * to work with normal GtkWindows and descendants of GtkWindow.
5352 */
5453
55 struct _XAppGtkWindow
56 {
57 GtkWindow parent_object;
58
59 XAppGtkWindowPrivate *priv;
60 };
61
62 struct _XAppGtkWindowPrivate
54 typedef struct
6355 {
6456 gchar *icon_name;
6557 gchar *icon_path;
6658 guint progress;
6759 gboolean progress_pulse;
60 } XAppGtkWindowPrivate;
61
62 struct _XAppGtkWindow
63 {
64 GtkWindow parent_object;
65
66 XAppGtkWindowPrivate *priv;
6867 };
6968
70 G_DEFINE_TYPE (XAppGtkWindow, xapp_gtk_window, GTK_TYPE_WINDOW);
69 G_DEFINE_TYPE_WITH_PRIVATE (XAppGtkWindow, xapp_gtk_window, GTK_TYPE_WINDOW)
7170
7271 static void
7372 clear_icon_strings (XAppGtkWindowPrivate *priv)
7776 }
7877
7978 static void
80 set_window_hint_utf8 (GtkWidget *widget,
79 set_window_hint_utf8 (Window xid,
8180 const gchar *atom_name,
8281 const gchar *str)
8382 {
8483 GdkDisplay *display;
85 GdkWindow *window;
86
87 window = gtk_widget_get_window (widget);
88
89 if (gdk_window_get_effective_toplevel (window) != window)
90 {
91 g_warning ("Window is not toplevel");
92 return;
93 }
94
95 display = gdk_window_get_display (window);
84
85 display = gdk_display_get_default ();
9686
9787 if (str != NULL)
9888 {
9989 XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
100 GDK_WINDOW_XID (window),
90 xid,
10191 gdk_x11_get_xatom_by_name_for_display (display, atom_name),
10292 gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
10393 PropModeReplace, (guchar *) str, strlen (str));
10595 else
10696 {
10797 XDeleteProperty (GDK_DISPLAY_XDISPLAY (display),
108 GDK_WINDOW_XID (window),
98 xid,
10999 gdk_x11_get_xatom_by_name_for_display (display, atom_name));
110100 }
111101 }
112102
113103 static void
114 set_window_hint_cardinal (GtkWidget *widget,
104 set_window_hint_cardinal (Window xid,
115105 const gchar *atom_name,
116106 gulong cardinal)
117107 {
118108 GdkDisplay *display;
119 GdkWindow *window;
120
121 window = gtk_widget_get_window (widget);
122
123 if (gdk_window_get_effective_toplevel (window) != window)
124 {
125 g_warning ("Window is not toplevel");
126 return;
127 }
128
129 display = gdk_window_get_display (window);
109
110 display = gdk_display_get_default ();
130111
131112 if (cardinal > 0)
132113 {
133114 XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
134 GDK_WINDOW_XID (window),
115 xid,
135116 gdk_x11_get_xatom_by_name_for_display (display, atom_name),
136117 XA_CARDINAL, 32,
137118 PropModeReplace,
140121 else
141122 {
142123 XDeleteProperty (GDK_DISPLAY_XDISPLAY (display),
143 GDK_WINDOW_XID (window),
124 xid,
144125 gdk_x11_get_xatom_by_name_for_display (display, atom_name));
145126 }
127 }
128
129 static Window
130 get_window_xid (GtkWindow *window)
131 {
132 GdkWindow *gdk_window;
133
134 gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
135
136 if (gdk_window_get_effective_toplevel (gdk_window) != gdk_window)
137 {
138 g_warning ("Window is not toplevel");
139 return 0;
140 }
141
142 return GDK_WINDOW_XID (gdk_window);
146143 }
147144
148145 static void
152149 /* Icon name/path */
153150 if (priv->icon_name != NULL)
154151 {
155 set_window_hint_utf8 (GTK_WIDGET (window), ICON_NAME_HINT, priv->icon_name);
152 set_window_hint_utf8 (get_window_xid (window),
153 ICON_NAME_HINT,
154 priv->icon_name);
156155 }
157156 else if (priv->icon_path != NULL)
158157 {
159 set_window_hint_utf8 (GTK_WIDGET (window), ICON_NAME_HINT, priv->icon_path);
158 set_window_hint_utf8 (get_window_xid (window),
159 ICON_NAME_HINT,
160 priv->icon_path);
160161 }
161162 else
162163 {
163 set_window_hint_utf8 (GTK_WIDGET (window), ICON_NAME_HINT, NULL);
164 set_window_hint_utf8 (get_window_xid (window),
165 ICON_NAME_HINT,
166 NULL);
164167 }
165168 }
166169
169172 XAppGtkWindowPrivate *priv)
170173 {
171174 /* Progress: 0 - 100 */
172 set_window_hint_cardinal (GTK_WIDGET (window), PROGRESS_HINT, (gulong) priv->progress);
173 set_window_hint_cardinal (GTK_WIDGET (window), PROGRESS_PULSE_HINT, (gulong) (priv->progress_pulse ? 1 : 0));
175 set_window_hint_cardinal (get_window_xid (window),
176 PROGRESS_HINT,
177 (gulong) priv->progress);
178
179 set_window_hint_cardinal (get_window_xid (window),
180 PROGRESS_PULSE_HINT,
181 (gulong) (priv->progress_pulse ? 1 : 0));
174182 }
175183
176184 static void
348356 gobject_class->finalize = xapp_gtk_window_finalize;
349357 wclass->realize = xapp_gtk_window_realize;
350358 wclass->unrealize = xapp_gtk_window_unrealize;
351
352 g_type_class_add_private (gobject_class, sizeof (XAppGtkWindowPrivate));
353359 }
354360
355361 /**
419425 * in some operation. The value sent to the WM will be clamped to
420426 * between 0 and 100.
421427 *
428 * Note: If a window will stick around after progress is complete, you will
429 * probaby need to set progress to 0 to remove any progress effects on taskbars
430 * and window lists.
431 *
422432 * Setting progress will also cancel the 'pulsing' flag on the window as
423433 * well, if it has been set.
424434 */
440450 * to make available when applications want to display indeterminate or
441451 * ongoing progress in a task manager.
442452 *
453 * Note: If a window will stick around after progress is complete, you will
454 * probaby need to set progress to 0 to remove any progress effects on taskbars
455 * and window lists. This will also remove the pulse state, if it is set.
456 *
443457 * Setting an explicit progress value will unset this flag.
444458 */
445459 void
573587 * xapp_set_window_progress:
574588 * @window: The #GtkWindow to set the progress for
575589 * @progress: The value to set for progress.
576 *
590 *
577591 * Sets the progress hint for a window manager (like muffin) to make
578592 * available when applications want to display the application's progress
579 * in some operation. The value sent to the WM will be clamped to
593 * in some operation. The value sent to the WM will be clamped to
580594 * between 0 and 100.
595 *
596 * Note: If a window will stick around after progress is complete, you will
597 * probaby need to set progress to 0 to remove any progress effects on taskbars
598 * and window lists.
581599 *
582600 * Setting progress will also cancel the 'pulsing' flag on the window as
583601 * well, if it has been set.
609627 * to make available when applications want to display indeterminate or
610628 * ongoing progress in a task manager.
611629 *
630 * Note: If a window will stick around after progress is complete, you will
631 * probaby need to set progress to 0 to remove any progress effects on taskbars
632 * and window lists. This will also remove the pulse state, if it is set.
633 *
612634 * Setting an explicit progress value will unset this flag.
613635 */
614636 void
628650
629651 set_progress_pulse_internal (GTK_WINDOW (window), priv, pulse);
630652 }
653
654 /**
655 * xapp_set_xid_icon_name:
656 * @xid: (type gulong): The #Window to set the icon name for
657 * @icon_name: (nullable): The icon name to set, or %NULL to unset.
658 *
659 * Sets the icon name hint for a window manager (like muffin) to make
660 * available when applications want to change their icons during runtime
661 * without having to resort to the internal low-res pixbufs that GdkWindow
662 * sets on the client side. This is a function, not a method, for applying
663 * the icon name property for a given (possibly foreign) window, by passing
664 * the window's XID. Set to %NULL to unset.
665 */
666 void
667 xapp_set_xid_icon_name (Window xid,
668 const gchar *icon_name)
669 {
670 g_return_if_fail (xid > 0);
671
672 set_window_hint_utf8 (xid, ICON_NAME_HINT, icon_name);
673 }
674
675 /**
676 * xapp_set_xid_icon_from_file:
677 * @xid: (type gulong): The #Window to set the icon name for
678 * @file_name: (nullable): The icon path to set, or %NULL to unset.
679 *
680 * Sets the icon name hint for a window manager (like muffin) to make
681 * available when applications want to change their icons during runtime
682 * without having to resort to the internal low-res pixbufs that GdkWindow
683 * sets on the client side. This is a function, not a method, for applying
684 * the icon name property for a given (possibly foreign) window, by passing
685 * the window's XID. Set to %NULL to unset.
686 */
687 void
688 xapp_set_xid_icon_from_file (Window xid,
689 const gchar *file_name)
690 {
691
692 g_return_if_fail (xid > 0);
693
694 set_window_hint_utf8 (xid, ICON_NAME_HINT, file_name);
695 }
696
697 /**
698 * xapp_set_xid_progress:
699 * @xid: (type gulong): The #Window to set the progress for
700 * @progress: The value to set for progress.
701 *
702 * Sets the progress hint for a window manager (like muffin) to make
703 * available when applications want to display the application's progress
704 * in some operation. The value sent to the WM will be clamped to
705 * between 0 and 100.
706 *
707 * Setting progress will also cancel the 'pulsing' flag on the window as
708 * well, if it has been set.
709 *
710 * Note: If a window will stick around after progress is complete, you will
711 * probaby need to set progress to 0 to remove any progress effects on taskbars
712 * and window lists.
713 *
714 * This is a function, not a method, for applying the progress property for
715 * a given (possibly foreign) window, by passing the window's XID.
716 */
717 void
718 xapp_set_xid_progress (Window xid,
719 gint progress)
720 {
721 g_return_if_fail (xid > 0);
722
723 set_window_hint_cardinal (xid, PROGRESS_HINT, (gulong) (CLAMP (progress, 0, 100)));
724 set_window_hint_cardinal (xid, PROGRESS_PULSE_HINT, (gulong) 0);
725 }
726
727 /**
728 * xapp_set_xid_progress_pulse:
729 * @xid: (type gulong): The #Window to set the progress for
730 * @pulse: Whether to have pulsing set or not.
731 *
732 * Sets the progress pulse hint hint for a window manager (like muffin)
733 * to make available when applications want to display indeterminate or
734 * ongoing progress in a task manager.
735 *
736 * Note: If a window will stick around after progress is complete, you will
737 * probaby need to set progress to 0 to remove any progress effects on taskbars
738 * and window lists.
739 *
740 * Setting an explicit progress value will unset this flag.
741 */
742 void
743 xapp_set_xid_progress_pulse (Window xid,
744 gboolean pulse)
745 {
746 g_return_if_fail (xid > 0);
747
748 set_window_hint_cardinal (xid, PROGRESS_PULSE_HINT, (gulong) (pulse ? 1 : 0));
749 }
44
55 #include <glib-object.h>
66 #include <gtk/gtk.h>
7 #include <X11/Xlib.h>
78
89 G_BEGIN_DECLS
910
1011 #define XAPP_TYPE_GTK_WINDOW (xapp_gtk_window_get_type ())
1112
1213 G_DECLARE_FINAL_TYPE (XAppGtkWindow, xapp_gtk_window, XAPP, GTK_WINDOW, GtkWindow)
13
14 typedef struct _XAppGtkWindowPrivate XAppGtkWindowPrivate;
1514
1615 /* Class */
1716 GtkWidget *xapp_gtk_window_new (GtkWindowType type);
3130 void xapp_set_window_icon_name (GtkWindow *window,
3231 const gchar *icon_name);
3332
34 void xapp_set_window_icon_from_file (GtkWindow *window,
35 const gchar *file_name,
36 GError **error);
37 void xapp_set_window_progress (GtkWindow *window,
38 gint progress);
39 void xapp_set_window_progress_pulse (GtkWindow *window,
40 gboolean pulse);
33 void xapp_set_window_icon_from_file (GtkWindow *window,
34 const gchar *file_name,
35 GError **error);
36 void xapp_set_window_progress (GtkWindow *window,
37 gint progress);
38 void xapp_set_window_progress_pulse (GtkWindow *window,
39 gboolean pulse);
40 /* Low level for X11 Window xid's */
41 void xapp_set_xid_icon_name (Window xid,
42 const gchar *icon_name);
43 void xapp_set_xid_icon_from_file (Window xid,
44 const gchar *file_name);
45 void xapp_set_xid_progress (Window xid,
46 gint progress);
47 void xapp_set_xid_progress_pulse (Window xid,
48 gboolean pulse);
4149
4250 G_END_DECLS
4351