forked from AuroraMiddleware/gtk
Apply patch by Vytautas Liuolia for changing the startup notification id
2007-03-13 Emmanuele Bassi <ebassi@gnome.org> Apply patch by Vytautas Liuolia for changing the startup notification id on a window in the X11 backend. (#347375) * gdk/gdk.h: * gdk/gdkx.h: * gdk/x11/gdkdisplay-x11.c: Add gdk_notify_startup_complete_wit_id() and gdk_x11_display_get_startup_notification_id(). * gdk/gdkwindow.h: * gdk/x11/gdkwindow-x11.c: Add gdk_window_set_startup_id(). * gtk/gtkwindow.h: * gtk/gtkwindow.c: Add gtk_window_set_startup_id(), used to change the startup notification id. (gtk_window_class_init), (gtk_window_init), (gtk_window_set_property): Add write-only "startup-id" property to GtkWindow. (gtk_window_realize): Set the startup notification id on a GtkWindow if it's valid. (gtk_window_map): If we have another valid startup notification id then finish the notification process. svn path=/trunk/; revision=17508
This commit is contained in:
parent
500435f2f9
commit
87c28d778a
27
ChangeLog
27
ChangeLog
@ -1,3 +1,30 @@
|
||||
2007-03-13 Emmanuele Bassi <ebassi@gnome.org>
|
||||
|
||||
Apply patch by Vytautas Liuolia for changing the startup
|
||||
notification id on a window in the X11 backend. (#347375)
|
||||
|
||||
* gdk/gdk.h:
|
||||
* gdk/gdkx.h:
|
||||
* gdk/x11/gdkdisplay-x11.c: Add gdk_notify_startup_complete_wit_id()
|
||||
and gdk_x11_display_get_startup_notification_id().
|
||||
|
||||
* gdk/gdkwindow.h:
|
||||
* gdk/x11/gdkwindow-x11.c: Add gdk_window_set_startup_id().
|
||||
|
||||
* gtk/gtkwindow.h:
|
||||
* gtk/gtkwindow.c: Add gtk_window_set_startup_id(), used to
|
||||
change the startup notification id.
|
||||
|
||||
(gtk_window_class_init), (gtk_window_init),
|
||||
(gtk_window_set_property): Add write-only "startup-id" property
|
||||
to GtkWindow.
|
||||
|
||||
(gtk_window_realize): Set the startup notification id
|
||||
on a GtkWindow if it's valid.
|
||||
|
||||
(gtk_window_map): If we have another valid startup notification
|
||||
id then finish the notification process.
|
||||
|
||||
2007-03-13 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* gtk/gtknotebook.c (gtk_notebook_real_insert_page):
|
||||
|
@ -177,6 +177,8 @@ gboolean gdk_event_send_client_message_for_display (GdkDisplay *display,
|
||||
|
||||
void gdk_notify_startup_complete (void);
|
||||
|
||||
void gdk_notify_startup_complete_with_id (const gchar* startup_id);
|
||||
|
||||
/* Threading
|
||||
*/
|
||||
|
||||
|
@ -482,6 +482,8 @@ void gdk_window_set_title (GdkWindow *window,
|
||||
const gchar *title);
|
||||
void gdk_window_set_role (GdkWindow *window,
|
||||
const gchar *role);
|
||||
void gdk_window_set_startup_id (GdkWindow *window,
|
||||
const gchar *startup_id);
|
||||
void gdk_window_set_transient_for (GdkWindow *window,
|
||||
GdkWindow *parent);
|
||||
void gdk_window_set_background (GdkWindow *window,
|
||||
|
@ -1079,7 +1079,36 @@ gdk_notify_startup_complete (void)
|
||||
if (!G_LIKELY (display_x11->trusted_client))
|
||||
return;
|
||||
|
||||
escaped_id = escape_for_xmessage (display_x11->startup_notification_id);
|
||||
gdk_notify_startup_complete_with_id (display_x11->startup_notification_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_notify_startup_complete_with_id:
|
||||
* @startup_id: a startup-notification identifier, for which notification
|
||||
* process should be completed
|
||||
*
|
||||
* Indicates to the GUI environment that the application has finished
|
||||
* loading, using a given identifier.
|
||||
*
|
||||
* GTK+ will call this function automatically for #GtkWindow with custom
|
||||
* startup-notification identifier unless
|
||||
* gtk_window_set_auto_startup_notification() is called to disable
|
||||
* that feature.
|
||||
*
|
||||
* Since: 2.12
|
||||
**/
|
||||
void
|
||||
gdk_notify_startup_complete_with_id (const gchar* startup_id)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
gchar *escaped_id;
|
||||
gchar *message;
|
||||
|
||||
display = gdk_display_get_default ();
|
||||
if (!display)
|
||||
return;
|
||||
|
||||
escaped_id = escape_for_xmessage (startup_id);
|
||||
message = g_strdup_printf ("remove: ID=%s", escaped_id);
|
||||
g_free (escaped_id);
|
||||
|
||||
@ -1091,7 +1120,6 @@ gdk_notify_startup_complete (void)
|
||||
g_free (message);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gdk_display_supports_selection_notification:
|
||||
* @display: a #GdkDisplay
|
||||
@ -1291,5 +1319,20 @@ gdk_display_supports_input_shapes (GdkDisplay *display)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gdk_x11_display_get_startup_notification_id:
|
||||
* @display: a #GdkDisplay
|
||||
*
|
||||
* Returns: the startup notification ID for
|
||||
* @display.
|
||||
*
|
||||
* Since: 2.12
|
||||
*/
|
||||
G_CONST_RETURN gchar *
|
||||
gdk_x11_display_get_startup_notification_id (GdkDisplay *display)
|
||||
{
|
||||
return GDK_DISPLAY_X11 (display)->startup_notification_id;
|
||||
}
|
||||
|
||||
#define __GDK_DISPLAY_X11_C__
|
||||
#include "gdkaliasdef.c"
|
||||
|
@ -2896,6 +2896,40 @@ gdk_window_set_role (GdkWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_window_set_startup_id:
|
||||
* @window: a toplevel #GdkWindow
|
||||
* @startup_id: a string with startup-notification identifier
|
||||
*
|
||||
* When using GTK+, typically you should use gtk_window_set_startup_id()
|
||||
* instead of this low-level function.
|
||||
*
|
||||
* Since: 2.12
|
||||
*
|
||||
**/
|
||||
void
|
||||
gdk_window_set_startup_id (GdkWindow *window,
|
||||
const gchar *startup_id)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
|
||||
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||
|
||||
display = gdk_drawable_get_display (window);
|
||||
|
||||
if (!GDK_WINDOW_DESTROYED (window))
|
||||
{
|
||||
if (startup_id)
|
||||
XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (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));
|
||||
else
|
||||
XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
|
||||
gdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_window_set_transient_for:
|
||||
* @window: a toplevel #GdkWindow
|
||||
|
@ -142,6 +142,8 @@ gpointer gdk_xid_table_lookup_for_display (GdkDisplay *display,
|
||||
guint32 gdk_x11_get_server_time (GdkWindow *window);
|
||||
guint32 gdk_x11_display_get_user_time (GdkDisplay *display);
|
||||
|
||||
G_CONST_RETURN gchar *gdk_x11_display_get_startup_notification_id (GdkDisplay *display);
|
||||
|
||||
void gdk_x11_display_set_cursor_theme (GdkDisplay *display,
|
||||
const gchar *theme,
|
||||
const gint size);
|
||||
|
140
gtk/gtkwindow.c
140
gtk/gtkwindow.c
@ -26,6 +26,8 @@
|
||||
|
||||
#include <config.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include "gdk/gdk.h"
|
||||
#include "gdk/gdkkeysyms.h"
|
||||
@ -95,6 +97,9 @@ enum {
|
||||
PROP_IS_ACTIVE,
|
||||
PROP_HAS_TOPLEVEL_FOCUS,
|
||||
|
||||
/* Writeonly properties */
|
||||
PROP_STARTUP_ID,
|
||||
|
||||
LAST_ARG
|
||||
};
|
||||
|
||||
@ -177,6 +182,8 @@ struct _GtkWindowPrivate
|
||||
|
||||
guint reset_type_hint : 1;
|
||||
GdkWindowTypeHint type_hint;
|
||||
|
||||
gchar *startup_id;
|
||||
};
|
||||
|
||||
static void gtk_window_dispose (GObject *object);
|
||||
@ -344,6 +351,33 @@ add_arrow_bindings (GtkBindingSet *binding_set,
|
||||
GTK_TYPE_DIRECTION_TYPE, direction);
|
||||
}
|
||||
|
||||
static guint32
|
||||
extract_time_from_startup_id (const gchar* startup_id)
|
||||
{
|
||||
gchar *timestr = g_strrstr (startup_id, "_TIME");
|
||||
guint32 retval = GDK_CURRENT_TIME;
|
||||
|
||||
if (timestr)
|
||||
{
|
||||
gchar *end;
|
||||
guint32 timestamp;
|
||||
|
||||
/* Skip past the "_TIME" part */
|
||||
timestr += 5;
|
||||
|
||||
timestamp = strtoul (timestr, &end, 0);
|
||||
if (end != timestr && errno == 0)
|
||||
retval = timestamp;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
startup_id_is_fake (const gchar* startup_id)
|
||||
{
|
||||
return strncmp (startup_id, "_TIME", 5) == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_window_class_init (GtkWindowClass *klass)
|
||||
@ -429,6 +463,23 @@ gtk_window_class_init (GtkWindowClass *klass)
|
||||
P_("Unique identifier for the window to be used when restoring a session"),
|
||||
NULL,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkWindow:startup-id:
|
||||
*
|
||||
* The :startup-id is a write-only property for setting window's
|
||||
* startup notification identifier. See gtk_window_set_startup_id()
|
||||
* for more details.
|
||||
*
|
||||
* Since: 2.12
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ROLE,
|
||||
g_param_spec_string ("startup-id",
|
||||
P_("Startup ID"),
|
||||
P_("Unique startup identifier for the window used by startup-notification"),
|
||||
NULL,
|
||||
GTK_PARAM_WRITABLE));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ALLOW_SHRINK,
|
||||
@ -810,6 +861,7 @@ gtk_window_init (GtkWindow *window)
|
||||
priv->focus_on_map = TRUE;
|
||||
priv->deletable = TRUE;
|
||||
priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
|
||||
priv->startup_id = NULL;
|
||||
|
||||
colormap = _gtk_widget_peek_colormap ();
|
||||
if (colormap)
|
||||
@ -846,6 +898,9 @@ gtk_window_set_property (GObject *object,
|
||||
case PROP_ROLE:
|
||||
gtk_window_set_role (window, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_STARTUP_ID:
|
||||
gtk_window_set_startup_id (window, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_ALLOW_SHRINK:
|
||||
window->allow_shrink = g_value_get_boolean (value);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (window));
|
||||
@ -1200,6 +1255,60 @@ gtk_window_set_role (GtkWindow *window,
|
||||
g_object_notify (G_OBJECT (window), "role");
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_window_set_startup_id:
|
||||
* @window: a #GtkWindow
|
||||
* @startup_id: a string with startup-notification identifier
|
||||
*
|
||||
* Startup notification identifiers are used by desktop environment to
|
||||
* track application startup, to provide user feedback and other
|
||||
* features. This function changes the corresponding property on the
|
||||
* underlying GdkWindow. Normally, startup identifier is managed
|
||||
* automatically and you should only use this function in special cases
|
||||
* like transferring focus from other processes. You should use this
|
||||
* function before calling gtk_window_present() or any equivalent
|
||||
* function generating a window map event.
|
||||
*
|
||||
* This function is only useful on X11, not with other GTK+ targets.
|
||||
*
|
||||
* Since: 2.12
|
||||
**/
|
||||
void
|
||||
gtk_window_set_startup_id (GtkWindow *window,
|
||||
const gchar *startup_id)
|
||||
{
|
||||
GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
|
||||
|
||||
g_return_if_fail (GTK_IS_WINDOW (window));
|
||||
|
||||
g_free (priv->startup_id);
|
||||
priv->startup_id = g_strdup (startup_id);
|
||||
|
||||
if (GTK_WIDGET_REALIZED (window))
|
||||
{
|
||||
/* Here we differentiate real and "fake" startup notification IDs,
|
||||
* constructed on purpose just to pass interaction timestamp
|
||||
*/
|
||||
if (startup_id_is_fake (priv->startup_id))
|
||||
{
|
||||
guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
|
||||
|
||||
gtk_window_present_with_time (window, timestamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_window_set_startup_id (GTK_WIDGET (window)->window,
|
||||
priv->startup_id);
|
||||
|
||||
/* If window is mapped, terminate the startup-notification too */
|
||||
if (GTK_WIDGET_MAPPED (window) && !disable_startup_notification)
|
||||
gdk_notify_startup_complete_with_id (priv->startup_id);
|
||||
}
|
||||
}
|
||||
|
||||
g_object_notify (G_OBJECT (window), "startup-id");
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_window_get_role:
|
||||
* @window: a #GtkWindow
|
||||
@ -4149,11 +4258,22 @@ gtk_window_map (GtkWidget *widget)
|
||||
if (window->frame)
|
||||
gdk_window_show (window->frame);
|
||||
|
||||
if (!disable_startup_notification &&
|
||||
!sent_startup_notification)
|
||||
if (!disable_startup_notification)
|
||||
{
|
||||
sent_startup_notification = TRUE;
|
||||
gdk_notify_startup_complete ();
|
||||
/* Do we have a custom startup-notification id? */
|
||||
if (priv->startup_id != NULL)
|
||||
{
|
||||
/* Make sure we have a "real" id */
|
||||
if (!startup_id_is_fake (priv->startup_id))
|
||||
gdk_notify_startup_complete_with_id (priv->startup_id);
|
||||
|
||||
priv->startup_id = NULL;
|
||||
}
|
||||
else if (!sent_startup_notification)
|
||||
{
|
||||
sent_startup_notification = TRUE;
|
||||
gdk_notify_startup_complete ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4223,7 +4343,6 @@ gtk_window_realize (GtkWidget *widget)
|
||||
GtkWindowPrivate *priv;
|
||||
|
||||
window = GTK_WINDOW (widget);
|
||||
|
||||
priv = GTK_WINDOW_GET_PRIVATE (window);
|
||||
|
||||
/* ensure widget tree is properly size allocated */
|
||||
@ -4377,6 +4496,17 @@ gtk_window_realize (GtkWidget *widget)
|
||||
gdk_window_set_modal_hint (widget->window, TRUE);
|
||||
else
|
||||
gdk_window_set_modal_hint (widget->window, FALSE);
|
||||
|
||||
if (priv->startup_id)
|
||||
{
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
|
||||
if (timestamp != GDK_CURRENT_TIME)
|
||||
gdk_x11_window_set_user_time (widget->window, timestamp);
|
||||
#endif
|
||||
if (!startup_id_is_fake (priv->startup_id))
|
||||
gdk_window_set_startup_id (widget->window, priv->startup_id);
|
||||
}
|
||||
|
||||
/* Icons */
|
||||
gtk_window_realize_icon (window);
|
||||
|
@ -178,6 +178,8 @@ void gtk_window_set_wmclass (GtkWindow *window,
|
||||
const gchar *wmclass_class);
|
||||
void gtk_window_set_role (GtkWindow *window,
|
||||
const gchar *role);
|
||||
void gtk_window_set_startup_id (GtkWindow *window,
|
||||
const gchar *startup_id);
|
||||
G_CONST_RETURN gchar *gtk_window_get_role (GtkWindow *window);
|
||||
void gtk_window_add_accel_group (GtkWindow *window,
|
||||
GtkAccelGroup *accel_group);
|
||||
|
Loading…
Reference in New Issue
Block a user