19 #include <tqpopupmenu.h>
20 #include <kxerrorhandler.h>
21 #include <tdestartupinfo.h>
22 #include <kstringhandler.h>
23 #include <tdelocale.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 )
412 setActiveClient( NULL, Allowed );
414 should_get_focus.remove( c );
416 if( focusChangeEnabled())
418 if ( options->focusPolicyIsReasonable())
421 Client* get_focus = NULL;
422 const ClientList mainwindows = ( c != NULL ? c->mainClients() : ClientList());
423 for( ClientList::ConstIterator it = focus_chain[currentDesktop()].fromLast();
424 it != focus_chain[currentDesktop()].end();
427 if( !(*it)->isShown(
false ) || !(*it)->isOnCurrentDesktop())
429 if( options->separateScreenFocus )
431 if( c != NULL && !(*it)->isOnScreen( c->screen()))
433 if( c == NULL && !(*it)->isOnScreen( activeScreen()))
436 if( mainwindows.contains( *it ))
441 if( get_focus == NULL )
444 if( get_focus == NULL )
445 get_focus = findDesktop(
true, currentDesktop());
446 if( get_focus != NULL )
448 requestFocus( get_focus );
463 void Workspace::setCurrentScreen(
int new_screen )
465 if (new_screen < 0 || new_screen > numScreens())
467 if ( !options->focusPolicyIsReasonable())
470 Client* get_focus = NULL;
471 for( ClientList::ConstIterator it = focus_chain[currentDesktop()].fromLast();
472 it != focus_chain[currentDesktop()].end();
475 if( !(*it)->isShown(
false ) || !(*it)->isOnCurrentDesktop())
477 if( !(*it)->screen() == new_screen )
482 if( get_focus == NULL )
483 get_focus = findDesktop(
true, currentDesktop());
484 if( get_focus != NULL && get_focus != mostRecentlyActivatedClient())
485 requestFocus( get_focus );
486 active_screen = new_screen;
489 void Workspace::gotFocusIn(
const Client* c )
491 if( should_get_focus.contains(
const_cast< Client*
>( c )))
494 while( should_get_focus.first() != c )
495 should_get_focus.pop_front();
496 should_get_focus.pop_front();
500 void Workspace::setShouldGetFocus( Client* c )
502 should_get_focus.append( c );
503 updateStackingOrder();
508 bool Workspace::allowClientActivation(
const Client* c, Time time,
bool focus_in )
519 time = c->userTime();
520 int level = c->rules()->checkFSP( options->focusStealingPreventionLevel );
521 if( session_saving && level <= 2 )
525 Client* ac = mostRecentlyActivatedClient();
528 if( should_get_focus.contains(
const_cast< Client*
>( c )))
532 ac = last_active_client;
540 if( !c->isOnCurrentDesktop())
542 if( c->ignoreFocusStealing())
544 if( ac == NULL || ac->isDesktop())
550 if( Client::belongToSameApplication( c, ac,
true ))
568 Time user_time = ac->userTime();
571 return timestampCompare( time, user_time ) >= 0;
578 bool Workspace::allowFullClientRaising(
const Client* c, Time time )
580 int level = c->rules()->checkFSP( options->focusStealingPreventionLevel );
581 if( session_saving && level <= 2 )
585 Client* ac = mostRecentlyActivatedClient();
590 if( ac == NULL || ac->isDesktop())
595 if( c->ignoreFocusStealing())
598 if( Client::belongToSameApplication( c, ac,
true ))
605 Time user_time = ac->userTime();
608 return timestampCompare( time, user_time ) >= 0;
613 void Workspace::restoreFocus()
620 if( should_get_focus.count() > 0 )
621 requestFocus( should_get_focus.last());
622 else if( last_active_client )
623 requestFocus( last_active_client );
626 void Workspace::clientAttentionChanged( Client* c,
bool set )
630 attention_chain.remove( c );
631 attention_chain.prepend( c );
634 attention_chain.remove( c );
640 bool Workspace::fakeRequestedActivity( Client* c )
642 if( should_get_focus.count() > 0 && should_get_focus.last() == c )
646 c->setActive(
true );
652 void Workspace::unfakeActivity( Client* c )
654 if( should_get_focus.count() > 0 && should_get_focus.last() == c )
656 if( last_active_client != NULL )
657 last_active_client->setActive(
true );
659 c->setActive(
false );
676 if( time == CurrentTime )
677 time = get_tqt_x_time();
679 && ( user_time == CurrentTime
680 || timestampCompare( time, user_time ) > 0 ))
682 group()->updateUserTime( user_time );
685 Time Client::readUserCreationTime()
const
690 unsigned long nitems = 0;
691 unsigned long extra = 0;
692 unsigned char *data = 0;
693 KXErrorHandler handler;
694 status = XGetWindowProperty( tqt_xdisplay(), window(),
695 atoms->kde_net_wm_user_creation_time, 0, 10000, FALSE, XA_CARDINAL,
696 &type, &format, &nitems, &extra, &data );
697 if (status == Success )
699 if (data && nitems > 0)
700 result = *((
long*) data);
706 void Client::demandAttention(
bool set )
710 if( demands_attention == set )
712 demands_attention = set;
713 if( demands_attention )
721 Notify::Event e = isOnCurrentDesktop() ? Notify::DemandAttentionCurrent : Notify::DemandAttentionOther;
724 if( Notify::makeDemandAttention( e ))
725 info->setState( set ? NET::DemandsAttention : 0, NET::DemandsAttention );
727 if( demandAttentionKNotifyTimer == NULL )
729 demandAttentionKNotifyTimer =
new TQTimer(
this );
730 connect( demandAttentionKNotifyTimer, TQ_SIGNAL( timeout()), TQ_SLOT( demandAttentionKNotify()));
732 demandAttentionKNotifyTimer->start( 1000,
true );
735 info->setState( set ? NET::DemandsAttention : 0, NET::DemandsAttention );
736 workspace()->clientAttentionChanged(
this, set );
739 void Client::demandAttentionKNotify()
741 Notify::Event e = isOnCurrentDesktop() ? Notify::DemandAttentionCurrent : Notify::DemandAttentionOther;
742 Notify::raise( e, i18n(
"Window '%1' demands attention." ).arg( KStringHandler::csqueeze(
caption())),
this );
743 demandAttentionKNotifyTimer->stop();
744 demandAttentionKNotifyTimer->deleteLater();
745 demandAttentionKNotifyTimer = NULL;
749 KWIN_COMPARE_PREDICATE( SameApplicationActiveHackPredicate,
const Client*,
752 !cl->isSplash() && !cl->isToolbar() && !cl->isTopMenu() && !cl->isUtility() && !cl->isMenu()
753 && Client::belongToSameApplication( cl, value,
true ) && cl != value);
755 Time Client::readUserTimeMapTimestamp(
const TDEStartupInfoId* asn_id,
const TDEStartupInfoData* asn_data,
758 Time time = info->userTime();
762 if( asn_data != NULL && time != 0 )
765 if( asn_id->timestamp() != 0
766 && ( time == -1U || timestampCompare( asn_id->timestamp(), time ) > 0 ))
768 time = asn_id->timestamp();
770 else if( asn_data->timestamp() != -1U
771 && ( time == -1U || timestampCompare( asn_data->timestamp(), time ) > 0 ))
773 time = asn_data->timestamp();
785 Client* act = workspace()->mostRecentlyActivatedClient();
786 if( act != NULL && !belongToSameApplication( act,
this,
true ))
788 bool first_window =
true;
791 if( act->hasTransient(
this,
true ))
794 else if( groupTransient() &&
795 findClientInList( mainClients(), SameApplicationActiveHackPredicate(
this )) == NULL )
798 first_window =
false;
802 if( workspace()->findClient( SameApplicationActiveHackPredicate(
this )))
803 first_window =
false;
806 if( !first_window && rules()->checkFSP( options->focusStealingPreventionLevel ) > 0 )
823 if( ignoreFocusStealing() && act != NULL )
824 time = act->userTime();
826 time = readUserCreationTime();
832 Time Client::userTime()
const
834 Time time = user_time;
837 assert( group() != NULL );
839 || ( group()->userTime() != -1U
840 && timestampCompare( group()->userTime(), time ) > 0 ))
841 time = group()->userTime();
861 workspace()->setActiveClient( act ?
this : NULL, Allowed );
863 if (updateOpacity_) updateOpacity();
864 if (isModal() && transientFor())
866 if (!act) transientFor()->updateOpacity();
867 else if (!transientFor()->custom_opacity) transientFor()->setOpacity(options->translucentActiveWindows, options->activeWindowOpacity);
873 Notify::raise( Notify::Activate );
874 if (options->shadowEnabled(
true))
876 if (options->shadowEnabled(
false))
883 this != workspace()->topClientOnDesktop(
desktop()))
887 drawOverlappingShadows(
true);
897 if (options->shadowEnabled(
false))
899 if (
this == workspace()->topClientOnDesktop(
desktop()))
906 if ((shadowAfterClient = workspace()->activeClient()))
908 drawShadowAfter(shadowAfterClient);
921 if( !active && shade_mode == ShadeActivated )
922 setShade( ShadeNormal );
924 StackingUpdatesBlocker blocker( workspace());
925 workspace()->updateClientLayer(
this );
927 ClientList mainclients = mainClients();
928 for( ClientList::ConstIterator it = mainclients.begin();
929 it != mainclients.end();
931 if( (*it)->isFullScreen())
932 workspace()->updateClientLayer( *it );
933 if( decoration != NULL )
934 decoration->activeChange();
939 void Client::startupIdChanged()
941 TDEStartupInfoId asn_id;
942 TDEStartupInfoData asn_data;
943 bool asn_valid = workspace()->checkStartupNotification( window(), asn_id, asn_data );
949 int desktop = workspace()->currentDesktop();
950 if( asn_data.desktop() != 0 )
952 if( !isOnAllDesktops())
953 workspace()->sendClientToDesktop(
this,
desktop,
true );
954 if( asn_data.xinerama() != -1 )
955 workspace()->sendClientToScreen(
this, asn_data.xinerama());
956 Time timestamp = asn_id.timestamp();
957 if( timestamp == 0 && asn_data.timestamp() != -1U )
958 timestamp = asn_data.timestamp();
961 bool activate = workspace()->allowClientActivation(
this, timestamp );
962 if( asn_data.desktop() != 0 && !isOnCurrentDesktop())
965 workspace()->activateClient(
this );
971 void Client::updateUrgency()
977 void Client::shortcutActivated()
979 workspace()->activateClient(
this,
true );
986 void Group::startupIdChanged()
988 TDEStartupInfoId asn_id;
989 TDEStartupInfoData asn_data;
990 bool asn_valid = workspace()->checkStartupNotification( leader_wid, asn_id, asn_data );
993 if( asn_id.timestamp() != 0 && user_time != -1U
994 && timestampCompare( asn_id.timestamp(), user_time ) > 0 )
996 user_time = asn_id.timestamp();
998 else if( asn_data.timestamp() != -1U && user_time != -1U
999 && timestampCompare( asn_data.timestamp(), user_time ) > 0 )
1001 user_time = asn_data.timestamp();
1005 void Group::updateUserTime( Time time )
1007 if( time == CurrentTime )
1008 time = get_tqt_x_time();
1010 && ( user_time == CurrentTime
1011 || timestampCompare( time, user_time ) > 0 ))
void setActive(bool, bool updateOpacity=true)
void updateUserTime(Time time=CurrentTime)
TQString caption(bool full=true) const