libnyanpasu/clash-nyanpasu · warning · anyhow::Error

failed to get close button

Error message

failed to get close button

What it means

set_traffic_lights_pos (macOS) requests the window's standard close button via NSWindow.standardWindowButton(.closeButton). AppKit returned nil, so the code errors with this message. Without the button handle, the traffic-light position cannot be adjusted.

Source

Thrown at backend/tauri/src/window.rs:913

            }
        }
    }

    impl From<Position> for (f64, f64) {
        fn from(value: Position) -> Self {
            (value.x, value.y)
        }
    }

    fn set_traffic_lights_pos(
        window: objc2::rc::Retained<objc2_app_kit::NSWindow>,
        pos: Position,
    ) -> anyhow::Result<()> {
        use objc2_app_kit::NSWindowButton;
        use objc2_foundation::NSRect;
        let close = window
            .standardWindowButton(NSWindowButton::CloseButton)
            .ok_or(anyhow::anyhow!("failed to get close button"))?;
        let miniaturize = window
            .standardWindowButton(NSWindowButton::MiniaturizeButton)
            .ok_or(anyhow::anyhow!("failed to get miniaturize button"))?;
        let zoom = window
            .standardWindowButton(NSWindowButton::ZoomButton)
            .ok_or(anyhow::anyhow!("failed to get zoom button"))?;

        let title_bar_container_view = unsafe {
            close
                .superview()
                .and_then(|view| view.superview())
                .ok_or(anyhow::anyhow!("failed to get title bar container view"))?
        };

        let close_rect = close.frame();
        let button_height = close_rect.size.height;

        let title_bar_frame_height = button_height + pos.y;

View on GitHub (pinned to f7dbce2997)

Solutions

  1. Create the window with decorations enabled (or .closable in the style mask) so standardWindowButton returns a button
  2. Defer set_traffic_lights_pos until the window is visible/on-screen (e.g. after on_window_event Focus/Resized) and retry once if nil
  3. Hide buttons via button.setHidden instead of removing decorations so handles still exist
  4. Fall back gracefully: log a warning and skip repositioning instead of failing the whole operation

Example fix

// before
let close = window
    .standardWindowButton(NSWindowButton::CloseButton)
    .ok_or(anyhow::anyhow!("failed to get close button"))?;
// after
let Some(close) = window.standardWindowButton(NSWindowButton::CloseButton) else {
    log::warn!("window has no standard close button (undecorated?); skipping traffic light reposition");
    return Ok(());
};
Defensive patterns

Strategy: fallback

Validate before calling

// only reposition when buttons exist
if window.standardWindowButton(NSWindowButton::CloseButton).is_none() {
    return Ok(()); // undecorated window; nothing to reposition
}

Type guard

fn has_traffic_lights(window: &NSWindow) -> bool {
    window.standardWindowButton(NSWindowButton::CloseButton).is_some()
}

Try / catch

match apply_traffic_lights_pos(window, pos) {
    Err(e) => log::warn!("traffic light reposition skipped: {e}"),
    Ok(()) => {}
}

Prevention

When it happens

Trigger: Calling apply_traffic_lights_pos / set_traffic_lights_pos on an NSWindow that has no standard close button — e.g. a borderless (titleBarStyle: Overlay/None) window whose buttons were hidden, a window not yet fully created, or an NSWindowStyleMask without .closable.

Common situations: Tauri windows created with decorations=false or decorations:false so AppKit never installs traffic lights; calling the API too early before the window is on-screen; fullscreen spaces where button access is transient; custom title bar replacements hiding the buttons.

Related errors


AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08). Data as JSON: /api/errors/8b8e2b846087df3c. Report an issue: GitHub.