This commit is contained in:
Mathew-D
2026-05-09 15:39:12 -04:00
4 changed files with 63 additions and 6 deletions
+14 -1
View File
@@ -23,7 +23,7 @@ local function cfg(key, default)
end
local function isProcessRunning()
local exitCode = noctalia.runSync("pgrep -f '[g]pu-screen-recorder' >/dev/null 2>&1")
local exitCode = noctalia.runSync("ps -eo args= | grep '[g]pu-screen-recorder' | grep -v ' -r ' | grep -q .")
return exitCode == 0
end
@@ -290,6 +290,12 @@ local function checkProcessState()
state = "idle"
noctalia.notify("Replay buffer stopped")
end
elseif state == "idle" then
if isReplayProcessRunning() then
state = "replaying"
elseif isProcessRunning() then
state = "recording"
end
end
end
@@ -335,6 +341,13 @@ function update()
if not checkedAvailability then
checkedAvailability = true
isAvailable = checkAvailability()
if isAvailable then
if isReplayProcessRunning() then
state = "replaying"
elseif isProcessRunning() then
state = "recording"
end
end
end
if tickCount % CHECK_TICKS == 0 then
+47 -4
View File
@@ -350,6 +350,20 @@ void TrayWidget::syncState(Renderer& renderer) {
for (const auto& item : next_items) {
stillPresent[item.id] = true;
auto hashVec = [](const std::vector<std::uint8_t>& vec) -> std::size_t {
if (vec.empty()) {
return 0;
}
return std::hash<std::string_view>{}(std::string_view(reinterpret_cast<const char*>(vec.data()), vec.size()));
};
const std::size_t currentHash = hashVec(item.iconArgb32) ^ (hashVec(item.attentionArgb32) << 1);
if (!m_initialPixmaps.contains(item.id)) {
m_initialPixmaps[item.id] = currentHash;
} else if (m_initialPixmaps[item.id] != currentHash) {
m_preferPixmap[item.id] = true;
}
const auto prevIt = previousById.find(item.id);
if (prevIt == previousById.end() || prevIt->second == nullptr) {
continue;
@@ -362,7 +376,10 @@ void TrayWidget::syncState(Renderer& renderer) {
prev.attentionIconName != item.attentionIconName || prev.iconThemePath != item.iconThemePath ||
prev.needsAttention != item.needsAttention || prev.status != item.status ||
prev.overlayWidth != item.overlayWidth || prev.overlayHeight != item.overlayHeight ||
prev.overlayArgb32 != item.overlayArgb32) {
prev.overlayArgb32 != item.overlayArgb32 || prev.iconWidth != item.iconWidth ||
prev.iconHeight != item.iconHeight || prev.iconArgb32 != item.iconArgb32 ||
prev.attentionWidth != item.attentionWidth || prev.attentionHeight != item.attentionHeight ||
prev.attentionArgb32 != item.attentionArgb32) {
kLog.debug("tray widget invalidate icon cache id={} icon='{}'->'{}' overlay='{}'->'{}' attention='{}'->'{}' "
"status={}=>{}",
item.id, prev.iconName, item.iconName, prev.overlayIconName, item.overlayIconName,
@@ -377,6 +394,20 @@ void TrayWidget::syncState(Renderer& renderer) {
++it;
}
}
for (auto it = m_initialPixmaps.begin(); it != m_initialPixmaps.end();) {
if (!stillPresent.contains(it->first)) {
it = m_initialPixmaps.erase(it);
} else {
++it;
}
}
for (auto it = m_preferPixmap.begin(); it != m_preferPixmap.end();) {
if (!stillPresent.contains(it->first)) {
it = m_preferPixmap.erase(it);
} else {
++it;
}
}
m_items = next_items;
m_rebuildPending = true;
@@ -777,13 +808,24 @@ void TrayWidget::buildDesktopIconIndex() {
}
std::string TrayWidget::resolveIconPath(const TrayItemInfo& item) {
if (const auto it = m_preferPixmap.find(item.id); it != m_preferPixmap.end() && it->second) {
kLog.debug("tray widget resolve id={} source=dynamic-pixmap", item.id);
return {};
}
if (const auto it = m_preferredIconPaths.find(item.id); it != m_preferredIconPaths.end() && !it->second.empty()) {
kLog.debug("tray widget resolve id={} source=cached path={}", item.id, it->second);
return it->second;
}
const std::string preferred =
item.needsAttention && !item.attentionIconName.empty() ? item.attentionIconName : item.iconName;
std::string preferred;
if (item.needsAttention && !item.attentionIconName.empty()) {
preferred = item.attentionIconName;
} else if (item.needsAttention && !item.attentionArgb32.empty()) {
preferred = "";
} else {
preferred = item.iconName;
}
if (const auto themed = resolveFromTrayThemePath(item.iconThemePath, preferred); !themed.empty()) {
kLog.debug("tray widget resolve id={} source=theme-path variant='{}' path={}", item.id, preferred, themed);
@@ -847,7 +889,8 @@ std::string TrayWidget::resolveIconPath(const TrayItemInfo& item) {
// When an explicit tray IconName is provided, treat it as authoritative.
// Falling back to generic app-id/title mappings can hide stateful icon
// changes (e.g. indicator on/off variants) behind a constant app icon.
if (preferred.empty()) {
const bool hasTargetPixmap = item.needsAttention ? !item.attentionArgb32.empty() : !item.iconArgb32.empty();
if (preferred.empty() && !hasTargetPixmap) {
candidates.emplace_back("itemName", &item.itemName);
candidates.emplace_back("title", &item.title);
candidates.emplace_back("objectPath", &item.objectPath);
+2
View File
@@ -49,6 +49,8 @@ private:
std::vector<std::string> m_hiddenItems;
std::vector<std::string> m_pinnedItems;
std::vector<Image*> m_loadedImages;
std::unordered_map<std::string, std::size_t> m_initialPixmaps;
std::unordered_map<std::string, bool> m_preferPixmap;
float m_contentHeight = 0.0f;
bool m_isVertical = false;
bool m_rebuildPending = true;
-1
View File
@@ -171,7 +171,6 @@ void Dock::reload() {
const auto& cfg = m_config->config().dock;
m_lastDockConfig = cfg;
m_lastShadow = m_config->config().shell.shadow;
m_lastPinnedConfig = cfg.pinned;
m_lastBarLayerStack = barLayerStackSignature(m_config->config());
if (!cfg.enabled) {