├── .gitignore ├── LICENSE.txt ├── README.md ├── media ├── demo-alfred-keyword-trigger.png ├── demo-notification-dismisser-in-action-1.gif └── demo-notification-dismisser-in-action-2.gif └── src └── dismiss-active-notifications.applescript /.gitignore: -------------------------------------------------------------------------------- 1 | ### macOS ### 2 | # General 3 | .DS_Store 4 | .AppleDouble 5 | .LSOverride 6 | 7 | # Icon must end with two \r 8 | Icon 9 | 10 | # Thumbnails 11 | ._* 12 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 zakyum 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Notification Dismisser 2 | >*Ever opened your Mac, just to have a million notifications pop up in you face and didn't feel like manually closing all of them? Or didn't feel like lifting your fingers from the keyboard (and wasting precious seconds!) just to dismiss a random notification from your boss?* 3 | \ 4 | \ 5 | *Then you've come to the right place!* 6 |
7 | 8 | ## About 9 | Simple Alfred workflow to dismiss all active (currently visible) notifications. 10 | - **Without using the mouse**, either by pressing a shortcut or typing a keyword into Alfred. 11 | - **No external dependencies**, just a bit of AppleScript. 12 | 13 | ## Demo 14 | 15 | 16 | ### Brief Explanation: 17 | 1. Shortcut is pressed. 18 | 2. Banner notifications are dismissed. In this example, the "Script Editor" notification. 19 | 3. Alert notifications are dismissed one-by-one. 20 | 4. Relax and enjoy your precious saved seconds 😌. 21 |
22 | 23 | ## Installing 24 | 1. Click this [download](https://github.com/zakyum/alfred-notification-dismisser/releases/download/v1.0.0/alfred-notification-dismisser.alfredworkflow) button or navigate to this project's releases page. 25 | 2. Double-click the downloaded workflow and import into Alfred. 26 | 3. Open the workflow and set a keyboard shortcut. [optional] 27 | 28 | ## Usage 29 | Launch the workflow by pressing the keyboard shortcut or by typing "dismiss" into Alfred. 30 | ![Usage](./media/demo-alfred-keyword-trigger.png) 31 | 32 | ## Specifics 33 | - All the work is done via the AppleScript, the Alfred workflow only runs the script. 34 | - Dismisses only the active/visible notifications on the screen, doesn't touch the notifications in notification center. 35 | - Dismisses alert notifications only if they have a close button, otherwise displays error. 36 | - Detects stuck notifications and displays error, but if there are currently more than 20 notifications will cause a false positive (reason why documented in code). 37 | 38 | ## FAQ 39 | - **Q:** How are banner notifications dismissed if they don't have any buttons?\ 40 | **A:** Banner notifications are cleared on notification center restart, so we "dismiss" them by restarting notification center. As far as I know, there is no way to dismiss banner notifications via GUI (AppleScript). 41 | 42 | - **Q:** Why are alert notifications closed one by one?\ 43 | **A:** Alert notifications persist notification center restarts and, as far as I know, there isn't a way to batch close them, so we do it via GUI one by one. 44 | 45 | ## License 46 | [MIT License](./LICENSE.txt) 47 | -------------------------------------------------------------------------------- /media/demo-alfred-keyword-trigger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zakyum/alfred-notification-dismisser/e9cb4434c84880a7adda124f1c756f6481ee73c5/media/demo-alfred-keyword-trigger.png -------------------------------------------------------------------------------- /media/demo-notification-dismisser-in-action-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zakyum/alfred-notification-dismisser/e9cb4434c84880a7adda124f1c756f6481ee73c5/media/demo-notification-dismisser-in-action-1.gif -------------------------------------------------------------------------------- /media/demo-notification-dismisser-in-action-2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zakyum/alfred-notification-dismisser/e9cb4434c84880a7adda124f1c756f6481ee73c5/media/demo-notification-dismisser-in-action-2.gif -------------------------------------------------------------------------------- /src/dismiss-active-notifications.applescript: -------------------------------------------------------------------------------- 1 | my dismissActiveNotifications() 2 | 3 | on dismissActiveNotifications() 4 | set nDismissedNotifications to 0 5 | 6 | repeat # until there are none notifications left 7 | my checkIfNotificationStuck(nDismissedNotifications) 8 | 9 | set notification to my getFirstNotification() 10 | if notification is missing value then 11 | log "No notifications, done" 12 | return 13 | end if 14 | 15 | # notification have to be closed differently based on type 16 | tell application "System Events" ¬ 17 | to set notificationType to role description of notification 18 | 19 | if notificationType contains "alert" then 20 | my dismissAlertNotification(notification) 21 | else if notificationType contains "banner" then 22 | my dismissAllBannerNotifications() 23 | else # something weird 24 | display notification "Manual closing required" ¬ 25 | with title "Error: non-standard notification" 26 | error "Error: unknown notification type" 27 | end if 28 | 29 | set nDismissedNotifications to (nDismissedNotifications + 1) 30 | end repeat 31 | end dismissActiveNotifications 32 | 33 | on getFirstNotification() 34 | tell application "System Events" ¬ 35 | to set notificationWindows to windows of process "Notification Center" 36 | 37 | if ((count notificationWindows) < 1) then 38 | return missing value 39 | end if 40 | 41 | set notification to first item of notificationWindows 42 | 43 | # if notification center is open, then it occupies the first window and 44 | #+ is a false positive, in that case we try to get the 2nd window 45 | set isNotificationCenterOpen to ((name of notification) is "Notification Center") 46 | if isNotificationCenterOpen then 47 | log "Notification center is open" 48 | 49 | # if another window exists then it is a genuine notification 50 | if ((count notificationWindows) > 1) then 51 | set notification to second item of notificationWindows 52 | else 53 | return missing value 54 | end if 55 | end if 56 | 57 | return notification 58 | end getFirstNotification 59 | 60 | on dismissAlertNotification(notification) 61 | tell application "System Events" ¬ 62 | to set closeButton to a reference to button "Close" of notification 63 | 64 | if closeButton exists then 65 | log "Dismissing an alert notification" 66 | tell application "System Events" to click closeButton 67 | delay 0.2 # wait (approximately) for it to disappear 68 | else 69 | # some applications make custom alert notifications without a close 70 | #+ button (e.g. System Preferences with its update alert) 71 | display notification "Manual closing required" ¬ 72 | with title "Error: notification has no close button" 73 | error "Error: can't close alert notification, no close button" 74 | end if 75 | end dismissAlertNotification 76 | 77 | on dismissAllBannerNotifications() 78 | log "Dismissing all banner notifications" 79 | 80 | # banner notifications don't have any buttons so our 81 | #+ only option is to "restart" the notification center 82 | # restarting it removes all banner notifications 83 | do shell script "killall NotificationCenter" 84 | 85 | # wait for NotificationCenter to "restart" so that we can 86 | #+ normally process any remaining notifications (i.e. alert 87 | #+ notifications as they persist restarts) 88 | delay 1 89 | end dismissAllBannerNotifications 90 | 91 | on checkIfNotificationStuck(nDismissedNotifications) 92 | # if we dismiss (or think we dismissed) more than 20 notifications 93 | #+ abort as then there is a high probabily that a notification got 94 | #+ stuck, then abort 95 | set isNotificationStuck to (nDismissedNotifications > 20) 96 | if isNotificationStuck then 97 | display notification "Manual closing required" ¬ 98 | with title "Error: can't close notifications" 99 | error "Error: can't close notifications, possibly a stuck notification" 100 | end if 101 | end checkIfNotificationStuck --------------------------------------------------------------------------------