Commit 48b29d9eaa for qemu.org

commit 48b29d9eaa7f71c7e44cba71b0e796eb9c774b65
Author: Marc-André Lureau <marcandre.lureau@redhat.com>
Date:   Tue Jun 23 11:44:35 2026 +0400

    ui/cocoa: implement display cleanup

    Move cbowner release from QemuCocoaAppController -dealloc to
    cocoa_display_cleanup(), since cbowner is allocated in
    cocoa_display_init() and cleanup is the symmetric teardown path.

    Tested-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
    Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
    Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
    Message-ID: <20260623-b4-ui-v4-20-4656aec3398d@redhat.com>

diff --git a/ui/cocoa.m b/ui/cocoa.m
index e157ad01d8..3751be3792 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -1206,8 +1206,6 @@ - (void) dealloc
     COCOA_DEBUG("QemuCocoaAppController: dealloc\n");

     [cocoaView release];
-    [cbowner release];
-    cbowner = nil;

     [super dealloc];
 }
@@ -2038,9 +2036,26 @@ static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts)
     qemu_main = cocoa_main;
 }

+static void cocoa_display_cleanup(void)
+{
+    if (!kbd) {
+        return;
+    }
+
+    qemu_console_unregister_listener(&dcl);
+    g_clear_pointer(&kbd, qkbd_state_free);
+    qemu_remove_mouse_mode_change_notifier(&mouse_mode_change_notifier);
+    qemu_clipboard_peer_unregister(&cbpeer);
+    g_clear_pointer(&cbinfo, qemu_clipboard_info_unref);
+    qemu_event_destroy(&cbevent);
+    [cbowner release];
+    cbowner = nil;
+}
+
 static QemuDisplay qemu_display_cocoa = {
     .type       = DISPLAY_TYPE_COCOA,
     .init       = cocoa_display_init,
+    .cleanup    = cocoa_display_cleanup,
 };

 static void register_cocoa(void)