5

Sometimes, I use KDE, and one of the things that I like the most in KDE 4 is the activity concept. At work, it is very useful because I often work on several different projects during one day. Switching to another activity enables me to change the widgets, so that I can have access to folders related to the current project, for instance.

I've decided to use this concept in the shell, so I have coded a small bash function called "switch", which sets aliases useful for the current project, e.g. alias cdwww=~/public_html/current_project/www , and so on.

My question is : Is there a way I can synchronise KDE activities with shell activities, that is calling 'switch myproj' on every opened terminal when switching to activity 'myproj' through KDE and vice versa (bonus question)?

Another question : how do I make my newly created aliases work in all consoles? Is there a way I can detect every opened terminal in konsole or in gnome-terminal and execute my function in it?

EDIT: here is the switch function, located at the end of my .bashrc file, feel free to comment:

function switch() {

    if [ ! -d ~/.switch ]
    then
        mkdir ~/.switch
    fi

    if [ ! -f ~/.switch/proj.save ]
    then
        touch ~/.switch/proj.save
    fi

    echo "$1" > ~/.switch/proj.save

    case $1 in
    meddispar )
        echo "Switching to meddispar..."

        echo "setting cdproj alias"
        alias cdproj="cd ~/public_html/onp/"

        echo "setting cdwww alias"
        alias cdwww="cd ~/public_html/onp/www/"

        echo "setting cc alias"
        alias cc="cdwww && php bin/php/ezcache.php --clear-all --purge && cd -"
    ;;
    darjeeling )
        echo "Switching to darjeeling..."

        echo "setting cdproj alias"
        alias cdproj="cd ~/public_html/darjeeling/"

        echo "setting cdwww alias"
        alias cdwww="cd ~/public_html/darjeeling/www/"

        echo "setting cc alias"
        alias cc="rm -rf ~/public_html/darjeeling/www/var/cache/*"
    ;;
    * )
        echo "'$1'? WTF?"
        rm ~/.switch/proj.save
    ;;
    esac
}
if [ -f ~/.switch/proj.save ]
then
     switch `cat ~/.switch/proj.save`
fi

As per Gilles' answer, here is what I have got:

greg@tiny :) ~ > qdbus |ack ctivity
 org.kde.ActivityController-1949
 org.kde.ActivityManager
