An Update: 2022-06-27
The update digs deeper into D-Bus activation and fixes some bugs within the text.
The Goal
Making terminal application behave like GUI application within Gnome-shell. For example, I would like the mc (midnight commander) to have its own icon when switching among the other windows, its own place in Gnome’s dash. Finally, mc should have its own window, which will be listed as Midnight commander window and not be hidden among other terminal windows.
Of course, this could also be done with other terminal applications like tmux/screen, mutt, rtorrent, mp3blaster, lftp, et cetera.
In short it works like this:
gnome terminal (mc) --> D-Bus -> systemd
I have used:
GNOME terminal version 3.44.1 for GNOME 42
Creating a desktop file
The mc.desktop
(can be placed in user path ~/.local/share/applications/ or system path /usr/share/applications/):
1
2
3
4
5
6
7
8
9
10
11
[Desktop Entry]
Name=Midnight Commander
Comment=File Manager
Exec=gnome-terminal --app-id org.gnome.Terminal-mc --geometry=111x40 --hide-menubar -- mc
Category=FileManager;FileTools;ConsoleOnly
Icon=mc
Type=Application
Keywords=file;manager;console;
StartupNotify=true
StartupWMClass=org.gnome.Terminal-mc
Terminal=true
Explanation (except for those that are self-explanatory):
-
exec
runs the client side-
--app-id= org.gnome.Terminal-mc
- application ID of the window (based on the original Gnome terminal application idorg.gnome.Terminal
) -
--geometry=WxH
- W…width, H…height -
--hide-menubar
- hides menubar if enabled, to have bigger working area -
--
stops parsing parameters and executes the command
-
-
Category=FileManager;FileTools;ConsoleOnly
- additional category as defined at freedesktop specification -
Icon=mc
- tries to serch for a mc.svg icon at /usr/share/icons/hicolor/scalable/apps/ -
Keywords=file;manager;console;
- defines keywords based on which we try to find the application in addition to the name. See more at DesktopFileKeywords -
StartupNotify=true
- When startup notification is set, the panel and cursor notifies the user that the application has started. When the application appears onscreen, the panel and cursor return to normal. -
StartupWMClass=org.gnome.Terminal-mc
- class (WM_CLASS
) of the window. Since we are already using--app-id
this is not really needed here. However, I like to fill the class of the window anyways. -
Terminal=true
- Specifies whether the command in the Exec key runs in a terminal window. If the value is true the command runs in a terminal window. If the command does not create a window in which to run, the value of this key must be true.
To correctly identify the WM_CLASS property of the window run
xprop WM_CLASS
. TheWM_CLASS
property uses a XClassHint structure, which is defined in theX11/Xutil.h
header file.
Be careful when using system path /usr/share/applications/ as the path can be used by the original package. If you upgrade the package it could get overwritten. The recommendation is to use the user path!
Creating a DBUS service
Since GNOME Terminal uses a D-Bus activated server, you cannot simply run the gnome-terminal directly. Instead, you need to create a new D-Bus service where the new gnome-terminal-server is started:
The path: sudo vim /usr/share/dbus-1/services/org.gnome.Terminal-mc.service
The script:
1
2
3
4
[D-BUS Service]
Name=org.gnome.Terminal-mc
SystemdService=gnome-terminal-mc-server.service
Exec=/bin/false
Explanation:
-
Name
- dbus service name (called@gt_dns_name@
in the gnome-terminal source, which refers to the original gnome-terminal’s app-idorg.gnome.Terminal
). -
SystemdService
- name of the systemd service which does the execution of the server part. -
Exec
- what will be executed.-
/bin/false
- exit with a status code indicating failure. This is a dummy execution. Runningfalse
to indicate that there should not be anything executed.
-
Many examples on the internet try to execute
gnome-terminal-server
here, which is wrong! The double execution slows down the execution and it is completely pointless here. What is needed is theSystemdService
directive which connects to the systemd unit which we will define below.
Creating a systemd unit
Creates a systemd unit which actually runs the gnome-terminal-server
(server part of gnome-terminal
).
The path: sudo vim /usr/lib/systemd/user/gnome-terminal-mc-server.service
The systemd unit:
1
2
3
4
5
6
7
[Unit]
Description=Midnight Commander Terminal Server (GNOME)
[Service]
Type=dbus
BusName=org.gnome.Terminal-mc
ExecStart=/usr/libexec/gnome-terminal-server --app-id org.gnome.Terminal-mc --class=org.gnome.Terminal-mc
KillMode=process
Explanation (skipping description):
-
Type=dbus
- the service is considered ready when the specifiedBusName
appears on D-Bus’s system bus. -
BusName=org.gnome.Terminal-mc
- the exact name of the D-Bus service as defined in the service -
ExecStart=...
is an array of structures each containing: the binary path to execute; an array with all arguments to pass to the executed command, starting with argument 0; a boolean whether it should be considered a failure if the process exits uncleanly; two pairs ofCLOCK_REALTIME/CLOCK_MONOTONIC
used timestamps when the process began and finished running the last time, or 0 if it never ran or never finished running; the PID of the process, or 0 if it has not run yet; the exit code and status of the last run. This field hence maps more or less to the corresponding setting in the service unit file but is augmented with runtime data. -
KillMode=process
- Specifies how processes of this unit shall be killed. Here it is set onprocess
, because only the main process (gnome terminal) itself needs to be killed.
The
app-id
interconnects the client/server parts (.desktop file, D-Bus, systemd). Theclass
part notifies the Gnome system that the application is running (shows running in dash, lists it in the application list when switching viaalt+tab
).
How it looks like?
Midnight Commander now behaves like GUI application
Resources
I have mainly used these resources. I’m including the list so the reader, should he be interested, could study it: