KService also provides ways to load services by name directly with the <tt>serviceBy*</tt> set of methods, of which the safest and most recommended is <tt>serviceByStorageId</tt>:

KService also provides ways to load services by name directly with the <tt>serviceBy*</tt> set of methods, of which the safest and most recommended is <tt>serviceByStorageId</tt>:

−

<code cppqt>

+

<syntaxhighlight lang="cpp-qt">

KService::Ptr service = KService::serviceByStorageId("konqueror");

KService::Ptr service = KService::serviceByStorageId("konqueror");

−

</code>

+

</syntaxhighlight>

Note that it passed back a <tt>KService::Ptr</tt> rather than just a {{class|KService}}. A <tt>{{class|KService}}::Ptr</tt> looks, acts and behaves just like a regular pointer (<tt>{{class|KService}}*</tt>) but it is automatically memory managed. It is not necessary to manually delete <tt>KService::Ptr</tt>s, because they are reference counted.

Note that it passed back a <tt>KService::Ptr</tt> rather than just a {{class|KService}}. A <tt>{{class|KService}}::Ptr</tt> looks, acts and behaves just like a regular pointer (<tt>{{class|KService}}*</tt>) but it is automatically memory managed. It is not necessary to manually delete <tt>KService::Ptr</tt>s, because they are reference counted.

Line 69:

Line 68:

At this point we now have access to all sorts of information on the service, which in this case is an application called <tt>konqueror</tt>. We can even launch the app using this service:

At this point we now have access to all sorts of information on the service, which in this case is an application called <tt>konqueror</tt>. We can even launch the app using this service:

−

<code cppqt>

+

<syntaxhighlight lang="cpp-qt">

if (service.isApplication()) {

if (service.isApplication()) {

KUrl::List urls;

KUrl::List urls;

Line 75:

Line 74:

KRun::run(service, urls, 0);

KRun::run(service, urls, 0);

}

}

−

</code>

+

</syntaxhighlight>

This would launch <tt>konqueror</tt> and cause it to open the KDE homepage.

This would launch <tt>konqueror</tt> and cause it to open the KDE homepage.

Abstract

Services represent applications, plugins and other add-ons available on the system. They make it easy to find, launch and load the items they represent without having to hardcode any specific component or even know ahead of time what services will be available. This tutorial covers what the services system provides and where the information is stored.

Advantages of Using Services

There are three main advantages to using services:

it's simple

it's future proof

it's flexible

Whenever your application needs to launch another desktop application, find available applications, load plugins or find application add-ons it's as simple as a few lines of code to do so and the code is quite similar regardless of what you are looking for.

Since most of the details involved in looking up services are hidden away from your application, if things change either due to time and new standards or platform specific features your code will continue to work. For instance, when KDE implemented the freedesktop.org specification for describing application launcher menu structures, application code that had been functioning previous to this continued to function without any changes or even a recompile.

Best of all, the services system provides a flexible system under the hood for users and administrators to be able to customize, add new entries, remove existing items and even lock down access without putting any burden of complexity on application developers.

Classes At A Glance

The main services related classes that applications are likely to use are generally limited to the following two:

KServiceTypeTrader: allows discovery of available services through a simple query language; this class and the query language is covered in detail in the next tutorial

Other classes that are available but less often used by applications include:

KServiceOffer: provides information on user preference for a given service; primarly used for mimetypes

KServiceType: provides access to information about a given type of service

KServiceTypeProfile: represents the user's preferences between multiple services of the same type; this is used internally by KServiceTypeTrader

KService

The KService class is at the center of the services system. It serves both an informational and a functional role. KService provides access to details on a given service such as whether it is an application, the name of the service, the associated icon (if any), etc. But it can also be used to launch applications and load plugins from disk.

KService also provides ways to load services by name directly with the serviceBy* set of methods, of which the safest and most recommended is serviceByStorageId:

KService::Ptrservice=KService::serviceByStorageId("konqueror");

Note that it passed back a KService::Ptr rather than just a KService. A KService::Ptr looks, acts and behaves just like a regular pointer (KService*) but it is automatically memory managed. It is not necessary to manually delete KService::Ptrs, because they are reference counted.

A list of all services can be retrieved using the KService::allServices method. Of course, one often wants finer grained control over locating services, which is the role of the KServiceTypeTrader and is the topic of the next tutorial in this series.

At this point we now have access to all sorts of information on the service, which in this case is an application called konqueror. We can even launch the app using this service:

Registering Services

Services are represented on disk as individual .desktop files. This makes it easy to add, remove, and customize services on the system. The .desktop files are organized by their type of service. Applications, plugins, protocols, and mimetypes are each kept in their own directories. The location of these directories is documented in the KDE Filesystem Hierarchy page. Installation is usually automated through the build system, such as CMake in KDE4.

Services may also have one or more "service types" that are used to categorize and search for them. While applications and mimetypes don't utilize this, plugins and other services do. These service types are registered by placing a .desktop file describing the service type in the correct location in the filesystem, usually share/kde4/servicetypes. See the KDE Filesystem Hierarchy page for more information.

SyCoCa: The System Configuration Cache

While the .desktop (file) method is very handy for users (and adding new entries), performance could be an issue because it is common to have thousands of these files describing various mimetypes, applications, plugins, screensavers, etc. Thus, the entries are put into a binary cache which is accessed via shared memory by all applications. The cache is known as the System Configuration Cache, or SyCoCa for short. Loading and locating KServices is done via this cache, transparently to the application.

Whenever a new .desktop file is added, removed or altered, the cache is automatically updated by the kbuildsycoca4 application. You can force an update of the cache by running kbuildsycoca4 manually, though usually it is launched by kded4 automatically when needed. A full rebuild of the cache (versus a simple update) can be triggered by passing --noincremental to kbuildsycoca4.