예제 #1
0
파일: layout.c 프로젝트: wavebeem/wmfs
/** Max layout function
*/
void
maxlayout(int screen)
{
     Client *c;
     int i;

     for(i = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++i)
     {
          c->flags &= ~TileFlag;
          c->flags |= LMaxFlag;
          client_maximize(c);
     }

     ewmh_update_current_tag_prop();

     return;
}
예제 #2
0
파일: layout.c 프로젝트: wavebeem/wmfs
/** Set the client as master
 * \param c Client
 */
void
layout_set_client_master(Client *c)
{
     screen_get_sel();

     if(!c || (c->flags & HintFlag) || !(c->flags & TileFlag)
               || (c->flags & FSSFlag))
          return;

     if(c == tiled_client(selscreen, clients))
          CHECK((c = tiled_client(selscreen, c->next)));

     client_detach(c);
     client_attach(c);

     tags[selscreen][seltag[selscreen]].layout.func(selscreen);

     return;
}
예제 #3
0
파일: layout.c 프로젝트: wavebeem/wmfs
/** Set the nmaster
 * \param cmd Nmaster (string)
*/
void
uicb_set_nmaster(uicb_t cmd)
{
     int nc, n = atoi(cmd);
     Client *c;

     screen_get_sel();

     for(nc = 0, c = tiled_client(selscreen, clients); c; c = tiled_client(selscreen, c->next), ++nc);

     if(!nc || tags[selscreen][seltag[selscreen]].nmaster + n == 0
               || tags[selscreen][seltag[selscreen]].nmaster + n > nc)
          return;

     tags[selscreen][seltag[selscreen]].nmaster += n;
     tags[selscreen][seltag[selscreen]].layout.func(selscreen);

     ewmh_update_current_tag_prop();

     return;
}
예제 #4
0
파일: split.c 프로젝트: pierreN/wmfs
/** Check if row direction is available to resize from it
  *\param c Client pointer
  *\param g Client pointer
  *\param p Position
  *\return True if available
*/
static bool
_split_check_row_dir(Client *c, Client *g, Position p)
{
     int s = 0, cs;
     Geo cgeo = c->frame_geo;
     Client *cc = tiled_client(c->screen, SLIST_FIRST(&clients));

     cs = (LDIR(p) ? g->frame_geo.height : g->frame_geo.width);

     for(; cc; cc = tiled_client(c->screen, SLIST_NEXT(cc, next)))
          if(CFACTOR_PARENTROW(cgeo, cc->frame_geo, RPOS(p))
                    && SPLIT_CHECK_ROW(cc->frame_geo, g->frame_geo, p))
          {
               s += (LDIR(p) ? cc->frame_geo.height : cc->frame_geo.width);

               if(s == cs)
                    return True;
               if(s > cs)
                    return False;
          }

     return False;
}
예제 #5
0
파일: split.c 프로젝트: pierreN/wmfs
/** Arrange clients after a client close
  *\param ghost Ghost client
 */
