X11: Set ICCCM property WM_CLASS with conformance to ICCCM 2.0 jv
authorJan Vrany <jan.vrany@fit.cvut.cz>
Wed, 09 Sep 2015 12:44:40 +0100
branchjv
changeset 6915 7f3a3fe5b871
parent 6914 e2d3459c6309
child 6916 2a4ce6c4d0b5
X11: Set ICCCM property WM_CLASS with conformance to ICCCM 2.0 The previous code that set WM_CLASS using setWindowClass:name: was not correct w.r.t. ICCCM 2.0. This commit makes it adhering to that spec. This in turn results in better UX under modern window managers, e.g. Gnome Shell. Specified by ICCCM, Section 4.1.2.5. WM_CLASS Property, see https://tronche.com/gui/x/icccm/sec-4.html#s-4.1.2.5
StandardSystemView.st
XWorkstation.st
--- a/StandardSystemView.st	Wed Sep 09 07:01:51 2015 +0100
+++ b/StandardSystemView.st	Wed Sep 09 12:44:40 2015 +0100
@@ -1659,43 +1659,6 @@
         self setCursor
     ].
 
-    "/JV@2012-11-11: Updated to be ICCCM 2.0 Compliant - some modern Window managers
-    "/               provide better UX when application behave nicely. Being
-    "/               conformant should not hurt as St/X don't depend on X resources anyway :-)
-    "/               See:
-    "/  
-    "/               http://tronche.com/gui/x/icccm/sec-4.html
-
-    (UserPreferences current icccm20Compliant) ifTrue:[
-        "/ICCCM 2.0 compliant name & class. See ICCCM 2.0 section 4.1.2.5.
-
-        | commandName lastSepIndex |
-
-        commandName := Smalltalk commandName.
-        lastSepIndex := commandName lastIndexOf: Filename separator.
-        windowNameString := commandName copyFrom: lastSepIndex + 1.
-        windowClassNameString := windowNameString asUppercaseFirst.
-
-        "/ Also, set _NET_WM_PID
-        self setWindowPid: nil.
-    ] ifFalse:[
-        "/ Old code..."
-        application notNil ifTrue:[
-            windowClassNameString := application class name.
-        ] ifFalse:[
-            (self class == StandardSystemView and:[subViews size == 1]) ifTrue:[
-                "This is a subclass of SimpleView wrapped into a StandardSystemView"
-                windowClassNameString := subViews first class name.
-            ] ifFalse:[
-                windowClassNameString := self class name.
-            ]
-        ].
-        windowClassNameString := 'Stx.', windowClassNameString.
-        windowNameString := 'main'.
-    ].
-
-    self windowClass:windowClassNameString name:windowNameString.
-
     "Modified: / 14-06-1996 / 17:14:25 / stefan"
     "Modified: / 04-01-2013 / 16:13:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
     "Modified: / 22-05-2015 / 21:09:35 / cg"
--- a/XWorkstation.st	Wed Sep 09 07:01:51 2015 +0100
+++ b/XWorkstation.st	Wed Sep 09 12:44:40 2015 +0100
@@ -31,7 +31,8 @@
 		selectionFetchers selectionHandlers preWaitAction xlibTimeout
 		xlibTimeoutForWindowCreation hasConnectionBroken uniqueDeviceID
 		stxDeviceAtom uuidAtom primaryBuffer windowGroupWindow
-		maxOperationsUntilFlush operationsUntilFlush lastError hostname wmClientLeaderAtom wmClientMachineAtom'
+		maxOperationsUntilFlush operationsUntilFlush lastError hostname 
+		wmClientLeaderAtom wmClientMachineAtom wmClassName wmClassClass'
 	classVariableNames:'RawKeySymTranslation ConservativeSync MaxStringLength
 		DefaultXLibTimeout DefaultXLibTimeoutForWindowCreation
 		ErrorDBCache'
@@ -1874,6 +1875,7 @@
     XGCValues xgcv;
     XSetWindowAttributes xswa;
     XSizeHints sizehints;
+    XClassHint classhint;
     int bw, bd, bg;
     Window newWindow, parentWindow, windowGroupWindow;
     XFontStruct *f;
@@ -2148,7 +2150,7 @@
 	 * Section 5.1. Client Support for Session Management,         
          */
 	XChangeProperty (dpy, newWindow, WmClientLeaderAtom, XA_WINDOW, 32, 
-	                 PropModeReplace, &windowGroupWindow, 1);
+	                 PropModeReplace, (unsigned char *)&windowGroupWindow, 1);
 	/* 
 	 * Section 4.1.2.9. WM_CLIENT_MACHINE Property
          */
@@ -2156,6 +2158,19 @@
 	XChangeProperty (dpy, newWindow, WmClientMachineAtom, XA_STRING, 8, 
 	                 PropModeReplace, __stringVal(__INST(hostname)), __stringSize(__INST(hostname)));
 	}
+	/* 
+	 * Section 4.1.2.5. WM_CLASS Property
+	 */
+	classhint.res_class = classhint.res_name = 0;
+
+	if (__isStringLike(__INST(wmClassClass))) {
+	    classhint.res_class = (char *) __stringVal(__INST(wmClassClass));
+	}
+
+	if (__isStringLike(__INST(wmClassName))) {
+	    classhint.res_name = (char *) __stringVal(__INST(wmClassName));
+	}	
+	XSetClassHint(myDpy, newWindow, &classhint);
 	LEAVE_XLIB();
 
 #ifdef SUPPORT_MOTIF_WM_HINTS
@@ -8884,6 +8899,24 @@
     "
     hostname := OperatingSystem getHostName.
 
+    "
+    Create (and cache) class and name for WM_CLASS property. 
+    (defined by ICCCM, Section 4.1.2.5. WM_CLASS Property)
+    "
+    wmClassName := OperatingSystem getEnvironment: 'RESOURCE_NAME'.
+    wmClassName isNil ifTrue:[
+	wmClassName := Smalltalk commandName.
+	"/ strip of any directory names
+	wmClassName := wmClassName copyFrom: (wmClassName lastIndexOf: Filename separator) + 1.
+    ].
+    wmClassName = 'stx' ifTrue:[
+    	wmClassName  := 'smalltalkx'.
+	wmClassClass := 'SmalltalkX'.
+    ] ifFalse:[
+	wmClassClass := wmClassName asUppercaseFirst.
+    ]
+
+
     "Modified (comment): / 17-04-2012 / 21:18:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !