1. fix the "kill kicker with -9 and loose system tray icons" problem:

// If the system tray gets destroyed, the system tray
	    // icons automatically get unmapped, reparented and mapped
	    // again to the closest non-client ancestor due to
	    // QXEmbed's SaveSet feature. Unfortunatly with kicker
	    // this closest ancestor is not the root window, but our
	    // decoration, so we reparent explicitely back to the root
	    // window.


2. Removed popupinfo feature for now. The feature is a great idea, but the
implementation was too much copy&paste and code duplication with the
tab box. Plus it was buggy (no vertical center alignment) and contained
many unused codelines.

3. Fixed and simplified the session management handling (thanks to
KSessionManaged in libkdecore). This way we actually get a proper
discardCommand generated by KApplication, something that was missing
previously.

svn path=/trunk/kdebase/kwin/; revision=146580
This commit is contained in:
Matthias Ettrich 2002-04-02 12:36:24 +00:00
parent 10a2e466e6
commit 789bb8c535
6 changed files with 38 additions and 326 deletions

View file

@ -8,7 +8,7 @@ lib_LTLIBRARIES = kwin.la
# workspace.cpp has to be first in order not to break --enable-final
kwin_la_SOURCES = workspace.cpp atoms.cpp client.cpp main.cpp \
tabbox.cpp options.cpp plugins.cpp events.cpp KWinInterface.skel \
popupinfo.cpp killwindow.cpp kwinbutton.cpp
killwindow.cpp kwinbutton.cpp
kwin_la_LIBADD = $(LIB_KDEUI) $(LIBXINERAMA)
kwin_la_LDFLAGS = $(all_libraries) -module -avoid-version
@ -18,7 +18,7 @@ kwinincludedir = $(includedir)/kwin
kwininclude_HEADERS = options.h client.h workspace.h kwinbutton.h
kwin_SOURCES = kwin_main.cpp
kwin_LDADD = kwin.la
kwin_LDADD = kwin.la
kwin_LDFLAGS = $(all_libraries) $(KDE_RPATH)
KDE_ICON = kwin

View file

@ -149,31 +149,20 @@ bool Application::x11EventFilter( XEvent *e )
return KApplication::x11EventFilter( e );
}
void Application::commitData( QSessionManager& /*sm*/ )
class SessionManaged : public KSessionManaged
{
// nothing to do, really
}
void Application::saveState( QSessionManager& sm )
{
KApplication::saveState( sm );
static bool firstTime = true;
if ( firstTime ) {
firstTime = false;
return; // no need to save this state.
}
sm.release();
if ( !sm.isPhase2() ) {
sm.requestPhase2();
return;
}
Workspace::self()->storeSession( kapp->sessionConfig() );
kapp->sessionConfig()->sync();
}
public:
bool saveState( QSessionManager& sm ) {
sm.release();
if ( !sm.isPhase2() ) {
sm.requestPhase2();
return true;
}
Workspace::self()->storeSession( kapp->sessionConfig() );
kapp->sessionConfig()->sync();
return true;
}
} ;
static void sighandler(int) {
QApplication::exit();
@ -260,6 +249,7 @@ int kdemain( int argc, char * argv[] )
signal(SIGHUP, SIG_IGN);
Application a;
SessionManaged weAreIndeed;
// KCrash::setCrashHandler(crashHandler); // Try to restart on crash
fcntl(ConnectionNumber(qt_xdisplay()), F_SETFD, 1);

5
main.h
View file

@ -1,6 +1,6 @@
/*****************************************************************
kwin - the KDE window manager
Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
******************************************************************/
#ifndef MAIN_H
@ -15,9 +15,6 @@ public:
Application();
~Application();
void commitData( QSessionManager& sm );
void saveState( QSessionManager& sm );
protected:
bool x11EventFilter( XEvent * );
};

View file

