Skip to content

Commit

Permalink
Fixed bug #113:
Browse files Browse the repository at this point in the history
Date: Sat, 16 Apr 2005 08:39:22 +1000
From: "Eric Mangold"
Subject: [SDL] Window manager does not show SDL window titles

Hello,

I have an issue with SDL-using applications and the sawfish window manager.

The problem is that SDL windows do not show the window caption. My gnome
panel *does* show the window name, but the actual sawfish window frame
shows no caption at all. All other non-SDL applications that I use work
fine.

I tried a couple other window managers, and they *were* able to show the
SDL window captions correctly. Though there many be other WMs that can't.

I believe the problem is that SDL is using the UTF8_STRING type for the
window's WM_NAME and WM_ICON properties. In fact, WM_NAME and WM_ICON are
supposed to set to a TEXT type, usually STRING (ISO 8859-1).
The property names _NET_WM_NAME and _NET_WM_ICON_NAME should be used to
store the UTF8_STRING versions of the window title and icon name.

You can see the properties I refer to with a command like this:
xprop|grep -e "WM.*NAME"

Please note the freedesktop.org standard:
http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html#id2506954

This page talks a little bit about the history of these properties. Just
search down the page for "WM_NAME".
http://www.cl.cam.ac.uk/~mgk25/unicode.html

Please let me know if I can be of any assistance in resolving this issue.

Thanks,
Eric Mangold
  • Loading branch information