greg@tiny :) ~ > qdbus org.kde.ActivityManager 
/
/ActivityManager
/MainApplication
/StatusNotifierWatcher
/connections
/kbuildsycoca
/kded
/kxkb
/modules
/modules/StatusNotifierWatcher
/modules/activitymanager
/modules/device_automounter
/modules/dnssdwatcher
/modules/favicons
/modules/freespacenotifier
/modules/keyboard
/modules/khotkeys
/modules/kpackagekitd
/modules/kremotecontroldaemon
/modules/ktimezoned
/modules/kwrited
/modules/nepomuksearchmodule
/modules/networkmanagement
/modules/networkstatus
/modules/powerdevil
/modules/randrmonitor
/modules/remotedirnotify
/modules/solidautoeject
/modules/statusnotifierwatcher
/org
/org/freedesktop
/org/freedesktop/PowerManagement
/org/freedesktop/PowerManagement/Inhibit
/org/kde
/org/kde/networkmanagement
/org/kde/networkmanagement/Activatable
/org/kde/networkmanagement/Activatable/10
/org/kde/networkmanagement/Activatable/11
/org/kde/networkmanagement/Activatable/12
/org/kde/networkmanagement/Activatable/13
/org/kde/networkmanagement/Activatable/14
/org/kde/networkmanagement/Activatable/15
/org/kde/networkmanagement/Activatable/16
/org/kde/networkmanagement/Activatable/17
/org/kde/networkmanagement/Activatable/2
/org/kde/networkmanagement/Activatable/3
/org/kde/networkmanagement/Activatable/4
/org/kde/networkmanagement/Activatable/5
/org/kde/networkmanagement/Activatable/6
/org/kde/networkmanagement/Activatable/7
/org/kde/networkmanagement/Activatable/8
greg@tiny :) ~ > qdbus org.kde.ActivityManager /ActivityManager
method QStringList org.kde.ActivityManager.ActivitiesForResource(QString uri)
method QString org.kde.ActivityManager.ActivityIcon(QString id)
method QString org.kde.ActivityManager.ActivityName(QString id)
signal void org.kde.ActivityManager.ActivityNameChanged(QString id, QString name)
method QString org.kde.ActivityManager.AddActivity(QString name)
method QStringList org.kde.ActivityManager.AvailableActivities()
method QString org.kde.ActivityManager.CurrentActivity()
signal void org.kde.ActivityManager.CurrentActivityChanged(QString id)
method bool org.kde.ActivityManager.IsBackstoreAvailable()
method void org.kde.ActivityManager.RegisterActivityController(QString service)
method void org.kde.ActivityManager.RegisterResourceWindow(uint wid, QString uri)
method QStringList org.kde.ActivityManager.RegisteredActivityControllers()
method void org.kde.ActivityManager.RemoveActivity(QString id)
method void org.kde.ActivityManager.SetActivityIcon(QString id, QString name)
method void org.kde.ActivityManager.SetActivityName(QString id, QString name)
method bool org.kde.ActivityManager.SetCurrentActivity(QString id)
method void org.kde.ActivityManager.UnregisterResourceWindow(uint wid, QString uri)
method QString org.kde.ActivityManager._allInfo()
method QString org.kde.ActivityManager._serviceIteration()
method QDBusVariant org.freedesktop.DBus.Properties.Get(QString interface_name, QString property_name)
method QVariantMap org.freedesktop.DBus.Properties.GetAll(QString interface_name)
method void org.freedesktop.DBus.Properties.Set(QString interface_name, QString property_name, QDBusVariant value)
method QString org.freedesktop.DBus.Introspectable.Introspect()
greg@tiny :) ~ > qdbus org.kde.ActivityController-1949 /ActivityController 
method void org.kde.ActivityController.ActivityAdded(QString id)
method void org.kde.ActivityController.ActivityRemoved(QString id)
method void org.kde.ActivityController.ResourceWindowRegistered(uint wid, QString uri)
method void org.kde.ActivityController.ResourceWindowUnregistered(uint wid, QString uri)
method QDBusVariant org.freedesktop.DBus.Properties.Get(QString interface_name, QString property_name)
method QVariantMap org.freedesktop.DBus.Properties.GetAll(QString interface_name)
method void org.freedesktop.DBus.Properties.Set(QString interface_name, QString property_name, QDBusVariant value)
method QString org.freedesktop.DBus.Introspectable.Introspect()

EDIT : I completely rewrote my script using python, and now the whole project is available here : https://github.com/greg0ire/switch

greg0ire
  • 3,005
  • in kde 4.6 you could just put a whole new konsole in your other activity with other settings... so your shell reacts to your activity change... – xenoterracide Jan 29 '11 at 01:37
  • Do you mean you can initialize your new konsole with something similar to a .bashrc script? – greg0ire Jan 29 '11 at 12:12

2 Answers2

9

Controlling KDE activities via dbus

KDE can be controlled from the command line with qdbus. The general syntax is qdbus COMPONENT PATH METHOD ARGUMENT1... where COMPONENT is typically something like org.freedesktop.Foo or org.kde.Bar, PATH denotes a class exposed by the component, METHOD is the name of a particular action in that class, and there may be further arguments depending on the method.

Here are commands for KDE ≥4.7 to list activities, to get the current activity, and to set the current activity.

qdbus org.kde.kactivitymanagerd /ActivityManager org.kde.ActivityManager.ListActivities
qdbus org.kde.kactivitymanagerd /ActivityManager org.kde.ActivityManager.CurrentActivity
qdbus org.kde.kactivitymanagerd /ActivityManager org.kde.ActivityManager.SetCurrentActivity "activity identifier "

Finding out what dbus can do

KDE's dbus documentation is very poor. Each class is minimally documented, e.g. Activity, DesktopCorona). But you'll probably have to experiment and perhaps read the source (there are links in the API documentation pages) to find out what is available.

If you type qdbus with up to two arguments, it will list the possibilities for the next argument. The following shell snippet lists all available Qt-dbus methods:

for x in $(qdbus | sed '/^:/d'); do
  for y in $(qdbus $x); do
    qdbus $x $y | sed "s~^~$x $y ~"
  done
done 2>/dev/null >qdbus.list

