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>
26 #include <tdeprocess.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),
171 layoutOrientation(TQt::Vertical),
176 managing_topmenus( false ),
177 topmenu_selection( NULL ),
178 topmenu_watcher( NULL ),
180 topmenu_space( NULL ),
181 set_active_client_recursion( 0 ),
182 block_stacking_updates( 0 ),
183 forced_global_mouse_grab( false )
187 root = tqt_xrootwin();
188 default_colormap = DefaultColormap(tqt_xdisplay(), tqt_xscreen() );
189 installed_colormap = default_colormap;
190 session.setAutoDelete( TRUE );
192 for (
int i = 0; i < ACTIVE_BORDER_COUNT; ++i)
194 active_reserved[i] = 0;
195 active_windows[i] = None;
198 connect( &temporaryRulesMessages, TQ_SIGNAL( gotMessage(
const TQString& )),
199 this, TQ_SLOT( gotTemporaryRulesMessage(
const TQString& )));
200 connect( &rulesUpdatedTimer, TQ_SIGNAL( timeout()),
this, TQ_SLOT( writeWindowRules()));
206 active_time_first = get_tqt_x_time();
207 active_time_last = get_tqt_x_time();
214 (void) TQApplication::desktop();
220 (WFlags)(TQt::WType_Desktop | TQt::WPaintUnclipped)
223 kapp->setGlobalMouseTracking(
true );
225 startup =
new TDEStartupInfo(
226 TDEStartupInfo::DisableKWinModule | TDEStartupInfo::AnnounceSilenceChanges,
this );
229 XSelectInput(tqt_xdisplay(), root,
233 SubstructureRedirectMask |
234 SubstructureNotifyMask |
250 (
unsigned char*) &data,
254 client_keys =
new TDEGlobalAccel(
this );
256 tab_box =
new TabBox(
this );
257 popupinfo =
new PopupInfo(
this );
261 #if (TQT_VERSION-0 >= 0x030200)
262 connect( kapp->desktop(), TQ_SIGNAL( resized(
int )), TQ_SLOT( desktopResized()));
265 if (!supportsCompMgr()) {
266 options->useTranslucency =
false;
272 pid_t kompmgrpid = getCompositorPID();
274 if (options->useTranslucency)
276 kompmgr =
new TDEProcess;
277 connect(kompmgr, TQ_SIGNAL(receivedStderr(TDEProcess*,
char*,
int)), TQ_SLOT(handleKompmgrOutput(TDEProcess*,
char*,
int)));
278 *kompmgr << TDE_COMPOSITOR_BINARY;
281 if (kill(kompmgrpid, 0) < 0)
292 else if (!disable_twin_composition_manager)
297 kill(kompmgrpid, SIGTERM);
307 void Workspace::init()
309 if (options->activeBorders() == Options::ActiveSwitchAlways)
311 reserveActiveBorderSwitching(
true);
313 updateActiveBorders();
319 supportWindow =
new TQWidget;
320 XLowerWindow( tqt_xdisplay(), supportWindow->winId());
322 XSetWindowAttributes attr;
323 attr.override_redirect = 1;
324 null_focus_window = XCreateWindow( tqt_xdisplay(), tqt_xrootwin(), -1,-1, 1, 1, 0, CopyFromParent,
325 InputOnly, CopyFromParent, CWOverrideRedirect, &attr );
326 XMapWindow(tqt_xdisplay(), null_focus_window);
328 unsigned long protocols[ 5 ] =
331 NET::SupportingWMCheck |
333 NET::ClientListStacking |
334 NET::DesktopGeometry |
335 NET::NumberOfDesktops |
336 NET::CurrentDesktop |
341 NET::KDESystemTrayWindows |
348 NET::WMIconGeometry |
352 NET::WMKDESystemTrayWinFor |
353 NET::WMFrameExtents |
380 NET::DemandsAttention |
385 NET::WM2AllowedActions |
386 NET::WM2RestackWindow |
387 NET::WM2MoveResizeWindow |
388 NET::WM2ExtendedStrut |
389 NET::WM2KDETemporaryRules |
390 NET::WM2ShowingDesktop |
391 NET::WM2FullPlacement |
392 NET::WM2DesktopLayout |
397 NET::ActionMinimize |
401 NET::ActionMaxHoriz |
402 NET::ActionFullScreen |
403 NET::ActionChangeDesktop |
409 rootInfo =
new RootInfo(
this, tqt_xdisplay(), supportWindow->winId(),
"KWin",
410 protocols, 5, tqt_xscreen() );
412 loadDesktopSettings();
413 updateDesktopLayout();
415 NETRootInfo client_info( tqt_xdisplay(), NET::ActiveWindow | NET::CurrentDesktop );
417 if( !kapp->isSessionRestored())
418 initial_desktop = client_info.currentDesktop();
421 TDEConfigGroupSaver saver( kapp->sessionConfig(),
"Session" );
422 initial_desktop = kapp->sessionConfig()->readNumEntry(
"desktop", 1 );
424 if( !setCurrentDesktop( initial_desktop ))
425 setCurrentDesktop( 1 );
428 initPositioning =
new Placement(
this);
430 connect(&reconfigureTimer, TQ_SIGNAL(timeout()),
this,
431 TQ_SLOT(slotReconfigure()));
432 connect( &updateToolWindowsTimer, TQ_SIGNAL( timeout()),
this, TQ_SLOT( slotUpdateToolWindows()));
434 connect(kapp, TQ_SIGNAL(appearanceChanged()),
this,
435 TQ_SLOT(slotReconfigure()));
436 connect(kapp, TQ_SIGNAL(settingsChanged(
int)),
this,
437 TQ_SLOT(slotSettingsChanged(
int)));
438 connect(kapp, TQ_SIGNAL( kipcMessage(
int,
int )),
this, TQ_SLOT( kipcMessage(
int,
int )));
440 active_client = NULL;
441 rootInfo->setActiveWindow( None );
443 if( !kapp->isSessionRestored())
447 sprintf( nm,
"_KDE_TOPMENU_OWNER_S%d", DefaultScreen( tqt_xdisplay()));
448 Atom topmenu_atom = XInternAtom( tqt_xdisplay(), nm, False );
449 topmenu_selection =
new TDESelectionOwner( topmenu_atom );
450 topmenu_watcher =
new TDESelectionWatcher( topmenu_atom );
454 StackingUpdatesBlocker blocker(
this );
456 if( options->topMenuEnabled() && topmenu_selection->claim(
false ))
457 setupTopMenuHandling();
459 lostTopMenuSelection();
461 unsigned int i, nwins;
462 Window root_return, parent_return, *wins;
463 XQueryTree(tqt_xdisplay(), root, &root_return, &parent_return, &wins, &nwins);
464 for (i = 0; i < nwins; i++)
466 XWindowAttributes attr;
467 XGetWindowAttributes(tqt_xdisplay(), wins[i], &attr);
468 if (attr.override_redirect )
470 if( topmenu_space && topmenu_space->winId() == wins[ i ] )
472 if (attr.map_state != IsUnmapped)
474 if ( addSystemTrayWin( wins[i] ) )
476 Client* c = createClient( wins[i],
true );
477 if ( c != NULL && root != tqt_xrootwin() )
480 XReparentWindow( tqt_xdisplay(), c->frameId(), root, 0, 0 );
486 XFree((
void *) wins);
488 updateStackingOrder(
true );
493 NETPoint* viewports =
new NETPoint[ number_of_desktops ];
494 rootInfo->setDesktopViewport( number_of_desktops, *viewports );
496 TQRect geom = TQApplication::desktop()->geometry();
497 NETSize desktop_geometry;
498 desktop_geometry.width = geom.width();
499 desktop_geometry.height = geom.height();
500 rootInfo->setDesktopGeometry( -1, desktop_geometry );
501 setShowingDesktop(
false );
505 Client* new_active_client = NULL;
506 if( !kapp->isSessionRestored())
509 new_active_client = findClient( WindowMatchPredicate( client_info.activeWindow()));
511 if( new_active_client == NULL
512 && activeClient() == NULL && should_get_focus.count() == 0 )
514 if( new_active_client == NULL )
515 new_active_client = topClientOnDesktop( currentDesktop());
516 if( new_active_client == NULL && !desktops.isEmpty() )
517 new_active_client = findDesktop(
true, currentDesktop());
519 if( new_active_client != NULL )
520 activateClient( new_active_client );
523 outline_left = XCreateWindow(tqt_xdisplay(), rootWin(), 0, 0, 1, 1, 0,
524 CopyFromParent, CopyFromParent, CopyFromParent,
525 CWOverrideRedirect, &attr);
526 outline_right = XCreateWindow(tqt_xdisplay(), rootWin(), 0, 0, 1, 1, 0,
527 CopyFromParent, CopyFromParent, CopyFromParent,
528 CWOverrideRedirect, &attr);
529 outline_top = XCreateWindow(tqt_xdisplay(), rootWin(), 0, 0, 1, 1, 0,
530 CopyFromParent, CopyFromParent, CopyFromParent,
531 CWOverrideRedirect, &attr);
532 outline_bottom = XCreateWindow(tqt_xdisplay(), rootWin(), 0, 0, 1, 1, 0,
533 CopyFromParent, CopyFromParent, CopyFromParent,
534 CWOverrideRedirect, &attr);
539 workspaceInit =
false;
543 Workspace::~Workspace()
547 blockStackingUpdates(
true );
550 for( ClientList::ConstIterator it = stacking_order.begin();
551 it != stacking_order.end();
555 (*it)->releaseWindow(
true );
559 clients.remove( *it );
560 desktops.remove( *it );
562 delete desktop_widget;
566 if ( root == tqt_xrootwin() )
567 XDeleteProperty(tqt_xdisplay(), tqt_xrootwin(), atoms->twin_running);
570 TDEGlobal::config()->sync();
573 XDestroyWindow(tqt_xdisplay(), outline_left);
574 XDestroyWindow(tqt_xdisplay(), outline_right);
575 XDestroyWindow(tqt_xdisplay(), outline_top);
576 XDestroyWindow(tqt_xdisplay(), outline_bottom);
579 delete supportWindow;
584 delete initPositioning;
585 delete topmenu_watcher;
586 delete topmenu_selection;
587 delete topmenu_space;
588 delete client_keys_dialog;
589 while( !rules.isEmpty())
591 delete rules.front();
594 XDestroyWindow( tqt_xdisplay(), null_focus_window );
599 Client* Workspace::createClient( Window w,
bool is_mapped )
601 StackingUpdatesBlocker blocker(
this );
602 Client* c =
new Client(
this );
603 if( !c->manage( w, is_mapped ))
605 Client::deleteClient( c, Allowed );
608 addClient( c, Allowed );
612 void Workspace::addClient( Client* c, allowed_t )
616 c->setBMP(c->resourceName() ==
"beep-media-player" || c->decorationId() == None);
618 c->getWindowOpacity();
622 if (!c->hasCustomOpacity())
624 c->setShadowSize(options->dockShadowSize);
625 c->setOpacity(options->translucentDocks, options->dockOpacity);
629 if (c->isMenu() || c->isTopMenu())
631 c->setShadowSize(options->menuShadowSize);
634 Group* grp = findGroup( c->window());
638 if ( c->isDesktop() )
640 desktops.append( c );
641 if( active_client == NULL && should_get_focus.isEmpty() && c->isOnCurrentDesktop())
646 updateFocusChains( c, FocusChainUpdate );
649 if( !unconstrained_stacking_order.contains( c ))
650 unconstrained_stacking_order.append( c );
651 if( !stacking_order.contains( c ))
652 stacking_order.append( c );
656 updateClientLayer( c );
661 if( activeClient() == NULL && should_get_focus.count() == 0 )
662 activateClient( findDesktop(
true, currentDesktop()));
664 c->checkActiveModal();
665 checkTransients( c->window());
666 updateStackingOrder(
true );
667 if( c->isUtility() || c->isMenu() || c->isToolbar())
668 updateToolWindows(
true );
669 checkNonExistentClients();
675 void Workspace::removeClient( Client* c, allowed_t )
677 if (c == active_popup_client)
680 if( client_keys_client == c )
681 setupWindowShortcutDone(
false );
682 if( !c->shortcut().isNull())
683 c->setShortcut( TQString::null );
686 Notify::raise( Notify::TransDelete );
687 if( c->isNormalWindow())
688 Notify::raise( Notify::Delete );
690 Q_ASSERT( clients.contains( c ) || desktops.contains( c ));
692 desktops.remove( c );
693 unconstrained_stacking_order.remove( c );
694 stacking_order.remove( c );
696 i <= numberOfDesktops();
698 focus_chain[ i ].remove( c );
699 global_focus_chain.remove( c );
700 attention_chain.remove( c );
701 showing_desktop_clients.remove( c );
704 Group* group = findGroup( c->window());
708 if ( c == most_recently_raised )
709 most_recently_raised = 0;
710 should_get_focus.remove( c );
711 Q_ASSERT( c != active_client );
712 if ( c == last_active_client )
713 last_active_client = 0;
714 if( c == pending_take_activity )
715 pending_take_activity = NULL;
716 if( c == delayfocus_client )
719 updateStackingOrder(
true );
727 void Workspace::updateFocusChains( Client* c, FocusChainChange change )
729 if( !c->wantsTabFocus())
732 i<= numberOfDesktops();
734 focus_chain[i].remove(c);
735 global_focus_chain.remove( c );
738 if(c->desktop() == NET::OnAllDesktops)
740 for(
int i=1; i<= numberOfDesktops(); i++)
742 if( i == currentDesktop()
743 && ( change == FocusChainMakeFirst || change == FocusChainMakeLast ))
745 focus_chain[ i ].remove( c );
746 if( change == FocusChainMakeFirst )
747 focus_chain[ i ].append( c );
749 focus_chain[ i ].prepend( c );
751 else if( !focus_chain[ i ].contains( c ))
753 if( active_client != NULL && active_client != c
754 && !focus_chain[ i ].isEmpty() && focus_chain[ i ].last() == active_client )
755 focus_chain[ i ].insert( focus_chain[ i ].fromLast(), c );
757 focus_chain[ i ].append( c );
763 for(
int i=1; i<= numberOfDesktops(); i++)
765 if( i == c->desktop())
767 if( change == FocusChainMakeFirst )
769 focus_chain[ i ].remove( c );
770 focus_chain[ i ].append( c );
772 else if( change == FocusChainMakeLast )
774 focus_chain[ i ].remove( c );
775 focus_chain[ i ].prepend( c );
777 else if( !focus_chain[ i ].contains( c ))
779 if( active_client != NULL && active_client != c
780 && !focus_chain[ i ].isEmpty() && focus_chain[ i ].last() == active_client )
781 focus_chain[ i ].insert( focus_chain[ i ].fromLast(), c );
783 focus_chain[ i ].append( c );
787 focus_chain[ i ].remove( c );
790 if( change == FocusChainMakeFirst )
792 global_focus_chain.remove( c );
793 global_focus_chain.append( c );
795 else if( change == FocusChainMakeLast )
797 global_focus_chain.remove( c );
798 global_focus_chain.prepend( c );
800 else if( !global_focus_chain.contains( c ))
802 if( active_client != NULL && active_client != c
803 && !global_focus_chain.isEmpty() && global_focus_chain.last() == active_client )
804 global_focus_chain.insert( global_focus_chain.fromLast(), c );
806 global_focus_chain.append( c );
810 void Workspace::updateOverlappingShadows(
unsigned long window)
814 if ((client = findClient(WindowMatchPredicate((WId)window))))
817 client->drawOverlappingShadows(
false);
820 void Workspace::setShadowed(
unsigned long window,
bool shadowed)
824 if ((client = findClient(WindowMatchPredicate((WId)window))))
825 client->setShadowed(shadowed);
828 void Workspace::updateCurrentTopMenu()
830 if( !managingTopMenus())
834 bool block_desktop_menubar =
false;
838 Client* menu_client = active_client;
841 if( menu_client->isFullScreen())
842 block_desktop_menubar =
true;
843 for( ClientList::ConstIterator it = menu_client->transients().begin();
844 it != menu_client->transients().end();
846 if( (*it)->isTopMenu())
851 if( menubar != NULL || !menu_client->isTransient())
853 if( menu_client->isModal() || menu_client->transientFor() == NULL )
855 menu_client = menu_client->transientFor();
859 for( ClientList::ConstIterator it = active_client->group()->members().begin();
860 it != active_client->group()->members().end();
862 if( (*it)->isTopMenu())
869 if( !menubar && !block_desktop_menubar && options->desktopTopMenu())
872 Client* desktop = findDesktop(
true, currentDesktop());
873 if( desktop != NULL )
875 for( ClientList::ConstIterator it = desktop->transients().begin();
876 it != desktop->transients().end();
878 if( (*it)->isTopMenu())
887 if( menubar == NULL )
889 for( ClientList::ConstIterator it = topmenus.begin();
890 it != topmenus.end();
892 if( (*it)->wasOriginallyGroupTransient())
903 if( active_client && !menubar->isOnDesktop( active_client->desktop()))
904 menubar->setDesktop( active_client->desktop());
905 menubar->hideClient(
false );
906 topmenu_space->hide();
910 unconstrained_stacking_order.remove( menubar );
911 unconstrained_stacking_order.append( menubar );
913 else if( !block_desktop_menubar )
915 topmenu_space->show();
919 for ( ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it)
921 if( (*it)->isTopMenu() && (*it) != menubar )
922 (*it)->hideClient(
true );
927 void Workspace::updateToolWindows(
bool also_hide )
930 if( !options->hideUtilityWindowsForInactive )
932 for( ClientList::ConstIterator it = clients.begin();
935 (*it)->hideClient(
false );
938 const Group* group = NULL;
939 const Client* client = active_client;
942 while( client != NULL )
944 if( !client->isTransient())
946 if( client->groupTransient())
948 group = client->group();
951 client = client->transientFor();
957 ClientList to_show, to_hide;
958 for( ClientList::ConstIterator it = stacking_order.begin();
959 it != stacking_order.end();
962 if( (*it)->isUtility() || (*it)->isMenu() || (*it)->isToolbar())
965 if( !(*it)->isTransient())
967 if( (*it)->group()->members().count() == 1 )
969 else if( client != NULL && (*it)->group() == client->group())
976 if( group != NULL && (*it)->group() == group )
978 else if( client != NULL && client->hasTransient( (*it),
true ))
983 if( !show && also_hide )
985 const ClientList mainclients = (*it)->mainClients();
988 if( mainclients.isEmpty())
990 for( ClientList::ConstIterator it2 = mainclients.begin();
991 it2 != mainclients.end();
994 if( (*it2)->isSpecialWindow())
998 to_hide.append( *it );
1001 to_show.append( *it );
1004 for( ClientList::ConstIterator it = to_show.fromLast();
1005 it != to_show.end();
1008 (*it)->hideClient(
false );
1011 for( ClientList::ConstIterator it = to_hide.begin();
1012 it != to_hide.end();
1014 (*it)->hideClient(
true );
1015 updateToolWindowsTimer.stop();
1019 updateToolWindowsTimer.start( 50,
true );
1023 void Workspace::slotUpdateToolWindows()
1025 updateToolWindows(
true );
1031 void Workspace::updateColormap()
1033 Colormap cmap = default_colormap;
1034 if ( activeClient() && activeClient()->colormap() != None )
1035 cmap = activeClient()->colormap();
1036 if ( cmap != installed_colormap )
1038 XInstallColormap(tqt_xdisplay(), cmap );
1039 installed_colormap = cmap;
1043 void Workspace::reconfigure()
1045 reconfigureTimer.start(200,
true);
1049 void Workspace::slotSettingsChanged(
int category)
1051 kdDebug(1212) <<
"Workspace::slotSettingsChanged()" << endl;
1052 if( category == (
int) TDEApplication::SETTINGS_SHORTCUTS )
1059 KWIN_PROCEDURE( CheckBorderSizesProcedure, cl->checkBorderSizes() );
1061 void Workspace::slotReconfigure()
1063 kdDebug(1212) <<
"Workspace::slotReconfigure()" << endl;
1064 reconfigureTimer.stop();
1066 if (options->activeBorders() == Options::ActiveSwitchAlways)
1068 reserveActiveBorderSwitching(
false);
1071 TDEGlobal::config()->reparseConfiguration();
1072 unsigned long changed = options->updateSettings();
1073 tab_box->reconfigure();
1074 popupinfo->reconfigure();
1075 initPositioning->reinitCascading( 0 );
1077 forEachClient( CheckIgnoreFocusStealingProcedure());
1078 updateToolWindows(
true );
1080 if( mgr->reset( changed ))
1084 curtain.setBackgroundMode( NoBackground );
1085 curtain.setGeometry( TQApplication::desktop()->geometry() );
1088 for( ClientList::ConstIterator it = clients.begin();
1089 it != clients.end();
1092 (*it)->updateDecoration(
true,
true );
1094 mgr->destroyPreviousPlugin();
1098 forEachClient( CheckBorderSizesProcedure());
1101 if (options->activeBorders() == Options::ActiveSwitchAlways)
1103 reserveActiveBorderSwitching(
true);
1106 if( options->topMenuEnabled() && !managingTopMenus())
1108 if( topmenu_selection->claim(
false ))
1109 setupTopMenuHandling();
1111 lostTopMenuSelection();
1113 else if( !options->topMenuEnabled() && managingTopMenus())
1115 topmenu_selection->release();
1116 lostTopMenuSelection();
1119 if( managingTopMenus())
1121 updateTopMenuGeometry();
1122 updateCurrentTopMenu();
1126 for( ClientList::Iterator it = clients.begin();
1127 it != clients.end();
1130 (*it)->setupWindowRules(
true );
1131 (*it)->applyWindowRules();
1132 discardUsedWindowRules( *it,
false );
1135 if (options->resetKompmgr)
1137 bool tmp = options->useTranslucency;
1142 const char *pidfile =
"compton-tde.pid";
1143 char uidstr[
sizeof(uid_t)*8+1];
1144 sprintf(uidstr,
"%d", getuid());
1145 int n = strlen(P_tmpdir)+strlen(uidstr)+strlen(pidfile)+3;
1146 filename = (
char*)malloc(n*
sizeof(
char)+1);
1147 memset(filename,0,n);
1148 strcat(filename, P_tmpdir);
1149 strcat(filename,
"/.");
1150 strcat(filename, uidstr);
1151 strcat(filename,
"-");
1152 strcat(filename, pidfile);
1157 pFile = fopen(filename,
"r");
1161 printf(
"[twin-workspace] Using '%s' as compton-tde pidfile\n\n", filename);
1163 fseek (pFile , 0 , SEEK_END);
1164 unsigned long lSize = ftell (pFile);
1168 size_t result = fread (buffer, 1, lSize, pFile);
1172 kompmgrpid = atoi(buffer);
1183 kill(kompmgrpid, SIGUSR2);
1190 kompmgr =
new TDEProcess;
1191 connect(kompmgr, TQ_SIGNAL(receivedStderr(TDEProcess*,
char*,
int)), TQ_SLOT(handleKompmgrOutput(TDEProcess*,
char*,
int)));
1192 *kompmgr << TDE_COMPOSITOR_BINARY;
1194 TQTimer::singleShot( 200,
this, TQ_SLOT(startKompmgr()) );
1201 kill(kompmgrpid, SIGTERM);
1211 void Workspace::loadDesktopSettings()
1213 TDEConfig* c = TDEGlobal::config();
1214 TQCString groupname;
1215 if (screen_number == 0)
1216 groupname =
"Desktops";
1218 groupname.sprintf(
"Desktops-screen-%d", screen_number);
1219 TDEConfigGroupSaver saver(c,groupname);
1221 int n = c->readNumEntry(
"Number", 4);
1222 number_of_desktops = n;
1224 workarea =
new TQRect[ n + 1 ];
1227 rootInfo->setNumberOfDesktops( number_of_desktops );
1228 desktop_focus_chain.resize( n );
1230 focus_chain.resize( n + 1 );
1231 for(
int i = 1; i <= n; i++)
1233 TQString s = c->readEntry(TQString(
"Name_%1").arg(i),
1234 i18n(
"Desktop %1").arg(i));
1235 rootInfo->setDesktopName( i, s.utf8().data() );
1236 desktop_focus_chain[i-1] = i;
1240 void Workspace::saveDesktopSettings()
1242 TDEConfig* c = TDEGlobal::config();
1243 TQCString groupname;
1244 if (screen_number == 0)
1245 groupname =
"Desktops";
1247 groupname.sprintf(
"Desktops-screen-%d", screen_number);
1248 TDEConfigGroupSaver saver(c,groupname);
1250 c->writeEntry(
"Number", number_of_desktops );
1251 for(
int i = 1; i <= number_of_desktops; i++)
1253 TQString s = desktopName( i );
1254 TQString defaultvalue = i18n(
"Desktop %1").arg(i);
1258 rootInfo->setDesktopName( i, s.utf8().data() );
1261 if (s != defaultvalue)
1263 c->writeEntry( TQString(
"Name_%1").arg(i), s );
1267 TQString currentvalue = c->readEntry(TQString(
"Name_%1").arg(i));
1268 if (currentvalue != defaultvalue)
1269 c->writeEntry( TQString(
"Name_%1").arg(i),
"" );
1274 TQStringList Workspace::configModules(
bool controlCenter)
1277 args <<
"tde-twindecoration.desktop";
1279 args <<
"tde-twinoptions.desktop";
1280 else if (kapp->authorizeControlModule(
"tde-twinoptions.desktop"))
1281 args <<
"twinactions" <<
"twinfocus" <<
"twinmoving" <<
"twinadvanced" <<
"twinrules" <<
"twintranslucency";
1285 void Workspace::configureWM()
1287 TDEApplication::tdeinitExec(
"tdecmshell", configModules(
false) );
1293 void Workspace::doNotManage( TQString title )
1295 doNotManageList.append( title );
1301 bool Workspace::isNotManaged(
const TQString& title )
1303 for ( TQStringList::Iterator it = doNotManageList.begin(); it != doNotManageList.end(); ++it )
1305 TQRegExp r( (*it) );
1306 if (r.search(title) != -1)
1308 doNotManageList.remove( it );
1318 void Workspace::refresh()
1321 w.setGeometry( TQApplication::desktop()->geometry() );
1324 TQApplication::flushX();
1334 class ObscuringWindows
1337 ~ObscuringWindows();
1338 void create( Client* c );
1340 TQValueList<Window> obscuring_windows;
1341 static TQValueList<Window>* cached;
1342 static unsigned int max_cache_size;
1345 TQValueList<Window>* ObscuringWindows::cached = 0;
1346 unsigned int ObscuringWindows::max_cache_size = 0;
1348 void ObscuringWindows::create( Client* c )
1351 cached =
new TQValueList<Window>;
1353 XWindowChanges chngs;
1354 int mask = CWSibling | CWStackMode;
1355 if( cached->count() > 0 )
1357 cached->remove( obs_win = cached->first());
1360 chngs.width = c->width();
1361 chngs.height = c->height();
1362 mask |= CWX | CWY | CWWidth | CWHeight;
1366 XSetWindowAttributes a;
1367 a.background_pixmap = None;
1368 a.override_redirect = True;
1369 obs_win = XCreateWindow( tqt_xdisplay(), tqt_xrootwin(), c->x(), c->y(),
1370 c->width(), c->height(), 0, CopyFromParent, InputOutput,
1371 CopyFromParent, CWBackPixmap | CWOverrideRedirect, &a );
1373 chngs.sibling = c->frameId();
1374 chngs.stack_mode = Below;
1375 XConfigureWindow( tqt_xdisplay(), obs_win, mask, &chngs );
1376 XMapWindow( tqt_xdisplay(), obs_win );
1377 obscuring_windows.append( obs_win );
1380 ObscuringWindows::~ObscuringWindows()
1382 max_cache_size = TQMAX( max_cache_size, obscuring_windows.count() + 4 ) - 1;
1383 for( TQValueList<Window>::ConstIterator it = obscuring_windows.begin();
1384 it != obscuring_windows.end();
1387 XUnmapWindow( tqt_xdisplay(), *it );
1388 if( cached->count() < max_cache_size )
1389 cached->prepend( *it );
1391 XDestroyWindow( tqt_xdisplay(), *it );
1402 bool Workspace::setCurrentDesktop(
int new_desktop )
1404 if (new_desktop < 1 || new_desktop > number_of_desktops )
1410 StackingUpdatesBlocker blocker(
this );
1412 int old_desktop = current_desktop;
1413 if (new_desktop != current_desktop)
1415 ++block_showing_desktop;
1420 Notify::raise((Notify::Event) (Notify::DesktopChange+new_desktop));
1422 ObscuringWindows obs_wins;
1424 current_desktop = new_desktop;
1426 bool desktopHasCompositing = kapp->isCompositionManagerAvailable();
1427 if (!desktopHasCompositing) {
1429 for ( ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it) {
1430 if ( !(*it)->isOnDesktop( new_desktop ) && (*it) != movingClient )
1432 if( (*it)->isShown(
true ) && (*it)->isOnDesktop( old_desktop )) {
1433 obs_wins.create( *it );
1435 (*it)->updateVisibility();
1440 rootInfo->setCurrentDesktop( current_desktop );
1442 if( movingClient && !movingClient->isOnDesktop( new_desktop ))
1443 movingClient->setDesktop( new_desktop );
1445 for ( ClientList::ConstIterator it = stacking_order.fromLast(); it != stacking_order.end(); --it) {
1446 if ( (*it)->isOnDesktop( new_desktop ) ) {
1447 (*it)->updateVisibility();
1451 if (desktopHasCompositing) {
1454 XSync( tqt_xdisplay(),
false);
1455 for ( ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it) {
1456 if ( !(*it)->isOnDesktop( new_desktop ) && (*it) != movingClient )
1458 if( (*it)->isShown(
true ) && (*it)->isOnDesktop( old_desktop )) {
1459 obs_wins.create( *it );
1461 (*it)->updateVisibility();
1466 --block_showing_desktop;
1467 if( showingDesktop())
1468 resetShowingDesktop(
false );
1475 if ( options->focusPolicyIsReasonable())
1478 if ( movingClient != NULL && active_client == movingClient
1479 && focus_chain[currentDesktop()].contains( active_client )
1480 && active_client->isShown(
true ) && active_client->isOnCurrentDesktop())
1486 for( ClientList::ConstIterator it = focus_chain[currentDesktop()].fromLast();
1487 it != focus_chain[currentDesktop()].end();
1490 if ( (*it)->isShown(
false ) && (*it)->isOnCurrentDesktop())
1502 else if( active_client && active_client->isShown(
true ) && active_client->isOnCurrentDesktop())
1505 if( c == NULL && !desktops.isEmpty())
1506 c = findDesktop(
true, currentDesktop());
1508 if( c != active_client )
1509 setActiveClient( NULL, Allowed );
1516 updateCurrentTopMenu();
1523 for(
int i = desktop_focus_chain.find( currentDesktop() ); i > 0; i-- )
1524 desktop_focus_chain[i] = desktop_focus_chain[i-1];
1525 desktop_focus_chain[0] = currentDesktop();
1532 if( old_desktop != 0 )
1533 popupinfo->showInfo( desktopName(currentDesktop()) );
1538 void Workspace::nextDesktop()
1540 int desktop = currentDesktop() + 1;
1541 setCurrentDesktop(desktop > numberOfDesktops() ? 1 : desktop);
1545 void Workspace::previousDesktop()
1547 int desktop = currentDesktop() - 1;
1548 setCurrentDesktop(desktop > 0 ? desktop : numberOfDesktops());
1551 int Workspace::desktopToRight(
int desktop )
const
1554 calcDesktopLayout(x,y);
1556 if (layoutOrientation == TQt::Vertical)
1559 if ( dt >= numberOfDesktops() )
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::desktopToLeft(
int desktop )
const
1585 calcDesktopLayout(x,y);
1587 if (layoutOrientation == TQt::Vertical)
1592 if ( options->rollOverDesktops )
1593 dt += numberOfDesktops();
1600 int d = (dt % x) - 1;
1603 if ( options->rollOverDesktops )
1608 dt = dt - (dt % x) + d;
1613 int Workspace::desktopUp(
int desktop )
const
1616 calcDesktopLayout(x,y);
1618 if (layoutOrientation == TQt::Horizontal)
1623 if ( options->rollOverDesktops )
1624 dt += numberOfDesktops();
1631 int d = (dt % y) - 1;
1634 if ( options->rollOverDesktops )
1639 dt = dt - (dt % y) + d;
1644 int Workspace::desktopDown(
int desktop )
const
1647 calcDesktopLayout(x,y);
1649 if (layoutOrientation == TQt::Horizontal)
1652 if ( dt >= numberOfDesktops() )
1654 if ( options->rollOverDesktops )
1655 dt -= numberOfDesktops();
1662 int d = (dt % y) + 1;
1665 if ( options->rollOverDesktops )
1670 dt = dt - (dt % y) + d;
1679 void Workspace::setNumberOfDesktops(
int n )
1681 if ( n == number_of_desktops )
1683 int old_number_of_desktops = number_of_desktops;
1684 number_of_desktops = n;
1686 if( currentDesktop() > numberOfDesktops())
1687 setCurrentDesktop( numberOfDesktops());
1691 if( old_number_of_desktops < number_of_desktops )
1693 rootInfo->setNumberOfDesktops( number_of_desktops );
1694 NETPoint* viewports =
new NETPoint[ number_of_desktops ];
1695 rootInfo->setDesktopViewport( number_of_desktops, *viewports );
1697 updateClientArea(
true );
1698 focus_chain.resize( number_of_desktops + 1 );
1703 if( old_number_of_desktops > number_of_desktops )
1705 for( ClientList::ConstIterator it = clients.begin();
1706 it != clients.end();
1709 if( !(*it)->isOnAllDesktops() && (*it)->desktop() > numberOfDesktops())
1710 sendClientToDesktop( *it, numberOfDesktops(),
true );
1713 if( old_number_of_desktops > number_of_desktops )
1715 rootInfo->setNumberOfDesktops( number_of_desktops );
1716 NETPoint* viewports =
new NETPoint[ number_of_desktops ];
1717 rootInfo->setDesktopViewport( number_of_desktops, *viewports );
1719 updateClientArea(
true );
1720 focus_chain.resize( number_of_desktops + 1 );
1723 saveDesktopSettings();
1726 desktop_focus_chain.resize( n );
1727 for(
int i = 0; i < (int)desktop_focus_chain.size(); i++ )
1728 desktop_focus_chain[i] = i+1;
1736 void Workspace::sendClientToDesktop( Client* c,
int desk,
bool dont_activate )
1738 bool was_on_desktop = c->isOnDesktop( desk ) || c->isOnAllDesktops();
1739 c->setDesktop( desk );
1740 if ( c->desktop() != desk )
1742 desk = c->desktop();
1744 if ( c->isOnDesktop( currentDesktop() ) )
1746 if ( c->wantsTabFocus() && options->focusPolicyIsReasonable()
1751 restackClientUnderActive( c );
1758 ClientList transients_stacking_order = ensureStackingOrder( c->transients());
1759 for( ClientList::ConstIterator it = transients_stacking_order.begin();
1760 it != transients_stacking_order.end();
1762 sendClientToDesktop( *it, desk, dont_activate );
1766 int Workspace::numScreens()
const
1768 if( !options->xineramaEnabled )
1770 return tqApp->desktop()->numScreens();
1773 int Workspace::activeScreen()
const
1775 if( !options->xineramaEnabled )
1777 if( !options->activeMouseScreen )
1779 if( activeClient() != NULL && !activeClient()->isOnScreen( active_screen ))
1780 return tqApp->desktop()->screenNumber( activeClient()->geometry().center());
1781 return active_screen;
1783 return tqApp->desktop()->screenNumber( TQCursor::pos());
1788 void Workspace::checkActiveScreen(
const Client* c )
1790 if( !options->xineramaEnabled )
1794 if( !c->isOnScreen( active_screen ))
1795 active_screen = c->screen();
1800 void Workspace::setActiveScreenMouse( TQPoint mousepos )
1802 if( !options->xineramaEnabled )
1804 active_screen = tqApp->desktop()->screenNumber( mousepos );
1807 TQRect Workspace::screenGeometry(
int screen )
const
1809 if (( !options->xineramaEnabled ) || (kapp->desktop()->numScreens() < 2))
1810 return tqApp->desktop()->geometry();
1811 return tqApp->desktop()->screenGeometry( screen );
1814 int Workspace::screenNumber( TQPoint pos )
const
1816 if( !options->xineramaEnabled )
1818 return tqApp->desktop()->screenNumber( pos );
1821 void Workspace::sendClientToScreen( Client* c,
int screen )
1823 if( c->screen() == screen )
1825 GeometryUpdatesPostponer blocker( c );
1826 TQRect old_sarea = clientArea( MaximizeArea, c );
1827 TQRect sarea = clientArea( MaximizeArea, screen, c->desktop());
1828 c->setGeometry( sarea.x() - old_sarea.x() + c->x(), sarea.y() - old_sarea.y() + c->y(),
1829 c->size().width(), c->size().height());
1830 c->checkWorkspacePosition();
1831 ClientList transients_stacking_order = ensureStackingOrder( c->transients());
1832 for( ClientList::ConstIterator it = transients_stacking_order.begin();
1833 it != transients_stacking_order.end();
1835 sendClientToScreen( *it, screen );
1837 active_screen = screen;
1841 void Workspace::setDesktopLayout(
int,
int,
int )
1845 void Workspace::updateDesktopLayout()
1848 layoutOrientation = ( rootInfo->desktopLayoutOrientation() == NET::OrientationHorizontal
1849 ? TQt::Horizontal : TQt::Vertical );
1850 layoutX = rootInfo->desktopLayoutColumnsRows().width();
1851 layoutY = rootInfo->desktopLayoutColumnsRows().height();
1852 if( layoutX == 0 && layoutY == 0 )
1856 void Workspace::calcDesktopLayout(
int &x,
int &y)
const
1860 if((x <= 0) && (y > 0))
1861 x = (numberOfDesktops()+y-1) / y;
1862 else if((y <=0) && (x > 0))
1863 y = (numberOfDesktops()+x-1) / x;
1875 bool Workspace::addSystemTrayWin( WId w )
1877 if ( systemTrayWins.contains( w ) )
1880 NETWinInfo ni( tqt_xdisplay(), w, root, NET::WMKDESystemTrayWinFor );
1881 WId trayWinFor = ni.kdeSystemTrayWinFor();
1884 systemTrayWins.append( SystemTrayWindow( w, trayWinFor ) );
1885 XSelectInput( tqt_xdisplay(), w,
1888 XAddToSaveSet( tqt_xdisplay(), w );
1889 propagateSystemTrayWins();
1897 bool Workspace::removeSystemTrayWin( WId w,
bool check )
1899 if ( !systemTrayWins.contains( w ) )
1911 Atom* props = XListProperties( tqt_xdisplay(), w, &num_props );
1917 if( props[ i ] == atoms->kde_system_tray_embedding )
1925 systemTrayWins.remove( w );
1926 XRemoveFromSaveSet (tqt_xdisplay (), w);
1927 propagateSystemTrayWins();
1935 void Workspace::propagateSystemTrayWins()
1937 Window *cl =
new Window[ systemTrayWins.count()];
1940 for ( SystemTrayWindowList::ConstIterator it = systemTrayWins.begin(); it != systemTrayWins.end(); ++it )
1942 cl[i++] = (*it).win;
1945 rootInfo->setKDESystemTrayWindows( cl, i );
1950 void Workspace::killWindowId( Window window_to_kill )
1952 if( window_to_kill == None )
1954 Window window = window_to_kill;
1955 Client* client = NULL;
1958 client = findClient( FrameIdMatchPredicate( window ));
1959 if( client != NULL )
1963 Window* children = 0L;
1964 unsigned int children_count;
1965 XQueryTree( tqt_xdisplay(), window, &root, &parent, &children, &children_count );
1966 if( children != NULL )
1968 if( window == root )
1974 if( client != NULL )
1975 client->killWindow();
1977 XKillClient( tqt_xdisplay(), window_to_kill );
1980 void Workspace::suspendWindowId( Window window_to_suspend )
1982 if( window_to_suspend == None )
1984 Window window = window_to_suspend;
1985 Client* client = NULL;
1988 client = findClient( FrameIdMatchPredicate( window ));
1989 if( client != NULL )
1993 Window* children = 0L;
1994 unsigned int children_count;
1995 XQueryTree( tqt_xdisplay(), window, &root, &parent, &children, &children_count );
1996 if( children != NULL )
1998 if( window == root )
2004 if( client != NULL )
2005 client->suspendWindow();
2010 void Workspace::resumeWindowId( Window window_to_resume )
2012 if( window_to_resume == None )
2014 Window window = window_to_resume;
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 client->resumeWindow();
2041 bool Workspace::isResumeableWindowID( Window window_to_check )
2043 if( window_to_check == None )
2045 Window window = window_to_check;
2046 Client* client = NULL;
2049 client = findClient( FrameIdMatchPredicate( window ));
2050 if( client != NULL )
2054 Window* children = 0L;
2055 unsigned int children_count;
2056 XQueryTree( tqt_xdisplay(), window, &root, &parent, &children, &children_count );
2057 if( children != NULL )
2059 if( window == root )
2065 if( client != NULL )
2066 return client->isResumeable();
2072 void Workspace::sendPingToWindow( Window window, Time timestamp )
2074 rootInfo->sendPing( window, timestamp );
2077 void Workspace::sendTakeActivity( Client* c, Time timestamp,
long flags )
2079 rootInfo->takeActivity( c->window(), timestamp, flags );
2080 pending_take_activity = c;
2087 void Workspace::slotGrabWindow()
2089 if ( active_client )
2091 TQPixmap snapshot = TQPixmap::grabWindow( active_client->frameId() );
2094 if( Shape::available())
2098 XRectangle* rects = XShapeGetRectangles( tqt_xdisplay(), active_client->frameId(),
2099 ShapeBounding, &count, &order);
2108 for (
int pos = 0; pos < count; pos++)
2109 contents += TQRegion(rects[pos].x, rects[pos].y,
2110 rects[pos].width, rects[pos].height);
2114 TQRegion bbox(0, 0, snapshot.width(), snapshot.height());
2117 TQRegion maskedAway = bbox - contents;
2118 TQMemArray<TQRect> maskedAwayRects = maskedAway.rects();
2121 TQBitmap mask( snapshot.width(), snapshot.height());
2123 p.fillRect(0, 0, mask.width(), mask.height(), TQt::color1);
2124 for (uint pos = 0; pos < maskedAwayRects.count(); pos++)
2125 p.fillRect(maskedAwayRects[pos], TQt::color0);
2127 snapshot.setMask(mask);
2131 TQClipboard *cb = TQApplication::clipboard();
2132 cb->setPixmap( snapshot );
2141 void Workspace::slotGrabDesktop()
2143 TQPixmap p = TQPixmap::grabWindow( tqt_xrootwin() );
2144 TQClipboard *cb = TQApplication::clipboard();
2152 void Workspace::slotMouseEmulation()
2155 if ( mouse_emulation )
2157 XUngrabKeyboard(tqt_xdisplay(), get_tqt_x_time());
2158 mouse_emulation = FALSE;
2162 if ( XGrabKeyboard(tqt_xdisplay(),
2164 GrabModeAsync, GrabModeAsync,
2165 get_tqt_x_time()) == GrabSuccess )
2167 mouse_emulation = TRUE;
2168 mouse_emulation_state = 0;
2169 mouse_emulation_window = 0;
2179 WId Workspace::getMouseEmulationWindow()
2182 Window child = tqt_xrootwin();
2183 int root_x, root_y, lx, ly;
2191 c = findClient( FrameIdMatchPredicate( w ));
2192 XQueryPointer( tqt_xdisplay(), w, &root, &child,
2193 &root_x, &root_y, &lx, &ly, &state );
2194 }
while ( child != None && child != w );
2196 if ( c && !c->isActive() )
2197 activateClient( c );
2204 unsigned int Workspace::sendFakedMouseEvent( TQPoint pos, WId w, MouseEmulation type,
int button,
unsigned int state )
2208 TQWidget* widget = TQWidget::find( w );
2209 if ( (!widget || widget->inherits(
"TQToolButton") ) && !findClient( WindowMatchPredicate( w )) )
2213 XTranslateCoordinates( tqt_xdisplay(), tqt_xrootwin(), w, pos.x(), pos.y(), &x, &y, &xw );
2214 if ( type == EmuMove )
2217 e.type = MotionNotify;
2218 e.xmotion.window = w;
2219 e.xmotion.root = tqt_xrootwin();
2220 e.xmotion.subwindow = w;
2221 e.xmotion.time = get_tqt_x_time();
2224 e.xmotion.x_root = pos.x();
2225 e.xmotion.y_root = pos.y();
2226 e.xmotion.state = state;
2227 e.xmotion.is_hint = NotifyNormal;
2228 XSendEvent( tqt_xdisplay(), w, TRUE, ButtonMotionMask, &e );
2233 e.type = type == EmuRelease ? ButtonRelease : ButtonPress;
2234 e.xbutton.window = w;
2235 e.xbutton.root = tqt_xrootwin();
2236 e.xbutton.subwindow = w;
2237 e.xbutton.time = get_tqt_x_time();
2240 e.xbutton.x_root = pos.x();
2241 e.xbutton.y_root = pos.y();
2242 e.xbutton.state = state;
2243 e.xbutton.button = button;
2244 XSendEvent( tqt_xdisplay(), w, TRUE, ButtonPressMask, &e );
2246 if ( type == EmuPress )
2251 state |= Button2Mask;
2254 state |= Button3Mask;
2257 state |= Button1Mask;
2266 state &= ~Button2Mask;
2269 state &= ~Button3Mask;
2272 state &= ~Button1Mask;
2284 bool Workspace::keyPressMouseEmulation( XKeyEvent& ev )
2286 if ( root != tqt_xrootwin() )
2288 int kc = XkbKeycodeToKeysym(tqt_xdisplay(), ev.keycode, 0, 0);
2289 int km = ev.state & (ControlMask | Mod1Mask | ShiftMask);
2291 bool is_control = km & ControlMask;
2292 bool is_alt = km & Mod1Mask;
2293 bool is_shift = km & ShiftMask;
2294 int delta = is_control?1:is_alt?32:8;
2295 TQPoint pos = TQCursor::pos();
2316 if ( !mouse_emulation_state )
2317 mouse_emulation_window = getMouseEmulationWindow();
2318 if ( (mouse_emulation_state & Button1Mask) == 0 )
2319 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuPress, Button1, mouse_emulation_state );
2321 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button1, mouse_emulation_state );
2324 if ( !mouse_emulation_state )
2325 mouse_emulation_window = getMouseEmulationWindow();
2326 if ( (mouse_emulation_state & Button2Mask) == 0 )
2327 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuPress, Button2, mouse_emulation_state );
2329 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button2, mouse_emulation_state );
2332 if ( !mouse_emulation_state )
2333 mouse_emulation_window = getMouseEmulationWindow();
2334 if ( (mouse_emulation_state & Button3Mask) == 0 )
2335 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuPress, Button3, mouse_emulation_state );
2337 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button3, mouse_emulation_state );
2344 if ( !mouse_emulation_state )
2347 mouse_emulation_window = getMouseEmulationWindow();
2348 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuPress, Button1, mouse_emulation_state );
2349 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button1, mouse_emulation_state );
2353 if ( mouse_emulation_state & Button1Mask )
2354 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button1, mouse_emulation_state );
2355 if ( mouse_emulation_state & Button2Mask )
2356 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button2, mouse_emulation_state );
2357 if ( mouse_emulation_state & Button3Mask )
2358 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuRelease, Button3, mouse_emulation_state );
2363 XUngrabKeyboard(tqt_xdisplay(), get_tqt_x_time());
2364 mouse_emulation = FALSE;
2370 TQCursor::setPos( pos );
2371 if ( mouse_emulation_state )
2372 mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuMove, 0, mouse_emulation_state );
2382 TQWidget* Workspace::desktopWidget()
2384 return desktop_widget;
2388 void Workspace::delayFocus()
2390 requestFocus( delayfocus_client );
2394 void Workspace::requestDelayFocus( Client* c )
2396 delayfocus_client = c;
2397 delete delayFocusTimer;
2398 delayFocusTimer =
new TQTimer(
this );
2399 connect( delayFocusTimer, TQ_SIGNAL( timeout() ),
this, TQ_SLOT( delayFocus() ) );
2400 delayFocusTimer->start( options->delayFocusInterval, TRUE );
2403 void Workspace::cancelDelayFocus()
2405 delete delayFocusTimer;
2406 delayFocusTimer = 0;
2416 void Workspace::updateActiveBorders()
2418 active_time_first = get_tqt_x_time();
2419 active_time_last = get_tqt_x_time();
2420 active_time_last_trigger = get_tqt_x_time();
2421 active_current_border = ActiveNone;
2422 TQRect r = TQApplication::desktop()->geometry();
2423 activeTop = r.top();
2424 activeBottom = r.bottom();
2425 activeLeft = r.left();
2426 activeRight = r.right();
2428 for (
int pos = 0; pos < ACTIVE_BORDER_COUNT; ++pos)
2430 if (active_reserved[pos] == 0)
2432 if (active_windows[pos] != None)
2434 XDestroyWindow( tqt_xdisplay(), active_windows[pos] );
2436 active_windows[pos] = None;
2440 if (active_windows[pos] != None)
2445 XSetWindowAttributes attributes;
2446 attributes.override_redirect = True;
2447 attributes.event_mask = EnterWindowMask;
2448 unsigned long valuemask = CWOverrideRedirect | CWEventMask;
2449 int xywh[ ACTIVE_BORDER_COUNT ][ 4 ] =
2451 { r.left() + 1, r.top(), r.width() - 2, 1 },
2452 { r.right(), r.top(), 1, 1 },
2453 { r.right(), r.top() + 1, 1, r.height() - 2 },
2454 { r.right(), r.bottom(), 1, 1 },
2455 { r.left() + 1, r.bottom(), r.width() - 2, 1 },
2456 { r.left(), r.bottom(), 1, 1 },
2457 { r.left(), r.top() + 1, 1, r.height() - 2 },
2458 { r.left(), r.top(), 1, 1 }
2460 active_windows[pos] = XCreateWindow(tqt_xdisplay(), tqt_xrootwin(),
2461 xywh[pos][0], xywh[pos][1],
2462 xywh[pos][2], xywh[pos][3],
2463 0, CopyFromParent, InputOnly,
2464 CopyFromParent, valuemask,
2466 XMapWindow(tqt_xdisplay(), active_windows[pos]);
2470 XChangeProperty(tqt_xdisplay(), active_windows[pos],
2471 atoms->xdnd_aware, XA_ATOM, 32, PropModeReplace,
2472 (
unsigned char*)&version, 1);
2476 void Workspace::destroyActiveBorders()
2478 for (
int pos = 0; pos < ACTIVE_BORDER_COUNT; ++pos)
2480 if (active_windows[ pos ] != None)
2482 XDestroyWindow( tqt_xdisplay(), active_windows[ pos ] );
2484 active_windows[ pos ] = None;
2488 void Workspace::reserveActiveBorderSwitching(
bool reserve )
2490 for (
int pos = 0; pos < ACTIVE_BORDER_COUNT; ++pos)
2494 reserveActiveBorder(
static_cast<ActiveBorder
>(pos));
2498 unreserveActiveBorder(
static_cast<ActiveBorder
>(pos));
2503 void Workspace::reserveActiveBorder( ActiveBorder border )
2505 if (border == ActiveNone)
2508 if (active_reserved[border]++ == 0)
2509 TQTimer::singleShot(0,
this, TQ_SLOT(updateActiveBorders()));
2512 void Workspace::unreserveActiveBorder( ActiveBorder border )
2514 if (border == ActiveNone)
2517 assert(active_reserved[ border ] > 0);
2518 if (--active_reserved[ border ] == 0)
2519 TQTimer::singleShot(0,
this, TQ_SLOT(updateActiveBorders()));
2522 void Workspace::checkActiveBorder(
const TQPoint &pos, Time now)
2524 Time treshold_set = options->activeBorderDelay();
2525 Time treshold_trigger = 250;
2526 Time treshold_reset = 250;
2527 int activation_distance = options->borderActivationDistance();
2529 bool have_borders =
false;
2530 for (
int i = 0; i < ACTIVE_BORDER_COUNT; ++i)
2532 if (active_windows[ i ] != None)
2534 have_borders =
true;
2537 if (!have_borders) {
2542 int distance_reset = activation_distance + 10;
2545 if (active_current_border != ActiveNone &&
2546 (pos.x() > activeLeft + distance_reset) &&
2547 (pos.x() < activeRight - distance_reset) &&
2548 (pos.y() > activeTop + distance_reset) &&
2549 (pos.y() < activeBottom - distance_reset))
2552 (options->activeBorders() == Options::ActiveTileMaximize ||
2553 options->activeBorders() == Options::ActiveTileOnly))
2555 movingClient->cancelActiveBorderMaximizing();
2562 bool active_left = pos.x() < activeLeft + activation_distance;
2563 bool active_right = pos.x() > activeRight - activation_distance;
2564 bool active_top = pos.y() < activeTop + activation_distance;
2565 bool active_bottom = pos.y() > activeBottom - activation_distance;
2567 if (!active_left && !active_right && !active_top && !active_bottom)
2575 int active_width_quart = (activeRight - activeLeft) / 4;
2576 int active_height_quart = (activeBottom - activeTop) / 4;
2578 bool active_qleft =
false;
2579 bool active_qright =
false;
2580 bool active_qtop =
false;
2581 bool active_qbottom =
false;
2582 if (options->activeBorders() == Options::ActiveTileMaximize ||
2583 options->activeBorders() == Options::ActiveTileOnly)
2585 active_qleft = pos.x() < activeLeft + active_width_quart;
2586 active_qright = pos.x() > activeRight - active_width_quart;
2587 active_qtop = pos.y() < activeTop + active_height_quart;
2588 active_qbottom = pos.y() > activeBottom - active_height_quart;
2591 ActiveBorder border = ActiveNone;
2592 if ((active_left && active_qtop) || (active_top && active_qleft))
2594 border = ActiveTopLeft;
2596 else if ((active_right && active_qtop) || (active_top && active_qright))
2598 border = ActiveTopRight;
2600 else if ((active_left && active_qbottom) || (active_bottom && active_qleft))
2602 border = ActiveBottomLeft;
2604 else if ((active_right && active_qbottom) || (active_bottom && active_qright))
2606 border = ActiveBottomRight;
2608 else if (active_left)
2610 border = ActiveLeft;
2612 else if (active_right)
2614 border = ActiveRight;
2616 else if (active_top)
2620 else if (active_bottom)
2622 border = ActiveBottom;
2630 if( active_windows[border] == None )
2635 if ((active_current_border == border) &&
2636 (timestampDiff(active_time_last, now) < treshold_reset) &&
2637 (timestampDiff(active_time_last_trigger, now) > treshold_trigger) &&
2638 ((pos-active_push_point).manhattanLength() < distance_reset))
2640 active_time_last = now;
2641 if (timestampDiff(active_time_first, now) > treshold_set)
2643 active_time_last_trigger = now;
2644 active_current_border = ActiveNone;
2645 bool isSide = (border == ActiveTop || border == ActiveRight ||
2646 border == ActiveBottom || border == ActiveLeft);
2651 if (options->activeBorders() == Options::ActiveSwitchAlways ||
2652 options->activeBorders() == Options::ActiveSwitchOnMove)
2654 activeBorderSwitchDesktop(border, pos);
2659 else if (options->activeBorders() == Options::ActiveTileMaximize &&
2660 border == ActiveTop && movingClient->isMaximizable())
2662 if (!movingClient->isResizable())
return;
2663 movingClient->setActiveBorderMode(ActiveMaximizeMode);
2664 movingClient->setActiveBorder(ActiveNone);
2665 movingClient->setActiveBorderMaximizing(
true);
2669 else if ((options->activeBorders() == Options::ActiveTileMaximize ||
2670 options->activeBorders() == Options::ActiveTileOnly))
2672 if (!movingClient->isResizable())
return;
2673 movingClient->setActiveBorderMode(ActiveTilingMode);
2674 movingClient->setActiveBorder(border);
2675 movingClient->setActiveBorderMaximizing(
true);
2686 if (options->activeBorders() == Options::ActiveSwitchAlways && isSide)
2688 activeBorderSwitchDesktop(border, pos);
2696 active_current_border = border;
2697 active_time_first = now;
2698 active_time_last = now;
2699 active_push_point = pos;
2702 if ((options->activeBorders() == Options::ActiveSwitchAlways && !movingClient) ||
2703 activation_distance < 2)
2707 const int xdiff[ ACTIVE_BORDER_COUNT ] = { 0, -1, -1, -1, 0, 1, 1, 1 };
2708 const int ydiff[ ACTIVE_BORDER_COUNT ] = { 1, 1, 0, -1, -1, -1, 0, 1 };
2709 TQCursor::setPos(pos.x() + xdiff[border], pos.y() + ydiff[border]);
2713 void Workspace::activeBorderSwitchDesktop(ActiveBorder border,
const TQPoint& _pos)
2716 TQRect r = TQApplication::desktop()->geometry();
2717 const int offset = 5;
2719 int desk_before = currentDesktop();
2720 if (border == ActiveLeft || border == ActiveTopLeft || border == ActiveBottomLeft)
2722 slotSwitchDesktopLeft();
2723 pos.setX(r.width() - offset);
2725 if (border == ActiveRight || border == ActiveTopRight || border == ActiveBottomRight)
2727 slotSwitchDesktopRight();
2731 if (border == ActiveTop || border == ActiveTopLeft || border == ActiveTopRight)
2733 slotSwitchDesktopUp();
2734 pos.setY(r.height() - offset);
2736 if (border == ActiveBottom || border == ActiveBottomLeft || border == ActiveBottomRight)
2738 slotSwitchDesktopDown();
2742 if (currentDesktop() != desk_before)
2744 TQCursor::setPos(pos);
2750 bool Workspace::activeBorderEvent(XEvent *e)
2752 if (e->type == EnterNotify)
2754 for (
int i = 0; i < ACTIVE_BORDER_COUNT; ++i)
2756 if (active_windows[i] != None && e->xcrossing.window == active_windows[i])
2758 checkActiveBorder(TQPoint(e->xcrossing.x_root, e->xcrossing.y_root), e->xcrossing.time);
2763 if (e->type == ClientMessage)
2765 if (e->xclient.message_type == atoms->xdnd_position)
2767 for (
int i = 0; i < ACTIVE_BORDER_COUNT; ++i)
2769 if (active_windows[i] != None && e->xclient.window == active_windows[i])
2772 checkActiveBorder(TQPoint(e->xclient.data.l[2]>>16, e->xclient.data.l[2]&0xffff), get_tqt_x_time());
2781 void Workspace::addTopMenu( Client* c )
2783 assert( c->isTopMenu());
2784 assert( !topmenus.contains( c ));
2785 topmenus.append( c );
2786 if( managingTopMenus())
2788 int minsize = c->minSize().height();
2789 if( minsize > topMenuHeight())
2791 topmenu_height = minsize;
2792 updateTopMenuGeometry();
2794 updateTopMenuGeometry( c );
2795 updateCurrentTopMenu();
2800 void Workspace::removeTopMenu( Client* c )
2804 assert( c->isTopMenu());
2805 assert( topmenus.contains( c ));
2806 topmenus.remove( c );
2807 updateCurrentTopMenu();
2811 void Workspace::lostTopMenuSelection()
2815 disconnect( topmenu_watcher, TQ_SIGNAL( lostOwner()),
this, TQ_SLOT( lostTopMenuOwner()));
2816 connect( topmenu_watcher, TQ_SIGNAL( lostOwner()),
this, TQ_SLOT( lostTopMenuOwner()));
2817 if( !managing_topmenus )
2819 connect( topmenu_watcher, TQ_SIGNAL( lostOwner()),
this, TQ_SLOT( lostTopMenuOwner()));
2820 disconnect( topmenu_selection, TQ_SIGNAL( lostOwnership()),
this, TQ_SLOT( lostTopMenuSelection()));
2821 managing_topmenus =
false;
2822 delete topmenu_space;
2823 topmenu_space = NULL;
2825 for( ClientList::ConstIterator it = topmenus.begin();
2826 it != topmenus.end();
2828 (*it)->checkWorkspacePosition();
2831 void Workspace::lostTopMenuOwner()
2833 if( !options->topMenuEnabled())
2836 if( !topmenu_selection->claim(
false ))
2842 setupTopMenuHandling();
2845 void Workspace::setupTopMenuHandling()
2847 if( managing_topmenus )
2849 connect( topmenu_selection, TQ_SIGNAL( lostOwnership()),
this, TQ_SLOT( lostTopMenuSelection()));
2850 disconnect( topmenu_watcher, TQ_SIGNAL( lostOwner()),
this, TQ_SLOT( lostTopMenuOwner()));
2851 managing_topmenus =
true;
2852 topmenu_space =
new TQWidget;
2854 stack[ 0 ] = supportWindow->winId();
2855 stack[ 1 ] = topmenu_space->winId();
2856 XRestackWindows(tqt_xdisplay(), stack, 2);
2857 updateTopMenuGeometry();
2858 topmenu_space->show();
2860 updateCurrentTopMenu();
2863 int Workspace::topMenuHeight()
const
2865 if( topmenu_height == 0 )
2868 tmpmenu.insertItem(
"dummy" );
2869 topmenu_height = tmpmenu.sizeHint().height();
2871 return topmenu_height;
2874 KDecoration* Workspace::createDecoration( KDecorationBridge* bridge )
2876 return mgr->createDecoration( bridge );
2879 TQString Workspace::desktopName(
int desk )
const
2881 return TQString::fromUtf8( rootInfo->desktopName( desk ) );
2884 bool Workspace::checkStartupNotification( Window w, TDEStartupInfoId&
id, TDEStartupInfoData& data )
2886 return startup->checkStartup( w,
id, data ) == TDEStartupInfo::Match;
2893 void Workspace::focusToNull()
2895 XSetInputFocus(tqt_xdisplay(), null_focus_window, RevertToPointerRoot, get_tqt_x_time() );
2898 void Workspace::helperDialog(
const TQString& message,
const Client* c )
2902 if( message ==
"noborderaltf3" )
2904 TQString shortcut = TQString(
"%1 (%2)" ).arg( keys->label(
"Window Operations Menu" ))
2905 .arg( keys->shortcut(
"Window Operations Menu" ).seq( 0 ).toString());
2906 args <<
"--msgbox" <<
2907 i18n(
"You have selected to show a window without its border.\n"
2908 "Without the border, you will not be able to enable the border "
2909 "again using the mouse: use the window operations menu instead, "
2910 "activated using the %1 keyboard shortcut." )
2912 type =
"altf3warning";
2914 else if( message ==
"fullscreenaltf3" )
2916 TQString shortcut = TQString(
"%1 (%2)" ).arg( keys->label(
"Window Operations Menu" ))
2917 .arg( keys->shortcut(
"Window Operations Menu" ).seq( 0 ).toString());
2918 args <<
"--msgbox" <<
2919 i18n(
"You have selected to show a window in fullscreen mode.\n"
2920 "If the application itself does not have an option to turn the fullscreen "
2921 "mode off you will not be able to disable it "
2922 "again using the mouse: use the window operations menu instead, "
2923 "activated using the %1 keyboard shortcut." )
2925 type =
"altf3warning";
2930 proc <<
"kdialog" << args;
2931 if( !type.isEmpty())
2933 TDEConfig cfg(
"twin_dialogsrc" );
2934 cfg.setGroup(
"Notification Messages" );
2935 if( !cfg.readBoolEntry( type,
true ))
2937 proc <<
"--dontagain" <<
"twin_dialogsrc:" + type;
2940 proc <<
"--embed" << TQString::number( c->window());
2941 proc.start( TDEProcess::DontCare );
2947 void Workspace::startKompmgr()
2952 unsigned long length, after;
2953 unsigned char* data_root;
2955 prop_root = XInternAtom(tqt_xdisplay(),
"_XROOTPMAP_ID", False);
2956 if( XGetWindowProperty( tqt_xdisplay(), tqt_xrootwin(), prop_root, 0L, 1L, False, AnyPropertyType, &type, &format, &length, &after, &data_root) == Success && data_root != NULL ) {
2961 TQTimer::singleShot( 200,
this, TQ_SLOT(startKompmgr()) );
2964 pid_t kompmgrpid = getCompositorPID();
2965 if (kompmgrpid && kill(kompmgrpid, 0) >= 0)
2970 if (!kompmgr || kompmgr->isRunning()) {
2971 kompmgrReloadSettings();
2974 if (!kompmgr->start(TDEProcess::OwnGroup, TDEProcess::Stderr))
2976 options->useTranslucency = FALSE;
2978 proc <<
"kdialog" <<
"--error"
2979 << i18n(
"The Composite Manager could not be started.\\nMake sure you have \"" TDE_COMPOSITOR_BINARY
"\" in a $PATH directory.")
2980 <<
"--title" <<
"Composite Manager Failure";
2981 proc.start(TDEProcess::DontCare);
2985 delete kompmgr_selection;
2986 char selection_name[ 100 ];
2987 sprintf( selection_name,
"_NET_WM_CM_S%d", DefaultScreen( tqt_xdisplay()));
2988 kompmgr_selection =
new TDESelectionOwner( selection_name );
2989 connect( kompmgr_selection, TQ_SIGNAL( lostOwnership()), TQ_SLOT( stopKompmgr()));
2990 kompmgr_selection->claim(
true );
2991 connect(kompmgr, TQ_SIGNAL(processExited(TDEProcess*)), TQ_SLOT(restartKompmgr(TDEProcess*)));
2992 options->useTranslucency = TRUE;
2996 TQDataStream arg(ba, IO_WriteOnly);
2998 kapp->dcopClient()->emitDCOPSignal(
"default",
"kompmgrStarted()", ba);
3000 if (popup){
delete popup; popup = 0L; }
3003 void Workspace::stopKompmgr()
3005 if (!kompmgr || !kompmgr->isRunning()) {
3008 delete kompmgr_selection;
3009 kompmgr_selection = NULL;
3010 kompmgr->disconnect(
this, TQ_SLOT(restartKompmgr(TDEProcess*)));
3011 options->useTranslucency = FALSE;
3012 if (popup){
delete popup; popup = 0L; }
3013 kompmgr->kill(SIGKILL);
3015 TQDataStream arg(ba, IO_WriteOnly);
3017 kapp->dcopClient()->emitDCOPSignal(
"default",
"kompmgrStopped()", ba);
3020 void Workspace::kompmgrReloadSettings()
3022 if (!kompmgr || !kompmgr->isRunning()) {
3025 kompmgr->kill(SIGUSR2);
3028 bool Workspace::kompmgrIsRunning()
3030 return kompmgr && kompmgr->isRunning();
3033 void Workspace::unblockKompmgrRestart()
3035 allowKompmgrRestart = TRUE;
3038 void Workspace::restartKompmgr( TDEProcess *proc )
3042 if (proc->signalled()) {
3043 int exit_signal_number = proc->exitSignal();
3044 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) ) {
3050 if (!allowKompmgrRestart)
3052 delete kompmgr_selection;
3053 kompmgr_selection = NULL;
3054 options->useTranslucency = FALSE;
3057 proc <<
"kdialog" <<
"--error"
3058 << i18n(
"The Composite Manager crashed twice within a minute and is therefore disabled for this session.")
3059 <<
"--title" << i18n(
"Composite Manager Failure");
3060 proc.start(TDEProcess::DontCare);
3074 if (!kompmgr->start(TDEProcess::NotifyOnExit, TDEProcess::Stderr))
3076 delete kompmgr_selection;
3077 kompmgr_selection = NULL;
3078 options->useTranslucency = FALSE;
3080 proc <<
"kdialog" <<
"--error"
3081 << i18n(
"The Composite Manager could not be started.\\nMake sure you have \"" TDE_COMPOSITOR_BINARY
"\" in a $PATH directory.")
3082 <<
"--title" << i18n(
"Composite Manager Failure");
3083 proc.start(TDEProcess::DontCare);
3087 allowKompmgrRestart = FALSE;
3088 TQTimer::singleShot( 60000,
this, TQ_SLOT(unblockKompmgrRestart()) );
3093 void Workspace::handleKompmgrOutput( TDEProcess* ,
char *buffer,
int buflen)
3096 TQString output = TQString::fromLocal8Bit( buffer, buflen );
3097 if (output.contains(
"Started",
false))
3099 else if (output.contains(
"Can't open display",
false))
3100 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>");
3101 else if (output.contains(
"No render extension",
false))
3102 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>");
3103 else if (output.contains(
"No composite extension",
false))
3104 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>"
3105 "<i>Section \"Extensions\"<br>"
3106 "Option \"Composite\" \"Enable\"<br>"
3107 "EndSection</i></qt>");
3108 else if (output.contains(
"No damage extension",
false))
3109 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>");
3110 else if (output.contains(
"No XFixes extension",
false))
3111 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>");
3114 kompmgr->closeStderr();
3115 disconnect(kompmgr, TQ_SIGNAL(receivedStderr(TDEProcess*,
char*,
int)),
this, TQ_SLOT(handleKompmgrOutput(TDEProcess*,
char*,
int)));
3116 if( !message.isEmpty())
3119 proc <<
"kdialog" <<
"--error"
3121 <<
"--title" << i18n(
"Composite Manager Failure");
3122 proc.start(TDEProcess::DontCare);
3126 void Workspace::setOpacity(
unsigned long winId,
unsigned int opacityPercent)
3128 if (opacityPercent > 100) opacityPercent = 100;
3129 for( ClientList::ConstIterator it = stackingOrder().begin(); it != stackingOrder().end(); it++ )
3130 if (winId == (*it)->window())
3132 (*it)->setOpacity(opacityPercent < 100, (
unsigned int)((opacityPercent/100.0)*0xFFFFFFFF));
3137 void Workspace::setShadowSize(
unsigned long winId,
unsigned int shadowSizePercent)
3140 if (shadowSizePercent > 400) shadowSizePercent = 400;
3141 for( ClientList::ConstIterator it = stackingOrder().begin(); it != stackingOrder().end(); it++ )
3142 if (winId == (*it)->window())
3144 (*it)->setShadowSize(shadowSizePercent);
3149 void Workspace::setUnshadowed(
unsigned long winId)
3151 for( ClientList::ConstIterator it = stackingOrder().begin(); it != stackingOrder().end(); it++ )
3152 if (winId == (*it)->window())
3154 (*it)->setShadowSize(0);
3159 void Workspace::setShowingDesktop(
bool showing )
3161 rootInfo->setShowingDesktop( showing );
3162 showing_desktop = showing;
3163 ++block_showing_desktop;
3164 if( showing_desktop )
3166 showing_desktop_clients.clear();
3168 ClientList cls = stackingOrder();
3171 for( ClientList::ConstIterator it = cls.begin();
3175 if( (*it)->isOnCurrentDesktop() && (*it)->isShown(
true ) && !(*it)->isSpecialWindow())
3176 showing_desktop_clients.prepend( *it );
3178 for( ClientList::ConstIterator it = showing_desktop_clients.begin();
3179 it != showing_desktop_clients.end();
3181 (*it)->minimize(
true);
3183 if( Client* desk = findDesktop(
true, currentDesktop()))
3184 requestFocus( desk );
3188 for( ClientList::ConstIterator it = showing_desktop_clients.begin();
3189 it != showing_desktop_clients.end();
3191 (*it)->unminimize(
true);
3192 if( showing_desktop_clients.count() > 0 )
3193 requestFocus( showing_desktop_clients.first());
3194 showing_desktop_clients.clear();
3196 --block_showing_desktop;
3208 void Workspace::resetShowingDesktop(
bool keep_hidden )
3210 if( block_showing_desktop > 0 )
3212 rootInfo->setShowingDesktop(
false );
3213 showing_desktop =
false;
3214 ++block_showing_desktop;
3217 for( ClientList::ConstIterator it = showing_desktop_clients.begin();
3218 it != showing_desktop_clients.end();
3220 (*it)->unminimize(
true);
3222 showing_desktop_clients.clear();
3223 --block_showing_desktop;
3233 void Workspace::slotDisableGlobalShortcuts()
3235 if( global_shortcuts_disabled || global_shortcuts_disabled_for_client )
3236 disableGlobalShortcuts(
false );
3238 disableGlobalShortcuts(
true );
3241 static bool pending_dfc =
false;
3243 void Workspace::disableGlobalShortcutsForClient(
bool disable )
3245 if( global_shortcuts_disabled_for_client == disable )
3247 if( !global_shortcuts_disabled )
3251 KIPC::sendMessageAll( KIPC::BlockShortcuts, disable );
3256 void Workspace::disableGlobalShortcuts(
bool disable )
3258 KIPC::sendMessageAll( KIPC::BlockShortcuts, disable );
3262 void Workspace::kipcMessage(
int id,
int data )
3264 if(
id != KIPC::BlockShortcuts )
3266 if( pending_dfc && data )
3268 global_shortcuts_disabled_for_client =
true;
3269 pending_dfc =
false;
3273 global_shortcuts_disabled = data;
3274 global_shortcuts_disabled_for_client =
false;
3277 for( ClientList::ConstIterator it = clients.begin();
3278 it != clients.end();
3280 (*it)->updateMouseGrab();
3285 #include "workspace.moc"