# HG changeset patch # User Sam Lantinga # Date 1138952342 0 # Node ID 1dfc85090d07c6300bdeb7b1cdf4790dbca130fe # Parent 42e95163d553eab0071753c70c54bf6cbe4b4593 Resolve bug #120 Use the real executable's name for the window class, if it's available. diff -r 42e95163d553 -r 1dfc85090d07 src/video/x11/SDL_x11video.c --- a/src/video/x11/SDL_x11video.c Fri Feb 03 06:33:54 2006 +0000 +++ b/src/video/x11/SDL_x11video.c Fri Feb 03 07:39:02 2006 +0000 @@ -279,10 +279,54 @@ return Xext_handler(d, ext_name, reason); } +/* Find out what class name we should use */ +static char *get_classname(char *classname, int maxlen) +{ + char *spot; +#if defined(linux) || defined(__FreeBSD__) + char procfile[1024]; + char linkfile[1024]; + int linksize; +#endif + + /* First allow environment variable override */ + spot = getenv("SDL_VIDEO_X11_WMCLASS"); + if ( spot ) { + strncpy(classname, spot, maxlen); + return classname; + } + + /* Next look at the application's executable name */ +#if defined(linux) || defined(__FreeBSD__) +#if defined(linux) + sprintf(procfile, "/proc/%d/exe", getpid()); +#elif defined(__FreeBSD__) + sprintf(procfile, "/proc/%d/file", getpid()); +#else +#error Where can we find the executable name? +#endif + linksize = readlink(procfile, linkfile, sizeof(linkfile)-1); + if ( linksize > 0 ) { + linkfile[linksize] = '\0'; + spot = strrchr(linkfile, '/'); + if ( spot ) { + strncpy(classname, spot+1, maxlen); + } else { + strncpy(classname, linkfile, maxlen); + } + return classname; + } +#endif /* linux */ + + /* Finally use the default we've used forever */ + strncpy(classname, "SDL_App", maxlen); + return classname; +} + /* Create auxiliary (toplevel) windows with the current visual */ static void create_aux_windows(_THIS) { - char * savedclassname = NULL; + char classname[1024]; XSetWindowAttributes xattr; XWMHints *hints; XTextProperty titleprop, iconprop; @@ -368,15 +412,11 @@ | PropertyChangeMask | StructureNotifyMask | KeymapStateMask); /* Set the class hints so we can get an icon (AfterStep) */ + get_classname(classname, sizeof(classname)); { XClassHint *classhints; classhints = pXAllocClassHint(); if(classhints != NULL) { - char *classname = getenv("SDL_VIDEO_X11_WMCLASS"); - if ( ! classname ) { - classname = "SDL_App"; - } - savedclassname = strdup(classname); classhints->res_name = classname; classhints->res_class = classname; pXSetClassHint(SDL_Display, WMwindow, classhints); @@ -389,7 +429,7 @@ SDL_IC = NULL; #ifdef X_HAVE_UTF8_STRING - SDL_IM = pXOpenIM(SDL_Display, NULL, savedclassname, savedclassname); + SDL_IM = pXOpenIM(SDL_Display, NULL, classname, classname); if (SDL_IM == NULL) { SDL_SetError("no input method could be opened"); } else { @@ -397,8 +437,8 @@ XNClientWindow, WMwindow, XNFocusWindow, WMwindow, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, - XNResourceName, savedclassname, - XNResourceClass, savedclassname, + XNResourceName, classname, + XNResourceClass, classname, NULL); if (SDL_IC == NULL) { SDL_SetError("no input context could be created"); @@ -408,9 +448,6 @@ } #endif - free(savedclassname); - - /* Allow the window to be deleted by the window manager */ WM_DELETE_WINDOW = pXInternAtom(SDL_Display, "WM_DELETE_WINDOW", False); pXSetWMProtocols(SDL_Display, WMwindow, &WM_DELETE_WINDOW, 1);