void
split_arrange_closed(Client *ghost)
{
     Position p;
     bool b = False;
     Geo cgeo;
     Client *c, *cc;
     int screen = ghost->screen;
     int tag = (ghost->tag ? ghost->tag : seltag[screen]);

     /* Use ghost client properties to fix holes in tile
      *     .--.  ~   ~
      *    /xx  \   ~   ~
      *  ~~\O _ (____     ~
      *  __.|    .--'-==~   ~
      * '---\    '.      ~  ,  ~
      *      '.    '-.___.-'/   ~
      *        '-.__     _.'  ~
      *             `````   ~
      */

     /* Search for single parent for easy resize
      * Example case:
      *  ___________               ___________
      * |     |  B  | ->       -> |     |     |
      * |  A  |_____| -> Close -> |  A  |  B  |
      * |     |  C  | ->   C   -> |     |v v v|
      * |_____|_____| ->       -> |_____|_____|
      */
     for(p = Right; p < Center; ++p)
          if((c = client_get_next_with_direction(ghost, p)))
               if(CFACTOR_CHECK2(ghost->frame_geo, c->frame_geo, p))
               {
                    _split_arrange_size(ghost->wrgeo, &c->wrgeo, p);
                    cfactor_clean(c);
                    client_moveresize(c, (c->pgeo = c->wrgeo), (tags[screen][tag].flags & ResizeHintFlag));

                    return;
               }

     /* Check row parents for full resize
      * Example case:
      *  ___________               ___________
      * |     |  B  | ->       -> | <<  B     |
      * |  A  |_____| -> Close -> |___________|
      * |     |  C  | ->   A   -> | <<  C     |
      * |_____|_____| ->       -> |___________|
      */
     for(p = Right; p < Center && !b; ++p)
          if((c = client_get_next_with_direction(ghost, p)) && _split_check_row_dir(c, ghost, p))
          {
               for(cgeo = c->frame_geo, cc = tiled_client(c->screen, SLIST_FIRST(&clients));
                         cc; cc = tiled_client(c->screen, SLIST_NEXT(cc, next)))
                    if(CFACTOR_PARENTROW(cgeo, cc->frame_geo, RPOS(p))
                              && SPLIT_CHECK_ROW(cc->frame_geo, ghost->frame_geo, p))
                    {
                         _split_arrange_size(ghost->wrgeo, &cc->wrgeo, p);
                         cfactor_clean(cc);
                         client_moveresize(cc, (cc->pgeo = cc->wrgeo), (tags[screen][tag].flags & ResizeHintFlag));
                         b = True;
                    }
          }

     return;
}
예제 #6
0
파일: layout.c 프로젝트: wavebeem/wmfs
/** Mirror layout function
 * \param screen Screen to execute this function
 * \param horizont To specify the mirror mode (vertical/horizontal)
 */
static void
mirror(int screen, Bool horizontal)
{
     Client *c;
     XRectangle sg = sgeo[screen];
     XRectangle mastergeo = {sg.x, sg.y, sg.width, sg.height};
     XRectangle cgeo = {sg.x, sg.y , sg.width, sg.height};
     XRectangle nextg[2];
     uint i, n, tilesize = 0, mwfact;
     uint nmaster = tags[screen][seltag[screen]].nmaster;
     int pa, imp;
     Bool isp = 0;

     memset(nextg, 0, sizeof(nextg));

     for(n = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++n);
     CHECK(n);

     /* Fix nmaster */
     nmaster = (n < nmaster) ? n : nmaster;

     imp = ((n - (nmaster - 1)) / 2);
     pa = ((n - (nmaster - 1)) / 2) - (((n - (nmaster - 1)) % 2) ? 0 : 1);

     /* Set mwfact */
     if(tags[screen][seltag[screen]].mwfact < 0.55)
          tags[screen][seltag[screen]].mwfact = 0.55;

     mwfact = tags[screen][seltag[screen]].mwfact * ((horizontal) ? sg.height : sg.width);

     /* Master size */
     if(horizontal)
     {
          mastergeo.width = (sg.width / nmaster) - (BORDH * 2);
          mastergeo.height -= BORDH;
     }
     else
     {
          mastergeo.width -= BORDH * 2;
          mastergeo.height = (sg.height / nmaster) - (TBARH + (BORDH * 2));
     }

     if(n == nmaster + 1)
     {
          if(horizontal)
          {
               mastergeo.height = mwfact - ((BORDH * 2) + TBARH);
               tilesize = (sg.height - mastergeo.height) - ((BORDH * 2) + TBARH);
          }
          else
          {
               mastergeo.width = mwfact - (BORDH * 3);
               tilesize = (sg.width - mastergeo.width) - (BORDH * 4);
          }
     }
     if(n > nmaster + 1)
     {
          if(horizontal)
          {
               mastergeo.y = (sg.y + (sg.height - mwfact)) + TBARH + BORDH;
               mastergeo.height = (2 * mwfact - sg.height) - ((BORDH * 3) + (TBARH * 2));
               tilesize = (mwfact - mastergeo.height) - ((BORDH * 3) + (TBARH * 2));
          }
          else
          {
               mastergeo.x = (sg.x + (sg.width - mwfact)) + BORDH;
               mastergeo.width = ((2 * mwfact - sg.width) - (BORDH * 4));
               tilesize = (mwfact - mastergeo.width) - (BORDH * 5);
          }
     }

     for(i = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++i)
     {
          /* Set client property */
          c->flags &= ~(MaxFlag | LMaxFlag);
          c->flags |= TileFlag;

          if(i < nmaster)
          {
               cgeo = mastergeo;

               /* Master remainder */
               if(i + 1 == nmaster)
               {
                    if(horizontal)
                         cgeo.width = (sg.x + sg.width) - (cgeo.x + (BORDH * 2));
                    else
                         cgeo.height = (sg.y + sg.height) - (cgeo.y + BORDH);
               }
          }
          else
          {
               if(horizontal)
                    cgeo.height = tilesize;
               else
                    cgeo.width = tilesize;

               if((i + nmaster) % 2)
               {
                    isp = 1;

                    if(horizontal)
                    {
                         cgeo.y = sg.y;
                         cgeo.width = (sg.width / pa) - (BORDH * 2);
                    }
                    else
                    {
                         cgeo.x = sg.x;
                         cgeo.height = (sg.height / pa) - (TBARH + (BORDH * 2));
                    }
               }
               else
               {
                    isp = 0;

                    if(horizontal)
                    {
                         cgeo.y = (sg.y + mwfact) - BORDH;
                         cgeo.width = (sg.width / imp) - (BORDH * 2);
                    }
                    else
                    {
                         cgeo.x = (sg.x + mwfact) - BORDH;
                         cgeo.height = (sg.height / imp) - (TBARH + (BORDH * 2));
                    }
               }

               /* Remainder */
               if(i + 1 == n || i + 1 == n - 1)
               {
                    if(horizontal)
                         cgeo.width = (sg.x + sg.width) - (cgeo.x + (BORDH * 2));
                    else
                         cgeo.height = (sg.y + sg.height) - (cgeo.y + BORDH);
               }
          }

          client_moveresize(c, cgeo, tags[screen][seltag[screen]].resizehint);

          if(i >= nmaster)
               nextg[!isp] = c->geo;

          /* Next y/x position */
          if(i >= nmaster - 1)
          {
               if(horizontal)
               {
                    if(i == nmaster || i == nmaster - 1)
                         cgeo.x = sg.x;
                    else
                         cgeo.x = nextg[isp].x + nextg[isp].width + BORDH * 2;
               }
               else
               {
                    if(i == nmaster || i == nmaster - 1)
                         cgeo.y = sg.y;
                    else
                         cgeo.y = nextg[isp].y + nextg[isp].height + BORDH + TBARH;
               }
          }
          else if (i <= nmaster - 1)
          {
               if(horizontal)
                    mastergeo.x = c->geo.x + c->geo.width + BORDH * 2;
               else
                    mastergeo.y = c->geo.y + c->geo.height + BORDH + TBARH;
          }

     }

     ewmh_update_current_tag_prop();

     return;
}
예제 #7
0
파일: layout.c 프로젝트: wavebeem/wmfs
/** Multi tile function
 * \param type Postion type { Top, Bottom, Left, Right }
*/
static void
multi_tile(int screen, Position type)
{
     Client *c;
     XRectangle sg = sgeo[screen];
     XRectangle mastergeo = {sg.x, sg.y, 0, 0};
     XRectangle cgeo = {sg.x, sg.y, 0, 0};
     uint i, n, tilesize = 0, mwfact, nmaster = tags[screen][seltag[screen]].nmaster;

     for(n = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++n);
     CHECK(n);

     /* FIX NMASTER */
     nmaster = (n < nmaster) ? n : nmaster;

     /* SET MWFACT */
     mwfact = (type == Top || type == Bottom)
          ? tags[screen][seltag[screen]].mwfact * sg.height
          : tags[screen][seltag[screen]].mwfact * sg.width;

     /* MASTER SIZE */
     if(type == Top || type == Bottom)
     {
          if(type == Top)
               mastergeo.y = (n <= nmaster) ? (uint)sg.y : sg.y + (sg.height - mwfact) - BORDH;
          mastergeo.width = (sg.width / nmaster) - (BORDH * 4);
          mastergeo.height = (n <= nmaster) ? (uint)(sg.height - BORDH) : mwfact;
     }
     else
     {
          if(type == Left)
               mastergeo.x = (n <= nmaster) ? (uint)sg.x : (sg.x + sg.width) - mwfact - (BORDH * 2);
          mastergeo.width = (n <= nmaster) ? (uint)(sg.width - (BORDH * 2)) : mwfact;
          mastergeo.height = (sg.height / nmaster) - BORDH;
     }

     /* TILED SIZE */
     if(n > nmaster)
     {
          if(type == Top || type == Bottom)
               tilesize = sg.width / (n - nmaster) - (BORDH * 4);
          else
               tilesize = sg.height / (n - nmaster) - ((BORDH * 2) + TBARH);
     }


     for(i = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++i)
     {
          /* Set client property */
          c->flags &= ~(MaxFlag | LMaxFlag);
          c->flags |= TileFlag;

          /* MASTER */
          if(i < nmaster)
          {
               cgeo.width = mastergeo.width;
               cgeo.height = mastergeo.height;

               if(type == Top || type == Bottom)
                    cgeo.y = mastergeo.y;
               else
               {
                    cgeo.x = mastergeo.x;
                    cgeo.height -= (TBARH + BORDH);
               }
          }

          /* TILED */
          else
          {
               if(i == nmaster)
               {
                    switch(type)
                    {
                    case Top:
                    case Left:
                         cgeo.y = sg.y;
                         cgeo.x = sg.x;
                         break;
                    case Bottom:
                         cgeo.y += mastergeo.height + TBARH + BORDH;
                         cgeo.x = sg.x;
                         break;
                    default:
                    case Right:
                         cgeo.x += mastergeo.width + (BORDH * 2);
                         cgeo.y = sg.y;
                         break;
                    }
               }
               if(type == Top || type == Bottom)
               {
                    cgeo.width = tilesize;
                    cgeo.height = sg.height - mastergeo.height - TBARH - (BORDH * 2);
               }
               else
               {
                    cgeo.width = sg.width - mastergeo.width - (BORDH * 4);
                    cgeo.height = tilesize;
               }
          }

          /* REMAINDER */
          if(i + 1 == n  || i + 1 == (n < nmaster ? n : nmaster))
          {
               if(type == Top || type == Bottom)
                    cgeo.width = sg.width - (cgeo.x - (sg.x - (BORDH * 2)));
               else
                    cgeo.height = (sg.y + sg.height) - cgeo.y - BORDH;
          }

          /* Magic instant */
          client_moveresize(c, cgeo, tags[screen][seltag[screen]].resizehint);

          /* Set the position of the next client */
          if(type == Top || type == Bottom)
               cgeo.x = c->geo.x + c->geo.width + (BORDH * 2);
          else
               cgeo.y = c->geo.y + c->geo.height + BORDH + TBARH;
     }

     ewmh_update_current_tag_prop();

     return;
}
예제 #8
0
파일: layout.c 프로젝트: wavebeem/wmfs
/** Grid layout function
*/
static void
grid(int screen, Bool horizontal)
{
     Client *c;
     XRectangle sg = sgeo[screen];
     XRectangle cgeo = {sg.x, sg.y, 0, 0};
     unsigned int i, n, temp, cols, rows, cpcols = 0;

     for(n = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++n);
     CHECK(n);

     for(rows = 0; rows <= n / 2; ++rows)
          if(rows * rows >= n)
               break;

     cols = (rows && ((rows - 1) * rows) >= n)
          ? rows - 1
          : rows;

     if(!horizontal)
     {
         temp = cols;
         cols = rows;
         rows = temp;
     }

     for(i = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++i)
     {
          /* Set client property */
          c->flags &= ~(MaxFlag | LMaxFlag);
          c->flags |= TileFlag;
          ++cpcols;
          cgeo.width = (sg.width / cols) - (BORDH * 2);
          cgeo.height = (sg.height / rows) - BORDH;

          /* Last row's and last client remainder */
          if(cpcols == rows || i + 1 == n)
               cgeo.height = sg.y + sg.height - cgeo.y - BORDH;

          /* Last column's client remainder */
          if(i >= rows * (cols - 1))
               cgeo.width = sg.width - (cgeo.x - (sg.x - (BORDH * 2)));

          /* Resize */
          client_moveresize(c, cgeo, tags[screen][seltag[screen]].resizehint);

          /* Set all the other size with current client info */
          cgeo.y = c->geo.y + c->geo.height + BORDH + TBARH;

          if(cpcols + 1 > rows)
          {
               cpcols = 0;
               cgeo.x = c->geo.x + c->geo.width + (BORDH * 2);
               cgeo.y = sg.y;
          }
     }

     ewmh_update_current_tag_prop();

     return;
}