19 #include <tqpopupmenu.h>
20 #include <kxerrorhandler.h>
21 #include <kstartupinfo.h>
22 #include <kstringhandler.h>
26 #include "workspace.h"
29 #include "notifications.h"
34 namespace KWinInternal
214 void Workspace::setActiveClient( Client* c, allowed_t )
216 if ( active_client == c )
218 if( active_popup && active_popup_client != c && set_active_client_recursion == 0 )
220 StackingUpdatesBlocker blocker(
this );
221 ++set_active_client_recursion;
222 updateFocusMousePosition( TQCursor::pos());
223 if( active_client != NULL )
225 active_client->setActive(
false, !c || !c->isModal() || c != active_client->transientFor() );
228 if (set_active_client_recursion == 1)
233 next_active_client = NULL;
235 Q_ASSERT( c == NULL || c->isActive());
236 if( active_client != NULL )
237 last_active_client = active_client;
240 updateFocusChains( active_client, FocusChainMakeFirst );
241 active_client->demandAttention(
false );
243 pending_take_activity = NULL;
245 updateCurrentTopMenu();
246 updateToolWindows(
false );
248 disableGlobalShortcutsForClient( c->rules()->checkDisableGlobalShortcuts(
false ));
250 disableGlobalShortcutsForClient(
false );
252 updateStackingOrder();
254 rootInfo->setActiveWindow( active_client? active_client->window() : 0 );
256 --set_active_client_recursion;
270 void Workspace::activateClient( Client* c,
bool force )
275 setActiveClient( NULL, Allowed );
279 if (!c->isOnDesktop(currentDesktop()) )
282 setCurrentDesktop( c->desktop() );
285 if( c->isMinimized())
289 if( options->focusPolicyIsReasonable() || force )
290 requestFocus( c, force );
299 if( !c->ignoreFocusStealing())
310 void Workspace::requestFocus( Client* c,
bool force )
312 takeActivity( c, ActivityFocus | ( force ? ActivityFocusForce : 0 ),
false);
315 void Workspace::takeActivity( Client* c,
int flags,
bool handled )
318 if (!focusChangeEnabled() && ( c != active_client) )
319 flags &= ~ActivityFocus;
327 if( flags & ActivityFocus )
329 Client* modal = c->findModal();
330 if( modal != NULL && modal != c )
332 next_active_client = modal;
333 if( !modal->isOnDesktop( c->desktop()))
335 modal->setDesktop( c->desktop());
336 if( modal->desktop() != c->desktop())
337 activateClient( modal );
343 if( flags & ActivityRaise )
350 if ( !( flags & ActivityFocusForce ) && ( c->isTopMenu() || c->isDock() || c->isSplash()) )
351 flags &= ~ActivityFocus;
354 if( c->wantsInput() && ( flags & ActivityFocus ))
357 c->setActive(
true );
361 next_active_client = c;
362 flags &= ~ActivityFocus;
365 if( !c->isShown(
true ))
367 next_active_client = c;
368 kdWarning( 1212 ) <<
"takeActivity: not shown" << endl;
371 c->takeActivity( flags, handled, Allowed );
372 if( !c->isOnScreen( active_screen ))
373 active_screen = c->screen();
376 void Workspace::handleTakeActivity( Client* c, Time ,
int flags )
378 if( pending_take_activity != c )
380 if(( flags & ActivityRaise ) != 0 )
382 if(( flags & ActivityFocus ) != 0 && c->isShown(
false ))
383 c->takeFocus( Allowed );
384 pending_take_activity = NULL;
394 void Workspace::clientHidden( Client* c )
396 assert( !c->isShown(
true ) || !c->isOnCurrentDesktop());
397 activateNextClient( c );
401 bool Workspace::activateNextClient( Client* c )
404 if( !( c == active_client
405 || ( should_get_focus.count() > 0 && c == should_get_focus.last())))
410 if( c == active_client )
411 setActiveClient( NULL, Allowed );
412 should_get_focus.remove( c );
414 if( focusChangeEnabled())
416 if ( options->focusPolicyIsReasonable())
419 Client* get_focus = NULL;
420 const ClientList mainwindows = ( c != NULL ? c->mainClients() : ClientList());
421 for( ClientList::ConstIterator it = focus_chain[currentDesktop()].fromLast();
422 it != focus_chain[currentDesktop()].end();
425 if( !(*it)->isShown(
false ) || !(*it)->isOnCurrentDesktop())
427 if( options->separateScreenFocus )
429 if( c != NULL && !(*it)->isOnScreen( c->screen()))
431 if( c == NULL && !(*it)->isOnScreen( activeScreen()))
434 if( mainwindows.contains( *it ))
439 if( get_focus == NULL )
442 if( get_focus == NULL )
443 get_focus = findDesktop(
true, currentDesktop());
444 if( get_focus != NULL )
445 requestFocus( get_focus );
459 void Workspace::setCurrentScreen(
int new_screen )
461 if (new_screen < 0 || new_screen > numScreens())
463 if ( !options->focusPolicyIsReasonable())
466 Client* get_focus = NULL;
467 for( ClientList::ConstIterator it = focus_chain[currentDesktop()].fromLast();
468 it != focus_chain[currentDesktop()].end();
471 if( !(*it)->isShown(
false ) || !(*it)->isOnCurrentDesktop())
473 if( !(*it)->screen() == new_screen )
478 if( get_focus == NULL )
479 get_focus = findDesktop(
true, currentDesktop());
480 if( get_focus != NULL && get_focus != mostRecentlyActivatedClient())
481 requestFocus( get_focus );
482 active_screen = new_screen;
485 void Workspace::gotFocusIn(
const Client* c )
487 if( should_get_focus.contains( const_cast< Client* >( c )))
490 while( should_get_focus.first() != c )
491 should_get_focus.pop_front();
492 should_get_focus.pop_front();
496 void Workspace::setShouldGetFocus( Client* c )
498 should_get_focus.append( c );
499 updateStackingOrder();
504 bool Workspace::allowClientActivation(
const Client* c, Time time,
bool focus_in )
515 time = c->userTime();
516 int level = c->rules()->checkFSP( options->focusStealingPreventionLevel );
517 if( session_saving && level <= 2 )
521 Client* ac = mostRecentlyActivatedClient();
524 if( should_get_focus.contains( const_cast< Client* >( c )))
528 ac = last_active_client;
536 if( !c->isOnCurrentDesktop())
538 if( c->ignoreFocusStealing())
540 if( ac == NULL || ac->isDesktop())
546 if( Client::belongToSameApplication( c, ac,
true ))
564 Time user_time = ac->userTime();
567 return timestampCompare( time, user_time ) >= 0;
574 bool Workspace::allowFullClientRaising(
const Client* c, Time time )
576 int level = c->rules()->checkFSP( options->focusStealingPreventionLevel );
577 if( session_saving && level <= 2 )
581 Client* ac = mostRecentlyActivatedClient();
586 if( ac == NULL || ac->isDesktop())
591 if( c->ignoreFocusStealing())
594 if( Client::belongToSameApplication( c, ac,
true ))
601 Time user_time = ac->userTime();
604 return timestampCompare( time, user_time ) >= 0;
609 void Workspace::restoreFocus()
616 if( should_get_focus.count() > 0 )
617 requestFocus( should_get_focus.last());
618 else if( last_active_client )
619 requestFocus( last_active_client );
622 void Workspace::clientAttentionChanged( Client* c,
bool set )
626 attention_chain.remove( c );
627 attention_chain.prepend( c );
630 attention_chain.remove( c );
636 bool Workspace::fakeRequestedActivity( Client* c )
638 if( should_get_focus.count() > 0 && should_get_focus.last() == c )
642 c->setActive(
true );
648 void Workspace::unfakeActivity( Client* c )
650 if( should_get_focus.count() > 0 && should_get_focus.last() == c )
652 if( last_active_client != NULL )
653 last_active_client->setActive(
true );
655 c->setActive(
false );
672 if( time == CurrentTime )
673 time = GET_QT_X_TIME();
675 && ( user_time == CurrentTime
676 || timestampCompare( time, user_time ) > 0 ))
678 group()->updateUserTime( user_time );
681 Time Client::readUserCreationTime()
const
686 unsigned long nitems = 0;
687 unsigned long extra = 0;
688 unsigned char *data = 0;
689 KXErrorHandler handler;
690 status = XGetWindowProperty( qt_xdisplay(), window(),
691 atoms->kde_net_wm_user_creation_time, 0, 10000, FALSE, XA_CARDINAL,
692 &type, &format, &nitems, &extra, &data );
693 if (status == Success )
695 if (data && nitems > 0)
696 result = *((
long*) data);
702 void Client::demandAttention(
bool set )
706 if( demands_attention ==
set )
708 demands_attention =
set;
709 if( demands_attention )
717 Notify::Event e = isOnCurrentDesktop() ? Notify::DemandAttentionCurrent : Notify::DemandAttentionOther;
720 if( Notify::makeDemandAttention( e ))
721 info->setState(
set ? NET::DemandsAttention : 0, NET::DemandsAttention );
723 if( demandAttentionKNotifyTimer == NULL )
725 demandAttentionKNotifyTimer =
new TQTimer(
this );
726 connect( demandAttentionKNotifyTimer, TQT_SIGNAL( timeout()), TQT_SLOT( demandAttentionKNotify()));
728 demandAttentionKNotifyTimer->start( 1000,
true );
731 info->setState(
set ? NET::DemandsAttention : 0, NET::DemandsAttention );
732 workspace()->clientAttentionChanged(
this,
set );
735 void Client::demandAttentionKNotify()
737 Notify::Event e = isOnCurrentDesktop() ? Notify::DemandAttentionCurrent : Notify::DemandAttentionOther;
738 Notify::raise( e, i18n(
"Window '%1' demands attention." ).arg( KStringHandler::csqueeze(
caption())),
this );
739 demandAttentionKNotifyTimer->stop();
740 demandAttentionKNotifyTimer->deleteLater();
741 demandAttentionKNotifyTimer = NULL;
745 KWIN_COMPARE_PREDICATE( SameApplicationActiveHackPredicate,
const Client*,
748 !cl->isSplash() && !cl->isToolbar() && !cl->isTopMenu() && !cl->isUtility() && !cl->isMenu()
749 && Client::belongToSameApplication( cl, value,
true ) && cl != value);
751 Time Client::readUserTimeMapTimestamp(
const KStartupInfoId* asn_id,
const KStartupInfoData* asn_data,
754 Time time = info->userTime();
758 if( asn_data != NULL && time != 0 )
761 if( asn_id->timestamp() != 0
762 && ( time == -1U || timestampCompare( asn_id->timestamp(), time ) > 0 ))
764 time = asn_id->timestamp();
766 else if( asn_data->timestamp() != -1U
767 && ( time == -1U || timestampCompare( asn_data->timestamp(), time ) > 0 ))
769 time = asn_data->timestamp();
781 Client* act = workspace()->mostRecentlyActivatedClient();
782 if( act != NULL && !belongToSameApplication( act,
this,
true ))
784 bool first_window =
true;
787 if( act->hasTransient(
this,
true ))
790 else if( groupTransient() &&
791 findClientInList( mainClients(), SameApplicationActiveHackPredicate(
this )) == NULL )
794 first_window =
false;
798 if( workspace()->findClient( SameApplicationActiveHackPredicate(
this )))
799 first_window =
false;
802 if( !first_window && rules()->checkFSP( options->focusStealingPreventionLevel ) > 0 )
819 if( ignoreFocusStealing() && act != NULL )
820 time = act->userTime();
822 time = readUserCreationTime();
828 Time Client::userTime()
const
830 Time time = user_time;
833 assert( group() != NULL );
835 || ( group()->userTime() != -1U
836 && timestampCompare( group()->userTime(), time ) > 0 ))
837 time = group()->userTime();
857 workspace()->setActiveClient( act ?
this : NULL, Allowed );
859 if (updateOpacity_) updateOpacity();
860 if (isModal() && transientFor())
862 if (!act) transientFor()->updateOpacity();
863 else if (!transientFor()->custom_opacity) transientFor()->setOpacity(options->translucentActiveWindows, options->activeWindowOpacity);
869 Notify::raise( Notify::Activate );
870 if (options->shadowEnabled(
true))
872 if (options->shadowEnabled(
false))
879 this != workspace()->topClientOnDesktop(
desktop()))
883 drawOverlappingShadows(
true);
893 if (options->shadowEnabled(
false))
894 if (
this == workspace()->topClientOnDesktop(
desktop()))
901 if ((shadowAfterClient = workspace()->activeClient()))
902 drawShadowAfter(shadowAfterClient);
911 if( !active && shade_mode == ShadeActivated )
912 setShade( ShadeNormal );
914 StackingUpdatesBlocker blocker( workspace());
915 workspace()->updateClientLayer(
this );
917 ClientList mainclients = mainClients();
918 for( ClientList::ConstIterator it = mainclients.begin();
919 it != mainclients.end();
921 if( (*it)->isFullScreen())
922 workspace()->updateClientLayer( *it );
923 if( decoration != NULL )
924 decoration->activeChange();
929 void Client::startupIdChanged()
931 KStartupInfoId asn_id;
932 KStartupInfoData asn_data;
933 bool asn_valid = workspace()->checkStartupNotification( window(), asn_id, asn_data );
939 int desktop = workspace()->currentDesktop();
940 if( asn_data.desktop() != 0 )
941 desktop = asn_data.desktop();
942 if( !isOnAllDesktops())
943 workspace()->sendClientToDesktop(
this, desktop,
true );
944 if( asn_data.xinerama() != -1 )
945 workspace()->sendClientToScreen(
this, asn_data.xinerama());
946 Time timestamp = asn_id.timestamp();
947 if( timestamp == 0 && asn_data.timestamp() != -1U )
948 timestamp = asn_data.timestamp();
951 bool activate = workspace()->allowClientActivation(
this, timestamp );
952 if( asn_data.desktop() != 0 && !isOnCurrentDesktop())
955 workspace()->activateClient(
this );
961 void Client::updateUrgency()
967 void Client::shortcutActivated()
969 workspace()->activateClient(
this,
true );
976 void Group::startupIdChanged()
978 KStartupInfoId asn_id;
979 KStartupInfoData asn_data;
980 bool asn_valid = workspace()->checkStartupNotification( leader_wid, asn_id, asn_data );
983 if( asn_id.timestamp() != 0 && user_time != -1U
984 && timestampCompare( asn_id.timestamp(), user_time ) > 0 )
986 user_time = asn_id.timestamp();
988 else if( asn_data.timestamp() != -1U && user_time != -1U
989 && timestampCompare( asn_data.timestamp(), user_time ) > 0 )
991 user_time = asn_data.timestamp();
995 void Group::updateUserTime( Time time )
997 if( time == CurrentTime )
998 time = GET_QT_X_TIME();
1000 && ( user_time == CurrentTime
1001 || timestampCompare( time, user_time ) > 0 ))