永不妥协 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"); } ... }