Home Running midnight commander as an independent instance of Gnome terminal
Post
Cancel

Running midnight commander as an independent instance of Gnome terminal

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 id org.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. The WM_CLASS property uses a XClassHint structure, which is defined in the X11/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-id org.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. Running false 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 the SystemdService 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 specified BusName 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 of CLOCK_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 on process, 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). The class part notifies the Gnome system that the application is running (shows running in dash, lists it in the application list when switching via alt+tab).

How it looks like?

Midnight CommanderMidnight 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:

This post is licensed under CC BY 4.0 by the author.