From 4b5f9e008d738dc7671cb14d3861755edcce79a9 Mon Sep 17 00:00:00 2001 From: Max <112043822+Maxaubert@users.noreply.github.com> Date: Wed, 14 Oct 2026 03:26:10 +0200 Subject: [PATCH 1/3] refactor(src): group the flat src/ into area subfolders (move-only, #486) git mv only, no content changes. Include paths and consumers follow in the next commits. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01TdjopXZfsUiesYxYLYHEdH --- src/{ => color}/color_filter.cpp | 0 src/{ => color}/color_filter.h | 0 src/{ => color}/color_matrix.h | 0 src/{ => color}/cursor_tint.cpp | 0 src/{ => color}/cursor_tint.h | 0 src/{ => color}/cursor_tint_pixels.h | 0 src/{ => config}/config.cpp | 0 src/{ => config}/config.h | 0 src/{ => config}/config_path.h | 0 src/{ => config}/ini_edit.cpp | 0 src/{ => config}/ini_edit.h | 0 src/{ => config}/profile_switch.h | 0 src/{ => config}/profiles.cpp | 0 src/{ => config}/profiles.h | 0 src/{ => config}/profiles_io.h | 0 src/{ => core}/com_util.h | 0 src/{ => core}/hitch_record.cpp | 0 src/{ => core}/hitch_record.h | 0 src/{ => core}/idle_policy.h | 0 src/{ => core}/log_queue.h | 0 src/{ => core}/logging.cpp | 0 src/{ => core}/logging.h | 0 src/{ => core}/main.cpp | 0 src/{ => core}/reload_gate.h | 0 src/{ => core}/sched_priority.h | 0 src/{ => core}/test_telemetry.h | 0 src/{ => core}/tick_span.h | 0 src/{ => core}/tick_stats.h | 0 src/{ => core}/uiaccess_gate.h | 0 src/{ => core}/uiaccess_token.h | 0 src/{ => cursor}/crosshair.cpp | 0 src/{ => cursor}/crosshair.h | 0 src/{ => cursor}/cursor_blanker.cpp | 0 src/{ => cursor}/cursor_blanker.h | 0 src/{ => cursor}/cursor_decode.cpp | 0 src/{ => cursor}/cursor_decode.h | 0 src/{ => cursor}/cursor_lock.cpp | 0 src/{ => cursor}/cursor_lock.h | 0 src/{ => cursor}/cursor_mapper.cpp | 0 src/{ => cursor}/cursor_mapper.h | 0 src/{ => cursor}/cursor_sprite.cpp | 0 src/{ => cursor}/cursor_sprite.h | 0 src/{ => cursor}/drag_follow.h | 0 src/{ => cursor}/gain_learner.h | 0 src/{ => cursor}/game_cursor.h | 0 src/{ => cursor}/inspect_focus.h | 0 src/{ => cursor}/lock_detector.cpp | 0 src/{ => cursor}/lock_detector.h | 0 src/{ => cursor}/pan_glide.h | 0 src/{ => cursor}/sprite_layer.h | 0 src/{ => engine}/engine_pick.h | 0 src/{ => engine}/launch_quiesce.h | 0 src/{ => engine}/magnifier_model.h | 0 src/{ => engine}/shell_desktop.h | 0 src/{ => input}/event_order.h | 0 src/{ => input}/input_router.cpp | 0 src/{ => input}/input_router.h | 0 src/{ => input}/keybind_rules.h | 0 src/{ => input}/keyboard_pan.h | 0 src/{ => input}/pointer_binds.h | 0 src/{ => input}/swallow_ledger.h | 0 src/{ => input}/typing_key.h | 0 src/{ => platform}/installer_state.h | 0 src/{ => platform}/webview2_probe.h | 0 src/{ => render}/band_window.h | 0 src/{ => render}/hdr_info.cpp | 0 src/{ => render}/hdr_info.h | 0 src/{ => render}/hdr_scale.h | 0 src/{ => render}/hlsl_compile.h | 0 src/{ => render}/png_dump.cpp | 0 src/{ => render}/png_dump.h | 0 src/{ => render}/render_engine.cpp | 0 src/{ => render}/render_engine.h | 0 src/{ => render}/render_model.cpp | 0 src/{ => render}/render_model.h | 0 src/{ => render}/render_params.cpp | 0 src/{ => render}/render_shaders.h | 0 src/{ => render}/upscale_nis.h | 0 src/{ => render}/upscale_pass.cpp | 0 src/{ => render}/upscale_pass.h | 0 src/{ => render}/upscale_shaders.h | 0 src/{ => track}/caret_rect.h | 0 src/{ => track}/detached_view.h | 0 src/{ => track}/edge_pan.h | 0 src/{ => track}/focus_identity.h | 0 src/{ => track}/focus_track.cpp | 0 src/{ => track}/focus_track.h | 0 src/{ => track}/java_bridge.cpp | 0 src/{ => track}/java_bridge.h | 0 src/{ => track}/java_bridge_util.h | 0 src/{ => track}/track_filter.h | 0 src/{ => track}/view_glide.h | 0 src/{ => track}/view_target.h | 0 src/{ => transform}/comp_pin.cpp | 0 src/{ => transform}/comp_pin.h | 0 src/{ => transform}/dwm_watch.cpp | 0 src/{ => transform}/dwm_watch.h | 0 src/{ => transform}/mag_host.cpp | 0 src/{ => transform}/mag_host.h | 0 src/{ => transform}/mpo.h | 0 src/{ => transform}/mpo_boot.h | 0 src/{ => transform}/mpo_boot_logic.h | 0 src/{ => transform}/mpo_guard.h | 0 src/{ => transform}/native_cursor.h | 0 src/{ => transform}/transform.cpp | 0 src/{ => transform}/transform.h | 0 src/{ => transform}/transform_model.cpp | 0 src/{ => transform}/transform_model.h | 0 src/{ => transform}/tx_warm.h | 0 src/{ => transform}/zoom_ladder.h | 0 src/{ => tray}/tray_host.cpp | 0 src/{ => tray}/tray_host.h | 0 src/{ => tray}/tray_ipc.h | 0 src/{ => tray}/tray_items.cpp | 0 src/{ => tray}/tray_items.h | 0 src/{ => tray}/tray_status.h | 0 src/{ => zoom}/zoom_controller.cpp | 0 src/{ => zoom}/zoom_controller.h | 0 118 files changed, 0 insertions(+), 0 deletions(-) rename src/{ => color}/color_filter.cpp (100%) rename src/{ => color}/color_filter.h (100%) rename src/{ => color}/color_matrix.h (100%) rename src/{ => color}/cursor_tint.cpp (100%) rename src/{ => color}/cursor_tint.h (100%) rename src/{ => color}/cursor_tint_pixels.h (100%) rename src/{ => config}/config.cpp (100%) rename src/{ => config}/config.h (100%) rename src/{ => config}/config_path.h (100%) rename src/{ => config}/ini_edit.cpp (100%) rename src/{ => config}/ini_edit.h (100%) rename src/{ => config}/profile_switch.h (100%) rename src/{ => config}/profiles.cpp (100%) rename src/{ => config}/profiles.h (100%) rename src/{ => config}/profiles_io.h (100%) rename src/{ => core}/com_util.h (100%) rename src/{ => core}/hitch_record.cpp (100%) rename src/{ => core}/hitch_record.h (100%) rename src/{ => core}/idle_policy.h (100%) rename src/{ => core}/log_queue.h (100%) rename src/{ => core}/logging.cpp (100%) rename src/{ => core}/logging.h (100%) rename src/{ => core}/main.cpp (100%) rename src/{ => core}/reload_gate.h (100%) rename src/{ => core}/sched_priority.h (100%) rename src/{ => core}/test_telemetry.h (100%) rename src/{ => core}/tick_span.h (100%) rename src/{ => core}/tick_stats.h (100%) rename src/{ => core}/uiaccess_gate.h (100%) rename src/{ => core}/uiaccess_token.h (100%) rename src/{ => cursor}/crosshair.cpp (100%) rename src/{ => cursor}/crosshair.h (100%) rename src/{ => cursor}/cursor_blanker.cpp (100%) rename src/{ => cursor}/cursor_blanker.h (100%) rename src/{ => cursor}/cursor_decode.cpp (100%) rename src/{ => cursor}/cursor_decode.h (100%) rename src/{ => cursor}/cursor_lock.cpp (100%) rename src/{ => cursor}/cursor_lock.h (100%) rename src/{ => cursor}/cursor_mapper.cpp (100%) rename src/{ => cursor}/cursor_mapper.h (100%) rename src/{ => cursor}/cursor_sprite.cpp (100%) rename src/{ => cursor}/cursor_sprite.h (100%) rename src/{ => cursor}/drag_follow.h (100%) rename src/{ => cursor}/gain_learner.h (100%) rename src/{ => cursor}/game_cursor.h (100%) rename src/{ => cursor}/inspect_focus.h (100%) rename src/{ => cursor}/lock_detector.cpp (100%) rename src/{ => cursor}/lock_detector.h (100%) rename src/{ => cursor}/pan_glide.h (100%) rename src/{ => cursor}/sprite_layer.h (100%) rename src/{ => engine}/engine_pick.h (100%) rename src/{ => engine}/launch_quiesce.h (100%) rename src/{ => engine}/magnifier_model.h (100%) rename src/{ => engine}/shell_desktop.h (100%) rename src/{ => input}/event_order.h (100%) rename src/{ => input}/input_router.cpp (100%) rename src/{ => input}/input_router.h (100%) rename src/{ => input}/keybind_rules.h (100%) rename src/{ => input}/keyboard_pan.h (100%) rename src/{ => input}/pointer_binds.h (100%) rename src/{ => input}/swallow_ledger.h (100%) rename src/{ => input}/typing_key.h (100%) rename src/{ => platform}/installer_state.h (100%) rename src/{ => platform}/webview2_probe.h (100%) rename src/{ => render}/band_window.h (100%) rename src/{ => render}/hdr_info.cpp (100%) rename src/{ => render}/hdr_info.h (100%) rename src/{ => render}/hdr_scale.h (100%) rename src/{ => render}/hlsl_compile.h (100%) rename src/{ => render}/png_dump.cpp (100%) rename src/{ => render}/png_dump.h (100%) rename src/{ => render}/render_engine.cpp (100%) rename src/{ => render}/render_engine.h (100%) rename src/{ => render}/render_model.cpp (100%) rename src/{ => render}/render_model.h (100%) rename src/{ => render}/render_params.cpp (100%) rename src/{ => render}/render_shaders.h (100%) rename src/{ => render}/upscale_nis.h (100%) rename src/{ => render}/upscale_pass.cpp (100%) rename src/{ => render}/upscale_pass.h (100%) rename src/{ => render}/upscale_shaders.h (100%) rename src/{ => track}/caret_rect.h (100%) rename src/{ => track}/detached_view.h (100%) rename src/{ => track}/edge_pan.h (100%) rename src/{ => track}/focus_identity.h (100%) rename src/{ => track}/focus_track.cpp (100%) rename src/{ => track}/focus_track.h (100%) rename src/{ => track}/java_bridge.cpp (100%) rename src/{ => track}/java_bridge.h (100%) rename src/{ => track}/java_bridge_util.h (100%) rename src/{ => track}/track_filter.h (100%) rename src/{ => track}/view_glide.h (100%) rename src/{ => track}/view_target.h (100%) rename src/{ => transform}/comp_pin.cpp (100%) rename src/{ => transform}/comp_pin.h (100%) rename src/{ => transform}/dwm_watch.cpp (100%) rename src/{ => transform}/dwm_watch.h (100%) rename src/{ => transform}/mag_host.cpp (100%) rename src/{ => transform}/mag_host.h (100%) rename src/{ => transform}/mpo.h (100%) rename src/{ => transform}/mpo_boot.h (100%) rename src/{ => transform}/mpo_boot_logic.h (100%) rename src/{ => transform}/mpo_guard.h (100%) rename src/{ => transform}/native_cursor.h (100%) rename src/{ => transform}/transform.cpp (100%) rename src/{ => transform}/transform.h (100%) rename src/{ => transform}/transform_model.cpp (100%) rename src/{ => transform}/transform_model.h (100%) rename src/{ => transform}/tx_warm.h (100%) rename src/{ => transform}/zoom_ladder.h (100%) rename src/{ => tray}/tray_host.cpp (100%) rename src/{ => tray}/tray_host.h (100%) rename src/{ => tray}/tray_ipc.h (100%) rename src/{ => tray}/tray_items.cpp (100%) rename src/{ => tray}/tray_items.h (100%) rename src/{ => tray}/tray_status.h (100%) rename src/{ => zoom}/zoom_controller.cpp (100%) rename src/{ => zoom}/zoom_controller.h (100%) diff --git a/src/color_filter.cpp b/src/color/color_filter.cpp similarity index 100% rename from src/color_filter.cpp rename to src/color/color_filter.cpp diff --git a/src/color_filter.h b/src/color/color_filter.h similarity index 100% rename from src/color_filter.h rename to src/color/color_filter.h diff --git a/src/color_matrix.h b/src/color/color_matrix.h similarity index 100% rename from src/color_matrix.h rename to src/color/color_matrix.h diff --git a/src/cursor_tint.cpp b/src/color/cursor_tint.cpp similarity index 100% rename from src/cursor_tint.cpp rename to src/color/cursor_tint.cpp diff --git a/src/cursor_tint.h b/src/color/cursor_tint.h similarity index 100% rename from src/cursor_tint.h rename to src/color/cursor_tint.h diff --git a/src/cursor_tint_pixels.h b/src/color/cursor_tint_pixels.h similarity index 100% rename from src/cursor_tint_pixels.h rename to src/color/cursor_tint_pixels.h diff --git a/src/config.cpp b/src/config/config.cpp similarity index 100% rename from src/config.cpp rename to src/config/config.cpp diff --git a/src/config.h b/src/config/config.h similarity index 100% rename from src/config.h rename to src/config/config.h diff --git a/src/config_path.h b/src/config/config_path.h similarity index 100% rename from src/config_path.h rename to src/config/config_path.h diff --git a/src/ini_edit.cpp b/src/config/ini_edit.cpp similarity index 100% rename from src/ini_edit.cpp rename to src/config/ini_edit.cpp diff --git a/src/ini_edit.h b/src/config/ini_edit.h similarity index 100% rename from src/ini_edit.h rename to src/config/ini_edit.h diff --git a/src/profile_switch.h b/src/config/profile_switch.h similarity index 100% rename from src/profile_switch.h rename to src/config/profile_switch.h diff --git a/src/profiles.cpp b/src/config/profiles.cpp similarity index 100% rename from src/profiles.cpp rename to src/config/profiles.cpp diff --git a/src/profiles.h b/src/config/profiles.h similarity index 100% rename from src/profiles.h rename to src/config/profiles.h diff --git a/src/profiles_io.h b/src/config/profiles_io.h similarity index 100% rename from src/profiles_io.h rename to src/config/profiles_io.h diff --git a/src/com_util.h b/src/core/com_util.h similarity index 100% rename from src/com_util.h rename to src/core/com_util.h diff --git a/src/hitch_record.cpp b/src/core/hitch_record.cpp similarity index 100% rename from src/hitch_record.cpp rename to src/core/hitch_record.cpp diff --git a/src/hitch_record.h b/src/core/hitch_record.h similarity index 100% rename from src/hitch_record.h rename to src/core/hitch_record.h diff --git a/src/idle_policy.h b/src/core/idle_policy.h similarity index 100% rename from src/idle_policy.h rename to src/core/idle_policy.h diff --git a/src/log_queue.h b/src/core/log_queue.h similarity index 100% rename from src/log_queue.h rename to src/core/log_queue.h diff --git a/src/logging.cpp b/src/core/logging.cpp similarity index 100% rename from src/logging.cpp rename to src/core/logging.cpp diff --git a/src/logging.h b/src/core/logging.h similarity index 100% rename from src/logging.h rename to src/core/logging.h diff --git a/src/main.cpp b/src/core/main.cpp similarity index 100% rename from src/main.cpp rename to src/core/main.cpp diff --git a/src/reload_gate.h b/src/core/reload_gate.h similarity index 100% rename from src/reload_gate.h rename to src/core/reload_gate.h diff --git a/src/sched_priority.h b/src/core/sched_priority.h similarity index 100% rename from src/sched_priority.h rename to src/core/sched_priority.h diff --git a/src/test_telemetry.h b/src/core/test_telemetry.h similarity index 100% rename from src/test_telemetry.h rename to src/core/test_telemetry.h diff --git a/src/tick_span.h b/src/core/tick_span.h similarity index 100% rename from src/tick_span.h rename to src/core/tick_span.h diff --git a/src/tick_stats.h b/src/core/tick_stats.h similarity index 100% rename from src/tick_stats.h rename to src/core/tick_stats.h diff --git a/src/uiaccess_gate.h b/src/core/uiaccess_gate.h similarity index 100% rename from src/uiaccess_gate.h rename to src/core/uiaccess_gate.h diff --git a/src/uiaccess_token.h b/src/core/uiaccess_token.h similarity index 100% rename from src/uiaccess_token.h rename to src/core/uiaccess_token.h diff --git a/src/crosshair.cpp b/src/cursor/crosshair.cpp similarity index 100% rename from src/crosshair.cpp rename to src/cursor/crosshair.cpp diff --git a/src/crosshair.h b/src/cursor/crosshair.h similarity index 100% rename from src/crosshair.h rename to src/cursor/crosshair.h diff --git a/src/cursor_blanker.cpp b/src/cursor/cursor_blanker.cpp similarity index 100% rename from src/cursor_blanker.cpp rename to src/cursor/cursor_blanker.cpp diff --git a/src/cursor_blanker.h b/src/cursor/cursor_blanker.h similarity index 100% rename from src/cursor_blanker.h rename to src/cursor/cursor_blanker.h diff --git a/src/cursor_decode.cpp b/src/cursor/cursor_decode.cpp similarity index 100% rename from src/cursor_decode.cpp rename to src/cursor/cursor_decode.cpp diff --git a/src/cursor_decode.h b/src/cursor/cursor_decode.h similarity index 100% rename from src/cursor_decode.h rename to src/cursor/cursor_decode.h diff --git a/src/cursor_lock.cpp b/src/cursor/cursor_lock.cpp similarity index 100% rename from src/cursor_lock.cpp rename to src/cursor/cursor_lock.cpp diff --git a/src/cursor_lock.h b/src/cursor/cursor_lock.h similarity index 100% rename from src/cursor_lock.h rename to src/cursor/cursor_lock.h diff --git a/src/cursor_mapper.cpp b/src/cursor/cursor_mapper.cpp similarity index 100% rename from src/cursor_mapper.cpp rename to src/cursor/cursor_mapper.cpp diff --git a/src/cursor_mapper.h b/src/cursor/cursor_mapper.h similarity index 100% rename from src/cursor_mapper.h rename to src/cursor/cursor_mapper.h diff --git a/src/cursor_sprite.cpp b/src/cursor/cursor_sprite.cpp similarity index 100% rename from src/cursor_sprite.cpp rename to src/cursor/cursor_sprite.cpp diff --git a/src/cursor_sprite.h b/src/cursor/cursor_sprite.h similarity index 100% rename from src/cursor_sprite.h rename to src/cursor/cursor_sprite.h diff --git a/src/drag_follow.h b/src/cursor/drag_follow.h similarity index 100% rename from src/drag_follow.h rename to src/cursor/drag_follow.h diff --git a/src/gain_learner.h b/src/cursor/gain_learner.h similarity index 100% rename from src/gain_learner.h rename to src/cursor/gain_learner.h diff --git a/src/game_cursor.h b/src/cursor/game_cursor.h similarity index 100% rename from src/game_cursor.h rename to src/cursor/game_cursor.h diff --git a/src/inspect_focus.h b/src/cursor/inspect_focus.h similarity index 100% rename from src/inspect_focus.h rename to src/cursor/inspect_focus.h diff --git a/src/lock_detector.cpp b/src/cursor/lock_detector.cpp similarity index 100% rename from src/lock_detector.cpp rename to src/cursor/lock_detector.cpp diff --git a/src/lock_detector.h b/src/cursor/lock_detector.h similarity index 100% rename from src/lock_detector.h rename to src/cursor/lock_detector.h diff --git a/src/pan_glide.h b/src/cursor/pan_glide.h similarity index 100% rename from src/pan_glide.h rename to src/cursor/pan_glide.h diff --git a/src/sprite_layer.h b/src/cursor/sprite_layer.h similarity index 100% rename from src/sprite_layer.h rename to src/cursor/sprite_layer.h diff --git a/src/engine_pick.h b/src/engine/engine_pick.h similarity index 100% rename from src/engine_pick.h rename to src/engine/engine_pick.h diff --git a/src/launch_quiesce.h b/src/engine/launch_quiesce.h similarity index 100% rename from src/launch_quiesce.h rename to src/engine/launch_quiesce.h diff --git a/src/magnifier_model.h b/src/engine/magnifier_model.h similarity index 100% rename from src/magnifier_model.h rename to src/engine/magnifier_model.h diff --git a/src/shell_desktop.h b/src/engine/shell_desktop.h similarity index 100% rename from src/shell_desktop.h rename to src/engine/shell_desktop.h diff --git a/src/event_order.h b/src/input/event_order.h similarity index 100% rename from src/event_order.h rename to src/input/event_order.h diff --git a/src/input_router.cpp b/src/input/input_router.cpp similarity index 100% rename from src/input_router.cpp rename to src/input/input_router.cpp diff --git a/src/input_router.h b/src/input/input_router.h similarity index 100% rename from src/input_router.h rename to src/input/input_router.h diff --git a/src/keybind_rules.h b/src/input/keybind_rules.h similarity index 100% rename from src/keybind_rules.h rename to src/input/keybind_rules.h diff --git a/src/keyboard_pan.h b/src/input/keyboard_pan.h similarity index 100% rename from src/keyboard_pan.h rename to src/input/keyboard_pan.h diff --git a/src/pointer_binds.h b/src/input/pointer_binds.h similarity index 100% rename from src/pointer_binds.h rename to src/input/pointer_binds.h diff --git a/src/swallow_ledger.h b/src/input/swallow_ledger.h similarity index 100% rename from src/swallow_ledger.h rename to src/input/swallow_ledger.h diff --git a/src/typing_key.h b/src/input/typing_key.h similarity index 100% rename from src/typing_key.h rename to src/input/typing_key.h diff --git a/src/installer_state.h b/src/platform/installer_state.h similarity index 100% rename from src/installer_state.h rename to src/platform/installer_state.h diff --git a/src/webview2_probe.h b/src/platform/webview2_probe.h similarity index 100% rename from src/webview2_probe.h rename to src/platform/webview2_probe.h diff --git a/src/band_window.h b/src/render/band_window.h similarity index 100% rename from src/band_window.h rename to src/render/band_window.h diff --git a/src/hdr_info.cpp b/src/render/hdr_info.cpp similarity index 100% rename from src/hdr_info.cpp rename to src/render/hdr_info.cpp diff --git a/src/hdr_info.h b/src/render/hdr_info.h similarity index 100% rename from src/hdr_info.h rename to src/render/hdr_info.h diff --git a/src/hdr_scale.h b/src/render/hdr_scale.h similarity index 100% rename from src/hdr_scale.h rename to src/render/hdr_scale.h diff --git a/src/hlsl_compile.h b/src/render/hlsl_compile.h similarity index 100% rename from src/hlsl_compile.h rename to src/render/hlsl_compile.h diff --git a/src/png_dump.cpp b/src/render/png_dump.cpp similarity index 100% rename from src/png_dump.cpp rename to src/render/png_dump.cpp diff --git a/src/png_dump.h b/src/render/png_dump.h similarity index 100% rename from src/png_dump.h rename to src/render/png_dump.h diff --git a/src/render_engine.cpp b/src/render/render_engine.cpp similarity index 100% rename from src/render_engine.cpp rename to src/render/render_engine.cpp diff --git a/src/render_engine.h b/src/render/render_engine.h similarity index 100% rename from src/render_engine.h rename to src/render/render_engine.h diff --git a/src/render_model.cpp b/src/render/render_model.cpp similarity index 100% rename from src/render_model.cpp rename to src/render/render_model.cpp diff --git a/src/render_model.h b/src/render/render_model.h similarity index 100% rename from src/render_model.h rename to src/render/render_model.h diff --git a/src/render_params.cpp b/src/render/render_params.cpp similarity index 100% rename from src/render_params.cpp rename to src/render/render_params.cpp diff --git a/src/render_shaders.h b/src/render/render_shaders.h similarity index 100% rename from src/render_shaders.h rename to src/render/render_shaders.h diff --git a/src/upscale_nis.h b/src/render/upscale_nis.h similarity index 100% rename from src/upscale_nis.h rename to src/render/upscale_nis.h diff --git a/src/upscale_pass.cpp b/src/render/upscale_pass.cpp similarity index 100% rename from src/upscale_pass.cpp rename to src/render/upscale_pass.cpp diff --git a/src/upscale_pass.h b/src/render/upscale_pass.h similarity index 100% rename from src/upscale_pass.h rename to src/render/upscale_pass.h diff --git a/src/upscale_shaders.h b/src/render/upscale_shaders.h similarity index 100% rename from src/upscale_shaders.h rename to src/render/upscale_shaders.h diff --git a/src/caret_rect.h b/src/track/caret_rect.h similarity index 100% rename from src/caret_rect.h rename to src/track/caret_rect.h diff --git a/src/detached_view.h b/src/track/detached_view.h similarity index 100% rename from src/detached_view.h rename to src/track/detached_view.h diff --git a/src/edge_pan.h b/src/track/edge_pan.h similarity index 100% rename from src/edge_pan.h rename to src/track/edge_pan.h diff --git a/src/focus_identity.h b/src/track/focus_identity.h similarity index 100% rename from src/focus_identity.h rename to src/track/focus_identity.h diff --git a/src/focus_track.cpp b/src/track/focus_track.cpp similarity index 100% rename from src/focus_track.cpp rename to src/track/focus_track.cpp diff --git a/src/focus_track.h b/src/track/focus_track.h similarity index 100% rename from src/focus_track.h rename to src/track/focus_track.h diff --git a/src/java_bridge.cpp b/src/track/java_bridge.cpp similarity index 100% rename from src/java_bridge.cpp rename to src/track/java_bridge.cpp diff --git a/src/java_bridge.h b/src/track/java_bridge.h similarity index 100% rename from src/java_bridge.h rename to src/track/java_bridge.h diff --git a/src/java_bridge_util.h b/src/track/java_bridge_util.h similarity index 100% rename from src/java_bridge_util.h rename to src/track/java_bridge_util.h diff --git a/src/track_filter.h b/src/track/track_filter.h similarity index 100% rename from src/track_filter.h rename to src/track/track_filter.h diff --git a/src/view_glide.h b/src/track/view_glide.h similarity index 100% rename from src/view_glide.h rename to src/track/view_glide.h diff --git a/src/view_target.h b/src/track/view_target.h similarity index 100% rename from src/view_target.h rename to src/track/view_target.h diff --git a/src/comp_pin.cpp b/src/transform/comp_pin.cpp similarity index 100% rename from src/comp_pin.cpp rename to src/transform/comp_pin.cpp diff --git a/src/comp_pin.h b/src/transform/comp_pin.h similarity index 100% rename from src/comp_pin.h rename to src/transform/comp_pin.h diff --git a/src/dwm_watch.cpp b/src/transform/dwm_watch.cpp similarity index 100% rename from src/dwm_watch.cpp rename to src/transform/dwm_watch.cpp diff --git a/src/dwm_watch.h b/src/transform/dwm_watch.h similarity index 100% rename from src/dwm_watch.h rename to src/transform/dwm_watch.h diff --git a/src/mag_host.cpp b/src/transform/mag_host.cpp similarity index 100% rename from src/mag_host.cpp rename to src/transform/mag_host.cpp diff --git a/src/mag_host.h b/src/transform/mag_host.h similarity index 100% rename from src/mag_host.h rename to src/transform/mag_host.h diff --git a/src/mpo.h b/src/transform/mpo.h similarity index 100% rename from src/mpo.h rename to src/transform/mpo.h diff --git a/src/mpo_boot.h b/src/transform/mpo_boot.h similarity index 100% rename from src/mpo_boot.h rename to src/transform/mpo_boot.h diff --git a/src/mpo_boot_logic.h b/src/transform/mpo_boot_logic.h similarity index 100% rename from src/mpo_boot_logic.h rename to src/transform/mpo_boot_logic.h diff --git a/src/mpo_guard.h b/src/transform/mpo_guard.h similarity index 100% rename from src/mpo_guard.h rename to src/transform/mpo_guard.h diff --git a/src/native_cursor.h b/src/transform/native_cursor.h similarity index 100% rename from src/native_cursor.h rename to src/transform/native_cursor.h diff --git a/src/transform.cpp b/src/transform/transform.cpp similarity index 100% rename from src/transform.cpp rename to src/transform/transform.cpp diff --git a/src/transform.h b/src/transform/transform.h similarity index 100% rename from src/transform.h rename to src/transform/transform.h diff --git a/src/transform_model.cpp b/src/transform/transform_model.cpp similarity index 100% rename from src/transform_model.cpp rename to src/transform/transform_model.cpp diff --git a/src/transform_model.h b/src/transform/transform_model.h similarity index 100% rename from src/transform_model.h rename to src/transform/transform_model.h diff --git a/src/tx_warm.h b/src/transform/tx_warm.h similarity index 100% rename from src/tx_warm.h rename to src/transform/tx_warm.h diff --git a/src/zoom_ladder.h b/src/transform/zoom_ladder.h similarity index 100% rename from src/zoom_ladder.h rename to src/transform/zoom_ladder.h diff --git a/src/tray_host.cpp b/src/tray/tray_host.cpp similarity index 100% rename from src/tray_host.cpp rename to src/tray/tray_host.cpp diff --git a/src/tray_host.h b/src/tray/tray_host.h similarity index 100% rename from src/tray_host.h rename to src/tray/tray_host.h diff --git a/src/tray_ipc.h b/src/tray/tray_ipc.h similarity index 100% rename from src/tray_ipc.h rename to src/tray/tray_ipc.h diff --git a/src/tray_items.cpp b/src/tray/tray_items.cpp similarity index 100% rename from src/tray_items.cpp rename to src/tray/tray_items.cpp diff --git a/src/tray_items.h b/src/tray/tray_items.h similarity index 100% rename from src/tray_items.h rename to src/tray/tray_items.h diff --git a/src/tray_status.h b/src/tray/tray_status.h similarity index 100% rename from src/tray_status.h rename to src/tray/tray_status.h diff --git a/src/zoom_controller.cpp b/src/zoom/zoom_controller.cpp similarity index 100% rename from src/zoom_controller.cpp rename to src/zoom/zoom_controller.cpp diff --git a/src/zoom_controller.h b/src/zoom/zoom_controller.h similarity index 100% rename from src/zoom_controller.h rename to src/zoom/zoom_controller.h From 62a8d66826cd57d63171f2b2d6e68afc59db23d2 Mon Sep 17 00:00:00 2001 From: Max <112043822+Maxaubert@users.noreply.github.com> Date: Wed, 14 Oct 2026 03:32:15 +0200 Subject: [PATCH 2/3] build: include every src folder and include Wind headers by bare name (#486) build.bat gains WIND_INC (every src folder on the include path) and CORE_SRC (Wind.exe's source folders), and every target's explicit source list follows the new paths. Includes that reached a header through a path (../config.h, ../src/config.h) now name it bare. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01TdjopXZfsUiesYxYLYHEdH --- build.bat | 30 +++++++++++++++++++----------- src/config_ui/main.cpp | 22 +++++++++++----------- src/tray_app/engine_dropdown.cpp | 12 ++++++------ src/tray_app/flyout_draw.cpp | 2 +- src/tray_app/flyout_model.h | 6 +++--- src/tray_app/flyout_test.cpp | 2 +- src/tray_app/flyout_tools.h | 2 +- src/tray_app/flyout_window.cpp | 12 ++++++------ src/tray_app/main.cpp | 10 +++++----- src/tray_app/tray_icon.cpp | 2 +- src/tray_app/tray_menu.cpp | 14 +++++++------- src/tray_app/tray_pin.cpp | 2 +- tests/test_bridge_json.cpp | 2 +- tests/test_caret_rect.cpp | 2 +- tests/test_color_matrix.cpp | 2 +- tests/test_config.cpp | 4 ++-- tests/test_config_defaults.cpp | 2 +- tests/test_config_model.cpp | 2 +- tests/test_crosshair.cpp | 2 +- tests/test_cursor_lock.cpp | 2 +- tests/test_cursor_mapper.cpp | 2 +- tests/test_cursor_tint.cpp | 2 +- tests/test_detached_view.cpp | 2 +- tests/test_drag_follow.cpp | 2 +- tests/test_dwm_watch.cpp | 2 +- tests/test_edge_pan.cpp | 2 +- tests/test_engine_pick.cpp | 2 +- tests/test_event_order.cpp | 2 +- tests/test_flyout.cpp | 8 ++++---- tests/test_flyout_interact.cpp | 4 ++-- tests/test_flyout_palettes.cpp | 4 ++-- tests/test_flyout_tools.cpp | 6 +++--- tests/test_focus_identity.cpp | 2 +- tests/test_free_cursor.cpp | 2 +- tests/test_gain_learner.cpp | 2 +- tests/test_game_cursor.cpp | 2 +- tests/test_hdr_scale.cpp | 2 +- tests/test_hitch_record.cpp | 2 +- tests/test_idle_policy.cpp | 2 +- tests/test_ini_edit.cpp | 2 +- tests/test_inspect_focus.cpp | 2 +- tests/test_installer_state.cpp | 2 +- tests/test_java_bridge_util.cpp | 2 +- tests/test_keybind_rules.cpp | 2 +- tests/test_keyboard_pan.cpp | 2 +- tests/test_launch_quiesce.cpp | 2 +- tests/test_lock_detector.cpp | 2 +- tests/test_log_queue.cpp | 2 +- tests/test_logging.cpp | 2 +- tests/test_mag_transform.cpp | 6 +++--- tests/test_mpo_boot.cpp | 2 +- tests/test_mpo_guard.cpp | 2 +- tests/test_native_cursor.cpp | 2 +- tests/test_pan_glide.cpp | 2 +- tests/test_pointer_binds.cpp | 4 ++-- tests/test_profiles.cpp | 6 +++--- tests/test_profiles_io.cpp | 2 +- tests/test_quick_zoom.cpp | 2 +- tests/test_reload_gate.cpp | 2 +- tests/test_render_params.cpp | 4 ++-- tests/test_shell_desktop.cpp | 2 +- tests/test_sprite_layer.cpp | 2 +- tests/test_swallow_ledger.cpp | 2 +- tests/test_telemetry.cpp | 2 +- tests/test_track_filter.cpp | 2 +- tests/test_transform.cpp | 2 +- tests/test_tray_ipc.cpp | 2 +- tests/test_tray_items.cpp | 6 +++--- tests/test_tray_pin.cpp | 2 +- tests/test_tray_status.cpp | 4 ++-- tests/test_tx_warm.cpp | 2 +- tests/test_typing_key.cpp | 4 ++-- tests/test_uiaccess_gate.cpp | 2 +- tests/test_version.cpp | 2 +- tests/test_view_glide.cpp | 2 +- tests/test_view_target.cpp | 2 +- tests/test_webview2_probe.cpp | 2 +- tests/test_webview_recover.cpp | 2 +- tests/test_wind_watchdog.cpp | 2 +- tests/test_zoom_controller.cpp | 2 +- tests/test_zoom_ladder.cpp | 2 +- 81 files changed, 149 insertions(+), 141 deletions(-) diff --git a/build.bat b/build.bat index 41b5394c..1d3212e9 100644 --- a/build.bat +++ b/build.bat @@ -33,6 +33,14 @@ set "BUILD=%ROOT%build" set "OBJ=%BUILD%\obj" if not exist "%BUILD%" mkdir "%BUILD%" +rem --- Source folders --------------------------------------------------------------- +rem src\ is grouped by area (the source map in docs\architecture\01-overview.md). Wind headers are +rem included by bare file name ("config.h", never a path), so every compile gets every src folder on +rem its include path. A new folder goes in WIND_INC, and in CORE_SRC when it holds Wind.exe sources. +rem wind.rc, resource.h and version.h stay in src\ itself: the version readers expect them there. +set "WIND_INC=/I src /I src\core /I src\engine /I src\render /I src\transform /I src\color /I src\input /I src\cursor /I src\track /I src\zoom /I src\config /I src\tray /I src\platform /I src\tray_app /I src\config_ui" +set "CORE_SRC=src\core\*.cpp src\render\*.cpp src\transform\*.cpp src\color\*.cpp src\input\*.cpp src\cursor\*.cpp src\track\*.cpp src\zoom\*.cpp src\config\*.cpp src\tray\*.cpp" + if /i "%1"=="test" goto :test if /i "%1"=="check" goto :check if /i "%1"=="uiaccess" goto :uiaccess @@ -65,9 +73,9 @@ if not exist "%CORE_OBJ%" mkdir "%CORE_OBJ%" rem Compile the app-icon resource (rc.exe ships with the Windows SDK, on PATH via vcvars). rc /nologo /fo "%CORE_OBJ%\wind.res" "%ROOT%src\wind.rc" if errorlevel 1 (echo [build] rc.exe failed & exit /b 1) -cl /nologo /std:c++17 /EHsc /O2 /W4 /Zi /DUNICODE /D_UNICODE %~1 ^ +cl /nologo /std:c++17 /EHsc /O2 /W4 /Zi /DUNICODE /D_UNICODE %~1 %WIND_INC% ^ /Fo"%CORE_OBJ%\\" /Fd"%CORE_OBJ%\\" ^ - src\*.cpp "%CORE_OBJ%\wind.res" ^ + %CORE_SRC% "%CORE_OBJ%\wind.res" ^ /Fe:"%BUILD%\Wind.exe" ^ /link Magnification.lib Dwmapi.lib user32.lib shell32.lib gdi32.lib Dbghelp.lib ^ d3d11.lib dxgi.lib dxguid.lib d3dcompiler.lib windowscodecs.lib ole32.lib oleaut32.lib uuid.lib advapi32.lib ^ @@ -87,9 +95,9 @@ if not exist "%OBJ%\tray" mkdir "%OBJ%\tray" rc /nologo /fo "%OBJ%\tray\wind_tray.res" "%ROOT%src\tray_app\wind_tray.rc" if errorlevel 1 (echo [build] rc.exe failed for WindTray & exit /b 1) rem Own object dir (build\obj\tray) so the shared sources never overwrite Wind.exe's .obj files. -cl /nologo /std:c++17 /EHsc /O2 /W4 /Zi /DUNICODE /D_UNICODE ^ +cl /nologo /std:c++17 /EHsc /O2 /W4 /Zi /DUNICODE /D_UNICODE %WIND_INC% ^ /Fo"%OBJ%\tray\\" /Fd"%OBJ%\tray\\" ^ - src\tray_app\*.cpp src\tray_items.cpp src\profiles.cpp src\config.cpp src\logging.cpp src\ini_edit.cpp ^ + src\tray_app\*.cpp src\tray\tray_items.cpp src\config\profiles.cpp src\config\config.cpp src\core\logging.cpp src\config\ini_edit.cpp ^ "%OBJ%\tray\wind_tray.res" ^ /Fe:"%BUILD%\WindTray.exe" ^ /link user32.lib shell32.lib gdi32.lib Dwmapi.lib Dbghelp.lib shlwapi.lib ole32.lib version.lib ^ @@ -116,9 +124,9 @@ rem Same app-icon resource as Wind.exe (rc.exe ships with the Windows SDK, on PA rc /nologo /fo "%OBJ%\config\wind.res" "%ROOT%src\wind.rc" if errorlevel 1 (echo [build] rc.exe failed & exit /b 1) cl /nologo /std:c++17 /EHsc /O2 /W4 /DUNICODE /D_UNICODE ^ - /I third_party\webview2\include ^ + /I third_party\webview2\include %WIND_INC% ^ /Fo"%OBJ%\config\\" /Fd"%OBJ%\config\\" ^ - src\config_ui\main.cpp src\ini_edit.cpp src\profiles.cpp src\config.cpp src\logging.cpp "%OBJ%\config\wind.res" ^ + src\config_ui\main.cpp src\config\ini_edit.cpp src\config\profiles.cpp src\config\config.cpp src\core\logging.cpp "%OBJ%\config\wind.res" ^ /Fe:"%BUILD%\WindConfig.exe" ^ /link third_party\webview2\x64\WebView2LoaderStatic.lib ^ user32.lib shell32.lib shlwapi.lib ole32.lib version.lib advapi32.lib ntdll.lib Dwmapi.lib /SUBSYSTEM:WINDOWS @@ -136,10 +144,10 @@ rem --- Test build (pure-logic sources only; no ) ----------------- :test rem /wd5285 silences a known doctest 2.4.11 header warning under MSVC /W4. if not exist "%OBJ%\test" mkdir "%OBJ%\test" -cl /nologo /std:c++17 /EHsc /W4 /wd5285 /DWIND_TESTS /I third_party ^ +cl /nologo /std:c++17 /EHsc /W4 /wd5285 /DWIND_TESTS /I third_party %WIND_INC% ^ /Fo"%OBJ%\test\\" /Fd"%OBJ%\test\\" ^ tests\*.cpp ^ - src\transform.cpp src\zoom_controller.cpp src\config.cpp src\profiles.cpp src\cursor_mapper.cpp src\lock_detector.cpp src\cursor_lock.cpp src\crosshair.cpp src\ini_edit.cpp src\logging.cpp src\tray_items.cpp src\hitch_record.cpp src\render_params.cpp src\tray_app\tray_pin_logic.cpp ^ + src\transform\transform.cpp src\zoom\zoom_controller.cpp src\config\config.cpp src\config\profiles.cpp src\cursor\cursor_mapper.cpp src\cursor\lock_detector.cpp src\cursor\cursor_lock.cpp src\cursor\crosshair.cpp src\config\ini_edit.cpp src\core\logging.cpp src\tray\tray_items.cpp src\core\hitch_record.cpp src\render\render_params.cpp src\tray_app\tray_pin_logic.cpp ^ /Fe:"%BUILD%\wind_tests.exe" if errorlevel 1 exit /b 1 rem Runs from the repo root (the current directory): the tests find tests\fixtures from there. @@ -149,13 +157,13 @@ exit /b %errorlevel% rem --- Compile-only check (no link; verifies all sources compile) ----------- :check for %%D in (core tray config) do if not exist "%OBJ%\check\%%D" mkdir "%OBJ%\check\%%D" -cl /nologo /std:c++17 /EHsc /W4 /DUNICODE /D_UNICODE /c /Fo"%OBJ%\check\core\\" src\*.cpp +cl /nologo /std:c++17 /EHsc /W4 /DUNICODE /D_UNICODE /c %WIND_INC% /Fo"%OBJ%\check\core\\" %CORE_SRC% if errorlevel 1 exit /b 1 rem WindTray.exe sources (issue #291); own object dir, its main.cpp would overwrite Wind's main.obj. -cl /nologo /std:c++17 /EHsc /W4 /DUNICODE /D_UNICODE /c /Fo"%OBJ%\check\tray\\" src\tray_app\*.cpp +cl /nologo /std:c++17 /EHsc /W4 /DUNICODE /D_UNICODE /c %WIND_INC% /Fo"%OBJ%\check\tray\\" src\tray_app\*.cpp if errorlevel 1 exit /b 1 rem WindConfig.exe's host (same flags as :config); own object dir for the same reason. -cl /nologo /std:c++17 /EHsc /W4 /DUNICODE /D_UNICODE /c /I third_party\webview2\include ^ +cl /nologo /std:c++17 /EHsc /W4 /DUNICODE /D_UNICODE /c /I third_party\webview2\include %WIND_INC% ^ /Fo"%OBJ%\check\config\\" src\config_ui\main.cpp exit /b %errorlevel% diff --git a/src/config_ui/main.cpp b/src/config_ui/main.cpp index 3f7f000e..331c5955 100644 --- a/src/config_ui/main.cpp +++ b/src/config_ui/main.cpp @@ -14,20 +14,20 @@ #include #include #include -#include "../ini_edit.h" +#include "ini_edit.h" #include "wind_watchdog.h" #include "bridge_json.h" -#include "../mpo_boot.h" -#include "../config_path.h" -#include "../config.h" -#include "../profiles.h" -#include "../profiles_io.h" -#include "../logging.h" -#include "../tray_ipc.h" // kQuitEventName -#include "../profile_switch.h" // SwitchProfile, LaunchWindExe, session.keep: shared with the tray -#include "../tray_app/flyout_palettes.h" // the theme colours (generated): the window background +#include "mpo_boot.h" +#include "config_path.h" +#include "config.h" +#include "profiles.h" +#include "profiles_io.h" +#include "logging.h" +#include "tray_ipc.h" // kQuitEventName +#include "profile_switch.h" // SwitchProfile, LaunchWindExe, session.keep: shared with the tray +#include "flyout_palettes.h" // the theme colours (generated): the window background #include -#include "../resource.h" +#include "resource.h" #pragma comment(lib, "shlwapi.lib") #pragma comment(lib, "comdlg32.lib") #pragma comment(lib, "gdi32.lib") diff --git a/src/tray_app/engine_dropdown.cpp b/src/tray_app/engine_dropdown.cpp index b95dede7..f4f0b97d 100644 --- a/src/tray_app/engine_dropdown.cpp +++ b/src/tray_app/engine_dropdown.cpp @@ -12,12 +12,12 @@ // single-instance handshake, and Wind then starts a fresh tray. #include "tray_app.h" #include "flyout_tools.h" -#include "../logging.h" -#include "../config_path.h" -#include "../profiles_io.h" -#include "../profile_switch.h" // WriteSessionKeep, LaunchWindExe, RevertModelAfterFailedRelaunch -#include "../tray_items.h" // IniValues -#include "../ini_edit.h" +#include "logging.h" +#include "config_path.h" +#include "profiles_io.h" +#include "profile_switch.h" // WriteSessionKeep, LaunchWindExe, RevertModelAfterFailedRelaunch +#include "tray_items.h" // IniValues +#include "ini_edit.h" #include namespace wind { namespace TrayApp { diff --git a/src/tray_app/flyout_draw.cpp b/src/tray_app/flyout_draw.cpp index 02d722b1..59e62fce 100644 --- a/src/tray_app/flyout_draw.cpp +++ b/src/tray_app/flyout_draw.cpp @@ -4,7 +4,7 @@ #include "flyout_icons.h" #include "flyout_palettes.h" #include "svg_path.h" -#include "../resource.h" +#include "resource.h" #include #include #include diff --git a/src/tray_app/flyout_model.h b/src/tray_app/flyout_model.h index 55d0fb47..3fe499ec 100644 --- a/src/tray_app/flyout_model.h +++ b/src/tray_app/flyout_model.h @@ -10,9 +10,9 @@ #include #include #include -#include "../tick_stats.h" -#include "../tray_items.h" -#include "../tray_status.h" +#include "tick_stats.h" +#include "tray_items.h" +#include "tray_status.h" #include "flyout_tools.h" namespace wind { namespace Flyout { diff --git a/src/tray_app/flyout_test.cpp b/src/tray_app/flyout_test.cpp index d824399f..96141dde 100644 --- a/src/tray_app/flyout_test.cpp +++ b/src/tray_app/flyout_test.cpp @@ -14,7 +14,7 @@ #include "tray_app.h" #include "flyout_draw.h" #include "flyout_model.h" -#include "../logging.h" +#include "logging.h" #include #include diff --git a/src/tray_app/flyout_tools.h b/src/tray_app/flyout_tools.h index f7f00930..fae2f119 100644 --- a/src/tray_app/flyout_tools.h +++ b/src/tray_app/flyout_tools.h @@ -5,7 +5,7 @@ // Spec: docs/specs/2026-10-02-tray-tools-design.md. #include #include -#include "../ini_edit.h" // TrimWs +#include "ini_edit.h" // TrimWs namespace wind { namespace Flyout { diff --git a/src/tray_app/flyout_window.cpp b/src/tray_app/flyout_window.cpp index 4a8e06f0..6bc5a593 100644 --- a/src/tray_app/flyout_window.cpp +++ b/src/tray_app/flyout_window.cpp @@ -18,12 +18,12 @@ #include "tray_app.h" #include "flyout_draw.h" #include "flyout_model.h" -#include "../logging.h" -#include "../config_path.h" -#include "../profiles_io.h" -#include "../config.h" -#include "../ini_edit.h" -#include "../tray_ipc.h" +#include "logging.h" +#include "config_path.h" +#include "profiles_io.h" +#include "config.h" +#include "ini_edit.h" +#include "tray_ipc.h" #include #include #include diff --git a/src/tray_app/main.cpp b/src/tray_app/main.cpp index d6be6143..b0d92aaf 100644 --- a/src/tray_app/main.cpp +++ b/src/tray_app/main.cpp @@ -5,11 +5,11 @@ // UIAccess token). We serve exactly that process and exit when it exits, removing the icon on the // way out, so a Wind killed from Task Manager leaves no ghost icon. Single instance per session. #include "tray_app.h" -#include "../logging.h" -#include "../tray_ipc.h" -#include "../config.h" -#include "../config_path.h" -#include "../profiles_io.h" +#include "logging.h" +#include "tray_ipc.h" +#include "config.h" +#include "config_path.h" +#include "profiles_io.h" #include "tray_pin.h" #include #include diff --git a/src/tray_app/tray_icon.cpp b/src/tray_app/tray_icon.cpp index f16b90ae..daf20fbd 100644 --- a/src/tray_app/tray_icon.cpp +++ b/src/tray_app/tray_icon.cpp @@ -1,5 +1,5 @@ #include "tray_app.h" -#include "../resource.h" +#include "resource.h" #include namespace wind { namespace TrayApp { diff --git a/src/tray_app/tray_menu.cpp b/src/tray_app/tray_menu.cpp index 1e77466e..92181a04 100644 --- a/src/tray_app/tray_menu.cpp +++ b/src/tray_app/tray_menu.cpp @@ -3,13 +3,13 @@ // owns the window. The old owner-drawn HMENU that lived here is gone (menus cannot host sliders). #include "tray_app.h" #include "flyout_palettes.h" -#include "../logging.h" -#include "../config_path.h" -#include "../profiles_io.h" -#include "../profile_switch.h" // SwitchProfile: shared with Settings -#include "../config.h" -#include "../ini_edit.h" -#include "../tray_ipc.h" +#include "logging.h" +#include "config_path.h" +#include "profiles_io.h" +#include "profile_switch.h" // SwitchProfile: shared with Settings +#include "config.h" +#include "ini_edit.h" +#include "tray_ipc.h" #include #include #pragma comment(lib, "comctl32.lib") diff --git a/src/tray_app/tray_pin.cpp b/src/tray_app/tray_pin.cpp index 377f15ea..a7f4cc86 100644 --- a/src/tray_app/tray_pin.cpp +++ b/src/tray_app/tray_pin.cpp @@ -1,5 +1,5 @@ #include "tray_pin.h" -#include "../logging.h" +#include "logging.h" #include #include #include diff --git a/tests/test_bridge_json.cpp b/tests/test_bridge_json.cpp index eaa2f52c..2d2bcbd1 100644 --- a/tests/test_bridge_json.cpp +++ b/tests/test_bridge_json.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/config_ui/bridge_json.h" +#include "bridge_json.h" using namespace wind; TEST_CASE("JsonField reads the string fields the page sends") { diff --git a/tests/test_caret_rect.cpp b/tests/test_caret_rect.cpp index 872ab236..9856c243 100644 --- a/tests/test_caret_rect.cpp +++ b/tests/test_caret_rect.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/caret_rect.h" +#include "caret_rect.h" using namespace wind; TEST_CASE("caret rect: a rect spanning blank lines above is trimmed to its bottom line (#337, UIA)") { diff --git a/tests/test_color_matrix.cpp b/tests/test_color_matrix.cpp index 5fdffb91..30fa02b6 100644 --- a/tests/test_color_matrix.cpp +++ b/tests/test_color_matrix.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/color_matrix.h" +#include "color_matrix.h" using namespace wind; static void Rgb(const ColorMatrix& m, double r, double g, double b, double& o0, double& o1, double& o2) { diff --git a/tests/test_config.cpp b/tests/test_config.cpp index bb0f5a2d..4a1c2878 100644 --- a/tests/test_config.cpp +++ b/tests/test_config.cpp @@ -1,6 +1,6 @@ #include "doctest.h" -#include "../src/config.h" -#include "../src/ini_edit.h" +#include "config.h" +#include "ini_edit.h" using namespace wind; TEST_CASE("defaults when text is empty") { diff --git a/tests/test_config_defaults.cpp b/tests/test_config_defaults.cpp index 3d80ffd3..70244220 100644 --- a/tests/test_config_defaults.cpp +++ b/tests/test_config_defaults.cpp @@ -8,7 +8,7 @@ // set WIND_UPDATE_FIXTURES=1 && build.bat test // then check the diff and run `npm run test:rules` in ui/. #include "doctest.h" -#include "../src/config.h" +#include "config.h" #include #include #include diff --git a/tests/test_config_model.cpp b/tests/test_config_model.cpp index 3e7bf20e..6cf37e98 100644 --- a/tests/test_config_model.cpp +++ b/tests/test_config_model.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/config.h" +#include "config.h" using namespace wind; diff --git a/tests/test_crosshair.cpp b/tests/test_crosshair.cpp index 702de004..b2e74946 100644 --- a/tests/test_crosshair.cpp +++ b/tests/test_crosshair.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/crosshair.h" +#include "crosshair.h" using namespace wind; static uint32_t at(const std::vector& px, int n, int x, int y) { return px[(size_t)y * n + x]; } diff --git a/tests/test_cursor_lock.cpp b/tests/test_cursor_lock.cpp index b777503d..064b83db 100644 --- a/tests/test_cursor_lock.cpp +++ b/tests/test_cursor_lock.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/cursor_lock.h" +#include "cursor_lock.h" using wind::CursorLockController; diff --git a/tests/test_cursor_mapper.cpp b/tests/test_cursor_mapper.cpp index 8156c56c..582af409 100644 --- a/tests/test_cursor_mapper.cpp +++ b/tests/test_cursor_mapper.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/cursor_mapper.h" +#include "cursor_mapper.h" using wind::CursorMapper; diff --git a/tests/test_cursor_tint.cpp b/tests/test_cursor_tint.cpp index 3c120fbf..dca62e98 100644 --- a/tests/test_cursor_tint.cpp +++ b/tests/test_cursor_tint.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/cursor_tint_pixels.h" +#include "cursor_tint_pixels.h" #include using namespace wind; diff --git a/tests/test_detached_view.cpp b/tests/test_detached_view.cpp index 0c8e391b..92afbab7 100644 --- a/tests/test_detached_view.cpp +++ b/tests/test_detached_view.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/detached_view.h" +#include "detached_view.h" using namespace wind; TEST_CASE("detached map: view from the given centre, cursor fields from the real pointer") { diff --git a/tests/test_drag_follow.cpp b/tests/test_drag_follow.cpp index f17de12a..2ce20b1a 100644 --- a/tests/test_drag_follow.cpp +++ b/tests/test_drag_follow.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/drag_follow.h" +#include "drag_follow.h" using wind::ShouldDragFollow; diff --git a/tests/test_dwm_watch.cpp b/tests/test_dwm_watch.cpp index 114d8806..0dfa9129 100644 --- a/tests/test_dwm_watch.cpp +++ b/tests/test_dwm_watch.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/dwm_watch.h" +#include "dwm_watch.h" using namespace wind; diff --git a/tests/test_edge_pan.cpp b/tests/test_edge_pan.cpp index b4f55883..b3a459fd 100644 --- a/tests/test_edge_pan.cpp +++ b/tests/test_edge_pan.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/edge_pan.h" +#include "edge_pan.h" using namespace wind; // level 4 on 3840x2160: view 960x540; at (1920,1080) the band is x 1584..2256, y 891..1269. diff --git a/tests/test_engine_pick.cpp b/tests/test_engine_pick.cpp index 617928e7..72c2b030 100644 --- a/tests/test_engine_pick.cpp +++ b/tests/test_engine_pick.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/engine_pick.h" +#include "engine_pick.h" using wind::EnginePickInputs; using wind::ShouldPickTransform; diff --git a/tests/test_event_order.cpp b/tests/test_event_order.cpp index 7f24ebf1..daa7e4c1 100644 --- a/tests/test_event_order.cpp +++ b/tests/test_event_order.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/event_order.h" +#include "event_order.h" using namespace wind; TEST_CASE("a raw UP is stale only when the hook saw a later DOWN of the same input") { diff --git a/tests/test_flyout.cpp b/tests/test_flyout.cpp index a54b9985..c6007240 100644 --- a/tests/test_flyout.cpp +++ b/tests/test_flyout.cpp @@ -1,8 +1,8 @@ #include "../third_party/doctest.h" -#include "../src/tray_app/flyout_model.h" -#include "../src/tray_app/flyout_icons.h" -#include "../src/tray_app/flyout_palettes.h" -#include "../src/tray_app/svg_path.h" +#include "flyout_model.h" +#include "flyout_icons.h" +#include "flyout_palettes.h" +#include "svg_path.h" using namespace wind; using namespace wind::Flyout; diff --git a/tests/test_flyout_interact.cpp b/tests/test_flyout_interact.cpp index af6f35cf..abf76678 100644 --- a/tests/test_flyout_interact.cpp +++ b/tests/test_flyout_interact.cpp @@ -2,8 +2,8 @@ // maths and ini formatting, the toggle writes (incl. "Keep within the edges" = two keys), keyboard // focus order and the profile list popup. All pure; flyout_window.cpp wires them to messages. #include "../third_party/doctest.h" -#include "../src/tray_app/flyout_model.h" -#include "../src/tray_app/flyout_icons.h" +#include "flyout_model.h" +#include "flyout_icons.h" using namespace wind; using namespace wind::Flyout; diff --git a/tests/test_flyout_palettes.cpp b/tests/test_flyout_palettes.cpp index e7a7dd9c..873aed1a 100644 --- a/tests/test_flyout_palettes.cpp +++ b/tests/test_flyout_palettes.cpp @@ -2,8 +2,8 @@ // palette in the same order, and the invariants the painter relies on. Pure; flyout_palettes.h is generated by // ui/tools/gen-flyout-palettes.cjs from the same mockup palettes as the Settings themes. #include "../third_party/doctest.h" -#include "../src/tray_app/flyout_palettes.h" -#include "../src/config.h" +#include "flyout_palettes.h" +#include "config.h" #include #include #include diff --git a/tests/test_flyout_tools.cpp b/tests/test_flyout_tools.cpp index 44e11354..7346eb0e 100644 --- a/tests/test_flyout_tools.cpp +++ b/tests/test_flyout_tools.cpp @@ -2,9 +2,9 @@ // segmented toggle group and engine dropdown (stretched geometry, hit testing, list alignment, arrow-key // navigation). All pure; engine_dropdown.cpp / flyout_window.cpp wire them to Win32. #include "../third_party/doctest.h" -#include "../src/tray_app/flyout_model.h" -#include "../src/tray_app/flyout_icons.h" -#include "../src/config.h" +#include "flyout_model.h" +#include "flyout_icons.h" +#include "config.h" #include #include using namespace wind; diff --git a/tests/test_focus_identity.cpp b/tests/test_focus_identity.cpp index d55e1f29..37a4d91c 100644 --- a/tests/test_focus_identity.cpp +++ b/tests/test_focus_identity.cpp @@ -1,6 +1,6 @@ // tests/test_focus_identity.cpp - repeat focus events for the same control keep caret following. #include "doctest.h" -#include "../src/focus_identity.h" +#include "focus_identity.h" using namespace wind; static FocusKey Key(int fg, int focus, long l, long t, long r, long b) { diff --git a/tests/test_free_cursor.cpp b/tests/test_free_cursor.cpp index 933cde46..13fa35b8 100644 --- a/tests/test_free_cursor.cpp +++ b/tests/test_free_cursor.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/cursor_mapper.h" +#include "cursor_mapper.h" #include using namespace wind; diff --git a/tests/test_gain_learner.cpp b/tests/test_gain_learner.cpp index 185452b9..e4948efb 100644 --- a/tests/test_gain_learner.cpp +++ b/tests/test_gain_learner.cpp @@ -1,5 +1,5 @@ #include "../third_party/doctest.h" -#include "../src/gain_learner.h" +#include "gain_learner.h" #include using namespace wind; diff --git a/tests/test_game_cursor.cpp b/tests/test_game_cursor.cpp index 8bb25e76..8b681eb7 100644 --- a/tests/test_game_cursor.cpp +++ b/tests/test_game_cursor.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/game_cursor.h" +#include "game_cursor.h" using namespace wind; diff --git a/tests/test_hdr_scale.cpp b/tests/test_hdr_scale.cpp index 498fcbac..c144c362 100644 --- a/tests/test_hdr_scale.cpp +++ b/tests/test_hdr_scale.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/hdr_scale.h" +#include "hdr_scale.h" using wind::AcceptSdrWhiteNits; using wind::ScRgbScale; diff --git a/tests/test_hitch_record.cpp b/tests/test_hitch_record.cpp index 30c5e41d..5045db4a 100644 --- a/tests/test_hitch_record.cpp +++ b/tests/test_hitch_record.cpp @@ -1,6 +1,6 @@ // tests/test_hitch_record.cpp - hitch classification and the hitch line (#361). #include "doctest.h" -#include "../src/hitch_record.h" +#include "hitch_record.h" #include using namespace wind; diff --git a/tests/test_idle_policy.cpp b/tests/test_idle_policy.cpp index 016455d3..c858c84d 100644 --- a/tests/test_idle_policy.cpp +++ b/tests/test_idle_policy.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/idle_policy.h" +#include "idle_policy.h" using namespace wind; static IdleInputs Quiet() { diff --git a/tests/test_ini_edit.cpp b/tests/test_ini_edit.cpp index 4d1b1871..d63b212d 100644 --- a/tests/test_ini_edit.cpp +++ b/tests/test_ini_edit.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/ini_edit.h" +#include "ini_edit.h" using namespace wind; TEST_CASE("ReadIniValues parses key=value, skipping comments and blanks") { diff --git a/tests/test_inspect_focus.cpp b/tests/test_inspect_focus.cpp index 27d5edae..4c88b298 100644 --- a/tests/test_inspect_focus.cpp +++ b/tests/test_inspect_focus.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/inspect_focus.h" +#include "inspect_focus.h" using wind::ShouldGameInspect; using wind::InspectLockTell; diff --git a/tests/test_installer_state.cpp b/tests/test_installer_state.cpp index 82812534..1d8608c6 100644 --- a/tests/test_installer_state.cpp +++ b/tests/test_installer_state.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/installer_state.h" +#include "installer_state.h" using namespace wind; diff --git a/tests/test_java_bridge_util.cpp b/tests/test_java_bridge_util.cpp index f909e311..5b29c646 100644 --- a/tests/test_java_bridge_util.cpp +++ b/tests/test_java_bridge_util.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/java_bridge_util.h" +#include "java_bridge_util.h" using namespace wind; TEST_CASE("bridge DLL candidates: JetBrains bundled runtime comes right after the exe's own folder") { diff --git a/tests/test_keybind_rules.cpp b/tests/test_keybind_rules.cpp index 271c1f33..5b15e3d3 100644 --- a/tests/test_keybind_rules.cpp +++ b/tests/test_keybind_rules.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/keybind_rules.h" +#include "keybind_rules.h" #include #include #include diff --git a/tests/test_keyboard_pan.cpp b/tests/test_keyboard_pan.cpp index 86d08fcc..5c3e330e 100644 --- a/tests/test_keyboard_pan.cpp +++ b/tests/test_keyboard_pan.cpp @@ -1,6 +1,6 @@ #include #include "doctest.h" -#include "../src/keyboard_pan.h" +#include "keyboard_pan.h" using namespace wind; // Index order: Left, Right, Up, Down. diff --git a/tests/test_launch_quiesce.cpp b/tests/test_launch_quiesce.cpp index 4338228a..e20542a8 100644 --- a/tests/test_launch_quiesce.cpp +++ b/tests/test_launch_quiesce.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/launch_quiesce.h" +#include "launch_quiesce.h" using namespace wind; diff --git a/tests/test_lock_detector.cpp b/tests/test_lock_detector.cpp index eed249b7..46fcd3bd 100644 --- a/tests/test_lock_detector.cpp +++ b/tests/test_lock_detector.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/lock_detector.h" +#include "lock_detector.h" using wind::LockDetector; diff --git a/tests/test_log_queue.cpp b/tests/test_log_queue.cpp index 2e8d4aef..fb8f1d00 100644 --- a/tests/test_log_queue.cpp +++ b/tests/test_log_queue.cpp @@ -1,6 +1,6 @@ // tests/test_log_queue.cpp - the non-blocking log queue (#361). #include "doctest.h" -#include "../src/log_queue.h" +#include "log_queue.h" #include #include using namespace wind; diff --git a/tests/test_logging.cpp b/tests/test_logging.cpp index e2990eb9..4eaf3773 100644 --- a/tests/test_logging.cpp +++ b/tests/test_logging.cpp @@ -1,6 +1,6 @@ // tests/test_logging.cpp #include "doctest.h" -#include "../src/logging.h" +#include "logging.h" using namespace wind; TEST_CASE("LogLevelName maps levels") { diff --git a/tests/test_mag_transform.cpp b/tests/test_mag_transform.cpp index 47dda309..9e1e42af 100644 --- a/tests/test_mag_transform.cpp +++ b/tests/test_mag_transform.cpp @@ -1,7 +1,7 @@ #include "doctest.h" -#include "../src/transform.h" -#include "../src/cursor_mapper.h" -#include "../src/config.h" +#include "transform.h" +#include "cursor_mapper.h" +#include "config.h" using namespace wind; diff --git a/tests/test_mpo_boot.cpp b/tests/test_mpo_boot.cpp index 638033bf..36204984 100644 --- a/tests/test_mpo_boot.cpp +++ b/tests/test_mpo_boot.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/mpo_boot_logic.h" +#include "mpo_boot_logic.h" using namespace wind; diff --git a/tests/test_mpo_guard.cpp b/tests/test_mpo_guard.cpp index fa6fc32d..932096fd 100644 --- a/tests/test_mpo_guard.cpp +++ b/tests/test_mpo_guard.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/mpo_guard.h" +#include "mpo_guard.h" using namespace wind; diff --git a/tests/test_native_cursor.cpp b/tests/test_native_cursor.cpp index c2948ec8..7341d4ad 100644 --- a/tests/test_native_cursor.cpp +++ b/tests/test_native_cursor.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/native_cursor.h" +#include "native_cursor.h" using namespace wind; diff --git a/tests/test_pan_glide.cpp b/tests/test_pan_glide.cpp index 231eb2de..ebea9c7e 100644 --- a/tests/test_pan_glide.cpp +++ b/tests/test_pan_glide.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/pan_glide.h" +#include "pan_glide.h" #include using namespace wind; diff --git a/tests/test_pointer_binds.cpp b/tests/test_pointer_binds.cpp index 64e1e6f9..853299b7 100644 --- a/tests/test_pointer_binds.cpp +++ b/tests/test_pointer_binds.cpp @@ -1,7 +1,7 @@ #include #include "doctest.h" -#include "../src/pointer_binds.h" -#include "../src/zoom_controller.h" +#include "pointer_binds.h" +#include "zoom_controller.h" using namespace wind; TEST_CASE("a click bind matches only with its modifiers held; extra modifiers are fine") { diff --git a/tests/test_profiles.cpp b/tests/test_profiles.cpp index 67430c73..fe25dc76 100644 --- a/tests/test_profiles.cpp +++ b/tests/test_profiles.cpp @@ -1,7 +1,7 @@ #include "doctest.h" -#include "../src/profiles.h" -#include "../src/ini_edit.h" -#include "../src/config.h" +#include "profiles.h" +#include "ini_edit.h" +#include "config.h" #include #include #include diff --git a/tests/test_profiles_io.cpp b/tests/test_profiles_io.cpp index 1d15752d..121a879c 100644 --- a/tests/test_profiles_io.cpp +++ b/tests/test_profiles_io.cpp @@ -2,7 +2,7 @@ // atomic write/read, the missing-vs-unreadable contract and profile listing. #include "doctest.h" #include -#include "../src/profiles_io.h" +#include "profiles_io.h" using namespace wind; namespace { diff --git a/tests/test_quick_zoom.cpp b/tests/test_quick_zoom.cpp index ff45b5be..6ff1e5e6 100644 --- a/tests/test_quick_zoom.cpp +++ b/tests/test_quick_zoom.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/zoom_controller.h" +#include "zoom_controller.h" using namespace wind; TEST_CASE("ApplyQuickZoom: zoomed above 200% snaps out and remembers") { diff --git a/tests/test_reload_gate.cpp b/tests/test_reload_gate.cpp index 819ec7a8..fe6a63a5 100644 --- a/tests/test_reload_gate.cpp +++ b/tests/test_reload_gate.cpp @@ -1,6 +1,6 @@ // tests/test_reload_gate.cpp - config hot-reload decisions (reload_gate.h). #include "doctest.h" -#include "../src/reload_gate.h" +#include "reload_gate.h" using namespace wind; TEST_CASE("an unreadable ini retries and never takes the mtime or reloads") { diff --git a/tests/test_render_params.cpp b/tests/test_render_params.cpp index 6b6e505b..d7667345 100644 --- a/tests/test_render_params.cpp +++ b/tests/test_render_params.cpp @@ -1,8 +1,8 @@ // tests/test_render_params.cpp - FillRenderParams / CursorModeFromCfg (render_params.cpp) and the // pure MPO ghost settle decision (mpo_guard.h). #include "doctest.h" -#include "../src/render_model.h" -#include "../src/mpo_guard.h" +#include "render_model.h" +#include "mpo_guard.h" using namespace wind; static MapResult Map() { diff --git a/tests/test_shell_desktop.cpp b/tests/test_shell_desktop.cpp index a681b8fa..b6936acc 100644 --- a/tests/test_shell_desktop.cpp +++ b/tests/test_shell_desktop.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/shell_desktop.h" +#include "shell_desktop.h" // Issue #172: the shell desktop (Win+D) is a caption-less monitor-covering window, so only this // class test keeps the hybrid pick from reading it as a borderless fullscreen game. diff --git a/tests/test_sprite_layer.cpp b/tests/test_sprite_layer.cpp index af3bd95e..719fbe46 100644 --- a/tests/test_sprite_layer.cpp +++ b/tests/test_sprite_layer.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/sprite_layer.h" +#include "sprite_layer.h" using wind::PickSpriteLayer; using wind::SpriteLayer; diff --git a/tests/test_swallow_ledger.cpp b/tests/test_swallow_ledger.cpp index fb7bfee7..d474d54d 100644 --- a/tests/test_swallow_ledger.cpp +++ b/tests/test_swallow_ledger.cpp @@ -1,6 +1,6 @@ // tests/test_swallow_ledger.cpp - the hook swallow records (swallow_ledger.h). #include "doctest.h" -#include "../src/swallow_ledger.h" +#include "swallow_ledger.h" #include using namespace wind; diff --git a/tests/test_telemetry.cpp b/tests/test_telemetry.cpp index 3cade38d..16467052 100644 --- a/tests/test_telemetry.cpp +++ b/tests/test_telemetry.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/test_telemetry.h" +#include "test_telemetry.h" #include #include diff --git a/tests/test_track_filter.cpp b/tests/test_track_filter.cpp index 6c6e6289..ad9d1172 100644 --- a/tests/test_track_filter.cpp +++ b/tests/test_track_filter.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/track_filter.h" +#include "track_filter.h" using namespace wind; TEST_CASE("caret inside its element is trusted; the field-recorded Firefox iframe caret is not") { diff --git a/tests/test_transform.cpp b/tests/test_transform.cpp index aff836de..dddf68d2 100644 --- a/tests/test_transform.cpp +++ b/tests/test_transform.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/transform.h" +#include "transform.h" TEST_CASE("ComputeOffsetF centers sub-pixel at 2x") { wind::OffsetF o = wind::ComputeOffsetF(960.25, 540.0, 2.0, 1920, 1080); diff --git a/tests/test_tray_ipc.cpp b/tests/test_tray_ipc.cpp index d0d0c0b1..2eb306da 100644 --- a/tests/test_tray_ipc.cpp +++ b/tests/test_tray_ipc.cpp @@ -1,5 +1,5 @@ #include "../third_party/doctest.h" -#include "../src/tray_ipc.h" +#include "tray_ipc.h" #include using namespace wind; diff --git a/tests/test_tray_items.cpp b/tests/test_tray_items.cpp index b53badde..e03bc995 100644 --- a/tests/test_tray_items.cpp +++ b/tests/test_tray_items.cpp @@ -1,7 +1,7 @@ #include "doctest.h" -#include "../src/tray_items.h" -#include "../src/profiles.h" -#include "../src/ini_edit.h" +#include "tray_items.h" +#include "profiles.h" +#include "ini_edit.h" using namespace wind; static std::vector Keys(const std::vector& v, bool onlyOn) { diff --git a/tests/test_tray_pin.cpp b/tests/test_tray_pin.cpp index 421ff1d7..d444ea13 100644 --- a/tests/test_tray_pin.cpp +++ b/tests/test_tray_pin.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/tray_app/tray_pin.h" +#include "tray_pin.h" using namespace wind::TrayPin; static const GuidResolver kResolver = [](const std::wstring& g, std::wstring& out) { diff --git a/tests/test_tray_status.cpp b/tests/test_tray_status.cpp index 775c63ef..0273d94b 100644 --- a/tests/test_tray_status.cpp +++ b/tests/test_tray_status.cpp @@ -1,6 +1,6 @@ #include "../third_party/doctest.h" -#include "../src/tray_status.h" -#include "../src/tick_stats.h" +#include "tray_status.h" +#include "tick_stats.h" #include using namespace wind; diff --git a/tests/test_tx_warm.cpp b/tests/test_tx_warm.cpp index e6d076fe..029d4f87 100644 --- a/tests/test_tx_warm.cpp +++ b/tests/test_tx_warm.cpp @@ -1,5 +1,5 @@ #include "../third_party/doctest.h" -#include "../src/tx_warm.h" +#include "tx_warm.h" using namespace wind; diff --git a/tests/test_typing_key.cpp b/tests/test_typing_key.cpp index 89d7f6eb..403b6ca8 100644 --- a/tests/test_typing_key.cpp +++ b/tests/test_typing_key.cpp @@ -1,6 +1,6 @@ #include "doctest.h" -#include "../src/typing_key.h" -#include "../src/view_target.h" +#include "typing_key.h" +#include "view_target.h" using namespace wind; TEST_CASE("typing key: only a fresh non-modifier down counts (#328, review #349)") { diff --git a/tests/test_uiaccess_gate.cpp b/tests/test_uiaccess_gate.cpp index 1a91fb09..1c0dffc9 100644 --- a/tests/test_uiaccess_gate.cpp +++ b/tests/test_uiaccess_gate.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/uiaccess_gate.h" +#include "uiaccess_gate.h" #include using wind::MustRefuseWithoutUiAccess; diff --git a/tests/test_version.cpp b/tests/test_version.cpp index c358dcfa..0d001790 100644 --- a/tests/test_version.cpp +++ b/tests/test_version.cpp @@ -1,7 +1,7 @@ // tests/test_version.cpp - src/version.h: WIND_VERSION_STR is written out by hand (the .rc files // consume it as one literal, so it is not stringized from the numbers); this keeps it in step. #include "doctest.h" -#include "../src/version.h" +#include "version.h" #include TEST_CASE("WIND_VERSION_STR matches WIND_VER_MAJOR.MINOR.PATCH") { diff --git a/tests/test_view_glide.cpp b/tests/test_view_glide.cpp index 2721f1d6..7e838cc7 100644 --- a/tests/test_view_glide.cpp +++ b/tests/test_view_glide.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/view_glide.h" +#include "view_glide.h" using namespace wind; TEST_CASE("centred: the target is the rect centre, clamped to the monitor") { diff --git a/tests/test_view_target.cpp b/tests/test_view_target.cpp index e50c5936..34f538a5 100644 --- a/tests/test_view_target.cpp +++ b/tests/test_view_target.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/view_target.h" +#include "view_target.h" using namespace wind; static ViewOwnerInputs Base() { diff --git a/tests/test_webview2_probe.cpp b/tests/test_webview2_probe.cpp index 74eaab0e..a0ff1207 100644 --- a/tests/test_webview2_probe.cpp +++ b/tests/test_webview2_probe.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/webview2_probe.h" +#include "webview2_probe.h" using namespace wind; diff --git a/tests/test_webview_recover.cpp b/tests/test_webview_recover.cpp index 6f4f2288..d5812edc 100644 --- a/tests/test_webview_recover.cpp +++ b/tests/test_webview_recover.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/config_ui/webview_recover.h" +#include "webview_recover.h" #include using namespace wind; diff --git a/tests/test_wind_watchdog.cpp b/tests/test_wind_watchdog.cpp index 3a8e4c9b..5c2d5e47 100644 --- a/tests/test_wind_watchdog.cpp +++ b/tests/test_wind_watchdog.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/config_ui/wind_watchdog.h" +#include "wind_watchdog.h" using wind::ShouldCloseOnWindGone; diff --git a/tests/test_zoom_controller.cpp b/tests/test_zoom_controller.cpp index b90ee537..0fe0a277 100644 --- a/tests/test_zoom_controller.cpp +++ b/tests/test_zoom_controller.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/zoom_controller.h" +#include "zoom_controller.h" #include using namespace wind; diff --git a/tests/test_zoom_ladder.cpp b/tests/test_zoom_ladder.cpp index 3e37c204..1aedcab7 100644 --- a/tests/test_zoom_ladder.cpp +++ b/tests/test_zoom_ladder.cpp @@ -1,5 +1,5 @@ #include "doctest.h" -#include "../src/zoom_ladder.h" +#include "zoom_ladder.h" #include using namespace wind; From 27d03b8480aee4e74c03c4048327b3ee1ce57ebc Mon Sep 17 00:00:00 2001 From: Max <112043822+Maxaubert@users.noreply.github.com> Date: Wed, 14 Oct 2026 03:35:32 +0200 Subject: [PATCH 3/3] docs: point every src path at its new folder; document the include rule (#486) Code comments, docs, CLAUDE.md, tools, ui comments and the NSIS headers now cite src//. Chapter 01's source map gains a folder column, chapter 11 and CLAUDE.md state the bare-name include rule and WIND_INC, and the frozen specs and history READMEs note that their paths predate the regrouping. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01TdjopXZfsUiesYxYLYHEdH --- CLAUDE.md | 19 +++++---- THIRD-PARTY-NOTICES.md | 4 +- docs/COLOUR-FILTER-FINDINGS.md | 2 +- docs/HITCH-FINDINGS.md | 2 +- docs/TRACKING-FINDINGS.md | 8 ++-- docs/architecture/01-overview.md | 47 ++++++++++++---------- docs/architecture/02-tick-loop.md | 38 ++++++++--------- docs/architecture/03-engines.md | 10 ++--- docs/architecture/04-render-engine.md | 20 ++++----- docs/architecture/05-transform-engine.md | 26 ++++++------ docs/architecture/06-input.md | 10 ++--- docs/architecture/07-cursor.md | 42 +++++++++---------- docs/architecture/08-config-profiles.md | 26 ++++++------ docs/architecture/09-settings-ui.md | 2 +- docs/architecture/11-build-test-release.md | 22 ++++++++-- docs/architecture/12-instrumentation.md | 12 +++--- docs/history/README.md | 4 +- docs/specs/README.md | 2 + installer/app.nsh | 6 +-- src/config/config.cpp | 6 +-- src/config/config.h | 20 ++++----- src/config/profiles.h | 2 +- src/config_ui/main.cpp | 2 +- src/core/hitch_record.cpp | 2 +- src/core/hitch_record.h | 2 +- src/core/log_queue.h | 2 +- src/core/logging.cpp | 2 +- src/core/logging.h | 2 +- src/core/main.cpp | 12 +++--- src/core/sched_priority.h | 2 +- src/core/tick_span.h | 2 +- src/cursor/cursor_mapper.h | 2 +- src/engine/magnifier_model.h | 2 +- src/input/input_router.h | 4 +- src/input/typing_key.h | 2 +- src/render/render_engine.cpp | 2 +- src/track/caret_rect.h | 2 +- src/track/focus_identity.h | 2 +- src/track/view_target.h | 2 +- src/transform/transform_model.cpp | 6 +-- src/transform/transform_model.h | 2 +- src/tray_app/flyout_tools.h | 2 +- tests/fixtures/global_keys.txt | 2 +- tests/test_tx_warm.cpp | 2 +- tools/gpu_ab.ps1 | 2 +- tools/testenv/README.md | 2 +- tools/testenv/lib.ps1 | 2 +- tools/zoom_response_ab.ps1 | 2 +- ui/src/lib/KeybindCapture.svelte | 4 +- ui/src/lib/keybindRules.js | 2 +- ui/src/prefs/profileName.js | 2 +- ui/src/session.js | 4 +- ui/src/tray/trayModel.js | 2 +- ui/tests/global-keys.nodetest.mjs | 2 +- ui/tests/tray.spec.js | 2 +- ui/tools/gen-themes.cjs | 2 +- 56 files changed, 223 insertions(+), 195 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index ddf49c78..89701ec9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -11,7 +11,7 @@ are frozen history cited from code, not kept in step with it. - `build.bat`: `Wind.exe` + `WindTray.exe` (uiAccess=false). Wind refuses to start without UIAccess; run a plain build with `WIND_ALLOW_NO_UIACCESS=1` (or `WIND_SELFTEST=1`). - `build.bat test`: builds and runs the doctest binary; exit 0 = pass. -- `build.bat check`: compile-only pass over `src\*.cpp`, the tray sources and WindConfig's host. +- `build.bat check`: compile-only pass over Wind.exe's sources, the tray sources and WindConfig's host. - `build.bat uiaccess`: the uiAccess=true build; works only signed and run from `C:\Program Files\Wind`. - `build.bat config`: builds the Svelte UI (`ui/` -> `ui/dist/`) and `WindConfig.exe`. - `build.bat tray`: `WindTray.exe` alone. It always uses the plain manifest; never make it uiAccess. @@ -22,8 +22,13 @@ are frozen history cited from code, not kept in step with it. ## Stack and map - Three binaries: `Wind.exe` (core, UIAccess when installed), `WindConfig.exe` (WebView2 settings), `WindTray.exe` (tray flyout, never UIAccess). Settings travel only through `magnifier.ini`. See 01. +- `src/` is grouped by area (`core`, `engine`, `render`, `transform`, `color`, `input`, `cursor`, + `track`, `zoom`, `config`, `tray`, `platform`, `tray_app`, `config_ui`; map in 01). Include a Wind + header by bare name (`"config.h"`, never a path); `build.bat`'s `WIND_INC` puts every folder on the + include path, and a new folder goes there (and in `CORE_SRC` if Wind.exe compiles it). `version.h`, + `resource.h` and `wind.rc` stay in `src/` itself. See 11. - Engines behind `IMagnifierModel`, chosen by `model=` (applies live: both engines are always built): `hybrid` (Auto, default) - picks `render` or `transform` per session via the pure `src/engine_pick.h`. `model=magnify` is + picks `render` or `transform` per session via the pure `src/engine/engine_pick.h`. `model=magnify` is parsed as `hybrid`; the magnify engine is retired, do not revive it. See 03, 04, 05. - Profiles: `profiles\.ini` next to the live ini; the live ini is the session, the profile file the saved state. See 08. @@ -44,7 +49,7 @@ Chapter numbers refer to `docs/architecture/NN-*.md`. **Magnification runtime (05)** - Never call `MagInitialize`/`MagUninitialize` directly; use `wind::MagApiAcquire()`/`MagApiRelease()` - (`src/mag_host.*`). Independent pairs break each other: two cursors, or transform writes returning + (`src/transform/mag_host.*`). Independent pairs break each other: two cursors, or transform writes returning FALSE. Keep every hold symmetric. - The COMPOSED pointer (DWM drawing it into the magnified frame) taxes every cursor change any app makes; a context alone does not (measured 2026-10-07). The transform engine builds the context + @@ -60,13 +65,13 @@ Chapter numbers refer to `docs/architecture/NN-*.md`. Never add `QS_RAWINPUT`/`QS_INPUT` to the mask. - Tick counts depend on the refresh rate; derive new ones through `TicksAtHz`/`setTickRate`. - A config reload rebuilds `ZoomController`; UI-only keys are stripped by `StripUiOnlyKeys` so they - never reload. Add new UI-only keys to `kUiOnlyKeys` (`src/profiles.h`) and + never reload. Add new UI-only keys to `kUiOnlyKeys` (`src/config/profiles.h`) and `tests/fixtures/global_keys.txt` (the UI's `GLOBAL_KEYS` is tested against it). **Cursor (07)** - In a transform session the lock (`lockApps`, tells) applies only while the pointer is hidden (`LockApplies`); gates read `t.lockEff`, not `t.detector.locked()`. See 07. -- Native cursor (the transform engine's only cursor, both sampling modes; `src/native_cursor.h`): DWM +- Native cursor (the transform engine's only cursor, both sampling modes; `src/transform/native_cursor.h`): DWM draws the real pointer via Wind's cursor lens (a hidden `WC_MAGNIFIER` window, built on the tick thread at idle) and centres the view itself (`SetFullscreenMagnifierOffsetsDWMUpdated`). While DWM centres, never write a same-level transform or warm pulse. Never use a public write to get the @@ -95,7 +100,7 @@ Chapter numbers refer to `docs/architecture/NN-*.md`. - Bound keys are swallowed by LL hooks with balanced down/up; release swallowed keys on teardown. - The keyboard hook is the authority for bound-key state; only the mouse hook skips Wind's own injections (`kWindInjectTag`), the keyboard hook counts the Alt/Win mask key. -- Bind rules live in `src/keybind_rules.h` and `ui/src/lib/keybindRules.js`, both tested against +- Bind rules live in `src/input/keybind_rules.h` and `ui/src/lib/keybindRules.js`, both tested against `tests/fixtures/keybind_cases.txt`: change both. - LL hooks cannot block Raw Input, so bound keys still reach raw-input games. No driver-based fix. @@ -105,7 +110,7 @@ Chapter numbers refer to `docs/architecture/NN-*.md`. - Keep the 2 px right/bottom clamp and the 1-texel left/top floor in `ComputeMagTransform` (TDR and grey-edge classes). - MPO on + nearest sampling overflows a 16-bit driver field above ~9.3x at the far right unless the - MPO guard (`src/mpo_guard.h`, default on) keeps apps off planes while zoomed. Never turn the guard + MPO guard (`src/transform/mpo_guard.h`, default on) keeps apps off planes while zoomed. Never turn the guard off with nearest on an MPO boot; walls come back only when it is off. - `txWarmMode`/`txWarmHz`: every warm write is a full DWM re-render; composition-rate metrics miss the pan-start hitch. Field-verify in a game. diff --git a/THIRD-PARTY-NOTICES.md b/THIRD-PARTY-NOTICES.md index 4e98ac8e..31f9134c 100644 --- a/THIRD-PARTY-NOTICES.md +++ b/THIRD-PARTY-NOTICES.md @@ -29,13 +29,13 @@ Copyright (c) 2016-2026 Svelte contributors. The Svelte runtime is compiled into which ships inside the installer. https://github.com/sveltejs/svelte ### xBR-lv2 shader (MIT) -Copyright (C) 2011-2022 Hyllian (sergiogdb@gmail.com). Ported to HLSL in `src/upscale_shaders.h` +Copyright (C) 2011-2022 Hyllian (sergiogdb@gmail.com). Ported to HLSL in `src/render/upscale_shaders.h` (the render engine's xBR scaling) from the libretro slang-shaders `edge-smoothing/xbr/shaders/xbr-lv2-standalone.slang`. https://github.com/libretro/slang-shaders ### NVIDIA Image Scaling 1.0.2 (MIT) Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. Ported to a pixel shader -in `src/upscale_nis.h` (the render engine's NVIDIA Image Scaling) via agyild's mpv port. +in `src/render/upscale_nis.h` (the render engine's NVIDIA Image Scaling) via agyild's mpv port. https://github.com/NVIDIAGameWorks/NVIDIAImageScaling ## Build and test only, not shipped diff --git a/docs/COLOUR-FILTER-FINDINGS.md b/docs/COLOUR-FILTER-FINDINGS.md index 0de73f1f..24cff588 100644 --- a/docs/COLOUR-FILTER-FINDINGS.md +++ b/docs/COLOUR-FILTER-FINDINGS.md @@ -59,7 +59,7 @@ harness, not committed.) Windows draws the pointer on a hardware cursor plane after composition, outside the DWM effect (Night light does reach it). Wind swaps the standard pointers for tinted copies while idle -(`src/cursor_tint.*`): at warmth 100 the arrow read 246,76,0 in Desktop Duplication, size and +(`src/color/cursor_tint.*`): at warmth 100 the arrow read 246,76,0 in Desktop Duplication, size and hotspot kept. Zoom-in swaps back in 1.1 ms. Idle restores always reload the real scheme, because in-memory copies of the pointers are not identical to the scheme's own. A force-killed Wind leaves the tint until its next start. Night-light apps that use the gamma ramp (f.lux, Iris) have the same diff --git a/docs/HITCH-FINDINGS.md b/docs/HITCH-FINDINGS.md index 52098a55..2e24d371 100644 --- a/docs/HITCH-FINDINGS.md +++ b/docs/HITCH-FINDINGS.md @@ -143,7 +143,7 @@ smoothness, which is why the transform model stays the default for games. Both engines are built at startup, so `model` and the per-category keys apply live on the config reload (#455); no restart. The pick rules are in [03](architecture/03-engines.md) and -`src/engine_pick.h`. +`src/engine/engine_pick.h`. | config | ini | behaviour today | |---|---|---| diff --git a/docs/TRACKING-FINDINGS.md b/docs/TRACKING-FINDINGS.md index 94d088df..60acd73f 100644 --- a/docs/TRACKING-FINDINGS.md +++ b/docs/TRACKING-FINDINGS.md @@ -35,7 +35,7 @@ follows only the terminal caret there. field's caret early. - **Click quiet period, 1 s.** A click that opens a page moves focus somewhere the user never asked to look, so caret and focus changes within 1 s of a mouse button are not followed. A fresh down of - a non-modifier key ends it early (#328, `src/typing_key.h`); key-ups and auto-repeat must not, or + a non-modifier key ends it early (#328, `src/input/typing_key.h`); key-ups and auto-repeat must not, or releasing Ctrl after a Ctrl+click handed the view to the click's own caret. - **Glide: critically damped spring, 200 ms** (A/B of 0, 25, 150, 200 ms and old ease versus spring). The old exponential ease restarted on every keystroke; the spring carries its velocity, @@ -78,7 +78,7 @@ follows only the terminal caret there. - Outlook on the web reports the caret as one line after Enter, then as a rect that also covers the blank lines above; the bottom stays on the caret line. Centring on it pushed the text lower with every blank line. -- `src/caret_rect.h` learns the one-line height per focus and trims a rect taller than 1.4 lines to +- `src/track/caret_rect.h` learns the one-line height per focus and trims a rect taller than 1.4 lines to one line at its bottom, but only when its top climbed more than half a line above the previous line's top (headings and font changes grow downward and are learned instead). UIA and Win32 carets are trimmed; Java carets are not. @@ -92,7 +92,7 @@ follows only the terminal caret there. made it follow again for a while. The focused element is xterm's `xterm-helper-textarea`, which xterm moves onto the cursor cell on every cursor move, but Chromium's selection rect for it goes stale for seconds (one typed line: ~60 textarea moves, 6 selection-rect changes). -- For that class (`IsXtermInput`, `src/caret_rect.h`) the textarea's own bounds are the caret +- For that class (`IsXtermInput`, `src/track/caret_rect.h`) the textarea's own bounds are the caret (`xterm-input` in trackLog), and its bounds are left out of the focus identity, since they move with every key. @@ -112,6 +112,6 @@ about to wrap, the caret is reported for one keystroke at the right edge of the space that hangs past the wrap: `2996,1944 1x49` -> `3375,1942 2x54` -> the next real position. Following it put the view on the composer's buttons with the text off screen. The ghost sits on the same line but in a different box (2 px higher, 5 px taller) and far to the right after a single key (380 px; a character is -8-30 px). `IsLineEndGhost` (src/caret_rect.h) skips a caret on the same line whose box changed by 2 px or +8-30 px). `IsLineEndGhost` (src/track/caret_rect.h) skips a caret on the same line whose box changed by 2 px or more and that jumped right by more than 3 line heights; End and clicks keep the caret's box, so they are followed. trackLog logs `caret skipped (line-end ghost)`. diff --git a/docs/architecture/01-overview.md b/docs/architecture/01-overview.md index fe840384..91605afd 100644 --- a/docs/architecture/01-overview.md +++ b/docs/architecture/01-overview.md @@ -15,7 +15,7 @@ These are commitments. Code that breaks one is a bug even if it works. app under the drawn cursor. See [04](04-render-engine.md) and [07](07-cursor.md). - **Zoom is a hold gesture.** Hold zoom-in to ramp in, hold zoom-out to ramp back, release to stay. Both held freezes the level. Quick zoom toggles between 1x and a remembered level - (`src/zoom_controller.h`). Binds ship unbound; first launch runs a guided setup. + (`src/zoom/zoom_controller.h`). Binds ship unbound; first launch runs a guided setup. - **One shared `maxLevel`**, the same for every engine. - **No driver, no injection into other processes.** Mouse motion comes from Raw Input, binds are swallowed with ordinary LL hooks. The cost: a bound key still reaches a raw-input game @@ -52,12 +52,12 @@ overlay; an ordinary process's popups do not. - Wind starts `WindTray.exe` with `ShellExecuteExW` (never `CreateProcess`, which would pass on the UIAccess token) and its PID, restarts it if it dies (at most 3 launches a minute, - `src/tray_host.cpp`), and the tray exits with its Wind. -- The shared block `Local\Wind_TrayState_v1` (`src/tray_ipc.h`) carries status and a frame-pacing + `src/tray/tray_host.cpp`), and the tray exits with its Wind. +- The shared block `Local\Wind_TrayState_v1` (`src/tray/tray_ipc.h`) carries status and a frame-pacing ring one way and `menuOpen` back (it pauses the cursor re-park while the user aims at the flyout). Quit sets `Local\Wind_QuitRequest`. - The flyout is a Direct2D window, not a menu (`src/tray_app/flyout_*`). Its content is chosen in - Settings > Tray menu and stored in the global `tray*` keys (`src/tray_items.*`). Details in + Settings > Tray menu and stored in the global `tray*` keys (`src/tray/tray_items.*`). Details in [09](09-settings-ui.md). - WindTray also applies `trayPinned` (Pin to taskbar, #436): it watches the ini folder and writes `IsPromoted` for its own icon (`src/tray_app/tray_pin.*`, [09](09-settings-ui.md#pin-to-taskbar)). @@ -77,23 +77,28 @@ build. See [11](11-build-test-release.md). ## Source map -| Area | Files | -|---|---| -| Loop and session state | `main.cpp` (`wWinMain`, `RunTick`), `uiaccess_gate.h` (refuse to start without UIAccess), `uiaccess_token.h`, `idle_policy.h`, `sched_priority.h`, `tick_stats.h` | -| Engine contract and pick | `magnifier_model.h`, `engine_pick.h`, `shell_desktop.h`, `launch_quiesce.h` | - -| Render engine | `render_engine.*`, `render_model.*`, `render_params.cpp`, `render_shaders.h`, `hlsl_compile.h`, `upscale_pass.*`, `upscale_shaders.h`, `upscale_nis.h`, `hdr_info.*`, `hdr_scale.h`, `band_window.h`, `png_dump.*` | -| Transform engine | `transform_model.*`, `transform.*`, `mag_host.*`, `tx_warm.h`, `comp_pin.*`, `mpo.h`, `mpo_boot.h`, `mpo_boot_logic.h`, `mpo_guard.h`, `native_cursor.h`, `zoom_ladder.h`, `dwm_watch.*` | -| Colour | `color_filter.*`, `color_matrix.h`, `cursor_tint.*`, `cursor_tint_pixels.h` | -| Input | `input_router.*`, `keybind_rules.h`, `pointer_binds.h`, `keyboard_pan.h`, `typing_key.h`, `event_order.h`, `swallow_ledger.h` | -| Cursor and lock | `cursor_mapper.*`, `lock_detector.*`, `drag_follow.h`, `gain_learner.h`, `cursor_sprite.*`, `cursor_blanker.*`, `cursor_decode.*`, `sprite_layer.h`, `crosshair.*`, `cursor_lock.*`, `inspect_focus.h`, `game_cursor.h`, `pan_glide.h` | -| Tracking | `focus_track.*`, `view_target.h`, `view_glide.h`, `detached_view.h`, `edge_pan.h`, `caret_rect.h`, `track_filter.h`, `java_bridge*`, `focus_identity.h` | -| Zoom | `zoom_controller.*` | -| Config and profiles | `config.*`, `config_path.h`, `ini_edit.*`, `profiles.*`, `profiles_io.h`, `profile_switch.h` | -| Tray | `tray_host.*`, `tray_ipc.h`, `tray_items.*`, `tray_status.h`, `tray_app/` | -| Settings host | `config_ui/` (`main.cpp`, `bridge_json.h`, `wind_watchdog.h`, `webview_recover.h`) | -| Logging and diagnostics | `logging.*`, `log_queue.h`, `test_telemetry.h`, `hitch_record.*`, `tick_span.h`, `com_util.h`, `reload_gate.h` | -| Installer support | `installer_state.h`, `webview2_probe.h`, `version.h`, `resource.h`, `wind.rc` | +Every file lives in the `src/` folder named in the second column. A header is included by its bare +file name; see [11](11-build-test-release.md#source-folders-and-includes) for the rule and the +build's include path. + +| Area | Folder | Files | +|---|---|---| +| Loop and session state | `core/` | `main.cpp` (`wWinMain`, `RunTick`), `uiaccess_gate.h` (refuse to start without UIAccess), `uiaccess_token.h`, `idle_policy.h`, `sched_priority.h`, `tick_stats.h` | +| Logging and diagnostics | `core/` | `logging.*`, `log_queue.h`, `test_telemetry.h`, `hitch_record.*`, `tick_span.h`, `com_util.h`, `reload_gate.h` | +| Engine contract and pick | `engine/` | `magnifier_model.h`, `engine_pick.h`, `shell_desktop.h`, `launch_quiesce.h` | +| Render engine | `render/` | `render_engine.*`, `render_model.*`, `render_params.cpp`, `render_shaders.h`, `hlsl_compile.h`, `upscale_pass.*`, `upscale_shaders.h`, `upscale_nis.h`, `hdr_info.*`, `hdr_scale.h`, `band_window.h`, `png_dump.*` | +| Transform engine | `transform/` | `transform_model.*`, `transform.*`, `mag_host.*`, `tx_warm.h`, `comp_pin.*`, `mpo.h`, `mpo_boot.h`, `mpo_boot_logic.h`, `mpo_guard.h`, `native_cursor.h`, `zoom_ladder.h`, `dwm_watch.*` | +| Colour | `color/` | `color_filter.*`, `color_matrix.h`, `cursor_tint.*`, `cursor_tint_pixels.h` | +| Input | `input/` | `input_router.*`, `keybind_rules.h`, `pointer_binds.h`, `keyboard_pan.h`, `typing_key.h`, `event_order.h`, `swallow_ledger.h` | +| Cursor and lock | `cursor/` | `cursor_mapper.*`, `lock_detector.*`, `drag_follow.h`, `gain_learner.h`, `cursor_sprite.*`, `cursor_blanker.*`, `cursor_decode.*`, `sprite_layer.h`, `crosshair.*`, `cursor_lock.*`, `inspect_focus.h`, `game_cursor.h`, `pan_glide.h` | +| Tracking | `track/` | `focus_track.*`, `view_target.h`, `view_glide.h`, `detached_view.h`, `edge_pan.h`, `caret_rect.h`, `track_filter.h`, `java_bridge*`, `focus_identity.h` | +| Zoom | `zoom/` | `zoom_controller.*` | +| Config and profiles | `config/` | `config.*`, `config_path.h`, `ini_edit.*`, `profiles.*`, `profiles_io.h`, `profile_switch.h` | +| Tray (core side) | `tray/` | `tray_host.*`, `tray_ipc.h`, `tray_items.*`, `tray_status.h` | +| Tray helper (`WindTray.exe`) | `tray_app/` | `main.cpp`, `flyout_*`, `tray_*`, `engine_dropdown.cpp`, `svg_path.h` | +| Settings host | `config_ui/` | `main.cpp`, `bridge_json.h`, `wind_watchdog.h`, `webview_recover.h` | +| Installer support | `platform/` | `installer_state.h`, `webview2_probe.h` | +| Version and resources | `src/` itself | `version.h`, `resource.h`, `wind.rc` (where the version readers and rc.exe expect them) | Other top-level folders: `ui/` (Svelte settings app and Playwright tests), `tests/` (doctest), `tools/` (deploy, release and measurement scripts, [12](12-instrumentation.md)), `installer/` diff --git a/docs/architecture/02-tick-loop.md b/docs/architecture/02-tick-loop.md index e3a99068..3b135788 100644 --- a/docs/architecture/02-tick-loop.md +++ b/docs/architecture/02-tick-loop.md @@ -1,6 +1,6 @@ # 02. The tick loop -Everything Wind does at runtime happens in one tick, `RunTick` in `src/main.cpp`. `RunTick` is a +Everything Wind does at runtime happens in one tick, `RunTick` in `src/core/main.cpp`. `RunTick` is a short sequence of calls to static phase functions in the same file (see [Phase functions](#phase-functions)). Each tick samples input, advances the zoom, resolves a pan and asks the current engine to present. This chapter lists the phases in source order, then covers @@ -51,7 +51,7 @@ flowchart TD 5. **Inspect edges.** The toggle edge snapshots whether the cursor was showing and whether Wind was hiding it (`t.cursorHiddenByUs`, which a transform session reads back from `TransformModel::pointerHidden()` after each present, since the model also hides and restores the - pointer on its own); both feed `ShouldGameInspect` (`src/inspect_focus.h`). Inspect keeps the overlay + pointer on its own); both feed `ShouldGameInspect` (`src/cursor/inspect_focus.h`). Inspect keeps the overlay active at 1x (`active = zoomed || inspect`). Details in [07](07-cursor.md). 6. **Pan delta.** One of three regimes, see [below](#pan-delta-three-regimes). 7. **Foreground facts and the pan wall.** `GetForegroundWindow`, `ForegroundCoversMonitor` and the @@ -68,7 +68,7 @@ flowchart TD re-reads its refresh rate, then runs the engine pick. The same pick runs every zoomed tick; a changed result hands over with controller and mapper untouched. The switch needs a stable candidate for 350 ms and is frozen while a transient overlay or the game-inspect focus stealer holds foreground. See [03](03-engines.md). -9. **Present.** The tick fills `PresentExtras` (`src/magnifier_model.h`): outline visibility and +9. **Present.** The tick fills `PresentExtras` (`src/engine/magnifier_model.h`): outline visibility and fades, cursor mode, `suppressCursorSync` (drag-follow, free cursor or a detached tracking view), transform write pauses (Inspect clicks, launch quiesce) and the game pacing flags, then calls `model->present`. The opt-in game pacing modes (`gameFpsCap`, `lowGpuPriority`) can skip @@ -139,8 +139,8 @@ There is no settings IPC. `WindConfig.exe` writes `magnifier.ini` and the core n **UI-only writes never reload.** A reload rebuilds `ZoomController` and `CursorMapper`, which is wasted work and risks a visible hitch mid-zoom (the live level and mapper centre are carried over -since #234, so the view no longer collapses to 1x). `StripUiOnlyKeys` (`src/config.cpp`) drops -the `kUiOnlyKeys` list (`src/profiles.h`): `uiTheme`, `uiPalette`, +since #234, so the view no longer collapses to 1x). `StripUiOnlyKeys` (`src/config/config.cpp`) drops +the `kUiOnlyKeys` list (`src/config/profiles.h`): `uiTheme`, `uiPalette`, `showAdvanced`, `onboarded`, `trayPinned`, `uiHighResNoticeOff` and the five tray layout keys (`trayPerf`, `traySliders`, `traySliderOrder`, `trayToggles`, `trayToggleOrder`), and the result is compared with the fingerprint of the last applied config (`t.lastCoreIni`). An identical fingerprint skips the reload. The fingerprint is seeded at startup; @@ -169,7 +169,7 @@ when one engine failed to init). The restart-only keys need a restart, see speed, and the locked pan replays it, so a locked game pans at desktop-cursor speed. - **Tracking** overrides the result afterwards: caret, focus or mouse-edge mode can detach the view from the pointer (`t.viewDetached`), see [07](07-cursor.md). -- `ShouldDragFollow` (`src/drag_follow.h`) suspends the render engine's weld while a mouse button is +- `ShouldDragFollow` (`src/cursor/drag_follow.h`) suspends the render engine's weld while a mouse button is held and follows the pointer 1:1. - In a free transform session (not Inspect, not locked) the mapper is reset to the real cursor each tick and fed zero delta: the view is a pure function of the pointer, nothing welds, and the free @@ -206,7 +206,7 @@ Transform while the device stays lost (`EnginePickInputs::renderLost`). At 1x with nothing in flight the loop sleeps in `MsgWaitForMultipleObjectsEx` on the input router's wake event and the quit event (100 ms timeout, mask -`QS_POSTMESSAGE | QS_SENDMESSAGE | QS_HOTKEY`). The rule is `IdleNow` (pure, `src/idle_policy.h`). +`QS_POSTMESSAGE | QS_SENDMESSAGE | QS_HOTKEY`). The rule is `IdleNow` (pure, `src/core/idle_policy.h`). Measured: Wind's CPU at 1x went from 37.5 to 3.1 ms per second, and a zoom starts 3–6 ms after the waking wheel notch. @@ -223,7 +223,7 @@ waking wheel notch. ## Priority under background load The tick thread runs at `THREAD_PRIORITY_HIGHEST` and the process opts out of power throttling -(`src/sched_priority.h`). At normal priority a busy machine queued the tick behind other threads +(`src/core/sched_priority.h`). At normal priority a busy machine queued the tick behind other threads (139–737 ms stalls mid-zoom). One step above normal stays below DWM, so the tick never delays composition. It does not help when the GPU is the bottleneck. @@ -233,24 +233,24 @@ The core process runs these threads. Named threads show up by name in WPA and de | Thread | Name | Source | Job | |---|---|---|---| -| Tick | `Wind tick` | `src/main.cpp` | The loop and every Magnification call. Highest priority, see above | -| Input hooks | `Wind input hooks` | `src/input_router.cpp` | LL mouse and keyboard hooks, Raw Input registration | -| Focus tracker | (WinEvent loop) | `src/focus_track.cpp` | Caret and focus tracking, own COM apartment | -| Focus lookup | `Wind focus lookup` | `src/focus_track.cpp` | One UIA focus query at a time, detached on timeout | -| Cursor swaps | `Wind cursor swaps` | `src/cursor_blanker.cpp` | System cursor hide, tint and restore swaps, off the tick | -| DWM watch | `Wind DWM watch` | `src/dwm_watch.cpp` | Polls for a dwm.exe restart once a second, bumps a generation | -| Log writer | `Wind log writer` | `src/logging.cpp` | Drains the log queue to disk (1000 ms wait) | -| Tray supervisor | (unnamed) | `src/tray_host.cpp` | Keeps `WindTray.exe` running, rate limited | -| Trace dump | (short lived) | `src/transform_model.cpp` | Writes the `txTrace=1` CSV at session end, below normal priority | +| Tick | `Wind tick` | `src/core/main.cpp` | The loop and every Magnification call. Highest priority, see above | +| Input hooks | `Wind input hooks` | `src/input/input_router.cpp` | LL mouse and keyboard hooks, Raw Input registration | +| Focus tracker | (WinEvent loop) | `src/track/focus_track.cpp` | Caret and focus tracking, own COM apartment | +| Focus lookup | `Wind focus lookup` | `src/track/focus_track.cpp` | One UIA focus query at a time, detached on timeout | +| Cursor swaps | `Wind cursor swaps` | `src/cursor/cursor_blanker.cpp` | System cursor hide, tint and restore swaps, off the tick | +| DWM watch | `Wind DWM watch` | `src/transform/dwm_watch.cpp` | Polls for a dwm.exe restart once a second, bumps a generation | +| Log writer | `Wind log writer` | `src/core/logging.cpp` | Drains the log queue to disk (1000 ms wait) | +| Tray supervisor | (unnamed) | `src/tray/tray_host.cpp` | Keeps `WindTray.exe` running, rate limited | +| Trace dump | (short lived) | `src/transform/transform_model.cpp` | Writes the `txTrace=1` CSV at session end, below normal priority | WindConfig has its own short-lived export thread, and the timer-polling threads (DWM watch, log writer) wake on a timer even at 1x, a known cost of the idle design. -- **Hook thread** (`src/input_router.cpp`). LL hook callbacks must return fast or Windows evicts the +- **Hook thread** (`src/input/input_router.cpp`). LL hook callbacks must return fast or Windows evicts the hook, and they stall system input while running, so they cannot share a thread that blocks in `Present`. The hook thread sets atomics, counts mickeys and swallows bound keys. See [06](06-input.md). -- **Focus-tracker thread** (`FocusTracker`, `src/focus_track.cpp`). WinEvents, `GetGUIThreadInfo` +- **Focus-tracker thread** (`FocusTracker`, `src/track/focus_track.cpp`). WinEvents, `GetGUIThreadInfo` and UI Automation can block and want their own message loop and COM apartment. The tick only calls `setActive()` and reads `snapshot()`. See [07](07-cursor.md). - **Magnification runtime owner.** Magnification calls are thread-affine: only the thread that diff --git a/docs/architecture/03-engines.md b/docs/architecture/03-engines.md index cf2118a4..497735ea 100644 --- a/docs/architecture/03-engines.md +++ b/docs/architecture/03-engines.md @@ -21,7 +21,7 @@ that can happen: ## The model interface -Every engine implements `wind::IMagnifierModel` (`src/magnifier_model.h`). `RunTick` drives +Every engine implements `wind::IMagnifierModel` (`src/engine/magnifier_model.h`). `RunTick` drives whatever `TickState::model` points at: | Method | Purpose | @@ -35,7 +35,7 @@ whatever `TickState::model` points at: `model` in `magnifier.ini` takes `hybrid`, `render` or `transform`. Anything else, including an old `model=magnify`, reads as `hybrid`. Both engines are built at startup whatever it says (`mRender`, -`mTransform`), and `model` only decides the pick (`PickTransformFor`, `src/engine_pick.h`): a change +`mTransform`), and `model` only decides the pick (`PickTransformFor`, `src/engine/engine_pick.h`): a change applies on the config reload, at the next zoom-in or, while zoomed, through the instant switch. A pinned Render still falls back to transform when the render device is lost or its overlay could not follow the monitor. `running.model` says `live`; if one engine fails to init it names the one left, @@ -44,15 +44,15 @@ and only then does an engine change relaunch Wind (Settings' Restart Wind button | Model | What it is | For | |---|---|---| | `hybrid` ("Auto") | `TickState` holds a `RenderModel` (`mRender`) and a `TransformModel` (`mTransform`) and points `model` at one per session | The default | -| `render` | DXGI Desktop Duplication + D3D11 onto a click-through, capture-excluded overlay (`src/render_engine.*`) | Sub-pixel pan, cursor in the same frame, shell coverage. [04](04-render-engine.md) | -| `transform` | The DWM fullscreen transform, no presents of its own (`src/transform_model.cpp`) | Games, protected video and rotated outputs, plus the desktop when `desktopTransform=1` and the input transform is verified. [05](05-transform-engine.md) | +| `render` | DXGI Desktop Duplication + D3D11 onto a click-through, capture-excluded overlay (`src/render/render_engine.*`) | Sub-pixel pan, cursor in the same frame, shell coverage. [04](04-render-engine.md) | +| `transform` | The DWM fullscreen transform, no presents of its own (`src/transform/transform_model.cpp`) | Games, protected video and rotated outputs, plus the desktop when `desktopTransform=1` and the input transform is verified. [05](05-transform-engine.md) | If the transform half fails to initialize, Auto logs a warning and runs render only; every pick site checks `t.mTransform`. ## The pick -`wind::ShouldPickTransform` (`src/engine_pick.h`) is header-only, has no `` and is +`wind::ShouldPickTransform` (`src/engine/engine_pick.h`) is header-only, has no `` and is doctested. It runs at the zoom-in edge and every zoomed tick, with the same `EnginePickInputs`. In order: diff --git a/docs/architecture/04-render-engine.md b/docs/architecture/04-render-engine.md index 6645867d..8d576301 100644 --- a/docs/architecture/04-render-engine.md +++ b/docs/architecture/04-render-engine.md @@ -9,9 +9,9 @@ for it ([03](03-engines.md)). ## Structure -`RenderEngine` (`src/render_engine.h`) is a PIMPL class; D3D and DXGI headers stay in -`src/render_engine.cpp`. `RenderModel` (`src/render_model.cpp`) adapts it to `IMagnifierModel`. -`RunTick` owns activation and reveal (`EnterSession`, `RevealAndHandover` in `src/main.cpp`), +`RenderEngine` (`src/render/render_engine.h`) is a PIMPL class; D3D and DXGI headers stay in +`src/render/render_engine.cpp`. `RenderModel` (`src/render/render_model.cpp`) adapts it to `IMagnifierModel`. +`RunTick` owns activation and reveal (`EnterSession`, `RevealAndHandover` in `src/core/main.cpp`), because they need facts the engine does not have (does the foreground cover the monitor, is this the idle-to-active edge). @@ -142,7 +142,7 @@ view. `renderFrame` re-asserts `HWND_TOPMOST` only when displaced (`overlayDispl stutters. A 1 s backstop catches misses and is skipped while a fullscreen game is foreground. **The band is a trade-off; the default is `zorderBand=0` (unbanded).** Both bandable windows go -through `wind::CreateBandedWindow` (`src/band_window.h`), which cascades the requested band to 16 +through `wind::CreateBandedWindow` (`src/render/band_window.h`), which cascades the requested band to 16 to unbanded and logs every refusal. | Band | Covers Start, taskbar, tray flyouts | Snipping Tool (Win+Shift+S) | @@ -170,13 +170,13 @@ tonemaps to SDR (`hdrTonemap=1`, default). and a failed query keeps the last good value. - `ensureDesktopCopy` recreates the copy in whatever format the capture delivers, so a runtime HDR toggle cannot mismatch it. -- Pure maths and the throttle: `src/hdr_scale.h`. The transform engine magnifies inside DWM and +- Pure maths and the throttle: `src/render/hdr_scale.h`. The transform engine magnifies inside DWM and never converts colour. ## Colour filters -Warmth and brightness (`colorWarmPct`, `colorDimPct`) are one colour matrix (`src/color_matrix.h`), -applied by `ColorFilterController` (`src/color_filter.*`) through `MagSetFullscreenColorEffect`. +Warmth and brightness (`colorWarmPct`, `colorDimPct`) are one colour matrix (`src/color/color_matrix.h`), +applied by `ColorFilterController` (`src/color/color_filter.*`) through `MagSetFullscreenColorEffect`. - **Desktop Duplication sees the DWM effect.** While a render session is visible the DWM effect is set to identity and the render shader applies the matrix instead; otherwise the overlay would be @@ -187,7 +187,7 @@ applied by `ColorFilterController` (`src/color_filter.*`) through `MagSetFullscr - **A filter holds the Magnification runtime at 1x**, which taxes cursor changes in other apps ([05](05-transform-engine.md)). Off by default. - At 1x the hardware pointer is outside the DWM effect, so Wind swaps the system pointers for - tinted copies (`src/cursor_tint.*`). + tinted copies (`src/color/cursor_tint.*`). - Windows clears the effect when the process dies, so a crash never leaves the screen filtered. Measurements and rejected filters: [../COLOUR-FILTER-FINDINGS.md](../COLOUR-FILTER-FINDINGS.md). @@ -199,7 +199,7 @@ then the cursor. - **Scaling filter** (`renderScaling`, Settings: Render scaling, issue #456): Nearest uses the plain pass with point sampling; xBR (the default) and NVIDIA Image Scaling are their own pixel - shaders (`src/upscale_shaders.h`, `src/upscale_nis.h`, drawn by `UpscalePass`). They read texels + shaders (`src/render/upscale_shaders.h`, `src/render/upscale_nis.h`, drawn by `UpscalePass`). They read texels through `Tap()`, which tonemaps first, so they work in display space on SDR and HDR alike, and the capture crop keeps a 4-texel margin for their taps. A shader that fails to build falls back to the plain bilinear pass (logged once). Chosen in an A/B of eleven filters on 2026-10-12 (xBR 0.24 ms, @@ -215,7 +215,7 @@ then the cursor. - The cursor comes from `GetCursorInfo` + `DecodeCursorBGRA`, cached per `HCURSOR` with a 5 s staleness bound (handles are recycled), with an invert blend for I-beam cursors. `cursorMode` 0 draws only when the app shows its own cursor. -- Inspect replaces it with the crosshair from `BuildCrosshairBGRA` (`src/crosshair.cpp`). +- Inspect replaces it with the crosshair from `BuildCrosshairBGRA` (`src/cursor/crosshair.cpp`). - The hidden OS pointer is parked under the drawn cursor with `SetCursorPos` so clicks land where the user sees the pointer; `parkedLastFrame()` reports whether the park ran, and the park pauses while a mouse button is held. See [07](07-cursor.md). diff --git a/docs/architecture/05-transform-engine.md b/docs/architecture/05-transform-engine.md index dfdd5f3c..4964e87b 100644 --- a/docs/architecture/05-transform-engine.md +++ b/docs/architecture/05-transform-engine.md @@ -1,6 +1,6 @@ # 05. The transform engine -The transform engine (`src/transform_model.*`) asks DWM to magnify the desktop: one fullscreen +The transform engine (`src/transform/transform_model.*`) asks DWM to magnify the desktop: one fullscreen scale-and-translate applied inside the compositor, the mechanism the built-in Magnifier uses. There is no capture, no swapchain and no Wind window in the composition path, so a game keeps its independent-flip presentation and Wind's per-frame cost is a sub-millisecond API write. Measured @@ -15,7 +15,7 @@ machinery is shared, global and partly undocumented; most of this chapter is the **Never call `MagInitialize`/`MagUninitialize` directly.** The runtime is process-scoped and both engines use it (transform: the fullscreen transform; render: `MagShowSystemCursor`). Use -`wind::MagApiAcquire()`/`MagApiRelease()` (`src/mag_host.cpp`), a process-wide refcount. Two +`wind::MagApiAcquire()`/`MagApiRelease()` (`src/transform/mag_host.cpp`), a process-wide refcount. Two independent pairs break each other: - The transform's idle release killed render's cursor hiding: two cursors. @@ -50,13 +50,13 @@ writes is gone, see [Hook writes](#hook-writes-removed)). | Public (fallback) | `MagSetFullscreenTransform(zoom, offX, offY)` | Whole source pixels. | A failed private write latches `privateBroken_` and the session falls back to public until the next -init. Both forms come from the pure `ComputeMagTransform` (`src/transform.h`), so they always +init. Both forms come from the pure `ComputeMagTransform` (`src/transform/transform.h`), so they always describe the same rect. ## The tick path `TransformModel::present` runs one zoomed tick as a fixed sequence of private steps (declared in -`src/transform_model.h` in call order): `resolveLevel` (step cap, smooth-zoom ladder, held ramp +`src/transform/transform_model.h` in call order): `resolveLevel` (step cap, smooth-zoom ladder, held ramp steps), `applySamplingMode`, `writeSiteTransform` (edge floor and the 16-bit backstop), `switchDwmCentre`, then, unless the click pauses writes, `writeAndWarm` (the transform write and warm pulse) and `publishInputTransform` (stomp guard, decimation, self-heal). After those come the @@ -91,7 +91,7 @@ then reverted the same day: a throttled view desynchronizes from the pointer (2 low zoom; 60 Hz looks like low fps at high zoom). Do not bring a write gate back without a test that watches the view under a SLOW hand, not just stall counts. -**Warm-keeping** (`txWarmMode=1`, pure gate in `src/tx_warm.h`). DWM's magnification re-render goes +**Warm-keeping** (`txWarmMode=1`, pure gate in `src/transform/tx_warm.h`). DWM's magnification re-render goes cold when the source rect sits still, and the first real pan after a pause pays ~25 ms (the pan-start hitch). A 1 px translation displacement and return is a real source change and keeps it warm. Re-sending the same transform, republishing the input transform and a sub-pixel level nudge @@ -141,7 +141,7 @@ stateDiagram-v2 `MagHost::setDwmCentring` wraps `SetFullscreenMagnifierOffsetsDWMUpdated` (user32, undocumented, resolved by name): TRUE,0,0 hands the pan to DWM, which re-centres on every cursor update; FALSE,0.8,0.8 -gives it back. Rules (`src/native_cursor.h`, tested): +gives it back. Rules (`src/transform/native_cursor.h`, tested): - On only where the view is a pure function of the pointer and no armed MPO wall is within a tick of the view (`NearWall`, a 64 source px margin: DWM's own pan is unclamped and could cross a wall @@ -162,7 +162,7 @@ gives it back. Rules (`src/native_cursor.h`, tested): `w - w/level`, fractional mid-ramp, and rounding can push the integer offset or private translation past it, so the rect samples outside the desktop texture: a GPU driver reset, always at the right or bottom edge. `ComputeMagTransform` clamps both forms with a 2 px margin. The comment block in -`src/transform.h` is the contract. +`src/transform/transform.h` is the contract. **Left and top: one texel inside.** DWM's nearest path samples around a half-texel offset, so at source 0 the first columns read outside the texture and show a light-grey line about `level/2` px @@ -200,7 +200,7 @@ Defences (wall arming in `RunTick`'s `ReadForegroundAndArmWall`, write clamp in | Off | Either | None | - The registry is read once at startup; the recorded state governs until dwm.exe restarts, because - DWM reads it only when it starts. The record (`src/mpo_boot.h`, pure half `mpo_boot_logic.h`) is + DWM reads it only when it starts. The record (`src/transform/mpo_boot.h`, pure half `mpo_boot_logic.h`) is keyed on dwm.exe's creation time, read without opening the process; OS boot time is the fallback. - The ghost is a fullscreen alpha-1 click-through window that demotes surfaces off the overlay plane. @@ -214,7 +214,7 @@ Defences (wall arming in `RunTick`'s `ReadForegroundAndArmWall`, write clamp in the MPO ghost. Field-tested 2026-10-07 on an MPO boot (RTX 5090): nearest with the guard, panned into the far-right and bottom-right corner above 10x, no driver reset; daily use up to 31x. - `tdrTest` is the field harness: 2 probes the clamp, 4 lifts the wall. -- **MPO nearest guard** (`src/mpo_guard.h`, issue #369). Zoomed at nearest on an MPO boot, Wind +- **MPO nearest guard** (`src/transform/mpo_guard.h`, issue #369). Zoomed at nearest on an MPO boot, Wind applies an invisible colour effect (0.998 on R, G, B). A colour transform, like the resample property, makes the scaled desktop visual require an external layer, and nothing under such a visual is recorded as a plane candidate, so no plane can carry the overflowing translation. @@ -240,7 +240,7 @@ DWM magnifies with nearest neighbour unless something calls smooth state can make a build look smooth that is not. The model re-applies its mode per context with up to 3 retries. - A DWM restart resets it to nearest while win32k still reads back smooth, so a read-back cannot - tell. `src/dwm_watch.*` watches this session's dwm.exe process id once a second (no handle to + tell. `src/transform/dwm_watch.*` watches this session's dwm.exe process id once a second (no handle to dwm.exe) and the model re-applies its mode when the generation changes (#396). - Smooth renders the magnified subtree into a scratch target at source resolution and scales it with Lanczos (`CResampleLayer::RenderLanczos`; the DWM registry value `ResampleModeOverride=1` @@ -249,7 +249,7 @@ DWM magnifies with nearest neighbour unless something calls 2 px and 3-7 at nearest; the same for the native pointer (and for the old sprite). Pans are clean. Suspected cause (untested): the scratch target snaps to whole source pixels while the private channel positions the view in screen pixels, so the image can jump up to one source pixel times the zoom. -- **Smooth-zoom ladder** (`txSmoothLadder=1`, `src/zoom_ladder.h`): the smooth path's scratch image +- **Smooth-zoom ladder** (`txSmoothLadder=1`, `src/transform/zoom_ladder.h`): the smooth path's scratch image has its size and origin rounded to whole pixels every frame, and two closed terms predict the resulting shift per level. While smooth, the applied level snaps to the nearest level predicting under 1 px (never backwards in a ramp; held once the zoom settles). Measured standalone at @@ -311,7 +311,7 @@ welded cursor has hover dead zones. Identity or no publish both produce dead zon [../history/POINTER-HITTEST-FINDINGS.md](../history/POINTER-HITTEST-FINDINGS.md). - **It needs UIAccess.** Availability is read from the process token's `TokenUIAccess` bit at - `initialize` (`ProcessHasUiAccess`, `src/uiaccess_token.h`), with zero Magnification calls; an acquire/release probe would run an identity + `initialize` (`ProcessHasUiAccess`, `src/core/uiaccess_token.h`), with zero Magnification calls; an acquire/release probe would run an identity write. A verified-failed publish clears `inputTransformAvailable_`, which stops Auto picking Transform for the desktop. Only `ERROR_ACCESS_DENIED` is permanent; any other failure is re-armed from the token probe when the session ends. @@ -338,7 +338,7 @@ dwmcore (RDR2 at 20x, issue #199). When a process younger than 60 s newly covers borderless, Wind holds transform writes, the weld and the zoom ramp for ~1.5 s (`TrackLaunchCover`/`QuiesceHoldActive`). -The pure `ShouldArmLaunchQuiesce` (`src/launch_quiesce.h`) vetoes composition-only overlays: +The pure `ShouldArmLaunchQuiesce` (`src/engine/launch_quiesce.h`) vetoes composition-only overlays: layered, click-through, tool, non-activating or no-redirection-bitmap windows. Without the veto the Snipping Tool overlay froze the view for 1.5 s on every snip. `WS_EX_TOPMOST` is not in the veto set, because games set it. `launchQuiesce=0` disables the hold; it is a test knob only. diff --git a/docs/architecture/06-input.md b/docs/architecture/06-input.md index 0ecbb4f0..88c604fe 100644 --- a/docs/architecture/06-input.md +++ b/docs/architecture/06-input.md @@ -3,8 +3,8 @@ Wind never has keyboard focus, yet it must see every bind press and every mouse movement system-wide without breaking input for other programs. This chapter covers the input channels, the hook thread, the swallowing rules, the bind safety rules and the recovery from silently evicted -hooks. The code is `src/input_router.*`, the `WM_INPUT` handling in `src/main.cpp`, -`src/keybind_rules.h`, `src/swallow_ledger.h` and `src/gain_learner.h`. +hooks. The code is `src/input/input_router.*`, the `WM_INPUT` handling in `src/core/main.cpp`, +`src/input/keybind_rules.h`, `src/input/swallow_ledger.h` and `src/cursor/gain_learner.h`. ## Channels @@ -63,7 +63,7 @@ Bound inputs are eaten so they never also fire in the focused app. ## Bind rules -**One rule set for every bind:** `src/keybind_rules.h` (`CheckKeyBind`, `CheckWheelBind`, +**One rule set for every bind:** `src/input/keybind_rules.h` (`CheckKeyBind`, `CheckWheelBind`, `CheckClickBind`), mirrored in `ui/src/lib/keybindRules.js`. Both are tested against `tests/fixtures/keybind_cases.txt`, so change both or the tests fail. @@ -88,7 +88,7 @@ for 0.1 s. The old `zoomWheelMods` key is migrated into free slots once at start **Keyboard panning** (`panLeftVk` .. `panDownVk` + mods, unbound by default). Pan slots match only while the tick arms them (`setPanArmed`: zoomed, not Inspect, no mouselook lock), so at 1x the keys reach apps. The swallow is decided once per press, and the tick pans only on presses the hook -swallowed (`keySwallowed`), as the `ViewOwner::Keys` detached view (`src/keyboard_pan.h`). +swallowed (`keySwallowed`), as the `ViewOwner::Keys` detached view (`src/input/keyboard_pan.h`). ## Raw Input as the safety net @@ -101,7 +101,7 @@ Both hooks have a Raw Input backstop for lost UP events, in the `WM_INPUT` handl - **Reordering guard.** `WM_INPUT` drains up to a tick late, so a raw UP can arrive after the hook recorded the next press. The net skips the clear when the hook recorded a DOWN for that input AFTER the UP, comparing event times (`GetMessageTime()` of the `WM_INPUT` against the hook - struct's `.time`, `src/event_order.h`), not the wall clock, so a main-thread stall of any length + struct's `.time`, `src/input/event_order.h`), not the wall clock, so a main-thread stall of any length cannot make a stale UP cancel a live hold. - DOWN edges stay hook-authoritative while the hook is active; `WM_INPUT` writes down-state only in the no-hook fallback. diff --git a/docs/architecture/07-cursor.md b/docs/architecture/07-cursor.md index 05b6d497..f95cd80d 100644 --- a/docs/architecture/07-cursor.md +++ b/docs/architecture/07-cursor.md @@ -10,7 +10,7 @@ Inspect crosshair, lock detection, Inspect, tracking and keyboard panning. ## The mapper -`CursorMapper` (`src/cursor_mapper.*`, pure, tested) integrates per-tick deltas into a float lens +`CursorMapper` (`src/cursor/cursor_mapper.*`, pure, tested) integrates per-tick deltas into a float lens centre `(cx_, cy_)` in monitor-local pixels (no easing: `cursorSmoothing` was removed in #430). Each tick `update` returns one `MapResult`: @@ -72,7 +72,7 @@ a regime switch never snaps. While a mouse button is held, the pointer is the interaction (window drag, text selection), and a per-tick weld fights the hand: the dragged content flickered ~85 px between two positions. -`ShouldDragFollow` (`src/drag_follow.h`) suspends the weld for exactly the button-hold, and the +`ShouldDragFollow` (`src/cursor/drag_follow.h`) suspends the weld for exactly the button-hold, and the lens follows the pointer 1:1, unscaled. Only the render engine welds a free session; a free transform session never welds, so the rule decides nothing there. The press landed under the welded cursor; the release lands where pointer and content are. On release `renderFrame` invalidates its park dedupe so the next @@ -91,7 +91,7 @@ Transform sessions use the pointer Windows Magnifier uses: the real pointer, dra magnified frame. It is the transform engine's only cursor. It works at either sampling mode, because DWM samples it like the content: Smooth transform scaling makes it sharp but it shimmers slightly during zoom ramps, nearest keeps it pixelated and steady. Pure rules: -`src/native_cursor.h` (tested). +`src/transform/native_cursor.h` (tested). - **The cursor lens.** `MagHost::createCursorLens` makes a hidden window of the documented magnifier control class (`WC_MAGNIFIER`) on the tick thread (the thread that owns the runtime). With @@ -136,7 +136,7 @@ slightly during zoom ramps, nearest keeps it pixelated and steady. Pure rules: reaches the screen about a display frame after the pointer moved, while DWM centring shows the newest pointer, so the game's cursor swung behind every movement and flipped side on each change of direction: rms 54 screen px at 6.5x and 1000 desktop px/s (2026-10-11, 3 runs). While a covering - foreground app hides the pointer (`GameDrawsCursor`, `src/game_cursor.h`; not Wind's own hiding), + foreground app hides the pointer (`GameDrawsCursor`, `src/cursor/game_cursor.h`; not Wind's own hiding), DWM centring is off and the view follows the pointer `gameCursorLagMs` late, read back from a per-tick `PointerHistory`: rms 15-23 px at 1000 px/s, 6 px at 400 (29 before). Wind's own write without the delay measured the same as DWM centring, so the gain is the delay. The rest is the @@ -147,7 +147,7 @@ slightly during zoom ramps, nearest keeps it pixelated and steady. Pure rules: Inspect. - **Pan glide (#430, `panGlideMaxPx`, 0 = off).** A soft stop: when a mouse movement stops, the POINTER eases on at the hand's speed and slows to rest within `panGlideMaxPx` SCREEN px - at any zoom (`src/pan_glide.h`). One setting since #434: the ease's time constant follows the + at any zoom (`src/cursor/pan_glide.h`). One setting since #434: the ease's time constant follows the distance (`PanGlideTauS`, 40 px = 60 ms), shortened for a fast hand so the cap holds. The view follows by DWM centring. Any hand movement, a mouse button, a game, Inspect, a detached view or 1x ends it. Wind's own steps move the tick baseline (`lastSetVirtual`), so the lock detector and the gain learner only ever see hand motion. A first, uncapped version @@ -196,7 +196,7 @@ gates and idle context release, all off or superseded before #369. Inspect and the hide-cursor hotkey (`cursorVisibility=never`) hide DWM's pointer in a transform session; the Inspect crosshair is then a window of Wind's. -- **`CursorBlanker`** (`src/cursor_blanker.*`) swaps the 14 system cursors for transparent ones and +- **`CursorBlanker`** (`src/cursor/cursor_blanker.*`) swaps the 14 system cursors for transparent ones and restores them by reloading the user's scheme (no cached originals). The constructor reloads it first, so a previously killed Wind's blanks never outlive it. `MagShowSystemCursor(FALSE)` covers app-custom cursors. The swaps run in order on the `Wind cursor swaps` worker thread (#363): the restore is a full @@ -204,7 +204,7 @@ session; the Inspect crosshair is then a window of Wind's. `SetSystemCursor` calls, which froze the 1x landing frame on the tick thread. The zoom-out repaint nudge rides on the worker after the restore. `restoreSync()` waits (shutdown); the crash filter restores directly. The blanker and the crosshair window are always created, whatever the config. -- **`CursorSprite`** (`src/cursor_sprite.*`) is a small layered window that only ever carries the +- **`CursorSprite`** (`src/cursor/cursor_sprite.*`) is a small layered window that only ever carries the Inspect crosshair (`showCrosshair`; it renders no cursor shape any more). It sits at the look point in desktop coordinates, so DWM shows it at the view's centre, magnified. `keepOnTop()` re-asserts topmost only when displaced. @@ -214,7 +214,7 @@ session; the Inspect crosshair is then a window of Wind's. **Bands.** A UIAccess crosshair lands in band 2; Start, taskbar thumbnails and tray flyouts are band 16; the Snipping Tool overlay is band 17. `cursorBandAuto=1` (default) keeps twin windows: the band-16 one shows unless the foreground window's band is above 16, when the low one shows instead -(pure rule: `src/sprite_layer.h`; checked only while the crosshair is drawn). `zorderBand` places the +(pure rule: `src/cursor/sprite_layer.h`; checked only while the crosshair is drawn). `zorderBand` places the low window. The window is excluded from capture (otherwise it is frozen into snip screenshots) and from Aero Peek. The native pointer needs none of this: DWM draws it above every band. @@ -224,7 +224,7 @@ Magnification runtime ([04](04-render-engine.md)). ## Lock detection A mouselook game owns the pointer (clips, freezes or warps it), so panning must come from raw -mickeys. `LockDetector` (`src/lock_detector.*`, pure) decides, with hysteresis. +mickeys. `LockDetector` (`src/cursor/lock_detector.*`, pure) decides, with hysteresis. | Tell | Rule | When | |---|---|---| @@ -244,7 +244,7 @@ mickeys. `LockDetector` (`src/lock_detector.*`, pure) decides, with hysteresis. outside it (1x, Inspect) the tick clears it (and `lockFreed`); `panArmed` reads it before that recompute and would otherwise act on the previous session's value for a tick. - **A shown pointer is a free pointer in a transform session** (`LockApplies`, - `src/native_cursor.h`; the tick's result is `t.lockEff`, which every gate reads). The locked path + `src/transform/native_cursor.h`; the tick's result is `t.lockEff`, which every gate reads). The locked path pans from raw mickeys and re-parks the real pointer once per tick; the native cursor IS the real pointer, so DWM drew it wherever the hand had moved it between ticks. Field case: DOOM: The Dark Ages menus under `lockApps` (2026-10-07), measured at 4.7x as 22 px @@ -305,7 +305,7 @@ the mouse hook only swallows clicks. deduped through `GetClipCursor` (a clip write under a live transform is in the TDR class). Transform writes pause ~3 ticks around the click. Inspect stays on after a click. - **Game-inspect.** A raw-input game's camera cannot be blocked by a hook, so when - `ShouldGameInspect` (`src/inspect_focus.h`) sees a mouselook game, Wind moves foreground to an + `ShouldGameInspect` (`src/cursor/inspect_focus.h`) sees a mouselook game, Wind moves foreground to an invisible 1x1 helper window: the backgrounded game stops receiving raw input and its camera freezes, while Wind's `RIDEV_INPUTSINK` pan keeps working. The tell is a cursor hidden by the app while Wind is not hiding it; a detector lock also engages it. Do not make the zoomed path @@ -318,7 +318,7 @@ the mouse hook only swallows clicks. ## Tracking: caret, focus and mouse edge mode The view can follow the text caret (`trackCaret`, default on) and keyboard focus (`trackFocus`, -default off). `FocusTracker` (`src/focus_track.*`) runs on its own thread with WinEvents, +default off). `FocusTracker` (`src/track/focus_track.*`) runs on its own thread with WinEvents, `GetGUIThreadInfo` and UI Automation, and publishes a snapshot; the tick never calls UIA. `FocusTracker::run` hands that thread to `FocusRun` (`focus_track.cpp`): `setUp` (COM, UIA timeouts, `FocusLookup`, WinEvent hooks), `messageLoop` (wakes, 30 ms coalescing, the 16 ms backstop poll) and @@ -326,15 +326,15 @@ default off). `FocusTracker` (`src/focus_track.*`) runs on its own thread with W leaves the caret to `followCaret` (sources in `findCaret`: xterm input, Win32, UIA, MSAA fixes). - **Tracking never moves the pointer.** While caret or focus owns the view, the view is detached - (`t.viewDetached`, weld off): `DetachedMap` (`src/detached_view.h`) maps the glided centre while + (`t.viewDetached`, weld off): `DetachedMap` (`src/track/detached_view.h`) maps the glided centre while the cursor fields report the real pointer. On a mouse-move takeover the pointer is placed into the view; the view does not jump to the pointer. -- `StepViewOwner` (`src/view_target.h`) picks one owner per tick: the latest caret or focus change +- `StepViewOwner` (`src/track/view_target.h`) picks one owner per tick: the latest caret or focus change wins; real mouse motion or a button takes it back. - **Only keyboard-driven caret moves are followed.** The first caret after a focus change is a baseline. After a click there is a 1 s quiet period, ended early by a fresh non-modifier key down - (`src/typing_key.h`), never by key-ups, auto-repeat or Ctrl/Shift. -- **A focus event for the same control is not a focus change** (`src/focus_identity.h`). Notepad + (`src/input/typing_key.h`), never by key-ups, auto-repeat or Ctrl/Shift. +- **A focus event for the same control is not a focus change** (`src/track/focus_identity.h`). Notepad and VS Code fire them while typing, about three per app switch, and each used to re-baseline, so the first second of typing after a switch was not followed. Same foreground window, same focus window and same element bounds keep the caret followed (`focus repeat` in trackLog). Zoom-in @@ -343,7 +343,7 @@ leaves the caret to `followCaret` (sources in `findCaret`: xterm input, Win32, U the enter tick calls `ResetViewOwnerForSession` (owner, latched target, `wasTracking`), clears `viewDetached`, the spring velocity and the pan keys; otherwise the next zoom-in opened on the previous session's caret. -- Caret rects are corrected in `src/caret_rect.h` (tall Chromium rects trimmed to the line, a +- Caret rects are corrected in `src/track/caret_rect.h` (tall Chromium rects trimmed to the line, a whole-line rect recognised). - **VS Code (EditContext).** Its editor element (`native-edit-context`, also Monaco elsewhere) reports the UIA caret at the start of the line wherever the caret is on it. For that class only, @@ -356,9 +356,9 @@ leaves the caret to `followCaret` (sources in `findCaret`: xterm input, Win32, U without UIA; no new lookup starts while one is stuck; a late answer is used if under 250 ms old and for the same window. With focus-following off, an app with a Win32 caret skips the lookup. Calls over 200 ms log `slow resolve` with the phase. -- The glide is a critically damped spring (`SpringToward`, `src/view_glide.h`, `trackGlideMs`). +- The glide is a critically damped spring (`SpringToward`, `src/track/view_glide.h`, `trackGlideMs`). - **Java apps** (IntelliJ, PyCharm) expose the caret only through the Java Access Bridge - (`src/java_bridge.*`). UIPI drops the JVM's handshake to a UIAccess process, so the bridge's + (`src/track/java_bridge.*`). UIPI drops the JVM's handshake to a UIAccess process, so the bridge's hidden windows get a narrow `ChangeWindowMessageFilterEx` allowance. Never poll the bridge (each read runs on the Java app's UI thread); read only after bridge callbacks. Load only Authenticode-signed bridge DLLs. Read the caret with `getCaretLocation`, scaled by the monitor @@ -369,7 +369,7 @@ leaves the caret to `followCaret` (sources in `findCaret`: xterm input, Win32, U window switch resets it. The MSAA caret (`MsaaCaret`) skips windows Windows reports as hung and sits out 2 s after a call over 250 ms. - **Mouse edge mode** (`mouseAlign=1`, free-pointer sessions only): the pointer is unwelded and - `EdgePanCenter` (`src/edge_pan.h`) moves the view only when the cursor's visible body leaves the + `EdgePanCenter` (`src/track/edge_pan.h`) moves the view only when the cursor's visible body leaves the margin band (`mouseMarginPct`). Edge-pinned motion is hidden from the lock detector (`PointerPinnedAtEdge`), or corners fling the pointer. `trackAlign` does the same for the caret. @@ -377,7 +377,7 @@ Field notes: [../TRACKING-FINDINGS.md](../TRACKING-FINDINGS.md). ## Keyboard panning -`ViewOwner::Keys` is a detached owner next to caret and focus. `KeyPan` (`src/keyboard_pan.h`, pure) +`ViewOwner::Keys` is a detached owner next to caret and focus. `KeyPan` (`src/input/keyboard_pan.h`, pure) turns held pan keys into a view delta in screen space, so the feel does not change with zoom: - A hold pans at `panSpeed x 1.25` screen widths per second at high zoom, scaled down at low zoom diff --git a/docs/architecture/08-config-profiles.md b/docs/architecture/08-config-profiles.md index ce515d30..4a333289 100644 --- a/docs/architecture/08-config-profiles.md +++ b/docs/architecture/08-config-profiles.md @@ -14,7 +14,7 @@ resolve it through `wind::ResolveIniPath()`. The settings app can crash or resta the magnifier, and the processes run at different integrity levels (`Wind.exe` is UIAccess, the others are not). -- Every writer uses `wind::WriteTextFileAtomic` (`src/profiles_io.h`): write a temp file, then +- Every writer uses `wind::WriteTextFileAtomic` (`src/config/profiles_io.h`): write a temp file, then `MoveFileExW(MOVEFILE_REPLACE_EXISTING)`. The temp name embeds the process id, so two writers never clobber each other's temp file. The temp is written with `WriteFile`, every byte count is checked and the data is flushed before the rename: a full disk fails the write and leaves the old @@ -36,7 +36,7 @@ others are not). - The only cross-process kernel objects are the single-instance mutexes, the ini write lock and the `Local\Wind_QuitRequest` event (quit, restart handshake, installer). A window message would not work: UIPI drops `PostMessage` from a normal process to a UIAccess one. Their names are constants - in `src/tray_ipc.h` (`kQuitEventName` and the rest); the NSIS and PowerShell copies point there. + in `src/tray/tray_ipc.h` (`kQuitEventName` and the rest); the NSIS and PowerShell copies point there. - The tray's status block (`Local\Wind_TrayState_v1`) carries status, not settings ([01](01-overview.md)). @@ -51,7 +51,7 @@ flowchart LR ## Where the file lives -`wind::ResolveIniPath()` (`src/config_path.h`) probes whether the exe's directory is writable +`wind::ResolveIniPath()` (`src/config/config_path.h`) probes whether the exe's directory is writable (a sentinel file opened with `FILE_FLAG_DELETE_ON_CLOSE`). - Writable (dev build): the ini sits next to the exe, in `build\` (see [11](11-build-test-release.md)). @@ -66,12 +66,12 @@ flowchart LR ## Parsing -`wind::ParseConfig` (`src/config.cpp`) is pure and tested. Every `Config` field carries its default +`wind::ParseConfig` (`src/config/config.cpp`) is pure and tested. Every `Config` field carries its default as an initializer, so a missing or malformed key keeps the default; parsing never fails. - Numeric values are clamped to tested ranges. - `model` must be `render`, `transform` or `hybrid`; anything else becomes `hybrid`. -- Unsafe binds read as unbound (`src/keybind_rules.h`, [06](06-input.md)). +- Unsafe binds read as unbound (`src/input/keybind_rules.h`, [06](06-input.md)). - `LoadConfig` is the I/O wrapper, excluded from the test build by `WIND_TESTS`. - Structure: per line `SplitIniLine` (key and value), `ApplyEmptyableKey` (the exe lists and `engine*`, which accept an empty value), then `ApplyValueKey` (one parser per key; a bad value @@ -83,7 +83,7 @@ as an initializer, so a missing or malformed key keeps the default; parsing neve The reload mechanics are in [02](02-tick-loop.md). A reload rebuilds `ZoomController`, so it collapses an active zoom; therefore `StripUiOnlyKeys` removes the eleven keys the core never reads -(`kUiOnlyKeys` in `src/profiles.h`: `uiTheme`, `uiPalette`, `showAdvanced`, `onboarded`, `trayPinned`, +(`kUiOnlyKeys` in `src/config/profiles.h`: `uiTheme`, `uiPalette`, `showAdvanced`, `onboarded`, `trayPinned`, `uiHighResNoticeOff` and the five tray layout keys `trayPerf`, `traySliders`, `traySliderOrder`, `trayToggles`, `trayToggleOrder`) and the reload is skipped when the stripped text is unchanged. `profile` stays in the fingerprint, so a profile switch reloads. @@ -107,10 +107,10 @@ values above 1 read as 1. A profile is a named full snapshot of the settings, keybinds included, stored as `profiles\.ini` next to the resolved ini, with `profile=` in the live ini. Pure logic is -in `src/profiles.*` (tested); I/O in `src/profiles_io.h`. +in `src/config/profiles.*` (tested); I/O in `src/config/profiles_io.h`. **Global keys never travel with a profile.** `IsGlobalProfileKey` covers `profile` plus the -`kUiOnlyKeys` list (`src/profiles.h`): `onboarded`, `uiTheme`, `uiPalette`, `showAdvanced`, +`kUiOnlyKeys` list (`src/config/profiles.h`): `onboarded`, `uiTheme`, `uiPalette`, `showAdvanced`, `trayPinned`, `uiHighResNoticeOff` and the five tray layout keys (`trayPerf`, `traySliders`, `traySliderOrder`, `trayToggles`, `trayToggleOrder`). `MakeProfileText` strips them from profile files; `MakeLiveText` carries them over from the old live text. Both work line by line and keep @@ -135,7 +135,7 @@ a node test (`npm run test:rules`) both read. - Tray Quit compares the files and prompts Save, Discard or Cancel. **Switching** (Settings or the tray flyout, one implementation: `wind::SwitchProfile` in -`src/profile_switch.h`; each surface only maps its result to its own messages): +`src/config/profile_switch.h`; each surface only maps its result to its own messages): 1. Read and check the profile with `ProfileTextError`, which rejects binary, oversized or unparseable text. A read failure is distinct from an empty file; treating a locked file as empty @@ -145,7 +145,7 @@ a node test (`npm run test:rules`) both read. 3. Write `MakeLiveText(profile, oldLive, name)` over the live ini. 4. The core hot-reloads it, `model` included (`running.model` reads `live`). Only when Wind runs one engine (`running.model` names it) and the parsed `model` differs does the surface relaunch - `Wind.exe` (`EngineSwitchesLive`, `src/profiles_io.h`), writing `session.keep` first. If that + `Wind.exe` (`EngineSwitchesLive`, `src/config/profiles_io.h`), writing `session.keep` first. If that relaunch fails, it writes the old `model` back (`RevertModelAfterFailedRelaunch`, also used by the tray's engine pick), so the ini always matches the running engine. @@ -203,7 +203,7 @@ Every key works in the ini whether or not Settings shows it. Keys hot-reload unl | Keys | Meaning | |---|---| | `txSamplingMode` (0) | Transform sampling: 0 nearest, 1 smooth (Settings: Transform scaling, formerly "High resolution cursor", [05](05-transform-engine.md)) | -| `edgeClip` (1, hot) | While a transform session is zoomed, clips the pointer 1 px inside the monitor so it cannot rest on the contested outermost pixel (cursor-shape flicker at the left/top edge). Side effect: in a native-cursor session the pointer cannot reach the last pixel row and column. A tighter existing clip (game confine, Inspect) always wins; 0 turns it off. Rationale: `Config::edgeClip` in `src/config.h`, mechanics in `TransformModel::edgeClipManage` | +| `edgeClip` (1, hot) | While a transform session is zoomed, clips the pointer 1 px inside the monitor so it cannot rest on the contested outermost pixel (cursor-shape flicker at the left/top edge). Side effect: in a native-cursor session the pointer cannot reach the last pixel row and column. A tighter existing clip (game confine, Inspect) always wins; 0 turns it off. Rationale: `Config::edgeClip` in `src/config/config.h`, mechanics in `TransformModel::edgeClipManage` | | `renderScaling` (1), `upscaleTiming` (0) | Render engine scaling: 0 nearest, 1 xBR, 2 NVIDIA Image Scaling (Settings: Render scaling, [04](04-render-engine.md)); `bilinear` is retired and only migrates (0 keeps nearest). `upscaleTiming=1` logs the filter's GPU time | | `sharpness`, `brightness`, `hdrTonemap` (1) | Render engine image | | `cursorConstantSize` (0), `cursorVisibility` (`auto`) | Render cursor size and when it is drawn | @@ -233,7 +233,7 @@ failed to init. | Keys | Meaning | |---|---| -| `edgeClip` (1) | While a transform session is zoomed, `ClipCursor` 1 px inside the monitor keeps the pointer off the contested outermost pixels (edge cursor-shape flicker); 0 lets the pointer reach the corner pixel. The trade-off is recorded at `Config::edgeClip` in `src/config.h` | +| `edgeClip` (1) | While a transform session is zoomed, `ClipCursor` 1 px inside the monitor keeps the pointer off the contested outermost pixels (edge cursor-shape flicker); 0 lets the pointer reach the corner pixel. The trade-off is recorded at `Config::edgeClip` in `src/config/config.h` | | `lockedBallistics` (1) | Locked games pan with the learned input-to-output gain (`GainLearner`); 0 pans with plain raw mickeys | | `smoothPan` (0, restart) | Hold the display composited while zoomed (a 1 px pin) so flip-model games keep DWM's pan path | | `fastPan` (1, restart) | Pan through the private `SetMagnificationDesktopMagnification` channel (finer than the public write) | @@ -246,4 +246,4 @@ failed to init. `diagnostics=1` writes the frame-pacing log; the rest is in [12](12-instrumentation.md). The other transform tuning keys (`tx*`, `ixDecimate`, `mpoBuster`, `tdrTest`) are documented on their `Config` -fields in `src/config.h`. +fields in `src/config/config.h`. diff --git a/docs/architecture/09-settings-ui.md b/docs/architecture/09-settings-ui.md index 6f815573..19421338 100644 --- a/docs/architecture/09-settings-ui.md +++ b/docs/architecture/09-settings-ui.md @@ -167,7 +167,7 @@ sequenceDiagram ## Tray menu page -`ui/src/tray/TrayMenuPage.svelte` (list logic in `trayModel.js`, mirroring `src/tray_items.*`). A +`ui/src/tray/TrayMenuPage.svelte` (list logic in `trayModel.js`, mirroring `src/tray/tray_items.*`). A toggle turns the Performance header on; two cards, Sliders (up to 4) and Toggles, list the eligible items with a drag handle, icon, name, description and a check button. Rows reorder inside their card by pointer drag, or with the keyboard: Space to pick up and drop, arrows to move. The keys are diff --git a/docs/architecture/11-build-test-release.md b/docs/architecture/11-build-test-release.md index 4d987b81..f91f0f24 100644 --- a/docs/architecture/11-build-test-release.md +++ b/docs/architecture/11-build-test-release.md @@ -19,7 +19,7 @@ compile the same sources with different defines, and the tray and settings hosts |---|---|---| | (none) | `build\Wind.exe` + `build\WindTray.exe` | The app with the `uiAccess=false` manifest. It refuses to start without UIAccess (issue #460) unless `WIND_ALLOW_NO_UIACCESS=1` or `WIND_SELFTEST=1` is set | | `test` | `build\wind_tests.exe` | The doctest binary over the pure sources; runs it from the repo root (it finds `tests\fixtures` there) and returns its exit code | -| `check` | – | Compile-only pass over `src\*.cpp`, `src\tray_app\*.cpp` and `src\config_ui\main.cpp`, objects in `build\obj\check\` | +| `check` | – | Compile-only pass over Wind.exe's sources (`CORE_SRC`), `src\tray_app\*.cpp` and `src\config_ui\main.cpp`, objects in `build\obj\check\` | | `uiaccess` | `build\Wind.exe` + `build\WindTray.exe` | `Wind.uiaccess.manifest` and `/DWIND_UIACCESS`; useful only signed and in Program Files. `WindTray.exe` always keeps the plain manifest | | `tray` | `build\WindTray.exe` | The tray helper alone | | `config` | `build\WindConfig.exe` | Builds the Svelte app to `ui/dist/`, then the WebView2 host against `third_party/webview2`, then mirrors `ui\dist` to `build\ui\dist` (the host loads `\ui\dist`) | @@ -35,6 +35,20 @@ the root by an older clone is no longer read (move it into `build\` to keep it). The installer treats NSIS warnings as errors: an unreferenced define in generated layout data is how a page ends up wired to nothing. +## Source folders and includes + +`src\` is grouped by area, one folder per row of the source map in [01](01-overview.md#source-map): +`core`, `engine`, `render`, `transform`, `color`, `input`, `cursor`, `track`, `zoom`, `config`, `tray`, +`platform`, plus `tray_app` and `config_ui`. `wind.rc`, `resource.h` and `version.h` stay in `src\` +itself, where `tools\version.ps1`, `installer\wind.nsi` and `ui/vite.config.js` read the version. + +**A Wind header is always included by its bare file name** (`#include "config.h"`, never +`"../config.h"` or `"../src/config/config.h"`), from `src\` and `tests\` alike. `build.bat` puts every +src folder on every compile's include path (`WIND_INC`) and lists Wind.exe's source folders once +(`CORE_SRC`). A new folder goes into `WIND_INC`, and into `CORE_SRC` when it holds Wind.exe sources. +Header file names must stay unique across `src\`. The `.rc` files are the exception: rc.exe gets no +include path, so `src\tray_app\wind_tray.rc` reaches `resource.h` and `version.h` through `..\`. + ## Pure versus Win32 **Anything with real logic compiles without ``.** The magnifier cannot be driven @@ -49,11 +63,11 @@ headlessly, so the unit tests are the only verification loop that runs everywher `config_ui/wind_watchdog.h`, `config_ui/bridge_json.h`, `swallow_ledger.h`, `reload_gate.h` and others) ride in through their test files. - One test file per module (`tests/test_.cpp`). A new pure `.cpp` also goes into the `:test` list. -- Files that straddle the line put their OS half under `#ifndef WIND_TESTS`. `src/config.cpp` is +- Files that straddle the line put their OS half under `#ifndef WIND_TESTS`. `src/config/config.cpp` is the example: `ParseConfig` and `StripUiOnlyKeys` above, `LoadConfig` and the only `#include ` below. - Thin header-only Win32 I/O layers may be tested too, from a test file that includes - `` itself: `tests/test_profiles_io.cpp` exercises `src/profiles_io.h` against real + `` itself: `tests/test_profiles_io.cpp` exercises `src/config/profiles_io.h` against real temp files. They need no Wind runtime, so they still run headless. - `tests/fixtures/keybind_cases.txt` is shared by the C++ and the JavaScript bind rules. The JS half is `ui/tests/keybind-rules.nodetest.mjs`, run by `npm run test:rules` in `ui/` (`node --test`, no @@ -159,7 +173,7 @@ environment-driven: `WIND_SIGN_THUMBPRINT`, or `WIND_SIGN_PFX` plus `WIND_SIGN_P before makensis packs it (UIAccess is granted on `Wind.exe`'s own signature). - Without one (CI today) it packs both variants: the ordinary build and the UIAccess build as `build\WindUA.exe` (the `uiaccess` build's `build\Wind.exe`, renamed). Setup signs `WindUA.exe` on each PC with a per-machine certificate whose private key - it deletes at once (`installer/local-sign.ps1`). If that fails, setup keeps the ordinary build, says signing failed and does not start Wind: without UIAccess, Wind refuses to start ("Wind can't start", `src/uiaccess_gate.h`). + it deletes at once (`installer/local-sign.ps1`). If that fails, setup keeps the ordinary build, says signing failed and does not start Wind: without UIAccess, Wind refuses to start ("Wind can't start", `src/core/uiaccess_gate.h`). - **Never put the self-signed dev certificate in CI**: it is trusted by nobody and looks worse than no signature. diff --git a/docs/architecture/12-instrumentation.md b/docs/architecture/12-instrumentation.md index dc48f353..97086b4f 100644 --- a/docs/architecture/12-instrumentation.md +++ b/docs/architecture/12-instrumentation.md @@ -2,7 +2,7 @@ Wind's output is compositor state on a real display and its input is a real mouse, so most questions are settled by measurement on hardware. This chapter covers the logging built into the -binaries (`src/logging.*`), the diagnostic knobs compiled into Wind, and the scripts in `tools/`. +binaries (`src/core/logging.*`), the diagnostic knobs compiled into Wind, and the scripts in `tools/`. ## Field method @@ -19,14 +19,14 @@ Write the conclusion into a findings file under `docs/` (index: ## The proving ground `tools/testenv/` is the reusable automated environment: `run.ps1` restarts Wind with per-tick -telemetry (`src/test_telemetry.h`, `WIND_TESTLOG` or `%LOCALAPPDATA%\Wind\testlog.txt`), drives +telemetry (`src/core/test_telemetry.h`, `WIND_TESTLOG` or `%LOCALAPPDATA%\Wind\testlog.txt`), drives scenarios (backdrop x zoom x movement) and compares pacing, ramp back-steps, cursor jitter and RAM against `baselines.json`; `-CI` exits nonzero on regression. Suites run from ~1 to ~8 minutes. Details: `tools/testenv/README.md`. ## Logging -Both binaries log through `src/logging.cpp`. The pure half (formatting, rotation, snapshot text) is +Both binaries log through `src/core/logging.cpp`. The pure half (formatting, rotation, snapshot text) is unit-tested; the Win32 half is excluded from the test build. - **Files.** The `logs\` folder next to the exe when that folder is writable (dev and portable @@ -38,7 +38,7 @@ unit-tested; the Win32 half is excluded from the test build. - **Lines.** `wind::Log(level, category, fmt, ...)` gives `2026-05-31T08:14:22.137Z +962862007.114 t57132 WARN render `: precise UTC, the QPC clock in ms (the clock of PresentMon `--qpc_time_ms`, ETW and the tick records) and the thread id. -- **Non-blocking (#361).** `Log` formats into a lock-free queue (`src/log_queue.h`, 1024 lines) +- **Non-blocking (#361).** `Log` formats into a lock-free queue (`src/core/log_queue.h`, 1024 lines) and returns; the `Wind log writer` thread (below normal priority) writes in batches, flushes on Warn and Error, and rotates at runtime. A caller never waits on the disk, an EDR scan or another thread, so the tick and hook threads may log. A full queue drops the line and the writer logs @@ -55,10 +55,10 @@ unit-tested; the Win32 half is excluded from the test build. ## Hitch recorder (#361) -Every tick fills a `TickRec` (`src/hitch_record.h`): its dt, the pacing wait before it and how +Every tick fills a `TickRec` (`src/core/hitch_record.h`): its dt, the pacing wait before it and how late that wait returned, its wall time and its thread CPU time (`QueryThreadCycleTime`, calibrated against QPC in the first second), and spans for the parts that can block. `SpanScope` -(`src/tick_span.h`) times a call into the current record from anywhere on the tick thread; it is +(`src/core/tick_span.h`) times a call into the current record from anywhere on the tick thread; it is a null check on other threads. Spans: `track`, `color`, `present`, `txwrite` (MagHost writes), `ix`, `sprite` (the Inspect crosshair window), `activate`, `cursor`. A ring keeps the last 512 records. Cost: about a dozen QPC reads per tick, no allocation, no I/O. diff --git a/docs/history/README.md b/docs/history/README.md index 9f728923..b81f3190 100644 --- a/docs/history/README.md +++ b/docs/history/README.md @@ -2,7 +2,9 @@ Frozen records of investigations that are closed. They stay for their measurements and their "do not re-try" conclusions; the code and [the architecture docs](../architecture/README.md) are -authoritative, and these files are not updated as the code moves on. +authoritative, and these files are not updated as the code moves on. Source paths here +(`src/`) predate the src/ regrouping into area folders (#486); find a file's folder in the +source map of [01](../architecture/01-overview.md#source-map). - [NATIVE-MAGNIFIER-STOMP.md](NATIVE-MAGNIFIER-STOMP.md): a running built-in Magnifier fights the transform engine; the stomp guard (#217; picking Render while it runs is parked). - [PERF-ACRYLIC-PARITY-2026-08-21.md](PERF-ACRYLIC-PARITY-2026-08-21.md): zoom-in stalls over acrylic versus the built-in Magnifier; the `txMaxStepPct` cap (#219). diff --git a/docs/specs/README.md b/docs/specs/README.md index b3f232b5..c44750ac 100644 --- a/docs/specs/README.md +++ b/docs/specs/README.md @@ -5,3 +5,5 @@ frozen: they record what was decided at the time and are not updated as the code parts of them no longer match today's behaviour (for example, engine changes now apply live instead of restarting Wind). The code and [the architecture docs](../architecture/README.md) are authoritative. New plans and brainstorm output are not committed; open work lives in GitHub issues. +Source paths here (`src/`) predate the src/ regrouping into area folders (#486); find a file's +folder in the source map of [01](../architecture/01-overview.md#source-map). diff --git a/installer/app.nsh b/installer/app.nsh index 85452ed2..1d1dc84e 100644 --- a/installer/app.nsh +++ b/installer/app.nsh @@ -14,7 +14,7 @@ ; Wind's own two kernel objects. Both are Local\, i.e. session-scoped, and UAC elevation ; stays inside the session, so the elevated installer and the user's Wind see the same -; objects. Names must match kInstanceMutexName and kQuitEventName in src\tray_ipc.h exactly. +; objects. Names must match kInstanceMutexName and kQuitEventName in src\tray\tray_ipc.h exactly. !define WIND_MUTEX "Local\Wind_Magnifier_SingleInstance" !define WIND_QUIT "Local\Wind_QuitRequest" @@ -31,7 +31,7 @@ Var LicenceDir ; where "Read the full licence" put its copy, empty until then ; ---- stop a running Wind ----------------------------------------------------- ; An upgrade always runs over a live tray app holding its own exe open. Wind exposes an -; auto-reset named event for exactly this (src\main.cpp:2199); setting it makes Wind exit +; auto-reset named event for exactly this (src\core\main.cpp:2199); setting it makes Wind exit ; CLEANLY, which restores the OS cursor, releases any ClipCursor and releases the shared ; Magnification runtime. Killing the process skips all of that and can leave the ; pointer hidden or pinned to one pixel. So: ask, wait, and only then kill. @@ -128,7 +128,7 @@ Var LicenceDir ; where "Read the full licence" put its copy, empty until then ; ---- WebView2 ---------------------------------------------------------------- ; WindConfig.exe paints an empty shell without the Evergreen runtime. Microsoft's ; uninstaller leaves `pv` behind set to "0.0.0.0" rather than deleting it, so a value -; being present is not proof. src\webview2_probe.h is the tested statement of that rule; NSIS +; being present is not proof. src\platform\webview2_probe.h is the tested statement of that rule; NSIS ; cannot call it, so this macro mirrors it for the two values the uninstaller leaves. !macro WIND_ENSURE_WEBVIEW2 StrCpy $0 "" diff --git a/src/config/config.cpp b/src/config/config.cpp index 4af4c288..6861d23b 100644 --- a/src/config/config.cpp +++ b/src/config/config.cpp @@ -128,7 +128,7 @@ static void SanitizeBinds(Config& c) { // Reject keybinds to keys Wind must never swallow (see IsForbiddenBindVk). A bound key is // eaten system-wide, so binding e.g. Backspace or the Windows key would make it unusable // everywhere; treat a forbidden bind as unbound regardless of how it got into the ini. - // Since #285 every bind goes through the one shared rule set (src/keybind_rules.h), which also + // Since #285 every bind goes through the one shared rule set (src/input/keybind_rules.h), which also // refuses typing keys alone, Shift/AltGr + a typing key and system-reserved combos: an unsafe bind // in an ini (hand-edited, or from an older version) reads as unbound. auto sanitizeKey = [](int& vk, int* mods) { @@ -429,7 +429,7 @@ std::string StripUiOnlyKeys(const std::string& iniText) { size_t b = line.find_first_not_of(" \t"); bool uiOnly = false; if (b != std::string::npos) { - // The global keys minus "profile" (kUiOnlyKeys, src/profiles.h): a profile switch must + // The global keys minus "profile" (kUiOnlyKeys, src/config/profiles.h): a profile switch must // still reload the core. for (const char* k : kUiOnlyKeys) { const size_t n = strlen(k); @@ -491,7 +491,7 @@ std::string DefaultIniText() { "; side-button mouse. The bound key is SWALLOWED (it won't reach the focused app), so\n" "; it can't double-fire. Typing keys, Backspace, a bare modifier, system combos (Alt+F4,\n" "; Alt+Tab...) and Windows-reserved Win combos can't be bound (they'd be lost system-wide;\n" - "; src/keybind_rules.h). e.g. 33=PageUp 34=PageDown 107/109=NumPad +/- 112=F1.\n" + "; src/input/keybind_rules.h). e.g. 33=PageUp 34=PageDown 107/109=NumPad +/- 112=F1.\n" "zoomInVk=0\nzoomOutVk=0\n" "; Modifier mask required with each zoom key (bit 1=Ctrl, 2=Alt, 4=Shift, 8=Win;\n" "; 0=no modifier). e.g. 3 = Ctrl+Alt. Extra modifiers held don't disqualify.\n" diff --git a/src/config/config.h b/src/config/config.h index ffb2ada8..6acddfb3 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -225,7 +225,7 @@ struct Config { // this tick: dt=25.01ms wrote=1 changed=1 <- the FIRST REAL pan write // DWM kept compositing at 143Hz through the rest and still paid ~25ms the moment the magnified // SOURCE REGION actually moved, so only a real change to the sampled region keeps it warm. The - // measurements and the channels that do NOT work are in src/tx_warm.h. + // measurements and the channels that do NOT work are in src/transform/tx_warm.h. // 0 = off (no warm-keeping) // 1 = 1px translation pulse (shipped). The cost is honest and known: the view sits 1px off // the truth for one tick per pulse. It is shipped anyway because the hitch it removes is @@ -240,7 +240,7 @@ struct Config { // where native Magnifier at rest costs 0.2%, and that was the entire GPU gap the field saw - // panning costs both about the same (Wind 16%, native 12%). So the warm write is a PULSE on // this cadence: one 1px displacement and its return per period, nothing in between. 0 = every - // tick (the 2026-08-27 behaviour). The pure gate is WarmAction (src/tx_warm.h). + // tick (the 2026-08-27 behaviour). The pure gate is WarmAction (src/transform/tx_warm.h). // Rest cost measured per cadence (same rig, dwm.exe 3D %): every tick 9-16, 48Hz 10.1, // 24Hz 8.3, 12Hz 4.6, 6Hz 2.4, off 0.0 - roughly 0.2% per re-render/s. The pan-start hitch // does NOT reproduce on the desktop at any cadence (tools/warm_cadence_sweep.ps1: wake-write @@ -276,7 +276,7 @@ struct Config { int launchQuiesce = 1; // Locked-regime pan speed (2026-08-28, hot). 1 (DEFAULT) = pan at the TRUE desktop cursor // speed, LEARNED from the OS itself: free-cursor ticks record the raw-in -> cursor-out ratio - // per speed (src/gain_learner.h) and locked sessions replay it - slider, acceleration curve, + // per speed (src/cursor/gain_learner.h) and locked sessions replay it - slider, acceleration curve, // polling rate and every undocumented constant included, nothing to tune. Modelling this // pipeline (per-packet Windows-ballistics cooking, since removed; Inspect now replays the // learned gain too) was tried twice and missed both ways, because WM_INPUT coalescing wrecks any @@ -296,23 +296,23 @@ struct Config { // intersected with whatever clip already exists, and never fighting a TIGHTER clip (a game // confine, Inspect's 1px freeze). 0 = off (hot). int edgeClip = 1; - // MPO nearest guard (issue #369, src/mpo_guard.h): 1 (DEFAULT, field-tested 2026-10-07) = + // MPO nearest guard (issue #369, src/transform/mpo_guard.h): 1 (DEFAULT, field-tested 2026-10-07) = // nearest sampling is allowed on an MPO-on boot, with an invisible colour effect while zoomed // so DWM composes the desktop itself (no plane, no 16-bit overflow). 0 = nearest on MPO boots // is turned into smooth as before. The pan walls stay armed either way. Hot: read on every // config load (EffectiveSamplingMode). int mpoNearestGuard = 1; - // Native cursor (issue #369, src/native_cursor.h): 1 (DEFAULT) = transform sessions use DWM's + // Native cursor (issue #369, src/transform/native_cursor.h): 1 (DEFAULT) = transform sessions use DWM's // own magnified pointer and DWM's centring. 0 = the pre-#369 legacy sprite session, kept as an // ini-only A/B fallback (issue #463): Wind hides the real pointer, draws its shape in a sprite // welded to the view, and writes every view itself. Not in the Settings UI or the ini template. // Read at zoom-in (hot for the next session). int txNativeCursor = 1; - // Smooth-zoom ladder (issue #369, src/zoom_ladder.h): with smooth sampling, zoom only through + // Smooth-zoom ladder (issue #369, src/transform/zoom_ladder.h): with smooth sampling, zoom only through // levels where DWM's per-frame scratch rounding predicts under 1 px of movement (the zoom shake: // 11 px p95 -> 0.7 px measured at 10-25x). 0 = off (hot). int txSmoothLadder = 1; - // Smooth high-zoom steps (issue #429, RampStepHeld in src/zoom_ladder.h): with smooth sampling + // Smooth high-zoom steps (issue #429, RampStepHeld in src/transform/zoom_ladder.h): with smooth sampling // and DWM centring, above txRampMinFrom the level only changes in steps of at least // txRampMinStep per mille. About 1 % of level changes show one frame half a source pixel off // (inside DWM, with or without the nudge), so fewer changes mean fewer jumps: per slow 1x-50x @@ -393,12 +393,12 @@ struct Config { // is then scaled by this (1.0 = exact match, the default); it also scales the raw-input pan while // a game has the cursor locked (relative-mouse mode). double cursorSensitivity = 1.0; - // Pan glide (issue #430, src/pan_glide.h): when a mouse movement stops, the pointer eases on and + // Pan glide (issue #430, src/cursor/pan_glide.h): when a mouse movement stops, the pointer eases on and // comes to rest instead of halting dead. panGlideMaxPx caps how far, in SCREEN px at any zoom // (0 = off, the default). The ease's time follows the distance (PanGlideTauS, one setting since // #434; the old panGlideMs key is ignored). Hot. Replaces cursorSmoothing (ignored). int panGlideMaxPx = 0; - // Game-drawn cursor (issue #443, src/game_cursor.h): while a covering foreground app hides the + // Game-drawn cursor (issue #443, src/cursor/game_cursor.h): while a covering foreground app hides the // pointer and draws its own cursor, the view follows the pointer this many ms late so it stays // on the game's cursor. -1 (default) = one display frame, 0 = off (DWM centring). Hot. int gameCursorLagMs = -1; @@ -581,7 +581,7 @@ int EffectiveGpuPriority(const Config& c); // setups) is untouched by rule 1 because nothing is pending. Applied at EVERY config load. // tdrTest != 0 bypasses (the field harness must be able to repro nearest+MPO deliberately). // nearestGuard (mpoNearestGuard, issue #369): nearest is allowed on an MPO boot because the MPO -// guard (src/mpo_guard.h) forces DWM's external layer while zoomed. +// guard (src/transform/mpo_guard.h) forces DWM's external layer while zoomed. int EffectiveSamplingMode(int iniValue, bool mpoDisabledAtBoot, bool mpoDisabledInRegistry, int tdrTest, bool nearestGuard = false); diff --git a/src/config/profiles.h b/src/config/profiles.h index 2c69ed1f..f13402cc 100644 --- a/src/config/profiles.h +++ b/src/config/profiles.h @@ -1,6 +1,6 @@ // Pure profile logic (no ): what belongs in a profile file vs the live magnifier.ini, // profile-name validation, and the text transforms used on every switch/mirror. I/O lives in -// src/profiles_io.h (Win32) and the callers. See docs/specs/2026-08-12-profiles-design.md. +// src/config/profiles_io.h (Win32) and the callers. See docs/specs/2026-08-12-profiles-design.md. #pragma once #include #include diff --git a/src/config_ui/main.cpp b/src/config_ui/main.cpp index 331c5955..adc6220a 100644 --- a/src/config_ui/main.cpp +++ b/src/config_ui/main.cpp @@ -88,7 +88,7 @@ static bool WindRunning() { // Launch the magnifier that sits next to us (wind::LaunchWindExe). Returns false when Wind.exe is // missing or ShellExecuteW failed (<= 32). Relaunching while Wind is ALREADY running is how a model // switch restarts it: the new instance evicts the incumbent through the quit event (AcquireSingleInstance -// in src/main.cpp). No extra IPC is needed here. +// in src/core/main.cpp). No extra IPC is needed here. static bool LaunchWind() { return wind::LaunchWindExe() > 32; } // Resolved at first call (and cached) so reads and writes always land on the same file the Wind // core uses. Falls back to %LOCALAPPDATA%\Wind\magnifier.ini when the exe dir is read-only. diff --git a/src/core/hitch_record.cpp b/src/core/hitch_record.cpp index f4fc8520..ca2fd3a7 100644 --- a/src/core/hitch_record.cpp +++ b/src/core/hitch_record.cpp @@ -1,4 +1,4 @@ -// src/hitch_record.cpp - see hitch_record.h. Pure: compiled into the WIND_TESTS build. +// src/core/hitch_record.cpp - see hitch_record.h. Pure: compiled into the WIND_TESTS build. #include "hitch_record.h" #include diff --git a/src/core/hitch_record.h b/src/core/hitch_record.h index d39527ca..096f8bad 100644 --- a/src/core/hitch_record.h +++ b/src/core/hitch_record.h @@ -1,4 +1,4 @@ -// src/hitch_record.h +// src/core/hitch_record.h // Per-tick flight recorder and hitch classifier (#361). Pure (no ): the tick loop fills // TickRec with QPC spans and thread CPU time; this file decides what a long frame was and renders // the log line. Unit-tested in tests/test_hitch_record.cpp. diff --git a/src/core/log_queue.h b/src/core/log_queue.h index b690bab0..22496d4a 100644 --- a/src/core/log_queue.h +++ b/src/core/log_queue.h @@ -1,4 +1,4 @@ -// src/log_queue.h +// src/core/log_queue.h // Bounded multi-producer / single-consumer queue for log lines (#361). Pure (no ). // // The point is that a producer NEVER waits: not on the disk, not on the consumer, not on a lock diff --git a/src/core/logging.cpp b/src/core/logging.cpp index 354549ad..41977582 100644 --- a/src/core/logging.cpp +++ b/src/core/logging.cpp @@ -1,4 +1,4 @@ -// src/logging.cpp +// src/core/logging.cpp #include "logging.h" #include #include diff --git a/src/core/logging.h b/src/core/logging.h index 899535bc..97fca238 100644 --- a/src/core/logging.h +++ b/src/core/logging.h @@ -1,4 +1,4 @@ -// src/logging.h +// src/core/logging.h #pragma once #include #include diff --git a/src/core/main.cpp b/src/core/main.cpp index 20a0cae0..1b14cf38 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -356,7 +356,7 @@ struct TickState { double lockedPanRemY = 0.0; bool renderStale = false; // the render overlay refused a retarget (multi-GPU) and still sits // on an old monitor: sessions use the transform engine - wind::PanGlide glide; // momentum after a flick (#430, src/pan_glide.h) + wind::PanGlide glide; // momentum after a flick (#430, src/cursor/pan_glide.h) GainLearner gainLearner; // free ticks teach it the real in->out ratio; // locked ticks replay it (gain_learner.h) bool inspectGame = false; // game-inspect (issue #144): foreground stolen from a mouselook @@ -841,7 +841,7 @@ static void UpdateColorFilter(TickState& t, bool zoomedNow, bool renderSession, if (ex) { ex->colorOn = inShader; ex->color = enc; } wind::ColorMatrix dwm = inShader ? wind::IdentityColorMatrix() : wind::BuildColorMatrix(w, d, g_hdrOn.load(std::memory_order_relaxed)); - // MPO guard (issue #369, src/mpo_guard.h): zoomed at nearest on an MPO boot, an invisible + // MPO guard (issue #369, src/transform/mpo_guard.h): zoomed at nearest on an MPO boot, an invisible // non-identity effect makes DWM compose the desktop itself, so no plane can take the 16-bit // translation. The engine's runtime carries it (zoomed only), so it never needs our own hold. const bool mpoGuard = t.cfg.mpoGuard != 0 && wind::WantMpoGuard(zoomedNow, dynamic_cast(t.model) != nullptr, @@ -1351,7 +1351,7 @@ static TickInput ResolveInputAndZoom(TickState& t, double dt) { // freeze holds it at ~1.01 until the hold expires. const bool quiesceFreeze = QuiesceHoldActive(t) && t.zoom.level() > 1.0; if (!quiesceFreeze) t.zoom.tick(dt < kMaxZoomDt ? dt : kMaxZoomDt); - // SMOOTH-ZOOM RELEASE (issue #369, src/zoom_ladder.h EaseOutShouldStop). With smooth sampling and + // SMOOTH-ZOOM RELEASE (issue #369, src/transform/zoom_ladder.h EaseOutShouldStop). With smooth sampling and // the zoom ladder, a slow zoom must cross DWM's whole-pixel rounding steps, each an image jump of // about the level in px; snapping the slow tail hopped, holding it froze then caught up (field). // So after a release the user's ease-out runs (snapped like a held zoom) until it moves less per @@ -1942,7 +1942,7 @@ static PointerMap MapPointer(TickState& t, bool inspect, double lvl, double dt, dynamic_cast(t.model) != nullptr; // (A shell input panel needs nothing special: DWM draws its pointer above the panels and // keeps it centred, so the hand moves the pointer directly.) - // PAN GLIDE (issue #430, src/pan_glide.h): a soft stop, a few screen px at most. The pointer + // PAN GLIDE (issue #430, src/cursor/pan_glide.h): a soft stop, a few screen px at most. The pointer // itself eases on and the view follows by DWM centring. curDx/curDy is this tick's HAND motion: during a // glide the previous tick ended with the baseline on Wind's own step, so any motion here is // the hand, which (like a button or leaving a plain zoomed desktop pan) ends the glide. @@ -1970,7 +1970,7 @@ static PointerMap MapPointer(TickState& t, bool inspect, double lvl, double dt, } } } - // GAME-DRAWN CURSOR (issue #443, src/game_cursor.h): a covering app that hides the pointer + // GAME-DRAWN CURSOR (issue #443, src/cursor/game_cursor.h): a covering app that hides the pointer // draws its own cursor about a display frame late, so the view follows the pointer that late // (and Wind, not DWM centring, writes it). The pointer itself is untouched. bool gameCursor = false; @@ -3057,7 +3057,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { // hook's g_swallowedDown record, so swallowing is unaffected. USHORT bf = m.usButtonFlags; // The UP's event time is the WM_INPUT's queue time, not now: the hook's reordering - // guard compares event times (src/event_order.h), so a main-thread stall is harmless. + // guard compares event times (src/input/event_order.h), so a main-thread stall is harmless. const uint32_t rawTime = static_cast(GetMessageTime()); // Click quiet period: stamp the edge here instead of relying on the tick to catch the // button down in GetAsyncKeyState (a click shorter than a tick was missed). diff --git a/src/core/sched_priority.h b/src/core/sched_priority.h index 6b719161..0faaa181 100644 --- a/src/core/sched_priority.h +++ b/src/core/sched_priority.h @@ -1,4 +1,4 @@ -// src/sched_priority.h - keep the tick loop on time when the rest of the PC is busy (issue #334). +// src/core/sched_priority.h - keep the tick loop on time when the rest of the PC is busy (issue #334). // // The tick thread ran at normal priority, so under heavy background CPU load (renders, builds) it // queued behind every other normal thread and a zoom in/out froze for a few frames (traces: 139-737 ms diff --git a/src/core/tick_span.h b/src/core/tick_span.h index 7d53d49b..ec13a838 100644 --- a/src/core/tick_span.h +++ b/src/core/tick_span.h @@ -1,4 +1,4 @@ -// src/tick_span.h +// src/core/tick_span.h // Time a part of the tick into the current TickRec (#361). The tick loop points tl_tickSpans at // the record it is filling; anywhere on the tick thread can then wrap a call in // wind::SpanScope s(wind::kSpanTxWrite); diff --git a/src/cursor/cursor_mapper.h b/src/cursor/cursor_mapper.h index c37b09cd..b253e753 100644 --- a/src/cursor/cursor_mapper.h +++ b/src/cursor/cursor_mapper.h @@ -18,7 +18,7 @@ class CursorMapper { public: // The lens centre follows its target exactly. (The old cursorSmoothing eased it toward the // target over several frames: lag, never momentum, so it was removed in #430. Momentum after a - // flick is the pan glide, src/pan_glide.h.) + // flick is the pan glide, src/cursor/pan_glide.h.) CursorMapper(int screenW, int screenH); void reset(double centerX, double centerY); // pin both target + rendered center // Pan wall (issue #148): upper bound for the source rect's LEFT edge (desktop px), or a diff --git a/src/engine/magnifier_model.h b/src/engine/magnifier_model.h index 2a5280a8..cc03b482 100644 --- a/src/engine/magnifier_model.h +++ b/src/engine/magnifier_model.h @@ -27,7 +27,7 @@ struct PresentExtras { // The view is a pure function of the real pointer this tick (free cursor, mouse-owned, no // walls, no quiesce): the transform model may hand the pan to DWM (issue #369). bool dwmCentre = false; - // Warm-keeping pulses may run (src/tx_warm.h): only where the pointer is not free (locked + // Warm-keeping pulses may run (src/transform/tx_warm.h): only where the pointer is not free (locked // mouselook, Inspect). A free pointer's detached view (caret, focus, keyboard pan) is a desktop // app, where the pulse's 1 px flash is the visible defect and there is no game frame rate to wake. bool warmAllowed = true; diff --git a/src/input/input_router.h b/src/input/input_router.h index 62b14c5f..09c7ed46 100644 --- a/src/input/input_router.h +++ b/src/input/input_router.h @@ -101,7 +101,7 @@ class InputRouter { // DOWN for that button AFTER it (a queued raw UP processed after the hook's next DOWN would // cancel a hold that is physically down - no auto-repeat re-asserts a button). // eventTimeMs is GetMessageTime() of the WM_INPUT; the guard compares event times with the - // hook's own stamps (src/event_order.h), never the wall clock, so a main-thread stall is harmless. + // hook's own stamps (src/input/event_order.h), never the wall clock, so a main-thread stall is harmless. void rawButtonUp(int xbuttonId, uint32_t eventTimeMs); // Hook-thread event-time stamps (KBDLLHOOKSTRUCT / MSLLHOOKSTRUCT .time) consumed by the guards. void noteHookKeyDown(int vk, uint32_t eventTimeMs); @@ -194,7 +194,7 @@ class InputRouter { // yet. Tracking uses it: only keyboard-driven caret/focus changes move the view (issue #289). unsigned long long lastAnyKeyDownMs() const { return kbLastAnyDownMs_.load(std::memory_order_relaxed); } void noteAnyKeyDown(unsigned long long ms) { kbLastAnyDownMs_.store(ms, std::memory_order_relaxed); } - // A fresh down of a non-modifier key (no ups, no auto-repeat; src/typing_key.h). Ends the click quiet + // A fresh down of a non-modifier key (no ups, no auto-repeat; src/input/typing_key.h). Ends the click quiet // period (#328): releasing Ctrl/Shift after a Ctrl/Shift+click must not count as typing (review #349). unsigned long long lastTypingKeyDownMs() const { return kbLastTypingDownMs_.load(std::memory_order_relaxed); } void noteTypingKeyDown(unsigned long long ms) { kbLastTypingDownMs_.store(ms, std::memory_order_relaxed); } diff --git a/src/input/typing_key.h b/src/input/typing_key.h index ecc58415..d6ed8b0e 100644 --- a/src/input/typing_key.h +++ b/src/input/typing_key.h @@ -1,4 +1,4 @@ -// src/typing_key.h - which keystrokes count as typing for the click quiet period (#328, review #349). +// src/input/typing_key.h - which keystrokes count as typing for the click quiet period (#328, review #349). // // #328 ends the 1 s click quiet period early when a key goes down after the click (clicking into Notepad // and typing at once). Its first stamp was the tracking key clock, which also counts key-ups and diff --git a/src/render/render_engine.cpp b/src/render/render_engine.cpp index e5c24886..5aa877ff 100644 --- a/src/render/render_engine.cpp +++ b/src/render/render_engine.cpp @@ -726,7 +726,7 @@ bool RenderEngine::State::buildDeviceResources() { // --- Inspect-mode crosshair sprite (48x48). Thin full-length cross: the vertical and horizontal // lines run continuously through the center (no gap), light-grey core + black outline so it reads // on any background; drawn (scaled by zoom) in place of the cursor while Inspect mode is on. The - // pixel design lives in BuildCrosshairBGRA (src/crosshair.cpp, pure + unit-tested) and is shared + // pixel design lives in BuildCrosshairBGRA (src/cursor/crosshair.cpp, pure + unit-tested) and is shared // with the transform model's layered-window crosshair, so the two models stay identical. --- { const int N = 48; diff --git a/src/track/caret_rect.h b/src/track/caret_rect.h index 40219d66..72f36617 100644 --- a/src/track/caret_rect.h +++ b/src/track/caret_rect.h @@ -1,4 +1,4 @@ -// src/caret_rect.h - trim a caret rect that spans more than the caret's own line (issue #337). +// src/track/caret_rect.h - trim a caret rect that spans more than the caret's own line (issue #337). // // Chromium web editors (Outlook on the web) report the caret as one line right after Enter // (field: 1927,1159 h44), but from the first typed character as a rect that also covers the blank diff --git a/src/track/focus_identity.h b/src/track/focus_identity.h index e76136ce..23723b95 100644 --- a/src/track/focus_identity.h +++ b/src/track/focus_identity.h @@ -1,4 +1,4 @@ -// src/focus_identity.h +// src/track/focus_identity.h // Which focus a caret baseline belongs to. Pure (no ): handles travel as void*. // // Apps fire focus events for a control that already has focus (Notepad and VS Code while typing, diff --git a/src/track/view_target.h b/src/track/view_target.h index 25696cd2..2515eb8b 100644 --- a/src/track/view_target.h +++ b/src/track/view_target.h @@ -47,7 +47,7 @@ struct ViewOwnerInputs { bool buttonDown = false; double msSinceButton = 1e9; // time since a mouse button was last down double msSinceKey = 0; // time since any key went down (0 when unknown: no gate) - bool keyAfterButton = false; // a typing key (fresh non-modifier down, src/typing_key.h) went down AFTER the last mouse button: the click quiet period is over (#328) + bool keyAfterButton = false; // a typing key (fresh non-modifier down, src/input/typing_key.h) went down AFTER the last mouse button: the click quiet period is over (#328) double dtMs = 0; TrackSnapshot snap; bool panning = false; // a pan key is held or its motion is still gliding (#287) diff --git a/src/transform/transform_model.cpp b/src/transform/transform_model.cpp index 9978f6da..03a80ce9 100644 --- a/src/transform/transform_model.cpp +++ b/src/transform/transform_model.cpp @@ -540,7 +540,7 @@ double TransformModel::resolveLevel(const MapResult& r, double level, const Conf const double up = lastLevel_ * (1.0 + cfg.txMaxStepPct / 1000.0); if (applyLevel > up) applyLevel = up; } - // SMOOTH-ZOOM LADDER (issue #369, src/zoom_ladder.h): with smooth sampling DWM rounds its scratch + // SMOOTH-ZOOM LADDER (issue #369, src/transform/zoom_ladder.h): with smooth sampling DWM rounds its scratch // image's size and origin every frame, which shakes a continuous zoom; snap to the nearest level // whose predicted rounding error is under 1 px (never backwards in the ramp). Once the zoom has // settled the chosen level is held: panning at a fixed level does not shake, re-snapping would. @@ -684,7 +684,7 @@ MagTransform TransformModel::writeSiteTransform(double srcL, double srcT, double } void TransformModel::switchDwmCentre(double applyLevel, const PresentExtras& ex) { - // DWM CENTRING (issue #369, src/native_cursor.h). In a native-cursor session where the view is + // DWM CENTRING (issue #369, src/transform/native_cursor.h). In a native-cursor session where the view is // a pure function of the pointer (RunTick's ex.dwmCentre), DWM re-centres the view itself on // every cursor update, latched with the pointer it draws: no tick-to-frame drift at any speed. // Switching off is allowed on a paused tick (it stops DWM moving the view); switching on waits @@ -737,7 +737,7 @@ bool TransformModel::writeAndWarm(const MagTransform& m, double applyLevel, bool trChanged = changed; int txJitter = 0; bool keepAliveActive = false; - // WARM-KEEPING (see src/tx_warm.h for the measurements). At rest Wind would otherwise stop + // WARM-KEEPING (see src/transform/tx_warm.h for the measurements). At rest Wind would otherwise stop // writing entirely and DWM's composition falls back to the game's present rate, so the first // movement after a pause lands late - the hitch felt at every direction reversal. Only views // Wind writes itself need it (locked, Inspect, a detached view): DWM's own centring moves diff --git a/src/transform/transform_model.h b/src/transform/transform_model.h index 8eaa9aea..22c7c159 100644 --- a/src/transform/transform_model.h +++ b/src/transform/transform_model.h @@ -14,7 +14,7 @@ namespace wind { class TransformModel : public IMagnifierModel { public: - // Sessions draw DWM's own pointer (issue #369, src/native_cursor.h); the sprite window is the + // Sessions draw DWM's own pointer (issue #369, src/transform/native_cursor.h); the sprite window is the // Inspect crosshair, and zorderBand / cursorBandAuto place that window. The legacy sprite session // (txNativeCursor=0, issue #463) paints the system cursor into it instead. TransformModel(bool fastPan, bool smoothPan, int zorderBand, bool cursorBandAuto = false) diff --git a/src/tray_app/flyout_tools.h b/src/tray_app/flyout_tools.h index fae2f119..d0d9999a 100644 --- a/src/tray_app/flyout_tools.h +++ b/src/tray_app/flyout_tools.h @@ -26,7 +26,7 @@ inline const wchar_t* EngineLabel(int i) { } // The option a `model` value means. Missing or unknown reads as Auto, exactly like the core's config -// parse (src/config.cpp falls back to "hybrid"). +// parse (src/config/config.cpp falls back to "hybrid"). inline int EngineIndex(const std::string& model) { const std::string m = TrimWs(model); for (int i = 0; i < kEngineCount; ++i) if (m == EngineValue(i)) return i; diff --git a/tests/fixtures/global_keys.txt b/tests/fixtures/global_keys.txt index c3ca163a..e9d3fdb6 100644 --- a/tests/fixtures/global_keys.txt +++ b/tests/fixtures/global_keys.txt @@ -1,6 +1,6 @@ # The profile-global ini keys, one per line: never stored in a profile, and every key but `profile` # is UI-only (the core never reads it, StripUiOnlyKeys drops it so editing it never reloads Wind). -# Must equal kUiOnlyKeys + "profile" (src/profiles.h) and GLOBAL_KEYS (ui/src/session.js). +# Must equal kUiOnlyKeys + "profile" (src/config/profiles.h) and GLOBAL_KEYS (ui/src/session.js). # Read by tests/test_profiles.cpp and ui/tests/global-keys.nodetest.mjs. profile onboarded diff --git a/tests/test_tx_warm.cpp b/tests/test_tx_warm.cpp index 029d4f87..1882e12f 100644 --- a/tests/test_tx_warm.cpp +++ b/tests/test_tx_warm.cpp @@ -3,7 +3,7 @@ using namespace wind; -// The pan-start hitch these guard is described in src/tx_warm.h with the measurements. +// The pan-start hitch these guard is described in src/transform/tx_warm.h with the measurements. static TxWarmIn Resting(double level = 7.0) { TxWarmIn in; diff --git a/tools/gpu_ab.ps1 b/tools/gpu_ab.ps1 index d9a722a1..fa82697d 100644 --- a/tools/gpu_ab.ps1 +++ b/tools/gpu_ab.ps1 @@ -119,7 +119,7 @@ public static class GA { } public static void StopMotion() { _mrun = false; if (_mt != null) _mt.Join(1000); _mt = null; } public static bool QuitWind() { - // Must match kQuitEventName in src/tray_ipc.h. + // Must match kQuitEventName in src/tray/tray_ipc.h. IntPtr h = OpenEvent(0x0002, false, "Local\\Wind_QuitRequest"); if (h == IntPtr.Zero) return false; bool ok = SetEvent(h); CloseHandle(h); return ok; diff --git a/tools/testenv/README.md b/tools/testenv/README.md index 116dd9ca..53bbebf1 100644 --- a/tools/testenv/README.md +++ b/tools/testenv/README.md @@ -51,7 +51,7 @@ circle – where wobble hides), `hold` (dead stop – wobble at rest), `rezoom` ## Telemetry -Wind writes one CSV line per tick when enabled (`src/test_telemetry.h`): level, engine, mapper +Wind writes one CSV line per tick when enabled (`src/core/test_telemetry.h`): level, engine, mapper centre, cursor, welded flag, tick duration, QPC timestamp. The runner's phase marks use the same QPC clock, so scenarios index directly into the file. Enablement travels via `%LOCALAPPDATA%\Wind\testlog.txt` (a control file – the signed uiAccess build launches diff --git a/tools/testenv/lib.ps1 b/tools/testenv/lib.ps1 index 55bcfff0..8c0f4adf 100644 --- a/tools/testenv/lib.ps1 +++ b/tools/testenv/lib.ps1 @@ -211,7 +211,7 @@ $script:WindExe = 'C:\Program Files\Wind\Wind.exe' function Stop-Wind { if (-not (Get-Process -Name Wind -ErrorAction SilentlyContinue)) { return } try { - # Must match kQuitEventName in src/tray_ipc.h. + # Must match kQuitEventName in src/tray/tray_ipc.h. $ev = [System.Threading.EventWaitHandle]::OpenExisting('Local\Wind_QuitRequest') [void]$ev.Set() } catch { } diff --git a/tools/zoom_response_ab.ps1 b/tools/zoom_response_ab.ps1 index da49284a..0471964b 100644 --- a/tools/zoom_response_ab.ps1 +++ b/tools/zoom_response_ab.ps1 @@ -67,7 +67,7 @@ public static class ZR { [DllImport("kernel32.dll", CharSet=CharSet.Unicode)] static extern IntPtr OpenFileMappingW(uint a, bool i, string n); [DllImport("kernel32.dll")] static extern IntPtr MapViewOfFile(IntPtr h, uint a, uint hi, uint lo, UIntPtr n); static IntPtr view = IntPtr.Zero; - // The name must match kTrayBlockName in src/tray_ipc.h; offset 16 is TrayShared::level. + // The name must match kTrayBlockName in src/tray/tray_ipc.h; offset 16 is TrayShared::level. public static double Level() { if (view == IntPtr.Zero) { var m = OpenFileMappingW(4, false, "Local\\Wind_TrayState_v1"); view = MapViewOfFile(m, 4, 0, 0, UIntPtr.Zero); } return BitConverter.Int64BitsToDouble(Marshal.ReadInt64(view, 16)); diff --git a/ui/src/lib/KeybindCapture.svelte b/ui/src/lib/KeybindCapture.svelte index 186bb7bc..ec3717c4 100644 --- a/ui/src/lib/KeybindCapture.svelte +++ b/ui/src/lib/KeybindCapture.svelte @@ -9,7 +9,7 @@ // #285: row.buttonModsKey = modifier mask for the button slot (left/right/middle click need one); // The scroll-wheel row is gone (#318: wheel up/down are zoom bindings on the Hotkeys page, see // controls/Bindings.svelte); this capture stays for the onboarding. Every capture goes through the shared - // safety rules (keybindRules.js, mirrored from src/keybind_rules.h); a refused press keeps the row + // safety rules (keybindRules.js, mirrored from src/input/keybind_rules.h); a refused press keeps the row // listening and says why, on screen and to screen readers. import { checkKeyBind, checkClickBind, refusalText } from './keybindRules.js'; import { MOD_BITS, vkName, BUTTON_NAMES, shortButtonName } from './bindNames.js'; @@ -125,7 +125,7 @@ // Capture on keydown so a combo (Ctrl+Alt+F1) is captured the instant the main key fires while // all modifiers are held. Modifier-only presses (Ctrl/Alt/Shift/Win) are skipped so we wait for // the main key. keyCode 0 is ignored (Fn/IME/synthesized events would otherwise clear the binding). - // checkKeyBind (keybindRules.js, the mirror of src/keybind_rules.h) refuses keys that must never be + // checkKeyBind (keybindRules.js, the mirror of src/input/keybind_rules.h) refuses keys that must never be // bound, such as Backspace; a refusal stays armed so the user can press a different key. function onKey(e) { if (!armed) return; diff --git a/ui/src/lib/keybindRules.js b/ui/src/lib/keybindRules.js index 58a46100..75fa3136 100644 --- a/ui/src/lib/keybindRules.js +++ b/ui/src/lib/keybindRules.js @@ -1,4 +1,4 @@ -// Mirror of src/keybind_rules.h (issue #285). Both are tested against tests/fixtures/keybind_cases.txt +// Mirror of src/input/keybind_rules.h (issue #285). Both are tested against tests/fixtures/keybind_cases.txt // (ui/tests/keybind-rules.nodetest.mjs and tests/test_keybind_rules.cpp), so a rule changed in one place // fails the other's tests until it is changed there too. const MOD = { ctrl: 1, alt: 2, shift: 4, win: 8 }; diff --git a/ui/src/prefs/profileName.js b/ui/src/prefs/profileName.js index b6f3c08f..7be11bcc 100644 --- a/ui/src/prefs/profileName.js +++ b/ui/src/prefs/profileName.js @@ -1,4 +1,4 @@ -// Profile name rules, mirroring the host's ValidateNewName (src/config_ui/main.cpp, src/profiles.*): a +// Profile name rules, mirroring the host's ValidateNewName (src/config_ui/main.cpp, src/config/profiles.*): a // profile is a file, so the name must be a legal Windows file name. Pure, no DOM, so tests import it. const forbidden = /[\\/:*?"<>|]/; const reserved = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i; diff --git a/ui/src/session.js b/ui/src/session.js index ca94c189..b672c744 100644 --- a/ui/src/session.js +++ b/ui/src/session.js @@ -2,14 +2,14 @@ // profile file is the saved state. No bridge, no DOM, so Playwright can import it directly. import { groups, groupRows, bindKeys } from './settings-schema.js'; -// Mirrors IsGlobalProfileKey (kUiOnlyKeys + profile, src/profiles.h): these are never part of a +// Mirrors IsGlobalProfileKey (kUiOnlyKeys + profile, src/config/profiles.h): these are never part of a // profile, so they never count as an unsaved change. tests/global-keys.nodetest.mjs pins the two // lists together through tests/fixtures/global_keys.txt. The five tray keys (#313) live in the live ini only. // uiHighResNoticeOff (#441) is the opt-out of the High resolution cursor notice. export const GLOBAL_KEYS = new Set(['profile', 'onboarded', 'uiTheme', 'uiPalette', 'showAdvanced', 'trayPerf', 'traySliders', 'traySliderOrder', 'trayToggles', 'trayToggleOrder', 'trayPinned', 'uiHighResNoticeOff']); -// Must match the core's shipped defaults (src/config.h): every keybind ships unbound except Quick +// Must match the core's shipped defaults (src/config/config.h): every keybind ships unbound except Quick // zoom. Seeding anything else here would invent a binding the user never chose. const KB_DEFAULTS = { zoomInButton: '0', zoomInVk: '0', zoomOutButton: '0', zoomOutVk: '0', diff --git a/ui/src/tray/trayModel.js b/ui/src/tray/trayModel.js index becc0cfe..6a24595d 100644 --- a/ui/src/tray/trayModel.js +++ b/ui/src/tray/trayModel.js @@ -1,5 +1,5 @@ // Tray menu lists (pure, no DOM): which quick controls the tray flyout shows and in what order. -// Mirrors src/tray_items.cpp (ParseTrayLayout / WriteTrayLayout) so the page and WindTray read the +// Mirrors src/tray/tray_items.cpp (ParseTrayLayout / WriteTrayLayout) so the page and WindTray read the // same five global ini keys the same way: trayPerf, traySliders, traySliderOrder, trayToggles, // trayToggleOrder. Items and limits: docs/specs/2026-10-01-tray-flyout-design.md. diff --git a/ui/tests/global-keys.nodetest.mjs b/ui/tests/global-keys.nodetest.mjs index 31cd7a1e..eece78eb 100644 --- a/ui/tests/global-keys.nodetest.mjs +++ b/ui/tests/global-keys.nodetest.mjs @@ -6,7 +6,7 @@ import { dirname, join } from 'node:path'; import { GLOBAL_KEYS } from '../src/session.js'; // Plain node:test, no browser: run with `npm run test:rules` (CI runs it too). -// GLOBAL_KEYS must be the same set as the C++ kUiOnlyKeys + "profile" (src/profiles.h); both sides +// GLOBAL_KEYS must be the same set as the C++ kUiOnlyKeys + "profile" (src/config/profiles.h); both sides // are checked against this shared fixture. test('UI global keys match the shared list', () => { const here = dirname(fileURLToPath(import.meta.url)); diff --git a/ui/tests/tray.spec.js b/ui/tests/tray.spec.js index 48acd640..4bae0e8e 100644 --- a/ui/tests/tray.spec.js +++ b/ui/tests/tray.spec.js @@ -1,6 +1,6 @@ // Settings "Tray menu" tab (#313): the Performance switch, the Sliders and Toggles lists with // check, drag and keyboard reorder, the four-slider cap, and the five global ini keys written -// through the mock bridge. Plus the pure list model that mirrors src/tray_items.cpp. +// through the mock bridge. Plus the pure list model that mirrors src/tray/tray_items.cpp. import { test, expect } from '@playwright/test'; import { parseTray, parseList, serialiseList, MAX_SLIDERS, SLIDERS, TOGGLES } from '../src/tray/trayModel.js'; diff --git a/ui/tools/gen-themes.cjs b/ui/tools/gen-themes.cjs index 9cf09343..1a59d4d0 100644 --- a/ui/tools/gen-themes.cjs +++ b/ui/tools/gen-themes.cjs @@ -11,7 +11,7 @@ // dangerbtn dangerbtnfg scrim bnfilter bntint bntop rc rp rsw rkn. // Wind grey takes the app's own tokens.css values for every token the app already had, so // today's look is exactly preserved; every other theme comes from the mockup palettes. -// Palette ids in the app: grey ember ocean hicon (the core's kUiPalettes, src/config.cpp). Four themes only (owner decision 2026-10-02). +// Palette ids in the app: grey ember ocean hicon (the core's kUiPalettes, src/config/config.cpp). Four themes only (owner decision 2026-10-02). // Dark only since 0.20.0 (#324): the mockup palettes' light halves are not read. const fs = require('fs'); const path = require('path');