mirror of
https://github.com/mintycube/dwm.git
synced 2024-10-22 14:05:45 +02:00
Adding tab patch
This commit is contained in:
parent
27185a74c4
commit
0f9104285b
@ -15,6 +15,8 @@ Refer to [https://dwm.suckless.org/](https://dwm.suckless.org/) for details on t
|
|||||||
|
|
||||||
### Changelog:
|
### Changelog:
|
||||||
|
|
||||||
|
2021-03-09 - Added the tab patch
|
||||||
|
|
||||||
2021-02-11 - Added the riodraw and focusdir patches
|
2021-02-11 - Added the riodraw and focusdir patches
|
||||||
|
|
||||||
2021-01-22 - Added the placemouse patch
|
2021-01-22 - Added the placemouse patch
|
||||||
@ -575,6 +577,13 @@ Refer to [https://dwm.suckless.org/](https://dwm.suckless.org/) for details on t
|
|||||||
- [systray](https://dwm.suckless.org/patches/systray/)
|
- [systray](https://dwm.suckless.org/patches/systray/)
|
||||||
- adds system tray in the status bar
|
- adds system tray in the status bar
|
||||||
|
|
||||||
|
- [tab](https://dwm.suckless.org/patches/tab/)
|
||||||
|
- transforms the monocle layout into a "tabbed" layout if more than one window is present on the monocle view
|
||||||
|
- this is essentially just a specific bar
|
||||||
|
- the patch has been added for demonstration purposes only and has limited compatibility with other patches
|
||||||
|
- it will conflict space-wise with a second bar
|
||||||
|
- note that fancybar, awesomebar, bartabgroups and similar patches make the tab patch redundant
|
||||||
|
|
||||||
- [tagall](https://dwm.suckless.org/patches/tagall/)
|
- [tagall](https://dwm.suckless.org/patches/tagall/)
|
||||||
- adds keyboard shortcuts to move all (or only floating) windows from one tag to another
|
- adds keyboard shortcuts to move all (or only floating) windows from one tag to another
|
||||||
|
|
||||||
|
14
config.def.h
14
config.def.h
@ -38,6 +38,14 @@ static const int showbar = 0; /* 0 means no bar */
|
|||||||
static const int showbar = 1; /* 0 means no bar */
|
static const int showbar = 1; /* 0 means no bar */
|
||||||
#endif // BAR_HOLDBAR_PATCH
|
#endif // BAR_HOLDBAR_PATCH
|
||||||
static const int topbar = 1; /* 0 means bottom bar */
|
static const int topbar = 1; /* 0 means bottom bar */
|
||||||
|
#if TAB_PATCH
|
||||||
|
/* Display modes of the tab bar: never shown, always shown, shown only in */
|
||||||
|
/* monocle mode in the presence of several windows. */
|
||||||
|
/* Modes after showtab_nmodes are disabled. */
|
||||||
|
enum showtab_modes { showtab_never, showtab_auto, showtab_nmodes, showtab_always};
|
||||||
|
static const int showtab = showtab_auto; /* Default tab bar show mode */
|
||||||
|
static const int toptab = False; /* False means bottom tab bar */
|
||||||
|
#endif // TAB_PATCH
|
||||||
#if BAR_HEIGHT_PATCH
|
#if BAR_HEIGHT_PATCH
|
||||||
static const int bar_height = 0; /* 0 means derive from font, >= 1 explicit height */
|
static const int bar_height = 0; /* 0 means derive from font, >= 1 explicit height */
|
||||||
#endif // BAR_HEIGHT_PATCH
|
#endif // BAR_HEIGHT_PATCH
|
||||||
@ -769,6 +777,9 @@ static Key keys[] = {
|
|||||||
{ MODKEY, XK_s, rioresize, {0} },
|
{ MODKEY, XK_s, rioresize, {0} },
|
||||||
#endif // RIODRAW_PATCH
|
#endif // RIODRAW_PATCH
|
||||||
{ MODKEY, XK_b, togglebar, {0} },
|
{ MODKEY, XK_b, togglebar, {0} },
|
||||||
|
#if TAB_PATCH
|
||||||
|
{ MODKEY|ControlMask, XK_b, tabmode, {-1} },
|
||||||
|
#endif // TAB_PATCH
|
||||||
#if FOCUSMASTER_PATCH
|
#if FOCUSMASTER_PATCH
|
||||||
{ MODKEY|ControlMask, XK_space, focusmaster, {0} },
|
{ MODKEY|ControlMask, XK_space, focusmaster, {0} },
|
||||||
#endif // FOCUSMASTER_PATCH
|
#endif // FOCUSMASTER_PATCH
|
||||||
@ -1206,6 +1217,9 @@ static Button buttons[] = {
|
|||||||
{ ClkTagBar, 0, Button3, toggleview, {0} },
|
{ ClkTagBar, 0, Button3, toggleview, {0} },
|
||||||
{ ClkTagBar, MODKEY, Button1, tag, {0} },
|
{ ClkTagBar, MODKEY, Button1, tag, {0} },
|
||||||
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
|
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
|
||||||
|
#if TAB_PATCH
|
||||||
|
{ ClkTabBar, 0, Button1, focuswin, {0} },
|
||||||
|
#endif // TAB_PATCH
|
||||||
};
|
};
|
||||||
|
|
||||||
#if DWMC_PATCH
|
#if DWMC_PATCH
|
||||||
|
119
dwm.c
119
dwm.c
@ -69,6 +69,9 @@
|
|||||||
#define Button9 9
|
#define Button9 9
|
||||||
#define NUMTAGS 9
|
#define NUMTAGS 9
|
||||||
#define BARRULES 20
|
#define BARRULES 20
|
||||||
|
#if TAB_PATCH
|
||||||
|
#define MAXTABS 50
|
||||||
|
#endif // TAB_PATCH
|
||||||
#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)
|
#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)
|
||||||
#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
|
#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
|
||||||
#if BAR_ANYBAR_PATCH
|
#if BAR_ANYBAR_PATCH
|
||||||
@ -205,6 +208,9 @@ enum {
|
|||||||
#if BAR_STATUSBUTTON_PATCH
|
#if BAR_STATUSBUTTON_PATCH
|
||||||
ClkButton,
|
ClkButton,
|
||||||
#endif // BAR_STATUSBUTTON_PATCH
|
#endif // BAR_STATUSBUTTON_PATCH
|
||||||
|
#if TAB_PATCH
|
||||||
|
ClkTabBar,
|
||||||
|
#endif // TAB_PATCH
|
||||||
ClkTagBar,
|
ClkTagBar,
|
||||||
ClkLtSymbol,
|
ClkLtSymbol,
|
||||||
ClkStatusText,
|
ClkStatusText,
|
||||||
@ -414,6 +420,9 @@ struct Monitor {
|
|||||||
int num;
|
int num;
|
||||||
int mx, my, mw, mh; /* screen size */
|
int mx, my, mw, mh; /* screen size */
|
||||||
int wx, wy, ww, wh; /* window area */
|
int wx, wy, ww, wh; /* window area */
|
||||||
|
#if TAB_PATCH
|
||||||
|
int ty; /* tab bar geometry */
|
||||||
|
#endif // TAB_PATCH
|
||||||
#if VANITYGAPS_PATCH
|
#if VANITYGAPS_PATCH
|
||||||
int gappih; /* horizontal gap between windows */
|
int gappih; /* horizontal gap between windows */
|
||||||
int gappiv; /* vertical gap between windows */
|
int gappiv; /* vertical gap between windows */
|
||||||
@ -427,6 +436,13 @@ struct Monitor {
|
|||||||
unsigned int sellt;
|
unsigned int sellt;
|
||||||
unsigned int tagset[2];
|
unsigned int tagset[2];
|
||||||
int showbar;
|
int showbar;
|
||||||
|
#if TAB_PATCH
|
||||||
|
int showtab;
|
||||||
|
int toptab;
|
||||||
|
Window tabwin;
|
||||||
|
int ntabs;
|
||||||
|
int tab_widths[MAXTABS];
|
||||||
|
#endif // TAB_PATCH
|
||||||
Client *clients;
|
Client *clients;
|
||||||
Client *sel;
|
Client *sel;
|
||||||
Client *stack;
|
Client *stack;
|
||||||
@ -973,6 +989,10 @@ arrange(Monitor *m)
|
|||||||
void
|
void
|
||||||
arrangemon(Monitor *m)
|
arrangemon(Monitor *m)
|
||||||
{
|
{
|
||||||
|
#if TAB_PATCH
|
||||||
|
updatebarpos(m);
|
||||||
|
XMoveResizeWindow(dpy, m->tabwin, m->wx, m->ty, m->ww, th);
|
||||||
|
#endif // TAB_PATCH
|
||||||
strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol);
|
strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol);
|
||||||
if (m->lt[m->sellt]->arrange)
|
if (m->lt[m->sellt]->arrange)
|
||||||
m->lt[m->sellt]->arrange(m);
|
m->lt[m->sellt]->arrange(m);
|
||||||
@ -1000,7 +1020,7 @@ attachstack(Client *c)
|
|||||||
void
|
void
|
||||||
buttonpress(XEvent *e)
|
buttonpress(XEvent *e)
|
||||||
{
|
{
|
||||||
int click, i, r;
|
int click, i, x, r;
|
||||||
Arg arg = {0};
|
Arg arg = {0};
|
||||||
Client *c;
|
Client *c;
|
||||||
Monitor *m;
|
Monitor *m;
|
||||||
@ -1043,6 +1063,26 @@ buttonpress(XEvent *e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if TAB_PATCH
|
||||||
|
if (ev->window == selmon->tabwin) {
|
||||||
|
for (i = 0, x = 0, c = selmon->clients; c; c = c->next) {
|
||||||
|
if (!ISVISIBLE(c) || HIDDEN(c))
|
||||||
|
continue;
|
||||||
|
x += selmon->tab_widths[i];
|
||||||
|
if (ev->x > x)
|
||||||
|
++i;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
if (i >= m->ntabs)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (c) {
|
||||||
|
click = ClkTabBar;
|
||||||
|
arg.ui = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // TAB_PATCH
|
||||||
|
|
||||||
if (click == ClkRootWin && (c = wintoclient(ev->window))) {
|
if (click == ClkRootWin && (c = wintoclient(ev->window))) {
|
||||||
#if FOCUSONCLICK_PATCH
|
#if FOCUSONCLICK_PATCH
|
||||||
if (focusonwheel || (ev->button != Button4 && ev->button != Button5))
|
if (focusonwheel || (ev->button != Button4 && ev->button != Button5))
|
||||||
@ -1058,11 +1098,17 @@ buttonpress(XEvent *e)
|
|||||||
for (i = 0; i < LENGTH(buttons); i++) {
|
for (i = 0; i < LENGTH(buttons); i++) {
|
||||||
if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button
|
if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button
|
||||||
&& CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) {
|
&& CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) {
|
||||||
|
buttons[i].func(
|
||||||
|
(
|
||||||
|
click == ClkTagBar
|
||||||
|
#if TAB_PATCH
|
||||||
|
|| click == ClkTabBar
|
||||||
|
#endif // TAB_PATCH
|
||||||
#if BAR_WINTITLEACTIONS_PATCH
|
#if BAR_WINTITLEACTIONS_PATCH
|
||||||
buttons[i].func((click == ClkTagBar || click == ClkWinTitle) && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg);
|
|| click == ClkWinTitle
|
||||||
#else
|
|
||||||
buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg);
|
|
||||||
#endif // BAR_WINTITLEACTIONS_PATCH
|
#endif // BAR_WINTITLEACTIONS_PATCH
|
||||||
|
) && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1149,6 +1195,10 @@ cleanupmon(Monitor *mon)
|
|||||||
#endif // BAR_SYSTRAY_PATCH
|
#endif // BAR_SYSTRAY_PATCH
|
||||||
free(bar);
|
free(bar);
|
||||||
}
|
}
|
||||||
|
#if TAB_PATCH
|
||||||
|
XUnmapWindow(dpy, mon->tabwin);
|
||||||
|
XDestroyWindow(dpy, mon->tabwin);
|
||||||
|
#endif // TAB_PATCH
|
||||||
free(mon);
|
free(mon);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1413,6 +1463,11 @@ createmon(void)
|
|||||||
m->nstack = nstack;
|
m->nstack = nstack;
|
||||||
#endif // FLEXTILE_DELUXE_LAYOUT
|
#endif // FLEXTILE_DELUXE_LAYOUT
|
||||||
m->showbar = showbar;
|
m->showbar = showbar;
|
||||||
|
#if TAB_PATCH
|
||||||
|
m->showtab = showtab;
|
||||||
|
m->toptab = toptab;
|
||||||
|
m->ntabs = 0;
|
||||||
|
#endif // TAB_PATCH
|
||||||
#if SETBORDERPX_PATCH
|
#if SETBORDERPX_PATCH
|
||||||
m->borderpx = borderpx;
|
m->borderpx = borderpx;
|
||||||
#endif // SETBORDERPX_PATCH
|
#endif // SETBORDERPX_PATCH
|
||||||
@ -1807,8 +1862,12 @@ expose(XEvent *e)
|
|||||||
Monitor *m;
|
Monitor *m;
|
||||||
XExposeEvent *ev = &e->xexpose;
|
XExposeEvent *ev = &e->xexpose;
|
||||||
|
|
||||||
if (ev->count == 0 && (m = wintomon(ev->window)))
|
if (ev->count == 0 && (m = wintomon(ev->window))) {
|
||||||
drawbar(m);
|
drawbar(m);
|
||||||
|
#if TAB_PATCH
|
||||||
|
drawtabs();
|
||||||
|
#endif // TAB_PATCH
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2567,12 +2626,18 @@ propertynotify(XEvent *e)
|
|||||||
updatewmhints(c);
|
updatewmhints(c);
|
||||||
if (c->isurgent)
|
if (c->isurgent)
|
||||||
drawbars();
|
drawbars();
|
||||||
|
#if TAB_PATCH
|
||||||
|
drawtabs();
|
||||||
|
#endif // TAB_PATCH
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) {
|
if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) {
|
||||||
updatetitle(c);
|
updatetitle(c);
|
||||||
if (c == c->mon->sel)
|
if (c == c->mon->sel)
|
||||||
drawbar(c->mon);
|
drawbar(c->mon);
|
||||||
|
#if TAB_PATCH
|
||||||
|
drawtab(c->mon);
|
||||||
|
#endif // TAB_PATCH
|
||||||
}
|
}
|
||||||
#if DECORATION_HINTS_PATCH
|
#if DECORATION_HINTS_PATCH
|
||||||
if (ev->atom == motifatom)
|
if (ev->atom == motifatom)
|
||||||
@ -2864,6 +2929,9 @@ restack(Monitor *m)
|
|||||||
#endif // WARP_PATCH
|
#endif // WARP_PATCH
|
||||||
|
|
||||||
drawbar(m);
|
drawbar(m);
|
||||||
|
#if TAB_PATCH
|
||||||
|
drawtab(m);
|
||||||
|
#endif // TAB_PATCH
|
||||||
if (!m->sel)
|
if (!m->sel)
|
||||||
return;
|
return;
|
||||||
if (m->sel->isfloating || !m->lt[m->sellt]->arrange)
|
if (m->sel->isfloating || !m->lt[m->sellt]->arrange)
|
||||||
@ -3345,6 +3413,9 @@ setup(void)
|
|||||||
bh = drw->fonts->h + 2;
|
bh = drw->fonts->h + 2;
|
||||||
#endif // BAR_HEIGHT_PATCH
|
#endif // BAR_HEIGHT_PATCH
|
||||||
#endif // BAR_STATUSPADDING_PATCH
|
#endif // BAR_STATUSPADDING_PATCH
|
||||||
|
#if TAB_PATCH
|
||||||
|
th = bh;
|
||||||
|
#endif // TAB_PATCH
|
||||||
updategeom();
|
updategeom();
|
||||||
/* init atoms */
|
/* init atoms */
|
||||||
utf8string = XInternAtom(dpy, "UTF8_STRING", False);
|
utf8string = XInternAtom(dpy, "UTF8_STRING", False);
|
||||||
@ -4069,12 +4140,32 @@ updatebars(void)
|
|||||||
XSetClassHint(dpy, bar->win, &ch);
|
XSetClassHint(dpy, bar->win, &ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if TAB_PATCH
|
||||||
|
if (!m->tabwin) {
|
||||||
|
#if BAR_ALPHA_PATCH
|
||||||
|
m->tabwin = XCreateWindow(dpy, root, m->wx, m->ty, m->ww, th, 0, depth,
|
||||||
|
InputOutput, visual,
|
||||||
|
CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa);
|
||||||
|
#else
|
||||||
|
m->tabwin = XCreateWindow(dpy, root, m->wx, m->ty, m->ww, th, 0, DefaultDepth(dpy, screen),
|
||||||
|
CopyFromParent, DefaultVisual(dpy, screen),
|
||||||
|
CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
|
||||||
|
#endif // BAR_ALPHA_PATCH
|
||||||
|
XDefineCursor(dpy, m->tabwin, cursor[CurNormal]->cursor);
|
||||||
|
XMapRaised(dpy, m->tabwin);
|
||||||
|
}
|
||||||
|
#endif // TAB_PATCH
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
updatebarpos(Monitor *m)
|
updatebarpos(Monitor *m)
|
||||||
{
|
{
|
||||||
|
#if TAB_PATCH
|
||||||
|
Client *c;
|
||||||
|
int nvis = 0;
|
||||||
|
#endif // TAB_PATCH
|
||||||
|
|
||||||
m->wx = m->mx;
|
m->wx = m->mx;
|
||||||
m->wy = m->my;
|
m->wy = m->my;
|
||||||
m->ww = m->mw;
|
m->ww = m->mw;
|
||||||
@ -4105,6 +4196,24 @@ updatebarpos(Monitor *m)
|
|||||||
for (bar = m->bar; bar; bar = bar->next)
|
for (bar = m->bar; bar; bar = bar->next)
|
||||||
if (!m->showbar || !bar->showbar)
|
if (!m->showbar || !bar->showbar)
|
||||||
bar->by = -bar->bh - y_pad;
|
bar->by = -bar->bh - y_pad;
|
||||||
|
|
||||||
|
#if TAB_PATCH
|
||||||
|
for (c = m->clients; c; c = c->next) {
|
||||||
|
if (ISVISIBLE(c) && !HIDDEN(c))
|
||||||
|
++nvis;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m->showtab == showtab_always
|
||||||
|
|| ((m->showtab == showtab_auto) && (nvis > 1) && (m->lt[m->sellt]->arrange == monocle))) {
|
||||||
|
m->wh -= th;
|
||||||
|
m->ty = m->toptab ? m->wy : m->wy + m->wh;
|
||||||
|
if (m->toptab)
|
||||||
|
m->wy += th;
|
||||||
|
} else {
|
||||||
|
m->ty = -th;
|
||||||
|
}
|
||||||
|
#endif // TAB_PATCH
|
||||||
|
|
||||||
if (!m->showbar)
|
if (!m->showbar)
|
||||||
return;
|
return;
|
||||||
for (bar = m->bar; bar; bar = bar->next) {
|
for (bar = m->bar; bar; bar = bar->next) {
|
||||||
|
@ -253,6 +253,9 @@
|
|||||||
#if SWITCHCOL_PATCH
|
#if SWITCHCOL_PATCH
|
||||||
#include "switchcol.c"
|
#include "switchcol.c"
|
||||||
#endif
|
#endif
|
||||||
|
#if TAB_PATCH
|
||||||
|
#include "tab.c"
|
||||||
|
#endif
|
||||||
#if TAGALL_PATCH
|
#if TAGALL_PATCH
|
||||||
#include "tagall.c"
|
#include "tagall.c"
|
||||||
#endif
|
#endif
|
||||||
|
@ -249,6 +249,9 @@
|
|||||||
#if SWITCHCOL_PATCH
|
#if SWITCHCOL_PATCH
|
||||||
#include "switchcol.h"
|
#include "switchcol.h"
|
||||||
#endif
|
#endif
|
||||||
|
#if TAB_PATCH
|
||||||
|
#include "tab.h"
|
||||||
|
#endif
|
||||||
#if TAGALL_PATCH
|
#if TAGALL_PATCH
|
||||||
#include "tagall.h"
|
#include "tagall.h"
|
||||||
#endif
|
#endif
|
||||||
|
132
patch/tab.c
Normal file
132
patch/tab.c
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
static int th = 0; /* tab bar geometry */
|
||||||
|
|
||||||
|
void
|
||||||
|
drawtabs(void)
|
||||||
|
{
|
||||||
|
Monitor *m;
|
||||||
|
|
||||||
|
for (m = mons; m; m = m->next)
|
||||||
|
drawtab(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmpint(const void *p1, const void *p2)
|
||||||
|
{
|
||||||
|
/* The actual arguments to this function are "pointers to
|
||||||
|
pointers to char", but strcmp(3) arguments are "pointers
|
||||||
|
to char", hence the following cast plus dereference */
|
||||||
|
return *((int*) p1) > * (int*) p2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
drawtab(Monitor *m)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
int i;
|
||||||
|
int itag = -1;
|
||||||
|
char view_info[50];
|
||||||
|
int view_info_w = 0;
|
||||||
|
int sorted_label_widths[MAXTABS];
|
||||||
|
int tot_width;
|
||||||
|
int maxsize = bh;
|
||||||
|
int x = 0;
|
||||||
|
int w = 0;
|
||||||
|
|
||||||
|
// view_info: indicate the tag which is displayed in the view
|
||||||
|
for (i = 0; i < NUMTAGS; ++i) {
|
||||||
|
if ((selmon->tagset[selmon->seltags] >> i) & 1) {
|
||||||
|
if (itag >=0) { // more than one tag selected
|
||||||
|
itag = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
itag = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 <= itag && itag < NUMTAGS) {
|
||||||
|
snprintf(view_info, sizeof view_info, "[%s]", tagicon(m, itag));
|
||||||
|
} else {
|
||||||
|
strncpy(view_info, "[...]", sizeof view_info);
|
||||||
|
}
|
||||||
|
view_info[sizeof(view_info) - 1 ] = 0;
|
||||||
|
view_info_w = TEXTW(view_info);
|
||||||
|
tot_width = view_info_w;
|
||||||
|
|
||||||
|
/* Calculates number of labels and their width */
|
||||||
|
m->ntabs = 0;
|
||||||
|
for (c = m->clients; c; c = c->next) {
|
||||||
|
if (!ISVISIBLE(c) || HIDDEN(c))
|
||||||
|
continue;
|
||||||
|
m->tab_widths[m->ntabs] = TEXTW(c->name);
|
||||||
|
tot_width += m->tab_widths[m->ntabs];
|
||||||
|
++m->ntabs;
|
||||||
|
if (m->ntabs >= MAXTABS)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tot_width > m->ww) { // not enough space to display the labels, they need to be truncated
|
||||||
|
memcpy(sorted_label_widths, m->tab_widths, sizeof(int) * m->ntabs);
|
||||||
|
qsort(sorted_label_widths, m->ntabs, sizeof(int), cmpint);
|
||||||
|
tot_width = view_info_w;
|
||||||
|
for (i = 0; i < m->ntabs; ++i) {
|
||||||
|
if (tot_width + (m->ntabs - i) * sorted_label_widths[i] > m->ww)
|
||||||
|
break;
|
||||||
|
tot_width += sorted_label_widths[i];
|
||||||
|
}
|
||||||
|
maxsize = (m->ww - tot_width) / (m->ntabs - i);
|
||||||
|
} else {
|
||||||
|
maxsize = m->ww;
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
for (c = m->clients; c; c = c->next) {
|
||||||
|
if (!ISVISIBLE(c) || HIDDEN(c))
|
||||||
|
continue;
|
||||||
|
if (i >= m->ntabs)
|
||||||
|
break;
|
||||||
|
if (m->tab_widths[i] > maxsize)
|
||||||
|
m->tab_widths[i] = maxsize;
|
||||||
|
w = m->tab_widths[i];
|
||||||
|
drw_setscheme(drw, scheme[(c == m->sel) ? SchemeSel : SchemeNorm]);
|
||||||
|
drw_text(drw, x, 0, w, th, 0, c->name, 0, False);
|
||||||
|
x += w;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
drw_setscheme(drw, scheme[SchemeNorm]);
|
||||||
|
|
||||||
|
/* cleans interspace between window names and current viewed tag label */
|
||||||
|
w = m->ww - view_info_w - x;
|
||||||
|
drw_text(drw, x, 0, w, th, 0, "", 0, False);
|
||||||
|
|
||||||
|
/* view info */
|
||||||
|
x += w;
|
||||||
|
w = view_info_w;
|
||||||
|
drw_text(drw, x, 0, w, th, 0, view_info, 0, False);
|
||||||
|
|
||||||
|
drw_map(drw, m->tabwin, 0, 0, m->ww, th);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
focuswin(const Arg* arg)
|
||||||
|
{
|
||||||
|
int iwin = arg->i;
|
||||||
|
Client* c = NULL;
|
||||||
|
for (c = selmon->clients; c && (iwin || !ISVISIBLE(c)) ; c = c->next) {
|
||||||
|
if (ISVISIBLE(c) && !HIDDEN(c))
|
||||||
|
--iwin;
|
||||||
|
};
|
||||||
|
if (c) {
|
||||||
|
focus(c);
|
||||||
|
restack(selmon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tabmode(const Arg *arg)
|
||||||
|
{
|
||||||
|
if (arg && arg->i >= 0)
|
||||||
|
selmon->showtab = arg->ui % showtab_nmodes;
|
||||||
|
else
|
||||||
|
selmon->showtab = (selmon->showtab + 1 ) % showtab_nmodes;
|
||||||
|
arrange(selmon);
|
||||||
|
}
|
4
patch/tab.h
Normal file
4
patch/tab.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
static void drawtab(Monitor *m);
|
||||||
|
static void drawtabs(void);
|
||||||
|
static void focuswin(const Arg* arg);
|
||||||
|
static void tabmode(const Arg *arg);
|
@ -963,6 +963,14 @@
|
|||||||
*/
|
*/
|
||||||
#define SWITCHTAG_PATCH 0
|
#define SWITCHTAG_PATCH 0
|
||||||
|
|
||||||
|
/* This patch transforms the monocle layout into a "tabbed" layout if more than one window is
|
||||||
|
* present on the monocle view. This patch has been added for demonstration purposes only and has
|
||||||
|
* limited compatibility with other patches. It will conflict space-wise with a second bar.
|
||||||
|
* Note that fancybar, awesomebar, bartabgroups and similar patches make the tab patch redundant.
|
||||||
|
* https://dwm.suckless.org/patches/tab/
|
||||||
|
*/
|
||||||
|
#define TAB_PATCH 0
|
||||||
|
|
||||||
/* Adds keyboard shortcuts to move all (or only floating) windows from one tag to another.
|
/* Adds keyboard shortcuts to move all (or only floating) windows from one tag to another.
|
||||||
* https://dwm.suckless.org/patches/tagall/
|
* https://dwm.suckless.org/patches/tagall/
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user