Compare commits

...

34 Commits

Author SHA1 Message Date
Sravan Balaji
f56f7bb943 Update devenv packages 2025-04-26 08:55:43 -04:00
Sravan Balaji
b4de07558c Merge remote-tracking branch 'upstream/0.7' 2025-03-24 17:39:37 -04:00
Sravan Balaji
090f655271 Add devenv files 2025-03-24 17:38:31 -04:00
Leonardo Hernández Hernández
2783d91611 remove binary before copying to destination
Since Linux 6.11 is possible overwrite a running executable, possibly making it
crash.

Thanks to: movq42rax
Fixes: https://codeberg.org/dwl/dwl/issues/709
References: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2a010c412853
References: https://lore.kernel.org/stable/CACKH++YAtEMYu2nTLUyfmxZoGO37fqogKMDkBpddmNaz5HE6ng@mail.gmail.com/T/#u

(cherry picked from commit 1d08ade13225343890e3476f7c4003ab87dc266c)
2025-03-13 22:00:48 +01:00
Guido Cella
b2abff8b57 fix a use after free
This line makes dwl crash after closing mpv with the switchtotag patch.

(cherry picked from commit 8206cc8889994b3e9ce3c50abefc19367cf49a8e)
2025-03-13 21:59:55 +01:00
DreamMaoMao
298c6e1839 fix: crash when open some x11 app
(cherry picked from commit e0f531d5087cbd1223577c77262ec7476c157088)
2025-03-13 21:58:14 +01:00
Sravan Balaji
455eedaa60 Fix whitespace 2025-02-09 09:34:44 -05:00
Sravan Balaji
b940c68606 Replace ghostty with foot 2025-01-05 22:25:31 -05:00
Sravan Balaji
6200290c05 Switch from kitty to ghostty terminal 2024-12-30 10:08:04 -05:00
Sravan Balaji
81bb55f185 Idle Inhibitor Active on Startup
- Make killall waybar fail silently if waybar
  isn't already running
- Update launch script to run in foreground
- Use verbose version of waybar CLI args
- Automatically restart waybar if it exits
  with non 143 (SIGTERM) exit code so random
  crashes (e.g., when opening LibreOffice or
  some games) don't persist and bar gets
  restarted
2024-12-29 16:20:39 -05:00
Sravan Balaji
fcee83d388 Fix for media with quotes in metadata 2024-11-07 09:24:24 -05:00
Sravan Balaji
82392f2bba Add window rules to start programs on certain tags 2024-11-03 16:29:43 -05:00
Sravan Balaji
1ff17a3e0b Make a new tag for productivity / email
- Remove the "media" tag
- Add productivity / email tag
2024-11-02 12:09:11 -04:00
Sravan Balaji
a0b20a574d Change dwl focused tag to an underline
- Remove debug from waybar launch
2024-10-18 23:48:43 -04:00
Sravan Balaji
e95d0bf9a9 Rounded widgets with transparent bar 2024-10-18 22:37:29 -04:00
Sravan Balaji
07c8cc46d3 Add menu patch 2024-10-06 15:30:35 -04:00
Sravan Balaji
65ef994e4c Add fake fullscreen client patch 2024-10-06 14:44:43 -04:00
Sravan Balaji
b7500d01e7 Rename patch files 2024-10-06 09:08:52 -04:00
Sravan Balaji
3d182ed166 Add movestack patch 2024-10-06 08:38:18 -04:00
Sravan Balaji
339440ac43 Add gaplessgrid patch 2024-10-06 08:24:02 -04:00
Sravan Balaji
418814a29d Adjust bar module colors 2024-10-05 21:38:46 -04:00
Sravan Balaji
661bad1870 Add idle inhibitor module 2024-10-03 23:55:06 -04:00
Sravan Balaji
ad9e99deea Add power menu group module
- Add shutdown, sleep, etc. buttons to app launcher
2024-10-03 23:16:56 -04:00
Sravan Balaji
ff7c1615fd Invert background and foreground module colors 2024-10-03 22:58:15 -04:00
Sravan Balaji
0ec71118ec Add dwl layout and window modules 2024-10-03 22:19:09 -04:00
Sravan Balaji
da0465aecc Re-order modules and update colors 2024-10-03 21:47:17 -04:00
Sravan Balaji
b3e47a4a2d Add calendar tooltip to clock module 2024-10-03 20:53:26 -04:00
Sravan Balaji
528d96221a Add System76 Power Module
- Remove sleep from waybar launch script
- Re-order and re-arrange modules
- Add left and right click events for modules
- Change module colors
- Remove commented lines
- Add a slower scroll step to pavucontrol module
2024-09-30 23:14:33 -04:00
Sravan Balaji
0220b902bb Add Playerctl Modules 2024-09-29 23:39:58 -04:00
Sravan Balaji
7f7b4bc534 Consolidate margin into one section 2024-09-29 21:36:10 -04:00
Sravan Balaji
e9f43f06f9 Remove rounded corners 2024-09-29 21:20:40 -04:00
Sravan Balaji
5e04c8685d Add dunst modules in a drawer group 2024-09-29 21:10:43 -04:00
Sravan Balaji
d53e47220f Add power menu module 2024-09-29 20:24:33 -04:00
Sravan Balaji
28f8d76316 Disable autostart and env var patches
- Disable the autostart and env var patch
- Replace customized autostart array with example
- Replace customized env var array with example
2024-09-29 16:18:30 -04:00
29 changed files with 2150 additions and 189 deletions

5
.envrc Normal file
View File

@@ -0,0 +1,5 @@
export DIRENV_WARN_TIMEOUT=20s
eval "$(devenv direnvrc)"
use devenv

10
.gitignore vendored
View File

@@ -4,3 +4,13 @@ dwl
*-protocol.h
.ccls-cache
patches.h
# Devenv
.devenv*
devenv.local.nix
# direnv
.direnv
# pre-commit
.pre-commit-config.yaml

View File

