diff options
author | Havoc Pennington <hp@redhat.com> | 2004-10-27 05:07:27 +0000 |
---|---|---|
committer | Havoc Pennington <hp@redhat.com> | 2004-10-27 05:07:27 +0000 |
commit | 0262bb314677af0fc411a3d98318bee2868f933a (patch) | |
tree | 37dc63ce02c22164f396a20d9c295c15830aaa23 | |
parent | 85dd7d49c7d06d66a413c3a5dde2d927ffbf78ae (diff) | |
download | startup-notification-0262bb314677af0fc411a3d98318bee2868f933a.tar.gz |
//bugzilla.gnome.org/show_bug.cgi?id=151245 to support new focus stealing
prevention stuff.
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | doc/startup-notification.txt | 2 | ||||
-rw-r--r-- | libsn/sn-internals.h | 3 | ||||
-rw-r--r-- | libsn/sn-launchee.c | 45 | ||||
-rw-r--r-- | libsn/sn-launchee.h | 2 | ||||
-rw-r--r-- | libsn/sn-launcher.c | 16 | ||||
-rw-r--r-- | libsn/sn-monitor.c | 37 | ||||
-rw-r--r-- | libsn/sn-util.c | 50 |
8 files changed, 145 insertions, 16 deletions
@@ -1,3 +1,9 @@ +2004-10-27 Havoc Pennington <hp@redhat.com> + + * patch from Elijah Newren + http://bugzilla.gnome.org/show_bug.cgi?id=151245 + to support new focus stealing prevention stuff. + 2004-06-24 Mark McLoughlin <mark@skynet.ie> * configure.in: post-release bump to 0.8. diff --git a/doc/startup-notification.txt b/doc/startup-notification.txt index 10371d9..0b754d1 100644 --- a/doc/startup-notification.txt +++ b/doc/startup-notification.txt @@ -209,7 +209,7 @@ All messages must include these keys: ID uniquely identifies a startup sequence; should be some globally - unique string (for example, hostname+pid+current time). + unique string (for example, hostname+pid+"_TIME"+current time). The string should be in the form of <unique>_TIME<timestamp>, where the timestamp is the X server timestamp of the user action that caused the launch. See the TIMESTAMP key diff --git a/libsn/sn-internals.h b/libsn/sn-internals.h index 03bdf27..354af35 100644 --- a/libsn/sn-internals.h +++ b/libsn/sn-internals.h @@ -71,6 +71,9 @@ void sn_internal_strfreev (char **strings); unsigned long sn_internal_string_to_ulong (const char* str); +char* sn_internal_find_last_occurrence (const char* haystack, + const char* needle); + void sn_internal_append_to_string (char **append_to, int *current_len, const char *append); diff --git a/libsn/sn-launchee.c b/libsn/sn-launchee.c index 1b476a1..db3ee05 100644 --- a/libsn/sn-launchee.c +++ b/libsn/sn-launchee.c @@ -123,6 +123,51 @@ sn_launchee_context_get_startup_id (SnLauncheeContext *context) return context->startup_id; } +/** + * sn_launchee_context_get_id_has_timestamp: + * @context: an #SnLauncheeContext + * + * Return whether the startup ID for the context contains a timestamp + * + * Return value: whether the startup ID has an embedded timestamp + **/ +int +sn_launchee_context_get_id_has_timestamp (SnLauncheeContext *context) +{ + char * time_str; + + time_str = sn_internal_find_last_occurrence(context->startup_id, "_TIME"); + + return time_str != NULL; +} + +/** + * sn_launchee_context_get_timestamp: + * @context: an #SnLauncheeContext + * + * Return the timestamp embedded in the startup ID + * + * Return value: timestamp embedded in the startup ID + **/ +Time +sn_launchee_context_get_timestamp (SnLauncheeContext *context) +{ + char * time_str; + + time_str = sn_internal_find_last_occurrence(context->startup_id, "_TIME"); + if (time_str != NULL) + { + /* Skip past the "_TIME" part */ + time_str += 5; + + return sn_internal_string_to_ulong (time_str); + } + + fprintf (stderr, + "libsn: No timestamp contained in the startup ID!\n"); + /* Unfortunately, all values are valid; let's just return -1 */ + return -1; +} /** * sn_launchee_context_complete: diff --git a/libsn/sn-launchee.h b/libsn/sn-launchee.h index bdd6081..a04d0ec 100644 --- a/libsn/sn-launchee.h +++ b/libsn/sn-launchee.h @@ -41,6 +41,8 @@ SnLauncheeContext* sn_launchee_context_new_from_environment (SnDisplay * void sn_launchee_context_ref (SnLauncheeContext *context); void sn_launchee_context_unref (SnLauncheeContext *context); const char* sn_launchee_context_get_startup_id (SnLauncheeContext *context); +int sn_launchee_context_get_id_has_timestamp (SnLauncheeContext *context); +Time sn_launchee_context_get_timestamp (SnLauncheeContext *context); void sn_launchee_context_complete (SnLauncheeContext *context); void sn_launchee_context_setup_window (SnLauncheeContext *context, Window xwindow); diff --git a/libsn/sn-launcher.c b/libsn/sn-launcher.c index 8bd6fc9..c60ff31 100644 --- a/libsn/sn-launcher.c +++ b/libsn/sn-launcher.c @@ -41,7 +41,6 @@ struct SnLauncherContext char *name; char *description; int workspace; - Time timestamp; char *wmclass; char *binary_name; char *icon_name; @@ -81,7 +80,6 @@ sn_launcher_context_new (SnDisplay *display, sn_display_ref (context->display); context->workspace = -1; - context->timestamp = 0; sn_list_prepend (context_list, context); @@ -179,7 +177,6 @@ sn_launcher_context_initiate (SnLauncherContext *context, char *values[MAX_PROPS]; char *message; char workspacebuf[257]; - char timestampbuf[257]; char screenbuf[257]; if (context->startup_id != NULL) @@ -205,15 +202,15 @@ sn_launcher_context_initiate (SnLauncherContext *context, 256; /* 256 is longer than a couple %d and some slashes */ s = sn_malloc (len + 3); - snprintf (s, len, "%s/%s/%lu/%d-%d-%s", - canonicalized_launcher, canonicalized_launchee, (unsigned long) timestamp, - (int) getpid (), (int) sequence_number, hostbuf); + snprintf (s, len, "%s/%s/%d-%d-%s_TIME%lu", + canonicalized_launcher, canonicalized_launchee, + (int) getpid (), (int) sequence_number, hostbuf, + (unsigned long) timestamp); ++sequence_number; sn_free (canonicalized_launcher); sn_free (canonicalized_launchee); - context->timestamp = timestamp; context->startup_id = s; i = 0; @@ -227,11 +224,6 @@ sn_launcher_context_initiate (SnLauncherContext *context, values[i] = screenbuf; ++i; - names[i] = "TIMESTAMP"; - sprintf (timestampbuf, "%lu", context->timestamp); - values[i] = timestampbuf; - ++i; - if (context->name != NULL) { names[i] = "NAME"; diff --git a/libsn/sn-monitor.c b/libsn/sn-monitor.c index b4d4ff8..b473fce 100644 --- a/libsn/sn-monitor.c +++ b/libsn/sn-monitor.c @@ -70,6 +70,7 @@ struct SnStartupSequence unsigned int completed : 1; unsigned int canceled : 1; + unsigned int timestamp_set : 1; int creation_serial; @@ -307,7 +308,15 @@ sn_startup_sequence_get_workspace (SnStartupSequence *sequence) Time sn_startup_sequence_get_timestamp (SnStartupSequence *sequence) { - return sequence->timestamp; + if (!sequence->timestamp_set) + { + fprintf (stderr, + "libsn: Buggy startup-notification launcher! No timestamp!\n"); + /* Unfortunately, all values are valid; let's just return -1 */ + return -1; + } + else + return sequence->timestamp; } const char* @@ -430,6 +439,7 @@ sn_startup_sequence_new (SnDisplay *display) sequence->screen = -1; /* not set */ sequence->workspace = -1; /* not set */ sequence->timestamp = 0; + sequence->timestamp_set = FALSE; sequence->initiation_time.tv_sec = 0; sequence->initiation_time.tv_usec = 0; @@ -708,12 +718,26 @@ xmessage_func (SnDisplay *display, if (sequence == NULL) { SnMonitorEvent *event; + char *time_str; sequence = add_sequence (display); if (sequence == NULL) goto out; sequence->id = sn_internal_strdup (launch_id); + + /* Current spec says timestamp is part of the startup id; so we need + * to get the timestamp here if the launcher is using the current spec + */ + time_str = sn_internal_find_last_occurrence(sequence->id, "_TIME"); + if (time_str != NULL) + { + /* Skip past the "_TIME" part */ + time_str += 5; + + sequence->timestamp = sn_internal_string_to_ulong (time_str); + sequence->timestamp_set = TRUE; + } event = sn_new (SnMonitorEvent, 1); @@ -791,13 +815,20 @@ xmessage_func (SnDisplay *display, sequence->workspace = workspace; changed = TRUE; } - else if (strcmp (names[i], "TIMESTAMP") == 0) + else if (strcmp (names[i], "TIMESTAMP") == 0 && + !sequence->timestamp_set) { + /* Old version of the spec says that the timestamp was + * sent as part of a TIMESTAMP message. We try to + * handle that to enable backwards compatibility with + * older launchers. + */ Time timestamp; - + timestamp = sn_internal_string_to_ulong (values[i]); sequence->timestamp = timestamp; + sequence->timestamp_set = TRUE; changed = TRUE; } else if (strcmp (names[i], "WMCLASS") == 0) diff --git a/libsn/sn-util.c b/libsn/sn-util.c index 7d12bfa..a9220f5 100644 --- a/libsn/sn-util.c +++ b/libsn/sn-util.c @@ -310,6 +310,56 @@ sn_internal_string_to_ulong (const char* str) return retval; } +/** + * sn_internal_find_last_occurrence: + * @haystack: a nul-terminated string. + * @needle: the nul-terminated string to search for. + * + * Searches the string @haystack for the last occurrence + * of the string @needle. + * + * Return value: a pointer to the found occurrence, or + * %NULL if not found. + **/ +char* +sn_internal_find_last_occurrence (const char* haystack, + const char* needle) +{ + int i; + int needle_len; + int haystack_len; + const char *p; + + if (haystack == NULL) + return NULL; + if (needle == NULL) + return NULL; + + needle_len = strlen (needle); + haystack_len = strlen (haystack); + + if (needle_len == 0) + return (char *)haystack; + + if (haystack_len < needle_len) + return NULL; + + p = haystack + haystack_len - needle_len; + + while (p >= haystack) + { + for (i = 0; i < needle_len; i++) + if (p[i] != needle[i]) + goto next; + + return (char *)p; + + next: + p--; + } + + return NULL; +} void sn_internal_append_to_string (char **append_to, |