[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Problem with applications which have a system tray applet and
From:       Ingo =?iso-8859-15?q?Kl=F6cker?= <kloecker () kde ! org>
Date:       2003-12-07 18:13:26
[Download RAW message or body]


Hi!

The situation (also see http://bugs.kde.org/show_bug.cgi?id=69656):
KMail's (or Kontact's) main window is hidden (because the user hid it by 
clicking on the system tray applet), but a secondary window is still 
visible (e. g. a composer window or a separate message viewer window). 
If the user now closes the secondary window then the last visible 
window has been closed. Therefore in KMainWindow::closeEvent() first 
queryExit() and then kapp->deref() is called. IMO this is wrong. All 
applications which have a system tray applet (another example is KSirc) 
have to invent complicated workarounds for this "feature" in order to 
prevent itself from exiting.

One solution would be to not only look for visible KMainWindows but also 
for a KSystemTray. If a KSystemTray is found then queryExit() (and 
later kapp->deref()) shouldn't be called from 
KMainWindow::closeEvent(). I realize that such a change isn't possible 
before KDE 4.0.

Another solution would be to allow applications which know much better 
than KMainWindow when they should be exited to disable the automatism 
in KMainWindow. Something like 
KMainWindow::setDontExitIfLastWindowIsClosed( bool ). This could even 
be added before KDE 4.0.

Just for your information, the workaround that I came up with for KMail 
is:
=====
bool KMComposeWin::queryExit()
{
  if ( kmkernel->shuttingDown() || kapp->sessionSaving() )
    return true;

  // prevent the kapp->deref() in KMainWindow::closeEvent() to close the
  // application in case we have a system tray applet
  if ( kmkernel->haveSystemTrayApplet() )
    kapp->ref();
  return true;
}
=====

As you can see it's a rather nasty workaround which will easily break as 
soon as someone changes something in KMainWindow::closeEvent(). 
Furthermore I had to look at the implementation of KMainWindow in order 
to find out what to do. That's not what application programmers should 
have to do. They should only have to read the API documentation. But 
unfortunately the documentation doesn't provide a solution for the 
above problem. In fact the documentation even confuses the reader by 
saying:
"Called before the very last window is closed, either by the user or 
indirectly by the session manager."
This should be changed to the more correct
"Called before the very last not hidden window is closed, either by the 
user or indirectly by the session manager."

Regards,
Ingo

[Attachment #3 (application/pgp-signature)]

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic