Иконка скайпа всегда выделялась в панели индикаторов, что очень сильно раздражало. И вот, вроде бы, уже привык к этому, но нашлось отличное решение проблемы, а именно подправить sni-qt, который и отвечает за вывод иконок трея Qt приложений в панели индикаторов unity.
Конечно можно, используя skype wrapper, иконку засунуть в indicator-messages, но мне удобней, чтобы иконка была сразу на панели.
Скатываем исходники sni-qt:
apt-get source sni-qt && cd sni-qt*
Находим файл iconcache.cpp и заменяем один метод:
void IconCache::cacheIcon(const QString& key, const QIcon& icon) const { QList<QSize> sizes = icon.availableSizes(); if (sizes.isEmpty()) { sizes << QSize(16,16) << QSize(22,22) << QSize(32,32) << QSize(48,48); } QDir dir(m_themePath); Q_FOREACH(const QSize& size, sizes) { QPixmap pix = icon.pixmap(size); QString dirName = QString("hicolor/%1x%1/apps").arg(size.width()); if (!dir.exists(dirName)) { if (!dir.mkpath(dirName)) { qWarning("Could not create '%s' dir in '%s'", qPrintable(m_themePath), qPrintable(dirName)); continue; } } QString pixPath = QString("%1/%2/%3.png").arg(m_themePath).arg(dirName).arg(key); bool replaced = false; // Если skype выполняем if (QString::compare(QCoreApplication::applicationFilePath().section('/', -1), "skype") == 0) { QString iconFile; QString hash = QString(key); hash.remove(0, hash.lastIndexOf("_")+1); // Сопоставляем хэшу изображения необходимого файла иконки if (QString::compare("37e170fc54e7355d9d298917e74f9ea9", hash) == 0) { // в сети iconFile = "skype_online.svg"; } else if (QString::compare("602c84fa0f4d61c64f770495a500279e", hash) == 0) { // нет на месте iconFile = "skype_away.svg"; } else if (QString::compare("bd2e3972c2a97520bbabac7e275d7b9f", hash) == 0) { // не беспокоить iconFile = "skype_busy.svg"; } else if (QString::compare("2d1ee5482260fd9cd180b32787792683", hash) == 0) { // не в сети iconFile = "skype_offline.svg"; } else if (QString::compare("ad07f7e1479ab81315ec8c6c23e19170", hash) == 0) { // невидимый iconFile = "skype_invisible.svg"; } else if (QString::compare("f2fc4a539a7b9553f5b35241d1154e84", hash) == 0) { // загрузка iconFile = "skype_load.svg"; } else if (QString::compare("dad77418071bead905e2dbe605715dcd", hash) == 0) { // загрузка iconFile = "skype_load.svg"; } else if (QString::compare("6cbeda8e2c9f56d3ac75ccdf8d282a69", hash) == 0) { // загрузка iconFile = "skype_load.svg"; } else if (QString::compare("0972e5fde53a4a87346ebb91c4c2b159", hash) == 0) { // загрузка iconFile = "skype_load.svg"; } else { // уведомления, пропущенные звонки, непрочитанные сообщения iconFile = "skype_message.svg"; } // Загружает и сохраняет в временном каталоге подменяемую иконку iconFile = QString("/usr/share/icons/skype/%1").arg(iconFile); QIcon newIcon = QIcon(iconFile); if (!newIcon.isNull()) { QList<QSize> newSizes = newIcon.availableSizes(); if (newSizes.isEmpty()) { newSizes << QSize(22, 22); } Q_FOREACH(const QSize& newSize, newSizes) { if (newSize.width() == 22) { QPixmap newPix = newIcon.pixmap(newSize); replaced = newPix.save(pixPath, "png"); break; } } } } if (!replaced) { if (!pix.save(pixPath, "png")) { qWarning("Could not save icon as '%s'", qPrintable(pixPath)); } } } m_cacheKeys << key; QFileInfo info(m_themePath); QDateTime mtime = info.lastModified(); FsUtils::touch(m_themePath, mtime.addSecs(1)); }
Собираем и устанавливаем
sudo apt-get build-dep sni-qt mkdir build && cmake --build=build . make && sudo make install
Как видно иконки будут браться из директории:
/usr/share/icons/skype
Иконки должны быть векторными. Можно использовать системные от empathy, только нужно будет дать им правильные названия или изменить в коде на нужные.
Есть один небольшой минус, на иконке не будет отображатся количество чатов с непрочитанными сообщениями, но это можно пережить.
UPD: существует проблема в 64 битных версиях. По непонятной причине библиотека отказывается конвертить из svg в png. Поступим просто, будем использовать png, но при изменении размера панели, придется иконки перерисовывать. Такое случается не часто, так что это не критично.
IconCache::IconCache(const QString& baseDir, QObject* parent) : QObject(parent) , m_themePath(baseDir + "/icons") { QDir dir(baseDir); bool ok = dir.mkdir("icons"); if (!ok) { qCritical("Could not create '%s' dir for SNI icon cache", qPrintable(m_themePath)); m_themePath = QString(); return; } } QString IconCache::themePath() const { return m_themePath; } QString IconCache::nameForIcon(const QIcon& icon) const { if (icon.isNull()) { return QString(); } QString key = computeKeyForIcon(icon); QStringList::iterator it = qFind(m_cacheKeys.begin(), m_cacheKeys.end(), key); if (it == m_cacheKeys.end()) { cacheIcon(key, icon); trimCache(); } else { // Place key at the end of list as it is the most recently accessed m_cacheKeys.erase(it); m_cacheKeys.append(key); } return key; } void IconCache::trimCache() const { QDir dir(m_themePath + "/hicolor"); dir.setFilter(QDir::Dirs); while (m_cacheKeys.count() > MaxIconCount) { QString cacheKey = m_cacheKeys.takeFirst(); Q_FOREACH(const QString& sizeDir, dir.entryList()) { QString iconSubPath = QString("%1/apps/%2.png").arg(sizeDir).arg(cacheKey); if (dir.exists(iconSubPath)) { dir.remove(iconSubPath); } } } } void IconCache::cacheIcon(const QString& key, const QIcon& icon) const { QList<QSize> sizes = icon.availableSizes(); if (sizes.isEmpty()) { sizes << QSize(16,16) << QSize(22,22) << QSize(32,32) << QSize(48,48); } QDir dir(m_themePath); Q_FOREACH(const QSize& size, sizes) { QPixmap pix = icon.pixmap(size); QString dirName = QString("hicolor/%1x%1/apps").arg(size.width()); if (!dir.exists(dirName)) { if (!dir.mkpath(dirName)) { qWarning("Could not create '%s' dir in '%s'", qPrintable(m_themePath), qPrintable(dirName)); continue; } } QString pixPath = QString("%1/%2/%3.png").arg(m_themePath).arg(dirName).arg(key); bool replaced = false; // Если skype выполняем if (QString::compare(QCoreApplication::applicationFilePath().section('/', -1), "skype") == 0) { QString iconFile; QString hash = QString(key); hash.remove(0, hash.lastIndexOf("_")+1); // Сопоставляем хэшу изображения необходимого файла иконки if (QString::compare("37e170fc54e7355d9d298917e74f9ea9", hash) == 0) { // в сети iconFile = "skype_online.png"; } else if (QString::compare("602c84fa0f4d61c64f770495a500279e", hash) == 0) { // нет на месте iconFile = "skype_away.png"; } else if (QString::compare("bd2e3972c2a97520bbabac7e275d7b9f", hash) == 0) { // не беспокоить iconFile = "skype_busy.png"; } else if (QString::compare("2d1ee5482260fd9cd180b32787792683", hash) == 0) { // не в сети iconFile = "skype_offline.png"; } else if (QString::compare("ad07f7e1479ab81315ec8c6c23e19170", hash) == 0) { // невидимый iconFile = "skype_invisible.png"; } else if (QString::compare("f2fc4a539a7b9553f5b35241d1154e84", hash) == 0) { // загрузка iconFile = "skype_load.png"; } else if (QString::compare("dad77418071bead905e2dbe605715dcd", hash) == 0) { // загрузка iconFile = "skype_load.png"; } else if (QString::compare("6cbeda8e2c9f56d3ac75ccdf8d282a69", hash) == 0) { // загрузка iconFile = "skype_load.png"; } else if (QString::compare("0972e5fde53a4a87346ebb91c4c2b159", hash) == 0) { // загрузка iconFile = "skype_load.png"; } else { // уведомления, пропущенные звонки, непрочитанные сообщения iconFile = "skype_message.png"; } // Загружает и сохраняет в временном каталоге подменяемую иконку iconFile = QString("/usr/share/pixmaps/skype/%1").arg(iconFile); QFile file(iconFile); if (QFile::exists(pixPath)) { replaced = true; } else if (file.exists()) { QFile::copy(iconFile, pixPath); replaced = true; } } if (!replaced) { if (!pix.save(pixPath, "png")) { qWarning("Could not save icon as '%s'", qPrintable(pixPath)); } } } m_cacheKeys << key; QFileInfo info(m_themePath); QDateTime mtime = info.lastModified(); FsUtils::touch(m_themePath, mtime.addSecs(1)); }
Один хороший человек подсказал, что правильней будет хранить изображения в
/usr/share/pixmaps/skype/
Результат:
Прикрепляю свои файлы иконок:
svg
png
Это надо столько сексом заниматься чтобы иконку сменить? А можно скрин как была иконка до ?
Огромнейшее спасибо, вот бы ещё добавить деб пакет было бы совсем супер. Я искал такую статью 3 дня!
Ну и конечно как на 64х разрядной системе компилировать 32х битный деб пакет было бы полезной информацией.
Все сделал, были ошибки с деб пакетом (коммент выше), но всё скомпилировал и разместил иконки. Но почему-то они не подтягиваются, как проверить узнать, что не так ?
Пробовал – на первом же этапе в терминале написали что нет такого пакета. Ubuntu 16.04 mate . Подскажите что не так то
Попробовал оба варианта, и для svg, и для png. Всё как по мануалу, никаких ошибок при компиляции. Но и результат тоже нулевой.