Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Sravan Balaji 2023-11-12 12:18:09 -05:00
commit bd29edf9c0
33 changed files with 396 additions and 87 deletions

View File

@ -9,17 +9,11 @@ OBJ = ${SRC:.c=.o}
# FreeBSD users, prefix all ifdef, else and endif statements with a . for this to work (e.g. .ifdef)
ifdef YAJLLIBS
all: options dwm dwm-msg
all: dwm dwm-msg
else
all: options dwm
all: dwm
endif
options:
@echo dwm build options:
@echo "CFLAGS = ${CFLAGS}"
@echo "LDFLAGS = ${LDFLAGS}"
@echo "CC = ${CC}"
.c.o:
${CC} -c ${CFLAGS} $<
@ -76,4 +70,4 @@ uninstall:
${DESTDIR}${MANPREFIX}/man1/dwm.1\
${DESTDIR}${PREFIX}/share/xsessions/dwm.desktop
.PHONY: all options clean dist install uninstall
.PHONY: all clean dist install uninstall

View File

@ -1,4 +1,4 @@
This dwm 6.4 (e81f17d, 2023-04-09) side project has a different take on dwm patching. It uses preprocessor directives to decide whether or not to include a patch during build time. Essentially this means that this build, for better or worse, contains both the patched _and_ the original code. The aim being that you can select which patches to include and the build will contain that code and nothing more. Due to the complexity of some of the patches dwm-flexipatch has diverged from mainstream dwm by making some core patches non-optional for maintenance reasons. For the classic dwm-flexipatch build refer to branch [dwm-flexipatch-1.0](https://github.com/bakkeby/dwm-flexipatch/tree/dwm-flexipatch-1.0).
This dwm 6.4 (9f88553, 2023-09-22) side project has a different take on dwm patching. It uses preprocessor directives to decide whether or not to include a patch during build time. Essentially this means that this build, for better or worse, contains both the patched _and_ the original code. The aim being that you can select which patches to include and the build will contain that code and nothing more. Due to the complexity of some of the patches dwm-flexipatch has diverged from mainstream dwm by making some core patches non-optional for maintenance reasons. For the classic dwm-flexipatch build refer to branch [dwm-flexipatch-1.0](https://github.com/bakkeby/dwm-flexipatch/tree/dwm-flexipatch-1.0).
For example to include the `alpha` patch then you would only need to flip this setting from 0 to 1 in [patches.h](https://github.com/bakkeby/dwm-flexipatch/blob/master/patches.def.h):
```c
@ -19,6 +19,10 @@ Browsing patches? There is a [map of patches](https://coggle.it/diagram/X9IiSSM6
### Changelog:
2023-11-12 - Added the focusmaster-return patch variant
2023-06-27 - Added the focusfollowmouse and unmanaged patches
2023-06-25 - Added the toggletopbar patch
2023-01-18 - Added the view history patch
@ -433,9 +437,17 @@ Browsing patches? There is a [map of patches](https://coggle.it/diagram/X9IiSSM6
- allows focusing on clients based on direction (up, down, left, right) instead of client
order
- [focusfollowmouse](https://github.com/bakkeby/patches/wiki/focusfollowmouse)
- the window under the mouse cursor will receive focus when changing tags, closing windows or
moving client out of view (as opposed to the most recently focused client)
- [focusmaster](https://dwm.suckless.org/patches/focusmaster/)
- a simple patch that just puts focus back to the master client
- [focusmaster-return](https://dwm.suckless.org/patches/focusmaster/)
- a simple patch that just puts focus back to the master client
- additionally allows focus to be switched back to the previous client
- [focusonclick](https://dwm.suckless.org/patches/focusonclick/)
- this patch makes you switch focus only by mouse click and not sloppy (focus follows mouse
pointer)
@ -802,6 +814,10 @@ Browsing patches? There is a [map of patches](https://coggle.it/diagram/X9IiSSM6
- resets isfloating on any visible windows that have it set and optionally also applies a
layout
- [unmanaged](https://github.com/bakkeby/patches/wiki/unmanaged)
- adds a client rule that allows for windows to not be managed by the window manager
- this can be useful for external bars, widgets, launchers, docks, desktop icons and more
- [~urgentborder~](https://dwm.suckless.org/patches/urgentborder/)
- ~this patch makes "urgent" windows have different colors~

View File

@ -89,7 +89,9 @@
- [[#float-position][Float Position]]
- [[#focus-adjacent-tag][Focus Adjacent Tag]]
- [[#focus-direction][Focus Direction]]
- [[#focus-follow-mouse][Focus Follow Mouse]]
- [[#focus-master][Focus Master]]
- [[#focus-master-return][Focus Master Return]]
- [[#focus-on-click][Focus On Click]]
- [[#focus-urgent][Focus Urgent]]
- [[#focus-on-net-active][Focus On Net Active]]
@ -167,6 +169,7 @@
- [[#toggle-tag][Toggle Tag]]
- [[#transfer][Transfer]]
- [[#unfloat-visible][Unfloat Visible]]
- [[#unmanaged][Unmanaged]]
- [[#vanity-gaps][Vanity Gaps]]
- [[#view-history][View History]]
- [[#view-on-tag][View On Tag]]
@ -281,7 +284,7 @@ exec dwm
* dwm flexipatch
This dwm 6.4 (e81f17d, 2023-04-09) side project has a different take on dwm patching. It uses preprocessor directives to decide whether or not to include a patch during build time. Essentially this means that this build, for better or worse, contains both the patched _and_ the original code. The aim being that you can select which patches to include and the build will contain that code and nothing more. Due to the complexity of some of the patches dwm-flexipatch has diverged from mainstream dwm by making some core patches non-optional for maintenance reasons. For the classic dwm-flexipatch build refer to branch [[https://github.com/bakkeby/dwm-flexipatch/tree/dwm-flexipatch-1.0][dwm-flexipatch-1.0]].
This dwm 6.4 (9f88553, 2023-09-22) side project has a different take on dwm patching. It uses preprocessor directives to decide whether or not to include a patch during build time. Essentially this means that this build, for better or worse, contains both the patched _and_ the original code. The aim being that you can select which patches to include and the build will contain that code and nothing more. Due to the complexity of some of the patches dwm-flexipatch has diverged from mainstream dwm by making some core patches non-optional for maintenance reasons. For the classic dwm-flexipatch build refer to branch [[https://github.com/bakkeby/dwm-flexipatch/tree/dwm-flexipatch-1.0][dwm-flexipatch-1.0]].
For example to include the ~alpha~ patch then you would only need to flip this setting from 0 to 1 in [[https://github.com/bakkeby/dwm-flexipatch/blob/master/patches.def.h][patches.h]]:
@ -301,6 +304,10 @@ Browsing patches? There is a [[https://coggle.it/diagram/X9IiSSM6PTWOM9Wz][map o
** Changelog
2023-11-12 - Added the focusmaster-return patch variant
2023-06-27 - Added the focusfollowmouse and unmanaged patches
2023-06-25 - Added the toggletopbar patch
2023-01-18 - Added the view history patch
@ -684,9 +691,17 @@ Browsing patches? There is a [[https://coggle.it/diagram/X9IiSSM6PTWOM9Wz][map o
- [[https://github.com/bakkeby/patches/wiki/focusdir][focusdir]]
- allows focusing on clients based on direction (up, down, left, right) instead of client order
- [[https://github.com/bakkeby/patches/wiki/focusfollowmouse][focusfollowmouse]]
- the window under the mouse cursor will receive focus when changing tags, closing windows or
moving client out of view (as opposed to the most recently focused client)
- [[https://dwm.suckless.org/patches/focusmaster/][focusmaster]]
- a simple patch that just puts focus back to the master client
- [[https://dwm.suckless.org/patches/focusmaster/][focusmaster-return]]
- a simple patch that just puts focus back to the master client
- additionally allows focus to be switched back to the previous client
- [[https://dwm.suckless.org/patches/focusonclick/][focusonclick]]
- this patch makes you switch focus only by mouse click and not sloppy (focus follows mouse pointer)
@ -1007,6 +1022,10 @@ Browsing patches? There is a [[https://coggle.it/diagram/X9IiSSM6PTWOM9Wz][map o
- [[https://dwm.suckless.org/patches/unfloatvisible/][unfloatvisible]]
- resets isfloating on any visible windows that have it set and optionally also applies a layout
- [[https://github.com/bakkeby/patches/wiki/unmanaged][unmanaged]]
- adds a client rule that allows for windows to not be managed by the window manager
- this can be useful for external bars, widgets, launchers, docks, desktop icons and more
- +[[https://dwm.suckless.org/patches/urgentborder/][urgentborder]]+
- +this patch makes "urgent" windows have different colors+
@ -2087,6 +2106,17 @@ https://github.com/bakkeby/patches/wiki/focusdir/
#define FOCUSDIR_PATCH 0
#+END_SRC
*** Focus Follow Mouse
When changing tags, closing windows or moving clients out of view then focus will revert to the
client window that remains under the mouse cursor rather than the most recently focused window.
https://github.com/bakkeby/patches/wiki/focusfollowmouse
#+BEGIN_SRC c :tangle patches.def.h
#define FOCUSFOLLOWMOUSE_PATCH 0
#+END_SRC
*** Focus Master
A simple patch that just puts focus back to the master client.
@ -2097,6 +2127,17 @@ https://dwm.suckless.org/patches/focusmaster/
#define FOCUSMASTER_PATCH 0
#+END_SRC
*** Focus Master Return
A variant of the focusmaster patch that additionally allows the focus to be returned to the
previously focused client
https://dwm.suckless.org/patches/focusmaster/
#+BEGIN_SRC c :tangle patches.def.h
#define FOCUSMASTER_RETURN_PATCH 0
#+END_SRC
*** Focus On Click
Switch focus only by mouse click and not sloppy (focus follows mouse pointer).
@ -3107,6 +3148,18 @@ https://dwm.suckless.org/patches/unfloatvisible/
#define UNFLOATVISIBLE_PATCH 1
#+END_SRC
*** Unmanaged
This patch adds a client rule that allows for windows that do not specify the override-redirect
to not be managed by the window manager. This can be useful for external bars, widgets,
launchers, docks, desktop icons and more.
https://github.com/bakkeby/patches/wiki/unmanaged
#+BEGIN_SRC c :tangle patches.def.h
#define UNMANAGED_PATCH 0
#+END_SRC
*** Vanity Gaps
**** Main
@ -3446,8 +3499,8 @@ XCBLIBS = -lX11-xcb -lxcb -lxcb-res
#IMLIB2LIBS = -lImlib2
# Uncomment for the bidi patch
#BDINC = -I/usr/include/fribidi
#BDLIBS = -lfribidi
#BDINC = `pkg-config --cflags fribidi`
#BDLIBS = `pkg-config --libs fribidi`
# includes and libs
INCS = -I${X11INC} -I${FREETYPEINC} ${YAJLINC} ${PANGOINC} ${BDINC}
@ -3480,17 +3533,11 @@ OBJ = ${SRC:.c=.o}
# FreeBSD users, prefix all ifdef, else and endif statements with a . for this to work (e.g. .ifdef)
ifdef YAJLLIBS
all: options dwm dwm-msg
all: dwm dwm-msg
else
all: options dwm
all: dwm
endif
options:
@echo dwm build options:
@echo "CFLAGS = ${CFLAGS}"
@echo "LDFLAGS = ${LDFLAGS}"
@echo "CC = ${CC}"
.c.o:
${CC} -c ${CFLAGS} $<
@ -3547,7 +3594,7 @@ uninstall:
${DESTDIR}${MANPREFIX}/man1/dwm.1\
${DESTDIR}${PREFIX}/share/xsessions/dwm.desktop
.PHONY: all options clean dist install uninstall
.PHONY: all clean dist install uninstall
#+END_SRC
* DWM Configuration
@ -3563,6 +3610,15 @@ static const unsigned int borderpx = 2; /* border pixel of windows */
#endif // ROUNDED_CORNERS_PATCH
#+END_SRC
#+BEGIN_SRC c :tangle config.def.h
#if BAR_BORDER_PATCH
/* This allows the bar border size to be explicitly set separately from borderpx.
* If left as 0 then it will default to the borderpx value of the monitor and will
* automatically update with setborderpx. */
static const unsigned int barborderpx = 0; /* border pixel of bar */
#endif // BAR_BORDER_PATCH
#+END_SRC
#+BEGIN_SRC c :tangle config.def.h
static const unsigned int snap = 10; /* snap pixel */
#+END_SRC
@ -4280,13 +4336,13 @@ static const BarRule barrules[] = {
{ -1, 0, BAR_ALIGN_LEFT, width_stbutton, draw_stbutton, click_stbutton, NULL, "statusbutton" },
#endif // BAR_STATUSBUTTON_PATCH
#if BAR_POWERLINE_TAGS_PATCH
{ 0, 0, BAR_ALIGN_LEFT, width_pwrl_tags, draw_pwrl_tags, click_pwrl_tags, NULL, "powerline_tags" },
{ 0, 0, BAR_ALIGN_LEFT, width_pwrl_tags, draw_pwrl_tags, click_pwrl_tags, hover_pwrl_tags, "powerline_tags" },
#endif // BAR_POWERLINE_TAGS_PATCH
#if BAR_TAGS_PATCH
{ -1, 0, BAR_ALIGN_LEFT, width_tags, draw_tags, click_tags, hover_tags, "tags" },
#endif // BAR_TAGS_PATCH
#if BAR_TAGLABELS_PATCH
{ -1, 0, BAR_ALIGN_LEFT, width_taglabels, draw_taglabels, click_taglabels, NULL, "taglabels" },
{ -1, 0, BAR_ALIGN_LEFT, width_taglabels, draw_taglabels, click_taglabels, hover_taglabels, "taglabels" },
#endif // BAR_TAGLABELS_PATCH
#if BAR_TAGGRID_PATCH
{ -1, 0, BAR_ALIGN_LEFT, width_taggrid, draw_taggrid, click_taggrid, NULL, "taggrid" },
@ -4736,9 +4792,9 @@ static const Key keys[] = {
{ MODKEY|ControlMask, XK_b, tabmode, {-1} },
#endif // TAB_PATCH
#if FOCUSMASTER_PATCH
#if FOCUSMASTER_PATCH || FOCUSMASTER_RETURN_PATCH
{ MODKEY|ControlMask, XK_space, focusmaster, {0} },
#endif // FOCUSMASTER_PATCH
#endif // FOCUSMASTER_PATCH / FOCUSMASTER_RETURN_PATCH
#if STACKER_PATCH
STACKKEYS(MODKEY, focus)

View File

@ -5,6 +5,13 @@ static const int corner_radius = 10;
static const unsigned int borderpx = 2; /* border pixel of windows */
#endif // ROUNDED_CORNERS_PATCH
#if BAR_BORDER_PATCH
/* This allows the bar border size to be explicitly set separately from borderpx.
* If left as 0 then it will default to the borderpx value of the monitor and will
* automatically update with setborderpx. */
static const unsigned int barborderpx = 0; /* border pixel of bar */
#endif // BAR_BORDER_PATCH
static const unsigned int snap = 10; /* snap pixel */
#if SWALLOW_PATCH
@ -529,13 +536,13 @@ static const BarRule barrules[] = {
{ -1, 0, BAR_ALIGN_LEFT, width_stbutton, draw_stbutton, click_stbutton, NULL, "statusbutton" },
#endif // BAR_STATUSBUTTON_PATCH
#if BAR_POWERLINE_TAGS_PATCH
{ 0, 0, BAR_ALIGN_LEFT, width_pwrl_tags, draw_pwrl_tags, click_pwrl_tags, NULL, "powerline_tags" },
{ 0, 0, BAR_ALIGN_LEFT, width_pwrl_tags, draw_pwrl_tags, click_pwrl_tags, hover_pwrl_tags, "powerline_tags" },
#endif // BAR_POWERLINE_TAGS_PATCH
#if BAR_TAGS_PATCH
{ -1, 0, BAR_ALIGN_LEFT, width_tags, draw_tags, click_tags, hover_tags, "tags" },
#endif // BAR_TAGS_PATCH
#if BAR_TAGLABELS_PATCH
{ -1, 0, BAR_ALIGN_LEFT, width_taglabels, draw_taglabels, click_taglabels, NULL, "taglabels" },
{ -1, 0, BAR_ALIGN_LEFT, width_taglabels, draw_taglabels, click_taglabels, hover_taglabels, "taglabels" },
#endif // BAR_TAGLABELS_PATCH
#if BAR_TAGGRID_PATCH
{ -1, 0, BAR_ALIGN_LEFT, width_taggrid, draw_taggrid, click_taggrid, NULL, "taggrid" },
@ -945,9 +952,9 @@ static const Key keys[] = {
{ MODKEY|ControlMask, XK_b, tabmode, {-1} },
#endif // TAB_PATCH
#if FOCUSMASTER_PATCH
#if FOCUSMASTER_PATCH || FOCUSMASTER_RETURN_PATCH
{ MODKEY|ControlMask, XK_space, focusmaster, {0} },
#endif // FOCUSMASTER_PATCH
#endif // FOCUSMASTER_PATCH / FOCUSMASTER_RETURN_PATCH
#if STACKER_PATCH
STACKKEYS(MODKEY, focus)

View File

@ -52,8 +52,8 @@ XCBLIBS = -lX11-xcb -lxcb -lxcb-res
#IMLIB2LIBS = -lImlib2
# Uncomment for the bidi patch
#BDINC = -I/usr/include/fribidi
#BDLIBS = -lfribidi
#BDINC = `pkg-config --cflags fribidi`
#BDLIBS = `pkg-config --libs fribidi`
# includes and libs
INCS = -I${X11INC} -I${FREETYPEINC} ${YAJLINC} ${PANGOINC} ${BDINC}

112
dwm.c
View File

@ -484,7 +484,7 @@ struct Monitor {
int gappov; /* vertical outer gaps */
#endif // VANITYGAPS_PATCH
#if SETBORDERPX_PATCH
unsigned int borderpx;
int borderpx;
#endif // SETBORDERPX_PATCH
unsigned int seltags;
unsigned int sellt;
@ -504,6 +504,9 @@ struct Monitor {
Client *clients;
Client *sel;
Client *stack;
#if FOCUSMASTER_RETURN_PATCH
Client *tagmarked[32];
#endif // FOCUSMASTER_RETURN_PATCH
Monitor *next;
Bar *bar;
const Layout *lt[2];
@ -568,6 +571,9 @@ typedef struct {
#if RENAMED_SCRATCHPADS_PATCH
const char scratchkey;
#endif // RENAMED_SCRATCHPADS_PATCH
#if UNMANAGED_PATCH
int unmanaged;
#endif // UNMANAGED_PATCH
#if XKB_PATCH
int xkb_layout;
#endif // XKB_PATCH
@ -676,9 +682,7 @@ static void killclient(const Arg *arg);
static void manage(Window w, XWindowAttributes *wa);
static void mappingnotify(XEvent *e);
static void maprequest(XEvent *e);
#if !FOCUSONCLICK_PATCH
static void motionnotify(XEvent *e);
#endif // FOCUSONCLICK_PATCH
static void movemouse(const Arg *arg);
static Client *nexttiled(Client *c);
#if !ZOOMSWAP_PATCH || TAGINTOSTACK_ALLMASTER_PATCH || TAGINTOSTACK_ONEMASTER_PATCH
@ -775,6 +779,9 @@ static int xkbEventType = 0;
static int screen;
static int sw, sh; /* X display screen geometry width, height */
static int bh; /* bar geometry */
#if UNMANAGED_PATCH
static int unmanaged = 0; /* whether the window manager should manage the new window or not */
#endif // UNMANAGED_PATCH
static int lrpad; /* sum of left and right padding for text */
/* Some clients (e.g. alacritty) helpfully send configure requests with a new size or position
* when they detect that they have been moved to another monitor. This can cause visual glitches
@ -811,9 +818,7 @@ static void (*handler[LASTEvent]) (XEvent *) = {
#endif // COMBO_PATCH / BAR_HOLDBAR_PATCH
[MappingNotify] = mappingnotify,
[MapRequest] = maprequest,
#if !FOCUSONCLICK_PATCH
[MotionNotify] = motionnotify,
#endif // FOCUSONCLICK_PATCH
[PropertyNotify] = propertynotify,
#if BAR_SYSTRAY_PATCH
[ResizeRequest] = resizerequest,
@ -932,6 +937,9 @@ applyrules(Client *c)
c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2);
}
#endif // SCRATCHPADS_PATCH
#if UNMANAGED_PATCH
unmanaged = r->unmanaged;
#endif // UNMANAGED_PATCH
for (m = mons; m && m->num != r->monitor; m = m->next);
if (m)
c->mon = m;
@ -1489,8 +1497,8 @@ configurenotify(XEvent *e)
createpreview(m);
#endif // BAR_TAGPREVIEW_PATCH
}
focus(NULL);
arrange(NULL);
focus(NULL);
}
}
}
@ -1676,7 +1684,7 @@ createmon(void)
bar->showbar = 1;
bar->external = 0;
#if BAR_BORDER_PATCH
bar->borderpx = borderpx;
bar->borderpx = (barborderpx ? barborderpx : borderpx);
#else
bar->borderpx = 0;
#endif // BAR_BORDER_PATCH
@ -1813,6 +1821,11 @@ detach(Client *c)
#if SEAMLESS_RESTART_PATCH
c->idx = 0;
#endif // SEAMLESS_RESTART_PATCH
#if FOCUSMASTER_RETURN_PATCH
for (int i = 1; i < NUMTAGS; i++)
if (c == c->mon->tagmarked[i])
c->mon->tagmarked[i] = NULL;
#endif // FOCUSMASTER_RETURN_PATCH
for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next);
*tc = c->next;
@ -2037,6 +2050,14 @@ expose(XEvent *e)
void
focus(Client *c)
{
#if FOCUSFOLLOWMOUSE_PATCH
if (!c || !ISVISIBLE(c))
c = getpointerclient();
#endif // FOCUSFOLLOWMOUSE_PATCH
#if STICKY_PATCH
if (!c || !ISVISIBLE(c))
for (c = selmon->stack; c && (!ISVISIBLE(c) || c->issticky); c = c->snext);
#endif // STICKY_PATCH
if (!c || !ISVISIBLE(c))
for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext);
if (selmon->sel && selmon->sel != c)
@ -2498,6 +2519,29 @@ manage(Window w, XWindowAttributes *wa)
#endif // SWALLOW_PATCH
}
#if UNMANAGED_PATCH
if (unmanaged) {
XMapWindow(dpy, c->win);
if (unmanaged == 1)
XRaiseWindow(dpy, c->win);
else if (unmanaged == 2)
XLowerWindow(dpy, c->win);
updatewmhints(c);
if (!c->neverfocus)
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
#if BAR_SYSTRAY_PATCH
sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0);
#else
sendevent(c, wmatom[WMTakeFocus]);
#endif // BAR_SYSTRAY_PATCH
free(c);
unmanaged = 0;
return;
}
#endif // UNMANAGED_PATCH
if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww)
c->x = c->mon->wx + c->mon->ww - WIDTH(c);
if (c->y + HEIGHT(c) > c->mon->wy + c->mon->wh)
@ -2666,16 +2710,17 @@ maprequest(XEvent *e)
manage(ev->window, &wa);
}
#if !FOCUSONCLICK_PATCH
void
motionnotify(XEvent *e)
{
#if !FOCUSONCLICK_PATCH
static Monitor *mon = NULL;
Monitor *m;
Bar *bar;
#if LOSEFULLSCREEN_PATCH
Client *sel;
#endif // LOSEFULLSCREEN_PATCH
#endif // FOCUSONCLICK_PATCH
Bar *bar;
XMotionEvent *ev = &e->xmotion;
if ((bar = wintobar(ev->window))) {
@ -2688,6 +2733,7 @@ motionnotify(XEvent *e)
hidetagpreview(selmon);
#endif // BAR_TAGPREVIEW_PATCH
#if !FOCUSONCLICK_PATCH
if (ev->window != root)
return;
if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) {
@ -2702,8 +2748,8 @@ motionnotify(XEvent *e)
focus(NULL);
}
mon = m;
#endif // FOCUSONCLICK_PATCH
}
#endif // FOCUSONCLICK_PATCH
void
movemouse(const Arg *arg)
@ -2808,6 +2854,13 @@ nexttiled(Client *c)
void
pop(Client *c)
{
#if FOCUSMASTER_RETURN_PATCH
int i;
for (i = 0; !(selmon->tagset[selmon->seltags] & 1 << i); i++);
i++;
c->mon->tagmarked[i] = nexttiled(c->mon->clients);
#endif // FOCUSMASTER_RETURN_PATCH
detach(c);
attach(c);
focus(c);
@ -3347,11 +3400,12 @@ sendmon(Client *c, Monitor *m)
if (hadfocus) {
focus(c);
restack(m);
} else
} else {
focus(NULL);
}
#else
focus(NULL);
arrange(NULL);
focus(NULL);
#endif // EXRESIZE_PATCH / SENDMON_KEEPFOCUS_PATCH
#if SWITCHTAG_PATCH
if (c->switchtag)
@ -4074,6 +4128,7 @@ tag(const Arg *arg)
if (selmon->sel->switchtag)
selmon->sel->switchtag = 0;
#endif // SWITCHTAG_PATCH
arrange(selmon);
focus(NULL);
#if SWAPFOCUS_PATCH && PERTAG_PATCH
selmon->pertag->prevclient[selmon->pertag->curtag] = NULL;
@ -4081,7 +4136,6 @@ tag(const Arg *arg)
if (tagmask & 1)
selmon->pertag->prevclient[tagindex] = NULL;
#endif // SWAPFOCUS_PATCH
arrange(selmon);
#if VIEWONTAG_PATCH
if ((arg->ui & TAGMASK) != selmon->tagset[selmon->seltags])
view(arg);
@ -4213,13 +4267,13 @@ toggletag(const Arg *arg)
newtags = selmon->sel->tags ^ (arg->ui & TAGMASK);
if (newtags) {
selmon->sel->tags = newtags;
arrange(selmon);
focus(NULL);
#if SWAPFOCUS_PATCH && PERTAG_PATCH
for (tagmask = arg->ui & TAGMASK, tagindex = 1; tagmask!=0; tagmask >>= 1, tagindex++)
if (tagmask & 1)
selmon->pertag->prevclient[tagindex] = NULL;
#endif // SWAPFOCUS_PATCH
arrange(selmon);
}
#if BAR_EWMHTAGS_PATCH
updatecurrentdesktop();
@ -4306,8 +4360,8 @@ toggleview(const Arg *arg)
#endif // PERTAGBAR_PATCH
#endif // PERTAG_PATCH
#if !TAGSYNC_PATCH
focus(NULL);
arrange(selmon);
focus(NULL);
#endif // TAGSYNC_PATCH
#if !EMPTYVIEW_PATCH
}
@ -4318,8 +4372,8 @@ toggleview(const Arg *arg)
#if !EMPTYVIEW_PATCH
if (newtagset) {
#endif // EMPTYVIEW_PATCH
focus(NULL);
arrange(NULL);
focus(NULL);
#if !EMPTYVIEW_PATCH
}
#endif // EMPTYVIEW_PATCH
@ -4338,13 +4392,24 @@ unfocus(Client *c, int setfocus, Client *nextfocus)
selmon->pertag->prevclient[selmon->pertag->curtag] = c;
#endif // SWAPFOCUS_PATCH
#if LOSEFULLSCREEN_PATCH
if (c->isfullscreen && ISVISIBLE(c) && c->mon == selmon && nextfocus && !nextfocus->isfloating)
if (c->isfullscreen && ISVISIBLE(c) && c->mon == selmon && nextfocus && !nextfocus->isfloating) {
#if RENAMED_SCRATCHPADS_PATCH && RENAMED_SCRATCHPADS_AUTO_HIDE_PATCH
#if FAKEFULLSCREEN_CLIENT_PATCH
if (c->scratchkey != 0 && c->fakefullscreen != 1)
togglescratch(&((Arg) {.v = (const char*[]){ &c->scratchkey, NULL } }));
#else
if (c->scratchkey != 0)
togglescratch(&((Arg) {.v = (const char*[]){ &c->scratchkey, NULL } }));
#endif // FAKEFULLSCREEN_CLIENT_PATCH
else
#endif // RENAMED_SCRATCHPADS_AUTO_HIDE_PATCH
#if FAKEFULLSCREEN_CLIENT_PATCH
if (c->fakefullscreen != 1)
setfullscreen(c, 0);
#else
setfullscreen(c, 0);
#endif // #if FAKEFULLSCREEN_CLIENT_PATCH
}
#endif // LOSEFULLSCREEN_PATCH
grabbuttons(c, 0);
#if !BAR_FLEXWINTITLE_PATCH
@ -4456,9 +4521,9 @@ unmanage(Client *c, int destroyed)
if (s)
return;
#endif // SWALLOW_PATCH
arrange(m);
focus(NULL);
updateclientlist();
arrange(m);
#if SWITCHTAG_PATCH
if (switchtag && ((switchtag & TAGMASK) != selmon->tagset[selmon->seltags]))
view(&((Arg) { .ui = switchtag }));
@ -4953,12 +5018,12 @@ view(const Arg *arg)
}
selmon = origselmon;
#endif // TAGSYNC_PATCH
focus(NULL);
#if TAGSYNC_PATCH
arrange(NULL);
#else
arrange(selmon);
#endif // TAGSYNC_PATCH
focus(NULL);
#if BAR_EWMHTAGS_PATCH
updatecurrentdesktop();
#endif // BAR_EWMHTAGS_PATCH
@ -5036,6 +5101,9 @@ void
zoom(const Arg *arg)
{
Client *c = selmon->sel;
#if FOCUSMASTER_RETURN_PATCH && ZOOMSWAP_PATCH
int i;
#endif // FOCUSMASTER_RETURN_PATCH
if (arg && arg->v)
c = (Client*)arg->v;
if (!c)
@ -5089,6 +5157,12 @@ zoom(const Arg *arg)
cold = nexttiled(c->mon->clients);
if (c != cold && !at)
at = findbefore(c);
#if FOCUSMASTER_RETURN_PATCH
for (i = 0; !(selmon->tagset[selmon->seltags] & 1 << i); i++);
i++;
c->mon->tagmarked[i] = cold;
#endif // FOCUSMASTER_RETURN_PATCH
detach(c);
attach(c);
/* swap windows instead of pushing the previous one down */

View File

@ -9,7 +9,7 @@ layoutmenu(const Arg *arg) {
s = fgets(c, sizeof(c), p);
pclose(p);
if (!s || *s == '\0' || c == '\0')
if (!s || *s == '\0' || c[0] == '\0')
return;
i = atoi(c);

View File

@ -105,3 +105,57 @@ click_pwrl_tags(Bar *bar, Arg *arg, BarArg *a)
return ClkTagBar;
}
int
hover_pwrl_tags(Bar *bar, BarArg *a, XMotionEvent *ev)
{
#if BAR_TAGPREVIEW_PATCH
int i = 0, x = lrpad / 2;
int px, py;
int plw = drw->fonts->h / 2 + 1;
Monitor *m = bar->mon;
#if VANITYGAPS_PATCH
int ov = gappov;
int oh = gappoh;
#else
int ov = 0;
int oh = 0;
#endif // VANITYGAPS_PATCH
#if BAR_HIDEVACANTTAGS_PATCH
Client *c;
unsigned int occ = 0;
for (c = bar->mon->clients; c; c = c->next)
occ |= c->tags == 255 ? 0 : c->tags;
#endif // BAR_HIDEVACANTTAGS_PATCH
do {
#if BAR_HIDEVACANTTAGS_PATCH
if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i))
continue;
#endif // BAR_HIDEVACANTTAGS_PATCH
x += TEXTW(tagicon(bar->mon, i)) + plw;
} while (a->x >= x && ++i < NUMTAGS);
if (i < NUMTAGS) {
if ((i + 1) != selmon->previewshow && !(selmon->tagset[selmon->seltags] & 1 << i)) {
if (bar->by > m->my + m->mh / 2) // bottom bar
py = bar->by - m->mh / scalepreview - oh;
else // top bar
py = bar->by + bar->bh + oh;
px = bar->bx + ev->x - m->mw / scalepreview / 2;
if (px + m->mw / scalepreview > m->mx + m->mw)
px = m->wx + m->ww - m->mw / scalepreview - ov;
else if (px < bar->bx)
px = m->wx + ov;
selmon->previewshow = i + 1;
showtagpreview(i, px, py);
} else if (selmon->tagset[selmon->seltags] & 1 << i) {
hidetagpreview(selmon);
}
} else if (selmon->previewshow != 0) {
hidetagpreview(selmon);
}
#endif // BAR_TAGPREVIEW_PATCH
return 1;
}

View File

@ -1,4 +1,4 @@
static int width_pwrl_tags(Bar *bar, BarArg *a);
static int draw_pwrl_tags(Bar *bar, BarArg *a);
static int click_pwrl_tags(Bar *bar, Arg *arg, BarArg *a);
static int hover_pwrl_tags(Bar *bar, BarArg *a, XMotionEvent *ev);

View File

@ -89,3 +89,48 @@ click_taglabels(Bar *bar, Arg *arg, BarArg *a)
}
return ClkTagBar;
}
int
hover_taglabels(Bar *bar, BarArg *a, XMotionEvent *ev)
{
#if BAR_TAGPREVIEW_PATCH
int i = 0, x = lrpad / 2;
int px, py;
Monitor *m = bar->mon;
#if VANITYGAPS_PATCH
int ov = gappov;
int oh = gappoh;
#else
int ov = 0;
int oh = 0;
#endif // VANITYGAPS_PATCH
do {
if (!m->taglabel[i][0])
continue;
x += TEXTW(m->taglabel[i]);
} while (a->x >= x && ++i < NUMTAGS);
if (i < NUMTAGS) {
if ((i + 1) != selmon->previewshow && !(selmon->tagset[selmon->seltags] & 1 << i)) {
if (bar->by > m->my + m->mh / 2) // bottom bar
py = bar->by - m->mh / scalepreview - oh;
else // top bar
py = bar->by + bar->bh + oh;
px = bar->bx + ev->x - m->mw / scalepreview / 2;
if (px + m->mw / scalepreview > m->mx + m->mw)
px = m->wx + m->ww - m->mw / scalepreview - ov;
else if (px < bar->bx)
px = m->wx + ov;
selmon->previewshow = i + 1;
showtagpreview(i, px, py);
} else if (selmon->tagset[selmon->seltags] & 1 << i) {
hidetagpreview(selmon);
}
} else if (selmon->previewshow != 0) {
hidetagpreview(selmon);
}
#endif // BAR_TAGPREVIEW_PATCH
return 1;
}

View File

@ -2,4 +2,5 @@
static int width_taglabels(Bar *bar, BarArg *a);
static int draw_taglabels(Bar *bar, BarArg *a);
static int click_taglabels(Bar *bar, Arg *arg, BarArg *a);
static int click_taglabels(Bar *bar, Arg *arg, BarArg *a);
static int hover_taglabels(Bar *bar, BarArg *a, XMotionEvent *ev);

View File

@ -51,7 +51,7 @@ togglewin(const Arg *arg)
Client *c = (Client*)arg->v;
if (!c)
return;
if (c == selmon->sel)
if (!HIDDEN(c) && c == selmon->sel)
hide(c);
else {
if (HIDDEN(c))

View File

@ -22,8 +22,8 @@ combotag(const Arg *arg)
combo = 1;
selmon->sel->tags = arg->ui & TAGMASK;
}
focus(NULL);
arrange(selmon);
focus(NULL);
}
}

View File

@ -22,10 +22,10 @@ distributetags(const Arg *arg)
#if TAGSYNC_PATCH
}
selmon = origselmon;
focus(NULL);
arrange(NULL);
#else
focus(NULL);
#else
arrange(selmon);
focus(NULL);
#endif // TAGSYNC_PATCH
}

View File

@ -6,8 +6,8 @@ tagtoleft(const Arg *arg)
&& __builtin_popcount(selmon->tagset[selmon->seltags] & MASK) == 1
&& selmon->tagset[selmon->seltags] > 1) {
selmon->sel->tags >>= 1;
focus(NULL);
arrange(selmon);
focus(NULL);
}
}
@ -19,8 +19,8 @@ tagtoright(const Arg *arg)
&& __builtin_popcount(selmon->tagset[selmon->seltags] & MASK) == 1
&& selmon->tagset[selmon->seltags] & (MASK >> 1)) {
selmon->sel->tags <<= 1;
focus(NULL);
arrange(selmon);
focus(NULL);
}
}

9
patch/focusfollowmouse.c Normal file
View File

@ -0,0 +1,9 @@
Client *
getpointerclient(void)
{
Window dummy, win;
int di;
unsigned int dui;
XQueryPointer(dpy, root, &dummy, &win, &di, &di, &di, &di, &dui);
return wintoclient(win);
}

1
patch/focusfollowmouse.h Normal file
View File

@ -0,0 +1 @@
static Client *getpointerclient(void);

View File

@ -1,14 +1,41 @@
void
focusmaster(const Arg *arg)
{
Client *c;
Client *master;
Monitor *m = selmon;
#if FOCUSMASTER_RETURN_PATCH
int i;
#endif // FOCUSMASTER_RETURN_PATCH
if (selmon->nmaster < 1)
if (m->nmaster < 1)
return;
#if !FAKEFULLSCREEN_PATCH
#if FAKEFULLSCREEN_CLIENT_PATCH
if (!m->sel || (m->sel->isfullscreen && m->sel->fakefullscreen != 1 && lockfullscreen))
return;
#else
if (!m->sel || (m->sel->isfullscreen && lockfullscreen))
return;
#endif // FAKEFULLSCREEN_CLIENT_PATCH
#endif // FAKEFULLSCREEN_PATCH
master = nexttiled(m->clients);
if (!master)
return;
c = nexttiled(selmon->clients);
#if FOCUSMASTER_RETURN_PATCH
for (i = 0; !(m->tagset[m->seltags] & 1 << i); i++);
i++;
if (c)
focus(c);
if (m->sel == master) {
if (m->tagmarked[i] && ISVISIBLE(m->tagmarked[i]))
focus(m->tagmarked[i]);
} else {
m->tagmarked[i] = m->sel;
focus(master);
}
#else
focus(master);
#endif // FOCUSMASTER_RETURN_PATCH
}

View File

@ -151,7 +151,10 @@
#if FOCUSDIR_PATCH
#include "focusdir.c"
#endif
#if FOCUSMASTER_PATCH
#if FOCUSFOLLOWMOUSE_PATCH
#include "focusfollowmouse.c"
#endif
#if FOCUSMASTER_PATCH || FOCUSMASTER_RETURN_PATCH
#include "focusmaster.c"
#endif
#if FOCUSURGENT_PATCH

View File

@ -154,7 +154,10 @@
#if FOCUSADJACENTTAG_PATCH
#include "focusadjacenttag.h"
#endif
#if FOCUSMASTER_PATCH
#if FOCUSFOLLOWMOUSE_PATCH
#include "focusfollowmouse.h"
#endif
#if FOCUSMASTER_PATCH || FOCUSMASTER_RETURN_PATCH
#include "focusmaster.h"
#endif
#if FOCUSURGENT_PATCH

View File

@ -643,7 +643,7 @@ arrange_tatami(Monitor *m, int x, int y, int h, int w, int ih, int iv, int n, in
if (j < ai + cats) {
/* Arrange cats (all excess clients that can't be tiled as mats). Cats sleep on mats. */
switch (cats) {
switch (cats) {
case 1: // fill
break;
case 2: // up and down

View File

@ -66,12 +66,13 @@ togglescratch(const Arg *arg)
if (c->scratchkey != ((char**)arg->v)[0][0])
continue;
/* awesomebar / wintitleactions compatibility, unhide scratchpad if hidden
#if BAR_WINTITLEACTIONS_PATCH
/* unhide scratchpad if hidden */
if (HIDDEN(c)) {
XMapWindow(dpy, c->win);
setclientstate(c, NormalState);
}
*/
#endif // BAR_WINTITLEACTIONS_PATCH
/* Record the first found scratchpad client for focus purposes, but prioritise the
scratchpad on the current monitor if one exists */

View File

@ -62,8 +62,8 @@ togglescratch(const Arg *arg)
if (found) {
if (newtagset) {
selmon->tagset[selmon->seltags] = newtagset;
focus(NULL);
arrange(selmon);
focus(NULL);
}
if (ISVISIBLE(found)) {
focus(found);

View File

@ -6,8 +6,8 @@ scratchpad_hide()
if (selmon->sel) {
selmon->sel->tags = SCRATCHPAD_MASK;
selmon->sel->isfloating = 1;
focus(NULL);
arrange(selmon);
focus(NULL);
}
}
@ -36,8 +36,8 @@ scratchpad_show()
if (scratchpad_last_showed->tags != SCRATCHPAD_MASK) {
scratchpad_last_showed->tags = SCRATCHPAD_MASK;
focus(NULL);
arrange(selmon);
focus(NULL);
return;
}

View File

@ -15,13 +15,15 @@ setborderpx(const Arg *arg)
int delta = 2 * (m->borderpx - prev_borderpx);
#if BAR_BORDER_PATCH
for (bar = m->bar; bar; bar = bar->next) {
bar->bh = bar->bh - 2 * bar->borderpx + 2 * m->borderpx;
bar->borderpx = m->borderpx;
if (!barborderpx) {
for (bar = m->bar; bar; bar = bar->next) {
bar->bh = bar->bh - 2 * bar->borderpx + 2 * m->borderpx;
bar->borderpx = m->borderpx;
}
updatebarpos(m);
for (bar = m->bar; bar; bar = bar->next)
XMoveResizeWindow(dpy, bar->win, bar->bx, bar->by, bar->bw, bar->bh);
}
updatebarpos(m);
for (bar = m->bar; bar; bar = bar->next)
XMoveResizeWindow(dpy, bar->win, bar->bx, bar->by, bar->bw, bar->bh);
#endif // BAR_BORDER_PATCH
for (c = m->clients; c; c = c->next) {

View File

@ -6,7 +6,7 @@ shift(const Arg *arg, int clients)
unsigned int tagmask = 0;
#if SCRATCHPADS_PATCH && !RENAMED_SCRATCHPADS_PATCH
shifted.ui = selmon->tagset[selmon->seltags];
shifted.ui = selmon->tagset[selmon->seltags] & ~SPTAGMASK;
#else
shifted.ui = selmon->tagset[selmon->seltags];
#endif // SCRATCHPADS_PATCH
@ -18,6 +18,10 @@ shift(const Arg *arg, int clients)
for (c = selmon->clients; c && clients; c = c->next) {
if (c == selmon->sel)
continue;
#if STICKY_PATCH
if (c->issticky)
continue;
#endif // STICKY_PATCH
#if SCRATCHPADS_PATCH && !RENAMED_SCRATCHPADS_PATCH
if (!(c->tags & SPTAGMASK))
tagmask |= c->tags;

View File

@ -91,8 +91,8 @@ unswallow(Client *c)
setfloatinghint(c);
#endif // BAR_EWMHTAGS_PATCH
setclientstate(c, NormalState);
focus(NULL);
arrange(c->mon);
focus(NULL);
}
pid_t

View File

@ -43,7 +43,7 @@ tagallmon(const Arg *arg)
}
}
focus(NULL);
arrange(NULL);
focus(NULL);
}

View File

@ -37,8 +37,8 @@ tagothermon(const Arg *arg, int dir)
sendmon(sel, newmon);
if (arg->ui & TAGMASK) {
sel->tags = arg->ui & TAGMASK;
focus(NULL);
arrange(newmon);
focus(NULL);
}
}

View File

@ -69,7 +69,7 @@ tagswapmon(const Arg *arg)
}
}
focus(NULL);
arrange(NULL);
focus(NULL);
}

View File

@ -10,8 +10,15 @@ resizemousescroll(const Arg *arg)
if (!(c = selmon->sel))
return;
#if !FAKEFULLSCREEN_PATCH
#if FAKEFULLSCREEN_CLIENT_PATCH
if (c->isfullscreen && c->fakefullscreen != 1) /* no support resizing fullscreen windows by mouse */
return;
#else
if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */
return;
#endif // FAKEFULLSCREEN_CLIENT_PATCH
#endif // !FAKEFULLSCREEN_PATCH
restack(selmon);
if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess)

View File

@ -132,7 +132,6 @@ xrdb(const Arg *arg)
#endif // BAR_ALPHA_PATCH
ColCount
);
focus(NULL);
arrange(NULL);
focus(NULL);
}

View File

@ -167,8 +167,12 @@
#define FOCUSDIR_PATCH 0
#define FOCUSFOLLOWMOUSE_PATCH 0
#define FOCUSMASTER_PATCH 0
#define FOCUSMASTER_RETURN_PATCH 0
#define FOCUSONCLICK_PATCH 0
#define FOCUSURGENT_PATCH 0
@ -345,6 +349,8 @@
#define UNFLOATVISIBLE_PATCH 1
#define UNMANAGED_PATCH 0
#define VANITYGAPS_PATCH 1
#define VANITYGAPS_MONOCLE_PATCH 0