feat: honor async-backend with epoll/io_uring, fix last RV13 items
Resolves the 4 P3 items in docs/rewrite/notes/review-rv13-codex.md (final-Z16.md): - async-backend now takes effect like Ghostty: ghostty_os::xev ports libxev's backend detection (io_uring, then epoll); global init detects and logs it, the GTK startup applies the config with Zig's messages, and +version reports the real backend. The termio IO loop runs on a new reactor with epoll, io_uring (io-uring crate) and poll(2) (kept for macOS, where libxev uses kqueue). The 21 exec integration tests run under every backend; io_uring was exercised here. - auto-update-channel defaults to the build's release channel. - Windows error names: sharing violation -> AccessDenied, plus ERROR_FILE_EXISTS -> PathAlreadyExists and virus errors -> AntivirusInterference, mirroring std.os.windows.OpenFile's NTSTATUS mapping in Zig 0.15.2 (verified against its source by the orchestrator). - Exact ports of std.fs.path.basenameWindows/basenamePosix for theme name validation (drive, UNC and device roots). Test Plan: - cargo test --workspace --no-fail-fast (3555 passed, exit 0) - just check-macos (both), just check-windows, just check-wasm - +show-config --default --docs vs /usr/bin/ghostty (only the build-specific gtk-opengl-debug line differs)
This commit is contained in:
1 parent
3ce3225642
commit
1bd918159a
18 files changed
+2012
-742
No files matched your search
@@ -206,6 +206,33 @@ fn set_gtk_env(config: &CoreConfig) {
|
||||
/// if that fails (usually an invalid `LANG`), retry with `LANG` unset, then fall
|
||||
/// back to `en_US.UTF-8` (updating `LANG` on success). Idempotent. This must
|
||||
/// run before GTK initializes and before the child environment is captured.
|
||||
/// Apply the `async-backend` config (Zig: `startupXev`): `auto` keeps the
|
||||
/// backend detected at startup, the others request that backend and fall
|
||||
/// back to the detected one when it is not available.
|
||||
pub fn apply_async_backend(backend: ghostty_config::types_b::AsyncBackend) -> bool {
|
||||
use ghostty_config::types_b::AsyncBackend;
|
||||
use ghostty_os::xev::{self, Backend};
|
||||
|
||||
// If our backend is auto then we have no setup to do.
|
||||
let want = match backend {
|
||||
AsyncBackend::Auto => return true,
|
||||
AsyncBackend::Epoll => Backend::Epoll,
|
||||
AsyncBackend::IoUring => Backend::IoUring,
|
||||
};
|
||||
|
||||
// Setup our event loop backend to the preferred method
|
||||
let result = xev::is_dynamic() && xev::prefer(want);
|
||||
if result {
|
||||
log::info!("libxev manual backend={}", xev::backend());
|
||||
} else {
|
||||
log::warn!(
|
||||
"libxev manual backend failed, using default={}",
|
||||
xev::backend()
|
||||
);
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
pub fn init_locale() {
|
||||
static ONCE: std::sync::Once = std::sync::Once::new();
|
||||
ONCE.call_once(|| {
|
||||
@@ -329,6 +356,9 @@ mod imp {
|
||||
// Set ourselves as the default application.
|
||||
gio::Application::set_default(obj.upcast_ref::<gio::Application>());
|
||||
|
||||
// Setup our event loop
|
||||
obj.startup_xev();
|
||||
|
||||
// Setup our style manager (light/dark mode)
|
||||
obj.startup_style_manager();
|
||||
// Setup some signal handlers
|
||||
@@ -889,6 +919,14 @@ impl Application {
|
||||
// -----------------------------------------------------------------
|
||||
// Startup
|
||||
|
||||
/// Configure the event loop (libxev) to use a specific backend.
|
||||
///
|
||||
/// This must be called before any event loop is created.
|
||||
fn startup_xev(&self) {
|
||||
let config = self.core_config();
|
||||
apply_async_backend(config.async_backend);
|
||||
}
|
||||
|
||||
/// Setup the style manager on startup: initial light/dark mode based on
|
||||
/// the configuration, plus change listeners.
|
||||
fn startup_style_manager(&self) {
|
||||
@@ -1900,3 +1938,35 @@ mod trim_tests {
|
||||
assert_eq!(trim_ascii_whitespace(" \t "), "");
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod async_backend_tests {
|
||||
use ghostty_config::types_b::AsyncBackend;
|
||||
use ghostty_os::xev::{self, Backend};
|
||||
|
||||
use super::apply_async_backend;
|
||||
|
||||
#[test]
|
||||
fn async_backend_selects_the_event_loop() {
|
||||
let _ = xev::detect();
|
||||
let detected = xev::backend();
|
||||
|
||||
// auto: nothing to do.
|
||||
assert!(apply_async_backend(AsyncBackend::Auto));
|
||||
assert_eq!(xev::backend(), detected);
|
||||
|
||||
// epoll is always available on Linux.
|
||||
assert!(apply_async_backend(AsyncBackend::Epoll));
|
||||
assert_eq!(xev::backend(), Backend::Epoll);
|
||||
|
||||
// io_uring only when the kernel allows it, else the backend stays.
|
||||
let ok = apply_async_backend(AsyncBackend::IoUring);
|
||||
assert_eq!(ok, xev::available(Backend::IoUring));
|
||||
assert_eq!(
|
||||
xev::backend(),
|
||||
if ok { Backend::IoUring } else { Backend::Epoll }
|
||||
);
|
||||
|
||||
let _ = xev::detect();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user