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.
This commit is contained in:
Owen Taylor 2002-11-02 05:37:04 +00:00 committed by Owen Taylor
parent 39a5a723f0
commit accc3a3365
17 changed files with 407 additions and 15 deletions

View File

@ -1,3 +1,30 @@
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.
Fri Nov 1 21:03:59 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkfilesel.c: Add a mnemonic to the "selection"

View File

@ -1,3 +1,30 @@
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.
Fri Nov 1 21:03:59 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkfilesel.c: Add a mnemonic to the "selection"

View File

@ -1,3 +1,30 @@
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.
Fri Nov 1 21:03:59 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkfilesel.c: Add a mnemonic to the "selection"

View File

@ -1,3 +1,30 @@
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.
Fri Nov 1 21:03:59 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkfilesel.c: Add a mnemonic to the "selection"

View File

@ -1,3 +1,30 @@
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.
Fri Nov 1 21:03:59 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkfilesel.c: Add a mnemonic to the "selection"

View File

@ -1,3 +1,30 @@
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.
Fri Nov 1 21:03:59 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkfilesel.c: Add a mnemonic to the "selection"

View File

@ -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
*/

View File

@ -1592,3 +1592,8 @@ gdk_error_trap_pop (void)
{
return 0;
}
void
gdk_notify_startup_complete (void)
{
}

View File

@ -213,3 +213,8 @@ gdk_error_trap_pop (void)
{
return 0;
}
void
gdk_notify_startup_complete (void)
{
}

View File

@ -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);
}

View File

@ -132,6 +132,9 @@ struct _GdkDisplayX11
gint input_gxid_port;
gint use_xft;
/* Startup notification */
gchar *startup_notification_id;
};
struct _GdkDisplayX11Class

View File

@ -104,15 +104,6 @@ _gdk_windowing_init (gint *argc,
_gdk_selection_property = gdk_atom_intern ("GDK_SELECTION", FALSE);
}
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)
{

View File

@ -535,7 +535,7 @@ gtk_combo_popup_list (GtkCombo * combo)
else
{
GTK_WIDGET_SET_FLAGS (list, GTK_CAN_FOCUS);
gtk_widget_grab_focus (list);
gtk_widget_grab_focus (combo->list);
GTK_WIDGET_UNSET_FLAGS (list, GTK_CAN_FOCUS);
}

View File

@ -866,8 +866,6 @@ gboolean
gtk_init_check (int *argc,
char ***argv)
{
GdkDisplay *display;
if (!gtk_parse_args (argc, argv))
return FALSE;
@ -902,7 +900,7 @@ gtk_init (int *argc, char ***argv)
{
if (!gtk_init_check (argc, argv))
{
char *display_name_arg = gdk_get_display_arg_name ();
const char *display_name_arg = gdk_get_display_arg_name ();
g_warning ("cannot open display: %s", display_name_arg ? display_name_arg : " ");
exit (1);
}

View File

@ -713,7 +713,7 @@ gtk_toolbar_size_allocate (GtkWidget *widget,
gint space_size;
gint ipadding;
GtkTextDirection direction;
gint ltr_x;
gint ltr_x = 0; /* Quiet GCC */
g_return_if_fail (GTK_IS_TOOLBAR (widget));
g_return_if_fail (allocation != NULL);

View File

@ -261,6 +261,8 @@ static GtkBinClass *parent_class = NULL;
static guint window_signals[LAST_SIGNAL] = { 0 };
static GList *default_icon_list = NULL;
static guint default_icon_serial = 0;
static gboolean disable_startup_notification = FALSE;
static gboolean sent_startup_notification = FALSE;
static void gtk_window_set_property (GObject *object,
guint prop_id,
@ -3548,6 +3550,13 @@ gtk_window_map (GtkWidget *widget)
if (window->frame)
gdk_window_show (window->frame);
if (!disable_startup_notification &&
!sent_startup_notification)
{
sent_startup_notification = TRUE;
gdk_notify_startup_complete ();
}
}
static void
@ -6709,3 +6718,25 @@ _gtk_window_set_has_toplevel_focus (GtkWindow *window,
g_object_notify (G_OBJECT (window), "has_toplevel_focus");
}
}
/**
* gtk_window_set_auto_startup_notification:
* @setting: %TRUE to automatically do startup notification
*
* By default, after showing the first #GtkWindow for each #GdkScreen,
* GTK+ calls gdk_screen_notify_startup_complete(). Call this
* function to disable the automatic startup notification. You might
* do this if your first window is a splash screen, and you want to
* delay notification until after your real main window has been
* shown, for example.
*
* In that example, you would disable startup notification
* temporarily, show your splash screen, then re-enable it so that
* showing the main window would automatically result in notification.
*
**/
void
gtk_window_set_auto_startup_notification (gboolean setting)
{
disable_startup_notification = !setting;
}

View File

@ -255,6 +255,7 @@ GList* gtk_window_get_default_icon_list (void);
gboolean gtk_window_set_default_icon_from_file (const gchar *filename,
GError **err);
void gtk_window_set_auto_startup_notification (gboolean setting);
/* If window is set modal, input will be grabbed when show and released when hide */
void gtk_window_set_modal (GtkWindow *window,