90 lines
3.6 KiB
JavaScript
90 lines
3.6 KiB
JavaScript
import * as Main from "resource:///org/gnome/shell/ui/main.js";
|
|
import { Extension } from "resource:///org/gnome/shell/extensions/extension.js";
|
|
import { isMatch } from "./isMatch.js";
|
|
export var LogLevel;
|
|
(function (LogLevel) {
|
|
LogLevel["DEBUG"] = "debug";
|
|
LogLevel["INFO"] = "info";
|
|
LogLevel["WARN"] = "warn";
|
|
LogLevel["ERROR"] = "error";
|
|
})(LogLevel || (LogLevel = {}));
|
|
function getObjectLabel(name, values) {
|
|
const labels = Object.entries(values)
|
|
.filter(([_, value]) => value)
|
|
.map(([label, value]) => `${label}: '${value}'`);
|
|
return `${name}(${labels.join(", ")})`;
|
|
}
|
|
function getWindowLabel(window) {
|
|
return getObjectLabel("Window", {
|
|
["Title"]: window.title,
|
|
["WMClass"]: window.wmClass,
|
|
["GTKAppId"]: window.gtkApplicationId,
|
|
["SandboxedAppId"]: window.get_sandboxed_app_id(),
|
|
});
|
|
}
|
|
function getSourceLabel(source) {
|
|
return getObjectLabel("Source", {
|
|
["Title"]: source.title,
|
|
["Icon"]: source.icon?.to_string(),
|
|
});
|
|
}
|
|
export default class JunkNotificationCleaner extends Extension {
|
|
focusListenerId = null;
|
|
closeListenerId = null;
|
|
settings = null;
|
|
log(level, message) {
|
|
let minLevel = this.settings.get_string("log-level");
|
|
const levels = Object.values(LogLevel);
|
|
if (!levels.includes(minLevel))
|
|
minLevel = LogLevel.INFO;
|
|
if (levels.indexOf(level) >= levels.indexOf(minLevel)) {
|
|
log(`[${this.metadata.uuid}][${level}] ${message}`);
|
|
}
|
|
}
|
|
clearNotificationsForApp(window, event) {
|
|
const windowLabel = getWindowLabel(window);
|
|
this.log(LogLevel.DEBUG, `${windowLabel}: received ${event}`);
|
|
const excludedApps = this.settings.get_strv("excluded-apps");
|
|
for (const wmClassPattern of excludedApps) {
|
|
if (new RegExp(wmClassPattern).test(window.wmClass)) {
|
|
this.log(LogLevel.DEBUG, `${windowLabel}: excluded by '${wmClassPattern}'`);
|
|
return;
|
|
}
|
|
}
|
|
for (const source of Main.messageTray.getSources()) {
|
|
const sourceLabel = getSourceLabel(source);
|
|
for (const notification of [...source.notifications]) {
|
|
this.log(LogLevel.DEBUG, `${windowLabel}: ${sourceLabel}: found ${notification.isTransient ? "transient" : "persistent"} notification${notification.title ? `: ${notification.title}` : ""}`);
|
|
if (isMatch(window, source) && !notification.isTransient) {
|
|
notification.destroy();
|
|
this.log(LogLevel.INFO, `${windowLabel}: ${sourceLabel}: removed notification${notification.title ? `: ${notification.title}` : ""}`);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
enable() {
|
|
this.settings = this.getSettings();
|
|
this.focusListenerId = global.display.connect("notify::focus-window", ({ focusWindow }) => {
|
|
if (this.settings.get_boolean("delete-on-focus") && focusWindow) {
|
|
this.clearNotificationsForApp(focusWindow, "focus");
|
|
}
|
|
});
|
|
this.closeListenerId = global.window_manager.connect("destroy", (_, { metaWindow }) => {
|
|
if (this.settings.get_boolean("delete-on-close") && metaWindow) {
|
|
this.clearNotificationsForApp(metaWindow, "close");
|
|
}
|
|
});
|
|
}
|
|
disable() {
|
|
if (this.focusListenerId !== null) {
|
|
global.display.disconnect(this.focusListenerId);
|
|
}
|
|
if (this.closeListenerId !== null) {
|
|
global.window_manager.disconnect(this.closeListenerId);
|
|
}
|
|
if (this.settings) {
|
|
this.settings = null;
|
|
}
|
|
}
|
|
}
|