Client.C

Index

      
      #include "Manager.h"
      #include "Client.h"
      
      #include <X11/Xutil.h>
      #include <X11/keysym.h>
      
      #if I18N
      #include <X11/Xmu/Atoms.h>
  10  #endif
      
      const char *const Client::m_defaultLabel = "incognito";
      
      
      
      Client::Client(WindowManager *const wm, Window w) :
          m_window(w),
          m_transient(None),
          m_revert(0),
  20      m_sticky(False),
          m_fixedSize(False),
          m_state(WithdrawnState),
          m_managed(False),
          m_reparenting(False),
          m_stubborn(False),
          m_lastPopTime(0L),
          m_isFullHeight(False),
          m_colormap(None),
          m_colormapWinCount(0),
  30      m_colormapWindows(NULL),
          m_windowColormaps(NULL),
          m_windowManager(wm)
      {
          XWindowAttributes attr;
          XGetWindowAttributes(display(), m_window, &attr);
      
          m_x = attr.x;
          m_y = attr.y;
          m_w = attr.width;
  40      m_h = attr.height;
          m_bw = attr.border_width;
          m_name = m_iconName = 0;
          m_sizeHints.flags = 0L;
      
          m_label = NewString(m_defaultLabel);
          m_border = new Border(this, w);
      
          m_channel = wm->channel();
          m_unmappedForChannel = False;
  50  
      //#if CONFIG_MAD_FEEDBACK != 0
          m_speculating = m_levelRaised = False;
      //#endif
      
          if (attr.map_state == IsViewable) manage(True);
      }
      
      
      Client::~Client()
  60  {
          // empty
      }    
      
      
      void Client::release()
      {
          // assume wm called for this, and will remove me from its list itself
      
          if (m_window == None) {
  70          fprintf(stderr,
                      "wmx: invalid parent in Client::release (released twice?)\n");
          }
      
          windowManager()->skipInRevert(this, m_revert);
      
          if (isHidden()) unhide(False);
          windowManager()->removeFromOrderedList(this);
      
          delete m_border;
  80      m_window = None;
      
          if (isActive()) {
              if (CONFIG_CLICK_TO_FOCUS) {
                  if (m_revert) {
                      windowManager()->setActiveClient(m_revert);
                      m_revert->activate();
                  } else windowManager()->setActiveClient(0);
              } else {
                  windowManager()->setActiveClient(0);
  90          }
          }
      
          if (m_colormapWinCount > 0) {
              XFree((char *)m_colormapWindows);
              free((char *)m_windowColormaps); // not allocated through X
          }
      
          if (m_iconName) XFree(m_iconName);
          if (m_name)     XFree(m_name);
 100      if (m_label) free((void *)m_label);
      
          delete this;
      }
      
      
      void Client::unreparent()
      {
          XWindowChanges wc;
      
 110      if (!isWithdrawn()) {
              gravitate(True);
              XReparentWindow(display(), m_window, root(), m_x, m_y);
          }
      
          wc.border_width = m_bw;
          XConfigureWindow(display(), m_window, CWBorderWidth, &wc);
      
          XSync(display(), True);
      }
 120  
      
      void Client::installColormap()
      {
          Client *cc = 0;
          int i, found;
      
          if (m_colormapWinCount != 0) {
      
              found = 0;
 130  
              for (i = m_colormapWinCount - 1; i >= 0; --i) {
                  windowManager()->installColormap(m_windowColormaps[i]);
                  if (m_colormapWindows[i] == m_window) ++found;
              }
      
              if (found == 0) {
                  windowManager()->installColormap(m_colormap);
              }
      
 140      } else if (m_transient != None &&
                     (cc = windowManager()->windowToClient(m_transient))) {
      
              cc->installColormap();
          } else {
              windowManager()->installColormap(m_colormap);
          }
      }
      
      
 150  void Client::manage(Boolean mapped)
      {
          static int lastX = 0, lastY = 0;
          Boolean shouldHide, reshape;
          XWMHints *hints;
          Display *d = display();
          long mSize;
          int state;
      
          XSelectInput(d, m_window, ColormapChangeMask | EnterWindowMask |
 160                   PropertyChangeMask | FocusChangeMask | KeyPressMask |
                       KeyReleaseMask); //!!!
      
          if (CONFIG_USE_KEYBOARD) {
      
              int i;
              int keycode;
      
              static KeySym keys[] = {
                  CONFIG_FLIP_UP_KEY, CONFIG_FLIP_DOWN_KEY, CONFIG_CIRCULATE_KEY,
 170              CONFIG_HIDE_KEY, CONFIG_DESTROY_KEY, CONFIG_RAISE_KEY,
                  CONFIG_LOWER_KEY, CONFIG_FULLHEIGHT_KEY, CONFIG_NORMALHEIGHT_KEY,
                  CONFIG_STICKY_KEY
      
      #if CONFIG_WANT_KEYBOARD_MENU
                  , CONFIG_MENU_KEY
      #endif
              };
      
              for (i = 0; i < sizeof(keys)/sizeof(keys[0]); ++i) {
 180              keycode = XKeysymToKeycode(display(), keys[i]);
                  if (keycode) {
                      XGrabKey(display(), keycode,
                               CONFIG_ALT_KEY_MASK, m_window, True,
                               GrabModeAsync, GrabModeAsync);
                  }
              }
      
              keycode = XKeysymToKeycode(display(), CONFIG_QUICKRAISE_KEY);
              if (keycode) {
 190              XGrabKey(display(), keycode, 0, m_window, True,
                           GrabModeAsync, GrabModeAsync);
              }
      
              keycode = XKeysymToKeycode(display(), CONFIG_QUICKHIDE_KEY);
              if (keycode) {
                  XGrabKey(display(), keycode, 0, m_window, True,
                           GrabModeAsync, GrabModeAsync);
              }
      
 200          keycode = XKeysymToKeycode(display(), CONFIG_QUICKHEIGHT_KEY);
              if (keycode) {
                  XGrabKey(display(), keycode, 0, m_window, True,
                           GrabModeAsync, GrabModeAsync);
              }
      
              if (CONFIG_USE_CHANNEL_KEYS) {
                  for (i = 0; i < 12; ++i) {
                      keycode = XKeysymToKeycode(display(), XK_F1 + i);
                      if (keycode) {
 210                      XGrabKey(display(), keycode,
                                   CONFIG_ALT_KEY_MASK, m_window, True,
                                   GrabModeAsync, GrabModeAsync);
                      }
                  }
              }
          }
      
          m_iconName = getProperty(XA_WM_ICON_NAME);
          m_name = getProperty(XA_WM_NAME);
 220      setLabel();
      
          getColormaps();
          getProtocols();
          getTransient();
      
          hints = XGetWMHints(d, m_window);
      
      #if CONFIG_USE_WINDOW_GROUPS != False
          m_groupParent = hints ? hints->window_group : None;
 230      if (m_groupParent == None) m_groupParent = m_window;
      //    fprintf(stderr, "Client %p (%s) has window %ld and groupParent %ld\n",
      //          this, m_name, m_window, m_groupParent);
      #endif
      
          if (!getState(&state)) {
              state = hints ? hints->initial_state : NormalState;
          }
      
          shouldHide = (state == IconicState);
 240      if (hints) XFree(hints);
      
          if (XGetWMNormalHints(d, m_window, &m_sizeHints, &mSize) == 0 ||
              m_sizeHints.flags == 0) {
              m_sizeHints.flags = PSize;
          }
      
          m_fixedSize = False;
          if ((m_sizeHints.flags & (PMinSize | PMaxSize)) == (PMinSize | PMaxSize) &&
              (m_sizeHints.min_width  == m_sizeHints.max_width &&
 250           m_sizeHints.min_height == m_sizeHints.max_height)) m_fixedSize = True;
      
          reshape = !mapped;
      
          if (m_fixedSize) {
              if ((m_sizeHints.flags & USPosition)) reshape = False;
              if ((m_sizeHints.flags & PPosition) && shouldHide) reshape = False;
              if ((m_transient != None)) reshape = False;
          }
      
 260      if ((m_sizeHints.flags & PBaseSize)) {
              m_minWidth  = m_sizeHints.base_width;
              m_minHeight = m_sizeHints.base_height;
          } else if ((m_sizeHints.flags & PMinSize)) {
              m_minWidth  = m_sizeHints.min_width;
              m_minHeight = m_sizeHints.min_height;
          } else {
              m_minWidth = m_minHeight = 50;
          }
      
 270      // act
      
          gravitate(False);
      
          // zeros are iffy, should be calling some Manager method
          int dw = DisplayWidth(display(), 0), dh = DisplayHeight(display(), 0);
      
          if (m_w < m_minWidth) {
              m_w = m_minWidth; m_fixedSize = False; reshape = True;
          }
 280      if (m_h < m_minHeight) {
              m_h = m_minHeight; m_fixedSize = False; reshape = True;
          }
      
          if (m_w > dw - 8) m_w = dw - 8;
          if (m_h > dh - 8) m_h = dh - 8;
      
          if (!mapped && m_transient == None &&
              !(m_sizeHints.flags & (PPosition | USPosition))) {
      
 290          lastX += 60; lastY += 40;
      
              if (lastX + m_w + m_border->xIndent() > dw) {
                  lastX = 0;
              }
              if (lastY + m_h + m_border->yIndent() > dh) {
                  lastY = 0;
              }
              m_x = lastX; m_y = lastY;
          }
 300  
          if (m_x > dw - m_border->xIndent()) {
              m_x = dw - m_border->xIndent();
          }
      
          if (m_y > dh - m_border->yIndent()) {
              m_y = dh - m_border->yIndent();
          }
      
          if (m_x < m_border->xIndent()) m_x = m_border->xIndent();
 310      if (m_y < m_border->yIndent()) m_y = m_border->yIndent();
          
          m_border->configure(m_x, m_y, m_w, m_h, 0L, Above);
      
          if (mapped) m_reparenting = True;
          if (reshape && !m_fixedSize) XResizeWindow(d, m_window, m_w, m_h);
          XSetWindowBorderWidth(d, m_window, 0);
      
          m_border->reparent();
      
 320      // (support for shaped windows absent)
      
          XAddToSaveSet(d, m_window);
          m_managed = True;
      
          if (shouldHide) hide();
          else {
              XMapWindow(d, m_window);
              m_border->map();
              setState(NormalState);
 330  
              if (CONFIG_CLICK_TO_FOCUS ||
                  (m_transient != None && activeClient() &&
                  activeClient()->m_window == m_transient)) {
                  activate();
                  mapRaised();
              } else {
                  deactivate();
              }
          }
 340      
          if (activeClient() && !isActive()) {
              activeClient()->installColormap();
          }
      
          if (CONFIG_AUTO_RAISE) {
              m_windowManager->stopConsideringFocus();
              focusIfAppropriate(False);
          }
      
 350      m_windowManager->hoistToTop(this);
          sendConfigureNotify(); // due to Martin Andrews
      }
      
      
      void Client::selectOnMotion(Window w, Boolean select)
      {
          if (!CONFIG_AUTO_RAISE) return;
          if (!w || w == root()) return;
      
 360      if (w == m_window || m_border->hasWindow(w)) {
              XSelectInput(display(), m_window, // not "w"
                           ColormapChangeMask | EnterWindowMask |
                           PropertyChangeMask | FocusChangeMask |
                           (select ? PointerMotionMask : 0L));
          } else {
              XSelectInput(display(), w, select ? PointerMotionMask : 0L);
          }
      }
      
 370  
      void Client::decorate(Boolean active)
      {
          m_border->decorate(active, m_w, m_h);
      }
      
      
      void Client::activate()
      {
      //    fprintf(stderr, "Client::activate (this = %p, window = %x, parent = %x)\n",
 380  //          this, m_window, parent());
      
          if (parent() == root()) {
              fprintf(stderr, "wmx: warning: bad parent in Client::activate\n");
              return;
          }
      
          if (!m_managed || isHidden() || isWithdrawn() ||
              (m_channel != windowManager()->channel())) return;
      
 390      if (isActive()) {
              decorate(True);
              if (CONFIG_AUTO_RAISE || CONFIG_RAISE_ON_FOCUS) mapRaised();
              return;
          }
      
          if (activeClient()) {
              activeClient()->deactivate();
              // & some other-screen business
          }
 400  
          XUngrabButton(display(), AnyButton, AnyModifier, parent());
      
          XSetInputFocus(display(), m_window, RevertToPointerRoot,
                         windowManager()->timestamp(False));
      
          if (m_protocol & PtakeFocus) {
              sendMessage(Atoms::wm_protocols, Atoms::wm_takeFocus);
          }
      
 410      // now set revert of window that reverts to this one so as to
          // revert to the window this one used to revert to (huh?)
      
          windowManager()->skipInRevert(this, m_revert);
      
          m_revert = activeClient();
          while (m_revert && !m_revert->isNormal()) m_revert = m_revert->revertTo();
      
          windowManager()->setActiveClient(this);
          decorate(True);
 420  
          installColormap();          // new!
      }
      
      
      void Client::deactivate()       // called from wm?
      {
          if (parent() == root()) {
              fprintf(stderr, "wmx: warning: bad parent in Client::deactivate\n");
              return;
 430      }
      
          XGrabButton(display(), AnyButton, AnyModifier, parent(), False,
                      ButtonPressMask | ButtonReleaseMask,
                      GrabModeAsync, GrabModeSync, None, None);
      
          decorate(False);
      }
      
      
 440  void Client::sendMessage(Atom a, long l)
      {
          XEvent ev;
          int status;
          long mask;
      
          memset(&ev, 0, sizeof(ev));
          ev.xclient.type = ClientMessage;
          ev.xclient.window = m_window;
          ev.xclient.message_type = a;
 450      ev.xclient.format = 32;
          ev.xclient.data.l[0] = l;
          ev.xclient.data.l[1] = windowManager()->timestamp(False);
          mask = 0L;
          status = XSendEvent(display(), m_window, False, mask, &ev);
      
          if (status == 0) {
              fprintf(stderr, "wmx: warning: Client::sendMessage failed\n");
          }
      }
 460  
      
      static int getProperty_aux(Display *d, Window w, Atom a, Atom type, long len,
                                 unsigned char **p)
      {
          Atom realType;
          int format;
          unsigned long n, extra;
          int status;
          Boolean retried = False;
 470  
      tryagain:
          status = XGetWindowProperty(d, w, a, 0L, len, False, type, &realType,
                                      &format, &n, &extra, p);
      
          if (status != Success || *p == 0) return -1;
          if (n == 0) XFree((void *) *p);
          if (type == XA_STRING || type == AnyPropertyType || retried) {
              if (realType != XA_STRING || format != 8) {
      #if I18N
 480              // XA_STRING is needed by a caller.  But XGetWindowProperty()
                  // returns other typed data.  So try to convert them.
                  XTextProperty textprop;
                  textprop.value = *p;
                  textprop.encoding = realType;
                  textprop.format = format;
                  textprop.nitems = n;
      
                  char **list;
                  int num, cnt;
 490              cnt = XmbTextPropertyToTextList(d, &textprop, &list, &num);
                  unsigned char *string;
                  if (cnt == Success && num > 0 && *list) {
                      string = (unsigned char*)NewString(*list);
                      XFreeStringList(list);
                      n = num;
                  } else if (cnt > Success) {
                      fprintf(stderr, "Something wrong, cannot conver "
                              "text property\n"
                              "  original type %ld, string %s\n"
 500                          "  converted string %s\n"
                              "  decide to use original value as STRING\n",
                              textprop.encoding, textprop.value, *list);
                      string = (unsigned char*)NewString(*(char**)p);
                      XFreeStringList(list);
                      n = n;
                  } else if (!retried) {
                      retried = True;
                      type = AnyPropertyType;
                      goto tryagain;
 510              } else {
                      string = NULL;
                      n = 0;
                  }
                  XFree((void *) *p);
                  *p = string;
      #else
                  XFree((void *) *p);
                  *p = NULL;
      #endif
 520          }
          }
      
          return n;
      }
      
      
      char *Client::getProperty(Atom a)
      {
          unsigned char *p;
 530  
          // no -- allow any type, not just string -- SGI has "compound
          // text", and part-garbage is possibly better than "incognito" --
          // thanks to Bill Spitzak
      
      //    if (getProperty_aux(display(), m_window, a, XA_STRING, 100L, &p) <= 0) {
          if (getProperty_aux(display(), m_window, a, AnyPropertyType, 100L, &p) <= 0) {
              return NULL;
          }
          return (char *)p;
 540  }
      
      
      int Client::getAtomProperty(Atom a, Atom type)
      {
          char **p, *x;
          if (getProperty_aux(display(), m_window, a, type, 1L,
                              (unsigned char **)&p) <= 0) {
              return 0;
          }
 550  
          x = *p;
          XFree((void *)p);
          return (int)x;
      }
      
      
      int Client::getIntegerProperty(Atom a)
      {
          return getAtomProperty(a, XA_INTEGER);
 560  }
      
      
      void Client::setState(int state)
      {
          m_state = state;
      
          long data[2];
          data[0] = (long)state;
          data[1] = (long)None;
 570  
          XChangeProperty(display(), m_window, Atoms::wm_state, Atoms::wm_state,
                          32, PropModeReplace, (unsigned char *)data, 2);
      }
      
      
      Boolean Client::getState(int *state)
      {
          long *p = 0;
      
 580      if (getProperty_aux(display(), m_window, Atoms::wm_state, Atoms::wm_state,
                              2L, (unsigned char **)&p) <= 0) {
              return False;
          }
      
          *state = (int) *p;
          XFree((char *)p);
          return True;
      }
      
 590  
      void Client::getProtocols()
      {
          long n;
          Atom *p;
      
          m_protocol = 0;
          if ((n = getProperty_aux(display(), m_window, Atoms::wm_protocols, XA_ATOM,
                                   20L, (unsigned char **)&p)) <= 0) {
              return;
 600      }
      
          for (int i = 0; i < n; ++i) {
              if (p[i] == Atoms::wm_delete) {
                  m_protocol |= Pdelete;
              } else if (p[i] == Atoms::wm_takeFocus) {
                  m_protocol |= PtakeFocus;
              }
          }
      
 610      XFree((char *) p);
      }
      
      
      void Client::gravitate(Boolean invert)
      {
          int gravity;
          int w = 0, h = 0, xdelta, ydelta;
      
          // possibly shouldn't work if we haven't been managed yet?
 620  
          gravity = NorthWestGravity;
          if (m_sizeHints.flags & PWinGravity) gravity = m_sizeHints.win_gravity;
      
          xdelta = m_bw - m_border->xIndent();
          ydelta = m_bw - m_border->yIndent();
      
          // note that right and bottom borders have indents of 1
      
          switch (gravity) {
 630  
          case NorthWestGravity:
              break;
      
          case NorthGravity:
              w = xdelta;
              break;
      
          case NorthEastGravity:
              w = xdelta + m_bw-1;
 640          break;
      
          case WestGravity:
              h = ydelta;
              break;
      
          case CenterGravity:
          case StaticGravity:
              w = xdelta;
              h = ydelta;
 650          break;
      
          case EastGravity:
              w = xdelta + m_bw-1;
              h = ydelta;
              break;
      
          case SouthWestGravity:
              h = ydelta + m_bw-1;
              break;
 660  
          case SouthGravity:
              w = xdelta;
              h = ydelta + m_bw-1;
              break;
      
          case SouthEastGravity:
              w = xdelta + m_bw-1;
              h = ydelta + m_bw-1;
              break;
 670  
          default:
              fprintf(stderr, "wmx: bad window gravity %d for window 0x%lx\n",
                      gravity, m_window);
              return;
          }
      
          w += m_border->xIndent();
          h += m_border->yIndent();
      
 680      if (invert) { w = -w; h = -h; }
      
          m_x += w;
          m_y += h;
      }
      
      
      Boolean Client::setLabel(void)
      {
          const char *newLabel;
 690  
          if (m_name) newLabel = m_name;
          else if (m_iconName) newLabel = m_iconName;
          else newLabel = m_defaultLabel;
      
          if (!m_label) {
      
              m_label = NewString(newLabel);
              return True;
      
 700      } else if (strcmp(m_label, newLabel)) {
      
              free((void *)m_label);
              m_label = NewString(newLabel);
              return True;
      
          } else return True;//False;// dammit!
      }
      
      
 710  void Client::getColormaps(void)
      {
          int i, n;
          Window *cw;
          XWindowAttributes attr;
      
          if (!m_managed) {
              XGetWindowAttributes(display(), m_window, &attr);
              m_colormap = attr.colormap;
          }
 720  
          n = getProperty_aux(display(), m_window, Atoms::wm_colormaps, XA_WINDOW,
                              100L, (unsigned char **)&cw);
      
          if (m_colormapWinCount != 0) {
              XFree((char *)m_colormapWindows);
              free((char *)m_windowColormaps);
          }
      
          if (n <= 0) {
 730          m_colormapWinCount = 0;
              return;
          }
          
          m_colormapWinCount = n;
          m_colormapWindows = cw;
      
          m_windowColormaps = (Colormap *)malloc(n * sizeof(Colormap));
      
          for (i = 0; i < n; ++i) {
 740          if (cw[i] == m_window) {
                  m_windowColormaps[i] = m_colormap;
              } else {
                  XSelectInput(display(), cw[i], ColormapChangeMask);
                  XGetWindowAttributes(display(), cw[i], &attr);
                  m_windowColormaps[i] = attr.colormap;
              }
          }
      }
      
 750  
      void Client::getTransient()
      {
          Window t = None;
      
          if (XGetTransientForHint(display(), m_window, &t) != 0) {
      
              if (windowManager()->windowToClient(t) == this) {
                  fprintf(stderr,
                          "wmx: warning: client \"%s\" thinks it's a transient "
 760                      "for\nitself -- ignoring WM_TRANSIENT_FOR property...\n",
                          m_label ? m_label : "(no name)");
                  m_transient = None;
              } else {                
                  m_transient = t;
              }
          } else {
              m_transient = None;
          }
      }
 770  
      
      void Client::hide()
      {
          if (isHidden()) {
              fprintf(stderr, "wmx: Client already hidden in Client::hide\n");
              return;
          }
      
          m_border->unmap();
 780      XUnmapWindow(display(), m_window);
      
          if (isActive()) windowManager()->clearFocus();
      
          setState(IconicState);
          windowManager()->addToHiddenList(this);
      
      #if CONFIG_USE_WINDOW_GROUPS != False
          if (isGroupParent()) {
              windowManager()->hideGroup(groupParent(), this);
 790      }
      #endif
      }
      
      
      void Client::unhide(Boolean map)
      {
          if (CONFIG_MAD_FEEDBACK) {
              m_speculating = False;
              if (!isHidden()) return;
 800      }
      
          if (!isHidden()) {
              fprintf(stderr, "wmx: Client not hidden in Client::unhide\n");
              return;
          }
      
          windowManager()->removeFromHiddenList(this);
      
          if (map) {
 810          setState(NormalState);
      
              if (m_channel == windowManager()->channel()) {
                  XMapWindow(display(), m_window);
              }
              mapRaised();
      
              if (CONFIG_AUTO_RAISE) focusIfAppropriate(False);
              else if (CONFIG_CLICK_TO_FOCUS) activate();
          }
 820  
      #if CONFIG_USE_WINDOW_GROUPS != False
          if (isGroupParent()) {
              windowManager()->unhideGroup(groupParent(), this, map);
          }
      #endif
      }
      
      
      void Client::sendConfigureNotify()
 830  {
          XConfigureEvent ce;
      
          ce.type   = ConfigureNotify;
          ce.event  = m_window;
          ce.window = m_window;
      
          ce.x = m_x;
          ce.y = m_y;
          ce.width  = m_w;
 840      ce.height = m_h;
          ce.border_width = m_bw;
          ce.above = None;
          ce.override_redirect = 0;
      
          XSendEvent(display(), m_window, False, StructureNotifyMask, (XEvent*)&ce);
      }
      
      
      void Client::withdraw(Boolean changeState)
 850  {
          m_border->unmap();
      
          gravitate(True);
          XReparentWindow(display(), m_window, root(), m_x, m_y);
      
          gravitate(False);
      
          if (changeState) {
              XRemoveFromSaveSet(display(), m_window);
 860          setState(WithdrawnState);
          }
      
      #if CONFIG_USE_WINDOW_GROUPS != False
          if (isGroupParent()) {
              windowManager()->withdrawGroup(groupParent(), this, changeState);
          }
      #endif
      
          ignoreBadWindowErrors = True;
 870      XSync(display(), False);
          ignoreBadWindowErrors = False;
      }
      
      
      void Client::rename()
      {
          m_border->configure(0, 0, m_w, m_h, CWWidth | CWHeight, Above);
      }
      
 880  
      void Client::mapRaised()
      {
          if (m_channel == windowManager()->channel()) m_border->mapRaised();
          windowManager()->hoistToTop(this);
          windowManager()->raiseTransients(this);
      }
      
      
      void Client::kill()
 890  {
          if (m_protocol & Pdelete) {
              sendMessage(Atoms::wm_protocols, Atoms::wm_delete);
          } else {
              XKillClient(display(), m_window);
          }
      
      #if CONFIG_USE_WINDOW_GROUPS != False
          if (isGroupParent()) {
              windowManager()->killGroup(groupParent(), this);
 900      }
      #endif
      }
      
      
      void Client::ensureVisible()
      {
          int mx = DisplayWidth(display(), 0) - 1; // hack
          int my = DisplayHeight(display(), 0) - 1;
          int px = m_x;
 910      int py = m_y;
          
          if (m_x + m_w > mx) m_x = mx - m_w;
          if (m_y + m_h > my) m_y = my - m_h;
          if (m_x < 0) m_x = 0;
          if (m_y < 0) m_y = 0;
      
          if (m_x != px || m_y != py) {
              m_border->moveTo(m_x, m_y);
              sendConfigureNotify();
 920      }
      }
      
      
      void Client::lower()
      {
          m_border->lower();
          windowManager()->hoistToBottom(this);
      }
      
 930  
      void Client::raiseOrLower()
      {
          if (windowManager()->isTop(this)) {
              lower();
          } else {
              mapRaised();
          }
      }
      
 940  
      void Client::fullHeight()
      {
          if (m_isFullHeight || m_fixedSize || (m_transient != None)) return;
      
          m_normalH = m_h;
          m_normalY = m_y;
      
          m_h = DisplayHeight(display(), windowManager()->screen())
              - m_border->yIndent() - 1;
 950      int dw, dh;
      
          fixResizeDimensions(m_w, m_h, dw, dh);
      
          if (m_h > m_normalH) {
              m_y -= (m_h - m_normalH);
              if (m_y < m_border->yIndent()) m_y = m_border->yIndent();
          }
      
          m_isFullHeight = True;
 960      m_border->configure(m_x, m_y, m_w, m_h, CWY | CWHeight, 0);
          XResizeWindow(display(), m_window, m_w, m_h);
          sendConfigureNotify();
      }
      
      
      void Client::normalHeight()
      {
          if (!m_isFullHeight) return;
      
 970      m_h = m_normalH;
          m_y = m_normalY;
      
          m_isFullHeight = False;
          m_border->configure(m_x, m_y, m_w, m_h, CWY | CWHeight, 0);
          XResizeWindow(display(), m_window, m_w, m_h);
          sendConfigureNotify();
      }
      
      
 980  void Client::warpPointer()
      {
          XWarpPointer(display(), None, parent(), 0, 0, 0, 0,
                       m_border->xIndent() / 2, m_border->xIndent() + 8);
      }
      
      
      void Client::flipChannel(Boolean leaving, int newChannel)
      {
      //    fprintf(stderr, "I could be supposed to pop up now...\n");
 990  
          if (m_channel != windowManager()->channel()) {
      
              if (CONFIG_MAD_FEEDBACK) {
                  if (leaving && m_channel == newChannel &&
                      m_unmappedForChannel) {
                      showFeedback();
                  }
              }
      
1000          return;
          }
      
          if (leaving) {
      
              if (CONFIG_MAD_FEEDBACK) {
                  removeFeedback(isNormal()); // mostly it won't be there anyway, but...
              }
      
              if (!isNormal()) return;
1010          m_unmappedForChannel = True;
              XUnmapWindow(display(), m_window);
              withdraw(False);
              return;
      
          } else {
      
              if (CONFIG_MAD_FEEDBACK) {
                  removeFeedback(isNormal()); // likewise
              }
1020  
              if (!m_unmappedForChannel) {
                  if (isNormal()) mapRaised();
                  return;
              }
      
              m_unmappedForChannel = False;
      
              setState(WithdrawnState);
              m_border->reparent();
1030          if (CONFIG_AUTO_RAISE) m_windowManager->stopConsideringFocus();
              XAddToSaveSet(display(), m_window);
              XMapWindow(display(), m_window);
              setState(NormalState);
              mapRaised();
              if (CONFIG_CLICK_TO_FOCUS) activate();
          }
      }
      
      
