diff --git a/client.cpp b/client.cpp index 7a5edf4b28..a206278c2f 100644 --- a/client.cpp +++ b/client.cpp @@ -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; } @@ -1134,11 +1148,11 @@ bool Client::isMaximizable() const */ void Client::mousePressEvent( QMouseEvent * e) { - if (buttonDown) + if (buttonDown) return; - + Options::MouseCommand com = Options::MouseNothing; - + if (e->state() & AltButton) { if ( e->button() == LeftButton ) { com = options->commandAll1(); @@ -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() ) diff --git a/client.h b/client.h index 8052a64279..d036e3399a 100644 --- a/client.h +++ b/client.h @@ -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(); @@ -217,7 +222,7 @@ protected: bool configureRequest( XConfigureRequestEvent& e ); bool propertyNotify( XPropertyEvent& e ); bool clientMessage( XClientMessageEvent& e ); - + private: QSize sizeForWindowSize( const QSize&, bool ignore_height = FALSE ) const; void getWmNormalHints(); @@ -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 diff --git a/main.cpp b/main.cpp index 7161b9a9dd..0a08480785 100644 --- a/main.cpp +++ b/main.cpp @@ -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[] ) diff --git a/workspace.cpp b/workspace.cpp index fb4f29ee6c..f7b3c4e416 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -15,6 +15,7 @@ Copyright (C) 1999, 2000 Matthias Ettrich #include #include #include +#include #include @@ -42,9 +43,6 @@ const int XIconicState = IconicState; #include - - - // 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; diff --git a/workspace.h b/workspace.h index 325944932d..de71e7d546 100644 --- a/workspace.h +++ b/workspace.h @@ -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; }; @@ -109,6 +111,8 @@ public: void setActiveClient( Client* ); 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