KUniqueApplication
Introduction
Do not use this class any more - it has been superceeded by a similar class with a confusingly
similar name in KDE2
This page is intended to introduce KUniqueApplication - a class
derived from KDE's KApplication - when used in place of KApplication
only one instance of a program (per user) is allowed to exist in a KDE system.
Also implemented is a small message passing protocol that allows a non-primary
application (ie one that discovers that there's already a copy of itself running)
to easily send a message to the primary.
For example you can tell a program to open a particular file, or to open a
new window or to perform a chosen action. Then put the action into a .kdelnk
and then maybe drag it to your panel as abutton (to maybe open a blank
document or something)
Files
Implementation code
And some sample code for using the class - this is the standard kless
from kdesdk changed so that only one copy can run - the message sent to the
primary application is displayed whenever it is received. By default
the application sends null messages but youcan use the '-U' flag to choose
which message to send - ie 'kless -U "hello world"'
Documentation
This is a derived class of KApplication - the only difference is that
no more than one KApplication of this type per user
may be running (type is defined by kapp->appName()).
It can be used two ways:
- Simply replace the instantiation of your KApplication object
with a definition of KUniqueApplication instead - in this case
your program will quietly exit if an existing application
is running - if one isn't running the creation of the
object will return cleanly
- the same as above but also pass in a 'message' - a string
that is passed to the primary instance of the app (case 1 above
acts as if you pass in a message value of "") - in this case a message is passed to
the primary application instance telling it that another application
tried to start up - the string value is passed as part
of this message
When should I use KUniqueApplication
From a programmer's perspective the obvious place is where there's
some object or data base which must be locked.
However a better way of looking at this problem is to think about how
your user thinks about the application - is it one thing (like their mail box)
or several (like documents being edited) - if it looks like one thing
then KUniqueApplication probably provides the expected behavior - if it's
several it may be that you should implement your application as several
cooperating programs (ie solve your locking problems otherwise. (a good
example of this is kfm vs. netscape - netscape's windows are all interrelated
and it behaves like one application while kfm's behave independantly)
Hooking the messages
The KUniqueApplication class has a single public signal, if you
connect to it your slot will get called with the signal code
every time another application attempts to be created and
your application is the primary instance
void uniqueCalled(char *message);
Messages
The messages are null terminated strings - they are limited to 255
characters by the message passing protocol.
Their contents and measnings are up to you to define - however the following
are reccomended:
- "" - null code - probably switches the application to the current
screen and brings it to the fore
- "--new" - 'new' create a new empty document and open it on the current screen
Example
Imagine a mail program - two usefull instances might be checking for
mail (triggered by clocking on KBiff in the dock which in turn executes
a 'mail --check' and 'mail --new' which opens the mail application and
pops up a new empty mail message ready to write - 'mail --new' might
be contained in a style-sheet .kdelnk one which when clocked on results
in a new message window being opened (now you can drag the new mail style-sheet
to the dock and have a 'create mail' button)
Normally you might process the program args something like:
for (i = 1; i <= argc; i++)
if (strcmp(argv[i], "--new") == 0) newflg = 1; else
if (strcmp(argv[i], "--check") == 0) chkflg = 1;
etc
app = new KApplication(argv, argv, "mail");
mail = new Mail();
if (newflg) mail->new();
if (chkflg) mail->chk();
mail->showbrowser();
'Uniquifying' the app and implementing passing 'new' and 'check' as messages would result in:
char *message = "";
for (i = 1; i <= argc; i++)
if (strcmp(argv[i], "--new") == 0) {
newflg = 1
message = argv[i];
} else
if (strcmp(argv[i], "--check") == 0)
chkflg = 1;
message = argv[i];
} else
etc
app = new KUniqueApplication(message, argv, argv, "mail");
mail = new Mail();
if (newflg) mail->new();
if (chkflg) mail->chk();
mail->showbrowser();
QObject::connect(app, SIGNAL(uniqueCalled(char *)), mail, SLOT(uniqueMessage(char *)));
The only difference here being using the KUniqueApplication class, passing a code
indicating the flag to it, and connecting a slot to receive the message from other
applications
In the mail class you need to register a slot:
void mail::uniqueMessage(char *message)
{
if (strcmp(message, "") == 0) {
showbrowser(); // bring it to the front
} else
if (strcmp(message, "--new") == 0) {
new(); // create a new mail window
} else
if (strcmp(message, "--check") == 0) {
chk(); // check for mail
}
}