slouken committed Mar 20, 2006
1 parent a789420 commit 7cbef89
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 39 deletions.
6 changes: 2 additions & 4 deletions src/video/x11/SDL_x11sym.h
Expand Up @@ -57,8 +57,7 @@ SDL_X11_SYM(1,XModifierKeymap*,XGetModifierMapping,(Display*))
SDL_X11_SYM(1,int,XGetPointerControl,(Display*,int*,int*,int*))
SDL_X11_SYM(1,XVisualInfo*,XGetVisualInfo,(Display*,long,XVisualInfo*,int*))
SDL_X11_SYM(1,XWMHints*,XGetWMHints,(Display*,Window))
SDL_X11_SYM(1,Status,XGetWMIconName,(Display*,Window,XTextProperty*))
SDL_X11_SYM(1,Status,XGetWMName,(Display*,Window,XTextProperty*))
SDL_X11_SYM(1,Status,XGetTextProperty,(Display*,Window,XTextProperty*,Atom))
SDL_X11_SYM(1,Status,XGetWindowAttributes,(Display*,Window,XWindowAttributes*))
SDL_X11_SYM(1,int,XGrabKeyboard,(Display*,Window,Bool,int,int,Time))
SDL_X11_SYM(1,int,XGrabPointer,(Display*,Window,Bool,unsigned int,int,int,Window,Cursor,Time))
Expand Down Expand Up @@ -93,8 +92,7 @@ SDL_X11_SYM(1,XErrorHandler,XSetErrorHandler,(XErrorHandler))
SDL_X11_SYM(1,XIOErrorHandler,XSetIOErrorHandler,(XIOErrorHandler))
SDL_X11_SYM(1,int,XSetTransientForHint,(Display*,Window,Window))
SDL_X11_SYM(1,int,XSetWMHints,(Display*,Window,XWMHints*))
SDL_X11_SYM(1,void,XSetWMIconName,(Display*,Window,XTextProperty*))
SDL_X11_SYM(1,void,XSetWMName,(Display*,Window,XTextProperty*))
SDL_X11_SYM(1,void,XSetTextProperty,(Display*,Window,XTextProperty*,Atom))
SDL_X11_SYM(1,void,XSetWMNormalHints,(Display*,Window,XSizeHints*))
SDL_X11_SYM(1,Status,XSetWMProtocols,(Display*,Window,Atom*,int))
SDL_X11_SYM(1,int,XSetWindowBackground,(Display*,Window,unsigned long))
Expand Down
31 changes: 24 additions & 7 deletions src/video/x11/SDL_x11video.c
Expand Up @@ -310,12 +310,19 @@ static char *get_classname(char *classname, int maxlen)
/* Create auxiliary (toplevel) windows with the current visual */
static void create_aux_windows(_THIS)
{
Atom _NET_WM_NAME;
Atom _NET_WM_ICON_NAME;
char classname[1024];
XSetWindowAttributes xattr;
XWMHints *hints;
XTextProperty titleprop, iconprop;
XTextProperty titleprop, titlepropUTF8, iconprop, iconpropUTF8;
int def_vis = (SDL_Visual == DefaultVisual(SDL_Display, SDL_Screen));

/* Look up some useful Atoms */
WM_DELETE_WINDOW = pXInternAtom(SDL_Display, "WM_DELETE_WINDOW", False);
_NET_WM_NAME = pXInternAtom(SDL_Display, "_NET_WM_NAME", False);
_NET_WM_ICON_NAME = pXInternAtom(SDL_Display, "_NET_WM_ICON_NAME", False);

/* Don't create any extra windows if we are being managed */
if ( SDL_windowid ) {
FSwindow = 0;
Expand Down Expand Up @@ -358,12 +365,15 @@ static void create_aux_windows(_THIS)
}

hints = NULL;
titleprop.value = iconprop.value = NULL;
titleprop.value = titlepropUTF8.value = NULL;
iconprop.value = iconpropUTF8.value = NULL;
if(WMwindow) {
/* All window attributes must survive the recreation */
hints = pXGetWMHints(SDL_Display, WMwindow);
pXGetWMName(SDL_Display, WMwindow, &titleprop);
pXGetWMIconName(SDL_Display, WMwindow, &iconprop);
pXGetTextProperty(SDL_Display, WMwindow, &titleprop, XA_WM_NAME);
pXGetTextProperty(SDL_Display, WMwindow, &titlepropUTF8, _NET_WM_NAME);
pXGetTextProperty(SDL_Display, WMwindow, &iconprop, XA_WM_ICON_NAME);
pXGetTextProperty(SDL_Display, WMwindow, &iconpropUTF8, _NET_WM_ICON_NAME);
pXDestroyWindow(SDL_Display, WMwindow);
}

Expand All @@ -383,13 +393,21 @@ static void create_aux_windows(_THIS)
pXSetWMHints(SDL_Display, WMwindow, hints);
pXFree(hints);
if(titleprop.value) {
pXSetWMName(SDL_Display, WMwindow, &titleprop);
pXSetTextProperty(SDL_Display, WMwindow, &titleprop, XA_WM_NAME);
pXFree(titleprop.value);
}
if(titlepropUTF8.value) {
pXSetTextProperty(SDL_Display, WMwindow, &titlepropUTF8, _NET_WM_NAME);
pXFree(titlepropUTF8.value);
}
if(iconprop.value) {
pXSetWMIconName(SDL_Display, WMwindow, &iconprop);
pXSetTextProperty(SDL_Display, WMwindow, &iconprop, XA_WM_ICON_NAME);
pXFree(iconprop.value);
}
if(iconpropUTF8.value) {
pXSetTextProperty(SDL_Display, WMwindow, &iconpropUTF8, _NET_WM_ICON_NAME);
pXFree(iconpropUTF8.value);
}

pXSelectInput(SDL_Display, WMwindow,
FocusChangeMask | KeyPressMask | KeyReleaseMask
Expand Down Expand Up @@ -433,7 +451,6 @@ static void create_aux_windows(_THIS)
#endif

/* 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);
}

Expand Down
71 changes: 43 additions & 28 deletions src/video/x11/SDL_x11wm.c
Expand Up @@ -243,46 +243,61 @@ void X11_SetIcon(_THIS, SDL_Surface *icon, Uint8 *mask)
void X11_SetCaption(_THIS, const char *title, const char *icon)
{
XTextProperty titleprop, iconprop;
Status status;

#ifdef X_HAVE_UTF8_STRING
Atom _NET_WM_NAME;
Atom _NET_WM_ICON_NAME;

/* Look up some useful Atoms */
_NET_WM_NAME = pXInternAtom(SDL_Display, "_NET_WM_NAME", False);
_NET_WM_ICON_NAME = pXInternAtom(SDL_Display, "_NET_WM_ICON_NAME", False);
#endif

/* Lock the event thread, in multi-threading environments */
SDL_Lock_EventThread();

if ( title != NULL ) {
int error = XLocaleNotSupported;
char *title_latin1 = SDL_iconv_utf8_latin1((char *)title);
if ( !title_latin1 ) {
SDL_OutOfMemory();
return;
}
status = pXStringListToTextProperty(&title_latin1, 1, &titleprop);
SDL_free(title_latin1);
if ( status ) {
pXSetTextProperty(SDL_Display, WMwindow, &titleprop, XA_WM_NAME);
pXFree(titleprop.value);
}
#ifdef X_HAVE_UTF8_STRING
error = pXutf8TextListToTextProperty(SDL_Display,
(char **)&title, 1, XUTF8StringStyle,
&titleprop);
#endif
if ( error != Success ) {
char *title_latin1 = SDL_iconv_utf8_latin1((char *)title);
if ( !title_latin1 ) {
SDL_OutOfMemory();
return;
}
pXStringListToTextProperty(&title_latin1, 1, &titleprop);
SDL_free(title_latin1);
status = pXutf8TextListToTextProperty(SDL_Display,
(char **)&title, 1, XUTF8StringStyle, &titleprop);
if ( status == Success ) {
pXSetTextProperty(SDL_Display, WMwindow, &titleprop, _NET_WM_NAME);
pXFree(titleprop.value);
}
pXSetWMName(SDL_Display, WMwindow, &titleprop);
pXFree(titleprop.value);
#endif
}
if ( icon != NULL ) {
int error = XLocaleNotSupported;
char *icon_latin1 = SDL_iconv_utf8_latin1((char *)icon);
if ( !icon_latin1 ) {
SDL_OutOfMemory();
return;
}
status = pXStringListToTextProperty(&icon_latin1, 1, &iconprop);
SDL_free(icon_latin1);
if ( status ) {
pXSetTextProperty(SDL_Display, WMwindow, &iconprop, XA_WM_ICON_NAME);
pXFree(iconprop.value);
}
#ifdef X_HAVE_UTF8_STRING
error = pXutf8TextListToTextProperty(SDL_Display,
status = pXutf8TextListToTextProperty(SDL_Display,
(char **)&icon, 1, XUTF8StringStyle, &iconprop);
#endif
if ( error != Success ) {
char *icon_latin1 = SDL_iconv_utf8_latin1((char *)title);
if ( !icon_latin1 ) {
SDL_OutOfMemory();
return;
}
pXStringListToTextProperty(&icon_latin1, 1, &iconprop);
SDL_free(icon_latin1);
if ( status == Success ) {
pXSetTextProperty(SDL_Display, WMwindow, &iconprop, _NET_WM_ICON_NAME);
pXFree(iconprop.value);
}
pXSetWMIconName(SDL_Display, WMwindow, &iconprop);
pXFree(iconprop.value);
#endif
}
pXSync(SDL_Display, False);

Expand Down

0 comments on commit 7cbef89

Please sign in to comment.