From fdd3f2cadb5260250db49fda5b5b9f4fac9854dd Mon Sep 17 00:00:00 2001 From: amolinae06 Date: Fri, 14 Feb 2025 23:17:37 -0600 Subject: [PATCH] added more layouts --- README.md | 8 +- config.def.h | 16 +++- config.h | 30 ++++-- config.mk | 8 +- dwl.c | 263 +++++++++++++++++++++++++++++++++++++++++++++------ 5 files changed, 280 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 6c59a75..17803ea 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,17 @@ philosophy. Like dwm, dwl is: - [autostart](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/autostart) - [bar](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/bar) - [barheight](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/barheight) +- [barpadding](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/barpadding) +- [centeredmaster](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/centeredmaster) +- [column](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/column) - [cursortheme](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/cursortheme) +- [deck](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/deck) - [en-keycodes](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/en-keycodes) -- [genericgaps](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/genericgaps/) +- [genericgaps](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/genericgaps) - [hide_vacant_tags](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/hide_vacant_tags) - [inputdevicerules](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/inputdevicerules) +- [nextlayout](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/nextlayout) +- [pertag](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/pertag) - [rotatetags](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/rotatetags) - [setupenv](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/setupenv) - [sticky](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/sticky) diff --git a/config.def.h b/config.def.h index 67cb5d0..042ad88 100644 --- a/config.def.h +++ b/config.def.h @@ -7,9 +7,11 @@ 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 unsigned int borderpx = 1; /* border pixel of windows */ -static const int user_bh = 30; /* 0 means that dwl will calculate barheight, >= 1 means dwl will use user_bh as the bar height. */ +static const int user_bh = 30; /* 0 means that dwl will calculate barheight, >= 1 means dwl will use user_bh as the bar height. */ static const int showbar = 1; /* 0 means no bar */ static const int topbar = 1; /* 0 means bottom bar */ +static const int vertpad = 10; /* vertical padding of bar */ +static const int sidepad = 10; /* horizontal padding of 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 */ @@ -63,6 +65,10 @@ static const Layout layouts[] = { { "[]=", tile }, { "><>", NULL }, /* no layout function means floating behavior */ { "[M]", monocle }, + { "|M|", centeredmaster }, + { "||", col }, + { "[D]", deck }, + { NULL, NULL }, /* terminate */ }; /* monitors */ @@ -205,8 +211,12 @@ static const Key keys[] = { { MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} }, { MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} }, { MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} }, - { MODKEY, XKB_KEY_space, setlayout, {0} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} }, + { MODKEY, XKB_KEY_c, setlayout, {.v = &layouts[3]} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, setlayout, {.v = &layouts[4]} }, + { MODKEY, XKB_KEY_p, setlayout, {.v = &layouts[5]} }, + { MODKEY, XKB_KEY_space, setlayout, {0} }, + { MODKEY, XKB_KEY_n, nextlayout, {0} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} }, { MODKEY, XKB_KEY_e, togglefullscreen, {0} }, { MODKEY, XKB_KEY_u, togglepointer, {0} }, { MODKEY, XKB_KEY_0, view, {.ui = ~0} }, diff --git a/config.h b/config.h index 011f9ed..fc8742f 100644 --- a/config.h +++ b/config.h @@ -14,6 +14,8 @@ static const char *cursor_theme = "macOS"; static const char cursor_size[] = "28"; /* Make sure it's a valid integer, otherwise things will break */ static const int user_bh = 30; /* 0 means that dwl will calculate barheight, >= 1 means dwl will use user_bh as the bar height. */ static const int showbar = 1; /* 0 means no bar */ +static const int vertpad = 25; /* vertical padding of bar */ +static const int sidepad = 25; /* horizontal padding of bar */ static const int topbar = 1; /* 0 means bottom bar */ static const char *fonts[] = {"inconsolata:size=11"}; /* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */ @@ -34,8 +36,9 @@ static int log_level = WLR_ERROR; /* Environment variables */ static const Env envs[] = { - /* variable value */ + /* variable value */ { "XDG_CURRENT_DESKTOP", "wlroots" }, + { "SDL_VIDEODRIVER", "wayland" }, }; /* Autostart */ @@ -63,6 +66,10 @@ static const Layout layouts[] = { { "[]=", tile }, { "><>", NULL }, /* no layout function means floating behavior */ { "[M]", monocle }, + { "|M|", centeredmaster }, + { "||", col }, + { "[D]", deck }, + { NULL, NULL }, /* terminate */ }; /* monitors */ @@ -186,6 +193,7 @@ static const Key keys[] = { { MODKEY, XKB_KEY_l, spawn, {.v = lockcmd} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_E, spawn, {.v = emojcmd} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q, spawn, {.v = pwmncmd} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_R, spawn, SHCMD("slurp | grim -g- - | wl-copy") }, { 0, XKB_KEY_XF86AudioMicMute, spawn,SHCMD("setvol -m mute") }, { WLR_MODIFIER_SHIFT, XKB_KEY_XF86AudioLowerVolume, spawn,SHCMD("setvol -m down") }, { WLR_MODIFIER_SHIFT, XKB_KEY_XF86AudioRaiseVolume, spawn,SHCMD("setvol -m up") }, @@ -198,14 +206,14 @@ static const Key keys[] = { { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_S, togglesticky, {0} }, { MODKEY, XKB_KEY_j, focusstack, {.i = +1} }, { MODKEY, XKB_KEY_k, focusstack, {.i = -1} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_A, incnmaster, {.i = -1} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_D, incnmaster, {.i = +1} }, + { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_q, incnmaster, {.i = -1} }, + { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_e, incnmaster, {.i = +1} }, { MODKEY, XKB_KEY_a, rotatetags, {.i = VIEW_L} }, { MODKEY, XKB_KEY_d, rotatetags, {.i = VIEW_R} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_A, rotatetags, {.i = SHIFT_L} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_D, rotatetags, {.i = SHIFT_R} }, - { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_a, setmfact, {.f = -0.05f} }, - { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_d, setmfact, {.f = +0.05f} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Z, setmfact, {.f = -0.05f} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_X, setmfact, {.f = +0.05f} }, { MODKEY, XKB_KEY_w, switchxkbrule, {0} }, /* { MODKEY, XKB_KEY_h, incgaps, {.i = +1 } }, @@ -226,14 +234,20 @@ static const Key keys[] = { { 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, XKB_KEY_q, killclient, {0} }, - { MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} }, + /* + { MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} }, { MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} }, { MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} }, - /* + { MODKEY, XKB_KEY_c, setlayout, {.v = &layouts[3]} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, setlayout, {.v = &layouts[4]} }, + { MODKEY, XKB_KEY_p, setlayout, {.v = &layouts[5]} }, + */ + { MODKEY, XKB_KEY_n, nextlayout, {0} }, + /* { MODKEY, XKB_KEY_space, setlayout, {0} }, */ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} }, diff --git a/config.mk b/config.mk index 1e0b810..153e80d 100644 --- a/config.mk +++ b/config.mk @@ -8,10 +8,10 @@ PREFIX = /usr/local MANDIR = $(PREFIX)/share/man DATADIR = $(PREFIX)/share -XWAYLAND = -XLIBS = +#XWAYLAND = +#XLIBS = # Uncomment to build XWayland support -#XWAYLAND = -DXWAYLAND -#XLIBS = xcb xcb-icccm +XWAYLAND = -DXWAYLAND +XLIBS = xcb xcb-icccm CC = gcc diff --git a/dwl.c b/dwl.c index f405548..13fc468 100644 --- a/dwl.c +++ b/dwl.c @@ -110,6 +110,7 @@ typedef struct { const Arg arg; } Button; +typedef struct Pertag Pertag; typedef struct Monitor Monitor; typedef struct { /* Must keep these three elements in this order */ @@ -228,7 +229,8 @@ 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 */ + Pertag *pertag; + int gappih; /* horizontal gap between windows */ int gappiv; /* vertical gap between windows */ int gappoh; /* horizontal outer gaps */ int gappov; /* vertical outer gaps */ @@ -299,11 +301,13 @@ static void bufdataend(struct wlr_buffer *buffer); static Buffer *bufmon(Monitor *m); static void bufrelease(struct wl_listener *listener, void *data); static void buttonpress(struct wl_listener *listener, void *data); +static void centeredmaster(Monitor *m); static void chvt(const Arg *arg); static void checkidleinhibitor(struct wlr_surface *exclude); static void cleanup(void); static void cleanupmon(struct wl_listener *listener, void *data); static void closemon(Monitor *m); +static void col(Monitor *m); static void commitlayersurfacenotify(struct wl_listener *listener, void *data); static void commitnotify(struct wl_listener *listener, void *data); static void commitpopup(struct wl_listener *listener, void *data); @@ -324,6 +328,7 @@ 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 deck(Monitor *m); 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); @@ -368,6 +373,7 @@ static void motionnotify(uint32_t time, struct wlr_input_device *device, double double sy, double sx_unaccel, double sy_unaccel); static void motionrelative(struct wl_listener *listener, void *data); static void moveresize(const Arg *arg); +static void nextlayout(const Arg *arg); static void outputmgrapply(struct wl_listener *listener, void *data); static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test); static void outputmgrtest(struct wl_listener *listener, void *data); @@ -493,17 +499,20 @@ static const struct wlr_buffer_impl buffer_impl = { .end_data_ptr_access = bufdataend, }; -static const struct xkb_rule_names en_rules = {.layout = "us"}; -static struct xkb_context *en_context; -static struct xkb_keymap *en_keymap; -static struct xkb_state *en_state, *en_state_shift; -static xkb_mod_index_t en_shift; - static int enablegaps = 1; /* enables gaps, used by togglegaps */ static void (*resize)(Client *c, struct wlr_box geo, int interact) = resizeapply; static struct libinput_device *togglepointerdevice = NULL; +static const struct xkb_rule_names en_rules = {.layout = "us"}; +static struct xkb_context *en_context; +static struct xkb_keymap *en_keymap; +static struct xkb_state *en_state; + +static struct xkb_context *en_context; +static struct xkb_keymap *en_keymap; +static struct xkb_state *en_state; + #ifdef XWAYLAND static void activatex11(struct wl_listener *listener, void *data); static void associatex11(struct wl_listener *listener, void *data); @@ -526,6 +535,14 @@ static xcb_atom_t netatom[NetLast]; static pid_t *autostart_pids; static size_t autostart_len; +struct Pertag { + unsigned int curtag, prevtag; /* current and previous tag */ + int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */ + float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */ + unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */ + const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */ +}; + /* function implementations */ void applybounds(Client *c, struct wlr_box *bbox) @@ -686,8 +703,8 @@ arrangelayers(Monitor *m) return; if (m->scene_buffer->node.enabled) { - usable_area.height -= m->b.real_height; - usable_area.y += topbar ? m->b.real_height : 0; + usable_area.height -= m->b.real_height + vertpad; + usable_area.y += topbar ? m->b.real_height + vertpad : 0; } /* Arrange exclusive surfaces from top->bottom */ @@ -859,7 +876,7 @@ buttonpress(struct wl_listener *listener, void *data) if (!c && !exclusive_focus && (node = wlr_scene_node_at(&layers[LyrBottom]->node, cursor->x, cursor->y, NULL, NULL)) && (buffer = wlr_scene_buffer_from_node(node)) && buffer == selmon->scene_buffer) { - cx = (cursor->x - selmon->m.x) * selmon->wlr_output->scale; + cx = (cursor->x - selmon->m.x - sidepad) * selmon->wlr_output->scale; wl_list_for_each(c, &clients, link) { if (c->mon != selmon) continue; @@ -916,6 +933,69 @@ buttonpress(struct wl_listener *listener, void *data) event->time_msec, event->button, event->state); } +void +centeredmaster(Monitor *m) +{ + unsigned int h, mw, mx, my, oty, ety, tw; + int i, n; + Client *c; + + n = 0; + wl_list_for_each(c, &clients, link) + if (VISIBLEON(c, m) && !c->isfloating && !c->isfullscreen) + n++; + if (n == 0) + return; + + /* initialize areas */ + mw = m->w.width; + mx = 0; + my = 0; + tw = mw; + + if (n > m->nmaster) { + /* go mfact box in the center if more than nmaster clients */ + mw = round(m->nmaster ? m->w.width * m->mfact : 0); + tw = m->w.width - mw; + + if (n - m->nmaster > 1) { + /* only one client */ + mx = (m->w.width - mw) / 2; + tw = (m->w.width - mw) / 2; + } + } + + i = 0; + oty = 0; + ety = 0; + wl_list_for_each(c, &clients, link) { + if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) + continue; + if (i < m->nmaster) { + /* nmaster clients are stacked vertically, in the center + * of the screen */ + h = (m->w.height - my) / (MIN(n, m->nmaster) - i); + resize(c, (struct wlr_box){.x = m->w.x + mx, .y = m->w.y + my, .width = mw, + .height = h}, 0); + my += c->geom.height; + } else { + /* stack clients are stacked vertically */ + if ((i - m->nmaster) % 2) { + h = (m->w.height - ety) / ( (1 + n - i) / 2); + resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + ety, .width = tw, + .height = h}, 0); + ety += c->geom.height; + } else { + h = (m->w.height - oty) / ((1 + n - i) / 2); + resize(c, (struct wlr_box){.x = m->w.x + mx + mw, .y = m->w.y + oty, .width = tw, + .height = h}, 0); + oty += c->geom.height; + } + } + i++; + } +} + void chvt(const Arg *arg) { @@ -972,7 +1052,6 @@ cleanup(void) wl_display_destroy(dpy); xkb_state_unref(en_state); - xkb_state_unref(en_state_shift); xkb_keymap_unref(en_keymap); xkb_context_unref(en_context); /* Destroy after the wayland display (when the monitors are already destroyed) @@ -1009,6 +1088,7 @@ cleanupmon(struct wl_listener *listener, void *data) wlr_output_layout_remove(output_layout, m->wlr_output); wlr_scene_output_destroy(m->scene_output); + free(m->pertag); closemon(m); wlr_scene_node_destroy(&m->fullscreen_bg->node); wlr_scene_node_destroy(&m->scene_buffer->node); @@ -1044,6 +1124,33 @@ closemon(Monitor *m) drawbars(); } +void +col(Monitor *m) +{ + Client *c; + unsigned int n = 0, i = 0; + + wl_list_for_each(c, &clients, link) + if (VISIBLEON(c, m) && !c->isfloating && !c->isfullscreen) + n++; + + wl_list_for_each(c, &clients, link) { + if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) + continue; + resize( + c, + (struct wlr_box){ + .x = m->w.x + i * m->w.width / n, + .y = m->w.y, + .width = m->w.width / n, + .height = m->w.height + }, + 0 + ); + i++; + } +} + void commitlayersurfacenotify(struct wl_listener *listener, void *data) { @@ -1327,6 +1434,18 @@ createmon(struct wl_listener *listener, void *data) wl_list_insert(&mons, &m->link); drawbars(); + m->pertag = calloc(1, sizeof(Pertag)); + m->pertag->curtag = m->pertag->prevtag = 1; + + for (i = 0; i <= LENGTH(tags); i++) { + m->pertag->nmasters[i] = m->nmaster; + m->pertag->mfacts[i] = m->mfact; + + m->pertag->ltidxs[i][0] = m->lt[0]; + m->pertag->ltidxs[i][1] = m->lt[1]; + m->pertag->sellts[i] = m->sellt; + } + /* The xdg-protocol specifies: * * If the fullscreened surface is not opaque, the compositor must make @@ -1506,6 +1625,41 @@ defaultgaps(const Arg *arg) setgaps(gappoh, gappov, gappih, gappiv); } +void +deck(Monitor *m) +{ + unsigned int mw, my; + int i, n = 0; + Client *c; + + wl_list_for_each(c, &clients, link) + if (VISIBLEON(c, m) && !c->isfloating && !c->isfullscreen) + n++; + if (n == 0) + return; + + if (n > m->nmaster) + mw = m->nmaster ? round(m->w.width * m->mfact) : 0; + else + mw = m->w.width; + i = my = 0; + 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; + } else { + resize(c, (struct wlr_box){.x = m->w.x + mw, .y = m->w.y, + .width = m->w.width - mw, .height = m->w.height}, 0); + if (c == focustop(m)) + wlr_scene_node_raise_to_top(&c->scene->node); + } + i++; + } +} + void destroydecoration(struct wl_listener *listener, void *data) { @@ -1728,8 +1882,8 @@ drawbar(Monitor *m) wlr_scene_buffer_set_dest_size(m->scene_buffer, m->b.real_width, m->b.real_height); - wlr_scene_node_set_position(&m->scene_buffer->node, m->m.x, - m->m.y + (topbar ? 0 : m->m.height - m->b.real_height)); + wlr_scene_node_set_position(&m->scene_buffer->node, m->m.x + sidepad, + m->m.y + (topbar ? vertpad : m->m.height - m->b.real_height - vertpad)); wlr_scene_buffer_set_buffer(m->scene_buffer, &buf->base); wlr_buffer_unlock(&buf->base); } @@ -1939,7 +2093,7 @@ incnmaster(const Arg *arg) { if (!arg || !selmon) return; - selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); + selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0); arrange(selmon); } @@ -2090,18 +2244,19 @@ keypress(struct wl_listener *listener, void *data) /* This event is raised when a key is pressed or released. */ KeyboardGroup *group = wl_container_of(listener, group, key); struct wlr_keyboard_key_event *event = data; + int nsyms, handled; /* Translate libinput keycode -> xkbcommon */ uint32_t keycode = event->keycode + 8; /* Get a list of keysyms based on the keymap for this keyboard */ const xkb_keysym_t *syms; - int shift = xkb_state_mod_index_is_active( - group->wlr_group->keyboard.xkb_state, en_shift, XKB_STATE_MODS_EFFECTIVE); - int nsyms = xkb_state_key_get_syms( - shift ? en_state_shift : en_state, keycode, &syms); - - int handled = 0; uint32_t mods = wlr_keyboard_get_modifiers(&group->wlr_group->keyboard); + xkb_state_update_key(en_state, keycode, + (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) + ? XKB_KEY_DOWN : XKB_KEY_UP); + nsyms = xkb_state_key_get_syms(en_state, keycode, &syms); + + handled = 0; wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); @@ -2454,6 +2609,17 @@ moveresize(const Arg *arg) } } +void +nextlayout(const Arg *arg) +{ + Layout *l; + for(l = (Layout *)layouts; l != selmon->lt[selmon->sellt]; l++); + if(l->symbol && (l + 1)->symbol) + setlayout(&((Arg) { .v = (l + 1) })); + else + setlayout(&((Arg) { .v = layouts })); +} + void outputmgrapply(struct wl_listener *listener, void *data) { @@ -2863,9 +3029,9 @@ setlayout(const Arg *arg) if (!selmon) return; if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) - selmon->sellt ^= 1; + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag] ^= 1; if (arg && arg->v) - selmon->lt[selmon->sellt] = (Layout *)arg->v; + selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v; strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, LENGTH(selmon->ltsymbol)); arrange(selmon); drawbar(selmon); @@ -2882,7 +3048,7 @@ setmfact(const Arg *arg) f = arg->f < 1.0f ? arg->f + selmon->mfact : arg->f - 1.0f; if (f < 0.1 || f > 0.9) return; - selmon->mfact = f; + selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f; arrange(selmon); } @@ -3119,9 +3285,6 @@ setup(void) en_keymap = xkb_keymap_new_from_names(en_context, &en_rules, XKB_KEYMAP_COMPILE_NO_FLAGS); en_state = xkb_state_new(en_keymap); - en_state_shift = xkb_state_new(en_keymap); - en_shift = xkb_keymap_mod_get_index(en_keymap, XKB_MOD_NAME_SHIFT); - xkb_state_update_mask(en_state_shift, 1 << en_shift, 0, 0, 0, 0, 0); LISTEN_STATIC(&backend->events.new_input, inputdevice); virtual_keyboard_mgr = wlr_virtual_keyboard_manager_v1_create(dpy); LISTEN_STATIC(&virtual_keyboard_mgr->events.new_virtual_keyboard, virtualkeyboard); @@ -3356,9 +3519,29 @@ void toggleview(const Arg *arg) { uint32_t newtagset; + size_t i; if (!(newtagset = selmon ? selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK) : 0)) return; + if (newtagset == (uint32_t)~0) { + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = 0; + } + + /* test if the user did not select the same tag */ + if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) { + selmon->pertag->prevtag = selmon->pertag->curtag; + for (i = 0; !(newtagset & 1 << i); i++) ; + selmon->pertag->curtag = i + 1; + } + + /* apply settings for this view */ + selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; + selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; + selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; + selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; + selmon->tagset[selmon->seltags] = newtagset; focusclient(focustop(selmon), 1); arrange(selmon); @@ -3535,8 +3718,8 @@ updatebar(Monitor *m) char fontattrs[12]; wlr_output_transformed_resolution(m->wlr_output, &rw, &rh); - m->b.width = rw; - m->b.real_width = (int)((float)m->b.width / m->wlr_output->scale); + m->b.width = rw - (2 * sidepad); + m->b.real_width = (int)((float)rw / m->wlr_output->scale) - (2 * sidepad); wlr_scene_node_set_enabled(&m->scene_buffer->node, m->wlr_output->enabled ? showbar : 0); @@ -3587,11 +3770,33 @@ urgent(struct wl_listener *listener, void *data) void view(const Arg *arg) { + size_t i, tmptag; + if (!selmon || (arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) return; selmon->seltags ^= 1; /* toggle sel tagset */ - if (arg->ui & TAGMASK) + if (arg->ui & ~0) { selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; + selmon->pertag->prevtag = selmon->pertag->curtag; + + if (arg->ui == TAGMASK) + selmon->pertag->curtag = 0; + else { + for (i = 0; !(arg->ui & 1 << i); i++) ; + selmon->pertag->curtag = i + 1; + } + } else { + tmptag = selmon->pertag->prevtag; + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = tmptag; + } + + selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; + selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; + selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; + selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; + focusclient(focustop(selmon), 1); arrange(selmon); drawbars();