Add the ability to specify a level when creating windows

This lets some windows stay on top of others, independently of
whether the application is in the foreground.
This commit is contained in:
Antonio Scandurra 2022-09-14 17:09:07 +02:00
parent c1f448d8a8
commit 1c9c7ef7ae
4 changed files with 31 additions and 12 deletions

View file

@ -62,17 +62,16 @@ impl ContactsStatusItem {
let size = vec2f(360., 460.); let size = vec2f(360., 460.);
let origin = window_bounds.lower_left() let origin = window_bounds.lower_left()
+ vec2f(window_bounds.width() / 2. - size.x() / 2., 0.); + vec2f(window_bounds.width() / 2. - size.x() / 2., 0.);
self.popover = Some( let (_, popover) = cx.add_window(
cx.add_window(
gpui::WindowOptions { gpui::WindowOptions {
bounds: gpui::WindowBounds::Fixed(RectF::new(origin, size)), bounds: gpui::WindowBounds::Fixed(RectF::new(origin, size)),
titlebar: None, titlebar: None,
center: false, center: false,
level: gpui::WindowLevel::PopUp,
}, },
|_| ContactsPopover::new(), |_| ContactsPopover::new(),
)
.1,
); );
self.popover = Some(popover);
} }
} }
} }

View file

@ -142,6 +142,7 @@ pub struct WindowOptions<'a> {
pub bounds: WindowBounds, pub bounds: WindowBounds,
pub titlebar: Option<TitlebarOptions<'a>>, pub titlebar: Option<TitlebarOptions<'a>>,
pub center: bool, pub center: bool,
pub level: WindowLevel,
} }
#[derive(Debug)] #[derive(Debug)]
@ -165,6 +166,12 @@ impl Default for Appearance {
} }
} }
#[derive(Copy, Clone, Debug)]
pub enum WindowLevel {
Normal,
PopUp,
}
#[derive(Debug)] #[derive(Debug)]
pub enum WindowBounds { pub enum WindowBounds {
Maximized, Maximized,
@ -276,6 +283,7 @@ impl<'a> Default for WindowOptions<'a> {
traffic_light_position: Default::default(), traffic_light_position: Default::default(),
}), }),
center: false, center: false,
level: WindowLevel::Normal,
} }
} }
} }

View file

@ -12,7 +12,7 @@ use crate::{
Event, WindowBounds, Event, WindowBounds,
}, },
InputHandler, KeyDownEvent, ModifiersChangedEvent, MouseButton, MouseButtonEvent, InputHandler, KeyDownEvent, ModifiersChangedEvent, MouseButton, MouseButtonEvent,
MouseMovedEvent, Scene, MouseMovedEvent, Scene, WindowLevel,
}; };
use block::ConcreteBlock; use block::ConcreteBlock;
use cocoa::{ use cocoa::{
@ -56,6 +56,12 @@ const WINDOW_STATE_IVAR: &str = "windowState";
static mut WINDOW_CLASS: *const Class = ptr::null(); static mut WINDOW_CLASS: *const Class = ptr::null();
static mut VIEW_CLASS: *const Class = ptr::null(); static mut VIEW_CLASS: *const Class = ptr::null();
#[allow(non_upper_case_globals)]
const NSNormalWindowLevel: NSInteger = 0;
#[allow(non_upper_case_globals)]
const NSPopUpWindowLevel: NSInteger = 101;
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
struct NSRange { struct NSRange {
@ -452,6 +458,11 @@ impl Window {
} }
native_window.makeKeyAndOrderFront_(nil); native_window.makeKeyAndOrderFront_(nil);
let native_level = match options.level {
WindowLevel::Normal => NSNormalWindowLevel,
WindowLevel::PopUp => NSPopUpWindowLevel,
};
native_window.setLevel_(native_level);
window.0.borrow().move_traffic_light(); window.0.borrow().move_traffic_light();
pool.drain(); pool.drain();

View file

@ -20,7 +20,7 @@ use gpui::{
geometry::vector::vec2f, geometry::vector::vec2f,
impl_actions, impl_actions,
platform::{WindowBounds, WindowOptions}, platform::{WindowBounds, WindowOptions},
AssetSource, AsyncAppContext, TitlebarOptions, ViewContext, AssetSource, AsyncAppContext, TitlebarOptions, ViewContext, WindowLevel,
}; };
use language::Rope; use language::Rope;
pub use lsp; pub use lsp;
@ -336,6 +336,7 @@ pub fn build_window_options() -> WindowOptions<'static> {
traffic_light_position: Some(vec2f(8., 8.)), traffic_light_position: Some(vec2f(8., 8.)),
}), }),
center: false, center: false,
level: WindowLevel::Normal,
} }
} }