Ich habe lange ein Applescript verwendet, das von einer Tastenkombination ausgelöst wurde, um Benachrichtigungen unter MacOS zu schließen. Es funktionierte, indem es einen Klick auf die Schaltfläche "Schließen" jedes geöffneten Fensters der Benachrichtigungszentrale simulierte.
Seit dem Upgrade auf Big Sur (derzeit 11.0.1) haben Benachrichtigungen keinen Schließen-Button mehr. Wenn Sie stattdessen mit der Maus darüber fahren, wird eine Schaltfläche "X" angezeigt. Für eine Person, die Schwierigkeiten beim genauen Klicken hat (ich habe ein leichtes Zittern der Hand), ist die Verwendung der Maus/des Trackpads schwierig.
Hat jemand Vorschläge, wie ich diese Funktionalität wiederherstellen kann, damit ich meine Hände einfach auf der Tastatur lassen kann?
Ich verwende Automator, um dies zu testen.
In Systemeinstellungen > Benachrichtigungen habe ich Automator ausgewählt :
test 1
, test 2
, und test 3
.subtitle 1
, subtitle 2
, und subtitle 3
.message 1
, message 2
, und message 3
.test 3
ist vollständig sichtbar und hat unten den Vermerk "2 weitere Benachrichtigungen".#!/usr/bin/osascript
am Anfang des Skripts hinzugefügt und als andrew.applescript
.chmod 755 andrew.applescript
)../andrew.applescript
)test 3
, test 2
, und test 1
von oben nach unten im Benachrichtigungsbereich gestapelt./andrew.applescript:370:377: execution error: System Events got an error: Can’t get action "Name:Clear All
Target:0x60000116ff20
Selector:_internal_handleCustomActionWithUiAction:" of group 1 of UI element 1 of scroll area 1 of window "Notification Center" of application process "NotificationCenter". (-1728)
Ich werde versuchen, damit herumzuspielen, um zu sehen, ob ich es mit Modifikationen zum Laufen bringen kann.
Hinweis: Wenn ich das Skript erneut ausführe, beginnend mit dem nicht gruppierten Zustand:
test 3
)action Name:Close
Target:0x60000116ff20
Selector:_internal_handleCustomActionWithUiAction: of group 1 of UI element 1 of scroll area 1 of window Notification Center of application process NotificationCenter
Ich poste eine robusteste Version, die sich aus meinem ersten Beitrag entwickelt hat. Dies scheint einen vernünftigen Job zum Schließen aller Fenster zu machen, aber es ist manchmal langsam in der Ausführung. Wie ich in den Kommentaren gesagt habe, weiß ich nicht viel über AppleScript, also kann uns vielleicht jemand, der weiß, was er tut, sagen, wie wir die Leistung verbessern können.
activate application "NotificationCenter"
tell application "System Events"
tell process "Notification Center"
repeat
try
set theWindow to group 1 of UI element 1 of scroll area 1 of window "Notification Center"
on error
exit repeat
end try
try
set theActions to actions of theWindow
# Try to close the whole group first. If that fails, close individual windows.
repeat with theAction in theActions
if description of theAction is "Clear All" then
set closed to true
tell theWindow
perform theAction
end tell
exit repeat
end if
end repeat
repeat with theAction in theActions
if description of theAction is "Close" then
set closed to true
tell theWindow
perform theAction
end tell
exit repeat
end if
end repeat
end try
end repeat
end tell
end tell
Ja, danke für die Veröffentlichung des Skripts, @AndrewJanian.
Ich habe einen Fehler ähnlich dem von @ColinFraizer erhalten, wenn ich ihn so verwende, wie er ist. Ich denke, das Problem ist die innere Wiederholung der Aktionen: In einigen Fällen wird versucht, auf Aktionen zuzugreifen, nachdem das Fenster geschlossen wurde. Eine kleine Änderung behebt dieses Problem für mich:
activate application "NotificationCenter"
tell application "System Events"
tell process "Notification Center"
set theWindow to group 1 of UI element 1 of scroll area 1 of window "Notification Center"
# click theWindow
set theActions to actions of theWindow
repeat with theAction in theActions
if description of theAction is "Close" then
tell theWindow
perform theAction
end tell
exit repeat
end if
end repeat
end tell
end tell
set theWindow
Zeile durch zu ersetzenset theWindow to group 1 of UI element 1 of scroll area 1 of UI element 1 of window "Notification Center"
Ich habe ein AppleScript, das funktioniert. Ich habe die Elemente mit UIBrowser gefunden . Vorbehalt ist, dass die Benachrichtigung eine „Schließen“-Aktion haben muss. Alle Benachrichtigungen, auf die ich gestoßen bin, haben diese Aktion.
activate application "NotificationCenter"
tell application "System Events"
tell process "Notification Center"
set theWindow to group 1 of UI element 1 of scroll area 1 of window "Notification Center"
click theWindow
set theActions to actions of theWindow
repeat with theAction in theActions
if description of theAction is "Close" then
tell theWindow
perform theAction
end tell
end if
end repeat
end tell
end tell
Ich habe eine Automator- JavaScript-Aktion gefunden , die funktioniert:
function run(input, parameters) {
const notNull = (val) => {
return val !== null && val !== undefined;
}
const appName = "";
const verbose = true;
const CLEAR_ALL_ACTION = "Clear All";
const CLOSE_ACTION = "Close";
const hasAppName = notNull(appName) && appName !== "";
const appNameForLog = hasAppName ? (" " + appName) : "";
const log = (message, ...optionalParams) => {
console.log("[close_notifications] " + message, optionalParams);
}
const logVerbose = (message) => {
if (verbose) {
log(message);
}
}
const findCloseAction = (group, closedCount) => {
try {
let clearAllAction;
let closeAction;
for (let action of group.actions()) {
if (action.description() === CLEAR_ALL_ACTION) {
clearAllAction = action;
break;
} else if (action.description() === CLOSE_ACTION) {
closeAction = action;
}
}
if (notNull(clearAllAction)) {
return clearAllAction;
} else if (notNull(closeAction)) {
return closeAction;
}
} catch (err) {
logVerbose(`${closedCount}: Caught error while searching for close action, window is probably closed.`);
logVerbose(err);
return null;
}
log("No close action found for notification");
return null;
}
const notificationGroupMatches = (group) => {
if (!hasAppName) {
return true;
}
logVerbose(`Checking UI elements of group...`);
try {
for (let elem of group.uiElements()) {
if (hasAppName && elem.role() === "AXStaticText" && elem.value().toLowerCase() === appName.toLowerCase()) {
return true;
}
}
} catch (err) {
logVerbose(`Caught error while checking window, window is probably closed.`);
logVerbose(err);
}
return false;
}
const closeNextGroup = (groups, closedCount) => {
for (let group of groups) {
if (notificationGroupMatches(group)) {
logVerbose(`${closedCount}: FIND_CLOSE_ACTION`);
let closeAction = findCloseAction(group, closedCount);
if (notNull(closeAction)) {
logVerbose(`${closedCount}: CLOSING`);
try {
closeAction.perform();
logVerbose(`${closedCount}: CLOSE_PERFORMED`);
return [true, 1];
} catch (err) {
logVerbose(`${closedCount}: Caught error while performing close action, window is probably closed.`);
logVerbose(err);
}
}
return [true, 0];
}
}
return false;
}
const getNotificationCenter = () => {
let systemEvents = Application("System Events");
return systemEvents.processes.byName("NotificationCenter");
}
const getNotificationCenterGroups = () => {
return getNotificationCenter().windows[0].uiElements[0].uiElements[0].uiElements();
}
let notificationCenter = getNotificationCenter();
if (notificationCenter.windows.length <= 0) {
return input;
}
let groupsCount = getNotificationCenterGroups().filter(group => notificationGroupMatches(group)).length;
if (groupsCount > 0) {
logVerbose(`Closing ${groupsCount}${appNameForLog} notification group${(groupsCount > 1 ? "s" : "")}`);
let closedCount = 0;
let maybeMore = true;
while (maybeMore) {
let closeResult = closeNextGroup(getNotificationCenterGroups(), closedCount);
maybeMore = closeResult[0];
if (maybeMore) {
closedCount = closedCount + closeResult[1];
}
}
} else {
throw Error(`No${appNameForLog} notifications found...`);
}
return input;
}
Das hat mich auch genervt, aber ich habe es heute geschafft, etwas zum Laufen zu bringen.
Zuerst habe ich clicclick installiert , ein Befehlszeilentool, mit dem Sie Mausbewegungen und Klicks simulieren können. Es ist über Homebrew mit verfügbar brew install cliclick
.
Dann habe ich die Koordinaten der Zeit oben rechts herausgefunden, die beim Klicken das Benachrichtigungszentrum öffnen. Dies erforderte ein wenig Experimentieren.
Dann habe ich die Koordinaten der Schließen-Schaltfläche herausgefunden, die beim Hover erscheint. Auch dies erforderte ein wenig Experimentieren.
Dann habe ich ein Skript geschrieben, das cliclick
diese Koordinaten verwendet, um das Benachrichtigungszentrum zu öffnen, die Maus über die Stelle zu bewegen, an der die Schaltfläche "Löschen" erscheint, 500 Millisekunden lang in den Ruhezustand versetzt wird, damit sie Zeit zum Erscheinen hat, und dann darauf klickt. Es funktionierte!
export PATH=/usr/local/bin:$PATH # make sure cliclick binary is on the path
cliclick c:1900,10 # click on the time to open Notification Center
cliclick -w 500 m:1570,45 c:. # move mouse over the close button, wait for it to appear, then click it
Ich habe dann versucht, dies als Automator-Dienst zum Laufen zu bringen. Ich habe es in Automator zum Laufen gebracht, aber obwohl das Skript dort funktionierte, funktionierte es nicht, als ich es einer Tastenkombination zuwies. Ich schlug meinen Kopf gegen eine Mauer und probierte verschiedene Berechtigungen usw. aus, bis ich aufgab.
Ich habe die HotKey-App ausprobiert, hatte aber das gleiche Ergebnis.
Irgendwann dachte ich darüber nach, einen Alfred-Workflow auszuprobieren, damit ich Alfred mit Cmd+Leertaste öffnen und dann „Benachrichtigungen löschen“ eingeben könnte, um sie zu löschen. Viel ausführlicher als eine Tastenkombination, aber ... es hat funktioniert! Und keine Maus benötigt. Meine beste Vermutung, warum Alfred das Skript ausführt, wird immer von Alfred aus ausgeführt , und Alfred hat bereits die erforderlichen Berechtigungen, um die Maus zu bewegen und auf Dinge zu klicken, aber wenn ich versuche, einen Automator-Dienst an eine Tastenkombination anzuhängen , wird dieser Dienst mit allen Berechtigungen ausgeführt, über die die aktuell fokussierte App verfügt.
Das fühlt sich wie eine schrecklich spröde Lösung an (was passiert, wenn ich meinen externen Monitor nicht verwende??) und es scheint Müll zu sein, dass es keine eingebaute Möglichkeit gibt, dies zu tun, aber zumindest funktioniert es.
TL;DR eine Kombination aus einem Skript cliclick
und einem Alfred-Workflow, um es auszuführen.
Ich habe die meisten der hier angebotenen Lösungen ausprobiert, aber keine hat so gut funktioniert, wie ich möchte. Seitdem habe ich versucht, Keysmith zu verwenden , und war mit den Ergebnissen ziemlich zufrieden.
Keysmith bietet hierfür eine vorhandene Verknüpfung an. Es sieht aus wie das:
Dadurch haben Sie die Möglichkeit, ⌘ escBenachrichtigungen zu schließen (von jeder Anwendung aus).
Das einzige Problem, das ich damit hatte, war, dass nach dem Schließen der Benachrichtigungen das aktive Fenster der aktuellen Anwendung den Fokus verlor. Glücklicherweise können Sie der Keysmith-Verknüpfung einen zusätzlichen Schritt hinzufügen, um den Fokus des aktiven Fensters wiederzuerlangen: ⌃F4. Das sieht in Keysmith so aus:
Danke @lunzwell. Ich habe eine Fehlerroutine hinzugefügt.
on run
try
activate application "NotificationCenter"
tell application "System Events"
tell process "Mitteilungszentrale"
set theWindow to group 1 of UI element 1 of scroll area 1 of window "Notification Center"
# click theWindow
set theActions to actions of theWindow
repeat with theAction in theActions
if description of theAction is "Schließen" then
tell theWindow
perform theAction
end tell
exit repeat
end if
end repeat
end tell
end tell
on error e
display dialog e
activate
end try
end run
Ich frage mich jedoch, ob es eine Möglichkeit gibt, eine Fehlermeldung zu vermeiden, wenn das Skript versehentlich ohne Benachrichtigungen auf dem Bildschirm ausgeführt wird.
Ich habe einige Verbesserungen an diesem Skript vorgenommen:
"Clear All"
Schaltfläche hinzugefügt (ich fand, dass ich manchmal diese anstelle von verwenden musste "Close"
)Mein vollständiges Skript befindet sich hier in meinen Dotfiles auf GitHub und ich habe es über einen Alfred-Workflow hier verfügbar gemacht .
#!/usr/bin/osascript
# via:
# https://apple.stackexchange.com/questions/408019/dismiss-macos-big-sur-notifications-with-keyboard
# define a function we can call recursively
on dismiss_notification_center(n)
log "dismiss_notification_center: " & n
set performedAction to false
activate application "NotificationCenter"
tell application "System Events"
tell process "Notification Center"
try
# when there are no notifications, this may result in:
# 'System Events got an error: Can’t get window "Notification Center" of process "Notification Center".'
# This is our recursion base case.
set theWindow to group 1 of UI element 1 of scroll area 1 of window "Notification Center"
on error e
# log the error to the console:
log quoted form of e
return
end try
# log theWindow
set theActions to actions of theWindow
repeat with theAction in theActions
# log theAction
# log description of theAction
if description of theAction is in {"Close", "Clear All"} then
tell theWindow
perform theAction
set performedAction to true
end tell
exit repeat
end if
end repeat
end tell
end tell
# log "performedAction: " & performedAction
if performedAction
# for some reason, the loop doesn't close them all when grouped, so
# we need to recurse. But, first we have to sleep to allow notif to re-appear:
do shell script "/bin/sleep 3" # min sleep time that worked for me, and sometimes reminders take even longer
dismiss_notification_center(n + 1)
end if
end dismiss_notification_center
# first call to recursive function:
dismiss_notification_center(0)
Ich habe auch ein funktionierendes Skript über Clickclick bekommen. Hier ist meine Version des Skripts, das ich verwende. Ich habe aus einer Reihe von Benutzerbibliotheken, die ich verwendet habe, genäht. Ich habe es der über Automator erstellten Sprachsteuerung anstelle einer Tastenkombination zugeordnet.
Es schlägt immer noch fehl, wenn die Benachrichtigung sich weigert, die Schließen-Schaltfläche anzuzeigen, egal wie weit Sie den Mauszeiger darüber bewegen.
activate application "NotificationCenter"
delay 0.1
tell application "System Events" to tell process "Notification Center"
if (count of windows) is 0 then return
set theGroup to first group of UI element 1 of scroll area 1 of window "Notification Center"
tell theGroup
if my isStacked(theGroup) then
click theGroup
delay 1
end if
my dismissNotification(theGroup)
end tell
end tell
on isStacked(nextGroup)
tell application "System Events" to tell process "Notification Center"
get help of nextGroup is "Activate to expand"
end tell
end isStacked
to dismissNotification(theNotification)
script CloseButtonClicker
-- pointer's saveCurrentPosition()
movePointer at theNotification
delay 0.1
tell application "System Events"
try
click button "Close" of theNotification
return true
end try
delay 0.1
end tell
-- pointer's restorePosition()
end script
exec on CloseButtonClicker for 3 by 0.4 -- Retry on failure up to 3x. Optional.
end dismissNotification
to movePointer at theUi
set coord to getCoord at theUi
set formattedCoord to formatCoordinates(item 1 of coord, item 2 of coord)
set clickCommand to "/usr/local/bin/cliclick -e 1 m:" & formattedCoord
do shell script clickCommand
end movePointer
to formatCoordinates(x, y)
if x is less than 0 then set x to "=" & x
if y is less than 0 then set y to "=" & y
return x & "," & y as text
end formatCoordinates
to exec on scriptObj by sleep : 1 for ntimes : 1000
repeat ntimes times
try
set handlerResult to run of scriptObj
if handlerResult is not missing value then return handlerResult
end try
delay sleep
end repeat
return missing value
end exec
Hatte jemand darüber nachgedacht, einfach zu verwenden:
pkill NotificationCenter
Der Prozess wird danach erneut gestartet. Ich verwende es, um alle Benachrichtigungen zu löschen, die ich mit einem externen Laufwerk erhalte.
Diese Antwort deutet darauf hin, dass es in Big Sur in seiner aktuellen Version keine zufriedenstellende Möglichkeit gibt, Benachrichtigungen mit einer Tastatur zu schließen. Stattdessen erläutert diese Antwort alternative Möglichkeiten, sie zu schließen, die an anderer Stelle in diesem Thread nicht erwähnt werden.
Zwei-Finger-Wischen nach rechts in der Benachrichtigungsgruppe funktioniert auf Big Sur mit dem Trackpad des Macbooks (bei Yosemite nicht sicher). Es funktioniert auch mit Linksklick und Ziehen nach rechts. Ich gehe davon aus, dass dies auch mit einer Apple Magic Mouse oder einem Magic Trackpad funktionieren würde. Ich persönlich finde sowohl das Streichen mit zwei Fingern als auch das Klicken und Ziehen mit der linken Maustaste einfacher, als auf das X-Symbol zu klicken und dann auf Alles löschen zu klicken. Ich finde es sehr schwierig, den Doppelklick auf so einem kleinen Gebiet zu koordinieren.
Dadurch werden nicht alle Benachrichtigungen dauerhaft "gelöscht". Sie werden weiterhin angezeigt, wenn Sie die Benachrichtigungsseitenleiste öffnen. Sie zeigen auch an, ob eine andere Nachricht durchkommt; Anstelle von 1 Benachrichtigung werden N + 1 verfügbare Benachrichtigungen angezeigt.
Diese Idee wurde in einem Kommentar in einer anderen Antwort vermerkt: Dismiss MacOS Big Sur Notifications with keyboard .
Der Grund, warum ich vorschlage, dass es keine zufriedenstellende Möglichkeit gibt, Benachrichtigungen mit einer Tastatur zu schließen, ist: Ein automatisiertes Skript ist bei einer großen Anzahl von Benachrichtigungen merklich langsam, die Keysmith-Lösung funktionierte nicht auf Big Sur (es war ein Fehler), pkill/killall NotificationCenter hat nicht funktioniert, die Benachrichtigungen schließen (was bedeutet, dass eine Tastenkombination dafür nicht helfen würde). Ich habe die Clickclick-Lösung nicht ausprobiert, weil ich befürchtete, dass ich zu viel Zeit damit verschwenden würde, sie zum Laufen zu bringen, und dass sie die gleichen Verzögerungen erfahren würde wie ein automatisiertes Skript.
Dieser Thread ist ähnlich wie Wie lösche ich alle OS X-Benachrichtigungen mit einem Klick? .
Aivar Paalberg
Colin Fraiser
X
Schaltfläche, auf die geklickt werden kann – es ist fast so, als wollten sie sie so klein machen wie die „Schließen“-Schaltfläche für Handy-Anzeigen. :-)Aivar Paalberg
X
wenn Sie ein Trackpad haben. Während Sie irgendwo über der Benachrichtigung schweben, sollten Sie sie mit zwei Fingern von links nach rechts schließen. Aus Produktivitätssicht glaube ich persönlich nicht, dass Benachrichtigungen auf dem Desktop und die sofortige Interaktion mit ihnen ein guter Workflow sind.Colin Fraiser
Snikola