Compare commits

...

13 Commits

Author SHA1 Message Date
Sravan Balaji
d29062d6bf Change vanitygaps modifier key from super to alt (since modkey was changed from alt to super) 2024-09-18 19:38:16 -04:00
Sravan Balaji
9bf05adb20 Add vanitygaps patch 2024-09-16 00:23:18 -04:00
Sravan Balaji
f8891c39f1 Add restore-monitor patch 2024-09-16 00:03:25 -04:00
Sravan Balaji
4d81408e32 Add warpcursor patch 2024-09-15 23:57:13 -04:00
Sravan Balaji
1b106aea12 Add attachtop patch 2024-09-15 23:53:14 -04:00
Sravan Balaji
7adf14be70 Change menu to fuzzel 2024-09-15 23:43:47 -04:00
Sravan Balaji
a7423d8210 Add cliphist startup and clipboard command 2024-09-15 23:43:47 -04:00
Sravan Balaji
014167bbab Switch from wofi to rofi-wayland 2024-09-15 23:43:47 -04:00
Sravan Balaji
96c0aecbfb Replace foot with kitty 2024-09-15 23:43:47 -04:00
Sravan Balaji
10c865c57f Re-order autostart 2024-09-15 23:43:47 -04:00
Sravan Balaji
eab33c78c5 Add shikane and azote to startup 2024-09-15 23:43:47 -04:00
Sravan Balaji
71411f99c8 Add initial autostart applications 2024-09-15 23:43:47 -04:00
Sravan Balaji
3bd02c9fb9 Add autostart patch 2024-09-15 23:43:41 -04:00
12 changed files with 1268 additions and 22 deletions

1
.gitignore vendored
View File

@@ -3,3 +3,4 @@ dwl
*-protocol.c
*-protocol.h
.ccls-cache
patches.h

View File

