gpui: Implement dynamic window control elements (#30828)

Allows setting element as window control elements which consist of
`Drag`, `Close`, `Max`, or `Min`. This allows you to implement
dynamically sized elements that control the platform window, this is
used for areas such as the title bar. Currently only implemented for
Windows.

Release Notes:

- N/A
This commit is contained in:
Matin Aniss 2025-06-07 03:11:24 +10:00 committed by GitHub
parent d9efa2860f
commit ca3f46588a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 129 additions and 96 deletions

View file

@ -1,4 +1,4 @@
use gpui::{Rgba, WindowAppearance, prelude::*};
use gpui::{Rgba, WindowAppearance, WindowControlArea, prelude::*};
use ui::prelude::*;
@ -118,17 +118,12 @@ impl WindowsCaptionButton {
impl RenderOnce for WindowsCaptionButton {
fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
// todo(windows) report this width to the Windows platform API
// NOTE: this is intentionally hard coded. An option to use the 'native' size
// could be added when the width is reported to the Windows platform API
// as this could change between future Windows versions.
let width = px(36.);
h_flex()
.id(self.id)
.justify_center()
.content_center()
.w(width)
.occlude()
.w(px(36.))
.h_full()
.text_size(px(10.0))
.hover(|style| style.bg(self.hover_background_color))
@ -138,6 +133,17 @@ impl RenderOnce for WindowsCaptionButton {
style.bg(active_color)
})
.map(|this| match self.icon {
WindowsCaptionButtonIcon::Close => {
this.window_control_area(WindowControlArea::Close)
}
WindowsCaptionButtonIcon::Maximize | WindowsCaptionButtonIcon::Restore => {
this.window_control_area(WindowControlArea::Max)
}
WindowsCaptionButtonIcon::Minimize => {
this.window_control_area(WindowControlArea::Min)
}
})
.child(match self.icon {
WindowsCaptionButtonIcon::Minimize => "\u{e921}",
WindowsCaptionButtonIcon::Restore => "\u{e923}",

View file

@ -22,7 +22,8 @@ use client::{Client, UserStore};
use gpui::{
Action, AnyElement, App, Context, Corner, Decorations, Element, Entity, InteractiveElement,
Interactivity, IntoElement, MouseButton, ParentElement, Render, Stateful,
StatefulInteractiveElement, Styled, Subscription, WeakEntity, Window, actions, div, px,
StatefulInteractiveElement, Styled, Subscription, WeakEntity, Window, WindowControlArea,
actions, div, px,
};
use onboarding_banner::OnboardingBanner;
use project::Project;
@ -143,6 +144,7 @@ impl Render for TitleBar {
h_flex()
.id("titlebar")
.window_control_area(WindowControlArea::Drag)
.w_full()
.h(height)
.map(|this| {