14 #include "workspace.h"
16 #include <tdeapplication.h>
17 #include <tdestartupinfo.h>
19 #include <tdeconfig.h>
20 #include <tdeglobal.h>
21 #include <tqpopupmenu.h>
22 #include <tdelocale.h>
24 #include <tqpainter.h>
26 #include <tqclipboard.h>
27 #include <tdemenubar.h>
29 #include <kglobalaccel.h>
30 #include <dcopclient.h>
35 #include "popupinfo.h"
38 #include "placement.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>
53 namespace KWinInternal
56 extern int screen_number;
58 Workspace *Workspace::_self = 0;
60 TDEProcess* kompmgr = 0;
61 TDESelectionOwner* kompmgr_selection;
63 bool allowKompmgrRestart = TRUE;
64 extern bool disable_twin_composition_manager;
66 bool supportsCompMgr()
68 if (disable_twin_composition_manager) {
74 bool damageExt = XQueryExtension(tqt_xdisplay(),
"DAMAGE", &i, &i, &i);
75 bool compositeExt = XQueryExtension(tqt_xdisplay(),
"Composite", &i, &i, &i);
76 bool xfixesExt = XQueryExtension(tqt_xdisplay(),
"XFIXES", &i, &i, &i);
78 return damageExt && compositeExt && xfixesExt;
81 pid_t getCompositorPID() {
84 const char *pidfile =
"compton-tde.pid";
85 char uidstr[
sizeof(uid_t)*8+1];
86 sprintf(uidstr,
"%d", getuid());
87 int n = strlen(P_tmpdir)+strlen(uidstr)+strlen(pidfile)+3;
88 filename = (
char*)malloc(n*
sizeof(
char)+1);
90 strcat(filename, P_tmpdir);
91 strcat(filename,
"/.");
92 strcat(filename, uidstr);
93 strcat(filename,
"-");
94 strcat(filename, pidfile);
99 pFile = fopen(filename,
"r");
100 pid_t kompmgrpid = 0;
103 printf(
"[twin-workspace] Using '%s' as compton-tde pidfile\n\n", filename);
105 fseek (pFile , 0 , SEEK_END);
106 unsigned long lSize = ftell (pFile);
110 size_t result = fread (buffer, 1, lSize, pFile);
114 kompmgrpid = atoi(buffer);
131 Workspace::Workspace(
bool restore )
132 : DCOPObject (
"KWinInterface"),
133 TQObject (0,
"workspace"),
135 number_of_desktops(0),
137 active_popup( NULL ),
138 active_popup_client( NULL ),
140 temporaryRulesMessages(
"_KDE_NET_WM_TEMPORARY_RULES", NULL, false ),
141 rules_updates_disabled( false ),
143 last_active_client (0),
144 next_active_client (0),
145 most_recently_raised (0),
147 pending_take_activity ( NULL ),
148 delayfocus_client (0),
149 showing_desktop( false ),
150 block_showing_desktop( 0 ),
151 was_user_interaction (false),
152 session_saving (false),
153 control_grab (false),
155 mouse_emulation (false),
162 desk_popup_index (0),
164 client_keys ( NULL ),
165 client_keys_dialog ( NULL ),
166 client_keys_client ( NULL ),
167 disable_shortcuts_keys ( NULL ),
168 global_shortcuts_disabled( false ),
169 global_shortcuts_disabled_for_client( false ),
171 workspaceInit (true),
172 startup(0), electric_have_borders(false),
173 electric_current_border(0),
174 electric_top_border(None),
175 electric_bottom_border(None),
176 electric_left_border(None),
177 electric_right_border(None),
178 layoutOrientation(Qt::Vertical),
183 managing_topmenus( false ),
184 topmenu_selection( NULL ),
185 topmenu_watcher( NULL ),
187 topmenu_space( NULL ),
188 set_active_client_recursion( 0 ),
189 block_stacking_updates( 0 ),
190 forced_global_mouse_grab( false )
194 root = tqt_xrootwin();
195 default_colormap = DefaultColormap(tqt_xdisplay(), tqt_xscreen() );
196 installed_colormap = default_colormap;
197 session.setAutoDelete( TRUE );
199 connect( &temporaryRulesMessages, TQT_SIGNAL( gotMessage(
const TQString& )),
200 this, TQT_SLOT( gotTemporaryRulesMessage(
const TQString& )));
201 connect( &rulesUpdatedTimer, TQT_SIGNAL( timeout()),
this, TQT_SLOT( writeWindowRules()));
207 electric_time_first = GET_QT_X_TIME();
208 electric_time_last = GET_QT_X_TIME();
215 (void) TQApplication::desktop();
221 (WFlags)(TQt::WType_Desktop | TQt::WPaintUnclipped)
224 kapp->setGlobalMouseTracking(
true );
226 startup =
new TDEStartupInfo(
227 TDEStartupInfo::DisableKWinModule | TDEStartupInfo::AnnounceSilenceChanges,
this );
230 XSelectInput(tqt_xdisplay(), root,
234 SubstructureRedirectMask |
235 SubstructureNotifyMask |
251 (
unsigned char*) &data,
255 client_keys =
new TDEGlobalAccel(
this );
257 tab_box =
new TabBox(
this );
258 popupinfo =
new PopupInfo(
this );
262 #if (TQT_VERSION-0 >= 0x030200) // XRANDR support
263 connect( kapp->desktop(), TQT_SIGNAL( resized(
int )), TQT_SLOT( desktopResized()));
266 if (!supportsCompMgr()) {
267 options->useTranslucency =
false;
273 pid_t kompmgrpid = getCompositorPID();
275 if (options->useTranslucency)
277 kompmgr =
new TDEProcess;
278 connect(kompmgr, TQT_SIGNAL(receivedStderr(TDEProcess*,
char*,
int)), TQT_SLOT(handleKompmgrOutput(TDEProcess*,
char*,
int)));
279 *kompmgr << TDE_COMPOSITOR_BINARY;
282 if (kill(kompmgrpid, 0) < 0)
293 else if (!disable_twin_composition_manager)
298 kill(kompmgrpid, SIGTERM);
308 void Workspace::init()
310 checkElectricBorders();
316 supportWindow =
new TQWidget;
317 XLowerWindow( tqt_xdisplay(), supportWindow->winId());
319 XSetWindowAttributes attr;
320 attr.override_redirect = 1;
321 null_focus_window = XCreateWindow( tqt_xdisplay(), tqt_xrootwin(), -1,-1, 1, 1, 0, CopyFromParent,
322 InputOnly, CopyFromParent, CWOverrideRedirect, &attr );
323 XMapWindow(tqt_xdisplay(), null_focus_window);
325 unsigned long protocols[ 5 ] =
328 NET::SupportingWMCheck |
330 NET::ClientListStacking |
331 NET::DesktopGeometry |
332 NET::NumberOfDesktops |
333 NET::CurrentDesktop |
338 NET::KDESystemTrayWindows |
345 NET::WMIconGeometry |
349 NET::WMKDESystemTrayWinFor |
350 NET::WMFrameExtents |
377 NET::DemandsAttention |
382 NET::WM2AllowedActions |
383 NET::WM2RestackWindow |
384 NET::WM2MoveResizeWindow |
385 NET::WM2ExtendedStrut |
386 NET::WM2KDETemporaryRules |
387 NET::WM2ShowingDesktop |
388 NET::WM2FullPlacement |
389 NET::WM2DesktopLayout |
394 NET::ActionMinimize |
398 NET::ActionMaxHoriz |
399 NET::ActionFullScreen |
400 NET::ActionChangeDesktop |
406 rootInfo =
new RootInfo(
this, tqt_xdisplay(), supportWindow->winId(),
"KWin",
407 protocols, 5, tqt_xscreen() );
409 loadDesktopSettings();
410 updateDesktopLayout();
412 NETRootInfo client_info( tqt_xdisplay(), NET::ActiveWindow | NET::CurrentDesktop );
414 if( !kapp->isSessionRestored())
415 initial_desktop = client_info.currentDesktop();
418 TDEConfigGroupSaver saver( kapp->sessionConfig(),
"Session" );
419 initial_desktop = kapp->sessionConfig()->readNumEntry(
"desktop", 1 );
421 if( !setCurrentDesktop( initial_desktop ))
422 setCurrentDesktop( 1 );
425 initPositioning =
new Placement(
this);
427 connect(&reconfigureTimer, TQT_SIGNAL(timeout()),
this,
428 TQT_SLOT(slotReconfigure()));
429 connect( &updateToolWindowsTimer, TQT_SIGNAL( timeout()),
this, TQT_SLOT( slotUpdateToolWindows()));
431 connect(kapp, TQT_SIGNAL(appearanceChanged()),
this,
432 TQT_SLOT(slotReconfigure()));
433 connect(kapp, TQT_SIGNAL(settingsChanged(
int)),
this,
434 TQT_SLOT(slotSettingsChanged(
int)));
435 connect(kapp, TQT_SIGNAL( kipcMessage(
int,
int )),
this, TQT_SLOT( kipcMessage(
int,
int )));
437 active_client = NULL;
438 rootInfo->setActiveWindow( None );
440 if( !kapp->isSessionRestored())
444 sprintf( nm,
"_KDE_TOPMENU_OWNER_S%d", DefaultScreen( tqt_xdisplay()));
445 Atom topmenu_atom = XInternAtom( tqt_xdisplay(), nm, False );
446 topmenu_selection =
new TDESelectionOwner( topmenu_atom );
447 topmenu_watcher =
new TDESelectionWatcher( topmenu_atom );
451 StackingUpdatesBlocker blocker(
this );
453 if( options->topMenuEnabled() && topmenu_selection->claim(
false ))
454 setupTopMenuHandling();
456 lostTopMenuSelection();
458 unsigned int i, nwins;
459 Window root_return, parent_return, *wins;
460 XQueryTree(tqt_xdisplay(), root, &root_return, &parent_return, &wins, &nwins);
461 for (i = 0; i < nwins; i++)
463 XWindowAttributes attr;
464 XGetWindowAttributes(tqt_xdisplay(), wins[i], &attr);
465 if (attr.override_redirect )
467 if( topmenu_space && topmenu_space->winId() == wins[ i ] )
469 if (attr.map_state != IsUnmapped)
471 if ( addSystemTrayWin( wins[i] ) )
473 Client* c = createClient( wins[i],
true );
474 if ( c != NULL && root != tqt_xrootwin() )
477 XReparentWindow( tqt_xdisplay(), c->frameId(), root, 0, 0 );
483 XFree((
void *) wins);
485 updateStackingOrder(
true );
488 raiseElectricBorders();
491 NETPoint* viewports =
new NETPoint[ number_of_desktops ];
492 rootInfo->setDesktopViewport( number_of_desktops, *viewports );
494 TQRect geom = TQApplication::desktop()->geometry();
495 NETSize desktop_geometry;
496 desktop_geometry.width = geom.width();
497 desktop_geometry.height = geom.height();
498 rootInfo->setDesktopGeometry( -1, desktop_geometry );
499 setShowingDesktop(
false );
503 Client* new_active_client = NULL;
504 if( !kapp->isSessionRestored())
507 new_active_client = findClient( WindowMatchPredicate( client_info.activeWindow()));
509 if( new_active_client == NULL
510 && activeClient() == NULL && should_get_focus.count() == 0 )
512 if( new_active_client == NULL )
513 new_active_client = topClientOnDesktop( currentDesktop());
514 if( new_active_client == NULL && !desktops.isEmpty() )
515 new_active_client = findDesktop(
true, currentDesktop());
517 if( new_active_client != NULL )
518 activateClient( new_active_client );
522 workspaceInit =
false;
526 Workspace::~Workspace()
530 blockStackingUpdates(
true );
533 for( ClientList::ConstIterator it = stacking_order.begin();
534 it != stacking_order.end();
538 (*it)->releaseWindow(
true );
542 clients.remove( *it );
543 desktops.remove( *it );
545 delete desktop_widget;
549 if ( root == tqt_xrootwin() )
550 XDeleteProperty(tqt_xdisplay(), tqt_xrootwin(), atoms->twin_running);
553 TDEGlobal::config()->sync();
556 delete supportWindow;
561 delete initPositioning;
562 delete topmenu_watcher;
563 delete topmenu_selection;
564 delete topmenu_space;
565 delete client_keys_dialog;
566 while( !rules.isEmpty())
568 delete rules.front();
571 XDestroyWindow( tqt_xdisplay(), null_focus_window );
576 Client* Workspace::createClient( Window w,
bool is_mapped )
578 StackingUpdatesBlocker blocker(
this );
579 Client* c =
new Client(
this );
580 if( !c->manage( w, is_mapped ))
582 Client::deleteClient( c, Allowed );
585 addClient( c, Allowed );
589 void Workspace::addClient( Client* c, allowed_t )
593 c->setBMP(c->resourceName() ==
"beep-media-player" || c->decorationId() == None);
595 c->getWindowOpacity();
599 if (!c->hasCustomOpacity())
601 c->setShadowSize(options->dockShadowSize);
602 c->setOpacity(options->translucentDocks, options->dockOpacity);
606 if (c->isMenu() || c->isTopMenu())
608 c->setShadowSize(options->menuShadowSize);
611 Group* grp = findGroup( c->window());
615 if ( c->isDesktop() )
617 desktops.append( c );
618 if( active_client == NULL && should_get_focus.isEmpty() && c->isOnCurrentDesktop())
623 updateFocusChains( c, FocusChainUpdate );
626 if( !unconstrained_stacking_order.contains( c ))
627 unconstrained_stacking_order.append( c );
628 if( !stacking_order.contains( c ))
629 stacking_order.append( c );
633 updateClientLayer( c );
638 if( activeClient() == NULL && should_get_focus.count() == 0 )
639 activateClient( findDesktop(
true, currentDesktop()));
641 c->checkActiveModal();
642 checkTransients( c->window());
643 updateStackingOrder(
true );
644 if( c->isUtility() || c->isMenu() || c->isToolbar())
645 updateToolWindows(
true );
646 checkNonExistentClients();
652 void Workspace::removeClient( Client* c, allowed_t )
654 if (c == active_popup_client)
657 if( client_keys_client == c )
658 setupWindowShortcutDone(
false );
659 if( !c->shortcut().isNull())
660 c->setShortcut( TQString::null );
663 Notify::raise( Notify::TransDelete );
664 if( c->isNormalWindow())
665 Notify::raise( Notify::Delete );
667 Q_ASSERT( clients.contains( c ) || desktops.contains( c ));
669 desktops.remove( c );
670 unconstrained_stacking_order.remove( c );
671 stacking_order.remove( c );
673 i <= numberOfDesktops();
675 focus_chain[ i ].
remove( c );
676 global_focus_chain.remove( c );
677 attention_chain.remove( c );
678 showing_desktop_clients.remove( c );
681 Group* group = findGroup( c->window());
685 if ( c == most_recently_raised )
686 most_recently_raised = 0;
687 should_get_focus.remove( c );
688 Q_ASSERT( c != active_client );
689 if ( c == last_active_client )
690 last_active_client = 0;
691 if( c == pending_take_activity )
692 pending_take_activity = NULL;
693 if( c == delayfocus_client )
696 updateStackingOrder(
true );
704 void Workspace::updateFocusChains( Client* c, FocusChainChange change )
706 if( !c->wantsTabFocus())
709 i<= numberOfDesktops();
711 focus_chain[i].
remove(c);
712 global_focus_chain.remove( c );
715 if(c->desktop() == NET::OnAllDesktops)
717 for(
int i=1; i<= numberOfDesktops(); i++)
719 if( i == currentDesktop()
720 && ( change == FocusChainMakeFirst || change == FocusChainMakeLast ))
722 focus_chain[ i ].remove( c );
723 if( change == FocusChainMakeFirst )
724 focus_chain[ i ].append( c );
726 focus_chain[ i ].prepend( c );
728 else if( !focus_chain[ i ].contains( c ))
730 if( active_client != NULL && active_client != c
731 && !focus_chain[ i ].isEmpty() && focus_chain[ i ].last() == active_client )
732 focus_chain[ i ].insert( focus_chain[ i ].fromLast(), c );
734 focus_chain[ i ].append( c );
740 for(
int i=1; i<= numberOfDesktops(); i++)
742 if( i == c->desktop())
744 if( change == FocusChainMakeFirst )
746 focus_chain[ i ].remove( c );
747 focus_chain[ i ].append( c );
749 else if( change == FocusChainMakeLast )
751 focus_chain[ i ].remove( c );
752 focus_chain[ i ].prepend( c );
754 else if( !focus_chain[ i ].contains( c ))
756 if( active_client != NULL && active_client != c
757 && !focus_chain[ i ].isEmpty() && focus_chain[ i ].last() == active_client )
758 focus_chain[ i ].insert( focus_chain[ i ].fromLast(), c );
760 focus_chain[ i ].append( c );
764 focus_chain[ i ].remove( c );
767 if( change == FocusChainMakeFirst )
769 global_focus_chain.remove( c );
770 global_focus_chain.append( c );
772 else if( change == FocusChainMakeLast )
774 global_focus_chain.remove( c );
775 global_focus_chain.prepend( c );
777 else if( !global_focus_chain.contains( c ))
779 if( active_client != NULL && active_client != c
780 && !global_focus_chain.isEmpty() && global_focus_chain.last() == active_client )
781 global_focus_chain.insert( global_focus_chain.fromLast(), c );
783 global_focus_chain.append( c );
787 void Workspace::updateOverlappingShadows(
unsigned long window)
791 if ((client = findClient(WindowMatchPredicate((WId)window))))
794 client->drawOverlappingShadows(
false);
797 void Workspace::setShadowed(
unsigned long window,
bool shadowed)
801 if ((client = findClient(WindowMatchPredicate((WId)window))))
802 client->setShadowed(shadowed);
805 void Workspace::updateCurrentTopMenu()
807 if( !managingTopMenus())
811 bool block_desktop_menubar =
false;
815 Client* menu_client = active_client;
818 if( menu_client->isFullScreen())
819 block_desktop_menubar =
true;
820 for( ClientList::ConstIterator it = menu_client->transients().begin();
821 it != menu_client->transients().end();
823 if( (*it)->isTopMenu())
828 if( menubar != NULL || !menu_client->isTransient())
830 if( menu_client->isModal() || menu_client->transientFor() == NULL )
832 menu_client = menu_client->transientFor();
836 for( ClientList::ConstIterator it = active_client->group()->members().begin();
837 it != active_client->group()->members().end();
839 if( (*it)->isTopMenu())
846 if( !menubar && !block_desktop_menubar && options->desktopTopMenu())
849 Client* desktop = findDesktop(
true, currentDesktop());
850 if( desktop != NULL )
852 for( ClientList::ConstIterator it = desktop->transients().begin();
853 it != desktop->transients().end();
855 if( (*it)->isTopMenu())
864 if( menubar == NULL )
866 for( ClientList::ConstIterator it = topmenus.begin();
867 it != topmenus.end();
869 if( (*it)->wasOriginallyGroupTransient())
880 if( active_client && !menubar->isOnDesktop( active_client->desktop()))
881 menubar->setDesktop( active_client->desktop());
882 menubar->hideClient(
false );
883 topmenu_space->hide();
887 unconstrained_stacking_order.remove( menubar );
888 unconstrained_stacking_order.append( menubar );
890 else if( !block_desktop_menubar )
892 topmenu_space->show();
896 for ( ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it)
898 if( (*it)->isTopMenu() && (*it) != menubar )
899 (*it)->hideClient(
true );
904 void Workspace::updateToolWindows(
bool also_hide )
907 if( !options->hideUtilityWindowsForInactive )
909 for( ClientList::ConstIterator it = clients.begin();
912 (*it)->hideClient(
false );
915 const Group* group = NULL;
916 const Client* client = active_client;
919 while( client != NULL )
921 if( !client->isTransient())
923 if( client->groupTransient())
925 group = client->group();
928 client = client->transientFor();
934 ClientList to_show, to_hide;
935 for( ClientList::ConstIterator it = stacking_order.begin();
936 it != stacking_order.end();
939 if( (*it)->isUtility() || (*it)->isMenu() || (*it)->isToolbar())
942 if( !(*it)->isTransient())
944 if( (*it)->group()->members().count() == 1 )
946 else if( client != NULL && (*it)->group() == client->group())
953 if( group != NULL && (*it)->group() == group )
955 else if( client != NULL && client->hasTransient( (*it),
true ))
960 if( !show && also_hide )
962 const ClientList mainclients = (*it)->mainClients();
965 if( mainclients.isEmpty())
967 for( ClientList::ConstIterator it2 = mainclients.begin();
968 it2 != mainclients.end();
971 if( (*it2)->isSpecialWindow())
975 to_hide.append( *it );
978 to_show.append( *it );
981 for( ClientList::ConstIterator it = to_show.fromLast();
985 (*it)->hideClient(
false );
988 for( ClientList::ConstIterator it = to_hide.begin();
991 (*it)->hideClient(
true );
992 updateToolWindowsTimer.stop();
996 updateToolWindowsTimer.start( 50,
true );
1000 void Workspace::slotUpdateToolWindows()
1002 updateToolWindows(
true );
1008 void Workspace::updateColormap()
1010 Colormap cmap = default_colormap;
1011 if ( activeClient() && activeClient()->colormap() != None )
1012 cmap = activeClient()->colormap();
1013 if ( cmap != installed_colormap )
1015 XInstallColormap(tqt_xdisplay(), cmap );
1016 installed_colormap = cmap;
1020 void Workspace::reconfigure()
1022 reconfigureTimer.start(200,
true);
1026 void Workspace::slotSettingsChanged(
int category)
1028 kdDebug(1212) <<
"Workspace::slotSettingsChanged()" << endl;
1029 if( category == (
int) TDEApplication::SETTINGS_SHORTCUTS )
1036 KWIN_PROCEDURE( CheckBorderSizesProcedure, cl->checkBorderSizes() );
1038 void Workspace::slotReconfigure()
1040 kdDebug(1212) <<
"Workspace::slotReconfigure()" << endl;
1041 reconfigureTimer.stop();
1043 TDEGlobal::config()->reparseConfiguration();
1044 unsigned long changed = options->updateSettings();
1045 tab_box->reconfigure();
1046 popupinfo->reconfigure();
1047 initPositioning->reinitCascading( 0 );
1049 forEachClient( CheckIgnoreFocusStealingProcedure());
1050 updateToolWindows(
true );
1052 if( mgr->reset( changed ))
1054 #if 0 // This actually seems to make things worse now
1056 curtain.setBackgroundMode( NoBackground );
1057 curtain.setGeometry( TQApplication::desktop()->geometry() );
1060 for( ClientList::ConstIterator it = clients.begin();
1061 it != clients.end();
1064 (*it)->updateDecoration(
true,
true );
1066 mgr->destroyPreviousPlugin();
1070 forEachClient( CheckBorderSizesProcedure());
1073 checkElectricBorders();
1075 if( options->topMenuEnabled() && !managingTopMenus())
1077 if( topmenu_selection->claim(
false ))
1078 setupTopMenuHandling();
1080 lostTopMenuSelection();
1082 else if( !options->topMenuEnabled() && managingTopMenus())
1084 topmenu_selection->release();
1085 lostTopMenuSelection();
1088 if( managingTopMenus())
1090 updateTopMenuGeometry();
1091 updateCurrentTopMenu();
1095 for( ClientList::Iterator it = clients.begin();
1096 it != clients.end();
1099 (*it)->setupWindowRules(
true );
1100 (*it)->applyWindowRules();
1101 discardUsedWindowRules( *it,
false );
1104 if (options->resetKompmgr)
1106 bool tmp = options->useTranslucency;
1111 const char *pidfile =
"compton-tde.pid";
1112 char uidstr[
sizeof(uid_t)*8+1];
1113 sprintf(uidstr,
"%d", getuid());
1114 int n = strlen(P_tmpdir)+strlen(uidstr)+strlen(pidfile)+3;
1115 filename = (
char*)malloc(n*
sizeof(
char)+1);
1116 memset(filename,0,n);
1117 strcat(filename, P_tmpdir);
1118 strcat(filename,
"/.");
1119 strcat(filename, uidstr);
1120 strcat(filename,
"-");
1121 strcat(filename, pidfile);
1126 pFile = fopen(filename,
"r");
1130 printf(
"[twin-workspace] Using '%s' as compton-tde pidfile\n\n", filename);
1132 fseek (pFile , 0 , SEEK_END);
1133 unsigned long lSize = ftell (pFile);
1137 size_t result = fread (buffer, 1, lSize, pFile);
1141 kompmgrpid = atoi(buffer);
1152 kill(kompmgrpid, SIGUSR2);
1159 kompmgr =
new TDEProcess;
1160 connect(kompmgr, TQT_SIGNAL(receivedStderr(TDEProcess*,
char*,
int)), TQT_SLOT(handleKompmgrOutput(TDEProcess*,
char*,
int)));
1161 *kompmgr << TDE_COMPOSITOR_BINARY;
1163 TQTimer::singleShot( 200,
this, TQT_SLOT(startKompmgr()) );
1170 kill(kompmgrpid, SIGTERM);
1180 void Workspace::loadDesktopSettings()
1182 TDEConfig* c = TDEGlobal::config();
1183 TQCString groupname;
1184 if (screen_number == 0)
1185 groupname =
"Desktops";
1187 groupname.sprintf(
"Desktops-screen-%d", screen_number);
1188 TDEConfigGroupSaver saver(c,groupname);
1190 int n = c->readNumEntry(
"Number", 4);
1191 number_of_desktops = n;
1193 workarea =
new TQRect[ n + 1 ];
1196 rootInfo->setNumberOfDesktops( number_of_desktops );
1197 desktop_focus_chain.resize( n );
1199 focus_chain.resize( n + 1 );
1200 for(
int i = 1; i <= n; i++)
1202 TQString s = c->readEntry(TQString(
"Name_%1").arg(i),
1203 i18n(
"Desktop %1").arg(i));
1204 rootInfo->setDesktopName( i, s.utf8().data() );
1205 desktop_focus_chain[i-1] = i;
1209 void Workspace::saveDesktopSettings()
1211 TDEConfig* c = TDEGlobal::config();
1212 TQCString groupname;
1213 if (screen_number == 0)
1214 groupname =
"Desktops";
1216 groupname.sprintf(
"Desktops-screen-%d", screen_number);
1217 TDEConfigGroupSaver saver(c,groupname);
1219 c->writeEntry(
"Number", number_of_desktops );
1220 for(
int i = 1; i <= number_of_desktops; i++)
1222 TQString s = desktopName( i );
1223 TQString defaultvalue = i18n(
"Desktop %1").arg(i);
1227 rootInfo->setDesktopName( i, s.utf8().data() );
1230 if (s != defaultvalue)
1232 c->writeEntry( TQString(
"Name_%1").arg(i), s );
1236 TQString currentvalue = c->readEntry(TQString(
"Name_%1").arg(i));
1237 if (currentvalue != defaultvalue)
1238 c->writeEntry( TQString(
"Name_%1").arg(i),
"" );
1243 TQStringList Workspace::configModules(
bool controlCenter)
1246 args <<
"tde-twindecoration.desktop";
1248 args <<
"tde-twinoptions.desktop";
1249 else if (kapp->authorizeControlModule(
"tde-twinoptions.desktop"))
1250 args <<
"twinactions" <<
"twinfocus" <<
"twinmoving" <<
"twinadvanced" <<
"twinrules" <<
"twintranslucency";
1254 void Workspace::configureWM()
1256 TDEApplication::tdeinitExec(
"tdecmshell", configModules(
false) );
1262 void Workspace::doNotManage( TQString title )
1264 doNotManageList.append( title );
1270 bool Workspace::isNotManaged(
const TQString& title )
1272 for ( TQStringList::Iterator it = doNotManageList.begin(); it != doNotManageList.end(); ++it )
1274 TQRegExp r( (*it) );
1275 if (r.search(title) != -1)
1277 doNotManageList.remove( it );
1287 void Workspace::refresh()
1290 w.setGeometry( TQApplication::desktop()->geometry() );
1293 TQApplication::flushX();
1303 class ObscuringWindows
1306 ~ObscuringWindows();
1307 void create( Client* c );
1309 TQValueList<Window> obscuring_windows;
1310 static TQValueList<Window>* cached;
1311 static unsigned int max_cache_size;
1314 TQValueList<Window>* ObscuringWindows::cached = 0;
1315 unsigned int ObscuringWindows::max_cache_size = 0;
1317 void ObscuringWindows::create( Client* c )
1320 cached =
new TQValueList<Window>;
1322 XWindowChanges chngs;
1323 int mask = CWSibling | CWStackMode;
1324 if( cached->count() > 0 )
1326 cached->remove( obs_win = cached->first());
1329 chngs.width = c->width();
1330 chngs.height = c->height();
1331 mask |= CWX | CWY | CWWidth | CWHeight;
1335 XSetWindowAttributes a;
1336 a.background_pixmap = None;
1337 a.override_redirect = True;
1338 obs_win = XCreateWindow( tqt_xdisplay(), tqt_xrootwin(), c->x(), c->y(),
1339 c->width(), c->height(), 0, CopyFromParent, InputOutput,
1340 CopyFromParent, CWBackPixmap | CWOverrideRedirect, &a );
1342 chngs.sibling = c->frameId();
1343 chngs.stack_mode = Below;
1344 XConfigureWindow( tqt_xdisplay(), obs_win, mask, &chngs );
1345 XMapWindow( tqt_xdisplay(), obs_win );
1346 obscuring_windows.append( obs_win );
1349 ObscuringWindows::~ObscuringWindows()
1351 max_cache_size = TQMAX( max_cache_size, obscuring_windows.count() + 4 ) - 1;
1352 for( TQValueList<Window>::ConstIterator it = obscuring_windows.begin();
1353 it != obscuring_windows.end();
1356 XUnmapWindow( tqt_xdisplay(), *it );
1357 if( cached->count() < max_cache_size )
1358 cached->prepend( *it );
1360 XDestroyWindow( tqt_xdisplay(), *it );
1371 bool Workspace::setCurrentDesktop(
int new_desktop )
1373 if (new_desktop < 1 || new_desktop > number_of_desktops )
1379 StackingUpdatesBlocker blocker(
this );
1381 int old_desktop = current_desktop;
1382 if (new_desktop != current_desktop)
1384 ++block_showing_desktop;
1389 Notify::raise((Notify::Event) (Notify::DesktopChange+new_desktop));
1391 ObscuringWindows obs_wins;
1393 current_desktop = new_desktop;
1395 bool desktopHasCompositing = kapp->isCompositionManagerAvailable();
1396 if (!desktopHasCompositing) {
1398 for ( ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it) {
1399 if ( !(*it)->isOnDesktop( new_desktop ) && (*it) != movingClient )
1401 if( (*it)->isShown(
true ) && (*it)->isOnDesktop( old_desktop )) {
1402 obs_wins.create( *it );
1404 (*it)->updateVisibility();
1409 rootInfo->setCurrentDesktop( current_desktop );
1411 if( movingClient && !movingClient->isOnDesktop( new_desktop ))
1412 movingClient->setDesktop( new_desktop );
1414 for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it) {
1415 if ( (*it)->isOnDesktop( new_desktop ) ) {
1416 (*it)->updateVisibility();
1420 if (desktopHasCompositing) {
1423 XSync( tqt_xdisplay(),
false);
1424 for ( ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it) {
1425 if ( !(*it)->isOnDesktop( new_desktop ) && (*it) != movingClient )
1427 if( (*it)->isShown(
true ) && (*it)->isOnDesktop( old_desktop )) {
1428 obs_wins.create( *it );
1430 (*it)->updateVisibility();
1435 --block_showing_desktop;
1436 if( showingDesktop())
1437 resetShowingDesktop(
false );
1444 if ( options->focusPolicyIsReasonable())
1447 if ( movingClient != NULL && active_client == movingClient
1448 && focus_chain[currentDesktop()].contains( active_client )
1449 && active_client->isShown(
true ) && active_client->isOnCurrentDesktop())
1455 for( ClientList::ConstIterator it = focus_chain[currentDesktop()].fromLast();
1456 it != focus_chain[currentDesktop()].end();
1459 if ( (*it)->isShown(
false ) && (*it)->isOnCurrentDesktop())
1471 else if( active_client && active_client->isShown(
true ) && active_client->isOnCurrentDesktop())
1474 if( c == NULL && !desktops.isEmpty())
1475 c = findDesktop(
true, currentDesktop());
1477 if( c != active_client )
1478 setActiveClient( NULL, Allowed );
1485 updateCurrentTopMenu();
1492 for(
int i = desktop_focus_chain.find( currentDesktop() ); i > 0; i-- )
1493 desktop_focus_chain[i] = desktop_focus_chain[i-1];
1494 desktop_focus_chain[0] = currentDesktop();
1501 if( old_desktop != 0 )
1502 popupinfo->showInfo( desktopName(currentDesktop()) );
1507 void Workspace::nextDesktop()
1509 int desktop = currentDesktop() + 1;
1510 setCurrentDesktop(desktop > numberOfDesktops() ? 1 : desktop);
1514 void Workspace::previousDesktop()
1516 int desktop = currentDesktop() - 1;
1517 setCurrentDesktop(desktop > 0 ? desktop : numberOfDesktops());
1520 int Workspace::desktopToRight(
int desktop )
const
1523 calcDesktopLayout(x,y);
1525 if (layoutOrientation == Qt::Vertical)
1528 if ( dt >= numberOfDesktops() )
1530 if ( options->rollOverDesktops )
1531 dt -= numberOfDesktops();
1538 int d = (dt % x) + 1;
1541 if ( options->rollOverDesktops )
1546 dt = dt - (dt % x) + d;
1551 int Workspace::desktopToLeft(
int desktop )
const
1554 calcDesktopLayout(x,y);
1556 if (layoutOrientation == Qt::Vertical)
1561 if ( options->rollOverDesktops )
1562 dt += numberOfDesktops();
1569 int d = (dt % x) - 1;
1572 if ( options->rollOverDesktops )
1577 dt = dt - (dt % x) + d;
1582 int Workspace::desktopUp(
int desktop )
const
1585 calcDesktopLayout(x,y);
1587 if (layoutOrientation == Qt::Horizontal)
1592 if ( options->rollOverDesktops )
1593 dt += numberOfDesktops();
1600 int d = (dt % y) - 1;
1603 if ( options->rollOverDesktops )
1608 dt = dt - (dt % y) + d;
1613 int Workspace::desktopDown(
int desktop )
const
1616 calcDesktopLayout(x,y);
1618 if (layoutOrientation == Qt::Horizontal)
1621 if ( dt >= numberOfDesktops() )
1623 if ( options->rollOverDesktops )
1624 dt -= numberOfDesktops();
1631 int d = (dt % y) + 1;
1634 if ( options->rollOverDesktops )
1639 dt = dt - (dt % y) + d;
1648 void Workspace::setNumberOfDesktops(
int n )
1650 if ( n == number_of_desktops )
1652 int old_number_of_desktops = number_of_desktops;
1653 number_of_desktops = n;
1655 if( currentDesktop() > numberOfDesktops())
1656 setCurrentDesktop( numberOfDesktops());
1660 if( old_number_of_desktops < number_of_desktops )
1662 rootInfo->setNumberOfDesktops( number_of_desktops );
1663 NETPoint* viewports =
new NETPoint[ number_of_desktops ];
1664 rootInfo->setDesktopViewport( number_of_desktops, *viewports );
1666 updateClientArea(
true );
1667 focus_chain.resize( number_of_desktops + 1 );
1672 if( old_number_of_desktops > number_of_desktops )
1674 for( ClientList::ConstIterator it = clients.begin();
1675 it != clients.end();
1678 if( !(*it)->isOnAllDesktops() && (*it)->desktop() > numberOfDesktops())
1679 sendClientToDesktop( *it, numberOfDesktops(), true );
1682 if( old_number_of_desktops > number_of_desktops )
1684 rootInfo->setNumberOfDesktops( number_of_desktops );
1685 NETPoint* viewports =
new NETPoint[ number_of_desktops ];
1686 rootInfo->setDesktopViewport( number_of_desktops, *viewports );
1688 updateClientArea(
true );
1689 focus_chain.resize( number_of_desktops + 1 );
1692 saveDesktopSettings();
1695 desktop_focus_chain.resize( n );
1696 for(
int i = 0; i < (int)desktop_focus_chain.size(); i++ )
1697 desktop_focus_chain[i] = i+1;
1705 void Workspace::sendClientToDesktop( Client* c,
int desk,
bool dont_activate )
1707 bool was_on_desktop = c->isOnDesktop( desk ) || c->isOnAllDesktops();
1708 c->setDesktop( desk );
1709 if ( c->desktop() != desk )
1711 desk = c->desktop();
1713 if ( c->isOnDesktop( currentDesktop() ) )
1715 if ( c->wantsTabFocus() && options->focusPolicyIsReasonable()
1720 restackClientUnderActive( c );
1727 ClientList transients_stacking_order = ensureStackingOrder( c->transients());
1728 for( ClientList::ConstIterator it = transients_stacking_order.begin();
1729 it != transients_stacking_order.end();
1731 sendClientToDesktop( *it, desk, dont_activate );
1735 int Workspace::numScreens()
const
1737 if( !options->xineramaEnabled )
1739 return tqApp->desktop()->numScreens();
1742 int Workspace::activeScreen()
const
1744 if( !options->xineramaEnabled )
1746 if( !options->activeMouseScreen )
1748 if( activeClient() != NULL && !activeClient()->isOnScreen( active_screen ))
1749 return tqApp->desktop()->screenNumber( activeClient()->geometry().center());
1750 return active_screen;
1752 return tqApp->desktop()->screenNumber( TQCursor::pos());
1757 void Workspace::checkActiveScreen(
const Client* c )
1759 if( !options->xineramaEnabled )
1763 if( !c->isOnScreen( active_screen ))
1764 active_screen = c->screen();
1769 void Workspace::setActiveScreenMouse( TQPoint mousepos )
1771 if( !options->xineramaEnabled )
1773 active_screen = tqApp->desktop()->screenNumber( mousepos );
1776 TQRect Workspace::screenGeometry(
int screen )
const
1778 if (( !options->xineramaEnabled ) || (kapp->desktop()->numScreens() < 2))
1779 return tqApp->desktop()->geometry();
1780 return tqApp->desktop()->screenGeometry( screen );
1783 int Workspace::screenNumber( TQPoint pos )
const
1785 if( !options->xineramaEnabled )
1787 return tqApp->desktop()->screenNumber( pos );
1790 void Workspace::sendClientToScreen( Client* c,
int screen )
1792 if( c->screen() == screen )
1794 GeometryUpdatesPostponer blocker( c );
1795 TQRect old_sarea = clientArea( MaximizeArea, c );
1796 TQRect sarea = clientArea( MaximizeArea, screen, c->desktop());
1797 c->setGeometry( sarea.x() - old_sarea.x() + c->x(), sarea.y() - old_sarea.y() + c->y(),
1798 c->size().width(), c->size().height());
1799 c->checkWorkspacePosition();
1800 ClientList transients_stacking_order = ensureStackingOrder( c->transients());
1801 for( ClientList::ConstIterator it = transients_stacking_order.begin();
1802 it != transients_stacking_order.end();
1804 sendClientToScreen( *it, screen );
1806 active_screen = screen;
1810 void Workspace::setDesktopLayout(
int,
int,
int )
1814 void Workspace::updateDesktopLayout()
1817 layoutOrientation = ( rootInfo->desktopLayoutOrientation() == NET::OrientationHorizontal
1818 ? Qt::Horizontal : Qt::Vertical );
1819 layoutX = rootInfo->desktopLayoutColumnsRows().width();
1820 layoutY = rootInfo->desktopLayoutColumnsRows().height();
1821 if( layoutX == 0 && layoutY == 0 )
1825 void Workspace::calcDesktopLayout(
int &x,
int &y)
const
1829 if((x <= 0) && (y > 0))
1830 x = (numberOfDesktops()+y-1) / y;
1831 else if((y <=0) && (x > 0))
1832 y = (numberOfDesktops()+x-1) / x;
1844 bool Workspace::addSystemTrayWin( WId w )
1846 if ( systemTrayWins.contains( w ) )
1849 NETWinInfo ni( tqt_xdisplay(), w, root, NET::WMKDESystemTrayWinFor );
1850 WId trayWinFor = ni.kdeSystemTrayWinFor();
1853 systemTrayWins.append( SystemTrayWindow( w, trayWinFor ) );
1854 XSelectInput( tqt_xdisplay(), w,
1857 XAddToSaveSet( tqt_xdisplay(), w );
1858 propagateSystemTrayWins();
1866 bool Workspace::removeSystemTrayWin( WId w,
bool check )
1868 if ( !systemTrayWins.contains( w ) )
1880 Atom* props = XListProperties( tqt_xdisplay(), w, &num_props );
1886 if( props[ i ] == atoms->kde_system_tray_embedding )
1894 systemTrayWins.remove( w );
1895 XRemoveFromSaveSet (tqt_xdisplay (), w);
1896 propagateSystemTrayWins();
1904 void Workspace::propagateSystemTrayWins()
1906 Window *cl =
new Window[ systemTrayWins.count()];
1909 for ( SystemTrayWindowList::ConstIterator it = systemTrayWins.begin(); it != systemTrayWins.end(); ++it )
1911 cl[i++] = (*it).win;
1914 rootInfo->setKDESystemTrayWindows( cl, i );
1919 void Workspace::killWindowId( Window window_to_kill )
1921 if( window_to_kill == None )
1923 Window window = window_to_kill;
1924 Client* client = NULL;
1927 client = findClient( FrameIdMatchPredicate( window ));
1928 if( client != NULL )
1932 Window* children = 0L;
1933 unsigned int children_count;
1934 XQueryTree( tqt_xdisplay(), window, &root, &parent, &children, &children_count );
1935 if( children != NULL )
1937 if( window == root )
1943 if( client != NULL )
1944 client->killWindow();
1946 XKillClient( tqt_xdisplay(), window_to_kill );
1949 void Workspace::suspendWindowId( Window window_to_suspend )
1951 if( window_to_suspend == None )
1953 Window window = window_to_suspend;
1954 Client* client = NULL;
1957 client = findClient( FrameIdMatchPredicate( window ));
1958 if( client != NULL )
1962 Window* children = 0L;
1963 unsigned int children_count;
1964 XQueryTree( tqt_xdisplay(), window, &root, &parent, &children, &children_count );
1965 if( children != NULL )
1967 if( window == root )
1973 if( client != NULL )
1974 client->suspendWindow();
1979 void Workspace::resumeWindowId( Window window_to_resume )
1981 if( window_to_resume == None )
1983 Window window = window_to_resume;
1984 Client* client = NULL;
1987 client = findClient( FrameIdMatchPredicate( window ));
1988 if( client != NULL )
1992 Window* children = 0L;
1993 unsigned int children_count;
1994 XQueryTree( tqt_xdisplay(), window, &root, &parent, &children, &children_count );
1995 if( children != NULL )
1997 if( window == root )
2003 if( client != NULL )
2004 client->resumeWindow();
2010 bool Workspace::isResumeableWindowID( Window window_to_check )
2012 if( window_to_check == None )
2014 Window window = window_to_check;
2015 Client* client = NULL;
2018 client = findClient( FrameIdMatchPredicate( window ));
2019 if( client != NULL )
2023 Window* children = 0L;
2024 unsigned int children_count;
2025 XQueryTree( tqt_xdisplay(), window, &root, &parent, &children, &children_count );
2026 if( children != NULL )
2028 if( window == root )
2034 if( client != NULL )
2035 return client->isResumeable();
2041 void Workspace::sendPingToWindow( Window window, Time timestamp )
2043 rootInfo->sendPing( window, timestamp );
2046 void Workspace::sendTakeActivity( Client* c, Time timestamp,
long flags )
2048 rootInfo->takeActivity( c->window(), timestamp, flags );
2049 pending_take_activity = c;
2056 void Workspace::slotGrabWindow()
2058 if ( active_client )
2060 TQPixmap snapshot = TQPixmap::grabWindow( active_client->frameId() );
2063 if( Shape::available())
2067 XRectangle* rects = XShapeGetRectangles( tqt_xdisplay(), active_client->frameId(),
2068 ShapeBounding, &count, &order);
2077 for (
int pos = 0; pos < count; pos++)
2078 contents += TQRegion(rects[pos].x, rects[pos].y,
2079 rects[pos].width, rects[pos].height);
2083 TQRegion bbox(0, 0, snapshot.width(), snapshot.height());
2086 TQRegion maskedAway = bbox - contents;
2087 TQMemArray<TQRect> maskedAwayRects = maskedAway.rects();
2090 TQBitmap mask( snapshot.width(), snapshot.height());
2092 p.fillRect(0, 0, mask.width(), mask.height(), Qt::color1);
2093 for (uint pos = 0; pos < maskedAwayRects.count(); pos++)
2094 p.fillRect(maskedAwayRects[pos], Qt::color0);
2096 snapshot.setMask(mask);
2100 TQClipboard *cb = TQApplication::clipboard();
2101 cb->setPixmap( snapshot );
2110 void Workspace::slotGrabDesktop()
2112 TQPixmap p = TQPixmap::grabWindow( tqt_xrootwin() );
2113 TQClipboard *cb = TQApplication::clipboard();
2121 void Workspace::slotMouseEmulation()
2124 if ( mouse_emulation )
2126 XUngrabKeyboard(tqt_xdisplay(), GET_QT_X_TIME());
2127 mouse_emulation = FALSE;
2131 if ( XGrabKeyboard(tqt_xdisplay(),
2133 GrabModeAsync, GrabModeAsync,
2134 GET_QT_X_TIME()) == GrabSuccess )
2136 mouse_emulation = TRUE;
2137 mouse_emulation_state = 0;
2138 mouse_emulation_window = 0;
2148 WId Workspace::getMouseEmulationWindow()
2151 Window child = tqt_xrootwin();
2152 int root_x, root_y, lx, ly;
2160 c = findClient( FrameIdMatchPredicate( w ));
2161 XQueryPointer( tqt_xdisplay(), w, &root, &child,
2162 &root_x, &root_y, &lx, &ly, &state );
2163 }
while ( child != None && child != w );
2165 if ( c && !c->isActive() )
2166 activateClient( c );
2173 unsigned int Workspace::sendFakedMouseEvent( TQPoint pos, WId w, MouseEmulation type,
int button,
unsigned int state )
2177 TQWidget* widget = TQWidget::find( w );
2178 if ( (!widget || widget->inherits(TQTOOLBUTTON_OBJECT_NAME_STRING) ) && !findClient( WindowMatchPredicate( w )) )
2182 XTranslateCoordinates( tqt_xdisplay(), tqt_xrootwin(), w, pos.x(), pos.y(), &x, &y, &xw );
2183 if ( type == EmuMove )
2186 e.type = MotionNotify;
2187 e.xmotion.window = w;
2188 e.xmotion.root = tqt_xrootwin();
2189 e.xmotion.subwindow = w;
2190 e.xmotion.time = GET_QT_X_TIME();
2193 e.xmotion.x_root = pos.x();
2194 e.xmotion.y_root = pos.y();
2195 e.xmotion.state = state;
2196 e.xmotion.is_hint = NotifyNormal;
2197 XSendEvent( tqt_xdisplay(), w, TRUE, ButtonMotionMask, &e );
2202 e.type = type == EmuRelease ? ButtonRelease : ButtonPress;
2203 e.xbutton.window = w;
2204 e.xbutton.root = tqt_xrootwin();
2205 e.xbutton.subwindow = w;
2206 e.xbutton.time = GET_QT_X_TIME();
2209 e.xbutton.x_root = pos.x();
2210 e.xbutton.y_root = pos.y();
2211 e.xbutton.state = state;
2212 e.xbutton.button = button;
2213 XSendEvent( tqt_xdisplay(), w, TRUE, ButtonPressMask, &e );
2215 if ( type == EmuPress )
2220 state |= Button2Mask;
2223 state |= Button3Mask;
2226 state |= Button1Mask;
2235 state &= ~Button2Mask;
2238 state &= ~Button3Mask;
2241 state &= ~Button1Mask;
2253 bool Workspace::keyPressMouseEmulation( XKeyEvent& ev )
2255 if ( root != tqt_xrootwin() )
2257 int kc = XkbKeycodeToKeysym(tqt_xdisplay(), ev.keycode, 0, 0);
2258 int km = ev.state & (ControlMask | Mod1Mask | ShiftMask);
2260 bool is_control = km & ControlMask;
2261 bool is_alt = km & Mod1Mask;
2262 bool is_shift = km & ShiftMask;
2263 int delta = is_control?1:is_alt?32:8;
2264 TQPoint pos = TQCursor::pos();
2285 if ( !mouse_emulation_state )
2286 mouse_emulation_window = getMouseEmulationWindow();
2287 if ( (mouse_emulation_state & Button1Mask) == 0 )
2288 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 );
2293 if ( !mouse_emulation_state )
2294 mouse_emulation_window = getMouseEmulationWindow();
2295 if ( (mouse_emulation_state & Button2Mask) == 0 )
2296 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuPress, Button2, mouse_emulation_state );
2298 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button2, mouse_emulation_state );
2301 if ( !mouse_emulation_state )
2302 mouse_emulation_window = getMouseEmulationWindow();
2303 if ( (mouse_emulation_state & Button3Mask) == 0 )
2304 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuPress, Button3, mouse_emulation_state );
2306 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button3, mouse_emulation_state );
2313 if ( !mouse_emulation_state )
2316 mouse_emulation_window = getMouseEmulationWindow();
2317 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuPress, Button1, mouse_emulation_state );
2318 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button1, mouse_emulation_state );
2322 if ( mouse_emulation_state & Button1Mask )
2323 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button1, mouse_emulation_state );
2324 if ( mouse_emulation_state & Button2Mask )
2325 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button2, mouse_emulation_state );
2326 if ( mouse_emulation_state & Button3Mask )
2327 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button3, mouse_emulation_state );
2332 XUngrabKeyboard(tqt_xdisplay(), GET_QT_X_TIME());
2333 mouse_emulation = FALSE;
2339 TQCursor::setPos( pos );
2340 if ( mouse_emulation_state )
2341 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuMove, 0, mouse_emulation_state );
2351 TQWidget* Workspace::desktopWidget()
2353 return desktop_widget;
2357 void Workspace::delayFocus()
2359 requestFocus( delayfocus_client );
2363 void Workspace::requestDelayFocus( Client* c )
2365 delayfocus_client = c;
2366 delete delayFocusTimer;
2367 delayFocusTimer =
new TQTimer(
this );
2368 connect( delayFocusTimer, TQT_SIGNAL( timeout() ),
this, TQT_SLOT( delayFocus() ) );
2369 delayFocusTimer->start( options->delayFocusInterval, TRUE );
2372 void Workspace::cancelDelayFocus()
2374 delete delayFocusTimer;
2375 delayFocusTimer = 0;
2385 void Workspace::checkElectricBorders(
bool force )
2388 destroyBorderWindows();
2390 electric_current_border = 0;
2392 TQRect r = TQApplication::desktop()->geometry();
2393 electricTop = r.top();
2394 electricBottom = r.bottom();
2395 electricLeft = r.left();
2396 electricRight = r.right();
2398 if (options->electricBorders() == Options::ElectricAlways)
2399 createBorderWindows();
2401 destroyBorderWindows();
2404 void Workspace::createBorderWindows()
2406 if ( electric_have_borders )
2409 electric_have_borders =
true;
2411 TQRect r = TQApplication::desktop()->geometry();
2412 XSetWindowAttributes attributes;
2413 unsigned long valuemask;
2414 attributes.override_redirect = True;
2415 attributes.event_mask = ( EnterWindowMask | LeaveWindowMask );
2416 valuemask= (CWOverrideRedirect | CWEventMask | CWCursor );
2417 attributes.cursor = XCreateFontCursor(tqt_xdisplay(),
2419 electric_top_border = XCreateWindow (tqt_xdisplay(), tqt_xrootwin(),
2423 CopyFromParent, InputOnly,
2425 valuemask, &attributes);
2426 XMapWindow(tqt_xdisplay(), electric_top_border);
2428 attributes.cursor = XCreateFontCursor(tqt_xdisplay(),
2430 electric_bottom_border = XCreateWindow (tqt_xdisplay(), tqt_xrootwin(),
2434 CopyFromParent, InputOnly,
2436 valuemask, &attributes);
2437 XMapWindow(tqt_xdisplay(), electric_bottom_border);
2439 attributes.cursor = XCreateFontCursor(tqt_xdisplay(),
2441 electric_left_border = XCreateWindow (tqt_xdisplay(), tqt_xrootwin(),
2445 CopyFromParent, InputOnly,
2447 valuemask, &attributes);
2448 XMapWindow(tqt_xdisplay(), electric_left_border);
2450 attributes.cursor = XCreateFontCursor(tqt_xdisplay(),
2452 electric_right_border = XCreateWindow (tqt_xdisplay(), tqt_xrootwin(),
2456 CopyFromParent, InputOnly,
2458 valuemask, &attributes);
2459 XMapWindow(tqt_xdisplay(), electric_right_border);
2462 XChangeProperty( tqt_xdisplay(), electric_top_border, atoms->xdnd_aware, XA_ATOM,
2463 32, PropModeReplace, (
unsigned char* )&version, 1 );
2464 XChangeProperty( tqt_xdisplay(), electric_bottom_border, atoms->xdnd_aware, XA_ATOM,
2465 32, PropModeReplace, (
unsigned char* )&version, 1 );
2466 XChangeProperty( tqt_xdisplay(), electric_left_border, atoms->xdnd_aware, XA_ATOM,
2467 32, PropModeReplace, (
unsigned char* )&version, 1 );
2468 XChangeProperty( tqt_xdisplay(), electric_right_border, atoms->xdnd_aware, XA_ATOM,
2469 32, PropModeReplace, (
unsigned char* )&version, 1 );
2478 void Workspace::destroyBorderWindows()
2480 if( !electric_have_borders)
2483 electric_have_borders =
false;
2485 if(electric_top_border)
2486 XDestroyWindow(tqt_xdisplay(),electric_top_border);
2487 if(electric_bottom_border)
2488 XDestroyWindow(tqt_xdisplay(),electric_bottom_border);
2489 if(electric_left_border)
2490 XDestroyWindow(tqt_xdisplay(),electric_left_border);
2491 if(electric_right_border)
2492 XDestroyWindow(tqt_xdisplay(),electric_right_border);
2494 electric_top_border = None;
2495 electric_bottom_border = None;
2496 electric_left_border = None;
2497 electric_right_border = None;
2500 void Workspace::clientMoved(
const TQPoint &pos, Time now)
2502 if (options->electricBorders() == Options::ElectricDisabled)
2505 if ((pos.x() != electricLeft) &&
2506 (pos.x() != electricRight) &&
2507 (pos.y() != electricTop) &&
2508 (pos.y() != electricBottom))
2511 Time treshold_set = options->electricBorderDelay();
2512 Time treshold_reset = 250;
2513 int distance_reset = 30;
2516 if (pos.x() == electricLeft)
2518 else if (pos.x() == electricRight)
2520 else if (pos.y() == electricTop)
2522 else if (pos.y() == electricBottom)
2525 if ((electric_current_border == border) &&
2526 (timestampDiff(electric_time_last, now) < treshold_reset) &&
2527 ((pos-electric_push_point).manhattanLength() < distance_reset))
2529 electric_time_last = now;
2531 if (timestampDiff(electric_time_first, now) > treshold_set)
2533 electric_current_border = 0;
2535 TQRect r = TQApplication::desktop()->geometry();
2538 int desk_before = currentDesktop();
2542 slotSwitchDesktopLeft();
2543 if (currentDesktop() != desk_before)
2545 offset = r.width() / 5;
2546 TQCursor::setPos(r.width() - offset, pos.y());
2551 slotSwitchDesktopRight();
2552 if (currentDesktop() != desk_before)
2554 offset = r.width() / 5;
2555 TQCursor::setPos(offset, pos.y());
2560 slotSwitchDesktopUp();
2561 if (currentDesktop() != desk_before)
2563 offset = r.height() / 5;
2564 TQCursor::setPos(pos.x(), r.height() - offset);
2569 slotSwitchDesktopDown();
2570 if (currentDesktop() != desk_before)
2572 offset = r.height() / 5;
2573 TQCursor::setPos(pos.x(), offset);
2582 electric_current_border = border;
2583 electric_time_first = now;
2584 electric_time_last = now;
2585 electric_push_point = pos;
2593 case 1: TQCursor::setPos(pos.x()+mouse_warp, pos.y());
break;
2594 case 2: TQCursor::setPos(pos.x()-mouse_warp, pos.y());
break;
2595 case 3: TQCursor::setPos(pos.x(), pos.y()+mouse_warp);
break;
2596 case 4: TQCursor::setPos(pos.x(), pos.y()-mouse_warp);
break;
2602 bool Workspace::electricBorder(XEvent *e)
2604 if( !electric_have_borders )
2606 if( e->type == EnterNotify )
2608 if( e->xcrossing.window == electric_top_border ||
2609 e->xcrossing.window == electric_left_border ||
2610 e->xcrossing.window == electric_bottom_border ||
2611 e->xcrossing.window == electric_right_border)
2614 clientMoved( TQPoint( e->xcrossing.x_root, e->xcrossing.y_root ), e->xcrossing.time );
2618 if( e->type == ClientMessage )
2620 if( e->xclient.message_type == atoms->xdnd_position
2621 && ( e->xclient.window == electric_top_border
2622 || e->xclient.window == electric_bottom_border
2623 || e->xclient.window == electric_left_border
2624 || e->xclient.window == electric_right_border ))
2627 clientMoved( TQPoint( e->xclient.data.l[2]>>16, e->xclient.data.l[2]&0xffff), GET_QT_X_TIME() );
2637 void Workspace::raiseElectricBorders()
2640 if(electric_have_borders)
2642 XRaiseWindow(tqt_xdisplay(), electric_top_border);
2643 XRaiseWindow(tqt_xdisplay(), electric_left_border);
2644 XRaiseWindow(tqt_xdisplay(), electric_bottom_border);
2645 XRaiseWindow(tqt_xdisplay(), electric_right_border);
2649 void Workspace::addTopMenu( Client* c )
2651 assert( c->isTopMenu());
2652 assert( !topmenus.contains( c ));
2653 topmenus.append( c );
2654 if( managingTopMenus())
2656 int minsize = c->minSize().height();
2657 if( minsize > topMenuHeight())
2659 topmenu_height = minsize;
2660 updateTopMenuGeometry();
2662 updateTopMenuGeometry( c );
2663 updateCurrentTopMenu();
2668 void Workspace::removeTopMenu( Client* c )
2672 assert( c->isTopMenu());
2673 assert( topmenus.contains( c ));
2674 topmenus.remove( c );
2675 updateCurrentTopMenu();
2679 void Workspace::lostTopMenuSelection()
2683 disconnect( topmenu_watcher, TQT_SIGNAL( lostOwner()),
this, TQT_SLOT( lostTopMenuOwner()));
2684 connect( topmenu_watcher, TQT_SIGNAL( lostOwner()),
this, TQT_SLOT( lostTopMenuOwner()));
2685 if( !managing_topmenus )
2687 connect( topmenu_watcher, TQT_SIGNAL( lostOwner()),
this, TQT_SLOT( lostTopMenuOwner()));
2688 disconnect( topmenu_selection, TQT_SIGNAL( lostOwnership()),
this, TQT_SLOT( lostTopMenuSelection()));
2689 managing_topmenus =
false;
2690 delete topmenu_space;
2691 topmenu_space = NULL;
2693 for( ClientList::ConstIterator it = topmenus.begin();
2694 it != topmenus.end();
2696 (*it)->checkWorkspacePosition();
2699 void Workspace::lostTopMenuOwner()
2701 if( !options->topMenuEnabled())
2704 if( !topmenu_selection->claim(
false ))
2710 setupTopMenuHandling();
2713 void Workspace::setupTopMenuHandling()
2715 if( managing_topmenus )
2717 connect( topmenu_selection, TQT_SIGNAL( lostOwnership()),
this, TQT_SLOT( lostTopMenuSelection()));
2718 disconnect( topmenu_watcher, TQT_SIGNAL( lostOwner()),
this, TQT_SLOT( lostTopMenuOwner()));
2719 managing_topmenus =
true;
2720 topmenu_space =
new TQWidget;
2722 stack[ 0 ] = supportWindow->winId();
2723 stack[ 1 ] = topmenu_space->winId();
2724 XRestackWindows(tqt_xdisplay(), stack, 2);
2725 updateTopMenuGeometry();
2726 topmenu_space->show();
2728 updateCurrentTopMenu();
2731 int Workspace::topMenuHeight()
const
2733 if( topmenu_height == 0 )
2736 tmpmenu.insertItem(
"dummy" );
2737 topmenu_height = tmpmenu.sizeHint().height();
2739 return topmenu_height;
2742 KDecoration* Workspace::createDecoration( KDecorationBridge* bridge )
2744 return mgr->createDecoration( bridge );
2747 TQString Workspace::desktopName(
int desk )
const
2749 return TQString::fromUtf8( rootInfo->desktopName( desk ) );
2752 bool Workspace::checkStartupNotification( Window w, TDEStartupInfoId&
id, TDEStartupInfoData& data )
2754 return startup->checkStartup( w,
id, data ) == TDEStartupInfo::Match;
2761 void Workspace::focusToNull()
2763 XSetInputFocus(tqt_xdisplay(), null_focus_window, RevertToPointerRoot, GET_QT_X_TIME() );
2766 void Workspace::helperDialog(
const TQString& message,
const Client* c )
2770 if( message ==
"noborderaltf3" )
2772 TQString shortcut = TQString(
"%1 (%2)" ).arg( keys->label(
"Window Operations Menu" ))
2773 .arg( keys->shortcut(
"Window Operations Menu" ).seq( 0 ).toString());
2774 args <<
"--msgbox" <<
2775 i18n(
"You have selected to show a window without its border.\n"
2776 "Without the border, you will not be able to enable the border "
2777 "again using the mouse: use the window operations menu instead, "
2778 "activated using the %1 keyboard shortcut." )
2780 type =
"altf3warning";
2782 else if( message ==
"fullscreenaltf3" )
2784 TQString shortcut = TQString(
"%1 (%2)" ).arg( keys->label(
"Window Operations Menu" ))
2785 .arg( keys->shortcut(
"Window Operations Menu" ).seq( 0 ).toString());
2786 args <<
"--msgbox" <<
2787 i18n(
"You have selected to show a window in fullscreen mode.\n"
2788 "If the application itself does not have an option to turn the fullscreen "
2789 "mode off you will not be able to disable it "
2790 "again using the mouse: use the window operations menu instead, "
2791 "activated using the %1 keyboard shortcut." )
2793 type =
"altf3warning";
2798 proc <<
"kdialog" << args;
2799 if( !type.isEmpty())
2801 TDEConfig cfg(
"twin_dialogsrc" );
2802 cfg.setGroup(
"Notification Messages" );
2803 if( !cfg.readBoolEntry( type,
true ))
2805 proc <<
"--dontagain" <<
"twin_dialogsrc:" + type;
2808 proc <<
"--embed" << TQString::number( c->window());
2809 proc.start( TDEProcess::DontCare );
2815 void Workspace::startKompmgr()
2820 unsigned long length, after;
2821 unsigned char* data_root;
2823 prop_root = XInternAtom(tqt_xdisplay(),
"_XROOTPMAP_ID", False);
2824 if( XGetWindowProperty( tqt_xdisplay(), tqt_xrootwin(), prop_root, 0L, 1L, False, AnyPropertyType, &type, &format, &length, &after, &data_root) == Success && data_root != NULL ) {
2829 TQTimer::singleShot( 200,
this, TQT_SLOT(startKompmgr()) );
2832 pid_t kompmgrpid = getCompositorPID();
2833 if (kompmgrpid && kill(kompmgrpid, 0) >= 0)
2838 if (!kompmgr || kompmgr->isRunning()) {
2839 kompmgrReloadSettings();
2842 if (!kompmgr->start(TDEProcess::OwnGroup, TDEProcess::Stderr))
2844 options->useTranslucency = FALSE;
2846 proc <<
"kdialog" <<
"--error"
2847 << i18n(
"The Composite Manager could not be started.\\nMake sure you have \"" TDE_COMPOSITOR_BINARY
"\" in a $PATH directory.")
2848 <<
"--title" <<
"Composite Manager Failure";
2849 proc.start(TDEProcess::DontCare);
2853 delete kompmgr_selection;
2854 char selection_name[ 100 ];
2855 sprintf( selection_name,
"_NET_WM_CM_S%d", DefaultScreen( tqt_xdisplay()));
2856 kompmgr_selection =
new TDESelectionOwner( selection_name );
2857 connect( kompmgr_selection, TQT_SIGNAL( lostOwnership()), TQT_SLOT( stopKompmgr()));
2858 kompmgr_selection->claim(
true );
2859 connect(kompmgr, TQT_SIGNAL(processExited(TDEProcess*)), TQT_SLOT(restartKompmgr(TDEProcess*)));
2860 options->useTranslucency = TRUE;
2864 TQDataStream arg(ba, IO_WriteOnly);
2866 kapp->dcopClient()->emitDCOPSignal(
"default",
"kompmgrStarted()", ba);
2868 if (popup){
delete popup; popup = 0L; }
2871 void Workspace::stopKompmgr()
2873 if (!kompmgr || !kompmgr->isRunning()) {
2876 delete kompmgr_selection;
2877 kompmgr_selection = NULL;
2878 kompmgr->disconnect(
this, TQT_SLOT(restartKompmgr(TDEProcess*)));
2879 options->useTranslucency = FALSE;
2880 if (popup){
delete popup; popup = 0L; }
2881 kompmgr->kill(SIGKILL);
2883 TQDataStream arg(ba, IO_WriteOnly);
2885 kapp->dcopClient()->emitDCOPSignal(
"default",
"kompmgrStopped()", ba);
2888 void Workspace::kompmgrReloadSettings()
2890 if (!kompmgr || !kompmgr->isRunning()) {
2893 kompmgr->kill(SIGUSR2);
2896 bool Workspace::kompmgrIsRunning()
2898 return kompmgr && kompmgr->isRunning();
2901 void Workspace::unblockKompmgrRestart()
2903 allowKompmgrRestart = TRUE;
2906 void Workspace::restartKompmgr( TDEProcess *proc )
2910 if (proc->signalled()) {
2911 int exit_signal_number = proc->exitSignal();
2912 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) ) {
2918 if (!allowKompmgrRestart)
2920 delete kompmgr_selection;
2921 kompmgr_selection = NULL;
2922 options->useTranslucency = FALSE;
2925 proc <<
"kdialog" <<
"--error"
2926 << i18n(
"The Composite Manager crashed twice within a minute and is therefore disabled for this session.")
2927 <<
"--title" << i18n(
"Composite Manager Failure");
2928 proc.start(TDEProcess::DontCare);
2942 if (!kompmgr->start(TDEProcess::NotifyOnExit, TDEProcess::Stderr))
2944 delete kompmgr_selection;
2945 kompmgr_selection = NULL;
2946 options->useTranslucency = FALSE;
2948 proc <<
"kdialog" <<
"--error"
2949 << i18n(
"The Composite Manager could not be started.\\nMake sure you have \"" TDE_COMPOSITOR_BINARY
"\" in a $PATH directory.")
2950 <<
"--title" << i18n(
"Composite Manager Failure");
2951 proc.start(TDEProcess::DontCare);
2955 allowKompmgrRestart = FALSE;
2956 TQTimer::singleShot( 60000,
this, TQT_SLOT(unblockKompmgrRestart()) );
2961 void Workspace::handleKompmgrOutput( TDEProcess* ,
char *buffer,
int buflen)
2964 TQString output = TQString::fromLocal8Bit( buffer, buflen );
2965 if (output.contains(
"Started",
false))
2967 else if (output.contains(
"Can't open display",
false))
2968 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>");
2969 else if (output.contains(
"No render extension",
false))
2970 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>");
2971 else if (output.contains(
"No composite extension",
false))
2972 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>"
2973 "<i>Section \"Extensions\"<br>"
2974 "Option \"Composite\" \"Enable\"<br>"
2975 "EndSection</i></qt>");
2976 else if (output.contains(
"No damage extension",
false))
2977 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>");
2978 else if (output.contains(
"No XFixes extension",
false))
2979 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>");
2982 kompmgr->closeStderr();
2983 disconnect(kompmgr, TQT_SIGNAL(receivedStderr(TDEProcess*,
char*,
int)),
this, TQT_SLOT(handleKompmgrOutput(TDEProcess*,
char*,
int)));
2984 if( !message.isEmpty())
2987 proc <<
"kdialog" <<
"--error"
2989 <<
"--title" << i18n(
"Composite Manager Failure");
2990 proc.start(TDEProcess::DontCare);
2995 void Workspace::setOpacity(
unsigned long winId,
unsigned int opacityPercent)
2997 if (opacityPercent > 100) opacityPercent = 100;
2998 for( ClientList::ConstIterator it = stackingOrder().begin(); it != stackingOrder().end(); it++ )
2999 if (winId == (*it)->window())
3001 (*it)->setOpacity(opacityPercent < 100, (
unsigned int)((opacityPercent/100.0)*0xFFFFFFFF));
3006 void Workspace::setShadowSize(
unsigned long winId,
unsigned int shadowSizePercent)
3009 if (shadowSizePercent > 400) shadowSizePercent = 400;
3010 for( ClientList::ConstIterator it = stackingOrder().begin(); it != stackingOrder().end(); it++ )
3011 if (winId == (*it)->window())
3013 (*it)->setShadowSize(shadowSizePercent);
3018 void Workspace::setUnshadowed(
unsigned long winId)
3020 for( ClientList::ConstIterator it = stackingOrder().begin(); it != stackingOrder().end(); it++ )
3021 if (winId == (*it)->window())
3023 (*it)->setShadowSize(0);
3028 void Workspace::setShowingDesktop(
bool showing )
3030 rootInfo->setShowingDesktop( showing );
3031 showing_desktop = showing;
3032 ++block_showing_desktop;
3033 if( showing_desktop )
3035 showing_desktop_clients.clear();
3037 ClientList cls = stackingOrder();
3040 for( ClientList::ConstIterator it = cls.begin();
3044 if( (*it)->isOnCurrentDesktop() && (*it)->isShown(
true ) && !(*it)->isSpecialWindow())
3045 showing_desktop_clients.prepend( *it );
3047 for( ClientList::ConstIterator it = showing_desktop_clients.begin();
3048 it != showing_desktop_clients.end();
3050 (*it)->minimize(
true);
3052 if( Client* desk = findDesktop(
true, currentDesktop()))
3053 requestFocus( desk );
3057 for( ClientList::ConstIterator it = showing_desktop_clients.begin();
3058 it != showing_desktop_clients.end();
3060 (*it)->unminimize(
true);
3061 if( showing_desktop_clients.count() > 0 )
3062 requestFocus( showing_desktop_clients.first());
3063 showing_desktop_clients.clear();
3065 --block_showing_desktop;
3077 void Workspace::resetShowingDesktop(
bool keep_hidden )
3079 if( block_showing_desktop > 0 )
3081 rootInfo->setShowingDesktop(
false );
3082 showing_desktop =
false;
3083 ++block_showing_desktop;
3086 for( ClientList::ConstIterator it = showing_desktop_clients.begin();
3087 it != showing_desktop_clients.end();
3089 (*it)->unminimize(
true);
3091 showing_desktop_clients.clear();
3092 --block_showing_desktop;
3102 void Workspace::slotDisableGlobalShortcuts()
3104 if( global_shortcuts_disabled || global_shortcuts_disabled_for_client )
3105 disableGlobalShortcuts(
false );
3107 disableGlobalShortcuts(
true );
3110 static bool pending_dfc =
false;
3112 void Workspace::disableGlobalShortcutsForClient(
bool disable )
3114 if( global_shortcuts_disabled_for_client == disable )
3116 if( !global_shortcuts_disabled )
3120 KIPC::sendMessageAll( KIPC::BlockShortcuts, disable );
3125 void Workspace::disableGlobalShortcuts(
bool disable )
3127 KIPC::sendMessageAll( KIPC::BlockShortcuts, disable );
3131 void Workspace::kipcMessage(
int id,
int data )
3133 if(
id != KIPC::BlockShortcuts )
3135 if( pending_dfc && data )
3137 global_shortcuts_disabled_for_client =
true;
3138 pending_dfc =
false;
3142 global_shortcuts_disabled = data;
3143 global_shortcuts_disabled_for_client =
false;
3146 for( ClientList::ConstIterator it = clients.begin();
3147 it != clients.end();
3149 (*it)->updateMouseGrab();
3154 #include "workspace.moc"