@@ -19,7 +19,7 @@ LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` -lm $(LIBS)
all: dwl
dwl: dwl.o util.o
$(CC) dwl.o util.o $(DWLCFLAGS) $(LDFLAGS) $(LDLIBS) -o $@
dwl.o: dwl.c client.h config.h config.mk cursor-shape-v1-protocol.h \
dwl.o: dwl.c client.h config.h config.mk patches.h cursor-shape-v1-protocol.h \
pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h \
wlr-output-power-management-unstable-v1-protocol.h xdg-shell-protocol.h
util.o: util.c util.h
@@ -48,8 +48,11 @@ xdg-shell-protocol.h:
config.h:
cp config.def.h $@
patches.h:
cp patches.def.h $@
clean:
rm -f dwl *.o *-protocol.h
rm -f patches.h
dist: clean
mkdir -p dwl-$(VERSION)

View File

@@ -6,10 +6,17 @@
* Table of Contents :TOC_3:noexport:
- [[#welcome][Welcome]]
- [[#dwl---dwm-for-wayland][dwl - dwm for Wayland]]
- [[#patches][Patches]]
- [[#attach-top][Attach Top]]
- [[#auto-start][Auto Start]]
- [[#restore-monitor][Restore Monitor]]
- [[#vanity-gaps][Vanity Gaps]]
- [[#warp-cursor][Warp Cursor]]
- [[#dwl-configuration][dwl Configuration]]
- [[#apearance][Apearance]]
- [[#appearance][Appearance]]
- [[#tagging][Tagging]]
- [[#logging][Logging]]
- [[#autostart][Autostart]]
- [[#window-rules][Window Rules]]
- [[#layouts][Layouts]]
- [[#monitor-rules][Monitor Rules]]
@@ -41,11 +48,63 @@ sudo make clean install
See [[./README.md][Upstream README]] for details on project.
* Patches
** [[https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/attachtop][Attach Top]]
This is a port of attachtop patch for dwm: https://dwm.suckless.org/patches/attachtop
New client attaches below the last master/on top of the stack.
Behavior feels very intuitive as it doesn't disrupt existing masters no matter the amount of them, it only pushes the clients in stack down.
#+BEGIN_SRC c :tangle patches.def.h
#define ATTACHTOP_PATCH 1
#+END_SRC
** [[https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/autostart][Auto Start]]
Allow dwl to execute commands from autostart array in your config.h file. And when you exit dwl all processes from autostart array will be killed.
Note: Commands from array are executed using execvp(). So if you need to execute shell command you need to prefix it with "sh", "-c" (change sh to any shell you like).
#+BEGIN_SRC c :tangle patches.def.h
#define AUTOSTART_PATCH 1
#+END_SRC
** [[https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/restore-monitor][Restore Monitor]]
Moves clients to their old output when it is reattached.
#+BEGIN_SRC c :tangle patches.def.h
#define RESTORE_MONITOR_PATCH 1
#+END_SRC
** [[https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/vanitygaps][Vanity Gaps]]
Adds (inner) gaps between client windows and (outer) gaps between windows and the screen edge in a flexible manner.
#+BEGIN_SRC c :tangle patches.def.h
#define VANITYGAPS_PATCH 1
#+END_SRC
** [[https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/warpcursor][Warp Cursor]]
Warp cursor to the centre of newly focused clients.
Only moves the cursor if the cursor is currently not on the new client.
This is my version of the orphaned cursorwarp patch except I left out the config flag as I think it is unnecessary.
#+BEGIN_SRC c :tangle patches.def.h
#define WARPCURSOR_PATCH 1
#+END_SRC
* dwl Configuration
Taken from https://github.com/djpohly/dwl/issues/466.
** Apearance
** Appearance
#+BEGIN_SRC c :tangle config.h
#define COLOR(hex) { ((hex >> 24) & 0xFF) / 255.0f, \
@@ -57,7 +116,17 @@ Taken from https://github.com/djpohly/dwl/issues/466.
#+BEGIN_SRC c :tangle config.h
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 */
#if VANITYGAPS_PATCH
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 */
#endif // VANITYGAPS_PATCH
static const unsigned int borderpx = 2; /* border pixel of windows */
#if VANITYGAPS_PATCH
static const unsigned int gappih = 20; /* horiz inner gap between windows */
static const unsigned int gappiv = 20; /* vert inner gap between windows */
static const unsigned int gappoh = 30; /* horiz outer gap between windows and screen edge */
static const unsigned int gappov = 30; /* vert outer gap between windows and screen edge */
#endif // VANITYGAPS_PATCH
static const float rootcolor[] = COLOR(0x282a36ff);
static const float bordercolor[] = COLOR(0x4d4d4dff);
static const float focuscolor[] = COLOR(0xbd93f9ff);
@@ -79,6 +148,27 @@ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca
static int log_level = WLR_ERROR;
#+END_SRC
** Autostart
#+BEGIN_SRC c :tangle config.h
#if AUTOSTART_PATCH
static const char *const autostart[] = {
"/usr/bin/shikane", NULL,
"/usr/bin/bash", "/home/sravan/.azotebg", NULL,
"/usr/libexec/polkit-gnome-authentication-agent-1", NULL,
"/usr/bin/kdeconnectd", "--replace", NULL,
"/usr/bin/bash", "/home/sravan/.scripts/dunst.sh", "--on", NULL,
"/usr/bin/nextcloud", NULL,
"/usr/bin/syncthing-gtk", NULL,
"/usr/bin/openrgb", NULL,
"/usr/bin/udiskie", "-a", "-n", "-s", NULL,
"wl-paste", "--type", "text", "--watch", "cliphist", "store", NULL,
"wl-paste", "--type", "image", "--watch", "cliphist", "store", NULL,
NULL /* terminate */
};
#endif // AUTOSTART_PATCH
#+END_SRC
** Window Rules
#+BEGIN_SRC c :tangle config.h
@@ -200,8 +290,8 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA
** Commands
#+BEGIN_SRC c :tangle config.h
static const char *termcmd[] = { "kitty", NULL };
static const char *menucmd[] = { "wofi", "--show", "drun", NULL };
static const char *termcmd[] = { "kitty", NULL };
static const char *menucmd[] = { "fuzzel", NULL };
static const Key keys[] = {
/* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */
@@ -214,6 +304,24 @@ 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} },
#if VANITYGAPS_PATCH
{ MODKEY|WLR_MODIFIER_ALT, XKB_KEY_h, incgaps, {.i = +1 } },
{ MODKEY|WLR_MODIFIER_ALT, XKB_KEY_l, incgaps, {.i = -1 } },
{ MODKEY|WLR_MODIFIER_ALT|WLR_MODIFIER_SHIFT, XKB_KEY_H, incogaps, {.i = +1 } },
{ MODKEY|WLR_MODIFIER_ALT|WLR_MODIFIER_SHIFT, XKB_KEY_L, incogaps, {.i = -1 } },
{ MODKEY|WLR_MODIFIER_ALT|WLR_MODIFIER_CTRL, XKB_KEY_h, incigaps, {.i = +1 } },
{ MODKEY|WLR_MODIFIER_ALT|WLR_MODIFIER_CTRL, XKB_KEY_l, incigaps, {.i = -1 } },
{ MODKEY|WLR_MODIFIER_ALT, XKB_KEY_0, togglegaps, {0} },
{ MODKEY|WLR_MODIFIER_ALT|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_ALT, XKB_KEY_y, incohgaps, {.i = +1 } },
{ MODKEY|WLR_MODIFIER_ALT, 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 } },
#endif // VANITYGAPS_PATCH
{ MODKEY, XKB_KEY_Return, zoom, {0} },
{ MODKEY, XKB_KEY_Tab, view, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, killclient, {0} },

View File

@@ -6,7 +6,13 @@
/* 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);
@@ -20,6 +26,13 @@ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca
/* logging */
static int log_level = WLR_ERROR;
/* Autostart */
static const char *const autostart[] = {
"wbg", "/path/to/your/image", NULL,
NULL /* terminate */
};
/* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */
static const Rule rules[] = {
/* app_id title tags mask isfloating monitor */
@@ -133,6 +146,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} },

View File

@@ -5,7 +5,17 @@
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 */
#if VANITYGAPS_PATCH
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 */
#endif // VANITYGAPS_PATCH
static const unsigned int borderpx = 2; /* border pixel of windows */
#if VANITYGAPS_PATCH
static const unsigned int gappih = 20; /* horiz inner gap between windows */
static const unsigned int gappiv = 20; /* vert inner gap between windows */
static const unsigned int gappoh = 30; /* horiz outer gap between windows and screen edge */
static const unsigned int gappov = 30; /* vert outer gap between windows and screen edge */
#endif // VANITYGAPS_PATCH
static const float rootcolor[] = COLOR(0x282a36ff);
static const float bordercolor[] = COLOR(0x4d4d4dff);
static const float focuscolor[] = COLOR(0xbd93f9ff);
@@ -18,6 +28,23 @@ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca
static int log_level = WLR_ERROR;
#if AUTOSTART_PATCH
static const char *const autostart[] = {
"/usr/bin/shikane", NULL,
"/usr/bin/bash", "/home/sravan/.azotebg", NULL,
"/usr/libexec/polkit-gnome-authentication-agent-1", NULL,
"/usr/bin/kdeconnectd", "--replace", NULL,
"/usr/bin/bash", "/home/sravan/.scripts/dunst.sh", "--on", NULL,
"/usr/bin/nextcloud", NULL,
"/usr/bin/syncthing-gtk", NULL,
"/usr/bin/openrgb", NULL,
"/usr/bin/udiskie", "-a", "-n", "-s", NULL,
"wl-paste", "--type", "text", "--watch", "cliphist", "store", NULL,
"wl-paste", "--type", "image", "--watch", "cliphist", "store", NULL,
NULL /* terminate */
};
#endif // AUTOSTART_PATCH
/* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */
static const Rule rules[] = {
/* app_id title tags mask isfloating monitor */
@@ -112,8 +139,8 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
static const char *termcmd[] = { "kitty", NULL };
static const char *menucmd[] = { "wofi", "--show", "drun", NULL };
static const char *termcmd[] = { "kitty", NULL };
static const char *menucmd[] = { "fuzzel", NULL };
static const Key keys[] = {
/* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */
@@ -126,6 +153,24 @@ 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} },
#if VANITYGAPS_PATCH
{ MODKEY|WLR_MODIFIER_ALT, XKB_KEY_h, incgaps, {.i = +1 } },
{ MODKEY|WLR_MODIFIER_ALT, XKB_KEY_l, incgaps, {.i = -1 } },
{ MODKEY|WLR_MODIFIER_ALT|WLR_MODIFIER_SHIFT, XKB_KEY_H, incogaps, {.i = +1 } },
{ MODKEY|WLR_MODIFIER_ALT|WLR_MODIFIER_SHIFT, XKB_KEY_L, incogaps, {.i = -1 } },
{ MODKEY|WLR_MODIFIER_ALT|WLR_MODIFIER_CTRL, XKB_KEY_h, incigaps, {.i = +1 } },
{ MODKEY|WLR_MODIFIER_ALT|WLR_MODIFIER_CTRL, XKB_KEY_l, incigaps, {.i = -1 } },
{ MODKEY|WLR_MODIFIER_ALT, XKB_KEY_0, togglegaps, {0} },
{ MODKEY|WLR_MODIFIER_ALT|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_ALT, XKB_KEY_y, incohgaps, {.i = +1 } },
{ MODKEY|WLR_MODIFIER_ALT, 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 } },
#endif // VANITYGAPS_PATCH
{ MODKEY, XKB_KEY_Return, zoom, {0} },
{ MODKEY, XKB_KEY_Tab, view, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, killclient, {0} },

380
dwl.c
View File

@@ -67,6 +67,7 @@
#include <xcb/xcb_icccm.h>
#endif
#include "patches.h"
#include "util.h"
/* macros */
@@ -109,6 +110,9 @@ typedef struct {
unsigned int type; /* XDGShell or X11* */
struct wlr_box geom; /* layout-relative, includes border */
Monitor *mon;
#if RESTORE_MONITOR_PATCH
char *output;
#endif // RESTORE_MONITOR_PATCH
struct wlr_scene_tree *scene;
struct wlr_scene_rect *border[4]; /* top, bottom, left, right */
struct wlr_scene_tree *scene_surface;
@@ -200,6 +204,12 @@ struct Monitor {
struct wlr_box w; /* window area, layout-relative */
struct wl_list layers[4]; /* LayerSurface.link */
const Layout *lt[2];
#if VANITYGAPS_PATCH
int gappih; /* horizontal gap between windows */
int gappiv; /* vertical gap between windows */
int gappoh; /* horizontal outer gaps */
int gappov; /* vertical outer gaps */
#endif // VANITYGAPS_PATCH
unsigned int seltags;
unsigned int sellt;
uint32_t tagset[2];
@@ -249,6 +259,9 @@ static void arrange(Monitor *m);
static void arrangelayer(Monitor *m, struct wl_list *list,
struct wlr_box *usable_area, int exclusive);
static void arrangelayers(Monitor *m);
#if AUTOSTART_PATCH
static void autostartexec(void);
#endif // AUTOSTART_PATCH
static void axisnotify(struct wl_listener *listener, void *data);
static void buttonpress(struct wl_listener *listener, void *data);
static void chvt(const Arg *arg);
@@ -273,6 +286,9 @@ 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);
#if VANITYGAPS_PATCH
static void defaultgaps(const Arg *arg);
#endif // VANITYGAPS_PATCH
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);
@@ -293,6 +309,15 @@ 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);
#if VANITYGAPS_PATCH
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);
#endif // VANITYGAPS_PATCH
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);
@@ -327,6 +352,9 @@ 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);
#if VANITYGAPS_PATCH
static void setgaps(int oh, int ov, int ih, int iv);
#endif // VANITYGAPS_PATCH
static void setlayout(const Arg *arg);
static void setmfact(const Arg *arg);
static void setmon(Client *c, Monitor *m, uint32_t newtags);
@@ -340,6 +368,9 @@ static void tagmon(const Arg *arg);
static void tile(Monitor *m);
static void togglefloating(const Arg *arg);
static void togglefullscreen(const Arg *arg);
#if VANITYGAPS_PATCH
static void togglegaps(const Arg *arg);
#endif // VANITYGAPS_PATCH
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unlocksession(struct wl_listener *listener, void *data);
@@ -351,6 +382,9 @@ static void urgent(struct wl_listener *listener, void *data);
static void view(const Arg *arg);
static void virtualkeyboard(struct wl_listener *listener, void *data);
static void virtualpointer(struct wl_listener *listener, void *data);
#if WARPCURSOR_PATCH
static void warpcursor(const Client *c);
#endif // WARPCURSOR_PATCH
static Monitor *xytomon(double x, double y);
static void xytonode(double x, double y, struct wlr_surface **psurface,
Client **pc, LayerSurface **pl, double *nx, double *ny);
@@ -413,6 +447,10 @@ static struct wlr_box sgeom;
static struct wl_list mons;
static Monitor *selmon;
#if VANITYGAPS_PATCH
static int enablegaps = 1; /* enables gaps, used by togglegaps */
#endif // VANITYGAPS_PATCH
#ifdef XWAYLAND
static void activatex11(struct wl_listener *listener, void *data);
static void associatex11(struct wl_listener *listener, void *data);
@@ -432,6 +470,11 @@ static xcb_atom_t netatom[NetLast];
/* attempt to encapsulate suck into one file */
#include "client.h"
#if AUTOSTART_PATCH
static pid_t *autostart_pids;
static size_t autostart_len;
#endif // AUTOSTART_PATCH
/* function implementations */
void
applybounds(Client *c, struct wlr_box *bbox)
@@ -519,6 +562,9 @@ arrange(Monitor *m)
m->lt[m->sellt]->arrange(m);
motionnotify(0, NULL, 0, 0, 0, 0);
checkidleinhibitor(NULL);
#if WARPCURSOR_PATCH
warpcursor(focustop(selmon));
#endif // WARPCURSOR_PATCH
}
void
@@ -580,6 +626,29 @@ arrangelayers(Monitor *m)
}
}
#if AUTOSTART_PATCH
void
autostartexec(void) {
const char *const *p;
size_t i = 0;
/* count entries */
for (p = autostart; *p; autostart_len++, p++)
while (*++p);
autostart_pids = calloc(autostart_len, sizeof(pid_t));
for (p = autostart; *p; i++, p++) {
if ((autostart_pids[i] = fork()) == 0) {
setsid();
execvp(*p, (char *const *)p);
die("dwl: execvp %s:", *p);
}
/* skip arguments */
while (*++p);
}
}
#endif // AUTOSTART_PATCH
void
axisnotify(struct wl_listener *listener, void *data)
{
@@ -676,11 +745,25 @@ checkidleinhibitor(struct wlr_surface *exclude)
void
cleanup(void)
{
#if AUTOSTART_PATCH
size_t i;
#endif // AUTOSTART_PATCH
#ifdef XWAYLAND
wlr_xwayland_destroy(xwayland);
xwayland = NULL;
#endif
wl_display_destroy_clients(dpy);
#if AUTOSTART_PATCH
/* kill child processes */
for (i = 0; i < autostart_len; i++) {
if (0 < autostart_pids[i]) {
kill(autostart_pids[i], SIGTERM);
waitpid(autostart_pids[i], NULL, 0);
}
}
#endif // AUTOSTART_PATCH
if (child_pid > 0) {
kill(-child_pid, SIGTERM);
waitpid(child_pid, NULL, 0);
@@ -981,6 +1064,9 @@ createmon(struct wl_listener *listener, void *data)
size_t i;
struct wlr_output_state state;
Monitor *m;
#if RESTORE_MONITOR_PATCH
Client *c;
#endif // RESTORE_MONITOR_PATCH
if (!wlr_output_init_render(wlr_output, alloc, drw))
return;
@@ -991,6 +1077,13 @@ createmon(struct wl_listener *listener, void *data)
for (i = 0; i < LENGTH(m->layers); i++)
wl_list_init(&m->layers[i]);
#if VANITYGAPS_PATCH
m->gappih = gappih;
m->gappiv = gappiv;
m->gappoh = gappoh;
m->gappov = gappov;
#endif // VANITYGAPS_PATCH
wlr_output_state_init(&state);
/* Initialize monitor state using configured rules */
m->tagset[0] = m->tagset[1] = 1;
@@ -1050,6 +1143,15 @@ createmon(struct wl_listener *listener, void *data)
wlr_output_layout_add_auto(output_layout, wlr_output);
else
wlr_output_layout_add(output_layout, wlr_output, m->m.x, m->m.y);
#if RESTORE_MONITOR_PATCH
wl_list_for_each(c, &clients, link) {
if (strcmp(wlr_output->name, c->output) == 0) {
c->mon = m;
}
}
updatemons(NULL, NULL);
#endif // RESTORE_MONITOR_PATCH
}
void
@@ -1173,6 +1275,14 @@ cursorwarptohint(void)
}
}
#if VANITYGAPS_PATCH
void
defaultgaps(const Arg *arg)
{
setgaps(gappoh, gappov, gappih, gappiv);
}
#endif // VANITYGAPS_PATCH
void
destroydecoration(struct wl_listener *listener, void *data)
{
@@ -1279,6 +1389,9 @@ destroynotify(struct wl_listener *listener, void *data)
wl_list_remove(&c->map.link);
wl_list_remove(&c->unmap.link);
}
#if RESTORE_MONITOR_PATCH
free(c->output);
#endif // RESTORE_MONITOR_PATCH
free(c);
}
@@ -1349,6 +1462,12 @@ focusclient(Client *c, int lift)
if (locked)
return;
#if WARPCURSOR_PATCH
/* Warp cursor to center of client if it is outside */
if (lift)
warpcursor(c);
#endif // WARPCURSOR_PATCH
/* Raise client in stacking order if requested */
if (c && lift)
wlr_scene_node_raise_to_top(&c->scene->node);
@@ -1500,6 +1619,33 @@ void
handlesig(int signo)
{
if (signo == SIGCHLD) {
#if AUTOSTART_PATCH
siginfo_t in;
/* wlroots expects to reap the XWayland process itself, so we
* use WNOWAIT to keep the child waitable until we know it's not
* XWayland.
*/
while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid
#ifdef XWAYLAND
&& (!xwayland || in.si_pid != xwayland->server->pid)
#endif
) {
pid_t *p, *lim;
waitpid(in.si_pid, NULL, 0);
if (in.si_pid == child_pid)
child_pid = -1;
if (!(p = autostart_pids))
continue;
lim = &p[autostart_len];
for (; p < lim; p++) {
if (*p == in.si_pid) {
*p = -1;
break;
}
}
}
#else // AUTOSTART_PATCH
#ifdef XWAYLAND
siginfo_t in;
/* wlroots expects to reap the XWayland process itself, so we
@@ -1507,11 +1653,12 @@ handlesig(int signo)
* XWayland.
*/
while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid
&& (!xwayland || in.si_pid != xwayland->server->pid))
waitpid(in.si_pid, NULL, 0);
&& (!xwayland || in.si_pid != xwayland->server->pid))
waitpid(in.si_pid, NULL, 0);
#else
while (waitpid(-1, NULL, WNOHANG) > 0);
while (waitpid(-1, NULL, WNOHANG) > 0);
#endif
#endif // AUTOSTART_PATCH
} else if (signo == SIGINT || signo == SIGTERM) {
quit(NULL);
}
@@ -1526,6 +1673,85 @@ incnmaster(const Arg *arg)
arrange(selmon);
}
#if VANITYGAPS_PATCH
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
);
}
#endif // VANITYGAPS_PATCH
void
inputdevice(struct wl_listener *listener, void *data)
{
@@ -1727,7 +1953,22 @@ mapnotify(struct wl_listener *listener, void *data)
c->geom.height += 2 * c->bw;
/* Insert this client into client lists. */
wl_list_insert(&clients, &c->link);
#if ATTACHTOP_PATCH
i = 0;
wl_list_for_each(w, &clients, link) {
if (!VISIBLEON(w, selmon) || c->isfloating)
continue;
p = w;
if (++i >= selmon->nmaster)
break;
}
if (i > 0)
wl_list_insert(&p->link, &c->link);
else
wl_list_insert(&clients, &c->link);
#else
wl_list_insert(&clients, &c->link);
#endif // ATTACHTOP_PATCH
wl_list_insert(&fstack, &c->flink);
/* Set initial monitor, tags, floating status, and focus:
@@ -1740,6 +1981,12 @@ mapnotify(struct wl_listener *listener, void *data)
} else {
applyrules(c);
}
#if RESTORE_MONITOR_PATCH
c->output = strdup(c->mon->wlr_output->name);
if (c->output == NULL) {
die("oom");
}
#endif // RESTORE_MONITOR_PATCH
printstatus();
unset_fullscreen:
@@ -1777,8 +2024,17 @@ monocle(Monitor *m)
wl_list_for_each(c, &clients, link) {
if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
continue;
resize(c, m->w, 0);
#if VANITYGAPS_PATCH
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);
#else // VANITYGAPS_PATCH
resize(c, m->w, 0);
n++;
#endif // VANITYGAPS_PATCH
}
if (n)
snprintf(m->ltsymbol, LENGTH(m->ltsymbol), "[%d]", n);
@@ -2227,6 +2483,9 @@ run(char *startup_cmd)
die("startup: backend_start");
/* Now that the socket exists and the backend is started, run the startup command */
#if AUTOSTART_PATCH
autostartexec();
#endif // AUTOSTART_PATCH
if (startup_cmd) {
int piperw[2];
if (pipe(piperw) < 0)
@@ -2354,6 +2613,18 @@ setgamma(struct wl_listener *listener, void *data)
wlr_output_schedule_frame(m->wlr_output);
}
#if VANITYGAPS_PATCH
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);
}
#endif // VANITYGAPS_PATCH
void
setlayout(const Arg *arg)
{
@@ -2686,14 +2957,29 @@ void
tagmon(const Arg *arg)
{
Client *sel = focustop(selmon);
if (sel)
setmon(sel, dirtomon(arg->i), 0);
#if RESTORE_MONITOR_PATCH
if (!sel)
return;
setmon(sel, dirtomon(arg->i), 0);
free(sel->output);
sel->output = strdup(sel->mon->wlr_output->name);
if (sel->output == NULL) {
die("oom");
}
#else // RESTORE_MONITOR_PATCH
if (sel)
setmon(sel, dirtomon(arg->i), 0);
#endif // RESTORE_MONITOR_PATCH
}
void
tile(Monitor *m)
{
#if VANITYGAPS_PATCH
unsigned int mw, my, ty, h, r, oe = enablegaps, ie = enablegaps;
#else // VANITYGAPS_PATCH
unsigned int mw, my, ty;
#endif // VANITYGAPS_PATCH
int i, n = 0;
Client *c;
@@ -2703,22 +2989,54 @@ tile(Monitor *m)
if (n == 0)
return;
#if VANITYGAPS_PATCH
if (smartgaps == n) {
oe = 0; // outer gaps disabled
}
#endif // VANITYGAPS_PATCH
if (n > m->nmaster)
#if VANITYGAPS_PATCH
mw = m->nmaster ? (int)roundf((m->w.width + m->gappiv*ie) * m->mfact) : 0;
#else // VANITYGAPS_PATCH
mw = m->nmaster ? (int)roundf(m->w.width * m->mfact) : 0;
#endif // VANITYGAPS_PATCH
else
mw = m->w.width;
i = my = ty = 0;
#if VANITYGAPS_PATCH
mw = m->w.width - 2*m->gappov*oe + m->gappiv*ie;
i = 0;
my = ty = m->gappoh*oe;
#else // VANITYGAPS_PATCH
mw = m->w.width;
i = my = ty = 0;
#endif // VANITYGAPS_PATCH
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;
#if VANITYGAPS_PATCH
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 // VANITYGAPS_PATCH
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;
#endif // VANITYGAPS_PATCH
} 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;
#if VANITYGAPS_PATCH
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;
#else // VANITYGAPS_PATCH
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;
#endif // VANITYGAPS_PATCH
}
i++;
}
@@ -2741,6 +3059,15 @@ togglefullscreen(const Arg *arg)
setfullscreen(sel, !sel->isfullscreen);
}
#if VANITYGAPS_PATCH
void
togglegaps(const Arg *arg)
{
enablegaps = !enablegaps;
arrange(selmon);
}
#endif // VANITYGAPS_PATCH
void
toggletag(const Arg *arg)
{
@@ -2985,6 +3312,29 @@ virtualpointer(struct wl_listener *listener, void *data)
wlr_cursor_map_input_to_output(cursor, device, event->suggested_output);
}
#if WARPCURSOR_PATCH
void
warpcursor(const Client *c) {
if (cursor_mode != CurNormal) {
return;
}
if (!c && selmon) {
wlr_cursor_warp_closest(cursor,
NULL,
selmon->w.x + selmon->w.width / 2.0 ,
selmon->w.y + selmon->w.height / 2.0);
}
else if ( c && (cursor->x < c->geom.x ||
cursor->x > c->geom.x + c->geom.width ||
cursor->y < c->geom.y ||
cursor->y > c->geom.y + c->geom.height))
wlr_cursor_warp_closest(cursor,
NULL,
c->geom.x + c->geom.width / 2.0,
c->geom.y + c->geom.height / 2.0);
}
#endif // WARPCURSOR_PATCH
Monitor *
xytomon(double x, double y)
{

9
patches.def.h Normal file
View File

@@ -0,0 +1,9 @@
#define ATTACHTOP_PATCH 1
#define AUTOSTART_PATCH 1
#define RESTORE_MONITOR_PATCH 1
#define VANITYGAPS_PATCH 1
#define WARPCURSOR_PATCH 1

View File

@@ -0,0 +1,36 @@
From 42a66d6e06c38e913766ce625f049fdbc3dd0d12 Mon Sep 17 00:00:00 2001
From: Nikita Ivanov <nikita.vyach.ivanov@gmail.com>
Date: Sun, 7 Apr 2024 21:10:17 +0200
Subject: [PATCH] New client are attached on top of the stack
---
dwl.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/dwl.c b/dwl.c
index bf763df..c0a3d74 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1605,7 +1605,18 @@ mapnotify(struct wl_listener *listener, void *data)
c->geom.height += 2 * c->bw;
/* Insert this client into client lists. */
- wl_list_insert(&clients, &c->link);
+ i = 0;
+ wl_list_for_each(w, &clients, link) {
+ if (!VISIBLEON(w, selmon) || c->isfloating)
+ continue;
+ p = w;
+ if (++i >= selmon->nmaster)
+ break;
+ }
+ if (i > 0)
+ wl_list_insert(&p->link, &c->link);
+ else
+ wl_list_insert(&clients, &c->link);
wl_list_insert(&fstack, &c->flink);
/* Set initial monitor, tags, floating status, and focus:
--
2.44.0

154
patches/autostart-0.7.patch Normal file
View File

@@ -0,0 +1,154 @@
From 787f7252d63945996f009828aff3c44afd0f7781 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
<leohdz172@proton.me>
Date: Sat, 8 Jul 2023 17:11:36 -0600
Subject: [PATCH] port autostart patch from dwm
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
https://dwm.suckless.org/patches/cool_autostart/
Signed-off-by: Leonardo Hernández Hernández <leohdz172@proton.me>
---
config.def.h | 7 +++++++
dwl.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 61 insertions(+), 5 deletions(-)
diff --git a/config.def.h b/config.def.h
index 22d2171..8dc6502 100644
--- a/config.def.h
+++ b/config.def.h
@@ -20,6 +20,13 @@ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca
/* logging */
static int log_level = WLR_ERROR;
+/* Autostart */
+static const char *const autostart[] = {
+ "wbg", "/path/to/your/image", NULL,
+ NULL /* terminate */
+};
+
+
/* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */
static const Rule rules[] = {
/* app_id title tags mask isfloating monitor */
diff --git a/dwl.c b/dwl.c
index 5bf995e..e8b8727 100644
--- a/dwl.c
+++ b/dwl.c
@@ -249,6 +249,7 @@ static void arrange(Monitor *m);
static void arrangelayer(Monitor *m, struct wl_list *list,
struct wlr_box *usable_area, int exclusive);
static void arrangelayers(Monitor *m);
+static void autostartexec(void);
static void axisnotify(struct wl_listener *listener, void *data);
static void buttonpress(struct wl_listener *listener, void *data);
static void chvt(const Arg *arg);
@@ -432,6 +433,9 @@ static xcb_atom_t netatom[NetLast];
/* attempt to encapsulate suck into one file */
#include "client.h"
+static pid_t *autostart_pids;
+static size_t autostart_len;
+
/* function implementations */
void
applybounds(Client *c, struct wlr_box *bbox)
@@ -580,6 +584,27 @@ arrangelayers(Monitor *m)
}
}
+void
+autostartexec(void) {
+ const char *const *p;
+ size_t i = 0;
+
+ /* count entries */
+ for (p = autostart; *p; autostart_len++, p++)
+ while (*++p);
+
+ autostart_pids = calloc(autostart_len, sizeof(pid_t));
+ for (p = autostart; *p; i++, p++) {
+ if ((autostart_pids[i] = fork()) == 0) {
+ setsid();
+ execvp(*p, (char *const *)p);
+ die("dwl: execvp %s:", *p);
+ }
+ /* skip arguments */
+ while (*++p);
+ }
+}
+
void
axisnotify(struct wl_listener *listener, void *data)
{
@@ -676,11 +701,21 @@ checkidleinhibitor(struct wlr_surface *exclude)
void
cleanup(void)
{
+ size_t i;
#ifdef XWAYLAND
wlr_xwayland_destroy(xwayland);
xwayland = NULL;
#endif
wl_display_destroy_clients(dpy);
+
+ /* kill child processes */
+ for (i = 0; i < autostart_len; i++) {
+ if (0 < autostart_pids[i]) {
+ kill(autostart_pids[i], SIGTERM);
+ waitpid(autostart_pids[i], NULL, 0);
+ }
+ }
+
if (child_pid > 0) {
kill(-child_pid, SIGTERM);
waitpid(child_pid, NULL, 0);
@@ -1497,18 +1532,31 @@ void
handlesig(int signo)
{
if (signo == SIGCHLD) {
-#ifdef XWAYLAND
siginfo_t in;
/* wlroots expects to reap the XWayland process itself, so we
* use WNOWAIT to keep the child waitable until we know it's not
* XWayland.
*/
while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid
- && (!xwayland || in.si_pid != xwayland->server->pid))
- waitpid(in.si_pid, NULL, 0);
-#else
- while (waitpid(-1, NULL, WNOHANG) > 0);
+#ifdef XWAYLAND
+ && (!xwayland || in.si_pid != xwayland->server->pid)
#endif
+ ) {
+ pid_t *p, *lim;
+ waitpid(in.si_pid, NULL, 0);
+ if (in.si_pid == child_pid)
+ child_pid = -1;
+ if (!(p = autostart_pids))
+ continue;
+ lim = &p[autostart_len];
+
+ for (; p < lim; p++) {
+ if (*p == in.si_pid) {
+ *p = -1;
+ break;
+ }
+ }
+ }
} else if (signo == SIGINT || signo == SIGTERM) {
quit(NULL);
}
@@ -2224,6 +2272,7 @@ run(char *startup_cmd)
die("startup: backend_start");
/* Now that the socket exists and the backend is started, run the startup command */
+ autostartexec();
if (startup_cmd) {
int piperw[2];
if (pipe(piperw) < 0)
--
2.45.2

View File

@@ -0,0 +1,82 @@
From e42ca1c539437d3098d80983cfe2ad6f938d7a08 Mon Sep 17 00:00:00 2001
From: Eldar Yusupov <eyusupov@gmail.com>
Date: Sun, 17 Mar 2024 19:12:29 +0300
Subject: [PATCH] Restore correct montior for client when it is reattached
---
dwl.c | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/dwl.c b/dwl.c
index bf763df..d8d8139 100644
--- a/dwl.c
+++ b/dwl.c
@@ -107,6 +107,7 @@ typedef struct {
unsigned int type; /* XDGShell or X11* */
struct wlr_box geom; /* layout-relative, includes border */
Monitor *mon;
+ char *output;
struct wlr_scene_tree *scene;
struct wlr_scene_rect *border[4]; /* top, bottom, left, right */
struct wlr_scene_tree *scene_surface;
@@ -869,6 +870,7 @@ createmon(struct wl_listener *listener, void *data)
size_t i;
struct wlr_output_state state;
Monitor *m;
+ Client *c;
if (!wlr_output_init_render(wlr_output, alloc, drw))
return;
@@ -938,6 +940,13 @@ createmon(struct wl_listener *listener, void *data)
wlr_output_layout_add_auto(output_layout, wlr_output);
else
wlr_output_layout_add(output_layout, wlr_output, m->m.x, m->m.y);
+
+ wl_list_for_each(c, &clients, link) {
+ if (strcmp(wlr_output->name, c->output) == 0) {
+ c->mon = m;
+ }
+ }
+ updatemons(NULL, NULL);
}
void
@@ -1186,6 +1195,7 @@ destroynotify(struct wl_listener *listener, void *data)
wl_list_remove(&c->map.link);
wl_list_remove(&c->unmap.link);
}
+ free(c->output);
free(c);
}
@@ -1618,6 +1628,10 @@ mapnotify(struct wl_listener *listener, void *data)
} else {
applyrules(c);
}
+ c->output = strdup(c->mon->wlr_output->name);
+ if (c->output == NULL) {
+ die("oom");
+ }
printstatus();
unset_fullscreen:
@@ -2565,8 +2579,14 @@ void
tagmon(const Arg *arg)
{
Client *sel = focustop(selmon);
- if (sel)
- setmon(sel, dirtomon(arg->i), 0);
+ if (!sel)
+ return;
+ setmon(sel, dirtomon(arg->i), 0);
+ free(sel->output);
+ sel->output = strdup(sel->mon->wlr_output->name);
+ if (sel->output == NULL) {
+ die("oom");
+ }
}
void
--
2.44.0

View File

@@ -0,0 +1,358 @@
From 3c95b58bc2b87ebd9b8481b3b16e49d99883f0a7 Mon Sep 17 00:00:00 2001
From: Bonicgamer <44382222+Bonicgamer@users.noreply.github.com>
Date: Mon, 17 Aug 2020 14:48:24 -0400
Subject: [PATCH 1/2] Implement vanitygaps
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Leonardo Hernández Hernández <leohdz172@proton.me>
---
config.def.h | 21 ++++++++
dwl.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 161 insertions(+), 10 deletions(-)
diff --git a/config.def.h b/config.def.h
index 22d2171d..39e528b1 100644
--- a/config.def.h
+++ b/config.def.h
@@ -6,7 +6,12 @@
/* 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 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);
@@ -133,6 +138,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} },
diff --git a/dwl.c b/dwl.c
index a2711f67..d749728a 100644
--- a/dwl.c
+++ b/dwl.c
@@ -200,6 +200,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];
@@ -273,6 +277,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);
@@ -293,6 +298,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);
@@ -327,6 +339,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);
@@ -340,6 +353,7 @@ static void tagmon(const Arg *arg);
static void tile(Monitor *m);
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);
@@ -413,6 +427,8 @@ static struct wlr_box sgeom;
static struct wl_list mons;
static Monitor *selmon;
+static int enablegaps = 1; /* enables gaps, used by togglegaps */
+
#ifdef XWAYLAND
static void activatex11(struct wl_listener *listener, void *data);
static void associatex11(struct wl_listener *listener, void *data);
@@ -989,6 +1005,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;
@@ -1171,6 +1192,12 @@ cursorwarptohint(void)
}
}
+void
+defaultgaps(const Arg *arg)
+{
+ setgaps(gappoh, gappov, gappih, gappiv);
+}
+
void
destroydecoration(struct wl_listener *listener, void *data)
{
@@ -1524,6 +1551,83 @@ incnmaster(const Arg *arg)
arrange(selmon);
}
+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)
{
@@ -2352,6 +2456,16 @@ setgamma(struct wl_listener *listener, void *data)
wlr_output_schedule_frame(m->wlr_output);
}
+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)
{
@@ -2691,7 +2805,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;
@@ -2701,22 +2815,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++;
}
@@ -2739,6 +2862,13 @@ togglefullscreen(const Arg *arg)
setfullscreen(sel, !sel->isfullscreen);
}
+void
+togglegaps(const Arg *arg)
+{
+ enablegaps = !enablegaps;
+ arrange(selmon);
+}
+
void
toggletag(const Arg *arg)
{
--
2.46.0
From 8b9db986eddeade22d92fb15a8c836912869be29 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
<leohdz172@protonmail.com>
Date: Wed, 20 Jul 2022 00:15:32 -0500
Subject: [PATCH 2/2] allow gaps in monocle layout if requested
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Leonardo Hernández Hernández <leohdz172@proton.me>
---
config.def.h | 1 +
dwl.c | 6 +++++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/config.def.h b/config.def.h
index 39e528b1..f4d4095d 100644
--- a/config.def.h
+++ b/config.def.h
@@ -7,6 +7,7 @@
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 */
diff --git a/dwl.c b/dwl.c
index d749728a..dbc66ef8 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1879,8 +1879,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);
--
2.46.0

View File

@@ -0,0 +1,71 @@
From 4951ccc89dac2b557994b2f6c3aacb2398e2d1b1 Mon Sep 17 00:00:00 2001
From: Ben Collerson <benc@benc.cc>
Date: Thu, 4 Jan 2024 20:30:01 +1000
Subject: [PATCH] warpcursor
---
dwl.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/dwl.c b/dwl.c
index 145fd018..f7ad6c13 100644
--- a/dwl.c
+++ b/dwl.c
@@ -347,6 +347,7 @@ static void urgent(struct wl_listener *listener, void *data);
static void view(const Arg *arg);
static void virtualkeyboard(struct wl_listener *listener, void *data);
static void virtualpointer(struct wl_listener *listener, void *data);
+static void warpcursor(const Client *c);
static Monitor *xytomon(double x, double y);
static void xytonode(double x, double y, struct wlr_surface **psurface,
Client **pc, LayerSurface **pl, double *nx, double *ny);
@@ -514,6 +515,7 @@ arrange(Monitor *m)
m->lt[m->sellt]->arrange(m);
motionnotify(0, NULL, 0, 0, 0, 0);
checkidleinhibitor(NULL);
+ warpcursor(focustop(selmon));
}
void
@@ -1323,6 +1325,10 @@ focusclient(Client *c, int lift)
if (locked)
return;
+ /* Warp cursor to center of client if it is outside */
+ if (lift)
+ warpcursor(c);
+
/* Raise client in stacking order if requested */
if (c && lift)
wlr_scene_node_raise_to_top(&c->scene->node);
@@ -2927,6 +2933,27 @@ virtualpointer(struct wl_listener *listener, void *data)
wlr_cursor_map_input_to_output(cursor, &pointer.base, event->suggested_output);
}
+void
+warpcursor(const Client *c) {
+ if (cursor_mode != CurNormal) {
+ return;
+ }
+ if (!c && selmon) {
+ wlr_cursor_warp_closest(cursor,
+ NULL,
+ selmon->w.x + selmon->w.width / 2.0 ,
+ selmon->w.y + selmon->w.height / 2.0);
+ }
+ else if ( c && (cursor->x < c->geom.x ||
+ cursor->x > c->geom.x + c->geom.width ||
+ cursor->y < c->geom.y ||
+ cursor->y > c->geom.y + c->geom.height))
+ wlr_cursor_warp_closest(cursor,
+ NULL,
+ c->geom.x + c->geom.width / 2.0,
+ c->geom.y + c->geom.height / 2.0);
+}
+
Monitor *
xytomon(double x, double y)
{
--
2.45.2