Skip to content

Commit

Permalink
Get application icons using XdgDesktopFile
Browse files Browse the repository at this point in the history
  • Loading branch information
marcusbritanicus committed Mar 27, 2024
1 parent 6ed1031 commit 8ae41f3
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 8 deletions.
3 changes: 3 additions & 0 deletions panel/backends/wayland/wlroots/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ add_library(lxqt-panel-backend-wlroots STATIC
lxqttaskbarbackendwlr.h
lxqttaskbarwlrwindowmanagment.h
lxqtwlrvirtualdesktop.h
icontools.hpp

lxqttaskbarbackendwlr.cpp
lxqttaskbarwlrwindowmanagment.cpp
lxqtwlrvirtualdesktop.cpp
icontools.cpp
)

qt6_generate_wayland_protocol_client_sources(lxqt-panel-backend-wlroots
Expand All @@ -23,5 +25,6 @@ target_link_libraries(lxqt-panel-backend-wlroots
Qt6::GuiPrivate
Qt6::WaylandClient
Qt6::Concurrent
Qt6Xdg
lxqt-panel-backend-common
)
150 changes: 150 additions & 0 deletions panel/backends/wayland/wlroots/icontools.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
#include <filesystem>

#include "icontools.hpp"

static inline QString getPixmapIcon( QString name ) {
QStringList paths{
QString::fromUtf8( "/usr/local/share/pixmaps/" ),
QString::fromUtf8( "/usr/share/pixmaps/" ),
};

QStringList sfxs{
QString::fromUtf8( ".svg" ), QString::fromUtf8( ".png" ), QString::fromUtf8( ".xpm" )
};

for ( QString path: paths ) {
for ( QString sfx: sfxs ) {
if ( QFile::exists( path + name + sfx ) ) {
return path + name + sfx;
}
}
}

return QString();
}


QIcon getIconForAppId( QString mAppId ) {
if ( mAppId.isEmpty() or (mAppId == QString::fromUtf8("Unknown")) ) {
return QIcon();
}

/** Wine apps */
if ( mAppId.endsWith( QString::fromUtf8(".exe") ) ) {
return QIcon::fromTheme( QString::fromUtf8("wine") );
}

/** Check if a theme icon exists called @mAppId */
if ( QIcon::hasThemeIcon( mAppId ) ) {
return QIcon::fromTheme( mAppId );
}

/** Check if the theme icon is @mAppId, but all lower-case letters */
else if ( QIcon::hasThemeIcon( mAppId.toLower() ) ) {
return QIcon::fromTheme( mAppId.toLower() );
}

QStringList appDirs = {
QDir::home().filePath( QString::fromUtf8( ".local/share/applications/" ) ),
QString::fromUtf8( "/usr/local/share/applications/" ),
QString::fromUtf8( "/usr/share/applications/" ),
QString::fromUtf8( "/usr/local/share/games/" ),
QString::fromUtf8( "/usr/share/games/" ),
};

/**
* Assume mAppId == desktop-file-name (ideal situation)
* or mAppId.toLower() == desktop-file-name (cheap fallback)
*/
QString iconName;

for ( QString path: appDirs ) {
/** Get the icon name from desktop (mAppId: as it is) */
if ( QFile::exists( path + mAppId + QString::fromUtf8(".desktop") ) ) {
QSettings desktop( path + mAppId + QString::fromUtf8(".desktop"), QSettings::IniFormat );
iconName = desktop.value( QString::fromUtf8( "Desktop Entry/Icon" ) ).toString();
}

/** Get the icon name from desktop (mAppId: all lower-case letters) */
else if ( QFile::exists( path + mAppId.toLower() + QString::fromUtf8(".desktop") ) ) {
QSettings desktop( path + mAppId.toLower() + QString::fromUtf8(".desktop"), QSettings::IniFormat );
iconName = desktop.value( QString::fromUtf8("Desktop Entry/Icon") ).toString();
}

/** No icon specified: try else-where */
if ( iconName.isEmpty() ) {
continue;
}

/** We got an iconName, and it's in the current theme */
if ( QIcon::hasThemeIcon( iconName ) ) {
return QIcon::fromTheme( iconName );
}

/** Not a theme icon, but an absolute path */
else if ( QFile::exists( iconName ) ) {
return QIcon( iconName );
}

/** Not theme icon or absolute path. So check /usr/share/pixmaps/ */
else {
iconName = getPixmapIcon( iconName );

if ( not iconName.isEmpty() ) {
return QIcon( iconName );
}
}
}

/* Check all desktop files for @mAppId */
for ( QString path: appDirs ) {
QStringList desktops = QDir( path ).entryList( { QString::fromUtf8( "*.desktop" ) } );
for ( QString dskf: desktops ) {
QSettings desktop( path + dskf, QSettings::IniFormat );

QString exec = desktop.value( QString::fromUtf8("Desktop Entry/Exec"), QString::fromUtf8("abcd1234/-") ).toString();
QString name = desktop.value( QString::fromUtf8("Desktop Entry/Name"), QString::fromUtf8("abcd1234/-") ).toString();
QString cls = desktop.value( QString::fromUtf8("Desktop Entry/StartupWMClass"), QString::fromUtf8("abcd1234/-") ).toString();

QString execPath( QString::fromUtf8( std::filesystem::path( exec.toStdString() ).filename().c_str() ) );

if ( mAppId.compare( execPath, Qt::CaseInsensitive ) == 0 ) {
iconName = desktop.value( QString::fromUtf8("Desktop Entry/Icon") ).toString();
}

else if ( mAppId.compare( name, Qt::CaseInsensitive ) == 0 ) {
iconName = desktop.value( QString::fromUtf8("Desktop Entry/Icon") ).toString();
}

else if ( mAppId.compare( cls, Qt::CaseInsensitive ) == 0 ) {
iconName = desktop.value( QString::fromUtf8("Desktop Entry/Icon") ).toString();
}

if ( not iconName.isEmpty() ) {
if ( QIcon::hasThemeIcon( iconName ) ) {
return QIcon::fromTheme( iconName );
}

else if ( QFile::exists( iconName ) ) {
return QIcon( iconName );
}

else {
iconName = getPixmapIcon( iconName );

if ( not iconName.isEmpty() ) {
return QIcon( iconName );
}
}
}
}
}

iconName = getPixmapIcon( iconName );

if ( not iconName.isEmpty() ) {
return QIcon( iconName );
}

return QIcon();
}
6 changes: 6 additions & 0 deletions panel/backends/wayland/wlroots/icontools.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once

#include <QtCore>
#include <QtGui>

QIcon getIconForAppId( QString );
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "lxqttaskbarwlrwindowmanagment.h"
#include "icontools.hpp"

#include <QString>
#include <QFuture>
Expand All @@ -11,6 +12,8 @@
#include <QWaylandClientExtension>
#include <QWindow>

#include <xdgdesktopfile.h>

#include <qpa/qplatformnativeinterface.h>

#include <fcntl.h>
Expand Down Expand Up @@ -97,6 +100,8 @@ void LXQtTaskBarWlrootsWindow::zwlr_foreign_toplevel_handle_v1_app_id(const QStr
appIdRecieved = true;
emit appIdChanged();

this->icon = getIconForAppId( app_id );

if ( appIdRecieved && titleRecieved )
{
qDebug() << "--------------> windowReady!!" << getWindowId() << title << appId;
Expand Down
9 changes: 1 addition & 8 deletions plugin-taskbar/lxqttaskbar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,7 @@ LXQtTaskBar::LXQtTaskBar(ILXQtPanelPlugin *plugin, QWidget *parent) :
QTimer::singleShot(0, this, &LXQtTaskBar::registerShortcuts);

connect(mBackend, &ILXQtTaskbarAbstractBackend::windowPropertyChanged, this, &LXQtTaskBar::onWindowChanged);
// connect(mBackend, &ILXQtTaskbarAbstractBackend::windowAdded, this, &LXQtTaskBar::onWindowAdded);
qDebug() << connect(mBackend, &ILXQtTaskbarAbstractBackend::windowAdded, [=](WId window){
qDebug() << "--------------> onWindowAdded" << window;
onWindowAdded(window);
});
connect(mBackend, &ILXQtTaskbarAbstractBackend::windowAdded, this, &LXQtTaskBar::onWindowAdded);
connect(mBackend, &ILXQtTaskbarAbstractBackend::windowRemoved, this, &LXQtTaskBar::onWindowRemoved);

// Consider already fetched windows
Expand Down Expand Up @@ -255,8 +251,6 @@ void LXQtTaskBar::addWindow(WId window)
// If grouping disabled group behaves like regular button
const QString group_id = mGroupingEnabled ? mBackend->getWindowClass(window) : QString::number(window);

qDebug() << "-------------->" << group_id;

LXQtTaskGroup *group = nullptr;
auto i_group = mKnownWindows.find(window);
if (mKnownWindows.end() != i_group)
Expand Down Expand Up @@ -351,7 +345,6 @@ void LXQtTaskBar::onWindowChanged(WId window, int prop)

void LXQtTaskBar::onWindowAdded(WId window)
{
qDebug() << "--------------> onWindowAdded" << window;
auto const pos = mKnownWindows.find(window);
if (mKnownWindows.end() == pos)
addWindow(window);
Expand Down

0 comments on commit 8ae41f3

Please sign in to comment.