00001
00002
00003
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
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
00296
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) {
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);
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
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
00555
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
00629
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
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
00877
00878
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