diff --git a/qt/src/GhosttySurface.cpp b/qt/src/GhosttySurface.cpp index 2c432f96c..e5abd29cf 100644 --- a/qt/src/GhosttySurface.cpp +++ b/qt/src/GhosttySurface.cpp @@ -317,8 +317,10 @@ void GhosttySurface::paintEvent(QPaintEvent *) { // Unfocused-split dimming: a translucent fill over an inactive pane. // Only split panes (a QSplitter parent) are dimmed, matching GTK. if (!hasFocus() && qobject_cast(parentWidget())) { - double opacity = 0.7; - config::get(&opacity, "unfocused-split-opacity"); + double opacity = 0.7; // default: 70% opaque + // On read failure opacity keeps the default; the success bit + // isn't load-bearing. + (void)config::get(&opacity, "unfocused-split-opacity"); if (opacity < 1.0) { QColor fill(0, 0, 0); // default: dim toward black ghostty_config_color_s c{}; diff --git a/qt/src/MainWindow.cpp b/qt/src/MainWindow.cpp index f7485aa6b..61a85922c 100644 --- a/qt/src/MainWindow.cpp +++ b/qt/src/MainWindow.cpp @@ -289,7 +289,8 @@ MainWindow *MainWindow::newWindow(ghostty_surface_t parent) { if (!s_initialWindowConsumed) { s_initialWindowConsumed = true; bool initialWindow = true; - config::get(&initialWindow, "initial-window"); + // Default-on; the success bit isn't load-bearing. + (void)config::get(&initialWindow, "initial-window"); wantsShow = initialWindow; } if (wantsShow) w->show(); @@ -1068,7 +1069,8 @@ void MainWindow::refreshChrome() { // runtime; mirrors the calculation in initialize(). if (GhosttyApp::instance().config()) { bool quitAfter = true; - config::get(&quitAfter, "quit-after-last-window-closed"); + // Default-on; the success bit isn't load-bearing. + (void)config::get(&quitAfter, "quit-after-last-window-closed"); // Same Duration-decode workaround as initialize(). const uint64_t delayNs = config::durationNs("quit-after-last-window-closed-delay", 0); @@ -1370,9 +1372,10 @@ void MainWindow::toggleCommandPalette(GhosttySurface *surface) { void MainWindow::applyBlur() { // background-blur is a union whose C value is an i16: 0 (and the // macOS-only negatives) means off, a positive radius means on. KWin - // uses its own configured radius, so only on/off matters here. + // uses its own configured radius, so only on/off matters here. On + // read failure blur stays 0 (off). short blur = 0; - config::get(&blur, "background-blur"); + (void)config::get(&blur, "background-blur"); applyWindowBlur(this, blur > 0); } diff --git a/qt/src/config/Config.h b/qt/src/config/Config.h index 7dcc8971e..dc5386cd2 100644 --- a/qt/src/config/Config.h +++ b/qt/src/config/Config.h @@ -20,17 +20,17 @@ namespace config { // The live ghostty_config_t. Returns nullptr before the singleton has // finished ensureInitialized — callers that read config during early // startup (before the first MainWindow::initialize) must check. -ghostty_config_t handle(); +[[nodiscard]] ghostty_config_t handle(); // Read a string-valued config key (or an enum, which libghostty // returns as its tag-name string). Empty if absent or the call // fails. -QString string(const char *key); +[[nodiscard]] QString string(const char *key); // Read a bool-valued config key. Returns `fallback` when the key is // absent or the call fails. Note: libghostty's bool config keys are // strict bools, NOT packed bitfields — see bitfield<>() for those. -bool boolean(const char *key, bool fallback); +[[nodiscard]] bool boolean(const char *key, bool fallback); // Parse a duration config key as nanoseconds via the on-disk // fallback. Use this for `?Duration` (optional) keys: c_get.zig @@ -41,18 +41,18 @@ bool boolean(const char *key, bool fallback); // with `unsigned long long` and a manual ms→ns multiplication, NOT // this wrapper, to avoid a redundant disk re-scan on every read. // Returns `fallbackNs` on parse failure or absent key. -uint64_t durationNs(const char *key, uint64_t fallbackNs); +[[nodiscard]] uint64_t durationNs(const char *key, uint64_t fallbackNs); // Scan the user's primary on-disk config file for `key = value` // directly. Used for keys ghostty_config_get can't decode (Duration, // repeating paths). Returns the last matching value, or empty. -QString diskValue(const char *key); +[[nodiscard]] QString diskValue(const char *key); // True if the live config has any custom-shader entry. Drives // GhosttySurface's premultiply pass — `custom-shader` is a // repeatable path that ghostty_config_get can't expose, so we scan // the on-disk config text directly. -bool hasCustomShader(); +[[nodiscard]] bool hasCustomShader(); // Read a packed-bitfield config key. libghostty serializes packed // structs as a c_uint via c_get.zig (`ptr.* = @intCast(@as(Backing, @@ -61,14 +61,14 @@ bool hasCustomShader(); // for a one-field packed struct) under-sizes the write and corrupts // adjacent stack — always go through this. Returns `fallbackBits` // when ghostty_config_get fails. -unsigned int bitfield(const char *key, unsigned int fallbackBits); +[[nodiscard]] unsigned int bitfield(const char *key, unsigned int fallbackBits); // Read a path-valued disk config and expand a leading `~/` to the // user's home directory. Returns empty when the key is absent. // Path-valued keys are read off-disk (libghostty doesn't surface // them through ghostty_config_get) so this is just diskValue() with // a tilde-expansion pass. -QString expandedPath(const char *key); +[[nodiscard]] QString expandedPath(const char *key); // Wrapper around ghostty_config_get that infers the value's length // from a string literal so call sites stop repeating qstrlen(). The @@ -79,9 +79,11 @@ QString expandedPath(const char *key); // `out` must point to the type ghostty.h documents for the key // (bool* for bool keys, ghostty_config_color_s* for colors, etc.). // Returns false when the key is absent or the underlying call -// fails. +// fails. The success bit MUST be checked — `out` is left untouched +// on failure, so dropping the return masks an unread / unwritten +// access. template -inline bool get(T *out, const char (&key)[N]) { +[[nodiscard]] inline bool get(T *out, const char (&key)[N]) { static_assert(N > 1, "config::get requires a non-empty key literal"); ghostty_config_t cfg = handle(); return cfg && ghostty_config_get(cfg, out, key, N - 1); diff --git a/qt/src/quickterm/QuickTerminal.cpp b/qt/src/quickterm/QuickTerminal.cpp index b00d647c6..dbc83e281 100644 --- a/qt/src/quickterm/QuickTerminal.cpp +++ b/qt/src/quickterm/QuickTerminal.cpp @@ -36,7 +36,9 @@ constexpr const char *kAnimProperty = "ghastty.quickterm.anim"; // and a very large value doesn't lock the user out. int animationMs() { double secs = 0.2; // matches Config.zig default - config::get(&secs, "quick-terminal-animation-duration"); + // On read failure secs keeps the default; the success bit isn't + // load-bearing. + (void)config::get(&secs, "quick-terminal-animation-duration"); if (secs <= 0.0) return 0; return std::clamp(static_cast(secs * 1000.0), 1, 1000); } @@ -117,8 +119,10 @@ void setupLayerShell(QWidget *window) { const QSize scr = screen ? screen->size() : QSize(1920, 1080); // quick-terminal-size: primary is the edge-perpendicular extent. + // On read failure qsz stays zero-initialized and toPx falls back to + // its `fallback` argument; the success bit isn't load-bearing. ghostty_config_quick_terminal_size_s qsz = {}; - config::get(&qsz, "quick-terminal-size"); + (void)config::get(&qsz, "quick-terminal-size"); const auto toPx = [](const ghostty_quick_terminal_size_s &s, int dim, int fallback) -> int { switch (s.tag) {