diff --git a/src/zen/common/ZenUIManager.mjs b/src/zen/common/ZenUIManager.mjs index ba7f68e0e..a216bbe9a 100644 --- a/src/zen/common/ZenUIManager.mjs +++ b/src/zen/common/ZenUIManager.mjs @@ -451,17 +451,7 @@ var gZenUIManager = { const [toast, reused] = this._createToastElement(messageId, options); this._toastContainer.removeAttribute('hidden'); this._toastContainer.appendChild(toast); - if (reused) { - await this.motion.animate(toast, { scale: 0.2 }, { duration: 0.1, bounce: 0 }); - } - if (!toast.style.hasOwnProperty('transform')) { - toast.style.transform = 'scale(0)'; - } - await this.motion.animate(toast, { scale: 1 }, { type: 'spring', bounce: 0.2, duration: 0.5 }); - if (this._toastTimeouts[messageId]) { - clearTimeout(this._toastTimeouts[messageId]); - } - this._toastTimeouts[messageId] = setTimeout(() => { + const timeoutFunction = () => { this.motion .animate(toast, { opacity: [1, 0], scale: [1, 0.5] }, { duration: 0.2, bounce: 0 }) .then(() => { @@ -470,7 +460,30 @@ var gZenUIManager = { this._toastContainer.setAttribute('hidden', true); } }); - }, options.timeout || 2000); + }; + if (reused) { + await this.motion.animate(toast, { scale: 0.2 }, { duration: 0.1, bounce: 0 }); + } else { + toast.addEventListener('mouseover', () => { + if (this._toastTimeouts[messageId]) { + clearTimeout(this._toastTimeouts[messageId]); + } + }); + toast.addEventListener('mouseout', () => { + if (this._toastTimeouts[messageId]) { + clearTimeout(this._toastTimeouts[messageId]); + } + this._toastTimeouts[messageId] = setTimeout(timeoutFunction, options.timeout || 2000); + }); + } + if (!toast.style.hasOwnProperty('transform')) { + toast.style.transform = 'scale(0)'; + } + await this.motion.animate(toast, { scale: 1 }, { type: 'spring', bounce: 0.2, duration: 0.5 }); + if (this._toastTimeouts[messageId]) { + clearTimeout(this._toastTimeouts[messageId]); + } + this._toastTimeouts[messageId] = setTimeout(timeoutFunction, options.timeout || 2000); }, get panelUIPosition() { diff --git a/src/zen/common/styles/zen-popup.css b/src/zen/common/styles/zen-popup.css index 6b5bb1b68..b8ff75ad6 100644 --- a/src/zen/common/styles/zen-popup.css +++ b/src/zen/common/styles/zen-popup.css @@ -363,6 +363,7 @@ menuitem { translate: 100%; } + gap: 10px; z-index: 1000; padding: 10px; border-radius: 12px; @@ -387,10 +388,16 @@ menuitem { font-size: smaller; } + & label { + margin-top: 0; + margin-bottom: 0; + } + & button { width: min-content; padding: 0 12px !important; min-width: unset !important; + margin: 0px !important; } } } diff --git a/src/zen/toolkit/common/ZenCommonUtils.cpp b/src/zen/toolkit/common/ZenCommonUtils.cpp index 12d82fb20..5d257b556 100644 --- a/src/zen/toolkit/common/ZenCommonUtils.cpp +++ b/src/zen/toolkit/common/ZenCommonUtils.cpp @@ -82,16 +82,17 @@ ZenCommonUtils::Share(nsIURI* url, const nsACString& title, if (!IsSharingSupported()) { return NS_OK; // We don't want to throw an error here } - ShareInternal(aWindow, url, title, text, aX, aY); - return NS_OK; + return ShareInternal(aWindow, url, title, text, aX, aY); } -void ZenCommonUtils::ShareInternal(nsCOMPtr& aWindow, nsIURI* url, +nsresult ZenCommonUtils::ShareInternal(nsCOMPtr& aWindow, nsIURI* url, const nsACString& title, const nsACString& text, uint32_t aX, uint32_t aY) { // We shoud've had done pointer checks before, so we can assume // aWindow is valid. -#ifdef ZEN_CAN_SHARE_NATIVE - ::nsZenNativeShareInternal(aWindow, url, title, text, aX, aY); +#ifdef NS_ZEN_CAN_SHARE_NATIVE + return ::nsZenNativeShareInternal::ShowNativeDialog(aWindow, url, title, text, aX, aY); +#else + return NS_ERROR_NOT_IMPLEMENTED; #endif } @@ -102,7 +103,7 @@ auto ZenCommonUtils::IsSharingSupported() -> bool { #elif defined(NS_ZEN_CAN_SHARE_NATIVE) return NS_ZEN_CAN_SHARE_NATIVE; #else - return true; + return false; #endif } diff --git a/src/zen/toolkit/common/ZenCommonUtils.h b/src/zen/toolkit/common/ZenCommonUtils.h index 4c66c4808..43161d8ed 100644 --- a/src/zen/toolkit/common/ZenCommonUtils.h +++ b/src/zen/toolkit/common/ZenCommonUtils.h @@ -41,7 +41,7 @@ class ZenCommonUtils final : public nsIZenCommonUtils { */ static auto ShareInternal(nsCOMPtr& aWindow, nsIURI* url, const nsACString& title, const nsACString& text, uint32_t aX, uint32_t aY) - -> void; + -> nsresult; }; } // namespace zen diff --git a/src/zen/toolkit/common/ZenShareInternal.h b/src/zen/toolkit/common/ZenShareInternal.h index 4987ff95e..2fcc9c5f0 100644 --- a/src/zen/toolkit/common/ZenShareInternal.h +++ b/src/zen/toolkit/common/ZenShareInternal.h @@ -28,10 +28,9 @@ class nsZenNativeShareInternal final { * @param aText The text to share. * @returns void */ - auto ShowNativeDialog(nsCOMPtr& aWindow, nsIURI* aUrl, - const nsACString& aTitle, const nsACString& aText, - uint32_t aX = 0, uint32_t aY = 0) const - -> void; + static auto ShowNativeDialog(nsCOMPtr& aWindow, nsIURI* aUrl, + const nsACString& aTitle, const nsACString& aText, uint32_t aX = 0, uint32_t aY = 0) + -> nsresult; nsZenNativeShareInternal() = default; ~nsZenNativeShareInternal() = default; diff --git a/src/zen/toolkit/common/cocoa/ZenShareInternal.mm b/src/zen/toolkit/common/cocoa/ZenShareInternal.mm index 166a088ca..84970d877 100644 --- a/src/zen/toolkit/common/cocoa/ZenShareInternal.mm +++ b/src/zen/toolkit/common/cocoa/ZenShareInternal.mm @@ -5,18 +5,44 @@ #include "ZenShareInternal.h" #include "nsCocoaUtils.h" +#include "nsPIDOMWindow.h" +#include "WidgetUtils.h" +#include "nsIWidget.h" + extern mozilla::LazyLogModule gCocoaUtilsLog; #undef LOG -#define LOG(...) MOZ_LOG(gCocoaUtilsLog, mozilla::LogLevel::Debug, (__VA_ARGS__)) +#define LOG(...) MOZ_LOG(gCocoaUtilsLog, mozilla::LogLevel::Info, (__VA_ARGS__)) #import #import -auto nsZenNativeShareInternal::ShowNativeDialog( - nsCOMPtr& aWindow, nsIURI* aUrl, - const nsACString& aTitle, const nsACString& aText, - uint32_t aX, uint32_t aY) const - -> void { +namespace zen { +using ::mozilla::widget::WidgetUtils; + +/** + * Get the native NSWindow pointer from a DOM window. + * + * @param a_window The DOM window to get the native window from. + * @param a_nativeWindow The pointer to the native NSWindow. + * @return NS_OK on success, or an error code on failure. + */ +static nsresult GetNativeWindowPointerFromDOMWindow(mozIDOMWindowProxy* a_window, + NSWindow** a_nativeWindow) { + *a_nativeWindow = nil; + if (!a_window) return NS_ERROR_INVALID_ARG; + nsPIDOMWindowOuter* win = nsPIDOMWindowOuter::From(a_window); + nsCOMPtr widget = WidgetUtils::DOMWindowToWidget(win); + if (!widget) { + return NS_ERROR_FAILURE; + } + *a_nativeWindow = (NSWindow*)widget->GetNativeData(NS_NATIVE_WINDOW); + return NS_OK; +} +} + +auto nsZenNativeShareInternal::ShowNativeDialog(nsCOMPtr& aWindow, + nsIURI* aUrl, const nsACString& aTitle, const nsACString& aText, uint32_t aX, uint32_t aY) + -> nsresult { // Just use the URL since apple doesn't support sharing text // and title in the share dialog nsAutoCString pageUrlAsStringTemp; @@ -30,14 +56,22 @@ auto nsZenNativeShareInternal::ShowNativeDialog( NSURL* pageUrl = nsCocoaUtils::ToNSURL( NS_ConvertUTF8toUTF16(pageUrlAsStringTemp) ); - LOG("pageUrl: %s", pageUrlAsStringTemp.get()); if (!pageUrl || (![pageUrl.scheme isEqualToString:@"https"] && ![pageUrl.scheme isEqualToString:@"http"])) { - return; + return NS_ERROR_FAILURE; } NSSharingServicePicker* sharingPicker = [[NSSharingServicePicker alloc] initWithItems:@[ pageUrl ]]; + NSWindow* cocoaMru = nil; + zen::GetNativeWindowPointerFromDOMWindow(aWindow, &cocoaMru); + if (!cocoaMru) { + LOG("ERROR: failed to get native window pointer"); + return NS_ERROR_FAILURE; + } // Create a rect for the sharing picker NSRect rect = NSMakeRect(aX, aY, 0, 0); - [sharingPicker showRelativeToRect:rect]; + [sharingPicker showRelativeToRect:rect + ofView:cocoaMru.contentView + preferredEdge:NSMinYEdge]; + return NS_OK; } diff --git a/src/zen/toolkit/common/cocoa/moz.build b/src/zen/toolkit/common/cocoa/moz.build index 5f78e58a9..004530c38 100644 --- a/src/zen/toolkit/common/cocoa/moz.build +++ b/src/zen/toolkit/common/cocoa/moz.build @@ -6,4 +6,7 @@ SOURCES += [ LOCAL_INCLUDES += [ "../", -] + "/widget", + "/widget/cocoa", + "/xpcom/base", +] \ No newline at end of file diff --git a/src/zen/toolkit/common/windows/ZenShareInternal.cpp b/src/zen/toolkit/common/windows/ZenShareInternal.cpp index 0ad231320..d2f585c97 100644 --- a/src/zen/toolkit/common/windows/ZenShareInternal.cpp +++ b/src/zen/toolkit/common/windows/ZenShareInternal.cpp @@ -9,7 +9,7 @@ auto nsZenNativeShareInternal::ShowNativeDialog( nsCOMPtr& aWindow, nsIURI* aUrl, const nsACString& aTitle, const nsACString& aText, uint32_t aX, uint32_t aY) const - -> void { + -> nsresult { nsAutoCString urlString; if (aUrl) { nsresult rv = aUrl->GetSpec(urlString); @@ -21,4 +21,5 @@ auto nsZenNativeShareInternal::ShowNativeDialog( (void)WindowsUIUtils::Share(NS_ConvertUTF8toUTF16_MaybeVoid(aTitle), NS_ConvertUTF8toUTF16_MaybeVoid(aText), NS_ConvertUTF8toUTF16_MaybeVoid(urlString)); + return NS_OK; }