- completed session management (maximize, shaded, and restore were missing)

- support for WM_COMMAND pseudo session management (xterm and friends)
- basic support for private colormaps, useful on the last remaining 8bit displays

svn path=/trunk/kdebase/kwin/; revision=62239
This commit is contained in:
Matthias Ettrich 2000-08-30 14:27:30 +00:00
parent 8cbea5ef2e
commit bf33b067be
5 changed files with 155 additions and 37 deletions

View file

@ -195,6 +195,7 @@ WindowWrapper::WindowWrapper( WId w, Client *parent, const char* name)
XSelectInput( qt_xdisplay(), w,
FocusChangeMask |
PropertyChangeMask |
ColormapChangeMask |
EnterWindowMask | LeaveWindowMask
);
@ -423,6 +424,9 @@ Client::Client( Workspace *ws, WId w, QWidget *parent, const char *name, WFlags
stays_on_top = FALSE;
may_move = TRUE;
skip_taskbar = FALSE;
max_mode = MaximizeRestore;
cmap = None;
getWMHints();
getWindowProtocols();
@ -479,15 +483,17 @@ bool Client::manage( bool isMapped, bool doNotShow )
layout()->setResizeMode( QLayout::Minimum );
XWindowAttributes attr;
if (XGetWindowAttributes(qt_xdisplay(), win, &attr))
if (XGetWindowAttributes(qt_xdisplay(), win, &attr)) {
cmap = attr.colormap;
original_geometry.setRect(attr.x, attr.y, attr.width, attr.height );
}
QRect geom( original_geometry );
bool placementDone = FALSE;
SessionInfo* session = workspace()->takeSessionInfo( this );
if ( session )
geom.setRect( session->x, session->y, session->width, session->height );
geom = session->geometry;
QRect area = workspace()->clientArea();
@ -608,6 +614,10 @@ bool Client::manage( bool isMapped, bool doNotShow )
// other settings from the previous session
if ( session ) {
setSticky( session->sticky );
setShade( session->shaded );
setStaysOnTop( session->staysOnTop );
maximize( (MaximizeMode) session->maximize );
geom_restore = session->restore;
}
delete session;
@ -742,6 +752,10 @@ bool Client::windowEvent( XEvent * e)
break;
case ClientMessage:
return clientMessage( e->xclient );
case ColormapChangeMask:
cmap = e->xcolormap.colormap;
if ( isActive() )
workspace()->updateColormap();
default:
break;
}
@ -1225,7 +1239,7 @@ void Client::mouseMoveEvent( QMouseEvent * e)
moveResizeMode = TRUE;
if ( isMaximized() ) {
// in case we were maximized, reset state
geom_restore = QRect();
max_mode = MaximizeRestore;
maximizeChange(FALSE );
}
workspace()->setFocusChangeEnabled(false);
@ -1565,8 +1579,11 @@ void Client::maximize( MaximizeMode m)
if ( m == MaximizeAdjust ) {
m = max_mode;
} else {
if ( !geom_restore.isNull() )
if ( max_mode != MaximizeRestore )
m = MaximizeRestore;
else if ( m == max_mode )
return; // nothing to do
if ( m != MaximizeRestore ) {
Events::raise( Events::Maximize );
@ -1597,7 +1614,7 @@ void Client::maximize( MaximizeMode m)
case MaximizeRestore: {
Events::raise( Events::UnMaximize );
setGeometry(geom_restore);
geom_restore = QRect();
max_mode = MaximizeRestore;
info->setState( 0, NET::Max );
} break;
@ -2125,7 +2142,7 @@ bool Client::performMouseCommand( Options::MouseCommand command, QPoint globalPo
moveResizeMode = TRUE;
if ( isMaximized() ) {
// in case we were maximized, reset state
geom_restore = QRect();
max_mode = MaximizeRestore;
maximizeChange(FALSE );
}
workspace()->setFocusChangeEnabled(false);
@ -2143,7 +2160,7 @@ bool Client::performMouseCommand( Options::MouseCommand command, QPoint globalPo
moveResizeMode = TRUE;
if ( isMaximized() ) {
// in case we were maximized, reset state
geom_restore = QRect();
max_mode = MaximizeRestore;
maximizeChange(FALSE );
}
workspace()->setFocusChangeEnabled(false);
@ -2328,6 +2345,36 @@ QCString Client::sessionId()
return result;
}
static int getprop(Window w, Atom a, Atom type, long len, unsigned char **p)
{
Atom real_type;
int format;
unsigned long n, extra;
int status;
status = XGetWindowProperty(qt_xdisplay(), w, a, 0L, len, False, type, &real_type, &format, &n, &extra, p);
if (status != Success || *p == 0)
return -1;
if (n == 0)
XFree((void*) *p);
return n;
}
QCString Client::wmCommand()
{
QCString result;
char *p;
int i,n;
if ((n = getprop(win, XA_WM_COMMAND, XA_STRING, 100L, (unsigned char **)&p)) > 0){
result = p;
for ( i = 0; (i += strlen(p+i)+1) < n; result.append(p+i) )
result.append(" ");
XFree((char *) p);
}
return result;
}
void Client::activateLayout()
{
if ( layout() )

View file

@ -113,8 +113,10 @@ public:
void giveUpShade();
bool isMaximized() const;
enum MaximizeMode { MaximizeVertical, MaximizeHorizontal, MaximizeFull, MaximizeRestore, MaximizeAdjust };
enum MaximizeMode { MaximizeRestore, MaximizeVertical, MaximizeHorizontal, MaximizeFull, MaximizeAdjust };
bool isMaximizable() const;
QRect geometryRestore() const;
MaximizeMode maximizeMode() const;
bool isSticky() const;
void setSticky( bool );
@ -158,9 +160,12 @@ public:
QCString windowRole();
QCString sessionId();
QCString wmCommand();
QRect adjustedClientArea( const QRect& area ) const;
Colormap colormap() const;
public slots:
void iconify();
void closeWindow();
@ -269,6 +274,7 @@ private:
QRegion mask;
WinInfo* info;
QTimer* autoRaiseTimer;
Colormap cmap;
};
@ -351,9 +357,18 @@ inline QPixmap Client::miniIcon() const
*/
inline bool Client::isMaximized() const
{
return !geom_restore.isNull();
return max_mode != MaximizeRestore;
}
inline QRect Client::geometryRestore() const
{
return geom_restore;
}
inline Client::MaximizeMode Client::maximizeMode() const
{
return max_mode;
}
inline bool Client::staysOnTop() const
{
@ -371,6 +386,12 @@ inline const QRegion& Client::getMask() const
return mask;
}
inline Colormap Client::colormap() const
{
return cmap;
}
class NoBorderClient : public Client
{
Q_OBJECT

View file

@ -189,7 +189,7 @@ static void sighandler(int) {
QApplication::exit();
}
static const char *version = "0.4";
static const char *version = "0.5";
static const char *description = I18N_NOOP( "The KDE window manager." );
int main( int argc, char * argv[] )

View file

@ -15,6 +15,7 @@ Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
#include <kapp.h>
#include <dcopclient.h>
#include <kdebug.h>
#include <kprocess.h>
#include <netwm.h>
@ -42,9 +43,6 @@ const int XIconicState = IconicState;
#include <kapp.h>
// NET WM Protocol handler class
class RootInfo : public NETRootInfo
{
@ -216,6 +214,8 @@ Workspace::Workspace( bool restore )
root (0)
{
root = qt_xrootwin();
default_colormap = DefaultColormap(qt_xdisplay(), qt_xscreen() );
installed_colormap = default_colormap;
session.setAutoDelete( TRUE );
area = QApplication::desktop()->geometry();
@ -267,6 +267,16 @@ Workspace::Workspace( bool restore )
tab_box = new TabBox( this );
init();
if ( restore ) { // pseudo session management with wmCommand
for (SessionInfo* info = session.first(); info; info = session.next() ) {
if ( info->sessionId.isEmpty() && !info->wmCommand.isEmpty() ) {
KShellProcess proc;
proc << QString::fromLatin1( info->wmCommand );
proc.start(KShellProcess::DontCare);
}
}
}
}
void Workspace::init()
@ -949,6 +959,7 @@ void Workspace::setActiveClient( Client* c )
}
rootInfo->setActiveWindow( active_client? active_client->window() : 0 );
updateColormap();
}
@ -1060,6 +1071,22 @@ void Workspace::requestFocus( Client* c)
}
/*!
Updates the current colormap according to the currently active client
*/
void Workspace::updateColormap()
{
Colormap cmap = default_colormap;
if ( activeClient() && activeClient()->colormap() != None )
cmap = activeClient()->colormap();
if ( cmap != installed_colormap ) {
XInstallColormap(qt_xdisplay(), cmap );
installed_colormap = cmap;
}
}
/*!
Informs the workspace that the client \a c has been hidden. If it
was the active client, the workspace activates another one.
@ -1703,7 +1730,7 @@ void Workspace::focusToNull(){
XMapWindow(qt_xdisplay(), w);
}
XSetInputFocus(qt_xdisplay(), w, RevertToPointerRoot, kwin_time );
//colormapFocus(0); TODO
updateColormap();
}
@ -2633,18 +2660,21 @@ void Workspace::storeSession( KConfig* config )
Client* c = (*it);
QCString sessionId = c->sessionId();
QCString windowRole = c->windowRole();
if ( !sessionId.isEmpty() ) {
QCString wmCommand = c->wmCommand();
if ( !sessionId.isEmpty() || !wmCommand.isEmpty() ) {
count++;
QString n = QString::number(count);
config->writeEntry( QString("sessionId")+n, c->sessionId().data() );
config->writeEntry( QString("windowRole")+n, c->windowRole().data() );
config->writeEntry( QString("x")+n, c->x() );
config->writeEntry( QString("y")+n, c->y() );
config->writeEntry( QString("width")+n, c->windowWrapper()->width() );
config->writeEntry( QString("height")+n, c->windowWrapper()->height() );
config->writeEntry( QString("sessionId")+n, sessionId.data() );
config->writeEntry( QString("windowRole")+n, windowRole.data() );
config->writeEntry( QString("wmCommand")+n, wmCommand.data() );
config->writeEntry( QString("geometry")+n, c->geometry() );
config->writeEntry( QString("restore")+n, c->geometryRestore() );
config->writeEntry( QString("maximize")+n, (int) c->maximizeMode() );
config->writeEntry( QString("desktop")+n, c->desktop() );
config->writeEntry( QString("iconified")+n, c->isIconified()?"true":"false" );
config->writeEntry( QString("sticky")+n, c->isSticky()?"true":"false" );
config->writeEntry( QString("shaded")+n, c->isShade()?"true":"false" );
config->writeEntry( QString("staysOnTop")+n, c->staysOnTop()?"true":"false" );
}
}
config->writeEntry( "count", count );
@ -2668,13 +2698,15 @@ void Workspace::loadSessionInfo()
session.append( info );
info->sessionId = config->readEntry( QString("sessionId")+n ).latin1();
info->windowRole = config->readEntry( QString("windowRole")+n ).latin1();
info->x = config->readNumEntry( QString("x")+n );
info->y = config->readNumEntry( QString("y")+n );
info->width = config->readNumEntry( QString("width")+n );
info->height = config->readNumEntry( QString("height")+n );
info->desktop = config->readNumEntry( QString("desktop")+n );
info->iconified = config->readBoolEntry( QString("iconified")+n );
info->sticky = config->readBoolEntry( QString("sticky")+n );
info->wmCommand = config->readEntry( QString("wmCommand")+n ).latin1();
info->geometry = config->readRectEntry( QString("geometry")+n );
info->restore = config->readRectEntry( QString("restore")+n );
info->maximize = config->readNumEntry( QString("maximize")+n, 0 );
info->desktop = config->readNumEntry( QString("desktop")+n, 0 );
info->iconified = config->readBoolEntry( QString("iconified")+n, FALSE );
info->sticky = config->readBoolEntry( QString("sticky")+n, FALSE );
info->shaded = config->readBoolEntry( QString("shaded")+n, FALSE );
info->staysOnTop = config->readBoolEntry( QString("staysOnTop")+n, FALSE );
}
}
@ -2692,12 +2724,22 @@ SessionInfo* Workspace::takeSessionInfo( Client* c )
QCString sessionId = c->sessionId();
QCString windowRole = c->windowRole();
QCString wmCommand = c->wmCommand();
for (SessionInfo* info = session.first(); info; info = session.next() ) {
for (SessionInfo* info = session.first(); info; info = session.next() ) {
// a real session managed client
if ( info->sessionId == sessionId &&
( ( info->windowRole.isEmpty() && windowRole.isEmpty() )
|| (info->windowRole == windowRole ) ) )
return session.take();
// pseudo session management
if ( info->sessionId.isEmpty() && !info->wmCommand.isEmpty() &&
info->wmCommand == wmCommand &&
( ( info->windowRole.isEmpty() && windowRole.isEmpty() )
|| (info->windowRole == windowRole ) ) )
return session.take();
}
return 0;

View file

@ -54,13 +54,15 @@ struct SessionInfo
{
QCString sessionId;
QCString windowRole;
int x;
int y;
int width;
int height;
QCString wmCommand; // compatibility
QRect geometry;
QRect restore;
int maximize;
int desktop;
bool iconified;
bool sticky;
bool shaded;
bool staysOnTop;
};
@ -110,6 +112,8 @@ public:
void activateClient( Client* );
void requestFocus( Client* c);
void updateColormap();
void setFocusChangeEnabled(bool b) { focus_change = b; }
bool focusChangeEnabled() { return focus_change; }
@ -325,6 +329,10 @@ private:
// swallowing
QStringList doNotManageList;
// colormap handling
Colormap default_colormap;
Colormap installed_colormap;
};
inline WId Workspace::rootWin() const