12 #include "workspace.h"
14 #include <tdeapplication.h>
15 #include <tdestartupinfo.h>
17 #include <tdeconfig.h>
18 #include <tdeglobal.h>
19 #include <tqpopupmenu.h>
20 #include <tdelocale.h>
22 #include <tqpainter.h>
24 #include <tqclipboard.h>
25 #include <tdemenubar.h>
27 #include <kglobalaccel.h>
28 #include <dcopclient.h>
33 #include "popupinfo.h"
36 #include "placement.h"
37 #include "notifications.h"
41 #include <X11/XKBlib.h>
42 #include <X11/extensions/shape.h>
43 #include <X11/keysym.h>
44 #include <X11/keysymdef.h>
45 #include <X11/cursorfont.h>
51 namespace KWinInternal
54 extern int screen_number;
56 Workspace *Workspace::_self = 0;
58 TDEProcess* kompmgr = 0;
59 TDESelectionOwner* kompmgr_selection;
61 bool allowKompmgrRestart = TRUE;
62 extern bool disable_twin_composition_manager;
64 bool supportsCompMgr()
66 if (disable_twin_composition_manager) {
72 bool damageExt = XQueryExtension(tqt_xdisplay(),
"DAMAGE", &i, &i, &i);
73 bool compositeExt = XQueryExtension(tqt_xdisplay(),
"Composite", &i, &i, &i);
74 bool xfixesExt = XQueryExtension(tqt_xdisplay(),
"XFIXES", &i, &i, &i);
76 return damageExt && compositeExt && xfixesExt;
79 pid_t getCompositorPID() {
82 const char *pidfile =
"compton-tde.pid";
83 char uidstr[
sizeof(uid_t)*8+1];
84 sprintf(uidstr,
"%d", getuid());
85 int n = strlen(P_tmpdir)+strlen(uidstr)+strlen(pidfile)+3;
86 filename = (
char*)malloc(n*
sizeof(
char)+1);
88 strcat(filename, P_tmpdir);
89 strcat(filename,
"/.");
90 strcat(filename, uidstr);
91 strcat(filename,
"-");
92 strcat(filename, pidfile);
97 pFile = fopen(filename,
"r");
101 printf(
"[twin-workspace] Using '%s' as compton-tde pidfile\n\n", filename);
103 fseek (pFile , 0 , SEEK_END);
104 unsigned long lSize = ftell (pFile);
108 size_t result = fread (buffer, 1, lSize, pFile);
112 kompmgrpid = atoi(buffer);
129 Workspace::Workspace(
bool restore )
130 : DCOPObject (
"KWinInterface"),
131 TQObject (0,
"workspace"),
133 number_of_desktops(0),
135 active_popup( NULL ),
136 active_popup_client( NULL ),
138 temporaryRulesMessages(
"_KDE_NET_WM_TEMPORARY_RULES", NULL, false ),
139 rules_updates_disabled( false ),
141 last_active_client (0),
142 next_active_client (0),
143 most_recently_raised (0),
145 pending_take_activity ( NULL ),
146 delayfocus_client (0),
147 showing_desktop( false ),
148 block_showing_desktop( 0 ),
149 was_user_interaction (false),
150 session_saving (false),
151 control_grab (false),
153 mouse_emulation (false),
160 desk_popup_index (0),
162 client_keys ( NULL ),
163 client_keys_dialog ( NULL ),
164 client_keys_client ( NULL ),
165 disable_shortcuts_keys ( NULL ),
166 global_shortcuts_disabled( false ),
167 global_shortcuts_disabled_for_client( false ),
169 workspaceInit (true),
170 startup(0), electric_have_borders(false),
171 electric_current_border(0),
172 electric_top_border(None),
173 electric_bottom_border(None),
174 electric_left_border(None),
175 electric_right_border(None),
176 layoutOrientation(Qt::Vertical),
181 managing_topmenus( false ),
182 topmenu_selection( NULL ),
183 topmenu_watcher( NULL ),
185 topmenu_space( NULL ),
186 set_active_client_recursion( 0 ),
187 block_stacking_updates( 0 ),
188 forced_global_mouse_grab( false )
192 root = tqt_xrootwin();
193 default_colormap = DefaultColormap(tqt_xdisplay(), tqt_xscreen() );
194 installed_colormap = default_colormap;
195 session.setAutoDelete( TRUE );
197 connect( &temporaryRulesMessages, TQT_SIGNAL( gotMessage(
const TQString& )),
198 this, TQT_SLOT( gotTemporaryRulesMessage(
const TQString& )));
199 connect( &rulesUpdatedTimer, TQT_SIGNAL( timeout()),
this, TQT_SLOT( writeWindowRules()));
205 electric_time_first = GET_QT_X_TIME();
206 electric_time_last = GET_QT_X_TIME();
213 (void) TQApplication::desktop();
219 (WFlags)(TQt::WType_Desktop | TQt::WPaintUnclipped)
222 kapp->setGlobalMouseTracking(
true );
224 startup =
new TDEStartupInfo(
225 TDEStartupInfo::DisableKWinModule | TDEStartupInfo::AnnounceSilenceChanges,
this );
228 XSelectInput(tqt_xdisplay(), root,
232 SubstructureRedirectMask |
233 SubstructureNotifyMask |
249 (
unsigned char*) &data,
253 client_keys =
new TDEGlobalAccel(
this );
255 tab_box =
new TabBox(
this );
256 popupinfo =
new PopupInfo(
this );
260 #if (TQT_VERSION-0 >= 0x030200)
261 connect( kapp->desktop(), TQT_SIGNAL( resized(
int )), TQT_SLOT( desktopResized()));
264 if (!supportsCompMgr()) {
265 options->useTranslucency =
false;
271 pid_t kompmgrpid = getCompositorPID();
273 if (options->useTranslucency)
275 kompmgr =
new TDEProcess;
276 connect(kompmgr, TQT_SIGNAL(receivedStderr(TDEProcess*,
char*,
int)), TQT_SLOT(handleKompmgrOutput(TDEProcess*,
char*,
int)));
277 *kompmgr << TDE_COMPOSITOR_BINARY;
280 if (kill(kompmgrpid, 0) < 0)
291 else if (!disable_twin_composition_manager)
296 kill(kompmgrpid, SIGTERM);
306 void Workspace::init()
308 checkElectricBorders();
314 supportWindow =
new TQWidget;
315 XLowerWindow( tqt_xdisplay(), supportWindow->winId());
317 XSetWindowAttributes attr;
318 attr.override_redirect = 1;
319 null_focus_window = XCreateWindow( tqt_xdisplay(), tqt_xrootwin(), -1,-1, 1, 1, 0, CopyFromParent,
320 InputOnly, CopyFromParent, CWOverrideRedirect, &attr );
321 XMapWindow(tqt_xdisplay(), null_focus_window);
323 unsigned long protocols[ 5 ] =
326 NET::SupportingWMCheck |
328 NET::ClientListStacking |
329 NET::DesktopGeometry |
330 NET::NumberOfDesktops |
331 NET::CurrentDesktop |
336 NET::KDESystemTrayWindows |
343 NET::WMIconGeometry |
347 NET::WMKDESystemTrayWinFor |
348 NET::WMFrameExtents |
375 NET::DemandsAttention |
380 NET::WM2AllowedActions |
381 NET::WM2RestackWindow |
382 NET::WM2MoveResizeWindow |
383 NET::WM2ExtendedStrut |
384 NET::WM2KDETemporaryRules |
385 NET::WM2ShowingDesktop |
386 NET::WM2FullPlacement |
387 NET::WM2DesktopLayout |
392 NET::ActionMinimize |
396 NET::ActionMaxHoriz |
397 NET::ActionFullScreen |
398 NET::ActionChangeDesktop |
404 rootInfo =
new RootInfo(
this, tqt_xdisplay(), supportWindow->winId(),
"KWin",
405 protocols, 5, tqt_xscreen() );
407 loadDesktopSettings();
408 updateDesktopLayout();
410 NETRootInfo client_info( tqt_xdisplay(), NET::ActiveWindow | NET::CurrentDesktop );
412 if( !kapp->isSessionRestored())
413 initial_desktop = client_info.currentDesktop();
416 TDEConfigGroupSaver saver( kapp->sessionConfig(),
"Session" );
417 initial_desktop = kapp->sessionConfig()->readNumEntry(
"desktop", 1 );
419 if( !setCurrentDesktop( initial_desktop ))
420 setCurrentDesktop( 1 );
423 initPositioning =
new Placement(
this);
425 connect(&reconfigureTimer, TQT_SIGNAL(timeout()),
this,
426 TQT_SLOT(slotReconfigure()));
427 connect( &updateToolWindowsTimer, TQT_SIGNAL( timeout()),
this, TQT_SLOT( slotUpdateToolWindows()));
429 connect(kapp, TQT_SIGNAL(appearanceChanged()),
this,
430 TQT_SLOT(slotReconfigure()));
431 connect(kapp, TQT_SIGNAL(settingsChanged(
int)),
this,
432 TQT_SLOT(slotSettingsChanged(
int)));
433 connect(kapp, TQT_SIGNAL( kipcMessage(
int,
int )),
this, TQT_SLOT( kipcMessage(
int,
int )));
435 active_client = NULL;
436 rootInfo->setActiveWindow( None );
438 if( !kapp->isSessionRestored())
442 sprintf( nm,
"_KDE_TOPMENU_OWNER_S%d", DefaultScreen( tqt_xdisplay()));
443 Atom topmenu_atom = XInternAtom( tqt_xdisplay(), nm, False );
444 topmenu_selection =
new TDESelectionOwner( topmenu_atom );
445 topmenu_watcher =
new TDESelectionWatcher( topmenu_atom );
449 StackingUpdatesBlocker blocker(
this );
451 if( options->topMenuEnabled() && topmenu_selection->claim(
false ))
452 setupTopMenuHandling();
454 lostTopMenuSelection();
456 unsigned int i, nwins;
457 Window root_return, parent_return, *wins;
458 XQueryTree(tqt_xdisplay(), root, &root_return, &parent_return, &wins, &nwins);
459 for (i = 0; i < nwins; i++)
461 XWindowAttributes attr;
462 XGetWindowAttributes(tqt_xdisplay(), wins[i], &attr);
463 if (attr.override_redirect )
465 if( topmenu_space && topmenu_space->winId() == wins[ i ] )
467 if (attr.map_state != IsUnmapped)
469 if ( addSystemTrayWin( wins[i] ) )
471 Client* c = createClient( wins[i],
true );
472 if ( c != NULL && root != tqt_xrootwin() )
475 XReparentWindow( tqt_xdisplay(), c->frameId(), root, 0, 0 );
481 XFree((
void *) wins);
483 updateStackingOrder(
true );
486 raiseElectricBorders();
489 NETPoint* viewports =
new NETPoint[ number_of_desktops ];
490 rootInfo->setDesktopViewport( number_of_desktops, *viewports );
492 TQRect geom = TQApplication::desktop()->geometry();
493 NETSize desktop_geometry;
494 desktop_geometry.width = geom.width();
495 desktop_geometry.height = geom.height();
496 rootInfo->setDesktopGeometry( -1, desktop_geometry );
497 setShowingDesktop(
false );
501 Client* new_active_client = NULL;
502 if( !kapp->isSessionRestored())
505 new_active_client = findClient( WindowMatchPredicate( client_info.activeWindow()));
507 if( new_active_client == NULL
508 && activeClient() == NULL && should_get_focus.count() == 0 )
510 if( new_active_client == NULL )
511 new_active_client = topClientOnDesktop( currentDesktop());
512 if( new_active_client == NULL && !desktops.isEmpty() )
513 new_active_client = findDesktop(
true, currentDesktop());
515 if( new_active_client != NULL )
516 activateClient( new_active_client );
520 workspaceInit =
false;
524 Workspace::~Workspace()
528 blockStackingUpdates(
true );
531 for( ClientList::ConstIterator it = stacking_order.begin();
532 it != stacking_order.end();
536 (*it)->releaseWindow(
true );
540 clients.remove( *it );
541 desktops.remove( *it );
543 delete desktop_widget;
547 if ( root == tqt_xrootwin() )
548 XDeleteProperty(tqt_xdisplay(), tqt_xrootwin(), atoms->twin_running);
551 TDEGlobal::config()->sync();
554 delete supportWindow;
559 delete initPositioning;
560 delete topmenu_watcher;
561 delete topmenu_selection;
562 delete topmenu_space;
563 delete client_keys_dialog;
564 while( !rules.isEmpty())
566 delete rules.front();
569 XDestroyWindow( tqt_xdisplay(), null_focus_window );
574 Client* Workspace::createClient( Window w,
bool is_mapped )
576 StackingUpdatesBlocker blocker(
this );
577 Client* c =
new Client(
this );
578 if( !c->manage( w, is_mapped ))
580 Client::deleteClient( c, Allowed );
583 addClient( c, Allowed );
587 void Workspace::addClient( Client* c, allowed_t )
591 c->setBMP(c->resourceName() ==
"beep-media-player" || c->decorationId() == None);
593 c->getWindowOpacity();
597 if (!c->hasCustomOpacity())
599 c->setShadowSize(options->dockShadowSize);
600 c->setOpacity(options->translucentDocks, options->dockOpacity);
604 if (c->isMenu() || c->isTopMenu())
606 c->setShadowSize(options->menuShadowSize);
609 Group* grp = findGroup( c->window());
613 if ( c->isDesktop() )
615 desktops.append( c );
616 if( active_client == NULL && should_get_focus.isEmpty() && c->isOnCurrentDesktop())
621 updateFocusChains( c, FocusChainUpdate );
624 if( !unconstrained_stacking_order.contains( c ))
625 unconstrained_stacking_order.append( c );
626 if( !stacking_order.contains( c ))
627 stacking_order.append( c );
631 updateClientLayer( c );
636 if( activeClient() == NULL && should_get_focus.count() == 0 )
637 activateClient( findDesktop(
true, currentDesktop()));
639 c->checkActiveModal();
640 checkTransients( c->window());
641 updateStackingOrder(
true );
642 if( c->isUtility() || c->isMenu() || c->isToolbar())
643 updateToolWindows(
true );
644 checkNonExistentClients();
650 void Workspace::removeClient( Client* c, allowed_t )
652 if (c == active_popup_client)
655 if( client_keys_client == c )
656 setupWindowShortcutDone(
false );
657 if( !c->shortcut().isNull())
658 c->setShortcut( TQString::null );
661 Notify::raise( Notify::TransDelete );
662 if( c->isNormalWindow())
663 Notify::raise( Notify::Delete );
665 Q_ASSERT( clients.contains( c ) || desktops.contains( c ));
667 desktops.remove( c );
668 unconstrained_stacking_order.remove( c );
669 stacking_order.remove( c );
671 i <= numberOfDesktops();
673 focus_chain[ i ].remove( c );
674 global_focus_chain.remove( c );
675 attention_chain.remove( c );
676 showing_desktop_clients.remove( c );
679 Group* group = findGroup( c->window());
683 if ( c == most_recently_raised )
684 most_recently_raised = 0;
685 should_get_focus.remove( c );
686 Q_ASSERT( c != active_client );
687 if ( c == last_active_client )
688 last_active_client = 0;
689 if( c == pending_take_activity )
690 pending_take_activity = NULL;
691 if( c == delayfocus_client )
694 updateStackingOrder(
true );
702 void Workspace::updateFocusChains( Client* c, FocusChainChange change )
704 if( !c->wantsTabFocus())
707 i<= numberOfDesktops();
709 focus_chain[i].remove(c);
710 global_focus_chain.remove( c );
713 if(c->desktop() == NET::OnAllDesktops)
715 for(
int i=1; i<= numberOfDesktops(); i++)
717 if( i == currentDesktop()
718 && ( change == FocusChainMakeFirst || change == FocusChainMakeLast ))
720 focus_chain[ i ].remove( c );
721 if( change == FocusChainMakeFirst )
722 focus_chain[ i ].append( c );
724 focus_chain[ i ].prepend( c );
726 else if( !focus_chain[ i ].contains( c ))
728 if( active_client != NULL && active_client != c
729 && !focus_chain[ i ].isEmpty() && focus_chain[ i ].last() == active_client )
730 focus_chain[ i ].insert( focus_chain[ i ].fromLast(), c );
732 focus_chain[ i ].append( c );
738 for(
int i=1; i<= numberOfDesktops(); i++)
740 if( i == c->desktop())
742 if( change == FocusChainMakeFirst )
744 focus_chain[ i ].remove( c );
745 focus_chain[ i ].append( c );
747 else if( change == FocusChainMakeLast )
749 focus_chain[ i ].remove( c );
750 focus_chain[ i ].prepend( c );
752 else if( !focus_chain[ i ].contains( c ))
754 if( active_client != NULL && active_client != c
755 && !focus_chain[ i ].isEmpty() && focus_chain[ i ].last() == active_client )
756 focus_chain[ i ].insert( focus_chain[ i ].fromLast(), c );
758 focus_chain[ i ].append( c );
762 focus_chain[ i ].remove( c );
765 if( change == FocusChainMakeFirst )
767 global_focus_chain.remove( c );
768 global_focus_chain.append( c );
770 else if( change == FocusChainMakeLast )
772 global_focus_chain.remove( c );
773 global_focus_chain.prepend( c );
775 else if( !global_focus_chain.contains( c ))
777 if( active_client != NULL && active_client != c
778 && !global_focus_chain.isEmpty() && global_focus_chain.last() == active_client )
779 global_focus_chain.insert( global_focus_chain.fromLast(), c );
781 global_focus_chain.append( c );
785 void Workspace::updateOverlappingShadows(
unsigned long window)
789 if ((client = findClient(WindowMatchPredicate((WId)window))))
792 client->drawOverlappingShadows(
false);
795 void Workspace::setShadowed(
unsigned long window,
bool shadowed)
799 if ((client = findClient(WindowMatchPredicate((WId)window))))
800 client->setShadowed(shadowed);
803 void Workspace::updateCurrentTopMenu()
805 if( !managingTopMenus())
809 bool block_desktop_menubar =
false;
813 Client* menu_client = active_client;
816 if( menu_client->isFullScreen())
817 block_desktop_menubar =
true;
818 for( ClientList::ConstIterator it = menu_client->transients().begin();
819 it != menu_client->transients().end();
821 if( (*it)->isTopMenu())
826 if( menubar != NULL || !menu_client->isTransient())
828 if( menu_client->isModal() || menu_client->transientFor() == NULL )
830 menu_client = menu_client->transientFor();
834 for( ClientList::ConstIterator it = active_client->group()->members().begin();
835 it != active_client->group()->members().end();
837 if( (*it)->isTopMenu())
844 if( !menubar && !block_desktop_menubar && options->desktopTopMenu())
847 Client* desktop = findDesktop(
true, currentDesktop());
848 if( desktop != NULL )
850 for( ClientList::ConstIterator it = desktop->transients().begin();
851 it != desktop->transients().end();
853 if( (*it)->isTopMenu())
862 if( menubar == NULL )
864 for( ClientList::ConstIterator it = topmenus.begin();
865 it != topmenus.end();
867 if( (*it)->wasOriginallyGroupTransient())
878 if( active_client && !menubar->isOnDesktop( active_client->desktop()))
879 menubar->setDesktop( active_client->desktop());
880 menubar->hideClient(
false );
881 topmenu_space->hide();
885 unconstrained_stacking_order.remove( menubar );
886 unconstrained_stacking_order.append( menubar );
888 else if( !block_desktop_menubar )
890 topmenu_space->show();
894 for ( ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it)
896 if( (*it)->isTopMenu() && (*it) != menubar )
897 (*it)->hideClient(
true );
902 void Workspace::updateToolWindows(
bool also_hide )
905 if( !options->hideUtilityWindowsForInactive )
907 for( ClientList::ConstIterator it = clients.begin();
910 (*it)->hideClient(
false );
913 const Group* group = NULL;
914 const Client* client = active_client;
917 while( client != NULL )
919 if( !client->isTransient())
921 if( client->groupTransient())
923 group = client->group();
926 client = client->transientFor();
932 ClientList to_show, to_hide;
933 for( ClientList::ConstIterator it = stacking_order.begin();
934 it != stacking_order.end();
937 if( (*it)->isUtility() || (*it)->isMenu() || (*it)->isToolbar())
940 if( !(*it)->isTransient())
942 if( (*it)->group()->members().count() == 1 )
944 else if( client != NULL && (*it)->group() == client->group())
951 if( group != NULL && (*it)->group() == group )
953 else if( client != NULL && client->hasTransient( (*it),
true ))
958 if( !show && also_hide )
960 const ClientList mainclients = (*it)->mainClients();
963 if( mainclients.isEmpty())
965 for( ClientList::ConstIterator it2 = mainclients.begin();
966 it2 != mainclients.end();
969 if( (*it2)->isSpecialWindow())
973 to_hide.append( *it );
976 to_show.append( *it );
979 for( ClientList::ConstIterator it = to_show.fromLast();
983 (*it)->hideClient(
false );
986 for( ClientList::ConstIterator it = to_hide.begin();
989 (*it)->hideClient(
true );
990 updateToolWindowsTimer.stop();
994 updateToolWindowsTimer.start( 50,
true );
998 void Workspace::slotUpdateToolWindows()
1000 updateToolWindows(
true );
1006 void Workspace::updateColormap()
1008 Colormap cmap = default_colormap;
1009 if ( activeClient() && activeClient()->colormap() != None )
1010 cmap = activeClient()->colormap();
1011 if ( cmap != installed_colormap )
1013 XInstallColormap(tqt_xdisplay(), cmap );
1014 installed_colormap = cmap;
1018 void Workspace::reconfigure()
1020 reconfigureTimer.start(200,
true);
1024 void Workspace::slotSettingsChanged(
int category)
1026 kdDebug(1212) <<
"Workspace::slotSettingsChanged()" << endl;
1027 if( category == (
int) TDEApplication::SETTINGS_SHORTCUTS )
1034 KWIN_PROCEDURE( CheckBorderSizesProcedure, cl->checkBorderSizes() );
1036 void Workspace::slotReconfigure()
1038 kdDebug(1212) <<
"Workspace::slotReconfigure()" << endl;
1039 reconfigureTimer.stop();
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 checkElectricBorders();
1073 if( options->topMenuEnabled() && !managingTopMenus())
1075 if( topmenu_selection->claim(
false ))
1076 setupTopMenuHandling();
1078 lostTopMenuSelection();
1080 else if( !options->topMenuEnabled() && managingTopMenus())
1082 topmenu_selection->release();
1083 lostTopMenuSelection();
1086 if( managingTopMenus())
1088 updateTopMenuGeometry();
1089 updateCurrentTopMenu();
1093 for( ClientList::Iterator it = clients.begin();
1094 it != clients.end();
1097 (*it)->setupWindowRules(
true );
1098 (*it)->applyWindowRules();
1099 discardUsedWindowRules( *it,
false );
1102 if (options->resetKompmgr)
1104 bool tmp = options->useTranslucency;
1109 const char *pidfile =
"compton-tde.pid";
1110 char uidstr[
sizeof(uid_t)*8+1];
1111 sprintf(uidstr,
"%d", getuid());
1112 int n = strlen(P_tmpdir)+strlen(uidstr)+strlen(pidfile)+3;
1113 filename = (
char*)malloc(n*
sizeof(
char)+1);
1114 memset(filename,0,n);
1115 strcat(filename, P_tmpdir);
1116 strcat(filename,
"/.");
1117 strcat(filename, uidstr);
1118 strcat(filename,
"-");
1119 strcat(filename, pidfile);
1124 pFile = fopen(filename,
"r");
1128 printf(
"[twin-workspace] Using '%s' as compton-tde pidfile\n\n", filename);
1130 fseek (pFile , 0 , SEEK_END);
1131 unsigned long lSize = ftell (pFile);
1135 size_t result = fread (buffer, 1, lSize, pFile);
1139 kompmgrpid = atoi(buffer);
1150 kill(kompmgrpid, SIGUSR2);
1157 kompmgr =
new TDEProcess;
1158 connect(kompmgr, TQT_SIGNAL(receivedStderr(TDEProcess*,
char*,
int)), TQT_SLOT(handleKompmgrOutput(TDEProcess*,
char*,
int)));
1159 *kompmgr << TDE_COMPOSITOR_BINARY;
1161 TQTimer::singleShot( 200,
this, TQT_SLOT(startKompmgr()) );
1168 kill(kompmgrpid, SIGTERM);
1178 void Workspace::loadDesktopSettings()
1180 TDEConfig* c = TDEGlobal::config();
1181 TQCString groupname;
1182 if (screen_number == 0)
1183 groupname =
"Desktops";
1185 groupname.sprintf(
"Desktops-screen-%d", screen_number);
1186 TDEConfigGroupSaver saver(c,groupname);
1188 int n = c->readNumEntry(
"Number", 4);
1189 number_of_desktops = n;
1191 workarea =
new TQRect[ n + 1 ];
1194 rootInfo->setNumberOfDesktops( number_of_desktops );
1195 desktop_focus_chain.resize( n );
1197 focus_chain.resize( n + 1 );
1198 for(
int i = 1; i <= n; i++)
1200 TQString s = c->readEntry(TQString(
"Name_%1").arg(i),
1201 i18n(
"Desktop %1").arg(i));
1202 rootInfo->setDesktopName( i, s.utf8().data() );
1203 desktop_focus_chain[i-1] = i;
1207 void Workspace::saveDesktopSettings()
1209 TDEConfig* c = TDEGlobal::config();
1210 TQCString groupname;
1211 if (screen_number == 0)
1212 groupname =
"Desktops";
1214 groupname.sprintf(
"Desktops-screen-%d", screen_number);
1215 TDEConfigGroupSaver saver(c,groupname);
1217 c->writeEntry(
"Number", number_of_desktops );
1218 for(
int i = 1; i <= number_of_desktops; i++)
1220 TQString s = desktopName( i );
1221 TQString defaultvalue = i18n(
"Desktop %1").arg(i);
1225 rootInfo->setDesktopName( i, s.utf8().data() );
1228 if (s != defaultvalue)
1230 c->writeEntry( TQString(
"Name_%1").arg(i), s );
1234 TQString currentvalue = c->readEntry(TQString(
"Name_%1").arg(i));
1235 if (currentvalue != defaultvalue)
1236 c->writeEntry( TQString(
"Name_%1").arg(i),
"" );
1241 TQStringList Workspace::configModules(
bool controlCenter)
1244 args <<
"tde-twindecoration.desktop";
1246 args <<
"tde-twinoptions.desktop";
1247 else if (kapp->authorizeControlModule(
"tde-twinoptions.desktop"))
1248 args <<
"twinactions" <<
"twinfocus" <<
"twinmoving" <<
"twinadvanced" <<
"twinrules" <<
"twintranslucency";
1252 void Workspace::configureWM()
1254 TDEApplication::tdeinitExec(
"tdecmshell", configModules(
false) );
1260 void Workspace::doNotManage( TQString title )
1262 doNotManageList.append( title );
1268 bool Workspace::isNotManaged(
const TQString& title )
1270 for ( TQStringList::Iterator it = doNotManageList.begin(); it != doNotManageList.end(); ++it )
1272 TQRegExp r( (*it) );
1273 if (r.search(title) != -1)
1275 doNotManageList.remove( it );
1285 void Workspace::refresh()
1288 w.setGeometry( TQApplication::desktop()->geometry() );
1291 TQApplication::flushX();
1301 class ObscuringWindows
1304 ~ObscuringWindows();
1305 void create( Client* c );
1307 TQValueList<Window> obscuring_windows;
1308 static TQValueList<Window>* cached;
1309 static unsigned int max_cache_size;
1312 TQValueList<Window>* ObscuringWindows::cached = 0;
1313 unsigned int ObscuringWindows::max_cache_size = 0;
1315 void ObscuringWindows::create( Client* c )
1318 cached =
new TQValueList<Window>;
1320 XWindowChanges chngs;
1321 int mask = CWSibling | CWStackMode;
1322 if( cached->count() > 0 )
1324 cached->remove( obs_win = cached->first());
1327 chngs.width = c->width();
1328 chngs.height = c->height();
1329 mask |= CWX | CWY | CWWidth | CWHeight;
1333 XSetWindowAttributes a;
1334 a.background_pixmap = None;
1335 a.override_redirect = True;
1336 obs_win = XCreateWindow( tqt_xdisplay(), tqt_xrootwin(), c->x(), c->y(),
1337 c->width(), c->height(), 0, CopyFromParent, InputOutput,
1338 CopyFromParent, CWBackPixmap | CWOverrideRedirect, &a );
1340 chngs.sibling = c->frameId();
1341 chngs.stack_mode = Below;
1342 XConfigureWindow( tqt_xdisplay(), obs_win, mask, &chngs );
1343 XMapWindow( tqt_xdisplay(), obs_win );
1344 obscuring_windows.append( obs_win );
1347 ObscuringWindows::~ObscuringWindows()
1349 max_cache_size = TQMAX( max_cache_size, obscuring_windows.count() + 4 ) - 1;
1350 for( TQValueList<Window>::ConstIterator it = obscuring_windows.begin();
1351 it != obscuring_windows.end();
1354 XUnmapWindow( tqt_xdisplay(), *it );
1355 if( cached->count() < max_cache_size )
1356 cached->prepend( *it );
1358 XDestroyWindow( tqt_xdisplay(), *it );
1369 bool Workspace::setCurrentDesktop(
int new_desktop )
1371 if (new_desktop < 1 || new_desktop > number_of_desktops )
1377 StackingUpdatesBlocker blocker(
this );
1379 int old_desktop = current_desktop;
1380 if (new_desktop != current_desktop)
1382 ++block_showing_desktop;
1387 Notify::raise((Notify::Event) (Notify::DesktopChange+new_desktop));
1389 ObscuringWindows obs_wins;
1391 current_desktop = new_desktop;
1393 bool desktopHasCompositing = kapp->isCompositionManagerAvailable();
1394 if (!desktopHasCompositing) {
1396 for ( ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it) {
1397 if ( !(*it)->isOnDesktop( new_desktop ) && (*it) != movingClient )
1399 if( (*it)->isShown(
true ) && (*it)->isOnDesktop( old_desktop )) {
1400 obs_wins.create( *it );
1402 (*it)->updateVisibility();
1407 rootInfo->setCurrentDesktop( current_desktop );
1409 if( movingClient && !movingClient->isOnDesktop( new_desktop ))
1410 movingClient->setDesktop( new_desktop );
1412 for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it) {
1413 if ( (*it)->isOnDesktop( new_desktop ) ) {
1414 (*it)->updateVisibility();
1418 if (desktopHasCompositing) {
1421 XSync( tqt_xdisplay(),
false);
1422 for ( ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it) {
1423 if ( !(*it)->isOnDesktop( new_desktop ) && (*it) != movingClient )
1425 if( (*it)->isShown(
true ) && (*it)->isOnDesktop( old_desktop )) {
1426 obs_wins.create( *it );
1428 (*it)->updateVisibility();
1433 --block_showing_desktop;
1434 if( showingDesktop())
1435 resetShowingDesktop(
false );
1442 if ( options->focusPolicyIsReasonable())
1445 if ( movingClient != NULL && active_client == movingClient
1446 && focus_chain[currentDesktop()].contains( active_client )
1447 && active_client->isShown(
true ) && active_client->isOnCurrentDesktop())
1453 for( ClientList::ConstIterator it = focus_chain[currentDesktop()].fromLast();
1454 it != focus_chain[currentDesktop()].end();
1457 if ( (*it)->isShown(
false ) && (*it)->isOnCurrentDesktop())
1469 else if( active_client && active_client->isShown(
true ) && active_client->isOnCurrentDesktop())
1472 if( c == NULL && !desktops.isEmpty())
1473 c = findDesktop(
true, currentDesktop());
1475 if( c != active_client )
1476 setActiveClient( NULL, Allowed );
1483 updateCurrentTopMenu();
1490 for(
int i = desktop_focus_chain.find( currentDesktop() ); i > 0; i-- )
1491 desktop_focus_chain[i] = desktop_focus_chain[i-1];
1492 desktop_focus_chain[0] = currentDesktop();
1499 if( old_desktop != 0 )
1500 popupinfo->showInfo( desktopName(currentDesktop()) );
1505 void Workspace::nextDesktop()
1507 int desktop = currentDesktop() + 1;
1508 setCurrentDesktop(desktop > numberOfDesktops() ? 1 : desktop);
1512 void Workspace::previousDesktop()
1514 int desktop = currentDesktop() - 1;
1515 setCurrentDesktop(desktop > 0 ? desktop : numberOfDesktops());
1518 int Workspace::desktopToRight(
int desktop )
const
1521 calcDesktopLayout(x,y);
1523 if (layoutOrientation == Qt::Vertical)
1526 if ( dt >= numberOfDesktops() )
1528 if ( options->rollOverDesktops )
1529 dt -= numberOfDesktops();
1536 int d = (dt % x) + 1;
1539 if ( options->rollOverDesktops )
1544 dt = dt - (dt % x) + d;
1549 int Workspace::desktopToLeft(
int desktop )
const
1552 calcDesktopLayout(x,y);
1554 if (layoutOrientation == Qt::Vertical)
1559 if ( options->rollOverDesktops )
1560 dt += numberOfDesktops();
1567 int d = (dt % x) - 1;
1570 if ( options->rollOverDesktops )
1575 dt = dt - (dt % x) + d;
1580 int Workspace::desktopUp(
int desktop )
const
1583 calcDesktopLayout(x,y);
1585 if (layoutOrientation == Qt::Horizontal)
1590 if ( options->rollOverDesktops )
1591 dt += numberOfDesktops();
1598 int d = (dt % y) - 1;
1601 if ( options->rollOverDesktops )
1606 dt = dt - (dt % y) + d;
1611 int Workspace::desktopDown(
int desktop )
const
1614 calcDesktopLayout(x,y);
1616 if (layoutOrientation == Qt::Horizontal)
1619 if ( dt >= numberOfDesktops() )
1621 if ( options->rollOverDesktops )
1622 dt -= numberOfDesktops();
1629 int d = (dt % y) + 1;
1632 if ( options->rollOverDesktops )
1637 dt = dt - (dt % y) + d;
1646 void Workspace::setNumberOfDesktops(
int n )
1648 if ( n == number_of_desktops )
1650 int old_number_of_desktops = number_of_desktops;
1651 number_of_desktops = n;
1653 if( currentDesktop() > numberOfDesktops())
1654 setCurrentDesktop( numberOfDesktops());
1658 if( old_number_of_desktops < number_of_desktops )
1660 rootInfo->setNumberOfDesktops( number_of_desktops );
1661 NETPoint* viewports =
new NETPoint[ number_of_desktops ];
1662 rootInfo->setDesktopViewport( number_of_desktops, *viewports );
1664 updateClientArea(
true );
1665 focus_chain.resize( number_of_desktops + 1 );
1670 if( old_number_of_desktops > number_of_desktops )
1672 for( ClientList::ConstIterator it = clients.begin();
1673 it != clients.end();
1676 if( !(*it)->isOnAllDesktops() && (*it)->desktop() > numberOfDesktops())
1677 sendClientToDesktop( *it, numberOfDesktops(),
true );
1680 if( old_number_of_desktops > number_of_desktops )
1682 rootInfo->setNumberOfDesktops( number_of_desktops );
1683 NETPoint* viewports =
new NETPoint[ number_of_desktops ];
1684 rootInfo->setDesktopViewport( number_of_desktops, *viewports );
1686 updateClientArea(
true );
1687 focus_chain.resize( number_of_desktops + 1 );
1690 saveDesktopSettings();
1693 desktop_focus_chain.resize( n );
1694 for(
int i = 0; i < (int)desktop_focus_chain.size(); i++ )
1695 desktop_focus_chain[i] = i+1;
1703 void Workspace::sendClientToDesktop( Client* c,
int desk,
bool dont_activate )
1705 bool was_on_desktop = c->isOnDesktop( desk ) || c->isOnAllDesktops();
1706 c->setDesktop( desk );
1707 if ( c->desktop() != desk )
1709 desk = c->desktop();
1711 if ( c->isOnDesktop( currentDesktop() ) )
1713 if ( c->wantsTabFocus() && options->focusPolicyIsReasonable()
1718 restackClientUnderActive( c );
1725 ClientList transients_stacking_order = ensureStackingOrder( c->transients());
1726 for( ClientList::ConstIterator it = transients_stacking_order.begin();
1727 it != transients_stacking_order.end();
1729 sendClientToDesktop( *it, desk, dont_activate );
1733 int Workspace::numScreens()
const
1735 if( !options->xineramaEnabled )
1737 return tqApp->desktop()->numScreens();
1740 int Workspace::activeScreen()
const
1742 if( !options->xineramaEnabled )
1744 if( !options->activeMouseScreen )
1746 if( activeClient() != NULL && !activeClient()->isOnScreen( active_screen ))
1747 return tqApp->desktop()->screenNumber( activeClient()->geometry().center());
1748 return active_screen;
1750 return tqApp->desktop()->screenNumber( TQCursor::pos());
1755 void Workspace::checkActiveScreen(
const Client* c )
1757 if( !options->xineramaEnabled )
1761 if( !c->isOnScreen( active_screen ))
1762 active_screen = c->screen();
1767 void Workspace::setActiveScreenMouse( TQPoint mousepos )
1769 if( !options->xineramaEnabled )
1771 active_screen = tqApp->desktop()->screenNumber( mousepos );
1774 TQRect Workspace::screenGeometry(
int screen )
const
1776 if (( !options->xineramaEnabled ) || (kapp->desktop()->numScreens() < 2))
1777 return tqApp->desktop()->geometry();
1778 return tqApp->desktop()->screenGeometry( screen );
1781 int Workspace::screenNumber( TQPoint pos )
const
1783 if( !options->xineramaEnabled )
1785 return tqApp->desktop()->screenNumber( pos );
1788 void Workspace::sendClientToScreen( Client* c,
int screen )
1790 if( c->screen() == screen )
1792 GeometryUpdatesPostponer blocker( c );
1793 TQRect old_sarea = clientArea( MaximizeArea, c );
1794 TQRect sarea = clientArea( MaximizeArea, screen, c->desktop());
1795 c->setGeometry( sarea.x() - old_sarea.x() + c->x(), sarea.y() - old_sarea.y() + c->y(),
1796 c->size().width(), c->size().height());
1797 c->checkWorkspacePosition();
1798 ClientList transients_stacking_order = ensureStackingOrder( c->transients());
1799 for( ClientList::ConstIterator it = transients_stacking_order.begin();
1800 it != transients_stacking_order.end();
1802 sendClientToScreen( *it, screen );
1804 active_screen = screen;
1808 void Workspace::setDesktopLayout(
int,
int,
int )
1812 void Workspace::updateDesktopLayout()
1815 layoutOrientation = ( rootInfo->desktopLayoutOrientation() == NET::OrientationHorizontal
1816 ? Qt::Horizontal : Qt::Vertical );
1817 layoutX = rootInfo->desktopLayoutColumnsRows().width();
1818 layoutY = rootInfo->desktopLayoutColumnsRows().height();
1819 if( layoutX == 0 && layoutY == 0 )
1823 void Workspace::calcDesktopLayout(
int &x,
int &y)
const
1827 if((x <= 0) && (y > 0))
1828 x = (numberOfDesktops()+y-1) / y;
1829 else if((y <=0) && (x > 0))
1830 y = (numberOfDesktops()+x-1) / x;
1842 bool Workspace::addSystemTrayWin( WId w )
1844 if ( systemTrayWins.contains( w ) )
1847 NETWinInfo ni( tqt_xdisplay(), w, root, NET::WMKDESystemTrayWinFor );
1848 WId trayWinFor = ni.kdeSystemTrayWinFor();
1851 systemTrayWins.append( SystemTrayWindow( w, trayWinFor ) );
1852 XSelectInput( tqt_xdisplay(), w,
1855 XAddToSaveSet( tqt_xdisplay(), w );
1856 propagateSystemTrayWins();
1864 bool Workspace::removeSystemTrayWin( WId w,
bool check )
1866 if ( !systemTrayWins.contains( w ) )
1878 Atom* props = XListProperties( tqt_xdisplay(), w, &num_props );
1884 if( props[ i ] == atoms->kde_system_tray_embedding )
1892 systemTrayWins.remove( w );
1893 XRemoveFromSaveSet (tqt_xdisplay (), w);
1894 propagateSystemTrayWins();
1902 void Workspace::propagateSystemTrayWins()
1904 Window *cl =
new Window[ systemTrayWins.count()];
1907 for ( SystemTrayWindowList::ConstIterator it = systemTrayWins.begin(); it != systemTrayWins.end(); ++it )
1909 cl[i++] = (*it).win;
1912 rootInfo->setKDESystemTrayWindows( cl, i );
1917 void Workspace::killWindowId( Window window_to_kill )
1919 if( window_to_kill == None )
1921 Window window = window_to_kill;
1922 Client* client = NULL;
1925 client = findClient( FrameIdMatchPredicate( window ));
1926 if( client != NULL )
1930 Window* children = 0L;
1931 unsigned int children_count;
1932 XQueryTree( tqt_xdisplay(), window, &root, &parent, &children, &children_count );
1933 if( children != NULL )
1935 if( window == root )
1941 if( client != NULL )
1942 client->killWindow();
1944 XKillClient( tqt_xdisplay(), window_to_kill );
1947 void Workspace::suspendWindowId( Window window_to_suspend )
1949 if( window_to_suspend == None )
1951 Window window = window_to_suspend;
1952 Client* client = NULL;
1955 client = findClient( FrameIdMatchPredicate( window ));
1956 if( client != NULL )
1960 Window* children = 0L;
1961 unsigned int children_count;
1962 XQueryTree( tqt_xdisplay(), window, &root, &parent, &children, &children_count );
1963 if( children != NULL )
1965 if( window == root )
1971 if( client != NULL )
1972 client->suspendWindow();
1977 void Workspace::resumeWindowId( Window window_to_resume )
1979 if( window_to_resume == None )
1981 Window window = window_to_resume;
1982 Client* client = NULL;
1985 client = findClient( FrameIdMatchPredicate( window ));
1986 if( client != NULL )
1990 Window* children = 0L;
1991 unsigned int children_count;
1992 XQueryTree( tqt_xdisplay(), window, &root, &parent, &children, &children_count );
1993 if( children != NULL )
1995 if( window == root )
2001 if( client != NULL )
2002 client->resumeWindow();
2008 bool Workspace::isResumeableWindowID( Window window_to_check )
2010 if( window_to_check == None )
2012 Window window = window_to_check;
2013 Client* client = NULL;
2016 client = findClient( FrameIdMatchPredicate( window ));
2017 if( client != NULL )
2021 Window* children = 0L;
2022 unsigned int children_count;
2023 XQueryTree( tqt_xdisplay(), window, &root, &parent, &children, &children_count );
2024 if( children != NULL )
2026 if( window == root )
2032 if( client != NULL )
2033 return client->isResumeable();
2039 void Workspace::sendPingToWindow( Window window, Time timestamp )
2041 rootInfo->sendPing( window, timestamp );
2044 void Workspace::sendTakeActivity( Client* c, Time timestamp,
long flags )
2046 rootInfo->takeActivity( c->window(), timestamp, flags );
2047 pending_take_activity = c;
2054 void Workspace::slotGrabWindow()
2056 if ( active_client )
2058 TQPixmap snapshot = TQPixmap::grabWindow( active_client->frameId() );
2061 if( Shape::available())
2065 XRectangle* rects = XShapeGetRectangles( tqt_xdisplay(), active_client->frameId(),
2066 ShapeBounding, &count, &order);
2075 for (
int pos = 0; pos < count; pos++)
2076 contents += TQRegion(rects[pos].x, rects[pos].y,
2077 rects[pos].width, rects[pos].height);
2081 TQRegion bbox(0, 0, snapshot.width(), snapshot.height());
2084 TQRegion maskedAway = bbox - contents;
2085 TQMemArray<TQRect> maskedAwayRects = maskedAway.rects();
2088 TQBitmap mask( snapshot.width(), snapshot.height());
2090 p.fillRect(0, 0, mask.width(), mask.height(), Qt::color1);
2091 for (uint pos = 0; pos < maskedAwayRects.count(); pos++)
2092 p.fillRect(maskedAwayRects[pos], Qt::color0);
2094 snapshot.setMask(mask);
2098 TQClipboard *cb = TQApplication::clipboard();
2099 cb->setPixmap( snapshot );
2108 void Workspace::slotGrabDesktop()
2110 TQPixmap p = TQPixmap::grabWindow( tqt_xrootwin() );
2111 TQClipboard *cb = TQApplication::clipboard();
2119 void Workspace::slotMouseEmulation()
2122 if ( mouse_emulation )
2124 XUngrabKeyboard(tqt_xdisplay(), GET_QT_X_TIME());
2125 mouse_emulation = FALSE;
2129 if ( XGrabKeyboard(tqt_xdisplay(),
2131 GrabModeAsync, GrabModeAsync,
2132 GET_QT_X_TIME()) == GrabSuccess )
2134 mouse_emulation = TRUE;
2135 mouse_emulation_state = 0;
2136 mouse_emulation_window = 0;
2146 WId Workspace::getMouseEmulationWindow()
2149 Window child = tqt_xrootwin();
2150 int root_x, root_y, lx, ly;
2158 c = findClient( FrameIdMatchPredicate( w ));
2159 XQueryPointer( tqt_xdisplay(), w, &root, &child,
2160 &root_x, &root_y, &lx, &ly, &state );
2161 }
while ( child != None && child != w );
2163 if ( c && !c->isActive() )
2164 activateClient( c );
2171 unsigned int Workspace::sendFakedMouseEvent( TQPoint pos, WId w, MouseEmulation type,
int button,
unsigned int state )
2175 TQWidget* widget = TQWidget::find( w );
2176 if ( (!widget || widget->inherits(TQTOOLBUTTON_OBJECT_NAME_STRING) ) && !findClient( WindowMatchPredicate( w )) )
2180 XTranslateCoordinates( tqt_xdisplay(), tqt_xrootwin(), w, pos.x(), pos.y(), &x, &y, &xw );
2181 if ( type == EmuMove )
2184 e.type = MotionNotify;
2185 e.xmotion.window = w;
2186 e.xmotion.root = tqt_xrootwin();
2187 e.xmotion.subwindow = w;
2188 e.xmotion.time = GET_QT_X_TIME();
2191 e.xmotion.x_root = pos.x();
2192 e.xmotion.y_root = pos.y();
2193 e.xmotion.state = state;
2194 e.xmotion.is_hint = NotifyNormal;
2195 XSendEvent( tqt_xdisplay(), w, TRUE, ButtonMotionMask, &e );
2200 e.type = type == EmuRelease ? ButtonRelease : ButtonPress;
2201 e.xbutton.window = w;
2202 e.xbutton.root = tqt_xrootwin();
2203 e.xbutton.subwindow = w;
2204 e.xbutton.time = GET_QT_X_TIME();
2207 e.xbutton.x_root = pos.x();
2208 e.xbutton.y_root = pos.y();
2209 e.xbutton.state = state;
2210 e.xbutton.button = button;
2211 XSendEvent( tqt_xdisplay(), w, TRUE, ButtonPressMask, &e );
2213 if ( type == EmuPress )
2218 state |= Button2Mask;
2221 state |= Button3Mask;
2224 state |= Button1Mask;
2233 state &= ~Button2Mask;
2236 state &= ~Button3Mask;
2239 state &= ~Button1Mask;
2251 bool Workspace::keyPressMouseEmulation( XKeyEvent& ev )
2253 if ( root != tqt_xrootwin() )
2255 int kc = XkbKeycodeToKeysym(tqt_xdisplay(), ev.keycode, 0, 0);
2256 int km = ev.state & (ControlMask | Mod1Mask | ShiftMask);
2258 bool is_control = km & ControlMask;
2259 bool is_alt = km & Mod1Mask;
2260 bool is_shift = km & ShiftMask;
2261 int delta = is_control?1:is_alt?32:8;
2262 TQPoint pos = TQCursor::pos();
2283 if ( !mouse_emulation_state )
2284 mouse_emulation_window = getMouseEmulationWindow();
2285 if ( (mouse_emulation_state & Button1Mask) == 0 )
2286 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuPress, Button1, mouse_emulation_state );
2288 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button1, mouse_emulation_state );
2291 if ( !mouse_emulation_state )
2292 mouse_emulation_window = getMouseEmulationWindow();
2293 if ( (mouse_emulation_state & Button2Mask) == 0 )
2294 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuPress, Button2, mouse_emulation_state );
2296 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button2, mouse_emulation_state );
2299 if ( !mouse_emulation_state )
2300 mouse_emulation_window = getMouseEmulationWindow();
2301 if ( (mouse_emulation_state & Button3Mask) == 0 )
2302 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuPress, Button3, mouse_emulation_state );
2304 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button3, mouse_emulation_state );
2311 if ( !mouse_emulation_state )
2314 mouse_emulation_window = getMouseEmulationWindow();
2315 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuPress, Button1, mouse_emulation_state );
2316 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button1, mouse_emulation_state );
2320 if ( mouse_emulation_state & Button1Mask )
2321 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button1, mouse_emulation_state );
2322 if ( mouse_emulation_state & Button2Mask )
2323 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button2, mouse_emulation_state );
2324 if ( mouse_emulation_state & Button3Mask )
2325 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button3, mouse_emulation_state );
2330 XUngrabKeyboard(tqt_xdisplay(), GET_QT_X_TIME());
2331 mouse_emulation = FALSE;
2337 TQCursor::setPos( pos );
2338 if ( mouse_emulation_state )
2339 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuMove, 0, mouse_emulation_state );
2349 TQWidget* Workspace::desktopWidget()
2351 return desktop_widget;
2355 void Workspace::delayFocus()
2357 requestFocus( delayfocus_client );
2361 void Workspace::requestDelayFocus( Client* c )
2363 delayfocus_client = c;
2364 delete delayFocusTimer;
2365 delayFocusTimer =
new TQTimer(
this );
2366 connect( delayFocusTimer, TQT_SIGNAL( timeout() ),
this, TQT_SLOT( delayFocus() ) );
2367 delayFocusTimer->start( options->delayFocusInterval, TRUE );
2370 void Workspace::cancelDelayFocus()
2372 delete delayFocusTimer;
2373 delayFocusTimer = 0;
2383 void Workspace::checkElectricBorders(
bool force )
2386 destroyBorderWindows();
2388 electric_current_border = 0;
2390 TQRect r = TQApplication::desktop()->geometry();
2391 electricTop = r.top();
2392 electricBottom = r.bottom();
2393 electricLeft = r.left();
2394 electricRight = r.right();
2396 if (options->electricBorders() == Options::ElectricAlways)
2397 createBorderWindows();
2399 destroyBorderWindows();
2402 void Workspace::createBorderWindows()
2404 if ( electric_have_borders )
2407 electric_have_borders =
true;
2409 TQRect r = TQApplication::desktop()->geometry();
2410 XSetWindowAttributes attributes;
2411 unsigned long valuemask;
2412 attributes.override_redirect = True;
2413 attributes.event_mask = ( EnterWindowMask | LeaveWindowMask );
2414 valuemask= (CWOverrideRedirect | CWEventMask | CWCursor );
2415 attributes.cursor = XCreateFontCursor(tqt_xdisplay(),
2417 electric_top_border = XCreateWindow (tqt_xdisplay(), tqt_xrootwin(),
2421 CopyFromParent, InputOnly,
2423 valuemask, &attributes);
2424 XMapWindow(tqt_xdisplay(), electric_top_border);
2426 attributes.cursor = XCreateFontCursor(tqt_xdisplay(),
2428 electric_bottom_border = XCreateWindow (tqt_xdisplay(), tqt_xrootwin(),
2432 CopyFromParent, InputOnly,
2434 valuemask, &attributes);
2435 XMapWindow(tqt_xdisplay(), electric_bottom_border);
2437 attributes.cursor = XCreateFontCursor(tqt_xdisplay(),
2439 electric_left_border = XCreateWindow (tqt_xdisplay(), tqt_xrootwin(),
2443 CopyFromParent, InputOnly,
2445 valuemask, &attributes);
2446 XMapWindow(tqt_xdisplay(), electric_left_border);
2448 attributes.cursor = XCreateFontCursor(tqt_xdisplay(),
2450 electric_right_border = XCreateWindow (tqt_xdisplay(), tqt_xrootwin(),
2454 CopyFromParent, InputOnly,
2456 valuemask, &attributes);
2457 XMapWindow(tqt_xdisplay(), electric_right_border);
2460 XChangeProperty( tqt_xdisplay(), electric_top_border, atoms->xdnd_aware, XA_ATOM,
2461 32, PropModeReplace, (
unsigned char* )&version, 1 );
2462 XChangeProperty( tqt_xdisplay(), electric_bottom_border, atoms->xdnd_aware, XA_ATOM,
2463 32, PropModeReplace, (
unsigned char* )&version, 1 );
2464 XChangeProperty( tqt_xdisplay(), electric_left_border, atoms->xdnd_aware, XA_ATOM,
2465 32, PropModeReplace, (
unsigned char* )&version, 1 );
2466 XChangeProperty( tqt_xdisplay(), electric_right_border, atoms->xdnd_aware, XA_ATOM,
2467 32, PropModeReplace, (
unsigned char* )&version, 1 );
2476 void Workspace::destroyBorderWindows()
2478 if( !electric_have_borders)
2481 electric_have_borders =
false;
2483 if(electric_top_border)
2484 XDestroyWindow(tqt_xdisplay(),electric_top_border);
2485 if(electric_bottom_border)
2486 XDestroyWindow(tqt_xdisplay(),electric_bottom_border);
2487 if(electric_left_border)
2488 XDestroyWindow(tqt_xdisplay(),electric_left_border);
2489 if(electric_right_border)
2490 XDestroyWindow(tqt_xdisplay(),electric_right_border);
2492 electric_top_border = None;
2493 electric_bottom_border = None;
2494 electric_left_border = None;
2495 electric_right_border = None;
2498 void Workspace::clientMoved(
const TQPoint &pos, Time now)
2500 if (options->electricBorders() == Options::ElectricDisabled)
2503 if ((pos.x() != electricLeft) &&
2504 (pos.x() != electricRight) &&
2505 (pos.y() != electricTop) &&
2506 (pos.y() != electricBottom))
2509 Time treshold_set = options->electricBorderDelay();
2510 Time treshold_reset = 250;
2511 int distance_reset = 30;
2514 if (pos.x() == electricLeft)
2516 else if (pos.x() == electricRight)
2518 else if (pos.y() == electricTop)
2520 else if (pos.y() == electricBottom)
2523 if ((electric_current_border == border) &&
2524 (timestampDiff(electric_time_last, now) < treshold_reset) &&
2525 ((pos-electric_push_point).manhattanLength() < distance_reset))
2527 electric_time_last = now;
2529 if (timestampDiff(electric_time_first, now) > treshold_set)
2531 electric_current_border = 0;
2533 TQRect r = TQApplication::desktop()->geometry();
2536 int desk_before = currentDesktop();
2540 slotSwitchDesktopLeft();
2541 if (currentDesktop() != desk_before)
2543 offset = r.width() / 5;
2544 TQCursor::setPos(r.width() - offset, pos.y());
2549 slotSwitchDesktopRight();
2550 if (currentDesktop() != desk_before)
2552 offset = r.width() / 5;
2553 TQCursor::setPos(offset, pos.y());
2558 slotSwitchDesktopUp();
2559 if (currentDesktop() != desk_before)
2561 offset = r.height() / 5;
2562 TQCursor::setPos(pos.x(), r.height() - offset);
2567 slotSwitchDesktopDown();
2568 if (currentDesktop() != desk_before)
2570 offset = r.height() / 5;
2571 TQCursor::setPos(pos.x(), offset);
2580 electric_current_border = border;
2581 electric_time_first = now;
2582 electric_time_last = now;
2583 electric_push_point = pos;
2591 case 1: TQCursor::setPos(pos.x()+mouse_warp, pos.y());
break;
2592 case 2: TQCursor::setPos(pos.x()-mouse_warp, pos.y());
break;
2593 case 3: TQCursor::setPos(pos.x(), pos.y()+mouse_warp);
break;
2594 case 4: TQCursor::setPos(pos.x(), pos.y()-mouse_warp);
break;
2600 bool Workspace::electricBorder(XEvent *e)
2602 if( !electric_have_borders )
2604 if( e->type == EnterNotify )
2606 if( e->xcrossing.window == electric_top_border ||
2607 e->xcrossing.window == electric_left_border ||
2608 e->xcrossing.window == electric_bottom_border ||
2609 e->xcrossing.window == electric_right_border)
2612 clientMoved( TQPoint( e->xcrossing.x_root, e->xcrossing.y_root ), e->xcrossing.time );
2616 if( e->type == ClientMessage )
2618 if( e->xclient.message_type == atoms->xdnd_position
2619 && ( e->xclient.window == electric_top_border
2620 || e->xclient.window == electric_bottom_border
2621 || e->xclient.window == electric_left_border
2622 || e->xclient.window == electric_right_border ))
2625 clientMoved( TQPoint( e->xclient.data.l[2]>>16, e->xclient.data.l[2]&0xffff), GET_QT_X_TIME() );
2635 void Workspace::raiseElectricBorders()
2638 if(electric_have_borders)
2640 XRaiseWindow(tqt_xdisplay(), electric_top_border);
2641 XRaiseWindow(tqt_xdisplay(), electric_left_border);
2642 XRaiseWindow(tqt_xdisplay(), electric_bottom_border);
2643 XRaiseWindow(tqt_xdisplay(), electric_right_border);
2647 void Workspace::addTopMenu( Client* c )
2649 assert( c->isTopMenu());
2650 assert( !topmenus.contains( c ));
2651 topmenus.append( c );
2652 if( managingTopMenus())
2654 int minsize = c->minSize().height();
2655 if( minsize > topMenuHeight())
2657 topmenu_height = minsize;
2658 updateTopMenuGeometry();
2660 updateTopMenuGeometry( c );
2661 updateCurrentTopMenu();
2666 void Workspace::removeTopMenu( Client* c )
2670 assert( c->isTopMenu());
2671 assert( topmenus.contains( c ));
2672 topmenus.remove( c );
2673 updateCurrentTopMenu();
2677 void Workspace::lostTopMenuSelection()
2681 disconnect( topmenu_watcher, TQT_SIGNAL( lostOwner()),
this, TQT_SLOT( lostTopMenuOwner()));
2682 connect( topmenu_watcher, TQT_SIGNAL( lostOwner()),
this, TQT_SLOT( lostTopMenuOwner()));
2683 if( !managing_topmenus )
2685 connect( topmenu_watcher, TQT_SIGNAL( lostOwner()),
this, TQT_SLOT( lostTopMenuOwner()));
2686 disconnect( topmenu_selection, TQT_SIGNAL( lostOwnership()),
this, TQT_SLOT( lostTopMenuSelection()));
2687 managing_topmenus =
false;
2688 delete topmenu_space;
2689 topmenu_space = NULL;
2691 for( ClientList::ConstIterator it = topmenus.begin();
2692 it != topmenus.end();
2694 (*it)->checkWorkspacePosition();
2697 void Workspace::lostTopMenuOwner()
2699 if( !options->topMenuEnabled())
2702 if( !topmenu_selection->claim(
false ))
2708 setupTopMenuHandling();
2711 void Workspace::setupTopMenuHandling()
2713 if( managing_topmenus )
2715 connect( topmenu_selection, TQT_SIGNAL( lostOwnership()),
this, TQT_SLOT( lostTopMenuSelection()));
2716 disconnect( topmenu_watcher, TQT_SIGNAL( lostOwner()),
this, TQT_SLOT( lostTopMenuOwner()));
2717 managing_topmenus =
true;
2718 topmenu_space =
new TQWidget;
2720 stack[ 0 ] = supportWindow->winId();
2721 stack[ 1 ] = topmenu_space->winId();
2722 XRestackWindows(tqt_xdisplay(), stack, 2);
2723 updateTopMenuGeometry();
2724 topmenu_space->show();
2726 updateCurrentTopMenu();
2729 int Workspace::topMenuHeight()
const
2731 if( topmenu_height == 0 )
2734 tmpmenu.insertItem(
"dummy" );
2735 topmenu_height = tmpmenu.sizeHint().height();
2737 return topmenu_height;
2740 KDecoration* Workspace::createDecoration( KDecorationBridge* bridge )
2742 return mgr->createDecoration( bridge );
2745 TQString Workspace::desktopName(
int desk )
const
2747 return TQString::fromUtf8( rootInfo->desktopName( desk ) );
2750 bool Workspace::checkStartupNotification( Window w, TDEStartupInfoId&
id, TDEStartupInfoData& data )
2752 return startup->checkStartup( w,
id, data ) == TDEStartupInfo::Match;
2759 void Workspace::focusToNull()
2761 XSetInputFocus(tqt_xdisplay(), null_focus_window, RevertToPointerRoot, GET_QT_X_TIME() );
2764 void Workspace::helperDialog(
const TQString& message,
const Client* c )
2768 if( message ==
"noborderaltf3" )
2770 TQString shortcut = TQString(
"%1 (%2)" ).arg( keys->label(
"Window Operations Menu" ))
2771 .arg( keys->shortcut(
"Window Operations Menu" ).seq( 0 ).toString());
2772 args <<
"--msgbox" <<
2773 i18n(
"You have selected to show a window without its border.\n"
2774 "Without the border, you will not be able to enable the border "
2775 "again using the mouse: use the window operations menu instead, "
2776 "activated using the %1 keyboard shortcut." )
2778 type =
"altf3warning";
2780 else if( message ==
"fullscreenaltf3" )
2782 TQString shortcut = TQString(
"%1 (%2)" ).arg( keys->label(
"Window Operations Menu" ))
2783 .arg( keys->shortcut(
"Window Operations Menu" ).seq( 0 ).toString());
2784 args <<
"--msgbox" <<
2785 i18n(
"You have selected to show a window in fullscreen mode.\n"
2786 "If the application itself does not have an option to turn the fullscreen "
2787 "mode off you will not be able to disable it "
2788 "again using the mouse: use the window operations menu instead, "
2789 "activated using the %1 keyboard shortcut." )
2791 type =
"altf3warning";
2796 proc <<
"kdialog" << args;
2797 if( !type.isEmpty())
2799 TDEConfig cfg(
"twin_dialogsrc" );
2800 cfg.setGroup(
"Notification Messages" );
2801 if( !cfg.readBoolEntry( type,
true ))
2803 proc <<
"--dontagain" <<
"twin_dialogsrc:" + type;
2806 proc <<
"--embed" << TQString::number( c->window());
2807 proc.start( TDEProcess::DontCare );
2813 void Workspace::startKompmgr()
2818 unsigned long length, after;
2819 unsigned char* data_root;
2821 prop_root = XInternAtom(tqt_xdisplay(),
"_XROOTPMAP_ID", False);
2822 if( XGetWindowProperty( tqt_xdisplay(), tqt_xrootwin(), prop_root, 0L, 1L, False, AnyPropertyType, &type, &format, &length, &after, &data_root) == Success && data_root != NULL ) {
2827 TQTimer::singleShot( 200,
this, TQT_SLOT(startKompmgr()) );
2830 pid_t kompmgrpid = getCompositorPID();
2831 if (kompmgrpid && kill(kompmgrpid, 0) >= 0)
2836 if (!kompmgr || kompmgr->isRunning()) {
2837 kompmgrReloadSettings();
2840 if (!kompmgr->start(TDEProcess::OwnGroup, TDEProcess::Stderr))
2842 options->useTranslucency = FALSE;
2844 proc <<
"kdialog" <<
"--error"
2845 << i18n(
"The Composite Manager could not be started.\\nMake sure you have \"" TDE_COMPOSITOR_BINARY
"\" in a $PATH directory.")
2846 <<
"--title" <<
"Composite Manager Failure";
2847 proc.start(TDEProcess::DontCare);
2851 delete kompmgr_selection;
2852 char selection_name[ 100 ];
2853 sprintf( selection_name,
"_NET_WM_CM_S%d", DefaultScreen( tqt_xdisplay()));
2854 kompmgr_selection =
new TDESelectionOwner( selection_name );
2855 connect( kompmgr_selection, TQT_SIGNAL( lostOwnership()), TQT_SLOT( stopKompmgr()));
2856 kompmgr_selection->claim(
true );
2857 connect(kompmgr, TQT_SIGNAL(processExited(TDEProcess*)), TQT_SLOT(restartKompmgr(TDEProcess*)));
2858 options->useTranslucency = TRUE;
2862 TQDataStream arg(ba, IO_WriteOnly);
2864 kapp->dcopClient()->emitDCOPSignal(
"default",
"kompmgrStarted()", ba);
2866 if (popup){
delete popup; popup = 0L; }
2869 void Workspace::stopKompmgr()
2871 if (!kompmgr || !kompmgr->isRunning()) {
2874 delete kompmgr_selection;
2875 kompmgr_selection = NULL;
2876 kompmgr->disconnect(
this, TQT_SLOT(restartKompmgr(TDEProcess*)));
2877 options->useTranslucency = FALSE;
2878 if (popup){
delete popup; popup = 0L; }
2879 kompmgr->kill(SIGKILL);
2881 TQDataStream arg(ba, IO_WriteOnly);
2883 kapp->dcopClient()->emitDCOPSignal(
"default",
"kompmgrStopped()", ba);
2886 void Workspace::kompmgrReloadSettings()
2888 if (!kompmgr || !kompmgr->isRunning()) {
2891 kompmgr->kill(SIGUSR2);
2894 bool Workspace::kompmgrIsRunning()
2896 return kompmgr && kompmgr->isRunning();
2899 void Workspace::unblockKompmgrRestart()
2901 allowKompmgrRestart = TRUE;
2904 void Workspace::restartKompmgr( TDEProcess *proc )
2908 if (proc->signalled()) {
2909 int exit_signal_number = proc->exitSignal();
2910 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) ) {
2916 if (!allowKompmgrRestart)
2918 delete kompmgr_selection;
2919 kompmgr_selection = NULL;
2920 options->useTranslucency = FALSE;
2923 proc <<
"kdialog" <<
"--error"
2924 << i18n(
"The Composite Manager crashed twice within a minute and is therefore disabled for this session.")
2925 <<
"--title" << i18n(
"Composite Manager Failure");
2926 proc.start(TDEProcess::DontCare);
2940 if (!kompmgr->start(TDEProcess::NotifyOnExit, TDEProcess::Stderr))
2942 delete kompmgr_selection;
2943 kompmgr_selection = NULL;
2944 options->useTranslucency = FALSE;
2946 proc <<
"kdialog" <<
"--error"
2947 << i18n(
"The Composite Manager could not be started.\\nMake sure you have \"" TDE_COMPOSITOR_BINARY
"\" in a $PATH directory.")
2948 <<
"--title" << i18n(
"Composite Manager Failure");
2949 proc.start(TDEProcess::DontCare);
2953 allowKompmgrRestart = FALSE;
2954 TQTimer::singleShot( 60000,
this, TQT_SLOT(unblockKompmgrRestart()) );
2959 void Workspace::handleKompmgrOutput( TDEProcess* ,
char *buffer,
int buflen)
2962 TQString output = TQString::fromLocal8Bit( buffer, buflen );
2963 if (output.contains(
"Started",
false))
2965 else if (output.contains(
"Can't open display",
false))
2966 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>");
2967 else if (output.contains(
"No render extension",
false))
2968 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>");
2969 else if (output.contains(
"No composite extension",
false))
2970 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>"
2971 "<i>Section \"Extensions\"<br>"
2972 "Option \"Composite\" \"Enable\"<br>"
2973 "EndSection</i></qt>");
2974 else if (output.contains(
"No damage extension",
false))
2975 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>");
2976 else if (output.contains(
"No XFixes extension",
false))
2977 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>");
2980 kompmgr->closeStderr();
2981 disconnect(kompmgr, TQT_SIGNAL(receivedStderr(TDEProcess*,
char*,
int)),
this, TQT_SLOT(handleKompmgrOutput(TDEProcess*,
char*,
int)));
2982 if( !message.isEmpty())
2985 proc <<
"kdialog" <<
"--error"
2987 <<
"--title" << i18n(
"Composite Manager Failure");
2988 proc.start(TDEProcess::DontCare);
2993 void Workspace::setOpacity(
unsigned long winId,
unsigned int opacityPercent)
2995 if (opacityPercent > 100) opacityPercent = 100;
2996 for( ClientList::ConstIterator it = stackingOrder().begin(); it != stackingOrder().end(); it++ )
2997 if (winId == (*it)->window())
2999 (*it)->setOpacity(opacityPercent < 100, (
unsigned int)((opacityPercent/100.0)*0xFFFFFFFF));
3004 void Workspace::setShadowSize(
unsigned long winId,
unsigned int shadowSizePercent)
3007 if (shadowSizePercent > 400) shadowSizePercent = 400;
3008 for( ClientList::ConstIterator it = stackingOrder().begin(); it != stackingOrder().end(); it++ )
3009 if (winId == (*it)->window())
3011 (*it)->setShadowSize(shadowSizePercent);
3016 void Workspace::setUnshadowed(
unsigned long winId)
3018 for( ClientList::ConstIterator it = stackingOrder().begin(); it != stackingOrder().end(); it++ )
3019 if (winId == (*it)->window())
3021 (*it)->setShadowSize(0);
3026 void Workspace::setShowingDesktop(
bool showing )
3028 rootInfo->setShowingDesktop( showing );
3029 showing_desktop = showing;
3030 ++block_showing_desktop;
3031 if( showing_desktop )
3033 showing_desktop_clients.clear();
3035 ClientList cls = stackingOrder();
3038 for( ClientList::ConstIterator it = cls.begin();
3042 if( (*it)->isOnCurrentDesktop() && (*it)->isShown(
true ) && !(*it)->isSpecialWindow())
3043 showing_desktop_clients.prepend( *it );
3045 for( ClientList::ConstIterator it = showing_desktop_clients.begin();
3046 it != showing_desktop_clients.end();
3048 (*it)->minimize(
true);
3050 if( Client* desk = findDesktop(
true, currentDesktop()))
3051 requestFocus( desk );
3055 for( ClientList::ConstIterator it = showing_desktop_clients.begin();
3056 it != showing_desktop_clients.end();
3058 (*it)->unminimize(
true);
3059 if( showing_desktop_clients.count() > 0 )
3060 requestFocus( showing_desktop_clients.first());
3061 showing_desktop_clients.clear();
3063 --block_showing_desktop;
3075 void Workspace::resetShowingDesktop(
bool keep_hidden )
3077 if( block_showing_desktop > 0 )
3079 rootInfo->setShowingDesktop(
false );
3080 showing_desktop =
false;
3081 ++block_showing_desktop;
3084 for( ClientList::ConstIterator it = showing_desktop_clients.begin();
3085 it != showing_desktop_clients.end();
3087 (*it)->unminimize(
true);
3089 showing_desktop_clients.clear();
3090 --block_showing_desktop;
3100 void Workspace::slotDisableGlobalShortcuts()
3102 if( global_shortcuts_disabled || global_shortcuts_disabled_for_client )
3103 disableGlobalShortcuts(
false );
3105 disableGlobalShortcuts(
true );
3108 static bool pending_dfc =
false;
3110 void Workspace::disableGlobalShortcutsForClient(
bool disable )
3112 if( global_shortcuts_disabled_for_client == disable )
3114 if( !global_shortcuts_disabled )
3118 KIPC::sendMessageAll( KIPC::BlockShortcuts, disable );
3123 void Workspace::disableGlobalShortcuts(
bool disable )
3125 KIPC::sendMessageAll( KIPC::BlockShortcuts, disable );
3129 void Workspace::kipcMessage(
int id,
int data )
3131 if(
id != KIPC::BlockShortcuts )
3133 if( pending_dfc && data )
3135 global_shortcuts_disabled_for_client =
true;
3136 pending_dfc =
false;
3140 global_shortcuts_disabled = data;
3141 global_shortcuts_disabled_for_client =
false;
3144 for( ClientList::ConstIterator it = clients.begin();
3145 it != clients.end();
3147 (*it)->updateMouseGrab();
3152 #include "workspace.moc"