And D-BUS can control a KDE application already

    thiago's picture
    2006
    6
    Jun

    So I was working on kdelibs over the weekend, trying to clear up a few problems with the D-BUS implementation in KDE. I found that the KMainWindow interface worked almost perfectly out of the box (it would have worked perfectly if I hadn't used a dash [-] in the object path in the first place).

    Here's what the object looks like: [image:2079 hspace=10 align=right class="show-on-planet" size=preview]

    $ dbus local.kmainwindowtest /kmainwindowtest/MainWindow_1
    method void local.kmainwindowtest.KMainWindow.appHelpActivated()
    method void local.kmainwindowtest.KMainWindow.configureToolbars()
    method void local.kmainwindowtest.KMainWindow.setCaption(QString caption)
    method void local.kmainwindowtest.KMainWindow.setCaption(QString caption, bool modified)
    method void local.kmainwindowtest.KMainWindow.setPlainCaption(QString caption)
    method void local.kmainwindowtest.KMainWindow.setSettingsDirty()
    method void local.kmainwindowtest.KMainWindow.slotStateChanged(QString newstate)
    method void local.kmainwindowtest.KMainWindow.slotStateChanged(QString newstate, bool reverse)
    property readwrite bool com.trolltech.Qt.QWidget.acceptDrops
    property readwrite QString com.trolltech.Qt.QWidget.accessibleDescription
    property readwrite QString com.trolltech.Qt.QWidget.accessibleName
    property readwrite bool com.trolltech.Qt.QWidget.autoFillBackground
    property readwrite bool com.trolltech.Qt.QWidget.enabled
    property read bool com.trolltech.Qt.QWidget.focus
    property read bool com.trolltech.Qt.QWidget.fullScreen
    property read int com.trolltech.Qt.QWidget.height
    property read bool com.trolltech.Qt.QWidget.isActiveWindow
    property read bool com.trolltech.Qt.QWidget.maximized
    property readwrite int com.trolltech.Qt.QWidget.maximumHeight
    property readwrite int com.trolltech.Qt.QWidget.maximumWidth
    property read bool com.trolltech.Qt.QWidget.minimized
    property readwrite int com.trolltech.Qt.QWidget.minimumHeight
    property readwrite int com.trolltech.Qt.QWidget.minimumWidth
    property read bool com.trolltech.Qt.QWidget.modal
    property readwrite bool com.trolltech.Qt.QWidget.mouseTracking
    property readwrite QString com.trolltech.Qt.QWidget.statusTip
    property readwrite QString com.trolltech.Qt.QWidget.toolTip
    property readwrite bool com.trolltech.Qt.QWidget.updatesEnabled
    property readwrite bool com.trolltech.Qt.QWidget.visible
    property readwrite QString com.trolltech.Qt.QWidget.whatsThis
    property read int com.trolltech.Qt.QWidget.width
    property readwrite QString com.trolltech.Qt.QWidget.windowIconText
    property readwrite bool com.trolltech.Qt.QWidget.windowModified
    property readwrite double com.trolltech.Qt.QWidget.windowOpacity
    property readwrite QString com.trolltech.Qt.QWidget.windowTitle
    property read int com.trolltech.Qt.QWidget.x
    property read int com.trolltech.Qt.QWidget.y
    method bool com.trolltech.Qt.QWidget.close()
    method void com.trolltech.Qt.QWidget.hide()
    method void com.trolltech.Qt.QWidget.lower()
    method void com.trolltech.Qt.QWidget.raise()
    method void com.trolltech.Qt.QWidget.repaint()
    method void com.trolltech.Qt.QWidget.setDisabled(bool)
    method void com.trolltech.Qt.QWidget.setEnabled(bool)
    method void com.trolltech.Qt.QWidget.setFocus()
    method void com.trolltech.Qt.QWidget.setHidden(bool hidden)
    method void com.trolltech.Qt.QWidget.setShown(bool shown)
    method void com.trolltech.Qt.QWidget.setVisible(bool visible)
    method void com.trolltech.Qt.QWidget.setWindowModified(bool)
    method void com.trolltech.Qt.QWidget.show()
    method void com.trolltech.Qt.QWidget.showFullScreen()
    method void com.trolltech.Qt.QWidget.showMaximized()
    method void com.trolltech.Qt.QWidget.showMinimized()
    method void com.trolltech.Qt.QWidget.showNormal()
    method void com.trolltech.Qt.QWidget.update()
    method bool org.kde.KMainWindow.actionIsEnabled(QString action)
    method QString org.kde.KMainWindow.actionToolTip(QString action)
    method QStringList org.kde.KMainWindow.actions()
    method bool org.kde.KMainWindow.activateAction(QString action)
    method bool org.kde.KMainWindow.disableAction(QString action)
    method bool org.kde.KMainWindow.enableAction(QString action)
    method void org.kde.KMainWindow.grabWindowToClipBoard()
    method qlonglong org.kde.KMainWindow.winId()
    method QString org.freedesktop.DBus.Introspectable.Introspect()
    method QVariant org.freedesktop.DBus.Properties.Get(QString interface_name, QString property_name)
    method void org.freedesktop.DBus.Properties.Set(QString interface_name, QString property_name, QVariant value)

    The local.kmainwindowtest.KMainWindow interface is a side-effect I'll have to correct eventually: I wanted to get all the QWidget slots public, but that also made the KMainWindow slots public as well.

    With that object, you can do nifty things like raising, lowering, minimising, restoring, hiding or showing a window, setting it to full-screen and normal mode or even copy it to the clipboard. Unfortunately, you can't move windows yet, because the geometry and pos properties take QRect and QPoint (respectively), which aren't supported in D-BUS for the moment.

    This is all cross-framework as well!

    Here's what the /MainApplication object currently looks like (it's the KApplication object):

    $ dbus local.kmainwindowtest /MainApplication
    method void org.kde.KApplication.quit()
    method void org.kde.KApplication.reparseConfiguration()
    method void org.kde.KApplication.updateUserTimestamp()
    method void org.kde.KApplication.updateUserTimestamp(int time)
    property readwrite int com.trolltech.Qt.QApplication.cursorFlashTime
    property readwrite int com.trolltech.Qt.QApplication.doubleClickInterval
    property readwrite int com.trolltech.Qt.QApplication.keyboardInputInterval
    property readwrite bool com.trolltech.Qt.QApplication.quitOnLastWindowClosed
    property readwrite int com.trolltech.Qt.QApplication.startDragDistance
    property readwrite int com.trolltech.Qt.QApplication.startDragTime
    property readwrite int com.trolltech.Qt.QApplication.wheelScrollLines
    property readwrite QString com.trolltech.Qt.QCoreApplication.applicationName
    property readwrite QString com.trolltech.Qt.QCoreApplication.organizationDomain
    property readwrite QString com.trolltech.Qt.QCoreApplication.organizationName
    method QString org.freedesktop.DBus.Introspectable.Introspect()
    method QVariant org.freedesktop.DBus.Properties.Get(QString interface_name, QString property_name)
    method void org.freedesktop.DBus.Properties.Set(QString interface_name, QString property_name, QVariant value)

    One interesting thing you may note is that, if your application is a KUniqueApplication, you automatically get a org.kde.KUniqueApplication.newInstance method.

    And when you're done with your test, you can just quit it:

    $ dbus local.kmainwindowtest /MainApplication quit
    
    [1]+  Done                    ./kmainwindowtest
    $

    Comments

    Comment viewing options

    Select your preferred way to display the comments and click "Save settings" to activate your changes.
    j6t's picture

    Raise window

    Your note that it's possible to raise a window stirred my attention. How would you do that? And does it really work?

    My guess is that you are refering to com.trolltech.Qt.QWidget.raise() and my further guess is that this plainly wraps QWidget::raise(). But this does not raise the window, it just makes it flash in the "task bar". Or has this changed in KDE4?

    lubos lunak's picture

    When you use DCOP ... er ...

    When you use DCOP ... er ... DBUS to ask an application to raise its window, it'll be the application trying to raise its window. Which means KWin may normally step in and e.g. prevent the raise if the application is in the background. However the dcop command-line client automatically updates the user timestamp in the application (unless it gets --no-user-time), so the raise should work (no idea if it's the same with DBUS).
    Still, it's better to ask the window manager to do it, because then the window manager knows it's the user asking for it. There's e.g. WMIface, KDE3-only though.

    pedahzur's picture

    Security question...

    Now, granted, users shouldn't be running random bits of code and shell scripts sent to them by people they don't know. However, with this much functionality "out in the open," this will make writing very annoying shell scripts (and possibly macro viruses, via system or library calls) very easy. Say, a simple script to e-mail itself to anyone in your Kontact address book. Are there ways to make sure these interfaces (which look very, very cool) don't get abused?

    quintesse's picture

    These scripts can't be

    These scripts can't be embedded in a webpage or email and made to run automatically if that is what you're worried about. The moment that is possible on your system you have far larger problems to worry about. And if you decide to download a script from a webpage or save a script attached to an email, give it execute rights and start it... well that's your responsibility, isn't it?

    Nice work Thiago!

    PS: Is that tool from the screenshot part of DBus nowadays? And does it mean that all KDE objects all support introspection (like all DBus objects should IMO ;-) )

    thiago's picture

    That tool is dbus-viewer,

    That tool is dbus-viewer, which uses the glib bindings. So the picture shows interoperability at its best.

    thiago's picture

    You don't seem too much

    You don't seem too much concerned about the fact that you can do this now. Or the fact that it has been possible to do it in DCOP for the past 4 years.

    I'm not adding any functionality: I'm porting the existing functionality to D-BUS.

    Comment viewing options

    Select your preferred way to display the comments and click "Save settings" to activate your changes.