workspace.cpp (23895B)
1 // Copyright (c) 2003 - 2009 Anselm R Garbe <anselm@garbe.us> 2 // See LICENSE for license details. 3 4 extern "C" { 5 #include <assert.h> 6 #include <unistd.h> 7 #include <X11/Xlib.h> 8 } 9 10 #include <map> 11 #include <sstream> 12 13 #include "workspace.h" 14 15 #include "binder.h" 16 #include "clientbar.h" 17 #include "float.h" 18 #include "frame.h" 19 #include "kernel.h" 20 #include "logger.h" 21 #include "kernel.h" 22 #include "monitor.h" 23 #include "slot.h" 24 #include "split.h" 25 #include "statusbar.h" 26 #include "thing.h" 27 #include "tree.h" 28 #include "util.h" 29 #include "xcore.h" 30 31 Workspace::Workspace(Monitor *monitor, unsigned int id, Rectangle *rect) 32 : Rectangle(*rect), floatingClients_(monitor), frames_(monitor) 33 { 34 id_ = id; 35 root_ = new Tree(0, this); 36 isFrameMode_ = true; 37 requestsFocus_ = false; 38 frameIds_ = 0; 39 monitor_ = monitor; 40 41 ostringstream oss; 42 oss << monitor->prefix() << ".workspace[" << id_ << "]"; 43 prefix_ = oss.str().c_str(); 44 45 isClientBarVisible_ = (Util::get(KERNEL->sessionSettings(), 46 prefix_ + ".clientbar") == "yes"); 47 isStatusBarVisible_ = (Util::get(KERNEL->sessionSettings(), 48 prefix_ + ".statusbar") == "yes"); 49 #ifdef SLOT_SUPPORT 50 slotTabName_ = Util::get(KERNEL->sessionSettings(), prefix_ + ".slot"); 51 #endif // SLOT_SUPPORT 52 53 name_ = Util::get(KERNEL->sessionSettings(), prefix_ + ".name"); 54 55 oss.str(""); 56 oss << "workspace my dim: " << x() << ", " << y() << ", " << width() 57 << ", " << height(); 58 LOGDEBUG(oss.str()); 59 XCORE->sync(); 60 } 61 62 Workspace::~Workspace() { 63 delete root_; 64 } 65 66 void Workspace::focus(Thing *thing, bool raise) { 67 68 if (!thing) { 69 XCORE->setInputFocus(PointerRoot); 70 illuminate(); 71 return; 72 } 73 74 Client *client = 0; 75 Frame *frame = 0; 76 if (thing->type() == Thing::CLIENT) { 77 client = (Client *)thing; 78 if (client->frame()) { 79 LOGDEBUG("client has frame"); 80 frame = client->frame(); 81 frame->focus(client); 82 } 83 } 84 else { 85 frame = (Frame *)thing; 86 } 87 88 if (frame) { 89 LOGDEBUG("focussing frame"); 90 if (raise) { 91 for (LFrame::iterator it = frames_.begin(); 92 it != frames_.end(); it++) 93 { 94 XCORE->raise(((Frame *)*it)->window()); 95 } 96 XCORE->raise(frame->window()); 97 } 98 frames_.focus(frame); 99 client = frame->focused(); 100 } 101 102 if (client) { 103 // grabbing/ungrabbing of the button 104 Client *tc = topClient(); 105 if (tc && tc != client) { 106 Binder::instance()->ungrabButtons(tc->clientWindow()); 107 Binder::instance()->grabButtons(tc->clientWindow(), AnyModifier); 108 } 109 110 LOGDEBUG("focussing client"); 111 client->setRequestsFocus(false); 112 #ifdef SLOT_SUPPORT 113 attached()->slot()->setGrabFocus(false); 114 #endif 115 116 Binder::instance()->ungrabButtons(client->clientWindow()); 117 118 removePushClient(client); 119 if (!frame) { 120 floatingClients_.focus(client); 121 } 122 123 if (raise) { 124 XCORE->raise(client->window()); 125 } 126 #ifdef SLOT_SUPPORT 127 static bool isSlotOverlap = 128 Util::get(KERNEL->commonSettings(), "slot.mode") == "overlap"; 129 if (isSlotOverlap || (isSlotVisible() 130 && (isFrameMode_ != (bool)frame))) { 131 XCORE->raise(monitor_->slot()->window()); 132 } 133 #endif // SLOT_SUPPORT 134 XCORE->setInputFocus(client->clientWindow()); 135 } 136 isFrameMode_ = frame; 137 illuminate(); 138 } 139 140 void Workspace::hide() { 141 142 for (LClient::iterator it = attached()->stickyClients()->begin(); 143 it != attached()->stickyClients()->end(); it++) 144 { 145 Client *client = *it; 146 client->setAttached(0); 147 floatingClients_.detach(client); 148 } 149 for (LClient::iterator it = floatingClients_.begin(); 150 it != floatingClients_.end(); it++) 151 { 152 (*it)->hide(); 153 } 154 155 for (LFrame::iterator it = frames_.begin(); 156 it != frames_.end(); it++) 157 { 158 (*it)->hide(); 159 } 160 } 161 162 void Workspace::show() { 163 164 for (LClient::iterator it = attached()->stickyClients()->begin(); 165 it != attached()->stickyClients()->end(); it++) 166 { 167 Client *client = *it; 168 client->setAttached(this); 169 floatingClients_.attach(client); 170 } 171 172 for (LClient::iterator it = floatingClients_.begin(); 173 it != floatingClients_.end(); it++) 174 { 175 (*it)->show(); 176 } 177 178 for (LFrame::iterator it = frames_.begin(); 179 it != frames_.end(); it++) 180 { 181 (*it)->show(); 182 } 183 184 focus(topClient()); 185 186 if (isClientBarVisible_) { 187 attached()->clientBar()->show(); 188 } 189 else { 190 attached()->clientBar()->hide(); 191 } 192 if (isStatusBarVisible_) { 193 attached()->statusBar()->show(); 194 } 195 else { 196 attached()->statusBar()->hide(); 197 } 198 #ifdef SLOT_SUPPORT 199 Slot *slot = attached()->slot(); 200 if (isSlotVisible()) { 201 bool doManage = (slotTabName_ != slot->tabName()); 202 slot->show(slotTabName_); 203 if (doManage) { 204 slot->manage(); 205 } 206 } 207 else { 208 slot->hide(); 209 } 210 slotTabName_ = slot->isVisible() ? slot->tabName() : ""; 211 #endif // SLOT_SUPPORT 212 } 213 214 void Workspace::illuminate() { 215 216 if (attached()->focused() != this) { 217 return; 218 } 219 220 for (LClient::iterator it = floatingClients_.begin(); 221 it != floatingClients_.end(); it++) 222 { 223 (*it)->illuminate(); 224 } 225 226 LOGDEBUG("floating clients illuminated, going to illuminate frames"); 227 for (LFrame::iterator it = frames_.begin(); 228 it != frames_.end(); it++) 229 { 230 (*it)->illuminate(); 231 } 232 attached()->updateBars(); 233 } 234 235 void Workspace::swapFrame(Direction dir) { 236 237 Frame *frame1 = focusedFrame(); 238 Frame *frame2 = nextFrame(dir); 239 if (!frame1 || !frame2) { 240 return; 241 } 242 243 Tree *tree1 = frame1->tree(); 244 Tree *tree2 = frame2->tree(); 245 246 tree1->setFrame(frame2); 247 tree2->setFrame(frame1); 248 frame2->setTree(tree1); 249 frame1->setTree(tree2); 250 Split::adjustSize(tree1, ((dir == LEFT) || (dir == RIGHT))); 251 Split::adjustSize(tree2, ((dir == LEFT) || (dir == RIGHT))); 252 } 253 254 void Workspace::swapClient(Direction dir) { 255 256 Frame *frame1 = focusedFrame(); 257 if (!frame1) { 258 return; 259 } 260 261 Frame *frame2 = nextFrame(dir); 262 263 if (frame1 && frame2) { 264 265 Client *client1 = frame1->focused(); 266 Client *client2 = frame2->focused(); 267 268 frame1->detach(client1); 269 frame2->detach(client2); 270 frame2->attach(client1); 271 frame1->attach(client2); 272 frame1->illuminate(); 273 frame2->illuminate(); 274 } 275 } 276 277 Tree *Workspace::neighborTree(Direction dir) { 278 279 if (focusedFrame()) { 280 return Split::neighbor(root_, focusedFrame()->tree(), dir); 281 } 282 return 0; 283 } 284 285 #define EPSILON 3 286 287 Frame *Workspace::recentVisitedFrame(Direction dir) { 288 289 if (!focusedFrame()) { 290 return 0; 291 } 292 Frame *focusedFrame = this->focusedFrame(); 293 Tree *focusedTree = focusedFrame->tree(); 294 // This algorithm is somewhat magic, because it uses the 295 // fact of the state of the globalClientStack_. 296 for (LClient::iterator it = globalClientStack_.begin(); 297 it != globalClientStack_.end(); it++) 298 { 299 Client *client = *it; 300 Frame *frame = client->frame(); 301 if (frame && (frame != focusedFrame)) { 302 303 Tree *tree = frame->tree(); 304 if (Split::isNeighbor(focusedTree, tree, dir)) { 305 bool isIgnore = false; 306 switch (dir) { 307 case LEFT: 308 isIgnore = 309 (int)(tree->x() + tree->width() + EPSILON) < 310 focusedTree->x(); 311 isIgnore = isIgnore || (focusedTree->y() > tree->y()) || 312 (focusedTree->height() < tree->height()); 313 break; 314 case RIGHT: 315 isIgnore = 316 (int)(focusedTree->x() + focusedTree->width() + 317 EPSILON) < tree->x(); 318 isIgnore = isIgnore || (focusedTree->y() > tree->y()) || 319 (focusedTree->height() < tree->height()); 320 break; 321 case UP: 322 isIgnore = 323 (int)(tree->y() + tree->height() + EPSILON) < 324 focusedTree->y(); 325 isIgnore = isIgnore || (focusedTree->x() > tree->x()) || 326 (focusedTree->width() < tree->width()); 327 break; 328 case DOWN: 329 isIgnore = 330 (int)(focusedTree->y() + focusedTree->height() + 331 EPSILON) < tree->y(); 332 isIgnore = isIgnore || (focusedTree->x() > tree->x()) || 333 (focusedTree->width() < tree->width()); 334 break; 335 default: 336 break; 337 } 338 if (!isIgnore) { 339 return frame; 340 } 341 } 342 } 343 } 344 return 0; 345 } 346 347 Frame *Workspace::nextFrame(Direction dir, bool isResize) { 348 349 Tree *neighbor = neighborTree(dir); 350 351 if (neighbor && isResize) { // normal case 352 return Split::firstLeaf(neighbor); 353 } 354 else if (neighbor) { 355 356 Frame *result = Split::firstLeaf(neighbor); 357 Frame *recent = recentVisitedFrame(dir); 358 359 if (recent && recent != result && recent != focusedFrame()) { 360 result = recent; 361 } 362 363 return result; 364 } 365 366 return 0; 367 } 368 369 void Workspace::selectFrame(Direction dir) { 370 371 Frame *next = nextFrame(dir, false); 372 373 if (next) { 374 focus(next->focused()); 375 } 376 } 377 378 void Workspace::attachFrame(Frame *frame, Direction dir) { 379 380 Tree *root = root_; 381 382 if (focusedFrame()) { 383 root = focusedFrame()->tree(); 384 } 385 386 Split::attach(root, frame, dir); 387 388 frames_.attach(frame); 389 frame->show(); 390 } 391 392 Frame *Workspace::newFrame() { 393 394 assert((frames_.size() == 0)); 395 Frame *frame = new Frame(this, this); 396 attachFrame(frame, LEFT); // direction doesn't matter 397 398 return frame; 399 } 400 401 void Workspace::attachClient(Client *client, bool isChangeMode) { 402 403 if (!client->frameWindow() && client->hasDecoration()) { 404 LOGDEBUG("creating frame window for client"); 405 client->createFrame(); 406 } 407 408 client->setAttached(this); 409 if (client->mode() == Client::MAX) { 410 // MAX mode is only allowed with decoration 411 Frame *frame = 0; 412 if (isChangeMode) { 413 frame = frameForPoint( 414 client->x() + client->width() / 2, 415 client->y() + client->height() / 2); 416 } 417 else { 418 frame = focusedFrame(); 419 } 420 if (!frame) { 421 frame = newFrame(); 422 } 423 frame->attach(client); 424 focus(frame->focused()); 425 return; 426 } 427 else if (client->mode() == Client::STICKY) { 428 attached()->stickyClients()->attach(client); 429 } 430 431 for (LClient::iterator it = floatingClients_.begin(); 432 it != floatingClients_.end(); it++) 433 { 434 if (*it == client) { 435 return; 436 } 437 } 438 floatingClients_.attach(client); 439 if (client->frameWindow()) { 440 client->reparent(client->frameWindow(), client->x(), client->y()); 441 } 442 XCORE->sync(); 443 Util::fitInto(client, attached()); 444 if (!isChangeMode) { 445 if (client->isCentered()) { 446 Float::center(client, this); 447 } 448 } 449 client->resize(); 450 client->show(); 451 focus(client); 452 } 453 454 void Workspace::destroyFrame(Frame *frame) { 455 456 unsigned int i = frame->size(); 457 while (i) { 458 Client *client = *frame->begin(); 459 attached()->detachClient(client); 460 KERNEL->killClient(client); 461 i--; 462 } 463 assert(frame->size() < 1); 464 frames_.detach(frame); 465 Split::detach(root_, frame->tree()); 466 delete frame; 467 LOGDEBUG("frame destroyed"); 468 } 469 470 void Workspace::sendClient(Direction dir) { 471 472 Frame *from = focusedFrame(); 473 Frame *to = nextFrame(dir); 474 475 if (from && to) { 476 Client *client = from->focused(); 477 if (!from->detach(client) && 478 (Util::get(KERNEL->commonSettings(), "frame.autodestroy") == "yes")) 479 { 480 destroyFrame(from); 481 } 482 client->initICCCM(); 483 to->attach(client); 484 focus(to->focused()); 485 } 486 } 487 488 void Workspace::joinFrame(Direction dir) { 489 490 Frame *from = focusedFrame(); 491 Frame *to = nextFrame(dir); 492 493 if (from && to) { 494 495 for (unsigned int i = from->size(); i > 0; i--) { 496 Client *client = from->focused(); 497 if (from->detach(client) == 0) { 498 destroyFrame(from); 499 } 500 client->initICCCM(); 501 to->attach(client); 502 } 503 focus(to->focused()); 504 } 505 } 506 507 void Workspace::splitFrame(Direction dir) { 508 509 Frame *frame = focusedFrame(); 510 if (frame && frame->size() > 1) { 511 Frame *splitFrame = new Frame(this, frame); 512 LOGDEBUG("split frame"); 513 Client *client = frame->focused(); 514 frame->detach(client); 515 attachFrame(splitFrame, dir); 516 splitFrame->attach(client); 517 focus(splitFrame->focused()); 518 } 519 } 520 521 void Workspace::resize(Thing *thing, Direction dir, bool grow) { 522 523 switch (thing->type()) { 524 case Thing::FRAME: 525 resizeFrame(dir, grow); 526 break; 527 case Thing::CLIENT: 528 if (((Client *)thing)->hasDecoration()) { 529 resizeClient(dir, grow); 530 } 531 break; 532 } 533 } 534 535 void Workspace::resizeFrame(Direction dir, bool grow) { 536 537 Monitor *monitor = attached(); 538 int stepW = width() / 100 * monitor->resizeFactor(); 539 int stepH = height() / 100 * monitor->resizeFactor(); 540 541 if (!grow) { 542 stepW *= -1; 543 stepH *= -1; 544 dir = Util::reverseDir(dir); 545 } 546 547 Split::resize(root_, focusedFrame()->tree(), 548 dir, stepW, stepH); 549 } 550 551 void Workspace::detachClient(Client *client) { 552 553 // we need to remove all references to a sticky client on *all* 554 // other workspaces first 555 if (client->mode() == Client::STICKY) { 556 for (LWorkspace::iterator it = attached()->begin(); 557 it != attached()->end(); it++) 558 { 559 Workspace *workspace = *it; 560 if (workspace == this) { 561 continue; 562 } 563 workspace->removeClient(client); 564 } 565 attached()->stickyClients()->detach(client); 566 } 567 568 Frame *frame = client->frame(); 569 if (frame) { 570 if (!frame->detach(client) && 571 (Util::get(KERNEL->commonSettings(), "frame.autodestroy") == "yes")) 572 { 573 destroyFrame(frame); 574 } 575 } 576 else { 577 floatingClients_.detach(client); 578 if (client->isVisible()) { 579 client->hide(); 580 } 581 client->reparent(attached()->rootWindow(), 582 client->x(), client->y()); 583 } 584 LOGDEBUG("detached from containers"); 585 586 removeClient(client); 587 588 client->setAttached(0); 589 590 assert(client != topClient()); 591 if (topClient()) { 592 focus(topClient()); 593 } 594 else { 595 illuminate(); 596 } 597 LOGDEBUG("final stuff of detaching client"); 598 } 599 600 Frame *Workspace::focusedFrame() const { 601 return frames_.focused(); 602 } 603 604 Thing *Workspace::thingWindow(Window window) { 605 606 for (LClient::iterator it = floatingClients_.begin(); 607 it != floatingClients_.end(); it++) 608 { 609 Client *client = *it; 610 if (client->frameWindow() == window) { 611 return client; 612 } 613 } 614 for (LFrame::iterator it = frames_.begin(); 615 it != frames_.end(); it++) 616 { 617 Frame *frame = *it; 618 if (frame->window() == window) { 619 return frame; 620 } 621 } 622 return 0; 623 } 624 625 void Workspace::matchBarNeighbors(Direction dir) { 626 627 // TODO: take care of dir 628 // commits current workspace rectangle to root_ tree map element 629 root_->copy(this); 630 Split::adjustSize(root_, ((dir == LEFT) || (dir == RIGHT))); 631 } 632 633 void Workspace::lower() { 634 635 Thing *thing = focusedThing(); 636 637 if (!thing) { 638 return; 639 } 640 641 XCORE->lower(thing->window()); 642 } 643 644 void Workspace::raise() { 645 646 Client *client = topClient(); 647 648 if (!client) { 649 return; 650 } 651 652 focus(client); 653 } 654 655 void Workspace::changeClientMode(Client *client, Client::Mode mode) { 656 assert(client); 657 detachClient(client); 658 client->setMode(mode); 659 attachClient(client, true); 660 } 661 662 void Workspace::toggleClientMode() { 663 Client *client = topClient(); 664 if (client) { 665 changeClientMode(client, (client->mode() == Client::MAX) ? 666 Client::FLOAT : Client::MAX); 667 } 668 } 669 670 void Workspace::toggleClientSticky() { 671 Client *client = topClient(); 672 if (client) { 673 if (client->mode() != Client::STICKY) { 674 changeClientMode(client, Client::STICKY); 675 } 676 else { 677 changeClientMode(client, Client::FLOAT); 678 } 679 } 680 } 681 682 void Workspace::resizeClient(Direction dir, bool grow) { 683 684 Client *client = topClient(); 685 if (!client || !client->hasDecoration()) { 686 return; 687 } 688 689 Monitor *monitor = attached(); 690 691 int stepW = width() / 100 * monitor->resizeFactor(); 692 int stepH = height() / 100 * monitor->resizeFactor(); 693 694 if ((dir == LEFT) || (dir == UP)) { 695 stepW *= -1; 696 stepH *= -1; 697 } 698 699 Float::resize(client, grow ? dir : Util::reverseDir(dir), 700 stepW, stepH); 701 702 client->resize(); 703 } 704 705 void Workspace::moveClient(Direction dir) { 706 707 Client *client = topClient(); 708 if (!client) { 709 return; 710 } 711 712 Monitor *monitor = attached(); 713 714 // review: correct 715 int stepW = width() / 100 * monitor->resizeFactor(); 716 int stepH = height() / 100 * monitor->resizeFactor(); 717 718 if ((dir == LEFT) || (dir == UP)) { 719 stepW *= -1; 720 stepH *= -1; 721 } 722 723 if ((dir == LEFT) || (dir == RIGHT)) { 724 Float::move(client, stepW, 0); 725 } 726 else { 727 Float::move(client, 0, stepH); 728 } 729 730 client->resize(); 731 } 732 733 734 void Workspace::serialize() { 735 736 (*KERNEL->sessionSettings())[prefix_ + ".name"] = name_; 737 (*KERNEL->sessionSettings())[prefix_ + ".clientbar"] = 738 isClientBarVisible_ ? "yes" : "no"; 739 (*KERNEL->sessionSettings())[prefix_ + ".statusbar"] = 740 isStatusBarVisible_ ? "yes" : "no"; 741 #ifdef SLOT_SUPPORT 742 (*KERNEL->sessionSettings())[prefix_ + ".slot"] = slotTabName_; 743 #endif // SLOT_SUPPORT 744 } 745 746 Frame *Workspace::frameForPoint(unsigned int x, unsigned int y) { 747 748 for (LFrame::iterator it = frames_.begin(); 749 it != frames_.end(); it++) 750 { 751 Frame *frame = *it; 752 if (Util::isPointWithinRect(x, y, frame, this)) { 753 return frame; 754 } 755 } 756 return focusedFrame(); 757 } 758 759 void Workspace::toggleBorders(bool visible) { 760 761 for (LFrame::iterator it = frames_.begin(); 762 it != frames_.end(); it++) 763 { 764 Frame *frame = *it; 765 frame->setBorderWidth(visible ? KERNEL->borderWidth() : 0); 766 frame->resize(); 767 } 768 for (LClient::iterator it = floatingClients_.begin(); 769 it != floatingClients_.end(); it++) 770 { 771 Client *client = *it; 772 if (client->hasDecoration()) { 773 client->setBorderWidth(visible ? KERNEL->borderWidth() : 0); 774 client->resize(); 775 } 776 } 777 } 778 779 void Workspace::toggleBars(bool visible) { 780 781 for (LFrame::iterator it = frames_.begin(); 782 it != frames_.end(); it++) 783 { 784 Frame *frame = *it; 785 frame->setTitleBarHeight(visible ? attached()->titleBarHeight() : 0); 786 frame->resize(); 787 } 788 for (LClient::iterator it = floatingClients_.begin(); 789 it != floatingClients_.end(); it++) 790 { 791 Client *client = *it; 792 if (client->hasDecoration()) { 793 client->setTitleBarHeight(visible ? attached()->titleBarHeight() : 0); 794 client->resize(); 795 } 796 } 797 } 798 799 void Workspace::cycleClientNext() { 800 801 if (isFrameMode_) { 802 if (focusedFrame()) { 803 focus(focusedFrame()->next()); 804 } 805 } 806 else { 807 focus(floatingClients_.next()); 808 } 809 } 810 811 void Workspace::cycleClientPrev() { 812 813 if (isFrameMode_) { 814 if (focusedFrame()) { 815 focus(focusedFrame()->prev()); 816 } 817 } 818 else { 819 focus(floatingClients_.prev()); 820 } 821 } 822 823 void Workspace::toggleMode() { 824 isFrameMode_ = !isFrameMode_; 825 if (isFrameMode_) { 826 if (focusedFrame()) { 827 focus(focusedFrame()->focused()); 828 } 829 else { 830 focus(0); 831 } 832 } 833 else { 834 for (LClient::iterator it = floatingClients_.begin(); 835 it != floatingClients_.end(); it++) 836 { 837 XCORE->raise(((Client *)*it)->window()); 838 } 839 focus(floatingClients_.focused()); 840 } 841 } 842 843 void Workspace::removePushClient(Client *client) { 844 removeClient(client); 845 pushClient(client); 846 } 847 848 void Workspace::removeClient(Client *client) { 849 if (stackContainsClient(client)) { 850 globalClientStack_.remove(client); 851 } 852 } 853 854 void Workspace::pushClient(Client *client) { 855 if (!stackContainsClient(client)) { 856 globalClientStack_.push_front(client); 857 } 858 } 859 860 bool Workspace::stackContainsClient(Client *client) { 861 for (LClient::iterator it = globalClientStack_.begin(); 862 it != globalClientStack_.end(); it++) 863 { 864 if (client == *it) { 865 return true; 866 } 867 } 868 return false; 869 } 870 871 Client *Workspace::topClient() { 872 873 #ifdef SLOT_SUPPORT 874 if (isSlotVisible() && attached()->slot()->isGrabFocus()) { 875 // if the slot grabs the focus currently, this workspace 876 // has temprarily no focussed topClient - so just return 877 // 0. 878 return 0; 879 } 880 #endif 881 if (globalClientStack_.size()) { 882 return globalClientStack_.front(); 883 } 884 return 0; 885 } 886 887 unsigned int Workspace::nextFrameId() { 888 ++frameIds_; 889 return frameIds_; 890 } 891 892 unsigned int Workspace::id() const { 893 return id_; 894 } 895 896 void Workspace::setName(string name) { 897 name_ = name; 898 } 899 900 string Workspace::name() const { 901 return name_; 902 } 903 904 string Workspace::prefix() const { 905 return prefix_; 906 } 907 908 Tree* Workspace::root() const { 909 return root_; 910 } 911 912 bool Workspace::isFrameMode() const { 913 return isFrameMode_; 914 } 915 916 void Workspace::setClientBarVisible(bool visible) { 917 isClientBarVisible_ = visible; 918 } 919 920 void Workspace::setStatusBarVisible(bool visible) { 921 isStatusBarVisible_ = visible; 922 } 923 924 #ifdef SLOT_SUPPORT 925 void Workspace::setSlotVisible(bool visible) { 926 slotTabName_ = visible ? 927 attached()->slot()->tabName() : ""; 928 } 929 930 bool Workspace::isSlotVisible() const { 931 return slotTabName_ != ""; 932 } 933 934 string Workspace::slotTabName() const { 935 return slotTabName_; 936 } 937 #endif // SLOT_SUPPORT 938 939 Thing *Workspace::focusedThing() { 940 941 Client *client = topClient(); 942 return (client && client->frame()) ? (Thing *)client->frame() : 943 (Thing *)client; 944 } 945 946 void Workspace::fitClient() { 947 948 Client *client = topClient(); 949 if (client) { 950 Util::fitInto(client, this); 951 client->resize(); 952 } 953 } 954 955 bool Workspace::isClientBarVisible() const { 956 return isClientBarVisible_; 957 } 958 959 bool Workspace::isStatusBarVisible() const { 960 return isStatusBarVisible_; 961 } 962 963 Monitor *Workspace::attached() const { 964 return monitor_; 965 } 966 967 CClient *Workspace::floatingClients() { 968 return &floatingClients_; 969 } 970 971 CFrame *Workspace::frames() { 972 return &frames_; 973 } 974 975 bool Workspace::requestsFocus() const { 976 return requestsFocus_; 977 } 978 979 void Workspace::setRequestsFocus(bool requestsFocus) { 980 requestsFocus_ = requestsFocus; 981 } 982 983 LClient *Workspace::clients() { 984 return &globalClientStack_; 985 } 986