From patchwork Mon Mar 7 13:49:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Akihiko Odaki X-Patchwork-Id: 12771905 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0CED1C433F5 for ; Mon, 7 Mar 2022 14:11:52 +0000 (UTC) Received: from localhost ([::1]:40458 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nRE5X-0001B4-7B for qemu-devel@archiver.kernel.org; Mon, 07 Mar 2022 09:11:51 -0500 Received: from eggs.gnu.org ([209.51.188.92]:60116) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nRDkN-00043a-Vq for qemu-devel@nongnu.org; Mon, 07 Mar 2022 08:50:00 -0500 Received: from [2607:f8b0:4864:20::62c] (port=43969 helo=mail-pl1-x62c.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1nRDkM-0007jg-2X for qemu-devel@nongnu.org; Mon, 07 Mar 2022 08:49:59 -0500 Received: by mail-pl1-x62c.google.com with SMTP id e2so13799459pls.10 for ; Mon, 07 Mar 2022 05:49:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=EfTY8TLtEi3OCisjI7SCHQnGUVW3tHzs9UCEtgZJuz0=; b=XilTYKZDSUw89raljsBYMconzFClDQGssy628SWWEJxJYn0/FDeNv5X6Q0+LdSs2LQ c44BTf39ULqihYaE44cz9Wdr//XjB/Py6KQhoCmonWela/NnauFrSdp8dgTbVs6ruQpv 7NO7fNOE1j7RdJS7a+Xni7/EbYjLAVnJWwBIiQwbMYjOef/UjA6BCXySIPkXsgqyD6O6 lWMYkAReA4I3zOsxKfT8CJcklBXwCP21qJqEDunYllrdEdC9MwgXOomrg2wCCPDfk+3F TiREJ4eMsvimmkelQDJ6AAouqLhtaBSZH7V3floIb79gzQ3hbZVZ04Ms5frdGEh0JsDi FHmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=EfTY8TLtEi3OCisjI7SCHQnGUVW3tHzs9UCEtgZJuz0=; b=2kMbWZCtASzz11YVTemjonBWwRh7zdplZiVOia0TjURiGo3L831kOkncOD6CxqfWOm 5ir/eI2jShV0X3qjtewfvy5hCKLFf9nvn4EzHlyDo+PMIkSV6H9megi2VTHoSHeM1ZLj niiDFoI5JMxzvUkDnQeHTyvJ1qEe1oa9UK0bA1lpOu6DIz6RlT3Bx6q0LRFDJ4v96WwL X0jalcrIekLFVBa9Kpjt+hMCYUoA3op1aeRlHILnq2Uzok8zRSJ7LcK3UECZXy/2cyxW Rt3Oitx8AR+3bL2n6m58I+a1UzTacFSQCKlsCyrKXvcUBAQhbxgxNC07rTYhQBG0IVyn kX7w== X-Gm-Message-State: AOAM532TEzJPYNin6gIfq3thd+8ynwUqlPO8+5AG6gWBg4+rUJHQ0bCN jzlPYD8NMPL9gU+o/NLs/uYPKwXdfIQ= X-Google-Smtp-Source: ABdhPJwzdgDdTkGIMuLrPsvbPyasjE7LddLY69EKcDlZE1Elhk1cTkPBNC5t5gjwyypuLbfzw1gsMA== X-Received: by 2002:a17:902:b582:b0:14c:a63d:3df6 with SMTP id a2-20020a170902b58200b0014ca63d3df6mr12117861pls.51.1646660996399; Mon, 07 Mar 2022 05:49:56 -0800 (PST) Received: from localhost.localdomain ([2400:4050:c360:8200:9058:25bf:2793:c7c7]) by smtp.gmail.com with ESMTPSA id o15-20020a17090a168f00b001bf66741097sm3622387pja.16.2022.03.07.05.49.54 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Mon, 07 Mar 2022 05:49:55 -0800 (PST) From: Akihiko Odaki To: Subject: [PATCH v2 1/2] ui/cocoa: Move create_initial_menus Date: Mon, 7 Mar 2022 22:49:45 +0900 Message-Id: <20220307134946.61407-2-akihiko.odaki@gmail.com> X-Mailer: git-send-email 2.32.0 (Apple Git-132) In-Reply-To: <20220307134946.61407-1-akihiko.odaki@gmail.com> References: <20220307134946.61407-1-akihiko.odaki@gmail.com> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::62c (failed) Received-SPF: pass client-ip=2607:f8b0:4864:20::62c; envelope-from=akihiko.odaki@gmail.com; helo=mail-pl1-x62c.google.com X-Spam_score_int: -6 X-Spam_score: -0.7 X-Spam_bar: / X-Spam_report: (-0.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, PDS_HP_HELO_NORDNS=0.659, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , qemu-devel@nongnu.org, Akihiko Odaki , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" The following change would make it use add_console_menu_entries and addRemovableDevicesMenuItems so it should come after them. Signed-off-by: Akihiko Odaki --- ui/cocoa.m | 178 ++++++++++++++++++++++++++--------------------------- 1 file changed, 89 insertions(+), 89 deletions(-) diff --git a/ui/cocoa.m b/ui/cocoa.m index 8ab9ab5e84d..6c6e82afb90 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -1604,6 +1604,95 @@ - (void)sendEvent:(NSEvent *)event } @end +/* Returns a name for a given console */ +static NSString * getConsoleName(QemuConsole * console) +{ + g_autofree char *label = qemu_console_get_label(console); + + return [NSString stringWithUTF8String:label]; +} + +/* Add an entry to the View menu for each console */ +static void add_console_menu_entries(void) +{ + NSMenu *menu; + NSMenuItem *menuItem; + int index = 0; + + menu = [[[NSApp mainMenu] itemWithTitle:@"View"] submenu]; + + [menu addItem:[NSMenuItem separatorItem]]; + + while (qemu_console_lookup_by_index(index) != NULL) { + menuItem = [[[NSMenuItem alloc] initWithTitle: getConsoleName(qemu_console_lookup_by_index(index)) + action: @selector(displayConsole:) keyEquivalent: @""] autorelease]; + [menuItem setTag: index]; + [menu addItem: menuItem]; + index++; + } +} + +/* Make menu items for all removable devices. + * Each device is given an 'Eject' and 'Change' menu item. + */ +static void addRemovableDevicesMenuItems(void) +{ + NSMenu *menu; + NSMenuItem *menuItem; + BlockInfoList *currentDevice, *pointerToFree; + NSString *deviceName; + + currentDevice = qmp_query_block(NULL); + pointerToFree = currentDevice; + + menu = [[[NSApp mainMenu] itemWithTitle:@"Machine"] submenu]; + + // Add a separator between related groups of menu items + [menu addItem:[NSMenuItem separatorItem]]; + + // Set the attributes to the "Removable Media" menu item + NSString *titleString = @"Removable Media"; + NSMutableAttributedString *attString=[[NSMutableAttributedString alloc] initWithString:titleString]; + NSColor *newColor = [NSColor blackColor]; + NSFontManager *fontManager = [NSFontManager sharedFontManager]; + NSFont *font = [fontManager fontWithFamily:@"Helvetica" + traits:NSBoldFontMask|NSItalicFontMask + weight:0 + size:14]; + [attString addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, [titleString length])]; + [attString addAttribute:NSForegroundColorAttributeName value:newColor range:NSMakeRange(0, [titleString length])]; + [attString addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInt: 1] range:NSMakeRange(0, [titleString length])]; + + // Add the "Removable Media" menu item + menuItem = [NSMenuItem new]; + [menuItem setAttributedTitle: attString]; + [menuItem setEnabled: NO]; + [menu addItem: menuItem]; + + /* Loop through all the block devices in the emulator */ + while (currentDevice) { + deviceName = [[NSString stringWithFormat: @"%s", currentDevice->value->device] retain]; + + if(currentDevice->value->removable) { + menuItem = [[NSMenuItem alloc] initWithTitle: [NSString stringWithFormat: @"Change %s...", currentDevice->value->device] + action: @selector(changeDeviceMedia:) + keyEquivalent: @""]; + [menu addItem: menuItem]; + [menuItem setRepresentedObject: deviceName]; + [menuItem autorelease]; + + menuItem = [[NSMenuItem alloc] initWithTitle: [NSString stringWithFormat: @"Eject %s", currentDevice->value->device] + action: @selector(ejectDeviceMedia:) + keyEquivalent: @""]; + [menu addItem: menuItem]; + [menuItem setRepresentedObject: deviceName]; + [menuItem autorelease]; + } + currentDevice = currentDevice->next; + } + qapi_free_BlockInfoList(pointerToFree); +} + static void create_initial_menus(void) { // Add menus @@ -1695,95 +1784,6 @@ static void create_initial_menus(void) [[NSApp mainMenu] addItem:menuItem]; } -/* Returns a name for a given console */ -static NSString * getConsoleName(QemuConsole * console) -{ - g_autofree char *label = qemu_console_get_label(console); - - return [NSString stringWithUTF8String:label]; -} - -/* Add an entry to the View menu for each console */ -static void add_console_menu_entries(void) -{ - NSMenu *menu; - NSMenuItem *menuItem; - int index = 0; - - menu = [[[NSApp mainMenu] itemWithTitle:@"View"] submenu]; - - [menu addItem:[NSMenuItem separatorItem]]; - - while (qemu_console_lookup_by_index(index) != NULL) { - menuItem = [[[NSMenuItem alloc] initWithTitle: getConsoleName(qemu_console_lookup_by_index(index)) - action: @selector(displayConsole:) keyEquivalent: @""] autorelease]; - [menuItem setTag: index]; - [menu addItem: menuItem]; - index++; - } -} - -/* Make menu items for all removable devices. - * Each device is given an 'Eject' and 'Change' menu item. - */ -static void addRemovableDevicesMenuItems(void) -{ - NSMenu *menu; - NSMenuItem *menuItem; - BlockInfoList *currentDevice, *pointerToFree; - NSString *deviceName; - - currentDevice = qmp_query_block(NULL); - pointerToFree = currentDevice; - - menu = [[[NSApp mainMenu] itemWithTitle:@"Machine"] submenu]; - - // Add a separator between related groups of menu items - [menu addItem:[NSMenuItem separatorItem]]; - - // Set the attributes to the "Removable Media" menu item - NSString *titleString = @"Removable Media"; - NSMutableAttributedString *attString=[[NSMutableAttributedString alloc] initWithString:titleString]; - NSColor *newColor = [NSColor blackColor]; - NSFontManager *fontManager = [NSFontManager sharedFontManager]; - NSFont *font = [fontManager fontWithFamily:@"Helvetica" - traits:NSBoldFontMask|NSItalicFontMask - weight:0 - size:14]; - [attString addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, [titleString length])]; - [attString addAttribute:NSForegroundColorAttributeName value:newColor range:NSMakeRange(0, [titleString length])]; - [attString addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInt: 1] range:NSMakeRange(0, [titleString length])]; - - // Add the "Removable Media" menu item - menuItem = [NSMenuItem new]; - [menuItem setAttributedTitle: attString]; - [menuItem setEnabled: NO]; - [menu addItem: menuItem]; - - /* Loop through all the block devices in the emulator */ - while (currentDevice) { - deviceName = [[NSString stringWithFormat: @"%s", currentDevice->value->device] retain]; - - if(currentDevice->value->removable) { - menuItem = [[NSMenuItem alloc] initWithTitle: [NSString stringWithFormat: @"Change %s...", currentDevice->value->device] - action: @selector(changeDeviceMedia:) - keyEquivalent: @""]; - [menu addItem: menuItem]; - [menuItem setRepresentedObject: deviceName]; - [menuItem autorelease]; - - menuItem = [[NSMenuItem alloc] initWithTitle: [NSString stringWithFormat: @"Eject %s", currentDevice->value->device] - action: @selector(ejectDeviceMedia:) - keyEquivalent: @""]; - [menu addItem: menuItem]; - [menuItem setRepresentedObject: deviceName]; - [menuItem autorelease]; - } - currentDevice = currentDevice->next; - } - qapi_free_BlockInfoList(pointerToFree); -} - @interface QemuCocoaPasteboardTypeOwner : NSObject @end From patchwork Mon Mar 7 13:49:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Akihiko Odaki X-Patchwork-Id: 12771906 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9E8EDC433F5 for ; Mon, 7 Mar 2022 14:13:29 +0000 (UTC) Received: from localhost ([::1]:44908 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nRE76-0004GI-KU for qemu-devel@archiver.kernel.org; Mon, 07 Mar 2022 09:13:28 -0500 Received: from eggs.gnu.org ([209.51.188.92]:60130) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nRDkP-000475-MW for qemu-devel@nongnu.org; Mon, 07 Mar 2022 08:50:03 -0500 Received: from [2607:f8b0:4864:20::102f] (port=35743 helo=mail-pj1-x102f.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1nRDkN-0007jp-Oj for qemu-devel@nongnu.org; Mon, 07 Mar 2022 08:50:01 -0500 Received: by mail-pj1-x102f.google.com with SMTP id mg21-20020a17090b371500b001bef9e4657cso13338456pjb.0 for ; Mon, 07 Mar 2022 05:49:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=fC0I4u+vWOgSM0UukBH5UPvzAJhk5E76i7ScCIK/+pg=; b=md4xgTeD1jEr1TG/kNETuRmmtWA3/HjW8WwvQnP6M9kpdNF5I0pMCOFcaHRxFa3IFH ZumafnZ0B9NbtWsnhRXLznNkWh3sDBwwFja0+vwgVUbUq3j6yt18j8WS9Iz8OzVumVHR ghejrulp+Z6xikALtPl/zhLqcnIV063mkxjNzFvVSpflzXl6BJ+9lQNp0Uc4FPKSgRSk wqccv4knbQyOmM2lzqJiW8u4IEZzfLeXuy10R0mj4oYiVymZ5DcYwA26QZ33m/cui/Lp Cmq23akqlDRuzBWKeR3RSWy+4QyiDx6vNvRRug3JQ4Msh4p9OfccFHVh1tf/49iX3hP3 L6zQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=fC0I4u+vWOgSM0UukBH5UPvzAJhk5E76i7ScCIK/+pg=; b=zMkrYQ/JrhN83sjbHtKagbUV5e7i+oT1EmbLizU/hZyk3cc4wTnKuXfcW+3Q9Ax9/Q hRy4IwUngv0O8TuBEQeJMhK8rwGFU2wsDsuc7GXhqCQ4UTPgQ09JXqoUFonds4kWHjNZ G8+RLhBRzEQe6NPCfPKJF1Qm0lGFgUXLReNMxINgRmmQYAb3rC7uGkWAw0p03xXfxiw2 rBPsGUT4ovWo7hwwAty3SGFsJ+wyHnJYot/9FN6j3JZTvTI55k8pna9Fgf1LamIRaj6n YSBtB12kQcAV2KpErmvdArH4vHS6KocUyOl7pamGr2WkSnZs0yeKPgDnonXHd8AX0AhG rGvw== X-Gm-Message-State: AOAM532pMBm6Hv2dmnUYUGohlNntyAI0Czo3iHnuUMbDKjI62G2BRkfw PZkyMcXTD+ItcQOqPiKr//GeH7+htIQ= X-Google-Smtp-Source: ABdhPJyjM0hbsxm54w+0wGMSPjdF88jcUSo+Yy7DFZHpMbbMnGlAO8E3AvqNl6TQU5Hu8aVDsIuDbQ== X-Received: by 2002:a17:902:d485:b0:151:f798:c8da with SMTP id c5-20020a170902d48500b00151f798c8damr1029743plg.108.1646660998199; Mon, 07 Mar 2022 05:49:58 -0800 (PST) Received: from localhost.localdomain ([2400:4050:c360:8200:9058:25bf:2793:c7c7]) by smtp.gmail.com with ESMTPSA id o15-20020a17090a168f00b001bf66741097sm3622387pja.16.2022.03.07.05.49.56 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Mon, 07 Mar 2022 05:49:57 -0800 (PST) From: Akihiko Odaki To: Subject: [PATCH v2 2/2] ui/cocoa: Create menus in iothread Date: Mon, 7 Mar 2022 22:49:46 +0900 Message-Id: <20220307134946.61407-3-akihiko.odaki@gmail.com> X-Mailer: git-send-email 2.32.0 (Apple Git-132) In-Reply-To: <20220307134946.61407-1-akihiko.odaki@gmail.com> References: <20220307134946.61407-1-akihiko.odaki@gmail.com> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::102f (failed) Received-SPF: pass client-ip=2607:f8b0:4864:20::102f; envelope-from=akihiko.odaki@gmail.com; helo=mail-pj1-x102f.google.com X-Spam_score_int: -6 X-Spam_score: -0.7 X-Spam_bar: / X-Spam_report: (-0.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, PDS_HP_HELO_NORDNS=0.659, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , qemu-devel@nongnu.org, Akihiko Odaki , Gerd Hoffmann Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Commit 0439c5a4623d674efa0c72abd62ca6e98bb7cf87 introduced an assertion that blk_all_next is called in the main thread. The function is called in the following chain: - blk_all_next - qmp_query_block - addRemovableDevicesMenuItems - main This change moves the menu creation to the iothread. This also changes the menu creation procedure to construct the entire menu tree before setting to NSApp, which is necessary because a menu set once cannot be modified if NSApp is already running. Signed-off-by: Akihiko Odaki --- ui/cocoa.m | 59 +++++++++++++++++++++--------------------------------- 1 file changed, 23 insertions(+), 36 deletions(-) diff --git a/ui/cocoa.m b/ui/cocoa.m index 6c6e82afb90..edacbef9f7a 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -1613,14 +1613,11 @@ - (void)sendEvent:(NSEvent *)event } /* Add an entry to the View menu for each console */ -static void add_console_menu_entries(void) +static void add_console_menu_entries(NSMenu *menu) { - NSMenu *menu; NSMenuItem *menuItem; int index = 0; - menu = [[[NSApp mainMenu] itemWithTitle:@"View"] submenu]; - [menu addItem:[NSMenuItem separatorItem]]; while (qemu_console_lookup_by_index(index) != NULL) { @@ -1635,9 +1632,8 @@ static void add_console_menu_entries(void) /* Make menu items for all removable devices. * Each device is given an 'Eject' and 'Change' menu item. */ -static void addRemovableDevicesMenuItems(void) +static void addRemovableDevicesMenuItems(NSMenu *menu) { - NSMenu *menu; NSMenuItem *menuItem; BlockInfoList *currentDevice, *pointerToFree; NSString *deviceName; @@ -1645,8 +1641,6 @@ static void addRemovableDevicesMenuItems(void) currentDevice = qmp_query_block(NULL); pointerToFree = currentDevice; - menu = [[[NSApp mainMenu] itemWithTitle:@"Machine"] submenu]; - // Add a separator between related groups of menu items [menu addItem:[NSMenuItem separatorItem]]; @@ -1693,17 +1687,19 @@ static void addRemovableDevicesMenuItems(void) qapi_free_BlockInfoList(pointerToFree); } -static void create_initial_menus(void) +static void create_menus(void) { // Add menus + NSString *title = [[[NSBundle mainBundle] executablePath] lastPathComponent]; + NSMenu *mainMenu; NSMenu *menu; NSMenuItem *menuItem; - [NSApp setMainMenu:[[NSMenu alloc] init]]; + mainMenu = [[NSMenu alloc] initWithTitle:@"Main Menu"]; [NSApp setServicesMenu:[[NSMenu alloc] initWithTitle:@"Services"]]; // Application menu - menu = [[NSMenu alloc] initWithTitle:@""]; + menu = [[NSMenu alloc] initWithTitle:title]; [menu addItemWithTitle:@"About QEMU" action:@selector(do_about_menu_item:) keyEquivalent:@""]; // About QEMU [menu addItem:[NSMenuItem separatorItem]]; //Separator menuItem = [menu addItemWithTitle:@"Services" action:nil keyEquivalent:@""]; @@ -1715,10 +1711,8 @@ static void create_initial_menus(void) [menu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; // Show All [menu addItem:[NSMenuItem separatorItem]]; //Separator [menu addItemWithTitle:@"Quit QEMU" action:@selector(terminate:) keyEquivalent:@"q"]; - menuItem = [[NSMenuItem alloc] initWithTitle:@"Apple" action:nil keyEquivalent:@""]; + menuItem = [mainMenu addItemWithTitle:title action:nil keyEquivalent:@""]; [menuItem setSubmenu:menu]; - [[NSApp mainMenu] addItem:menuItem]; - [NSApp performSelector:@selector(setAppleMenu:) withObject:menu]; // Workaround (this method is private since 10.4+) // Machine menu menu = [[NSMenu alloc] initWithTitle: @"Machine"]; @@ -1730,17 +1724,17 @@ static void create_initial_menus(void) [menu addItem: [NSMenuItem separatorItem]]; [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Reset" action: @selector(restartQEMU:) keyEquivalent: @""] autorelease]]; [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Power Down" action: @selector(powerDownQEMU:) keyEquivalent: @""] autorelease]]; - menuItem = [[[NSMenuItem alloc] initWithTitle: @"Machine" action:nil keyEquivalent:@""] autorelease]; + addRemovableDevicesMenuItems(menu); + menuItem = [mainMenu addItemWithTitle: @"Machine" action:nil keyEquivalent:@""]; [menuItem setSubmenu:menu]; - [[NSApp mainMenu] addItem:menuItem]; // View menu menu = [[NSMenu alloc] initWithTitle:@"View"]; [menu addItem: [[[NSMenuItem alloc] initWithTitle:@"Enter Fullscreen" action:@selector(doToggleFullScreen:) keyEquivalent:@"f"] autorelease]]; // Fullscreen [menu addItem: [[[NSMenuItem alloc] initWithTitle:@"Zoom To Fit" action:@selector(zoomToFit:) keyEquivalent:@""] autorelease]]; - menuItem = [[[NSMenuItem alloc] initWithTitle:@"View" action:nil keyEquivalent:@""] autorelease]; + add_console_menu_entries(menu); + menuItem = [mainMenu addItemWithTitle:@"View" action:nil keyEquivalent:@""]; [menuItem setSubmenu:menu]; - [[NSApp mainMenu] addItem:menuItem]; // Speed menu menu = [[NSMenu alloc] initWithTitle:@"Speed"]; @@ -1764,24 +1758,23 @@ static void create_initial_menus(void) [menuItem setTag: throttle_pct]; [menu addItem: menuItem]; } - menuItem = [[[NSMenuItem alloc] initWithTitle:@"Speed" action:nil keyEquivalent:@""] autorelease]; + menuItem = [mainMenu addItemWithTitle:@"Speed" action:nil keyEquivalent:@""]; [menuItem setSubmenu:menu]; - [[NSApp mainMenu] addItem:menuItem]; // Window menu menu = [[NSMenu alloc] initWithTitle:@"Window"]; [menu addItem: [[[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"] autorelease]]; // Miniaturize - menuItem = [[[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""] autorelease]; + menuItem = [mainMenu addItemWithTitle:@"Window" action:nil keyEquivalent:@""]; [menuItem setSubmenu:menu]; - [[NSApp mainMenu] addItem:menuItem]; [NSApp setWindowsMenu:menu]; // Help menu menu = [[NSMenu alloc] initWithTitle:@"Help"]; [menu addItem: [[[NSMenuItem alloc] initWithTitle:@"QEMU Documentation" action:@selector(showQEMUDoc:) keyEquivalent:@"?"] autorelease]]; // QEMU Help - menuItem = [[[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""] autorelease]; + menuItem = [mainMenu addItemWithTitle:@"Window" action:nil keyEquivalent:@""]; [menuItem setSubmenu:menu]; - [[NSApp mainMenu] addItem:menuItem]; + + [NSApp setMainMenu:mainMenu]; } @interface QemuCocoaPasteboardTypeOwner : NSObject @@ -1947,18 +1940,6 @@ int main (int argc, char **argv) { [QemuApplication sharedApplication]; - create_initial_menus(); - - /* - * Create the menu entries which depend on QEMU state (for consoles - * and removeable devices). These make calls back into QEMU functions, - * which is OK because at this point we know that the second thread - * holds the iothread lock and is synchronously waiting for us to - * finish. - */ - add_console_menu_entries(); - addRemovableDevicesMenuItems(); - // Create an Application controller QemuCocoaAppController *appController = [[QemuCocoaAppController alloc] init]; [NSApp setDelegate:appController]; @@ -2050,6 +2031,8 @@ static void cocoa_refresh(DisplayChangeListener *dcl) static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + COCOA_DEBUG("qemu_cocoa: cocoa_display_init\n"); /* Tell main thread to go ahead and create the app and enter the run loop */ @@ -2057,6 +2040,8 @@ static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts) qemu_sem_wait(&app_started_sem); COCOA_DEBUG("cocoa_display_init: app start completed\n"); + create_menus(); + /* if fullscreen mode is to be used */ if (opts->has_full_screen && opts->full_screen) { dispatch_async(dispatch_get_main_queue(), ^{ @@ -2074,6 +2059,8 @@ static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts) qemu_event_init(&cbevent, false); cbowner = [[QemuCocoaPasteboardTypeOwner alloc] init]; qemu_clipboard_peer_register(&cbpeer); + + [pool release]; } static QemuDisplay qemu_display_cocoa = {