From 784727748c60183665cabf3c18fb54896c81214e Mon Sep 17 00:00:00 2001 From: Ryan McGrath Date: Sun, 5 Apr 2020 00:09:17 -0700 Subject: [PATCH] Missing files from last commit, whoops. Also begin the long arduous process of bringing in NSNotificationName. Just end me now. --- src/notification_center/mod.rs | 3 + src/notification_center/name.rs | 1321 +++++++++++++++++++++++++++++++ src/view/controller/ios.rs | 72 ++ src/view/controller/macos.rs | 73 ++ src/view/ios.rs | 45 ++ src/view/macos.rs | 125 +++ 6 files changed, 1639 insertions(+) create mode 100644 src/notification_center/name.rs create mode 100644 src/view/controller/ios.rs create mode 100644 src/view/controller/macos.rs create mode 100644 src/view/ios.rs create mode 100644 src/view/macos.rs diff --git a/src/notification_center/mod.rs b/src/notification_center/mod.rs index a2b05cb..d0d7e6a 100644 --- a/src/notification_center/mod.rs +++ b/src/notification_center/mod.rs @@ -20,6 +20,9 @@ //use objc::runtime::Object; //use objc_id::ShareId; +mod name; +pub use name::NotificationName; + mod traits; pub use traits::Dispatcher; diff --git a/src/notification_center/name.rs b/src/notification_center/name.rs new file mode 100644 index 0000000..ee56932 --- /dev/null +++ b/src/notification_center/name.rs @@ -0,0 +1,1321 @@ +use crate::foundation::NSString; + +/// An enum that wraps NSNotificationName. +/// +/// Since this framework utilizes Objective-C, these are ultimately backed by `NSString`... but we +/// want them to be a bit more type-friendly and autocomplete-able. +#[derive(Copy, Clone, Debug)] +pub enum NotificationName { + /// Posted when the audio engine config changes. + /// + /// When using this, you must register from an `AudioEngine` instance. + /// + /// From Apple's documentation: + /// + /// > _When the audio engine’s I/O unit observes a change to the audio input or output + /// > hardware’s channel count or sample rate, the audio engine stops, uninitializes itself, + /// > and issues this notification. The nodes remain attached and connected with previously + /// > set formats. The app must reestablish connections if the connection formats need to change. + /// > + /// > The engine must not be deallocated from within the client's notification handler. Callback + /// > happens on an internal dispatch queue and can deadlock while trying to teardown the engine + /// > synchronously._ + AudioEngineConfigurationChange, + + /// Posted when an audio interruption occurs. + AudioSessionInterruption, + + /// Posted when the system terminates the media server. + /// + /// Most apps don't need to utilize this, and should opt to instead use + /// `AudioSessionMediaServicesWereReset`. According to Apple, you can use this if you need to + /// take action for requests that come in before the server restarts. + AudioSessionMediaServicesWereLost, + + /// Posted when the media server restarts. + /// + /// In very rare cases, the system may terminate and restart its media services daemon. Respond to + /// these events by reinitializing audio objects such as players, recorders, converters, and so on. + /// Reset your audio session category, options, and mode configuration. Only restart playback, recording, or + /// processing when initiated by the user. + AudioSessionMediaServicesWereReset, + + /// Posted when the system audio route changes. + /// + /// The info provided by this notification contains the `AVAudioSessionRouteChange` keys, which + /// provide more information. + /// + /// This notification is posted on a background thread. + /// + /// See [Apple's documentation on responding to Audio Session Route Changes](https://developer.apple.com/documentation/avfoundation/avaudiosession/responding_to_audio_session_route_changes?language=objc) for more information on using this notification. + AudioSessionRouteChange, + + /// Posted when primary audio from other apps starts or stops. + /// + /// Subscribe to this notification to ensure that the system notifies your app when optional secondary + /// audio muting should begin or end. The system sends this notification to registered listeners who + /// are currently in the foreground with an active audio session. + /// + /// The info provided contains a `AVAudioSessionSilenceSecondaryAudioHintType` value for the + /// `AVAudioSessionSilenceSecondaryAudioHintTypeKey`. Use the audio hint type to determine if your secondary + /// audio muting should begin or end. + /// + /// This notification is posted on the main thread. + AudioSessionSilenceSecondaryAudioHint, + + /// Posted when unit component tags change. + /// + /// The notification object is the AVAudioUnitComponent object which has changed tags. + /// + /// @TODO: This one may be tricky. Revisit when we do AVFoundation. + AudioUnitComponentTagsDidChange, + + /// Posted when the signed-in iCloud account has changed. + /// + /// This notification is sent by instances of `CloudKitContainer`. If none exist, you won't get + /// this notification. It can be sent on any thread, according to Apple. + /// + /// If you get this notification, you should query for the current account status. + CloudKitAccountChanged, + + /// + CLKComplicationServerActiveComplicationsDidChange, + + /// + CNContactStoreDidChange, + + /// + EKEventStoreChanged, + + /// + HKUserPreferencesDidChange, + + /// + HMCharacteristicPropertySupportsEvent, + + /// + NSBundleResourceRequestLowDiskSpace, + + /// + NSCalendarDayChanged, + + /// + NSExtensionHostDidBecomeActive, + + /// + NSExtensionHostDidEnterBackground, + + /// + NSExtensionHostWillEnterForeground, + + /// + NSExtensionHostWillResignActive, + + /// + NSFileHandleConnectionAccepted, + + /// + NSFileHandleDataAvailable, + + /// + NSFileHandleReadToEndOfFileCompletion, + + /// + NSHTTPCookieManagerAcceptPolicyChanged, + + /// + NSHTTPCookieManagerCookiesChanged, + + /// + NSManagedObjectContextDidSave, + + /// + NSManagedObjectContextObjectsDidChange, + + /// + NSManagedObjectContextWillSave, + + /// + NSMetadataQueryDidFinishGathering, + + /// + NSMetadataQueryDidStartGathering, + + /// + NSMetadataQueryDidUpdate, + + /// + NSMetadataQueryGatheringProgress, + + /// + NSPersistentStoreCoordinatorStoresDidChange, + + /// + NSPersistentStoreCoordinatorStoresWillChange, + + /// + NSPersistentStoreCoordinatorWillRemoveStore, + + /// + NSProcessInfoPowerStateDidChange, + + /// + NSSystemClockDidChange, + + /// + NSSystemTimeZoneDidChange, + + /// + NSURLCredentialStorageChanged, + + /// + NSUbiquityIdentityDidChange, + + /// + NSUndoManagerCheckpoint, + + /// + NSUndoManagerDidCloseUndoGroup, + + /// + NSUndoManagerDidOpenUndoGroup, + + /// + NSUndoManagerDidRedoChange, + + /// + NSUndoManagerDidUndoChange, + + /// + NSUndoManagerWillCloseUndoGroup, + + /// + NSUndoManagerWillRedoChange, + + /// + NSUndoManagerWillUndoChange, + + /// + PKPassLibraryDidChange, + + /// + PKPassLibraryRemotePaymentPassesDidChange, + + /// + UIAccessibilityAnnouncementDidFinish, + + /// + UIAccessibilityElementFocused, + + /// + WKAudioFilePlayerItemDidPlayToEndTime, + + /// + WKAudioFilePlayerItemFailedToPlayToEndTime, + + /// + WKAudioFilePlayerItemTimeJumped, + + /// + ABPeoplePickerDisplayedPropertyDidChange, + + /// + ABPeoplePickerGroupSelectionDidChange, + + /// + ABPeoplePickerNameSelectionDidChange, + + /// + ABPeoplePickerValueSelectionDidChange, + + /// + ACAccountStoreDidChange, + + /// + AVAssetChapterMetadataGroupsDidChange, + + /// + AVAssetContainsFragmentsDidChange, + + /// + AVAssetDurationDidChange, + + /// + AVAssetMediaSelectionGroupsDidChange, + + /// + AVAssetTrackSegmentsDidChange, + + /// + AVAssetTrackTimeRangeDidChange, + + /// + AVAssetTrackTrackAssociationsDidChange, + + /// + AVAssetWasDefragmented, + + /// + AVCaptureDeviceWasConnected, + + /// + AVCaptureDeviceWasDisconnected, + + /// + AVCaptureInputPortFormatDescriptionDidChange, + + /// + AVCaptureSessionDidStartRunning, + + /// + AVCaptureSessionDidStopRunning, + + /// + AVCaptureSessionRuntimeError, + + /// + AVFragmentedMovieContainsMovieFragmentsDidChange, + + /// + AVFragmentedMovieDurationDidChange, + + /// + AVFragmentedMovieTrackSegmentsDidChange, + + /// + AVFragmentedMovieTrackTimeRangeDidChange, + + /// + AVFragmentedMovieTrackTotalSampleDataLengthDidChange, + + /// + AVFragmentedMovieWasDefragmented, + + /// + AVPlayerItemDidPlayToEndTime, + + /// + AVPlayerItemFailedToPlayToEndTime, + + /// + AVPlayerItemNewAccessLogEntry, + + /// + AVPlayerItemNewErrorLogEntry, + + /// + AVPlayerItemPlaybackStalled, + + /// + AVPlayerItemTimeJumped, + + /// + AVSampleBufferDisplayLayerFailedToDecode, + + /// + CWBSSIDDidChange, + + /// + CWCountryCodeDidChange, + + /// + CWLinkDidChange, + + /// + CWLinkQualityDidChange, + + /// + CWModeDidChange, + + /// + CWPowerDidChange, + + /// + CWSSIDDidChange, + + /// + CWScanCacheDidUpdate, + + /// + GCControllerDidConnect, + + /// + GCControllerDidDisconnect, + + /// + IKFilterBrowserFilterDoubleClick, + + /// + IKFilterBrowserFilterSelected, + + /// + IKFilterBrowserWillPreviewFilter, + + /// + IOBluetoothHostControllerPoweredOff, + + /// + IOBluetoothHostControllerPoweredOn, + + /// + IOBluetoothL2CAPChannelPublished, + + /// + IOBluetoothL2CAPChannelTerminated, + + /// + MKAnnotationCalloutInfoDidChange, + + /// + NEFilterConfigurationDidChange, + + /// + NEVPNConfigurationChange, + + /// + NEVPNStatusDidChange, + + /// + NSAccessibilityAnnouncementRequested, + + /// + NSAccessibilityAnnouncementKey, + + /// + NSAccessibilityPriorityKey, + + /// + NSAccessibilityApplicationActivated, + + /// + NSAccessibilityApplicationDeactivated, + + /// + NSAccessibilityApplicationHidden, + + /// + NSAccessibilityApplicationShown, + + /// + NSAccessibilityCreated, + + /// + NSAccessibilityDrawerCreated, + + /// + NSAccessibilityFocusedUIElementChanged, + + /// + NSAccessibilityFocusedWindowChanged, + + /// + NSAccessibilityHelpTagCreated, + + /// + NSAccessibilityLayoutChanged, + + /// + NSAccessibilityUIElementsKey, + + /// + NSAccessibilityMainWindowChanged, + + /// + NSAccessibilityMoved, + + /// + NSAccessibilityResized, + + /// + NSAccessibilityRowCollapsed, + + /// + NSAccessibilityRowCountChanged, + + /// + NSAccessibilityRowExpanded, + + /// + NSAccessibilitySelectedCellsChanged, + + /// + NSAccessibilitySelectedChildrenChanged, + + /// + NSAccessibilitySelectedChildrenMoved, + + /// + NSAccessibilitySelectedColumnsChanged, + + /// + NSAccessibilitySelectedRowsChanged, + + /// + NSAccessibilitySelectedTextChanged, + + /// + NSAccessibilitySheetCreated, + + /// + NSAccessibilityTitleChanged, + + /// + NSAccessibilityUIElementDestroyed, + + /// + NSAccessibilityUnitsChanged, + + /// + NSAccessibilityValueChanged, + + /// + NSAccessibilityWindowCreated, + + /// + NSAccessibilityWindowDeminiaturized, + + /// + NSAccessibilityWindowMiniaturized, + + /// + NSAccessibilityWindowMoved, + + /// + NSAccessibilityWindowResized, + + /// + NSAnimationProgressMark, + + /// + NSAntialiasThresholdChanged, + + /// + NSAppleEventManagerWillProcessFirstEvent, + + /// + NSApplicationDidBecomeActive, + + /// + NSApplicationDidChangeOcclusionState, + + /// + NSApplicationDidChangeScreenParameters, + + /// + NSApplicationDidFinishLaunching, + + /// + NSApplicationDidFinishRestoringWindows, + + /// + NSApplicationDidHide, + + /// + NSApplicationDidResignActive, + + /// + NSApplicationDidUnhide, + + /// + NSApplicationDidUpdate, + + /// + NSApplicationWillBecomeActive, + + /// + NSApplicationWillFinishLaunching, + + /// + NSApplicationWillHide, + + /// + NSApplicationWillResignActive, + + /// + NSApplicationWillTerminate, + + /// + NSApplicationWillUnhide, + + /// + NSApplicationWillUpdate, + + /// + NSBrowserColumnConfigurationDidChange, + + /// + NSClassDescriptionNeededForClass, + + /// + NSColorListDidChange, + + /// + NSColorPanelColorDidChange, + + /// + NSColorPanel, + + /// + NSComboBoxSelectionDidChange, + + /// + NSComboBoxSelectionIsChanging, + + /// + NSComboBoxWillDismiss, + + /// + NSComboBoxWillPopUp, + + /// + NSContextHelpModeDidActivate, + + /// + NSContextHelpModeDidDeactivate, + + /// + NSControlTextDidBeginEditing, + + /// + NSControlTextDidChange, + + /// + NSControlTextDidEndEditing, + + /// + NSControlTintDidChange, + + /// + NSDrawerDidClose, + + /// + NSDrawerDidOpen, + + /// + NSDrawerWillClose, + + /// + NSDrawerWillOpen, + + /// + NSFontCollectionDidChange, + + /// + NSFontSetChanged, + + /// + NSImageRepRegistryDidChange, + + /// + NSMenuDidAddItem, + + /// + NSMenuDidBeginTracking, + + /// + NSMenuDidChangeItem, + + /// + NSMenuDidEndTracking, + + /// + NSMenuDidRemoveItem, + + /// + NSMenuDidSendAction, + + /// + NSMenuWillSendAction, + + /// + NSOutlineViewColumnDidMove, + + /// + NSOutlineViewColumnDidResize, + + /// + NSOutlineViewItemDidCollapse, + + /// + NSOutlineViewItemDidExpand, + + /// + NSOutlineViewItemWillCollapse, + + /// + NSOutlineViewItemWillExpand, + + /// + NSOutlineViewSelectionDidChange, + + /// + NSOutlineViewSelectionIsChanging, + + /// + NSPersistentStoreDidImportUbiquitousContentChanges, + + /// + NSPopUpButtonCellWillPopUp, + + /// + NSPopUpButtonWillPopUp, + + /// + NSPopoverDidClose, + + /// + NSPopoverDidShow, + + /// + NSPopoverWillClose, + + /// + NSPopoverWillShow, + + /// + NSPreferencePaneCancelUnselect, + + /// + NSPreferencePaneDoUnselect, + + /// + NSPreferencePaneSwitchToPane, + + /// + NSPreferencePaneUpdateHelpMenu, + + /// + NSPreferencePrefPaneIsAvailable, + + /// + NSPreferredScrollerStyleDidChange, + + /// + NSRuleEditorRowsDidChange, + + /// + NSScreenColorSpaceDidChange, + + /// + NSScrollViewDidEndLiveMagnify, + + /// + NSScrollViewDidEndLiveScroll, + + /// + NSScrollViewDidLiveScroll, + + /// + NSScrollViewWillStartLiveMagnify, + + /// + NSScrollViewWillStartLiveScroll, + + /// + NSSpellCheckerDidChangeAutomaticCapitalization, + + /// + NSSpellCheckerDidChangeAutomaticDashSubstitution, + + /// + NSSpellCheckerDidChangeAutomaticPeriodSubstitution, + + /// + NSSpellCheckerDidChangeAutomaticQuoteSubstitution, + + /// + NSSpellCheckerDidChangeAutomaticSpellingCorrection, + + /// + NSSpellCheckerDidChangeAutomaticTextReplacement, + + /// + NSSplitViewDidResizeSubviews, + + /// + NSSplitViewWillResizeSubviews, + + /// + NSSystemColorsDidChange, + + /// + NSTableViewColumnDidMove, + + /// + NSTableViewColumnDidResize, + + /// + NSTableViewSelectionDidChange, + + /// + NSTableViewSelectionIsChanging, + + /// + NSTextAlternativesSelectedAlternativeString, + + /// + NSTextDidBeginEditing, + + /// + NSTextDidChange, + + /// + NSTextDidEndEditing, + + /// + NSTextInputContextKeyboardSelectionDidChange, + + /// + NSTextStorageDidProcessEditing, + + /// + NSTextStorageWillProcessEditing, + + /// + NSTextViewDidChangeSelection, + + /// + NSTextViewDidChangeTypingAttributes, + + /// + NSTextViewWillChangeNotifyingTextView, + + /// + NSToolbarDidRemoveItem, + + /// + NSToolbarWillAddItem, + + /// + NSViewBoundsDidChange, + + /// + NSViewDidUpdateTrackingAreas, + + /// + NSViewFocusDidChange, + + /// + NSViewFrameDidChange, + + /// + NSViewGlobalFrameDidChange, + + /// + NSWindowDidBecomeKey, + + /// + NSWindowDidBecomeMain, + + /// + NSWindowDidChangeBackingProperties, + + /// + NSWindowDidChangeOcclusionState, + + /// + NSWindowDidChangeScreen, + + /// + NSWindowDidChangeScreenProfile, + + /// + NSWindowDidDeminiaturize, + + /// + NSWindowDidEndLiveResize, + + /// + NSWindowDidEndSheet, + + /// + NSWindowDidEnterFullScreen, + + /// + NSWindowDidEnterVersionBrowser, + + /// + NSWindowDidExitFullScreen, + + /// + NSWindowDidExitVersionBrowser, + + /// + NSWindowDidExpose, + + /// + NSWindowDidMiniaturize, + + /// + NSWindowDidMove, + + /// + NSWindowDidResignKey, + + /// + NSWindowDidResignMain, + + /// + NSWindowDidResize, + + /// + NSWindowDidUpdate, + + /// + NSWindowWillBeginSheet, + + /// + NSWindowWillClose, + + /// + NSWindowWillEnterFullScreen, + + /// + NSWindowWillEnterVersionBrowser, + + /// + NSWindowWillExitFullScreen, + + /// + NSWindowWillExitVersionBrowser, + + /// + NSWindowWillMiniaturize, + + /// + NSWindowWillMove, + + /// + NSWindowWillStartLiveResize, + + /// + NSWorkspaceAccessibilityDisplayOptionsDidChange, + + /// + NSWorkspaceActiveSpaceDidChange, + + /// + NSWorkspaceDidActivateApplication, + + /// + NSWorkspaceDidChangeFileLabels, + + /// + NSWorkspaceDidDeactivateApplication, + + /// + NSWorkspaceDidHideApplication, + + /// + NSWorkspaceDidLaunchApplication, + + /// + NSWorkspaceDidMount, + + /// + NSWorkspaceDidPerformFileOperation, + + /// + NSWorkspaceDidRenameVolume, + + /// + NSWorkspaceDidTerminateApplication, + + /// + NSWorkspaceDidUnhideApplication, + + /// + NSWorkspaceDidUnmount, + + /// + NSWorkspaceDidWake, + + /// + NSWorkspaceScreensDidSleep, + + /// + NSWorkspaceScreensDidWake, + + /// + NSWorkspaceSessionDidBecomeActive, + + /// + NSWorkspaceSessionDidResignActive, + + /// + NSWorkspaceWillLaunchApplication, + + /// + NSWorkspaceWillPowerOff, + + /// + NSWorkspaceWillSleep, + + /// + NSWorkspaceWillUnmount, + + /// + PDFDocumentDidBeginFind, + + /// + PDFDocumentDidBeginPageFind, + + /// + PDFDocumentDidBeginPageWrite, + + /// + PDFDocumentDidBeginWrite, + + /// + PDFDocumentDidEndFind, + + /// + PDFDocumentDidEndPageFind, + + /// + PDFDocumentDidEndPageWrite, + + /// + PDFDocumentDidEndWrite, + + /// + PDFDocumentDidFindMatch, + + /// + PDFDocumentDidUnlock, + + /// + PDFThumbnailViewDocumentEdited, + + /// + PDFViewAnnotationHit, + + /// + PDFViewAnnotationWillHit, + + /// + PDFViewChangedHistory, + + /// + PDFViewCopyPermission, + + /// + PDFViewDisplayBoxChanged, + + /// + PDFViewDisplayModeChanged, + + /// + PDFViewDocumentChanged, + + /// + PDFViewPageChanged, + + /// + PDFViewPrintPermission, + + /// + PDFViewScaleChanged, + + /// + PDFViewSelectionChanged, + + /// + PDFViewVisiblePagesChanged, + + /// + kABDatabaseChanged, + + /// + kABDatabaseChangedExternally, + + /// + kQuartzFilterManagerDidAddFilter, + + /// + kQuartzFilterManagerDidModifyFilter, + + /// + kQuartzFilterManagerDidRemoveFilter, + + /// + kQuartzFilterManagerDidSelectFilter, + + /// + EAAccessoryDidConnect, + + /// + EAAccessoryDidDisconnect, + + /// + SKCloudServiceCapabilitiesDidChange, + + /// + SKStorefrontIdentifierDidChange, + + /// + UIAccessibilityAssistiveTouchStatusDidChange, + + /// + UIAccessibilityBoldTextStatusDidChange, + + /// + UIAccessibilityClosedCaptioningStatusDidChange, + + /// + UIAccessibilityDarkerSystemColorsStatusDidChange, + + /// + UIAccessibilityGrayscaleStatusDidChange, + + /// + UIAccessibilityGuidedAccessStatusDidChange, + + /// + UIAccessibilityHearingDevicePairedEarDidChange, + + /// + UIAccessibilityInvertColorsStatusDidChange, + + /// + UIAccessibilityMonoAudioStatusDidChange, + + /// + UIAccessibilityReduceMotionStatusDidChange, + + /// + UIAccessibilityReduceTransparencyStatusDidChange, + + /// + UIAccessibilityShakeToUndoDidChange, + + /// + UIAccessibilitySpeakScreenStatusDidChange, + + /// + UIAccessibilitySpeakSelectionStatusDidChange, + + /// + UIAccessibilitySwitchControlStatusDidChange, + + /// + UIApplicationDidBecomeActive, + + /// + UIApplicationDidEnterBackground, + + /// + UIApplicationDidFinishLaunching, + + /// + UIApplicationDidReceiveMemoryWarning, + + /// + UIApplicationSignificantTimeChange, + + /// + UIApplicationUserDidTakeScreenshot, + + /// + UIApplicationWillEnterForeground, + + /// + UIApplicationWillResignActive, + + /// + UIApplicationWillTerminate, + + /// + UIContentSizeCategoryDidChange, + + /// + UIDeviceProximityStateDidChange, + + /// + UIScreenBrightnessDidChange, + + /// + UIScreenDidConnect, + + /// + UIScreenDidDisconnect, + + /// + UIScreenModeDidChange, + + /// + UITableViewSelectionDidChange, + + /// + UITextFieldTextDidBeginEditing, + + /// + UITextFieldTextDidChange, + + /// + UITextFieldTextDidEndEditing, + + /// + UITextInputCurrentInputModeDidChange, + + /// + UITextViewTextDidBeginEditing, + + /// + UITextViewTextDidChange, + + /// + UITextViewTextDidEndEditing, + + /// + UIViewControllerShowDetailTargetDidChange, + + /// + UIWindowDidBecomeHidden, + + /// + UIWindowDidBecomeKey, + + /// + UIWindowDidBecomeVisible, + + /// + UIWindowDidResignKey, + + /// + AVCaptureDeviceSubjectAreaDidChange, + + /// + AVCaptureSessionInterruptionEnded, + + /// + AVCaptureSessionWasInterrupted, + + /// + MFMessageComposeViewControllerTextMessageAvailabilityDidChange, + + /// + MPMediaLibraryDidChange, + + /// + MPMusicPlayerControllerNowPlayingItemDidChange, + + /// + MPMusicPlayerControllerPlaybackStateDidChange, + + /// + MPMusicPlayerControllerVolumeDidChange, + + /// + UIApplicationBackgroundRefreshStatusDidChange, + + /// + UIDeviceBatteryLevelDidChange, + + /// + UIDeviceBatteryStateDidChange, + + /// + UIDeviceOrientationDidChange, + + /// + UIDocumentStateChanged, + + /// + UIKeyboardDidChangeFrame, + + /// + UIKeyboardDidHide, + + /// + UIKeyboardDidShow, + + /// + UIKeyboardWillChangeFrame, + + /// + UIKeyboardWillHide, + + /// + UIKeyboardWillShow, + + /// + UIMenuControllerDidHideMenu, + + /// + UIMenuControllerDidShowMenu, + + /// + UIMenuControllerMenuFrameDidChange, + + /// + UIMenuControllerWillHideMenu, + + /// + UIMenuControllerWillShowMenu, + + /// + UIPasteboardChanged, + + /// + UIPasteboardRemoved, + + /// + UIApplicationProtectedDataDidBecomeAvailable, + + /// + UIApplicationProtectedDataWillBecomeUnavailable, + + /// + NSSpellCheckerDidChangeAutomaticTextCompletion, + + /// + MPMusicPlayerControllerQueueDidChange, + + /// + AVDisplayManagerModeSwitchEnd, + + /// + AVDisplayManagerModeSwitchSettingsChanged, + + /// + AVDisplayManagerModeSwitchStart, + + /// + AVPlayerAvailableHDRModesDidChange, + + /// + AVRouteDetectorMultipleRoutesDetectedDidChange, + + /// + AVSampleBufferAudioRendererWasFlushedAutomatically, + + /// + CTServiceRadioAccessTechnologyDidChange, + + /// + GKPlayerAuthenticationDidChangeNotificationName, + + /// + GKPlayerDidChangeNotificationName, + + /// + NEDNSProxyConfigurationDidChange, + + /// + NSPersistentStoreRemoteChange, + + /// + SKStorefrontCountryCodeDidChange, + + /// + WKAccessibilityReduceMotionStatusDidChange +} + +impl From for NSString { + fn from(name: NotificationName) -> Self { + match name { + _ => NSString::new("") + } + } +} diff --git a/src/view/controller/ios.rs b/src/view/controller/ios.rs new file mode 100644 index 0000000..3db20a5 --- /dev/null +++ b/src/view/controller/ios.rs @@ -0,0 +1,72 @@ +use std::sync::Once; +use std::unreachable; + +use objc::declare::ClassDecl; +use objc::runtime::{Class, Object, Sel}; +use objc::{class, msg_send, sel, sel_impl}; + +use crate::foundation::{BOOL}; +use crate::view::{VIEW_DELEGATE_PTR, ViewDelegate}; +use crate::utils::{load, as_bool}; + +/// Called when the view controller receives a `viewWillAppear:` message. +extern fn will_appear(this: &mut Object, _: Sel, animated: BOOL) { + unsafe { + let _: () = msg_send![super(this, class!(UIViewController)), viewWillAppear:animated]; + } + + let controller = load::(this, VIEW_DELEGATE_PTR); + controller.will_appear(as_bool(animated)); +} + +/// Called when the view controller receives a `viewDidAppear:` message. +extern fn did_appear(this: &mut Object, _: Sel, animated: BOOL) { + unsafe { + let _: () = msg_send![super(this, class!(UIViewController)), viewDidAppear:animated]; + } + + let controller = load::(this, VIEW_DELEGATE_PTR); + controller.did_appear(as_bool(animated)); +} + +/// Called when the view controller receives a `viewWillDisappear:` message. +extern fn will_disappear(this: &mut Object, _: Sel, animated: BOOL) { + unsafe { + let _: () = msg_send![super(this, class!(UIViewController)), viewWillDisappear:animated]; + } + + let controller = load::(this, VIEW_DELEGATE_PTR); + controller.will_disappear(as_bool(animated)); +} + +/// Called when the view controller receives a `viewDidDisappear:` message. +extern fn did_disappear(this: &mut Object, _: Sel, animated: BOOL) { + unsafe { + let _: () = msg_send![super(this, class!(UIViewController)), viewDidDisappear:animated]; + } + + let controller = load::(this, VIEW_DELEGATE_PTR); + controller.did_disappear(as_bool(animated)); +} + +/// Registers an `NSViewDelegate`. +pub(crate) fn register_view_controller_class() -> *const Class { + static mut VIEW_CLASS: *const Class = 0 as *const Class; + static INIT: Once = Once::new(); + + INIT.call_once(|| unsafe { + let superclass = class!(UIViewController); + let mut decl = ClassDecl::new("RSTViewController", superclass).unwrap(); + + decl.add_ivar::(VIEW_DELEGATE_PTR); + + decl.add_method(sel!(viewWillAppear:), will_appear:: as extern fn(&mut Object, _, BOOL)); + decl.add_method(sel!(viewDidAppear:), did_appear:: as extern fn(&mut Object, _, BOOL)); + decl.add_method(sel!(viewWillDisappear:), will_disappear:: as extern fn(&mut Object, _, BOOL)); + decl.add_method(sel!(viewDidDisappear:), did_disappear:: as extern fn(&mut Object, _, BOOL)); + + VIEW_CLASS = decl.register(); + }); + + unsafe { VIEW_CLASS } +} diff --git a/src/view/controller/macos.rs b/src/view/controller/macos.rs new file mode 100644 index 0000000..7f4860c --- /dev/null +++ b/src/view/controller/macos.rs @@ -0,0 +1,73 @@ +//! Hoists a basic `NSViewController`. + +use std::sync::Once; + +use objc::declare::ClassDecl; +use objc::runtime::{Class, Object, Sel}; +use objc::{class, msg_send, sel, sel_impl}; + +use crate::view::{VIEW_DELEGATE_PTR, ViewDelegate}; +use crate::utils::load; + +/// Called when the view controller receives a `viewWillAppear` message. +extern fn will_appear(this: &mut Object, _: Sel) { + unsafe { + let _: () = msg_send![super(this, class!(NSViewController)), viewWillAppear]; + } + + let controller = load::(this, VIEW_DELEGATE_PTR); + controller.will_appear(false); +} + +/// Called when the view controller receives a `viewDidAppear` message. +extern fn did_appear(this: &mut Object, _: Sel) { + unsafe { + let _: () = msg_send![super(this, class!(NSViewController)), viewDidAppear]; + } + + let controller = load::(this, VIEW_DELEGATE_PTR); + controller.did_appear(false); +} + +/// Called when the view controller receives a `viewWillDisappear` message. +extern fn will_disappear(this: &mut Object, _: Sel) { + unsafe { + let _: () = msg_send![super(this, class!(NSViewController)), viewWillDisappear]; + } + + let controller = load::(this, VIEW_DELEGATE_PTR); + controller.will_disappear(false); +} + +/// Called when the view controller receives a `viewDidDisappear` message. +extern fn did_disappear(this: &mut Object, _: Sel) { + unsafe { + let _: () = msg_send![super(this, class!(NSViewController)), viewDidDisappear]; + } + + let controller = load::(this, VIEW_DELEGATE_PTR); + controller.did_disappear(false); +} + +/// Registers an `NSViewDelegate`. +pub(crate) fn register_view_controller_class() -> *const Class { + static mut VIEW_CLASS: *const Class = 0 as *const Class; + static INIT: Once = Once::new(); + + INIT.call_once(|| unsafe { + let superclass = class!(NSViewController); + let mut decl = ClassDecl::new("RSTViewController", superclass).unwrap(); + + decl.add_ivar::(VIEW_DELEGATE_PTR); + + // NSViewDelegate + decl.add_method(sel!(viewWillAppear), will_appear:: as extern fn(&mut Object, _)); + decl.add_method(sel!(viewDidAppear), did_appear:: as extern fn(&mut Object, _)); + decl.add_method(sel!(viewWillDisappear), will_disappear:: as extern fn(&mut Object, _)); + decl.add_method(sel!(viewDidDisappear), did_disappear:: as extern fn(&mut Object, _)); + + VIEW_CLASS = decl.register(); + }); + + unsafe { VIEW_CLASS } +} diff --git a/src/view/ios.rs b/src/view/ios.rs new file mode 100644 index 0000000..1e835ed --- /dev/null +++ b/src/view/ios.rs @@ -0,0 +1,45 @@ +use std::sync::Once; + +use objc::declare::ClassDecl; +use objc::runtime::{Class, Object, Sel, BOOL}; +use objc::{class, sel, sel_impl}; +use objc_id::Id; + +use crate::foundation::{id, YES, NO, NSUInteger}; +use crate::dragdrop::DragInfo; +use crate::view::{VIEW_DELEGATE_PTR, ViewDelegate}; +use crate::utils::load; + +/// Injects an `NSView` subclass. This is used for the default views that don't use delegates - we +/// have separate classes here since we don't want to waste cycles on methods that will never be +/// used if there's no delegates. +pub(crate) fn register_view_class() -> *const Class { + static mut VIEW_CLASS: *const Class = 0 as *const Class; + static INIT: Once = Once::new(); + + INIT.call_once(|| unsafe { + let superclass = class!(UIView); + let mut decl = ClassDecl::new("RSTView", superclass).unwrap(); + VIEW_CLASS = decl.register(); + }); + + unsafe { VIEW_CLASS } +} + +/// Injects an `NSView` subclass, with some callback and pointer ivars for what we +/// need to do. +pub(crate) fn register_view_class_with_delegate() -> *const Class { + static mut VIEW_CLASS: *const Class = 0 as *const Class; + static INIT: Once = Once::new(); + + INIT.call_once(|| unsafe { + let superclass = class!(UIView); + let mut decl = ClassDecl::new("RSTViewWithDelegate", superclass).unwrap(); + decl.add_ivar::(VIEW_DELEGATE_PTR); + VIEW_CLASS = decl.register(); + }); + + unsafe { + VIEW_CLASS + } +} diff --git a/src/view/macos.rs b/src/view/macos.rs new file mode 100644 index 0000000..af49ce9 --- /dev/null +++ b/src/view/macos.rs @@ -0,0 +1,125 @@ +//! This module does one specific thing: register a custom `NSView` class that's... brought to the +//! modern era. +//! +//! I kid, I kid. +//! +//! It just enforces that coordinates are judged from the top-left, which is what most people look +//! for in the modern era. It also implements a few helpers for things like setting a background +//! color, and enforcing layer backing by default. + +use std::sync::Once; + +use objc::declare::ClassDecl; +use objc::runtime::{Class, Object, Sel, BOOL}; +use objc::{class, sel, sel_impl}; +use objc_id::Id; + +use crate::foundation::{id, YES, NO, NSUInteger}; +use crate::dragdrop::DragInfo; +use crate::view::{VIEW_DELEGATE_PTR, ViewDelegate}; +use crate::utils::load; + +/// Enforces normalcy, or: a needlessly cruel method in terms of the name. You get the idea though. +extern fn enforce_normalcy(_: &Object, _: Sel) -> BOOL { + return YES; +} + +/// Called when a drag/drop operation has entered this view. +extern fn dragging_entered(this: &mut Object, _: Sel, info: id) -> NSUInteger { + let view = load::(this, VIEW_DELEGATE_PTR); + view.dragging_entered(DragInfo { + info: unsafe { Id::from_ptr(info) } + }).into() +} + +/// Called when a drag/drop operation has entered this view. +extern fn prepare_for_drag_operation(this: &mut Object, _: Sel, info: id) -> BOOL { + let view = load::(this, VIEW_DELEGATE_PTR); + + match view.prepare_for_drag_operation(DragInfo { + info: unsafe { Id::from_ptr(info) } + }) { + true => YES, + false => NO + } +} + +/// Called when a drag/drop operation has entered this view. +extern fn perform_drag_operation(this: &mut Object, _: Sel, info: id) -> BOOL { + let view = load::(this, VIEW_DELEGATE_PTR); + + match view.perform_drag_operation(DragInfo { + info: unsafe { Id::from_ptr(info) } + }) { + true => YES, + false => NO + } +} + +/// Called when a drag/drop operation has entered this view. +extern fn conclude_drag_operation(this: &mut Object, _: Sel, info: id) { + let view = load::(this, VIEW_DELEGATE_PTR); + + view.conclude_drag_operation(DragInfo { + info: unsafe { Id::from_ptr(info) } + }); +} + +/// Called when a drag/drop operation has entered this view. +extern fn dragging_exited(this: &mut Object, _: Sel, info: id) { + let view = load::(this, VIEW_DELEGATE_PTR); + + view.dragging_exited(DragInfo { + info: unsafe { Id::from_ptr(info) } + }); +} + +/// Injects an `NSView` subclass. This is used for the default views that don't use delegates - we +/// have separate classes here since we don't want to waste cycles on methods that will never be +/// used if there's no delegates. +pub(crate) fn register_view_class() -> *const Class { + static mut VIEW_CLASS: *const Class = 0 as *const Class; + static INIT: Once = Once::new(); + + INIT.call_once(|| unsafe { + let superclass = class!(NSView); + let mut decl = ClassDecl::new("RSTView", superclass).unwrap(); + + decl.add_method(sel!(isFlipped), enforce_normalcy as extern fn(&Object, _) -> BOOL); + + VIEW_CLASS = decl.register(); + }); + + unsafe { VIEW_CLASS } +} + +/// Injects an `NSView` subclass, with some callback and pointer ivars for what we +/// need to do. +pub(crate) fn register_view_class_with_delegate() -> *const Class { + static mut VIEW_CLASS: *const Class = 0 as *const Class; + static INIT: Once = Once::new(); + + INIT.call_once(|| unsafe { + let superclass = class!(NSView); + let mut decl = ClassDecl::new("RSTViewWithDelegate", superclass).unwrap(); + + // A pointer to the "view controller" on the Rust side. It's expected that this doesn't + // move. + decl.add_ivar::(VIEW_DELEGATE_PTR); + + decl.add_method(sel!(isFlipped), enforce_normalcy as extern fn(&Object, _) -> BOOL); + + // Drag and drop operations (e.g, accepting files) + decl.add_method(sel!(draggingEntered:), dragging_entered:: as extern fn (&mut Object, _, _) -> NSUInteger); + decl.add_method(sel!(prepareForDragOperation:), prepare_for_drag_operation:: as extern fn (&mut Object, _, _) -> BOOL); + decl.add_method(sel!(performDragOperation:), perform_drag_operation:: as extern fn (&mut Object, _, _) -> BOOL); + decl.add_method(sel!(concludeDragOperation:), conclude_drag_operation:: as extern fn (&mut Object, _, _)); + decl.add_method(sel!(draggingExited:), dragging_exited:: as extern fn (&mut Object, _, _)); + + VIEW_CLASS = decl.register(); + }); + + unsafe { + VIEW_CLASS + } +}