summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2002-10-21 02:47:15 +0000
committerHavoc Pennington <hp@redhat.com>2002-10-21 02:47:15 +0000
commitccaabe6206adab552c6daa70e892d0f66f9a4448 (patch)
tree781be3d608770e291b1632a2dec5d48bcadddf07
parent3fda9848b002bcfb5fc376bbf5d36bb0f7851c9c (diff)
downloadstartup-notification-ccaabe6206adab552c6daa70e892d0f66f9a4448.tar.gz
port to new setup, add multihead support
port to new setup, and blow away all monitoring stuff, just use sn-monitor.h make it all multihead-safe port to new setup and strip the other stuff out s/DESKTOP_LAUNCH_ID/DESKTOP_STARTUP_ID/ for env variable, add _NET_STARTUP_ID window manager hint.
-rw-r--r--ChangeLog20
-rw-r--r--doc/startup-notification.txt13
-rw-r--r--libsn/sn-common.c3
-rw-r--r--libsn/sn-internals.h8
-rw-r--r--libsn/sn-launchee.c157
-rw-r--r--libsn/sn-launchee.h12
-rw-r--r--libsn/sn-launcher.c856
-rw-r--r--libsn/sn-launcher.h63
-rw-r--r--libsn/sn-monitor.c696
-rw-r--r--libsn/sn-monitor.h59
-rw-r--r--libsn/sn-util.c18
-rw-r--r--libsn/sn-xmessages.c64
-rw-r--r--libsn/sn-xmessages.h4
-rw-r--r--test/test-launchee.c17
-rw-r--r--test/test-launcher.c35
-rw-r--r--test/test-monitor.c93
-rw-r--r--test/test-send-xmessage.c2
-rw-r--r--test/test-watch-xmessages.c3
18 files changed, 398 insertions, 1725 deletions
diff --git a/ChangeLog b/ChangeLog
index 31037b2..435429a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,25 @@
2002-10-20 Havoc Pennington <hp@pobox.com>
+ * libsn/sn-monitor.c: port to new setup, add multihead support
+
+ * libsn/sn-launcher.c: port to new setup, and blow away
+ all monitoring stuff, just use sn-monitor.h
+
+ * libsn/sn-xmessages.c: make it all multihead-safe
+
+ * libsn/sn-launchee.c: port to new setup and strip the other stuff
+ out
+
+ * doc/startup-notification.txt:
+ s/DESKTOP_LAUNCH_ID/DESKTOP_STARTUP_ID/ for env variable,
+ add _NET_STARTUP_ID window manager hint.
+
+2002-10-20 Havoc Pennington <hp@pobox.com>
+
+ * doc/startup-notification.txt: new docs, new proposed spec
+
+2002-10-20 Havoc Pennington <hp@pobox.com>
+
* Massively rename everything from liblf to libsn, and reimport
to CVS.
diff --git a/doc/startup-notification.txt b/doc/startup-notification.txt
index 1406b1e..1939c19 100644
--- a/doc/startup-notification.txt
+++ b/doc/startup-notification.txt
@@ -262,7 +262,7 @@ To communicate the startup sequence information from a launcher
process to a launchee process, when possible an environment variable
should be used:
- DESKTOP_LAUNCH_ID
+ DESKTOP_STARTUP_ID
value of the "ID" field in the "new" message
Mechanisms other than the environment variable may be used as well, as
@@ -271,7 +271,7 @@ the launchee code is in a process started by the launcher code; if
they are in the same process the environment variable may not be
relevant.
-Desktop entry extensions
+Desktop entry spec extensions
===
StartupNotify=BOOLEAN
@@ -285,6 +285,15 @@ StartupWMClass=STRING
If true, it is KNOWN that the application will map at least one
window with the given string as its WM class or WM name hint.
+EWMH spec extensions
+===
+
+_NET_STARTUP_ID, UTF8_STRING
+
+ The ID used for the startup sequence for the window. If set
+ on a group leader window, applies to all application windows
+ in that group that do not set their own _NET_STARTUP_ID.
+
A. Sample code to send X message
===
diff --git a/libsn/sn-common.c b/libsn/sn-common.c
index b6c449e..33f6237 100644
--- a/libsn/sn-common.c
+++ b/libsn/sn-common.c
@@ -168,9 +168,6 @@ sn_display_process_event (SnDisplay *display,
retval = FALSE;
- if (sn_internal_launcher_process_event (display, xevent))
- retval = TRUE;
-
if (sn_internal_monitor_process_event (display, xevent))
retval = TRUE;
diff --git a/libsn/sn-internals.h b/libsn/sn-internals.h
index d4e2953..5f73c6d 100644
--- a/libsn/sn-internals.h
+++ b/libsn/sn-internals.h
@@ -49,10 +49,6 @@ SN_BEGIN_DECLS
#define NULL ((void*) 0)
#endif
-/* --- From sn-launcher.c --- */
-sn_bool_t sn_internal_launcher_process_event (SnDisplay *display,
- XEvent *xevent);
-
/* --- From sn-monitor.c --- */
sn_bool_t sn_internal_monitor_process_event (SnDisplay *display,
XEvent *xevent);
@@ -67,6 +63,10 @@ void sn_internal_strfreev (char **strings);
unsigned long sn_internal_string_to_ulong (const char* str);
+void sn_internal_append_to_string (char **append_to,
+ int *current_len,
+ const char *append);
+
/* --- From sn-xmessages.c --- */
sn_bool_t sn_internal_xmessage_process_event (SnDisplay *display,
XEvent *xevent);
diff --git a/libsn/sn-launchee.c b/libsn/sn-launchee.c
index bade52c..bdf9ab3 100644
--- a/libsn/sn-launchee.c
+++ b/libsn/sn-launchee.c
@@ -23,31 +23,32 @@
*/
#include "sn-launchee.h"
#include "sn-internals.h"
+#include "sn-xmessages.h"
#include <errno.h>
struct SnLauncheeContext
{
int refcount;
SnDisplay *display;
- char *launch_id;
- Window launch_window;
+ int screen;
+ char *startup_id;
};
/**
* sn_launchee_context_new:
* @display: an #SnDisplay
- * @launch_id: launch ID as in DESKTOP_LAUNCH_ID
- * @launch_window: launch window as in DESKTOP_LAUNCH_WINDOW
+ * @screen: an X screen number
+ * @startup_id: launch ID as in DESKTOP_STARTUP_ID env variable
*
- * Creates a new launchee-side context for the launch feedback
+ * Creates a new launchee-side context for the startup notification
* protocol.
*
* Return value: a new launchee context
**/
SnLauncheeContext*
sn_launchee_context_new (SnDisplay *display,
- const char *launch_id,
- Window launch_window)
+ int screen,
+ const char *startup_id)
{
SnLauncheeContext *context;
@@ -57,11 +58,9 @@ sn_launchee_context_new (SnDisplay *display,
context->display = display;
sn_display_ref (context->display);
-
- context->launch_id = sn_malloc (strlen (launch_id) + 1);
- strcpy (context->launch_id, launch_id);
-
- context->launch_window = launch_window;
+ context->screen = screen;
+
+ context->startup_id = sn_internal_strdup (startup_id);
return context;
}
@@ -69,33 +68,27 @@ sn_launchee_context_new (SnDisplay *display,
/**
* sn_launchee_context_new_from_environment:
* @display: an #SnDisplay
+ * @screen: an X screen number
*
- * Tries to create an #SnLauncheeContext given information in
- * the program's environment (DESKTOP_LAUNCH_ID and DESKTOP_LAUNCH_WINDOW
- * environment variables). Returns %NULL if the env variables are not
- * available or can't be parsed.
+ * Tries to create an #SnLauncheeContext given information in the
+ * program's environment (DESKTOP_STARTUP_ID environment
+ * variable). Returns %NULL if the env variables are not available or
+ * can't be parsed.
*
* Return value: a new #SnLauncheeContext or %NULL
**/
SnLauncheeContext*
-sn_launchee_context_new_from_environment (SnDisplay *display)
+sn_launchee_context_new_from_environment (SnDisplay *display,
+ int screen)
{
const char *id_str;
- const char *window_str;
- unsigned long window;
-
- id_str = getenv ("DESKTOP_LAUNCH_ID");
- window_str = getenv ("DESKTOP_LAUNCH_WINDOW");
- if (id_str == NULL || window_str == NULL)
- return NULL;
-
- window = sn_internal_string_to_ulong (window_str);
+ id_str = getenv ("DESKTOP_STARTUP_ID");
- if (window == None)
+ if (id_str == NULL)
return NULL;
- return sn_launchee_context_new (display, id_str, window);
+ return sn_launchee_context_new (display, screen, id_str);
}
void
@@ -110,92 +103,57 @@ sn_launchee_context_unref (SnLauncheeContext *context)
context->refcount -= 1;
if (context->refcount == 0)
{
- sn_free (context->launch_id);
+ sn_free (context->startup_id);
sn_free (context);
}
}
-Window
-sn_launchee_context_get_launch_window (SnLauncheeContext *context)
-{
- return context->launch_window;
-}
-
-const char*
-sn_launchee_context_get_launch_id (SnLauncheeContext *context)
-{
- return context->launch_id;
-}
-
/**
- * sn_launchee_context_pulse:
+ * sn_launchee_context_get_startup_id:
* @context: an #SnLauncheeContext
- *
- * Notifies the launcher that progress is being made. Should be
- * called regularly during a long launch operation.
*
- **/
-void
-sn_launchee_context_pulse (SnLauncheeContext *context)
-{
- XEvent xev;
-
- xev.xclient.type = ClientMessage;
- xev.xclient.serial = 0;
- xev.xclient.send_event = True;
- xev.xclient.display = sn_display_get_x_display (context->display);
- xev.xclient.window = context->launch_window;
- xev.xclient.message_type = sn_internal_atom_get (context->display,
- "_NET_LAUNCH_PULSE");
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = 0;
- xev.xclient.data.l[1] = 0;
- xev.xclient.data.l[2] = 0;
- xev.xclient.data.l[3] = 0;
-
- sn_display_error_trap_push (context->display);
- XSendEvent (sn_display_get_x_display (context->display),
- context->launch_window,
- False,
- PropertyChangeMask,
- &xev);
- XFlush (sn_display_get_x_display (context->display));
- sn_display_error_trap_pop (context->display);
-}
-
-/**
- * sn_launchee_context_cancel:
- * @context: an #SnLauncheeContext
- *
- * Called by the launchee application to cancel a launch (will
- * probably cause the launcher to kill the launchee).
+ * Get the startup ID for the context.
*
+ * Return value: the startup ID for the context.
**/
-void
-sn_launchee_context_cancel (SnLauncheeContext *context)
+const char*
+sn_launchee_context_get_startup_id (SnLauncheeContext *context)
{
- sn_internal_set_cardinal (context->display,
- context->launch_window,
- "_NET_LAUNCH_CANCELED",
- 0);
+ return context->startup_id;
}
+
/**
* sn_launchee_context_complete:
* @context: an #SnLauncheeContext
*
- * Called by the launchee application when it is fully started up
- * and launch feedback should end.
+ * Called by the launchee when it is fully started up and the startup
+ * sequence should end.
*
**/
void
sn_launchee_context_complete (SnLauncheeContext *context)
{
- sn_internal_set_cardinal (context->display,
- context->launch_window,
- "_NET_LAUNCH_COMPLETE",
- 0);
+ char *keys[2];
+ char *vals[2];
+ char *message;
+
+ keys[0] = "ID";
+ keys[1] = NULL;
+ vals[0] = context->startup_id;
+ vals[1] = NULL;
+
+ message = sn_internal_serialize_message ("remove",
+ (const char**) keys,
+ (const char **) vals);
+
+ sn_internal_broadcast_xmessage (context->display,
+ context->screen,
+ "_NET_STARTUP_INFO",
+ message);
+
+ sn_free (message);
}
/**
@@ -203,12 +161,11 @@ sn_launchee_context_complete (SnLauncheeContext *context)
* @context: a #SnLauncheeContext
* @xwindow: window to be set up
*
- * Sets up @xwindow, marking it as launched by the launch sequence
- * represented by @context. For example sets the _NET_LAUNCH_ID
- * property. Only the group leader windows of an application
- * MUST be set up with this function, though if
- * any other windows come from a separate launch sequence,
- * they can be setup up separately.
+ * Sets up @xwindow, marking it as launched by the startup sequence
+ * represented by @context. For example sets the _NET_STARTUP_ID
+ * property. Only the group leader windows of an application MUST be
+ * set up with this function, though if any other windows come from a
+ * separate startup sequence, they can be set up separately.
*
**/
void
@@ -217,6 +174,6 @@ sn_launchee_context_setup_window (SnLauncheeContext *context,
{
sn_internal_set_string (context->display,
xwindow,
- "_NET_LAUNCH_ID",
- context->launch_id);
+ "_NET_STARTUP_ID",
+ context->startup_id);
}
diff --git a/libsn/sn-launchee.h b/libsn/sn-launchee.h
index ee9f189..bdd6081 100644
--- a/libsn/sn-launchee.h
+++ b/libsn/sn-launchee.h
@@ -34,15 +34,13 @@ SN_BEGIN_DECLS
typedef struct SnLauncheeContext SnLauncheeContext;
SnLauncheeContext* sn_launchee_context_new (SnDisplay *display,
- const char *launch_id,
- Window launch_window);
-SnLauncheeContext* sn_launchee_context_new_from_environment (SnDisplay *display);
+ int screen,
+ const char *startup_id);
+SnLauncheeContext* sn_launchee_context_new_from_environment (SnDisplay *display,
+ int screen);
void sn_launchee_context_ref (SnLauncheeContext *context);
void sn_launchee_context_unref (SnLauncheeContext *context);
-Window sn_launchee_context_get_launch_window (SnLauncheeContext *context);
-const char* sn_launchee_context_get_launch_id (SnLauncheeContext *context);
-void sn_launchee_context_pulse (SnLauncheeContext *context);
-void sn_launchee_context_cancel (SnLauncheeContext *context);
+const char* sn_launchee_context_get_startup_id (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 520a342..3e27d35 100644
--- a/libsn/sn-launcher.c
+++ b/libsn/sn-launcher.c
@@ -23,9 +23,11 @@
*/
#include "sn-launcher.h"
#include "sn-internals.h"
+#include "sn-xmessages.h"
#include <sys/types.h>
#include <unistd.h>
+#include <assert.h>
static SnList* context_list = NULL;
@@ -33,38 +35,28 @@ struct SnLauncherContext
{
int refcount;
SnDisplay *display;
- SnLauncherEventFunc event_func;
- void *event_func_data;
- SnFreeFunc free_data_func;
- char *launch_id;
- Window launch_window;
- SnLaunchType type;
- Window geometry_window;
+ int screen;
+ char *startup_id;
char *name;
char *description;
int workspace;
- char *resource_class;
- char *resource_name;
- char *window_title;
+ char *wmclass;
char *binary_name;
- int pid;
char *icon_name;
- int x, y, width, height;
- unsigned int supports_cancel : 1;
unsigned int completed : 1;
unsigned int canceled : 1;
- unsigned int geometry_set : 1;
};
/**
* sn_launcher_context_new:
* @display: an #SnDisplay
+ * @screen: X screen number
* @event_func: function to be called when a notable event occurs
* @event_func_data: data to pass to @event_func
* @free_data_func: function to be called on @event_func_data when freeing the context
*
* Creates a new launcher context, to be used by the program that is
- * starting a launch sequence. For example a file manager might
+ * starting a startup sequence. For example a file manager might
* create a launcher context when the user double-clicks on
* an application icon.
*
@@ -72,9 +64,7 @@ struct SnLauncherContext
**/
SnLauncherContext*
sn_launcher_context_new (SnDisplay *display,
- SnLauncherEventFunc event_func,
- void *event_func_data,
- SnFreeFunc free_data_func)
+ int screen)
{
SnLauncherContext *context;
@@ -86,13 +76,8 @@ sn_launcher_context_new (SnDisplay *display,
context->refcount = 1;
context->display = display;
sn_display_ref (context->display);
- context->event_func = event_func;
- context->event_func_data = event_func_data;
- context->free_data_func = free_data_func;
context->workspace = -1;
- context->pid = -1;
- context->type = SN_LAUNCH_TYPE_OTHER;
sn_list_prepend (context_list, context);
@@ -127,26 +112,14 @@ sn_launcher_context_unref (SnLauncherContext *context)
{
sn_list_remove (context_list, context);
- if (context->free_data_func)
- (* context->free_data_func) (context->event_func_data);
-
- sn_free (context->launch_id);
-
- if (context->launch_window != None)
- {
- sn_display_error_trap_push (context->display);
-
- XDestroyWindow (sn_display_get_x_display (context->display),
- context->launch_window);
-
- sn_display_error_trap_pop (context->display);
- }
+ sn_free (context->startup_id);
sn_display_unref (context->display);
sn_free (context);
}
}
+
static char*
strip_slashes (const char *src)
{
@@ -173,7 +146,7 @@ strip_slashes (const char *src)
* @launchee_name: name of the launchee app, suitable for debug output
* @timestamp: X timestamp of event causing the launch
*
- * Initiates a launch sequence. All the properties of the launch (such
+ * Initiates a startup sequence. All the properties of the launch (such
* as type, geometry, description) should be set up prior to
* initiating the sequence.
**/
@@ -188,12 +161,16 @@ sn_launcher_context_initiate (SnLauncherContext *context,
static char hostbuf[257];
char *s;
int len;
- Display *xdisplay;
char *canonicalized_launcher;
char *canonicalized_launchee;
- Atom atoms[1];
+ int i;
+#define MAX_PROPS 12
+ char *names[MAX_PROPS];
+ char *values[MAX_PROPS];
+ char *message;
+ char workspacebuf[257];
- if (context->launch_id != NULL)
+ if (context->startup_id != NULL)
{
fprintf (stderr, "%s called twice for the same SnLaunchContext\n",
__FUNCTION__);
@@ -220,302 +197,89 @@ sn_launcher_context_initiate (SnLauncherContext *context,
canonicalized_launcher, canonicalized_launchee, (unsigned long) timestamp,
(int) getpid (), (int) sequence_number, hostbuf);
++sequence_number;
-
+
sn_free (canonicalized_launcher);
sn_free (canonicalized_launchee);
- context->launch_id = s;
-
- xdisplay = sn_display_get_x_display (context->display);
-
- {
- XSetWindowAttributes attrs;
-
- attrs.override_redirect = True;
- attrs.event_mask = PropertyChangeMask | StructureNotifyMask;
-
- context->launch_window =
- XCreateWindow (xdisplay,
- RootWindow (xdisplay, 0),
- -100, -100, 1, 1,
- 0,
- CopyFromParent,
- CopyFromParent,
- CopyFromParent,
- CWOverrideRedirect | CWEventMask,
- &attrs);
- }
-
- /* push outer error to allow avoiding XSync after every
- * property set
- */
- sn_display_error_trap_push (context->display);
+ context->startup_id = s;
- sn_internal_set_string (context->display,
- context->launch_window,
- "_NET_LAUNCH_ID",
- context->launch_id);
-
- sn_internal_set_string (context->display,
- context->launch_window,
- "_NET_LAUNCH_HOSTNAME",
- hostbuf);
-
- switch (context->type)
- {
- case SN_LAUNCH_TYPE_OTHER:
- atoms[0] = sn_internal_atom_get (context->display,
- "_NET_LAUNCH_TYPE_OTHER");
- break;
- case SN_LAUNCH_TYPE_DOCK_ICON:
- atoms[0] = sn_internal_atom_get (context->display,
- "_NET_LAUNCH_TYPE_DOCK_ICON");
- break;
- case SN_LAUNCH_TYPE_DESKTOP_ICON:
- atoms[0] = sn_internal_atom_get (context->display,
- "_NET_LAUNCH_TYPE_DESKTOP_ICON");
- break;
- case SN_LAUNCH_TYPE_MENU:
- atoms[0] = sn_internal_atom_get (context->display,
- "_NET_LAUNCH_TYPE_MENU");
- break;
- case SN_LAUNCH_TYPE_KEY_SHORTCUT:
- atoms[0] = sn_internal_atom_get (context->display,
- "_NET_LAUNCH_TYPE_KEY_SHORTCUT");
- break;
- }
-
- sn_internal_set_atom_list (context->display,
- context->launch_window,
- "_NET_LAUNCH_TYPE",
- atoms, 1);
+ i = 0;
- if (context->geometry_set)
- {
- int cardinals[4];
-
- cardinals[0] = context->x;
- cardinals[1] = context->y;
- cardinals[2] = context->width;
- cardinals[3] = context->height;
-
- sn_internal_set_cardinal_list (context->display,
- context->launch_window,
- "_NET_LAUNCH_GEOMETRY",
- cardinals, 4);
- }
-
- if (context->geometry_window != None)
- {
- sn_internal_set_window (context->display,
- context->launch_window,
- "_NET_LAUNCH_GEOMETRY_WINDOW",
- context->geometry_window);
- }
-
- if (context->supports_cancel)
- {
- sn_internal_set_cardinal (context->display,
- context->launch_window,
- "_NET_LAUNCH_SUPPORTS_CANCEL",
- context->supports_cancel);
- }
+ names[i] = "ID";
+ values[i] = context->startup_id;
+ ++i;
- if (context->name)
+ if (context->name != NULL)
{
- sn_internal_set_utf8_string (context->display,
- context->launch_window,
- "_NET_LAUNCH_NAME",
- context->name);
+ names[i] = "NAME";
+ values[i] = context->name;
+ ++i;
}
- if (context->description)
+ if (context->description != NULL)
{
- sn_internal_set_utf8_string (context->display,
- context->launch_window,
- "_NET_LAUNCH_DESCRIPTION",
- context->description);
+ names[i] = "DESCRIPTION";
+ values[i] = context->description;
+ ++i;
}
if (context->workspace >= 0)
{
- sn_internal_set_cardinal (context->display,
- context->launch_window,
- "_NET_LAUNCH_DESKTOP",
- context->workspace);
+ names[i] = "DESCRIPTION";
+ sprintf (workspacebuf, "%d", context->workspace);
+ values[i] = workspacebuf;
+ ++i;
}
- if (context->pid >= 0)
+ if (context->wmclass != NULL)
{
- sn_internal_set_cardinal (context->display,
- context->launch_window,
- "_NET_LAUNCH_PID",
- context->pid);
- }
-
- if (context->binary_name)
- {
- sn_internal_set_string (context->display,
- context->launch_window,
- "_NET_LAUNCH_BINARY_NAME",
- context->binary_name);
- }
-
- if (context->icon_name)
- {
- sn_internal_set_string (context->display,
- context->launch_window,
- "_NET_LAUNCH_ICON_NAME",
- context->icon_name);
+ names[i] = "WMCLASS";
+ values[i] = context->wmclass;
+ ++i;
}
- if (context->resource_class)
+ if (context->binary_name != NULL)
{
- sn_internal_set_string (context->display,
- context->launch_window,
- "_NET_LAUNCH_LEGACY_RESOURCE_CLASS",
- context->resource_class);
+ names[i] = "BIN";
+ values[i] = context->binary_name;
+ ++i;
}
- if (context->resource_name)
+ if (context->icon_name != NULL)
{
- sn_internal_set_string (context->display,
- context->launch_window,
- "_NET_LAUNCH_LEGACY_RESOURCE_NAME",
- context->resource_name);
+ names[i] = "ICON";
+ values[i] = context->icon_name;
+ ++i;
}
- if (context->window_title)
- {
- sn_internal_set_string (context->display,
- context->launch_window,
- "_NET_LAUNCH_LEGACY_NAME",
- context->window_title);
- }
+ assert (i < MAX_PROPS);
- sn_display_error_trap_pop (context->display);
+ names[i] = NULL;
+ values[i] = NULL;
- /* Sync to server (so the launch window ID exists for example) */
- XFlush (xdisplay);
-
- /* Initiation message to all screens */
- {
- XEvent xev;
-
- xev.xclient.type = ClientMessage;
- xev.xclient.serial = 0;
- xev.xclient.send_event = True;
- xev.xclient.display = xdisplay;
- xev.xclient.window = context->launch_window;
- xev.xclient.message_type = sn_internal_atom_get (context->display,
- "_NET_LAUNCH_INITIATE");
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = timestamp;
- xev.xclient.data.l[1] = 0;
- xev.xclient.data.l[2] = 0;
- xev.xclient.data.l[3] = 0;
-
- sn_internal_send_event_all_screens (context->display,
- PropertyChangeMask,
- &xev);
- }
-}
+ message = sn_internal_serialize_message ("new",
+ (const char**) names,
+ (const char**) values);
-Window
-sn_launcher_context_get_launch_window (SnLauncherContext *context)
-{
- return context->launch_window;
+ sn_internal_broadcast_xmessage (context->display,
+ context->screen,
+ "_NET_STARTUP_INFO",
+ message);
+
+ sn_free (message);
}
const char*
-sn_launcher_context_get_launch_id (SnLauncherContext *context)
+sn_launcher_context_get_startup_id (SnLauncherContext *context)
{
- return context->launch_id;
+ return context->startup_id;
}
sn_bool_t
sn_launcher_context_get_initiated (SnLauncherContext *context)
{
- return context->launch_id != NULL;
-}
-
-sn_bool_t
-sn_launcher_context_get_canceled (SnLauncherContext *context)
-{
- return context->canceled;
-}
-
-/**
- * sn_launcher_context_get_completed:
- * @context: an #SnLauncherContext
- *
- * Returns %TRUE if _NET_LAUNCH_COMPLETE has been set or the
- * launch sequence window has been destroyed.
- *
- * Return value: %TRUE if the launch sequence has been completed
- **/
-sn_bool_t
-sn_launcher_context_get_completed (SnLauncherContext *context)
-{
- return context->completed;
-}
-
-/**
- * sn_launcher_context_cancel:
- * @context: an #SnLauncherContext
- *
- * Marks the launch canceled by setting the _NET_LAUNCH_CANCELED
- * property on the launch window. May not be called if the launch has
- * not been initiated. An #SN_LAUNCHER_EVENT_CANCELED event should be
- * received in response to the cancellation, under normal
- * circumstances.
- *
- * sn_launcher_context_cancel() should be called to request a
- * cancellation. Normally the launcher process is the process that
- * performs the cancellation as well, in response to an
- * #SN_LAUNCHER_EVENT_CANCELED event.
- *
- **/
-void
-sn_launcher_context_cancel (SnLauncherContext *context)
-{
- if (context->launch_id == NULL)
- {
- fprintf (stderr, "%s called for an SnLauncherContext that hasn't been initiated\n",
- __FUNCTION__);
- return;
- }
-
- sn_internal_set_cardinal (context->display,
- context->launch_window,
- "_NET_LAUNCH_CANCELED",
- 0);
-}
-
-/**
- * sn_launcher_context_complete:
- * @context: an #SnLauncherContext
- *
- * Marks @context as completed. Normally the launchee process marks a
- * launch sequence completed, however the launcher has to do it
- * if the launch is canceled.
- *
- **/
-void
-sn_launcher_context_complete (SnLauncherContext *context)
-{
- if (context->launch_id == NULL)
- {
- fprintf (stderr, "%s called for an SnLauncherContext that hasn't been initiated\n",
- __FUNCTION__);
- return;
- }
-
- sn_internal_set_cardinal (context->display,
- context->launch_window,
- "_NET_LAUNCH_COMPLETE",
- 0);
+ return context->startup_id != NULL;
}
/**
@@ -524,7 +288,7 @@ sn_launcher_context_complete (SnLauncherContext *context)
*
* This function should be called after forking, but before exec(), in
* the child process being launched. It sets up the environment variables
- * telling the child process about the launch ID and launch window.
+ * telling the child process about the launch ID.
* This function will leak the strings passed to putenv() so should
* only be used prior to an exec().
*
@@ -532,11 +296,9 @@ sn_launcher_context_complete (SnLauncherContext *context)
void
sn_launcher_context_setup_child_process (SnLauncherContext *context)
{
- char *launch_id;
- char *s;
- char *launch_window;
+ char *startup_id;
- if (context->launch_id == NULL)
+ if (context->startup_id == NULL)
{
fprintf (stderr, "%s called for an SnLauncherContext that hasn't been initiated\n",
__FUNCTION__);
@@ -545,61 +307,25 @@ sn_launcher_context_setup_child_process (SnLauncherContext *context)
/* Man we need glib here */
- launch_id = sn_malloc (strlen (context->launch_id) + strlen ("DESKTOP_LAUNCH_ID") + 3);
- strcpy (launch_id, "DESKTOP_LAUNCH_ID=");
- strcat (launch_id, context->launch_id);
-
- putenv (launch_id);
-
- launch_window = sn_malloc (strlen ("DESKTOP_LAUNCH_WINDOW") + 128);
- strcpy (launch_window, "DESKTOP_LAUNCH_WINDOW=");
- s = launch_window;
- while (*s)
- ++s;
-
- snprintf (s, 100, "0x%lx", context->launch_window);
+ startup_id = sn_malloc (strlen (context->startup_id) + strlen ("DESKTOP_STARTUP_ID") + 3);
+ strcpy (startup_id, "DESKTOP_STARTUP_ID=");
+ strcat (startup_id, context->startup_id);
- putenv (launch_window);
+ putenv (startup_id);
/* Can't free strings passed to putenv */
}
-#define WARN_ALREADY_INITIATED(context) do { if ((context)->launch_id != NULL) { \
+/* FIXME use something pluggable, not fprintf */
+#define WARN_ALREADY_INITIATED(context) do { if ((context)->startup_id != NULL) { \
fprintf (stderr, "%s called for an SnLauncherContext that has already been initiated\n", \
__FUNCTION__); \
return; \
} } while (0)
void
-sn_launcher_context_set_launch_type (SnLauncherContext *context,
- SnLaunchType type)
-{
- WARN_ALREADY_INITIATED (context);
-
- context->type = type;
-}
-
-void
-sn_launcher_context_set_geometry_window (SnLauncherContext *context,
- Window xwindow)
-{
- WARN_ALREADY_INITIATED (context);
-
- context->geometry_window = xwindow;
-}
-
-void
-sn_launcher_context_set_supports_cancel (SnLauncherContext *context,
- sn_bool_t supports_cancel)
-{
- WARN_ALREADY_INITIATED (context);
-
- context->supports_cancel = supports_cancel;
-}
-
-void
-sn_launcher_context_set_launch_name (SnLauncherContext *context,
- const char *name)
+sn_launcher_context_set_name (SnLauncherContext *context,
+ const char *name)
{
WARN_ALREADY_INITIATED (context);
@@ -608,8 +334,8 @@ sn_launcher_context_set_launch_name (SnLauncherContext *context,
}
void
-sn_launcher_context_set_launch_description (SnLauncherContext *context,
- const char *description)
+sn_launcher_context_set_description (SnLauncherContext *context,
+ const char *description)
{
WARN_ALREADY_INITIATED (context);
@@ -618,8 +344,8 @@ sn_launcher_context_set_launch_description (SnLauncherContext *context,
}
void
-sn_launcher_context_set_launch_workspace (SnLauncherContext *context,
- int workspace)
+sn_launcher_context_set_workspace (SnLauncherContext *context,
+ int workspace)
{
WARN_ALREADY_INITIATED (context);
@@ -627,33 +353,13 @@ sn_launcher_context_set_launch_workspace (SnLauncherContext *context,
}
void
-sn_launcher_context_set_legacy_resource_class (SnLauncherContext *context,
- const char *klass)
+sn_launcher_context_set_wmclass (SnLauncherContext *context,
+ const char *klass)
{
WARN_ALREADY_INITIATED (context);
- sn_free (context->resource_class);
- context->resource_class = sn_internal_strdup (klass);
-}
-
-void
-sn_launcher_context_set_legacy_resource_name (SnLauncherContext *context,
- const char *name)
-{
- WARN_ALREADY_INITIATED (context);
-
- sn_free (context->resource_name);
- context->resource_name = sn_internal_strdup (name);
-}
-
-void
-sn_launcher_context_set_legacy_window_title (SnLauncherContext *context,
- const char *title)
-{
- WARN_ALREADY_INITIATED (context);
-
- sn_free (context->window_title);
- context->window_title = sn_internal_strdup (title);
+ sn_free (context->wmclass);
+ context->wmclass = sn_internal_strdup (klass);
}
void
@@ -667,22 +373,6 @@ sn_launcher_context_set_binary_name (SnLauncherContext *context,
}
void
-sn_launcher_context_set_pid (SnLauncherContext *context,
- int pid)
-{
- context->pid = pid;
-
- /* set the X property if launch window already exists */
- if (context->launch_id != NULL)
- {
- sn_internal_set_cardinal (context->display,
- context->launch_window,
- "_NET_LAUNCH_PID",
- context->pid);
- }
-}
-
-void
sn_launcher_context_set_icon_name (SnLauncherContext *context,
const char *name)
{
@@ -691,385 +381,3 @@ sn_launcher_context_set_icon_name (SnLauncherContext *context,
sn_free (context->icon_name);
context->icon_name = sn_internal_strdup (name);
}
-
-struct SnLauncherEvent
-{
- int refcount;
- SnLauncherEventType type;
- Time timestamp;
- SnLauncherContext *context;
-};
-
-/**
- * sn_launcher_event_copy:
- * @event: event to copy
- *
- * Creates a copy of @event, the copy has a reference count of one.
- *
- * Return value: a new #SnLauncherEvent that's a copy of @event
- **/
-SnLauncherEvent*
-sn_launcher_event_copy (SnLauncherEvent *event)
-{
- SnLauncherEvent *copy;
-
- copy = sn_new (SnLauncherEvent, 1);
-
- copy->refcount = 1;
- copy->type = event->type;
- copy->timestamp = event->timestamp;
- copy->context = event->context;
- if (copy->context)
- sn_launcher_context_ref (copy->context);
-
- return copy;
-}
-
-/**
- * sn_launcher_event_ref:
- * @event: a #SnLauncherEvent
- *
- * Increments @event's reference count.
- **/
-void
-sn_launcher_event_ref (SnLauncherEvent *event)
-{
- event->refcount += 1;
-}
-
-/**
- * sn_launcher_event_unref:
- * @event: a #SnLauncherEvent
- *
- * Decrements @event's reference count and frees @event
- * if the count reaches zero.
- **/
-void
-sn_launcher_event_unref (SnLauncherEvent *event)
-{
- event->refcount -= 1;
-
- if (event->refcount == 0)
- {
- if (event->context)
- sn_launcher_context_unref (event->context);
- sn_free (event);
- }
-}
-
-/**
- * sn_launcher_event_get_type:
- * @event: a #SnLauncherEvent
- *
- * Gets the type of the launcher event.
- *
- * Return value: the type of event
- **/
-SnLauncherEventType
-sn_launcher_event_get_type (SnLauncherEvent *event)
-{
- return event->type;
-}
-
-/**
- * sn_launcher_event_get_context:
- * @event: a #SnLauncherEvent
- *
- * Gets the context associated with @event. The
- * returned context is owned by the event, i.e.
- * the caller of sn_launcher_event_get_context() should
- * not unref the context.
- *
- * Return value: the context for this event
- **/
-SnLauncherContext*
-sn_launcher_event_get_context (SnLauncherEvent *event)
-{
- return event->context;
-}
-
-/**
- * sn_launcher_event_get_time:
- * @event: a #SnLauncherEvent
- *
- * Gets the X Window System timestamp associated with this launcher
- * event.
- *
- * Return value: timestamp for the event, or CurrentTime if none available
- **/
-Time
-sn_launcher_event_get_time (SnLauncherEvent *event)
-{
- return event->timestamp;
-}
-
-static sn_bool_t
-check_cardinal_exists (SnDisplay *display,
- Window xwindow,
- const char *property)
-{
- int val;
-
- return sn_internal_get_cardinal (display, xwindow, property,
- &val);
-}
-
-typedef struct
-{
- SnDisplay *display;
- Window launch_window;
- sn_bool_t result;
-} HaveContextsData;
-
-static sn_bool_t
-have_active_contexts_foreach (void *value,
- void *data)
-{
- SnLauncherContext *context = value;
- HaveContextsData *hcd = data;
-
- if (!context->completed &&
- context->launch_window == hcd->launch_window &&
- sn_display_get_x_display (context->display) ==
- sn_display_get_x_display (hcd->display))
- {
- hcd->result = TRUE;
- return FALSE;
- }
-
- return TRUE;
-}
-
-typedef struct
-{
- SnDisplay *display;
- Window launch_window;
- SnList *contexts;
-} FindContextsData;
-
-static sn_bool_t
-find_active_contexts_foreach (void *value,
- void *data)
-{
- SnLauncherContext *context = value;
- FindContextsData *fcd = data;
-
- if (!context->completed &&
- context->launch_window == fcd->launch_window &&
- sn_display_get_x_display (context->display) ==
- sn_display_get_x_display (fcd->display))
- sn_list_prepend (fcd->contexts, context);
-
- return TRUE;
-}
-
-typedef struct
-{
- SnLauncherEvent *base_event;
- SnList *events;
-} CreateEventsData;
-
-static sn_bool_t
-create_events_foreach (void *value,
- void *data)
-{
- SnLauncherContext *context = value;
- CreateEventsData *ced = data;
- SnLauncherEvent *event;
-
- event = sn_launcher_event_copy (ced->base_event);
- event->context = context;
- sn_launcher_context_ref (context);
-
- sn_list_prepend (ced->events, event);
-
- return TRUE;
-}
-
-static sn_bool_t
-dispatch_events_foreach (void *value,
- void *data)
-{
- SnLauncherEvent *event = value;
-
- /* Filter out duplicate events and update flags */
- switch (event->type)
- {
- case SN_LAUNCHER_EVENT_CANCELED:
- if (event->context->canceled)
- {
- sn_launcher_event_unref (event);
- event = NULL;
- }
- else
- {
- event->context->canceled = TRUE;
- }
- break;
- case SN_LAUNCHER_EVENT_COMPLETED:
- if (event->context->completed)
- {
- sn_launcher_event_unref (event);
- event = NULL;
- }
- else
- {
- event->context->completed = TRUE;
- }
- break;
-
- default:
- break;
- }
-
- if (event)
- {
- if (event->context->event_func)
- (* event->context->event_func) (event,
- event->context->event_func_data);
- sn_launcher_event_unref (event);
- }
-
- return TRUE;
-}
-
-static void
-dispatch_event (SnDisplay *display,
- Window launch_window,
- SnLauncherEvent *event)
-{
- /* Find all applicable contexts, create an event for each, and send
- * the events out.
- */
- FindContextsData fcd;
- CreateEventsData ced;
-
- fcd.display = display;
- fcd.launch_window = launch_window;
- fcd.contexts = sn_list_new ();
-
- if (context_list != NULL)
- sn_list_foreach (context_list, find_active_contexts_foreach, &fcd);
-
- ced.base_event = event;
- ced.events = sn_list_new ();
- sn_list_foreach (fcd.contexts, create_events_foreach, &ced);
-
- /* This unref's each event as it's dispatched */
- sn_list_foreach (ced.events, dispatch_events_foreach, NULL);
-
- sn_list_free (fcd.contexts);
- sn_list_free (ced.events);
-}
-
-sn_bool_t
-sn_internal_launcher_process_event (SnDisplay *display,
- XEvent *xevent)
-{
- sn_bool_t retval;
- SnLauncherEvent *event;
- Window event_xwindow;
-
- if (context_list == NULL ||
- sn_list_empty (context_list))
- return FALSE; /* no one cares */
-
- event_xwindow = None;
- event = NULL;
- retval = FALSE;
-
- switch (xevent->xany.type)
- {
- case PropertyNotify:
- if (xevent->xproperty.atom ==
- sn_internal_atom_get (display, "_NET_LAUNCH_CANCELED"))
- {
- event_xwindow = xevent->xproperty.window;
-
- if (check_cardinal_exists (display, event_xwindow,
- "_NET_LAUNCH_CANCELED"))
- {
- event = sn_new (SnLauncherEvent, 1);
-
- event->refcount = 1;
- event->type = SN_LAUNCHER_EVENT_CANCELED;
- event->timestamp = xevent->xproperty.time;
- event->context = NULL;
- }
-
- retval = TRUE;
- }
- else if (xevent->xproperty.atom ==
- sn_internal_atom_get (display, "_NET_LAUNCH_COMPLETE"))
- {
- event_xwindow = xevent->xproperty.window;
-
- if (check_cardinal_exists (display, event_xwindow,
- "_NET_LAUNCH_COMPLETE"))
- {
- event = sn_new (SnLauncherEvent, 1);
-
- event->refcount = 1;
- event->type = SN_LAUNCHER_EVENT_COMPLETED;
- event->timestamp = xevent->xproperty.time;
- event->context = NULL;
- }
-
- retval = TRUE;
- }
- break;
-
- case ClientMessage:
- if (xevent->xclient.message_type ==
- sn_internal_atom_get (display,
- "_NET_LAUNCH_PULSE"))
- {
- event_xwindow = xevent->xclient.window;
-
- event = sn_new (SnLauncherEvent, 1);
-
- event->refcount = 1;
- event->type = SN_LAUNCHER_EVENT_PULSE;
- event->timestamp = CurrentTime;
- event->context = NULL;
-
- retval = TRUE;
- }
- break;
-
- case DestroyNotify:
- {
- HaveContextsData hcd;
- hcd.display = display;
- hcd.launch_window = xevent->xdestroywindow.window;
- hcd.result = FALSE;
- if (context_list)
- sn_list_foreach (context_list, have_active_contexts_foreach, &hcd);
- if (hcd.result)
- {
- event_xwindow = hcd.launch_window;
-
- event = sn_new (SnLauncherEvent, 1);
-
- event->refcount = 1;
- event->type = SN_LAUNCHER_EVENT_COMPLETED;
- event->timestamp = CurrentTime;
- event->context = NULL;
- }
- }
- break;
-
- default:
- break;
- }
-
- if (event != NULL)
- {
- dispatch_event (display, event_xwindow, event);
-
- sn_launcher_event_unref (event);
- }
-
- return retval;
-}
-
diff --git a/libsn/sn-launcher.h b/libsn/sn-launcher.h
index bafeef1..07ad7c6 100644
--- a/libsn/sn-launcher.h
+++ b/libsn/sn-launcher.h
@@ -32,22 +32,9 @@
SN_BEGIN_DECLS
typedef struct SnLauncherContext SnLauncherContext;
-typedef struct SnLauncherEvent SnLauncherEvent;
-
-typedef void (* SnLauncherEventFunc) (SnLauncherEvent *event,
- void *user_data);
-
-typedef enum
-{
- SN_LAUNCHER_EVENT_CANCELED,
- SN_LAUNCHER_EVENT_COMPLETED,
- SN_LAUNCHER_EVENT_PULSE
-} SnLauncherEventType;
SnLauncherContext* sn_launcher_context_new (SnDisplay *display,
- SnLauncherEventFunc event_func,
- void *event_func_data,
- SnFreeFunc free_data_func);
+ int screen);
void sn_launcher_context_ref (SnLauncherContext *context);
void sn_launcher_context_unref (SnLauncherContext *context);
@@ -56,47 +43,23 @@ void sn_launcher_context_initiate (SnLauncherContext *context,
const char *launcher_name,
const char *launchee_name,
Time timestamp);
-Window sn_launcher_context_get_launch_window (SnLauncherContext *context);
const char* sn_launcher_context_get_launch_id (SnLauncherContext *context);
sn_bool_t sn_launcher_context_get_initiated (SnLauncherContext *context);
-sn_bool_t sn_launcher_context_get_canceled (SnLauncherContext *context);
-sn_bool_t sn_launcher_context_get_completed (SnLauncherContext *context);
-void sn_launcher_context_cancel (SnLauncherContext *context);
-void sn_launcher_context_complete (SnLauncherContext *context);
void sn_launcher_context_setup_child_process (SnLauncherContext *context);
-void sn_launcher_context_set_launch_type (SnLauncherContext *context,
- SnLaunchType type);
-void sn_launcher_context_set_geometry_window (SnLauncherContext *context,
- Window xwindow);
-void sn_launcher_context_set_supports_cancel (SnLauncherContext *context,
- sn_bool_t supports_cancel);
-void sn_launcher_context_set_launch_name (SnLauncherContext *context,
- const char *name);
-void sn_launcher_context_set_launch_description (SnLauncherContext *context,
- const char *description);
-void sn_launcher_context_set_launch_workspace (SnLauncherContext *context,
- int workspace);
-void sn_launcher_context_set_legacy_resource_class (SnLauncherContext *context,
- const char *klass);
-void sn_launcher_context_set_legacy_resource_name (SnLauncherContext *context,
- const char *name);
-void sn_launcher_context_set_legacy_window_title (SnLauncherContext *context,
- const char *title);
-void sn_launcher_context_set_binary_name (SnLauncherContext *context,
- const char *name);
-void sn_launcher_context_set_pid (SnLauncherContext *context,
- int pid);
-void sn_launcher_context_set_icon_name (SnLauncherContext *context,
- const char *name);
-
-SnLauncherEvent* sn_launcher_event_copy (SnLauncherEvent *event);
-void sn_launcher_event_ref (SnLauncherEvent *event);
-void sn_launcher_event_unref (SnLauncherEvent *event);
-SnLauncherEventType sn_launcher_event_get_type (SnLauncherEvent *event);
-SnLauncherContext* sn_launcher_event_get_context (SnLauncherEvent *event);
-Time sn_launcher_event_get_time (SnLauncherEvent *event);
+void sn_launcher_context_set_name (SnLauncherContext *context,
+ const char *name);
+void sn_launcher_context_set_description (SnLauncherContext *context,
+ const char *description);
+void sn_launcher_context_set_workspace (SnLauncherContext *context,
+ int workspace);
+void sn_launcher_context_set_wmclass (SnLauncherContext *context,
+ const char *klass);
+void sn_launcher_context_set_binary_name (SnLauncherContext *context,
+ const char *name);
+void sn_launcher_context_set_icon_name (SnLauncherContext *context,
+ const char *name);
SN_END_DECLS
diff --git a/libsn/sn-monitor.c b/libsn/sn-monitor.c
index c657114..c3f3f1a 100644
--- a/libsn/sn-monitor.c
+++ b/libsn/sn-monitor.c
@@ -25,12 +25,11 @@
#include "sn-internals.h"
#include "sn-xmessages.h"
-#define KDE_STARTUP_INFO_ATOM "_KDE_STARTUP_INFO"
-
struct SnMonitorContext
{
int refcount;
SnDisplay *display;
+ int screen;
SnMonitorEventFunc event_func;
void *event_func_data;
SnFreeFunc free_data_func;
@@ -45,42 +44,31 @@ struct SnMonitorEvent
int refcount;
SnMonitorEventType type;
SnMonitorContext *context;
- SnLaunchSequence *sequence;
- Time timestamp;
+ SnStartupSequence *sequence;
+ Window xwindow; /* where event occurred */
};
-struct SnLaunchSequence
+struct SnStartupSequence
{
int refcount;
-
- char *id;
+
SnDisplay *display;
+ int screen;
- /* launch_window is NULL for Xmessage-based launches */
- Window launch_window;
-
+ char *id;
+
char *name;
char *description;
- char *resource_class;
- char *resource_name;
- char *window_title;
+ char *wmclass;
int workspace;
char *binary_name;
- char *hostname;
- char *icon_name;
- int pid;
-
- /* geometry */
- Window geometry_window;
- int x, y, width, height;
+ char *icon_name;
- unsigned int geometry_set : 1;
- unsigned int canceled : 1;
unsigned int completed : 1;
- unsigned int supports_cancel : 1;
+ unsigned int canceled : 1;
int creation_serial;
};
@@ -91,23 +79,25 @@ static int next_sequence_serial = 0;
static void xmessage_func (SnDisplay *display,
const char *message_type,
+ Window xwindow,
const char *message,
void *user_data);
/**
* sn_monitor_context_new:
* @display: an #SnDisplay
+ * @screen: an X screen number
* @event_func: function to call when an event is received
* @event_func_data: extra data to pass to @event_func
* @free_data_func: function to free @event_func_data when the context is freed
*
- * Creates a new context for monitoring launch sequences. Normally
+ * Creates a new context for monitoring startup sequences. Normally
* only launch feedback indicator applications such as the window
* manager or task manager would use #SnMonitorContext.
* #SnLauncherContext and #SnLauncheeContext are more often used by
* applications.
*
- * To detect launch sequence initiations, PropertyChangeMask must be
+ * To detect startup sequence initiations, PropertyChangeMask must be
* selected on all root windows for a display. libsn does not do this
* for you because it's pretty likely to mess something up. So you
* have to do it yourself in programs that use #SnMonitorContext.
@@ -116,6 +106,7 @@ static void xmessage_func (SnDisplay *display,
**/
SnMonitorContext*
sn_monitor_context_new (SnDisplay *display,
+ int screen,
SnMonitorEventFunc event_func,
void *event_func_data,
SnFreeFunc free_data_func)
@@ -131,13 +122,15 @@ sn_monitor_context_new (SnDisplay *display,
context->display = display;
sn_display_ref (context->display);
-
+ context->screen = screen;
+
if (context_list == NULL)
context_list = sn_list_new ();
if (sn_list_empty (context_list))
sn_internal_add_xmessage_func (display,
- KDE_STARTUP_INFO_ATOM,
+ screen,
+ "_NET_STARTUP_INFO",
xmessage_func,
NULL, NULL);
@@ -180,7 +173,8 @@ sn_monitor_context_unref (SnMonitorContext *context)
if (sn_list_empty (context_list))
sn_internal_remove_xmessage_func (context->display,
- KDE_STARTUP_INFO_ATOM,
+ context->screen,
+ "_NET_STARTUP_INFO",
xmessage_func,
NULL);
@@ -208,7 +202,7 @@ sn_monitor_event_unref (SnMonitorEvent *event)
if (event->context)
sn_monitor_context_unref (event->context);
if (event->sequence)
- sn_launch_sequence_unref (event->sequence);
+ sn_startup_sequence_unref (event->sequence);
sn_free (event);
}
}
@@ -228,10 +222,9 @@ sn_monitor_event_copy (SnMonitorEvent *event)
sn_monitor_context_ref (copy->context);
copy->sequence = event->sequence;
if (copy->sequence)
- sn_launch_sequence_ref (copy->sequence);
-
- copy->timestamp = event->timestamp;
-
+ sn_startup_sequence_ref (copy->sequence);
+ copy->xwindow = event->xwindow;
+
return copy;
}
@@ -241,8 +234,8 @@ sn_monitor_event_get_type (SnMonitorEvent *event)
return event->type;
}
-SnLaunchSequence*
-sn_monitor_event_get_launch_sequence (SnMonitorEvent *event)
+SnStartupSequence*
+sn_monitor_event_get_startup_sequence (SnMonitorEvent *event)
{
return event->sequence;
}
@@ -253,163 +246,14 @@ sn_monitor_event_get_context (SnMonitorEvent *event)
return event->context;
}
-Time
-sn_monitor_event_get_time (SnMonitorEvent *event)
-{
- return event->timestamp;
-}
-
-static void
-update_geometry (SnLaunchSequence *sequence)
-{
- int *vals;
- int n_vals;
-
- sequence->geometry_set = FALSE;
-
- vals = NULL;
- n_vals = 0;
- if (sn_internal_get_cardinal_list (sequence->display,
- sequence->launch_window,
- "_NET_LAUNCH_GEOMETRY",
- &vals, &n_vals) &&
- n_vals == 4)
- {
- sequence->x = vals[0];
- sequence->y = vals[1];
- sequence->width = vals[2];
- sequence->height = vals[3];
- }
-
- sn_free (vals);
-}
-
-static void
-update_pid (SnLaunchSequence *sequence)
-{
- int val;
-
- sequence->pid = -1;
-
- val = -1;
- if (sn_internal_get_cardinal (sequence->display,
- sequence->launch_window,
- "_NET_LAUNCH_PID",
- &val))
- sequence->pid = val;
-}
-
-static SnLaunchSequence*
-sn_launch_sequence_new (SnDisplay *display,
- Window launch_window)
-{
- SnLaunchSequence *sequence;
- char *id;
- int val;
-
- /* Select input, then get _NET_LAUNCH_ID,
- * because we want to be sure we detect a BadWindow
- * if it happens prior to selecting input, and
- * getting _NET_LAUNCH_ID will bomb on BadWindow
- */
- if (launch_window != None) /* launch_window may be NULL for xmessage sequence */
- {
- sn_display_error_trap_push (display);
- XSelectInput (sn_display_get_x_display (display),
- launch_window,
- PropertyChangeMask | StructureNotifyMask);
- sn_display_error_trap_pop (display);
-
- id = NULL;
- if (!sn_internal_get_string (display, launch_window,
- "_NET_LAUNCH_ID", &id))
- {
- return NULL;
- }
- }
-
- sequence = sn_new0 (SnLaunchSequence, 1);
-
- sequence->refcount = 1;
-
- sequence->creation_serial = next_sequence_serial;
- ++next_sequence_serial;
-
- sequence->id = id;
- sequence->launch_window = launch_window;
- sequence->display = display;
- sn_display_ref (display);
-
- sequence->workspace = -1; /* not set */
- sequence->pid = -1;
-
- /* Update stuff that can change over time */
- update_geometry (sequence);
- update_pid (sequence);
-
- if (sequence->launch_window != None)
- {
- /* Grab all the stuff that can't be changed later */
- sn_internal_get_utf8_string (sequence->display,
- sequence->launch_window,
- "_NET_LAUNCH_NAME",
- &sequence->name);
- sn_internal_get_utf8_string (sequence->display,
- sequence->launch_window,
- "_NET_LAUNCH_DESCRIPTION",
- &sequence->description);
- sn_internal_get_string (sequence->display,
- sequence->launch_window,
- "_NET_LAUNCH_LEGACY_RESOURCE_CLASS",
- &sequence->resource_class);
- sn_internal_get_string (sequence->display,
- sequence->launch_window,
- "_NET_LAUNCH_LEGACY_RESOURCE_NAME",
- &sequence->resource_name);
- sn_internal_get_string (sequence->display,
- sequence->launch_window,
- "_NET_LAUNCH_LEGACY_NAME",
- &sequence->window_title);
- if (sn_internal_get_cardinal (sequence->display,
- sequence->launch_window,
- "_NET_LAUNCH_DESKTOP",
- &val))
- sequence->workspace = val;
- sn_internal_get_string (sequence->display,
- sequence->launch_window,
- "_NET_LAUNCH_BINARY_NAME",
- &sequence->binary_name);
- sn_internal_get_string (sequence->display,
- sequence->launch_window,
- "_NET_LAUNCH_HOSTNAME",
- &sequence->hostname);
- sn_internal_get_string (sequence->display,
- sequence->launch_window,
- "_NET_LAUNCH_ICON_NAME",
- &sequence->icon_name);
- sn_internal_get_window (sequence->display,
- sequence->launch_window,
- "_NET_LAUNCH_GEOMETRY_WINDOW",
- &sequence->geometry_window);
-
- if (sn_internal_get_cardinal (sequence->display,
- sequence->launch_window,
- "_NET_LAUNCH_SUPPORTS_CANCEL",
- &val))
- sequence->supports_cancel = val != 0;
- }
-
- return sequence;
-}
-
void
-sn_launch_sequence_ref (SnLaunchSequence *sequence)
+sn_startup_sequence_ref (SnStartupSequence *sequence)
{
sequence->refcount += 1;
}
void
-sn_launch_sequence_unref (SnLaunchSequence *sequence)
+sn_startup_sequence_unref (SnStartupSequence *sequence)
{
sequence->refcount -= 1;
@@ -419,12 +263,9 @@ sn_launch_sequence_unref (SnLaunchSequence *sequence)
sn_free (sequence->name);
sn_free (sequence->description);
- sn_free (sequence->resource_class);
- sn_free (sequence->resource_name);
- sn_free (sequence->window_title);
+ sn_free (sequence->wmclass);
sn_free (sequence->binary_name);
sn_free (sequence->icon_name);
- sn_free (sequence->hostname);
sn_display_unref (sequence->display);
sn_free (sequence);
@@ -432,145 +273,73 @@ sn_launch_sequence_unref (SnLaunchSequence *sequence)
}
const char*
-sn_launch_sequence_get_id (SnLaunchSequence *sequence)
+sn_startup_sequence_get_id (SnStartupSequence *sequence)
{
return sequence->id;
}
-Window
-sn_launch_sequence_get_window (SnLaunchSequence *sequence)
-{
- return sequence->launch_window;
-}
-
-sn_bool_t
-sn_launch_sequence_get_geometry (SnLaunchSequence *sequence,
- int *x,
- int *y,
- int *width,
- int *height)
-{
- if (sequence->geometry_set)
- {
- *x = sequence->x;
- *y = sequence->y;
- *width = sequence->width;
- *height = sequence->height;
- return TRUE;
- }
- else
- {
- *x = 0;
- *y = 0;
- *width = 0;
- *height = 0;
- return FALSE;
- }
-}
-
-Window
-sn_launch_sequence_get_geometry_window (SnLaunchSequence *sequence)
-{
- return sequence->geometry_window;
-}
-
sn_bool_t
-sn_launch_sequence_get_completed (SnLaunchSequence *sequence)
+sn_startup_sequence_get_completed (SnStartupSequence *sequence)
{
return sequence->completed;
}
-sn_bool_t
-sn_launch_sequence_get_canceled (SnLaunchSequence *sequence)
-{
- return sequence->canceled;
-}
-
const char*
-sn_launch_sequence_get_name (SnLaunchSequence *sequence)
+sn_startup_sequence_get_name (SnStartupSequence *sequence)
{
return sequence->name;
}
const char*
-sn_launch_sequence_get_description (SnLaunchSequence *sequence)
+sn_startup_sequence_get_description (SnStartupSequence *sequence)
{
return sequence->description;
}
int
-sn_launch_sequence_get_workspace (SnLaunchSequence *sequence)
+sn_startup_sequence_get_workspace (SnStartupSequence *sequence)
{
return sequence->workspace;
}
const char*
-sn_launch_sequence_get_legacy_resource_class (SnLaunchSequence *sequence)
-{
- return sequence->resource_class;
-}
-
-const char*
-sn_launch_sequence_get_legacy_resource_name (SnLaunchSequence *sequence)
+sn_startup_sequence_get_wmclass (SnStartupSequence *sequence)
{
- return sequence->resource_name;
+ return sequence->wmclass;
}
const char*
-sn_launch_sequence_get_legacy_window_title (SnLaunchSequence *sequence)
-{
- return sequence->window_title;
-}
-
-sn_bool_t
-sn_launch_sequence_get_supports_cancel (SnLaunchSequence *sequence)
-{
- return sequence->supports_cancel;
-}
-
-int
-sn_launch_sequence_get_pid (SnLaunchSequence *sequence)
-{
- return sequence->pid;
-}
-
-const char*
-sn_launch_sequence_get_binary_name (SnLaunchSequence *sequence)
+sn_startup_sequence_get_binary_name (SnStartupSequence *sequence)
{
return sequence->binary_name;
}
const char*
-sn_launch_sequence_get_hostname (SnLaunchSequence *sequence)
-{
- return sequence->hostname;
-}
-
-const char*
-sn_launch_sequence_get_icon_name (SnLaunchSequence *sequence)
+sn_startup_sequence_get_icon_name (SnStartupSequence *sequence)
{
return sequence->icon_name;
}
-void
-sn_launch_sequence_cancel (SnLaunchSequence *sequence)
-{
- if (sequence->supports_cancel)
- sn_internal_set_cardinal (sequence->display,
- sequence->launch_window,
- "_NET_LAUNCH_CANCELED",
- 0);
-}
-static sn_bool_t
-check_cardinal_exists (SnDisplay *display,
- Window xwindow,
- const char *property)
+static SnStartupSequence*
+sn_startup_sequence_new (SnDisplay *display)
{
- int val;
+ SnStartupSequence *sequence;
+
+ sequence = sn_new0 (SnStartupSequence, 1);
+
+ sequence->refcount = 1;
- return sn_internal_get_cardinal (display, xwindow, property,
- &val);
+ sequence->creation_serial = next_sequence_serial;
+ ++next_sequence_serial;
+
+ sequence->id = NULL;
+ sequence->display = display;
+ sn_display_ref (display);
+
+ sequence->workspace = -1; /* not set */
+
+ return sequence;
}
typedef struct
@@ -589,7 +358,7 @@ create_context_events_foreach (void *value,
SnMonitorContext *context = value;
CreateContextEventsData *ced = data;
- /* Don't send events for launch sequences initiated before the
+ /* Don't send events for startup sequences initiated before the
* context was created
*/
if (ced->base_event->sequence->creation_serial >=
@@ -662,61 +431,17 @@ filter_event (SnMonitorEvent *event)
return retval;
}
-typedef struct
-{
- SnDisplay *display;
- Window launch_window;
- SnLaunchSequence *found;
-} FindSequenceData;
-
-static sn_bool_t
-find_sequence_foreach (void *value,
- void *data)
-{
- SnLaunchSequence *sequence = value;
- FindSequenceData *fsd = data;
-
- if (sequence->launch_window == fsd->launch_window &&
- sn_display_get_x_display (sequence->display) ==
- sn_display_get_x_display (fsd->display))
- {
- fsd->found = sequence;
- return FALSE;
- }
-
- return TRUE;
-}
-
-static SnLaunchSequence*
-find_sequence_for_window (SnDisplay *display,
- Window event_window)
-{
- FindSequenceData fsd;
-
- if (sequence_list == NULL)
- return NULL;
-
- fsd.display = display;
- fsd.launch_window = event_window;
- fsd.found = NULL;
-
- sn_list_foreach (sequence_list, find_sequence_foreach, &fsd);
-
- return fsd.found;
-}
-
-static SnLaunchSequence*
-add_sequence (SnDisplay *display,
- Window event_xwindow)
+static SnStartupSequence*
+add_sequence (SnDisplay *display)
{
- SnLaunchSequence *sequence;
+ SnStartupSequence *sequence;
sequence =
- sn_launch_sequence_new (display, event_xwindow);
+ sn_startup_sequence_new (display);
if (sequence)
{
- sn_launch_sequence_ref (sequence); /* ref held by sequence list */
+ sn_startup_sequence_ref (sequence); /* ref held by sequence list */
if (sequence_list == NULL)
sequence_list = sn_list_new ();
sn_list_prepend (sequence_list, sequence);
@@ -726,46 +451,21 @@ add_sequence (SnDisplay *display,
}
static void
-remove_sequence (SnLaunchSequence *sequence)
+remove_sequence (SnStartupSequence *sequence)
{
sn_list_remove (sequence_list, sequence);
- sn_launch_sequence_unref (sequence);
+ sn_startup_sequence_unref (sequence);
}
static void
dispatch_monitor_event (SnDisplay *display,
- SnMonitorEvent *event,
- Window event_xwindow)
+ SnMonitorEvent *event)
{
if (event->type == SN_MONITOR_EVENT_INITIATED)
{
if (event->sequence == NULL)
- event->sequence = add_sequence (display, event_xwindow);
+ event->sequence = add_sequence (display);
}
- else if (event->sequence == NULL)
- {
- event->sequence = find_sequence_for_window (display,
- event_xwindow);
- if (event->sequence)
- sn_launch_sequence_ref (event->sequence); /* ref held by event */
- }
-
- if (event->sequence != NULL)
- {
- switch (event->type)
- {
- case SN_MONITOR_EVENT_GEOMETRY_CHANGED:
- update_geometry (event->sequence);
- break;
-
- case SN_MONITOR_EVENT_PID_CHANGED:
- update_pid (event->sequence);
- break;
-
- default:
- break;
- }
- }
if (event->sequence != NULL &&
!filter_event (event))
@@ -794,170 +494,13 @@ sn_internal_monitor_process_event (SnDisplay *display,
XEvent *xevent)
{
sn_bool_t retval;
- SnMonitorEvent *event;
- Window event_xwindow;
if (context_list == NULL ||
sn_list_empty (context_list))
return FALSE; /* no one cares */
-
- event_xwindow = None;
- event = NULL;
- retval = FALSE;
-
- switch (xevent->xany.type)
- {
- case PropertyNotify:
- if (xevent->xproperty.atom ==
- sn_internal_atom_get (display, "_NET_LAUNCH_CANCELED"))
- {
- event_xwindow = xevent->xproperty.window;
-
- if (check_cardinal_exists (display, event_xwindow,
- "_NET_LAUNCH_CANCELED"))
- {
- event = sn_new (SnMonitorEvent, 1);
-
- event->refcount = 1;
- event->type = SN_MONITOR_EVENT_CANCELED;
- event->timestamp = xevent->xproperty.time;
- event->context = NULL;
- event->sequence = NULL;
-
- retval = TRUE;
- }
- }
- else if (xevent->xproperty.atom ==
- sn_internal_atom_get (display, "_NET_LAUNCH_COMPLETE"))
- {
- event_xwindow = xevent->xproperty.window;
-
- if (check_cardinal_exists (display, event_xwindow,
- "_NET_LAUNCH_COMPLETE"))
- {
- event = sn_new (SnMonitorEvent, 1);
-
- event->refcount = 1;
- event->type = SN_MONITOR_EVENT_COMPLETED;
- event->timestamp = xevent->xproperty.time;
- event->context = NULL;
- event->sequence = NULL;
-
- retval = TRUE;
- }
- }
- else if (xevent->xproperty.atom ==
- sn_internal_atom_get (display, "_NET_LAUNCH_GEOMETRY"))
- {
- event_xwindow = xevent->xproperty.window;
-
- event = sn_new (SnMonitorEvent, 1);
-
- event->refcount = 1;
- event->type = SN_MONITOR_EVENT_GEOMETRY_CHANGED;
- event->timestamp = xevent->xproperty.time;
- event->context = NULL;
- event->sequence = NULL;
-
- retval = TRUE;
- }
- else if (xevent->xproperty.atom ==
- sn_internal_atom_get (display, "_NET_LAUNCH_PID"))
- {
- event_xwindow = xevent->xproperty.window;
-
- event = sn_new (SnMonitorEvent, 1);
-
- event->refcount = 1;
- event->type = SN_MONITOR_EVENT_PID_CHANGED;
- event->timestamp = xevent->xproperty.time;
- event->context = NULL;
- event->sequence = NULL;
-
- retval = TRUE;
- }
- break;
-
- case ClientMessage:
- if (xevent->xclient.message_type ==
- sn_internal_atom_get (display,
- "_NET_LAUNCH_PULSE"))
- {
- event_xwindow = xevent->xclient.window;
-
- event = sn_new (SnMonitorEvent, 1);
-
- event->refcount = 1;
- event->type = SN_MONITOR_EVENT_PULSE;
- event->timestamp = CurrentTime;
- event->context = NULL;
- event->sequence = NULL;
-
- retval = TRUE;
- }
- else if (xevent->xclient.message_type ==
- sn_internal_atom_get (display,
- "_NET_LAUNCH_INITIATE"))
- {
- SnLaunchSequence *sequence;
-
- /* Don't be fooled by duplicate initiate messages -
- * check that the sequence doesn't exist yet
- */
- sequence = find_sequence_for_window (display,
- xevent->xclient.window);
-
- if (sequence == NULL)
- {
- event_xwindow = xevent->xclient.window;
-
- event = sn_new (SnMonitorEvent, 1);
-
- event->refcount = 1;
- event->type = SN_MONITOR_EVENT_INITIATED;
- event->timestamp = xevent->xclient.data.l[0];
- event->context = NULL;
- event->sequence = NULL;
- }
-
- retval = TRUE;
- }
- break;
-
- case DestroyNotify:
- {
- SnLaunchSequence *sequence;
-
- sequence = find_sequence_for_window (display,
- xevent->xdestroywindow.window);
-
- if (sequence != NULL)
- {
- event_xwindow = xevent->xdestroywindow.window;
-
- event = sn_new (SnMonitorEvent, 1);
-
- event->refcount = 1;
- event->type = SN_MONITOR_EVENT_COMPLETED;
- event->timestamp = CurrentTime;
- event->context = NULL;
- event->sequence = sequence;
- sn_launch_sequence_ref (sequence);
- }
- }
- break;
-
- default:
- break;
- }
-
- if (event != NULL)
- {
- dispatch_monitor_event (display, event, event_xwindow);
-
- sn_monitor_event_unref (event);
- }
+ retval = FALSE;
+
return retval;
}
@@ -965,14 +508,14 @@ typedef struct
{
SnDisplay *display;
const char *id;
- SnLaunchSequence *found;
+ SnStartupSequence *found;
} FindSequenceByIdData;
static sn_bool_t
find_sequence_by_id_foreach (void *value,
void *data)
{
- SnLaunchSequence *sequence = value;
+ SnStartupSequence *sequence = value;
FindSequenceByIdData *fsd = data;
if (strcmp (sequence->id, fsd->id) == 0 &&
@@ -986,7 +529,7 @@ find_sequence_by_id_foreach (void *value,
return TRUE;
}
-static SnLaunchSequence*
+static SnStartupSequence*
find_sequence_for_id (SnDisplay *display,
const char *id)
{
@@ -1011,7 +554,7 @@ do_xmessage_event_foreach (void *value,
SnMonitorEvent *event = value;
SnDisplay *display = data;
- dispatch_monitor_event (display, event, None);
+ dispatch_monitor_event (display, event);
return TRUE;
}
@@ -1027,6 +570,7 @@ unref_event_foreach (void *value,
static void
xmessage_func (SnDisplay *display,
const char *message_type,
+ Window xwindow,
const char *message,
void *user_data)
{
@@ -1036,7 +580,7 @@ xmessage_func (SnDisplay *display,
char **values;
int i;
const char *launch_id;
- SnLaunchSequence *sequence;
+ SnStartupSequence *sequence;
SnList *events;
prefix = NULL;
@@ -1070,7 +614,7 @@ xmessage_func (SnDisplay *display,
{
SnMonitorEvent *event;
- sequence = add_sequence (display, None);
+ sequence = add_sequence (display);
if (sequence == NULL)
goto out;
@@ -1080,10 +624,10 @@ xmessage_func (SnDisplay *display,
event->refcount = 1;
event->type = SN_MONITOR_EVENT_INITIATED;
- event->timestamp = CurrentTime;
event->context = NULL;
event->sequence = sequence; /* ref from add_sequence goes here */
-
+ event->xwindow = xwindow;
+
sn_list_append (events, event);
}
}
@@ -1094,9 +638,7 @@ xmessage_func (SnDisplay *display,
if (strcmp (prefix, "change") == 0 ||
strcmp (prefix, "new") == 0)
{
- sn_bool_t random_stuff_changed = FALSE;
- sn_bool_t pid_changed = FALSE;
- sn_bool_t workspace_changed = FALSE;
+ sn_bool_t changed = FALSE;
i = 0;
while (names[i])
@@ -1106,7 +648,7 @@ xmessage_func (SnDisplay *display,
if (sequence->binary_name == NULL)
{
sequence->binary_name = sn_internal_strdup (values[i]);
- random_stuff_changed = TRUE;
+ changed = TRUE;
}
}
else if (strcmp (names[i], "NAME") == 0)
@@ -1114,15 +656,23 @@ xmessage_func (SnDisplay *display,
if (sequence->name == NULL)
{
sequence->name = sn_internal_strdup (values[i]);
- random_stuff_changed = TRUE;
+ changed = TRUE;
}
}
+ else if (strcmp (names[i], "DESCRIPTION") == 0)
+ {
+ if (sequence->description == NULL)
+ {
+ sequence->description = sn_internal_strdup (values[i]);
+ changed = TRUE;
+ }
+ }
else if (strcmp (names[i], "ICON") == 0)
{
if (sequence->icon_name == NULL)
{
sequence->icon_name = sn_internal_strdup (values[i]);
- random_stuff_changed = TRUE;
+ changed = TRUE;
}
}
else if (strcmp (names[i], "DESKTOP") == 0)
@@ -1132,77 +682,35 @@ xmessage_func (SnDisplay *display,
workspace = sn_internal_string_to_ulong (values[i]);
sequence->workspace = workspace;
- workspace_changed = TRUE;
+ changed = TRUE;
}
else if (strcmp (names[i], "WMCLASS") == 0)
{
- if (sequence->resource_class == NULL)
+ if (sequence->wmclass == NULL)
{
- sequence->resource_class = sn_internal_strdup (values[i]);
- random_stuff_changed = TRUE;
- }
- }
- else if (strcmp (names[i], "PID") == 0)
- {
- int pid;
-
- pid = sn_internal_string_to_ulong (values[i]);
-
- if (pid > 0)
- {
- sequence->pid = pid;
-
- pid_changed = TRUE;
- }
- }
- else if (strcmp (names[i], "HOSTNAME") == 0)
- {
- if (sequence->hostname == NULL)
- {
- sequence->hostname = sn_internal_strdup (values[i]);
- random_stuff_changed = TRUE;
+ sequence->wmclass = sn_internal_strdup (values[i]);
+ changed = TRUE;
}
}
++i;
}
-
- if (pid_changed)
+
+ if (changed)
{
SnMonitorEvent *event;
event = sn_new (SnMonitorEvent, 1);
event->refcount = 1;
- event->type = SN_MONITOR_EVENT_PID_CHANGED;
- event->timestamp = CurrentTime;
+ event->type = SN_MONITOR_EVENT_CHANGED;
event->context = NULL;
event->sequence = sequence;
- sn_launch_sequence_ref (sequence);
-
- sn_list_append (events, event);
- }
-
- if (workspace_changed)
- {
- SnMonitorEvent *event;
-
- event = sn_new (SnMonitorEvent, 1);
+ sn_startup_sequence_ref (sequence);
+ event->xwindow = xwindow;
- event->refcount = 1;
- event->type = SN_MONITOR_EVENT_WORKSPACE_CHANGED;
- event->timestamp = CurrentTime;
- event->context = NULL;
- event->sequence = sequence;
- sn_launch_sequence_ref (sequence);
-
sn_list_append (events, event);
}
-
- if (random_stuff_changed)
- {
- /* FIXME */
- }
}
else if (strcmp (prefix, "remove") == 0)
{
@@ -1212,11 +720,11 @@ xmessage_func (SnDisplay *display,
event->refcount = 1;
event->type = SN_MONITOR_EVENT_COMPLETED;
- event->timestamp = CurrentTime;
event->context = NULL;
event->sequence = sequence;
- sn_launch_sequence_ref (sequence);
-
+ sn_startup_sequence_ref (sequence);
+ event->xwindow = xwindow;
+
sn_list_append (events, event);
}
diff --git a/libsn/sn-monitor.h b/libsn/sn-monitor.h
index 9f799c5..508bb94 100644
--- a/libsn/sn-monitor.h
+++ b/libsn/sn-monitor.h
@@ -33,7 +33,7 @@ SN_BEGIN_DECLS
typedef struct SnMonitorContext SnMonitorContext;
typedef struct SnMonitorEvent SnMonitorEvent;
-typedef struct SnLaunchSequence SnLaunchSequence;
+typedef struct SnStartupSequence SnStartupSequence;
typedef void (* SnMonitorEventFunc) (SnMonitorEvent *event,
void *user_data);
@@ -42,55 +42,36 @@ typedef enum
{
SN_MONITOR_EVENT_INITIATED,
SN_MONITOR_EVENT_COMPLETED,
- SN_MONITOR_EVENT_CANCELED,
- SN_MONITOR_EVENT_PULSE,
- SN_MONITOR_EVENT_GEOMETRY_CHANGED,
- SN_MONITOR_EVENT_PID_CHANGED,
- /* only allowed with xmessages protocol */
- SN_MONITOR_EVENT_WORKSPACE_CHANGED
+ SN_MONITOR_EVENT_CHANGED,
+ SN_MONITOR_EVENT_CANCELED /* not used for now */
} SnMonitorEventType;
SnMonitorContext* sn_monitor_context_new (SnDisplay *display,
+ int screen,
SnMonitorEventFunc event_func,
void *event_func_data,
SnFreeFunc free_data_func);
void sn_monitor_context_ref (SnMonitorContext *context);
void sn_monitor_context_unref (SnMonitorContext *context);
+void sn_monitor_event_ref (SnMonitorEvent *event);
+void sn_monitor_event_unref (SnMonitorEvent *event);
+SnMonitorEvent* sn_monitor_event_copy (SnMonitorEvent *event);
+SnMonitorEventType sn_monitor_event_get_type (SnMonitorEvent *event);
+SnStartupSequence* sn_monitor_event_get_startup_sequence (SnMonitorEvent *event);
+SnMonitorContext* sn_monitor_event_get_context (SnMonitorEvent *event);
-void sn_monitor_event_ref (SnMonitorEvent *event);
-void sn_monitor_event_unref (SnMonitorEvent *event);
-SnMonitorEvent* sn_monitor_event_copy (SnMonitorEvent *event);
-SnMonitorEventType sn_monitor_event_get_type (SnMonitorEvent *event);
-SnLaunchSequence* sn_monitor_event_get_launch_sequence (SnMonitorEvent *event);
-SnMonitorContext* sn_monitor_event_get_context (SnMonitorEvent *event);
-Time sn_monitor_event_get_time (SnMonitorEvent *event);
-void sn_launch_sequence_ref (SnLaunchSequence *sequence);
-void sn_launch_sequence_unref (SnLaunchSequence *sequence);
-const char* sn_launch_sequence_get_id (SnLaunchSequence *sequence);
-Window sn_launch_sequence_get_window (SnLaunchSequence *sequence);
-sn_bool_t sn_launch_sequence_get_geometry (SnLaunchSequence *sequence,
- int *x,
- int *y,
- int *width,
- int *height);
-Window sn_launch_sequence_get_geometry_window (SnLaunchSequence *sequence);
-sn_bool_t sn_launch_sequence_get_completed (SnLaunchSequence *sequence);
-sn_bool_t sn_launch_sequence_get_canceled (SnLaunchSequence *sequence);
-const char* sn_launch_sequence_get_name (SnLaunchSequence *sequence);
-const char* sn_launch_sequence_get_description (SnLaunchSequence *sequence);
-int sn_launch_sequence_get_workspace (SnLaunchSequence *sequence);
-const char* sn_launch_sequence_get_legacy_resource_class (SnLaunchSequence *sequence);
-const char* sn_launch_sequence_get_legacy_resource_name (SnLaunchSequence *sequence);
-const char* sn_launch_sequence_get_legacy_window_title (SnLaunchSequence *sequence);
-sn_bool_t sn_launch_sequence_get_supports_cancel (SnLaunchSequence *sequence);
-int sn_launch_sequence_get_pid (SnLaunchSequence *sequence);
-const char* sn_launch_sequence_get_binary_name (SnLaunchSequence *sequence);
-const char* sn_launch_sequence_get_hostname (SnLaunchSequence *sequence);
-const char* sn_launch_sequence_get_icon_name (SnLaunchSequence *sequence);
-
-void sn_launch_sequence_cancel (SnLaunchSequence *sequence);
+void sn_startup_sequence_ref (SnStartupSequence *sequence);
+void sn_startup_sequence_unref (SnStartupSequence *sequence);
+const char* sn_startup_sequence_get_id (SnStartupSequence *sequence);
+sn_bool_t sn_startup_sequence_get_completed (SnStartupSequence *sequence);
+const char* sn_startup_sequence_get_name (SnStartupSequence *sequence);
+const char* sn_startup_sequence_get_description (SnStartupSequence *sequence);
+int sn_startup_sequence_get_workspace (SnStartupSequence *sequence);
+const char* sn_startup_sequence_get_wmclass (SnStartupSequence *sequence);
+const char* sn_startup_sequence_get_binary_name (SnStartupSequence *sequence);
+const char* sn_startup_sequence_get_icon_name (SnStartupSequence *sequence);
SN_END_DECLS
diff --git a/libsn/sn-util.c b/libsn/sn-util.c
index 89ef913..775df13 100644
--- a/libsn/sn-util.c
+++ b/libsn/sn-util.c
@@ -308,3 +308,21 @@ sn_internal_string_to_ulong (const char* str)
return retval;
}
+
+
+void
+sn_internal_append_to_string (char **append_to,
+ int *current_len,
+ const char *append)
+{
+ int len;
+ char *end;
+
+ len = strlen (append);
+
+ *append_to = sn_realloc (*append_to, *current_len + len + 1);
+
+ end = *append_to + *current_len;
+ strcpy (end, append);
+ *current_len = *current_len + len;
+}
diff --git a/libsn/sn-xmessages.c b/libsn/sn-xmessages.c
index 61577e8..e1e3652 100644
--- a/libsn/sn-xmessages.c
+++ b/libsn/sn-xmessages.c
@@ -29,6 +29,7 @@
typedef struct
{
Display *xdisplay;
+ Window root;
Atom type_atom;
char *message_type;
SnXmessageFunc func;
@@ -49,6 +50,7 @@ static SnList *pending_messages = NULL;
void
sn_internal_add_xmessage_func (SnDisplay *display,
+ int screen,
const char *message_type,
SnXmessageFunc func,
void *func_data,
@@ -62,6 +64,7 @@ sn_internal_add_xmessage_func (SnDisplay *display,
handler = sn_new0 (SnXmessageHandler, 1);
handler->xdisplay = sn_display_get_x_display (display);
+ handler->root = RootWindow (handler->xdisplay, screen);
handler->type_atom = sn_internal_atom_get (display, message_type);
handler->message_type = sn_internal_strdup (message_type);
handler->func= func;
@@ -76,6 +79,7 @@ typedef struct
const char *message_type;
SnXmessageFunc func;
void *func_data;
+ Window root;
SnXmessageHandler *handler;
} FindHandlerData;
@@ -88,6 +92,7 @@ find_handler_foreach (void *value,
if (handler->func == fhd->func &&
handler->func_data == fhd->func_data &&
+ handler->root == fhd->root &&
strcmp (fhd->message_type, handler->message_type) == 0)
{
fhd->handler = handler;
@@ -99,6 +104,7 @@ find_handler_foreach (void *value,
void
sn_internal_remove_xmessage_func (SnDisplay *display,
+ int screen,
const char *message_type,
SnXmessageFunc func,
void *func_data)
@@ -108,7 +114,8 @@ sn_internal_remove_xmessage_func (SnDisplay *display,
fhd.func = func;
fhd.func_data = func_data;
fhd.handler = NULL;
-
+ fhd.root = RootWindow (sn_display_get_x_display (display), screen);
+
if (xmessage_funcs != NULL)
sn_list_foreach (xmessage_funcs, find_handler_foreach, &fhd);
@@ -127,6 +134,7 @@ sn_internal_remove_xmessage_func (SnDisplay *display,
void
sn_internal_broadcast_xmessage (SnDisplay *display,
+ int screen,
const char *message_type,
const char *message)
{
@@ -201,7 +209,7 @@ sn_internal_broadcast_xmessage (SnDisplay *display,
}
XSendEvent (xdisplay,
- target_xwindow,
+ RootWindow (xdisplay, screen),
False,
PropertyChangeMask,
&xevent);
@@ -216,6 +224,7 @@ typedef struct
{
Display *xdisplay;
Atom atom;
+ Window xwindow;
sn_bool_t found_handler;
} HandlerForAtomData;
@@ -227,7 +236,8 @@ handler_for_atom_foreach (void *value,
HandlerForAtomData *hfad = data;
if (handler->xdisplay == hfad->xdisplay &&
- handler->type_atom == hfad->atom)
+ handler->type_atom == hfad->atom &&
+ handler->root == hfad->xwindow)
{
hfad->found_handler = TRUE;
return FALSE;
@@ -244,6 +254,7 @@ some_handler_handles_event (SnDisplay *display,
hfad.atom = xevent->xclient.message_type;
hfad.xdisplay = sn_display_get_x_display (display);
+ hfad.xwindow = xevent->xclient.window;
hfad.found_handler = FALSE;
if (xmessage_funcs)
@@ -380,6 +391,7 @@ dispatch_message_foreach (void *value,
(* handler->func) (mdd->display,
handler->message_type,
+ mdd->message->xwindow,
mdd->message->message,
handler->func_data);
@@ -430,6 +442,11 @@ sn_internal_xmessage_process_event (SnDisplay *display,
dispatch_message_foreach,
&mdd);
}
+ else
+ {
+ /* FIXME don't use fprintf, use something pluggable */
+ fprintf (stderr, "Bad UTF-8 in startup notification message\n");
+ }
sn_free (message->message);
sn_free (message);
@@ -439,26 +456,9 @@ sn_internal_xmessage_process_event (SnDisplay *display,
}
static void
-append_to_string (char **append_to,
- int *current_len,
- const char *append)
-{
- int len;
- char *end;
-
- len = strlen (append);
-
- *append_to = sn_realloc (*append_to, *current_len + len + 1);
-
- end = *append_to + *current_len;
- strcpy (end, append);
- *current_len = *current_len + len;
-}
-
-static void
-append_to_string_escaped (char **append_to,
- int *current_len,
- const char *append)
+sn_internal_append_to_string_escaped (char **append_to,
+ int *current_len,
+ const char *append)
{
char *escaped;
int len;
@@ -477,16 +477,16 @@ append_to_string_escaped (char **append_to,
if (*p == '\\' || *p == '"' || *p == ' ')
{
buf[0] = '\\';
- append_to_string (&escaped, &len, buf);
+ sn_internal_append_to_string (&escaped, &len, buf);
}
buf[0] = *p;
- append_to_string (&escaped, &len, buf);
+ sn_internal_append_to_string (&escaped, &len, buf);
++p;
}
- append_to_string (append_to, current_len, escaped);
-
+ sn_internal_append_to_string (append_to, current_len, escaped);
+
sn_free (escaped);
}
@@ -503,15 +503,15 @@ sn_internal_serialize_message (const char *prefix,
len = 0;
retval = NULL;
- append_to_string (&retval, &len, prefix);
- append_to_string (&retval, &len, ": ");
+ sn_internal_append_to_string (&retval, &len, prefix);
+ sn_internal_append_to_string (&retval, &len, ": ");
i = 0;
while (property_names[i])
{
- append_to_string (&retval, &len, property_names[i]);
- append_to_string (&retval, &len, "=");
- append_to_string_escaped (&retval, &len, property_values[i]);
+ sn_internal_append_to_string (&retval, &len, property_names[i]);
+ sn_internal_append_to_string (&retval, &len, "=");
+ sn_internal_append_to_string_escaped (&retval, &len, property_values[i]);
++i;
}
diff --git a/libsn/sn-xmessages.h b/libsn/sn-xmessages.h
index 8f03b77..57b933b 100644
--- a/libsn/sn-xmessages.h
+++ b/libsn/sn-xmessages.h
@@ -31,19 +31,23 @@ SN_BEGIN_DECLS
typedef void (* SnXmessageFunc) (SnDisplay *display,
const char *message_type,
+ Window message_window,
const char *message,
void *user_data);
void sn_internal_add_xmessage_func (SnDisplay *display,
+ int screen,
const char *message_type,
SnXmessageFunc func,
void *func_data,
SnFreeFunc free_data_func);
void sn_internal_remove_xmessage_func (SnDisplay *display,
+ int screen,
const char *message_type,
SnXmessageFunc func,
void *func_data);
void sn_internal_broadcast_xmessage (SnDisplay *display,
+ int screen,
const char *message_type,
const char *message);
diff --git a/test/test-launchee.c b/test/test-launchee.c
index 7751cbd..14a7fd9 100644
--- a/test/test-launchee.c
+++ b/test/test-launchee.c
@@ -33,7 +33,6 @@ main (int argc, char **argv)
Display *xdisplay;
SnDisplay *display;
SnLauncheeContext *context;
- int i;
xdisplay = XOpenDisplay (NULL);
if (xdisplay == NULL)
@@ -51,7 +50,8 @@ main (int argc, char **argv)
error_trap_push,
error_trap_pop);
- context = sn_launchee_context_new_from_environment (display);
+ context = sn_launchee_context_new_from_environment (display,
+ DefaultScreen (xdisplay));
if (context == NULL)
{
@@ -59,18 +59,11 @@ main (int argc, char **argv)
exit (1);
}
- printf ("Launchee started with window 0x%lx ID \"%s\"\n",
- sn_launchee_context_get_launch_window (context),
- sn_launchee_context_get_launch_id (context));
+ printf ("Launchee started with window ID \"%s\"\n",
+ sn_launchee_context_get_startup_id (context));
/* simulate startup time */
- i = 0;
- while (i < 4)
- {
- sleep (1);
- sn_launchee_context_pulse (context);
- ++i;
- }
+ sleep (4);
printf ("Launchee startup complete\n");
sn_launchee_context_complete (context);
diff --git a/test/test-launcher.c b/test/test-launcher.c
index 2005026..053e84b 100644
--- a/test/test-launcher.c
+++ b/test/test-launcher.c
@@ -29,30 +29,6 @@
static pid_t child_pid = 0;
-static void
-launcher_event_func (SnLauncherEvent *event,
- void *user_data)
-{
- SnLauncherContext *context;
-
- context = sn_launcher_event_get_context (event);
-
- switch (sn_launcher_event_get_type (event))
- {
- case SN_LAUNCHER_EVENT_COMPLETED:
- printf ("Completed!\n");
- break;
- case SN_LAUNCHER_EVENT_CANCELED:
- printf ("Canceled!\n");
- kill (child_pid, SIGTERM);
- sn_launcher_context_complete (context);
- break;
- case SN_LAUNCHER_EVENT_PULSE:
- printf (" pulse.\n");
- break;
- }
-}
-
int
main (int argc, char **argv)
{
@@ -82,13 +58,10 @@ main (int argc, char **argv)
error_trap_push,
error_trap_pop);
- context = sn_launcher_context_new (display,
- launcher_event_func,
- NULL, NULL);
+ context = sn_launcher_context_new (display, DefaultScreen (xdisplay));
- sn_launcher_context_set_launch_name (context, "Test Launch");
- sn_launcher_context_set_launch_description (context, "Launching a test program for libsn");
- sn_launcher_context_set_supports_cancel (context, TRUE);
+ sn_launcher_context_set_name (context, "Test Launch");
+ sn_launcher_context_set_description (context, "Launching a test program for libsn");
sn_launcher_context_set_binary_name (context, argv[1]);
sn_launcher_context_initiate (context,
@@ -108,8 +81,6 @@ main (int argc, char **argv)
_exit (1);
break;
}
-
- sn_launcher_context_set_pid (context, child_pid);
while (TRUE)
{
diff --git a/test/test-monitor.c b/test/test-monitor.c
index 6f031fd..b6e40d2 100644
--- a/test/test-monitor.c
+++ b/test/test-monitor.c
@@ -32,106 +32,51 @@ monitor_event_func (SnMonitorEvent *event,
void *user_data)
{
SnMonitorContext *context;
- SnLaunchSequence *sequence;
+ SnStartupSequence *sequence;
context = sn_monitor_event_get_context (event);
- sequence = sn_monitor_event_get_launch_sequence (event);
+ sequence = sn_monitor_event_get_startup_sequence (event);
switch (sn_monitor_event_get_type (event))
{
case SN_MONITOR_EVENT_INITIATED:
+ printf ("Initiated sequence %s\n",
+ sn_startup_sequence_get_id (sequence));
+ /* FALL THRU */
+ case SN_MONITOR_EVENT_CHANGED:
{
- int x, y, w, h;
const char *s;
-
- printf ("Initiated sequence %s\n",
- sn_launch_sequence_get_id (sequence));
- printf (" launch window 0x%lx\n",
- sn_launch_sequence_get_window (sequence));
- s = sn_launch_sequence_get_name (sequence);
+ s = sn_startup_sequence_get_id (sequence);
+ printf (" id %s\n", s ? s : "(unset)");
+
+ s = sn_startup_sequence_get_name (sequence);
printf (" name %s\n", s ? s : "(unset)");
- s = sn_launch_sequence_get_description (sequence);
+ s = sn_startup_sequence_get_description (sequence);
printf (" description %s\n", s ? s : "(unset)");
printf (" workspace %d\n",
- sn_launch_sequence_get_workspace (sequence));
-
- printf (" %s cancel\n",
- sn_launch_sequence_get_supports_cancel (sequence) ?
- "supports" : "does not support");
-
- if (sn_launch_sequence_get_geometry (sequence,
- &x, &y, &w, &h))
- printf (" geometry %d,%d %d x %d window 0x%lx\n",
- x, y, w, h,
- sn_launch_sequence_get_geometry_window (sequence));
- else
- printf (" no geometry set\n");
-
- printf (" pid %d\n",
- sn_launch_sequence_get_pid (sequence));
+ sn_startup_sequence_get_workspace (sequence));
- s = sn_launch_sequence_get_binary_name (sequence);
+ s = sn_startup_sequence_get_binary_name (sequence);
printf (" binary name %s\n", s ? s : "(unset)");
- s = sn_launch_sequence_get_icon_name (sequence);
+ s = sn_startup_sequence_get_icon_name (sequence);
printf (" icon name %s\n", s ? s : "(unset)");
- s = sn_launch_sequence_get_hostname (sequence);
- printf (" hostname %s\n", s ? s : "(unset)");
- s = sn_launch_sequence_get_legacy_resource_class (sequence);
- printf (" legacy class %s\n", s ? s : "(unset)");
- s = sn_launch_sequence_get_legacy_resource_name (sequence);
- printf (" legacy name %s\n", s ? s : "(unset)");
- s = sn_launch_sequence_get_legacy_window_title (sequence);
- printf (" legacy title %s\n", s ? s : "(unset)");
+ s = sn_startup_sequence_get_wmclass (sequence);
+ printf (" wm class %s\n", s ? s : "(unset)");
}
break;
case SN_MONITOR_EVENT_COMPLETED:
printf ("Completed sequence %s\n",
- sn_launch_sequence_get_id (sequence));
+ sn_startup_sequence_get_id (sequence));
break;
case SN_MONITOR_EVENT_CANCELED:
printf ("Canceled sequence %s\n",
- sn_launch_sequence_get_id (sequence));
- break;
-
- case SN_MONITOR_EVENT_PULSE:
- printf ("Pulse for sequence %s\n",
- sn_launch_sequence_get_id (sequence));
- break;
-
- case SN_MONITOR_EVENT_GEOMETRY_CHANGED:
- {
- int x, y, w, h;
-
- printf ("Geometry changed for sequence %s\n",
- sn_launch_sequence_get_id (sequence));
- if (sn_launch_sequence_get_geometry (sequence,
- &x, &y, &w, &h))
- printf (" geometry %d,%d %d x %d window 0x%lx\n",
- x, y, w, h,
- sn_launch_sequence_get_geometry_window (sequence));
- else
- printf (" no geometry set\n");
- }
- break;
- case SN_MONITOR_EVENT_PID_CHANGED:
- {
- printf ("PID for sequence %s is now %d\n",
- sn_launch_sequence_get_id (sequence),
- sn_launch_sequence_get_pid (sequence));
- }
- break;
- case SN_MONITOR_EVENT_WORKSPACE_CHANGED:
- {
- printf ("Workspace for sequence %s is now %d\n",
- sn_launch_sequence_get_id (sequence),
- sn_launch_sequence_get_workspace (sequence));
- }
+ sn_startup_sequence_get_id (sequence));
break;
}
}
@@ -166,7 +111,7 @@ main (int argc, char **argv)
error_trap_push,
error_trap_pop);
- context = sn_monitor_context_new (display,
+ context = sn_monitor_context_new (display, DefaultScreen (xdisplay),
monitor_event_func,
NULL, NULL);
diff --git a/test/test-send-xmessage.c b/test/test-send-xmessage.c
index 00ae71a..d1c0a6f 100644
--- a/test/test-send-xmessage.c
+++ b/test/test-send-xmessage.c
@@ -56,7 +56,7 @@ main (int argc, char **argv)
error_trap_push,
error_trap_pop);
- sn_internal_broadcast_xmessage (display,
+ sn_internal_broadcast_xmessage (display, DefaultScreen (xdisplay),
argv[1],
argv[2]);
diff --git a/test/test-watch-xmessages.c b/test/test-watch-xmessages.c
index 85728a5..3374f0e 100644
--- a/test/test-watch-xmessages.c
+++ b/test/test-watch-xmessages.c
@@ -32,6 +32,7 @@
static void
message_func (SnDisplay *display,
const char *message_type,
+ Window xwindow,
const char *message,
void *user_data)
{
@@ -100,7 +101,7 @@ main (int argc, char **argv)
error_trap_push,
error_trap_pop);
- sn_internal_add_xmessage_func (display,
+ sn_internal_add_xmessage_func (display, DefaultScreen (xdisplay),
argv[1],
message_func,
NULL, NULL);