-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for drawing custom headerbars #759
Comments
I think winit already have almost everything required to do client side decoration. All we need is a way to call I think the |
It would also be a nice touch if we can make the title bar transparent on MacOS, a la Tauri 1.2. Not sure what the best interface for this would be, seeing as it's a platform-specific thing, but it looks pleasant and would certainly be good to have available. (If anyone who actually knows how windowing works wants to implement this, this is the thing you need.) |
Given this is not closed, does it mean one cannot achieve headerbars akin to GTK's/Adwaita's in Iced? Just curious. |
You can disable window decorations in winit and then draw whatever you want. There are just no widgets to do this easily. I was hoping iced could at least have a widget that lets me drag the associated window, so I can build my own title bar with it. |
Use a |
for anyone who wants to achieve transparent title bar with content underneath, i pieced together a small snippet of doing so, which sets the style whenever a new window is opened: impl App {
pub fn subscription(&self) -> Subscription<Message> {
iced::event::listen().map(Message::IcedEventReceived)
}
pub fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::IcedEventReceived(iced::event::Event::Window(iced::window::Event::Opened { .. })) => {
iced::window::get_latest().and_then(|id| {
iced::window::run_with_handle(id, |handle| {
on_window_opened(handle);
Message::WindowOpened
})
})
}
_ => Task::none()
}
}
pub fn view(&self) -> iced::Element<Message> {
// omitted
}
}
fn on_window_opened(handle: WindowHandle) {
if let RawWindowHandle::AppKit(raw_handle) = handle.as_raw() {
let ns_view = raw_handle.ns_view.as_ptr();
// SAFETY: The pointer came from `WindowHandle`, which ensures
// that the `AppKitWindowHandle` contains a valid pointer to an
// `NSView`.
// Unwrap is fine, since the pointer came from `NonNull`.
let ns_view: Retained<NSView> = unsafe { Retained::retain(ns_view.cast()) }.unwrap();
let window = ns_view.window().expect("view was not installed in a window");
window.setStyleMask(window.styleMask() | NSFullSizeContentViewWindowMask);
window.setTitlebarAppearsTransparent(true);
}
} then, simply pass App::subscription to your iced::run/iced::application call: fn main() -> iced::Result {
iced::application("my app", app::App::update, app::App::view)
.subscription(app::App::subscription) // pass it here
.run()
} the gist is to obtain the underlying raw window handle, then you can obtain the attached (make sure you have objc2 and objc2-app-kit installed) |
On most Unix desktop environments applications can draw an application-specific CSD that replaces the native window title bar.
Here are screenshots of Telegram doing this: electron/electron#11907 (comment)
It would be cool to do this in iced as well, for example, to draw a semi-transparent title bar over a 3d scene.
This should be possible to implement once
winit
lands support for it (see here)The text was updated successfully, but these errors were encountered: