Repository: tauri
Issue: [feat] Allowing for native inset OS X traffic lights on NSWindow
Labels: type: feature request

### Describe the problem

Many apps (also electron apps) have customized traffic light position to fit their style better. In electron this is achieved through a config file that calls native objc code. I would like this in tauri as it would allow for cleaner more intentional designs.

### Describe the solution you'd like

I have already worked on this in issue #2663. I used [the electron source](https://github.com/electron/electron/pull/21781/commits/63c1caa8d8f966eca68754b859b50d1f7c9c7088) as inspiration.

A file called `window_ext.rs`:

```rust
use tauri::{Runtime, Window};

pub trait WindowExt {
    #[cfg(target_os = "macos")]
    fn set_transparent_titlebar(&self, transparent: bool);
    fn position_traffic_lights(&self, x: f64, y: f64);
}

impl<R: Runtime> WindowExt for Window<R> {
    #[cfg(target_os = "macos")]
    fn set_transparent_titlebar(&self, transparent: bool) {
        use cocoa::appkit::{NSWindow, NSWindowTitleVisibility};

        let window = self.ns_window().unwrap() as cocoa::base::id;

        unsafe {
            window.setTitleVisibility_(NSWindowTitleVisibility::NSWindowTitleHidden);

            if transparent {
                window.setTitlebarAppearsTransparent_(cocoa::base::YES);
            } else {
                window.setTitlebarAppearsTransparent_(cocoa::base::NO);
            }
        }
    }

    #[cfg(target_os = "macos")]
    fn position_traffic_lights(&self, x: f64, y: f64) {
        use cocoa::appkit::{NSView, NSWindow, NSWindowButton};
        use cocoa::foundation::NSRect;

        let window = self.ns_window().unwrap() as cocoa::base::id;

        unsafe {
            let close = window.standardWindowButton_(NSWindowButton::NSWindowCloseButton);
            let miniaturize =
                window.standardWindowButton_(NSWindowButton::NSWindowMiniaturizeButton);
            let zoom = window.standardWindowButton_(NSWindowButton::NSWindowZoomButton);

            let title_bar_container_view = close.superview().superview();

            let close_rect: NSRect = msg_send![close, frame];
            let button_height = close_rect.size.height;

            let title_bar_frame_height = button_height + y;
            let mut title_bar_rect = NSView::frame(title_bar_container_view);
            title_bar_rect.size.height = title_bar_frame_height;
            title_bar_rect.origin.y = NSView::frame(window).size.height - title_bar_frame_height;
            let _: () = msg_send![title_bar_container_view, setFrame: title_bar_rect];

            let window_buttons = vec![close, miniaturize, zoom];
            let space_between = NSView::frame(miniaturize).origin.x - NSView::frame(close).origin.x;

            for (i, button) in window_buttons.into_iter().enumerate() {
                let mut rect: NSRect = NSView::frame(button);
                rect.origin.x = x + (i as f64 * space_between);
                button.setFrameOrigin(rect.origin);
            }
        }
    }
}
```

`main.rs`:

```rust
#![cfg_attr(
    all(not(debug_assertions), target_os = "windows"),
    windows_subsystem = "windows"
)]

#[cfg(target_os = "macos")]
#[macro_use]
extern crate objc;

use tauri::{Manager, WindowEvent};
use window_ext::WindowExt;

mod window_ext;

fn main() {
    tauri::Builder::default()
        .setup(|app| {
            let win = app.get_window("main").unwrap();
            win.set_transparent_titlebar(true);
            win.position_traffic_lights(30.0, 30.0);
            Ok(())
        })
        .on_window_event(|e| {
            if let WindowEvent::Resized(..) = e.event() {
                let win = e.window();
                win.position_traffic_lights(30., 30.);
            }
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");

}
```

In general this works:

<img width="592" alt="Screenshot 2022-07-27 at 14 36 04" src="https://user-images.githubusercontent.com/104835302/181439210-ea94aaf5-5ae6-4d06-bd74-3857c98e4587.png">


The `on_window_event` listener is there because without it the traffic lights would take their original position when the window is resized. This comes however with an annoying problem: The `NSWindow` handle becomes only available _after_ the window is already rendered. That causes some annoying artifacts. You can see the original traffic lights before they are repositioned for a very short time.

So the task is somehow tapping into the tao render pipeline or something else to draw the traffic lights before the window is rendered.

### Alternatives considered

I don't really have any. Maybe somehow controlling the NSWindow completely ourselves. _Please_ make suggestions if you know more about the tauri source.

### Additional context

There are still some `#[cfg(target_os = "macos")]` missing. Feel free to add them.