Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Crash on macOS when the subclassing adapter is dropped while the view has key-value observers

Abierto
#823 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

@RXNova ya está trabajando en esto.

Desde el 11/10/2026.

  • #822 de @RXNova — abierto

Evaluación

Dificultad
3/5
Tiempo estimado
1-2 días
Aptitud para principiantes
35/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Estancado
Stack tecnológico
macos, rust
Área
backend

Línea de trabajo

Start in adapters/macos/src/subclass.rs, especially SubclassingAdapter::drop, and inspect the linked pull request #822 for current work. Reproduce with the supplied observer example and trace how the view’s Objective-C class changes while observers are registered. Done means dropping the adapter leaves observers removable without raising an exception.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

What happens

An app that uses the macOS SubclassingAdapter is terminated by an uncaught exception every time its window is closed. In our case this is an eframe/egui 0.36 app (winit 0.30, accesskit_winit 0.32, accesskit_macos 0.26.3) on macOS 27.0.1, on a MacBook Pro with a Touch Bar (MacBookPro17,1):

*** Terminating app due to uncaught exception 'NSRangeException', reason:
'Cannot remove an observer <_NSTouchBarFinderObservation 0x…> for the key path
"nextResponder" from <WinitView 0x…> because it is not registered as an observer.'

-[NSObject(NSKeyValueObserverRegistration) _removeObserver:forProperty:]
-[NSObject(NSKeyValueObserverRegistration) removeObserver:forKeyPath:]
-[NSObject(NSKeyValueObserverRegistration) removeObserver:forKeyPath:context:]
-[_NSTouchBarFinderObservation invalidate]
___NSTouchBarFinderSetNeedsUpdateOnMain_block_invoke_2
NSDisplayCycleObserverInvoke
NSDisplayCycleFlush

I haven't checked other macOS versions or Macs without a Touch Bar.

Cause

SubclassingAdapter::drop calls object_setClass(view, prev_class) unconditionally. AppKit registers key-value observers on the window's first responder (_NSTouchBarFinderObservation, key paths nextResponder and touchBar), so by the time the adapter is dropped, the view's real class is NSKVONotifying_AccessKitSubclassOfWinitView. Resetting the class discards KVO's subclass while the observers are still registered, and AppKit's later removeObserver:forKeyPath: raises.

Tracing addObserver:/removeObserver: in a debugger showed the observers being added while the view's class was AccessKitSubclassOfWinitView, and removed after it had been reset to WinitView.

adapters/macos/src/subclass.rs on main has the same code as 0.26.3.

What should happen

Dropping the adapter shouldn't break observers that other code has registered on the view.

How to reproduce

This program does what AppKit does, with an observer of its own. With accesskit_macos 0.27.1 it aborts at the last line (fatal runtime error: Rust cannot catch foreign exceptions, aborting).

[dependencies]
accesskit = "0.25"
accesskit_macos = "0.27.1"
objc2 = "0.5.1"
objc2-app-kit = { version = "0.2.0", features = ["NSResponder", "NSView"] }
objc2-foundation = { version = "0.2.0", features = ["NSString"] }
use std::ffi::c_void;

use accesskit::{ActionHandler, ActionRequest, ActivationHandler, TreeUpdate};
use accesskit_macos::SubclassingAdapter;
use objc2::rc::Id;
use objc2::{class, msg_send, msg_send_id};
use objc2_app_kit::NSView;
use objc2_foundation::{NSObject, NSString};

struct NoTree;

impl ActivationHandler for NoTree {
    fn request_initial_tree(&mut self) -> Option<TreeUpdate> {
        None
    }
}

struct NoActions;

impl ActionHandler for NoActions {
    fn do_action(&mut self, _request: ActionRequest) {}
}

fn main() {
    let view: Id<NSView> = unsafe { msg_send_id![class!(NSView), new] };
    let adapter = unsafe {
        SubclassingAdapter::new(&*view as *const NSView as *mut c_void, NoTree, NoActions)
    };

    // Stand-in for AppKit's own observers on the first responder.
    let observer = NSObject::new();
    let key_path = NSString::from_str("nextResponder");
    let context: *mut c_void = std::ptr::null_mut();
    let _: () = unsafe {
        msg_send![&view, addObserver: &*observer, forKeyPath: &*key_path, options: 0usize, context: context]
    };

    drop(adapter);

    // Raises NSRangeException.
    let _: () = unsafe { msg_send![&view, removeObserver: &*observer, forKeyPath: &*key_path] };
}
Lenguaje dominante
Rust
Estrellas
1.5k
Forks
122
Merge medio
1 h 14 min
PR fusionados (30 d)
16

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de AccessKit/accesskit

Todos los issues de AccessKit/accesskit

Issues similares

Más issues de Rust

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.