From 4947b4c9a3115bbf35d8130f6c41a76cd238f3d7 Mon Sep 17 00:00:00 2001 From: "Mr. M" Date: Tue, 13 May 2025 10:33:24 +0200 Subject: [PATCH] feat: Addded haptic feedback support, b=(no-bug), c=common --- src/zen/toolkit/common/ZenCommonUtils.cpp | 14 ++++-- src/zen/toolkit/common/ZenCommonUtils.h | 26 +++++++--- .../toolkit/common/cocoa/ZenHapticFeedback.mm | 48 +++++++++++++++++++ .../toolkit/common/cocoa/ZenShareInternal.mm | 1 + src/zen/toolkit/common/cocoa/moz.build | 1 + src/zen/toolkit/common/nsIZenCommonUtils.idl | 5 ++ 6 files changed, 83 insertions(+), 12 deletions(-) create mode 100644 src/zen/toolkit/common/cocoa/ZenHapticFeedback.mm diff --git a/src/zen/toolkit/common/ZenCommonUtils.cpp b/src/zen/toolkit/common/ZenCommonUtils.cpp index e4fa84e0d..aa3044dc7 100644 --- a/src/zen/toolkit/common/ZenCommonUtils.cpp +++ b/src/zen/toolkit/common/ZenCommonUtils.cpp @@ -57,11 +57,15 @@ using mozilla::dom::WindowGlobalChild; *canShare = false; \ return NS_OK; -/* - * @brief Check if the current context can share data. - * @param data The data to share. - * @returns True if the current context can share data, false otherwise. - */ +#ifdef XP_MACOSX +NS_IMETHODIMP +ZenCommonUtils::PlayHapticFeedback(uint32_t type) { + // We don't have any haptic feedback on non-macOS platforms + // so we can just return. + return PlayHapticFeedbackInternal(type); +} +#endif + NS_IMETHODIMP ZenCommonUtils::CanShare(bool* canShare) { auto aWindow = GetMostRecentWindow(); diff --git a/src/zen/toolkit/common/ZenCommonUtils.h b/src/zen/toolkit/common/ZenCommonUtils.h index 3f58702e7..50e5c40bc 100644 --- a/src/zen/toolkit/common/ZenCommonUtils.h +++ b/src/zen/toolkit/common/ZenCommonUtils.h @@ -32,17 +32,29 @@ class ZenCommonUtils final : public nsIZenCommonUtils { */ static auto IsSharingSupported() -> bool; /** - * @brief Helper function to share data via the native dialogs. - * @param aWindow The window to use for the share dialog. - * @param url The URL to share. - * @param title The title of the share. - * @param text The text to share. - * @returns A promise that resolves when the share is complete. - */ + * @brief Helper function to share data via the native dialogs. + * @param aWindow The window to use for the share dialog. + * @param url The URL to share. + * @param title The title of the share. + * @param text The text to share. + * @returns A promise that resolves when the share is complete. + */ static auto ShareInternal(nsCOMPtr& aWindow, nsIURI* url, const nsACString& title, const nsACString& text, uint32_t aX, uint32_t aY, uint32_t aWidth, uint32_t aHeight) -> nsresult; + /** + * @brief Helper function to play haptic feedback. + * @param type The type of haptic feedback to play. + */ +#if !defined(XP_MACOSX) + static auto PlayHapticFeedbackInternal(uint32_t type) -> nsresult { + // No-op on non-macOS platforms + return NS_ERROR_NOT_IMPLEMENTED; + } +#else + static auto PlayHapticFeedbackInternal(uint32_t type) -> nsresult; +#endif }; } // namespace zen diff --git a/src/zen/toolkit/common/cocoa/ZenHapticFeedback.mm b/src/zen/toolkit/common/cocoa/ZenHapticFeedback.mm new file mode 100644 index 000000000..58397a881 --- /dev/null +++ b/src/zen/toolkit/common/cocoa/ZenHapticFeedback.mm @@ -0,0 +1,48 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ZenCommonUtils.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::Info, (__VA_ARGS__)) + +#import +#import + +namespace zen { +using ::mozilla::widget::WidgetUtils; +namespace { +/** + * Get the native haptic feedback type from the uint32_t. + * + * @param type The uint32_t to convert. + * @return The native haptic feedback type. + */ +inline UIImpactFeedbackStyle GetNativeHapticFeedbackType(uint32_t type) { + return static_cast(type); +} +} + +nsresult ZenCommonUtils::PlayHapticFeedbackInternal(uint32_t type) { + NS_OBJC_BEGIN_TRY_BLOCK_RETURN; + auto style = GetNativeHapticFeedbackType(type); + if (@available(iOS 10.0, macOS 10.14, *)) { + UIImpactFeedbackGenerator *generator = [[UIImpactFeedbackGenerator alloc] initWithStyle:style]; + [generator prepare]; + [generator impactOccurred]; + generator = nil; + } else { + // Fallback on earlier versions + // Note: This is a no-op on older versions of iOS/macOS + } + NS_OBJC_END_TRY_BLOCK_RETURN(nil); +} +} + diff --git a/src/zen/toolkit/common/cocoa/ZenShareInternal.mm b/src/zen/toolkit/common/cocoa/ZenShareInternal.mm index eb47cb62d..ae5bd5577 100644 --- a/src/zen/toolkit/common/cocoa/ZenShareInternal.mm +++ b/src/zen/toolkit/common/cocoa/ZenShareInternal.mm @@ -74,5 +74,6 @@ auto nsZenNativeShareInternal::ShowNativeDialog(nsCOMPtr& aW [sharingPicker showRelativeToRect:rect ofView:cocoaMru.contentView preferredEdge:NSMaxYEdge]; + [sharingPicker release]; return NS_OK; } diff --git a/src/zen/toolkit/common/cocoa/moz.build b/src/zen/toolkit/common/cocoa/moz.build index 004530c38..1746d17db 100644 --- a/src/zen/toolkit/common/cocoa/moz.build +++ b/src/zen/toolkit/common/cocoa/moz.build @@ -2,6 +2,7 @@ FINAL_LIBRARY = "xul" SOURCES += [ "ZenShareInternal.mm", + "ZenHapticFeedback.mm", ] LOCAL_INCLUDES += [ diff --git a/src/zen/toolkit/common/nsIZenCommonUtils.idl b/src/zen/toolkit/common/nsIZenCommonUtils.idl index 06eb62ea8..cb2bc407c 100644 --- a/src/zen/toolkit/common/nsIZenCommonUtils.idl +++ b/src/zen/toolkit/common/nsIZenCommonUtils.idl @@ -28,5 +28,10 @@ interface nsIZenCommonUtils : nsISupports { * @returns True if the current context can share data, false otherwise. */ boolean canShare(); + /* + * @brief Play a single haptic feedback note if supported. + * @param type The type of haptic feedback to play. + */ + void playHapticFeedback(in uint32_t type); };