From 86f980a95e97fc24c0efd7231351e8307e06a66e Mon Sep 17 00:00:00 2001 From: amolinae06 Date: Mon, 26 May 2025 23:29:37 -0600 Subject: [PATCH] minimized fork --- CHANGELOG.md | 14 ++ Makefile | 1 + README.md | 31 +--- config.def.h | 52 +++--- config.h | 235 ++++++++++++-------------- dwl.c | 464 ++++++++++++--------------------------------------- 6 files changed, 254 insertions(+), 543 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a299c4..e79aaff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,24 @@ # Changelog +* [Unreleased](#unreleased) * [0.7](#0.7) * [0.6](#0.6) * [0.5](#0.5) +## Unreleased +### Added +### Changed +### Deprecated +### Removed +### Fixed + +* Crash when a client is created while all outputs are disabled. + +### Security +### Contributors + + ## 0.7 See also [0.6](#0.6) release notes. 0.7 builds against wlroots 0.18.x. diff --git a/Makefile b/Makefile index 9bc67db..984a474 100644 --- a/Makefile +++ b/Makefile @@ -61,6 +61,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 diff --git a/README.md b/README.md index 06d9aad..aa95bab 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # dwl - dwm for Wayland Join us on our IRC channel: [#dwl on Libera Chat] -Or on the community-maintained [Discord server]. +Or on our [Discord server]. dwl is a compact, hackable compositor for [Wayland] based on [wlroots]. It is intended to fill the same space in the Wayland world that dwm does in X11, @@ -12,34 +12,10 @@ philosophy. Like dwm, dwl is: - One C source file (or a very small number) configurable via `config.h` - Tied to as few external dependencies as possible -### Applied patches -- [alwayscenter](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/alwayscenter) -- [attachtop](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/attachtop) -- [autostart](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/autostart) -- [bar](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/bar) -- [barcolors](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/barcolors) -- [barheight](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/barheight) -- [centeredmaster](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/centeredmaster) -- [column](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/column) -- [cursortheme](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/cursortheme) -- [deck](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/deck) -- [en-keycodes](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/en-keycodes) -- [genericgaps](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/genericgaps) -- [hide_vacant_tags](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/hide_vacant_tags) -- [inputdevicerules](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/inputdevicerules) -- [movestack](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/movestack) -- [nextlayout](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/nextlayout) -- [pertag](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/pertag) -- [primaryselection](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/primaryselection) -- [rotatetags](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/rotatetags) -- [setupenv](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/setupenv) -- [sticky](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/sticky) -- [swallow](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/swallow) -- [swallow-freebsd](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/swallow) -- [xkb-rules-switcher](https://codeberg.org/wochap/dwl/src/branch/v0.6-b/xkb-rules-switcher/xkb-rules-switcher.patch) - ## Getting Started: +### **dwl branch 0.7 and releases based upon 0.7 build against [wlroots] 0.18** + ### Latest semi-stable [release] This is probably where you want to start. This builds against the dependent packages' versions currently shipping in major distributions. If your @@ -223,4 +199,3 @@ inspiration, and to the various contributors to the project, including: [wiki]: https://codeberg.org/dwl/dwl/wiki/Home#compatible-status-bars [Discord server]: https://discord.gg/jJxZnrGPWN [Wayland]: https://wayland.freedesktop.org/ - diff --git a/config.def.h b/config.def.h index 21fcb25..f8bd97e 100644 --- a/config.def.h +++ b/config.def.h @@ -6,16 +6,23 @@ /* 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 enablegaps = 1; /* 1 means gaps are enabled */ +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 int user_bh = 30; /* 0 means that dwl will calculate barheight, >= 1 means dwl will use user_bh as the bar height. */ -static const int showbar = 1; /* 0 means no bar */ -static const int topbar = 1; /* 0 means bottom bar */ +static const int showbar = 1; /* 0 means no bar */ +static const int topbar = 1; /* 0 means bottom bar */ static const char *fonts[] = {"monospace:size=10"}; static const float rootcolor[] = COLOR(0x000000ff); /* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */ -static int enableautoswallow = 1; /* enables autoswallowing newly spawned clients */ -static float swallowborder = 1.0f; /* add this multiplied by borderpx to border when a client is swallowed */ +static int enableautoswallow = 1; /* enables autoswallowing newly spawned clients */ +static float swallowborder = 1.0f; /* add this multiplied by borderpx to border when a client is swallowed */ static const char *cursor_theme = NULL; static const char cursor_size[] = "24"; /* Make sure it's a valid integer, otherwise things will break */ static uint32_t colors[][3] = { @@ -38,7 +45,6 @@ static char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; /* logging */ static int log_level = WLR_ERROR; -/* Environment variables */ static const Env envs[] = { /* variable value */ { "XDG_CURRENT_DESKTOP", "wlroots" }, @@ -66,10 +72,7 @@ static const Layout layouts[] = { { "[]=", tile }, { "><>", NULL }, /* no layout function means floating behavior */ { "[M]", monocle }, - { "|M|", centeredmaster }, - { "||", col }, - { "[D]", deck }, - { NULL, NULL }, /* terminate */ + { NULL, NULL }, /* terminate */ }; /* monitors */ @@ -88,16 +91,12 @@ static const MonitorRule monrules[] = { }; /* keyboard */ -static const struct xkb_rule_names xkb_rules[] = { - { - /* can specify fields: rules, model, layout, variant, options */ - .layout = "us", - .options = NULL, - }, - { - .layout = "us", - .options = "compose:ralt", - }, +static const struct xkb_rule_names xkb_rules = { + /* can specify fields: rules, model, layout, variant, options */ + /* example: + .options = "ctrl:nocaps", + */ + .options = NULL, }; /* input devices */ @@ -123,7 +122,6 @@ static const int natural_scrolling = 0; static const int disable_while_typing = 1; static const int left_handed = 0; static const int middle_button_emulation = 0; -static const int enable_primary_selection = 0; /* You can choose between: LIBINPUT_CONFIG_SCROLL_NO_SCROLL LIBINPUT_CONFIG_SCROLL_2FG @@ -183,8 +181,6 @@ static const Key keys[] = { { MODKEY, XKB_KEY_b, togglebar, {0} }, { 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|WLR_MODIFIER_SHIFT, XKB_KEY_i, incnmaster, {.i = -1} }, { MODKEY, XKB_KEY_a, rotatetags, {.i = VIEW_L} }, @@ -215,13 +211,10 @@ 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_c, setlayout, {.v = &layouts[3]} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, setlayout, {.v = &layouts[4]} }, - { MODKEY, XKB_KEY_p, setlayout, {.v = &layouts[5]} }, - { MODKEY, XKB_KEY_space, setlayout, {0} }, - { MODKEY, XKB_KEY_n, nextlayout, {0} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} }, - { MODKEY, XKB_KEY_e, togglefullscreen, {0} }, + { MODKEY, XKB_KEY_space, setlayout, {0} }, + { MODKEY, XKB_KEY_n, nextlayout, {0} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} }, + { MODKEY, XKB_KEY_e, togglefullscreen, {0} }, { MODKEY, XKB_KEY_a, toggleswallow, {0} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_A, toggleautoswallow,{0} }, { MODKEY, XKB_KEY_u, togglepointer, {0} }, @@ -231,7 +224,6 @@ static const Key keys[] = { { MODKEY, XKB_KEY_period, focusmon, {.i = WLR_DIRECTION_RIGHT} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less, tagmon, {.i = WLR_DIRECTION_LEFT} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_greater, tagmon, {.i = WLR_DIRECTION_RIGHT} }, - { MODKEY, XKB_KEY_w, switchxkbrule, {0} }, TAGKEYS( XKB_KEY_1, XKB_KEY_exclam, 0), TAGKEYS( XKB_KEY_2, XKB_KEY_at, 1), TAGKEYS( XKB_KEY_3, XKB_KEY_numbersign, 2), diff --git a/config.h b/config.h index e149441..d0aa193 100644 --- a/config.h +++ b/config.h @@ -3,28 +3,28 @@ ((hex >> 16) & 0xFF) / 255.0f, \ ((hex >> 8) & 0xFF) / 255.0f, \ (hex & 0xFF) / 255.0f } -#include "/home/amolinae/.cache/hellwal/dwl-colors-bar.h" - /* 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 unsigned int borderpx = 2; /* border pixel of windows */ +static const int enablegaps = 1; /* 1 means gaps are enabled */ 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 gappih = 4; /* horiz inner gap between windows */ -static const unsigned int gappiv = 4; /* vert inner gap between windows */ -static const unsigned int gappoh = 1; /* horiz outer gap between windows and screen edge */ -static const unsigned int gappov = 1; /* vert outer gap between windows and screen edge */ -static const char *cursor_theme = "macOS"; -static const char cursor_size[] = "28"; /* Make sure it's a valid integer, otherwise things will break */ +static const unsigned int borderpx = 2; /* border pixel of windows */ +static const unsigned int gappih = 4; /* horiz inner gap between windows */ +static const unsigned int gappiv = 4; /* vert inner gap between windows */ +static const unsigned int gappoh = 1; /* horiz outer gap between windows and screen edge */ +static const unsigned int gappov = 1; /* vert outer gap between windows and screen edge */ static const int user_bh = 30; /* 0 means that dwl will calculate barheight, >= 1 means dwl will use user_bh as the bar height. */ static const int showbar = 1; /* 0 means no bar */ static const int topbar = 1; /* 0 means bottom bar */ static const char *fonts[] = {"Inconsolata:size=12"}; /* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */ -static int enableautoswallow = 1; /* enables autoswallowing newly spawned clients */ +static int enableautoswallow = 1; /* enables autoswallowing newly spawned clients */ static float swallowborder = 1.0f; /* add this multiplied by borderpx to border when a client is swallowed */ +static const char *cursor_theme = "macOS"; +static const char cursor_size[] = "28"; /* Make sure it's a valid integer, otherwise things will break */ +#include "/home/amolinae/.cache/hellwal/dwl-colors-bar.h" enum { VIEW_L = -1, @@ -34,50 +34,47 @@ enum { } RotateTags; /* tagging - TAGCOUNT must be no greater than 31 */ -static char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8" }; +static char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; /* logging */ static int log_level = WLR_ERROR; -/* Environment variables */ static const Env envs[] = { - /* variable value */ - { "XDG_CURRENT_DESKTOP", "wlroots" }, - { "XCURSOR_THEME", "macOS" }, - { "SDL_VIDEODRIVER", "wayland" }, + /* variable value */ + { "XDG_CURRENT_DESKTOP", "wlroots" }, + { "XCURSOR_THEME", "macOS" }, + { "SDL_VIDEODRIVER", "wayland" }, }; /* Autostart */ static const char *const autostart[] = { - "/usr/libexec/xdg-desktop-portal", "-r", NULL, - "/usr/libexec/xdg-desktop-portal-wlr", "-r", NULL, - "wbg", WALLPAPER, NULL, - "foot", "--server", NULL, - "swayidle", NULL, - "mako", NULL, - NULL /* terminate */ + "/usr/libexec/xdg-desktop-portal", "-r", NULL, + "/usr/libexec/xdg-desktop-portal-wlr", "-r", NULL, + "wbg", WALLPAPER, NULL, + "foot", "--server", NULL, + "swayidle", NULL, + "mako", 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 isterm noswallow monitor */ - /* examples: */ - { "foot", NULL, 0, 0, 1, 1, -1 }, /* make foot swallow clients that are not foot */ + /* app_id title tags mask isfloating isterm noswallow monitor */ + /* examples: */ + { "footclient", NULL, 0, 0, 1, 1, -1 }, { "Gimp_EXAMPLE", NULL, 0, 1, 0, 0, -1 }, /* Start on currently visible tags floating, not tiled */ { "firefox_EXAMPLE", NULL, 1 << 8, 0, 0, 0, -1 }, /* Start on ONLY tag "9" */ - { "mpv", "webcam", 0, 1, 0, 0, -1 }, /* Launch camera as floating only*/ + { "mpv", "webcam", 0, 1, 0, 0, -1 }, }; - + /* layout(s) */ static const Layout layouts[] = { /* symbol arrange function */ { "[]=", tile }, { "><>", NULL }, /* no layout function means floating behavior */ { "[M]", monocle }, - { "|M|", centeredmaster }, - { "||", col }, - { "[D]", deck }, - { NULL, NULL }, /* terminate */ + { NULL, NULL }, /* terminate */ }; /* monitors */ @@ -96,23 +93,20 @@ static const MonitorRule monrules[] = { }; /* keyboard */ -static const struct xkb_rule_names xkb_rules[] = { - { - /* can specify fields: rules, model, layout, variant, options */ - .layout = "latam", - .options = NULL, - }, - { - .layout = "us", - .options = NULL, - }, +static const struct xkb_rule_names xkb_rules = { + /* can specify fields: rules, model, layout, variant, options */ + /* example: + .options = "ctrl:nocaps", + */ + .layout = "latam", + .options = NULL, }; /* input devices */ static const InputRule inputrules[] = { /* name kbcreate ptrcreate */ /* ignore bad device - like a touchpad ;) */ - { "Synaptics TM3276-022", NULL, NULL }, + { "Synaptics TM3276-022", NULL, NULL }, /* ungroup ydotool device - fixes a bug */ { "ydotoold virtual device", createungroupedkeyboard, createpointer }, /* put your touchpad name here to enable toggle touchpad */ @@ -131,7 +125,6 @@ static const int natural_scrolling = 0; static const int disable_while_typing = 1; static const int left_handed = 0; static const int middle_button_emulation = 0; -static const int enable_primary_selection = 0; /* You can choose between: LIBINPUT_CONFIG_SCROLL_NO_SCROLL LIBINPUT_CONFIG_SCROLL_2FG @@ -180,78 +173,66 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } /* commands */ -static const char *termcmd[] = { "footclient", NULL }; // Terminal -static const char *menucmd[] = { "fuzzel", NULL }; // Application launcher -static const char *fmgrcmd[] = { "footclient", "--title", "lf", "lf", NULL }; // File manager -static const char *sptfcmd[] = { "footclient", "--title", "Spotify", "spotify_player", NULL }; // Spotify client -static const char *ncmxcmd[] = { "footclient", "--title", "ncpamixer", "ncpamixer", NULL }; // Volume control -static const char *blthcmd[] = { "bluetooth", NULL }; // Bluetooth manager -static const char *pdfrcmd[] = { "zathura", NULL }; // PDF reader -static const char *brwscmd[] = { "librewolf", NULL }; // Web Browser -static const char *lockcmd[] = { "swaylock", NULL }; // Launch swaylock -static const char *camrcmd[] = { "camera", NULL }; // Launch mpv window showing my cameras -static const char *rgsscmd[] = { "rgnss", NULL }; // Region screenshoot -static const char *fssscmd[] = { "fsss", NULL }; // Takes screenshot -static const char *recscmd[] = { "recordscreen", NULL }; // Launch recording menu -static const char *pwmncmd[] = { "powermenu", NULL }; // Launch powermenu -static const char *emojcmd[] = { "tofiunicode", NULL }; // Launch emoji menu -static const char *btopcmd[] = { "footclient", "--title", "btop", "btop", NULL }; // Launch btop -static const char *musicmd[] = { "footclient", "--title", "cmus", "cmus", NULL }; // cmus player +static const char *termcmd[] = { "footclient", NULL }; +static const char *menucmd[] = { "fuzzel", NULL }; +static const char *filecmd[] = { "footclient", "--title", "lf", "lf", NULL }; +static const char *volmcmd[] = { "footclient", "--title", "ncpamixer", "ncpamixer", NULL }; +static const char *sptpcmd[] = { "footclient", "--title", "Spotify", "spotify_player", NULL }; +static const char *editcmd[] = { "footclient", "nvim", NULL }; +static const char *lockcmd[] = { "swaylock", NULL }; +static const char *wcamcmd[] = { "camera", NULL }; +static const char *awsfcmd[] = { "aws", "-f", NULL }; +static const char *awsrcmd[] = { "aws", "-r", NULL }; +static const char *artrcmd[] = { "art", NULL }; +static const char *sysucmd[] = { "sysutils", NULL }; +static const char *emomcmd[] = { "emojimenu", NULL }; static const Key keys[] = { /* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */ /* modifier key function argument */ { MODKEY, XKB_KEY_r, spawn, {.v = menucmd} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = termcmd} }, - { MODKEY, XKB_KEY_e, spawn, {.v = fmgrcmd} }, - { MODKEY, XKB_KEY_s, spawn, {.v = sptfcmd} }, - { MODKEY, XKB_KEY_b, spawn, {.v = blthcmd} }, - //{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_S, spawn, {.v = pdfrcmd} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_R, spawn, {.v = brwscmd} }, - { MODKEY, XKB_KEY_v, spawn, {.v = ncmxcmd} }, + { MODKEY, XKB_KEY_e, spawn, {.v = filecmd} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q, spawn, {.v = sysucmd} }, + { MODKEY, XKB_KEY_v, spawn, {.v = volmcmd} }, + { MODKEY, XKB_KEY_s, spawn, {.v = sptpcmd} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_E, spawn, {.v = editcmd} }, { MODKEY, XKB_KEY_l, spawn, {.v = lockcmd} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, spawn, {.v = camrcmd} }, - { 0, XKB_KEY_Print, spawn, {.v = rgsscmd} }, - { WLR_MODIFIER_SHIFT, XKB_KEY_Print, spawn, {.v = fssscmd} }, - { WLR_MODIFIER_CTRL, XKB_KEY_Print, spawn, {.v = recscmd} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_E, spawn, {.v = emojcmd} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q, spawn, {.v = pwmncmd} }, - { MODKEY, XKB_KEY_Delete, spawn, {.v = btopcmd} }, - { MODKEY, XKB_KEY_m, spawn, {.v = musicmd} }, - { 0, XKB_KEY_XF86AudioMicMute, spawn,SHCMD("wpctl set-mute @DEFAULT_SOURCE@ toggle && pkill -RTMIN+3 slstatus") }, - { WLR_MODIFIER_SHIFT, XKB_KEY_XF86AudioLowerVolume, spawn,SHCMD("wpctl set-volume -l 1.0 @DEFAULT_SOURCE@ 5%- && pkill -RTMIN+3 slstatus") }, - { WLR_MODIFIER_SHIFT, XKB_KEY_XF86AudioRaiseVolume, spawn,SHCMD("wpctl set-volume -l 1.0 @DEFAULT_SOURCE@ 5%+ && pkill -RTMIN+3 slstatus") }, - { 0, XKB_KEY_XF86AudioMute, spawn,SHCMD("wpctl set-mute @DEFAULT_SINK@ toggle && pkill -RTMIN+2 slstatus") }, - { 0, XKB_KEY_XF86AudioLowerVolume, spawn,SHCMD("wpctl set-volume -l 1.0 @DEFAULT_SINK@ 5%- && pkill -RTMIN+3 slstatus") }, - { 0, XKB_KEY_XF86AudioRaiseVolume, spawn,SHCMD("wpctl set-volume -l 1.0 @DEFAULT_SINK@ 5%+ && pkill -RTMIN+2 slstatus") }, - { 0, XKB_KEY_XF86MonBrightnessUp, spawn,SHCMD("brillo -a -u 125000 -q -A 5")}, - { 0, XKB_KEY_XF86MonBrightnessDown,spawn,SHCMD("brillo -a -u 125000 -q -U 5")}, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_B, togglebar, {0} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_S, togglesticky, {0} }, - { MODKEY, XKB_KEY_j, focusstack, {.i = +1} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_c, spawn, {.v = wcamcmd} }, + { WLR_MODIFIER_SHIFT, XKB_KEY_Print, spawn, {.v = awsfcmd} }, + { 0, XKB_KEY_Print, spawn, {.v = awsrcmd} }, + { MODKEY, XKB_KEY_Print, spawn, {.v = artrcmd} }, + { MODKEY, XKB_KEY_q, killclient, {0} }, + { 0, XKB_KEY_XF86AudioMicMute, spawn,SHCMD("setvol -m mute") }, + { WLR_MODIFIER_SHIFT, XKB_KEY_XF86AudioRaiseVolume, spawn,SHCMD("setvol -m up") }, + { WLR_MODIFIER_SHIFT, XKB_KEY_XF86AudioLowerVolume, spawn,SHCMD("setvol -m down") }, + { 0, XKB_KEY_XF86AudioMute, spawn,SHCMD("setvol mute") }, + { 0, XKB_KEY_XF86AudioRaiseVolume, spawn,SHCMD("setvol up") }, + { 0, XKB_KEY_XF86AudioLowerVolume, spawn,SHCMD("setvol down") }, + { 0, XKB_KEY_XF86MonBrightnessUp, spawn,SHCMD("setbr increase")}, + { 0, XKB_KEY_XF86MonBrightnessDown,spawn,SHCMD("setbr decrease")}, + /* + { MODKEY, XKB_KEY_b, togglebar, {0} }, + */ + { 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|WLR_MODIFIER_CTRL, XKB_KEY_q, incnmaster, {.i = -1} }, - { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_e, incnmaster, {.i = +1} }, + { MODKEY, XKB_KEY_i, incnmaster, {.i = +1} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_i, incnmaster, {.i = -1} }, { MODKEY, XKB_KEY_a, rotatetags, {.i = VIEW_L} }, { MODKEY, XKB_KEY_d, rotatetags, {.i = VIEW_R} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_A, rotatetags, {.i = SHIFT_L} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_D, rotatetags, {.i = SHIFT_R} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Z, setmfact, {.f = -0.05f} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_X, setmfact, {.f = +0.05f} }, - { MODKEY, XKB_KEY_w, switchxkbrule, {0} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_a, rotatetags, {.i = SHIFT_L} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_d, rotatetags, {.i = SHIFT_R} }, + { MODKEY, XKB_KEY_z, setmfact, {.f = -0.05f} }, + { MODKEY, XKB_KEY_x, setmfact, {.f = +0.05f} }, /* - { MODKEY, XKB_KEY_h, incgaps, {.i = +1 } }, - { MODKEY, XKB_KEY_l, incgaps, {.i = -1 } }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_H, incogaps, {.i = +1 } }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_L, incogaps, {.i = -1 } }, - { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_h, incigaps, {.i = +1 } }, - { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_l, incigaps, {.i = -1 } }, - */ - { MODKEY, XKB_KEY_0, togglegaps, {0} }, - /* - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, defaultgaps, {0} }, + { 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 } }, @@ -263,51 +244,49 @@ static const Key keys[] = { */ { MODKEY, XKB_KEY_Return, zoom, {0} }, { MODKEY, XKB_KEY_Tab, view, {0} }, - { MODKEY, XKB_KEY_q, killclient, {0} }, - /* - { MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} }, + /* + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, killclient, {0} }, + { MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} }, { MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} }, { MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} }, - { MODKEY, XKB_KEY_c, setlayout, {.v = &layouts[3]} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, setlayout, {.v = &layouts[4]} }, - { MODKEY, XKB_KEY_p, setlayout, {.v = &layouts[5]} }, + { MODKEY, XKB_KEY_space, setlayout, {0} }, */ - { MODKEY, XKB_KEY_n, nextlayout, {0} }, + { MODKEY, XKB_KEY_n, nextlayout, {0} }, + + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_F, togglefullscreen,{0} }, /* - { MODKEY, XKB_KEY_space, setlayout, {0} }, - */ - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_F, togglefullscreen, {0} }, - { MODKEY, XKB_KEY_g, toggleswallow, {0} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_G, toggleautoswallow,{0} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_U, togglepointer, {0} }, + { MODKEY, XKB_KEY_a, toggleswallow, {0} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_A, toggleautoswallow,{0} }, + */ + { MODKEY, XKB_KEY_u, togglepointer, {0} }, /* - { MODKEY, XKB_KEY_0, view, {.ui = ~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} }, { MODKEY, XKB_KEY_period, focusmon, {.i = WLR_DIRECTION_RIGHT} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_semicolon, tagmon, {.i = WLR_DIRECTION_LEFT} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_colon, tagmon, {.i = WLR_DIRECTION_RIGHT} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less, tagmon, {.i = WLR_DIRECTION_LEFT} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_greater, tagmon, {.i = WLR_DIRECTION_RIGHT} }, */ - TAGKEYS( XKB_KEY_1, XKB_KEY_exclam, 0), - TAGKEYS( XKB_KEY_2, XKB_KEY_at, 1), - TAGKEYS( XKB_KEY_3, XKB_KEY_numbersign, 2), + TAGKEYS( XKB_KEY_1, XKB_KEY_exclam, 0), + TAGKEYS( XKB_KEY_2, XKB_KEY_at, 1), + TAGKEYS( XKB_KEY_3, XKB_KEY_numbersign, 2), TAGKEYS( XKB_KEY_4, XKB_KEY_dollar, 3), TAGKEYS( XKB_KEY_5, XKB_KEY_percent, 4), TAGKEYS( XKB_KEY_6, XKB_KEY_asciicircum, 5), TAGKEYS( XKB_KEY_7, XKB_KEY_ampersand, 6), TAGKEYS( XKB_KEY_8, XKB_KEY_asterisk, 7), TAGKEYS( XKB_KEY_9, XKB_KEY_parenleft, 8), - /* + /* { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q, quit, {0} }, - */ + */ /* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */ { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} }, /* Ctrl-Alt-Fx is used to switch to another VT, if you don't know what a VT is * do not remove them. */ - #define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} } +#define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} } CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6), CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12), }; diff --git a/dwl.c b/dwl.c index 3a4251f..e161ab1 100644 --- a/dwl.c +++ b/dwl.c @@ -69,14 +69,6 @@ #include #endif -#ifdef __FreeBSD__ -#define __BSD_VISIBLE -#include -#include -#include -#include -#endif - #include "util.h" #include "drwl.h" @@ -84,7 +76,7 @@ #define MAX(A, B) ((A) > (B) ? (A) : (B)) #define MIN(A, B) ((A) < (B) ? (A) : (B)) #define CLEANMASK(mask) (mask & ~WLR_MODIFIER_CAPS) -#define VISIBLEON(C, M) ((M) && (C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags]) && !(C)->swallowedby) +#define VISIBLEON(C, M) ((M) && (C)->mon == (M) && (((C)->tags & (M)->tagset[(M)->seltags]) || C->issticky) && !(C)->swallowedby) #define LENGTH(X) (sizeof X / sizeof X[0]) #define END(A) ((A) + LENGTH(A)) #define TAGMASK ((1u << LENGTH(tags)) - 1) @@ -92,7 +84,6 @@ #define LISTEN_STATIC(E, H) do { static struct wl_listener _l = {.notify = (H)}; wl_signal_add((E), &_l); } while (0) #define BORDERPX(C) (borderpx + ((C)->swallowing ? (int)ceilf(swallowborder * (C)->swallowing->bw) : 0)) #define TEXTW(mon, text) (drwl_font_getwidth(mon->drw, text) + mon->lrpad) -#define PREFIX(str, prefix) !strncmp(str, prefix, strlen(prefix)) /* enums */ enum { SchemeNorm, SchemeSel, SchemeUrg }; /* color schemes */ @@ -126,7 +117,6 @@ typedef struct Client Client; struct Client { /* Must keep these three elements in this order */ unsigned int type; /* XDGShell or X11* */ - int interact; struct wlr_box geom; /* layout-relative, includes border */ Monitor *mon; struct wlr_scene_tree *scene; @@ -159,12 +149,12 @@ struct Client { #endif unsigned int bw; uint32_t tags; - int isfloating, isurgent, isfullscreen, issticky; + int isfloating, isurgent, isfullscreen, issticky; int isterm, noswallow; - uint32_t resize; /* configure serial of a pending resize */ - pid_t pid; - Client *swallowing; /* client being hidden */ - Client *swallowedby; + uint32_t resize; /* configure serial of a pending resize */ + pid_t pid; + Client *swallowing; /* client being hidden */ + Client *swallowedby; }; typedef struct { @@ -244,11 +234,12 @@ struct Monitor { struct wlr_box w; /* window area, layout-relative */ struct wl_list layers[4]; /* LayerSurface.link */ const Layout *lt[2]; - Pertag *pertag; - int gappih; /* horizontal gap between windows */ + int enablegaps; /* enable gaps, used by togglegaps */ + int gappih; /* horizontal gap between windows */ int gappiv; /* vertical gap between windows */ int gappoh; /* horizontal outer gaps */ int gappov; /* vertical outer gaps */ + Pertag *pertag; unsigned int seltags; unsigned int sellt; uint32_t tagset[2]; @@ -305,6 +296,7 @@ typedef struct { static void applybounds(Client *c, struct wlr_box *bbox); static void applyrules(Client *c); static void arrange(Monitor *m); +void arrangegaps(Monitor *m); static void arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int exclusive); static void arrangelayers(Monitor *m); @@ -318,13 +310,11 @@ static void bufdataend(struct wlr_buffer *buffer); static Buffer *bufmon(Monitor *m); static void bufrelease(struct wl_listener *listener, void *data); static void buttonpress(struct wl_listener *listener, void *data); -static void centeredmaster(Monitor *m); static void chvt(const Arg *arg); static void checkidleinhibitor(struct wlr_surface *exclude); static void cleanup(void); static void cleanupmon(struct wl_listener *listener, void *data); static void closemon(Monitor *m); -static void col(Monitor *m); static void commitlayersurfacenotify(struct wl_listener *listener, void *data); static void commitnotify(struct wl_listener *listener, void *data); static void commitpopup(struct wl_listener *listener, void *data); @@ -345,7 +335,6 @@ static void cursorconstrain(struct wlr_pointer_constraint_v1 *constraint); static void cursorframe(struct wl_listener *listener, void *data); static void cursorwarptohint(void); static void defaultgaps(const Arg *arg); -static void deck(Monitor *m); static void destroydecoration(struct wl_listener *listener, void *data); static void destroydragicon(struct wl_listener *listener, void *data); static void destroyidleinhibitor(struct wl_listener *listener, void *data); @@ -360,7 +349,6 @@ static void destroykeyboardgroup(struct wl_listener *listener, void *data); static Monitor *dirtomon(enum wlr_direction dir); static void drawbar(Monitor *m); static void drawbars(void); -static int drawstatus(Monitor *m); static void focusclient(Client *c, int lift); static void focusmon(const Arg *arg); static void focusstack(const Arg *arg); @@ -386,7 +374,6 @@ 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 monocle(Monitor *m); -static void movestack(const Arg *arg); 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); @@ -399,14 +386,14 @@ static void outputmgrtest(struct wl_listener *listener, void *data); static pid_t parentpid(pid_t pid); static void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, uint32_t time); +static void preparegaps(Monitor *m); static void powermgrsetmode(struct wl_listener *listener, void *data); static void quit(const Arg *arg); static void rendermon(struct wl_listener *listener, void *data); static void requestdecorationmode(struct wl_listener *listener, void *data); static void requeststartdrag(struct wl_listener *listener, void *data); static void requestmonstate(struct wl_listener *listener, void *data); -static void resizeapply(Client *c, struct wlr_box geo, int interact); -static void resizenoapply(Client *c, struct wlr_box geo, int interact); +static void resize(Client *c, struct wlr_box geo, int interact); static void run(char *startup_cmd); static void setcursor(struct wl_listener *listener, void *data); static void setcursorshape(struct wl_listener *listener, void *data); @@ -425,7 +412,6 @@ static void spawn(const Arg *arg); static void startdrag(struct wl_listener *listener, void *data); static void swallow(Client *c, Client *toswallow); static int statusin(int fd, unsigned int mask, void *data); -static void switchxkbrule(const Arg *arg); static void tag(const Arg *arg); static void tagmon(const Arg *arg); static Client *termforwin(Client *c); @@ -505,7 +491,6 @@ static struct wl_listener lock_listener = {.notify = locksession}; static struct wlr_seat *seat; static KeyboardGroup *kb_group; static unsigned int cursor_mode; -static unsigned int xkb_rule_index = 0; static Client *grabc; static int grabcx, grabcy; /* client-relative */ @@ -514,7 +499,7 @@ static struct wlr_box sgeom; static struct wl_list mons; static Monitor *selmon; -static char stext[512]; +static char stext[256]; static struct wl_event_source *status_event_source; static const struct wlr_buffer_impl buffer_impl = { @@ -523,19 +508,14 @@ static const struct wlr_buffer_impl buffer_impl = { .end_data_ptr_access = bufdataend, }; -static int enablegaps = 1; /* enables gaps, used by togglegaps */ -static void (*resize)(Client *c, struct wlr_box geo, int interact) = resizeapply; - -static struct libinput_device *togglepointerdevice = NULL; - static const struct xkb_rule_names en_rules = {.layout = "us"}; static struct xkb_context *en_context; static struct xkb_keymap *en_keymap; static struct xkb_state *en_state; -static struct xkb_context *en_context; -static struct xkb_keymap *en_keymap; -static struct xkb_state *en_state; +static int resizelock = 0; /* do not actually resize during arrange */ + +static struct libinput_device *togglepointerdevice = NULL; #ifdef XWAYLAND static void activatex11(struct wl_listener *listener, void *data); @@ -630,25 +610,9 @@ applyrules(Client *c) setmon(c, mon, newtags); } -void -applygaps(Client *c) -{ - struct wlr_box geom = c->geom; - - if (!c->mon) - return; - - geom.x += c->mon->gappih + c->mon->gappoh; - geom.y += c->mon->gappiv + c->mon->gappov; - geom.width -= c->mon->gappih; - geom.height -= c->mon->gappiv; - resize(c, geom, 0); -} - void arrange(Monitor *m) { - int save_width, save_height; Client *c; if (!m->wlr_output->enabled) @@ -681,29 +645,51 @@ arrange(Monitor *m) } if (m->lt[m->sellt]->arrange) { - save_width = m->w.width; - save_height = m->w.height; - if (enablegaps) { - m->w.width -= m->gappih + 2 * m->gappoh; - m->w.height -= m->gappiv + 2 * m->gappov; - } - resize = resizenoapply; + preparegaps(m); m->lt[m->sellt]->arrange(m); - wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) - continue; - if (enablegaps) - applygaps(c); - resizeapply(c, c->geom, c->interact); - } - m->w.width = save_width; - m->w.height = save_height; - resize = resizeapply; + arrangegaps(m); } motionnotify(0, NULL, 0, 0, 0, 0); checkidleinhibitor(NULL); } +void +arrangegaps(Monitor *m) +{ + Client *c; + int n, gaps; + + if (!m->enablegaps) + return; + + resizelock = 0; + + n = 0; + wl_list_for_each(c, &clients, link) { + if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) + continue; + n++; + } + + gaps = !(smartgaps && n == 1) && + (monoclegaps || m->lt[m->sellt]->arrange != monocle); + if (gaps) { + m->w.width += m->gappih + 2 * m->gappoh; + m->w.height += m->gappiv + 2 * m->gappov; + } + wl_list_for_each(c, &clients, link) { + if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) + continue; + if (gaps) { + c->geom.x += c->mon->gappih + c->mon->gappoh; + c->geom.y += c->mon->gappiv + c->mon->gappov; + c->geom.width -= c->mon->gappih; + c->geom.height -= c->mon->gappiv; + } + resize(c, c->geom, 0); + } +} + void arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int exclusive) { @@ -911,7 +897,7 @@ buttonpress(struct wl_listener *listener, void *data) (node = wlr_scene_node_at(&layers[LyrBottom]->node, cursor->x, cursor->y, NULL, NULL)) && (buffer = wlr_scene_buffer_from_node(node)) && buffer == selmon->scene_buffer) { cx = (cursor->x - selmon->m.x) * selmon->wlr_output->scale; - wl_list_for_each(c, &clients, link) { + wl_list_for_each(c, &clients, link) { if (c->mon != selmon) continue; occ |= c->tags == TAGMASK ? 0 : c->tags; @@ -967,69 +953,6 @@ buttonpress(struct wl_listener *listener, void *data) event->time_msec, event->button, event->state); } -void -centeredmaster(Monitor *m) -{ - unsigned int h, mw, mx, my, oty, ety, tw; - int i, n; - Client *c; - - n = 0; - wl_list_for_each(c, &clients, link) - if (VISIBLEON(c, m) && !c->isfloating && !c->isfullscreen) - n++; - if (n == 0) - return; - - /* initialize areas */ - mw = m->w.width; - mx = 0; - my = 0; - tw = mw; - - if (n > m->nmaster) { - /* go mfact box in the center if more than nmaster clients */ - mw = round(m->nmaster ? m->w.width * m->mfact : 0); - tw = m->w.width - mw; - - if (n - m->nmaster > 1) { - /* only one client */ - mx = (m->w.width - mw) / 2; - tw = (m->w.width - mw) / 2; - } - } - - i = 0; - oty = 0; - ety = 0; - wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) - continue; - if (i < m->nmaster) { - /* nmaster clients are stacked vertically, in the center - * of the screen */ - h = (m->w.height - my) / (MIN(n, m->nmaster) - i); - resize(c, (struct wlr_box){.x = m->w.x + mx, .y = m->w.y + my, .width = mw, - .height = h}, 0); - my += c->geom.height; - } else { - /* stack clients are stacked vertically */ - if ((i - m->nmaster) % 2) { - h = (m->w.height - ety) / ( (1 + n - i) / 2); - resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + ety, .width = tw, - .height = h}, 0); - ety += c->geom.height; - } else { - h = (m->w.height - oty) / ((1 + n - i) / 2); - resize(c, (struct wlr_box){.x = m->w.x + mx + mw, .y = m->w.y + oty, .width = tw, - .height = h}, 0); - oty += c->geom.height; - } - } - i++; - } -} - void chvt(const Arg *arg) { @@ -1158,33 +1081,6 @@ closemon(Monitor *m) drawbars(); } -void -col(Monitor *m) -{ - Client *c; - unsigned int n = 0, i = 0; - - wl_list_for_each(c, &clients, link) - if (VISIBLEON(c, m) && !c->isfloating && !c->isfullscreen) - n++; - - wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) - continue; - resize( - c, - (struct wlr_box){ - .x = m->w.x + i * m->w.width / n, - .y = m->w.y, - .width = m->w.width / n, - .height = m->w.height - }, - 0 - ); - i++; - } -} - void commitlayersurfacenotify(struct wl_listener *listener, void *data) { @@ -1234,8 +1130,10 @@ commitnotify(struct wl_listener *listener, void *data) * a wrong monitor. */ applyrules(c); - wlr_surface_set_preferred_buffer_scale(client_surface(c), (int)ceilf(c->mon->wlr_output->scale)); - wlr_fractional_scale_v1_notify_scale(client_surface(c), c->mon->wlr_output->scale); + if (c->mon) { + wlr_surface_set_preferred_buffer_scale(client_surface(c), (int)ceilf(c->mon->wlr_output->scale)); + wlr_fractional_scale_v1_notify_scale(client_surface(c), c->mon->wlr_output->scale); + } setmon(c, NULL, 0); /* Make sure to reapply rules in mapnotify() */ wlr_xdg_toplevel_set_wm_capabilities(c->surface.xdg->toplevel, WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); @@ -1324,7 +1222,7 @@ createkeyboardgroup(void) /* Prepare an XKB keymap and assign it to the keyboard group. */ context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - if (!(keymap = xkb_keymap_new_from_names(context, &xkb_rules[xkb_rule_index], + if (!(keymap = xkb_keymap_new_from_names(context, &xkb_rules, XKB_KEYMAP_COMPILE_NO_FLAGS))) die("failed to compile keymap"); @@ -1420,13 +1318,14 @@ createmon(struct wl_listener *listener, void *data) for (i = 0; i < LENGTH(m->layers); i++) wl_list_init(&m->layers[i]); - wlr_output_state_init(&state); - /* Initialize monitor state using configured rules */ - + m->enablegaps = enablegaps; 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; for (r = monrules; r < END(monrules); r++) { if (!r->name || strstr(wlr_output->name, r->name)) { @@ -1659,46 +1558,10 @@ defaultgaps(const Arg *arg) setgaps(gappoh, gappov, gappih, gappiv); } -void -deck(Monitor *m) -{ - unsigned int mw, my; - int i, n = 0; - Client *c; - - wl_list_for_each(c, &clients, link) - if (VISIBLEON(c, m) && !c->isfloating && !c->isfullscreen) - n++; - if (n == 0) - return; - - if (n > m->nmaster) - mw = m->nmaster ? round(m->w.width * m->mfact) : 0; - else - mw = m->w.width; - i = my = 0; - wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) - continue; - if (i < m->nmaster) { - resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + my, .width = mw, - .height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0); - my += c->geom.height; - } else { - resize(c, (struct wlr_box){.x = m->w.x + mw, .y = m->w.y, - .width = m->w.width - mw, .height = m->w.height}, 0); - if (c == focustop(m)) - wlr_scene_node_raise_to_top(&c->scene->node); - } - i++; - } -} - void destroydecoration(struct wl_listener *listener, void *data) { 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); @@ -1875,8 +1738,11 @@ drawbar(Monitor *m) return; /* draw status first so it can be overdrawn by tags later */ - if (m == selmon) /* status is only drawn on selected monitor */ - tw = drawstatus(m); + if (m == selmon) { /* status is only drawn on selected monitor */ + drwl_setscheme(m->drw, colors[SchemeNorm]); + tw = TEXTW(m, stext) - m->lrpad + 2; /* 2px right padding */ + drwl_text(m->drw, m->b.width - tw, 0, tw, m->b.height, 0, stext, 0); + } wl_list_for_each(c, &clients, link) { if (c->mon != m) @@ -1928,88 +1794,6 @@ drawbars(void) drawbar(m); } -int -drawstatus(Monitor *m) -{ - int x, tw, iw; - char rstext[512] = ""; - char *p, *argstart, *argend, *itext; - uint32_t scheme[3], *color; - - /* calculate real width of stext */ - for (p = stext; *p; p++) { - if (PREFIX(p, "^^")) { - strncat(rstext, p, 2); - p++; - } else if (PREFIX(p, "^fg(") || PREFIX(p, "^bg(")) { - argend = strchr(p, ')'); - if (!argend) { /* ignore this command */ - argstart = strchr(p, '(') + 1; - strncat(rstext, p, argstart - p); - p = argstart - 1; - } else { - p = argend; - } - } else { - strncat(rstext, p, 1); - } - } - tw = TEXTW(m, rstext) - m->lrpad; - - x = m->b.width - tw; - itext = stext; - scheme[0] = colors[SchemeNorm][0]; - scheme[1] = colors[SchemeNorm][1]; - drwl_setscheme(m->drw, scheme); - for (p = stext; *p; p++) { - if (PREFIX(p, "^^")) { - p++; - } else if (PREFIX(p, "^fg(") || PREFIX(p, "^bg(")) { - argstart = strchr(p, '(') + 1; - argend = strchr(argstart, ')'); - if (!argend) { /* ignore this command */ - p = argstart - 1; - continue; - } - - *p = '\0'; - iw = TEXTW(m, itext) - m->lrpad; - if (*itext) /* only draw text if there is something to draw */ - x = drwl_text(m->drw, x, 0, iw, m->b.height, 0, itext, 0); - *p = '^'; - - if (PREFIX(p, "^fg(")) - color = &scheme[0]; - else - color = &scheme[1]; - - if (argend != argstart) { - *argend = '\0'; - *color = strtoul(argstart, NULL, 16); - *color = *color << 8 | 0xff; /* add alpha channel */ - *argend = ')'; - } else { - *color = 0; /* reset */ - } - - /* reset color back to normal if none was provided */ - if (!scheme[0]) - scheme[0] = colors[SchemeNorm][0]; - if (!scheme[1]) - scheme[1] = colors[SchemeNorm][1]; - - itext = argend + 1; - drwl_setscheme(m->drw, scheme); - p = argend; - } - } - iw = TEXTW(m, itext) - m->lrpad; - if (*itext) - drwl_text(m->drw, x, 0, iw, m->b.height, 0, itext, 0); - - return tw; -} - void focusclient(Client *c, int lift) { @@ -2579,48 +2363,6 @@ 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 (&c->link == &clients) { - c = wl_container_of(&clients, c, link); - break; /* wrap past the sentinel node */ - } - if (VISIBLEON(c, selmon) || &c->link == &clients) { - break; /* found it */ - } - } - } else { - wl_list_for_each_reverse(c, &sel->link, link) { - if (&c->link == &clients) { - c = wl_container_of(&clients, c, link); - break; /* wrap past the sentinel node */ - } - 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) { @@ -2852,6 +2594,31 @@ outputmgrtest(struct wl_listener *listener, void *data) outputmgrapplyortest(config, 1); } +void +preparegaps(Monitor *m) +{ + Client *c; + int n; + + if (!m->enablegaps) + return; + + n = 0; + wl_list_for_each(c, &clients, link) { + if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) + continue; + n++; + } + + resizelock = 1; + + if ((smartgaps && n == 1) || (!monoclegaps && m->lt[m->sellt]->arrange == monocle)) + return; + + m->w.width -= m->gappih + 2 * m->gappoh; + m->w.height -= m->gappiv + 2 * m->gappov; +} + pid_t parentpid(pid_t pid) { @@ -3000,11 +2767,16 @@ requestmonstate(struct wl_listener *listener, void *data) } void -resizeapply(Client *c, struct wlr_box geo, int interact) +resize(Client *c, struct wlr_box geo, int interact) { struct wlr_box *bbox; struct wlr_box clip; + if (resizelock) { + c->geom = geo; + return; + } + if (!c->mon || !client_surface(c)->mapped) return; @@ -3032,13 +2804,6 @@ resizeapply(Client *c, struct wlr_box geo, int interact) wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip); } -void -resizenoapply(Client *c, struct wlr_box geo, int interact) -{ - c->geom = geo; - c->interact = interact; -} - void run(char *startup_cmd) { @@ -3342,8 +3107,7 @@ setup(void) wlr_export_dmabuf_manager_v1_create(dpy); wlr_screencopy_manager_v1_create(dpy); wlr_data_control_manager_v1_create(dpy); - if (enable_primary_selection) - wlr_primary_selection_v1_device_manager_create(dpy); + wlr_primary_selection_v1_device_manager_create(dpy); wlr_viewporter_create(dpy); wlr_single_pixel_buffer_manager_v1_create(dpy); wlr_fractional_scale_manager_v1_create(dpy, 1); @@ -3467,8 +3231,7 @@ setup(void) seat = wlr_seat_create(dpy, "seat0"); LISTEN_STATIC(&seat->events.request_set_cursor, setcursor); LISTEN_STATIC(&seat->events.request_set_selection, setsel); - if (enable_primary_selection) - LISTEN_STATIC(&seat->events.request_set_primary_selection, setpsel); + LISTEN_STATIC(&seat->events.request_set_primary_selection, setpsel); LISTEN_STATIC(&seat->events.request_start_drag, requeststartdrag); LISTEN_STATIC(&seat->events.start_drag, startdrag); @@ -3551,21 +3314,6 @@ statusin(int fd, unsigned int mask, void *data) return 0; } -void -switchxkbrule(const Arg *arg) -{ - struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - struct xkb_keymap *keymap; - - xkb_rule_index = (xkb_rule_index + 1) % LENGTH(xkb_rules); - if (!(keymap = xkb_keymap_new_from_names(context, &xkb_rules[xkb_rule_index], - XKB_KEYMAP_COMPILE_NO_FLAGS))) - die("failed to compile keymap"); - wlr_keyboard_set_keymap(&kb_group->wlr_group->keyboard, keymap); - xkb_keymap_unref(keymap); - xkb_context_unref(context); -} - void swallow(Client *c, Client *toswallow) { @@ -3721,7 +3469,9 @@ togglefullscreen(const Arg *arg) void togglegaps(const Arg *arg) { - enablegaps = !enablegaps; + if (!selmon) + return; + selmon->enablegaps = !selmon->enablegaps; arrange(selmon); } @@ -4295,7 +4045,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);