Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wf-dock] improved icon search. #82

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
92 changes: 10 additions & 82 deletions src/dock/toplevel-icon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,6 @@ namespace IconProvider

namespace
{
std::string tolower(std::string str)
{
for (auto& c : str)
c = std::tolower(c);
return str;
}

std::map<std::string, std::string> custom_icons;
}

Expand Down Expand Up @@ -196,54 +189,6 @@ namespace IconProvider
return true;
}

/* Gio::DesktopAppInfo
*
* Usually knowing the app_id, we can get a desktop app info from Gio
* The filename is either the app_id + ".desktop" or lower_app_id + ".desktop" */
Icon get_from_desktop_app_info(std::string app_id)
{
Glib::RefPtr<Gio::DesktopAppInfo> app_info;

std::vector<std::string> prefixes = {
"",
"/usr/share/applications/",
"/usr/share/applications/kde/",
"/usr/share/applications/org.kde.",
"/usr/local/share/applications/",
"/usr/local/share/applications/org.kde.",
};

std::vector<std::string> app_id_variations = {
app_id,
tolower(app_id),
};

std::vector<std::string> suffixes = {
"",
".desktop"
};

for (auto& prefix : prefixes)
{
for (auto& id : app_id_variations)
{
for (auto& suffix : suffixes)
{
if (!app_info)
{
app_info = Gio::DesktopAppInfo
::create_from_filename(prefix + id + suffix);
}
}
}
}

if (app_info) // success
return app_info->get_icon();

return Icon{};
}

void set_image_from_icon(Gtk::Image& image,
std::string app_id_list, int size, int scale)
{
Expand All @@ -256,40 +201,23 @@ namespace IconProvider
* send a single app-id, but in any case this works fine */
while (stream >> app_id)
{
/* Try first method: custom icon file provided by the user */
if (set_custom_icon(image, app_id, size, scale))
{
found_icon = true;
break;
}

/* Then try to load the DesktopAppInfo */
auto icon = get_from_desktop_app_info(app_id);
std::string icon_name = "unknown";

if (!icon)
{
/* Finally try directly looking up the icon, if it exists */
if (Gtk::IconTheme::get_default()->lookup_icon(app_id, 24))
icon_name = app_id;
} else
{
icon_name = icon->to_string();
}

WfIconLoadOptions options;
options.user_scale = scale;
set_image_icon(image, icon_name, size, options);
std::string app_name = app_id.substr(
app_id.rfind(".")+1, app_id.size()
);

/* finally found some icon */
if (icon_name != "unknown")
/* Try first method: custom icon file provided by the user */
if (
set_custom_icon(image, app_id, size, scale)
||
set_custom_icon(image, app_name, size, scale)
)
{
found_icon = true;
break;
}
}

if (!found_icon)
std::cout << "Failed to load icon for any of " << app_id_list << std::endl;
::set_image_from_icon(image, app_id_list, size, scale);
}
};
110 changes: 1 addition & 109 deletions src/panel/widgets/window-list/toplevel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,6 @@ namespace
extern zwlr_foreign_toplevel_handle_v1_listener toplevel_handle_v1_impl;
}

namespace IconProvider
{
void set_image_from_icon(Gtk::Image& image,
std::string app_id_list, int size, int scale);
}

class WayfireToplevel::impl
{
zwlr_foreign_toplevel_handle_v1 *handle, *parent;
Expand Down Expand Up @@ -277,8 +271,7 @@ class WayfireToplevel::impl
void set_app_id(std::string app_id)
{
this->app_id = app_id;
IconProvider::set_image_from_icon(image, app_id,
24, button.get_scale_factor());
set_image_from_icon(image, app_id, 24, button.get_scale_factor());
}

void send_rectangle_hint()
Expand Down Expand Up @@ -573,104 +566,3 @@ struct zwlr_foreign_toplevel_handle_v1_listener toplevel_handle_v1_impl = {
.parent = handle_toplevel_parent
};
}

/* Icon loading functions */
namespace IconProvider
{
using Icon = Glib::RefPtr<Gio::Icon>;

namespace
{
std::string tolower(std::string str)
{
for (auto& c : str)
c = std::tolower(c);
return str;
}
}

/* Gio::DesktopAppInfo
*
* Usually knowing the app_id, we can get a desktop app info from Gio
* The filename is either the app_id + ".desktop" or lower_app_id + ".desktop" */
Icon get_from_desktop_app_info(std::string app_id)
{
Glib::RefPtr<Gio::DesktopAppInfo> app_info;

std::vector<std::string> prefixes = {
"",
"/usr/share/applications/",
"/usr/share/applications/kde/",
"/usr/share/applications/org.kde.",
"/usr/local/share/applications/",
"/usr/local/share/applications/org.kde.",
};

std::vector<std::string> app_id_variations = {
app_id,
tolower(app_id),
};

std::vector<std::string> suffixes = {
"",
".desktop"
};

for (auto& prefix : prefixes)
{
for (auto& id : app_id_variations)
{
for (auto& suffix : suffixes)
{
if (!app_info)
{
app_info = Gio::DesktopAppInfo
::create_from_filename(prefix + id + suffix);
}
}
}
}

if (app_info) // success
return app_info->get_icon();

return Icon{};
}

/* Second method: Just look up the built-in icon theme,
* perhaps some icon can be found there */

void set_image_from_icon(Gtk::Image& image,
std::string app_id_list, int size, int scale)
{
std::string app_id;
std::istringstream stream(app_id_list);

/* Wayfire sends a list of app-id's in space separated format, other compositors
* send a single app-id, but in any case this works fine */
while (stream >> app_id)
{
auto icon = get_from_desktop_app_info(app_id);
std::string icon_name = "unknown";

if (!icon)
{
/* Perhaps no desktop app info, but we might still be able to
* get an icon directly from the icon theme */
if (Gtk::IconTheme::get_default()->lookup_icon(app_id, 24))
icon_name = app_id;
} else
{
icon_name = icon->to_string();
}

WfIconLoadOptions options;
options.user_scale = scale;
set_image_icon(image, icon_name, size, options);

/* finally found some icon */
if (icon_name != "unknown")
break;
}
}
};
Loading