dwm

Kris's build of dwm
git clone git clone https://git.krisyotam.com/krisyotam/dwm.git
Log | Files | Refs | README | LICENSE

CLAUDE.md (10671B)


      1 # DWM - Development Rules
      2 
      3 ## Build System: dwm-flexipatch
      4 
      5 This is a **flexipatch** build. Patches are toggled via `#define` flags, NOT by applying `.diff` files.
      6 
      7 ### Critical File Hierarchy
      8 
      9 | File | Role | Committed? |
     10 |------|------|------------|
     11 | `config.def.h` | **Source of truth** for all configuration | YES |
     12 | `patches.def.h` | **Source of truth** for patch enable/disable flags | YES |
     13 | `config.h` | Local working copy (generated from `config.def.h`) | NO (gitignored) |
     14 | `patches.h` | Local working copy (generated from `patches.def.h`) | NO (gitignored) |
     15 | `config.mk` | Compiler/linker flags, library paths | YES |
     16 | `dwm.c` | Core window manager (includes config.h at line 878) | YES |
     17 | `patch/*.c` `patch/*.h` | Patch implementations and headers | YES |
     18 | `patch/include.c` `patch/include.h` | Conditional patch includes (do NOT edit by hand) | YES |
     19 
     20 ### Rules for Editing Configuration
     21 
     22 1. **ALWAYS edit `config.def.h`** for keybindings, layouts, rules, colors, and custom functions.
     23 2. **ALWAYS edit `patches.def.h`** to enable/disable patches (`#define PATCH_NAME 0` or `1`).
     24 3. **ALSO update `config.h` and `patches.h`** to match, so local builds work without regenerating.
     25 4. **NEVER edit only `config.h` or `patches.h`** — those are gitignored and will be lost.
     26 5. When `config.h` does not exist, `make` generates it by copying `config.def.h`. Same for `patches.h`.
     27 
     28 ### Build & Deploy Process
     29 
     30 **Local build (this desktop):**
     31 ```bash
     32 cd /home/krisyotam/dev/dwm
     33 sudo make clean install
     34 ```
     35 
     36 **Deploy to laptop (khr1st):**
     37 ```bash
     38 # 1. Commit and push from desktop
     39 cd /home/krisyotam/dev/dwm
     40 git add config.def.h patches.def.h
     41 git commit -m "description"
     42 git push
     43 
     44 # 2. SSH to laptop, pull, rebuild
     45 ssh khr1st
     46 cd ~/.local/src/dwm && git pull && sudo make clean install
     47 
     48 # 3. Self-restart dwm (preserves all windows — no session kill)
     49 # Trigger via sysact menu or a keybinding mapped to self_restart
     50 ```
     51 
     52 **NEVER** tell the user to "restart dwm" or "log out and back in" without mentioning self_restart. The SELFRESTART_PATCH is enabled and does an in-place `execv()` that preserves all window positions.
     53 
     54 ---
     55 
     56 ## Suckless Coding Style
     57 
     58 Reference: https://suckless.org/coding_style/
     59 
     60 The following are guidelines. The most important aspect of style is **consistency**.
     61 
     62 Recommended reading:
     63 - https://man.openbsd.org/style
     64 - http://doc.cat-v.org/bell_labs/pikestyle
     65 - https://www.kernel.org/doc/Documentation/process/coding-style.rst
     66 
     67 ### File Layout
     68 
     69 Organize files in this order:
     70 
     71 1. Comment with LICENSE and file/tool explanation
     72 2. Headers
     73 3. Macros
     74 4. Types
     75 5. Function declarations (include variable names; group logically)
     76 6. Global variables
     77 7. Function definitions matching declaration order
     78 8. `main`
     79 
     80 ### C Features
     81 
     82 - Use **C99 without extensions** (ISO/IEC 9899:1999).
     83 - Use **POSIX.1-2008**: define `_POSIX_C_SOURCE 200809L` or `_XOPEN_SOURCE 700`.
     84 - **Do not mix declarations and code.**
     85 - **Do not use for loop initial declarations** (e.g., `for (int i = 0; ...)`).
     86 - Use `/* */` for comments, **not `//`**.
     87 - Variadic macros are acceptable but be cautious with `__VA_ARGS__`.
     88 
     89 ### Blocks
     90 
     91 - All variable declarations at the **top of the block**.
     92 - `{` on the same line, preceded by a single space (except for function definitions).
     93 - `}` on its own line unless continuing a statement (`} else {`).
     94 
     95 Use blocks for single statements only when the inner statement needs blocks:
     96 ```c
     97 for (;;) {
     98 	if (foo) {
     99 		bar;
    100 		baz;
    101 	}
    102 }
    103 ```
    104 
    105 Use blocks when any branch requires them:
    106 ```c
    107 if (foo) {
    108 	bar;
    109 } else {
    110 	baz;
    111 	qux;
    112 }
    113 ```
    114 
    115 ### Leading Whitespace
    116 
    117 - Use **tabs for indentation** and **spaces for alignment**.
    118 - No tabs except at the beginning of a line.
    119 - Use **spaces** (not tabs) for multiline macros, as the indentation level is 0.
    120 
    121 ### Functions
    122 
    123 - Return type and modifiers on a **separate line**.
    124 - Function name and argument list on the next line.
    125 - Opening `{` on its **own line** (function definitions only).
    126 - Functions not used outside the translation unit must be `static`.
    127 
    128 ```c
    129 static void
    130 usage(void)
    131 {
    132 	eprintf("usage: %s [file ...]\n", argv0);
    133 }
    134 ```
    135 
    136 ### Variables
    137 
    138 - Global variables not used outside the translation unit must be `static`.
    139 - In pointer declarations, `*` is adjacent to the **variable name**, not the type:
    140   ```c
    141   char *p;    /* correct */
    142   char* p;    /* wrong */
    143   ```
    144 
    145 ### Keywords
    146 
    147 - Use a **space after** `if`, `for`, `while`, `switch` (they are not function calls).
    148 - **No space** after `(` or before `)`.
    149 - Preferably use `()` with `sizeof`.
    150 - **No space** with `sizeof()`:
    151   ```c
    152   sizeof(int)   /* correct */
    153   sizeof (int)  /* wrong */
    154   ```
    155 
    156 ### Switch Statements
    157 
    158 - **Do not indent cases** another level.
    159 - **Comment cases that fall through.**
    160 
    161 ```c
    162 switch (value) {
    163 case 0: /* FALLTHROUGH */
    164 case 1:
    165 case 2:
    166 	break;
    167 default:
    168 	break;
    169 }
    170 ```
    171 
    172 ### Headers
    173 
    174 - Place **system/libc headers first**, in alphabetical order.
    175 - Add comments if a specific inclusion order is required.
    176 - Place **local headers after an empty line**.
    177 - Avoid cyclic dependencies; include headers only where needed.
    178 
    179 ### User Defined Types
    180 
    181 - **Do not use `type_t` naming** (reserved for POSIX, less readable).
    182 - Typedef opaque structs.
    183 - **Do not typedef builtin types.**
    184 - Use **`CamelCase`** for typedef'd types.
    185 
    186 ### Line Length
    187 
    188 Keep lines to a reasonable length: **max 79 characters**.
    189 
    190 ### Tests and Boolean Values
    191 
    192 - **Do not use C99 `bool`** types. Stick to integer types.
    193 - Use compound assignment and tests unless lines grow too long:
    194   ```c
    195   if (!(p = malloc(sizeof(*p))))
    196   	hcf();
    197   ```
    198 
    199 ### Error Handling
    200 
    201 - When functions return `-1` for error, **test against `0`**, not `-1`:
    202   ```c
    203   if (func() < 0)
    204   	hcf();
    205   ```
    206 - Use `goto` to unwind and cleanup when necessary, instead of multiple nested levels.
    207 - `return` or `exit` early on failures instead of deeply nesting.
    208 - Unreachable code should have a `/* NOTREACHED */` comment.
    209 - For fatal errors in one-shot programs, memory freeing may be skipped, but temporary files should be cleaned.
    210 
    211 ### Enums and #define
    212 
    213 Use enums for semantically grouped values. Use `#define` otherwise:
    214 ```c
    215 #define MAXSZ  4096
    216 #define MAGIC1 0xdeadbeef
    217 
    218 enum {
    219 	DIRECTION_X,
    220 	DIRECTION_Y,
    221 	DIRECTION_Z
    222 };
    223 ```
    224 
    225 ---
    226 
    227 ## DWM-Specific Conventions
    228 
    229 ### Naming in dwm
    230 
    231 - `CamelCase` for types and structs: `Client`, `Monitor`, `Layout`, `Key`, `Button`
    232 - `lowercase` or `lowercasemultiword` for functions: `focusmon`, `tagmon`, `sendmon`, `killclient`
    233 - `UPPERCASE` for macros and constants: `MODKEY`, `NUMTAGS`, `CLEANMASK`, `SHCMD`
    234 - Enum values: `SchemeNorm`, `SchemeSel`, `NetSupported`
    235 
    236 ### Comments in Config Files
    237 
    238 - `/* C89-style block comments */` in `.c` source files (mandatory per suckless style).
    239 - `// C99 inline comments` are acceptable in `config.def.h` for brief binding annotations only.
    240 - Preprocessor guards: `#endif // PATCH_NAME`
    241 
    242 ### Conditional Compilation (Patch Guards)
    243 
    244 ```c
    245 #if SOME_PATCH
    246 /* patch-specific code */
    247 #endif // SOME_PATCH
    248 ```
    249 - Always include the patch name in the `#endif` comment.
    250 - Custom (non-patch) code added to `config.def.h` does NOT need guards.
    251 
    252 ### Adding a Custom Function in config.def.h
    253 
    254 Custom functions go **before** the `static const Key keys[]` array. They can reference any forward-declared function from `dwm.c` (`sendmon`, `focusmon`, `arrange`, `focus`, `selmon`, `mons`, etc.) because `config.h` is included after all declarations in `dwm.c` (line 878).
    255 
    256 ---
    257 
    258 ## Layout Array Reference
    259 
    260 The layout array uses **flextile-deluxe**. Index matters for keybindings.
    261 
    262 | Index | Symbol | Layout | Notes |
    263 |-------|--------|--------|-------|
    264 | 0 | `[]=` | Tile | Default |
    265 | 1 | `><>` | Floating | |
    266 | 2 | `[M]` | Monocle | |
    267 | 3 | `\|\|\|` | Columns | |
    268 | 4 | `>M>` | Floating master | |
    269 | 5 | `[D]` | Deck | |
    270 | 6 | `TTT` | Bottom stack | |
    271 | 7 | `===` | Bottom stack horiz | |
    272 | 8 | `\|M\|` | Centered master | |
    273 | 9 | `-M-` | Centered master horiz | |
    274 | 10 | `:::` | Gappless grid | |
    275 | 11 | `[\\]` | Fibonacci dwindle | |
    276 | 12 | `(@)` | Fibonacci spiral | |
    277 | 13 | `[T]` | Tatami mats | |
    278 | 14 | `RRR` | Reading mode (3 vertical panes) | Custom: nmaster=3 |
    279 
    280 **When referencing layouts in keybindings, ALWAYS verify the index by counting from 0 in the `layouts[]` array.** Off-by-one errors here cause the wrong layout to activate with no obvious error.
    281 
    282 ---
    283 
    284 ## Currently Enabled Patches
    285 
    286 Patches set to `1` in `patches.def.h`:
    287 
    288 **Bar:** BAR_DWMBLOCKS, BAR_LTSYMBOL, BAR_STATUS, BAR_STATUSCMD, BAR_TAGS, BAR_WINTITLE, BAR_HIDEVACANTTAGS
    289 
    290 **Core:** CFACTS, COOL_AUTOSTART, CYCLELAYOUTS, PERTAG, RESTARTSIG, SCRATCHPADS, SEAMLESS_RESTART, SELFRESTART, SHIFTTAG, SHIFTVIEW, STACKER, STICKY, SWALLOW, TOGGLEFULLSCREEN, VANITYGAPS, XRESOURCES
    291 
    292 **Layouts:** BSTACK, CENTEREDMASTER, CENTEREDFLOATINGMASTER, COLUMNS, DECK, FIBONACCI_DWINDLE, FIBONACCI_SPIRAL, NROWGRID, TILE, MONOCLE
    293 
    294 ---
    295 
    296 ## Current Custom Keybindings
    297 
    298 | Binding | Action |
    299 |---------|--------|
    300 | Super+Q | Reading mode (RRR layout) |
    301 | Super+Shift+Q | Kill client (close window) |
    302 | Super+Backspace | sysact (system actions menu) |
    303 | Super+Left/Right/Up/Down | Send window to monitor in that direction |
    304 | Super+Comma/Period | Focus previous/next monitor |
    305 | Super+T | Tile layout |
    306 | Super+F | Floating layout |
    307 
    308 ---
    309 
    310 ## Rules for Making Changes
    311 
    312 1. **Read before writing.** Always read the relevant section of `config.def.h` before modifying it. Understand the surrounding `#if` guards.
    313 2. **Count layout indices.** Never assume a layout index. Count from 0 in the `layouts[]` array every time.
    314 3. **Check for keybinding conflicts.** Before adding a new binding, grep for the key symbol (e.g., `XK_w`) across `config.def.h` to find all uses and check which patches guard them.
    315 4. **Test compilation.** Clang diagnostics on `config.h` standalone are ALWAYS false positives (missing types like `Arg`, `Client`, `Monitor`). The only valid test is `make` in the repo root.
    316 5. **Keep both files in sync.** Every edit to `config.def.h` must also be applied to `config.h` (and vice versa for patches).
    317 6. **Preserve removed bindings as comments.** When removing a keybinding, comment it out with a `// removed: reason` note rather than deleting the line, so the history is visible.
    318 7. **Do not modify `dwm.c` unless absolutely necessary.** Configuration belongs in `config.def.h`. New functions go in `config.def.h` (before the keys array) or as a new file in `patch/`.
    319 8. **Do not modify `patch/include.c` or `patch/include.h`** unless adding a completely new patch file to the `patch/` directory.
    320 9. **Commit messages:** Imperative mood, concise. Example: `"Rebind reading mode to Super+Q, add directional tagmon"`. No "Co-Authored-By" lines.