update
This commit is contained in:
@@ -14,6 +14,8 @@ Item {
|
||||
property ShellScreen screen
|
||||
property string widgetId: ""
|
||||
property string section: ""
|
||||
property int sectionWidgetIndex: -1
|
||||
property int sectionWidgetsCount: 0
|
||||
|
||||
// Bar positioning properties
|
||||
readonly property string screenName: screen ? screen.name : ""
|
||||
|
||||
@@ -10,7 +10,7 @@ Item {
|
||||
property var pluginApi: null
|
||||
|
||||
// --- Logic extracted from BarWidget.qml ---
|
||||
|
||||
|
||||
property bool micActive: false
|
||||
property bool camActive: false
|
||||
property bool scrActive: false
|
||||
@@ -19,7 +19,7 @@ Item {
|
||||
property var scrApps: []
|
||||
|
||||
property var accessHistory: []
|
||||
|
||||
|
||||
// Previous states for history tracking
|
||||
property var _prevMicApps: []
|
||||
property var _prevCamApps: []
|
||||
@@ -30,6 +30,7 @@ Item {
|
||||
property var defaults: pluginApi?.manifest?.metadata?.defaultSettings || ({})
|
||||
property bool enableToast: cfg.enableToast ?? defaults.enableToast ?? true
|
||||
property string activeColorKey: cfg.activeColor ?? defaults.activeColor ?? "primary"
|
||||
property string micFilterRegex: cfg.micFilterRegex ?? defaults.micFilterRegex ?? ""
|
||||
|
||||
PwObjectTracker {
|
||||
objects: Pipewire.ready ? Pipewire.nodes.values : []
|
||||
@@ -73,6 +74,16 @@ Item {
|
||||
function updateMicrophoneState(nodes, links) {
|
||||
var appNames = [];
|
||||
var isActive = false;
|
||||
|
||||
var filterRegex = null;
|
||||
if (root.micFilterRegex && root.micFilterRegex.length > 0) {
|
||||
try {
|
||||
filterRegex = new RegExp(root.micFilterRegex);
|
||||
} catch (e) {
|
||||
Logger.w("PrivacyIndicator: Invalid micFilterRegex:", root.micFilterRegex);
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < nodes.length; i++) {
|
||||
var node = nodes[i];
|
||||
if (!node || !node.isStream || !node.audio || node.isSink) continue;
|
||||
@@ -80,8 +91,11 @@ Item {
|
||||
var mediaClass = node.properties["media.class"] || "";
|
||||
if (mediaClass === "Stream/Input/Audio") {
|
||||
if (node.properties["stream.capture.sink"] === "true") continue;
|
||||
isActive = true;
|
||||
|
||||
var appName = getAppName(node);
|
||||
if (filterRegex && appName && filterRegex.test(appName)) continue;
|
||||
|
||||
isActive = true;
|
||||
if (appName && appNames.indexOf(appName) === -1) appNames.push(appName);
|
||||
}
|
||||
}
|
||||
@@ -133,7 +147,7 @@ Item {
|
||||
}
|
||||
|
||||
// --- History Persistence ---
|
||||
|
||||
|
||||
property string stateFile: ""
|
||||
property bool isLoaded: false
|
||||
|
||||
@@ -164,7 +178,7 @@ Item {
|
||||
root.accessHistory = adapter.history;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onLoadFailed: error => {
|
||||
// If file doesn't exist (error 2), we are ready to save new data
|
||||
if (error === 2) {
|
||||
@@ -178,9 +192,9 @@ Item {
|
||||
|
||||
function saveHistory() {
|
||||
if (!stateFile || !isLoaded) return;
|
||||
|
||||
|
||||
adapter.history = root.accessHistory;
|
||||
|
||||
|
||||
// Ensure cache directory exists and save
|
||||
try {
|
||||
Quickshell.execDetached(["mkdir", "-p", Settings.cacheDir]);
|
||||
@@ -220,7 +234,7 @@ Item {
|
||||
|
||||
function checkAppChanges(newApps, oldApps, type, icon, colorKey) {
|
||||
if (!newApps && !oldApps) return;
|
||||
|
||||
|
||||
// Check for new apps (Started)
|
||||
if (newApps) {
|
||||
for (var i = 0; i < newApps.length; i++) {
|
||||
@@ -230,7 +244,7 @@ Item {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check for removed apps (Stopped)
|
||||
if (oldApps) {
|
||||
for (var j = 0; j < oldApps.length; j++) {
|
||||
@@ -279,6 +293,6 @@ Item {
|
||||
checkAppChanges(scrApps, _prevScrApps, "Screen", "screen-share", activeColorKey);
|
||||
_prevScrApps = scrApps;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -18,8 +18,10 @@ A privacy indicator widget that monitors and displays when microphone, camera, o
|
||||
Access the plugin settings in Noctalia to configure the following options:
|
||||
|
||||
- **Hide Inactive States**: If enabled, microphone, camera, and screen icons are hidden whenever they are inactive. Only active states are shown.
|
||||
- **RemoveMargins**: If enabled, removes all outer margins of the widget.
|
||||
- **Remove Margins**: If enabled, removes all outer margins of the widget.
|
||||
- **Icon Spacing**: Controls the horizontal/vertical spacing between the icons.
|
||||
- **Active/Inactive Icon Color**: Customize the colors for active and inactive states.
|
||||
- **Microphone Filter Regex**: Regex pattern to filter out specific microphone applications. Matching apps are completely excluded from detection (they won't trigger the indicator or appear in tooltips). Use `|` to specify multiple patterns, e.g., `effect_input.rnnoise|easyeffects`.
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -17,6 +17,7 @@ ColumnLayout {
|
||||
property int iconSpacing: cfg.iconSpacing ?? defaults.iconSpacing ?? 4
|
||||
property string activeColor: cfg.activeColor ?? defaults.activeColor ?? "primary"
|
||||
property string inactiveColor: cfg.inactiveColor ?? defaults.inactiveColor ?? "none"
|
||||
property string micFilterRegex: cfg.micFilterRegex ?? defaults.micFilterRegex
|
||||
|
||||
spacing: Style.marginL
|
||||
|
||||
@@ -46,7 +47,7 @@ ColumnLayout {
|
||||
onToggled: checked => {
|
||||
root.enableToast = checked;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: pluginApi?.tr("settings.removeMargins.label")
|
||||
@@ -98,6 +99,15 @@ ColumnLayout {
|
||||
currentKey: root.iconSpacing.toFixed(0)
|
||||
onSelected: key => root.iconSpacing = key
|
||||
}
|
||||
|
||||
NTextInput {
|
||||
Layout.fillWidth: true
|
||||
label: pluginApi?.tr("settings.micFilterRegex.label") || "Microphone filter regex"
|
||||
description: pluginApi?.tr("settings.micFilterRegex.desc") || "Regex pattern to filter out microphone applications"
|
||||
placeholderText: "effect_input.rnnoise|easyeffects"
|
||||
text: root.micFilterRegex
|
||||
onTextChanged: root.micFilterRegex = text
|
||||
}
|
||||
}
|
||||
|
||||
function saveSettings() {
|
||||
@@ -112,6 +122,7 @@ ColumnLayout {
|
||||
pluginApi.pluginSettings.removeMargins = root.removeMargins;
|
||||
pluginApi.pluginSettings.activeColor = root.activeColor;
|
||||
pluginApi.pluginSettings.inactiveColor = root.inactiveColor;
|
||||
pluginApi.pluginSettings.micFilterRegex = root.micFilterRegex;
|
||||
|
||||
pluginApi.saveSettings();
|
||||
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
"removeMargins": {
|
||||
"desc": "Remove all outer margins of the widget.",
|
||||
"label": "Remove margins"
|
||||
},
|
||||
"micFilterRegex": {
|
||||
"desc": "Regex pattern to filter out microphone applications. Matching apps are completely excluded from detection.",
|
||||
"label": "Microphone filter regex"
|
||||
}
|
||||
},
|
||||
"tooltip": {
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"menu": {
|
||||
"settings": "Cài đặt tiện ích"
|
||||
},
|
||||
"settings": {
|
||||
"activeColor": {
|
||||
"desc": "Màu của biểu tượng khi đang hoạt động.",
|
||||
"label": "Màu biểu tượng khi hoạt động"
|
||||
},
|
||||
"hideInactive": {
|
||||
"desc": "Ẩn biểu tượng micro, camera và màn hình khi không hoạt động.",
|
||||
"label": "Ẩn trạng thái không hoạt động"
|
||||
},
|
||||
"enableToast": {
|
||||
"desc": "Hiển thị thông báo khi một trạng thái thay đổi.",
|
||||
"label": "Bật thông báo"
|
||||
},
|
||||
"inactiveColor": {
|
||||
"desc": "Màu của biểu tượng khi không hoạt động.",
|
||||
"label": "Màu biểu tượng khi không hoạt động"
|
||||
},
|
||||
"iconSpacing": {
|
||||
"desc": "Thiết lập khoảng cách giữa các biểu tượng.",
|
||||
"label": "Khoảng cách biểu tượng"
|
||||
},
|
||||
"removeMargins": {
|
||||
"desc": "Loại bỏ toàn bộ lề ngoài của widget.",
|
||||
"label": "Xóa lề"
|
||||
},
|
||||
"micFilterRegex": {
|
||||
"desc": "Biểu thức chính quy để lọc các ứng dụng sử dụng micro. Các ứng dụng khớp sẽ bị loại khỏi việc phát hiện.",
|
||||
"label": "Regex lọc micro"
|
||||
}
|
||||
},
|
||||
"tooltip": {
|
||||
"cam-on": "Camera: {apps}",
|
||||
"mic-on": "Micro: {apps}",
|
||||
"screen-on": "Chia sẻ màn hình: {apps}"
|
||||
},
|
||||
"toast": {
|
||||
"cam-on": "Camera đang hoạt động",
|
||||
"mic-on": "Micro đang hoạt động",
|
||||
"screen-on": "Chia sẻ màn hình đang hoạt động"
|
||||
},
|
||||
"history": {
|
||||
"title": "Lịch sử truy cập",
|
||||
"empty": "Không có truy cập gần đây",
|
||||
"clear": "Xóa",
|
||||
"action": {
|
||||
"started": "Bắt đầu",
|
||||
"stopped": "Dừng"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "privacy-indicator",
|
||||
"name": "Privacy Indicator",
|
||||
"version": "1.2.5",
|
||||
"version": "1.2.7",
|
||||
"minNoctaliaVersion": "3.6.0",
|
||||
"author": "Noctalia Team",
|
||||
"official": true,
|
||||
@@ -29,7 +29,8 @@
|
||||
"removeMargins": false,
|
||||
"iconSpacing": 4,
|
||||
"activeColor": "primary",
|
||||
"inactiveColor": "none"
|
||||
"inactiveColor": "none",
|
||||
"micFilterRegex": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user