- 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:
parent
8cbea5ef2e
commit
bf33b067be
5 changed files with 155 additions and 37 deletions
67
client.cpp
67
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() )
|
||||
|
|
27
client.h
27
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
|
||||
|
|
2
main.cpp
2
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[] )
|
||||
|
|
|
@ -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;
|
||||
|
|
16
workspace.h
16
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
|
||||
|
|
Loading…
Reference in a new issue