@ -1,196 +0,0 @@
/*****************************************************************
kwin - the KDE window manager
Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
******************************************************************/
//#define QT_CLEAN_NAMESPACE
#include "popupinfo.h"
#include "workspace.h"
#include "client.h"
#include <qpainter.h>
#include <qlabel.h>
#include <qdrawutil.h>
#include <qstyle.h>
#undef Bool // f**king X11
#include <kglobal.h>
#include <kconfig.h>
#include <kdebug.h>
#include <klocale.h>
#include <qapplication.h>
#include <qdesktopwidget.h>
#include <qcursor.h>
#include <kstringhandler.h>
// specify externals before namespace
extern QPixmap* kwin_get_menu_pix_hack();
using namespace KWinInternal;
PopupInfo::PopupInfo( Workspace *ws, const char *name )
: QWidget( 0, name, WStyle_Customize | WStyle_NoBorder )
{
no_tasks = i18n("*** No Tasks ***");
m = DesktopMode; // init variables
wspace = ws;
reconfigure();
reset();
connect(&delayedHideTimer, SIGNAL(timeout()), this, SLOT(hide()));
}
PopupInfo::~PopupInfo()
{
}
/*!
Sets the current mode to \a mode, either DesktopListMode or WindowsMode
\sa mode()
*/
void PopupInfo::setMode( Mode mode )
{
m = mode;
}
/*!
Resets the tab box to display the active client in WindowsMode, or the
current desktop in DesktopListMode
*/
void PopupInfo::reset()
{
QFont f = font();
f.setBold( TRUE );
f.setPointSize( 14 );
setFont( f );
wmax = 0;
desk = workspace()->currentDesktop();
QDesktopWidget* desktop = qApp->desktop();
int screen = desktop->screenNumber( QCursor::pos() );
QRect r = desktop->screenGeometry(screen);
int w = QMIN( QMAX( wmax + 20, r.width()/3 ), r.width() );
setGeometry( (r.width()-w)/2 + r.x(),
r.height()/2-fontMetrics().height()*2-10 + r.y(),
w, fontMetrics().height()*2 + 20 );
wmax = QMIN( wmax, width() - 12 );
}
/*!
Returns the currently displayed client ( only works in WindowsMode ).
Returns 0 if no client is displayed.
*/
Client* PopupInfo::currentClient()
{
if ( mode() != WindowsMode )
return 0;
if (!workspace()->hasClient( client ))
return 0;
return client;
}
/*!
Returns the currently displayed virtual desktop ( only works in
DesktopListMode )
Returns -1 if no desktop is displayed.
*/
int PopupInfo::currentDesktop()
{
if ( mode() == DesktopListMode || mode() == DesktopMode )
return desk;
else
return -1;
}
/*!
Reimplemented to raise the tab box as well
*/
void PopupInfo::showEvent( QShowEvent* )
{
}
/*!
hide the icon box if necessary
*/
void PopupInfo::hideEvent( QHideEvent* )
{
}
/*!
Paints the tab box
*/
void PopupInfo::paintEvent( QPaintEvent* )
{
QPainter p( this );
#if QT_VERSION < 300
style().drawPanel( &p, 0, 0, width(), height(), colorGroup(), FALSE );
style().drawPanel( &p, 4, 4, width()-8, height()-8, colorGroup(), TRUE );
#else
style().drawPrimitive( QStyle::PE_Panel, &p, QRect( 0, 0, width(), height() ),
colorGroup(), QStyle::Style_Default );
style().drawPrimitive( QStyle::PE_Panel, &p, QRect( 4, 4, width()-8, height()-8 ),
colorGroup(), QStyle::Style_Sunken );
#endif
paintContents();
}
/*!
Paints the contents of the tab box. Used in paintEvent() and
whenever the contents changes.
*/
void PopupInfo::paintContents()
{
QPixmap* menu_pix = kwin_get_menu_pix_hack();
QPainter p( this );
QRect r( 6, 6, width()-12, height()-32 );
p.fillRect( r, colorGroup().brush( QColorGroup::Background ) );
p.drawText( r, AlignCenter, workspace()->desktopName(desk) );
int x = (width() - workspace()->numberOfDesktops() * 20 )/2;
int y = height() - 16;
QFont f( font() );
f.setPointSize( 12 );
f.setBold( FALSE );
p.setFont(f );
}
void PopupInfo::hide()
{
delayedHideTimer.stop();
QWidget::hide();
QApplication::syncX();
XEvent otherEvent;
while (XCheckTypedEvent (qt_xdisplay(), EnterNotify, &otherEvent ) )
;
}
void PopupInfo::reconfigure()
{
KConfig * c(KGlobal::config());
c->setGroup("PopupInfo");
m_show = c->readNumEntry("Show", false);
m_delayTime = c->readNumEntry("DelayTime", 250);
}
void PopupInfo::showInfo()
{
if (m_show) {
reset();
show();
raise();
delayedHideTimer.start(m_delayTime, true);
}
}
#include "popupinfo.moc"

View file

