From e9d0a9798f58c9502f224f7d05364b647bb570d7 Mon Sep 17 00:00:00 2001 From: David Capello Date: Mon, 2 Oct 2017 19:31:16 -0300 Subject: [PATCH] Fix macOS issue: NSSavePanel is still open/visible after it's used If we use the [NSSavePanel savePanel] singleton, after the file is selected, we can Cmd+Tab to switch to another app and go back to our app and the NSSavePanel will be visible again. With this patch we ensure 1) we create our own panel, and 2) after selecting the filename, the panel is destroyed/freed (so it will not be shown again when we switch between apps). --- src/she/osx/native_dialogs.mm | 86 ++++++++++++++++------------------- 1 file changed, 40 insertions(+), 46 deletions(-) diff --git a/src/she/osx/native_dialogs.mm b/src/she/osx/native_dialogs.mm index 2733238eb..e6ba2dafb 100644 --- a/src/she/osx/native_dialogs.mm +++ b/src/she/osx/native_dialogs.mm @@ -130,63 +130,57 @@ public: } bool show(Display* display) override { - NSSavePanel* panel = nil; + bool retValue = false; + @autoreleasepool { + NSSavePanel* panel = nil; - if (m_save) { - panel = [NSSavePanel savePanel]; - } - else { - panel = [NSOpenPanel openPanel]; - [(NSOpenPanel*)panel setAllowsMultipleSelection:(m_multipleSelection ? YES: NO)]; - [(NSOpenPanel*)panel setCanChooseDirectories:NO]; - } + if (m_save) { + panel = [NSSavePanel new]; + } + else { + panel = [NSOpenPanel new]; + [(NSOpenPanel*)panel setAllowsMultipleSelection:(m_multipleSelection ? YES: NO)]; + [(NSOpenPanel*)panel setCanChooseDirectories:NO]; + } - [panel setTitle:[NSString stringWithUTF8String:m_title.c_str()]]; - [panel setCanCreateDirectories:YES]; + [panel setTitle:[NSString stringWithUTF8String:m_title.c_str()]]; + [panel setCanCreateDirectories:YES]; - std::string defPath = base::get_file_path(m_filename); - std::string defName = base::get_file_name(m_filename); - if (!defPath.empty()) - [panel setDirectoryURL:[NSURL fileURLWithPath:[NSString stringWithUTF8String:defPath.c_str()]]]; - if (!defName.empty()) - [panel setNameFieldStringValue:[NSString stringWithUTF8String:defName.c_str()]]; + std::string defPath = base::get_file_path(m_filename); + std::string defName = base::get_file_name(m_filename); + if (!defPath.empty()) + [panel setDirectoryURL:[NSURL fileURLWithPath:[NSString stringWithUTF8String:defPath.c_str()]]]; + if (!defName.empty()) + [panel setNameFieldStringValue:[NSString stringWithUTF8String:defName.c_str()]]; - NSMutableArray* types = [[NSMutableArray alloc] init]; - // The first extension in the array is used as the default one. - if (!m_defExtension.empty()) - [types addObject:[NSString stringWithUTF8String:m_defExtension.c_str()]]; - for (const auto& filter : m_filters) - [types addObject:[NSString stringWithUTF8String:filter.second.c_str()]]; - [panel setAllowedFileTypes:types]; + NSMutableArray* types = [[NSMutableArray alloc] init]; + // The first extension in the array is used as the default one. + if (!m_defExtension.empty()) + [types addObject:[NSString stringWithUTF8String:m_defExtension.c_str()]]; + for (const auto& filter : m_filters) + [types addObject:[NSString stringWithUTF8String:filter.second.c_str()]]; + [panel setAllowedFileTypes:types]; - OpenSaveHelper* helper = [[OpenSaveHelper alloc] init]; - [helper setPanel:panel]; - [helper setDisplay:display]; - [helper performSelectorOnMainThread:@selector(runModal) withObject:nil waitUntilDone:YES]; + OpenSaveHelper* helper = [OpenSaveHelper new]; + [helper setPanel:panel]; + [helper setDisplay:display]; + [helper performSelectorOnMainThread:@selector(runModal) withObject:nil waitUntilDone:YES]; - bool retValue; - if ([helper result] == NSFileHandlingPanelOKButton) { - if (m_multipleSelection) { - for (NSURL* url in [(NSOpenPanel*)panel URLs]) { + if ([helper result] == NSFileHandlingPanelOKButton) { + if (m_multipleSelection) { + for (NSURL* url in [(NSOpenPanel*)panel URLs]) { + m_filename = [[url path] UTF8String]; + m_filenames.push_back(m_filename); + } + } + else { + NSURL* url = [panel URL]; m_filename = [[url path] UTF8String]; m_filenames.push_back(m_filename); } + retValue = true; } - else { - NSURL* url = [panel URL]; - m_filename = [[url path] UTF8String]; - m_filenames.push_back(m_filename); - } - retValue = true; } - else { - retValue = false; - } - -#if !__has_feature(objc_arc) - [helper release]; - [types release]; -#endif return retValue; }