Exemple #1
0
void
subEwmhFinish(void)
{
  /* Delete root properties on real shutdown */
  if(subtle->flags & SUB_SUBTLE_EWMH)
    {
      /* EWMH properties */
      subSharedPropertyDelete(subtle->dpy, ROOT, subEwmhGet(SUB_EWMH_NET_SUPPORTED));
      subSharedPropertyDelete(subtle->dpy, ROOT, subEwmhGet(SUB_EWMH_NET_SUPPORTING_WM_CHECK));
      subSharedPropertyDelete(subtle->dpy, ROOT, subEwmhGet(SUB_EWMH_NET_ACTIVE_WINDOW));
      subSharedPropertyDelete(subtle->dpy, ROOT, subEwmhGet(SUB_EWMH_NET_CURRENT_DESKTOP));
      subSharedPropertyDelete(subtle->dpy, ROOT, subEwmhGet(SUB_EWMH_NET_DESKTOP_NAMES));
      subSharedPropertyDelete(subtle->dpy, ROOT, subEwmhGet(SUB_EWMH_NET_NUMBER_OF_DESKTOPS));
      subSharedPropertyDelete(subtle->dpy, ROOT, subEwmhGet(SUB_EWMH_NET_DESKTOP_VIEWPORT));
      subSharedPropertyDelete(subtle->dpy, ROOT, subEwmhGet(SUB_EWMH_NET_DESKTOP_GEOMETRY));
      subSharedPropertyDelete(subtle->dpy, ROOT, subEwmhGet(SUB_EWMH_NET_WORKAREA));
      subSharedPropertyDelete(subtle->dpy, ROOT, subEwmhGet(SUB_EWMH_NET_CLIENT_LIST));
      subSharedPropertyDelete(subtle->dpy, ROOT, subEwmhGet(SUB_EWMH_NET_CLIENT_LIST_STACKING));

      /* subtle extension */
      subSharedPropertyDelete(subtle->dpy, ROOT, subEwmhGet(SUB_EWMH_SUBTLE_GRAVITY_LIST));
      subSharedPropertyDelete(subtle->dpy, ROOT, subEwmhGet(SUB_EWMH_SUBTLE_TAG_LIST));
      subSharedPropertyDelete(subtle->dpy, ROOT, subEwmhGet(SUB_EWMH_SUBTLE_TRAY_LIST));
      subSharedPropertyDelete(subtle->dpy, ROOT, subEwmhGet(SUB_EWMH_SUBTLE_VIEW_TAGS));
      subSharedPropertyDelete(subtle->dpy, ROOT, subEwmhGet(SUB_EWMH_SUBTLE_COLORS));
      subSharedPropertyDelete(subtle->dpy, ROOT, subEwmhGet(SUB_EWMH_SUBTLE_FONT));
      subSharedPropertyDelete(subtle->dpy, ROOT, subEwmhGet(SUB_EWMH_SUBTLE_SUBLET_LIST));
      subSharedPropertyDelete(subtle->dpy, ROOT, subEwmhGet(SUB_EWMH_SUBTLE_SCREEN_VIEWS));
      subSharedPropertyDelete(subtle->dpy, ROOT, subEwmhGet(SUB_EWMH_SUBTLE_VISIBLE_VIEWS));
      subSharedPropertyDelete(subtle->dpy, ROOT, subEwmhGet(SUB_EWMH_SUBTLE_VISIBLE_TAGS));
    }

  subSubtleLogDebugSubtle("Finish\n");
} /* }}} */
Exemple #2
0
void
subScreenKill(SubScreen *s)
{
  assert(s);

  if(s->panels) subArrayKill(s->panels, True);

  /* Destroy panel windows */
  if(s->panel1)
    {
      XDeleteContext(subtle->dpy, s->panel1, SCREENID);
      XDestroyWindow(subtle->dpy, s->panel1);
    }
  if(s->panel2)
    {
      XDeleteContext(subtle->dpy, s->panel2, SCREENID);
      XDestroyWindow(subtle->dpy, s->panel2);
    }

  /* Destroy drawable */
  if(s->drawable) XFreePixmap(subtle->dpy, s->drawable);

  free(s);

  subSubtleLogDebugSubtle("Kill\n");
} /* }}} */
Exemple #3
0
void
subScreenPublish(void)
{
  int i;
  long *views = NULL;

  assert(subtle);

  /* EWMH: Views per screen */
  views = (long *)subSharedMemoryAlloc(subtle->screens->ndata,
    sizeof(long));

  /* Collect views */
  for(i = 0; i < subtle->screens->ndata; i++)
    views[i] = SCREEN(subtle->screens->data[i])->viewid;

  subEwmhSetCardinals(ROOT, SUB_EWMH_SUBTLE_SCREEN_VIEWS,
    views, subtle->screens->ndata);

  free(views);

  XSync(subtle->dpy, False); ///< Sync all changes

  subSubtleLogDebugSubtle("Publish: screens=%d\n",
    subtle->screens->ndata);
} /* }}} */
Exemple #4
0
SubScreen *
subScreenCurrent(int *sid)
{
  SubScreen *ret = NULL;

  /* Check if there is only one screen */
  if(1 == subtle->screens->ndata)
    {
      if(sid) *sid = 0;

      ret = SCREEN(subtle->screens->data[0]);
    }
  else
    {
      int rx = 0, ry = 0, x = 0, y = 0;
      Window root = None, win = None;
      unsigned int mask = 0;

      /* Get current screen */
      XQueryPointer(subtle->dpy, ROOT, &root, &win, &rx, &ry, &x, &y, &mask);

      ret = subScreenFind(rx, ry, sid);
    }

  subSubtleLogDebugSubtle("Current\n");

  return ret;
} /* }}} */
Exemple #5
0
SubScreen *
subScreenFind(int x,
  int y,
  int *sid)
{
  int i;
  SubScreen *ret = SCREEN(subtle->screens->data[0]);

  /* Check screens */
  for(i = 0; i < subtle->screens->ndata; i++)
    {
      SubScreen *s = SCREEN(subtle->screens->data[i]);

      /* Check if coordinates are in screen rects */
      if((x >= s->base.x && x < s->base.x + s->base.width) &&
          (y >= s->base.y && y < s->base.y + s->base.height))
        {
          ret = s;
          if(sid) *sid = i;

          break;
        }
    }

  subSubtleLogDebugSubtle("Find\n");

  return ret;
} /* }}} */
Exemple #6
0
void
subHookKill(SubHook *h)
{
  assert(h);

  free(h);

  subSubtleLogDebugSubtle("kill=hook\n");
} /* }}} */
Exemple #7
0
void
subScreenWarp(SubScreen *s)
{
  assert(s);

  /* Move pointer to screen center */
  XWarpPointer(subtle->dpy, None, ROOT, 0, 0, s->geom.x, s->geom.y,
    s->geom.x + s->geom.width / 2, s->geom.y + s->geom.height / 2);

  subSubtleLogDebugSubtle("Warp\n");
} /* }}} */
Exemple #8
0
void
subScreenResize(void)
{
  int i;

  assert(subtle);

  /* Update screens */
  for(i = 0; i < subtle->screens->ndata; i++)
    {
      SubScreen *s = SCREEN(subtle->screens->data[i]);

      /* Add strut */
      s->geom.x      = s->base.x + subtle->styles.subtle.padding.left;
      s->geom.y      = s->base.y + subtle->styles.subtle.padding.top;
      s->geom.width  = s->base.width - subtle->styles.subtle.padding.left -
        subtle->styles.subtle.padding.right;
      s->geom.height = s->base.height - subtle->styles.subtle.padding.top -
        subtle->styles.subtle.padding.bottom;

      /* Update panels */
      if(s->flags & SUB_SCREEN_PANEL1)
        {
          XMoveResizeWindow(subtle->dpy, s->panel1, s->base.x, s->base.y,
            s->base.width, subtle->ph);
          XMapRaised(subtle->dpy, s->panel1);

          /* Update height */
          s->geom.y      += subtle->ph;
          s->geom.height -= subtle->ph;
        }
      else XUnmapWindow(subtle->dpy, s->panel1);

      if(s->flags & SUB_SCREEN_PANEL2)
        {
          XMoveResizeWindow(subtle->dpy, s->panel2, s->base.x,
            s->base.y + s->base.height - subtle->ph, s->base.width, subtle->ph);
          XMapRaised(subtle->dpy, s->panel2);

          /* Update height */
          s->geom.height -= subtle->ph;
        }
      else XUnmapWindow(subtle->dpy, s->panel2);

      /* Create/update drawable for double buffering */
      if(s->drawable) XFreePixmap(subtle->dpy, s->drawable);
      s->drawable = XCreatePixmap(subtle->dpy, ROOT, s->base.width, subtle->ph,
        XDefaultDepth(subtle->dpy, DefaultScreen(subtle->dpy)));
    }

  ScreenPublish();

  subSubtleLogDebugSubtle("Resize\n");
} /* }}} */
Exemple #9
0
/* ScreenPublish {{{ */
static void
ScreenPublish(void)
{
  int i;
  long *workareas = NULL, *panels = NULL, *viewports = NULL;

  assert(subtle);

  /* EWMH: Workarea and screen panels */
  workareas = (long *)subSharedMemoryAlloc(4 * subtle->screens->ndata,
    sizeof(long));
  panels = (long *)subSharedMemoryAlloc(2 * subtle->screens->ndata,
    sizeof(long));

  /* Collect data*/
  for(i = 0; i < subtle->screens->ndata; i++)
    {
      SubScreen *s = SCREEN(subtle->screens->data[i]);

      /* Set workareas */
      workareas[i * 4 + 0] = s->geom.x;
      workareas[i * 4 + 1] = s->geom.y;
      workareas[i * 4 + 2] = s->geom.width;
      workareas[i * 4 + 3] = s->geom.height;

      /* Set panels */
      panels[i * 2 + 0] = s->flags & SUB_SCREEN_PANEL1 ? subtle->ph : 0;
      panels[i * 2 + 1] = s->flags & SUB_SCREEN_PANEL2 ? subtle->ph : 0;
    }

  subEwmhSetCardinals(ROOT, SUB_EWMH_NET_WORKAREA, workareas,
    4 * subtle->screens->ndata);
  subEwmhSetCardinals(ROOT, SUB_EWMH_SUBTLE_SCREEN_PANELS, panels,
    2 * subtle->screens->ndata);

  /* EWMH: Desktop viewport */
  viewports = (long *)subSharedMemoryAlloc(2 * subtle->screens->ndata,
    sizeof(long)); ///< Calloc inits with zero - great

  subEwmhSetCardinals(ROOT, SUB_EWMH_NET_DESKTOP_VIEWPORT, viewports,
    2 * subtle->screens->ndata);

  free(workareas);
  free(panels);
  free(viewports);

  XSync(subtle->dpy, False); ///< Sync all changes

  subSubtleLogDebugSubtle("Publish: screens=%d\n",
    subtle->screens->ndata);
} /* }}} */
Exemple #10
0
SubHook *
subHookNew(int type,
  unsigned long proc)
{
  SubHook *h = NULL;

  assert(proc);

  /* Create new hook */
  h = HOOK(subSharedMemoryAlloc(1, sizeof(SubHook)));
  h->flags = (SUB_TYPE_HOOK|type);
  h->proc  = proc;

  subSubtleLogDebugSubtle("new=hook, type=%d, proc=%ld\n", type, proc);

  return h;
} /* }}} */
Exemple #11
0
SubScreen *
subScreenNew(int x,
  int y,
  unsigned int width,
  unsigned int height)
{
  SubScreen *s = NULL;
  XSetWindowAttributes sattrs;
  unsigned long mask = 0;

  /* Create screen */
  s = SCREEN(subSharedMemoryAlloc(1, sizeof(SubScreen)));
  s->flags       = SUB_TYPE_SCREEN;
  s->geom.x      = x;
  s->geom.y      = y;
  s->geom.width  = width;
  s->geom.height = height;
  s->base        = s->geom; ///< Backup size
  s->viewid      = subtle->screens->ndata; ///< Init

  /* Create panel windows */
  sattrs.event_mask        = ButtonPressMask|EnterWindowMask|
    LeaveWindowMask|ExposureMask;
  sattrs.override_redirect = True;
  sattrs.background_pixmap = ParentRelative;
  mask                     = CWEventMask|CWOverrideRedirect|CWBackPixmap;

  s->panel1 = XCreateWindow(subtle->dpy, ROOT, 0, 1, 1, 1, 0,
    CopyFromParent, InputOutput, CopyFromParent, mask, &sattrs);
  s->panel2 = XCreateWindow(subtle->dpy, ROOT, 0, 0, 1, 1, 0,
    CopyFromParent, InputOutput, CopyFromParent, mask, &sattrs);

  XSaveContext(subtle->dpy, s->panel1, SCREENID, (void *)s);
  XSaveContext(subtle->dpy, s->panel2, SCREENID, (void *)s);

  subSubtleLogDebugSubtle("New: x=%d, y=%d, width=%u, height=%u\n",
    s->geom.x, s->geom.y, s->geom.width, s->geom.height);

  return s;
} /* }}} */
Exemple #12
0
void
subScreenRender(void)
{
  int i, j;

  /* Render all screens */
  for(i = 0; i < subtle->screens->ndata; i++)
    {
      SubScreen *s = SCREEN(subtle->screens->data[i]);
      Window panel = s->panel1;

      ScreenClear(s, subtle->styles.subtle.top);

      /* Render panel items */
      for(j = 0; s->panels && j < s->panels->ndata; j++)
        {
          SubPanel *p = PANEL(s->panels->data[j]);

          if(p->flags & SUB_PANEL_HIDDEN) continue;
          if(panel != s->panel2 && p->flags & SUB_PANEL_BOTTOM)
            {
              XCopyArea(subtle->dpy, s->drawable, panel, subtle->gcs.draw,
                0, 0, s->base.width, subtle->ph, 0, 0);

              ScreenClear(s, subtle->styles.subtle.bottom);
              panel = s->panel2;
            }

          subPanelRender(p, s->drawable);
        }

      XCopyArea(subtle->dpy, s->drawable, panel, subtle->gcs.draw,
        0, 0, s->base.width, subtle->ph, 0, 0);
    }

  XSync(subtle->dpy, False); ///< Sync before going on

  subSubtleLogDebugSubtle("Render\n");
} /* }}} */
Exemple #13
0
void
subEwmhInit(void)
{
  int len = 0;
  long data[2] = { 0, 0 }, pid = (long)getpid();
  char *selection = NULL, *names[] =
  {
    /* ICCCM */
    "WM_NAME", "WM_CLASS", "WM_STATE", "WM_PROTOCOLS", "WM_TAKE_FOCUS",
    "WM_DELETE_WINDOW", "WM_NORMAL_HINTS", "WM_SIZE_HINTS", "WM_HINTS",
    "WM_WINDOW_ROLE", "WM_CLIENT_LEADER",

    /* EWMH */
    "_NET_SUPPORTED", "_NET_CLIENT_LIST", "_NET_CLIENT_LIST_STACKING",
    "_NET_NUMBER_OF_DESKTOPS", "_NET_DESKTOP_NAMES", "_NET_DESKTOP_GEOMETRY",
    "_NET_DESKTOP_VIEWPORT", "_NET_CURRENT_DESKTOP", "_NET_ACTIVE_WINDOW",
    "_NET_WORKAREA", "_NET_SUPPORTING_WM_CHECK", "_NET_WM_FULL_PLACEMENT",
    "_NET_FRAME_EXTENTS",

    /* Client */
    "_NET_CLOSE_WINDOW", "_NET_RESTACK_WINDOW", "_NET_MOVERESIZE_WINDOW",
    "_NET_WM_NAME", "_NET_WM_PID", "_NET_WM_DESKTOP", "_NET_WM_STRUT",

    /* Types */
    "_NET_WM_WINDOW_TYPE", "_NET_WM_WINDOW_TYPE_DOCK",
    "_NET_WM_WINDOW_TYPE_DESKTOP", "_NET_WM_WINDOW_TYPE_TOOLBAR",
    "_NET_WM_WINDOW_TYPE_SPLASH", "_NET_WM_WINDOW_TYPE_DIALOG",

    /* States */
    "_NET_WM_STATE", "_NET_WM_STATE_FULLSCREEN", "_NET_WM_STATE_ABOVE",
    "_NET_WM_STATE_STICKY", "_NET_WM_STATE_DEMANDS_ATTENTION",

    /* Tray */
    "_NET_SYSTEM_TRAY_OPCODE", "_NET_SYSTEM_TRAY_MESSAGE_DATA",
    "_NET_SYSTEM_TRAY_S",

    /* Misc */
    "UTF8_STRING", "MANAGER", "_MOTIF_WM_HINTS",

    /* XEmbed */
    "_XEMBED", "_XEMBED_INFO",

    /* subtle */
    "SUBTLE_CLIENT_TAGS", "SUBTLE_CLIENT_RETAG",
    "SUBTLE_CLIENT_GRAVITY", "SUBTLE_CLIENT_SCREEN", "SUBTLE_CLIENT_FLAGS",
    "SUBTLE_GRAVITY_NEW", "SUBTLE_GRAVITY_FLAGS", "SUBTLE_GRAVITY_LIST",
    "SUBTLE_GRAVITY_KILL",
    "SUBTLE_TAG_NEW", "SUBTLE_TAG_LIST", "SUBTLE_TAG_KILL", "SUBTLE_TRAY_LIST",
    "SUBTLE_VIEW_NEW", "SUBTLE_VIEW_TAGS", "SUBTLE_VIEW_STYLE",
    "SUBTLE_VIEW_ICONS", "SUBTLE_VIEW_KILL",
    "SUBTLE_SUBLET_UPDATE", "SUBTLE_SUBLET_DATA", "SUBTLE_SUBLET_STYLE",
    "SUBTLE_SUBLET_FLAGS", "SUBTLE_SUBLET_LIST", "SUBTLE_SUBLET_KILL",
    "SUBTLE_SCREEN_PANELS", "SUBTLE_SCREEN_VIEWS", "SUBTLE_SCREEN_JUMP",
    "SUBTLE_VISIBLE_TAGS", "SUBTLE_VISIBLE_VIEWS",
    "SUBTLE_RENDER", "SUBTLE_RELOAD", "SUBTLE_RESTART", "SUBTLE_QUIT",
    "SUBTLE_COLORS", "SUBTLE_FONT", "SUBTLE_DATA", "SUBTLE_VERSION"
  };

  assert(SUB_EWMH_TOTAL == LENGTH(names));

  /* Update tray selection name for current screen */
  len       = strlen(names[SUB_EWMH_NET_SYSTEM_TRAY_SELECTION]) + 5; ///< For high screen counts
  selection = (char *)subSharedMemoryAlloc(len, sizeof(char));

  snprintf(selection, len, "%s%u", names[SUB_EWMH_NET_SYSTEM_TRAY_SELECTION], SCRN);
  subSubtleLogDebug("Selection: len=%d, name=%s\n", len, selection);
  names[SUB_EWMH_NET_SYSTEM_TRAY_SELECTION] = selection;

  /* Register atoms */
  XInternAtoms(subtle->dpy, names, SUB_EWMH_TOTAL, 0, atoms);
  subtle->flags |= SUB_SUBTLE_EWMH; ///< Set EWMH flag

  free(selection);

  /* EWMH: Supported hints */
  XChangeProperty(subtle->dpy, ROOT, atoms[SUB_EWMH_NET_SUPPORTED], XA_ATOM,
    32, PropModeReplace, (unsigned char *)&atoms, SUB_EWMH_TOTAL);

  /* EWMH: Window manager information */
  subEwmhSetWindows(ROOT, SUB_EWMH_NET_SUPPORTING_WM_CHECK,
    &subtle->windows.support, 1);
  subEwmhSetString(subtle->windows.support, SUB_EWMH_NET_WM_NAME, PKG_NAME);
  subEwmhSetString(subtle->windows.support, SUB_EWMH_WM_CLASS, PKG_NAME);
  subEwmhSetCardinals(subtle->windows.support, SUB_EWMH_NET_WM_PID, &pid, 1);
  subEwmhSetString(subtle->windows.support,
    SUB_EWMH_SUBTLE_VERSION, PKG_VERSION);

  /* EWMH: Desktop geometry */
  data[0] = subtle->width;
  data[1] = subtle->height;
  subEwmhSetCardinals(ROOT, SUB_EWMH_NET_DESKTOP_GEOMETRY, (long *)&data, 2);

  /* EWMH: Client list and client list stacking */
  subEwmhSetWindows(ROOT, SUB_EWMH_NET_CLIENT_LIST, NULL, 0);
  subEwmhSetWindows(ROOT, SUB_EWMH_NET_CLIENT_LIST_STACKING, NULL, 0);

  subSubtleLogDebugSubtle("Init\n");
} /* }}} */
Exemple #14
0
void
subScreenInit(void)
{
  SubScreen *s = NULL;

#ifdef HAVE_X11_EXTENSIONS_XRANDR_H
  /* Check both but prefer xrandr */
  if(subtle->flags & SUB_SUBTLE_XRANDR)
    {
      XRRScreenResources *res = NULL;

      if((res = XRRGetScreenResourcesCurrent(subtle->dpy, ROOT)))
        {
          int i;
          XRRCrtcInfo *crtc = NULL;

          /* Query screens */
          for(i = 0; i < res->ncrtc; i++)
            {
              if((crtc = XRRGetCrtcInfo(subtle->dpy, res, res->crtcs[i])))
                {
                  /* Create new screen if crtc is enabled */
                  if(None != crtc->mode && (s = subScreenNew(crtc->x,
                      crtc->y, crtc->width, crtc->height)))
                    subArrayPush(subtle->screens, (void *)s);

                  XRRFreeCrtcInfo(crtc);
                }
            }

          XRRFreeScreenResources(res);
        }
    }
#endif /* HAVE_X11_EXTENSIONS_XRANDR_H */

#ifdef HAVE_X11_EXTENSIONS_XINERAMA_H
  if(subtle->flags & SUB_SUBTLE_XINERAMA && 0 == subtle->screens->ndata &&
      XineramaIsActive(subtle->dpy))
    {
      int i, n = 0;
      XineramaScreenInfo *info = NULL;

      /* Query screens */
      if((info = XineramaQueryScreens(subtle->dpy, &n)))
        {
          for(i = 0; i < n; i++)
            {
              /* Create new screen */
              if((s = subScreenNew(info[i].x_org, info[i].y_org,
                  info[i].width, info[i].height)))
                subArrayPush(subtle->screens, (void *)s);
            }

          XFree(info);
        }
    }
#endif /* HAVE_X11_EXTENSIONS_XINERAMA_H */

  /* Create default screen */
  if(0 == subtle->screens->ndata)
    {
      /* Create new screen */
      if((s = subScreenNew(0, 0, subtle->width, subtle->height)))
        subArrayPush(subtle->screens, (void *)s);
    }

  printf("Running on %d screen(s)\n", subtle->screens->ndata);

  ScreenPublish();
  subScreenPublish();

  subSubtleLogDebugSubtle("init=screen\n");
} /* }}} */
Exemple #15
0
void
subScreenUpdate(void)
{
  int i;

  /* Update screens */
  for(i = 0; i < subtle->screens->ndata; i++)
    {
      SubScreen *s = SCREEN(subtle->screens->data[i]);
      SubPanel *p = NULL;
      int j, npanel = 0, center = False, offset = 0;
      int x[4] = { 0 }, nspacer[4] = { 0 }; ///< Waste ints but it's easier for the algo
      int sw[4] = { 0 }, fix[4] = { 0 }, width[4] = { 0 }, spacer[4] = { 0 };

      /* Pass 1: Collect width for spacer sizes */
      for(j = 0; s->panels && j < s->panels->ndata; j++)
        {
          p = PANEL(s->panels->data[j]);

          subPanelUpdate(p);

          /* Check flags */
          if(p->flags & SUB_PANEL_HIDDEN)  continue;
          if(0 == npanel && p->flags & SUB_PANEL_BOTTOM)
            {
              npanel = 1;
              center = False;
            }
          if(p->flags & SUB_PANEL_CENTER) center = !center;

          /* Offset selects panel variables for either center or not */
          offset = center ? npanel + 2 : npanel;

          if(p->flags & SUB_PANEL_SPACER1) spacer[offset]++;
          if(p->flags & SUB_PANEL_SPACER2) spacer[offset]++;
          if(p->flags & SUB_PANEL_SEPARATOR1 &&
              subtle->styles.separator.separator)
            width[offset] += subtle->styles.separator.separator->width;
          if(p->flags & SUB_PANEL_SEPARATOR2 &&
              subtle->styles.separator.separator)
            width[offset] += subtle->styles.separator.separator->width;

          width[offset] += p->width;
        }

      /* Calculate spacer and fix sizes */
      for(j = 0; j < 4; j++)
        {
          if(0 < spacer[j])
            {
              sw[j]  = (s->base.width - width[j]) / spacer[j];
              fix[j] = s->base.width - (width[j] + spacer[j] * sw[j]);
            }
        }

      /* Pass 2: Move and resize windows */
      for(j = 0, npanel = 0, center = False;
          s->panels && j < s->panels->ndata; j++)
        {
          p = PANEL(s->panels->data[j]);

          /* Check flags */
          if(p->flags & SUB_PANEL_HIDDEN) continue;
          if(0 == npanel && p->flags & SUB_PANEL_BOTTOM)
            {
              /* Reset for new panel */
              npanel     = 1;
              nspacer[0] = 0;
              nspacer[2] = 0;
              x[0]       = 0;
              x[2]       = 0;
              center     = False;
            }
          if(p->flags & SUB_PANEL_CENTER) center = !center;

          /* Offset selects panel variables for either center or not */
          offset = center ? npanel + 2 : npanel;

          /* Set start position of centered panel items */
          if(center && 0 == x[offset])
            x[offset] = (s->base.width - width[offset]) / 2;

          /* Add separator before panel item */
          if(p->flags & SUB_PANEL_SEPARATOR1 &&
              subtle->styles.separator.separator)
            x[offset] += subtle->styles.separator.separator->width;

          /* Add spacer before item */
          if(p->flags & SUB_PANEL_SPACER1)
            {
              x[offset] += sw[offset];

              /* Increase last spacer size by rounding fix */
              if(++nspacer[offset] == spacer[offset])
                x[offset] += fix[offset];
            }

          /* Set panel position */
          if(p->flags & SUB_PANEL_TRAY)
            XMoveWindow(subtle->dpy, subtle->windows.tray, x[offset], 0);
          p->x = x[offset];

          /* Add separator after panel item */
          if(p->flags & SUB_PANEL_SEPARATOR2 &&
              subtle->styles.separator.separator)
            x[offset] += subtle->styles.separator.separator->width;

          /* Add spacer after item */
          if(p->flags & SUB_PANEL_SPACER2)
            {
              x[offset] += sw[offset];

              /* Increase last spacer size by rounding fix */
              if(++nspacer[offset] == spacer[offset])
                x[offset] += fix[offset];
            }

          x[offset] += p->width;
        }
    }

  subSubtleLogDebugSubtle("Update\n");
} /* }}} */
Exemple #16
0
void
subScreenConfigure(void)
{
  int i;
  SubScreen *s = NULL;
  SubView *v = NULL;

  /* Reset visible tags, views and available clients */
  subtle->visible_tags  = 0;
  subtle->visible_views = 0;
  subtle->client_tags   = 0;

  /* Either check each client or just get visible clients */
  if(0 < subtle->clients->ndata)
    {
      int j;

      /* Check each client */
      for(i = 0; i < subtle->clients->ndata; i++)
        {
          SubClient *c = CLIENT(subtle->clients->data[i]);
          int gravityid = 0, screenid = 0, viewid = 0, visible = 0;

          /* Ignore dead or just iconified clients */
          if(c->flags & SUB_CLIENT_DEAD) continue;

          /* Set available client tags to ease lookups */
          subtle->client_tags |= c->tags;

          /* Check view of each screen */
          for(j = 0; j < subtle->screens->ndata; j++)
            {
              s = SCREEN(subtle->screens->data[j]);
              v = VIEW(subtle->views->data[s->viewid]);

              /* Set visible tags and views to ease lookups */
              subtle->visible_tags  |= v->tags;
              subtle->visible_views |= (1L << (s->viewid + 1));

              /* Find visible clients */
              if(VISIBLETAGS(c, v->tags))
                {
                  /* Keep screen when sticky */
                  if(c->flags & SUB_CLIENT_MODE_STICK)
                    {
                      /* Keep gravity from sticky screen/view and not the one
                       * of the current screen/view in loop */
                      s = SCREEN(subtle->screens->data[c->screenid]);

                      screenid = c->screenid;
                    }
                  else screenid = j;

                  viewid    = s->viewid;
                  gravityid = c->gravities[s->viewid];
                  visible++;
                }
            }

          /* After all screens are checked.. */
          if(0 < visible)
            {
              /* Update client */
              subClientArrange(c, gravityid, screenid);
              XMapWindow(subtle->dpy, c->win);
              subEwmhSetWMState(c->win, NormalState);

              /* Warp after gravity and screen have been set if not disabled */
              if(c->flags & SUB_CLIENT_MODE_URGENT &&
                  !(subtle->flags & SUB_SUBTLE_SKIP_URGENT_WARP) &&
                  !(subtle->flags & SUB_SUBTLE_SKIP_WARP))
                subClientWarp(c);

              /* EWMH: Desktop, screen */
              subEwmhSetCardinals(c->win, SUB_EWMH_NET_WM_DESKTOP,
                (long *)&viewid, 1);
              subEwmhSetCardinals(c->win, SUB_EWMH_SUBTLE_CLIENT_SCREEN,
                (long *)&screenid, 1);
            }
          else ///< Unmap other windows
            {
              c->flags |= SUB_CLIENT_UNMAP; ///< Ignore next unmap
              subEwmhSetWMState(c->win, WithdrawnState);
              XUnmapWindow(subtle->dpy, c->win);
            }
        }
    }
  else
    {
      /* Check views of each screen */
      for(i = 0; i < subtle->screens->ndata; i++)
        {
          s = SCREEN(subtle->screens->data[i]);
          v = VIEW(subtle->views->data[s->viewid]);

          /* Set visible tags and views to ease lookups */
          subtle->visible_tags  |= v->tags;
          subtle->visible_views |= (1L << (s->viewid + 1));
        }
    }

  /* EWMH: Visible tags, views */
  subEwmhSetCardinals(ROOT, SUB_EWMH_SUBTLE_VISIBLE_TAGS,
    (long *)&subtle->visible_tags, 1);
  subEwmhSetCardinals(ROOT, SUB_EWMH_SUBTLE_VISIBLE_VIEWS,
    (long *)&subtle->visible_views, 1);

  XSync(subtle->dpy, False); ///< Sync before going on

  /* Hook: Configure */
  subHookCall(SUB_HOOK_TILE, NULL);

  subSubtleLogDebugSubtle("Configure\n");
} /* }}} */