Files
egui/examples/custom_window_frame
Mårten Björk 35b9cbf27a Add Frame::set_traffic_lights_position for macOS custom title bars (#8494)
Adds `eframe::Frame::set_traffic_lights_position` for placing the native
macOS "traffic lights" (close/minimize/maximize buttons) inside a custom
title bar, e.g. when using
`ViewportBuilder::with_fullsize_content_view`.

## New API
```rust
impl eframe::Frame {
    /// Center the traffic lights vertically in `title_bar_y` (measured from the top of the window),
    /// with the close button `left_margin` from the left edge. Both in egui points.
    /// Call it every frame. Does nothing on other platforms.
    pub fn set_traffic_lights_position(
        &self,
        egui_ctx: &egui::Context,
        title_bar_y: egui::Rangef,
        left_margin: f32,
    );
}
```

Usage (from the `custom_window_frame` example):
```rust
frame.set_traffic_lights_position(
    ui.ctx(),
    title_bar_rect.y_range(),
    title_bar_rect.left() + 12.0,
);
```

## Details
* The buttons keep AppKit's native spacing.
* The native title bar is resized to cover the buttons, so they stay
clickable in title bars taller than the default.
* Units are egui points; the zoom factor is applied internally.
* It is immediate mode: AppKit resets the button positions whenever it
re-lays out the window (e.g. on resize), so call it every frame.
* No-op in fullscreen (the traffic lights live in a separate window
there) and on non-macOS platforms.

## Other changes
* `custom_window_frame` example: on macOS, uses a full-size content view
with the native traffic lights centered in the custom title bar, instead
of drawing its own buttons.
* `emath::Rangef` now supports `Rangef * f32`, `f32 * Rangef`, and
`Rangef / f32`.
* `WindowChromeMetrics::traffic_lights_size.y` now measures the top
margin from the top of the title bar (previously it was taken from the
bottom in AppKit's non-flipped coordinates), so the reported height may
change.

## Testing
Ran `custom_window_frame` on macOS: traffic lights stay centered when
resizing and zooming (cmd +/-).

* [x] I have followed the instructions in the PR template

🤖 This PR was written with Codex and Claude Code; Marten remains
responsible for the change.

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2026-10-06 15:25:45 +02:00
..

Example how to show a custom window frame instead of the default OS window chrome decorations.

cargo run -p custom_window_frame