Another way to explore the dbus tree is qdbusviewer in the Qt development tools. There is also a Python qt-dbus interface as part of PyQt.

Getting the shell to react

To make a shell react to external events, the best you can reasonably do is make it check something before displaying a prompt. Bash runs $PROMPT_COMMAND before displaying a prompt, and zsh executes the precmd function. So you can look up the current KDE activity and do something if it's changed from the last time you looked.

greg0ire
  • 3,005
  • Thank you Gilles, I'll try these tricks and give a feedback later, but it seems to be what I'm looking for. – greg0ire Oct 29 '10 at 07:02
  • Actually, qdbus|grep Activity gives nothing back nor does qdbus|grep Corona , so I'm a bit lost... qdbus org.kde.plasma-netbook gives some output back, but I don't know how to search sub-commands globally... – greg0ire Oct 29 '10 at 09:33
  • This was on my netbook, on my desktop I get a similar result with org.kde.plasma-desktop – greg0ire Oct 29 '10 at 09:42
  • @greg0ire: I may have inferred things erroneously from the documentation (I don't have a recent enough version of KDE to test). See my edit for a script that lists all potential qdbus calls. – Gilles 'SO- stop being evil' Oct 29 '10 at 18:35
  • @Gilles: awesome piece of code, but it does only find things that seem unrelevant to me:org.gnome.ScreenSaver / method void org.gnome.ScreenSaver.SimulateUserActivity() org.kde.konsole /Sessions/1 method bool org.kde.konsole.Session.isMonitorActivity() org.kde.konsole /Sessions/1 method void org.kde.konsole.Session.setMonitorActivity(bool) (nothing found for Corona= – greg0ire Oct 29 '10 at 18:54
  • @greg0ire: Sorry, I have no idea what DesktopCorona is, I stumbled upon it on a search for “activity” in the KDE APIs. What about the activity manager — is there a way to invoke it from the command line? Otherwise you might have to write a short C++ (or whatever other language gives access to the relevant API) program that triggers the activity change. – Gilles 'SO- stop being evil' Oct 29 '10 at 19:23
  • Hello Gilles, I upgraded to Fedora 14 recently, and KDE was upgraded to a newer version in the process. It seems there are now a lot of results, but I think I might be very near to the solution to the first question. – greg0ire Nov 11 '10 at 16:03
  • The thing is, it does not seem to work for netbooks, which have a special configuration for activities. More news tomorrow : I have KDE on a desktop at work, and my ISP will open my new line at home tomorrow too, so I'll have an up to date kde for my home desktop. Then qdbus org.kde.ActivityManager /ActivityManager org.kde.ActivityManager.CurrentActivity should output something not empty, unlike on my netbook. – greg0ire Nov 11 '10 at 17:41
  • Hello, I'm at works, and here is the solution (I cannot edit your answer but you could update it : list activities : qdbus org.kde.ActivityManager /ActivityManager org.kde.ActivityManager.AvailableActivities set current activity : qdbus org.kde.ActivityManager /ActivityManager org.kde.ActivityManager.SetCurrentActivity <put activity id here> – greg0ire Nov 12 '10 at 08:59
  • @greg0ire: Go ahead and write an answer with the KDE dbus paths (and accept it, even). I'll keep my answer up for the shell tricks. – Gilles 'SO- stop being evil' Nov 12 '10 at 12:45
  • If I had enough rep, I would edit your answer, all I did was searching for the path, the main idea was yours. Really, just adapt your answer and it'll be fine (and less complicated for others to read). – greg0ire Nov 12 '10 at 15:51
  • @greg0ire: Ok, you can edit the answer now. Could you add how to retrieve the current activity? – Gilles 'SO- stop being evil' Nov 12 '10 at 16:34
  • @Gilles: great! Done. – greg0ire Nov 12 '10 at 17:25
  • I updated the answer because the API has changed, and I put a link at the bottom of my question if you want to see what this looks like. – greg0ire Feb 05 '12 at 19:11
0

how do I make my newly created aliases work in all consoles

This especially easy when using the fish shell instead of bash. Besides increasing productivity in general (at least for me), it knows the concept of a global (universal) variable, which is defined by

set -U VARIABLE_NAME VALUES

The variable is immediately available in all consoles and the value is restored after reboot.