Toggle contacts popover when clicking on status bar icon
This commit is contained in:
parent
9b8492a3ba
commit
d10f6f60ad
9 changed files with 208 additions and 44 deletions
|
@ -1244,6 +1244,10 @@ impl MutableAppContext {
|
|||
.map_or(false, |window| window.is_fullscreen)
|
||||
}
|
||||
|
||||
pub fn window_bounds(&self, window_id: usize) -> RectF {
|
||||
self.presenters_and_platform_windows[&window_id].1.bounds()
|
||||
}
|
||||
|
||||
pub fn render_view(&mut self, params: RenderParams) -> Result<ElementBox> {
|
||||
let window_id = params.window_id;
|
||||
let view_id = params.view_id;
|
||||
|
@ -2032,10 +2036,12 @@ impl MutableAppContext {
|
|||
window_id,
|
||||
}));
|
||||
|
||||
let scene =
|
||||
presenter
|
||||
.borrow_mut()
|
||||
.build_scene(window.size(), window.scale_factor(), false, self);
|
||||
let scene = presenter.borrow_mut().build_scene(
|
||||
window.content_size(),
|
||||
window.scale_factor(),
|
||||
false,
|
||||
self,
|
||||
);
|
||||
window.present_scene(scene);
|
||||
self.presenters_and_platform_windows
|
||||
.insert(window_id, (presenter.clone(), window));
|
||||
|
@ -2411,8 +2417,12 @@ impl MutableAppContext {
|
|||
{
|
||||
let mut presenter = presenter.borrow_mut();
|
||||
presenter.invalidate(&mut invalidation, window.appearance(), self);
|
||||
let scene =
|
||||
presenter.build_scene(window.size(), window.scale_factor(), false, self);
|
||||
let scene = presenter.build_scene(
|
||||
window.content_size(),
|
||||
window.scale_factor(),
|
||||
false,
|
||||
self,
|
||||
);
|
||||
window.present_scene(scene);
|
||||
}
|
||||
self.presenters_and_platform_windows
|
||||
|
@ -2477,7 +2487,8 @@ impl MutableAppContext {
|
|||
window.appearance(),
|
||||
self,
|
||||
);
|
||||
let scene = presenter.build_scene(window.size(), window.scale_factor(), true, self);
|
||||
let scene =
|
||||
presenter.build_scene(window.content_size(), window.scale_factor(), true, self);
|
||||
window.present_scene(scene);
|
||||
}
|
||||
self.presenters_and_platform_windows = presenters;
|
||||
|
@ -3749,6 +3760,10 @@ impl<'a, T: View> ViewContext<'a, T> {
|
|||
self.app.toggle_window_full_screen(self.window_id)
|
||||
}
|
||||
|
||||
pub fn window_bounds(&self) -> RectF {
|
||||
self.app.window_bounds(self.window_id)
|
||||
}
|
||||
|
||||
pub fn prompt(
|
||||
&self,
|
||||
level: PromptLevel,
|
||||
|
|
|
@ -128,7 +128,8 @@ pub trait Window {
|
|||
fn zoom(&self);
|
||||
fn toggle_full_screen(&self);
|
||||
|
||||
fn size(&self) -> Vector2F;
|
||||
fn bounds(&self) -> RectF;
|
||||
fn content_size(&self) -> Vector2F;
|
||||
fn scale_factor(&self) -> f32;
|
||||
fn titlebar_height(&self) -> f32;
|
||||
fn present_scene(&mut self, scene: Scene);
|
||||
|
@ -140,6 +141,7 @@ pub trait Window {
|
|||
pub struct WindowOptions<'a> {
|
||||
pub bounds: WindowBounds,
|
||||
pub titlebar: Option<TitlebarOptions<'a>>,
|
||||
pub center: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -273,6 +275,7 @@ impl<'a> Default for WindowOptions<'a> {
|
|||
appears_transparent: Default::default(),
|
||||
traffic_light_position: Default::default(),
|
||||
}),
|
||||
center: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use crate::{
|
||||
geometry::vector::{vec2f, Vector2F},
|
||||
geometry::{
|
||||
rect::RectF,
|
||||
vector::{vec2f, Vector2F},
|
||||
},
|
||||
platform::{
|
||||
self,
|
||||
mac::{
|
||||
|
@ -10,7 +13,7 @@ use crate::{
|
|||
Event, FontSystem, Scene,
|
||||
};
|
||||
use cocoa::{
|
||||
appkit::{NSSquareStatusItemLength, NSStatusBar, NSStatusItem, NSView, NSWindow},
|
||||
appkit::{NSScreen, NSSquareStatusItemLength, NSStatusBar, NSStatusItem, NSView, NSWindow},
|
||||
base::{id, nil, YES},
|
||||
foundation::{NSPoint, NSRect, NSSize, NSString},
|
||||
};
|
||||
|
@ -163,7 +166,7 @@ impl StatusItem {
|
|||
let state = state.borrow();
|
||||
let layer = state.renderer.layer();
|
||||
let scale_factor = state.scale_factor();
|
||||
let size = state.size() * scale_factor;
|
||||
let size = state.content_size() * scale_factor;
|
||||
layer.set_contents_scale(scale_factor.into());
|
||||
layer.set_drawable_size(metal::CGSize::new(size.x().into(), size.y().into()));
|
||||
}
|
||||
|
@ -235,8 +238,12 @@ impl platform::Window for StatusItem {
|
|||
unimplemented!()
|
||||
}
|
||||
|
||||
fn size(&self) -> Vector2F {
|
||||
self.0.borrow().size()
|
||||
fn bounds(&self) -> RectF {
|
||||
self.0.borrow().bounds()
|
||||
}
|
||||
|
||||
fn content_size(&self) -> Vector2F {
|
||||
self.0.borrow().content_size()
|
||||
}
|
||||
|
||||
fn scale_factor(&self) -> f32 {
|
||||
|
@ -264,10 +271,28 @@ impl platform::Window for StatusItem {
|
|||
}
|
||||
|
||||
impl StatusItemState {
|
||||
fn size(&self) -> Vector2F {
|
||||
fn bounds(&self) -> RectF {
|
||||
unsafe {
|
||||
let window: id = msg_send![self.native_item.button(), window];
|
||||
let screen_frame = window.screen().visibleFrame();
|
||||
let window_frame = NSWindow::frame(window);
|
||||
let origin = vec2f(
|
||||
window_frame.origin.x as f32,
|
||||
(window_frame.origin.y - screen_frame.size.height - window_frame.size.height)
|
||||
as f32,
|
||||
);
|
||||
let size = vec2f(
|
||||
window_frame.size.width as f32,
|
||||
window_frame.size.height as f32,
|
||||
);
|
||||
RectF::new(origin, size)
|
||||
}
|
||||
}
|
||||
|
||||
fn content_size(&self) -> Vector2F {
|
||||
unsafe {
|
||||
let NSSize { width, height, .. } =
|
||||
NSWindow::frame(self.native_item.button().superview().superview()).size;
|
||||
NSView::frame(self.native_item.button().superview().superview()).size;
|
||||
vec2f(width as f32, height as f32)
|
||||
}
|
||||
}
|
||||
|
@ -275,7 +300,7 @@ impl StatusItemState {
|
|||
fn scale_factor(&self) -> f32 {
|
||||
unsafe {
|
||||
let window: id = msg_send![self.native_item.button(), window];
|
||||
window.screen().backingScaleFactor() as f32
|
||||
NSScreen::backingScaleFactor(window.screen()) as f32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -292,7 +317,9 @@ extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) {
|
|||
unsafe {
|
||||
if let Some(state) = get_state(this).upgrade() {
|
||||
let mut state_borrow = state.as_ref().borrow_mut();
|
||||
if let Some(event) = Event::from_native(native_event, Some(state_borrow.size().y())) {
|
||||
if let Some(event) =
|
||||
Event::from_native(native_event, Some(state_borrow.content_size().y()))
|
||||
{
|
||||
if let Some(mut callback) = state_borrow.event_callback.take() {
|
||||
drop(state_borrow);
|
||||
callback(event);
|
||||
|
|
|
@ -335,12 +335,6 @@ impl Window {
|
|||
unsafe {
|
||||
let pool = NSAutoreleasePool::new(nil);
|
||||
|
||||
let frame = match options.bounds {
|
||||
WindowBounds::Maximized => RectF::new(Default::default(), vec2f(1024., 768.)),
|
||||
WindowBounds::Fixed(rect) => rect,
|
||||
}
|
||||
.to_ns_rect();
|
||||
|
||||
let mut style_mask;
|
||||
if let Some(titlebar) = options.titlebar.as_ref() {
|
||||
style_mask = NSWindowStyleMask::NSClosableWindowMask
|
||||
|
@ -357,16 +351,31 @@ impl Window {
|
|||
|
||||
let native_window: id = msg_send![WINDOW_CLASS, alloc];
|
||||
let native_window = native_window.initWithContentRect_styleMask_backing_defer_(
|
||||
frame,
|
||||
RectF::new(Default::default(), vec2f(1024., 768.)).to_ns_rect(),
|
||||
style_mask,
|
||||
NSBackingStoreBuffered,
|
||||
NO,
|
||||
);
|
||||
assert!(!native_window.is_null());
|
||||
|
||||
if matches!(options.bounds, WindowBounds::Maximized) {
|
||||
let screen = native_window.screen();
|
||||
native_window.setFrame_display_(screen.visibleFrame(), YES);
|
||||
let screen = native_window.screen();
|
||||
match options.bounds {
|
||||
WindowBounds::Maximized => {
|
||||
native_window.setFrame_display_(screen.visibleFrame(), YES);
|
||||
}
|
||||
WindowBounds::Fixed(top_left_bounds) => {
|
||||
let frame = screen.visibleFrame();
|
||||
let bottom_left_bounds = RectF::new(
|
||||
vec2f(
|
||||
top_left_bounds.origin_x(),
|
||||
frame.size.height as f32
|
||||
- top_left_bounds.origin_y()
|
||||
- top_left_bounds.height(),
|
||||
),
|
||||
top_left_bounds.size(),
|
||||
);
|
||||
native_window.setFrame_display_(bottom_left_bounds.to_ns_rect(), YES);
|
||||
}
|
||||
}
|
||||
|
||||
let native_view: id = msg_send![VIEW_CLASS, alloc];
|
||||
|
@ -438,7 +447,10 @@ impl Window {
|
|||
native_window.setContentView_(native_view.autorelease());
|
||||
native_window.makeFirstResponder_(native_view);
|
||||
|
||||
native_window.center();
|
||||
if options.center {
|
||||
native_window.center();
|
||||
}
|
||||
|
||||
native_window.makeKeyAndOrderFront_(nil);
|
||||
let _: () = msg_send![
|
||||
native_window,
|
||||
|
@ -633,8 +645,12 @@ impl platform::Window for Window {
|
|||
.detach();
|
||||
}
|
||||
|
||||
fn size(&self) -> Vector2F {
|
||||
self.0.as_ref().borrow().size()
|
||||
fn bounds(&self) -> RectF {
|
||||
self.0.as_ref().borrow().bounds()
|
||||
}
|
||||
|
||||
fn content_size(&self) -> Vector2F {
|
||||
self.0.as_ref().borrow().content_size()
|
||||
}
|
||||
|
||||
fn scale_factor(&self) -> f32 {
|
||||
|
@ -706,7 +722,24 @@ impl WindowState {
|
|||
}
|
||||
}
|
||||
|
||||
fn size(&self) -> Vector2F {
|
||||
fn bounds(&self) -> RectF {
|
||||
unsafe {
|
||||
let screen_frame = self.native_window.screen().visibleFrame();
|
||||
let window_frame = NSWindow::frame(self.native_window);
|
||||
let origin = vec2f(
|
||||
window_frame.origin.x as f32,
|
||||
(window_frame.origin.y - screen_frame.size.height - window_frame.size.height)
|
||||
as f32,
|
||||
);
|
||||
let size = vec2f(
|
||||
window_frame.size.width as f32,
|
||||
window_frame.size.height as f32,
|
||||
);
|
||||
RectF::new(origin, size)
|
||||
}
|
||||
}
|
||||
|
||||
fn content_size(&self) -> Vector2F {
|
||||
let NSSize { width, height, .. } =
|
||||
unsafe { NSView::frame(self.native_window.contentView()) }.size;
|
||||
vec2f(width as f32, height as f32)
|
||||
|
@ -783,7 +816,8 @@ extern "C" fn handle_key_event(this: &Object, native_event: id, key_equivalent:
|
|||
|
||||
let mut window_state_borrow = window_state.as_ref().borrow_mut();
|
||||
|
||||
let event = unsafe { Event::from_native(native_event, Some(window_state_borrow.size().y())) };
|
||||
let event =
|
||||
unsafe { Event::from_native(native_event, Some(window_state_borrow.content_size().y())) };
|
||||
|
||||
if let Some(event) = event {
|
||||
if key_equivalent {
|
||||
|
@ -875,7 +909,8 @@ extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) {
|
|||
let weak_window_state = Rc::downgrade(&window_state);
|
||||
let mut window_state_borrow = window_state.as_ref().borrow_mut();
|
||||
|
||||
let event = unsafe { Event::from_native(native_event, Some(window_state_borrow.size().y())) };
|
||||
let event =
|
||||
unsafe { Event::from_native(native_event, Some(window_state_borrow.content_size().y())) };
|
||||
if let Some(event) = event {
|
||||
match &event {
|
||||
Event::MouseMoved(
|
||||
|
@ -1060,7 +1095,7 @@ extern "C" fn view_did_change_backing_properties(this: &Object, _: Sel) {
|
|||
|
||||
unsafe {
|
||||
let scale_factor = window_state_borrow.scale_factor() as f64;
|
||||
let size = window_state_borrow.size();
|
||||
let size = window_state_borrow.content_size();
|
||||
let drawable_size: NSSize = NSSize {
|
||||
width: size.x() as f64 * scale_factor,
|
||||
height: size.y() as f64 * scale_factor,
|
||||
|
@ -1087,7 +1122,7 @@ extern "C" fn set_frame_size(this: &Object, _: Sel, size: NSSize) {
|
|||
let window_state = unsafe { get_window_state(this) };
|
||||
let window_state_borrow = window_state.as_ref().borrow();
|
||||
|
||||
if window_state_borrow.size() == vec2f(size.width as f32, size.height as f32) {
|
||||
if window_state_borrow.content_size() == vec2f(size.width as f32, size.height as f32) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
use super::{AppVersion, CursorStyle, WindowBounds};
|
||||
use crate::{
|
||||
geometry::vector::{vec2f, Vector2F},
|
||||
geometry::{
|
||||
rect::RectF,
|
||||
vector::{vec2f, Vector2F},
|
||||
},
|
||||
keymap, Action, ClipboardItem,
|
||||
};
|
||||
use anyhow::{anyhow, Result};
|
||||
|
@ -283,7 +286,11 @@ impl super::Window for Window {
|
|||
|
||||
fn toggle_full_screen(&self) {}
|
||||
|
||||
fn size(&self) -> Vector2F {
|
||||
fn bounds(&self) -> RectF {
|
||||
RectF::new(Default::default(), self.size)
|
||||
}
|
||||
|
||||
fn content_size(&self) -> Vector2F {
|
||||
self.size
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue