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 readCompositorPID(
const TQString &pidfileFName) {
83 TQFile pidFile(pidfileFName);
85 if (pidFile.open(IO_ReadOnly)) {
89 pidFile.readLine(pidStr, 21);
90 rv = pidStr.toInt(&ok);
100pid_t getCompositorPID() {
101 pid_t rv = readCompositorPID(compositorPIDFile());
104 if (kill(rv, 0) != 0) {
118Workspace::Workspace(
bool restore )
119 : DCOPObject (
"KWinInterface"),
120 TQObject (0,
"workspace"),
122 number_of_desktops(0),
124 active_popup( NULL ),
125 active_popup_client( NULL ),
127 temporaryRulesMessages(
"_KDE_NET_WM_TEMPORARY_RULES", NULL, false ),
128 rules_updates_disabled( false ),
130 last_active_client (0),
131 next_active_client (0),
132 most_recently_raised (0),
134 pending_take_activity ( NULL ),
135 delayfocus_client (0),
136 showing_desktop( false ),
137 block_showing_desktop( 0 ),
138 was_user_interaction (false),
139 session_saving (false),
140 control_grab (false),
142 mouse_emulation (false),
149 desk_popup_index (0),
151 client_keys ( NULL ),
152 client_keys_dialog ( NULL ),
153 client_keys_client ( NULL ),
154 disable_shortcuts_keys ( NULL ),
155 global_shortcuts_disabled( false ),
156 global_shortcuts_disabled_for_client( false ),
158 workspaceInit (true),
160 layoutOrientation(TQt::Vertical),
165 managing_topmenus( false ),
166 topmenu_selection( NULL ),
167 topmenu_watcher( NULL ),
169 topmenu_space( NULL ),
170 set_active_client_recursion( 0 ),
171 block_stacking_updates( 0 ),
172 forced_global_mouse_grab( false ),
174 kompmgr_selection( NULL ),
175 kompmgr_kill_timer( NULL ),
176 allowKompmgrRestart( true )
180 root = tqt_xrootwin();
181 default_colormap = DefaultColormap(tqt_xdisplay(), tqt_xscreen() );
182 installed_colormap = default_colormap;
183 session.setAutoDelete(
true );
185 for (
int i = 0; i < ACTIVE_BORDER_COUNT; ++i)
187 active_reserved[i] = 0;
188 active_windows[i] = None;
191 connect( &temporaryRulesMessages, TQ_SIGNAL( gotMessage(
const TQString& )),
192 this, TQ_SLOT( gotTemporaryRulesMessage(
const TQString& )));
193 connect( &rulesUpdatedTimer, TQ_SIGNAL( timeout()),
this, TQ_SLOT( writeWindowRules()));
199 active_time_first = get_tqt_x_time();
200 active_time_last = get_tqt_x_time();
207 (void) TQApplication::desktop();
213 (WFlags)(TQt::WType_Desktop | TQt::WPaintUnclipped)
216 tdeApp->setGlobalMouseTracking(
true );
218 startup =
new TDEStartupInfo(
219 TDEStartupInfo::DisableKWinModule | TDEStartupInfo::AnnounceSilenceChanges,
this );
222 XSelectInput(tqt_xdisplay(), root,
226 SubstructureRedirectMask |
227 SubstructureNotifyMask |
243 (
unsigned char*) &data,
247 client_keys =
new TDEGlobalAccel(
this );
249 tab_box =
new TabBox(
this );
250 popupinfo =
new PopupInfo(
this );
254#if (TQT_VERSION-0 >= 0x030200)
255 connect( tdeApp->desktop(), TQ_SIGNAL( resized(
int )), TQ_SLOT( desktopResized()));
258 if (!supportsCompMgr()) {
259 options->useTranslucency =
false;
265 if (pid_t kompmgrpid = getCompositorPID())
266 kill(kompmgrpid, SIGTERM);
268 if (options->useTranslucency)
273void Workspace::init()
275 if (options->activeBorders() == Options::ActiveSwitchAlways)
277 reserveActiveBorderSwitching(
true);
279 updateActiveBorders();
285 supportWindow =
new TQWidget;
286 XLowerWindow( tqt_xdisplay(), supportWindow->winId());
288 XSetWindowAttributes attr;
289 attr.override_redirect = 1;
290 null_focus_window = XCreateWindow( tqt_xdisplay(), tqt_xrootwin(), -1,-1, 1, 1, 0, CopyFromParent,
291 InputOnly, CopyFromParent, CWOverrideRedirect, &attr );
292 XMapWindow(tqt_xdisplay(), null_focus_window);
294 unsigned long protocols[ 5 ] =
297 NET::SupportingWMCheck |
299 NET::ClientListStacking |
300 NET::DesktopGeometry |
301 NET::NumberOfDesktops |
302 NET::CurrentDesktop |
307 NET::KDESystemTrayWindows |
314 NET::WMIconGeometry |
318 NET::WMKDESystemTrayWinFor |
319 NET::WMFrameExtents |
346 NET::DemandsAttention |
351 NET::WM2AllowedActions |
352 NET::WM2RestackWindow |
353 NET::WM2MoveResizeWindow |
354 NET::WM2ExtendedStrut |
355 NET::WM2KDETemporaryRules |
356 NET::WM2ShowingDesktop |
357 NET::WM2FullPlacement |
358 NET::WM2DesktopLayout |
363 NET::ActionMinimize |
367 NET::ActionMaxHoriz |
368 NET::ActionFullScreen |
369 NET::ActionChangeDesktop |
375 rootInfo =
new RootInfo(
this, tqt_xdisplay(), supportWindow->winId(),
"KWin",
376 protocols, 5, tqt_xscreen() );
378 loadDesktopSettings();
379 updateDesktopLayout();
381 NETRootInfo client_info( tqt_xdisplay(), NET::ActiveWindow | NET::CurrentDesktop );
383 if( !tdeApp->isSessionRestored())
384 initial_desktop = client_info.currentDesktop();
387 TDEConfigGroupSaver saver( tdeApp->sessionConfig(),
"Session" );
388 initial_desktop = tdeApp->sessionConfig()->readNumEntry(
"desktop", 1 );
390 if( !setCurrentDesktop( initial_desktop ))
391 setCurrentDesktop( 1 );
394 initPositioning =
new Placement(
this);
396 connect(&reconfigureTimer, TQ_SIGNAL(timeout()),
this,
397 TQ_SLOT(slotReconfigure()));
398 connect( &updateToolWindowsTimer, TQ_SIGNAL( timeout()),
this, TQ_SLOT( slotUpdateToolWindows()));
400 connect(tdeApp, TQ_SIGNAL(appearanceChanged()),
this,
401 TQ_SLOT(slotReconfigure()));
402 connect(tdeApp, TQ_SIGNAL(settingsChanged(
int)),
this,
403 TQ_SLOT(slotSettingsChanged(
int)));
404 connect(tdeApp, TQ_SIGNAL( kipcMessage(
int,
int )),
this, TQ_SLOT( kipcMessage(
int,
int )));
406 active_client = NULL;
407 rootInfo->setActiveWindow( None );
409 if( !tdeApp->isSessionRestored())
413 sprintf( nm,
"_KDE_TOPMENU_OWNER_S%d", DefaultScreen( tqt_xdisplay()));
414 Atom topmenu_atom = XInternAtom( tqt_xdisplay(), nm, False );
415 topmenu_selection =
new TDESelectionOwner( topmenu_atom );
416 topmenu_watcher =
new TDESelectionWatcher( topmenu_atom );
420 StackingUpdatesBlocker blocker(
this );
422 if( options->topMenuEnabled() && topmenu_selection->claim(
false ))
423 setupTopMenuHandling();
425 lostTopMenuSelection();
427 unsigned int i, nwins;
428 Window root_return, parent_return, *wins;
429 XQueryTree(tqt_xdisplay(), root, &root_return, &parent_return, &wins, &nwins);
430 for (i = 0; i < nwins; i++)
432 XWindowAttributes attr;
433 XGetWindowAttributes(tqt_xdisplay(), wins[i], &attr);
434 if (attr.override_redirect )
436 if( topmenu_space && topmenu_space->winId() == wins[ i ] )
438 if (attr.map_state != IsUnmapped)
440 if ( addSystemTrayWin( wins[i] ) )
442 Client* c = createClient( wins[i],
true );
443 if ( c != NULL && root != tqt_xrootwin() )
446 XReparentWindow( tqt_xdisplay(), c->frameId(), root, 0, 0 );
452 XFree((
void *) wins);
454 updateStackingOrder(
true );
459 NETPoint* viewports =
new NETPoint[ number_of_desktops ];
460 rootInfo->setDesktopViewport( number_of_desktops, *viewports );
462 TQRect geom = TQApplication::desktop()->geometry();
463 NETSize desktop_geometry;
464 desktop_geometry.width = geom.width();
465 desktop_geometry.height = geom.height();
466 rootInfo->setDesktopGeometry( -1, desktop_geometry );
467 setShowingDesktop(
false );
471 Client* new_active_client = NULL;
472 if( !tdeApp->isSessionRestored())
475 new_active_client = findClient( WindowMatchPredicate( client_info.activeWindow()));
477 if( new_active_client == NULL
478 && activeClient() == NULL && should_get_focus.count() == 0 )
480 if( new_active_client == NULL )
481 new_active_client = topClientOnDesktop( currentDesktop());
482 if( new_active_client == NULL && !desktops.isEmpty() )
483 new_active_client = findDesktop(
true, currentDesktop());
485 if( new_active_client != NULL )
486 activateClient( new_active_client );
489 outline_left = XCreateWindow(tqt_xdisplay(), rootWin(), 0, 0, 1, 1, 0,
490 CopyFromParent, CopyFromParent, CopyFromParent,
491 CWOverrideRedirect, &attr);
492 outline_right = XCreateWindow(tqt_xdisplay(), rootWin(), 0, 0, 1, 1, 0,
493 CopyFromParent, CopyFromParent, CopyFromParent,
494 CWOverrideRedirect, &attr);
495 outline_top = XCreateWindow(tqt_xdisplay(), rootWin(), 0, 0, 1, 1, 0,
496 CopyFromParent, CopyFromParent, CopyFromParent,
497 CWOverrideRedirect, &attr);
498 outline_bottom = XCreateWindow(tqt_xdisplay(), rootWin(), 0, 0, 1, 1, 0,
499 CopyFromParent, CopyFromParent, CopyFromParent,
500 CWOverrideRedirect, &attr);
505 workspaceInit =
false;
509Workspace::~Workspace()
513 blockStackingUpdates(
true );
516 for( ClientList::ConstIterator it = stacking_order.begin();
517 it != stacking_order.end();
521 (*it)->releaseWindow(
true );
525 clients.remove( *it );
526 desktops.remove( *it );
528 delete desktop_widget;
532 if ( root == tqt_xrootwin() )
533 XDeleteProperty(tqt_xdisplay(), tqt_xrootwin(), atoms->twin_running);
536 TDEGlobal::config()->sync();
539 XDestroyWindow(tqt_xdisplay(), outline_left);
540 XDestroyWindow(tqt_xdisplay(), outline_right);
541 XDestroyWindow(tqt_xdisplay(), outline_top);
542 XDestroyWindow(tqt_xdisplay(), outline_bottom);
545 delete supportWindow;
550 delete initPositioning;
551 delete topmenu_watcher;
552 delete topmenu_selection;
553 delete topmenu_space;
554 delete client_keys_dialog;
555 while( !rules.isEmpty())
557 delete rules.front();
560 XDestroyWindow( tqt_xdisplay(), null_focus_window );
565Client* Workspace::createClient( Window w,
bool is_mapped )
567 StackingUpdatesBlocker blocker(
this );
568 Client* c =
new Client(
this );
569 if( !c->manage( w, is_mapped ))
571 Client::deleteClient( c, Allowed );
574 addClient( c, Allowed );
578void Workspace::addClient( Client* c, allowed_t )
582 c->setBMP(c->resourceName() ==
"beep-media-player" || c->decorationId() == None);
584 c->getWindowOpacity();
588 if (!c->hasCustomOpacity())
590 c->setShadowSize(options->dockShadowSize);
591 c->setOpacity(options->translucentDocks ? options->dockOpacity : Client::Opacity::Opaque);
599 if (c->isMenu() || c->isTopMenu())
601 c->setShadowSize(options->menuShadowSize);
604 Group* grp = findGroup( c->window());
608 if ( c->isDesktop() )
610 desktops.append( c );
611 if( active_client == NULL && should_get_focus.isEmpty() && c->isOnCurrentDesktop())
616 updateFocusChains( c, FocusChainUpdate );
619 if( !unconstrained_stacking_order.contains( c ))
620 unconstrained_stacking_order.append( c );
621 if( !stacking_order.contains( c ))
622 stacking_order.append( c );
626 updateClientLayer( c );
631 if( activeClient() == NULL && should_get_focus.count() == 0 )
632 activateClient( findDesktop(
true, currentDesktop()));
634 c->checkActiveModal();
635 checkTransients( c->window());
636 updateStackingOrder(
true );
637 if( c->isUtility() || c->isMenu() || c->isToolbar())
638 updateToolWindows(
true );
639 checkNonExistentClients();
645void Workspace::removeClient( Client* c, allowed_t )
647 if (c == active_popup_client)
650 if( client_keys_client == c )
651 setupWindowShortcutDone(
false );
652 if( !c->shortcut().isNull())
653 c->setShortcut( TQString::null );
656 Notify::raise( Notify::TransDelete );
657 if( c->isNormalWindow())
658 Notify::raise( Notify::Delete );
660 Q_ASSERT( clients.contains( c ) || desktops.contains( c ));
662 desktops.remove( c );
663 unconstrained_stacking_order.remove( c );
664 stacking_order.remove( c );
666 i <= numberOfDesktops();
668 focus_chain[ i ].remove( c );
669 global_focus_chain.remove( c );
670 attention_chain.remove( c );
671 showing_desktop_clients.remove( c );
674 Group* group = findGroup( c->window());
678 if ( c == most_recently_raised )
679 most_recently_raised = 0;
680 should_get_focus.remove( c );
681 Q_ASSERT( c != active_client );
682 if ( c == last_active_client )
683 last_active_client = 0;
684 if( c == pending_take_activity )
685 pending_take_activity = NULL;
686 if( c == delayfocus_client )
689 updateStackingOrder(
true );
697void Workspace::updateFocusChains( Client* c, FocusChainChange change )
699 if( !c->wantsTabFocus())
702 i<= numberOfDesktops();
704 focus_chain[i].remove(c);
705 global_focus_chain.remove( c );
708 if(c->desktop() == NET::OnAllDesktops)
710 for(
int i=1; i<= numberOfDesktops(); i++)
712 if( i == currentDesktop()
713 && ( change == FocusChainMakeFirst || change == FocusChainMakeLast ))
715 focus_chain[ i ].remove( c );
716 if( change == FocusChainMakeFirst )
717 focus_chain[ i ].append( c );
719 focus_chain[ i ].prepend( c );
721 else if( !focus_chain[ i ].contains( c ))
723 if( active_client != NULL && active_client != c
724 && !focus_chain[ i ].isEmpty() && focus_chain[ i ].last() == active_client )
725 focus_chain[ i ].insert( focus_chain[ i ].fromLast(), c );
727 focus_chain[ i ].append( c );
733 for(
int i=1; i<= numberOfDesktops(); i++)
735 if( i == c->desktop())
737 if( change == FocusChainMakeFirst )
739 focus_chain[ i ].remove( c );
740 focus_chain[ i ].append( c );
742 else if( change == FocusChainMakeLast )
744 focus_chain[ i ].remove( c );
745 focus_chain[ i ].prepend( c );
747 else if( !focus_chain[ i ].contains( c ))
749 if( active_client != NULL && active_client != c
750 && !focus_chain[ i ].isEmpty() && focus_chain[ i ].last() == active_client )
751 focus_chain[ i ].insert( focus_chain[ i ].fromLast(), c );
753 focus_chain[ i ].append( c );
757 focus_chain[ i ].remove( c );
760 if( change == FocusChainMakeFirst )
762 global_focus_chain.remove( c );
763 global_focus_chain.append( c );
765 else if( change == FocusChainMakeLast )
767 global_focus_chain.remove( c );
768 global_focus_chain.prepend( c );
770 else if( !global_focus_chain.contains( c ))
772 if( active_client != NULL && active_client != c
773 && !global_focus_chain.isEmpty() && global_focus_chain.last() == active_client )
774 global_focus_chain.insert( global_focus_chain.fromLast(), c );
776 global_focus_chain.append( c );
780void Workspace::updateOverlappingShadows(
unsigned long window)
784 if ((client = findClient(WindowMatchPredicate((WId)window))))
787 client->drawOverlappingShadows(
false);
790void Workspace::setShadowed(
unsigned long window,
bool shadowed)
794 if ((client = findClient(WindowMatchPredicate((WId)window))))
795 client->setShadowed(shadowed);
798void Workspace::updateCurrentTopMenu()
800 if( !managingTopMenus())
804 bool block_desktop_menubar =
false;
808 Client* menu_client = active_client;
811 if( menu_client->isFullScreen())
812 block_desktop_menubar =
true;
813 for( ClientList::ConstIterator it = menu_client->transients().begin();
814 it != menu_client->transients().end();
816 if( (*it)->isTopMenu())
821 if( menubar != NULL || !menu_client->isTransient())
823 if( menu_client->isModal() || menu_client->transientFor() == NULL )
825 menu_client = menu_client->transientFor();
829 for( ClientList::ConstIterator it = active_client->group()->members().begin();
830 it != active_client->group()->members().end();
832 if( (*it)->isTopMenu())
839 if( !menubar && !block_desktop_menubar && options->desktopTopMenu())
842 Client* desktop = findDesktop(
true, currentDesktop());
843 if( desktop != NULL )
845 for( ClientList::ConstIterator it = desktop->transients().begin();
846 it != desktop->transients().end();
848 if( (*it)->isTopMenu())
857 if( menubar == NULL )
859 for( ClientList::ConstIterator it = topmenus.begin();
860 it != topmenus.end();
862 if( (*it)->wasOriginallyGroupTransient())
873 if( active_client && !menubar->isOnDesktop( active_client->desktop()))
874 menubar->setDesktop( active_client->desktop());
875 menubar->hideClient(
false );
876 topmenu_space->hide();
880 unconstrained_stacking_order.remove( menubar );
881 unconstrained_stacking_order.append( menubar );
883 else if( !block_desktop_menubar )
885 topmenu_space->show();
889 for ( ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it)
891 if( (*it)->isTopMenu() && (*it) != menubar )
892 (*it)->hideClient(
true );
897void Workspace::updateToolWindows(
bool also_hide )
900 if( !options->hideUtilityWindowsForInactive )
902 for( ClientList::ConstIterator it = clients.begin();
905 (*it)->hideClient(
false );
908 const Group* group = NULL;
909 const Client* client = active_client;
912 while( client != NULL )
914 if( !client->isTransient())
916 if( client->groupTransient())
918 group = client->group();
921 client = client->transientFor();
927 ClientList to_show, to_hide;
928 for( ClientList::ConstIterator it = stacking_order.begin();
929 it != stacking_order.end();
932 if( (*it)->isUtility() || (*it)->isMenu() || (*it)->isToolbar())
935 if( !(*it)->isTransient())
937 if( (*it)->group()->members().count() == 1 )
939 else if( client != NULL && (*it)->group() == client->group())
946 if( group != NULL && (*it)->group() == group )
948 else if( client != NULL && client->hasTransient( (*it),
true ))
953 if( !show && also_hide )
955 const ClientList mainclients = (*it)->mainClients();
958 if( mainclients.isEmpty())
960 for( ClientList::ConstIterator it2 = mainclients.begin();
961 it2 != mainclients.end();
964 if( (*it2)->isSpecialWindow())
968 to_hide.append( *it );
971 to_show.append( *it );
974 for( ClientList::ConstIterator it = to_show.fromLast();
978 (*it)->hideClient(
false );
981 for( ClientList::ConstIterator it = to_hide.begin();
984 (*it)->hideClient(
true );
985 updateToolWindowsTimer.stop();
989 updateToolWindowsTimer.start( 50,
true );
993void Workspace::slotUpdateToolWindows()
995 updateToolWindows(
true );
1001void Workspace::updateColormap()
1003 Colormap cmap = default_colormap;
1004 if ( activeClient() && activeClient()->colormap() != None )
1005 cmap = activeClient()->colormap();
1006 if ( cmap != installed_colormap )
1008 XInstallColormap(tqt_xdisplay(), cmap );
1009 installed_colormap = cmap;
1013void Workspace::reconfigure()
1015 reconfigureTimer.start(200,
true);
1019void Workspace::slotSettingsChanged(
int category)
1021 kdDebug(1212) <<
"Workspace::slotSettingsChanged()" << endl;
1022 if( category == (
int) TDEApplication::SETTINGS_SHORTCUTS )
1029KWIN_PROCEDURE( CheckBorderSizesProcedure, cl->checkBorderSizes() );
1031void Workspace::slotReconfigure()
1033 kdDebug(1212) <<
"Workspace::slotReconfigure()" << endl;
1034 reconfigureTimer.stop();
1036 if (options->activeBorders() == Options::ActiveSwitchAlways)
1038 reserveActiveBorderSwitching(
false);
1041 TDEGlobal::config()->reparseConfiguration();
1042 unsigned long changed = options->updateSettings();
1043 tab_box->reconfigure();
1044 popupinfo->reconfigure();
1045 initPositioning->reinitCascading( 0 );
1047 forEachClient( CheckIgnoreFocusStealingProcedure());
1048 updateToolWindows(
true );
1050 if( mgr->reset( changed ))
1054 curtain.setBackgroundMode( NoBackground );
1055 curtain.setGeometry( TQApplication::desktop()->geometry() );
1058 for( ClientList::ConstIterator it = clients.begin();
1059 it != clients.end();
1062 (*it)->updateDecoration(
true,
true );
1064 mgr->destroyPreviousPlugin();
1068 forEachClient( CheckBorderSizesProcedure());
1071 if (options->activeBorders() == Options::ActiveSwitchAlways)
1073 reserveActiveBorderSwitching(
true);
1076 if( options->topMenuEnabled() && !managingTopMenus())
1078 if( topmenu_selection->claim(
false ))
1079 setupTopMenuHandling();
1081 lostTopMenuSelection();
1083 else if( !options->topMenuEnabled() && managingTopMenus())
1085 topmenu_selection->release();
1086 lostTopMenuSelection();
1089 if( managingTopMenus())
1091 updateTopMenuGeometry();
1092 updateCurrentTopMenu();
1096 for( ClientList::Iterator it = clients.begin();
1097 it != clients.end();
1100 (*it)->setupWindowRules(
true );
1101 (*it)->applyWindowRules();
1102 discardUsedWindowRules( *it,
false );
1105 if (options->resetKompmgr)
1107 if (options->useTranslucency)
1109 if (kompmgrIsRunning())
1110 kompmgrReloadSettings();
1112 TQTimer::singleShot( 200,
this, TQ_SLOT(startKompmgr()) );
1121void Workspace::loadDesktopSettings()
1123 TDEConfig* c = TDEGlobal::config();
1124 TQCString groupname;
1125 if (screen_number == 0)
1126 groupname =
"Desktops";
1128 groupname.sprintf(
"Desktops-screen-%d", screen_number);
1129 TDEConfigGroupSaver saver(c,groupname);
1131 int n = c->readNumEntry(
"Number", 4);
1132 number_of_desktops = n;
1134 workarea =
new TQRect[ n + 1 ];
1137 rootInfo->setNumberOfDesktops( number_of_desktops );
1138 desktop_focus_chain.resize( n );
1140 focus_chain.resize( n + 1 );
1141 for(
int i = 1; i <= n; i++)
1143 TQString s = c->readEntry(TQString(
"Name_%1").arg(i),
1144 i18n(
"Desktop %1").arg(i));
1145 rootInfo->setDesktopName( i, s.utf8().data() );
1146 desktop_focus_chain[i-1] = i;
1150void Workspace::saveDesktopSettings()
1152 TDEConfig* c = TDEGlobal::config();
1153 TQCString groupname;
1154 if (screen_number == 0)
1155 groupname =
"Desktops";
1157 groupname.sprintf(
"Desktops-screen-%d", screen_number);
1158 TDEConfigGroupSaver saver(c,groupname);
1160 c->writeEntry(
"Number", number_of_desktops );
1161 for(
int i = 1; i <= number_of_desktops; i++)
1163 TQString s = desktopName( i );
1164 TQString defaultvalue = i18n(
"Desktop %1").arg(i);
1168 rootInfo->setDesktopName( i, s.utf8().data() );
1171 if (s != defaultvalue)
1173 c->writeEntry( TQString(
"Name_%1").arg(i), s );
1177 TQString currentvalue = c->readEntry(TQString(
"Name_%1").arg(i));
1178 if (currentvalue != defaultvalue)
1179 c->writeEntry( TQString(
"Name_%1").arg(i),
"" );
1184TQStringList Workspace::configModules(
bool controlCenter)
1187 args <<
"tde-twindecoration.desktop";
1189 args <<
"tde-twinoptions.desktop";
1190 else if (tdeApp->authorizeControlModule(
"tde-twinoptions.desktop"))
1191 args <<
"twinactions" <<
"twinfocus" <<
"twinmoving" <<
"twinadvanced" <<
"twinrules" <<
"twintranslucency";
1195void Workspace::configureWM()
1197 TDEApplication::tdeinitExec(
"tdecmshell", configModules(
false) );
1203void Workspace::doNotManage( TQString title )
1205 doNotManageList.append( title );
1211bool Workspace::isNotManaged(
const TQString& title )
1213 for ( TQStringList::Iterator it = doNotManageList.begin(); it != doNotManageList.end(); ++it )
1215 TQRegExp r( (*it) );
1216 if (r.search(title) != -1)
1218 doNotManageList.remove( it );
1228void Workspace::refresh()
1231 w.setGeometry( TQApplication::desktop()->geometry() );
1234 TQApplication::flushX();
1244class ObscuringWindows
1247 ~ObscuringWindows();
1248 void create( Client* c );
1250 TQValueList<Window> obscuring_windows;
1251 static TQValueList<Window>* cached;
1252 static unsigned int max_cache_size;
1255TQValueList<Window>* ObscuringWindows::cached = 0;
1256unsigned int ObscuringWindows::max_cache_size = 0;
1258void ObscuringWindows::create( Client* c )
1261 cached =
new TQValueList<Window>;
1263 XWindowChanges chngs;
1264 int mask = CWSibling | CWStackMode;
1265 if( cached->count() > 0 )
1267 cached->remove( obs_win = cached->first());
1270 chngs.width = c->width();
1271 chngs.height = c->height();
1272 mask |= CWX | CWY | CWWidth | CWHeight;
1276 XSetWindowAttributes a;
1277 a.background_pixmap = None;
1278 a.override_redirect = True;
1279 obs_win = XCreateWindow( tqt_xdisplay(), tqt_xrootwin(), c->x(), c->y(),
1280 c->width(), c->height(), 0, CopyFromParent, InputOutput,
1281 CopyFromParent, CWBackPixmap | CWOverrideRedirect, &a );
1283 chngs.sibling = c->frameId();
1284 chngs.stack_mode = Below;
1285 XConfigureWindow( tqt_xdisplay(), obs_win, mask, &chngs );
1286 XMapWindow( tqt_xdisplay(), obs_win );
1287 obscuring_windows.append( obs_win );
1290ObscuringWindows::~ObscuringWindows()
1292 max_cache_size = TQMAX( max_cache_size, obscuring_windows.count() + 4 ) - 1;
1293 for( TQValueList<Window>::ConstIterator it = obscuring_windows.begin();
1294 it != obscuring_windows.end();
1297 XUnmapWindow( tqt_xdisplay(), *it );
1298 if( cached->count() < max_cache_size )
1299 cached->prepend( *it );
1301 XDestroyWindow( tqt_xdisplay(), *it );
1312bool Workspace::setCurrentDesktop(
int new_desktop )
1314 if (new_desktop < 1 || new_desktop > number_of_desktops )
1320 StackingUpdatesBlocker blocker(
this );
1322 int old_desktop = current_desktop;
1323 if (new_desktop != current_desktop)
1325 ++block_showing_desktop;
1330 Notify::raise((Notify::Event) (Notify::DesktopChange+new_desktop));
1332 ObscuringWindows obs_wins;
1334 current_desktop = new_desktop;
1336 bool desktopHasCompositing = tdeApp->isCompositionManagerAvailable();
1337 if (!desktopHasCompositing) {
1339 for ( ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it) {
1340 if ( !(*it)->isOnDesktop( new_desktop ) && (*it) != movingClient )
1342 if( (*it)->isShown(
true ) && (*it)->isOnDesktop( old_desktop )) {
1343 obs_wins.create( *it );
1345 (*it)->updateVisibility();
1350 rootInfo->setCurrentDesktop( current_desktop );
1352 if( movingClient && !movingClient->isOnDesktop( new_desktop ))
1353 movingClient->setDesktop( new_desktop );
1355 for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it) {
1356 if ( (*it)->isOnDesktop( new_desktop ) ) {
1357 (*it)->updateVisibility();
1361 if (desktopHasCompositing) {
1364 XSync( tqt_xdisplay(),
false);
1365 for ( ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it) {
1366 if ( !(*it)->isOnDesktop( new_desktop ) && (*it) != movingClient )
1368 if( (*it)->isShown(
true ) && (*it)->isOnDesktop( old_desktop )) {
1369 obs_wins.create( *it );
1371 (*it)->updateVisibility();
1376 --block_showing_desktop;
1377 if( showingDesktop())
1378 resetShowingDesktop(
false );
1385 if ( options->focusPolicyIsReasonable())
1388 if ( movingClient != NULL && active_client == movingClient
1389 && focus_chain[currentDesktop()].contains( active_client )
1390 && active_client->isShown(
true ) && active_client->isOnCurrentDesktop())
1396 for( ClientList::ConstIterator it = focus_chain[currentDesktop()].fromLast();
1397 it != focus_chain[currentDesktop()].end();
1400 if ( (*it)->isShown(
false ) && (*it)->isOnCurrentDesktop())
1412 else if( active_client && active_client->isShown(
true ) && active_client->isOnCurrentDesktop())
1415 if( c == NULL && !desktops.isEmpty())
1416 c = findDesktop(
true, currentDesktop());
1418 if( c != active_client )
1419 setActiveClient( NULL, Allowed );
1426 updateCurrentTopMenu();
1433 for(
int i = desktop_focus_chain.find( currentDesktop() ); i > 0; i-- )
1434 desktop_focus_chain[i] = desktop_focus_chain[i-1];
1435 desktop_focus_chain[0] = currentDesktop();
1442 if( old_desktop != 0 )
1443 popupinfo->showInfo( desktopName(currentDesktop()) );
1448void Workspace::nextDesktop()
1450 int desktop = currentDesktop() + 1;
1451 setCurrentDesktop(desktop > numberOfDesktops() ? 1 : desktop);
1455void Workspace::previousDesktop()
1457 int desktop = currentDesktop() - 1;
1458 setCurrentDesktop(desktop > 0 ? desktop : numberOfDesktops());
1461int Workspace::desktopToRight(
int desktop )
const
1464 calcDesktopLayout(x,y);
1466 if (layoutOrientation == TQt::Vertical)
1469 if ( dt >= numberOfDesktops() )
1471 if ( options->rollOverDesktops )
1472 dt -= numberOfDesktops();
1479 int d = (dt % x) + 1;
1482 if ( options->rollOverDesktops )
1487 dt = dt - (dt % x) + d;
1492int Workspace::desktopToLeft(
int desktop )
const
1495 calcDesktopLayout(x,y);
1497 if (layoutOrientation == TQt::Vertical)
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::desktopUp(
int desktop )
const
1526 calcDesktopLayout(x,y);
1528 if (layoutOrientation == TQt::Horizontal)
1533 if ( options->rollOverDesktops )
1534 dt += numberOfDesktops();
1541 int d = (dt % y) - 1;
1544 if ( options->rollOverDesktops )
1549 dt = dt - (dt % y) + d;
1554int Workspace::desktopDown(
int desktop )
const
1557 calcDesktopLayout(x,y);
1559 if (layoutOrientation == TQt::Horizontal)
1562 if ( dt >= numberOfDesktops() )
1564 if ( options->rollOverDesktops )
1565 dt -= numberOfDesktops();
1572 int d = (dt % y) + 1;
1575 if ( options->rollOverDesktops )
1580 dt = dt - (dt % y) + d;
1589void Workspace::setNumberOfDesktops(
int n )
1591 if ( n == number_of_desktops )
1593 int old_number_of_desktops = number_of_desktops;
1594 number_of_desktops = n;
1596 if( currentDesktop() > numberOfDesktops())
1597 setCurrentDesktop( numberOfDesktops());
1601 if( old_number_of_desktops < number_of_desktops )
1603 rootInfo->setNumberOfDesktops( number_of_desktops );
1604 NETPoint* viewports =
new NETPoint[ number_of_desktops ];
1605 rootInfo->setDesktopViewport( number_of_desktops, *viewports );
1607 updateClientArea(
true );
1608 focus_chain.resize( number_of_desktops + 1 );
1613 if( old_number_of_desktops > number_of_desktops )
1615 for( ClientList::ConstIterator it = clients.begin();
1616 it != clients.end();
1619 if( !(*it)->isOnAllDesktops() && (*it)->desktop() > numberOfDesktops())
1620 sendClientToDesktop( *it, numberOfDesktops(),
true );
1623 if( old_number_of_desktops > number_of_desktops )
1625 rootInfo->setNumberOfDesktops( number_of_desktops );
1626 NETPoint* viewports =
new NETPoint[ number_of_desktops ];
1627 rootInfo->setDesktopViewport( number_of_desktops, *viewports );
1629 updateClientArea(
true );
1630 focus_chain.resize( number_of_desktops + 1 );
1633 saveDesktopSettings();
1636 desktop_focus_chain.resize( n );
1637 for(
int i = 0; i < (int)desktop_focus_chain.size(); i++ )
1638 desktop_focus_chain[i] = i+1;
1646void Workspace::sendClientToDesktop( Client* c,
int desk,
bool dont_activate )
1648 bool was_on_desktop = c->isOnDesktop( desk ) || c->isOnAllDesktops();
1649 c->setDesktop( desk );
1650 if ( c->desktop() != desk )
1652 desk = c->desktop();
1654 if ( c->isOnDesktop( currentDesktop() ) )
1656 if ( c->wantsTabFocus() && options->focusPolicyIsReasonable()
1661 restackClientUnderActive( c );
1668 ClientList transients_stacking_order = ensureStackingOrder( c->transients());
1669 for( ClientList::ConstIterator it = transients_stacking_order.begin();
1670 it != transients_stacking_order.end();
1672 sendClientToDesktop( *it, desk, dont_activate );
1676int Workspace::numScreens()
const
1678 if( !options->xineramaEnabled )
1680 return tqApp->desktop()->numScreens();
1683int Workspace::activeScreen()
const
1685 if( !options->xineramaEnabled )
1687 if( !options->activeMouseScreen )
1689 if( activeClient() != NULL && !activeClient()->isOnScreen( active_screen ))
1690 return tqApp->desktop()->screenNumber( activeClient()->geometry().center());
1691 return active_screen;
1693 return tqApp->desktop()->screenNumber( TQCursor::pos());
1698void Workspace::checkActiveScreen(
const Client* c )
1700 if( !options->xineramaEnabled )
1704 if( !c->isOnScreen( active_screen ))
1705 active_screen = c->screen();
1710void Workspace::setActiveScreenMouse( TQPoint mousepos )
1712 if( !options->xineramaEnabled )
1714 active_screen = tqApp->desktop()->screenNumber( mousepos );
1717TQRect Workspace::screenGeometry(
int screen )
const
1719 if (( !options->xineramaEnabled ) || (tdeApp->desktop()->numScreens() < 2))
1720 return tqApp->desktop()->geometry();
1721 return tqApp->desktop()->screenGeometry( screen );
1724int Workspace::screenNumber( TQPoint pos )
const
1726 if( !options->xineramaEnabled )
1728 return tqApp->desktop()->screenNumber( pos );
1731void Workspace::sendClientToScreen( Client* c,
int screen )
1733 if( c->screen() == screen )
1735 GeometryUpdatesPostponer blocker( c );
1736 TQRect old_sarea = clientArea( MaximizeArea, c );
1737 TQRect sarea = clientArea( MaximizeArea, screen, c->desktop());
1738 c->setGeometry( sarea.x() - old_sarea.x() + c->x(), sarea.y() - old_sarea.y() + c->y(),
1739 c->size().width(), c->size().height());
1740 c->checkWorkspacePosition();
1741 ClientList transients_stacking_order = ensureStackingOrder( c->transients());
1742 for( ClientList::ConstIterator it = transients_stacking_order.begin();
1743 it != transients_stacking_order.end();
1745 sendClientToScreen( *it, screen );
1747 active_screen = screen;
1751void Workspace::setDesktopLayout(
int,
int,
int )
1755void Workspace::updateDesktopLayout()
1758 layoutOrientation = ( rootInfo->desktopLayoutOrientation() == NET::OrientationHorizontal
1759 ? TQt::Horizontal : TQt::Vertical );
1760 layoutX = rootInfo->desktopLayoutColumnsRows().width();
1761 layoutY = rootInfo->desktopLayoutColumnsRows().height();
1762 if( layoutX == 0 && layoutY == 0 )
1766void Workspace::calcDesktopLayout(
int &x,
int &y)
const
1770 if((x <= 0) && (y > 0))
1771 x = (numberOfDesktops()+y-1) / y;
1772 else if((y <=0) && (x > 0))
1773 y = (numberOfDesktops()+x-1) / x;
1785bool Workspace::addSystemTrayWin( WId w )
1787 if ( systemTrayWins.contains( w ) )
1790 NETWinInfo ni( tqt_xdisplay(), w, root, NET::WMKDESystemTrayWinFor );
1791 WId trayWinFor = ni.kdeSystemTrayWinFor();
1794 systemTrayWins.append( SystemTrayWindow( w, trayWinFor ) );
1795 XSelectInput( tqt_xdisplay(), w,
1798 XAddToSaveSet( tqt_xdisplay(), w );
1799 propagateSystemTrayWins();
1807bool Workspace::removeSystemTrayWin( WId w,
bool check )
1809 if ( !systemTrayWins.contains( w ) )
1821 Atom* props = XListProperties( tqt_xdisplay(), w, &num_props );
1827 if( props[ i ] == atoms->kde_system_tray_embedding )
1835 systemTrayWins.remove( w );
1836 XRemoveFromSaveSet (tqt_xdisplay (), w);
1837 propagateSystemTrayWins();
1845void Workspace::propagateSystemTrayWins()
1847 Window *cl =
new Window[ systemTrayWins.count()];
1850 for ( SystemTrayWindowList::ConstIterator it = systemTrayWins.begin(); it != systemTrayWins.end(); ++it )
1852 cl[i++] = (*it).win;
1855 rootInfo->setKDESystemTrayWindows( cl, i );
1860void Workspace::killWindowId( Window window_to_kill )
1862 if( window_to_kill == None )
1864 Window window = window_to_kill;
1865 Client* client = NULL;
1868 client = findClient( FrameIdMatchPredicate( window ));
1869 if( client != NULL )
1873 Window* children = 0L;
1874 unsigned int children_count;
1875 XQueryTree( tqt_xdisplay(), window, &root, &parent, &children, &children_count );
1876 if( children != NULL )
1878 if( window == root )
1884 if( client != NULL )
1885 client->killWindow();
1887 XKillClient( tqt_xdisplay(), window_to_kill );
1890void Workspace::suspendWindowId( Window window_to_suspend )
1892 if( window_to_suspend == None )
1894 Window window = window_to_suspend;
1895 Client* client = NULL;
1898 client = findClient( FrameIdMatchPredicate( window ));
1899 if( client != NULL )
1903 Window* children = 0L;
1904 unsigned int children_count;
1905 XQueryTree( tqt_xdisplay(), window, &root, &parent, &children, &children_count );
1906 if( children != NULL )
1908 if( window == root )
1914 if( client != NULL )
1915 client->suspendWindow();
1920void Workspace::resumeWindowId( Window window_to_resume )
1922 if( window_to_resume == None )
1924 Window window = window_to_resume;
1925 Client* client = NULL;
1928 client = findClient( FrameIdMatchPredicate( window ));
1929 if( client != NULL )
1933 Window* children = 0L;
1934 unsigned int children_count;
1935 XQueryTree( tqt_xdisplay(), window, &root, &parent, &children, &children_count );
1936 if( children != NULL )
1938 if( window == root )
1944 if( client != NULL )
1945 client->resumeWindow();
1951bool Workspace::isResumeableWindowID( Window window_to_check )
1953 if( window_to_check == None )
1955 Window window = window_to_check;
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 return client->isResumeable();
1982void Workspace::sendPingToWindow( Window window, Time timestamp )
1984 rootInfo->sendPing( window, timestamp );
1987void Workspace::sendTakeActivity( Client* c, Time timestamp,
long flags )
1989 rootInfo->takeActivity( c->window(), timestamp, flags );
1990 pending_take_activity = c;
1997void Workspace::slotGrabWindow()
1999 if ( active_client )
2001 TQPixmap snapshot = TQPixmap::grabWindow( active_client->frameId() );
2004 if( Shape::available())
2008 XRectangle* rects = XShapeGetRectangles( tqt_xdisplay(), active_client->frameId(),
2009 ShapeBounding, &count, &order);
2018 for (
int pos = 0; pos < count; pos++)
2019 contents += TQRegion(rects[pos].x, rects[pos].y,
2020 rects[pos].width, rects[pos].height);
2024 TQRegion bbox(0, 0, snapshot.width(), snapshot.height());
2027 TQRegion maskedAway = bbox - contents;
2028 TQMemArray<TQRect> maskedAwayRects = maskedAway.rects();
2031 TQBitmap mask( snapshot.width(), snapshot.height());
2033 p.fillRect(0, 0, mask.width(), mask.height(), TQt::color1);
2034 for (uint pos = 0; pos < maskedAwayRects.count(); pos++)
2035 p.fillRect(maskedAwayRects[pos], TQt::color0);
2037 snapshot.setMask(mask);
2041 TQClipboard *cb = TQApplication::clipboard();
2042 cb->setPixmap( snapshot );
2051void Workspace::slotGrabDesktop()
2053 TQPixmap p = TQPixmap::grabWindow( tqt_xrootwin() );
2054 TQClipboard *cb = TQApplication::clipboard();
2062void Workspace::slotMouseEmulation()
2065 if ( mouse_emulation )
2067 XUngrabKeyboard(tqt_xdisplay(), get_tqt_x_time());
2068 mouse_emulation =
false;
2072 if ( XGrabKeyboard(tqt_xdisplay(),
2074 GrabModeAsync, GrabModeAsync,
2075 get_tqt_x_time()) == GrabSuccess )
2077 mouse_emulation =
true;
2078 mouse_emulation_state = 0;
2079 mouse_emulation_window = 0;
2089WId Workspace::getMouseEmulationWindow()
2092 Window child = tqt_xrootwin();
2093 int root_x, root_y, lx, ly;
2101 c = findClient( FrameIdMatchPredicate( w ));
2102 XQueryPointer( tqt_xdisplay(), w, &root, &child,
2103 &root_x, &root_y, &lx, &ly, &state );
2104 }
while ( child != None && child != w );
2106 if ( c && !c->isActive() )
2107 activateClient( c );
2114unsigned int Workspace::sendFakedMouseEvent( TQPoint pos, WId w, MouseEmulation type,
int button,
unsigned int state )
2118 TQWidget* widget = TQWidget::find( w );
2119 if ( (!widget || widget->inherits(
"TQToolButton") ) && !findClient( WindowMatchPredicate( w )) )
2123 XTranslateCoordinates( tqt_xdisplay(), tqt_xrootwin(), w, pos.x(), pos.y(), &x, &y, &xw );
2124 if ( type == EmuMove )
2127 e.type = MotionNotify;
2128 e.xmotion.window = w;
2129 e.xmotion.root = tqt_xrootwin();
2130 e.xmotion.subwindow = w;
2131 e.xmotion.time = get_tqt_x_time();
2134 e.xmotion.x_root = pos.x();
2135 e.xmotion.y_root = pos.y();
2136 e.xmotion.state = state;
2137 e.xmotion.is_hint = NotifyNormal;
2138 XSendEvent( tqt_xdisplay(), w, True, ButtonMotionMask, &e );
2143 e.type = type == EmuRelease ? ButtonRelease : ButtonPress;
2144 e.xbutton.window = w;
2145 e.xbutton.root = tqt_xrootwin();
2146 e.xbutton.subwindow = w;
2147 e.xbutton.time = get_tqt_x_time();
2150 e.xbutton.x_root = pos.x();
2151 e.xbutton.y_root = pos.y();
2152 e.xbutton.state = state;
2153 e.xbutton.button = button;
2154 XSendEvent( tqt_xdisplay(), w, True, ButtonPressMask, &e );
2156 if ( type == EmuPress )
2161 state |= Button2Mask;
2164 state |= Button3Mask;
2167 state |= Button1Mask;
2176 state &= ~Button2Mask;
2179 state &= ~Button3Mask;
2182 state &= ~Button1Mask;
2194bool Workspace::keyPressMouseEmulation( XKeyEvent& ev )
2196 if ( root != tqt_xrootwin() )
2198 int kc = XkbKeycodeToKeysym(tqt_xdisplay(), ev.keycode, 0, 0);
2199 int km = ev.state & (ControlMask | Mod1Mask | ShiftMask);
2201 bool is_control = km & ControlMask;
2202 bool is_alt = km & Mod1Mask;
2203 bool is_shift = km & ShiftMask;
2204 int delta = is_control?1:is_alt?32:8;
2205 TQPoint pos = TQCursor::pos();
2226 if ( !mouse_emulation_state )
2227 mouse_emulation_window = getMouseEmulationWindow();
2228 if ( (mouse_emulation_state & Button1Mask) == 0 )
2229 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuPress, Button1, mouse_emulation_state );
2231 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button1, mouse_emulation_state );
2234 if ( !mouse_emulation_state )
2235 mouse_emulation_window = getMouseEmulationWindow();
2236 if ( (mouse_emulation_state & Button2Mask) == 0 )
2237 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuPress, Button2, mouse_emulation_state );
2239 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button2, mouse_emulation_state );
2242 if ( !mouse_emulation_state )
2243 mouse_emulation_window = getMouseEmulationWindow();
2244 if ( (mouse_emulation_state & Button3Mask) == 0 )
2245 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuPress, Button3, mouse_emulation_state );
2247 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button3, mouse_emulation_state );
2254 if ( !mouse_emulation_state )
2257 mouse_emulation_window = getMouseEmulationWindow();
2258 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuPress, Button1, mouse_emulation_state );
2259 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button1, mouse_emulation_state );
2263 if ( mouse_emulation_state & Button1Mask )
2264 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button1, mouse_emulation_state );
2265 if ( mouse_emulation_state & Button2Mask )
2266 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button2, mouse_emulation_state );
2267 if ( mouse_emulation_state & Button3Mask )
2268 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button3, mouse_emulation_state );
2273 XUngrabKeyboard(tqt_xdisplay(), get_tqt_x_time());
2274 mouse_emulation =
false;
2280 TQCursor::setPos( pos );
2281 if ( mouse_emulation_state )
2282 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuMove, 0, mouse_emulation_state );
2292TQWidget* Workspace::desktopWidget()
2294 return desktop_widget;
2298void Workspace::delayFocus()
2300 requestFocus( delayfocus_client );
2304void Workspace::requestDelayFocus( Client* c )
2306 delayfocus_client = c;
2307 delete delayFocusTimer;
2308 delayFocusTimer =
new TQTimer(
this );
2309 connect( delayFocusTimer, TQ_SIGNAL( timeout() ),
this, TQ_SLOT( delayFocus() ) );
2310 delayFocusTimer->start( options->delayFocusInterval,
true );
2313void Workspace::cancelDelayFocus()
2315 delete delayFocusTimer;
2316 delayFocusTimer = 0;
2326void Workspace::updateActiveBorders()
2328 active_time_first = get_tqt_x_time();
2329 active_time_last = get_tqt_x_time();
2330 active_time_last_trigger = get_tqt_x_time();
2331 active_current_border = ActiveNone;
2332 TQRect r = TQApplication::desktop()->geometry();
2333 activeTop = r.top();
2334 activeBottom = r.bottom();
2335 activeLeft = r.left();
2336 activeRight = r.right();
2338 for (
int pos = 0; pos < ACTIVE_BORDER_COUNT; ++pos)
2340 if (active_reserved[pos] == 0)
2342 if (active_windows[pos] != None)
2344 XDestroyWindow( tqt_xdisplay(), active_windows[pos] );
2346 active_windows[pos] = None;
2350 if (active_windows[pos] != None)
2355 XSetWindowAttributes attributes;
2356 attributes.override_redirect = True;
2357 attributes.event_mask = EnterWindowMask;
2358 unsigned long valuemask = CWOverrideRedirect | CWEventMask;
2359 int xywh[ ACTIVE_BORDER_COUNT ][ 4 ] =
2361 { r.left() + 1, r.top(), r.width() - 2, 1 },
2362 { r.right(), r.top(), 1, 1 },
2363 { r.right(), r.top() + 1, 1, r.height() - 2 },
2364 { r.right(), r.bottom(), 1, 1 },
2365 { r.left() + 1, r.bottom(), r.width() - 2, 1 },
2366 { r.left(), r.bottom(), 1, 1 },
2367 { r.left(), r.top() + 1, 1, r.height() - 2 },
2368 { r.left(), r.top(), 1, 1 }
2370 active_windows[pos] = XCreateWindow(tqt_xdisplay(), tqt_xrootwin(),
2371 xywh[pos][0], xywh[pos][1],
2372 xywh[pos][2], xywh[pos][3],
2373 0, CopyFromParent, InputOnly,
2374 CopyFromParent, valuemask,
2376 XMapWindow(tqt_xdisplay(), active_windows[pos]);
2380 XChangeProperty(tqt_xdisplay(), active_windows[pos],
2381 atoms->xdnd_aware, XA_ATOM, 32, PropModeReplace,
2382 (
unsigned char*)&version, 1);
2386void Workspace::destroyActiveBorders()
2388 for (
int pos = 0; pos < ACTIVE_BORDER_COUNT; ++pos)
2390 if (active_windows[ pos ] != None)
2392 XDestroyWindow( tqt_xdisplay(), active_windows[ pos ] );
2394 active_windows[ pos ] = None;
2398void Workspace::reserveActiveBorderSwitching(
bool reserve )
2400 for (
int pos = 0; pos < ACTIVE_BORDER_COUNT; ++pos)
2404 reserveActiveBorder(
static_cast<ActiveBorder
>(pos));
2408 unreserveActiveBorder(
static_cast<ActiveBorder
>(pos));
2413void Workspace::reserveActiveBorder( ActiveBorder border )
2415 if (border == ActiveNone)
2418 if (active_reserved[border]++ == 0)
2419 TQTimer::singleShot(0,
this, TQ_SLOT(updateActiveBorders()));
2422void Workspace::unreserveActiveBorder( ActiveBorder border )
2424 if (border == ActiveNone)
2427 assert(active_reserved[ border ] > 0);
2428 if (--active_reserved[ border ] == 0)
2429 TQTimer::singleShot(0,
this, TQ_SLOT(updateActiveBorders()));
2432void Workspace::checkActiveBorder(
const TQPoint &pos, Time now)
2434 Time treshold_set = options->activeBorderDelay();
2435 Time treshold_trigger = 250;
2436 Time treshold_reset = 250;
2437 int activation_distance = options->borderActivationDistance();
2439 bool have_borders =
false;
2440 for (
int i = 0; i < ACTIVE_BORDER_COUNT; ++i)
2442 if (active_windows[ i ] != None)
2444 have_borders =
true;
2447 if (!have_borders) {
2452 int distance_reset = activation_distance + 10;
2456 (options->activeBorders() == Options::ActiveTileMaximize ||
2457 options->activeBorders() == Options::ActiveTileOnly))
2459 TQRect r = TQApplication::desktop()->screenGeometry(pos);
2460 activeTop = r.top();
2461 activeBottom = r.bottom();
2462 activeLeft = r.left();
2463 activeRight = r.right();
2465 if (active_current_border != ActiveNone &&
2466 (pos.x() > activeLeft + distance_reset) &&
2467 (pos.x() < activeRight - distance_reset) &&
2468 (pos.y() > activeTop + distance_reset) &&
2469 (pos.y() < activeBottom - distance_reset))
2471 movingClient->cancelActiveBorderMaximizing();
2478 bool active_left = pos.x() < activeLeft + activation_distance;
2479 bool active_right = pos.x() > activeRight - activation_distance;
2480 bool active_top = pos.y() < activeTop + activation_distance;
2481 bool active_bottom = pos.y() > activeBottom - activation_distance;
2483 if (!active_left && !active_right && !active_top && !active_bottom)
2491 int active_width_quart = (activeRight - activeLeft) / 4;
2492 int active_height_quart = (activeBottom - activeTop) / 4;
2494 bool active_qleft =
false;
2495 bool active_qright =
false;
2496 bool active_qtop =
false;
2497 bool active_qbottom =
false;
2498 if (options->activeBorders() == Options::ActiveTileMaximize ||
2499 options->activeBorders() == Options::ActiveTileOnly)
2501 active_qleft = pos.x() < activeLeft + active_width_quart;
2502 active_qright = pos.x() > activeRight - active_width_quart;
2503 active_qtop = pos.y() < activeTop + active_height_quart;
2504 active_qbottom = pos.y() > activeBottom - active_height_quart;
2507 ActiveBorder border = ActiveNone;
2508 if ((active_left && active_qtop) || (active_top && active_qleft))
2510 border = ActiveTopLeft;
2512 else if ((active_right && active_qtop) || (active_top && active_qright))
2514 border = ActiveTopRight;
2516 else if ((active_left && active_qbottom) || (active_bottom && active_qleft))
2518 border = ActiveBottomLeft;
2520 else if ((active_right && active_qbottom) || (active_bottom && active_qright))
2522 border = ActiveBottomRight;
2524 else if (active_left)
2526 border = ActiveLeft;
2528 else if (active_right)
2530 border = ActiveRight;
2532 else if (active_top)
2536 else if (active_bottom)
2538 border = ActiveBottom;
2546 if( active_windows[border] == None )
2551 if ((active_current_border == border) &&
2552 (timestampDiff(active_time_last, now) < treshold_reset) &&
2553 (timestampDiff(active_time_last_trigger, now) > treshold_trigger) &&
2554 ((pos-active_push_point).manhattanLength() < distance_reset))
2556 active_time_last = now;
2557 if (timestampDiff(active_time_first, now) > treshold_set)
2559 active_time_last_trigger = now;
2560 active_current_border = ActiveNone;
2561 bool isSide = (border == ActiveTop || border == ActiveRight ||
2562 border == ActiveBottom || border == ActiveLeft);
2567 if (options->activeBorders() == Options::ActiveSwitchAlways ||
2568 options->activeBorders() == Options::ActiveSwitchOnMove)
2570 activeBorderSwitchDesktop(border, pos);
2575 else if (options->activeBorders() == Options::ActiveTileMaximize &&
2576 border == ActiveTop && movingClient->isMaximizable())
2578 if (!movingClient->isResizable())
return;
2579 movingClient->setActiveBorderMode(ActiveMaximizeMode);
2580 movingClient->setActiveBorderPos(pos);
2581 movingClient->setActiveBorder(ActiveNone);
2582 movingClient->setActiveBorderMaximizing(
true);
2586 else if ((options->activeBorders() == Options::ActiveTileMaximize ||
2587 options->activeBorders() == Options::ActiveTileOnly))
2589 if (!movingClient->isResizable())
return;
2590 movingClient->setActiveBorderMode(ActiveTilingMode);
2591 movingClient->setActiveBorderPos(pos);
2592 movingClient->setActiveBorder(border);
2593 movingClient->setActiveBorderMaximizing(
true);
2604 if (options->activeBorders() == Options::ActiveSwitchAlways && isSide)
2606 activeBorderSwitchDesktop(border, pos);
2614 active_current_border = border;
2615 active_time_first = now;
2616 active_time_last = now;
2617 active_push_point = pos;
2620 if ((options->activeBorders() == Options::ActiveSwitchAlways && !movingClient) ||
2621 activation_distance < 2)
2625 const int xdiff[ ACTIVE_BORDER_COUNT ] = { 0, -1, -1, -1, 0, 1, 1, 1 };
2626 const int ydiff[ ACTIVE_BORDER_COUNT ] = { 1, 1, 0, -1, -1, -1, 0, 1 };
2627 TQCursor::setPos(pos.x() + xdiff[border], pos.y() + ydiff[border]);
2631void Workspace::activeBorderSwitchDesktop(ActiveBorder border,
const TQPoint& _pos)
2634 TQRect r = TQApplication::desktop()->geometry();
2635 const int offset = 5;
2637 int desk_before = currentDesktop();
2638 if (border == ActiveLeft || border == ActiveTopLeft || border == ActiveBottomLeft)
2640 slotSwitchDesktopLeft();
2641 pos.setX(r.width() - offset);
2643 if (border == ActiveRight || border == ActiveTopRight || border == ActiveBottomRight)
2645 slotSwitchDesktopRight();
2649 if (border == ActiveTop || border == ActiveTopLeft || border == ActiveTopRight)
2651 slotSwitchDesktopUp();
2652 pos.setY(r.height() - offset);
2654 if (border == ActiveBottom || border == ActiveBottomLeft || border == ActiveBottomRight)
2656 slotSwitchDesktopDown();
2660 if (currentDesktop() != desk_before)
2662 TQCursor::setPos(pos);
2668bool Workspace::activeBorderEvent(XEvent *e)
2670 if (e->type == EnterNotify)
2672 for (
int i = 0; i < ACTIVE_BORDER_COUNT; ++i)
2674 if (active_windows[i] != None && e->xcrossing.window == active_windows[i])
2676 checkActiveBorder(TQPoint(e->xcrossing.x_root, e->xcrossing.y_root), e->xcrossing.time);
2681 if (e->type == ClientMessage)
2683 if (e->xclient.message_type == atoms->xdnd_position)
2685 for (
int i = 0; i < ACTIVE_BORDER_COUNT; ++i)
2687 if (active_windows[i] != None && e->xclient.window == active_windows[i])
2690 checkActiveBorder(TQPoint(e->xclient.data.l[2]>>16, e->xclient.data.l[2]&0xffff), get_tqt_x_time());
2699void Workspace::addTopMenu( Client* c )
2701 assert( c->isTopMenu());
2702 assert( !topmenus.contains( c ));
2703 topmenus.append( c );
2704 if( managingTopMenus())
2706 int minsize = c->minSize().height();
2707 if( minsize > topMenuHeight())
2709 topmenu_height = minsize;
2710 updateTopMenuGeometry();
2712 updateTopMenuGeometry( c );
2713 updateCurrentTopMenu();
2718void Workspace::removeTopMenu( Client* c )
2722 assert( c->isTopMenu());
2723 assert( topmenus.contains( c ));
2724 topmenus.remove( c );
2725 updateCurrentTopMenu();
2729void Workspace::lostTopMenuSelection()
2733 disconnect( topmenu_watcher, TQ_SIGNAL( lostOwner()),
this, TQ_SLOT( lostTopMenuOwner()));
2734 connect( topmenu_watcher, TQ_SIGNAL( lostOwner()),
this, TQ_SLOT( lostTopMenuOwner()));
2735 if( !managing_topmenus )
2737 connect( topmenu_watcher, TQ_SIGNAL( lostOwner()),
this, TQ_SLOT( lostTopMenuOwner()));
2738 disconnect( topmenu_selection, TQ_SIGNAL( lostOwnership()),
this, TQ_SLOT( lostTopMenuSelection()));
2739 managing_topmenus =
false;
2740 delete topmenu_space;
2741 topmenu_space = NULL;
2743 for( ClientList::ConstIterator it = topmenus.begin();
2744 it != topmenus.end();
2746 (*it)->checkWorkspacePosition();
2749void Workspace::lostTopMenuOwner()
2751 if( !options->topMenuEnabled())
2754 if( !topmenu_selection->claim(
false ))
2760 setupTopMenuHandling();
2763void Workspace::setupTopMenuHandling()
2765 if( managing_topmenus )
2767 connect( topmenu_selection, TQ_SIGNAL( lostOwnership()),
this, TQ_SLOT( lostTopMenuSelection()));
2768 disconnect( topmenu_watcher, TQ_SIGNAL( lostOwner()),
this, TQ_SLOT( lostTopMenuOwner()));
2769 managing_topmenus =
true;
2770 topmenu_space =
new TQWidget;
2772 stack[ 0 ] = supportWindow->winId();
2773 stack[ 1 ] = topmenu_space->winId();
2774 XRestackWindows(tqt_xdisplay(), stack, 2);
2775 updateTopMenuGeometry();
2776 topmenu_space->show();
2778 updateCurrentTopMenu();
2781int Workspace::topMenuHeight()
const
2783 if( topmenu_height == 0 )
2786 tmpmenu.insertItem(
"dummy" );
2787 topmenu_height = tmpmenu.sizeHint().height();
2789 return topmenu_height;
2792KDecoration* Workspace::createDecoration( KDecorationBridge* bridge )
2794 return mgr->createDecoration( bridge );
2797TQString Workspace::desktopName(
int desk )
const
2799 return TQString::fromUtf8( rootInfo->desktopName( desk ) );
2802bool Workspace::checkStartupNotification( Window w, TDEStartupInfoId&
id, TDEStartupInfoData& data )
2804 return startup->checkStartup( w,
id, data ) == TDEStartupInfo::Match;
2811void Workspace::focusToNull()
2813 XSetInputFocus(tqt_xdisplay(), null_focus_window, RevertToPointerRoot, get_tqt_x_time() );
2816void Workspace::helperDialog(
const TQString& message,
const Client* c )
2820 if( message ==
"noborderaltf3" )
2822 TQString shortcut = TQString(
"%1 (%2)" ).arg( keys->label(
"Window Operations Menu" ))
2823 .arg( keys->shortcut(
"Window Operations Menu" ).seq( 0 ).toString());
2824 args <<
"--msgbox" <<
2825 i18n(
"You have selected to show a window without its border.\n"
2826 "Without the border, you will not be able to enable the border "
2827 "again using the mouse: use the window operations menu instead, "
2828 "activated using the %1 keyboard shortcut." )
2830 type =
"altf3warning";
2832 else if( message ==
"fullscreenaltf3" )
2834 TQString shortcut = TQString(
"%1 (%2)" ).arg( keys->label(
"Window Operations Menu" ))
2835 .arg( keys->shortcut(
"Window Operations Menu" ).seq( 0 ).toString());
2836 args <<
"--msgbox" <<
2837 i18n(
"You have selected to show a window in fullscreen mode.\n"
2838 "If the application itself does not have an option to turn the fullscreen "
2839 "mode off you will not be able to disable it "
2840 "again using the mouse: use the window operations menu instead, "
2841 "activated using the %1 keyboard shortcut." )
2843 type =
"altf3warning";
2848 proc <<
"kdialog" << args;
2849 if( !type.isEmpty())
2851 TDEConfig cfg(
"twin_dialogsrc" );
2852 cfg.setGroup(
"Notification Messages" );
2853 if( !cfg.readBoolEntry( type,
true ))
2855 proc <<
"--dontagain" <<
"twin_dialogsrc:" + type;
2858 proc <<
"--embed" << TQString::number( c->window());
2859 proc.start( TDEProcess::DontCare );
2865void Workspace::startKompmgr()
2870 unsigned long length, after;
2871 unsigned char* data_root;
2873 bool retry_later =
false;
2878 kompmgr =
new TDEProcess;
2879 connect(kompmgr, TQ_SIGNAL(receivedStderr(TDEProcess*,
char*,
int)), TQ_SLOT(handleKompmgrOutput(TDEProcess*,
char*,
int)));
2880 *kompmgr << TDE_COMPOSITOR_BINARY;
2881 *kompmgr <<
"--write-pid-path" << compositorPIDFile();
2883 if (!kompmgr_kill_timer)
2885 kompmgr_kill_timer =
new TQTimer(
this);
2886 connect(kompmgr_kill_timer, TQ_SIGNAL(timeout()),
this, TQ_SLOT(killKompmgr()));
2889 prop_root = XInternAtom(tqt_xdisplay(),
"_XROOTPMAP_ID", False);
2890 if( XGetWindowProperty( tqt_xdisplay(), tqt_xrootwin(), prop_root, 0L, 1L, False, AnyPropertyType, &type, &format, &length, &after, &data_root) != Success || data_root == NULL ) {
2894 else if (kompmgrIsRunning())
2896 if (kompmgr_kill_timer->isActive())
2900 kompmgr_kill_timer->stop();
2906 kompmgrReloadSettings();
2910 else if ( (kompmgrpid = getCompositorPID()) )
2913 kill(kompmgrpid, SIGKILL);
2919 TQTimer::singleShot( 200,
this, TQ_SLOT(startKompmgr()) );
2922 if (!kompmgr->start(TDEProcess::OwnGroup, TDEProcess::Stderr))
2924 options->useTranslucency =
false;
2926 proc <<
"kdialog" <<
"--error"
2927 << i18n(
"The Composite Manager could not be started.\\nMake sure you have \"" TDE_COMPOSITOR_BINARY
"\" in a $PATH directory.")
2928 <<
"--title" <<
"Composite Manager Failure";
2929 proc.start(TDEProcess::DontCare);
2933 delete kompmgr_selection;
2934 char selection_name[ 100 ];
2935 sprintf( selection_name,
"_NET_WM_CM_S%d", DefaultScreen( tqt_xdisplay()));
2936 kompmgr_selection =
new TDESelectionOwner( selection_name );
2937 connect( kompmgr_selection, TQ_SIGNAL( lostOwnership()), TQ_SLOT( stopKompmgr()));
2938 kompmgr_selection->claim(
true );
2939 connect(kompmgr, TQ_SIGNAL(processExited(TDEProcess*)), TQ_SLOT(restartKompmgr(TDEProcess*)));
2940 options->useTranslucency =
true;
2944 TQDataStream arg(ba, IO_WriteOnly);
2946 tdeApp->dcopClient()->emitDCOPSignal(
"default",
"kompmgrStarted()", ba);
2948 if (popup){
delete popup; popup = 0L; }
2951void Workspace::stopKompmgr()
2953 if (!kompmgrIsRunning()) {
2956 delete kompmgr_selection;
2957 kompmgr_selection = NULL;
2958 kompmgr->disconnect(
this, TQ_SLOT(restartKompmgr(TDEProcess*)));
2959 options->useTranslucency =
false;
2960 if (popup){
delete popup; popup = 0L; }
2961 connect(kompmgr, TQ_SIGNAL(processExited(TDEProcess *)), kompmgr_kill_timer, TQ_SLOT());
2962 kompmgr->kill(SIGTERM);
2963 kompmgr_kill_timer->start(5000,
true);
2965 TQDataStream arg(ba, IO_WriteOnly);
2967 tdeApp->dcopClient()->emitDCOPSignal(
"default",
"kompmgrStopped()", ba);
2970void Workspace::killKompmgr() {
2971 if (!kompmgrIsRunning()) {
2977 TQString pidfileFName = compositorPIDFile();
2979 if (readCompositorPID(pidfileFName) == kompmgr->pid()) {
2980 TQFile::remove(pidfileFName);
2983 kompmgr->kill(SIGKILL);
2986void Workspace::kompmgrReloadSettings()
2988 if (!kompmgrIsRunning()) {
2991 kompmgr->kill(SIGUSR1);
2994bool Workspace::kompmgrIsRunning()
2996 return kompmgr && kompmgr->isRunning();
2999void Workspace::unblockKompmgrRestart()
3001 allowKompmgrRestart =
true;
3004void Workspace::restartKompmgr( TDEProcess *proc )
3008 if (proc->signalled()) {
3009 int exit_signal_number = proc->exitSignal();
3010 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) ) {
3016 if (!allowKompmgrRestart)
3018 delete kompmgr_selection;
3019 kompmgr_selection = NULL;
3020 options->useTranslucency =
false;
3023 proc <<
"kdialog" <<
"--error"
3024 << i18n(
"The Composite Manager crashed twice within a minute and is therefore disabled for this session.")
3025 <<
"--title" << i18n(
"Composite Manager Failure");
3026 proc.start(TDEProcess::DontCare);
3040 if (!kompmgr->start(TDEProcess::NotifyOnExit, TDEProcess::Stderr))
3042 delete kompmgr_selection;
3043 kompmgr_selection = NULL;
3044 options->useTranslucency =
false;
3046 proc <<
"kdialog" <<
"--error"
3047 << i18n(
"The Composite Manager could not be started.\\nMake sure you have \"" TDE_COMPOSITOR_BINARY
"\" in a $PATH directory.")
3048 <<
"--title" << i18n(
"Composite Manager Failure");
3049 proc.start(TDEProcess::DontCare);
3053 allowKompmgrRestart =
false;
3054 TQTimer::singleShot( 60000,
this, TQ_SLOT(unblockKompmgrRestart()) );
3059void Workspace::handleKompmgrOutput( TDEProcess* ,
char *buffer,
int buflen)
3062 TQString output = TQString::fromLocal8Bit( buffer, buflen );
3063 if (output.contains(
"Started",
false))
3065 else if (output.contains(
"Can't open display",
false))
3066 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>");
3067 else if (output.contains(
"No render extension",
false))
3068 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>");
3069 else if (output.contains(
"No composite extension",
false))
3070 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>"
3071 "<i>Section \"Extensions\"<br>"
3072 "Option \"Composite\" \"Enable\"<br>"
3073 "EndSection</i></qt>");
3074 else if (output.contains(
"No damage extension",
false))
3075 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>");
3076 else if (output.contains(
"No XFixes extension",
false))
3077 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>");
3080 kompmgr->closeStderr();
3081 disconnect(kompmgr, TQ_SIGNAL(receivedStderr(TDEProcess*,
char*,
int)),
this, TQ_SLOT(handleKompmgrOutput(TDEProcess*,
char*,
int)));
3082 if( !message.isEmpty())
3085 proc <<
"kdialog" <<
"--error"
3087 <<
"--title" << i18n(
"Composite Manager Failure");
3088 proc.start(TDEProcess::DontCare);
3092uint Workspace::percentToUint(
int percent) {
3095 }
else if (percent<100) {
3097 return (0xffffffff/100) * (uint) percent + (0xffffffff % 100) * percent / 100;
3103void Workspace::setOpacity(
unsigned long winId,
unsigned int opacityPercent)
3105 if (opacityPercent > 100) opacityPercent = 100;
3106 for( ClientList::ConstIterator it = stackingOrder().begin(); it != stackingOrder().end(); it++ )
3107 if (winId == (*it)->window())
3109 (*it)->setOpacity(percentToUint(opacityPercent));
3114void Workspace::setShadowSize(
unsigned long winId,
unsigned int shadowSizePercent)
3117 if (shadowSizePercent > 400) shadowSizePercent = 400;
3118 for( ClientList::ConstIterator it = stackingOrder().begin(); it != stackingOrder().end(); it++ )
3119 if (winId == (*it)->window())
3121 (*it)->setShadowSize(shadowSizePercent);
3126void Workspace::setUnshadowed(
unsigned long winId)
3128 for( ClientList::ConstIterator it = stackingOrder().begin(); it != stackingOrder().end(); it++ )
3129 if (winId == (*it)->window())
3131 (*it)->setShadowSize(0);
3136void Workspace::setShowingDesktop(
bool showing )
3138 rootInfo->setShowingDesktop( showing );
3139 showing_desktop = showing;
3140 ++block_showing_desktop;
3141 if( showing_desktop )
3143 showing_desktop_clients.clear();
3145 ClientList cls = stackingOrder();
3148 for( ClientList::ConstIterator it = cls.begin();
3152 if( (*it)->isOnCurrentDesktop() && (*it)->isShown(
true ) && !(*it)->isSpecialWindow())
3153 showing_desktop_clients.prepend( *it );
3155 for( ClientList::ConstIterator it = showing_desktop_clients.begin();
3156 it != showing_desktop_clients.end();
3158 (*it)->minimize(
true);
3160 if( Client* desk = findDesktop(
true, currentDesktop()))
3161 requestFocus( desk );
3165 for( ClientList::ConstIterator it = showing_desktop_clients.begin();
3166 it != showing_desktop_clients.end();
3168 (*it)->unminimize(
true);
3169 if( showing_desktop_clients.count() > 0 )
3170 requestFocus( showing_desktop_clients.first());
3171 showing_desktop_clients.clear();
3173 --block_showing_desktop;
3185void Workspace::resetShowingDesktop(
bool keep_hidden )
3187 if( block_showing_desktop > 0 )
3189 rootInfo->setShowingDesktop(
false );
3190 showing_desktop =
false;
3191 ++block_showing_desktop;
3194 for( ClientList::ConstIterator it = showing_desktop_clients.begin();
3195 it != showing_desktop_clients.end();
3197 (*it)->unminimize(
true);
3199 showing_desktop_clients.clear();
3200 --block_showing_desktop;
3210void Workspace::slotDisableGlobalShortcuts()
3212 if( global_shortcuts_disabled || global_shortcuts_disabled_for_client )
3213 disableGlobalShortcuts(
false );
3215 disableGlobalShortcuts(
true );
3218static bool pending_dfc =
false;
3220void Workspace::disableGlobalShortcutsForClient(
bool disable )
3222 if( global_shortcuts_disabled_for_client == disable )
3224 if( !global_shortcuts_disabled )
3228 KIPC::sendMessageAll( KIPC::BlockShortcuts, disable );
3233void Workspace::disableGlobalShortcuts(
bool disable )
3235 KIPC::sendMessageAll( KIPC::BlockShortcuts, disable );
3239void Workspace::kipcMessage(
int id,
int data )
3241 if(
id != KIPC::BlockShortcuts )
3243 if( pending_dfc && data )
3245 global_shortcuts_disabled_for_client =
true;
3246 pending_dfc =
false;
3250 global_shortcuts_disabled = data;
3251 global_shortcuts_disabled_for_client =
false;
3254 for( ClientList::ConstIterator it = clients.begin();
3255 it != clients.end();
3257 (*it)->updateMouseGrab();
3262#include "workspace.moc"