判断程序实例是否已经运行的N种方法(判断窗口已经运行)

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

    ...

}
 

相关推荐