diff options
Diffstat (limited to 'dwl.c')
-rw-r--r-- | dwl.c | 186 |
1 files changed, 174 insertions, 12 deletions
@@ -213,6 +213,10 @@ struct Monitor { struct wlr_box w; /* window area, layout-relative */ struct wl_list layers[4]; /* LayerSurface.link */ const Layout *lt[2]; + int gappih; /* horizontal gap between windows */ + int gappiv; /* vertical gap between windows */ + int gappoh; /* horizontal outer gaps */ + int gappov; /* vertical outer gaps */ unsigned int seltags; unsigned int sellt; uint32_t tagset[2]; @@ -299,6 +303,7 @@ static void createpopup(struct wl_listener *listener, void *data); static void cursorconstrain(struct wlr_pointer_constraint_v1 *constraint); static void cursorframe(struct wl_listener *listener, void *data); static void cursorwarptohint(void); +static void defaultgaps(const Arg *arg); static void destroydecoration(struct wl_listener *listener, void *data); static void destroydragicon(struct wl_listener *listener, void *data); static void destroyidleinhibitor(struct wl_listener *listener, void *data); @@ -321,6 +326,13 @@ static void fullscreennotify(struct wl_listener *listener, void *data); static void gpureset(struct wl_listener *listener, void *data); static void handlesig(int signo); static void incnmaster(const Arg *arg); +static void incgaps(const Arg *arg); +static void incigaps(const Arg *arg); +static void incihgaps(const Arg *arg); +static void incivgaps(const Arg *arg); +static void incogaps(const Arg *arg); +static void incohgaps(const Arg *arg); +static void incovgaps(const Arg *arg); static void inputdevice(struct wl_listener *listener, void *data); static int keybinding(uint32_t mods, xkb_keysym_t sym); static void keypress(struct wl_listener *listener, void *data); @@ -354,6 +366,7 @@ static void setcursorshape(struct wl_listener *listener, void *data); static void setfloating(Client *c, int floating); static void setfullscreen(Client *c, int fullscreen); static void setgamma(struct wl_listener *listener, void *data); +static void setgaps(int oh, int ov, int ih, int iv); static void setlayout(const Arg *arg); static void setmfact(const Arg *arg); static void setmon(Client *c, Monitor *m, uint32_t newtags); @@ -362,6 +375,7 @@ static void setsel(struct wl_listener *listener, void *data); static void setup(void); static void spawn(const Arg *arg); static void startdrag(struct wl_listener *listener, void *data); +static void incxkbrules(const Arg *arg); static int status_in(int fd, unsigned int mask, void *data); static void tag(const Arg *arg); static void tagmon(const Arg *arg); @@ -369,6 +383,7 @@ static void tile(Monitor *m); static void togglebar(const Arg *arg); static void togglefloating(const Arg *arg); static void togglefullscreen(const Arg *arg); +static void togglegaps(const Arg *arg); static void toggletag(const Arg *arg); static void toggleview(const Arg *arg); static void unlocksession(struct wl_listener *listener, void *data); @@ -434,6 +449,7 @@ static struct wl_listener lock_listener = {.notify = locksession}; static struct wlr_seat *seat; static KeyboardGroup *kb_group; +static unsigned int kblayout = 0; static unsigned int cursor_mode; static Client *grabc; static int grabcx, grabcy; /* client-relative */ @@ -443,6 +459,7 @@ static struct wlr_box sgeom; static struct wl_list mons; static Monitor *selmon; +static int enablegaps = 1; /* enables gaps, used by togglegaps */ static char stext[256]; static struct wl_event_source *status_event_source; @@ -517,6 +534,10 @@ applyrules(Client *c) } } } + if (mon) { + c->geom.x = (mon->w.width - c->geom.width) / 2 + mon->m.x; + c->geom.y = (mon->w.height - c->geom.height) / 2 + mon->m.y; + } setmon(c, mon, newtags); } @@ -1009,7 +1030,7 @@ createkeyboardgroup(void) /* Prepare an XKB keymap and assign it to the keyboard group. */ context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - if (!(keymap = xkb_keymap_new_from_names(context, &xkb_rules, + if (!(keymap = xkb_keymap_new_from_names(context, &xkb_rules[kblayout], XKB_KEYMAP_COMPILE_NO_FLAGS))) die("failed to compile keymap"); @@ -1107,6 +1128,11 @@ createmon(struct wl_listener *listener, void *data) for (i = 0; i < LENGTH(m->layers); i++) wl_list_init(&m->layers[i]); + m->gappih = gappih; + m->gappiv = gappiv; + m->gappoh = gappoh; + m->gappov = gappov; + wlr_output_state_init(&state); /* Initialize monitor state using configured rules */ m->tagset[0] = m->tagset[1] = 1; @@ -1298,6 +1324,12 @@ cursorwarptohint(void) } void +defaultgaps(const Arg *arg) +{ + setgaps(gappoh, gappov, gappih, gappiv); +} + +void destroydecoration(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, destroy_decoration); @@ -1735,6 +1767,83 @@ incnmaster(const Arg *arg) } void +incgaps(const Arg *arg) +{ + setgaps( + selmon->gappoh + arg->i, + selmon->gappov + arg->i, + selmon->gappih + arg->i, + selmon->gappiv + arg->i + ); +} + +void +incigaps(const Arg *arg) +{ + setgaps( + selmon->gappoh, + selmon->gappov, + selmon->gappih + arg->i, + selmon->gappiv + arg->i + ); +} + +void +incihgaps(const Arg *arg) +{ + setgaps( + selmon->gappoh, + selmon->gappov, + selmon->gappih + arg->i, + selmon->gappiv + ); +} + +void +incivgaps(const Arg *arg) +{ + setgaps( + selmon->gappoh, + selmon->gappov, + selmon->gappih, + selmon->gappiv + arg->i + ); +} + +void +incogaps(const Arg *arg) +{ + setgaps( + selmon->gappoh + arg->i, + selmon->gappov + arg->i, + selmon->gappih, + selmon->gappiv + ); +} + +void +incohgaps(const Arg *arg) +{ + setgaps( + selmon->gappoh + arg->i, + selmon->gappov, + selmon->gappih, + selmon->gappiv + ); +} + +void +incovgaps(const Arg *arg) +{ + setgaps( + selmon->gappoh, + selmon->gappov + arg->i, + selmon->gappih, + selmon->gappiv + ); +} + +void inputdevice(struct wl_listener *listener, void *data) { /* This event is raised by the backend when a new input device becomes @@ -1944,6 +2053,10 @@ mapnotify(struct wl_listener *listener, void *data) * try to apply rules for them */ if ((p = client_get_parent(c))) { c->isfloating = 1; + if (p->mon) { + c->geom.x = (p->mon->w.width - c->geom.width) / 2 + p->mon->m.x; + c->geom.y = (p->mon->w.height - c->geom.height) / 2 + p->mon->m.y; + } setmon(c, p->mon, p->tags); } else { applyrules(c); @@ -1985,8 +2098,12 @@ monocle(Monitor *m) wl_list_for_each(c, &clients, link) { if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) continue; - resize(c, m->w, 0); n++; + if (!monoclegaps) + resize(c, m->w, 0); + else + resize(c, (struct wlr_box){.x = m->w.x + gappoh, .y = m->w.y + gappov, + .width = m->w.width - 2 * gappoh, .height = m->w.height - 2 * gappov}, 0); } if (n) snprintf(m->ltsymbol, LENGTH(m->ltsymbol), "[%d]", n); @@ -2515,6 +2632,16 @@ setgamma(struct wl_listener *listener, void *data) } void +setgaps(int oh, int ov, int ih, int iv) +{ + selmon->gappoh = MAX(oh, 0); + selmon->gappov = MAX(ov, 0); + selmon->gappih = MAX(ih, 0); + selmon->gappiv = MAX(iv, 0); + arrange(selmon); +} + +void setlayout(const Arg *arg) { if (!selmon) @@ -2861,6 +2988,25 @@ status_in(int fd, unsigned int mask, void *data) } void +incxkbrules(const Arg *arg) +{ + KeyboardGroup *group; + struct wlr_keyboard_group *wlr_group; + const struct xkb_rule_names newrule = xkb_rules[(kblayout + 1) % LENGTH(xkb_rules)]; + + wl_list_for_each(group, &kb_group->link, link) { + wl_list_for_each(wlr_group, &group->wlr_group->keys, keys) { + struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + struct xkb_keymap *keymap = xkb_map_new_from_names(context, &newrule, + XKB_KEYMAP_COMPILE_NO_FLAGS); + wlr_keyboard_set_keymap(&wlr_group->keyboard, keymap); + xkb_keymap_unref(keymap); + xkb_context_unref(context); + } + } +} + +void tag(const Arg *arg) { Client *sel = focustop(selmon); @@ -2884,7 +3030,7 @@ tagmon(const Arg *arg) void tile(Monitor *m) { - unsigned int mw, my, ty; + unsigned int mw, my, ty, h, r, oe = enablegaps, ie = enablegaps; int i, n = 0; Client *c; @@ -2894,22 +3040,31 @@ tile(Monitor *m) if (n == 0) return; + if (smartgaps == n) { + oe = 0; // outer gaps disabled + } + if (n > m->nmaster) - mw = m->nmaster ? (int)roundf(m->w.width * m->mfact) : 0; + mw = m->nmaster ? (int)roundf((m->w.width + m->gappiv*ie) * m->mfact) : 0; else - mw = m->w.width; - i = my = ty = 0; + mw = m->w.width - 2*m->gappov*oe + m->gappiv*ie; + i = 0; + my = ty = m->gappoh*oe; wl_list_for_each(c, &clients, link) { if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) continue; if (i < m->nmaster) { - resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + my, .width = mw, - .height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0); - my += c->geom.height; + r = MIN(n, m->nmaster) - i; + h = (m->w.height - my - m->gappoh*oe - m->gappih*ie * (r - 1)) / r; + resize(c, (struct wlr_box){.x = m->w.x + m->gappov*oe, .y = m->w.y + my, + .width = mw - m->gappiv*ie, .height = h}, 0); + my += c->geom.height + m->gappih*ie; } else { - resize(c, (struct wlr_box){.x = m->w.x + mw, .y = m->w.y + ty, - .width = m->w.width - mw, .height = (m->w.height - ty) / (n - i)}, 0); - ty += c->geom.height; + r = n - i; + h = (m->w.height - ty - m->gappoh*oe - m->gappih*ie * (r - 1)) / r; + resize(c, (struct wlr_box){.x = m->w.x + mw + m->gappov*oe, .y = m->w.y + ty, + .width = m->w.width - mw - 2*m->gappov*oe, .height = h}, 0); + ty += c->geom.height + m->gappih*ie; } i++; } @@ -2941,6 +3096,13 @@ togglefullscreen(const Arg *arg) } void +togglegaps(const Arg *arg) +{ + enablegaps = !enablegaps; + arrange(selmon); +} + +void toggletag(const Arg *arg) { uint32_t newtags; |