1040  void Client::showFeedback()
      {
          if (CONFIG_MAD_FEEDBACK) {
              if (m_speculating || m_levelRaised) removeFeedback(False);
              m_border->showFeedback(m_x, m_y, m_w, m_h);
      //    XSync(display(), False);
          }
      }
      
      void Client::raiseFeedbackLevel()
1050  {
          if (CONFIG_MAD_FEEDBACK) {
      
              m_border->removeFeedback();
              m_levelRaised = True;
      
              if (isNormal()) {
                  mapRaised();
              } else if (isHidden()) {
                  unhide(True);
1060              m_speculating = True;
      //      XSync(display(), False);
              }
          }
      }
      
      void Client::removeFeedback(Boolean mapped)
      {
          if (CONFIG_MAD_FEEDBACK) {
      
1070          m_border->removeFeedback();
              
              if (m_levelRaised) {
                  if (m_speculating) {
                      if (!mapped) hide();
                      XSync(display(), False);
                  } else {
                      // not much we can do
                  }
              }
1080  
              m_speculating = m_levelRaised = False;
          }
      }
      
      

Index

  • Client::release (function) returns void
  • Client::unreparent (function) returns void
  • Client::installColormap (function) returns void
  • Client::manage (function) returns void
  • Client::selectOnMotion (function) returns void
  • Client::decorate (function) returns void
  • Client::activate (function) returns void
  • Client::deactivate (function) returns void
  • Client::sendMessage (function) returns void
  • getProperty_aux (function) returns static int
  • Client::getProperty (function) returns char *
  • Client::getAtomProperty (function) returns int
  • Client::getIntegerProperty (function) returns int
  • Client::setState (function) returns void
  • Client::getState (function) returns Boolean
  • Client::getProtocols (function) returns void
  • Client::gravitate (function) returns void
  • Client::setLabel (function) returns Boolean
  • Client::getColormaps (function) returns void
  • Client::getTransient (function) returns void
  • Client::hide (function) returns void
  • Client::unhide (function) returns void
  • Client::sendConfigureNotify (function) returns void
  • Client::withdraw (function) returns void
  • Client::rename (function) returns void
  • Client::mapRaised (function) returns void
  • Client::kill (function) returns void
  • Client::ensureVisible (function) returns void
  • Client::lower (function) returns void
  • Client::raiseOrLower (function) returns void
  • Client::fullHeight (function) returns void
  • Client::normalHeight (function) returns void
  • Client::warpPointer (function) returns void
  • Client::flipChannel (function) returns void
  • Client::showFeedback (function) returns void
  • Client::raiseFeedbackLevel (function) returns void
  • Client::removeFeedback (function) returns void