Persistent daemon#3
Open
neko-kai wants to merge 94 commits into
Open
Conversation
This reverts commit 1740f93.
Behaviour-preserving relocation: - args.rs (new): TrayFocusOnly, Args (clap derive), parse_dbus_suffix_arg, resolve_install_gnome_extension, resolve_control_command. - autostart.rs (new): the 8 desktop-entry helpers plus the 3 AUTOSTART_* constants. main.rs: 7092 -> 6788 LOC. Verification: cargo build clean; cargo test --bin kanata-switcher 261 passed / 0 failed.
Behaviour-preserving relocation: - broadcasters.rs (new): StatusSnapshot, LayerSource, StatusBroadcaster, RestartHandle, PauseBroadcaster, RuntimeEnvironmentBroadcaster, ShutdownHandle, wait_for_restart_or_shutdown. main.rs: 6788 -> 6588 LOC. Verification: cargo build clean; cargo test --bin kanata-switcher 261 passed / 0 failed.
Behaviour-preserving relocation of the kanata TCP client. Highest- coupling extraction so far — every backend consumes KanataClient. kanata.rs (new): all *Msg/*Payload wire types, KanataClientInner, KanataClient + full impl, ShutdownGuard + Drop. KanataClient stays `pub` per plan lock; everything else `pub(crate)`. Whitebox tests required widening the inner field and three helper fns to pub(crate). main.rs: 6588 -> 5945 LOC. Verification: cargo build clean; cargo test --bin kanata-switcher 261 passed / 0 failed.
First nested-directory module. Behaviour-preserving relocation: - control/mod.rs: ControlCommand + impl, ControlDispatch. - control/client.rs: send_control_command*, BroadcastEntryReport, BroadcastReport, enumerate_daemon_names, send_control_command_broadcast, plus BROADCAST_PER_CALL_TIMEOUT. main.rs: 5945 -> 5791 LOC. args.rs updated to use crate::control::ControlCommand (was super::ControlCommand from PR-04a). Verification: cargo build clean; cargo test --bin kanata-switcher 261 passed / 0 failed.
Behaviour-preserving relocation: - pause.rs (new): UnpauseContext, local_sni_unpause_context, pause_daemon, unpause_daemon, plus test-only TEST_LAST_UNPAUSE_REQUEST_ENV and its helpers. - focus_pipeline.rs (new): execute_focus_actions, extract_focus_layer, update_status_for_focus, handle_focus_event, native_terminal_window, resolve_sni_focus_only. main.rs: 5791 -> 5579 LOC. Visibility widenings (D19 + extras): query_focus_for_env, apply_focus_for_env, SniSettingsStore, SNI_DEFAULT_SHOW_FOCUS_ONLY are now pub(crate) so the new modules can reach still-in-main.rs consumers. apply/query_focus_for_env revert when they move to backends/mod.rs in PR-11; SNI items move in PR-14. Verification: cargo build clean; cargo test --bin kanata-switcher 261 passed / 0 failed.
Behaviour-preserving relocation of the lifecycle-provider cluster into a directory module. ~640 LOC moved. - lifecycle/mod.rs: LifecycleProvider enum + impl, plus pub(crate) re-exports of the three submodules so main.rs's lifecycle::* glob reaches submodule items (per plan D13). - lifecycle/logind.rs: all logind parse/decode helpers, LogindLifecycleProvider, monitor task helpers, snapshot decoders. - lifecycle/startup.rs: StartupSnapshotProvider. - lifecycle/snapshot.rs: snapshot_no_session helper. main.rs: 5579 -> 4911 LOC. resolve_logind_session_path widened to pub(crate) because resolve_display_override_from_logind (still in main.rs until PR-08) consumes it. Verification: cargo build clean (warning count 1 -> 7, all unused imports in main.rs from incomplete cleanup — follow-up tracked); cargo test --bin kanata-switcher 261 passed / 0 failed.
Largest single-PR extraction so far (~920 LOC). Per defect D01, display_override.rs lands at crate root (not under supervisor/) to break the cycle that backends would create in PR-11. - display_override.rs (top-level, new): the display-override block including both test statics (X11 and Wayland) and the cfg-test/ cfg-not(test) variants of the test setters. - supervisor/capabilities.rs (new): detect_desktop_capabilities, resolve_runtime_target_for_snapshot. - supervisor/mod.rs (new): BackendContext, BackendHandle, runtime_target helpers, the five run_*_backend_task adapters, start_backend, SupervisorState, transition_runtime_target variants, run_lifecycle_supervisor variants, wait/poll helpers, WAYLAND_CAPABILITY_RECHECK_INTERVAL. main.rs: 4911 -> 4026 LOC. Visibility widenings per D06 + D23: run_gnome/kde/wayland/x11, query_*_focus / query_*_active_window, BackendExit, map_run_outcome_to_backend_exit all widened to pub(crate); plus the unplanned session_bus_name_has_owner widening. BackendExit and the mapping helper stay in main.rs until PR-12 moves them to backends/mod.rs. Verification: cargo build clean; cargo test --bin kanata-switcher 261 passed / 0 failed.
Highest-macro-risk PR — wayland_scanner generators relocated into a
nested module. PR-00 confirmed CARGO_MANIFEST_DIR-relative path
resolution; the literal "src/protocols/..." path strings ride
along unchanged.
- backends/mod.rs: RawFdWatcher (shared by wayland and x11 per D05);
pub(crate) mod wayland; pub(crate) use wayland::*.
- backends/wayland/mod.rs: ToplevelWindow, WaylandState + impl,
WaylandProtocol, run_wayland and the four wayland helpers
(resolve_wayland_socket_path, connect_wayland_with_display_override,
query_wayland_active_window, wayland_query_count). Submodule
re-exports per D24.
- backends/wayland/protocols.rs: mod cosmic_workspace + mod cosmic_toplevel
with wayland_scanner generators. Intra-module crate::cosmic_workspace
paths rewritten to super::/super::super:: per D03.
- backends/wayland/dispatch_{common,wlr,cosmic}.rs: split-out Dispatch
impls (8 total) for cleaner per-protocol diffs.
main.rs: 4026 -> 3526 LOC. supervisor/mod.rs's run_wayland call site
updated to crate::backends::wayland::run_wayland.
Verification: cargo build clean (warnings 8 -> 18, all unused-import
drift; cleanup deferred); cargo test --bin kanata-switcher 261/0.
Behaviour-preserving relocation: - backends/x11.rs (new): x11rb::atom_manager! block (per D11), X11State + impl, run_x11, query_x11_active_window. - backends/linux_console.rs: placeholder only. run_linux_console_backend_task stays in supervisor/mod.rs because it takes BackendContext, which would create a backends -> supervisor cycle if moved. PR-12 will absorb it into a FocusBackend impl together with the other backend_task adapters. main.rs: 3526 -> 3300 LOC. supervisor/mod.rs's run_x11 import updated to crate::backends::x11::run_x11. Verification: cargo build clean; cargo test --bin kanata-switcher 261/0.
Behaviour-preserving relocation. ~800 LOC across 4 files.
- backends/gnome.rs: run_gnome + query_gnome_focus + GNOME focus
signal subscription helpers.
- backends/kde/mod.rs: KwinScriptGuard + run_kde, plus pub(crate)
re-exports of script and probe submodules (per D24).
- backends/kde/script.rs: KWin script-generation helpers
(kwin_*_script_path, KdeFocusQueryService with zbus interface,
build_kde_query_script, build_kde_focus_push_script).
- backends/kde/probe.rs: KWin runtime-mode probe + script unload
helpers + query_kde_focus.
- backends/mod.rs: added query_focus_for_env and apply_focus_for_env
dispatch helpers (the natural home per plan §3 line 113).
main.rs: 3300 -> 2514 LOC. supervisor/mod.rs's run_* imports
updated to crate::backends::{gnome,kde}::run_{gnome,kde}.
pause.rs's apply_focus_for_env import updated to
crate::backends::apply_focus_for_env. Visibility widenings
on these items from PR-06/PR-08 are now redundant (functions
moved); no main.rs widening to revert because the items left
main.rs entirely.
Verification: cargo build clean; cargo test --bin kanata-switcher 261/0.
First semantic-shaped change. Behaviour identical; dispatch via
Box<dyn FocusBackend> instead of a 5-arm match calling free
adapter functions. Trait shape per PR-00 finding:
fn run(
self: Box<Self>,
ctx: BackendRunContext,
) -> Pin<Box<dyn Future<Output = Result<BackendExit, DynError>>
+ Send + 'static>>;
(RPIT-in-traits remains dyn-incompatible on rustc 1.92.0; boxed
future is the locked shape.)
- backends/mod.rs: BackendExit + map_run_outcome_to_backend_exit
relocated from main.rs (D23 contract honored — they lived in
main.rs widened to pub(crate) from PR-08 to here). Added
BackendRunContext struct and FocusBackend trait.
- backends/{gnome,kde,wayland,x11,linux_console}.rs: one
XxxBackend zero-sized struct + impl FocusBackend per backend.
Each run body Box::pin-s an async move that delegates to the
existing free run_xxx function and maps the result through
map_run_outcome_to_backend_exit. linux_console got its body
inlined from the former supervisor adapter (the only one with
substantive content).
- supervisor/mod.rs: start_backend now dispatches via the trait;
the five run_*_backend_task adapter functions deleted (-188 LOC).
main.rs: 2514 -> 2501 LOC.
Verification: cargo build clean; cargo test --bin kanata-switcher
261/0. No Send-propagation issues.
Behaviour-preserving relocation. ~545 LOC moved out of main.rs.
- control/server.rs: DbusWindowFocusService + its zbus #[interface]
impl (kept colocated — macro requires same file),
resolve_runtime_unpause_context, DbusServiceRegistration + Drop,
register_dbus_service variants.
- control/persistent.rs: DBUS_RECONNECT_DELAYS_MS,
dbus_reconnect_delay, wait_for_dbus_reconnect_retry,
PersistentDbusServiceGuard + Drop, start/run persistent
service variants.
- control/mod.rs: pub(crate) mod server / persistent and
pub(crate) use {server::*, persistent::*} for test reach.
main.rs: 2501 -> 1979 LOC. All consumers of the moved items lived
in main.rs already; no cross-call-site updates needed.
Verification: cargo build clean; cargo test --bin kanata-switcher 261/0.
Largest single-PR extraction so far (~1015 LOC). Behaviour-preserving.
- sni/mod.rs: SniControl variant enum, SniControlMode,
SniRuntimeTransitionPlan, SniRuntimeWakeReason, mode-resolution
and transition-planning helpers. pub(crate) use re-exports all
submodules per D24.
- sni/settings.rs: DconfBackend trait + ShellDconfBackend,
SniSettingsStore, dconf helpers.
- sni/state.rs: MenuRefresh + SniIndicatorState.
- sni/indicator.rs: SniIndicator + impl Tray, start_sni_indicator,
SniIndicatorRuntimeHandle + Drop. Test-only ACTIVE_SNI_WATCHER_TASKS
+ SniWatcherTaskGuard + sni_watcher_task_count under cfg(test).
- sni/control_{local,dbus}.rs: SniLocalControl and SniDbusControl
structs (fields pub(crate) so control_ops can pattern-match).
- sni/control_ops.rs: SniControlOps trait + impl for SniControl.
- sni/guard.rs: SniGuard + build_sni_control_for_mode +
SNI_RUNTIME_RETRY_INTERVAL.
main.rs: 1979 -> 958 LOC. (Broke below 1000 LOC.) Removed ksni and
noto_sans_mono_bitmap top-level imports.
Verification: cargo build clean; cargo test --bin kanata-switcher
261 passed / 0 failed.
Behaviour-preserving relocation. Closes the M1 milestone.
- gnome_ext/embed.rs (cfg-gated): gnome_ext_file! macro with the
critical relative-path bump from concat!("../../", ...) to
concat!("../../../", ...) — one level deeper because the file
moved one module level. All 9 EMBEDDED_* include_str! consts.
compile_gnome_schemas + write_embedded_extension_to_dir.
- gnome_ext/detection.rs: GnomeExtensionStatus, GnomeDbusProbeResult,
state parsers, dbus probe variants, gnome_extension_status,
session_bus_name_has_owner (PR-08 widening's final home).
- gnome_ext/install.rs: pack/install/enable + path helpers.
- gnome_ext/mod.rs: submodule declarations + pub(crate) use re-exports
+ orchestration fns (setup_gnome_extension, ensure_gnome_extension,
print_*).
main.rs: 958 -> 250 LOC. Pre-refactor was 7983 LOC — 96.9% reduction.
Well below the plan's <=400 LOC target.
supervisor/capabilities.rs: two call sites updated to
crate::gnome_ext::detection::session_bus_name_has_owner.
Verification: cargo build (default features) ✓; cargo build
--no-default-features ✓; cargo test --bin kanata-switcher 261/0.
M1 milestone complete.
cargo fix cleanup: 16 unused imports removed across backends/mod.rs, backends/wayland/mod.rs, control/mod.rs, lifecycle/mod.rs, gnome_ext/mod.rs, sni/mod.rs. main.rs and sni/indicator.rs were reverted from cargo fix because their "unused" imports are used by test code via the #[cfg(test)] pub(crate) use super::*; re-export chain — removing them broke cargo test. Remaining 26 warnings on those two files are intentional test-surface re-exports; leave them. Verification: cargo build clean (default + no-default-features); cargo test --bin kanata-switcher 261/0.
Captures the full PR-00 through PR-15 sequence: per-PR LOC moved, surprises (e.g. environ vs env, dropping BackendRunContext.environment, linux_console staying in supervisor), trait seams (FocusBackend new, DconfBackend and SniControlOps formalized), V0 reality (cargo build + test only — pre-existing clippy/fmt debt out of scope), and follow-ups for the user (test-surface unused-import warnings, pre-existing clippy debt).
Behaviour-preserving: 4864 LOC flat file becomes: - tests/common/helpers.rs (101 LOC): TEST_TIMEOUT const, SNI_WATCHER_TEST_LOCK static, with_test_timeout, win, rule, rule_vk, rule_raw_vk, rule_with_fallthrough, has_action, get_layers, get_raw_vk_actions. - tests/common/mod.rs (3 LOC): use super::*; mod helpers; pub(super) use helpers::*; - tests/mod.rs (4768 LOC): all 189 tests, unchanged, plus `mod common; pub(super) use common::*;` at the top. src/daemon/tests.rs deleted. Rust's mod resolver picks tests/mod.rs automatically — main.rs unchanged. Helper visibility is pub(crate) rather than pub(super) (deviation from plan §4); fine because the whole tests module is cfg(test). Verification: 189 test attrs preserved; cargo build clean; cargo test 261 passed / 0 failed.
Behaviour-preserving. 189 test attributes preserved (105 in new leaf files + 86 still in mod.rs awaiting M2-PR-03 lifecycle split). - focus_flow.rs (711 LOC, 32 tests) - focus_pipeline.rs (193, 6 — including 2 misfiled from the "GNOME Extension State Parsing Tests" banner) - focus_property.rs (279, 1 proptest block / 5 prop tests + 8 strategy fns) - autostart.rs (58, 3) - dbus_naming.rs (303, 28 + 1 proptest block) - control_commands.rs (31, 4) - kde_script_paths.rs (69, 4 path tests + build_kde_focus_push) - sni_presentation.rs (484, 17 — plan estimated 14 but actual audit shows 17 legitimate SNI tests) - gnome_ext_state.rs (46, 3 — the rest of the misnamed banner relocated to focus_pipeline.rs and stay in mod.rs) - config_parsing.rs (119, 8) Residual tests/mod.rs: 2499 LOC, 86 test attrs — all relocate in M2-PR-03 (lifecycle subtree). No production source files modified. cargo build clean; cargo test --bin kanata-switcher 261/0.
Behaviour-preserving. 86 tests moved from tests/mod.rs to 10 leaf files under tests/lifecycle/. After this PR, tests/mod.rs is 26 LOC — just module declarations + re-exports; zero test bodies remain at the directory root. - lifecycle/fixtures.rs (67, 0): 4 backend-context helpers (pub(crate)) - lifecycle/restart_or_shutdown.rs (47, 3): rescued from "GNOME Extension State Parsing Tests" misnomer banner - lifecycle/logind_decode.rs (388, 29): 9 rescued + 20 logind decode/ path/error tests - lifecycle/display_apply.rs (81, 5) - lifecycle/runtime_target.rs (273, 10) - lifecycle/persistent_dbus.rs (74, 2) - lifecycle/sni_runtime.rs (311, 7) - lifecycle/transition.rs (370, 9) - lifecycle/provider.rs (98, 5) - lifecycle/supervisor.rs (770, 16) No production source files modified. cargo build clean; cargo test --bin kanata-switcher 261/0. tests.rs split complete: 4864 LOC mono file -> 22 leaf files + common/helpers.rs, all <= 770 LOC.
Behaviour-preserving. 7176 LOC flat file becomes: - integration_tests/common/polling.rs (90): POLL_*/LONG_TEST_TIMEOUT constants, 4 env locks, EnvVarGuard, wait_for, wait_for_async, with_*_test_timeout. - integration_tests/common/mock_kanata.rs (191): KanataMessage, wait_for/drain_kanata_messages, MockKanataConfig, MockKanataServer. - integration_tests/common/focus_service.rs (149): start_wayland_test_server, pause/unpause_daemon_direct, FocusService zbus interface, TEST_DAEMON_DBUS_NAME, start_gnome_focus_service. - integration_tests/common/dbus_session.rs (119): dbus_daemon_available, DBUS_TEST_COUNTER, DbusSessionGuard. - integration_tests/common/mod.rs (11): mod decls + pub(crate) use. - integration_tests/mod.rs (6638): all 65 tests + mod common. src/daemon/integration_tests.rs deleted. One zbus visibility tweak: FocusService::focus_changed signal made pub (was implicit-private when the interface lived next to callers). No other production source changes. start_wayland_test_server stays in common/focus_service.rs; references super::super::wayland_mock::WaylandMockServer (inline child still in mod.rs). No cycle. Verification: 65 test attrs preserved; cargo build clean; cargo test --bin kanata-switcher 261 passed / 0 failed.
Behaviour-preserving. 65 tests moved from integration_tests/mod.rs into 10 backend-grouped leaf files. After this PR, mod.rs is 32 LOC of module declarations; zero test bodies remain at the directory root. - gnome/mod.rs (4) + gnome/focus_query.rs (100, 1) + gnome/ extension_detection.rs (309, 2 + MockGnomeShellExtensions) - kde/mod.rs (3) + kde/focus_query.rs (742, 4 + MockKwinScripting/ MockKwinScript/extract_call_dbus_parts) - wayland.rs (444, 4 + inline pub(super) mod wayland_mock) - x11.rs (753, 6 + xvfb_available, XvfbGuard) - vk_validation.rs (694, 12) - dbus_control.rs (288, 3) - dbus_session_tests.rs (1631, 14) — slightly over the 1500-LOC soft cap; tests share DbusSessionGuard lifecycle so kept together. Optional M2-PR-06 can split if the byte count is unacceptable. - dbus_multiplex.rs (1463, 15 + TEST_DAEMON_DBUS_NAME_A/_B consts + register_test_daemon_with_name) - dconf.rs (201, 3 + IsolatedDconfEnv, is_dconf_available) One visibility fix during integration: mod wayland_mock (inline child of wayland.rs) needed pub(super) modifier — fixed inline. common/focus_service.rs path updated to super::super::wayland::wayland_mock::WaylandMockServer. Verification: 65 test attrs preserved (sum across leaves = 65; mod.rs = 0). cargo build clean; cargo test --bin kanata-switcher 261 passed / 0 failed. M2 milestone complete: tests.rs (4864 LOC) -> 22 leaf files; integration_tests.rs (7176 LOC) -> 14 leaf files. No production source changes; behaviour preserved.
Behaviour-preserving. 15 tests moved from dbus_session_tests.rs into 4 leaf files by what each test exercises: - dbus_session_status.rs (674, 5): real-bus + initial-layer + focus-source + paused-changed signal + status-changed focus signal. - dbus_session_restart.rs (238, 3): dbus-restart + control-command restart + control-command error-without-service. - dbus_session_pause.rs (627, 6): pause/unpause + focus-ignored paused + pause-wayland-env + unfocus-ignored + release-VKs/reset + control-command pause/unpause. - dbus_session_persistent.rs (95, 1): persistent-service handles restart in idle. All four files under 1500 LOC. dbus_session_tests.rs deleted. integration_tests/mod.rs declarations updated. Plan inventory delta: M2-PR-05 reported 14 tests in this section; actual count was 15 (plan §2 missed test_dbus_paused_changed_signal). The aggregate 65 integration-test count is unchanged. Verification: 15 test attrs preserved (sum across leaves); cargo build clean; cargo test --bin kanata-switcher 261 passed / 0 failed. M2 milestone complete: - tests.rs (4864 LOC, 189 tests) -> 22 leaf files (max 770 LOC) - integration_tests.rs (7176 LOC, 65 tests) -> 16 leaf files (max 1463) - No production source changes; behaviour preserved.
M2 milestone complete: tests.rs (4864 LOC, 189 tests) split into 22 leaf files; integration_tests.rs (7176 LOC, 65 tests) split into 17 leaf files. Max leaf-file LOC 1463 (under plan's 1500 strict ceiling). 261/0 tests pass throughout. Two trivial visibility tweaks to production code (FocusService::focus_changed pub, mod wayland_mock pub(super)); otherwise zero daemon changes. Plan deviations: pub(super) -> pub(crate) on shared helpers (test re-export chain needed broader visibility); a couple of plan test counts were off by 1-3 (sni_presentation, dbus_session_tests). M2-PR-06 was conditional in the plan; activated because dbus_session_tests.rs landed 1631 LOC, over the 1500 ceiling.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Goal: daemon should work in the Linux console and in the display manager before login. It should support switching between DEs, logging out to DM, destroying display server and starting it back, all without having to restart the daemon and while switching layers to expected state.
Non-goal: support parallel desktop sessions. The daemon works via dbus - if each session uses a separate dbus, that would work naturally, otherwise not.
Nice to have: support connections to multiple Kanatas within one daemon
Current state: