KSystemTray: The saga continues...

Martijn Klingens klingens at kde.org
Sat Apr 13 16:33:18 BST 2002


... and we need help :-)

I talked with Simon about the KSystemTray problem on IRC and we're not sure 
how to fix the problem.

In case you haven't read the previous thread, the problem is basically that 
closing the main window of a systray app shouldn't quit the entire 
application, but instead should make it live on in the tray. This is what the 
style guide sais, and it is what the user would expect as well.

That can be solved by making the closeEvent() of the window call hide() 
instead of close(). And there KSystemTray kicks in: the quit action from the 
tray context menu just attempts to close all windows, assuming that would 
automatically quit the app if no background processes like KIO jobs need to 
be done.

Once the closeEvent does a hide() that no longer works. If the tray calls 
kapp->quit directly the background KIO case would stop to work. Whatever we 
could think of, either of those cases will be broken.

Below is the IRC communication that we had. All ideas that we considered are 
in, maybe they can be used as suggestions that would work when done slightly 
differently. Now let's hope someone can follow-up with a good solution 
(David? ;-)

Martijn

-----
<tronical> I think a better fix would be to call kapp->deref();
although that's still not perfect
<spaze> hmm.
at least you see the problem we have?: )
<tronical> yes, I see it.
it's a quite grave bug in kdelibs if you ask me :)
but I'm not entirely sure about a proper fix
http://tronical.homeip.net/test.cc <-- in an ideal world this testcase should 
work out of the box. even with your patch it still doesn't though. closing 
the mainwindow quits the application, because it's the main widget
(well, in fact there is no difference whether your patch is applied or not, in 
this case)
the most obvious fix would be to reset the mainwidget of qapp to zero but 
that's a workaround, actually. it's not a proper fix
<spaze> hmmz...
you can also tell qapp to keep on running if the last window is closed iirc
how does a kio job do its event loop? I guess it would be enough to have a 
similar event loop for the systray
<tronical> nope, unfortunately QApplication always quits the application if 
the main widget accepts the close event
a kio job does not 'do' an event loop, it uses the main event loop via 
QSocketNotifiers and QTimer objects
<spaze> so in our case the kopete main window shouldn't be the main widget?
<tronical> well, that would be the obvious fix. but I think it is semantically 
wrong. there _is_ a main widget after all
<spaze> ehm... can't you consider the _systray_ the main widget in our case? 
after all it's the tray that is always visible...
<tronical> no, that's wrong. the purpose of the main widget is more than just 
controlling QWidget::close's behaviour
<tronical> the main widget is where cmdline args like -geometry are applied 
to, which hardly makes sense for a systray window ;)
<spaze> yeah.. the kopete contact list is indeed the main window then for us
grmbl
<tronical> it's also the 'central' window for the windowmanager
one possible workaround would be like this:
in kmainwindow::closeEvent we check for the existance of a systemtray. if
  this == mainWidget && thereIsASystemTray then closeEvent->ignore();
that's essentially what an application would do, I believe
butthh
this of course doesn't work if File->Quit is connected to close(); , because 
File->Quit is supposed to really quit IIRC
<spaze> maybe there should be something like kapp->scheduleQuit() that quits 
as soon as no jobs are running and in the mean time closes all open windows ?
<tronical> yes, maybe
<spaze> or... you said that windows register with kapp, right?
<tronical> the main widget is accessible through QApplicaton::mainWidget();
<spaze> why not make the tray also register? additionally, there should be a 
refcountChanged() signal in kapp that the tray intercepts. if a quit is 
pending the tray then derefs if the refcount reaches one (only the tray 
itself)
<tronical> register as what?
<spaze> well... if something guiless like a kio job can addref then the tray 
certainly can do as well
hmm, how should i explain?
<tronical> yes, it can call kapp->ref();
that... hmm, that could work
hm, no
the close event would still get accepted
<spaze> oh shit... close event can't be overridden to hide() instead of close, 
because then the refcount messes up.
argl..
not to mention that it would still require app-side hacks in the close query 
code
<tronical> yes
we need to ask david about this. his genious will help, I'm optimistic :)
-----





More information about the kde-core-devel mailing list