@@ -76,6 +76,7 @@ dist: clean
install: dwl
mkdir -p $(DESTDIR)$(PREFIX)/bin
rm -f $(DESTDIR)$(PREFIX)/bin/dwl
cp -f dwl $(DESTDIR)$(PREFIX)/bin
chmod 755 $(DESTDIR)$(PREFIX)/bin/dwl
mkdir -p $(DESTDIR)$(MANDIR)/man1

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,8 @@
/* Taken from https://github.com/djpohly/dwl/issues/466 */
#define COLOR(hex) { ((hex >> 24) & 0xFF) / 255.0f, \
((hex >> 16) & 0xFF) / 255.0f, \
((hex >> 8) & 0xFF) / 255.0f, \
(hex & 0xFF) / 255.0f }
((hex >> 16) & 0xFF) / 255.0f, \
((hex >> 8) & 0xFF) / 255.0f, \
(hex & 0xFF) / 255.0f }
/* 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 */
@@ -33,6 +33,14 @@ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca
/* logging */
static int log_level = WLR_ERROR;
#if MENU_PATCH
static const Menu menus[] = {
/* command feed function action function */
{ "rofi -dmenu -i", menuwinfeed, menuwinaction },
{ "rofi -dmenu -i", menulayoutfeed, menulayoutaction },
};
#endif // MENU_PATCH
#if SETUPENV_PATCH
static const Env envs[] = {
/* variable value */
@@ -43,8 +51,8 @@ static const Env envs[] = {
/* Autostart */
#if AUTOSTART_PATCH
static const char *const autostart[] = {
"wbg", "/path/to/your/image", NULL,
NULL /* terminate */
"wbg", "/path/to/your/image", NULL,
NULL /* terminate */
};
#endif // AUTOSTART_PATCH
@@ -62,6 +70,9 @@ static const Layout layouts[] = {
{ "[]=", tile },
{ "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
#if GAPLESSGRID_PATCH
{ "###", gaplessgrid },
#endif // GAPLESSGRID_PATCH
};
/* monitors */
@@ -169,6 +180,10 @@ static const Key keys[] = {
#endif // IPC_PATCH
{ MODKEY, XKB_KEY_j, focusstack, {.i = +1} },
{ MODKEY, XKB_KEY_k, focusstack, {.i = -1} },
#if MOVESTACK_PATCH
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_J, movestack, {.i = +1} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_K, movestack, {.i = -1} },
#endif // MOVESTACK_PATCH
{ MODKEY, XKB_KEY_i, incnmaster, {.i = +1} },
{ MODKEY, XKB_KEY_d, incnmaster, {.i = -1} },
{ MODKEY, XKB_KEY_h, setmfact, {.f = -0.05f} },
@@ -197,9 +212,19 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
{ MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
#if GAPLESSGRID_PATCH
{ MODKEY, XKB_KEY_g, setlayout, {.v = &layouts[3]} },
#endif // GAPLESSGRID_PATCH
{ MODKEY, XKB_KEY_space, setlayout, {0} },
#if MENU_PATCH
{ MODKEY|WLR_MODIFIER_SHIFT|WLR_MODIFIER_CTRL, XKB_KEY_p, menu, {.v = &menus[0]} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_P, menu, {.v = &menus[1]} },
#endif // MENU_PATCH
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
#if FAKE_FULLSCREEN_CLIENT_PATCH
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_E, togglefakefullscreen, {0} },
#endif // FAKE_FULLSCREEN_CLIENT_PATCH
{ MODKEY, XKB_KEY_0, view, {.ui = ~0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} },
{ MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} },

View File

@@ -31,54 +31,47 @@ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca
static int log_level = WLR_ERROR;
#if MENU_PATCH
static const Menu menus[] = {
/* command feed function action function */
{ "rofi -dmenu -i", menuwinfeed, menuwinaction },
{ "rofi -dmenu -i", menulayoutfeed, menulayoutaction },
};
#endif // MENU_PATCH
#if SETUPENV_PATCH
static const Env envs[] = {
/* variable value */
{ "TERM", "xterm-256color" },
{ "SHELL", "/bin/fish" },
{ "EDITOR", "emacs" },
{ "GIT_EDITOR", "emacs" },
{ "BROWSER", "vivaldi-stable" },
{ "QT_QPA_PLATFORMTHEME", "qt6ct" },
{ "_JAVA_AWT_WM_NONREPARENTING", "1" },
{ "XDG_CURRENT_DESKTOP", "wlroots" },
/* variable value */
{ "XDG_CURRENT_DESKTOP", "wlroots" },
};
#endif // SETUPENV_PATCH
#if AUTOSTART_PATCH
static const char *const autostart[] = {
/* Display / Compositor Setup */
"/usr/bin/shikane", NULL,
"/usr/bin/bash", "/home/sravan/.azotebg", NULL,
"/usr/bin/gammastep", "-x", NULL,
/* Background Processes */
"/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/wl-paste", "--type", "text", "--watch", "cliphist", "store", NULL,
"/usr/bin/wl-paste", "--type", "image", "--watch", "cliphist", "store", NULL,
/* Tray Applications */
"/usr/bin/gammastep-indicator", NULL,
"/usr/bin/blueman-applet", NULL,
"/usr/bin/nm-applet", NULL,
"/usr/bin/kdeconnect-indicator", NULL,
"/usr/bin/udiskie", "-a", "-n", "-s", NULL,
/* Status Bar */
"/usr/bin/sh", "-c", "/home/sravan/.config/dwl/waybar/launch.sh", NULL,
/* GUI Applications */
"/usr/bin/nextcloud", NULL,
"/usr/bin/syncthing-gtk", NULL,
"/usr/bin/openrgb", NULL,
NULL /* terminate */
"wbg", "/path/to/your/image", 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 */
/* examples: */
{ "Gimp_EXAMPLE", NULL, 0, 1, -1 }, /* Start on currently visible tags floating, not tiled */
{ "firefox_EXAMPLE", NULL, 1 << 8, 0, -1 }, /* Start on ONLY tag "9" */
/* app_id title tags mask isfloating monitor */
{ "thunderbird-esr", NULL, 1 << 0, 0, -1 }, /* Start on ONLY tag "1" */
{ "Beeper", NULL, 1 << 1, 0, -1 }, /* Start on ONLY tag "2" */
{ "zoom", NULL, 1 << 1, 0, -1 }, /* Start on ONLY tag "2" */
{ "Signal", NULL, 1 << 1, 0, -1 }, /* Start on ONLY tag "2" */
{ "discord", NULL, 1 << 1, 0, -1 }, /* Start on ONLY tag "2" */
{ "obsidian", NULL, 1 << 2, 0, -1 }, /* Start on ONLY tag "3" */
{ "pocket-casts-linux", NULL, 1 << 3, 0, -1 }, /* Start on ONLY tag "4" */
{ "Spotify", NULL, 1 << 3, 0, -1 }, /* Start on ONLY tag "4" */
{ "Vivaldi-stable", NULL, 1 << 4, 0, -1 }, /* Start on ONLY tag "5" */
{ "foot", NULL, 1 << 5, 0, -1 }, /* Start on ONLY tag "6" */
{ "Emacs", NULL, 1 << 6, 0, -1 }, /* Start on ONLY tag "7" */
{ "steam", NULL, 1 << 7, 0, -1 }, /* Start on ONLY tag "8" */
{ "lutris", NULL, 1 << 7, 0, -1 }, /* Start on ONLY tag "8" */
{ "net.davidotek.pupgui2", NULL, 1 << 7, 0, -1 }, /* Start on ONLY tag "8" */
{ "gamescope", NULL, 1 << 7, 0, -1 }, /* Start on ONLY tag "8" */
{ "syncthing-gtk", NULL, 1 << 8, 0, -1 }, /* Start on ONLY tag "9" */
{ "openrgb", NULL, 1 << 8, 0, -1 }, /* Start on ONLY tag "9" */
};
static const Layout layouts[] = {
@@ -86,6 +79,9 @@ static const Layout layouts[] = {
{ "[]=", tile },
{ "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
#if GAPLESSGRID_PATCH
{ "###", gaplessgrid },
#endif // GAPLESSGRID_PATCH
};
/* (x=-1, y=-1) is reserved as an "autoconfigure" monitor position indicator
@@ -177,7 +173,7 @@ 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 *termcmd[] = { "foot", NULL };
static const char *menucmd[] = { "rofi", "-show", "combi", NULL };
static const Key keys[] = {
@@ -190,6 +186,10 @@ static const Key keys[] = {
#endif // IPC_PATCH
{ MODKEY, XKB_KEY_j, focusstack, {.i = +1} },
{ MODKEY, XKB_KEY_k, focusstack, {.i = -1} },
#if MOVESTACK_PATCH
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_J, movestack, {.i = +1} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_K, movestack, {.i = -1} },
#endif // MOVESTACK_PATCH
{ MODKEY, XKB_KEY_i, incnmaster, {.i = +1} },
{ MODKEY, XKB_KEY_d, incnmaster, {.i = -1} },
{ MODKEY, XKB_KEY_h, setmfact, {.f = -0.05f} },
@@ -218,9 +218,19 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
{ MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
#if GAPLESSGRID_PATCH
{ MODKEY, XKB_KEY_g, setlayout, {.v = &layouts[3]} },
#endif // GAPLESSGRID_PATCH
{ MODKEY, XKB_KEY_space, setlayout, {0} },
#if MENU_PATCH
{ MODKEY|WLR_MODIFIER_SHIFT|WLR_MODIFIER_CTRL, XKB_KEY_p, menu, {.v = &menus[0]} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_P, menu, {.v = &menus[1]} },
#endif // MENU_PATCH
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
#if FAKE_FULLSCREEN_CLIENT_PATCH
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_E, togglefakefullscreen, {0} },
#endif // FAKE_FULLSCREEN_CLIENT_PATCH
{ MODKEY, XKB_KEY_0, view, {.ui = ~0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} },
{ MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} },

103
devenv.lock Normal file
View File

@@ -0,0 +1,103 @@
{
"nodes": {
"devenv": {
"locked": {
"dir": "src/modules",
"lastModified": 1745604263,
"owner": "cachix",
"repo": "devenv",
"rev": "36807c727e743e7a00999922e7f737a0cc4e05ac",
"type": "github"
},
"original": {
"dir": "src/modules",
"owner": "cachix",
"repo": "devenv",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1733328505,
"owner": "edolstra",
"repo": "flake-compat",
"rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"git-hooks": {
"inputs": {
"flake-compat": "flake-compat",
"gitignore": "gitignore",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1742649964,
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "dcf5072734cb576d2b0c59b2ac44f5050b5eac82",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "git-hooks.nix",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"git-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1733477122,
"owner": "cachix",
"repo": "devenv-nixpkgs",
"rev": "7bd9e84d0452f6d2e63b6e6da29fe73fac951857",
"type": "github"
},
"original": {
"owner": "cachix",
"ref": "rolling",
"repo": "devenv-nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"devenv": "devenv",
"git-hooks": "git-hooks",
"nixpkgs": "nixpkgs",
"pre-commit-hooks": [
"git-hooks"
]
}
}
},
"root": "root",
"version": 7
}

19
devenv.nix Normal file
View File

@@ -0,0 +1,19 @@
{ pkgs, lib, config, inputs, ... }:
{
# https://devenv.sh/packages/
packages = [
pkgs.git
pkgs.yaml-language-server
pkgs.gdb
];
# https://devenv.sh/languages/
languages.c = {
enable = true;
debugger = pkgs.gdb;
};
languages.cplusplus = {
enable = true;
};
}

15
devenv.yaml Normal file
View File

@@ -0,0 +1,15 @@
# yaml-language-server: $schema=https://devenv.sh/devenv.schema.json
inputs:
nixpkgs:
url: github:cachix/devenv-nixpkgs/rolling
# If you're using non-OSS software, you can set allowUnfree to true.
# allowUnfree: true
# If you're willing to use a package that's vulnerable
# permittedInsecurePackages:
# - "openssl-1.1.1w"
# If you have more than one devenv you can merge them
#imports:
# - ./backend

296
dwl.c
View File

@@ -162,7 +162,11 @@ typedef struct {
#endif // XWAYLAND
unsigned int bw;
uint32_t tags;
#if !FAKE_FULLSCREEN_CLIENT_PATCH
int isfloating, isurgent, isfullscreen;
#else // FAKE_FULLSCREEN_CLIENT_PATCH
int isfloating, isurgent, isfullscreen, isfakefullscreen;
#endif // FAKE_FULLSCREEN_CLIENT_PATCH
uint32_t resize; /* configure serial of a pending resize */
} Client;
@@ -292,6 +296,14 @@ typedef struct {
struct wl_listener destroy;
} SessionLock;
#if MENU_PATCH
typedef struct {
const char *cmd; /* command to run a menu */
void (*feed)(FILE *f); /* feed input to menu */
void (*action)(char *line); /* do action based on menu output */
} Menu;
#endif // MENU_PATCH
/* function declarations */
static void applybounds(Client *c, struct wlr_box *bbox);
static void applyrules(Client *c);
@@ -360,6 +372,9 @@ static void focusstack(const Arg *arg);
static Client *focustop(Monitor *m);
static void fullscreennotify(struct wl_listener *listener, void *data);
static void gpureset(struct wl_listener *listener, void *data);
#if GAPLESSGRID_PATCH
static void gaplessgrid(Monitor *m);
#endif // GAPLESSGRID_PATCH
#if UNCLUTTER_PATCH
static void handlecursoractivity(void);
static int hidecursor(void *data);
@@ -384,7 +399,18 @@ static void killclient(const Arg *arg);
static void locksession(struct wl_listener *listener, void *data);
static void mapnotify(struct wl_listener *listener, void *data);
static void maximizenotify(struct wl_listener *listener, void *data);
#if MENU_PATCH
static void menu(const Arg *arg);
static int menuloop(void *data);
static void menuwinfeed(FILE *f);
static void menuwinaction(char *line);
static void menulayoutfeed(FILE *f);
static void menulayoutaction(char *line);
#endif // MENU_PATCH
static void monocle(Monitor *m);
#if MOVESTACK_PATCH
static void movestack(const Arg *arg);
#endif // MOVESTACK_PATCH
static void motionabsolute(struct wl_listener *listener, void *data);
static void motionnotify(uint32_t time, struct wlr_input_device *device, double sx,
double sy, double sx_unaccel, double sy_unaccel);
@@ -408,6 +434,9 @@ static void setcursor(struct wl_listener *listener, void *data);
static void setcursorshape(struct wl_listener *listener, void *data);
static void setfloating(Client *c, int floating);
static void setfullscreen(Client *c, int fullscreen);
#if FAKE_FULLSCREEN_CLIENT_PATCH
static void setfakefullscreen(Client *c, int fullscreen);
#endif // FAKE_FULLSCREEN_CLIENT_PATCH
static void setgamma(struct wl_listener *listener, void *data);
#if VANITYGAPS_PATCH
static void setgaps(int oh, int ov, int ih, int iv);
@@ -428,6 +457,9 @@ static void togglebar(const Arg *arg);
#endif // IPC_PATCH
static void togglefloating(const Arg *arg);
static void togglefullscreen(const Arg *arg);
#if FAKE_FULLSCREEN_CLIENT_PATCH
static void togglefakefullscreen(const Arg *arg);
#endif // FAKE_FULLSCREEN_CLIENT_PATCH
#if VANITYGAPS_PATCH
static void togglegaps(const Arg *arg);
#endif // VANITYGAPS_PATCH
@@ -531,6 +563,13 @@ static struct wlr_box sgeom;
static struct wl_list mons;
static Monitor *selmon;
#if MENU_PATCH
static struct wl_event_source *menu_source;
static pid_t menu_pid;
static int menu_fd;
static const Menu *menu_current;
#endif // MENU_PATCH
#if IPC_PATCH
static struct zdwl_ipc_manager_v2_interface dwl_manager_implementation = {.release = dwl_ipc_manager_release, .get_output = dwl_ipc_manager_get_output};
static struct zdwl_ipc_output_v2_interface dwl_output_implementation = {.release = dwl_ipc_output_release, .set_tags = dwl_ipc_output_set_tags, .set_layout = dwl_ipc_output_set_layout, .set_client_tags = dwl_ipc_output_set_client_tags};
@@ -875,6 +914,9 @@ cleanup(void)
wlr_xwayland_destroy(xwayland);
xwayland = NULL;
#endif // XWAYLAND
#if MENU_PATCH
wl_event_source_remove(menu_source);
#endif // MENU_PATCH
wl_display_destroy_clients(dpy);
#if AUTOSTART_PATCH
@@ -1464,7 +1506,6 @@ void
destroydecoration(struct wl_listener *listener, void *data)
{
Client *c = wl_container_of(listener, c, destroy_decoration);
c->decoration = NULL;
wl_list_remove(&c->destroy_decoration.link);
wl_list_remove(&c->set_decoration_mode.link);
@@ -2048,6 +2089,58 @@ gpureset(struct wl_listener *listener, void *data)
wlr_renderer_destroy(old_drw);
}
#if GAPLESSGRID_PATCH
void
gaplessgrid(Monitor *m)
{
unsigned int n = 0, i = 0, ch, cw, cn, rn, rows, cols;
Client *c;
wl_list_for_each(c, &clients, link)
if (VISIBLEON(c, m) && !c->isfloating)
n++;
if (n == 0)
return;
/* grid dimensions */
for (cols = 0; cols <= (n / 2); cols++)
if ((cols * cols) >= n)
break;
if (n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */
cols = 2;
/* widescreen is better if 3 columns */
if (n >= 3 && n <= 6 && (m->w.width / m->w.height) > 1)
cols = 3;
rows = n / cols;
/* window geometries */
cw = cols ? m->w.width / cols : m->w.width;
cn = 0; /* current column number */
rn = 0; /* current row number */
wl_list_for_each(c, &clients, link) {
unsigned int cx, cy;
if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
continue;
if ((i / rows + 1) > (cols - n % cols))
rows = n / cols + 1;
ch = rows ? m->w.height / rows : m->w.height;
cx = m->w.x + cn * cw;
cy = m->w.y + rn * ch;
resize(c, (struct wlr_box) { cx, cy, cw, ch}, 0);
rn++;
if (rn >= rows) {
rn = 0;
cn++;
}
i++;
}
}
#endif // GAPLESSGRID_PATCH
void
handlesig(int signo)
{
@@ -2490,6 +2583,138 @@ maximizenotify(struct wl_listener *listener, void *data)
wlr_xdg_surface_schedule_configure(c->surface.xdg);
}
#if MENU_PATCH
void
menu(const Arg *arg)
{
FILE *f;
pid_t pid;
int fd_right[2], fd_left[2];
if (!selmon || menu_pid != 0)
return;
menu_current = arg->v;
if (pipe(fd_right) == -1 || pipe(fd_left) == -1)
return;
if ((pid = fork()) == -1)
return;
if (pid == 0) {
close(fd_right[1]);
close(fd_left[0]);
dup2(fd_right[0], STDIN_FILENO);
close(fd_right[0]);
dup2(fd_left[1], STDOUT_FILENO);
close(fd_left[1]);
execl("/bin/sh", "/bin/sh", "-c", menu_current->cmd, NULL);
die("dwl: execl %s failed:", "/bin/sh");
}
close(fd_right[0]);
close(fd_left[1]);
if (!(f = fdopen(fd_right[1], "w")))
return;
menu_current->feed(f);
fclose(f);
menu_pid = pid;
menu_fd = fd_left[0];
wl_event_source_timer_update(menu_source, 10);
}
int
menuloop(void *data)
{
FILE *f;
pid_t pid;
char line[256], *s;
/* If process is still running, wait for another 50 ms */
if ((pid = waitpid(menu_pid, NULL, WNOHANG)) == 0) {
wl_event_source_timer_update(menu_source, 10);
return 0;
}
menu_pid = 0;
if (!(f = fdopen(menu_fd, "r")))
return 0;
if (fgets(line, sizeof(line), f)) {
if ((s = strchr(line, '\n')))
*s = '\0';
menu_current->action(line);
}
fclose(f);
return 0;
}
void
menuwinfeed(FILE *f)
{
Client *c;
const char *title;
wl_list_for_each(c, &fstack, flink) {
if (!(title = client_get_title(c)))
continue;
fprintf(f, "%s\n", title);
}
}
void
menuwinaction(char *line)
{
Client *c;
Monitor *prevm = selmon;
const char *title;
if (!selmon)
return;
wl_list_for_each(c, &fstack, flink) {
if (!(title = client_get_title(c)))
continue;
if (strcmp(line, title) == 0)
goto found;
}
return;
found:
focusclient(c, 1);
wlr_cursor_move(cursor, NULL, selmon->m.x - prevm->m.x , 0);
selmon->seltags ^= 1; /* toggle sel tagset */
selmon->tagset[selmon->seltags] = c->tags;
arrange(selmon);
printstatus();
}
void
menulayoutfeed(FILE *f)
{
unsigned int i;
for (i = 0; i < LENGTH(layouts); i++)
fprintf(f, "%s\n", layouts[i].symbol);
}
void
menulayoutaction(char *line)
{
unsigned int i;
Arg a;
for (i = 0; i < LENGTH(layouts); i++)
if (strcmp(line, layouts[i].symbol) == 0)
goto found;
return;
found:
a.v = &layouts[i];
setlayout(&a);
}
#endif // MENU_PATCH
void
monocle(Monitor *m)
{
@@ -2517,6 +2742,42 @@ monocle(Monitor *m)
wlr_scene_node_raise_to_top(&c->scene->node);
}
#if MOVESTACK_PATCH
void
movestack(const Arg *arg)
{
Client *c, *sel = focustop(selmon);
if (!sel) {
return;
}
if (wl_list_length(&clients) <= 1) {
return;
}
if (arg->i > 0) {
wl_list_for_each(c, &sel->link, link) {
if (VISIBLEON(c, selmon) || &c->link == &clients) {
break; /* found it */
}
}
} else {
wl_list_for_each_reverse(c, &sel->link, link) {
if (VISIBLEON(c, selmon) || &c->link == &clients) {
break; /* found it */
}
}
/* backup one client */
c = wl_container_of(c->link.prev, c, link);
}
wl_list_remove(&sel->link);
wl_list_insert(&c->link, &sel->link);
arrange(selmon);
}
#endif // MOVESTACK_PATCH
void
motionabsolute(struct wl_listener *listener, void *data)
{
@@ -3094,7 +3355,7 @@ setfloating(Client *c, int floating)
(p && p->isfullscreen) ? LyrFS
: c->isfloating ? LyrFloat : LyrTile]);
#if FLOAT_UNFOCUSED_BORDER_COLOR_PATCH
if (!grabc && floating)
if (!grabc && floating)
for (int i = 0; i < 4; i++) {
wlr_scene_rect_set_color(c->border[i], floatcolor);
wlr_scene_node_lower_to_bottom(&c->border[i]->node);
@@ -3127,6 +3388,19 @@ setfullscreen(Client *c, int fullscreen)
printstatus();
}
#if FAKE_FULLSCREEN_CLIENT_PATCH
void
setfakefullscreen(Client *c, int fullscreen)
{
c->isfakefullscreen = fullscreen;
if (!c->mon)
return;
if (c->isfullscreen)
setfullscreen(c, 0);
client_set_fullscreen(c, fullscreen);
}
#endif // FAKE_FULLSCREEN_CLIENT_PATCH
void
setgamma(struct wl_listener *listener, void *data)
{
@@ -3465,6 +3739,12 @@ setup(void)
* e.g when running in the x11 backend or the wayland backend and the
* compositor has Xwayland support */
unsetenv("DISPLAY");
#if MENU_PATCH
menu_source = wl_event_loop_add_timer(
wl_display_get_event_loop(dpy), menuloop, NULL);
#endif // MENU_PATCH
#ifdef XWAYLAND
/*
* Initialise the XWayland X server.
@@ -3631,6 +3911,16 @@ togglefullscreen(const Arg *arg)
setfullscreen(sel, !sel->isfullscreen);
}
#if FAKE_FULLSCREEN_CLIENT_PATCH
void
togglefakefullscreen(const Arg *arg)
{
Client *sel = focustop(selmon);
if (sel)
setfakefullscreen(sel, !sel->isfakefullscreen);
}
#endif // FAKE_FULLSCREEN_CLIENT_PATCH
#if VANITYGAPS_PATCH
void
togglegaps(const Arg *arg)
@@ -4185,7 +4475,7 @@ sethints(struct wl_listener *listener, void *data)
{
Client *c = wl_container_of(listener, c, set_hints);
struct wlr_surface *surface = client_surface(c);
if (c == focustop(selmon))
if (c == focustop(selmon) || !c->surface.xwayland->hints)
return;
c->isurgent = xcb_icccm_wm_hints_get_urgency(c->surface.xwayland->hints);

View File

@@ -2,14 +2,22 @@
#define ATTACHTOP_PATCH 1
#define AUTOSTART_PATCH 1
#define AUTOSTART_PATCH 0
#define FAKE_FULLSCREEN_CLIENT_PATCH 1
#define FLOAT_UNFOCUSED_BORDER_COLOR_PATCH 1
#define FOREIGN_TOPLEVEL_MANAGEMENT_PATCH 1
#define GAPLESSGRID_PATCH 1
#define IPC_PATCH 1
#define MENU_PATCH 1
#define MOVESTACK_PATCH 1
#define NATURALSCROLLTRACKPAD_PATCH 1
#define NUMLOCK_CAPSLOCK_PATCH 1
@@ -18,7 +26,7 @@
#define RESTORE_MONITOR_PATCH 1
#define SETUPENV_PATCH 1
#define SETUPENV_PATCH 0
#define UNCLUTTER_PATCH 1

View File

@@ -0,0 +1,87 @@
From 2ec6d0c668b4daee601337f8da45ccfa3a7d5fc6 Mon Sep 17 00:00:00 2001
From: choc <notchoc@proton.me>
Date: Fri, 29 Mar 2024 22:50:00 +0800
Subject: [PATCH] implement fakefullscreenclient
---
config.def.h | 1 +
dwl.c | 23 ++++++++++++++++++++++-
2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/config.def.h b/config.def.h
index 9009517..8c220eb 100644
--- a/config.def.h
+++ b/config.def.h
@@ -137,6 +137,7 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_space, setlayout, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_E, togglefakefullscreen, {0} },
{ MODKEY, XKB_KEY_0, view, {.ui = ~0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} },
{ MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} },
diff --git a/dwl.c b/dwl.c
index 5867b0c..1e78491 100644
--- a/dwl.c
+++ b/dwl.c
@@ -137,7 +137,7 @@ typedef struct {
#endif
unsigned int bw;
uint32_t tags;
- int isfloating, isurgent, isfullscreen;
+ int isfloating, isurgent, isfullscreen, isfakefullscreen;
uint32_t resize; /* configure serial of a pending resize */
} Client;
@@ -318,6 +318,7 @@ static void setcursor(struct wl_listener *listener, void *data);
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 setfakefullscreen(Client *c, int fullscreen);
static void setgamma(struct wl_listener *listener, void *data);
static void setlayout(const Arg *arg);
static void setmfact(const Arg *arg);
@@ -332,6 +333,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 togglefakefullscreen(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unlocksession(struct wl_listener *listener, void *data);
@@ -2181,6 +2183,17 @@ setfullscreen(Client *c, int fullscreen)
printstatus();
}
+void
+setfakefullscreen(Client *c, int fullscreen)
+{
+ c->isfakefullscreen = fullscreen;
+ if (!c->mon)
+ return;
+ if (c->isfullscreen)
+ setfullscreen(c, 0);
+ client_set_fullscreen(c, fullscreen);
+}
+
void
setgamma(struct wl_listener *listener, void *data)
{
@@ -2620,6 +2633,14 @@ togglefullscreen(const Arg *arg)
setfullscreen(sel, !sel->isfullscreen);
}
+void
+togglefakefullscreen(const Arg *arg)
+{
+ Client *sel = focustop(selmon);
+ if (sel)
+ setfakefullscreen(sel, !sel->isfakefullscreen);
+}
+
void
toggletag(const Arg *arg)
{
--
2.44.0

View File

@@ -0,0 +1,89 @@
diff --git a/config.def.h b/config.def.h
index 22d2171..014a909 100644
--- a/config.def.h
+++ b/config.def.h
@@ -34,6 +34,7 @@ static const Layout layouts[] = {
{ "[]=", tile },
{ "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
+ { "###", gaplessgrid },
};
/* monitors */
@@ -139,6 +140,7 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
{ MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
+ { MODKEY, XKB_KEY_g, setlayout, {.v = &layouts[3]} },
{ MODKEY, XKB_KEY_space, setlayout, {0} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
diff --git a/dwl.c b/dwl.c
index dc0c861..875d8cd 100644
--- a/dwl.c
+++ b/dwl.c
@@ -292,6 +292,7 @@ static void focusstack(const Arg *arg);
static Client *focustop(Monitor *m);
static void fullscreennotify(struct wl_listener *listener, void *data);
static void gpureset(struct wl_listener *listener, void *data);
+static void gaplessgrid(Monitor *m);
static void handlesig(int signo);
static void incnmaster(const Arg *arg);
static void inputdevice(struct wl_listener *listener, void *data);
@@ -1510,6 +1511,56 @@ handlesig(int signo)
}
}
+void
+gaplessgrid(Monitor *m)
+{
+ unsigned int n = 0, i = 0, ch, cw, cn, rn, rows, cols;
+ Client *c;
+
+ wl_list_for_each(c, &clients, link)
+ if (VISIBLEON(c, m) && !c->isfloating)
+ n++;
+ if (n == 0)
+ return;
+
+ /* grid dimensions */
+ for (cols = 0; cols <= (n / 2); cols++)
+ if ((cols * cols) >= n)
+ break;
+
+ if (n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */
+ cols = 2;
+
+ /* widescreen is better if 3 columns */
+ if (n >= 3 && n <= 6 && (m->w.width / m->w.height) > 1)
+ cols = 3;
+
+ rows = n / cols;
+
+ /* window geometries */
+ cw = cols ? m->w.width / cols : m->w.width;
+ cn = 0; /* current column number */
+ rn = 0; /* current row number */
+ wl_list_for_each(c, &clients, link) {
+ unsigned int cx, cy;
+ if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
+ continue;
+
+ if ((i / rows + 1) > (cols - n % cols))
+ rows = n / cols + 1;
+ ch = rows ? m->w.height / rows : m->w.height;
+ cx = m->w.x + cn * cw;
+ cy = m->w.y + rn * ch;
+ resize(c, (struct wlr_box) { cx, cy, cw, ch}, 0);
+ rn++;
+ if (rn >= rows) {
+ rn = 0;
+ cn++;
+ }
+ i++;
+ }
+}
+
void
incnmaster(const Arg *arg)
{

230
patches/menu-20240713.patch Normal file
View File

@@ -0,0 +1,230 @@
commit 2d7e19dc948aec61746fd858394a9c80d34a3216
Author: Nikita Ivanov <nikita.vyach.ivanov@gmail.com>
Date: Sat Jul 13 01:05:20 2024 +0200
Add menu command
diff --git a/config.def.h b/config.def.h
index 22d2171..ecd2c67 100644
--- a/config.def.h
+++ b/config.def.h
@@ -20,6 +20,12 @@ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca
/* logging */
static int log_level = WLR_ERROR;
+static const Menu menus[] = {
+ /* command feed function action function */
+ { "wmenu -i -l 5 -p Windows", menuwinfeed, menuwinaction },
+ { "wmenu -i -p Layouts", menulayoutfeed, menulayoutaction },
+};
+
/* 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 */
@@ -140,6 +146,8 @@ static const Key keys[] = {
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
{ MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
{ MODKEY, XKB_KEY_space, setlayout, {0} },
+ { MODKEY, XKB_KEY_o, menu, {.v = &menus[0]} },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_O, menu, {.v = &menus[1]} },
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
{ MODKEY, XKB_KEY_0, view, {.ui = ~0} },
diff --git a/dwl.c b/dwl.c
index dc0437e..90bb09a 100644
--- a/dwl.c
+++ b/dwl.c
@@ -241,6 +241,12 @@ typedef struct {
struct wl_listener destroy;
} SessionLock;
+typedef struct {
+ const char *cmd; /* command to run a menu */
+ void (*feed)(FILE *f); /* feed input to menu */
+ void (*action)(char *line); /* do action based on menu output */
+} Menu;
+
/* function declarations */
static void applybounds(Client *c, struct wlr_box *bbox);
static void applyrules(Client *c);
@@ -298,6 +304,12 @@ static void killclient(const Arg *arg);
static void locksession(struct wl_listener *listener, void *data);
static void mapnotify(struct wl_listener *listener, void *data);
static void maximizenotify(struct wl_listener *listener, void *data);
+static void menu(const Arg *arg);
+static int menuloop(void *data);
+static void menuwinfeed(FILE *f);
+static void menuwinaction(char *line);
+static void menulayoutfeed(FILE *f);
+static void menulayoutaction(char *line);
static void monocle(Monitor *m);
static void motionabsolute(struct wl_listener *listener, void *data);
static void motionnotify(uint32_t time, struct wlr_input_device *device, double sx,
@@ -408,6 +420,11 @@ static struct wlr_box sgeom;
static struct wl_list mons;
static Monitor *selmon;
+static struct wl_event_source *menu_source;
+static pid_t menu_pid;
+static int menu_fd;
+static const Menu *menu_current;
+
#ifdef XWAYLAND
static void activatex11(struct wl_listener *listener, void *data);
static void associatex11(struct wl_listener *listener, void *data);
@@ -675,6 +692,7 @@ cleanup(void)
wlr_xwayland_destroy(xwayland);
xwayland = NULL;
#endif
+ wl_event_source_remove(menu_source);
wl_display_destroy_clients(dpy);
if (child_pid > 0) {
kill(-child_pid, SIGTERM);
@@ -1717,6 +1735,136 @@ maximizenotify(struct wl_listener *listener, void *data)
wlr_xdg_surface_schedule_configure(c->surface.xdg);
}
+void
+menu(const Arg *arg)
+{
+ FILE *f;
+ pid_t pid;
+ int fd_right[2], fd_left[2];
+
+ if (!selmon || menu_pid != 0)
+ return;
+
+ menu_current = arg->v;
+
+ if (pipe(fd_right) == -1 || pipe(fd_left) == -1)
+ return;
+ if ((pid = fork()) == -1)
+ return;
+ if (pid == 0) {
+ close(fd_right[1]);
+ close(fd_left[0]);
+ dup2(fd_right[0], STDIN_FILENO);
+ close(fd_right[0]);
+ dup2(fd_left[1], STDOUT_FILENO);
+ close(fd_left[1]);
+
+ execl("/bin/sh", "/bin/sh", "-c", menu_current->cmd, NULL);
+ die("dwl: execl %s failed:", "/bin/sh");
+ }
+
+ close(fd_right[0]);
+ close(fd_left[1]);
+
+ if (!(f = fdopen(fd_right[1], "w")))
+ return;
+ menu_current->feed(f);
+ fclose(f);
+
+ menu_pid = pid;
+ menu_fd = fd_left[0];
+ wl_event_source_timer_update(menu_source, 10);
+}
+
+int
+menuloop(void *data)
+{
+ FILE *f;
+ pid_t pid;
+ char line[256], *s;
+
+ /* If process is still running, wait for another 50 ms */
+ if ((pid = waitpid(menu_pid, NULL, WNOHANG)) == 0) {
+ wl_event_source_timer_update(menu_source, 10);
+ return 0;
+ }
+
+ menu_pid = 0;
+
+ if (!(f = fdopen(menu_fd, "r")))
+ return 0;
+ if (fgets(line, sizeof(line), f)) {
+ if ((s = strchr(line, '\n')))
+ *s = '\0';
+ menu_current->action(line);
+ }
+ fclose(f);
+ return 0;
+}
+
+void
+menuwinfeed(FILE *f)
+{
+ Client *c;
+ const char *title;
+
+ wl_list_for_each(c, &fstack, flink) {
+ if (!(title = client_get_title(c)))
+ continue;
+ fprintf(f, "%s\n", title);
+ }
+}
+
+void
+menuwinaction(char *line)
+{
+ Client *c;
+ Monitor *prevm = selmon;
+ const char *title;
+
+ if (!selmon)
+ return;
+
+ wl_list_for_each(c, &fstack, flink) {
+ if (!(title = client_get_title(c)))
+ continue;
+ if (strcmp(line, title) == 0)
+ goto found;
+ }
+ return;
+
+found:
+ focusclient(c, 1);
+ wlr_cursor_move(cursor, NULL, selmon->m.x - prevm->m.x , 0);
+ selmon->seltags ^= 1; /* toggle sel tagset */
+ selmon->tagset[selmon->seltags] = c->tags;
+ arrange(selmon);
+ printstatus();
+}
+
+void
+menulayoutfeed(FILE *f)
+{
+ unsigned int i;
+ for (i = 0; i < LENGTH(layouts); i++)
+ fprintf(f, "%s\n", layouts[i].symbol);
+}
+
+void
+menulayoutaction(char *line)
+{
+ unsigned int i;
+ Arg a;
+ for (i = 0; i < LENGTH(layouts); i++)
+ if (strcmp(line, layouts[i].symbol) == 0)
+ goto found;
+ return;
+
+found:
+ a.v = &layouts[i];
+ setlayout(&a);
+}
+
void
monocle(Monitor *m)
{
@@ -2576,6 +2724,10 @@ setup(void)
* e.g when running in the x11 backend or the wayland backend and the
* compositor has Xwayland support */
unsetenv("DISPLAY");
+
+ menu_source = wl_event_loop_add_timer(
+ wl_display_get_event_loop(dpy), menuloop, NULL);
+
#ifdef XWAYLAND
/*
* Initialise the XWayland X server.

79
patches/movestack.patch Normal file
View File

@@ -0,0 +1,79 @@
From b051f50233033b399db324b29ab24227257ac141 Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Tue, 5 Mar 2024 23:31:51 -0500
Subject: [PATCH] apply NikitaIvanovV movestack patch
source: https://github.com/djpohly/dwl/wiki/movestack
---
config.def.h | 2 ++
dwl.c | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 37 insertions(+)
diff --git a/config.def.h b/config.def.h
index db0babc..778a0dc 100644
--- a/config.def.h
+++ b/config.def.h
@@ -122,6 +122,8 @@ static const Key keys[] = {
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = termcmd} },
{ MODKEY, XKB_KEY_j, focusstack, {.i = +1} },
{ MODKEY, XKB_KEY_k, focusstack, {.i = -1} },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_J, movestack, {.i = +1} },
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_K, movestack, {.i = -1} },
{ MODKEY, XKB_KEY_i, incnmaster, {.i = +1} },
{ MODKEY, XKB_KEY_d, incnmaster, {.i = -1} },
{ MODKEY, XKB_KEY_h, setmfact, {.f = -0.05} },
diff --git a/dwl.c b/dwl.c
index ef27a1d..69b9756 100644
--- a/dwl.c
+++ b/dwl.c
@@ -279,6 +279,7 @@ static void maplayersurfacenotify(struct wl_listener *listener, void *data);
static void mapnotify(struct wl_listener *listener, void *data);
static void maximizenotify(struct wl_listener *listener, void *data);
static void monocle(Monitor *m);
+static void movestack(const Arg *arg);
static void motionabsolute(struct wl_listener *listener, void *data);
static void motionnotify(uint32_t time);
static void motionrelative(struct wl_listener *listener, void *data);
@@ -1603,6 +1604,40 @@ monocle(Monitor *m)
wlr_scene_node_raise_to_top(&c->scene->node);
}
+void
+movestack(const Arg *arg)
+{
+ Client *c, *sel = focustop(selmon);
+
+ if (!sel) {
+ return;
+ }
+
+ if (wl_list_length(&clients) <= 1) {
+ return;
+ }
+
+ if (arg->i > 0) {
+ wl_list_for_each(c, &sel->link, link) {
+ if (VISIBLEON(c, selmon) || &c->link == &clients) {
+ break; /* found it */
+ }
+ }
+ } else {
+ wl_list_for_each_reverse(c, &sel->link, link) {
+ if (VISIBLEON(c, selmon) || &c->link == &clients) {
+ break; /* found it */
+ }
+ }
+ /* backup one client */
+ c = wl_container_of(c->link.prev, c, link);
+ }
+
+ wl_list_remove(&sel->link);
+ wl_list_insert(&c->link, &sel->link);
+ arrange(selmon);
+}
+
void
motionabsolute(struct wl_listener *listener, void *data)
{
--
2.42.0

10
util.c
View File

@@ -38,14 +38,14 @@ ecalloc(size_t nmemb, size_t size)
int
fd_set_nonblock(int fd) {
int flags = fcntl(fd, F_GETFL);
if (flags < 0) {
if (flags < 0) {
perror("fcntl(F_GETFL):");
return -1;
}
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
return -1;
}
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
perror("fcntl(F_SETFL):");
return -1;
}
}
return 0;
}

View File

@@ -6,26 +6,71 @@
"position": "top", // Waybar position (top|bottom|left|right)
// "height": 25, // Waybar height (to be removed for auto height)
// "width": 1280, // Waybar width
// Choose the order of the modules
"spacing": 4, // Gaps between modules (4px)
"mode": "dock",
"start_hidden": false,
"fixed-center": true,
"reload_style_on_change": true,
"modules-left": [
"group/power-menu",
"dwl/tags",
"dwl/window#title",
"dwl/window#layout",
],
"modules-center": [
"tray",
],
"modules-right": [
"group/media-playing",
"pulseaudio",
"idle_inhibitor",
"custom/system76-power",
"cpu",
"memory",
"disk",
"battery",
"clock"
"clock",
"group/dunst",
],
"group/power-menu": {
"orientation": "inherit",
"modules": [
"custom/power-menu-launcher",
"custom/power-menu-shutdown",
"custom/power-menu-reboot",
"custom/power-menu-sleep",
"custom/power-menu-lock",
"custom/power-menu-logout",
],
"drawer": {
"transition-duration": 500,
"transition-left-to-right": true,
"click-to-reveal": false,
},
},
"group/media-playing": {
"orientation": "inherit",
"modules": [
"custom/media-playing-source",
"custom/media-playing-prev",
"custom/media-playing-play-pause",
"custom/media-playing-next",
],
},
"group/dunst": {
"orientation": "inherit",
"modules": [
"custom/dunst-status",
"custom/dunst-history-view",
"custom/dunst-clear",
"custom/dunst-history-clear",
],
"drawer": {
"transition-duration": 500,
"transition-left-to-right": true,
"click-to-reveal": false,
},
},
"battery": {
"interval": 60,
@@ -39,31 +84,170 @@
"interval": 5,
"format": " {usage}%",
"tooltip": true,
"on-click-right": "foot btop",
},
"clock": {
"interval": 60,
"format": "󰥔 {:%H:%M}"
"format": "󰥔 {:%I:%M %p}",
"tooltip": true,
"tooltip-format": "<tt><small>{calendar}</small></tt>",
"calendar": {
"mode" : "month",
"mode-mon-col" : 3,
"weeks-pos" : "left",
"on-scroll" : 1,
"format": {
"months": "<span color='#50fa7b'><b>{}</b></span>",
"days": "<span color='#f8f8f2'><b>{}</b></span>",
"weeks": "<span color='#8be9fd'><b>W{}</b></span>",
"weekdays": "<span color='#f1fa8c'><b>{}</b></span>",
"today": "<span color='#bd93f9'><b><u>{}</u></b></span>"
},
},
"actions": {
"on-click": "mode",
"on-click-right": "shift_reset",
"on-scroll-up": "shift_up",
"on-scroll-down": "shift_down",
},
},
"custom/dunst-status": {
"exec": "~/.config/dwl/waybar/scripts/dunst.sh",
"restart-interval": 1,
"on-click": "~/.scripts/dunst.sh --dnd",
"on-click-right": "~/.scripts/dunst.sh --rofi",
"tooltip": true,
"tooltip-format": "Toggle Do Not Disturb",
},
"custom/dunst-clear": {
"format": "",
"on-click": "~/.scripts/dunst.sh --close-all",
"tooltip": true,
"tooltip-format": "Close Open Notifications",
},
"custom/dunst-history-view": {
"format": "󰋚",
"on-click": "~/.scripts/dunst.sh --history",
"tooltip": true,
"tooltip-format": "View Notification History",
},
"custom/dunst-history-clear": {
"format": "󰎟",
"on-click": "~/.scripts/dunst.sh --history-clear",
"tooltip": true,
"tooltip-format": "Clear Notification History",
},
"dwl/tags": {
"num-tags": 9,
"tag-labels": [ "󰍩 ₁", "󰠮 ₂", " ₃", "󰿎 ₄", "󰖟 ₅", " ₆", "󰊢 ₇", "󰊖 ₈", " ₉" ],
"tag-labels": [ "󰻧 ₁", "󰍩 ₂", "󰠮 ₃", " ₄", "󰖟 ₅", " ₆", "󰊢 ₇", "󰊖 ₈", " ₉" ],
"disable-click": false
},
"dwl/window#title": {
"format": "{title}",
"all-outputs": false,
"icon": true,
"icon-size": 21,
"tooltip": true,
"max-length": 30,
},
"dwl/window#layout": {
"format": "{layout}",
"tooltip": false,
"all-outputs": false,
"icon": false,
},
"disk": {
"interval": 60,
"format": "󰋊 {percentage_used}%",
"tooltip": true,
"tooltip-format": "Used: {used} ({percentage_used}%)\nFree: {free} ({percentage_free}%)\nTotal: {total}",
"on-click-right": "qdirstat",
},
"idle_inhibitor": {
"format": "{icon}",
"format-icons": {
"activated": "󱄄 on",
"deactivated": "󰶐 off",
},
"tooltip": true,
"tooltip-format-activated": "Idle Inhibitor: {status}",
"tooltip-format-deactivated": "Idle Inhibitor: {status}",
"start-activated": true,
},
"memory": {
"interval": 5,
"format": " {percentage}%",
"format": " {percentage}%",
"tooltip": true,
"tooltip-format": "RAM:\n\tUsed: {used} GiB ({percentage}%)\n\tFree: {avail} GiB\n\tTotal: {total} GiB\nSwap:\n\tUsed: {swapUsed} GiB ({swapPercentage}%)\n\tFree: {swapAvail} GiB\n\tTotal: {swapTotal} GiB",
"on-click-right": "foot btop",
},
"custom/media-playing-source": {
"exec": "~/.config/dwl/waybar/scripts/get-media-playing.sh",
"return-type": "json",
"restart-interval": 1,
"on-click": "~/.scripts/playerctl.sh --change",
"tooltip": true,
},
"custom/media-playing-prev": {
"format": "󰒮",
"on-click": "~/.scripts/playerctl.sh --prev",
"tooltip": false,
},
"custom/media-playing-play-pause": {
"exec": "~/.config/dwl/waybar/scripts/get-media-status-icon.sh",
"restart-interval": 1,
"on-click": "~/.scripts/playerctl.sh --play-pause",
"tooltip": false,
},
"custom/media-playing-next": {
"format": "󰒭",
"on-click": "~/.scripts/playerctl.sh --next",
"tooltip": false,
},
"custom/power-menu-launcher": {
"format": "",
"on-click": "rofi -show combi",
"on-click-right": "~/.scripts/control-center.sh --rofi",
"tooltip": true,
"tooltip-format": "Application Launcher",
},
"custom/power-menu-shutdown": {
"format": "",
"on-click": "~/.scripts/session.sh --shutdown",
"tooltip": true,
"tooltip-format": "Shutdown",
},
"custom/power-menu-reboot": {
"format": "",
"on-click": "~/.scripts/session.sh --reboot",
"tooltip": true,
"tooltip-format": "Reboot",
},
"custom/power-menu-sleep": {
"format": "⏾",
"on-click": "~/.scripts/session.sh --sleep",
"tooltip": true,
"tooltip-format": "Sleep",
},
"custom/power-menu-lock": {
"format": "",
"on-click": "~/.scripts/session.sh --lock",
"tooltip": true,
"tooltip-format": "Lock",
},
"custom/power-menu-logout": {
"format": "",
"on-click": "~/.scripts/session.sh --logout",
"tooltip": true,
"tooltip-format": "Logout",
},
"pulseaudio": {
@@ -81,9 +265,19 @@
"default": "",
},
"scroll-step": 5,
"on-click": "pavucontrol",
"on-click": "~/.scripts/pactl.sh --mute",
"on-click-right": "~/.scripts/pactl.sh --mixer",
"tooltip": true,
"tooltip-format": "{desc}",
"scroll-step": 0.25,
},
"custom/system76-power": {
"exec": "~/.config/dwl/waybar/scripts/system76-power.sh",
"return-type": "json",
"restart-interval": 60,
"on-click-right": "~/.scripts/cpu-gpu.sh --rofi",
"tooltip": true,
},
"tray": {

View File

@@ -1,8 +1,15 @@
#!/usr/bin/env bash
killall waybar
killall waybar || true
sleep 5
/usr/bin/waybar \
-c $HOME/.config/dwl/waybar/config.jsonc \
-s $HOME/.config/dwl/waybar/style.css &
until /usr/bin/waybar \
--config $HOME/.config/dwl/waybar/config.jsonc \
--style $HOME/.config/dwl/waybar/style.css;
do
if [ $? -ne 143 ]; then
echo "Dwl Waybar stopped with exit code $?. Respawning..." >&2;
sleep 1;
else
echo "Dwl Waybar manually killed with SIGTERM";
break;
fi
done

9
waybar/scripts/dunst.sh Executable file
View File

@@ -0,0 +1,9 @@
#!/usr/bin/env bash
isPaused=$(dunstctl is-paused)
notificationCount=$(dunstctl count history)
if [[ "$isPaused" == "true" ]]; then
echo "󰂛 $notificationCount"
else
echo "󰂚 $notificationCount"
fi

View File

@@ -0,0 +1,33 @@
#!/usr/bin/env bash
mediaSourceIcon=$(`dirname $0`/get-media-source-icon.sh)
mediaStatus=$(playerctl --player=playerctld metadata 2>&1)
if [[ "$mediaStatus" == "No player could handle this command" ]]; then
artist="N/A"
title="N/A"
album="N/A"
status="N/A"
else
artist=$(playerctl --player=playerctld metadata --format '{{ xesam:artist }}')
title=$(playerctl --player=playerctld metadata --format '{{ xesam:title }}')
album=$(playerctl --player=playerctld metadata --format '{{ xesam:album }}')
status=$(playerctl --player=playerctld metadata --format '{{ status }}')
if [[ $artist == "" ]]; then
artist="N/A"
fi
if [[ $title == "" ]]; then
title="N/A"
fi
if [[ $album == "" ]]; then
album="N/A"
fi
if [[ $status == "" ]]; then
status="N/A"
fi
fi
echo '{"text":"'$mediaSourceIcon'","tooltip":"󰝚\t'${title//'"'/'\"'}'\r󰠃\t'${artist//'"'/'\"'}'\r󰀥\t'${album//'"'/'\"'}'\r󰐎\t'${status//'"'/'\"'}'"}'

View File

@@ -0,0 +1,27 @@
#!/usr/bin/env bash
mediaStatus=$(playerctl --player=playerctld metadata 2>&1)
if [[ "$mediaStatus" == "No player could handle this command" ]]; then
echo "󰡀"
else
trackid=$(playerctl --player=playerctld metadata --format '{{ mpris:trackid }}')
title=$(playerctl --player=playerctld metadata --format '{{ xesam:title }}')
if grep -q -i "netflix" <<< "$title"; then
echo "󰝆"
elif grep -q -i "hulu" <<< "$title"; then
echo "󰠩"
elif grep -q -i "prime video" <<< "$title"; then
echo ""
elif grep -q -i "youtube tv" <<< "$title"; then
echo "󰑈"
elif grep -q -i "chromium" <<< "$trackid"; then
echo ""
elif grep -q -i "vlc" <<< "$trackid"; then
echo "󰕼"
elif grep -q -i "spotify" <<< "$trackid"; then
echo ""
else
echo "󰡀"
fi
fi

View File

@@ -0,0 +1,12 @@
#!/usr/bin/env bash
mediaStatus=$(`dirname $0`/get-media-status.sh)
if [[ "$mediaStatus" == "N/A" ]]; then
echo "󰐎"
else
if [[ "$mediaStatus" == "Playing" ]]; then
echo "󰏤"
elif [[ "$mediaStatus" == "Paused" ]]; then
echo "󰐊"
fi
fi

View File

@@ -0,0 +1,10 @@
#!/usr/bin/env bash
mediaStatus=$(playerctl --player=playerctld metadata 2>&1)
if [[ "$mediaStatus" == "No player could handle this command" ]]; then
echo "N/A"
else
status=$(playerctl --player=playerctld metadata --format '{{ status }}')
echo $status
fi

View File

@@ -0,0 +1,7 @@
#!/usr/bin/env bash
profile="$(sudo system76-power profile | sed -z '$ s/\n$//' | tr '\n' '\r')"
graphics="$(sudo system76-power graphics)"
graphicsPower="$(sudo system76-power graphics power)"
chargeThresholds="$(sudo system76-power charge-thresholds | sed -z '$ s/\n$//' | tr '\n' '\r')"
echo '{"text":"󰢮 '$graphics'","tooltip":"󰢮\t'$graphics'\r󰐥\t'$graphicsPower'\r\r Profile\r'$profile'\r\r󰚥 Charge Thresholds\r'$chargeThresholds'"}'

View File

@@ -1,66 +1,190 @@
window#waybar {
background: #282a36;
background: transparent;
}
.module {
#window {
padding: 0px 0px;
color: transparent;
background: transparent;
}
widget {
background: #282a36;
border-radius: 25px;
padding: 0px 3px;
}
label.module {
padding: 0px 10px;
}
button {
border-radius: 0px;
padding: 0px 0px;
}
.module,button {
font-size: 15px;
font-family: Ubuntu Nerd Font
font-family: Ubuntu Nerd Font;
}
#battery {
background: #50fa7b;
color: #282a36;
background: transparent;
color: #ff79c6;
}
#cpu {
background: #bd93f9;
color: #282a36;
background: transparent;
color: #ffb86c;
}
#clock {
background: #bd93f9;
color: #282a36;
background: transparent;
color: #bd93f9;
}
box#dunst {
padding: 0px 10px;
}
#custom-dunst-status {
background: transparent;
color: #50fa7b;
padding: 0px 5px;
}
#custom-dunst-clear {
background: transparent;
color: #50fa7b;
padding: 0px 5px;
}
#custom-dunst-history-view {
background: transparent;
color: #50fa7b;
padding: 0px 5px;
}
#custom-dunst-history-clear {
background: transparent;
color: #50fa7b;
padding: 0px 5px;
}
#tags {
color: #f8f8f2;
background: #44475a;
padding: 0px 10px;
}
#tags button {
margin-left: 3px;
margin-right: 3px;
padding: 0px 3px;
background: transparent;
color: #44475a;
padding: 0px 5px;
}
#tags button.occupied {
background: #f1fa8c;
color: #282a36;
background: transparent;
color: #f1fa8c;
}
#tags button.focused {
background: #bd93f9;
color: #282a36;
background: transparent;
box-shadow: inset 0 -3px #bd93f9;
}
#tags button.urgent {
background: #ff5555;
color: #282a36;
background: transparent;
color: #ff5555;
}
#window.title {
background: transparent;
color: #f8f8f2;
padding: 0px 10px;
}
#window.layout {
background: transparent;
color: #50fa7b;
padding: 0px 10px;
}
#disk {
color: #282a36;
background: #ff79c6;
background: transparent;
color: #f1fa8c;
}
#idle_inhibitor.activated {
background: transparent;
color: #f1fa8c;
}
#idle_inhibitor.deactivated {
background: transparent;
color: #44475a;
}
#memory {
color: #282a36;
background: #8be9fd;
background: transparent;
color: #8be9fd;
}
box#media-playing {
padding: 0px 10px;
}
#custom-media-playing-source {
background: transparent;
color: #ff5555;
padding: 0px 5px;
}
#custom-media-playing-prev {
background: transparent;
color: #ff5555;
padding: 0px 5px;
}
#custom-media-playing-play-pause {
background: transparent;
color: #ff5555;
padding: 0px 5px;
}
#custom-media-playing-next {
background: transparent;
color: #ff5555;
padding: 0px 5px;
}
box#power-menu {
padding: 0px 10px;
}
#custom-power-menu-launcher {
background: transparent;
color: #8be9fd;
padding: 0px 5px;
}
#custom-power-menu-shutdown {
background: transparent;
color: #ff5555;
padding: 0px 5px;
}
#custom-power-menu-reboot {
background: transparent;
color: #50fa7b;
padding: 0px 5px;
}
#custom-power-menu-sleep {
background: transparent;
color: #f1fa8c;
padding: 0px 5px;
}
#custom-power-menu-lock {
background: transparent;
color: #ff79c6;
padding: 0px 5px;
}
#custom-power-menu-logout {
background: transparent;
color: #ffb86c;
padding: 0px 5px;
}
#pulseaudio {
color: #282a36;
background: #ff5555;
background: transparent;
color: #ff79c6;
}
#custom-system76-power {
background: transparent;
color: #50fa7b;
}
#tray {
background: #44475a;
background: transparent;
padding: 0px 10px;
}