71 #include "workspace.h"
76 namespace KWinInternal
83 void Workspace::updateClientLayer( Client* c )
87 if( c->layer() == c->belongsToLayer())
89 StackingUpdatesBlocker blocker(
this );
91 for( ClientList::ConstIterator it = c->transients().begin();
92 it != c->transients().end();
94 updateClientLayer( *it );
97 void Workspace::updateStackingOrder(
bool propagate_new_clients )
99 if( block_stacking_updates > 0 )
101 blocked_propagating_new_clients = blocked_propagating_new_clients || propagate_new_clients;
104 ClientList new_stacking_order = constrainedStackingOrder();
105 bool changed = ( new_stacking_order != stacking_order );
106 stacking_order = new_stacking_order;
108 kdDebug() <<
"stacking:" << changed << endl;
109 if( changed || propagate_new_clients )
111 for( ClientList::ConstIterator it = stacking_order.begin();
112 it != stacking_order.end();
114 kdDebug() << (
void*)(*it) << *it <<
":" << (*it)->layer() << endl;
117 if( changed || propagate_new_clients )
119 propagateClients( propagate_new_clients );
121 active_client->updateMouseGrab();
129 void Workspace::propagateClients(
bool propagate_new_clients )
136 Window* new_stack =
new Window[ stacking_order.count() + 2 ];
141 Window *dock_shadow_stack, *window_stack;
142 int i, numDocks, pos, topmenu_space_pos;
144 dock_shadow_stack =
new Window[ stacking_order.count() * 2 ];
145 window_stack =
new Window[ stacking_order.count() * 2 + 2 ];
148 topmenu_space_pos = 1;
156 new_stack[ pos++ ] = supportWindow->winId();
157 int topmenu_space_pos = 1;
159 window_stack[pos++] = supportWindow->winId();
160 for( ClientList::ConstIterator it = stacking_order.fromLast();
161 it != stacking_order.end();
165 new_stack[ pos++ ] = (*it)->frameId();
166 if( (*it)->belongsToLayer() >= DockLayer )
167 topmenu_space_pos = pos;
169 t = (*it)->windowType();
173 window_stack[pos++] = (*it)->frameId();
174 if ((shadow = (*it)->shadowId()) != None)
175 dock_shadow_stack[i++] = shadow;
179 for (i = 0; i < numDocks; i++)
181 window_stack[pos++] = dock_shadow_stack[i];
182 window_stack[pos++] = (*it)->frameId();
185 topmenu_space_pos = pos;
188 window_stack[pos++] = (*it)->frameId();
189 if ((shadow = (*it)->shadowId()) != None)
192 window_stack[pos++] = shadow;
195 if( topmenu_space != NULL )
198 i > topmenu_space_pos;
201 new_stack[ i ] = new_stack[ i - 1 ];
202 new_stack[ topmenu_space_pos ] = topmenu_space->winId();
204 window_stack[ i ] = window_stack[ i - 1 ];
205 window_stack[ topmenu_space_pos ] = topmenu_space->winId();
211 assert( new_stack[ 0 ] = supportWindow->winId());
214 XRestackWindows(tqt_xdisplay(), new_stack, pos);
217 XRestackWindows(tqt_xdisplay(), window_stack, pos);
218 delete [] dock_shadow_stack;
219 delete [] window_stack;
221 if ( propagate_new_clients )
223 cl =
new Window[ desktops.count() + clients.count()];
226 for ( ClientList::ConstIterator it = desktops.begin(); it != desktops.end(); ++it )
227 cl[pos++] = (*it)->window();
228 for ( ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it )
229 cl[pos++] = (*it)->window();
230 rootInfo->setClientList( cl, pos );
234 cl =
new Window[ stacking_order.count()];
236 for ( ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it)
237 cl[pos++] = (*it)->window();
238 rootInfo->setClientListStacking( cl, pos );
249 Client* Workspace::topClientOnDesktop(
int desktop,
bool unconstrained,
bool only_normal )
const
252 ClientList::ConstIterator begin, end;
255 begin = stacking_order.fromLast();
256 end = stacking_order.end();
260 begin = unconstrained_stacking_order.fromLast();
261 end = unconstrained_stacking_order.end();
263 for( ClientList::ConstIterator it = begin;
267 if( (*it)->isOnDesktop( desktop ) && (*it)->isShown(
false ))
271 if( (*it)->wantsTabFocus() && !(*it)->isSpecialWindow())
278 Client* Workspace::findDesktop(
bool topmost,
int desktop )
const
283 for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it)
285 if ( (*it)->isOnDesktop( desktop ) && (*it)->isDesktop()
286 && (*it)->isShown(
true ))
292 for ( ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it)
294 if ( (*it)->isOnDesktop( desktop ) && (*it)->isDesktop()
295 && (*it)->isShown(
true ))
302 void Workspace::raiseOrLowerClient( Client *c)
305 Client* topmost = NULL;
307 if ( most_recently_raised && stacking_order.contains( most_recently_raised ) &&
308 most_recently_raised->isShown(
true ) && c->isOnCurrentDesktop())
309 topmost = most_recently_raised;
311 topmost = topClientOnDesktop( c->isOnAllDesktops() ? currentDesktop() : c->desktop());
320 void Workspace::lowerClient( Client* c )
327 c->cancelAutoRaise();
329 StackingUpdatesBlocker blocker(
this );
331 unconstrained_stacking_order.remove( c );
332 unconstrained_stacking_order.prepend( c );
333 if( c->isTransient())
336 ClientList mainclients = ensureStackingOrder( c->mainClients());
337 for( ClientList::ConstIterator it = mainclients.fromLast();
338 it != mainclients.end();
343 if ( c == most_recently_raised )
344 most_recently_raised = 0;
347 void Workspace::lowerClientWithinApplication( Client* c )
354 c->cancelAutoRaise();
356 StackingUpdatesBlocker blocker(
this );
358 unconstrained_stacking_order.remove( c );
359 bool lowered =
false;
361 for( ClientList::Iterator it = unconstrained_stacking_order.begin();
362 it != unconstrained_stacking_order.end();
364 if( Client::belongToSameApplication( *it, c ))
366 unconstrained_stacking_order.insert( it, c );
371 unconstrained_stacking_order.prepend( c );
375 void Workspace::raiseClient( Client* c )
382 c->cancelAutoRaise();
384 StackingUpdatesBlocker blocker(
this );
386 if( c->isTransient())
388 ClientList mainclients = ensureStackingOrder( c->mainClients());
389 for( ClientList::ConstIterator it = mainclients.begin();
390 it != mainclients.end();
395 unconstrained_stacking_order.remove( c );
396 unconstrained_stacking_order.append( c );
397 if (options->shadowEnabled(c->isActive()))
400 c->drawDelayedShadow();
403 if( !c->isSpecialWindow())
405 most_recently_raised = c;
406 pending_take_activity = NULL;
410 void Workspace::raiseClientWithinApplication( Client* c )
417 c->cancelAutoRaise();
419 StackingUpdatesBlocker blocker(
this );
423 for( ClientList::Iterator it = unconstrained_stacking_order.fromLast();
424 it != unconstrained_stacking_order.end();
429 if( Client::belongToSameApplication( *it, c ))
431 unconstrained_stacking_order.remove( c );
433 unconstrained_stacking_order.insert( it, c );
439 void Workspace::raiseClientRequest( Client* c, NET::RequestSource src, Time timestamp )
441 if( src == NET::FromTool || allowFullClientRaising( c, timestamp ))
445 raiseClientWithinApplication( c );
446 c->demandAttention();
450 void Workspace::lowerClientRequest( Client* c, NET::RequestSource src, Time )
456 if( src == NET::FromTool || !c->hasUserTimeSupport())
459 lowerClientWithinApplication( c );
462 void Workspace::restackClientUnderActive( Client* c )
466 if( !active_client || active_client == c )
472 assert( unconstrained_stacking_order.contains( active_client ));
473 if( Client::belongToSameApplication( active_client, c ))
475 unconstrained_stacking_order.remove( c );
476 unconstrained_stacking_order.insert( unconstrained_stacking_order.find( active_client ), c );
480 for( ClientList::Iterator it = unconstrained_stacking_order.begin();
481 it != unconstrained_stacking_order.end();
484 if( Client::belongToSameApplication( active_client, *it ))
488 unconstrained_stacking_order.remove( c );
489 unconstrained_stacking_order.insert( it, c );
495 assert( unconstrained_stacking_order.contains( c ));
496 for(
int desktop = 1;
497 desktop <= numberOfDesktops();
500 if( c->wantsTabFocus() && c->isOnDesktop( desktop ) && focus_chain[ desktop ].contains( active_client ))
502 if( Client::belongToSameApplication( active_client, c ))
504 focus_chain[ desktop ].remove( c );
505 focus_chain[ desktop ].insert( focus_chain[ desktop ].find( active_client ), c );
509 focus_chain[ desktop ].remove( c );
510 for( ClientList::Iterator it = focus_chain[ desktop ].fromLast();
511 it != focus_chain[ desktop ].end();
514 if( Client::belongToSameApplication( active_client, *it ))
516 focus_chain[ desktop ].insert( it, c );
524 if( c->wantsTabFocus() && global_focus_chain.contains( active_client ))
526 if( Client::belongToSameApplication( active_client, c ))
528 global_focus_chain.remove( c );
529 global_focus_chain.insert( global_focus_chain.find( active_client ), c );
533 global_focus_chain.remove( c );
534 for( ClientList::Iterator it = global_focus_chain.fromLast();
535 it != global_focus_chain.end();
538 if( Client::belongToSameApplication( active_client, *it ))
540 global_focus_chain.insert( it, c );
546 updateStackingOrder();
549 void Workspace::circulateDesktopApplications()
551 if ( desktops.count() > 1 )
553 bool change_active = activeClient()->isDesktop();
554 raiseClient( findDesktop(
false, currentDesktop()));
556 activateClient( findDesktop(
true, currentDesktop()));
559 if( desktops.count() > 0 && activeClient() == NULL && should_get_focus.count() == 0 )
560 activateClient( findDesktop(
true, currentDesktop()));
567 ClientList Workspace::constrainedStackingOrder()
569 ClientList layer[ NumLayers ];
572 kdDebug() <<
"stacking1:" << endl;
575 TQMap< Group*, Layer > minimum_layer;
576 for( ClientList::ConstIterator it = unconstrained_stacking_order.begin();
577 it != unconstrained_stacking_order.end();
580 Layer l = (*it)->layer();
584 if( minimum_layer.contains( (*it)->group())
585 && minimum_layer[ (*it)->group() ] == ActiveLayer
586 && ( l == NormalLayer || l == AboveLayer ))
588 l = minimum_layer[ (*it)->group() ];
590 minimum_layer[ (*it)->group() ] = l;
591 layer[ l ].append( *it );
594 for( Layer lay = FirstLayer;
597 stacking += layer[ lay ];
599 kdDebug() <<
"stacking2:" << endl;
600 for( ClientList::ConstIterator it = stacking.begin();
601 it != stacking.end();
603 kdDebug() << (
void*)(*it) << *it <<
":" << (*it)->layer() << endl;
607 for( ClientList::Iterator it = stacking.fromLast();
608 it != stacking.end();
611 if( !(*it)->isTransient())
616 ClientList::Iterator it2 = stacking.end();
617 if( (*it)->groupTransient())
619 if( (*it)->group()->members().count() > 0 )
621 for( it2 = stacking.fromLast();
622 it2 != stacking.end();
627 it2 = stacking.end();
630 if( (*it2)->hasTransient( *it,
true ) && keepTransientAbove( *it2, *it ))
637 for( it2 = stacking.fromLast();
638 it2 != stacking.end();
643 it2 = stacking.end();
646 if( *it2 == (*it)->transientFor() && keepTransientAbove( *it2, *it ))
651 if( it2 == stacking.end())
656 Client* current = *it;
657 ClientList::Iterator remove_it = it;
659 stacking.remove( remove_it );
660 if( !current->transients().isEmpty())
663 stacking.insert( it2, current );
666 kdDebug() <<
"stacking3:" << endl;
667 for( ClientList::ConstIterator it = stacking.begin();
668 it != stacking.end();
670 kdDebug() << (
void*)(*it) << *it <<
":" << (*it)->layer() << endl;
671 kdDebug() <<
"\n\n" << endl;
676 void Workspace::blockStackingUpdates(
bool block )
680 if( block_stacking_updates == 0 )
681 blocked_propagating_new_clients =
false;
682 ++block_stacking_updates;
685 if( --block_stacking_updates == 0 )
686 updateStackingOrder( blocked_propagating_new_clients );
690 ClientList Workspace::ensureStackingOrder(
const ClientList& list )
const
693 if( list.count() < 2 )
696 ClientList result = list;
697 for( ClientList::ConstIterator it = stacking_order.begin();
698 it != stacking_order.end();
700 if( result.remove( *it ) != 0 )
701 result.append( *it );
707 bool Workspace::keepTransientAbove(
const Client* mainwindow,
const Client*
transient )
713 if( mainwindow->isTopMenu() &&
transient->groupTransient())
716 if( transient->isSplash() && mainwindow->isDialog())
722 if( transient->isDialog() && !
transient->isModal() &&
transient->groupTransient())
726 if( mainwindow->isDock())
735 void Client::restackWindow( Window ,
int detail, NET::RequestSource src, Time timestamp,
bool send_event )
741 workspace()->raiseClientRequest(
this, src, timestamp );
745 workspace()->lowerClientRequest(
this, src, timestamp );
752 sendSyntheticConfigureNotify();
755 void Client::setKeepAbove(
bool b )
757 b = rules()->checkKeepAbove( b );
758 if( b && !rules()->checkKeepBelow(
false ))
759 setKeepBelow(
false );
762 if(
bool( info->state() & NET::KeepAbove ) !=
keepAbove())
763 info->setState(
keepAbove() ? NET::KeepAbove : 0, NET::KeepAbove );
767 info->setState(
keepAbove() ? NET::KeepAbove : 0, NET::KeepAbove );
768 if( decoration != NULL )
769 decoration->emitKeepAboveChanged(
keepAbove());
770 workspace()->updateClientLayer(
this );
774 void Client::setKeepBelow(
bool b )
776 b = rules()->checkKeepBelow( b );
777 if( b && !rules()->checkKeepAbove(
false ))
778 setKeepAbove(
false );
779 if ( b == keepBelow())
781 if(
bool( info->state() & NET::KeepBelow ) != keepBelow())
782 info->setState( keepBelow() ? NET::KeepBelow : 0, NET::KeepBelow );
786 info->setState( keepBelow() ? NET::KeepBelow : 0, NET::KeepBelow );
787 if( decoration != NULL )
788 decoration->emitKeepBelowChanged( keepBelow());
789 workspace()->updateClientLayer(
this );
793 Layer Client::layer()
const
795 if( in_layer == UnknownLayer )
796 const_cast< Client*
>( this )->in_layer = belongsToLayer();
800 Layer Client::belongsToLayer()
const
806 if( isDock() && keepBelow())
813 if( isDock() && !keepBelow())
819 const Client* ac = workspace()->mostRecentlyActivatedClient();
820 const Client* top = workspace()->topClientOnDesktop(
desktop(),
true,
false );
821 if( isFullScreen() && ac != NULL && top != NULL
822 && ( ac ==
this || this->group() == ac->group())
823 && ( top ==
this || this->group() == top->group()))