Fixed bug #113:
authorSam Lantinga <slouken@libsdl.org>
Mon, 20 Mar 2006 07:31:36 +0000
changeset 1558 b46bb79cc197
parent 1557 61c237f69076
child 1559 e7f61857028a
Fixed bug #113: 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
src/video/x11/SDL_x11sym.h
src/video/x11/SDL_x11video.c
src/video/x11/SDL_x11wm.c
--- a/src/video/x11/SDL_x11sym.h	Mon Mar 20 06:37:58 2006 +0000
+++ b/src/video/x11/SDL_x11sym.h	Mon Mar 20 07:31:36 2006 +0000
@@ -57,8 +57,7 @@
 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))
@@ -93,8 +92,7 @@
 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))
--- a/src/video/x11/SDL_x11video.c	Mon Mar 20 06:37:58 2006 +0000
+++ b/src/video/x11/SDL_x11video.c	Mon Mar 20 07:31:36 2006 +0000
@@ -310,12 +310,19 @@
 /* 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;
@@ -358,12 +365,15 @@
     }
 
     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);
     }
 
@@ -383,13 +393,21 @@
     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
@@ -433,7 +451,6 @@
     #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);
 }
 
--- a/src/video/x11/SDL_x11wm.c	Mon Mar 20 06:37:58 2006 +0000
+++ b/src/video/x11/SDL_x11wm.c	Mon Mar 20 07:31:36 2006 +0000
@@ -243,46 +243,61 @@
 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);
+		status = pXutf8TextListToTextProperty(SDL_Display,
+				(char **)&title, 1, XUTF8StringStyle, &titleprop);
+		if ( status == Success ) {
+			pXSetTextProperty(SDL_Display, WMwindow, &titleprop, _NET_WM_NAME);
+			pXFree(titleprop.value);
+		}
 #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);
-		}
-		pXSetWMName(SDL_Display, WMwindow, &titleprop);
-		pXFree(titleprop.value);
 	}
 	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);
+		if ( status == Success ) {
+			pXSetTextProperty(SDL_Display, WMwindow, &iconprop, _NET_WM_ICON_NAME);
+			pXFree(iconprop.value);
+		}
 #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);
-		}
-		pXSetWMIconName(SDL_Display, WMwindow, &iconprop);
-		pXFree(iconprop.value);
 	}
 	pXSync(SDL_Display, False);