2011/06/12

Notes for dwm

In dwm, we use Meta+[1~9] to choose which view to display,
Meta+Shift+[1~9] to move client to specified view,
Meta+Ctrl+[1~9] to toggle multiple displayed views,
Meta+Ctrl+Shift+[1~9] to toggle client to specified view.
void
view(const Arg *arg) {
    if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
        return;
    selmon->seltags ^= 1; /* toggle sel tagset */
    if(arg->ui & TAGMASK)
        selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
    arrange(selmon);
}

void
toggleview(const Arg *arg) {
    unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);

    if(newtagset) {
        selmon->tagset[selmon->seltags] = newtagset;
        arrange(selmon);
    }
}

void
tag(const Arg *arg) {
    if(selmon->sel && arg->ui & TAGMASK) {
        selmon->sel->tags = arg->ui & TAGMASK;
        arrange(selmon);
    }
}

void
toggletag(const Arg *arg) {
    unsigned int newtags;

    if(!selmon->sel)
        return;
    newtags = selmon->sel->tags ^ (arg->ui & TAGMASK);
    if(newtags) {
        selmon->sel->tags = newtags;
        arrange(selmon);
    }
}

dwm supports multiple monitors.
static Monitor *mons = NULL, *selmon = NULL;

However, all views within one monitor share the same layout.
This means you can't use monocle layout in 1st view while tile layout in 2nd view.
struct Monitor {
    char ltsymbol[16];
    float mfact;
    int num;
    int by;               /* bar geometry */
    int mx, my, mw, mh;   /* screen size */
    int wx, wy, ww, wh;   /* window area  */
    unsigned int seltags;
    unsigned int sellt;
    unsigned int tagset[2];
    Bool showbar;
    Bool topbar;
    Client *clients;
    Client *sel;
    Client *stack;
    Monitor *next;
    Window barwin;
    const Layout *lt[2];
};

struct Client {
    char name[256];
    float mina, maxa;
    int x, y, w, h;
    int oldx, oldy, oldw, oldh;
    int basew, baseh, incw, inch, maxw, maxh, minw, minh;
    int bw, oldbw;
    unsigned int tags;
    Bool isfixed, isfloating, isurgent, oldstate;
    Client *next;
    Client *snext;
    Monitor *mon;
    Window win;
};

A solution to this problem is making Clients, Views, and Monitors independent.

One list for all clients.
One list for all views (at most 9).
One list for all monitors.

A global pivot indicates the selected monitor.
A pivot in monitor indicates selected view.

A client must be tagged to at least one view.
A view may belong to zero, one, or multiple monitors.

A view consists of:
  1. A tag which is unique among all views.
  2. A layout
  3. A floating number indicates the percentage of screen occupied to the master client of this view.