@ -1,87 +0,0 @@
/*****************************************************************
kwin - the KDE window manager
Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
******************************************************************/
#ifndef POPUPINFO_H
#define POPUPINFO_H
#include <qwidget.h>
#include <qtimer.h>
#include <qvaluelist.h>
class QLabel;
namespace KWinInternal {
class Workspace;
class Client;
typedef QValueList<Client*> ClientList;
class PopupInfo : public QWidget
{
Q_OBJECT
public:
PopupInfo( Workspace *ws, const char *name=0 );
~PopupInfo();
Client* currentClient();
int currentDesktop();
// DesktopMode and WindowsMode are based on the order in which the desktop
// or window were viewed.
// DesktopListMode lists them in the order created.
enum Mode { DesktopMode, DesktopListMode, WindowsMode };
void setMode( Mode mode );
Mode mode() const;
void reset();
void hide();
void showInfo();
Workspace* workspace() const;
void reconfigure();
protected:
void paintEvent( QPaintEvent* );
void showEvent( QShowEvent* );
void hideEvent( QHideEvent* );
void paintContents();
private:
Client* client;
Mode m;
Workspace* wspace;
ClientList clients;
int desk;
QLabel* icon;
int wmax;
QTimer delayedHideTimer;
QString no_tasks;
bool options_traverse_all;
int m_delayTime;
bool m_show;
};
/*!
Returns the tab box' workspace
*/
inline Workspace* PopupInfo::workspace() const
{
return wspace;
}
/*!
Returns the current mode, either DesktopListMode or WindowsMode
\sa setMode()
*/
inline PopupInfo::Mode PopupInfo::mode() const
{
return m;
}
};
#endif

View file

@ -28,7 +28,6 @@ Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
#include "workspace.h"
#include "client.h"
#include "tabbox.h"
#include "popupinfo.h"
#include "atoms.h"
#include "plugins.h"
#include "events.h"
@ -273,7 +272,6 @@ Workspace::Workspace( bool restore )
mouse_emulation (false),
focus_change (true),
tab_box (0),
popupinfo (0),
popup (0),
desk_popup (0),
keys (0),
@ -333,7 +331,6 @@ Workspace::Workspace( bool restore )
initShortcuts();
tab_box = new TabBox( this );
popupinfo = new PopupInfo( this );
init();
@ -459,7 +456,6 @@ Workspace::~Workspace()
}
delete desktop_widget;
delete tab_box;
delete popupinfo;
delete popup;
if ( root == qt_xrootwin() )
XDeleteProperty(qt_xdisplay(), qt_xrootwin(), atoms->kwin_running);
@ -535,8 +531,25 @@ bool Workspace::workspaceEvent( XEvent * e )
return c->windowEvent( e );
// check for system tray windows
if ( removeSystemTrayWin( e->xunmap.window ) )
return TRUE;
if ( removeSystemTrayWin( e->xunmap.window ) ) {
// If the system tray gets destroyed, the system tray
// icons automatically get unmapped, reparented and mapped
// again to the closest non-client ancestor due to
// QXEmbed's SaveSet feature. Unfortunatly with kicker
// this closest ancestor is not the root window, but our
// decoration, so we reparent explicitely back to the root
// window.
XEvent ev;
WId w = e->xunmap.window;
if ( XCheckTypedWindowEvent (qt_xdisplay(), w,
ReparentNotify, &ev) ){
if ( ev.xreparent.parent != root ) {
XReparentWindow( qt_xdisplay(), w, root, 0, 0 );
addSystemTrayWin( w );
}
}
return TRUE;
}
return ( e->xunmap.event != e->xunmap.window ); // hide wm typical event from Qt
@ -561,7 +574,7 @@ bool Workspace::workspaceEvent( XEvent * e )
checkStartOnDesktop( e->xmaprequest.window );
c = findClient( e->xmaprequest.window );
if ( !c ) {
if ( e->xmaprequest.parent ) { // == root ) { //###TODO store previously destroyed client ids
if ( e->xmaprequest.parent == root ) { //###TODO store previously destroyed client ids
if ( addSystemTrayWin( e->xmaprequest.window ) )
return TRUE;
c = clientFactory( e->xmaprequest.window );
@ -2026,7 +2039,6 @@ void Workspace::slotReconfigure()
KGlobal::config()->reparseConfiguration();
options->reload();
tab_box->reconfigure();
popupinfo->reconfigure();
readShortcuts();
mgr->updatePlugin();
@ -2199,9 +2211,6 @@ void Workspace::raiseClient( Client* c )
if ( tab_box->isVisible() )
tab_box->raise();
if ( popupinfo->isVisible() )
popupinfo->raise();
raiseElectricBorders();
}
@ -2870,7 +2879,6 @@ void Workspace::slotSwitchDesktopDown(){
void Workspace::slotSwitchToDesktop( int i )
{
popupinfo->showInfo();
setCurrentDesktop( i );
}
@ -3191,7 +3199,7 @@ void Workspace::slotWindowOperations()
*/
void Workspace::slotWindowClose()
{
if ( tab_box->isVisible() || popupinfo->isVisible() )
if ( tab_box->isVisible() )
return;
performWindowOperation( popup_client, Options::CloseOp );
}