summaryrefslogtreecommitdiff
path: root/gdk
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2002-11-02 05:37:04 +0000
committerOwen Taylor <otaylor@src.gnome.org>2002-11-02 05:37:04 +0000
commitaccc3a3365fa56b02e647686750e5106e020c425 (patch)
tree8d5129f3e28bf612bd5fd3ec065da1e4e6ec6a7c /gdk
parent39a5a723f0381cca485fd366499a07e31b57c89f (diff)
downloadgdk-pixbuf-accc3a3365fa56b02e647686750e5106e020c425.tar.gz
Add startup notification hooks - mostly based on patch by Havoc Pennington
Sat Nov 2 00:22:33 2002 Owen Taylor <otaylor@redhat.com> Add startup notification hooks - mostly based on patch by Havoc Pennington in #96772. * gdk/gdk.h gdk/x11/gdkdisplay-x11.c gdk/{win32,linux-fb}/gdkmain-*.c: (gdk_notify_startup_complete): new function that indicates an application has finished starting up. * gdk/x11/gdkmain-x11.c gdk/x11/gdkdisplay-x11.c (_gdk_windowing_set_default_display): store value of DESKTOP_STARTUP_ID on the default screen, and clear it from the environment. * gdk/x11/gdkdisplay-x11.c: Set _NET_STARTUP_ID hint on display's group leader window. * gtk/gtkwindow.c (gtk_window_set_auto_startup_notification): function to toggle whether we automatically broadcast that we've started up, after mapping the first toplevel window. (gtk_window_map): call gdk_screen_notify_startup_complete() by default, unless enabled by above. * gtk/gtkmain.c gtk/gtkcombo.c gtk/gtktoolbar.c: Couple of warning fixes.
Diffstat (limited to 'gdk')
-rw-r--r--gdk/gdk.h3
-rw-r--r--gdk/linux-fb/gdkmain-fb.c5
-rw-r--r--gdk/win32/gdkmain-win32.c5
-rw-r--r--gdk/x11/gdkdisplay-x11.c195
-rw-r--r--gdk/x11/gdkdisplay-x11.h3
-rw-r--r--gdk/x11/gdkmain-x11.c9
6 files changed, 210 insertions, 10 deletions
diff --git a/gdk/gdk.h b/gdk/gdk.h
index 811c48493..e48683e2e 100644
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -160,6 +160,9 @@ void gdk_event_send_clientmessage_toall (GdkEvent *event);
gboolean gdk_event_send_client_message_for_display (GdkDisplay *display,
GdkEvent *event,
GdkNativeWindow winid);
+
+void gdk_notify_startup_complete (void);
+
/* Threading
*/
diff --git a/gdk/linux-fb/gdkmain-fb.c b/gdk/linux-fb/gdkmain-fb.c
index 24c910f15..2325d5734 100644
--- a/gdk/linux-fb/gdkmain-fb.c
+++ b/gdk/linux-fb/gdkmain-fb.c
@@ -1592,3 +1592,8 @@ gdk_error_trap_pop (void)
{
return 0;
}
+
+void
+gdk_notify_startup_complete (void)
+{
+}
diff --git a/gdk/win32/gdkmain-win32.c b/gdk/win32/gdkmain-win32.c
index f0feada70..f36be8883 100644
--- a/gdk/win32/gdkmain-win32.c
+++ b/gdk/win32/gdkmain-win32.c
@@ -213,3 +213,8 @@ gdk_error_trap_pop (void)
{
return 0;
}
+
+void
+gdk_notify_startup_complete (void)
+{
+}
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index 5ff1bb469..964c83491 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -143,7 +143,8 @@ gdk_display_open (const gchar *display_name)
display_x11->default_screen = display_x11->screens[DefaultScreen (display_x11->xdisplay)];
display_x11->leader_window = XCreateSimpleWindow (display_x11->xdisplay,
GDK_SCREEN_X11 (display_x11->default_screen)->xroot_window,
- 10, 10, 10, 10, 0, 0, 0);
+ 10, 10, 10, 10, 0, 0, 0);
+
display_x11->have_shape = GDK_UNKNOWN;
display_x11->gravity_works = GDK_UNKNOWN;
@@ -568,6 +569,8 @@ gdk_display_x11_finalize (GObject *object)
for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
g_object_unref (display_x11->screens[i]);
g_free (display_x11->screens);
+ g_free (display_x11->startup_notification_id);
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -632,3 +635,193 @@ gdk_x11_display_get_xdisplay (GdkDisplay *display)
{
return GDK_DISPLAY_X11 (display)->xdisplay;
}
+
+void
+_gdk_windowing_set_default_display (GdkDisplay *display)
+{
+ GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
+ const gchar *startup_id;
+
+ if (display)
+ gdk_display = GDK_DISPLAY_XDISPLAY (display);
+ else
+ gdk_display = NULL;
+
+ g_free (display_x11->startup_notification_id);
+ display_x11->startup_notification_id = NULL;
+
+ startup_id = g_getenv ("DESKTOP_STARTUP_ID");
+ if (startup_id && *startup_id != '\0')
+ {
+ if (!g_utf8_validate (startup_id, -1, NULL))
+ g_warning ("DESKTOP_STARTUP_ID contains invalid UTF-8");
+ else
+ display_x11->startup_notification_id = g_strdup (startup_id);
+
+ /* Clear the environment variable so it won't be inherited by
+ * child processes and confuse things. unsetenv isn't portable,
+ * right...
+ */
+ putenv ("DESKTOP_STARTUP_ID=");
+
+ /* Set the startup id on the leader window so it
+ * applies to all windows we create on this display
+ */
+ XChangeProperty (display_x11->xdisplay,
+ display_x11->leader_window,
+ gdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"),
+ gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
+ PropModeReplace,
+ startup_id, strlen (startup_id));
+ }
+}
+
+char*
+escape_for_xmessage (const char *str)
+{
+ GString *retval;
+ const char *p;
+
+ retval = g_string_new ("");
+
+ p = str;
+ while (*p)
+ {
+ switch (*p)
+ {
+ case ' ':
+ case '"':
+ case '\\':
+ g_string_append_c (retval, '\\');
+ break;
+ }
+
+ g_string_append_c (retval, *p);
+ ++p;
+ }
+
+ return g_string_free (retval, FALSE);
+}
+
+static void
+broadcast_xmessage (GdkDisplay *display,
+ const char *message_type,
+ const char *message_type_begin,
+ const char *message)
+{
+ Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
+ GdkScreen *screen = gdk_display_get_default_screen (display);
+ GdkWindow *root_window = gdk_screen_get_root_window (screen);
+ Window xroot_window = GDK_WINDOW_XID (root_window);
+
+ Atom type_atom;
+ Atom type_atom_begin;
+ Window xwindow;
+
+ {
+ XSetWindowAttributes attrs;
+
+ attrs.override_redirect = True;
+ attrs.event_mask = PropertyChangeMask | StructureNotifyMask;
+
+ xwindow =
+ XCreateWindow (xdisplay,
+ xroot_window,
+ -100, -100, 1, 1,
+ 0,
+ CopyFromParent,
+ CopyFromParent,
+ CopyFromParent,
+ CWOverrideRedirect | CWEventMask,
+ &attrs);
+ }
+
+ type_atom = gdk_x11_get_xatom_by_name_for_display (display,
+ message_type);
+ type_atom_begin = gdk_x11_get_xatom_by_name_for_display (display,
+ message_type_begin);
+
+ {
+ XEvent xevent;
+ const char *src;
+ const char *src_end;
+ char *dest;
+ char *dest_end;
+
+ xevent.xclient.type = ClientMessage;
+ xevent.xclient.message_type = type_atom_begin;
+ xevent.xclient.display =xdisplay;
+ xevent.xclient.window = xwindow;
+ xevent.xclient.format = 8;
+
+ src = message;
+ src_end = message + strlen (message) + 1; /* +1 to include nul byte */
+
+ while (src != src_end)
+ {
+ dest = &xevent.xclient.data.b[0];
+ dest_end = dest + 20;
+
+ while (dest != dest_end &&
+ src != src_end)
+ {
+ *dest = *src;
+ ++dest;
+ ++src;
+ }
+
+ XSendEvent (xdisplay,
+ xroot_window,
+ False,
+ PropertyChangeMask,
+ &xevent);
+
+ xevent.xclient.message_type = type_atom;
+ }
+ }
+
+ XDestroyWindow (xdisplay, xwindow);
+ XFlush (xdisplay);
+}
+
+/**
+ * gdk_notify_startup_complete:
+ *
+ * Indicates to the GUI environment that the application has finished
+ * loading. If the applications opens windows, this function is
+ * normally called after opening the application's initial set of
+ * windows.
+ *
+ * GTK+ will call this function automatically after opening the first
+ * #GtkWindow unless
+ * gtk_window_set_auto_startup_notification() is called to disable
+ * that feature.
+ **/
+void
+gdk_notify_startup_complete (void)
+{
+ GdkDisplay *display;
+ GdkDisplayX11 *display_x11;
+ gchar *escaped_id;
+ gchar *message;
+
+ display = gdk_display_get_default ();
+ if (!display)
+ return;
+
+ display_x11 = GDK_DISPLAY_X11 (display);
+
+ if (display_x11->startup_notification_id == NULL)
+ return;
+
+ escaped_id = escape_for_xmessage (display_x11->startup_notification_id);
+ message = g_strdup_printf ("remove: ID=%s", escaped_id);
+ g_free (escaped_id);
+
+ broadcast_xmessage (display,
+ "_NET_STARTUP_INFO",
+ "_NET_STARTUP_INFO_BEGIN",
+ message);
+
+ g_free (message);
+}
diff --git a/gdk/x11/gdkdisplay-x11.h b/gdk/x11/gdkdisplay-x11.h
index f0a076ebf..2cc752245 100644
--- a/gdk/x11/gdkdisplay-x11.h
+++ b/gdk/x11/gdkdisplay-x11.h
@@ -132,6 +132,9 @@ struct _GdkDisplayX11
gint input_gxid_port;
gint use_xft;
+
+ /* Startup notification */
+ gchar *startup_notification_id;
};
struct _GdkDisplayX11Class
diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c
index 27a09b3a3..2d8828db3 100644
--- a/gdk/x11/gdkmain-x11.c
+++ b/gdk/x11/gdkmain-x11.c
@@ -105,15 +105,6 @@ _gdk_windowing_init (gint *argc,
}
void
-_gdk_windowing_set_default_display (GdkDisplay *display)
-{
- if (display)
- gdk_display = GDK_DISPLAY_XDISPLAY (display);
- else
- gdk_display = NULL;
-}
-
-void
gdk_set_use_xshm (gboolean use_xshm)
{
}