summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.def.h43
-rw-r--r--dwl.c186
2 files changed, 210 insertions, 19 deletions
diff --git a/config.def.h b/config.def.h
index 5d1dc2b..d31b59e 100644
--- a/config.def.h
+++ b/config.def.h
@@ -6,11 +6,20 @@
/* appearance */
static const int sloppyfocus = 1; /* focus follows mouse */
static const int bypass_surface_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if it's surface isn't visible */
+static const int smartgaps = 0; /* 1 means no outer gap when there is only one window */
+static const int monoclegaps = 0; /* 1 means outer gaps in monocle layout */
static const unsigned int borderpx = 1; /* border pixel of windows */
+static const unsigned int gappih = 10; /* horiz inner gap between windows */
+static const unsigned int gappiv = 10; /* vert inner gap between windows */
+static const unsigned int gappoh = 10; /* horiz outer gap between windows and screen edge */
+static const unsigned int gappov = 10; /* vert outer gap between windows and screen edge */
+static const float rootcolor[] = COLOR(0x222222ff);
+static const float bordercolor[] = COLOR(0x444444ff);
+static const float focuscolor[] = COLOR(0x005577ff);
+static const float urgentcolor[] = COLOR(0xff0000ff);
static const int showbar = 1; /* 0 means no bar */
static const int topbar = 1; /* 0 means bottom bar */
static const char *fonts[] = {"monospace:size=10"};
-static const float rootcolor[] = COLOR(0x000000ff);
/* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */
static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */
static uint32_t colors[][3] = {
@@ -58,12 +67,15 @@ static const MonitorRule monrules[] = {
};
/* keyboard */
-static const struct xkb_rule_names xkb_rules = {
- /* can specify fields: rules, model, layout, variant, options */
- /* example:
- .options = "ctrl:nocaps",
- */
- .options = NULL,
+static const struct xkb_rule_names xkb_rules[] = {
+ {
+ .layout = "us"
+ },
+ /*{
+ .layout = "us",
+ .variant = "dvp",
+ .options = "compose:102,numpad:shift3,kpdl:semi,keypad:atm,caps:super"
+ }*/
};
static const int repeat_rate = 25;
@@ -140,6 +152,22 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_d, incnmaster, {.i = -1} },
{ MODKEY, XKB_KEY_h, setmfact, {.f = -0.05f} },
{ MODKEY, XKB_KEY_l, setmfact, {.f = +0.05f} },
+ { MODKEY|WLR_MODIFIER_LOGO, XKB_KEY_h, incgaps, {.i = +1 } },
+ { MODKEY|WLR_MODIFIER_LOGO, XKB_KEY_l, incgaps, {.i = -1 } },
+ { MODKEY|WLR_MODIFIER_LOGO|WLR_MODIFIER_SHIFT, XKB_KEY_H, incogaps, {.i = +1 } },
+ { MODKEY|WLR_MODIFIER_LOGO|WLR_MODIFIER_SHIFT, XKB_KEY_L, incogaps, {.i = -1 } },
+ { MODKEY|WLR_MODIFIER_LOGO|WLR_MODIFIER_CTRL, XKB_KEY_h, incigaps, {.i = +1 } },
+ { MODKEY|WLR_MODIFIER_LOGO|WLR_MODIFIER_CTRL, XKB_KEY_l, incigaps, {.i = -1 } },
+ { MODKEY|WLR_MODIFIER_LOGO, XKB_KEY_0, togglegaps, {0} },
+ { MODKEY|WLR_MODIFIER_LOGO|WLR_MODIFIER_SHIFT, XKB_KEY_parenright,defaultgaps, {0} },
+ { MODKEY, XKB_KEY_y, incihgaps, {.i = +1 } },
+ { MODKEY, XKB_KEY_o, incihgaps, {.i = -1 } },
+ { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_y, incivgaps, {.i = +1 } },
+ { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_o, incivgaps, {.i = -1 } },
+ { MODKEY|WLR_MODIFIER_LOGO, XKB_KEY_y, incohgaps, {.i = +1 } },
+ { MODKEY|WLR_MODIFIER_LOGO, XKB_KEY_o, incohgaps, {.i = -1 } },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Y, incovgaps, {.i = +1 } },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_O, incovgaps, {.i = -1 } },
{ MODKEY, XKB_KEY_Return, zoom, {0} },
{ MODKEY, XKB_KEY_Tab, view, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, killclient, {0} },
@@ -155,6 +183,7 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_period, focusmon, {.i = WLR_DIRECTION_RIGHT} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less, tagmon, {.i = WLR_DIRECTION_LEFT} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_greater, tagmon, {.i = WLR_DIRECTION_RIGHT} },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_A, incxkbrules, {.i = +1} },
TAGKEYS( XKB_KEY_1, XKB_KEY_exclam, 0),
TAGKEYS( XKB_KEY_2, XKB_KEY_at, 1),
TAGKEYS( XKB_KEY_3, XKB_KEY_numbersign, 2),
diff --git a/dwl.c b/dwl.c
index 07926d5..ecc6dfb 100644
--- a/dwl.c
+++ b/dwl.c
@@ -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;