From 8cee7f2b186044d7a38a184d7539a1b457398a65 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Wed, 25 May 2022 18:51:46 -0500 Subject: [PATCH 1/4] Issue #1905 - Part 1 - Implement detection of Monterey (12.x), Intel emulation and fix required OS version check. --- toolkit/xre/nsNativeAppSupportCocoa.mm | 2 +- widget/cocoa/nsCocoaFeatures.h | 3 ++ widget/cocoa/nsCocoaFeatures.mm | 43 ++++++++++++++++++++++++-- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/toolkit/xre/nsNativeAppSupportCocoa.mm b/toolkit/xre/nsNativeAppSupportCocoa.mm index 6da6790c15..3f292ec743 100644 --- a/toolkit/xre/nsNativeAppSupportCocoa.mm +++ b/toolkit/xre/nsNativeAppSupportCocoa.mm @@ -89,7 +89,7 @@ NS_IMETHODIMP nsNativeAppSupportCocoa::Start(bool *_retval) // alert here. But the alert's message and buttons would require custom // localization. So (for now at least) we just log an English message // to the console before quitting. - if (major < 10 || minor < 6) { + if (major < 10 || (major == 10 && minor < 7)) { NSLog(@"Minimum OS version requirement not met!"); return NS_OK; } diff --git a/widget/cocoa/nsCocoaFeatures.h b/widget/cocoa/nsCocoaFeatures.h index a9cab95d56..c6841a7491 100644 --- a/widget/cocoa/nsCocoaFeatures.h +++ b/widget/cocoa/nsCocoaFeatures.h @@ -25,9 +25,12 @@ public: static bool OnMojaveOrLater(); static bool OnCatalinaOrLater(); static bool OnBigSurOrLater(); + static bool OnMontereyOrLater(); static bool IsAtLeastVersion(int32_t aMajor, int32_t aMinor, int32_t aBugFix=0); + static bool ProcessIsRosettaTranslated(); + // These are utilities that do not change or depend on the value of mOSXVersion // and instead just encapsulate the encoding algorithm. Note that GetVersion // actually adjusts to the lowest supported OS, so it will always return diff --git a/widget/cocoa/nsCocoaFeatures.mm b/widget/cocoa/nsCocoaFeatures.mm index e0fafb7d96..2edb958931 100644 --- a/widget/cocoa/nsCocoaFeatures.mm +++ b/widget/cocoa/nsCocoaFeatures.mm @@ -26,6 +26,7 @@ #define MACOS_VERSION_10_15_HEX 0x000A0F00 #define MACOS_VERSION_10_16_HEX 0x000A1000 #define MACOS_VERSION_11_0_HEX 0x000B0000 +#define MACOS_VERSION_12_0_HEX 0x000C0000 #include "nsCocoaFeatures.h" #include "nsCocoaUtils.h" @@ -33,6 +34,7 @@ #include "nsObjCExceptions.h" #import +#include int32_t nsCocoaFeatures::mOSVersion = 0; @@ -196,14 +198,51 @@ nsCocoaFeatures::OnCatalinaOrLater() /* static */ bool nsCocoaFeatures::OnBigSurOrLater() { - // Account for the version being 10.16 (which occurs when the - // application is linked with an older SDK) or 11.0 on Big Sur. + // Account for the version being 10.16 or 11.0 on Big Sur. + // The version is reported as 10.16 if SYSTEM_VERSION_COMPAT is set to 1, + // or if SYSTEM_VERSION_COMPAT is not set and the application is linked + // with a pre-Big Sur SDK. + // We should set SYSTEM_VERSION_COMPAT to 0 in its Info.plist, so it'll + // usually see the correct 11.* version, despite being linked against an + // old SDK. However, it still sees the 10.16 compatibility version when + // launched from the command line, see bug 1727624. (This only applies to + // the Intel build - the arm64 build is linked against a Big Sur SDK and + // always sees the correct version.) return ((macOSVersion() >= MACOS_VERSION_10_16_HEX) || (macOSVersion() >= MACOS_VERSION_11_0_HEX)); } +/* static */ bool nsCocoaFeatures::OnMontereyOrLater() +{ + // Monterey pretends to be 10.16 and is indistinguishable from Big Sur. + // In practice, this means that an Intel build can return false + // from this function if it's launched from the command line, see bug 1727624. + // This will not be an issue anymore once we link against the Big Sur SDK. + return (macOSVersion() >= MACOS_VERSION_12_0_HEX); +} + /* static */ bool nsCocoaFeatures::IsAtLeastVersion(int32_t aMajor, int32_t aMinor, int32_t aBugFix) { return macOSVersion() >= GetVersion(aMajor, aMinor, aBugFix); } + +/* + * Returns true if the process is running under Rosetta translation. Returns + * false if running natively or if an error was encountered. We use the + * `sysctl.proc_translated` sysctl which is documented by Apple to be used + * for this purpose. Note: using this in a sandboxed process requires allowing + * the sysctl in the sandbox policy. + */ +/* static */ bool nsCocoaFeatures::ProcessIsRosettaTranslated() +{ + int ret = 0; + size_t size = sizeof(ret); + if (sysctlbyname("sysctl.proc_translated", &ret, &size, NULL, 0) == -1) { + if (errno != ENOENT) { + fprintf(stderr, "Failed to check for translation environment\n"); + } + return false; + } + return (ret == 1); +} From 45606ffa5981afa0f99c0a5f5320b1ded4a94826 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Thu, 2 Jun 2022 15:56:05 -0500 Subject: [PATCH 2/4] Issue #1905 - Part 2a - Build system fixes to allow use of SDK versioned 11.0 and higher. Also don't include code incompatible with SDK 10.15 and higher, when building with such a SDK. --- media/webrtc/trunk/build/mac/find_sdk.py | 2 +- media/webrtc/trunk/build/mac/find_sdk_uxp.py | 9 +++++---- widget/cocoa/nsChildView.mm | 3 +++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/media/webrtc/trunk/build/mac/find_sdk.py b/media/webrtc/trunk/build/mac/find_sdk.py index ca58284eac..c26c3763c9 100644 --- a/media/webrtc/trunk/build/mac/find_sdk.py +++ b/media/webrtc/trunk/build/mac/find_sdk.py @@ -52,7 +52,7 @@ def main(): sdk_dir = xcode43_sdk_path else: sdk_dir = os.path.join(out.rstrip(), 'SDKs') - sdks = [re.findall('^MacOSX(10\.\d+)\.sdk$', s) for s in os.listdir(sdk_dir)] + sdks = [re.findall('^MacOSX(\d+\.\d+)\.sdk$', s) for s in os.listdir(sdk_dir)] sdks = [s[0] for s in sdks if s] # [['10.5'], ['10.6']] => ['10.5', '10.6'] sdks = [s for s in sdks # ['10.5', '10.6'] => ['10.6'] if parse_version(s) >= parse_version(min_sdk_version)] diff --git a/media/webrtc/trunk/build/mac/find_sdk_uxp.py b/media/webrtc/trunk/build/mac/find_sdk_uxp.py index 3c419f1e45..a68e165f1a 100644 --- a/media/webrtc/trunk/build/mac/find_sdk_uxp.py +++ b/media/webrtc/trunk/build/mac/find_sdk_uxp.py @@ -19,11 +19,12 @@ if sys.platform == 'darwin': print("find_sdk_uxp.py: error: Specified path does not exist or is not a directory") sys.exit(1) - KNOWN_SDK_VERSIONS = ["10.7", "10.8", "10.9", "10.10", - "10.11", "10.12", "10.13", "10.14", - "10.15"] + KNOWN_SDK_VERSIONS = ["10.7", "10.8", "10.9", "10.10", "10.11" + "10.12", "10.13", "10.14", "10.15", "10.16", + "11.0", "11.1", "11.2", "11.3", + "12.0"] - REGEX = "^MacOSX(10\.\d+)\.sdk$" + REGEX = "^MacOSX(\d+\.\d+)\.sdk$" SDK_VERSION = re.findall(REGEX, os.path.basename(SDK_PATH)) if not SDK_VERSION: diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index 868687fe16..e2aa6729e9 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -209,6 +209,8 @@ uint32_t nsChildView::sLastInputEventCount = 0; + (BOOL)_shouldZoomOnDoubleClick; // present on 10.7 and above @end +// This is only possible with SDKs below 10.15 +#ifndef MAC_OS_X_VERSION_10_15 // Starting with 10.7 the bottom corners of all windows are rounded. // Unfortunately, the standard rounding that OS X applies to OpenGL views // does not use anti-aliasing and looks very crude. Since we want a smooth, @@ -226,6 +228,7 @@ uint32_t nsChildView::sLastInputEventCount = 0; return region; } @end +#endif #pragma mark - From d18524ab7e54ca535b850cfea1c787e339278e2b Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Fri, 3 Jun 2022 05:56:46 -0500 Subject: [PATCH 3/4] Issue #1905 - Part 2b - Fix crash on startup due to inability to load system font with newer SDKs. Fix based on Mozilla Bug 1672842. --- gfx/thebes/gfxMacPlatformFontList.mm | 90 ++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 4 deletions(-) diff --git a/gfx/thebes/gfxMacPlatformFontList.mm b/gfx/thebes/gfxMacPlatformFontList.mm index 4536ab527b..55263e7e6b 100644 --- a/gfx/thebes/gfxMacPlatformFontList.mm +++ b/gfx/thebes/gfxMacPlatformFontList.mm @@ -849,11 +849,60 @@ gfxMacPlatformFontList::InitSingleFaceList() static NSString* GetRealFamilyName(NSFont* aFont) { + if(nsCocoaFeatures::OnCatalinaOrLater()) + { + NSString* psName = [[aFont fontDescriptor] postscriptName]; + // With newer macOS versions and SDKs (e.g. when compiled against SDK 10.15), + // [NSFont fontWithName:] fails for hidden system fonts, because the underlying + // Core Text functions it uses reject such names and tell us to use the special + // CTFontCreateUIFontForLanguage API instead. + // To work around this, as we don't yet work directly with the CTFontUIFontType + // identifiers, we create a Core Graphics font (as it doesn't reject system font + // names), and use this to create a Core Text font that we can query for the + // family name. + // Eventually we should move to using CTFontUIFontType constants to identify + // system fonts, and eliminate the need to instantiate them (indirectly) from + // their postscript names. + CGFontRef cgFont = CGFontCreateWithFontName(CFStringRef(psName)); + if (!cgFont) { + return [aFont familyName]; + } + + CTFontRef ctFont = CTFontCreateWithGraphicsFont(cgFont, 0.0, nullptr, nullptr); + if (!ctFont) { + CFRelease(cgFont); + return [aFont familyName]; + } + NSString* familyName = (NSString*)CTFontCopyFamilyName(ctFont); + + CFRelease(cgFont); + CFRelease(ctFont); + return [familyName autorelease]; + } NSFont* f = [NSFont fontWithName: [[aFont fontDescriptor] postscriptName] size: 0.0]; return [f familyName]; } +// Create a gfxFontFamily that corresponds to the "system" font name, +// and populate it with the given font face. We only use this on Catalina or later, +// so we expect the system font to be a variable-weight face rather than requiring +// a number of discrete faces of different weights. +static gfxFontFamily* CreateFamilyForSystemFont(NSFont* aFont, const nsString& aFamilyName) { + gfxFontFamily* familyEntry = new gfxFontFamily(aFamilyName); + + NSString* psNameNS = [[aFont fontDescriptor] postscriptName]; + nsAutoString psName; + nsCocoaUtils::GetStringForNSString(psNameNS, psName); + + MacOSFontEntry* fe = new MacOSFontEntry(psName, 400.0, true, 0.0); + + familyEntry->AddFontEntry(fe); + familyEntry->SetHasStyles(true); + + return familyEntry; +} + // System fonts under OSX 10.11 use a combination of two families, one // for text sizes and another for larger, display sizes. Each has a // different number of weights. There aren't efficient API's for looking @@ -867,7 +916,9 @@ gfxMacPlatformFontList::InitSystemFontNames() { // system font under 10.11 are two distinct families for text/display sizes if (nsCocoaFeatures::OnElCapitanOrLater()) { - mUseSizeSensitiveSystemFont = true; + // On Catalina+, the system font uses optical sizing rather than individual + // faces, so we don't need to look for a separate display-sized face. + mUseSizeSensitiveSystemFont = !nsCocoaFeatures::OnCatalinaOrLater(); } // text font family @@ -877,12 +928,28 @@ gfxMacPlatformFontList::InitSystemFontNames() nsCocoaUtils::GetStringForNSString(textFamilyName, familyName); mSystemTextFontFamilyName = familyName; - // display font family, if on OSX 10.11 + // On Catalina or later, we store an in-process gfxFontFamily for the system font + // even if using the shared fontlist to manage "normal" fonts, because the hidden + // system fonts may be excluded from the font list altogether. + if (nsCocoaFeatures::OnCatalinaOrLater()) { + RefPtr fam = CreateFamilyForSystemFont(sys, mSystemTextFontFamilyName); + if (fam) { + nsAutoString key; + GenerateFontListKey(mSystemTextFontFamilyName, key); + mFontFamilies.Put(key, fam); + } + } + + // display font family, if on OSX 10.11 - 10.14 if (mUseSizeSensitiveSystemFont) { NSFont* displaySys = [NSFont systemFontOfSize: 128.0]; NSString* displayFamilyName = GetRealFamilyName(displaySys); + if ([displayFamilyName isEqualToString: textFamilyName]) { + mUseSizeSensitiveSystemFont = false; + } else { nsCocoaUtils::GetStringForNSString(displayFamilyName, familyName); mSystemDisplayFontFamilyName = familyName; + } #if DEBUG // confirm that the optical size switch is at 20.0 @@ -993,7 +1060,6 @@ gfxMacPlatformFontList::PlatformGlobalFontFallback(const uint32_t aCh, gfxFontEntry *fontEntry = nullptr; CTFontRef fallback; - bool cantUseFallbackFont = false; if (!mDefaultFont) { mDefaultFont = ::CTFontCreateWithName(CFSTR("LucidaGrande"), 12.f, @@ -1029,10 +1095,26 @@ gfxMacPlatformFontList::PlatformGlobalFontFallback(const uint32_t aCh, *aMatchedFamily = family; } else { fontEntry = nullptr; - cantUseFallbackFont = true; } } } + + // The macOS system font does not appear in the shared font list, so if + // we didn't find the fallback font above, we should also check for an + // unshared fontFamily in the system list. + if (!fontEntry) { + gfxFontFamily* family = FindSystemFontFamily(familyNameString); + if (family) { + fontEntry = family->FindFontForStyle(*aMatchStyle, needsBold); + if (fontEntry) { + if (fontEntry->HasCharacter(aCh)) { + *aMatchedFamily = family; + } else { + fontEntry = nullptr; + } + } + } + } } if (familyNameRef) { From 6182744d96bbb5587c13bf23bcb4713c9cd0129b Mon Sep 17 00:00:00 2001 From: Jeremy Andrews Date: Wed, 1 Jun 2022 19:32:33 -0500 Subject: [PATCH 4/4] [MailNews] Allow shift-clicking on Edit As New to edit a message as plaintext. Ref: BZ 731688 --- .../compose/public/nsIMsgComposeParams.idl | 6 + mailnews/compose/src/nsMsgCompose.cpp | 4 +- mailnews/compose/src/nsMsgComposeService.cpp | 12 +- mailnews/mime/src/mimedrft.cpp | 122 ++++++++++++++---- 4 files changed, 115 insertions(+), 29 deletions(-) diff --git a/mailnews/compose/public/nsIMsgComposeParams.idl b/mailnews/compose/public/nsIMsgComposeParams.idl index 87c15eac37..bed6fb4dbf 100644 --- a/mailnews/compose/public/nsIMsgComposeParams.idl +++ b/mailnews/compose/public/nsIMsgComposeParams.idl @@ -39,6 +39,12 @@ interface nsIMsgCompType { */ const long Redirect = 14; + /** + * Used to compose a new message from an existing message. Links + * are sanitized since the message could be from external sources. + */ + const long EditAsNew = 15; + /** * Add this value to a reply type to suppress quoting the current selection * which may not belong to the message being replied to. diff --git a/mailnews/compose/src/nsMsgCompose.cpp b/mailnews/compose/src/nsMsgCompose.cpp index a7c2140ad7..040d9a4f0d 100644 --- a/mailnews/compose/src/nsMsgCompose.cpp +++ b/mailnews/compose/src/nsMsgCompose.cpp @@ -1070,7 +1070,8 @@ nsMsgCompose::Initialize(nsIMsgComposeParams *aParams, // by checking the identity prefs - but don't clobber the values for // drafts and templates as they were set up already by mime when // initializing the message. - if (m_identity && draftId.IsEmpty() && type != nsIMsgCompType::Template) + if (m_identity && draftId.IsEmpty() && type != nsIMsgCompType::Template + && type != nsIMsgCompType::EditAsNew) { bool requestReturnReceipt = false; rv = m_identity->GetRequestReturnReceipt(&requestReturnReceipt); @@ -4766,6 +4767,7 @@ nsMsgCompose::BuildBodyMessageAndSignature() case nsIMsgCompType::Draft : case nsIMsgCompType::Template : case nsIMsgCompType::Redirect : + case nsIMsgCompType::EditAsNew : addSignature = false; break; diff --git a/mailnews/compose/src/nsMsgComposeService.cpp b/mailnews/compose/src/nsMsgComposeService.cpp index bec88f8fe3..dfd2d75b61 100644 --- a/mailnews/compose/src/nsMsgComposeService.cpp +++ b/mailnews/compose/src/nsMsgComposeService.cpp @@ -387,14 +387,22 @@ nsMsgComposeService::OpenComposeWindow(const char *msgComposeWindowURL, nsIMsgDB /* Actually, the only way to implement forward inline is to simulate a template message. Maybe one day when we will have more time we can change that */ - if (type == nsIMsgCompType::ForwardInline || type == nsIMsgCompType::Draft || type == nsIMsgCompType::Template - || type == nsIMsgCompType::ReplyWithTemplate || type == nsIMsgCompType::Redirect) + if (type == nsIMsgCompType::ForwardInline || type == nsIMsgCompType::Draft || + type == nsIMsgCompType::Template || + type == nsIMsgCompType::ReplyWithTemplate || + type == nsIMsgCompType::Redirect || + type == nsIMsgCompType::EditAsNew) { nsAutoCString uriToOpen(originalMsgURI); uriToOpen += (uriToOpen.FindChar('?') == kNotFound) ? '?' : '&'; uriToOpen.Append("fetchCompleteMessage=true"); + // The compose type that gets transmitted to a compose window open in mime + // is communicated using url query parameters here. + if (type == nsIMsgCompType::Redirect) uriToOpen.Append("&redirect=true"); + else if (type == nsIMsgCompType::EditAsNew) + uriToOpen.Append("&editasnew=true"); return LoadDraftOrTemplate(uriToOpen, type == nsIMsgCompType::ForwardInline || type == nsIMsgCompType::Draft ? nsMimeOutput::nsMimeMessageDraftOrTemplate : nsMimeOutput::nsMimeMessageEditorTemplate, diff --git a/mailnews/mime/src/mimedrft.cpp b/mailnews/mime/src/mimedrft.cpp index 90ca027d8b..06f8ea8d36 100644 --- a/mailnews/mime/src/mimedrft.cpp +++ b/mailnews/mime/src/mimedrft.cpp @@ -1087,6 +1087,33 @@ mime_insert_forwarded_message_headers(char **body, } } +static void +convert_plaintext_body_to_html(char **body, uint32_t bodyLen) +{ + // We need to convert the plain/text to HTML in order to escape any HTML markup + char *escapedBody = MsgEscapeHTML(*body); + if (escapedBody) + { + PR_Free(*body); + *body = escapedBody; + bodyLen = strlen(*body); + } + + // +13 chars for
 & 
