永不妥协 2010-10-19
对于某些情况,我们可以通过判断窗口是否正在运行来保证只有一个程序实例运行。
下面是判断窗口是否正在运行的代码段:
#define MYWINDOW_SELECTION_FMT "MYWINDOW_SELECTION_DISPLAY_%d"
gboolean
mywindow_check_is_running(Window *xid)
{
const gchar *display = g_getenv("DISPLAY");
gchar *p;
gint xscreen = -1;
gchar selection_name[100];
Atom selection_atom;
if(display) {
if((p=g_strrstr(display, ".")))
xscreen = atoi(p);
}
if(xscreen == -1)
xscreen = 0;
g_snprintf(selection_name, 100, MYWINDOW_SELECTION_FMT, xscreen);
g_print("selection_name:%s\n",selection_name);
selection_atom = XInternAtom(GDK_DISPLAY(), selection_name, False);
if((*xid = XGetSelectionOwner(GDK_DISPLAY(), selection_atom)))
return TRUE;
return FALSE;
}
static void screen_set_selection()
{
Window xwin;
gint xscreen;
gchar selection_name[100];
Atom selection_atom, manager_atom;
GtkWidget *invisible;
invisible = gtk_invisible_new ();
gtk_widget_realize (invisible);
xwin = GDK_WINDOW_XWINDOW (invisible->window);;
xscreen = gdk_screen_get_number(gdk_screen_get_default());
g_snprintf(selection_name, 100, MYWINDOW_SELECTION_FMT, xscreen);
selection_atom = XInternAtom(GDK_DISPLAY(), selection_name, False);
manager_atom = XInternAtom(GDK_DISPLAY(), "MANAGER", False);
XSelectInput(GDK_DISPLAY(), xwin, PropertyChangeMask | ButtonPressMask);
XSetSelectionOwner(GDK_DISPLAY(), selection_atom, xwin, GDK_CURRENT_TIME);
if(XGetSelectionOwner(GDK_DISPLAY(), selection_atom) == xwin) {
XClientMessageEvent xev;
xev.type = ClientMessage;
xev.window = GDK_ROOT_WINDOW();
xev.message_type = manager_atom;
xev.format = 32;
xev.data.l[0] = GDK_CURRENT_TIME;
xev.data.l[1] = selection_atom;
xev.data.l[2] = xwin;
xev.data.l[3] = 0; /* manager specific data */
xev.data.l[4] = 0; /* manager specific data */
XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), False, StructureNotifyMask, (XEvent *)&xev);
} else {
g_error(" could not set selection ownership\n");
exit(1);
}
}
int
main (int argc, char *argv[])
{
Window xid;
gtk_init(&argc, &argv);
...
if(mywindow_check_is_running(&xid))
{
g_debug("mywindow is already running!");
return 0;
}
else
{
screen_set_selection();
g_debug("run mywindow first time");
}
...
}