About
=====

This is a modified version of the KDE taskbar, and taskmanager library.
The main change is to preserve the position of tasks and launchers. e.g.
when a launcher is activated, the resultant task item appears in the same place
in the taskbar as the launcher did.

Synced-with KDE/master as of 10th Nov 2011 20:00



Differences To KDE Taskbar
==========================

 1. Show only icons (no text) in taskbar.
 2. When a launcher is activated, place the task's taskbar entry at the
    same location as the launcher.
 3. Tasks with no associated launcher, are placed after launcher tasks
    (unless alphabetically sorted).
 4. Always group tasks.
 5. Only allow launchers for items with .desktop files
 6. Add a dialog to manually set the association from a window to a
    .desktop file - so that launcher can be created.
 7. Add option to activate/iconify whole group when left button is pressed
    (taken from SmoothTasks). If disabled, then present windows is used
    for the group.
 8. Use oxygen '+' icon to indicate a collpased group.
 9. Use middle button to launch new instance of a task.
10. Attempt to place start-up spinner over launcher/task.
11. Add option to always use the launcher icon for taskbar entry - even
    when app is active. This works-around the issue where some applications
    (e.g. LibreOffice) have a different launcher/menu icon than the actual
    app uses.
12. Workaround an issue with a tasks attention state.
13. More tasks shown in tooltips.
14. Close tasks via tooltips.
15. Show right-click menu for task in tooltips.
16. Option to show job progress over task icon.
17. Support for DockManager plugins.
18. Unity API support.
19. Add back/play/next buttons to tooltips for media players.
20. Show recent documents in popup menu



Installation
============

To build and install:

1. mkdir build
2. cd build
3. cmake .. -DCMAKE_INSTALL_PREFIX=`kde4-config --prefix`
4. make
5. sudo make install

The following may als be passed to cmake:

    -DICON_TASKS_SHOW_DROP_INDICATOR_FOR_MOVE=true
        When moving tasks/launchers, show the drop indicator to indicate where
        the item will be moved to - as opposed to moving the item istantly.
        May help on slow machines.


Matching Windows to Launchers
=============================
Icon tasks attempts to match a window to a launcher by comapring its WM_CLASS
name to the DesktopEntryName, StartupWMClass, and Name. If this fails, it then
attempts to compare the applications commandline with the Exec line from the
.desktop file - this is compared using; complete commandline, complete
commandline without path, commandline without arguments, and finally the
commandline without path or arguments.

This can *still* fail - and in these cases you will be prompted to select the
application from the list of installed apps.

---
As an aside, you can see the keys used by IconTasks for your installed
applications, by running the following in a konsole window (all on one line):

ktraderclient --servicetype Application --constraint "exist Exec" | egrep "(DesktopEntryName|StartupWMClass|Name|Exec)"
--

taskmanagerrulesrc
-------------
IconTasks ships a file named taskmanagerrulesrc (which is installed to 
/usr/share/kde4/config/) This file can be used to control some of this matching.

The "Mapping" section contains a list of WM_CLASS to 'Name' or .desktop file 
mappings. e.g. libreoffice-writer is mappeed to the application name 
'LibreOffice Writer

The "Settings" sections has two keys that influence the automatic mapping.
"ManualOnly" contains a list of WM_CLASS names that will cause the user to
*always* be prompted to select the application - as IconTasks cannot
automatically do this. This is set by default to contain "Wine", as wine sets
the WM_CLASS of all its windows to "Wine". However, it also sets the className
part to the windows executable name. So, when IconTasks prompts you to manually
select the launcher, it will save the mapping as (e.g.) 
Wine::notepade.exe=/usr/share/applications/wine/notepad.desktop

Some applications are even worse, and all parts of WM_CLASS are the same.
If these apps use different commandline's then this can be used to
differentiate the instances. One such example is VirtualBox. If you have
manually created launchers for each virtual machine, and these have an
Exec line such as - "Exec=VirtualBox --startvm KUbuntu" - the each instance
can be determined via the commanline. Therefore, its is preferable in these
circumstances if the commandline is cehcked *before* the other checks above.
To accomodate this, IconTasks has the "MatchCommandLineFirst" key in the
"Settings" section.



Media Player Control Buttons
============================
To control media players, IconTasks uses the MPRIS dbus API. Each media player
has a unique DBUS MPRIS service name - org.mpris.MediaPlayer2.NAME (where NAME
is amarok for Amarok) - or org.mpris.NAME (for the older v1 MPRIS spec)

IconTasks needs to map from a task to a MPRIS service - in order to know which
tooltip to display the controls in!