tags and CRLF + uint32_t newbodylen = bodyLen + 14; + char* newbody = (char *)PR_MALLOC (newbodylen); + if (newbody) + { + *newbody = 0; + PL_strcatn(newbody, newbodylen, "
");
+    PL_strcatn(newbody, newbodylen, *body);
+    PL_strcatn(newbody, newbodylen, "
" CRLF); + PR_Free(*body); + *body = newbody; + } +} + + static void mime_parse_stream_complete(nsMIMESession *stream) { @@ -1415,28 +1442,8 @@ mime_parse_stream_complete(nsMIMESession *stream) { // ... but the message body is currently plain text. - //We need to convert the plain/text to HTML in order to escape any HTML markup - char *escapedBody = MsgEscapeHTML(body); - if (escapedBody) - { - PR_Free(body); - body = escapedBody; - bodyLen = strlen(body); - } - - //+13 chars for
 & 
tags and CRLF - uint32_t newbodylen = bodyLen + 14; - char* newbody = (char *)PR_MALLOC (newbodylen); - if (newbody) - { - *newbody = 0; - PL_strcatn(newbody, newbodylen, "
");
-                PL_strcatn(newbody, newbodylen, body);
-                PL_strcatn(newbody, newbodylen, "
" CRLF); - PR_Free(body); - body = newbody; - } - } + convert_plaintext_body_to_html(&body, bodyLen); + } // Body is now HTML, set the format too (so headers are inserted in // correct format). composeFormat = nsIMsgCompFormat::HTML; @@ -1460,6 +1467,68 @@ mime_parse_stream_complete(nsMIMESession *stream) } + MSG_ComposeType msgComposeType = 0; // Keep compilers happy. + if (mdd->format_out == nsMimeOutput::nsMimeMessageEditorTemplate) + { + if (PL_strstr(mdd->url_name, "&redirect=true")) + msgComposeType = nsIMsgCompType::Redirect; + else if (PL_strstr(mdd->url_name, "&editasnew=true")) + msgComposeType = nsIMsgCompType::EditAsNew; + else + msgComposeType = nsIMsgCompType::Template; + } + + if (body && msgComposeType == nsIMsgCompType::EditAsNew) + { + // When editing as new, we respect the identities preferred format + // which can be overridden. + if (mdd->identity) + { + bool identityComposeHTML; + mdd->identity->GetComposeHtml(&identityComposeHTML); + + if (composeFormat == nsIMsgCompFormat::HTML && + identityComposeHTML == mdd->overrideComposeFormat) + { + // We we have HTML: + // If they want HTML and they want to override it (true == true) + // or they don't want HTML and they don't want to override it + // (false == false), then convert. Conversion happens below. + convertToPlainText = true; + composeFormat = nsIMsgCompFormat::PlainText; + } + else if (composeFormat == nsIMsgCompFormat::PlainText && + identityComposeHTML != mdd->overrideComposeFormat) + { + // We have plain text: + // If they want HTML and they don't want to override it (true != false) + // or they don't want HTML and they want to override it + // (false != true), then convert. + convert_plaintext_body_to_html(&body, bodyLen); + composeFormat = nsIMsgCompFormat::HTML; + } + } + } + else if (body && mdd->overrideComposeFormat && + (msgComposeType == nsIMsgCompType::Template || + !mdd->forwardInline)) // Draft processing. + { + // When using a template and overriding, the user gets the + // "other" format. + if (composeFormat == nsIMsgCompFormat::PlainText) + { + convert_plaintext_body_to_html(&body, bodyLen); + composeFormat = nsIMsgCompFormat::HTML; + } + else + { + // Conversion happens below. + convertToPlainText = true; + composeFormat = nsIMsgCompFormat::PlainText; + } + } + + // convert from UTF-8 to UTF-16 if (body) { @@ -1474,10 +1543,9 @@ mime_parse_stream_complete(nsMIMESession *stream) // if (mdd->format_out == nsMimeOutput::nsMimeMessageEditorTemplate) { - MSG_ComposeType msgComposeType = PL_strstr(mdd->url_name, - "&redirect=true") ? - nsIMsgCompType::Redirect : - nsIMsgCompType::Template; + if (convertToPlainText) + fields->ConvertBodyToPlainText(); + CreateTheComposeWindow(fields, newAttachData, msgComposeType, composeFormat, mdd->identity, mdd->originalMsgURI, mdd->origMsgHdr); @@ -1505,6 +1573,8 @@ mime_parse_stream_complete(nsMIMESession *stream) } else { + if (convertToPlainText) + fields->ConvertBodyToPlainText(); fields->SetDraftId(mdd->url_name); CreateTheComposeWindow(fields, newAttachData, nsIMsgCompType::Draft, composeFormat, mdd->identity, mdd->originalMsgURI, mdd->origMsgHdr); }