src/workspace.cpp

Go to the documentation of this file.
00001 // See ../LICENSE.txt for license details.
00002 //
00003 // $Id: workspace.cpp 2 2007-05-16 10:38:27Z eg $
00004 
00005 extern "C" {
00006 #include <assert.h>
00007 #include <unistd.h>
00008 #include <X11/Xlib.h>
00009 }
00010 
00011 #include <map>
00012 #include <sstream>
00013 
00014 #include "workspace.h"
00015 
00016 #include "binder.h"
00017 #include "clientbar.h"
00018 #include "float.h"
00019 #include "frame.h"
00020 #include "kernel.h"
00021 #include "logger.h"
00022 #include "kernel.h"
00023 #include "monitor.h"
00024 #include "slot.h"
00025 #include "split.h"
00026 #include "statusbar.h"
00027 #include "thing.h"
00028 #include "tree.h"
00029 #include "util.h"
00030 #include "xcore.h"
00031 
00032 Workspace::Workspace(Monitor *monitor, unsigned int id, Rectangle *rect)
00033     : Rectangle(*rect), floatingClients_(monitor), frames_(monitor)
00034 {
00035     id_ = id;
00036     root_ = new Tree(0, this);
00037     isFrameMode_ = true;
00038     requestsFocus_ = false;
00039     frameIds_ = 0;
00040     monitor_ = monitor;
00041 
00042     ostringstream oss;
00043     oss << monitor->prefix() << ".workspace[" << id_ << "]";
00044     prefix_ = oss.str().c_str();
00045 
00046     isClientBarVisible_ = (Util::get(KERNEL->sessionSettings(),
00047                           prefix_ + ".clientbar") == "yes");
00048     isStatusBarVisible_ = (Util::get(KERNEL->sessionSettings(),
00049                            prefix_ + ".statusbar") == "yes");
00050 #ifdef SLOT_SUPPORT
00051     slotTabName_ = Util::get(KERNEL->sessionSettings(), prefix_ + ".slot");
00052 #endif // SLOT_SUPPORT
00053 
00054     name_ = Util::get(KERNEL->sessionSettings(), prefix_ + ".name");
00055 
00056     oss.str("");
00057     oss << "workspace my dim: " << x() << ", " << y() << ", " << width()
00058         << ", " << height();
00059     LOGDEBUG(oss.str());
00060     XCORE->sync();
00061 }
00062 
00063 Workspace::~Workspace() {
00064     delete root_;
00065 }
00066 
00067 void Workspace::focus(Thing *thing, bool raise) {
00068 
00069     if (!thing) {
00070         XCORE->setInputFocus(PointerRoot);
00071         illuminate();
00072         return;
00073     }
00074 
00075     Client *client = 0;
00076     Frame *frame = 0;
00077     if (thing->type() == Thing::CLIENT) {
00078         client = (Client *)thing;
00079         if (client->frame()) {
00080             LOGDEBUG("client has frame");
00081             frame = client->frame();
00082             frame->focus(client);
00083         }
00084     }
00085     else {
00086         frame = (Frame *)thing;
00087     }
00088 
00089     if (frame) {
00090         LOGDEBUG("focussing frame");
00091         if (raise) {
00092             for (LFrame::iterator it = frames_.begin();
00093                     it != frames_.end(); it++)
00094             {
00095                 XCORE->raise(((Frame *)*it)->window());
00096             }
00097             XCORE->raise(frame->window());
00098         }
00099         frames_.focus(frame);
00100         client = frame->focused();
00101     }
00102 
00103     if (client) {
00104         // grabbing/ungrabbing of the button
00105         Client *tc = topClient();
00106         if (tc && tc != client) {
00107             Binder::instance()->ungrabButtons(tc->clientWindow());
00108             Binder::instance()->grabButtons(tc->clientWindow(), AnyModifier);
00109         }
00110 
00111         LOGDEBUG("focussing client");
00112         client->setRequestsFocus(false);
00113 #ifdef SLOT_SUPPORT
00114         attached()->slot()->setGrabFocus(false);
00115 #endif
00116 
00117         Binder::instance()->ungrabButtons(client->clientWindow());
00118 
00119         removePushClient(client);
00120         if (!frame) {
00121             floatingClients_.focus(client);
00122         }
00123 
00124         if (raise) {
00125             XCORE->raise(client->window());
00126         }
00127 #ifdef SLOT_SUPPORT
00128         static bool isSlotOverlap =
00129             Util::get(KERNEL->commonSettings(), "slot.mode") == "overlap";
00130         if (isSlotOverlap || (isSlotVisible()
00131             && (isFrameMode_ != (bool)frame))) {
00132             XCORE->raise(monitor_->slot()->window());
00133         }
00134 #endif // SLOT_SUPPORT
00135         XCORE->setInputFocus(client->clientWindow());
00136     }
00137     isFrameMode_ = frame;
00138     illuminate();
00139 }
00140 
00141 void Workspace::hide() {
00142 
00143     for (LClient::iterator it = attached()->stickyClients()->begin();
00144          it != attached()->stickyClients()->end(); it++)
00145     {
00146         Client *client = *it;
00147         client->setAttached(0);
00148         floatingClients_.detach(client);
00149     }
00150     for (LClient::iterator it = floatingClients_.begin();
00151          it != floatingClients_.end(); it++)
00152     {
00153         (*it)->hide();
00154     }
00155 
00156     for (LFrame::iterator it = frames_.begin();
00157          it != frames_.end(); it++)
00158     {
00159         (*it)->hide();
00160     }
00161 }
00162 
00163 void Workspace::show() {
00164 
00165     for (LClient::iterator it = attached()->stickyClients()->begin();
00166          it != attached()->stickyClients()->end(); it++)
00167     {
00168         Client *client = *it;
00169         client->setAttached(this);
00170         floatingClients_.attach(client);
00171     }
00172 
00173     for (LClient::iterator it = floatingClients_.begin();
00174          it != floatingClients_.end(); it++)
00175     {
00176         (*it)->show();
00177     }
00178 
00179     for (LFrame::iterator it = frames_.begin();
00180          it != frames_.end(); it++)
00181     {
00182         (*it)->show();
00183     }
00184 
00185     focus(topClient());
00186 
00187     if (isClientBarVisible_) {
00188         attached()->clientBar()->show();
00189     }
00190     else {
00191         attached()->clientBar()->hide();
00192     }
00193     if (isStatusBarVisible_) {
00194         attached()->statusBar()->show();
00195     }
00196     else {
00197         attached()->statusBar()->hide();
00198     }
00199 #ifdef SLOT_SUPPORT
00200     Slot *slot = attached()->slot();
00201     if (isSlotVisible()) {
00202         bool doManage = (slotTabName_ != slot->tabName());
00203         slot->show(slotTabName_);
00204         if (doManage) {
00205             slot->manage();
00206         }
00207     }
00208     else {
00209         slot->hide();
00210     }
00211     slotTabName_ = slot->isVisible() ?  slot->tabName() : "";
00212 #endif // SLOT_SUPPORT
00213 }
00214 
00215 void Workspace::illuminate() {
00216 
00217     if (attached()->focused() != this) {
00218         return;
00219     }
00220 
00221     for (LClient::iterator it = floatingClients_.begin();
00222          it != floatingClients_.end(); it++)
00223     {
00224         (*it)->illuminate();
00225     }
00226 
00227     LOGDEBUG("floating clients illuminated, going to illuminate frames");
00228     for (LFrame::iterator it = frames_.begin();
00229          it != frames_.end(); it++)
00230     {
00231         (*it)->illuminate();
00232     }
00233     attached()->updateBars();
00234 }
00235 
00236 void Workspace::swapFrame(Direction dir) {
00237 
00238     Frame *frame1 = focusedFrame();
00239     Frame *frame2 = nextFrame(dir);
00240     if (!frame1 || !frame2) {
00241         return;
00242     }
00243 
00244     Tree *tree1 = frame1->tree();
00245     Tree *tree2 = frame2->tree();
00246 
00247     tree1->setFrame(frame2);
00248     tree2->setFrame(frame1);
00249     frame2->setTree(tree1);
00250     frame1->setTree(tree2);
00251     Split::adjustSize(tree1, ((dir == LEFT) || (dir == RIGHT)));
00252     Split::adjustSize(tree2, ((dir == LEFT) || (dir == RIGHT)));
00253 }
00254 
00255 void Workspace::swapClient(Direction dir) {
00256 
00257     Frame *frame1 = focusedFrame();
00258     if (!frame1) {
00259         return;
00260     }
00261 
00262     Frame *frame2 = nextFrame(dir);
00263 
00264     if (frame1 && frame2) {
00265 
00266         Client *client1 = frame1->focused();
00267         Client *client2 = frame2->focused();
00268 
00269         frame1->detach(client1);
00270         frame2->detach(client2);
00271         frame2->attach(client1);
00272         frame1->attach(client2);
00273         frame1->illuminate();
00274         frame2->illuminate();
00275     }
00276 }
00277 
00278 Tree *Workspace::neighborTree(Direction dir) {
00279 
00280     if (focusedFrame()) {
00281         return Split::neighbor(root_, focusedFrame()->tree(), dir);
00282     }
00283     return 0;
00284 }
00285 
00286 #define EPSILON 3
00287 
00288 Frame *Workspace::recentVisitedFrame(Direction dir) {
00289 
00290     if (!focusedFrame()) {
00291         return 0;
00292     }
00293     Frame *focusedFrame = this->focusedFrame();
00294     Tree *focusedTree = focusedFrame->tree();
00295     // This algorithm is somewhat magic, because it uses the
00296     // fact of the state of the globalClientStack_. 
00297     for (LClient::iterator it = globalClientStack_.begin();
00298             it != globalClientStack_.end(); it++)
00299     {
00300         Client *client = *it;
00301         Frame *frame = client->frame();
00302         if (frame && (frame != focusedFrame)) {
00303 
00304             Tree *tree = frame->tree();
00305             if (Split::isNeighbor(focusedTree, tree, dir)) {
00306                 bool isIgnore = false;
00307                 switch (dir) {
00308                 case LEFT:
00309                     isIgnore =
00310                         (int)(tree->x() + tree->width() + EPSILON) <
00311                         focusedTree->x();
00312                     isIgnore = isIgnore || (focusedTree->y() > tree->y()) ||
00313                         (focusedTree->height() < tree->height());
00314                     break;
00315                 case RIGHT:
00316                     isIgnore =
00317                         (int)(focusedTree->x() + focusedTree->width() +
00318                         EPSILON) < tree->x();
00319                     isIgnore = isIgnore || (focusedTree->y() > tree->y()) ||
00320                         (focusedTree->height() < tree->height());
00321                     break;
00322                 case UP:
00323                     isIgnore =
00324                         (int)(tree->y() + tree->height() + EPSILON) <
00325                         focusedTree->y();
00326                     isIgnore = isIgnore || (focusedTree->x() > tree->x()) ||
00327                         (focusedTree->width() < tree->width());
00328                     break;
00329                 case DOWN:
00330                     isIgnore =
00331                         (int)(focusedTree->y() + focusedTree->height() +
00332                         EPSILON) < tree->y();
00333                     isIgnore = isIgnore || (focusedTree->x() > tree->x()) ||
00334                         (focusedTree->width() < tree->width());
00335                     break;
00336                 default:
00337                     break;
00338                 }
00339                 if (!isIgnore) {
00340                     return frame;
00341                 }
00342             }
00343         }
00344     }
00345     return 0;
00346 }
00347 
00348 Frame *Workspace::nextFrame(Direction dir, bool isResize) {
00349 
00350     Tree *neighbor = neighborTree(dir);
00351 
00352     if (neighbor && isResize) { // normal case
00353         return Split::firstLeaf(neighbor);
00354     }
00355     else if (neighbor) {
00356 
00357         Frame *result = Split::firstLeaf(neighbor);
00358         Frame *recent = recentVisitedFrame(dir);
00359 
00360         if (recent && recent != result && recent != focusedFrame()) {
00361             result = recent;
00362         }
00363 
00364         return result;
00365     }
00366 
00367     return 0;
00368 }
00369 
00370 void Workspace::selectFrame(Direction dir) {
00371 
00372     Frame *next = nextFrame(dir, false);
00373 
00374     if (next) {
00375         focus(next->focused());
00376     }
00377 }
00378 
00379 void Workspace::attachFrame(Frame *frame, Direction dir) {
00380 
00381     Tree *root = root_;
00382 
00383     if (focusedFrame()) {
00384         root = focusedFrame()->tree();
00385     }
00386 
00387     Split::attach(root, frame, dir);
00388 
00389     frames_.attach(frame);
00390     frame->show();
00391 }
00392 
00393 Frame *Workspace::newFrame() {
00394 
00395     assert((frames_.size() == 0));
00396     Frame *frame = new Frame(this, this);
00397     attachFrame(frame, LEFT); // direction doesn't matter
00398 
00399     return frame;
00400 }
00401 
00402 void Workspace::attachClient(Client *client, bool isChangeMode) {
00403 
00404     if (!client->frameWindow() && client->hasDecoration()) {
00405         LOGDEBUG("creating frame window for client");
00406         client->createFrame();
00407     }
00408 
00409     client->setAttached(this);
00410     if (client->mode() == Client::MAX) {
00411         // MAX mode is only allowed with decoration
00412         Frame *frame = 0;
00413         if (isChangeMode) {
00414             frame = frameForPoint(
00415                     client->x() + client->width() / 2,
00416                     client->y() + client->height() / 2);
00417         }
00418         else {
00419             frame = focusedFrame();
00420         }
00421         if (!frame) {
00422             frame = newFrame();
00423         }
00424         frame->attach(client);
00425         focus(frame->focused());
00426         return;
00427     }
00428     else if (client->mode() == Client::STICKY) {
00429         attached()->stickyClients()->attach(client);
00430     }
00431 
00432     for (LClient::iterator it = floatingClients_.begin();
00433             it != floatingClients_.end(); it++)
00434     {
00435         if (*it == client) {
00436             return;
00437         }
00438     }
00439     floatingClients_.attach(client);
00440     if (client->frameWindow()) {
00441         client->reparent(client->frameWindow(), client->x(), client->y());
00442     }
00443     XCORE->sync();
00444     Util::fitInto(client, attached());
00445     if (!isChangeMode) {
00446         if (client->isCentered()) {
00447             Float::center(client, this);
00448         }
00449     }
00450     client->resize();
00451     client->show();
00452     focus(client);
00453 }
00454 
00455 void Workspace::destroyFrame(Frame *frame) {
00456 
00457     unsigned int i = frame->size();
00458     while (i) {
00459         Client *client = *frame->begin();
00460         attached()->detachClient(client);
00461         KERNEL->killClient(client);
00462         i--;
00463     }
00464     assert(frame->size() < 1);
00465     frames_.detach(frame);
00466     Split::detach(root_, frame->tree());
00467     delete frame;
00468     LOGDEBUG("frame destroyed");
00469 }
00470 
00471 void Workspace::sendClient(Direction dir) {
00472 
00473     Frame *from = focusedFrame();
00474     Frame *to = nextFrame(dir);
00475 
00476     if (from && to) {
00477         Client *client = from->focused();
00478         if (!from->detach(client) &&
00479             (Util::get(KERNEL->commonSettings(), "frame.autodestroy") == "yes"))
00480         {
00481             destroyFrame(from);
00482         }
00483         client->initICCCM();
00484         to->attach(client);
00485         focus(to->focused());
00486     }
00487 }
00488 
00489 void Workspace::joinFrame(Direction dir) {
00490 
00491     Frame *from = focusedFrame();
00492     Frame *to = nextFrame(dir);
00493 
00494     if (from && to) {
00495 
00496         for (unsigned int i = from->size(); i > 0; i--) {
00497             Client *client = from->focused();
00498             if (from->detach(client) == 0) {
00499                 destroyFrame(from);
00500             }
00501             client->initICCCM();
00502             to->attach(client);
00503         }
00504         focus(to->focused());
00505     }
00506 }
00507 
00508 void Workspace::splitFrame(Direction dir) {
00509 
00510     Frame *frame = focusedFrame();
00511     if (frame && frame->size() > 1) {
00512         Frame *splitFrame = new Frame(this, frame);
00513         LOGDEBUG("split frame");
00514         Client *client = frame->focused();
00515         frame->detach(client);
00516         attachFrame(splitFrame, dir);
00517         splitFrame->attach(client);
00518         focus(splitFrame->focused());
00519     }
00520 }
00521 
00522 void Workspace::resize(Thing *thing, Direction dir, bool grow) {
00523 
00524     switch (thing->type()) {
00525     case Thing::FRAME:
00526         resizeFrame(dir, grow);
00527         break;
00528     case Thing::CLIENT:
00529         if (((Client *)thing)->hasDecoration()) {
00530             resizeClient(dir, grow);
00531         }
00532         break;
00533     }
00534 }
00535 
00536 void Workspace::resizeFrame(Direction dir, bool grow) {
00537 
00538     Monitor *monitor = attached();
00539     int stepW = width() / 100 * monitor->resizeFactor();
00540     int stepH = height() / 100 * monitor->resizeFactor();
00541 
00542     if (!grow) {
00543         stepW *= -1;
00544         stepH *= -1;
00545         dir = Util::reverseDir(dir);
00546     }
00547 
00548     Split::resize(root_, focusedFrame()->tree(),
00549                   dir, stepW, stepH);
00550 }
00551 
00552 void Workspace::detachClient(Client *client) {
00553 
00554     // we need to remove all references to a sticky client on *all*
00555     // other workspaces first
00556     if (client->mode() == Client::STICKY) {
00557         for (LWorkspace::iterator it = attached()->begin();
00558                 it != attached()->end(); it++)
00559         {
00560             Workspace *workspace = *it;
00561             if (workspace == this) {
00562                 continue;
00563             }
00564             workspace->removeClient(client);
00565         }
00566         attached()->stickyClients()->detach(client);
00567     }
00568 
00569     Frame *frame = client->frame();
00570     if (frame) {
00571         if (!frame->detach(client) &&
00572             (Util::get(KERNEL->commonSettings(), "frame.autodestroy") == "yes"))
00573         {
00574             destroyFrame(frame);
00575         }
00576     }
00577     else {
00578         floatingClients_.detach(client);
00579         if (client->isVisible()) {
00580             client->hide();
00581         }
00582         client->reparent(attached()->rootWindow(),
00583                          client->x(), client->y());
00584     }
00585     LOGDEBUG("detached from containers");
00586 
00587     removeClient(client);
00588 
00589     client->setAttached(0);
00590 
00591     assert(client != topClient());
00592     if (topClient()) {
00593         focus(topClient());
00594     }
00595     else {
00596         illuminate();
00597     }
00598     LOGDEBUG("final stuff of detaching client");
00599 }
00600 
00601 Frame *Workspace::focusedFrame() const {
00602     return frames_.focused();
00603 }
00604 
00605 Thing *Workspace::thingWindow(Window window) {
00606 
00607     for (LClient::iterator it = floatingClients_.begin();
00608          it != floatingClients_.end(); it++)
00609     {
00610         Client *client = *it;
00611         if (client->frameWindow() == window) {
00612             return client;
00613         }
00614     }
00615     for (LFrame::iterator it = frames_.begin();
00616          it != frames_.end(); it++)
00617     {
00618         Frame *frame = *it;
00619         if (frame->window() == window) {
00620             return frame;
00621         }
00622     }
00623     return 0;
00624 }
00625 
00626 void Workspace::matchBarNeighbors(Direction dir) {
00627 
00628     // TODO: take care of dir
00629     // commits current workspace rectangle to root_ tree map element
00630     root_->copy(this);
00631     Split::adjustSize(root_, ((dir == LEFT) || (dir == RIGHT)));
00632 }
00633 
00634 void Workspace::lower() {
00635 
00636     Thing *thing = focusedThing();
00637 
00638     if (!thing) {
00639         return;
00640     }
00641 
00642     XCORE->lower(thing->window());
00643 }
00644 
00645 void Workspace::raise() {
00646 
00647     Client *client = topClient();
00648 
00649     if (!client) {
00650         return;
00651     }
00652 
00653     focus(client);
00654 }
00655 
00656 void Workspace::changeClientMode(Client *client, Client::Mode mode) {
00657     assert(client);
00658     detachClient(client);
00659     client->setMode(mode);
00660     attachClient(client, true);
00661 }
00662 
00663 void Workspace::toggleClientMode() {
00664     Client *client = topClient();
00665     if (client) {
00666         changeClientMode(client, (client->mode() == Client::MAX) ?
00667                                  Client::FLOAT : Client::MAX);
00668     }
00669 }
00670 
00671 void Workspace::toggleClientSticky() {
00672     Client *client = topClient();
00673     if (client) {
00674         if (client->mode() != Client::STICKY) {
00675             changeClientMode(client, Client::STICKY);
00676         }
00677         else {
00678             changeClientMode(client, Client::FLOAT);
00679         }
00680     }
00681 }
00682 
00683 void Workspace::resizeClient(Direction dir, bool grow) {
00684 
00685     Client *client = topClient();
00686     if (!client || !client->hasDecoration()) {
00687         return;
00688     }
00689 
00690     Monitor *monitor = attached();
00691 
00692     int stepW = width() / 100 * monitor->resizeFactor();
00693     int stepH = height() / 100 * monitor->resizeFactor();
00694 
00695     if ((dir == LEFT) || (dir == UP)) {
00696         stepW *= -1;
00697         stepH *= -1;
00698     }
00699 
00700     Float::resize(client, grow ? dir : Util::reverseDir(dir),
00701                   stepW, stepH);
00702 
00703     client->resize();
00704 }
00705 
00706 void Workspace::moveClient(Direction dir) {
00707 
00708     Client *client = topClient();
00709     if (!client) {
00710         return;
00711     }
00712 
00713     Monitor *monitor = attached();
00714 
00715     // review: correct
00716     int stepW = width() / 100 * monitor->resizeFactor();
00717     int stepH = height() / 100 * monitor->resizeFactor();
00718 
00719     if ((dir == LEFT) || (dir == UP)) {
00720         stepW *= -1;
00721         stepH *= -1;
00722     }
00723 
00724     if ((dir == LEFT) || (dir == RIGHT)) {
00725         Float::move(client, stepW, 0);
00726     }
00727     else {
00728         Float::move(client, 0, stepH);
00729     }
00730 
00731     client->resize();
00732 }
00733 
00734 
00735 void Workspace::serialize() {
00736 
00737     (*KERNEL->sessionSettings())[prefix_ + ".name"] = name_;
00738     (*KERNEL->sessionSettings())[prefix_ + ".clientbar"] =
00739         isClientBarVisible_ ? "yes" : "no";
00740     (*KERNEL->sessionSettings())[prefix_ + ".statusbar"] =
00741         isStatusBarVisible_ ? "yes" : "no";
00742 #ifdef SLOT_SUPPORT
00743     (*KERNEL->sessionSettings())[prefix_ + ".slot"] = slotTabName_;
00744 #endif // SLOT_SUPPORT
00745 }
00746 
00747 Frame *Workspace::frameForPoint(unsigned int x, unsigned int y) {
00748 
00749     for (LFrame::iterator it = frames_.begin();
00750          it != frames_.end(); it++)
00751     {
00752         Frame *frame = *it;
00753         if (Util::isPointWithinRect(x, y, frame, this)) {
00754             return frame;
00755         }
00756     }
00757     return focusedFrame();
00758 }
00759 
00760 void Workspace::toggleBorders(bool visible) {
00761 
00762     for (LFrame::iterator it = frames_.begin();
00763             it != frames_.end(); it++)
00764     {
00765         Frame *frame = *it;
00766         frame->setBorderWidth(visible ? KERNEL->borderWidth() : 0);
00767         frame->resize();
00768     }
00769     for (LClient::iterator it = floatingClients_.begin();
00770             it != floatingClients_.end(); it++)
00771     {
00772         Client *client = *it;
00773         if (client->hasDecoration()) {
00774             client->setBorderWidth(visible ? KERNEL->borderWidth() : 0);
00775             client->resize();
00776         }
00777     }
00778 }
00779 
00780 void Workspace::toggleBars(bool visible) {
00781 
00782     for (LFrame::iterator it = frames_.begin();
00783             it != frames_.end(); it++)
00784     {
00785         Frame *frame = *it;
00786         frame->setTitleBarHeight(visible ? attached()->titleBarHeight() : 0);
00787         frame->resize();
00788     }
00789     for (LClient::iterator it = floatingClients_.begin();
00790             it != floatingClients_.end(); it++)
00791     {
00792         Client *client = *it;
00793         if (client->hasDecoration()) {
00794             client->setTitleBarHeight(visible ? attached()->titleBarHeight() : 0);
00795             client->resize();
00796         }
00797     }
00798 }
00799 
00800 void Workspace::cycleClientNext() {
00801 
00802     if (isFrameMode_) {
00803         if (focusedFrame()) {
00804             focus(focusedFrame()->next());
00805         }
00806     }
00807     else {
00808         focus(floatingClients_.next());
00809     }
00810 }
00811 
00812 void Workspace::cycleClientPrev() {
00813 
00814     if (isFrameMode_) {
00815         if (focusedFrame()) {
00816             focus(focusedFrame()->prev());
00817         }
00818     }
00819     else {
00820         focus(floatingClients_.prev());
00821     }
00822 }
00823 
00824 void Workspace::toggleMode() {
00825     isFrameMode_ = !isFrameMode_;
00826     if (isFrameMode_) {
00827         if (focusedFrame()) {
00828             focus(focusedFrame()->focused());
00829         }
00830         else {
00831             focus(0);
00832         }
00833     }
00834     else {
00835         for (LClient::iterator it = floatingClients_.begin();
00836              it != floatingClients_.end(); it++)
00837         {
00838             XCORE->raise(((Client *)*it)->window());
00839         }
00840         focus(floatingClients_.focused());
00841     }
00842 }
00843 
00844 void Workspace::removePushClient(Client *client) {
00845     removeClient(client);
00846     pushClient(client);
00847 }
00848 
00849 void Workspace::removeClient(Client *client) {
00850     if (stackContainsClient(client)) {
00851         globalClientStack_.remove(client);
00852     }
00853 }
00854 
00855 void Workspace::pushClient(Client *client) {
00856     if (!stackContainsClient(client)) {
00857         globalClientStack_.push_front(client);
00858     }
00859 }
00860 
00861 bool Workspace::stackContainsClient(Client *client) {
00862     for (LClient::iterator it = globalClientStack_.begin();
00863             it != globalClientStack_.end(); it++)
00864     {
00865         if (client == *it) {
00866             return true;
00867         }
00868     }
00869     return false;
00870 }
00871 
00872 Client *Workspace::topClient() {
00873 
00874 #ifdef SLOT_SUPPORT
00875     if (isSlotVisible() && attached()->slot()->isGrabFocus()) {
00876         // if the slot grabs the focus currently, this workspace
00877         // has temprarily no focussed topClient - so just return
00878         // 0.
00879         return 0;
00880     }
00881 #endif
00882     if (globalClientStack_.size()) {
00883         return globalClientStack_.front();
00884     }
00885     return 0;
00886 }
00887 
00888 unsigned int Workspace::nextFrameId() {
00889     ++frameIds_;
00890     return frameIds_;
00891 }
00892 
00893 unsigned int Workspace::id() const {
00894     return id_;
00895 }
00896 
00897 void Workspace::setName(string name) {
00898     name_ = name;
00899 }
00900 
00901 string Workspace::name() const {
00902     return name_;
00903 }
00904 
00905 string Workspace::prefix() const {
00906     return prefix_;
00907 }
00908 
00909 Tree* Workspace::root() const {
00910     return root_;
00911 }
00912 
00913 bool Workspace::isFrameMode() const {
00914     return isFrameMode_;
00915 }
00916 
00917 void Workspace::setClientBarVisible(bool visible) {
00918     isClientBarVisible_ = visible;
00919 }
00920 
00921 void Workspace::setStatusBarVisible(bool visible) {
00922     isStatusBarVisible_ = visible;
00923 }
00924 
00925 #ifdef SLOT_SUPPORT
00926 void Workspace::setSlotVisible(bool visible) {
00927     slotTabName_ = visible ?
00928         attached()->slot()->tabName() : "";
00929 }
00930 
00931 bool Workspace::isSlotVisible() const {
00932     return slotTabName_ != "";
00933 }
00934 
00935 string Workspace::slotTabName() const {
00936     return slotTabName_;
00937 }
00938 #endif // SLOT_SUPPORT
00939 
00940 Thing *Workspace::focusedThing() {
00941 
00942     Client *client = topClient();
00943     return (client && client->frame()) ? (Thing *)client->frame() :
00944         (Thing *)client;
00945 }
00946 
00947 void Workspace::fitClient() {
00948 
00949     Client *client = topClient();
00950     if (client) {
00951         Util::fitInto(client, this);
00952         client->resize();
00953     }
00954 }
00955 
00956 bool Workspace::isClientBarVisible() const {
00957     return isClientBarVisible_;
00958 }
00959 
00960 bool Workspace::isStatusBarVisible() const {
00961     return isStatusBarVisible_;
00962 }
00963 
00964 Monitor *Workspace::attached() const {
00965     return monitor_;
00966 }
00967 
00968 CClient *Workspace::floatingClients() {
00969     return &floatingClients_;
00970 }
00971 
00972 CFrame *Workspace::frames() {
00973     return &frames_;
00974 }
00975 
00976 bool Workspace::requestsFocus() const {
00977     return requestsFocus_;
00978 }
00979 
00980 void Workspace::setRequestsFocus(bool requestsFocus) {
00981     requestsFocus_ = requestsFocus;
00982 }
00983 
00984 LClient *Workspace::clients() {
00985     return &globalClientStack_;
00986 }
00987 

Generated on Thu May 24 15:19:32 2007 for ncwm by  doxygen 1.5.1