First of all, IconTasks queries the KDE system configuration cache (ksycoca)
to obtain the list of apps in the 'AudioVideo' and 'Music' categories.

---
As an aside, you can see the list of AudioVideo/Music apps installed by running
the following in a konsole window (all on one line):

ktraderclient --servicetype Application --constraint "exist Exec and (exist Categories and ( ('AudioVideo' ~subin Categories) or ('Music' ~subin Categories) ) )" | grep DesktopEntryName
---

Each time you hover over a task/launcher icon, IconTasks checks whether the
item is within this list of apps. If it is, it attempts to map from the app
to an MPRIS service.

To do this mapping, IconTasks takes the wmClass (or desktop filename, if wmClass
cannot be ascertained), and queries whether there is an MPRIS dbus service
of that name running. It queries the following:

    org.mpris.MediaPlayer2.NAME
    org.mpris.MediaPlayer2.NAME.PID
    org.mpris.MediaPlayer2.NAME-PID
    org.mpris.NAME
    org.mpris.NAME.PID
    org.mpris.NAME-PID

The first to match is used. (In this way if an app has both MPRIS v2 and v1, 
then v2 is preferred). If a match is found, then the mapping of app to service
is saved - so that subsquent queries do not have to repeat the process.

It is possible that the MPRIS service name for an app is not related to its
wmClass or desktop filename. In this case IconTasks needs to be informed of the
wmClass to MPRIS service mapping. For this IconTasks supplies a file named
'mediabuttonsrc' which contains (e.g.):

    [Aliases]
    mpd=qmpdclient,sonata

This instructs IconTasks that the window with class name 'sonata' can be used to
control the MPRIS dbus service org.mpris.MediaPlayer2.mpd

If IconTasks fails to match a taskbar entry to an MPRIS service, please perform
the following:

1. Start the media player.

2. In a konsole window, run the following (when the player has started):

    qdbus | grep -i "org.mpris"

3. Again, in the konsole window, type the following:

    xprop | grep WM_CLASS | awk '{print $4}'

   - Now when the mouse pointer changes to a '+', click over the media player
     window. The value returned (in quotes) is the wmClass of the window.

4. You now need to determine which of the values returned in step 2 is for
   your media player (with any luck there will be only one!)

5. Edit mediabuttonsrc (either the global one (/usr/share/kde4/apps/plasma-icontasks/mediabuttonsrc)
   or your personal copy (~/.kde/share/apps/plasma-icontasks/mediabuttonsrc)
   and add an entry in the "Aliases" section. (You also need to remove any PID
   from the MRPIS name). e.g. for the following:

   App=MyMediaPlayer
   MPRIS=org.mpris.MediaPlayer2.thePlayer-1234
   WM_CLASS=ThePlayerWindow

   You would have:

   thePlayer=ThePlayerWindow


If you send me the above details, I can add the alias to the mediabuttonsrc
shipped with IconTasks - so that all users can be updated.


DockManager API
===============

DockManager plugins connect running applications to taskbar entries by querying
the .desktop filename. To display the .desktop filenames of the current dock
manager items, type the following in a konsole window:

    for item in `qdbus org.kde.plasma-desktop | grep "/net/launchpad/DockManager/Item"` ; do qdbus org.kde.plasma-desktop $item DesktopFile; done


Unity API
=========

To test the Unity API support of IconTasks, save the following to unity.cpp

--------------------8<---------------------------

#include <QtDBus/QtDBus>
#include <QtCore/QtCore>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qDebug() << "REGISTER:" << QDBusConnection::sessionBus().registerService("org.kde.test");
    QDBusMessage msg=QDBusMessage::createSignal("/Wibble", "com.canonical.Unity.LauncherEntry", "Update");
    QList<QVariant> msgArgs;
    QMap<QString, QVariant> props;
    props["count-visible"]=true;
    props["count"]=(unsigned int)22;
    props["progress-visible"]=true;
    props["progress"]=(double)0.75;
    msgArgs.append("application://firefox.desktop");
    msgArgs.append(props);
    msg.setArguments(msgArgs);
    qDebug() << "SEND:" << QDBusConnection::sessionBus().send(msg);
    return a.exec();
}

--------------------8<---------------------------

Compile with: g++ unity.cpp -o unity -lQtDBus -lQtCore -I/usr/include/qt4
(May need to change /usr/include/qt4 to wherever your Qt4 headers are installed)

Start firefox (as this is where our fake message will pretend to be from), then run
test app: ./unity

You should now see "22" appear over the IconTasks Firefox icon.

The test app can be terminated with CTRL-C in the konsole. When the test app
terminates, the "22" will disappear from the Firefox icon.
