Route whether or not a window is fullscreen down into GPUI
This still needs to be able to invalidate things to be useful but it's a good first cut at just making the information available to platform-agnostic code Co-authored-by: Mikayla <mikayla@zed.dev>
This commit is contained in:
parent
ae8dd1e3fd
commit
ab760493cf
4 changed files with 129 additions and 3 deletions
|
@ -1248,6 +1248,13 @@ impl MutableAppContext {
|
|||
.map_or(false, |window| window.is_active)
|
||||
}
|
||||
|
||||
pub fn window_is_fullscreen(&self, window_id: usize) -> bool {
|
||||
self.cx
|
||||
.windows
|
||||
.get(&window_id)
|
||||
.map_or(false, |window| window.is_fullscreen)
|
||||
}
|
||||
|
||||
pub fn render_view(&mut self, params: RenderParams) -> Result<ElementBox> {
|
||||
let window_id = params.window_id;
|
||||
let view_id = params.view_id;
|
||||
|
@ -1934,6 +1941,7 @@ impl MutableAppContext {
|
|||
focused_view_id: Some(root_view.id()),
|
||||
is_active: false,
|
||||
invalidation: None,
|
||||
is_fullscreen: false,
|
||||
},
|
||||
);
|
||||
root_view.update(this, |view, cx| view.on_focus(cx));
|
||||
|
@ -2010,6 +2018,13 @@ impl MutableAppContext {
|
|||
}));
|
||||
}
|
||||
|
||||
{
|
||||
let mut app = self.upgrade();
|
||||
window.on_fullscreen(Box::new(move |is_fullscreen| {
|
||||
app.update(|cx| cx.window_was_fullscreen_changed(window_id, is_fullscreen))
|
||||
}));
|
||||
}
|
||||
|
||||
{
|
||||
let mut app = self.upgrade();
|
||||
window.on_close(Box::new(move || {
|
||||
|
@ -2151,7 +2166,9 @@ impl MutableAppContext {
|
|||
subscription_id,
|
||||
callback,
|
||||
} => self.handle_subscription_effect(entity_id, subscription_id, callback),
|
||||
|
||||
Effect::Event { entity_id, payload } => self.emit_event(entity_id, payload),
|
||||
|
||||
Effect::GlobalSubscription {
|
||||
type_id,
|
||||
subscription_id,
|
||||
|
@ -2161,21 +2178,27 @@ impl MutableAppContext {
|
|||
subscription_id,
|
||||
callback,
|
||||
),
|
||||
|
||||
Effect::GlobalEvent { payload } => self.emit_global_event(payload),
|
||||
|
||||
Effect::Observation {
|
||||
entity_id,
|
||||
subscription_id,
|
||||
callback,
|
||||
} => self.handle_observation_effect(entity_id, subscription_id, callback),
|
||||
|
||||
Effect::ModelNotification { model_id } => {
|
||||
self.handle_model_notification_effect(model_id)
|
||||
}
|
||||
|
||||
Effect::ViewNotification { window_id, view_id } => {
|
||||
self.handle_view_notification_effect(window_id, view_id)
|
||||
}
|
||||
|
||||
Effect::GlobalNotification { type_id } => {
|
||||
self.handle_global_notification_effect(type_id)
|
||||
}
|
||||
|
||||
Effect::Deferred {
|
||||
callback,
|
||||
after_window_update,
|
||||
|
@ -2186,15 +2209,19 @@ impl MutableAppContext {
|
|||
callback(self)
|
||||
}
|
||||
}
|
||||
|
||||
Effect::ModelRelease { model_id, model } => {
|
||||
self.handle_entity_release_effect(model_id, model.as_any())
|
||||
}
|
||||
|
||||
Effect::ViewRelease { view_id, view } => {
|
||||
self.handle_entity_release_effect(view_id, view.as_any())
|
||||
}
|
||||
|
||||
Effect::Focus { window_id, view_id } => {
|
||||
self.handle_focus_effect(window_id, view_id);
|
||||
}
|
||||
|
||||
Effect::FocusObservation {
|
||||
view_id,
|
||||
subscription_id,
|
||||
|
@ -2202,6 +2229,7 @@ impl MutableAppContext {
|
|||
} => {
|
||||
self.handle_focus_observation_effect(view_id, subscription_id, callback)
|
||||
}
|
||||
|
||||
Effect::ResizeWindow { window_id } => {
|
||||
if let Some(window) = self.cx.windows.get_mut(&window_id) {
|
||||
window
|
||||
|
@ -2209,6 +2237,7 @@ impl MutableAppContext {
|
|||
.get_or_insert(WindowInvalidation::default());
|
||||
}
|
||||
}
|
||||
|
||||
Effect::WindowActivationObservation {
|
||||
window_id,
|
||||
subscription_id,
|
||||
|
@ -2218,10 +2247,17 @@ impl MutableAppContext {
|
|||
subscription_id,
|
||||
callback,
|
||||
),
|
||||
|
||||
Effect::ActivateWindow {
|
||||
window_id,
|
||||
is_active,
|
||||
} => self.handle_window_activation_effect(window_id, is_active),
|
||||
|
||||
Effect::FullscreenWindow {
|
||||
window_id,
|
||||
is_fullscreen,
|
||||
} => self.handle_fullscreen_effect(window_id, is_fullscreen),
|
||||
|
||||
Effect::RefreshWindows => {
|
||||
refreshing = true;
|
||||
}
|
||||
|
@ -2294,6 +2330,13 @@ impl MutableAppContext {
|
|||
.push_back(Effect::ResizeWindow { window_id });
|
||||
}
|
||||
|
||||
fn window_was_fullscreen_changed(&mut self, window_id: usize, is_fullscreen: bool) {
|
||||
self.pending_effects.push_back(Effect::FullscreenWindow {
|
||||
window_id,
|
||||
is_fullscreen,
|
||||
});
|
||||
}
|
||||
|
||||
fn window_changed_active_status(&mut self, window_id: usize, is_active: bool) {
|
||||
self.pending_effects.push_back(Effect::ActivateWindow {
|
||||
window_id,
|
||||
|
@ -2608,13 +2651,36 @@ impl MutableAppContext {
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_window_activation_effect(&mut self, window_id: usize, active: bool) {
|
||||
fn handle_fullscreen_effect(&mut self, window_id: usize, is_fullscreen: bool) {
|
||||
//Short circuit evaluation if we're already g2g
|
||||
if self
|
||||
.cx
|
||||
.windows
|
||||
.get(&window_id)
|
||||
.map(|w| w.is_active)
|
||||
.map_or(false, |cur_active| cur_active == active)
|
||||
.map(|w| w.is_fullscreen == is_fullscreen)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self.update(|this| {
|
||||
let window = this.cx.windows.get_mut(&window_id)?;
|
||||
window.is_fullscreen = is_fullscreen;
|
||||
|
||||
// self.emit_event(entity_id, payload);
|
||||
|
||||
Some(())
|
||||
});
|
||||
}
|
||||
|
||||
fn handle_window_activation_effect(&mut self, window_id: usize, active: bool) {
|
||||
//Short circuit evaluation if we're already g2g
|
||||
if self
|
||||
.cx
|
||||
.windows
|
||||
.get(&window_id)
|
||||
.map(|w| w.is_active == active)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2622,6 +2688,8 @@ impl MutableAppContext {
|
|||
self.update(|this| {
|
||||
let window = this.cx.windows.get_mut(&window_id)?;
|
||||
window.is_active = active;
|
||||
|
||||
//Handle focus
|
||||
let view_id = window.focused_view_id?;
|
||||
if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) {
|
||||
if active {
|
||||
|
@ -2632,6 +2700,7 @@ impl MutableAppContext {
|
|||
this.cx.views.insert((window_id, view_id), view);
|
||||
}
|
||||
|
||||
//Deliver events
|
||||
let callbacks = this
|
||||
.window_activation_observations
|
||||
.lock()
|
||||
|
@ -2640,6 +2709,7 @@ impl MutableAppContext {
|
|||
for (id, callback) in callbacks {
|
||||
if let Some(mut callback) = callback {
|
||||
let alive = callback(active, this);
|
||||
//Put entry back
|
||||
if alive {
|
||||
match this
|
||||
.window_activation_observations
|
||||
|
@ -3072,6 +3142,7 @@ struct Window {
|
|||
root_view: AnyViewHandle,
|
||||
focused_view_id: Option<usize>,
|
||||
is_active: bool,
|
||||
is_fullscreen: bool,
|
||||
invalidation: Option<WindowInvalidation>,
|
||||
}
|
||||
|
||||
|
@ -3138,6 +3209,10 @@ pub enum Effect {
|
|||
ResizeWindow {
|
||||
window_id: usize,
|
||||
},
|
||||
FullscreenWindow {
|
||||
window_id: usize,
|
||||
is_fullscreen: bool,
|
||||
},
|
||||
ActivateWindow {
|
||||
window_id: usize,
|
||||
is_active: bool,
|
||||
|
@ -3256,6 +3331,14 @@ impl Debug for Effect {
|
|||
.field("window_id", window_id)
|
||||
.field("is_active", is_active)
|
||||
.finish(),
|
||||
Effect::FullscreenWindow {
|
||||
window_id,
|
||||
is_fullscreen,
|
||||
} => f
|
||||
.debug_struct("Effect::FullscreenWindow")
|
||||
.field("window_id", window_id)
|
||||
.field("is_fullscreen", is_fullscreen)
|
||||
.finish(),
|
||||
Effect::RefreshWindows => f.debug_struct("Effect::FullViewRefresh").finish(),
|
||||
Effect::WindowShouldCloseSubscription { window_id, .. } => f
|
||||
.debug_struct("Effect::WindowShouldCloseSubscription")
|
||||
|
@ -4032,6 +4115,10 @@ impl<'a, V: View> RenderContext<'a, V> {
|
|||
WeakViewHandle::new(self.window_id, self.view_id)
|
||||
}
|
||||
|
||||
pub fn window_id(&self) -> usize {
|
||||
self.window_id
|
||||
}
|
||||
|
||||
pub fn view_id(&self) -> usize {
|
||||
self.view_id
|
||||
}
|
||||
|
|
|
@ -112,6 +112,7 @@ pub trait Window: WindowContext {
|
|||
fn on_event(&mut self, callback: Box<dyn FnMut(Event) -> bool>);
|
||||
fn on_active_status_change(&mut self, callback: Box<dyn FnMut(bool)>);
|
||||
fn on_resize(&mut self, callback: Box<dyn FnMut()>);
|
||||
fn on_fullscreen(&mut self, callback: Box<dyn FnMut(bool)>);
|
||||
fn on_should_close(&mut self, callback: Box<dyn FnMut() -> bool>);
|
||||
fn on_close(&mut self, callback: Box<dyn FnOnce()>);
|
||||
fn set_input_handler(&mut self, input_handler: Box<dyn InputHandler>);
|
||||
|
|
|
@ -128,6 +128,14 @@ unsafe fn build_classes() {
|
|||
sel!(windowDidResize:),
|
||||
window_did_resize as extern "C" fn(&Object, Sel, id),
|
||||
);
|
||||
decl.add_method(
|
||||
sel!(windowDidEnterFullScreen:),
|
||||
window_did_enter_fullscreen as extern "C" fn(&Object, Sel, id),
|
||||
);
|
||||
decl.add_method(
|
||||
sel!(windowDidExitFullScreen:),
|
||||
window_did_exit_fullscreen as extern "C" fn(&Object, Sel, id),
|
||||
);
|
||||
decl.add_method(
|
||||
sel!(windowDidBecomeKey:),
|
||||
window_did_change_key_status as extern "C" fn(&Object, Sel, id),
|
||||
|
@ -276,6 +284,7 @@ struct WindowState {
|
|||
event_callback: Option<Box<dyn FnMut(Event) -> bool>>,
|
||||
activate_callback: Option<Box<dyn FnMut(bool)>>,
|
||||
resize_callback: Option<Box<dyn FnMut()>>,
|
||||
fullscreen_callback: Option<Box<dyn FnMut(bool)>>,
|
||||
should_close_callback: Option<Box<dyn FnMut() -> bool>>,
|
||||
close_callback: Option<Box<dyn FnOnce()>>,
|
||||
input_handler: Option<Box<dyn InputHandler>>,
|
||||
|
@ -368,6 +377,7 @@ impl Window {
|
|||
should_close_callback: None,
|
||||
close_callback: None,
|
||||
activate_callback: None,
|
||||
fullscreen_callback: None,
|
||||
input_handler: None,
|
||||
pending_key_down: None,
|
||||
performed_key_equivalent: false,
|
||||
|
@ -467,6 +477,10 @@ impl platform::Window for Window {
|
|||
self.0.as_ref().borrow_mut().resize_callback = Some(callback);
|
||||
}
|
||||
|
||||
fn on_fullscreen(&mut self, callback: Box<dyn FnMut(bool)>) {
|
||||
self.0.as_ref().borrow_mut().fullscreen_callback = Some(callback);
|
||||
}
|
||||
|
||||
fn on_should_close(&mut self, callback: Box<dyn FnMut() -> bool>) {
|
||||
self.0.as_ref().borrow_mut().should_close_callback = Some(callback);
|
||||
}
|
||||
|
@ -908,6 +922,24 @@ extern "C" fn window_did_resize(this: &Object, _: Sel, _: id) {
|
|||
window_state.as_ref().borrow().move_traffic_light();
|
||||
}
|
||||
|
||||
extern "C" fn window_did_enter_fullscreen(this: &Object, _: Sel, _: id) {
|
||||
window_fullscreen_changed(this, true);
|
||||
}
|
||||
|
||||
extern "C" fn window_did_exit_fullscreen(this: &Object, _: Sel, _: id) {
|
||||
window_fullscreen_changed(this, false);
|
||||
}
|
||||
|
||||
fn window_fullscreen_changed(this: &Object, is_fullscreen: bool) {
|
||||
let window_state = unsafe { get_window_state(this) };
|
||||
let mut window_state_borrow = window_state.as_ref().borrow_mut();
|
||||
if let Some(mut callback) = window_state_borrow.fullscreen_callback.take() {
|
||||
drop(window_state_borrow);
|
||||
callback(is_fullscreen);
|
||||
window_state.borrow_mut().fullscreen_callback = Some(callback);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" fn window_did_change_key_status(this: &Object, selector: Sel, _: id) {
|
||||
let is_active = if selector == sel!(windowDidBecomeKey:) {
|
||||
true
|
||||
|
|
|
@ -37,6 +37,7 @@ pub struct Window {
|
|||
event_handlers: Vec<Box<dyn FnMut(super::Event) -> bool>>,
|
||||
resize_handlers: Vec<Box<dyn FnMut()>>,
|
||||
close_handlers: Vec<Box<dyn FnOnce()>>,
|
||||
fullscreen_handlers: Vec<Box<dyn FnMut(bool)>>,
|
||||
pub(crate) active_status_change_handlers: Vec<Box<dyn FnMut(bool)>>,
|
||||
pub(crate) should_close_handler: Option<Box<dyn FnMut() -> bool>>,
|
||||
pub(crate) title: Option<String>,
|
||||
|
@ -199,6 +200,7 @@ impl Window {
|
|||
close_handlers: Default::default(),
|
||||
should_close_handler: Default::default(),
|
||||
active_status_change_handlers: Default::default(),
|
||||
fullscreen_handlers: Default::default(),
|
||||
scale_factor: 1.0,
|
||||
current_scene: None,
|
||||
title: None,
|
||||
|
@ -253,6 +255,10 @@ impl super::Window for Window {
|
|||
self.active_status_change_handlers.push(callback);
|
||||
}
|
||||
|
||||
fn on_fullscreen(&mut self, callback: Box<dyn FnMut(bool)>) {
|
||||
self.fullscreen_handlers.push(callback)
|
||||
}
|
||||
|
||||
fn on_resize(&mut self, callback: Box<dyn FnMut()>) {
|
||||
self.resize_handlers.push(callback);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue