Esempio n. 1
0
File: init.c Progetto: pierreN/wmfs
/** Init WMFS
*/
void
init(void)
{
     /* Init lists heads */
     SLIST_INIT(&bwhead);
     SLIST_INIT(&clients);
     SLIST_INIT(&trayicons);

     /* First init */
     ewmh_init_hints();
     init_conf();
     init_gc();
     init_font();
     init_cursor();
     init_key();
     init_root();
     screen_init_geo();
     event_make_array();
     infobar_init();
     systray_acquire();
     ewmh_update_current_tag_prop();
     grabkeys();

     return;
}
Esempio n. 2
0
/** Layout switching function
 * \param b Bool True : next False : previous
*/
void
layoutswitch(Bool b)
{
     int i;
     Client *c;

     screen_get_sel();

     if(tags[selscreen][seltag[selscreen]].layout.func == freelayout)
          for(c = clients; c && (c->tag != (uint)seltag[selscreen] && c->screen != selscreen); c = c->next)
          {
               c->ogeo = c->geo;
               c->free_geo = c->geo;
          }

     for(i = 0; i < conf.nlayout; ++i)
     {
          if(tags[selscreen][seltag[selscreen]].layout.func == conf.layout[i].func
             && tags[selscreen][seltag[selscreen]].layout.symbol == conf.layout[i].symbol)
          {
               if(b)
                    tags[selscreen][seltag[selscreen]].layout = conf.layout[(i + 1) % conf.nlayout];
               else
                    tags[selscreen][seltag[selscreen]].layout = conf.layout[(i + conf.nlayout - 1) % conf.nlayout];
               break;
          }
     }

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

     return;
}
Esempio n. 3
0
/** 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;
}
Esempio n. 4
0
/** The free layout function
*/
void
freelayout(int screen)
{
     Client *c;
     (void)screen;

     for(c = clients; c; c = c->next)
          if(!ishide(c, selscreen)
             && c->screen == screen_get_sel()
             && !(c->flags & MaxFlag))
          {
               client_moveresize(c, c->free_geo, True);
               c->flags &= ~(TileFlag | LMaxFlag);
          }

     ewmh_update_current_tag_prop();

     return;
}
Esempio n. 5
0
/** Init MWM
*/
void
init(void)
{
     /* First init */
     ewmh_init_hints();
     init_conf();
     init_gc();
     init_font();
     init_cursor();
     init_key();
     init_root();
     screen_init_geo();
     infobar_init();
     systray_acquire();
     init_status();
     ewmh_update_current_tag_prop();
     grabkeys();

     return;
}
Esempio n. 6
0
/** Set the mwfact
 * \param cmd Mwfact (string)
*/
void
uicb_set_mwfact(uicb_t cmd)
{
     double c;

     screen_get_sel();

     CHECK((sscanf(cmd, "%lf", &c)));

     if(tags[selscreen][seltag[selscreen]].mwfact + c > 0.95
        || tags[selscreen][seltag[selscreen]].mwfact + c < 0.05)
          return;

     tags[selscreen][seltag[selscreen]].mwfact += c;
     tags[selscreen][seltag[selscreen]].layout.func(selscreen);

     ewmh_update_current_tag_prop();

     return;
}
Esempio n. 7
0
/** 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;
}
Esempio n. 8
0
File: tag.c Progetto: wavebeem/wmfs
/* Set the tag
 * \param tag The tag number
*/
void
tag_set(int tag)
{
     Client *c;
     Bool al = False;
     int i;

     if(tag < 0 || tag > MAXTAG)
          return;

     screen_get_sel();

     if(seltag[selscreen] != tag)
          prevseltag[selscreen] = seltag[selscreen];
     else if(tag == seltag[selscreen] && tag != prevseltag[selscreen] && conf.tag_auto_prev)
          tag = seltag[selscreen] = prevseltag[selscreen];
     else
          seltag[selscreen] = tag;

     if(conf.tag_round)
     {
          if(tag <= 0)
               seltag[selscreen] = conf.ntag[selscreen];
          else if(tag > conf.ntag[selscreen])
               seltag[selscreen] = 1;
          else
               seltag[selscreen] = tag;
     }
     else
     {
          if(!tag || tag > conf.ntag[selscreen])
               return;

          seltag[selscreen] = tag;
     }

     ewmh_update_current_tag_prop();

     /* Arrange infobar position */
     if(tags[selscreen][prevseltag[selscreen]].barpos != tags[selscreen][seltag[selscreen]].barpos
               || prevseltag[selscreen] == seltag[selscreen])
          infobar_set_position(tags[selscreen][seltag[selscreen]].barpos);

     /* Check if a layout update is needed with additional tags */
     if(tags[selscreen][seltag[selscreen]].tagad)
          al = True;
     else if(tags[selscreen][seltag[selscreen]].request_update)
     {
          al = True;
          tags[selscreen][seltag[selscreen]].request_update = False;
     }

     for(i = 1; i < conf.ntag[selscreen] + 1; ++i)
          if(tags[selscreen][i].tagad & TagFlag(seltag[selscreen]))
          {
               al = True;
               break;
          }

     /* Check for ignore_tag clients */
     for(c = clients; c; c = c->next)
          if(c->tag == MAXTAG + 1 && c->screen == selscreen)
          {
               al = True;
               break;
          }

     arrange(selscreen, al);

     if(tags[selscreen][tag].request_update)
     {
          tags[selscreen][seltag[selscreen]].layout.func(selscreen);
          tags[selscreen][tag].request_update = False;
     }

     /* To focus selected client of the via focusontag option */
     for(c = clients; c; c = c->next)
          if(c->focusontag == tag && c->screen == selscreen)
               break;

     /* No focusontag option found on any client, try to find the first of the tag */
     if(!c)
          for(c = clients; c; c = c->next)
               if(c->tag == (uint)seltag[selscreen] && c->screen == selscreen)
                    break;

     client_focus((c) ? c : NULL);

     return;
}
Esempio n. 9
0
/** 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;
}
Esempio n. 10
0
/** 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;
}
Esempio n. 11
0
/** 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;
}
Esempio n. 12
0
File: event.c Progetto: n4cht/kwm
/* ClientMessage handle event
 *\param ev XClientMessageEvent pointer
*/
static void
clientmessageevent(XClientMessageEvent *ev)
{
     Client *c;
     Systray *sy;
     int s, i, mess_t = 0;
     Atom rt;
     int rf;
     ulong ir, il;
     uchar *ret = NULL;
     uchar *ret_cmd = NULL;
     void (*func)(uicb_t);

     if(ev->format != 32)
          return;

     s = screen_count();

     for(i = 0; i < net_last + s; ++i)
          if(net_atom[i] == ev->message_type)
               mess_t = i;

     if(ev->window == ROOT)
     {
          /* Manage _NET_CURRENT_DESKTOP */
          if(mess_t == net_current_desktop
             && ev->data.l[0] >= 0
             && ev->data.l[0] < conf.ntag[selscreen])
               tag_set((int)(ev->data.l[0] + 1));

          /* Manage _WMFS_SET_SCREEN */
          if(mess_t == wmfs_set_screen
             && ev->data.l[0] >= 0
             && ev->data.l[0] <= s)
               screen_set_sel((int)(ev->data.l[0]));

          /* Manage _NET_ACTIVE_WINDOW */
          else if(mess_t == net_active_window)
          {
               if((c = client_gb_win(ev->window)))
                    client_focus(c);
               else if((sy = systray_find(ev->data.l[0])))
                    XSetInputFocus(dpy, sy->win, RevertToNone, CurrentTime);
          }
     }
     else if(ev->window == traywin)
     {
          /* Manage _NET_WM_SYSTEM_TRAY_OPCODE */
          if(mess_t == net_wm_system_tray_opcode)
          {
               if(ev->data.l[1] == XEMBED_EMBEDDED_NOTIFY)
               {
                    systray_add(ev->data.l[2]);
                    systray_update();
               }
               else if(ev->data.l[1] == XEMBED_REQUEST_FOCUS)
                    if((sy = systray_find(ev->data.l[2])))
                         ewmh_send_message(sy->win, sy->win, "_XEMBED",
                                   XEMBED_FOCUS_IN, XEMBED_FOCUS_CURRENT, 0, 0, 0);
          }
     }

     /* Manage _NET_WM_STATE */
     if(mess_t == net_wm_state)
          if((c = client_gb_win(ev->window)))
               ewmh_manage_net_wm_state(ev->data.l, c);

     /* Manage _NET_CLOSE_WINDOW */
     if(mess_t == net_close_window)
          if((c = client_gb_win(ev->window)))
               client_kill(c);

     /* Manage _NET_WM_DESKTOP */
     if(mess_t == net_wm_desktop)
          if((c = client_gb_win(ev->window)) && ev->data.l[0] != (long)0xFFFFFFFF)
               tag_transfert(c, ev->data.l[0]);

     /* Manage _WMFS_STATUSTEXT_x */
     if(mess_t >= wmfs_statustext && ev->data.l[4] == True)
     {
          if(XGetWindowProperty(dpy, ROOT, net_atom[mess_t], 0, 4096,
                                False, net_atom[utf8_string], &rt, &rf, &ir, &il, &ret) == Success)
          {
               statustext_handle(mess_t - wmfs_statustext, (char*)ret);
               XFree(ret);
          }
     }

     /* Manage _WMFS_FUNCTION && _WMFS_CMD */
     if((mess_t == wmfs_function && ev->data.l[4] == True)
        || (mess_t == wmfs_cmd && ev->data.l[4] == True))
     {
          XGetWindowProperty(dpy, ROOT, net_atom[wmfs_function], 0, 4096,
                    False, net_atom[utf8_string], &rt, &rf, &ir, &il, &ret);

          XGetWindowProperty(dpy, ROOT, net_atom[wmfs_cmd], 0, 4096,
                    False, net_atom[utf8_string], &rt, &rf, &ir, &il, &ret_cmd);

          if((func = name_to_func((char*)ret, func_list)))
               func((uicb_t)ret_cmd);

          XFree(ret_cmd);
          XFree(ret);
     }

     /* Manage _WMFS_UPDATE_HINTS */
     if(mess_t == wmfs_update_hints)
     {
          ewmh_get_number_of_desktop();
          ewmh_update_current_tag_prop();
          ewmh_get_client_list();
          ewmh_get_desktop_names();
          ewmh_set_desktop_geometry();
          screen_count();
          screen_get_sel();
     }

     if(mess_t == wmfs_update_status
               && estatus)
          spawn(conf.status_path);

     return;
}