Start and Control konsole with DBUS

Some time back I wrote about creating a number of konsoles automatically using dcop. Although we were at the time well into the KDE4 era I had not yet upgraded since there were still things that weren't quite working with KDE4, most of these have now been fixed so I've upgraded some of my systems to KDE4, which means it's time to update the original code to now use dbus.

My first attempt at this was using dbus-send but after not making a lot of progress with that I tried using qdbus instead, this proved easier to use. In re-implementing this code for KDE4 I also discovered a few things that aren't quite working yet in Konsole's dbus interface:

  • It's not yet possible to start a new konsole in another konsole window, all new konsoles appear in the current konsole. My original code created a completely new konsole window and filled it with the new konsoles. Since this is not yet implemented that feature is yanked.
  • Starting a console with a particular "Schema" is also not working yet. The code for doing this is still in the sample below but it's commented out. Also note that schemas have been replaced by "profiles" in KDE4.
  • There's no way to activate a specific session yet using dbus.

At the top are the definitions of the konsoles that I want to start. This is an array where each konsole is defined by 3 entries in the array: the first is the name that I want to give to the konsole tab, the second is the profile to use (ignored for now since this is not working), and the third is the initial command to execute within the konsole.

sessions=(
    sh1   $profile   'clear; bash'
    sh1   $profile   'clear; bash'
    su1   $profile   'clear; su'
    ssh1  $profile   'clear; ssh 127.0.0.1'
    )

After that is the start_sessions function which is quite similar to the original one from the KDE3 version of the code, the main difference being that it calls qdbus rather than dcop to interace with konsole. To create a new session it does:

        # Starting with a specific profile appears to be broken.
        #local session_num=$(qdbus org.kde.konsole /Konsole newSession $profile $HOME)
        local session_num=$(qdbus org.kde.konsole /Konsole newSession)
        sleep 0.1

You'll notice above that the call with the profile included is commented out as that call is still not working in KDE4/Konsole.

To set the title of the session it does:

        qdbus org.kde.konsole /Sessions/$session_num setTitle 0 $name
        sleep 0.1
        qdbus org.kde.konsole /Sessions/$session_num setTitle 1 $name
        sleep 0.1

Title "0" appears to be the initial title, title "1" is the title used after commands are executed. So if you don't set title "1" then the tab title changes after each command that you enter.

To set the command to be run by the new konsole you send text to it:

        qdbus org.kde.konsole /Sessions/$session_num sendText "$command"
        sleep 0.1
        qdbus org.kde.konsole /Sessions/$session_num sendText $'\n'
        sleep 0.1

The second send sends a newline so the konsole actually executes the command.

The main part of the script asks if you want to create the konsoles and executes start_sessions if you answer with something that looks like yes. After starting the sessions it activates the first session. As I mentioned above there's no way to activate a specific session so the code activates the first session by activating the "previous" session multiple times.

    # Activate first session.
    while [[ $nsessions -gt 1 ]]
    do
        qdbus org.kde.konsole /Konsole prevSession
        let nsessions--
    done

Run this and you should get a konsole window that looks something like:

konsoles.jpg

The entire code follows:

#!/bin/bash
#
# Create my standard konsole windows.

if [[ ! "$profile" ]]; then
    profile=Shell
fi

sessions=(
    sh1   $profile   'clear; bash'
    sh1   $profile   'clear; bash'
    su1   $profile   'clear; su'
    ssh1  $profile   'clear; ssh 127.0.0.1'
    )

nsessions=0

#####################################################################
# Start sessions in konsole.
function start_sessions()
{
    local session_count=${#sessions[*]}
    local i=0

    while [[ $i -lt $session_count ]]
    do
        local name=${sessions[$i]}
        let i++
        local profile=${sessions[$i]}
        let i++
        local command=${sessions[$i]}
        let i++

        echo "Creating $name: $command"
        # Starting with a specific profile appears to be broken.
        #local session_num=$(qdbus org.kde.konsole /Konsole newSession $profile $HOME)
        local session_num=$(qdbus org.kde.konsole /Konsole newSession)
        sleep 0.1
        qdbus org.kde.konsole /Sessions/$session_num setTitle 0 $name
        sleep 0.1
        qdbus org.kde.konsole /Sessions/$session_num setTitle 1 $name
        sleep 0.1
        qdbus org.kde.konsole /Sessions/$session_num sendText "$command"
        sleep 0.1
        qdbus org.kde.konsole /Sessions/$session_num sendText $'\n'
        sleep 0.1

        let nsessions++
    done
}

read -p "Create konsoles? " ans
if [[ "${ans:0:1}" == 'y' ]]; then
    start_sessions

    # Activate first session.
    while [[ $nsessions -gt 1 ]]
    do
        qdbus org.kde.konsole /Konsole prevSession
        let nsessions--
    done
fi


# vim: tabstop=4: shiftwidth=4: noexpandtab:
# kate: tab-width 4; indent-width 4; replace-tabs false;

Mitch Frazier is an embedded systems programmer at Emerson Electric Co. Mitch has been a contributor to and a friend of Linux Journal since the early 2000s.

Load Disqus comments