src/client.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: client.cpp 2 2007-05-16 10:38:27Z eg $
00005 
00006 #include <sstream>
00007 
00008 extern "C" {
00009 #include <assert.h>
00010 #include <X11/Xatom.h>
00011 }
00012 
00013 #include "client.h"
00014 
00015 #include "atoms.h"
00016 #include "binder.h"
00017 #include "cursors.h"
00018 #include "draw.h"
00019 #include "clientbar.h"
00020 #include "frame.h"
00021 #include "kernel.h"
00022 #include "label.h"
00023 #include "logger.h"
00024 #include "rectangle.h"
00025 #include "statusbar.h"
00026 #include "monitor.h"
00027 #include "util.h"
00028 #include "slot.h"
00029 #include "theme.h"
00030 #include "workspace.h"
00031 #include "xcore.h"
00032 
00033 Client::Client(Monitor *monitor, Window window, XWindowAttributes *attr)
00034     : Thing(monitor, new Rectangle(), Thing::CLIENT)
00035 {
00036     clientWindow_ = window;
00037     frame_ = 0;
00038     state_ = WithdrawnState;
00039     iconName_ = "";
00040     isCentered_ = false;
00041     protocols_ = 0;
00042     hasFrame_ = false;
00043     requestsFocus_ = false;
00044     isDestroyed_ = false;
00045     hooked_ = "";
00046     workspace_ = 0;
00047 
00048     ostringstream oss;
00049     oss << "<" << monitor->nextClientId() << ">";
00050     id_ = oss.str();
00051 
00052     eventMask_ = PropertyChangeMask;
00053     XCORE->selectEvents(clientWindow_, eventMask_);
00054 
00055     setX(attr->x);
00056     setY(attr->y);
00057     setWidth(attr->width);
00058     setHeight(attr->height);
00059     borderWidth_ = attr->border_width;
00060 
00061     oss.str("");
00062     oss << "constructing new client with dimensions: " <<
00063         x() << "," << y() << "," << width() << "," << height();
00064     LOGDEBUG(oss.str());
00065 
00066     className_ = XCORE->className(clientWindow_);
00067     instanceName_ = XCORE->instanceName(clientWindow_);
00068 
00069     string value;
00070 
00071     updateTransient();
00072     if (transient_) {
00073          value = Util::get(KERNEL->sessionSettings(),
00074                      "client." + className_ + "::" + instanceName_ + ".transient-mode");
00075 
00076         if ("" == value) {
00077             value = Util::get(KERNEL->commonSettings(),
00078                               "default.transient-mode");
00079 
00080             if ("" == value) {
00081                 value = "float";
00082             }
00083         }
00084     }
00085     else {
00086         value = Util::get(KERNEL->sessionSettings(),
00087                          "client." + className_ + "::" + instanceName_ + ".mode");
00088     }
00089 
00090     if (value == "float") {
00091         mode_ = FLOAT;
00092     }
00093     else if (value == "sticky") {
00094         mode_ = STICKY;
00095     }
00096     else if (value == "max") {
00097         mode_ = MAX;
00098     }
00099 #ifdef SLOT_SUPPORT
00100     else if (value == "slot") {
00101         mode_ = SLOT;
00102     }
00103 #endif // SLOT_SUPPORT
00104     // fallback, unknown yet
00105     else if (Util::get(KERNEL->commonSettings(), "default.client-mode")
00106             == "float")
00107     {
00108         mode_ = FLOAT;
00109     }
00110     else {
00111         mode_ = MAX;
00112     }
00113 
00114     hooked_ = Util::get(KERNEL->sessionSettings(),
00115             "client." + className_ + "::" + instanceName_ + ".hooked");
00116 }
00117 
00118 Client::~Client() {
00119 }
00120 
00121 string Client::id() {
00122     return id_;
00123 }
00124 
00125 void Client::initICCCM() {
00126 
00127     state_ = XCORE->state(clientWindow_);
00128     iconName_ = XCORE->atomValue(clientWindow_, XA_WM_ICON_NAME);
00129     setName(XCORE->atomValue(clientWindow_, XA_WM_NAME) + id_);
00130     if (iconName_ == "") {
00131         iconName_ = name();
00132     }
00133     else {
00134         iconName_ += id_;
00135     }
00136     updateSize();
00137     protocols_ = XCORE->protocols(clientWindow_);
00138     if (XCORE->hasDecoration(clientWindow_) && !frameWindow()) {
00139         hasDecoration_ = true;
00140     }
00141 
00142     updateTransient();
00143 }
00144 
00145 void Client::updateSize() {
00146 
00147     unsigned int dummy;
00148     // TODO: increment handling
00149     XCORE->updateSize(clientWindow_, &dummy, &dummy,
00150                       &dummy, &dummy, &isCentered_);
00151 }
00152 
00153 void Client::updateTransient() {
00154 
00155     Window trans = XCORE->transient(clientWindow_);
00156     transient_ = KERNEL->clientForWindow(trans);
00157 }
00158 
00159 Client *Client::transient() const {
00160     return transient_;
00161 }
00162 
00163 void Client::sendConfiguration() {
00164     XConfigureEvent event;
00165 
00166     ostringstream oss;
00167 
00168     oss << "send configuration: " << clientAreaRect_.x() << ","
00169         << clientAreaRect_.y() << "," << clientAreaRect_.width()
00170         << "," << clientAreaRect_.height();
00171     LOGDEBUG(oss.str());
00172     event.type = ConfigureNotify;
00173     event.event = clientWindow_;
00174     event.window = clientWindow_;
00175     if (hasFrame_) {
00176         event.x = x() + clientAreaRect_.x();
00177         event.y = y() + clientAreaRect_.y();
00178     }
00179     else if (frame()) {
00180         event.x = frame()->x() + clientAreaRect_.x();
00181         event.y = frame()->y() + clientAreaRect_.y();
00182     }
00183     else {
00184         event.x = clientAreaRect_.x();
00185         event.y = clientAreaRect_.y();
00186     }
00187     event.width = clientAreaRect_.width();
00188     event.height = clientAreaRect_.height();
00189     event.border_width = clientBorderWidth_;
00190     event.above = None;
00191     event.override_redirect = False;
00192 
00193     XCORE->configure(clientWindow_, &event);
00194 }
00195 
00196 void Client::resize() {
00197 
00198     clientAreaRect_.copy(this);
00199 
00200     if (hasFrame_) {
00201         ostringstream oss;
00202         oss << "frame resize: x=" << x() << ", y=" << y() << ", w=" <<
00203             width() << ", h=" << height();
00204         LOGDEBUG(oss.str());
00205         XCORE->moveResize(frameWindow(), this);
00206 
00207         if (frame()) {
00208             // maximize client window
00209             clientAreaRect_.setX(0);
00210             clientAreaRect_.setY(0);
00211             clientAreaRect_.setWidth(width());
00212             clientAreaRect_.setHeight(height());
00213         }
00214         else {
00215             label_->setY(borderWidth_); // label fix for toggleBorder
00216             fitClientArea();
00217         }
00218     }
00219     XCORE->moveResize(clientWindow_, &clientAreaRect_);
00220     sendConfiguration();
00221     illuminate();
00222 }
00223 
00224 void Client::gravitate(bool invert) {
00225 
00226     int dx = 0;
00227     int dy = 0;
00228     int gravity = NorthWestGravity;
00229     XSizeHints sizeHints;
00230 
00231     XCORE->sizeHints(clientWindow_, &sizeHints);
00232 
00233     if (sizeHints.flags & PWinGravity) {
00234         gravity = sizeHints.win_gravity;
00235     }
00236 
00237     switch (gravity) {
00238     case NorthEastGravity:
00239     case EastGravity:
00240     case SouthEastGravity:
00241         dx = -borderWidth_;
00242         break;
00243     default:
00244         break;
00245     }
00246 
00247     switch (gravity) {
00248     case SouthWestGravity:
00249     case SouthGravity:
00250     case SouthEastGravity:
00251         dy = -titleBarHeight_ - borderWidth_;
00252         break;
00253     default:
00254         break;
00255     }
00256 
00257     if (invert) {
00258         dx = -dx;
00259         dy = -dy;
00260     }
00261 
00262     setX(x() + dx);
00263     setY(y() + dy);
00264 }
00265 
00266 void Client::handleConfigureRequest(XConfigureRequestEvent *event) {
00267 
00268     XWindowChanges wc;
00269 
00270     if (event->value_mask & CWStackMode) {
00271         if (attached()) {
00272             if (!isFocused()) {
00273                 requestsFocus_ = true;
00274             }
00275             if (monitor()->focused() != attached()) {
00276                 attached()->setRequestsFocus(true);
00277             }
00278         }
00279         event->value_mask &= ~CWStackMode;
00280     }
00281 
00282     event->value_mask &= ~CWSibling;
00283     if (!frame()
00284 #ifdef SLOT_SUPPORT
00285         || (mode_ == SLOT)
00286 #endif
00287        ) {
00288 
00289         // floating client
00290 
00291         gravitate(true);
00292 
00293         if (event->value_mask & CWX) {
00294             setX(event->x);
00295         }
00296         if (event->value_mask & CWY) {
00297             setY(event->y);
00298         }
00299         if (event->value_mask & CWWidth) {
00300             setWidth(event->width);
00301         }
00302         if (event->value_mask & CWHeight) {
00303             setHeight(event->height);
00304         }
00305         if (event->value_mask & CWBorderWidth) {
00306             clientBorderWidth_ = event->border_width;
00307         }
00308         ostringstream oss;
00309         oss << "configure request: x=" << x() << ", y=" << y()
00310             << ", w=" << width() << ", h=" << height();
00311         LOGDEBUG(oss.str());
00312 
00313         gravitate(false);
00314 
00315         // applied patch by Dr. J. Pfefferl
00316         if (hasFrame_) {
00317 
00318             if((event->value_mask & CWWidth)) {
00319                 setWidth(width() + 2 * borderWidth_);
00320             }
00321             if((event->value_mask & CWHeight)) {
00322                 setHeight(height() + titleBarHeight_ + 2 * borderWidth_
00323                         + (titleBarHeight_ ? 1 : 0));
00324             }
00325             if((event->value_mask & CWX)) {
00326                 setX(x() - borderWidth_);
00327             }
00328             if((event->value_mask & CWY)) {
00329                 setY(y() - titleBarHeight_ - borderWidth_);
00330             }
00331 
00332             wc.x = x();
00333             wc.y = y();
00334             wc.width = width();
00335             wc.height = height();
00336             wc.border_width = 1; // event->border_width
00337             wc.sibling = None;
00338             wc.stack_mode = event->detail;
00339             XCORE->configureWindow(frameWindow(), event->value_mask, &wc);
00340             fitClientArea();
00341             sendConfiguration();
00342         }
00343         else {
00344             // save current dimensions to client area
00345             clientAreaRect_.copy(this);
00346         }
00347     }
00348 
00349 #ifdef SLOT_SUPPORT
00350     if (mode_ == SLOT) {
00351         monitor()->slot()->manage();
00352     }
00353     else
00354 #endif // SLOT_SUPPORT
00355     {
00356         // If client is attached to a frame, the clientAreaRect_ has
00357         // the size of the frames client area.
00358         wc.x = clientAreaRect_.x();
00359         wc.y = clientAreaRect_.y();
00360         wc.width = clientAreaRect_.width();
00361         wc.height = clientAreaRect_.height();
00362         wc.border_width = 0;
00363         wc.sibling = None;
00364         event->value_mask |= CWBorderWidth;
00365 
00366         XCORE->configureWindow(clientWindow_, event->value_mask, &wc);
00367 
00368         illuminate();
00369     }
00370 }
00371 
00372 void Client::handlePropertyNotify(XPropertyEvent *event) {
00373 
00374     if (event->state == PropertyDelete) {
00375         return; // ignore delete properties
00376     }
00377 
00378     // WM atoms
00379     if (event->atom == Atoms::WM_PROTOCOLS) {
00380         protocols_ = XCORE->protocols(clientWindow_);
00381         return;
00382     }
00383     else if (event->atom == Atoms::MWM_HINTS) {
00384         if (XCORE->hasDecoration(clientWindow_) && !frameWindow()) {
00385             hasDecoration_ = true;
00386         }
00387         return;
00388     }
00389 
00390     // default atoms
00391     static string tmp;
00392     ostringstream oss;
00393     switch (event->atom) {
00394     case XA_WM_ICON_NAME:
00395         tmp = XCORE->atomValue(clientWindow_, XA_WM_ICON_NAME);
00396         if (tmp.length() > 0) {
00397             // update only if the icon name is != 0
00398             iconName_ = tmp + id_;
00399         }
00400         monitor()->clientBar()->illuminate();
00401         monitor()->statusBar()->illuminate();
00402         break;
00403     case XA_WM_NAME:
00404         tmp = XCORE->atomValue(clientWindow_, XA_WM_NAME);
00405         if (tmp.length() > 0) {
00406             // update only if the title is != 0
00407             setName(tmp + id_);
00408         }
00409         illuminate();
00410         monitor()->statusBar()->illuminate();
00411         break;
00412     case XA_WM_TRANSIENT_FOR:
00413         updateTransient();
00414         break;
00415     case XA_WM_NORMAL_HINTS:
00416         updateSize();
00417         oss << "git size: x=" << x() << ", y=" << y() << ", w=" <<
00418             width() << ", h=" << height();
00419         LOGDEBUG(oss.str());
00420         break;
00421     }
00422 }
00423 
00424 void Client::handleUnmapNotify(XUnmapEvent *event) {
00425 
00426     if (!isVisible_ || !event->send_event) {
00427        LOGDEBUG("client is already unvisible");
00428        return;
00429     }
00430 
00431     LOGDEBUG("handle unmap client: " + name());
00432     if (frameWindow()) {
00433         XCORE->hide(frameWindow());
00434     }
00435     isVisible_ = false;
00436     XCORE->setState(clientWindow_, WithdrawnState);
00437     Workspace *ws = this->attached();
00438     if (ws) {
00439         LOGDEBUG("going detaching client from workspace");
00440         ws->detachClient(this);
00441     }
00442 }
00443 
00444 void Client::show() {
00445     if (isDestroyed_) {
00446         return;
00447     }
00448     XCORE->showRaised(clientWindow_);
00449     if (hasFrame_) {
00450         XCORE->showRaised(frameWindow());
00451     }
00452     state_ = NormalState;
00453     KERNEL->installCursor(Cursors::NORMAL_CURSOR, clientWindow_);
00454     XCORE->setState(clientWindow_, state_);
00455     isVisible_ = true;
00456 }
00457 
00458 void Client::hide() {
00459     if (isDestroyed_) {
00460         return;
00461     }
00462     if (hasFrame_) {
00463         XCORE->hide(frameWindow());
00464     }
00465     XCORE->hide(clientWindow_);
00466     state_ = WithdrawnState;
00467     XCORE->setState(clientWindow_, state_);
00468     isVisible_ = false;
00469     LOGDEBUG("client state changed");
00470     XCORE->sync();
00471 }
00472 
00473 void Client::setMode(Client::Mode mode) {
00474 
00475     mode_ = mode;
00476     string modeStr;
00477 
00478     switch (mode_) {
00479     case MAX:
00480         modeStr = "max";
00481         break;
00482     case STICKY:
00483         modeStr = "sticky";
00484         break;
00485     case FLOAT:
00486         modeStr = "float";
00487         break;
00488 #ifdef SLOT_SUPPORT
00489     case SLOT:
00490         modeStr = "slot";
00491         break;
00492 #endif // SLOT_SUPPORT
00493     }
00494     if (transient_) {
00495         (*KERNEL->sessionSettings())["client." + className_ + "::" +
00496                 instanceName_ + ".transient-mode"] = modeStr;
00497     }
00498     else {
00499         (*KERNEL->sessionSettings())["client." + className_ + "::" +
00500                 instanceName_ + ".mode"] = modeStr;
00501     }
00502 }
00503 
00504 long Client::eventMask() const {
00505     return eventMask_;
00506 }
00507 
00508 string Client::className() const {
00509     return className_;
00510 }
00511 
00512 string Client::instanceName() const {
00513     return instanceName_;
00514 }
00515 
00516 string Client::iconName() const {
00517     return iconName_;
00518 }
00519 
00520 int Client::protocols() const {
00521     return protocols_;
00522 }
00523 
00524 // TODO: It would be a good idea to implement an align method
00525 //       for gravitation with value VH_CENTER
00526 bool Client::isCentered() const {
00527     return isCentered_;
00528 }
00529 
00530 Client::Mode Client::mode() const {
00531     return mode_;
00532 }
00533 
00534 int Client::state() const {
00535     return state_;
00536 }
00537 
00538 Window Client::window() {
00539     if (hasFrame_) {
00540         return frameWindow_;
00541     }
00542     else {
00543         return clientWindow_;
00544     }
00545 }
00546 
00547 void Client::reparent(Window parentWindow, int x, int y) {
00548     if (isDestroyed_) {
00549         return;
00550     }
00551     XCORE->reparent(clientWindow_, parentWindow, x, y);
00552     assert(parentWindow);
00553     hasFrame_ = (parentWindow == frameWindow());
00554 }
00555 
00556 void Client::createFrame() {
00557     initFrameWindow();
00558     fitClientArea();
00559     XCORE->sync();
00560 }
00561 
00562 bool Client::isFocused() {
00563 
00564     if (frame()) {
00565         return frame()->isFocused()
00566                && frame()->focused() == this;
00567     }
00568     else if (attached()) {
00569         return attached()->topClient() == this;
00570     }
00571     return 0;
00572 }
00573 
00574 void Client::illuminate() {
00575 
00576     if (!isVisible_) {
00577         return;
00578     }
00579 
00580     if (frame()) {
00581         frame()->illuminate();
00582         return;
00583     }
00584 
00585     if (!hasFrame_) {
00586         return;
00587     }
00588     LOGDEBUG("within client illuminate");
00589     XCORE->sync();
00590 
00591     illuminateBorder();
00592 
00593     bool foc = isFocused();
00594     unsigned int buttonWidth = 0;
00595 
00596     if (foc) {
00597         buttonWidth = monitor()->buttonWidth();
00598     }
00599 
00600     if (titleBarHeight_) {
00601         label_->setText(name());
00602         label_->setX(borderWidth_);
00603         unsigned int textWidth = label_->adjustWidth();
00604         unsigned long tabShine = 0;
00605         unsigned long tabShadow = 0;
00606         label_->setWidth(width() - label_->x() - borderWidth_);
00607         if (foc) {
00608             if (areButtonsVisible_) {
00609                 label_->setWidth(label_->width() - 3 * buttonWidth - 2);
00610             }
00611             tabShine = theme_->TAB_SHINE_ACTIVE_FOCUSSED;
00612             tabShadow = theme_->TAB_SHADOW_ACTIVE_FOCUSSED;
00613             label_->update(theme_->TAB_BACKGROUND_ACTIVE_FOCUSSED,
00614                            theme_->TAB_TEXT_ACTIVE_FOCUSSED,
00615                            tabShine, tabShadow, true, true);
00616         }
00617         else if (requestsFocus_) {
00618             tabShine = theme_->FOCUSREQ_SHINE;
00619             tabShadow = theme_->FOCUSREQ_SHADOW;
00620             label_->update(theme_->FOCUSREQ_BACKGROUND,
00621                            theme_->FOCUSREQ_TEXT,
00622                            tabShine, tabShadow, true, true);
00623         }
00624         else if (frame() && frame()->focused() == this) {
00625             tabShine = theme_->TAB_SHINE_ACTIVE_NORMAL;
00626             tabShadow = theme_->TAB_SHADOW_ACTIVE_NORMAL;
00627             label_->update(theme_->TAB_BACKGROUND_ACTIVE_NORMAL,
00628                            theme_->TAB_TEXT_ACTIVE_NORMAL,
00629                            tabShine, tabShadow, true, true);
00630         }
00631         else {
00632             tabShine = theme_->TAB_SHINE_INACTIVE_NORMAL;
00633             tabShadow = theme_->TAB_SHADOW_INACTIVE_NORMAL;
00634             label_->update(theme_->TAB_BACKGROUND_INACTIVE_NORMAL,
00635                            theme_->TAB_TEXT_INACTIVE_NORMAL,
00636                            tabShine, tabShadow, true, true);
00637         }
00638 
00639         if (mode_ == Client::STICKY) {
00640 
00641             Draw::drawStickyNotifier(frameWindow(), gc_, label_,
00642                     tabShine, tabShadow, textWidth);
00643         }
00644     }
00645 
00646     if (foc) {
00647         Draw::drawFloatBorderAnchors(frameWindow(), gc_, this,
00648                 theme_->FRAME_SHINE_FOCUSSED,
00649                 theme_->FRAME_SHADOW_FOCUSSED,
00650                 titleBarHeight_ + borderWidth_ + 1,
00651                 borderWidth_);
00652     }
00653 }
00654 
00655 void Client::handleButtonPress(XButtonEvent *event) {
00656 
00657     LOGDEBUG("entered ClientFrame::handleButtonPress");
00658 #ifdef SLOT_SUPPORT
00659     if (mode_ == SLOT) {
00660         monitor()->slot()->focusClient(this);
00661         return;
00662     }
00663 #endif
00664     if (attached() && !isFocused()) {
00665         attached()->focus(this);
00666         return;
00667     }
00668     else {
00669         XCORE->raise(window());
00670     }
00671 
00672     if (frame()) {
00673         return;
00674     }
00675 
00676     buttonState_ = NONE;
00677 
00678     if (event->button == Button1) {
00679 
00680         if (titleBarHeight_ && areButtonsVisible_ &&
00681                 (cursor_ == Cursors::NORMAL_CURSOR))
00682         {
00683             int xPosition = event->x;
00684             unsigned int buttonWidth = titleBarHeight_ + 1;
00685             unsigned int offsetButtonGroup = width() - borderWidth_ - 3 * buttonWidth;
00686             if ((xPosition > (int)offsetButtonGroup) &&
00687                     (xPosition < (int)(width() - borderWidth_ - 1)))
00688             {
00689                 xPosition -= offsetButtonGroup;
00690                 unsigned int buttonNum = xPosition / buttonWidth;
00691                 switch (buttonNum) {
00692                 case 0:
00693                     buttonState_ = MINCLIENT;
00694                     break;
00695                 case 1:
00696                     buttonState_ = DEMAX;
00697                     break;
00698                 case 2:
00699                     buttonState_ = CLOSE;
00700                     break;
00701                 }
00702                 illuminate();
00703                 return;
00704             }
00705         }
00706 
00707         if (monitor()->isThingMaximized()) {
00708             return;
00709         }
00710 
00711         Direction dir = SOUTH_EAST;
00712         if (cursor_ == Cursors::RESIZE_LEFT_CURSOR) {
00713             dir = LEFT;
00714         }
00715         else if (cursor_ == Cursors::RESIZE_RIGHT_CURSOR) {
00716             dir = RIGHT;
00717         }
00718         else if (cursor_ == Cursors::RESIZE_UP_CURSOR) {
00719             dir = UP;
00720         }
00721         else if (cursor_ == Cursors::RESIZE_DOWN_CURSOR) {
00722             dir = DOWN;
00723         }
00724         else if (cursor_ == Cursors::RESIZE_NORTH_WEST_CURSOR) {
00725             dir = NORTH_WEST;
00726         }
00727         else if (cursor_ == Cursors::RESIZE_NORTH_EAST_CURSOR) {
00728             dir = NORTH_EAST;
00729         }
00730         else if (cursor_ == Cursors::RESIZE_SOUTH_WEST_CURSOR) {
00731             dir = SOUTH_WEST;
00732         }
00733         else if (cursor_ == Cursors::RESIZE_SOUTH_EAST_CURSOR) {
00734             dir = SOUTH_EAST;
00735         }
00736 
00737         KERNEL->runResizeMode(this, event, dir,
00738                               cursor_ != Cursors::NORMAL_CURSOR);
00739     }
00740 }
00741 
00742 void Client::handleButtonRelease(XButtonEvent *event) {
00743 
00744     // TODO: make buttons customizable
00745     if (event->button == Button1) {
00746 
00747         if (titleBarHeight_ && (cursor_ == Cursors::NORMAL_CURSOR) &&
00748             (buttonState_ != NONE)) 
00749         {
00750             if (monitor()->isThingMaximized()) {
00751                 monitor()->toggleThingMaximization();
00752             }
00753             switch (buttonState_) {
00754             case MINCLIENT:
00755                 monitor()->detachClient();
00756                 break;
00757             case DEMAX:
00758                 attached()->toggleClientMode();
00759                 break;
00760             case CLOSE:
00761                 XCORE->kill(clientWindow_, protocols_);
00762                 break;
00763             default:
00764                 break;
00765             }
00766             buttonState_ = NONE;
00767             return;
00768         }
00769     }
00770 }
00771 
00772 Cursor Client::cursorForXY(int pointerX, int pointerY) {
00773 
00774     if (frame() || (borderWidth_ == 0))
00775     {
00776         return Cursors::NORMAL_CURSOR;
00777     }
00778 
00779     // rectangle attributes of client are used
00780     bool left = pointerX < clientAreaRect_.x();
00781     bool right = pointerX >= (int)(clientAreaRect_.x()
00782                                    + clientAreaRect_.width());
00783     bool up = pointerY < (int)(clientAreaRect_.y()
00784                                - titleBarHeight_ - 1);
00785     bool down = pointerY >= (int)(clientAreaRect_.y()
00786                                   + clientAreaRect_.height());
00787 
00788     bool tolLeft = pointerX < (int)(clientAreaRect_.x() + titleBarHeight_);
00789     bool tolRight = pointerX > (int)(clientAreaRect_.x()
00790                                      + clientAreaRect_.width()
00791                                      - titleBarHeight_ - 1);
00792     bool tolUp = pointerY < (int)(clientAreaRect_.y() + titleBarHeight_);
00793     bool tolDown = pointerY > (int)(clientAreaRect_.y()
00794                                     + clientAreaRect_.height()
00795                                     - titleBarHeight_ - 1);
00796 
00797     if ((left && up) || (left && tolUp) || (up && tolLeft)) {
00798         return Cursors::RESIZE_NORTH_WEST_CURSOR;
00799     }
00800     else if ((right && up) || (right && tolUp) || (up && tolRight)) {
00801         return Cursors::RESIZE_NORTH_EAST_CURSOR;
00802     }
00803     else if ((left && down) || (left && tolDown) ||
00804              (down && tolLeft))
00805     {
00806         return Cursors::RESIZE_SOUTH_WEST_CURSOR;
00807     }
00808     else if ((right && down) || (right && tolDown) || (down &&
00809                 tolRight))
00810     {
00811         return Cursors::RESIZE_SOUTH_EAST_CURSOR;
00812     }
00813 
00814     if (left) {
00815         return Cursors::RESIZE_LEFT_CURSOR;
00816     }
00817     else if (right) {
00818         return Cursors::RESIZE_RIGHT_CURSOR;
00819     }
00820     else if (up) {
00821         return Cursors::RESIZE_UP_CURSOR;
00822     }
00823     else if (down) {
00824         return Cursors::RESIZE_DOWN_CURSOR;
00825     }
00826 
00827     return Cursors::NORMAL_CURSOR;
00828 }
00829 
00830 Frame *Client::frame() const {
00831     return frame_;
00832 }
00833 
00834 void Client::setFrame(Frame *frame) {
00835      frame_ = frame;
00836 }
00837 
00838 Workspace *Client::attached() const {
00839     return workspace_;
00840 }
00841 
00842 void Client::setAttached(Workspace *workspace) {
00843      workspace_ = workspace;
00844 }
00845 
00846 Window Client::frameWindow() const {
00847     return frameWindow_;
00848 }
00849 
00850 Window Client::clientWindow() const {
00851     return clientWindow_;
00852 }
00853 
00854 bool Client::requestsFocus() const {
00855     return requestsFocus_;
00856 }
00857 
00858 void Client::setRequestsFocus(bool requestsFocus) {
00859     requestsFocus_ = requestsFocus;
00860 }
00861 
00862 void Client::setHooked(string hooked) {
00863     hooked_ = hooked;
00864     if (hooked_ != "") {
00865         (*KERNEL->sessionSettings())["client." + className_ + "::" +
00866                                     instanceName_ + ".hooked"] = hooked_;
00867     }
00868     else {
00869         Util::remove(KERNEL->sessionSettings(),
00870                      "client." + className_ + "::" + instanceName_ + ".hooked");
00871     }
00872 }
00873 
00874 string Client::hooked() const {
00875     return hooked_;
00876 }
00877 
00878 void Client::setDestroyed(bool isDestroyed) {
00879     isDestroyed_ = isDestroyed;
00880 }
00881 
00882 bool Client::isDestroyed() const {
00883     return isDestroyed_;
00884 }

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