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