Having two instances of Smalltalk/X is a great idea I got from Jan Vraný. If you do so, you can debug at one instance and in the second one you can continue developing.
This guide shows you how to have two same instances differentiated in Linux Gnome shell in a way you don’t confuse them between each other.
Gnome-Shell based instance differentiation
Different SVG icons
First what comes into mind is to have different icons for each instance. I have used the icon distributed with Smalltalk/X and added a number for each instance. I have placed the custom icons to the path:
The svg instances icons:
The first instance svg icon
The second instance svg icon
Different window class the
Next is for the Gnome to be able to differentiate between each instance. This was tricky and took some time of playing around even with D-Bus. Which led to creation of article about terminal mc terminal application being able to run as GUI application.
The best solution in my eyes is using the
WM_CLASS property. The definition is taken from the link:
The WM_CLASS property (of type STRING without control characters) contains two consecutive null-terminated strings. These specify the Instance and Class names to be used by both the client and the window manager for looking up resources for the application or as identifying information. This property must be present when the window leaves the Withdrawn state and may be changed only while the window is in the Withdrawn state. Window managers may examine the property only when they start up and when the window leaves the Withdrawn state, but there should be no need for a client to change its state dynamically.
The two strings, respectively, are:
- A string that names the particular instance of the application to which the client that owns this window belongs. Resources that are specified by instance name override any resources that are specified by class name. Instance names can be specified by the user in an operating-system specific manner. On POSIX-conformant systems, the following conventions are used:
- If “-name NAME” is given on the command line, NAME is used as the instance name.
- Otherwise, if the environment variable RESOURCE_NAME is set, its value will be used as the instance name.
- Otherwise, the trailing part of the name used to invoke the program (argv stripped of any directory names) is used as the instance name.
- A string that names the general class of applications to which the client that owns this window belongs. Resources that are specified by class apply to all applications that have the same class name. Class names are specified by the application writer. Examples of commonly used class names include: “Emacs”, “XTerm”, “XClock”, “XLoad”, and so on.
Note that WM_CLASS strings are null-terminated and, thus, differ from the general conventions that STRING properties are null-separated. This inconsistency is necessary for backwards compatibility.
How to set or read the
WM_CLASS property in your code visit - 14.1.8 Setting and Reading the WM_CLASS Property
WM_CLASS property at Smalltalk/X
The Smalltalk/X works with the
WM_CLASS property in the
WM_CLASS is read into Smalltalk/X via environment variable
RESOURCE_NAME. If you export the
RESOURCE_NAME before running the Smalltalk/X you will be able to differentiate the instances from each other.
Here is the excerpt of the
XWorkstation>>initializeDefaultValues code which defines the
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ... " Create (and cache) class and name for WM_CLASS property. (defined by ICCCM, Section 18.104.22.168. 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' or:[wmClassName = 'stx-bin']) ifTrue:[ wmClassName := 'smalltalkx'. wmClassClass := 'SmalltalkX'. ] ifFalse:[ wmClassClass := wmClassName asUppercaseFirst. ]. ...
To export the variable before running Smalltalk/X while not having it permanently in the environment, the smalltalk bash launcher has to be edited at path:
- To export the variable you have to do add this to the launcher bash script (at the second instance):
- Last but not the least, you have to edit the
~/.local/share/applications/. The desktop file must contain the
StartupWMClass=SmalltalkX-2ndwhich identifies the the seconds instance for Gnome Shell. I recommend adding the
StartupWMClassalso to the first instance as
StartupWMClass=SmalltalkX(which is hard-coded as default
The complete first instance desktop file:
1 2 3 4 5 6 7 8 9 [Desktop Entry] Name=First Smalltalk/X Comment=Smalltalk IDE Exec="/home/tukan/Prg_sdk/1st-stx8-jv/build/stx/projects/smalltalk/smalltalk" --quick Icon=smalltalkx-first Type=Application Keywords=Smalltalk;IDE;Development StartupWMClass=SmalltalkX Terminal=false
The complete second instance desktop file:
1 2 3 4 5 6 7 8 9 10 [Desktop Entry] Name=Second Smalltalk/X Comment=Smalltalk IDE Exec="/home/tukan/Prg_sdk/2nd-stx8-jv/build/stx/projects/smalltalk/smalltalk" --quick Icon=smalltalkx-second Type=Application Keywords=Smalltalk;IDE;Development StartupWMClass=SmalltalkX-2nd StartupNotify=true Terminal=false
If a gnome terminal window should be started with Smalltalk/X, the
Terminal=trueneeds to be set. Note: this terminal window will not be listed among other terminal windows.
The only disadvantage, I have noticed, when using
WM_CLASSproperty is that the Gnome Shell tab switcher takes some time (up to few seconds) to register (list it among other applications) the second Smalltalk/X instance (which is using the changed
RESOURCE_NAME). The Gnome’s dash, on the other hand, registers it instantly.
The Smalltalk/X based instance differentiation
I have created patch which will hopefully end up in the Smalltalk/X-jv soon. It exposes two menuPanel color variables
menu_fg_color to the Adwaita style file, which enables anyone who wants to customize the menu color to their liking.
The Adwaita style file is to be found at
~/smalltalkx/build/stx/libview/styles/Adwaita_colors.style. There are two variants
dark, which have their own set of variables set. I’m using dark scheme at Smalltalk/X so I’ll be changing only the dark part only.
@Adwaita_colors.style file customization (the default values):
1 2 3 4 5 6 7 8 9 10 #if $variant = 'light' ... menu_bg_color Color rgbValue: 16rf6f5f4 menu_fg_color Color rgbValue: 16r2e3436 ... #else //variant = 'dark' ... menu_bg_color Color rgbValue: 16r353535 menu_fg_color Color rgbValue: 16reeeeec ...
The only changed value is enough for me:
1 2 3 4 5 6 7 #else //variant = 'dark' ... ; second instance menuPanel color menu_bg_color Color rgbValue: 16r19334c ; the fg is the same for the 2nd instance menu_fg_color Color rgbValue: 16reeeeec ...
How does the result look like?
Here is a screenshot
Two differentiated Smalltalk/X instances
For myself, I must say I’m really happy with the result. After this change I have never mistaken one Smalltalk/X instance for the other.
Note: In this blog I’m using Smalltalk/x-jv branch, which is maintained by Jan Vraný. The upstream Smalltalk/X was created and build by Claus Gittinger. It is used in products developed by the eXept company.