Stop display link when window is occluded (#7511)

Release Notes:

- Fixed a bug that caused the window to become unresponsive after
foregrounding.

---------

Co-authored-by: Conrad <conrad@zed.dev>
This commit is contained in:
Antonio Scandurra 2024-02-07 19:45:30 +01:00 committed by GitHub
parent 114889b8bb
commit 07fce7aae1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -12,7 +12,7 @@ use cocoa::{
CGPoint, NSApplication, NSBackingStoreBuffered, NSEventModifierFlags,
NSFilenamesPboardType, NSPasteboard, NSScreen, NSView, NSViewHeightSizable,
NSViewWidthSizable, NSWindow, NSWindowButton, NSWindowCollectionBehavior,
NSWindowStyleMask, NSWindowTitleVisibility,
NSWindowOcclusionState, NSWindowStyleMask, NSWindowTitleVisibility,
},
base::{id, nil},
foundation::{
@ -249,6 +249,10 @@ unsafe fn build_window_class(name: &'static str, superclass: &Class) -> *const C
sel!(windowDidResize:),
window_did_resize as extern "C" fn(&Object, Sel, id),
);
decl.add_method(
sel!(windowDidChangeOcclusionState:),
window_did_change_occlusion_state as extern "C" fn(&Object, Sel, id),
);
decl.add_method(
sel!(windowWillEnterFullScreen:),
window_will_enter_fullscreen as extern "C" fn(&Object, Sel, id),
@ -530,14 +534,12 @@ impl MacWindow {
let native_view = NSView::init(native_view);
assert!(!native_view.is_null());
let display_link = start_display_link(native_window.screen(), native_view);
let window = Self(Arc::new(Mutex::new(MacWindowState {
handle,
executor,
native_window,
native_view: NonNull::new_unchecked(native_view),
display_link,
display_link: nil,
renderer: MetalRenderer::new(instance_buffer_pool),
kind: options.kind,
request_frame_callback: None,
@ -1332,6 +1334,23 @@ extern "C" fn cancel_operation(this: &Object, _sel: Sel, _sender: id) {
}
}
extern "C" fn window_did_change_occlusion_state(this: &Object, _: Sel, _: id) {
let window_state = unsafe { get_window_state(this) };
let mut lock = window_state.lock();
unsafe {
if lock
.native_window
.occlusionState()
.contains(NSWindowOcclusionState::NSWindowOcclusionStateVisible)
{
lock.display_link =
start_display_link(lock.native_window.screen(), lock.native_view.as_ptr());
} else {
lock.display_link = nil;
}
}
}
extern "C" fn window_did_resize(this: &Object, _: Sel, _: id) {
let window_state = unsafe { get_window_state(this) };
window_state.as_ref().lock().move_traffic_light();