An attempt at solving KControl's usability problems..
Frans Englich
frans.englich at telia.com
Sun Jan 25 17:27:25 GMT 2004
On kde-usability I laid a proposal a couple of weeks ago for solving
KControl's usability and maintenance problems. AFAICT it still needs to be
shot down(explaining why it's a bad idea), and if that's not the case -
embrasement. Basically, it needs a thorough review and feedback, especially
since it's pretty invasive, affecting large parts of KDE.
The best way to get a grip on the proposal is to read this thread:
http://lists.kde.org/?l=kde-usability&m=107352838517059&w=2
but instead of the files attached to that thread read the updated file
attached to this mail. (That is KCM_CONVENTIONS)
Attached KCM_HOWTO is an update of kdebase/kcontrol/HOWTO, needs a review and
some opinions.
In contrast to what the thread says, KCM_HOWTO and KCM_CONVENTIONS is probably
best located on dev.kde.org.
Attached TODO could also be of interest - gives a indicator of what
suggestions is circulating. (opinions very welcome)
Cheers,
Frans
-------------- next part --------------
Copyright (C) 2004 Frans Englich <frans.englich at telia.com>.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
Texts. A copy of the license is included in the section entitled "GNU
Free Documentation License".
PLEASE NOTE: This is a draft so don't jump in your chair if something
is unreasonable. But please tell the authors(kde-usability) if they are
unreasonable. Otherwise you will really have to jump in your chair.
This file describes the organisational layout and file structure for KDE's
KCMs(KControl Modules) as well as design recommendations and conventions
used.
Writing KCMs is covered in KCM_HOWTO.
These guidelines assumes a basic understanding of the technical side of
Kcontrol and KCMs. This is covered in the KCM_HOWTO, which really should be read before this
document. In case it does not cover your wondering, drop a line on kde-usability.
KControl, but most notable all the KCMs have had major problems, the
usability aspect have been critical, large parts of the code have been
half baked and poorly maintained as well as the development of the
approximately 70 KCMs have been framented with no coordination.
These guidelines exists in the hope to correct these problems. It establishes
guidelines and polices ranging from usability, such as naming and layout, to
how to arange code and name files, in order to make life easier for
the developers as well as promoting usability and code quality.
In order for this to succeed, these guidelines must be followed. But, it should
not be foolishd followed, for example the naming recommendations is just
recommendations, in case the name must be a little longer than average in
order to be informative that is of course OK.
If there's an interest to not adhere to these guidelines the right way is not
to just ignore the guidelines and go hacking away in an own style - KDE is a
community project. As soon there is a case not covered in this guide, or the
guidelines seemes to simply be wrong the issue should be raised on the
mailinglist kde-usability so your idea can be peer reviewed and discussed,
and these guidelines changed accordingly. As soon as
you look at other KCMs in order to see how they behave or have solved
a problem it probably means these guidelines have not covered that area and
must be completed - raise the issue on kde-usability.
Suggestions and most of all questions, regarding these guidelines is very much
appreciated, don't hesitate to to drop a line on kde-usability. Of course, don't
edit this document, except for obvious typos without having reached consensus and
agreement with other KDE developers.
If you need to get in contact with the maintainer for a particular KCM, that
information can be obtained from PACKAGE/KCMs/README, where PACKAGE is the
relevant KDE module, for example kdemultimedia. There you will also find
information specific for that module's KCMs, such as design policies specific for
that module.
A good KCM to study which follows these guidelines correctly can be found in
TODO :P
--- Directory Layout and Filename Conventions ---
In each KDE package which contains KCMs(for example kdenetwork)
a top directory named "KCMs" exists which contains everything related to
the KCM's for that package, regardless of what application or
functionality the KCM represents.
Each "KCMs" directory contains a README file where the maintainers for the
KCMs is listed as well as other information specific information for
that package's KCMs. For KCMs and their associated files a
set of filename conventions exists:
* All the KCM's files resides in a sub directory of "KCMs". The
name of that directory is the same as X-KDE-Library for that module.
Ie, if a KCM's desktop file contains "X-KDE-Library=kmix" all its
files resides in "KCMs/kmix/".
* The name of the desktop file is the KCM's library name prefixed
with "kcm_". All lower case. For example "kcm_kmix.desktop".
* For compability reasons the old .desktop file(if any) must be kept
as well as being installed. It goes fine to have two. In the next major
KDE release the compability .desktop file will be removed. <!-- KDE4 -->
* If the KCM has an specific icon its basename should be
the same as the library name prefixed with "kcm_". All lowercase.
* The main source file(containing the KCModule subclass) and its header
must be named "main.cpp" and "main.h", respectively.
* The name of the .kcfg file shall be the name of the library name.
All lowercase. For example, "kmix.kcfg".
* The name of the .kcfgc file must be the name of the library name.
All lowercase. For example, "kmix.kcfgc".
* The name of the .ui file for the main widget(the KCM) shall be named
"main_widget.ui".
* All C++ files should have the extension ".cpp" and ".h", respectively.
* If the main widget in main_widget.ui must be sub
classed, it should reside in "main_widget_impl.h" and
"main_widget_impl.cpp", respectively.
* The name of the KCModule subclass should be the library name prepended
with "KCM" and with the usual capitalization of key letters. For example,
if the library name is "useraccount" the classname would be "KCMUserAccount".
--- Broad Design Hints ---
Keep the following in mind when adding or modifying existing KCMs:
* The content of an KCM may not be, from the user's point of view,
application specific. KControl's purpose is to in a central place
provide configuration for functionality which is global for KDE.
Keeping application specific configuration in KControl simply makes
it too big and bloated(people have already tried this). Technically,
the functionality the KCM represents can be an application or isolated
and separated but that is irrelevant - it is about how the users percepts
and sees it, not how it is implemented.
* We don't want configuration. In a perfect world the default settings
fits everyone and the hardware Just Works. This is not the case so
we have KControl.
But that is no reason to have unnecessary options and
bloat in a KCM. For every configuration option you could ask: Is this
option really, really necessary? Does a significant part of KDE's users need
it? Was it implemented because it was a "cool" feature and fun to do? Does
other KCMs have similar options which could be combined into a global
one? Could the implementation be changed so the user does not have to take
the (configuration) decision?
The one with the simplest, and smallest amount of config options wins. Assuming
functionality is sustained as well as it means usability is actually improved,
of course.
* Don't make a KCM available in several places. For example, don't have an
entry in one category while having the same KCM available as a tab in another
KCM. A bogus reason to doing this is it allows the user to access the
functionality in different ways(a well established UI design principle). This is
a bogus reason because from the user's perspective it
is not percepted as different ways of accessing one unit of functionality - it
appears as a doubled amount of options. In short, to the user the functionality
in the two(or more..) places is not percepted as identical but different and thus confusing.
If you feel a need of doing this, it is an alarm bell for something is wrong. Perhaps
you need to split up the functionality in different KCMs? Is the Name wrong? Perhaps even
the top level categories are wrong. In either case, discussing it on kde-usability
is a good idea.
*
* Navigating with KControl among the KCM's is hard because it is monotone, all the
KCM's looks roughly the same and involves the same widgets - it is hard distinguishing
the different KCM's from each other. One way to counteract this is to personalize them
and give them an individual touch so they easier puts a print in the user's memory.
This can be accomplished by adding images, with relevant, easily associated motives.
Images also gives an opportunity to affect the user emotionally. For example,
if the the content is highly technical the image can be used to bring an feeling
of confidence and assurance to the user. It could also lead in the opposite direction -
steal focus and be distracting(especially if the image affects emotionally). The
design and use of images needs deep consideration, in either case.
--- A Valid KCM ---
In order for an KCM to be good and valid it must conform to:
1) KDE Licensing Policy. Basically, a OSI approved license
as well as correct license and copyright headers. For details see:
http://developer.kde.org/policies/licensepolicy.html
2) KDE User Interface Guidelines. Please see:
http://developer.kde.org/documentation/standards/kde/style/basics/index.html
3) The conventions and recommendations in this file.
4) A valid .desktop file. If you are not 110% sure of what you're doing,
validate with freedesktop's desktop-file-utils:
http://www.freedesktop.org/Software/desktop-file-utils
If the KCM does not conform, it is considered a broken KCM.
--- Words and Phrases ---
When picking or changing a name(that is the Name directive in TODO rephrase
the .desktop file) for a KCM it is good idea keeping the
following issues in mind in order to promote usability and
consistency between the modules:
When picking phrases for the Name and Categories .desktop directives as well
as other texts for the KCM, the following issues must be kept in mind:
* Try to keep the phrase short. Shorter phrases is easier and
faster to interpret and give better options for designing the layout.
From a esthetically perspective it also looks cleaner and simpler.
* Avoid complex phrases involving backslashes("/)" and paranteses
for the same reasons as above. It also makes translations more
accurate.
* Use "Monitor" instead of "Display". The main reason is simply
consistency but Monitor is preferred because it is not a verb
(easier to translate and non ambiguous) as well as it more directly refers to
physical Monitor - the word Display has more denotations. A negative
side is that people tends to associate with "old" CRT monitors,
while there now a days exists exists all kind of fancy stuff
like TFT screens. For some users this does not cause a problem. I for
example, are well aware of that those nifty things only exists in my
imagination.
* Generally speaking, use "Hardware" instead of "Peripherals". Hardware
is less technical and not as abstract as Peripherals. Everything
classified as Peripherals also classifies as Hardware, and thus the
substitution can't be misinforming, although possible vague(but that can also be
a good thing). There is strictly speaking cases where Peripherals
is more semantically correct but the usability aspect of the choice
must be deeply considered.
* Avoid including words like "Management" and "Configuration" etc.
since it is abundant - KControl is all about that, which the user
already is aware of. Furthermore, such terms does not inform the
user about what your module contains, except that it is for
configuration or management(and that is already clear since it is
in KControl).
Another reason is that it makes it more cumbersome for the user to
find what he/she wants. For example, if the user looks for monitor
settings the word "monitor" is looked for, not "settings". Thus,
the phrase "Monitor" can look incomplete and half baked compared to
"monitor Settings" but actually fullfills its purpose better than the
latter.
Another example, pick "Sony Vaio Laptop" in front of "Sony Vaio Laptop
Hardware Configuration" since the user already knows it's about
Configuration and Hardware.
* KControl as the rest of KDE targets a wide audience where a
majority(to say the least) of the users does not have technical
expertise. In order to have a compelling interface it is important
to avoid technical and "scary" terms. The goal is to reach the user and
communicate successfully - that is not succeeded by using words
the user does not understand.
--- Selecting a Category ---
TODO Document the different categories and provide information about when to
choose category A in front of B, etc.
TODO Some guideline specifying how to classify, ie. should the energy/power settings
reside under a "Power Control" toplevel entry or under "Hardware/Monitor"?
X-KDE-settings-looknfeel Appearance & Themes
X-KDE-settings-desktop Desktop
X-KDE-settings-network Internet & Network
X-KDE-settings-webbrowsing Web Browser
(submenu of Internet & Network)
X-KDE-settings-components KDE Components
X-KDE-settings-peripherals Peripherals
X-KDE-settings-power Power Control
X-KDE-settings-accessibility Regional & Accessibility
X-KDE-settings-security Security & Privacy
X-KDE-settings-sound Sound & Multimedia
X-KDE-settings-system System & Administration
As of rule of thumb, it is a good idea ensuring each category stays around 5
entries(KCMs) each. It is also preferred to have roughly the same amount in each
category. This makes it easier to use different KControl layouts as well as each
"portion" is not too big to interpret and makes it easier to remember. This should
be taken lightly, but can be good to keep in mind when case otherwise is "tie". As
a side note, this has nothing to do with Millers's 7+-2 theory.
--- Technical Recommendations ---
When building a new KCM or improving an old one, a set of
KDE technologies is preferred in front of others:
* Use .ui files instead of handcrafted
Graphical user interfaces designed with QT Designer is preferred
instead of handwritten ones because 1) It allows people without
C++ experience to modify GUIs; 2) It is safer since it is not
manually written code; 3) It allows more obtrusive changes to be
done in code freezes; and 4) Faster development.
* KConfigXT framework instead of handcrafted configuration code
The rationalis is similar to the above with notable addition: It
saves disk space on installed clients.
--- Breif History ---
This structuring of KCMs and the policies were started around the
release of KDE 3.1 since the KControl/KCM situation had been unbearable
since KDE 3.0. Some fresh thinking was needed.
-------------- next part --------------
Copyright (C) 2003 Daniel Molkentin <molketin at kde.org>
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
Texts. A copy of the license is included in the section entitled "GNU
Free Documentation License".
The KDE Control Center
======================
Author: Daniel Molkentin <molkentin at kde.org>
The author of this document, as well as the person
you should redirect your questions to, if this document
does not answer them.
This file describes how to write KControl Modules(KCMs).
Please also read KCM_CONVENTIONS before modifying or writing
KCMs since it contains guidelines and design rules which must be
followed.
The KDE Control Center is a central application that allows a
user to:
a) change user specific settings
b) change KDE specific system settings
c) change system settings
The functionality is provided by a great number of KControl
Modules that are embedded into a framework application
called "kcontrol".
How to write a KControl Module
------------------------------
The mechanism to implement kcontrol modules changed quite a bit since
KDE 2.0. In KDE 1.x the modules have been implemented as separate
processes that were swallowed into the control center. This had several
advantages, as well as disadvantages:
+ modules could run standalone
+ broken modules (segfaulting) left the framework untouched
- focus handling was hard to achive
- layout management was a pain
- communication between modules and framework was inefficient
To overcome the problems, modules from KDE 2.0 on are implemented as
simple shared libraries that are loaded, at runtime, into the process
of the frame application. This solves all of the disadvantages.
To allow modules to run "standalone", there is a wrapper application
"kcmshell". What is left is the problem of segfaulting modules; the
solution is simple: don't let your modules segfault! :-)
Now to the practical side of things: Modules have to inherit from the
class KCModule, defined in kcmodule.h, which is part of kdeui.
This class defines some important functions that are used in the
communication between framework and module:
virtual void load();
This method is invoked whenever the module should read its configuration
(most of the times from a config file) and update the user interface.
This happens when the user clicks the "Reset" button in the control
center, to undo all of his changes and restore the currently valid
settings. NOTE that this is not called after the modules is loaded,
so you probably want to call this method in the constructor.
virtual void save();
You might have guessed it: this function gets called when the user
wants to save the settings in the user interface, updating the
config files or wherever the configuration is stored.
The method is called when the user clicks "Apply" or "Ok".
virtual void defaults();
This function is called to set the settings in the module to sensible
default values. It gets called when hitting the "Defaults" button.
The default values should probably be the same as the ones the
application uses when started without a config file.
int buttons();
The control center calls this function to decide which buttons should
be displayed. For example, it does not make sense to display an "Apply"
button for one of the information modules. The value returned can
be set by modules using setButtons. E.g.
setButtons(KCModule::Ok|KCModule::Help);
will make sure that only the "Ok" and the "Help" button is enabled.
There is also a signal used by the modules:
void changed(bool state);
This signal should be emitted whenever the state of the modules changes.
"state" is true, if the contents of the modules differ from the ones in
the current configuration, "false" otherwise. For example, if the user
changes a value, you emit "changed(true)". When the user reloads the
systems settings, emit "changed(false)". The control center uses
this signal to keep track about unsaved changes in certain modules.
How to make a module available?
-------------------------------
Ok, now that you have implemented your class with the module, you
must make sure it can be accessed from the control center.
To achieve this, the preferred way since KDE 3.0 is to simply use
KGenericFactory. Don't forget to #include <kgenericfactory.h>.
typedef KGenericFactory<MyKCModule, QWidget> KDEDFactory;
K_EXPORT_COMPONENT_FACTORY( kcm_xyz, KDEDFactory( "kcmxyz" ) );
If you get errors, make sure that the constructor of your derived class
equals the one of the KCModule baseclass (yes, the QStringList argument
matters).
If you need to export more than one module per library, you have to use the
old loader. That is, you need to create a function like this:
extern "C"
{
KCModule *create_xyz(QWidget *parent, const char *name)
{
return new XYZ(parent, name); // XYZ inherits from KCModule
};
}
This function and the implementation of the module is then compiled
as a shared library. If the name of your modules is 'xyz', the
name of the library should be
kcm_xyz(.la|.so)
and should be installed into $KDEDIR/lib/kde3. (Ok, beat me for the KDEDIR,
but you all know what I mean, don't you? :)
Use "kde_module_LTLIBRARIES = kcm_xyz.la" for that in your Makefile.am.
Don't call it libkcm_xyz as that is deprecated since KDE 3.0.
Further issues regarding Makefile.am writing is hopefully covered in the
Makefile.am HOWTO:
http://developer.kde.org/documentation/other/makefile_am_howto.html
Initialize things on startup
----------------------------
If your module needs to initialize things on startup, you must have a
construct like:
extern "C"
{
KCModule *init_xyz(QWidget *parent, const char *name)
{
// to startup stuff here
};
}
Don't forget to add X-KDE-Init to your desktop file! (see next chapter)
The .desktop entry
------------------
To make the control center find the module, it needs a .desktop
entry. This has to be placed under:
$KDEDIR/applnk/Settings/...
so put it in kdebase/applnk/Settings... to have it installed.
It could be a good idea to know the basics of the .desktop standard.
It is very easy to read and quite short:
http://www.freedesktop.org/Standards/desktop-entry-spec
A KCM's .desktop file supports the following .desktop directives:
X-KDE-Library
This is the name of the library, without the kcm_ prefix.
So in the example, the library name would be "xyz".
X-KDE-FactoryName
This entry can be used to set the name of the factory
function in the library. Usually, this is the same as
the Library, but if you want to have more than
one module in one library, you need this entry.
To make it clear, if you have several KCMs in one library
you will need a .desktop file for each KCM.
For example, if you have a library named
kcm_frog.la
with two modules, named "kermit" and "quak", you would
have
X-KDE-Library=frog
X-KDE-FactoryName=kermit
in one of the .desktop files, and in the other
X-KDE-Library=frog
X-KDE-FactoryName=quak
The control center would then call the "create_kermit" and
"create_quak" functions respectively.
X-KDE-RootOnly
If this is set to "true", the module must be executed
with root permissions. The control center will then show
the module in greyed-out (disabled) state with a warning
until the "modify" button is pressed which allows running
the module in an root environment using kdesu and QXEmbed.
X-KDE-ParentApp
This one should be set to "kcontrol" and tells what KSycocaGroup
the module will belong to. Eg., there is a sycoca group called kcontrol
which all KCM's(since they have a "X-KDE-ParentApp=kcontrol") belongs
to which KControl then can look up in order to list all modules.
X-KDE-Init
If the module has to perform some action at system startup,
use this entry to build the name of a function to call.
if X-KDE-Init is "bell", for example, the function
"init_bell" is called in the library indicated by
X-KDE-Library.
NoDisplay
If this is set to true the module will not show up in
kcontrol or when viewed with kcmshell. This is usable when
you need to do something at startup(X-KDE-Init etc.) but
don't want the module to show up in kcontrol, eg. the module
has no GUI.
Name
This is 'labels' for the KCMs and fill the nodes in the three
view. Please see KCM_CONVENTIONS on how to pick
a good Name.
Comment
This directive shows up in the main area in KControl if you
select a top node in the three view. See the same section as for
Name in KCM_CONVENTIONS for how to pick a good phrase.
Categories
This describes where the KCM should be put in KControl's
navigation. It should look like "Categories=QT;KDE;X;" where
X is the category. A list of available categories, as well as
which one to choose is found in KCM_CONVENTIONS.
Icon
Specifies the icon for the module.
Exec/Type
These two should say "Exec=kcmshell dir/file" and
"Type=Application". If you run the KCM from its .desktop
file, as opposed to KControl these two directives tells
KDE what to do.
Keywords
A semi colon separated list containing words/phrases
KControl's search tab should trigger on.
To summarize, a valid .desktop file must contain these entries:
* Name
* Comment
* Icon
* Exec=kcmshell dir/file // Replace dir/file
* Type=Application
* Categories=QT;KDE;X; // Replace X
* Keywords
* X-KDE-Library
* X-KDE-ParentApp=kcontrol
The following directives are optional:
* X-KDE-Init
* NoDisplay
* X-KDE-Root-Only
* X-KDE-Factory-Name
* DocPath TODO
Any other directives(except the translator's :) can safely be
removed, since they most ikely are abundant or are left over's
from old KDE versions. For example, X-ModuleType was relevant
for KDE 2.0 but not in any new versions.
What else do I need?
--------------------
There are a number of additional things for convenience.
- kcmshell
Consider you want to run a module standalone, without the control
center. You can no longer call the module, as it is a library
now. Instead, call "kcmshell module". For example, to get the
font and the desktop color settings, use
kcmshell fonts colors
If kcmshell for some reason couldn't load on of the modules, it will
silently be ignored. <!--TODO: Do we really want that behavior? :)) -->
- multiple instances of kcontrol
With the new control center, it is no longer possible to have multiple
instances in the control center.
- KCDialog
Sometimes, you may want to reuse your control center modules
inside an application. There are two ways to accomplish this:
a) call "kcmshell modules"
to run the module as a separate program.
b) use "KCMultiDialog" (in kdelibs/kutils)
This is a simple dialog that can show an abitrary number of modules
in a normal KDialogBase.
The advantage is that you can control the behaviour and the results
much easier that with a separate process. And as your module is a
simple library, you can just link to it anyway.
Debugging your module
---------------------
You can attach gdb, valgrind or whatever to kcmshell <yourmodule> to track
down leaks or crashes. If you need to trace it down inside kcontrol, make
sure you pass --nofork to kontrol on startup. Anyway, you really want to use
kcmshell for debugging as long as your debugging does not involve debugging bad
interaction with the kcontrol framework itself.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: TODO
Type: text/x-c++src
Size: 6745 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/kde-core-devel/attachments/20040125/d1737016/attachment.c>
More information about the kde-core-devel
mailing list