gracefully handle more than one desktop client application (which
happens triggered by a kdesktop bug on David Faure's machine). You can now launch additional desktop applications with kstart --type Desktop konqueror or kstart --type Desktop konsole and toggle between them with dcop kwin default circulateDesktopApplications svn path=/trunk/kdebase/kwin/; revision=140330
This commit is contained in:
parent
f10a38655b
commit
83f58ed248
6 changed files with 115 additions and 112 deletions
|
@ -21,6 +21,7 @@ class KWinInterface : virtual public DCOPObject
|
|||
virtual int currentDesktop() const = 0;
|
||||
virtual void nextDesktop() = 0;
|
||||
virtual void previousDesktop() = 0;
|
||||
virtual void circulateDesktopApplications() = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
28
client.cpp
28
client.cpp
|
@ -494,8 +494,7 @@ Client::Client( Workspace *ws, WId w, QWidget *parent, const char *name, WFlags
|
|||
NET::WMWindowType |
|
||||
NET::WMStrut |
|
||||
NET::WMName |
|
||||
NET::WMIconGeometry |
|
||||
NET::WMPid
|
||||
NET::WMIconGeometry
|
||||
;
|
||||
|
||||
info = new WinInfo( this, qt_xdisplay(), win, qt_xrootwin(), properties );
|
||||
|
@ -635,6 +634,13 @@ bool Client::manage( bool isMapped, bool doNotShow, bool isInitial )
|
|||
may_move = FALSE; // don't let fullscreen windows be moved around
|
||||
}
|
||||
|
||||
if ( isDesktop() ) {
|
||||
// desktops are treated slightly special
|
||||
geom = workspace()->geometry();
|
||||
may_move = FALSE;
|
||||
isMapped = TRUE;
|
||||
}
|
||||
|
||||
if ( isMapped || session || isTransient() ) {
|
||||
placementDone = TRUE;
|
||||
} else {
|
||||
|
@ -1117,10 +1123,9 @@ void Client::withdraw()
|
|||
Events::raise( isTransient() ? Events::TransDelete : Events::Delete );
|
||||
// remove early from client list
|
||||
workspace()->removeClient( this );
|
||||
setMappingState( WithdrawnState );
|
||||
info->setDesktop( 0 );
|
||||
desk = 0;
|
||||
releaseWindow();
|
||||
releaseWindow(TRUE);
|
||||
workspace()->destroyClient( this );
|
||||
}
|
||||
|
||||
|
@ -1132,6 +1137,12 @@ bool Client::configureRequest( XConfigureRequestEvent& e )
|
|||
if ( isResize() )
|
||||
return TRUE; // we have better things to do right now
|
||||
|
||||
if ( isDesktop() ) {
|
||||
setGeometry( workspace()->geometry() );
|
||||
sendSyntheticConfigureNotify();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ( isShade() )
|
||||
setShade( FALSE );
|
||||
|
||||
|
@ -1833,12 +1844,19 @@ void Client::paintEvent( QPaintEvent * )
|
|||
|
||||
/*!
|
||||
Releases the window. The client has done its job and the window is still existing.
|
||||
|
||||
If withdraw is TRUE, the function also sets the mapping state of the
|
||||
window to WithdrawnState
|
||||
*/
|
||||
void Client::releaseWindow()
|
||||
void Client::releaseWindow( bool withdraw )
|
||||
{
|
||||
if ( win ) {
|
||||
move(gravitate(TRUE));
|
||||
if ( withdraw )
|
||||
XUnmapWindow( qt_xdisplay(), win );
|
||||
windowWrapper()->releaseWindow();
|
||||
if ( withdraw )
|
||||
setMappingState( WithdrawnState );
|
||||
win = 0;
|
||||
}
|
||||
}
|
||||
|
|
2
client.h
2
client.h
|
@ -80,7 +80,7 @@ public:
|
|||
WId window() const;
|
||||
WindowWrapper* windowWrapper() const;
|
||||
Workspace* workspace() const;
|
||||
void releaseWindow();
|
||||
void releaseWindow( bool withdraw = FALSE );
|
||||
void invalidateWindow();
|
||||
WId transientFor() const;
|
||||
bool isTransient() const;
|
||||
|
|
2
main.cpp
2
main.cpp
|
@ -260,7 +260,7 @@ int kdemain( int argc, char * argv[] )
|
|||
signal(SIGHUP, SIG_IGN);
|
||||
|
||||
Application a;
|
||||
KCrash::setCrashHandler(crashHandler); // Try to restart on crash
|
||||
// KCrash::setCrashHandler(crashHandler); // Try to restart on crash
|
||||
fcntl(ConnectionNumber(qt_xdisplay()), F_SETFD, 1);
|
||||
|
||||
QCString appname;
|
||||
|
|
183
workspace.cpp
183
workspace.cpp
|
@ -225,7 +225,6 @@ Client* Workspace::clientFactory( WId w )
|
|||
XLowerWindow( qt_xdisplay(), w );
|
||||
Client * c = new NoBorderClient( this, w);
|
||||
c->setSticky( TRUE );
|
||||
setDesktopClient( c );
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -268,7 +267,6 @@ Workspace::Workspace( bool restore )
|
|||
current_desktop (0),
|
||||
number_of_desktops(0),
|
||||
desktop_widget (0),
|
||||
desktop_client (0),
|
||||
active_client (0),
|
||||
last_active_client (0),
|
||||
should_get_focus (0),
|
||||
|
@ -436,15 +434,9 @@ void Workspace::init()
|
|||
if ( addSystemTrayWin( wins[i] ) )
|
||||
continue;
|
||||
Client* c = clientFactory( wins[i] );
|
||||
if ( c != desktop_client ) {
|
||||
clients.append( c );
|
||||
stacking_order.append( c );
|
||||
}
|
||||
if ( c->wantsTabFocus() )
|
||||
focus_chain.append( c );
|
||||
addClient( c );
|
||||
c->manage( TRUE );
|
||||
if ( c == desktop_client )
|
||||
setDesktopClient( c );
|
||||
|
||||
if ( root != qt_xrootwin() ) {
|
||||
// TODO may use QWidget:.create
|
||||
XReparentWindow( qt_xdisplay(), c->winId(), root, 0, 0 );
|
||||
|
@ -471,9 +463,9 @@ void Workspace::init()
|
|||
|
||||
Workspace::~Workspace()
|
||||
{
|
||||
if ( desktop_client ) {
|
||||
WId win = desktop_client->window();
|
||||
delete desktop_client;
|
||||
for ( ClientList::ConstIterator it = desktops.fromLast(); it != desktops.end(); --it) {
|
||||
WId win = (*it)->window();
|
||||
delete (*it);
|
||||
XMapWindow( qt_xdisplay(), win );
|
||||
XLowerWindow( qt_xdisplay(), win );
|
||||
}
|
||||
|
@ -591,7 +583,7 @@ bool Workspace::workspaceEvent( XEvent * e )
|
|||
checkStartOnDesktop( e->xmaprequest.window );
|
||||
c = findClient( e->xmaprequest.window );
|
||||
if ( !c ) {
|
||||
if ( e->xmaprequest.parent ) { // == root ) { //###TODO store rpeviously 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 );
|
||||
|
@ -599,19 +591,11 @@ bool Workspace::workspaceEvent( XEvent * e )
|
|||
// TODO may use QWidget:.create
|
||||
XReparentWindow( qt_xdisplay(), c->winId(), root, 0, 0 );
|
||||
}
|
||||
if ( c != desktop_client ) {
|
||||
if ( c->wantsTabFocus() )
|
||||
focus_chain.append( c );
|
||||
clients.append( c );
|
||||
stacking_order.append( c );
|
||||
}
|
||||
addClient( c );
|
||||
}
|
||||
}
|
||||
if ( c ) {
|
||||
bool result = c->windowEvent( e );
|
||||
if ( c == desktop_client )
|
||||
setDesktopClient( c );
|
||||
return result;
|
||||
return c->windowEvent( e );
|
||||
}
|
||||
break;
|
||||
case EnterNotify:
|
||||
|
@ -702,8 +686,10 @@ Client* Workspace::findClient( WId w ) const
|
|||
if ( (*it)->window() == w )
|
||||
return *it;
|
||||
}
|
||||
if ( desktop_client && w == desktop_client->window() )
|
||||
return desktop_client;
|
||||
for ( ClientList::ConstIterator it = desktops.begin(); it != desktops.end(); ++it) {
|
||||
if ( (*it)->window() == w )
|
||||
return *it;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -763,8 +749,8 @@ bool Workspace::destroyClient( Client* c)
|
|||
|
||||
c->invalidateWindow();
|
||||
clientHidden( c );
|
||||
if ( c == desktop_client )
|
||||
desktop_client = 0;
|
||||
if ( desktops.contains(c) )
|
||||
desktops.remove(c);
|
||||
if ( c == most_recently_raised )
|
||||
most_recently_raised = 0;
|
||||
if ( c == should_get_focus )
|
||||
|
@ -1225,6 +1211,45 @@ int Workspace::previousDesktop( int iDesktop ) const
|
|||
return numberOfDesktops();
|
||||
}
|
||||
|
||||
void Workspace::circulateDesktopApplications()
|
||||
{
|
||||
if ( desktops.count() <= 1 )
|
||||
return;
|
||||
Client* first = desktops.first();
|
||||
desktops.remove( first );
|
||||
desktops.append( first );
|
||||
Window* new_stack = new Window[ desktops.count() + 1 ];
|
||||
int i = 0;
|
||||
for ( ClientList::ConstIterator it = desktops.fromLast(); it != desktops.end(); --it)
|
||||
new_stack[i++] = (*it)->winId();
|
||||
XRestackWindows(qt_xdisplay(), new_stack, i);
|
||||
delete [] new_stack;
|
||||
}
|
||||
|
||||
void Workspace::addClient( Client* c )
|
||||
{
|
||||
if ( c->isDesktop() ) {
|
||||
if ( !desktops.isEmpty() ) {
|
||||
Client* first = desktops.first();
|
||||
Window stack[2];
|
||||
stack[0] = first->winId();
|
||||
stack[1] = c->winId();
|
||||
XRestackWindows( qt_xdisplay(), stack, 2 );
|
||||
desktops.prepend( c );
|
||||
circulateDesktopApplications();
|
||||
} else {
|
||||
c->lower();
|
||||
desktops.append( c );
|
||||
}
|
||||
} else {
|
||||
if ( c->wantsTabFocus() )
|
||||
focus_chain.append( c );
|
||||
clients.append( c );
|
||||
stacking_order.append( c );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
auxiliary functions to travers all clients according the focus
|
||||
order. Useful for kwm´s Alt-tab feature.
|
||||
|
@ -1356,9 +1381,9 @@ void Workspace::setActiveClient( Client* c )
|
|||
break;
|
||||
}
|
||||
}
|
||||
if ( !menubar && desktop_client ) {
|
||||
if ( !menubar && !desktops.isEmpty() ) {
|
||||
for ( ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it) {
|
||||
if ( (*it)->isMenu() && (*it)->mainClient() == desktop_client ) {
|
||||
if ( (*it)->isMenu() && (*it)->mainClient()->isDesktop() ) {
|
||||
menubar = *it;
|
||||
break;
|
||||
}
|
||||
|
@ -1542,14 +1567,15 @@ void Workspace::clientHidden( Client* c )
|
|||
}
|
||||
}
|
||||
}
|
||||
if ( desktop_client )
|
||||
requestFocus( desktop_client );
|
||||
else
|
||||
focusToNull();
|
||||
} // if blocking focus, move focus to desktop_client later if needed
|
||||
// in order to avoid flickering
|
||||
else
|
||||
focusToNull();
|
||||
if ( !c->isDesktop() && !desktops.isEmpty() )
|
||||
requestFocus( desktops.last() );
|
||||
else
|
||||
focusToNull();
|
||||
} else {
|
||||
// if blocking focus, move focus to the desktop later if needed
|
||||
// in order to avoid flickering
|
||||
focusToNull();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1759,7 +1785,7 @@ void Workspace::smartPlacement(Client* c){
|
|||
cyt = y; cyb = y + ch;
|
||||
QValueList<Client*>::ConstIterator l;
|
||||
for(l = clients.begin(); l != clients.end() ; ++l ) {
|
||||
if((*l)->isOnDesktop(desktop) && (*l) != desktop_client &&
|
||||
if((*l)->isOnDesktop(desktop) &&
|
||||
!(*l)->isIconified() && (*l) != c ) {
|
||||
|
||||
xl = (*l)->x(); yt = (*l)->y();
|
||||
|
@ -1807,7 +1833,7 @@ void Workspace::smartPlacement(Client* c){
|
|||
QValueList<Client*>::ConstIterator l;
|
||||
for(l = clients.begin(); l != clients.end() ; ++l) {
|
||||
|
||||
if ( (*l)->isOnDesktop(desktop) && (*l) != desktop_client &&
|
||||
if ( (*l)->isOnDesktop(desktop) &&
|
||||
!(*l)->isIconified() && (*l) != c ) {
|
||||
|
||||
xl = (*l)->x(); yt = (*l)->y();
|
||||
|
@ -1837,7 +1863,7 @@ void Workspace::smartPlacement(Client* c){
|
|||
//test the position of each window on the desk
|
||||
QValueList<Client*>::ConstIterator l;
|
||||
for( l = clients.begin(); l != clients.end() ; ++l ) {
|
||||
if( (*l)->isOnDesktop(desktop) && (*l) != desktop_client &&
|
||||
if( (*l)->isOnDesktop(desktop) &&
|
||||
(*l) != c && !c->isIconified() ) {
|
||||
|
||||
xl = (*l)->x(); yt = (*l)->y();
|
||||
|
@ -2052,7 +2078,7 @@ void Workspace::lowerClient( Client* c )
|
|||
if ( !c )
|
||||
return;
|
||||
|
||||
if ( c == desktop_client )
|
||||
if ( c->isDesktop() )
|
||||
return; // deny
|
||||
|
||||
ClientList saveset;
|
||||
|
@ -2070,7 +2096,7 @@ void Workspace::lowerClient( Client* c )
|
|||
saveset.append( t );
|
||||
t = tmp;
|
||||
}
|
||||
if ( t && !saveset.contains( t ) && t != desktop_client ) {
|
||||
if ( t && !saveset.contains( t ) ) {
|
||||
lowerClient( t );
|
||||
return;
|
||||
}
|
||||
|
@ -2085,9 +2111,8 @@ void Workspace::lowerClient( Client* c )
|
|||
stacking_order = constrainedStackingOrder( stacking_order );
|
||||
Window* new_stack = new Window[ stacking_order.count() + 1 ];
|
||||
int i = 0;
|
||||
for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it) {
|
||||
for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it)
|
||||
new_stack[i++] = (*it)->winId();
|
||||
}
|
||||
XRestackWindows(qt_xdisplay(), new_stack, i);
|
||||
delete [] new_stack;
|
||||
|
||||
|
@ -2110,7 +2135,7 @@ void Workspace::raiseClient( Client* c )
|
|||
|
||||
ClientList saveset;
|
||||
|
||||
if ( c == desktop_client ) {
|
||||
if ( c->isDesktop() ) {
|
||||
saveset.clear();
|
||||
saveset.append( c );
|
||||
raiseTransientsOf(saveset, c );
|
||||
|
@ -2133,7 +2158,7 @@ void Workspace::raiseClient( Client* c )
|
|||
saveset.append( t );
|
||||
t = tmp;
|
||||
}
|
||||
if ( t && !saveset.contains( t ) && t != desktop_client ) {
|
||||
if ( t && !saveset.contains( t ) ) {
|
||||
raiseClient( t );
|
||||
most_recently_raised = c;
|
||||
return;
|
||||
|
@ -2171,9 +2196,8 @@ void Workspace::raiseClient( Client* c )
|
|||
|
||||
Window* new_stack = new Window[ stacking_order.count() + 1 ];
|
||||
int i = 0;
|
||||
for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it) {
|
||||
for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it)
|
||||
new_stack[i++] = (*it)->winId();
|
||||
}
|
||||
XRestackWindows(qt_xdisplay(), new_stack, i);
|
||||
delete [] new_stack;
|
||||
|
||||
|
@ -2300,43 +2324,15 @@ void Workspace::focusToNull(){
|
|||
}
|
||||
|
||||
|
||||
/*!
|
||||
Declares client \a c to be the desktop.
|
||||
*/
|
||||
void Workspace::setDesktopClient( Client* c)
|
||||
{
|
||||
desktop_client = c;
|
||||
if ( desktop_client ) {
|
||||
desktop_client->lower();
|
||||
desktop_client->setGeometry( geometry() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Refreshes all the client windows
|
||||
*/
|
||||
void Workspace::refresh() {
|
||||
/* This idea/code is borrowed from FVWM 2.x */
|
||||
XSetWindowAttributes attributes;
|
||||
unsigned long valuemask = CWOverrideRedirect|
|
||||
CWBackingStore|
|
||||
CWSaveUnder|
|
||||
CWBackPixmap;
|
||||
attributes.background_pixmap = None;
|
||||
attributes.save_under = False;
|
||||
attributes.override_redirect = True;
|
||||
attributes.backing_store = NotUseful;
|
||||
WId rw = XCreateWindow(qt_xdisplay(), root, 0, 0,
|
||||
desktop_client->width(),
|
||||
desktop_client->height(),
|
||||
0,
|
||||
CopyFromParent, CopyFromParent,
|
||||
CopyFromParent, valuemask,
|
||||
&attributes);
|
||||
XMapWindow(qt_xdisplay(), rw);
|
||||
XDestroyWindow(qt_xdisplay(), rw);
|
||||
XFlush(qt_xdisplay());
|
||||
QWidget w( 0, 0, WX11BypassWM );
|
||||
w.setGeometry( QApplication::desktop()->geometry() );
|
||||
w.show();
|
||||
w.hide();
|
||||
QApplication::flushX();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -2517,12 +2513,12 @@ void Workspace::setCurrentDesktop( int new_desktop ){
|
|||
} else {
|
||||
focusToNull();
|
||||
}
|
||||
if( desktop_client ) {
|
||||
if( !desktops.isEmpty() ) {
|
||||
Window w_tmp;
|
||||
int i_tmp;
|
||||
XGetInputFocus( qt_xdisplay(), &w_tmp, &i_tmp );
|
||||
if( w_tmp == null_focus_window )
|
||||
requestFocus( desktop_client );
|
||||
requestFocus( desktops.last() );
|
||||
}
|
||||
|
||||
// Update focus chain:
|
||||
|
@ -2882,19 +2878,6 @@ void Workspace::slotSwitchToDesktop( int i )
|
|||
setCurrentDesktop( i );
|
||||
}
|
||||
|
||||
/*void Workspace::slotSwitchToWindow( int i )
|
||||
{
|
||||
int n = 0;
|
||||
for ( ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it) {
|
||||
if( (*it)->isOnDesktop( currentDesktop() ) ) {
|
||||
if( n == i ) {
|
||||
activateClient( (*it) );
|
||||
break;
|
||||
}
|
||||
n++;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
void Workspace::slotWindowToDesktop( int i )
|
||||
{
|
||||
|
@ -3297,7 +3280,7 @@ QPoint Workspace::adjustClientPosition( Client* c, QPoint pos )
|
|||
QValueList<Client *>::ConstIterator l;
|
||||
for (l = clients.begin();l != clients.end();++l )
|
||||
{
|
||||
if ((*l)->isOnDesktop(currentDesktop()) && (*l) != desktop_client &&
|
||||
if ((*l)->isOnDesktop(currentDesktop()) &&
|
||||
!(*l)->isIconified()
|
||||
#if 0
|
||||
&& (*l)->transientFor() == None
|
||||
|
@ -3596,8 +3579,8 @@ void Workspace::slotResetAllClients()
|
|||
block_focus = FALSE;
|
||||
if ( active )
|
||||
requestFocus( active );
|
||||
else if( desktop_client )
|
||||
requestFocus( desktop_client );
|
||||
else if( !desktops.isEmpty() )
|
||||
requestFocus( desktops.last() );
|
||||
else
|
||||
focusToNull();
|
||||
|
||||
|
|
11
workspace.h
11
workspace.h
|
@ -206,8 +206,6 @@ public:
|
|||
QPopupMenu* clientPopup( Client* );
|
||||
void showWindowMenuAt( unsigned long id, int x, int y );
|
||||
|
||||
void setDesktopClient( Client* );
|
||||
|
||||
void iconifyOrDeiconifyTransientsOf( Client* );
|
||||
void setStickyTransientsOf( Client*, bool sticky );
|
||||
|
||||
|
@ -229,8 +227,9 @@ public:
|
|||
void unclutterDesktop();
|
||||
void doNotManage(QString);
|
||||
void setCurrentDesktop( int new_desktop );
|
||||
void nextDesktop();
|
||||
void previousDesktop();
|
||||
void nextDesktop();
|
||||
void previousDesktop();
|
||||
void circulateDesktopApplications();
|
||||
|
||||
QString desktopName( int desk );
|
||||
void setDesktopLayout(int o, int x, int y);
|
||||
|
@ -389,13 +388,13 @@ private:
|
|||
void writeFakeSessionInfo();
|
||||
QValueList<CascadingInfo> cci;
|
||||
|
||||
Client* desktop_client;
|
||||
Client* active_client;
|
||||
Client* last_active_client;
|
||||
Client* should_get_focus;
|
||||
Client* most_recently_raised;
|
||||
|
||||
ClientList clients;
|
||||
ClientList desktops;
|
||||
ClientList stacking_order;
|
||||
ClientList focus_chain;
|
||||
|
||||
|
@ -449,6 +448,8 @@ private:
|
|||
XineramaScreenInfo *xineramaInfo;
|
||||
XineramaScreenInfo dummy_xineramaInfo;
|
||||
#endif
|
||||
|
||||
void addClient( Client* c );
|
||||
};
|
||||
|
||||
inline WId Workspace::rootWin() const
|
||||
|
|
Loading…
Reference in a new issue