- client_update_scale(): re-notifies clients when output scale changes
using current_outputs max scale (avoids stale c->mon for floating windows)
- layersurface_update_scale(): same logic for layer shell surfaces (static)
- Initialize current_scale on initial commit for both surface types
- Uses 0.001f tolerance for float comparison to prevent redundant events
- Falls back to c->mon->wlr_output->scale if no current_outputs
Root cause: applyrules() called setmon() which called resize(), but
resize() dereferences c->scene_surface->node before c->scene_surface
was created in mapnotify(). Fix by storing target monitor/tags in
pending_mon/pending_tags fields and calling setmon() after scene
nodes exist.
The crash affected all new windows, not just Firefox (which was
the first tested).
The dynamic Config array conversion (Todo 2.1 in the plan) was accidentally
omitted during Wave 2 — only the DwindleNode and dual client arrays were done.
This commit implements the missing work:
- Convert Config keybinds/buttons/scrolls from fixed-size arrays
(keybinds[128]) to pointer+count+cap (keybinds, nkeybinds, keybinds_cap)
- config_load allocates with ecalloc(16) for each array, doubles on overflow
- on_config_reload and do_reload use deep-copy protocol:
free old arrays → *newcfg → zero source pointers
- sizeof(Config): ~250 KB → ~28 KB (latest measurement)
- Zero-warning build
Wave 3 changes:
- Static JSON buffer reuse across IPC calls: file-scope json_shared_buf/json_shared_cap,
json_init allocates once via malloc, json_finish is no-op, json_grow reallocs static buffer
→ eliminates ~30 malloc/free pairs per IPC test workload
- Capped lazy IPC payload: payload_size capped at 64KB, first alloc is min(size+1, 65536),
subsequent reallocs only when new payload larger than current allocation
→ bounds worst-case per-client allocation
- Embedded wl_listeners: IdleInhibitorTrack and PopupCommitTrack wrapper structs replace
bare heap-allocated listeners; LISTEN_STATIC macro deprecated
→ consolidates listener + state into one allocation
- Lazy shadow allocation: shadow kept alive across config reload (set_enabled(false) instead
of destroy); zero shadow allocations for users with shadows disabled
→ eliminates per-client shadow overhead for non-shadow users
- Zero-warning build with clang -Werror -Wpedantic
Add wlr_scene_shadow node creation in mapnotify() with correct z-order
(wlr_scene_node_place_below for shadow-behind-borders). Update shadow
size/position/color/radius/blur/clip on every resize() with config-driven
visibility logic respecting fullscreen_shadows, nogaps_shadows, and
only_floating flags. Re-apply shadow on config hot-reload via
reapply_client_appearance() — create or destroy shadow nodes as needed.
Colors are premultiplied alpha per SceneFX API requirements.
- Parse effects.windows.rounded/rounding from Lua config
- Add CfgEffectsWindows and CfgEffects structs to Config
- Switch to fx_renderer_create for scenefx support
- Replace 5 wlr/types/wlr_scene.h includes with scenefx variant
- Add config_get_corner_radius() helper (light=6px, heavy=14px)
- Apply corner_radii_top/bottom/left/right to 4 border rects
- Apply wlr_scene_buffer_set_corner_radius to surface buffers
- Disable on fullscreen, restore on exit
- Re-apply on resize and config hot-reload
- Add -Wno-extra-semi for scenefx header compatibility
- All targets compile cleanly (make test passes)
make release - compiles with clang, uses more aggressive compilation
flags for errors/warnings.
CC=tcc/gcc/clang make - lets you select your wanted compiler.