14#include <tdeapplication.h>
15#include <tdestartupinfo.h>
19#include <tqpopupmenu.h>
24#include <tqclipboard.h>
26#include <tdemenubar.h>
27#include <tdeprocess.h>
28#include <tdeglobalaccel.h>
29#include <tdestandarddirs.h>
30#include <dcopclient.h>
39#include "notifications.h"
43#include <X11/XKBlib.h>
44#include <X11/extensions/shape.h>
45#include <X11/keysym.h>
46#include <X11/keysymdef.h>
47#include <X11/cursorfont.h>
56extern int screen_number;
57extern bool disable_twin_composition_manager;
59Workspace *Workspace::_self = 0;
63 if (disable_twin_composition_manager) {
69 bool damageExt = XQueryExtension(tqt_xdisplay(),
"DAMAGE", &i, &i, &i);
70 bool compositeExt = XQueryExtension(tqt_xdisplay(),
"Composite", &i, &i, &i);
71 bool xfixesExt = XQueryExtension(tqt_xdisplay(),
"XFIXES", &i, &i, &i);
73 return damageExt && compositeExt && xfixesExt;
76TQString compositorPIDFile () {
77 return locateLocal(
"tmp", TQString(
"compton-tde.").append(getenv(
"DISPLAY")).append(
".pid"));
80pid_t getCompositorPID() {
83 TQFile pidFile(compositorPIDFile());
85 if (pidFile.open(IO_ReadOnly)) {
89 pidFile.readLine(pidStr, 21);
90 rv = pidStr.toInt(&ok);
107Workspace::Workspace(
bool restore )
108 : DCOPObject (
"KWinInterface"),
109 TQObject (0,
"workspace"),
111 number_of_desktops(0),
113 active_popup( NULL ),
114 active_popup_client( NULL ),
116 temporaryRulesMessages(
"_KDE_NET_WM_TEMPORARY_RULES", NULL, false ),
117 rules_updates_disabled( false ),
119 last_active_client (0),
120 next_active_client (0),
121 most_recently_raised (0),
123 pending_take_activity ( NULL ),
124 delayfocus_client (0),
125 showing_desktop( false ),
126 block_showing_desktop( 0 ),
127 was_user_interaction (false),
128 session_saving (false),
129 control_grab (false),
131 mouse_emulation (false),
138 desk_popup_index (0),
140 client_keys ( NULL ),
141 client_keys_dialog ( NULL ),
142 client_keys_client ( NULL ),
143 disable_shortcuts_keys ( NULL ),
144 global_shortcuts_disabled( false ),
145 global_shortcuts_disabled_for_client( false ),
147 workspaceInit (true),
149 layoutOrientation(TQt::Vertical),
154 managing_topmenus( false ),
155 topmenu_selection( NULL ),
156 topmenu_watcher( NULL ),
158 topmenu_space( NULL ),
159 set_active_client_recursion( 0 ),
160 block_stacking_updates( 0 ),
161 forced_global_mouse_grab( false ),
163 kompmgr_selection( NULL ),
164 allowKompmgrRestart( true )
168 root = tqt_xrootwin();
169 default_colormap = DefaultColormap(tqt_xdisplay(), tqt_xscreen() );
170 installed_colormap = default_colormap;
171 session.setAutoDelete(
true );
173 for (
int i = 0; i < ACTIVE_BORDER_COUNT; ++i)
175 active_reserved[i] = 0;
176 active_windows[i] = None;
179 connect( &temporaryRulesMessages, TQ_SIGNAL( gotMessage(
const TQString& )),
180 this, TQ_SLOT( gotTemporaryRulesMessage(
const TQString& )));
181 connect( &rulesUpdatedTimer, TQ_SIGNAL( timeout()),
this, TQ_SLOT( writeWindowRules()));
187 active_time_first = get_tqt_x_time();
188 active_time_last = get_tqt_x_time();
195 (void) TQApplication::desktop();
201 (WFlags)(TQt::WType_Desktop | TQt::WPaintUnclipped)
204 tdeApp->setGlobalMouseTracking(
true );
206 startup =
new TDEStartupInfo(
207 TDEStartupInfo::DisableKWinModule | TDEStartupInfo::AnnounceSilenceChanges,
this );
210 XSelectInput(tqt_xdisplay(), root,
214 SubstructureRedirectMask |
215 SubstructureNotifyMask |
231 (
unsigned char*) &data,
235 client_keys =
new TDEGlobalAccel(
this );
237 tab_box =
new TabBox(
this );
238 popupinfo =
new PopupInfo(
this );
242#if (TQT_VERSION-0 >= 0x030200)
243 connect( tdeApp->desktop(), TQ_SIGNAL( resized(
int )), TQ_SLOT( desktopResized()));
246 if (!supportsCompMgr()) {
247 options->useTranslucency =
false;
253 pid_t kompmgrpid = getCompositorPID();
255 if (options->useTranslucency)
257 createKompmgrProcess();
261 if (kill(kompmgrpid, 0) < 0)
272 else if (!disable_twin_composition_manager)
277 kill(kompmgrpid, SIGTERM);
287void Workspace::init()
289 if (options->activeBorders() == Options::ActiveSwitchAlways)
291 reserveActiveBorderSwitching(
true);
293 updateActiveBorders();
299 supportWindow =
new TQWidget;
300 XLowerWindow( tqt_xdisplay(), supportWindow->winId());
302 XSetWindowAttributes attr;
303 attr.override_redirect = 1;
304 null_focus_window = XCreateWindow( tqt_xdisplay(), tqt_xrootwin(), -1,-1, 1, 1, 0, CopyFromParent,
305 InputOnly, CopyFromParent, CWOverrideRedirect, &attr );
306 XMapWindow(tqt_xdisplay(), null_focus_window);
308 unsigned long protocols[ 5 ] =
311 NET::SupportingWMCheck |
313 NET::ClientListStacking |
314 NET::DesktopGeometry |
315 NET::NumberOfDesktops |
316 NET::CurrentDesktop |
321 NET::KDESystemTrayWindows |
328 NET::WMIconGeometry |
332 NET::WMKDESystemTrayWinFor |
333 NET::WMFrameExtents |
360 NET::DemandsAttention |
365 NET::WM2AllowedActions |
366 NET::WM2RestackWindow |
367 NET::WM2MoveResizeWindow |
368 NET::WM2ExtendedStrut |
369 NET::WM2KDETemporaryRules |
370 NET::WM2ShowingDesktop |
371 NET::WM2FullPlacement |
372 NET::WM2DesktopLayout |
377 NET::ActionMinimize |
381 NET::ActionMaxHoriz |
382 NET::ActionFullScreen |
383 NET::ActionChangeDesktop |
389 rootInfo =
new RootInfo(
this, tqt_xdisplay(), supportWindow->winId(),
"KWin",
390 protocols, 5, tqt_xscreen() );
392 loadDesktopSettings();
393 updateDesktopLayout();
395 NETRootInfo client_info( tqt_xdisplay(), NET::ActiveWindow | NET::CurrentDesktop );
397 if( !tdeApp->isSessionRestored())
398 initial_desktop = client_info.currentDesktop();
401 TDEConfigGroupSaver saver( tdeApp->sessionConfig(),
"Session" );
402 initial_desktop = tdeApp->sessionConfig()->readNumEntry(
"desktop", 1 );
404 if( !setCurrentDesktop( initial_desktop ))
405 setCurrentDesktop( 1 );
408 initPositioning =
new Placement(
this);
410 connect(&reconfigureTimer, TQ_SIGNAL(timeout()),
this,
411 TQ_SLOT(slotReconfigure()));
412 connect( &updateToolWindowsTimer, TQ_SIGNAL( timeout()),
this, TQ_SLOT( slotUpdateToolWindows()));
414 connect(tdeApp, TQ_SIGNAL(appearanceChanged()),
this,
415 TQ_SLOT(slotReconfigure()));
416 connect(tdeApp, TQ_SIGNAL(settingsChanged(
int)),
this,
417 TQ_SLOT(slotSettingsChanged(
int)));
418 connect(tdeApp, TQ_SIGNAL( kipcMessage(
int,
int )),
this, TQ_SLOT( kipcMessage(
int,
int )));
420 active_client = NULL;
421 rootInfo->setActiveWindow( None );
423 if( !tdeApp->isSessionRestored())
427 sprintf( nm,
"_KDE_TOPMENU_OWNER_S%d", DefaultScreen( tqt_xdisplay()));
428 Atom topmenu_atom = XInternAtom( tqt_xdisplay(), nm, False );
429 topmenu_selection =
new TDESelectionOwner( topmenu_atom );
430 topmenu_watcher =
new TDESelectionWatcher( topmenu_atom );
434 StackingUpdatesBlocker blocker(
this );
436 if( options->topMenuEnabled() && topmenu_selection->claim(
false ))
437 setupTopMenuHandling();
439 lostTopMenuSelection();
441 unsigned int i, nwins;
442 Window root_return, parent_return, *wins;
443 XQueryTree(tqt_xdisplay(), root, &root_return, &parent_return, &wins, &nwins);
444 for (i = 0; i < nwins; i++)
446 XWindowAttributes attr;
447 XGetWindowAttributes(tqt_xdisplay(), wins[i], &attr);
448 if (attr.override_redirect )
450 if( topmenu_space && topmenu_space->winId() == wins[ i ] )
452 if (attr.map_state != IsUnmapped)
454 if ( addSystemTrayWin( wins[i] ) )
456 Client* c = createClient( wins[i],
true );
457 if ( c != NULL && root != tqt_xrootwin() )
460 XReparentWindow( tqt_xdisplay(), c->frameId(), root, 0, 0 );
466 XFree((
void *) wins);
468 updateStackingOrder(
true );
473 NETPoint* viewports =
new NETPoint[ number_of_desktops ];
474 rootInfo->setDesktopViewport( number_of_desktops, *viewports );
476 TQRect geom = TQApplication::desktop()->geometry();
477 NETSize desktop_geometry;
478 desktop_geometry.width = geom.width();
479 desktop_geometry.height = geom.height();
480 rootInfo->setDesktopGeometry( -1, desktop_geometry );
481 setShowingDesktop(
false );
485 Client* new_active_client = NULL;
486 if( !tdeApp->isSessionRestored())
489 new_active_client = findClient( WindowMatchPredicate( client_info.activeWindow()));
491 if( new_active_client == NULL
492 && activeClient() == NULL && should_get_focus.count() == 0 )
494 if( new_active_client == NULL )
495 new_active_client = topClientOnDesktop( currentDesktop());
496 if( new_active_client == NULL && !desktops.isEmpty() )
497 new_active_client = findDesktop(
true, currentDesktop());
499 if( new_active_client != NULL )
500 activateClient( new_active_client );
503 outline_left = XCreateWindow(tqt_xdisplay(), rootWin(), 0, 0, 1, 1, 0,
504 CopyFromParent, CopyFromParent, CopyFromParent,
505 CWOverrideRedirect, &attr);
506 outline_right = XCreateWindow(tqt_xdisplay(), rootWin(), 0, 0, 1, 1, 0,
507 CopyFromParent, CopyFromParent, CopyFromParent,
508 CWOverrideRedirect, &attr);
509 outline_top = XCreateWindow(tqt_xdisplay(), rootWin(), 0, 0, 1, 1, 0,
510 CopyFromParent, CopyFromParent, CopyFromParent,
511 CWOverrideRedirect, &attr);
512 outline_bottom = XCreateWindow(tqt_xdisplay(), rootWin(), 0, 0, 1, 1, 0,
513 CopyFromParent, CopyFromParent, CopyFromParent,
514 CWOverrideRedirect, &attr);
519 workspaceInit =
false;
523Workspace::~Workspace()
527 blockStackingUpdates(
true );
530 for( ClientList::ConstIterator it = stacking_order.begin();
531 it != stacking_order.end();
535 (*it)->releaseWindow(
true );
539 clients.remove( *it );
540 desktops.remove( *it );
542 delete desktop_widget;
546 if ( root == tqt_xrootwin() )
547 XDeleteProperty(tqt_xdisplay(), tqt_xrootwin(), atoms->twin_running);
550 TDEGlobal::config()->sync();
553 XDestroyWindow(tqt_xdisplay(), outline_left);
554 XDestroyWindow(tqt_xdisplay(), outline_right);
555 XDestroyWindow(tqt_xdisplay(), outline_top);
556 XDestroyWindow(tqt_xdisplay(), outline_bottom);
559 delete supportWindow;
564 delete initPositioning;
565 delete topmenu_watcher;
566 delete topmenu_selection;
567 delete topmenu_space;
568 delete client_keys_dialog;
569 while( !rules.isEmpty())
571 delete rules.front();
574 XDestroyWindow( tqt_xdisplay(), null_focus_window );
579Client* Workspace::createClient( Window w,
bool is_mapped )
581 StackingUpdatesBlocker blocker(
this );
582 Client* c =
new Client(
this );
583 if( !c->manage( w, is_mapped ))
585 Client::deleteClient( c, Allowed );
588 addClient( c, Allowed );
592void Workspace::addClient( Client* c, allowed_t )
596 c->setBMP(c->resourceName() ==
"beep-media-player" || c->decorationId() == None);
598 c->getWindowOpacity();
602 if (!c->hasCustomOpacity())
604 c->setShadowSize(options->dockShadowSize);
605 c->setOpacity(options->translucentDocks, options->dockOpacity);
609 if (c->isMenu() || c->isTopMenu())
611 c->setShadowSize(options->menuShadowSize);
614 Group* grp = findGroup( c->window());
618 if ( c->isDesktop() )
620 desktops.append( c );
621 if( active_client == NULL && should_get_focus.isEmpty() && c->isOnCurrentDesktop())
626 updateFocusChains( c, FocusChainUpdate );
629 if( !unconstrained_stacking_order.contains( c ))
630 unconstrained_stacking_order.append( c );
631 if( !stacking_order.contains( c ))
632 stacking_order.append( c );
636 updateClientLayer( c );
641 if( activeClient() == NULL && should_get_focus.count() == 0 )
642 activateClient( findDesktop(
true, currentDesktop()));
644 c->checkActiveModal();
645 checkTransients( c->window());
646 updateStackingOrder(
true );
647 if( c->isUtility() || c->isMenu() || c->isToolbar())
648 updateToolWindows(
true );
649 checkNonExistentClients();
655void Workspace::removeClient( Client* c, allowed_t )
657 if (c == active_popup_client)
660 if( client_keys_client == c )
661 setupWindowShortcutDone(
false );
662 if( !c->shortcut().isNull())
663 c->setShortcut( TQString::null );
666 Notify::raise( Notify::TransDelete );
667 if( c->isNormalWindow())
668 Notify::raise( Notify::Delete );
670 Q_ASSERT( clients.contains( c ) || desktops.contains( c ));
672 desktops.remove( c );
673 unconstrained_stacking_order.remove( c );
674 stacking_order.remove( c );
676 i <= numberOfDesktops();
678 focus_chain[ i ].remove( c );
679 global_focus_chain.remove( c );
680 attention_chain.remove( c );
681 showing_desktop_clients.remove( c );
684 Group* group = findGroup( c->window());
688 if ( c == most_recently_raised )
689 most_recently_raised = 0;
690 should_get_focus.remove( c );
691 Q_ASSERT( c != active_client );
692 if ( c == last_active_client )
693 last_active_client = 0;
694 if( c == pending_take_activity )
695 pending_take_activity = NULL;
696 if( c == delayfocus_client )
699 updateStackingOrder(
true );
707void Workspace::updateFocusChains( Client* c, FocusChainChange change )
709 if( !c->wantsTabFocus())
712 i<= numberOfDesktops();
714 focus_chain[i].remove(c);
715 global_focus_chain.remove( c );
718 if(c->desktop() == NET::OnAllDesktops)
720 for(
int i=1; i<= numberOfDesktops(); i++)
722 if( i == currentDesktop()
723 && ( change == FocusChainMakeFirst || change == FocusChainMakeLast ))
725 focus_chain[ i ].remove( c );
726 if( change == FocusChainMakeFirst )
727 focus_chain[ i ].append( c );
729 focus_chain[ i ].prepend( c );
731 else if( !focus_chain[ i ].contains( c ))
733 if( active_client != NULL && active_client != c
734 && !focus_chain[ i ].isEmpty() && focus_chain[ i ].last() == active_client )
735 focus_chain[ i ].insert( focus_chain[ i ].fromLast(), c );
737 focus_chain[ i ].append( c );
743 for(
int i=1; i<= numberOfDesktops(); i++)
745 if( i == c->desktop())
747 if( change == FocusChainMakeFirst )
749 focus_chain[ i ].remove( c );
750 focus_chain[ i ].append( c );
752 else if( change == FocusChainMakeLast )
754 focus_chain[ i ].remove( c );
755 focus_chain[ i ].prepend( c );
757 else if( !focus_chain[ i ].contains( c ))
759 if( active_client != NULL && active_client != c
760 && !focus_chain[ i ].isEmpty() && focus_chain[ i ].last() == active_client )
761 focus_chain[ i ].insert( focus_chain[ i ].fromLast(), c );
763 focus_chain[ i ].append( c );
767 focus_chain[ i ].remove( c );
770 if( change == FocusChainMakeFirst )
772 global_focus_chain.remove( c );
773 global_focus_chain.append( c );
775 else if( change == FocusChainMakeLast )
777 global_focus_chain.remove( c );
778 global_focus_chain.prepend( c );
780 else if( !global_focus_chain.contains( c ))
782 if( active_client != NULL && active_client != c
783 && !global_focus_chain.isEmpty() && global_focus_chain.last() == active_client )
784 global_focus_chain.insert( global_focus_chain.fromLast(), c );
786 global_focus_chain.append( c );
790void Workspace::updateOverlappingShadows(
unsigned long window)
794 if ((client = findClient(WindowMatchPredicate((WId)window))))
797 client->drawOverlappingShadows(
false);
800void Workspace::setShadowed(
unsigned long window,
bool shadowed)
804 if ((client = findClient(WindowMatchPredicate((WId)window))))
805 client->setShadowed(shadowed);
808void Workspace::updateCurrentTopMenu()
810 if( !managingTopMenus())
814 bool block_desktop_menubar =
false;
818 Client* menu_client = active_client;
821 if( menu_client->isFullScreen())
822 block_desktop_menubar =
true;
823 for( ClientList::ConstIterator it = menu_client->transients().begin();
824 it != menu_client->transients().end();
826 if( (*it)->isTopMenu())
831 if( menubar != NULL || !menu_client->isTransient())
833 if( menu_client->isModal() || menu_client->transientFor() == NULL )
835 menu_client = menu_client->transientFor();
839 for( ClientList::ConstIterator it = active_client->group()->members().begin();
840 it != active_client->group()->members().end();
842 if( (*it)->isTopMenu())
849 if( !menubar && !block_desktop_menubar && options->desktopTopMenu())
852 Client* desktop = findDesktop(
true, currentDesktop());
853 if( desktop != NULL )
855 for( ClientList::ConstIterator it = desktop->transients().begin();
856 it != desktop->transients().end();
858 if( (*it)->isTopMenu())
867 if( menubar == NULL )
869 for( ClientList::ConstIterator it = topmenus.begin();
870 it != topmenus.end();
872 if( (*it)->wasOriginallyGroupTransient())
883 if( active_client && !menubar->isOnDesktop( active_client->desktop()))
884 menubar->setDesktop( active_client->desktop());
885 menubar->hideClient(
false );
886 topmenu_space->hide();
890 unconstrained_stacking_order.remove( menubar );
891 unconstrained_stacking_order.append( menubar );
893 else if( !block_desktop_menubar )
895 topmenu_space->show();
899 for ( ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it)
901 if( (*it)->isTopMenu() && (*it) != menubar )
902 (*it)->hideClient(
true );
907void Workspace::updateToolWindows(
bool also_hide )
910 if( !options->hideUtilityWindowsForInactive )
912 for( ClientList::ConstIterator it = clients.begin();
915 (*it)->hideClient(
false );
918 const Group* group = NULL;
919 const Client* client = active_client;
922 while( client != NULL )
924 if( !client->isTransient())
926 if( client->groupTransient())
928 group = client->group();
931 client = client->transientFor();
937 ClientList to_show, to_hide;
938 for( ClientList::ConstIterator it = stacking_order.begin();
939 it != stacking_order.end();
942 if( (*it)->isUtility() || (*it)->isMenu() || (*it)->isToolbar())
945 if( !(*it)->isTransient())
947 if( (*it)->group()->members().count() == 1 )
949 else if( client != NULL && (*it)->group() == client->group())
956 if( group != NULL && (*it)->group() == group )
958 else if( client != NULL && client->hasTransient( (*it),
true ))
963 if( !show && also_hide )
965 const ClientList mainclients = (*it)->mainClients();
968 if( mainclients.isEmpty())
970 for( ClientList::ConstIterator it2 = mainclients.begin();
971 it2 != mainclients.end();
974 if( (*it2)->isSpecialWindow())
978 to_hide.append( *it );
981 to_show.append( *it );
984 for( ClientList::ConstIterator it = to_show.fromLast();
988 (*it)->hideClient(
false );
991 for( ClientList::ConstIterator it = to_hide.begin();
994 (*it)->hideClient(
true );
995 updateToolWindowsTimer.stop();
999 updateToolWindowsTimer.start( 50,
true );
1003void Workspace::slotUpdateToolWindows()
1005 updateToolWindows(
true );
1011void Workspace::updateColormap()
1013 Colormap cmap = default_colormap;
1014 if ( activeClient() && activeClient()->colormap() != None )
1015 cmap = activeClient()->colormap();
1016 if ( cmap != installed_colormap )
1018 XInstallColormap(tqt_xdisplay(), cmap );
1019 installed_colormap = cmap;
1023void Workspace::reconfigure()
1025 reconfigureTimer.start(200,
true);
1029void Workspace::slotSettingsChanged(
int category)
1031 kdDebug(1212) <<
"Workspace::slotSettingsChanged()" << endl;
1032 if( category == (
int) TDEApplication::SETTINGS_SHORTCUTS )
1039KWIN_PROCEDURE( CheckBorderSizesProcedure, cl->checkBorderSizes() );
1041void Workspace::slotReconfigure()
1043 kdDebug(1212) <<
"Workspace::slotReconfigure()" << endl;
1044 reconfigureTimer.stop();
1046 if (options->activeBorders() == Options::ActiveSwitchAlways)
1048 reserveActiveBorderSwitching(
false);
1051 TDEGlobal::config()->reparseConfiguration();
1052 unsigned long changed = options->updateSettings();
1053 tab_box->reconfigure();
1054 popupinfo->reconfigure();
1055 initPositioning->reinitCascading( 0 );
1057 forEachClient( CheckIgnoreFocusStealingProcedure());
1058 updateToolWindows(
true );
1060 if( mgr->reset( changed ))
1064 curtain.setBackgroundMode( NoBackground );
1065 curtain.setGeometry( TQApplication::desktop()->geometry() );
1068 for( ClientList::ConstIterator it = clients.begin();
1069 it != clients.end();
1072 (*it)->updateDecoration(
true,
true );
1074 mgr->destroyPreviousPlugin();
1078 forEachClient( CheckBorderSizesProcedure());
1081 if (options->activeBorders() == Options::ActiveSwitchAlways)
1083 reserveActiveBorderSwitching(
true);
1086 if( options->topMenuEnabled() && !managingTopMenus())
1088 if( topmenu_selection->claim(
false ))
1089 setupTopMenuHandling();
1091 lostTopMenuSelection();
1093 else if( !options->topMenuEnabled() && managingTopMenus())
1095 topmenu_selection->release();
1096 lostTopMenuSelection();
1099 if( managingTopMenus())
1101 updateTopMenuGeometry();
1102 updateCurrentTopMenu();
1106 for( ClientList::Iterator it = clients.begin();
1107 it != clients.end();
1110 (*it)->setupWindowRules(
true );
1111 (*it)->applyWindowRules();
1112 discardUsedWindowRules( *it,
false );
1115 if (options->resetKompmgr)
1117 bool tmp = options->useTranslucency;
1120 pid_t kompmgrpid = getCompositorPID();
1126 kill(kompmgrpid, SIGUSR1);
1133 createKompmgrProcess();
1135 TQTimer::singleShot( 200,
this, TQ_SLOT(startKompmgr()) );
1142 kill(kompmgrpid, SIGTERM);
1152void Workspace::loadDesktopSettings()
1154 TDEConfig* c = TDEGlobal::config();
1155 TQCString groupname;
1156 if (screen_number == 0)
1157 groupname =
"Desktops";
1159 groupname.sprintf(
"Desktops-screen-%d", screen_number);
1160 TDEConfigGroupSaver saver(c,groupname);
1162 int n = c->readNumEntry(
"Number", 4);
1163 number_of_desktops = n;
1165 workarea =
new TQRect[ n + 1 ];
1168 rootInfo->setNumberOfDesktops( number_of_desktops );
1169 desktop_focus_chain.resize( n );
1171 focus_chain.resize( n + 1 );
1172 for(
int i = 1; i <= n; i++)
1174 TQString s = c->readEntry(TQString(
"Name_%1").arg(i),
1175 i18n(
"Desktop %1").arg(i));
1176 rootInfo->setDesktopName( i, s.utf8().data() );
1177 desktop_focus_chain[i-1] = i;
1181void Workspace::saveDesktopSettings()
1183 TDEConfig* c = TDEGlobal::config();
1184 TQCString groupname;
1185 if (screen_number == 0)
1186 groupname =
"Desktops";
1188 groupname.sprintf(
"Desktops-screen-%d", screen_number);
1189 TDEConfigGroupSaver saver(c,groupname);
1191 c->writeEntry(
"Number", number_of_desktops );
1192 for(
int i = 1; i <= number_of_desktops; i++)
1194 TQString s = desktopName( i );
1195 TQString defaultvalue = i18n(
"Desktop %1").arg(i);
1199 rootInfo->setDesktopName( i, s.utf8().data() );
1202 if (s != defaultvalue)
1204 c->writeEntry( TQString(
"Name_%1").arg(i), s );
1208 TQString currentvalue = c->readEntry(TQString(
"Name_%1").arg(i));
1209 if (currentvalue != defaultvalue)
1210 c->writeEntry( TQString(
"Name_%1").arg(i),
"" );
1215TQStringList Workspace::configModules(
bool controlCenter)
1218 args <<
"tde-twindecoration.desktop";
1220 args <<
"tde-twinoptions.desktop";
1221 else if (tdeApp->authorizeControlModule(
"tde-twinoptions.desktop"))
1222 args <<
"twinactions" <<
"twinfocus" <<
"twinmoving" <<
"twinadvanced" <<
"twinrules" <<
"twintranslucency";
1226void Workspace::configureWM()
1228 TDEApplication::tdeinitExec(
"tdecmshell", configModules(
false) );
1234void Workspace::doNotManage( TQString title )
1236 doNotManageList.append( title );
1242bool Workspace::isNotManaged(
const TQString& title )
1244 for ( TQStringList::Iterator it = doNotManageList.begin(); it != doNotManageList.end(); ++it )
1246 TQRegExp r( (*it) );
1247 if (r.search(title) != -1)
1249 doNotManageList.remove( it );
1259void Workspace::refresh()
1262 w.setGeometry( TQApplication::desktop()->geometry() );
1265 TQApplication::flushX();
1275class ObscuringWindows
1278 ~ObscuringWindows();
1279 void create( Client* c );
1281 TQValueList<Window> obscuring_windows;
1282 static TQValueList<Window>* cached;
1283 static unsigned int max_cache_size;
1286TQValueList<Window>* ObscuringWindows::cached = 0;
1287unsigned int ObscuringWindows::max_cache_size = 0;
1289void ObscuringWindows::create( Client* c )
1292 cached =
new TQValueList<Window>;
1294 XWindowChanges chngs;
1295 int mask = CWSibling | CWStackMode;
1296 if( cached->count() > 0 )
1298 cached->remove( obs_win = cached->first());
1301 chngs.width = c->width();
1302 chngs.height = c->height();
1303 mask |= CWX | CWY | CWWidth | CWHeight;
1307 XSetWindowAttributes a;
1308 a.background_pixmap = None;
1309 a.override_redirect = True;
1310 obs_win = XCreateWindow( tqt_xdisplay(), tqt_xrootwin(), c->x(), c->y(),
1311 c->width(), c->height(), 0, CopyFromParent, InputOutput,
1312 CopyFromParent, CWBackPixmap | CWOverrideRedirect, &a );
1314 chngs.sibling = c->frameId();
1315 chngs.stack_mode = Below;
1316 XConfigureWindow( tqt_xdisplay(), obs_win, mask, &chngs );
1317 XMapWindow( tqt_xdisplay(), obs_win );
1318 obscuring_windows.append( obs_win );
1321ObscuringWindows::~ObscuringWindows()
1323 max_cache_size = TQMAX( max_cache_size, obscuring_windows.count() + 4 ) - 1;
1324 for( TQValueList<Window>::ConstIterator it = obscuring_windows.begin();
1325 it != obscuring_windows.end();
1328 XUnmapWindow( tqt_xdisplay(), *it );
1329 if( cached->count() < max_cache_size )
1330 cached->prepend( *it );
1332 XDestroyWindow( tqt_xdisplay(), *it );
1343bool Workspace::setCurrentDesktop(
int new_desktop )
1345 if (new_desktop < 1 || new_desktop > number_of_desktops )
1351 StackingUpdatesBlocker blocker(
this );
1353 int old_desktop = current_desktop;
1354 if (new_desktop != current_desktop)
1356 ++block_showing_desktop;
1361 Notify::raise((Notify::Event) (Notify::DesktopChange+new_desktop));
1363 ObscuringWindows obs_wins;
1365 current_desktop = new_desktop;
1367 bool desktopHasCompositing = tdeApp->isCompositionManagerAvailable();
1368 if (!desktopHasCompositing) {
1370 for ( ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it) {
1371 if ( !(*it)->isOnDesktop( new_desktop ) && (*it) != movingClient )
1373 if( (*it)->isShown(
true ) && (*it)->isOnDesktop( old_desktop )) {
1374 obs_wins.create( *it );
1376 (*it)->updateVisibility();
1381 rootInfo->setCurrentDesktop( current_desktop );
1383 if( movingClient && !movingClient->isOnDesktop( new_desktop ))
1384 movingClient->setDesktop( new_desktop );
1386 for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it) {
1387 if ( (*it)->isOnDesktop( new_desktop ) ) {
1388 (*it)->updateVisibility();
1392 if (desktopHasCompositing) {
1395 XSync( tqt_xdisplay(),
false);
1396 for ( ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it) {
1397 if ( !(*it)->isOnDesktop( new_desktop ) && (*it) != movingClient )
1399 if( (*it)->isShown(
true ) && (*it)->isOnDesktop( old_desktop )) {
1400 obs_wins.create( *it );
1402 (*it)->updateVisibility();
1407 --block_showing_desktop;
1408 if( showingDesktop())
1409 resetShowingDesktop(
false );
1416 if ( options->focusPolicyIsReasonable())
1419 if ( movingClient != NULL && active_client == movingClient
1420 && focus_chain[currentDesktop()].contains( active_client )
1421 && active_client->isShown(
true ) && active_client->isOnCurrentDesktop())
1427 for( ClientList::ConstIterator it = focus_chain[currentDesktop()].fromLast();
1428 it != focus_chain[currentDesktop()].end();
1431 if ( (*it)->isShown(
false ) && (*it)->isOnCurrentDesktop())
1443 else if( active_client && active_client->isShown(
true ) && active_client->isOnCurrentDesktop())
1446 if( c == NULL && !desktops.isEmpty())
1447 c = findDesktop(
true, currentDesktop());
1449 if( c != active_client )
1450 setActiveClient( NULL, Allowed );
1457 updateCurrentTopMenu();
1464 for(
int i = desktop_focus_chain.find( currentDesktop() ); i > 0; i-- )
1465 desktop_focus_chain[i] = desktop_focus_chain[i-1];
1466 desktop_focus_chain[0] = currentDesktop();
1473 if( old_desktop != 0 )
1474 popupinfo->showInfo( desktopName(currentDesktop()) );
1479void Workspace::nextDesktop()
1481 int desktop = currentDesktop() + 1;
1482 setCurrentDesktop(desktop > numberOfDesktops() ? 1 : desktop);
1486void Workspace::previousDesktop()
1488 int desktop = currentDesktop() - 1;
1489 setCurrentDesktop(desktop > 0 ? desktop : numberOfDesktops());
1492int Workspace::desktopToRight(
int desktop )
const
1495 calcDesktopLayout(x,y);
1497 if (layoutOrientation == TQt::Vertical)
1500 if ( dt >= numberOfDesktops() )
1502 if ( options->rollOverDesktops )
1503 dt -= numberOfDesktops();
1510 int d = (dt % x) + 1;
1513 if ( options->rollOverDesktops )
1518 dt = dt - (dt % x) + d;
1523int Workspace::desktopToLeft(
int desktop )
const
1526 calcDesktopLayout(x,y);
1528 if (layoutOrientation == TQt::Vertical)
1533 if ( options->rollOverDesktops )
1534 dt += numberOfDesktops();
1541 int d = (dt % x) - 1;
1544 if ( options->rollOverDesktops )
1549 dt = dt - (dt % x) + d;
1554int Workspace::desktopUp(
int desktop )
const
1557 calcDesktopLayout(x,y);
1559 if (layoutOrientation == TQt::Horizontal)
1564 if ( options->rollOverDesktops )
1565 dt += numberOfDesktops();
1572 int d = (dt % y) - 1;
1575 if ( options->rollOverDesktops )
1580 dt = dt - (dt % y) + d;
1585int Workspace::desktopDown(
int desktop )
const
1588 calcDesktopLayout(x,y);
1590 if (layoutOrientation == TQt::Horizontal)
1593 if ( dt >= numberOfDesktops() )
1595 if ( options->rollOverDesktops )
1596 dt -= numberOfDesktops();
1603 int d = (dt % y) + 1;
1606 if ( options->rollOverDesktops )
1611 dt = dt - (dt % y) + d;
1620void Workspace::setNumberOfDesktops(
int n )
1622 if ( n == number_of_desktops )
1624 int old_number_of_desktops = number_of_desktops;
1625 number_of_desktops = n;
1627 if( currentDesktop() > numberOfDesktops())
1628 setCurrentDesktop( numberOfDesktops());
1632 if( old_number_of_desktops < number_of_desktops )
1634 rootInfo->setNumberOfDesktops( number_of_desktops );
1635 NETPoint* viewports =
new NETPoint[ number_of_desktops ];
1636 rootInfo->setDesktopViewport( number_of_desktops, *viewports );
1638 updateClientArea(
true );
1639 focus_chain.resize( number_of_desktops + 1 );
1644 if( old_number_of_desktops > number_of_desktops )
1646 for( ClientList::ConstIterator it = clients.begin();
1647 it != clients.end();
1650 if( !(*it)->isOnAllDesktops() && (*it)->desktop() > numberOfDesktops())
1651 sendClientToDesktop( *it, numberOfDesktops(),
true );
1654 if( old_number_of_desktops > number_of_desktops )
1656 rootInfo->setNumberOfDesktops( number_of_desktops );
1657 NETPoint* viewports =
new NETPoint[ number_of_desktops ];
1658 rootInfo->setDesktopViewport( number_of_desktops, *viewports );
1660 updateClientArea(
true );
1661 focus_chain.resize( number_of_desktops + 1 );
1664 saveDesktopSettings();
1667 desktop_focus_chain.resize( n );
1668 for(
int i = 0; i < (int)desktop_focus_chain.size(); i++ )
1669 desktop_focus_chain[i] = i+1;
1677void Workspace::sendClientToDesktop( Client* c,
int desk,
bool dont_activate )
1679 bool was_on_desktop = c->isOnDesktop( desk ) || c->isOnAllDesktops();
1680 c->setDesktop( desk );
1681 if ( c->desktop() != desk )
1683 desk = c->desktop();
1685 if ( c->isOnDesktop( currentDesktop() ) )
1687 if ( c->wantsTabFocus() && options->focusPolicyIsReasonable()
1692 restackClientUnderActive( c );
1699 ClientList transients_stacking_order = ensureStackingOrder( c->transients());
1700 for( ClientList::ConstIterator it = transients_stacking_order.begin();
1701 it != transients_stacking_order.end();
1703 sendClientToDesktop( *it, desk, dont_activate );
1707int Workspace::numScreens()
const
1709 if( !options->xineramaEnabled )
1711 return tqApp->desktop()->numScreens();
1714int Workspace::activeScreen()
const
1716 if( !options->xineramaEnabled )
1718 if( !options->activeMouseScreen )
1720 if( activeClient() != NULL && !activeClient()->isOnScreen( active_screen ))
1721 return tqApp->desktop()->screenNumber( activeClient()->geometry().center());
1722 return active_screen;
1724 return tqApp->desktop()->screenNumber( TQCursor::pos());
1729void Workspace::checkActiveScreen(
const Client* c )
1731 if( !options->xineramaEnabled )
1735 if( !c->isOnScreen( active_screen ))
1736 active_screen = c->screen();
1741void Workspace::setActiveScreenMouse( TQPoint mousepos )
1743 if( !options->xineramaEnabled )
1745 active_screen = tqApp->desktop()->screenNumber( mousepos );
1748TQRect Workspace::screenGeometry(
int screen )
const
1750 if (( !options->xineramaEnabled ) || (tdeApp->desktop()->numScreens() < 2))
1751 return tqApp->desktop()->geometry();
1752 return tqApp->desktop()->screenGeometry( screen );
1755int Workspace::screenNumber( TQPoint pos )
const
1757 if( !options->xineramaEnabled )
1759 return tqApp->desktop()->screenNumber( pos );
1762void Workspace::sendClientToScreen( Client* c,
int screen )
1764 if( c->screen() == screen )
1766 GeometryUpdatesPostponer blocker( c );
1767 TQRect old_sarea = clientArea( MaximizeArea, c );
1768 TQRect sarea = clientArea( MaximizeArea, screen, c->desktop());
1769 c->setGeometry( sarea.x() - old_sarea.x() + c->x(), sarea.y() - old_sarea.y() + c->y(),
1770 c->size().width(), c->size().height());
1771 c->checkWorkspacePosition();
1772 ClientList transients_stacking_order = ensureStackingOrder( c->transients());
1773 for( ClientList::ConstIterator it = transients_stacking_order.begin();
1774 it != transients_stacking_order.end();
1776 sendClientToScreen( *it, screen );
1778 active_screen = screen;
1782void Workspace::setDesktopLayout(
int,
int,
int )
1786void Workspace::updateDesktopLayout()
1789 layoutOrientation = ( rootInfo->desktopLayoutOrientation() == NET::OrientationHorizontal
1790 ? TQt::Horizontal : TQt::Vertical );
1791 layoutX = rootInfo->desktopLayoutColumnsRows().width();
1792 layoutY = rootInfo->desktopLayoutColumnsRows().height();
1793 if( layoutX == 0 && layoutY == 0 )
1797void Workspace::calcDesktopLayout(
int &x,
int &y)
const
1801 if((x <= 0) && (y > 0))
1802 x = (numberOfDesktops()+y-1) / y;
1803 else if((y <=0) && (x > 0))
1804 y = (numberOfDesktops()+x-1) / x;
1816bool Workspace::addSystemTrayWin( WId w )
1818 if ( systemTrayWins.contains( w ) )
1821 NETWinInfo ni( tqt_xdisplay(), w, root, NET::WMKDESystemTrayWinFor );
1822 WId trayWinFor = ni.kdeSystemTrayWinFor();
1825 systemTrayWins.append( SystemTrayWindow( w, trayWinFor ) );
1826 XSelectInput( tqt_xdisplay(), w,
1829 XAddToSaveSet( tqt_xdisplay(), w );
1830 propagateSystemTrayWins();
1838bool Workspace::removeSystemTrayWin( WId w,
bool check )
1840 if ( !systemTrayWins.contains( w ) )
1852 Atom* props = XListProperties( tqt_xdisplay(), w, &num_props );
1858 if( props[ i ] == atoms->kde_system_tray_embedding )
1866 systemTrayWins.remove( w );
1867 XRemoveFromSaveSet (tqt_xdisplay (), w);
1868 propagateSystemTrayWins();
1876void Workspace::propagateSystemTrayWins()
1878 Window *cl =
new Window[ systemTrayWins.count()];
1881 for ( SystemTrayWindowList::ConstIterator it = systemTrayWins.begin(); it != systemTrayWins.end(); ++it )
1883 cl[i++] = (*it).win;
1886 rootInfo->setKDESystemTrayWindows( cl, i );
1891void Workspace::killWindowId( Window window_to_kill )
1893 if( window_to_kill == None )
1895 Window window = window_to_kill;
1896 Client* client = NULL;
1899 client = findClient( FrameIdMatchPredicate( window ));
1900 if( client != NULL )
1904 Window* children = 0L;
1905 unsigned int children_count;
1906 XQueryTree( tqt_xdisplay(), window, &root, &parent, &children, &children_count );
1907 if( children != NULL )
1909 if( window == root )
1915 if( client != NULL )
1916 client->killWindow();
1918 XKillClient( tqt_xdisplay(), window_to_kill );
1921void Workspace::suspendWindowId( Window window_to_suspend )
1923 if( window_to_suspend == None )
1925 Window window = window_to_suspend;
1926 Client* client = NULL;
1929 client = findClient( FrameIdMatchPredicate( window ));
1930 if( client != NULL )
1934 Window* children = 0L;
1935 unsigned int children_count;
1936 XQueryTree( tqt_xdisplay(), window, &root, &parent, &children, &children_count );
1937 if( children != NULL )
1939 if( window == root )
1945 if( client != NULL )
1946 client->suspendWindow();
1951void Workspace::resumeWindowId( Window window_to_resume )
1953 if( window_to_resume == None )
1955 Window window = window_to_resume;
1956 Client* client = NULL;
1959 client = findClient( FrameIdMatchPredicate( window ));
1960 if( client != NULL )
1964 Window* children = 0L;
1965 unsigned int children_count;
1966 XQueryTree( tqt_xdisplay(), window, &root, &parent, &children, &children_count );
1967 if( children != NULL )
1969 if( window == root )
1975 if( client != NULL )
1976 client->resumeWindow();
1982bool Workspace::isResumeableWindowID( Window window_to_check )
1984 if( window_to_check == None )
1986 Window window = window_to_check;
1987 Client* client = NULL;
1990 client = findClient( FrameIdMatchPredicate( window ));
1991 if( client != NULL )
1995 Window* children = 0L;
1996 unsigned int children_count;
1997 XQueryTree( tqt_xdisplay(), window, &root, &parent, &children, &children_count );
1998 if( children != NULL )
2000 if( window == root )
2006 if( client != NULL )
2007 return client->isResumeable();
2013void Workspace::sendPingToWindow( Window window, Time timestamp )
2015 rootInfo->sendPing( window, timestamp );
2018void Workspace::sendTakeActivity( Client* c, Time timestamp,
long flags )
2020 rootInfo->takeActivity( c->window(), timestamp, flags );
2021 pending_take_activity = c;
2028void Workspace::slotGrabWindow()
2030 if ( active_client )
2032 TQPixmap snapshot = TQPixmap::grabWindow( active_client->frameId() );
2035 if( Shape::available())
2039 XRectangle* rects = XShapeGetRectangles( tqt_xdisplay(), active_client->frameId(),
2040 ShapeBounding, &count, &order);
2049 for (
int pos = 0; pos < count; pos++)
2050 contents += TQRegion(rects[pos].x, rects[pos].y,
2051 rects[pos].width, rects[pos].height);
2055 TQRegion bbox(0, 0, snapshot.width(), snapshot.height());
2058 TQRegion maskedAway = bbox - contents;
2059 TQMemArray<TQRect> maskedAwayRects = maskedAway.rects();
2062 TQBitmap mask( snapshot.width(), snapshot.height());
2064 p.fillRect(0, 0, mask.width(), mask.height(), TQt::color1);
2065 for (uint pos = 0; pos < maskedAwayRects.count(); pos++)
2066 p.fillRect(maskedAwayRects[pos], TQt::color0);
2068 snapshot.setMask(mask);
2072 TQClipboard *cb = TQApplication::clipboard();
2073 cb->setPixmap( snapshot );
2082void Workspace::slotGrabDesktop()
2084 TQPixmap p = TQPixmap::grabWindow( tqt_xrootwin() );
2085 TQClipboard *cb = TQApplication::clipboard();
2093void Workspace::slotMouseEmulation()
2096 if ( mouse_emulation )
2098 XUngrabKeyboard(tqt_xdisplay(), get_tqt_x_time());
2099 mouse_emulation =
false;
2103 if ( XGrabKeyboard(tqt_xdisplay(),
2105 GrabModeAsync, GrabModeAsync,
2106 get_tqt_x_time()) == GrabSuccess )
2108 mouse_emulation =
true;
2109 mouse_emulation_state = 0;
2110 mouse_emulation_window = 0;
2120WId Workspace::getMouseEmulationWindow()
2123 Window child = tqt_xrootwin();
2124 int root_x, root_y, lx, ly;
2132 c = findClient( FrameIdMatchPredicate( w ));
2133 XQueryPointer( tqt_xdisplay(), w, &root, &child,
2134 &root_x, &root_y, &lx, &ly, &state );
2135 }
while ( child != None && child != w );
2137 if ( c && !c->isActive() )
2138 activateClient( c );
2145unsigned int Workspace::sendFakedMouseEvent( TQPoint pos, WId w, MouseEmulation type,
int button,
unsigned int state )
2149 TQWidget* widget = TQWidget::find( w );
2150 if ( (!widget || widget->inherits(
"TQToolButton") ) && !findClient( WindowMatchPredicate( w )) )
2154 XTranslateCoordinates( tqt_xdisplay(), tqt_xrootwin(), w, pos.x(), pos.y(), &x, &y, &xw );
2155 if ( type == EmuMove )
2158 e.type = MotionNotify;
2159 e.xmotion.window = w;
2160 e.xmotion.root = tqt_xrootwin();
2161 e.xmotion.subwindow = w;
2162 e.xmotion.time = get_tqt_x_time();
2165 e.xmotion.x_root = pos.x();
2166 e.xmotion.y_root = pos.y();
2167 e.xmotion.state = state;
2168 e.xmotion.is_hint = NotifyNormal;
2169 XSendEvent( tqt_xdisplay(), w, True, ButtonMotionMask, &e );
2174 e.type = type == EmuRelease ? ButtonRelease : ButtonPress;
2175 e.xbutton.window = w;
2176 e.xbutton.root = tqt_xrootwin();
2177 e.xbutton.subwindow = w;
2178 e.xbutton.time = get_tqt_x_time();
2181 e.xbutton.x_root = pos.x();
2182 e.xbutton.y_root = pos.y();
2183 e.xbutton.state = state;
2184 e.xbutton.button = button;
2185 XSendEvent( tqt_xdisplay(), w, True, ButtonPressMask, &e );
2187 if ( type == EmuPress )
2192 state |= Button2Mask;
2195 state |= Button3Mask;
2198 state |= Button1Mask;
2207 state &= ~Button2Mask;
2210 state &= ~Button3Mask;
2213 state &= ~Button1Mask;
2225bool Workspace::keyPressMouseEmulation( XKeyEvent& ev )
2227 if ( root != tqt_xrootwin() )
2229 int kc = XkbKeycodeToKeysym(tqt_xdisplay(), ev.keycode, 0, 0);
2230 int km = ev.state & (ControlMask | Mod1Mask | ShiftMask);
2232 bool is_control = km & ControlMask;
2233 bool is_alt = km & Mod1Mask;
2234 bool is_shift = km & ShiftMask;
2235 int delta = is_control?1:is_alt?32:8;
2236 TQPoint pos = TQCursor::pos();
2257 if ( !mouse_emulation_state )
2258 mouse_emulation_window = getMouseEmulationWindow();
2259 if ( (mouse_emulation_state & Button1Mask) == 0 )
2260 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuPress, Button1, mouse_emulation_state );
2262 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button1, mouse_emulation_state );
2265 if ( !mouse_emulation_state )
2266 mouse_emulation_window = getMouseEmulationWindow();
2267 if ( (mouse_emulation_state & Button2Mask) == 0 )
2268 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuPress, Button2, mouse_emulation_state );
2270 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button2, mouse_emulation_state );
2273 if ( !mouse_emulation_state )
2274 mouse_emulation_window = getMouseEmulationWindow();
2275 if ( (mouse_emulation_state & Button3Mask) == 0 )
2276 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuPress, Button3, mouse_emulation_state );
2278 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button3, mouse_emulation_state );
2285 if ( !mouse_emulation_state )
2288 mouse_emulation_window = getMouseEmulationWindow();
2289 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuPress, Button1, mouse_emulation_state );
2290 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button1, mouse_emulation_state );
2294 if ( mouse_emulation_state & Button1Mask )
2295 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button1, mouse_emulation_state );
2296 if ( mouse_emulation_state & Button2Mask )
2297 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button2, mouse_emulation_state );
2298 if ( mouse_emulation_state & Button3Mask )
2299 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button3, mouse_emulation_state );
2304 XUngrabKeyboard(tqt_xdisplay(), get_tqt_x_time());
2305 mouse_emulation =
false;
2311 TQCursor::setPos( pos );
2312 if ( mouse_emulation_state )
2313 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuMove, 0, mouse_emulation_state );
2323TQWidget* Workspace::desktopWidget()
2325 return desktop_widget;
2329void Workspace::delayFocus()
2331 requestFocus( delayfocus_client );
2335void Workspace::requestDelayFocus( Client* c )
2337 delayfocus_client = c;
2338 delete delayFocusTimer;
2339 delayFocusTimer =
new TQTimer(
this );
2340 connect( delayFocusTimer, TQ_SIGNAL( timeout() ),
this, TQ_SLOT( delayFocus() ) );
2341 delayFocusTimer->start( options->delayFocusInterval,
true );
2344void Workspace::cancelDelayFocus()
2346 delete delayFocusTimer;
2347 delayFocusTimer = 0;
2357void Workspace::updateActiveBorders()
2359 active_time_first = get_tqt_x_time();
2360 active_time_last = get_tqt_x_time();
2361 active_time_last_trigger = get_tqt_x_time();
2362 active_current_border = ActiveNone;
2363 TQRect r = TQApplication::desktop()->geometry();
2364 activeTop = r.top();
2365 activeBottom = r.bottom();
2366 activeLeft = r.left();
2367 activeRight = r.right();
2369 for (
int pos = 0; pos < ACTIVE_BORDER_COUNT; ++pos)
2371 if (active_reserved[pos] == 0)
2373 if (active_windows[pos] != None)
2375 XDestroyWindow( tqt_xdisplay(), active_windows[pos] );
2377 active_windows[pos] = None;
2381 if (active_windows[pos] != None)
2386 XSetWindowAttributes attributes;
2387 attributes.override_redirect = True;
2388 attributes.event_mask = EnterWindowMask;
2389 unsigned long valuemask = CWOverrideRedirect | CWEventMask;
2390 int xywh[ ACTIVE_BORDER_COUNT ][ 4 ] =
2392 { r.left() + 1, r.top(), r.width() - 2, 1 },
2393 { r.right(), r.top(), 1, 1 },
2394 { r.right(), r.top() + 1, 1, r.height() - 2 },
2395 { r.right(), r.bottom(), 1, 1 },
2396 { r.left() + 1, r.bottom(), r.width() - 2, 1 },
2397 { r.left(), r.bottom(), 1, 1 },
2398 { r.left(), r.top() + 1, 1, r.height() - 2 },
2399 { r.left(), r.top(), 1, 1 }
2401 active_windows[pos] = XCreateWindow(tqt_xdisplay(), tqt_xrootwin(),
2402 xywh[pos][0], xywh[pos][1],
2403 xywh[pos][2], xywh[pos][3],
2404 0, CopyFromParent, InputOnly,
2405 CopyFromParent, valuemask,
2407 XMapWindow(tqt_xdisplay(), active_windows[pos]);
2411 XChangeProperty(tqt_xdisplay(), active_windows[pos],
2412 atoms->xdnd_aware, XA_ATOM, 32, PropModeReplace,
2413 (
unsigned char*)&version, 1);
2417void Workspace::destroyActiveBorders()
2419 for (
int pos = 0; pos < ACTIVE_BORDER_COUNT; ++pos)
2421 if (active_windows[ pos ] != None)
2423 XDestroyWindow( tqt_xdisplay(), active_windows[ pos ] );
2425 active_windows[ pos ] = None;
2429void Workspace::reserveActiveBorderSwitching(
bool reserve )
2431 for (
int pos = 0; pos < ACTIVE_BORDER_COUNT; ++pos)
2435 reserveActiveBorder(
static_cast<ActiveBorder
>(pos));
2439 unreserveActiveBorder(
static_cast<ActiveBorder
>(pos));
2444void Workspace::reserveActiveBorder( ActiveBorder border )
2446 if (border == ActiveNone)
2449 if (active_reserved[border]++ == 0)
2450 TQTimer::singleShot(0,
this, TQ_SLOT(updateActiveBorders()));
2453void Workspace::unreserveActiveBorder( ActiveBorder border )
2455 if (border == ActiveNone)
2458 assert(active_reserved[ border ] > 0);
2459 if (--active_reserved[ border ] == 0)
2460 TQTimer::singleShot(0,
this, TQ_SLOT(updateActiveBorders()));
2463void Workspace::checkActiveBorder(
const TQPoint &pos, Time now)
2465 Time treshold_set = options->activeBorderDelay();
2466 Time treshold_trigger = 250;
2467 Time treshold_reset = 250;
2468 int activation_distance = options->borderActivationDistance();
2470 bool have_borders =
false;
2471 for (
int i = 0; i < ACTIVE_BORDER_COUNT; ++i)
2473 if (active_windows[ i ] != None)
2475 have_borders =
true;
2478 if (!have_borders) {
2483 int distance_reset = activation_distance + 10;
2487 (options->activeBorders() == Options::ActiveTileMaximize ||
2488 options->activeBorders() == Options::ActiveTileOnly))
2490 TQRect r = TQApplication::desktop()->screenGeometry(pos);
2491 activeTop = r.top();
2492 activeBottom = r.bottom();
2493 activeLeft = r.left();
2494 activeRight = r.right();
2496 if (active_current_border != ActiveNone &&
2497 (pos.x() > activeLeft + distance_reset) &&
2498 (pos.x() < activeRight - distance_reset) &&
2499 (pos.y() > activeTop + distance_reset) &&
2500 (pos.y() < activeBottom - distance_reset))
2502 movingClient->cancelActiveBorderMaximizing();
2509 bool active_left = pos.x() < activeLeft + activation_distance;
2510 bool active_right = pos.x() > activeRight - activation_distance;
2511 bool active_top = pos.y() < activeTop + activation_distance;
2512 bool active_bottom = pos.y() > activeBottom - activation_distance;
2514 if (!active_left && !active_right && !active_top && !active_bottom)
2522 int active_width_quart = (activeRight - activeLeft) / 4;
2523 int active_height_quart = (activeBottom - activeTop) / 4;
2525 bool active_qleft =
false;
2526 bool active_qright =
false;
2527 bool active_qtop =
false;
2528 bool active_qbottom =
false;
2529 if (options->activeBorders() == Options::ActiveTileMaximize ||
2530 options->activeBorders() == Options::ActiveTileOnly)
2532 active_qleft = pos.x() < activeLeft + active_width_quart;
2533 active_qright = pos.x() > activeRight - active_width_quart;
2534 active_qtop = pos.y() < activeTop + active_height_quart;
2535 active_qbottom = pos.y() > activeBottom - active_height_quart;
2538 ActiveBorder border = ActiveNone;
2539 if ((active_left && active_qtop) || (active_top && active_qleft))
2541 border = ActiveTopLeft;
2543 else if ((active_right && active_qtop) || (active_top && active_qright))
2545 border = ActiveTopRight;
2547 else if ((active_left && active_qbottom) || (active_bottom && active_qleft))
2549 border = ActiveBottomLeft;
2551 else if ((active_right && active_qbottom) || (active_bottom && active_qright))
2553 border = ActiveBottomRight;
2555 else if (active_left)
2557 border = ActiveLeft;
2559 else if (active_right)
2561 border = ActiveRight;
2563 else if (active_top)
2567 else if (active_bottom)
2569 border = ActiveBottom;
2577 if( active_windows[border] == None )
2582 if ((active_current_border == border) &&
2583 (timestampDiff(active_time_last, now) < treshold_reset) &&
2584 (timestampDiff(active_time_last_trigger, now) > treshold_trigger) &&
2585 ((pos-active_push_point).manhattanLength() < distance_reset))
2587 active_time_last = now;
2588 if (timestampDiff(active_time_first, now) > treshold_set)
2590 active_time_last_trigger = now;
2591 active_current_border = ActiveNone;
2592 bool isSide = (border == ActiveTop || border == ActiveRight ||
2593 border == ActiveBottom || border == ActiveLeft);
2598 if (options->activeBorders() == Options::ActiveSwitchAlways ||
2599 options->activeBorders() == Options::ActiveSwitchOnMove)
2601 activeBorderSwitchDesktop(border, pos);
2606 else if (options->activeBorders() == Options::ActiveTileMaximize &&
2607 border == ActiveTop && movingClient->isMaximizable())
2609 if (!movingClient->isResizable())
return;
2610 movingClient->setActiveBorderMode(ActiveMaximizeMode);
2611 movingClient->setActiveBorderPos(pos);
2612 movingClient->setActiveBorder(ActiveNone);
2613 movingClient->setActiveBorderMaximizing(
true);
2617 else if ((options->activeBorders() == Options::ActiveTileMaximize ||
2618 options->activeBorders() == Options::ActiveTileOnly))
2620 if (!movingClient->isResizable())
return;
2621 movingClient->setActiveBorderMode(ActiveTilingMode);
2622 movingClient->setActiveBorderPos(pos);
2623 movingClient->setActiveBorder(border);
2624 movingClient->setActiveBorderMaximizing(
true);
2635 if (options->activeBorders() == Options::ActiveSwitchAlways && isSide)
2637 activeBorderSwitchDesktop(border, pos);
2645 active_current_border = border;
2646 active_time_first = now;
2647 active_time_last = now;
2648 active_push_point = pos;
2651 if ((options->activeBorders() == Options::ActiveSwitchAlways && !movingClient) ||
2652 activation_distance < 2)
2656 const int xdiff[ ACTIVE_BORDER_COUNT ] = { 0, -1, -1, -1, 0, 1, 1, 1 };
2657 const int ydiff[ ACTIVE_BORDER_COUNT ] = { 1, 1, 0, -1, -1, -1, 0, 1 };
2658 TQCursor::setPos(pos.x() + xdiff[border], pos.y() + ydiff[border]);
2662void Workspace::activeBorderSwitchDesktop(ActiveBorder border,
const TQPoint& _pos)
2665 TQRect r = TQApplication::desktop()->geometry();
2666 const int offset = 5;
2668 int desk_before = currentDesktop();
2669 if (border == ActiveLeft || border == ActiveTopLeft || border == ActiveBottomLeft)
2671 slotSwitchDesktopLeft();
2672 pos.setX(r.width() - offset);
2674 if (border == ActiveRight || border == ActiveTopRight || border == ActiveBottomRight)
2676 slotSwitchDesktopRight();
2680 if (border == ActiveTop || border == ActiveTopLeft || border == ActiveTopRight)
2682 slotSwitchDesktopUp();
2683 pos.setY(r.height() - offset);
2685 if (border == ActiveBottom || border == ActiveBottomLeft || border == ActiveBottomRight)
2687 slotSwitchDesktopDown();
2691 if (currentDesktop() != desk_before)
2693 TQCursor::setPos(pos);
2699bool Workspace::activeBorderEvent(XEvent *e)
2701 if (e->type == EnterNotify)
2703 for (
int i = 0; i < ACTIVE_BORDER_COUNT; ++i)
2705 if (active_windows[i] != None && e->xcrossing.window == active_windows[i])
2707 checkActiveBorder(TQPoint(e->xcrossing.x_root, e->xcrossing.y_root), e->xcrossing.time);
2712 if (e->type == ClientMessage)
2714 if (e->xclient.message_type == atoms->xdnd_position)
2716 for (
int i = 0; i < ACTIVE_BORDER_COUNT; ++i)
2718 if (active_windows[i] != None && e->xclient.window == active_windows[i])
2721 checkActiveBorder(TQPoint(e->xclient.data.l[2]>>16, e->xclient.data.l[2]&0xffff), get_tqt_x_time());
2730void Workspace::addTopMenu( Client* c )
2732 assert( c->isTopMenu());
2733 assert( !topmenus.contains( c ));
2734 topmenus.append( c );
2735 if( managingTopMenus())
2737 int minsize = c->minSize().height();
2738 if( minsize > topMenuHeight())
2740 topmenu_height = minsize;
2741 updateTopMenuGeometry();
2743 updateTopMenuGeometry( c );
2744 updateCurrentTopMenu();
2749void Workspace::removeTopMenu( Client* c )
2753 assert( c->isTopMenu());
2754 assert( topmenus.contains( c ));
2755 topmenus.remove( c );
2756 updateCurrentTopMenu();
2760void Workspace::lostTopMenuSelection()
2764 disconnect( topmenu_watcher, TQ_SIGNAL( lostOwner()),
this, TQ_SLOT( lostTopMenuOwner()));
2765 connect( topmenu_watcher, TQ_SIGNAL( lostOwner()),
this, TQ_SLOT( lostTopMenuOwner()));
2766 if( !managing_topmenus )
2768 connect( topmenu_watcher, TQ_SIGNAL( lostOwner()),
this, TQ_SLOT( lostTopMenuOwner()));
2769 disconnect( topmenu_selection, TQ_SIGNAL( lostOwnership()),
this, TQ_SLOT( lostTopMenuSelection()));
2770 managing_topmenus =
false;
2771 delete topmenu_space;
2772 topmenu_space = NULL;
2774 for( ClientList::ConstIterator it = topmenus.begin();
2775 it != topmenus.end();
2777 (*it)->checkWorkspacePosition();
2780void Workspace::lostTopMenuOwner()
2782 if( !options->topMenuEnabled())
2785 if( !topmenu_selection->claim(
false ))
2791 setupTopMenuHandling();
2794void Workspace::setupTopMenuHandling()
2796 if( managing_topmenus )
2798 connect( topmenu_selection, TQ_SIGNAL( lostOwnership()),
this, TQ_SLOT( lostTopMenuSelection()));
2799 disconnect( topmenu_watcher, TQ_SIGNAL( lostOwner()),
this, TQ_SLOT( lostTopMenuOwner()));
2800 managing_topmenus =
true;
2801 topmenu_space =
new TQWidget;
2803 stack[ 0 ] = supportWindow->winId();
2804 stack[ 1 ] = topmenu_space->winId();
2805 XRestackWindows(tqt_xdisplay(), stack, 2);
2806 updateTopMenuGeometry();
2807 topmenu_space->show();
2809 updateCurrentTopMenu();
2812int Workspace::topMenuHeight()
const
2814 if( topmenu_height == 0 )
2817 tmpmenu.insertItem(
"dummy" );
2818 topmenu_height = tmpmenu.sizeHint().height();
2820 return topmenu_height;
2823KDecoration* Workspace::createDecoration( KDecorationBridge* bridge )
2825 return mgr->createDecoration( bridge );
2828TQString Workspace::desktopName(
int desk )
const
2830 return TQString::fromUtf8( rootInfo->desktopName( desk ) );
2833bool Workspace::checkStartupNotification( Window w, TDEStartupInfoId&
id, TDEStartupInfoData& data )
2835 return startup->checkStartup( w,
id, data ) == TDEStartupInfo::Match;
2842void Workspace::focusToNull()
2844 XSetInputFocus(tqt_xdisplay(), null_focus_window, RevertToPointerRoot, get_tqt_x_time() );
2847void Workspace::helperDialog(
const TQString& message,
const Client* c )
2851 if( message ==
"noborderaltf3" )
2853 TQString shortcut = TQString(
"%1 (%2)" ).arg( keys->label(
"Window Operations Menu" ))
2854 .arg( keys->shortcut(
"Window Operations Menu" ).seq( 0 ).toString());
2855 args <<
"--msgbox" <<
2856 i18n(
"You have selected to show a window without its border.\n"
2857 "Without the border, you will not be able to enable the border "
2858 "again using the mouse: use the window operations menu instead, "
2859 "activated using the %1 keyboard shortcut." )
2861 type =
"altf3warning";
2863 else if( message ==
"fullscreenaltf3" )
2865 TQString shortcut = TQString(
"%1 (%2)" ).arg( keys->label(
"Window Operations Menu" ))
2866 .arg( keys->shortcut(
"Window Operations Menu" ).seq( 0 ).toString());
2867 args <<
"--msgbox" <<
2868 i18n(
"You have selected to show a window in fullscreen mode.\n"
2869 "If the application itself does not have an option to turn the fullscreen "
2870 "mode off you will not be able to disable it "
2871 "again using the mouse: use the window operations menu instead, "
2872 "activated using the %1 keyboard shortcut." )
2874 type =
"altf3warning";
2879 proc <<
"kdialog" << args;
2880 if( !type.isEmpty())
2882 TDEConfig cfg(
"twin_dialogsrc" );
2883 cfg.setGroup(
"Notification Messages" );
2884 if( !cfg.readBoolEntry( type,
true ))
2886 proc <<
"--dontagain" <<
"twin_dialogsrc:" + type;
2889 proc <<
"--embed" << TQString::number( c->window());
2890 proc.start( TDEProcess::DontCare );
2896void Workspace::createKompmgrProcess()
2898 kompmgr =
new TDEProcess;
2899 connect(kompmgr, TQ_SIGNAL(receivedStderr(TDEProcess*,
char*,
int)), TQ_SLOT(handleKompmgrOutput(TDEProcess*,
char*,
int)));
2900 *kompmgr << TDE_COMPOSITOR_BINARY;
2901 *kompmgr <<
"--write-pid-path" << compositorPIDFile();
2904void Workspace::startKompmgr()
2909 unsigned long length, after;
2910 unsigned char* data_root;
2912 prop_root = XInternAtom(tqt_xdisplay(),
"_XROOTPMAP_ID", False);
2913 if( XGetWindowProperty( tqt_xdisplay(), tqt_xrootwin(), prop_root, 0L, 1L, False, AnyPropertyType, &type, &format, &length, &after, &data_root) == Success && data_root != NULL ) {
2918 TQTimer::singleShot( 200,
this, TQ_SLOT(startKompmgr()) );
2921 pid_t kompmgrpid = getCompositorPID();
2922 if (kompmgrpid && kill(kompmgrpid, 0) >= 0)
2927 if (!kompmgr || kompmgr->isRunning()) {
2928 kompmgrReloadSettings();
2931 if (!kompmgr->start(TDEProcess::OwnGroup, TDEProcess::Stderr))
2933 options->useTranslucency =
false;
2935 proc <<
"kdialog" <<
"--error"
2936 << i18n(
"The Composite Manager could not be started.\\nMake sure you have \"" TDE_COMPOSITOR_BINARY
"\" in a $PATH directory.")
2937 <<
"--title" <<
"Composite Manager Failure";
2938 proc.start(TDEProcess::DontCare);
2942 delete kompmgr_selection;
2943 char selection_name[ 100 ];
2944 sprintf( selection_name,
"_NET_WM_CM_S%d", DefaultScreen( tqt_xdisplay()));
2945 kompmgr_selection =
new TDESelectionOwner( selection_name );
2946 connect( kompmgr_selection, TQ_SIGNAL( lostOwnership()), TQ_SLOT( stopKompmgr()));
2947 kompmgr_selection->claim(
true );
2948 connect(kompmgr, TQ_SIGNAL(processExited(TDEProcess*)), TQ_SLOT(restartKompmgr(TDEProcess*)));
2949 options->useTranslucency =
true;
2953 TQDataStream arg(ba, IO_WriteOnly);
2955 tdeApp->dcopClient()->emitDCOPSignal(
"default",
"kompmgrStarted()", ba);
2957 if (popup){
delete popup; popup = 0L; }
2960void Workspace::stopKompmgr()
2962 if (!kompmgr || !kompmgr->isRunning()) {
2965 delete kompmgr_selection;
2966 kompmgr_selection = NULL;
2967 kompmgr->disconnect(
this, TQ_SLOT(restartKompmgr(TDEProcess*)));
2968 options->useTranslucency =
false;
2969 if (popup){
delete popup; popup = 0L; }
2970 kompmgr->kill(SIGKILL);
2972 TQDataStream arg(ba, IO_WriteOnly);
2974 tdeApp->dcopClient()->emitDCOPSignal(
"default",
"kompmgrStopped()", ba);
2977void Workspace::kompmgrReloadSettings()
2979 if (!kompmgr || !kompmgr->isRunning()) {
2982 kompmgr->kill(SIGUSR1);
2985bool Workspace::kompmgrIsRunning()
2987 return kompmgr && kompmgr->isRunning();
2990void Workspace::unblockKompmgrRestart()
2992 allowKompmgrRestart =
true;
2995void Workspace::restartKompmgr( TDEProcess *proc )
2999 if (proc->signalled()) {
3000 int exit_signal_number = proc->exitSignal();
3001 if ( (exit_signal_number == SIGILL) || (exit_signal_number == SIGTRAP) || (exit_signal_number == SIGABRT) || (exit_signal_number == SIGSYS) || (exit_signal_number == SIGFPE) || (exit_signal_number == SIGBUS) || (exit_signal_number == SIGSEGV) ) {
3007 if (!allowKompmgrRestart)
3009 delete kompmgr_selection;
3010 kompmgr_selection = NULL;
3011 options->useTranslucency =
false;
3014 proc <<
"kdialog" <<
"--error"
3015 << i18n(
"The Composite Manager crashed twice within a minute and is therefore disabled for this session.")
3016 <<
"--title" << i18n(
"Composite Manager Failure");
3017 proc.start(TDEProcess::DontCare);
3031 if (!kompmgr->start(TDEProcess::NotifyOnExit, TDEProcess::Stderr))
3033 delete kompmgr_selection;
3034 kompmgr_selection = NULL;
3035 options->useTranslucency =
false;
3037 proc <<
"kdialog" <<
"--error"
3038 << i18n(
"The Composite Manager could not be started.\\nMake sure you have \"" TDE_COMPOSITOR_BINARY
"\" in a $PATH directory.")
3039 <<
"--title" << i18n(
"Composite Manager Failure");
3040 proc.start(TDEProcess::DontCare);
3044 allowKompmgrRestart =
false;
3045 TQTimer::singleShot( 60000,
this, TQ_SLOT(unblockKompmgrRestart()) );
3050void Workspace::handleKompmgrOutput( TDEProcess* ,
char *buffer,
int buflen)
3053 TQString output = TQString::fromLocal8Bit( buffer, buflen );
3054 if (output.contains(
"Started",
false))
3056 else if (output.contains(
"Can't open display",
false))
3057 message = i18n(
"<qt><b>The TDE composition manager failed to open the display</b><br>There is probably an invalid display entry in your ~/.compton-tde.conf file.</qt>");
3058 else if (output.contains(
"No render extension",
false))
3059 message = i18n(
"<qt><b>The TDE composition manager cannot find the Xrender extension</b><br>You are using either an outdated or a crippled version of XOrg.<br>Get XOrg ≥ 6.8 from www.freedesktop.org.<br></qt>");
3060 else if (output.contains(
"No composite extension",
false))
3061 message = i18n(
"<qt><b>Composite extension not found</b><br>You <i>must</i> use XOrg ≥ 6.8 for translucency and shadows to work.<br>Additionally, you need to add a new section to your X config file:<br>"
3062 "<i>Section \"Extensions\"<br>"
3063 "Option \"Composite\" \"Enable\"<br>"
3064 "EndSection</i></qt>");
3065 else if (output.contains(
"No damage extension",
false))
3066 message = i18n(
"<qt><b>Damage extension not found</b><br>You <i>must</i> use XOrg ≥ 6.8 for translucency and shadows to work.</qt>");
3067 else if (output.contains(
"No XFixes extension",
false))
3068 message = i18n(
"<qt><b>XFixes extension not found</b><br>You <i>must</i> use XOrg ≥ 6.8 for translucency and shadows to work.</qt>");
3071 kompmgr->closeStderr();
3072 disconnect(kompmgr, TQ_SIGNAL(receivedStderr(TDEProcess*,
char*,
int)),
this, TQ_SLOT(handleKompmgrOutput(TDEProcess*,
char*,
int)));
3073 if( !message.isEmpty())
3076 proc <<
"kdialog" <<
"--error"
3078 <<
"--title" << i18n(
"Composite Manager Failure");
3079 proc.start(TDEProcess::DontCare);
3083void Workspace::setOpacity(
unsigned long winId,
unsigned int opacityPercent)
3085 if (opacityPercent > 100) opacityPercent = 100;
3086 for( ClientList::ConstIterator it = stackingOrder().begin(); it != stackingOrder().end(); it++ )
3087 if (winId == (*it)->window())
3089 (*it)->setOpacity(opacityPercent < 100, (
unsigned int)((opacityPercent/100.0)*0xFFFFFFFF));
3094void Workspace::setShadowSize(
unsigned long winId,
unsigned int shadowSizePercent)
3097 if (shadowSizePercent > 400) shadowSizePercent = 400;
3098 for( ClientList::ConstIterator it = stackingOrder().begin(); it != stackingOrder().end(); it++ )
3099 if (winId == (*it)->window())
3101 (*it)->setShadowSize(shadowSizePercent);
3106void Workspace::setUnshadowed(
unsigned long winId)
3108 for( ClientList::ConstIterator it = stackingOrder().begin(); it != stackingOrder().end(); it++ )
3109 if (winId == (*it)->window())
3111 (*it)->setShadowSize(0);
3116void Workspace::setShowingDesktop(
bool showing )
3118 rootInfo->setShowingDesktop( showing );
3119 showing_desktop = showing;
3120 ++block_showing_desktop;
3121 if( showing_desktop )
3123 showing_desktop_clients.clear();
3125 ClientList cls = stackingOrder();
3128 for( ClientList::ConstIterator it = cls.begin();
3132 if( (*it)->isOnCurrentDesktop() && (*it)->isShown(
true ) && !(*it)->isSpecialWindow())
3133 showing_desktop_clients.prepend( *it );
3135 for( ClientList::ConstIterator it = showing_desktop_clients.begin();
3136 it != showing_desktop_clients.end();
3138 (*it)->minimize(
true);
3140 if( Client* desk = findDesktop(
true, currentDesktop()))
3141 requestFocus( desk );
3145 for( ClientList::ConstIterator it = showing_desktop_clients.begin();
3146 it != showing_desktop_clients.end();
3148 (*it)->unminimize(
true);
3149 if( showing_desktop_clients.count() > 0 )
3150 requestFocus( showing_desktop_clients.first());
3151 showing_desktop_clients.clear();
3153 --block_showing_desktop;
3165void Workspace::resetShowingDesktop(
bool keep_hidden )
3167 if( block_showing_desktop > 0 )
3169 rootInfo->setShowingDesktop(
false );
3170 showing_desktop =
false;
3171 ++block_showing_desktop;
3174 for( ClientList::ConstIterator it = showing_desktop_clients.begin();
3175 it != showing_desktop_clients.end();
3177 (*it)->unminimize(
true);
3179 showing_desktop_clients.clear();
3180 --block_showing_desktop;
3190void Workspace::slotDisableGlobalShortcuts()
3192 if( global_shortcuts_disabled || global_shortcuts_disabled_for_client )
3193 disableGlobalShortcuts(
false );
3195 disableGlobalShortcuts(
true );
3198static bool pending_dfc =
false;
3200void Workspace::disableGlobalShortcutsForClient(
bool disable )
3202 if( global_shortcuts_disabled_for_client == disable )
3204 if( !global_shortcuts_disabled )
3208 KIPC::sendMessageAll( KIPC::BlockShortcuts, disable );
3213void Workspace::disableGlobalShortcuts(
bool disable )
3215 KIPC::sendMessageAll( KIPC::BlockShortcuts, disable );
3219void Workspace::kipcMessage(
int id,
int data )
3221 if(
id != KIPC::BlockShortcuts )
3223 if( pending_dfc && data )
3225 global_shortcuts_disabled_for_client =
true;
3226 pending_dfc =
false;
3230 global_shortcuts_disabled = data;
3231 global_shortcuts_disabled_for_client =
false;
3234 for( ClientList::ConstIterator it = clients.begin();
3235 it != clients.end();
3237 (*it)->updateMouseGrab();
3242#include "workspace.moc"