![将 KDE 活动概念扩展到 shell](https://linux22.com/image/42219/%E5%B0%86%20KDE%20%E6%B4%BB%E5%8A%A8%E6%A6%82%E5%BF%B5%E6%89%A9%E5%B1%95%E5%88%B0%20shell.png)
有时,我使用 KDE,KDE 4 中我最喜欢的事情之一就是活动概念。在工作中,它非常有用,因为我经常在一天内处理几个不同的项目。例如,切换到另一个活动使我能够更改小部件,以便我可以访问与当前项目相关的文件夹。
我决定在 shell 中使用这个概念,因此我编写了一个名为“switch”的小型 bash 函数,它设置对当前项目有用的别名,例如alias cdwww=~/public_html/current_project/www
等等。
我的问题是:有没有一种方法可以将 KDE 活动与 shell 活动同步,即通过 KDE 切换到活动“myproj”时在每个打开的终端上调用“switch myproj”,并且反之亦然(奖励问题)?
另一个问题:如何使我新创建的别名在所有控制台中工作?有没有办法可以检测 konsole 或 gnome-terminal 中每个打开的终端并在其中执行我的函数?
编辑:这是开关函数,位于我的 .bashrc 文件的末尾,请随意评论:
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
根据吉尔斯的回答,这是我得到的:
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()
编辑:我使用 python 完全重写了我的脚本,现在整个项目可以在这里使用:https://github.com/greg0ire/switch
答案1
通过 dbus 控制 KDE 活动
KDE 可以通过命令行进行控制qdbus
。一般语法是,qdbus COMPONENT PATH METHOD ARGUMENT1...
其中COMPONENT
通常类似于org.freedesktop.Foo
或org.kde.Bar
,PATH
表示组件公开的类,METHOD 是该类中特定操作的名称,并且可能还有更多参数,具体取决于方法。
以下是 KDE ≥4.7 的命令,用于列出活动、获取当前活动以及设置当前活动。
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 "
了解 dbus 可以做什么
KDE 的 dbus 文档非常差。每个类都有最少的记录,例如活动,桌面Corona)。但您可能必须进行试验,或许还需要阅读源代码(API 文档页面中有链接)才能找出可用的内容。
如果您输入qdbus
最多两个参数,它将列出下一个参数的可能性。以下 shell 片段列出了所有可用的 Qt-dbus 方法:
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
探索 dbus 树的另一种方法是qdbusviewer
使用 Qt 开发工具。还有一个 Python qt-dbus 接口作为pyqt。
让外壳做出反应
要使 shell 对外部事件做出反应,您可以合理地做的最好的事情就是让它在显示提示之前检查某些内容。 Bash$PROMPT_COMMAND
在显示提示之前运行,而 zsh 执行该precmd
函数。因此,您可以查找当前的 KDE 活动,如果它与您上次查看时相比发生了变化,则可以执行某些操作。
答案2
如何使新创建的别名在所有控制台中工作
当使用鱼壳而不是bash。除了总体上提高生产力(至少对我来说)之外,它还知道全局(通用)变量的概念,该变量的定义为
set -U VARIABLE_NAME VALUES
该变量在所有控制台中立即可用,并且该值在重新启动后恢复。