src/monitor.cpp

Go to the documentation of this file.
00001 // Copyright (c) 2003 - 2004 Anselm R. Garbe <anselmg at t-online.de>
00002 // See ../LICENSE.txt for license details.
00003 //
00004 // $Id: monitor.cpp 7 2007-05-24 11:03:53Z eg1981 $
00005 
00006 extern "C" {
00007 #include <assert.h>
00008 #include <X11/keysym.h>
00009 #include <X11/Xlib.h>
00010 #include <X11/Xutil.h>
00011 }
00012 
00013 #include <iostream>
00014 #include <sstream>
00015 
00016 #include "monitor.h"
00017 
00018 #include "action.h"
00019 #include "actions.h"
00020 #include "atoms.h"
00021 #include "binder.h"
00022 #include "box.h"
00023 #include "client.h"
00024 #include "clientbar.h"
00025 #include "cursors.h"
00026 #include "draw.h"
00027 #include "font.h"
00028 #include "frame.h"
00029 #include "inputbar.h"
00030 #include "logger.h"
00031 #include "menu.h"
00032 #include "rectangle.h"
00033 #include "slot.h"
00034 #include "statusbar.h"
00035 #include "theme.h"
00036 #include "thing.h"
00037 #include "util.h"
00038 #include "kernel.h"
00039 #include "workspace.h"
00040 #include "xcore.h"
00041 #include "xfont.h"
00042 
00043 Monitor::Monitor(Display *display, unsigned int id)
00044     : Container<Display, LWorkspace, LWorkspace::iterator, Workspace>(display),
00045       Rectangle(), detachedClients_(this), stickyClients_(this)
00046 {
00047 
00048     ostringstream oss;
00049     oss << "monitor[" << id << "]";
00050     prefix_ = oss.str();
00051     id_ = id;
00052     themeSettings_ = KERNEL->themeSettings();
00053     commonSettings_ = KERNEL->commonSettings();
00054     sessionSettings_ = KERNEL->sessionSettings();
00055     setWidth(DisplayWidth(attached(), id_));
00056     setHeight(DisplayHeight(attached(), id_));
00057     rootWindow_ = RootWindow(attached(), id_);
00058 
00059     resizeFactor_ = Util::strToUInt(
00060             Util::get(commonSettings_, "resize-move.factor"));
00061 
00062     theme_ = new Theme();
00063     maxThing_ = 0;
00064     clientIds_ = 0;
00065     fixed_ = 0;
00066 
00067     initFonts();
00068     LOGDEBUG("font initialized");
00069     initDisplayString();
00070     LOGDEBUG("display string '" + displayString_ + "' initialized");
00071     theme_->initTheme(themeSettings_, XCORE->defaultColormap(id_));
00072     LOGDEBUG("colors initialized");
00073     initGC();
00074     LOGDEBUG("GC initialized");
00075     initBars();
00076     LOGDEBUG("bars initialized");
00077     XCORE->sync();
00078 #ifdef SLOT_SUPPORT
00079     initSlot();
00080     LOGDEBUG("slot initialized");
00081 #endif // SLOT_SUPPORT
00082     initWorkspaces();
00083     LOGDEBUG("workspaces initialized");
00084 
00085     XCORE->selectEvents(rootWindow_,
00086                  SubstructureRedirectMask | SubstructureNotifyMask 
00087                  | PropertyChangeMask);
00088 
00089     KERNEL->installCursor(Cursors::NORMAL_CURSOR, rootWindow_);
00090 
00091     XCORE->sync();
00092 }
00093 
00094 void Monitor::initFonts() {
00095 
00096     string fontName = Util::get(KERNEL->themeSettings(), "font");
00097     font_ = WFont::load(this, fontName);
00098     if (!font_) {
00099         // fallback, trying to load "fixed"
00100         LOGWARN("cannot load font '" + fontName +
00101                      "', trying loading default font 'fixed'");
00102         font_ = WFont::load(this, "fixed");
00103         if (!font_) {
00104             LOGERROR("cannot load any font", true);
00105             // exits NCWM
00106         }
00107     }
00108     if (font_->height() < MINIMAL_BARHEIGHT) {
00109         font_->setHeight(MINIMAL_BARHEIGHT);
00110     }
00111     if (font_->type() == WFont::XFT) {
00112         fixed_ = XFont::load(this, "fixed");
00113         if (!fixed_) {
00114             LOGERROR("cannot load any font", true);
00115             // exits NCWM
00116         }
00117     }
00118 }
00119 
00120 void Monitor::initBars() {
00121 
00122     Rectangle rect(0, 0, width(),  titleBarHeight() + 2);
00123 
00124     if (Util::get(commonSettings_, "statusbar.alignment") != "bottom") {
00125         statusBar_ = new StatusBar(this, &rect);
00126         inputBar_ = new InputBar(this, &rect);
00127         rect.setY(height() - rect.height());
00128         clientBar_ = new ClientBar(this, &rect);
00129     }
00130     else {
00131         clientBar_ = new ClientBar(this, &rect);
00132         rect.setY(height() - rect.height());
00133         statusBar_ = new StatusBar(this, &rect);
00134         inputBar_ = new InputBar(this, &rect);
00135     }
00136 
00137     rect.setY(height() / 2 - rect.height() / 2);
00138     box_ = new Box(this, &rect, "");
00139 }
00140 
00141 void Monitor::initGC() {
00142 
00143     unsigned long mask = 
00144                   GCForeground | GCGraphicsExposures
00145                 | GCFunction | GCSubwindowMode | GCLineWidth
00146                 | GCPlaneMask;
00147     XGCValues gcv;
00148     gcv.subwindow_mode=IncludeInferiors;
00149     gcv.function=GXxor;
00150     gcv.foreground = theme_->FRAME_PSEUDO;
00151     gcv.fill_style=FillSolid;
00152     gcv.line_width = Util::strToUInt(
00153             Util::get(KERNEL->commonSettings(), "border.width"));
00154     gcv.plane_mask = AllPlanes;
00155     gcv.graphics_exposures = False;
00156     if (font_->type() == WFont::NORMAL) {
00157         gcv.font = ((XFont *)font_)->font()->fid;
00158         mask |= GCFont;
00159     }
00160 
00161     pseudoBorderGC_ = XCORE->createGC(rootWindow_, mask, &gcv);
00162 
00163     gcv.function=GXcopy;
00164     borderGC_ = XCORE->createGC(rootWindow_, mask, &gcv);
00165 }
00166 
00167 Monitor::~Monitor() {
00168     for (MClient::iterator it = clients_.begin();
00169          it != clients_.end(); it++)
00170     {
00171         Client *client = (*it).second;
00172         clients_.erase(it);
00173         delete client;
00174     }
00175     delete statusBar_;
00176     delete clientBar_;
00177 #ifdef SLOT_SUPPORT
00178     delete slot_;
00179 #endif // SLOT_SUPPORT
00180 }
00181 
00182 void Monitor::rectForWorkspace(Workspace *workspace) {
00183 
00184     bool isClientBarVisible = workspace->isClientBarVisible();
00185     bool isStatusBarVisible = workspace->isStatusBarVisible();
00186 
00187     // bar dimensions
00188     if (Util::get(commonSettings_, "statusbar.alignment") != "bottom") {
00189         workspace->setY((isStatusBarVisible ? statusBar_->height() : 0));
00190     }
00191     else {
00192         workspace->setY((isClientBarVisible ? clientBar_->height() : 0));
00193     }
00194     workspace->setHeight(height()
00195                          - (isStatusBarVisible ?  statusBar_->height() : 0)
00196                          - (isClientBarVisible ?  clientBar_->height() : 0));
00197 
00198 #ifdef SLOT_SUPPORT
00199     static bool isSlotOverlap =
00200         Util::get(commonSettings_, "slot.mode") == "overlap";
00201     // slot dimensions
00202     if (workspace->isSlotVisible() && !isSlotOverlap
00203         && slot_->hasClients())
00204     {
00205         if (slot_->alignment() == LEFT) {
00206             workspace->setX(slot_->width());
00207         }
00208         else {
00209             workspace->setX(x());
00210         }
00211         workspace->setWidth(width() - slot_->width());
00212     }
00213     else
00214 #endif // SLOT_SUPPORT
00215     {
00216         workspace->setX(x());
00217         workspace->setWidth(width());
00218     }
00219 }
00220 
00221 void Monitor::initWorkspaces() {
00222 
00223     string key = prefix_ + ".workspaces";
00224 
00225     unsigned int workspaceCount =
00226         Util::strToUInt(Util::get(sessionSettings_, key));
00227     string id =
00228         Util::get(KERNEL->sessionSettings(), prefix_ + ".focused");
00229     unsigned int focusedWSNum = (id != "") ? Util::strToUInt(id) : 0;
00230 
00231     Rectangle rect;
00232     Workspace *toFocus = 0;
00233     for (unsigned int i = 0; i < workspaceCount; i++) {
00234         Workspace *workspace = new Workspace(this, i, &rect);
00235         matchWorkspace(workspace, LEFT);
00236         attach(workspace);
00237         if (i == focusedWSNum) {
00238             toFocus = workspace;
00239         }
00240     }
00241     LOGDEBUG("workspaces created");
00242     XCORE->sync();
00243     focus(toFocus);
00244 }
00245 
00246 void Monitor::initDisplayString() {
00247 
00248     ostringstream oss;
00249 
00250     displayString_ = DisplayString(attached());
00251     unsigned int dot = displayString_.rfind('.');
00252 
00253     LOGDEBUG("initializing display string '" + displayString_ + "'");
00254     oss << "DISPLAY=";
00255     LOGDEBUG("ok displayString_");
00256     if (dot > 0) {
00257         oss << displayString_.substr(0, dot + 1) << id_;
00258     }
00259     else {
00260         oss << displayString_;
00261     }
00262 
00263     displayString_ = oss.str();
00264 }
00265 
00266 void Monitor::scanWindows() {
00267 
00268     unsigned int numWindows = 0;
00269     Window *windows;
00270     XWindowAttributes attr;
00271 
00272     // Queries only the tree of this monitor
00273     XCORE->queryTree(rootWindow_, &windows, &numWindows);
00274 
00275     ostringstream oss;
00276     oss << "scanning " << numWindows << " windows";
00277     LOGDEBUG(oss.str());
00278     for (unsigned int i = 0; i < numWindows; i++) {
00279         XCORE->windowAttributes(windows[i], &attr);
00280 
00281         // ignore default windows
00282         if (attr.override_redirect ||
00283             menuWindow(windows[i]) ||
00284             (box_->window() == windows[i]) ||
00285             barWindow(windows[i]) ||
00286 #ifdef SLOT_SUPPORT
00287             slotWindow(windows[i]) ||
00288 #endif // SLOT_SUPPORT
00289             (windows[i] == rootWindow_))
00290         {
00291             LOGDEBUG("ignoring scanned window (override redirect)");
00292             continue;
00293         }
00294 
00295         if (XCORE->transient(windows[i])) {
00296             LOGDEBUG("ignoring scanned window (transient)");
00297             continue;
00298         }
00299 
00300         // determine client
00301         Client *client;
00302         if ((client = clientForWindow(windows[i])) == 0) {
00303             if (attr.map_state == IsViewable) {
00304                 client = new Client(this, windows[i], &attr);
00305                 addClient(client);
00306                 attachClient(client);
00307             }
00308         }
00309     }
00310     if (windows) {
00311         XCORE->free((void *)windows);
00312     }
00313 }
00314 
00315 Thing *Monitor::thingWindow(Window window) {
00316 
00317     for (LWorkspace::iterator it = begin(); it != end(); it++) {
00318         Workspace *workspace = *it;
00319         Thing *thing = workspace->thingWindow(window);
00320         if (thing) {
00321             return thing;
00322         }
00323     }
00324     return 0;
00325 }
00326 
00327 
00328 Bar *Monitor::barWindow(Window window) {
00329 
00330     if (statusBar_->window() == window) {
00331         return statusBar_;
00332     }
00333     if (clientBar_->window() == window) {
00334         return clientBar_;
00335     }
00336     if (inputBar_->window() == window) {
00337         return inputBar_;
00338     }
00339     return 0;
00340 }
00341 
00342 Menu *Monitor::menuWindow(Window window) {
00343     Menu *menu = clientBar_->menu();
00344     if (clientBar_->menu()->window() == window) {
00345         return menu;
00346     }
00347 
00348     return 0;
00349 }
00350 
00351 #ifdef SLOT_SUPPORT
00352 void Monitor::initSlot() {
00353 
00354     Direction align;
00355     string valueAlign = Util::get(commonSettings_, "slot.alignment");
00356     Rectangle rect;
00357 
00358     int offsetX = 0;
00359     if (valueAlign == "right") {
00360         align = RIGHT;
00361         offsetX = width() - 1; // initial offset :)
00362     }
00363     else {
00364         align = LEFT;
00365     }
00366     rect = Rectangle(offsetX, titleBarHeight(), 1,
00367                      height() - 2 * titleBarHeight());
00368 
00369     slot_ = new Slot(this, &rect, align);
00370 }
00371 
00372 
00373 Slot *Monitor::slotWindow(Window window) {
00374 
00375     if (slot_->window() == window) {
00376         return slot_;
00377     }
00378 
00379     return 0;
00380 }
00381 
00382 Slot *Monitor::slot() const {
00383     return slot_;
00384 }
00385 
00386 void Monitor::unslotClient() {
00387 
00388     Client *client = slot_->focused()->focused();
00389     if (client) {
00390         slot_->detachClient(client);
00391         client->setMode(Client::FLOAT);
00392         attachClient(client);
00393     }
00394 }
00395 
00396 void Monitor::slotClient() {
00397 
00398     Client *client = focusedClient();
00399     if (client) {
00400         // HACK: removeClient also removes it from clients
00401         // TODO: thus it would be useful to distinguish removeClient
00402         //       with detachClient -> overwork around wmi-10
00403         removeClient(client);
00404         addClient(client); // we've to add it again, because it was removed
00405         client->setMode(Client::SLOT);
00406         attachClient(client);
00407     }
00408 }
00409 
00410 void Monitor::toggleSlot() {
00411 
00412     if (slot_->isVisible()) {
00413         focused()->setSlotVisible(false);
00414         slot_->hide();
00415     }
00416     else {
00417         focused()->setSlotVisible(true);
00418         slot_->show(focused()->slotTabName());
00419         slot_->manage();
00420     }
00421 
00422     focused()->setSlotVisible(slot_->isVisible());
00423 }
00424 
00425 void Monitor::cycleSlotTabPrev() {
00426     slot_->focused()->hide();
00427     slot_->focus(slot_->prev());
00428     slot_->focused()->show();
00429     slot_->manage();
00430 }
00431 
00432 void Monitor::cycleSlotTabNext() {
00433     slot_->focused()->hide();
00434     slot_->focus(slot_->next());
00435     slot_->focused()->show();
00436     slot_->manage();
00437 }
00438 #endif // SLOT_SUPPORT
00439 
00440 Client *Monitor::clientForWindow(Window window) {
00441 
00442     if (window == 0 || window == rootWindow_) {
00443         return 0;
00444     }
00445 
00446     MClient::iterator it = clients_.find((long)window);
00447 
00448     if (it != clients_.end()) {
00449         return (*it).second;
00450     }
00451 
00452     // client does not exist
00453     return 0;
00454 }
00455 
00456 void Monitor::addClient(Client *client) {
00457 
00458     clients_[(long)client->clientWindow()] = client;
00459 }
00460 
00461 void Monitor::cleanup() {
00462     while (clients_.size()) {
00463         MClient::iterator it = clients_.begin();
00464         Client *client = (*it).second;
00465         removeClient(client);
00466         if (!client->transient()) {
00467             XCORE->addToSaveSet(client->clientWindow());
00468         }
00469         delete client;
00470     }
00471 }
00472 
00473 Client *Monitor::focusedClient() {
00474     return focused()->topClient();
00475 }
00476 
00477 void Monitor::removeClient(Client *client) {
00478 
00479     XCORE->sync();
00480     LOGDEBUG("removing client");
00481 
00482     Workspace *workspace = client->attached();
00483     if (workspace) {
00484         workspace->detachClient(client);
00485         LOGDEBUG("client removed from workspace");
00486     }
00487 #ifdef SLOT_SUPPORT
00488     else if (client->mode() == Client::SLOT) {
00489         LOGDEBUG("removing slot client");
00490         slot_->detachClient(client);
00491         matchWorkspace(focused(), slot_->alignment());
00492     }
00493 #endif
00494     else if (!client->isVisible()) {
00495         // seems to be an detached client
00496         detachedClients_.detach(client);
00497         XCORE->sync();
00498         LOGDEBUG("removing detached client");
00499         statusBar_->illuminate();
00500     }
00501     // else already detached
00502     XCORE->sync();
00503     clients_.erase((long)client->clientWindow());
00504     LOGDEBUG("client removed");
00505 }
00506 
00507 void Monitor::matchWorkspace(Workspace *workspace, Direction dir) {
00508 
00509     rectForWorkspace(workspace);
00510     workspace->matchBarNeighbors(dir);
00511 #ifdef SLOT_SUPPORT
00512     // slot fix
00513     slot_->setY(workspace->y());
00514 #endif // SLOT_SUPPORT
00515 }
00516 
00517 void Monitor::toggleClientBar() {
00518 
00519     if (clientBar_->isVisible()) {
00520         clientBar_->hide();
00521     }
00522     else {
00523         clientBar_->show();
00524     }
00525 
00526     focused()->setClientBarVisible(clientBar_->isVisible());
00527     Direction dir =
00528         (Util::get(commonSettings_, "statusbar.alignment") == "bottom") ? UP : DOWN;
00529     matchWorkspace(focused(), dir);
00530 #ifdef SLOT_SUPPORT
00531     slot_->manage();
00532 #endif // SLOT_SUPPORT
00533 }
00534 
00535 void Monitor::toggleStatusBar() {
00536 
00537     if (statusBar_->isVisible()) {
00538         statusBar_->hide();
00539     }
00540     else {
00541         statusBar_->show();
00542     }
00543 
00544     focused()->setStatusBarVisible(statusBar_->isVisible());
00545     Direction dir =
00546         (Util::get(commonSettings_, "statusbar.alignment") != "bottom") ? UP : DOWN;
00547     matchWorkspace(focused(), dir);
00548 #ifdef SLOT_SUPPORT
00549     slot_->manage();
00550 #endif // SLOT_SUPPORT
00551 }
00552 
00553 void Monitor::toggleAllClientStates() {
00554 
00555     Workspace *workspace = focused();
00556     assert(workspace);
00557     Thing *thing = workspace->focusedThing();
00558 
00559     if (!thing || (thing->type() != Thing::FRAME)) {
00560         return;
00561     }
00562     Frame *frame = (Frame *)thing;
00563 
00564     unsigned int num = frame->size();
00565     for (unsigned int i = 0; (i < num) && (frame->size() != 0); i++) {
00566         workspace->changeClientMode(frame->focused(), Client::FLOAT);
00567     }
00568     statusBar_->illuminate();
00569 }
00570 
00571 void Monitor::attachAllClients() {
00572 
00573     while (detachedClients_.size()) {
00574         Client *client = *detachedClients_.begin();
00575         detachedClients_.detach(client);
00576         attachClient(client);
00577     }
00578 }
00579 
00580 void Monitor::detachAllClients() {
00581 
00582     Workspace *workspace = focused();
00583     assert(workspace);
00584 
00585     if (workspace->isFrameMode()) {
00586         Frame *frame = workspace->focusedFrame();
00587         unsigned int i = frame->size();
00588         while (i) {
00589             detachClient(*frame->begin());
00590             i--;
00591         }
00592     }
00593     else {
00594         CClient *floatingClients = workspace->floatingClients();
00595         unsigned int i = floatingClients->size();
00596         while (i) {
00597             detachClient(*floatingClients->begin());
00598             i--;
00599         }
00600     }
00601     statusBar_->illuminate();
00602 }
00603 
00604 void Monitor::detachClient(Client *client) {
00605 
00606     if (!client) {
00607         return;
00608     }
00609 
00610     Workspace *workspace = client->attached();
00611 
00612     if (workspace) {
00613         workspace->detachClient(client);
00614         detachedClients_.attach(client);
00615     }
00616 }
00617 
00618 void Monitor::detachClient() {
00619     detachClient(focused()->topClient());
00620 }
00621 
00622 void Monitor::attachClientByName(string name) {
00623 
00624     for (LClient::iterator it = detachedClients_.begin();
00625             it != detachedClients_.end(); it++)
00626     {
00627         Client *client = *it;
00628         if (client->name() == name) {
00629             detachedClients_.detach(client);
00630             attachClient(client);
00631             return;
00632         }
00633     }
00634 }
00635 
00636 void Monitor::attachLastClient() {
00637 
00638     Client *client = detachedClients_.focused();
00639     if (client) {
00640         detachedClients_.detach(client);
00641         attachClient(client);
00642     }
00643 }
00644 
00645 void Monitor::attachClient(Client *client) {
00646 
00647     // first we've to init all necessary info
00648     client->initICCCM();
00649 
00650     if (client->state() == IconicState) {
00651         assert(!client->attached());
00652         detachedClients_.attach(client);
00653         return;
00654     }
00655 
00656     // first transient handling
00657     Client *transient = client->transient();
00658 
00659     if (transient && !transient->attached()
00660 #ifdef SLOT_SUPPORT
00661         && (transient->mode() != Client::SLOT)
00662 #endif // SLOT_SUPPORT
00663         )
00664     {
00665         // attach also the transient, if some
00666         detachedClients_.detach(transient);
00667         attachClient(transient);
00668     }
00669 
00670 #ifdef SLOT_SUPPORT
00671     if (client->mode() == Client::SLOT) {
00672         // will be handled by the slot
00673         LOGDEBUG("new slot client");
00674         slot_->attachClient(client);
00675     }
00676     else
00677 #endif // SLOT_SUPPORT
00678     {
00679         Workspace *hooked = workspaceForName(client->hooked());
00680         if (hooked && contains(hooked)) {
00681             focus(hooked);
00682         }
00683         focused()->attachClient(client);
00684     }
00685 }
00686 
00687 void Monitor::attachDetachedClient(Workspace *workspace, Client *client) {
00688 
00689     focus(workspace);
00690     detachedClients_.detach(client);
00691     attachClient(client);
00692 }
00693 
00694 void Monitor::createNewWorkspace(string name) {
00695 
00696     static Rectangle rect;
00697     unsigned int id = size();
00698 
00699     ostringstream key;
00700     key << prefix_ << ".workspace[" << id << "]";
00701 
00702     (*sessionSettings_)[key.str() + ".name"] = name;
00703     (*sessionSettings_)[key.str() + ".clientbar"] = "yes";
00704     (*sessionSettings_)[key.str() + ".statusbar"] = "yes";
00705 #ifdef SLOT_SUPPORT
00706     (*sessionSettings_)[key.str() + ".slot"] = slot_->tabName();
00707 #endif // SLOT_SUPPORT
00708     (*sessionSettings_)[key.str() + ".focused"] = "0";
00709 
00710     if (focused()) {
00711         focused()->hide();
00712     }
00713     Workspace *workspace = new Workspace(this , id, this);
00714     matchWorkspace(workspace, LEFT);
00715     attach(workspace);
00716     focused()->show();
00717 
00718     ostringstream value;
00719     value << size();
00720     (*sessionSettings_)[prefix_ + ".workspaces"] = value.str();
00721 }
00722 
00723 void Monitor::serialize() {
00724 
00725     ostringstream value;
00726     value << size();
00727     (*sessionSettings_)[prefix_ + ".workspaces"] = value.str();
00728 
00729     for (LWorkspace::iterator it = begin(); it != end(); it++) {
00730          Workspace *workspace = *it;
00731          workspace->serialize();
00732     }
00733 
00734     value.str("");
00735     value << focused()->id();
00736     (*sessionSettings_)[prefix_ + ".focused"] = value.str();
00737 }
00738 
00739 void Monitor::focus(Workspace *workspace) {
00740 
00741     workspace->setRequestsFocus(false);
00742     if (focused() != workspace) {
00743         focused()->hide();
00744         LOGDEBUG("focussing workspace");
00745         XCORE->sync();
00746         Container<Display, LWorkspace, LWorkspace::iterator,
00747             Workspace>::focus(workspace);
00748     }
00749     focused()->show();
00750     updateBars();
00751 }
00752 
00753 void Monitor::focusClient(Client *client) {
00754 
00755     Workspace *workspace = client->attached();
00756     if (workspace) {
00757         focus(workspace);
00758         workspace->focus(client);
00759     }
00760 }
00761 
00762 void Monitor::focusClientById(string id) {
00763 
00764     for (MClient::iterator it = clients_.begin();
00765             it != clients_.end(); it++)
00766     {
00767         Client *client = (*it).second;
00768 
00769         if (client->id() == id) {
00770             focusClient(client);
00771         }
00772     }
00773 }
00774 
00775 void Monitor::focusClientByName(string name) {
00776 
00777     for (MClient::iterator it = clients_.begin();
00778             it != clients_.end(); it++)
00779     {
00780         Client *client = (*it).second;
00781 
00782         if (client->name() == name) {
00783             focusClient(client);
00784         }
00785     }
00786 }
00787 
00788 Workspace *Monitor::workspaceForName(string name) {
00789 
00790     for (LWorkspace::iterator it = begin(); it != end(); it++) {
00791         if ((*it)->name() == name) {
00792             return (Workspace *)*it;
00793         }
00794     }
00795     return 0;
00796 }
00797 
00798 void Monitor::focusWorkspaceNum(unsigned int workspaceNum) {
00799 
00800     unsigned int i = 0;
00801     for (LWorkspace::iterator it = begin(); it != end(); it++) {
00802         if (i == workspaceNum) {
00803             focus(*it);
00804             return;
00805         }
00806         i++;
00807     }
00808 }
00809 
00810 void Monitor::destroyWorkspace(Workspace *workspace) {
00811 
00812     assert(workspace);
00813     if (size() > 1) {
00814         LClient *clients = workspace->clients();
00815         while (clients->size()) {
00816             Client *client = *clients->begin();
00817             detachClient(client);
00818             KERNEL->killClient(client);
00819         }
00820         detach(workspace);
00821         Util::remove(sessionSettings_, workspace->prefix());
00822         delete workspace;
00823         focused()->show();
00824         updateBars();
00825     }
00826 }
00827 
00828 void Monitor::renameWorkspace(Workspace *workspace, string newName) {
00829     workspace->setName(newName);
00830     (*sessionSettings_)[workspace->prefix() + ".name"] = newName;
00831 }
00832 
00833 void Monitor::updateBars() {
00834 
00835     static string value;
00836 
00837     if (XCORE->textProperty(rootWindow_, Atoms::NCWM_STATUSTEXT, &value)) {
00838         statusBar_->setText(value);
00839     }
00840     if (XCORE->textProperty(rootWindow_, Atoms::NCWM_METERTEXT, &value)) {
00841         statusBar_->setMeterText(value);
00842     }
00843 
00844     LOGDEBUG("update status");
00845     statusBar_->illuminate();
00846     clientBar_->illuminate();
00847     XCORE->sync();
00848 }
00849 
00850 void Monitor::toggleThingMaximization() {
00851 
00852     if (!focused()) {
00853         return;
00854     }
00855 
00856     if (maxThing_) {
00857 
00858         maxThing_->copy(maxThing_->prevRectangle());
00859         maxThing_->resize();
00860         focused()->illuminate();
00861         maxThing_ = 0; // reset
00862 
00863     }
00864     else {
00865 
00866         Workspace *workspace = focused();
00867         maxThing_ = workspace->focusedThing();
00868 
00869         if (!maxThing_) {
00870             return;
00871         }
00872 
00873         maxThing_->prevRectangle()->copy(maxThing_);
00874         maxThing_->setX(x());
00875         maxThing_->setY(y());
00876         maxThing_->setWidth(width());
00877         maxThing_->setHeight(height());
00878         maxThing_->resize();
00879         XCORE->raise(maxThing_->window());
00880         maxThing_->illuminate();
00881     }
00882 }
00883 
00884 void Monitor::illuminateTransRect(Rectangle *rect, unsigned int barHeight)
00885 {
00886     Draw::drawTransRectangle(rootWindow_, pseudoBorderGC_, rect, barHeight,
00887                              KERNEL->borderWidth());
00888 
00889     // additional size info
00890     ostringstream oss;
00891     oss << "x=" << rect->x()  << ", y=" << rect->y()
00892         << ": " << rect->width() << "x" << rect->height();
00893 
00894     illuminateTransText(rect, oss.str());
00895 }
00896 
00897 unsigned int Monitor::nextClientId() {
00898     ++clientIds_;
00899     return clientIds_;
00900 }
00901 
00902 void Monitor::illuminateTransText(Rectangle *rect, string text)
00903 {
00904     WFont *font = (font_->type() == WFont::NORMAL) ?
00905                     font_ : fixed_;
00906 
00907     // additional size info
00908     int textWidth = font->textWidth(text);
00909     unsigned int fontBaseLine = font->ascent();
00910     unsigned int fontY = rect->y() + rect->height() / 2
00911                 - font->height() / 2 + fontBaseLine;
00912 
00913     unsigned int fontX = rect->x() +
00914                 (rect->width() / 2 - textWidth / 2);
00915     font->drawText(rootWindow_, pseudoBorderGC_,
00916                     fontX, fontY, text);
00917 }
00918 
00919 
00920 unsigned int Monitor::id() const {
00921     return id_;
00922 }
00923 
00924 Window Monitor::rootWindow() const {
00925     return rootWindow_;
00926 }
00927 
00928 string Monitor::displayString() const {
00929     return displayString_;
00930 }
00931 
00932 Theme *Monitor::theme() const {
00933     return theme_;
00934 }
00935 
00936 unsigned int Monitor::resizeFactor() const {
00937     return resizeFactor_;
00938 }
00939 
00940 string Monitor::prefix() const {
00941     return prefix_;
00942 }
00943 
00944 Box *Monitor::box() const {
00945     return box_;
00946 }
00947 
00948 StatusBar *Monitor::statusBar() const {
00949     return statusBar_;
00950 }
00951 
00952 ClientBar *Monitor::clientBar() const {
00953     return clientBar_;
00954 }
00955 
00956 CClient *Monitor::detachedClients() {
00957     return &detachedClients_;
00958 }
00959 
00960 bool Monitor::isThingMaximized() {
00961     return maxThing_ != 0;
00962 }
00963 
00964 GC Monitor::borderGC() {
00965     return borderGC_;
00966 }
00967 
00968 CClient *Monitor::stickyClients() {
00969     return &stickyClients_;
00970 }
00971 
00972 WFont *Monitor::font() const {
00973     return font_;
00974 }
00975 
00976 unsigned int Monitor::titleBarHeight() const {
00977     return font_->height() + 2;
00978 }
00979 
00980 MClient *Monitor::clients() {
00981     return &clients_;
00982 }
00983 
00984 InputBar *Monitor::inputBar() const {
00985     return inputBar_;
00986 }
00987 
00988 void Monitor::banish() {
00989     XCORE->warpPointer(rootWindow_, width(), height());
00990 }
00991 
00992 unsigned int Monitor::buttonWidth() const {
00993     return font_->height() + 4;
00994 }
00995 
00996 void Monitor::hookClient() {
00997 
00998     Client *client = 0;
00999 #ifdef SLOT_SUPPORT
01000     if (slot_->isGrabFocus() ||
01001         (!focused()->clients()->size() && slot_->focused()->focused()))
01002     {
01003         client = slot_->focused()->focused();
01004         if (client) {
01005             client->setHooked(slot_->tabName());
01006             return;
01007         }
01008     }
01009     else
01010 #endif // SLOT_SUPPORT 
01011     {
01012         client = focused()->topClient();
01013         if (client) {
01014             client->setHooked(focused()->name());
01015         }
01016     }
01017 }
01018 
01019 void Monitor::unhookClient() {
01020 
01021     Client *client = 0;
01022 #ifdef SLOT_SUPPORT
01023     if (slot_->isGrabFocus() ||
01024         (!focused()->clients()->size() && slot_->focused()->focused()))
01025     {
01026         client = slot_->focused()->focused();
01027         if (client) {
01028             client->setHooked("");
01029             return;
01030         }
01031     }
01032     else
01033 #endif // SLOT_SUPPORT
01034     {
01035         client = focused()->topClient();
01036         if (client) {
01037             client->setHooked("");
01038         }
01039     }
01040 }

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