Start and Control konsole with DCOP

I like to open a lot of tabs in my terminal (konsole) window: a few standard shells, a couple of su shells, and some ssh connections to other systems that I access regularly. KDE can remember some of these settings via its session capability, but it doesn't always remember everything I want, and sometimes it remembers things I wish it would forget. So, to get my standard tabs, I use DCOP to start what I want when I want it.

DCOP (Desktop COmmunication Protocol) is a protocol that allows applications to interoperate. DCOP has a command-line tool for using it, named, of course, dcop. Note, that DCOP has been replaced in KDE4 with D-Bus (Desktop Bus), so if you've moved to KDE4, this won't do you any good.

The idea is to create a script that creates the konsole tabs I want to create. First are the library functions. There are three functions:

  • create_konsole - starts a new copy of konsole and returns the DCOP ID for it.

  • wait_for_session - waits until the session count (that is, the tab count) in the specified konsole reaches a certain value. This is used to make sure a recently created session has actually started before we try to interact with it.

  • start_sessions - uses a global sessions array to start a list of sessions. The array contains three items for each session:

    • The session name
    • The schema for the session
    • The command to run in the session

The library code follows:

#!/bin/bash
#
# Functions from creating konsoles.


#####################################################################
# Create new console.
function create_konsole()
{
    local basename=$(date +"%H%M%N")
    local name=$basename"_konsoleX1_"
    local kstart_options=$1
    local konsole_options=$2
    kstart $kstart_options --window $name konsole $konsole_options --script -T $name >/dev/null 2>&1
    local konsole_id=konsole-$(ps aux | grep konsole | grep -v grep | grep $name | awk '{print $2}')
    echo $konsole_id
}

#####################################################################
# Wait to make sure the session count equals $1.
function wait_for_session()
{
    local konsole_id=$1
    local count=$2
    local session_count=$(dcop $konsole_id konsole sessionCount 2>/dev/null)
    while [[ $session_count -ne $count ]]
    do
        sleep 0.1
        session_count=$(dcop $konsole_id konsole sessionCount)
    done
}

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

    while [[ $i -lt $session_count ]]
    do
        local name=${sessions[$i]}
        let i++
        local schema=${sessions[$i]}
        let i++
        local command=${sessions[$i]}
        let i++
        dcop $konsole_id $session_id renameSession "$name"
        sleep 0.1
        dcop $konsole_id $session_id setSchema "$schema"
        sleep 0.1
        dcop $konsole_id $session_id sendSession "$command"
        sleep 0.1

        if [[ $i -lt $session_count ]]; then
            let nsessions++
            local session_id=$(dcop $konsole_id konsole newSession)
            wait_for_session $konsole_id $nsessions
        fi
    done
}

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

In create_konsole we start the new konsole with the command:

    kstart $kstart_options --window $name konsole $konsole_options --script -T $name >/dev/null 2>&1

This uses kstart to start konsole with a known window name, so that we can get its name via some ps/grep shenanigans in the next line.

In start_sessions, we use dcop to rename the session:

        dcop $konsole_id $session_id renameSession "$name"

To set the schema for the session:

        dcop $konsole_id $session_id setSchema "$schema"

And to send the command to the session:

        dcop $konsole_id $session_id sendSession "$command"

At the end of the function, if there are more sessions to create, we also use dcop to start another session:

            local session_id=$(dcop $konsole_id konsole newSession)

In our main script, we need to define the sessions we want. For this sample, we'll start two standard shells, one su shell and one ssh connection:

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

The schema variable here is set to the *.schema file that we want konsole to use for the tab. The entire script is:

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

source ~/bin/konsoles.sh

if [[ ! "$schema" ]]; then
    #schema=XTerm.schema
    #schema=BlackOnLightColor.schema
    #schema=Linux.schema
    #schema=GreenTint.schema
    #schema=syscolor.schema
    #schema=LightPicture.schema
    #schema=DarkPicture.schema
    schema=GreenOnBlack.schema
    #schema=BlackOnLightYellow.schema
    #schema=LightPaper.schema
    #schema=WhiteOnBlack.schema
    #schema=BlackOnWhite.schema
    #schema=Transparent.schema
    #schema=Transparent_MC.schema
    #schema=Transparent_lightbg.schema
    #schema=GreenTint_MC.schema
    #schema=vim.schema
    #schema=Transparent_darkbg.schema
fi

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

konsole_id=$(create_konsole '--iconify')
wait_for_session 1

session_id=$(dcop $konsole_id konsole currentSession)
first_session_id=$session_id

start_sessions $konsole_id

dcop $konsole_id konsole activateSession $first_session_id
sleep 0.1
dcop $konsole_id 'konsole-mainwindow#1' restore
sleep 0.1
dcop $konsole_id 'konsole-mainwindow#1' setGeometry 100 100 600 400

# vim: tabstop=4: shiftwidth=4: noexpandtab:
# kate: tab-width 4; indent-width 4; replace-tabs false;
The steps are:
  • Call create_konsole to create the initial console and wait for it to become ready. The window is created iconified.
  • Use dcop to get the session id of the first session created. We use this after creating all the other sessions to activate the first session.
  • Call start_sessions to create the sessions in our sessions array.
  • Use dcop to activate the first session that was created.
  • Use dcop to restore the main window.
  • Use dcop to size and place the main window.

Run the main script and you should get a konsole window that looks like:

konsoles.jpg

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