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: /usr/share/icons/hicolor/scalable/apps/
.
The svg instances icons:
The first instance svg icon
The second instance svg icon
Different window class the WM_CLASS
property
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[0] 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
Setting WM_CLASS
property at Smalltalk/X
The Smalltalk/X works with the WM_CLASS
property in the XWorkstation>>initializeDefaultValues
. 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 wmClassName
:
XWorkstation>>initializeDefaultValues
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 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' 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:
~/smalltalkx/build/stx/projects/smalltalk/smalltalk
. - To export the variable you have to do add this to the launcher bash script (at the second instance):
1
export RESOURCE_NAME="SmalltalkX-2nd"
- Last but not the least, you have to edit the
.desktop
file at~/.local/share/applications/
. The desktop file must contain theStartupWMClass=SmalltalkX-2nd
which identifies the the seconds instance for Gnome Shell. I recommend adding theStartupWMClass
also to the first instance asStartupWMClass=SmalltalkX
(which is hard-coded as defaultWM_CLASS
for Smalltalk/X).
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=true
needs to be set. Note: this terminal window will not be listed among other terminal windows.
The only disadvantage, I have noticed, when using
WM_CLASS
property 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 changedRESOURCE_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_bg_color
and 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 light
and 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.
The @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
Conclusion
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.