summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2004-10-27 05:07:27 +0000
committerHavoc Pennington <hp@redhat.com>2004-10-27 05:07:27 +0000
commit0262bb314677af0fc411a3d98318bee2868f933a (patch)
tree37dc63ce02c22164f396a20d9c295c15830aaa23
parent85dd7d49c7d06d66a413c3a5dde2d927ffbf78ae (diff)
downloadstartup-notification-0262bb314677af0fc411a3d98318bee2868f933a.tar.gz
//bugzilla.gnome.org/show_bug.cgi?id=151245 to support new focus stealing
prevention stuff.
-rw-r--r--ChangeLog6
-rw-r--r--doc/startup-notification.txt2
-rw-r--r--libsn/sn-internals.h3
-rw-r--r--libsn/sn-launchee.c45
-rw-r--r--libsn/sn-launchee.h2
-rw-r--r--libsn/sn-launcher.c16
-rw-r--r--libsn/sn-monitor.c37
-rw-r--r--libsn/sn-util.c50
8 files changed, 145 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index 6ae36a6..a37e7a0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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,