Skip to content

Commit f8d1c42

Browse files
committed
util: centralise icon-loading code path
1 parent d340a17 commit f8d1c42

9 files changed

Lines changed: 125 additions & 314 deletions

File tree

src/dock/dock-app.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "dock.hpp"
22
#include "giomm/application.h"
3+
#include "gtk-utils.hpp"
34
#include "toplevel.hpp"
45
#include "toplevel-icon.hpp"
56
#include <iostream>
@@ -49,7 +50,7 @@ void WfDockApp::on_activate()
4950
{
5051
WayfireShellApp::on_activate();
5152
new CssFromConfigInt("dock/icon_height", ".toplevel-icon {-gtk-icon-size:", "px;}");
52-
IconProvider::load_custom_icons();
53+
IconProvider::load_custom_icons("dock");
5354

5455
/* At this point, wayland connection has been initialized,
5556
* and hopefully outputs have been created */

src/dock/toplevel-icon.cpp

Lines changed: 2 additions & 186 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#include <giomm/desktopappinfo.h>
21
#include <gtkmm/button.h>
32
#include <gtkmm/box.h>
43
#include <gtkmm/icontheme.h>
@@ -12,16 +11,9 @@
1211
#include "toplevel.hpp"
1312
#include "toplevel-icon.hpp"
1413
#include "gtk-utils.hpp"
15-
#include <iostream>
16-
#include <sstream>
1714
#include <cassert>
1815
#include "wf-option-wrap.hpp"
1916

20-
namespace IconProvider
21-
{
22-
void set_image_from_icon(Gtk::Image& image,
23-
std::string app_id_list, int size, int scale);
24-
}
2517

2618
class WfToplevelIcon::impl
2719
{
@@ -88,10 +80,8 @@ class WfToplevelIcon::impl
8880
}
8981

9082
this->app_id = app_id;
91-
IconProvider::set_image_from_icon(image,
92-
app_id,
93-
icon_height,
94-
button.get_scale_factor());
83+
IconProvider::image_set_icon(image,
84+
app_id);
9585
}
9686

9787
void send_rectangle_hint()
@@ -210,177 +200,3 @@ void WfToplevelIcon::close()
210200
{
211201
return pimpl->close();
212202
}
213-
214-
/* Icon loading functions */
215-
namespace IconProvider
216-
{
217-
using Icon = Glib::RefPtr<Gio::Icon>;
218-
219-
namespace
220-
{
221-
std::string tolower(std::string str)
222-
{
223-
for (auto& c : str)
224-
{
225-
c = std::tolower(c);
226-
}
227-
228-
return str;
229-
}
230-
231-
std::map<std::string, std::string> custom_icons;
232-
}
233-
234-
void load_custom_icons()
235-
{
236-
static const std::string prefix = "icon_mapping_";
237-
auto section = WayfireShellApp::get().config.get_section("dock");
238-
239-
for (auto option : section->get_registered_options())
240-
{
241-
if (option->get_name().compare(0, prefix.length(), prefix) != 0)
242-
{
243-
continue;
244-
}
245-
246-
auto app_id = option->get_name().substr(prefix.length());
247-
custom_icons[app_id] = option->get_value_str();
248-
}
249-
}
250-
251-
bool set_custom_icon(Gtk::Image& image, std::string app_id, int size, int scale)
252-
{
253-
if (!custom_icons.count(app_id))
254-
{
255-
return false;
256-
}
257-
258-
image_set_icon(&image, custom_icons[app_id]);
259-
return true;
260-
}
261-
262-
/* Gio::DesktopAppInfo
263-
*
264-
* Usually knowing the app_id, we can get a desktop app info from Gio
265-
* The filename is either the app_id + ".desktop" or lower_app_id + ".desktop" */
266-
Icon get_from_desktop_app_info(std::string app_id)
267-
{
268-
Glib::RefPtr<Gio::DesktopAppInfo> app_info;
269-
270-
std::vector<std::string> prefixes = {
271-
"",
272-
"/usr/share/applications/",
273-
"/usr/share/applications/kde/",
274-
"/usr/share/applications/org.kde.",
275-
"/usr/share/applications/org.gnome.",
276-
"/usr/local/share/applications/",
277-
"/usr/local/share/applications/org.kde.",
278-
"/usr/local/share/applications/org.gnome.",
279-
};
280-
281-
std::vector<std::string> app_id_variations = {
282-
app_id,
283-
tolower(app_id),
284-
tolower(app_id),
285-
};
286-
// e.g. org.gnome.Evince.desktop
287-
app_id_variations[2][0] = std::toupper(app_id_variations[2][0]);
288-
289-
std::vector<std::string> suffixes = {
290-
"",
291-
".desktop"
292-
};
293-
294-
for (auto& prefix : prefixes)
295-
{
296-
for (auto& id : app_id_variations)
297-
{
298-
for (auto& suffix : suffixes)
299-
{
300-
if (!app_info)
301-
{
302-
app_info = Gio::DesktopAppInfo
303-
::create_from_filename(prefix + id + suffix);
304-
}
305-
}
306-
}
307-
}
308-
309-
if (!app_info)
310-
{
311-
// special treatment for snap apps
312-
std::string prefix = "/var/lib/snapd/desktop/applications/";
313-
auto& id = app_id_variations[1]; // seems to be lower case
314-
for (auto& suffix : suffixes)
315-
{
316-
app_info = Gio::DesktopAppInfo::create_from_filename(
317-
prefix + id + "_" + id + suffix);
318-
if (app_info)
319-
{
320-
break;
321-
}
322-
}
323-
}
324-
325-
if (app_info) // success
326-
{
327-
return app_info->get_icon();
328-
}
329-
330-
return Icon{};
331-
}
332-
333-
void set_image_from_icon(Gtk::Image& image,
334-
std::string app_id_list, int size, int scale)
335-
{
336-
std::string app_id;
337-
std::istringstream stream(app_id_list);
338-
339-
bool found_icon = false;
340-
341-
/* Wayfire sends a list of app-id's in space separated format, other compositors
342-
* send a single app-id, but in any case this works fine */
343-
auto display = image.get_display();
344-
while (stream >> app_id)
345-
{
346-
/* Try first method: custom icon file provided by the user */
347-
if (set_custom_icon(image, app_id, size, scale))
348-
{
349-
found_icon = true;
350-
break;
351-
}
352-
353-
/* Then try to load the DesktopAppInfo */
354-
auto icon = get_from_desktop_app_info(app_id);
355-
std::string icon_name = "unknown";
356-
357-
if (!icon)
358-
{
359-
/* Finally try directly looking up the icon, if it exists */
360-
if (Gtk::IconTheme::get_for_display(display)->lookup_icon(app_id, 24))
361-
{
362-
icon_name = app_id;
363-
}
364-
} else
365-
{
366-
icon_name = icon->to_string();
367-
}
368-
369-
WfIconLoadOptions options;
370-
options.user_scale = scale;
371-
image_set_icon(&image, icon_name);
372-
373-
/* finally found some icon */
374-
if (icon_name != "unknown")
375-
{
376-
found_icon = true;
377-
break;
378-
}
379-
}
380-
381-
if (!found_icon)
382-
{
383-
std::cout << "Failed to load icon for any of " << app_id_list << std::endl;
384-
}
385-
}
386-
}

src/dock/toplevel-icon.hpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,3 @@ class WfToplevelIcon
1818
private:
1919
std::unique_ptr<impl> pimpl;
2020
};
21-
22-
namespace IconProvider
23-
{
24-
/* Loads custom app_id -> icon file mappings from the section
25-
* They have the format icon_mapping_<app_id> = <icon file> */
26-
void load_custom_icons();
27-
}

src/panel/widgets/command-output.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ WfCommandOutputButtons::CommandOutput::CommandOutput(const std::string & name,
5353
{
5454
this->tooltip_command = tooltip_command;
5555

56-
image_set_icon(&icon, icon_name);
56+
IconProvider::image_set_icon(icon, icon_name);
5757

5858
if (icon_size > 0)
5959
{

src/panel/widgets/launchers.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ bool WfLauncherButton::initialize(std::string name, std::string icon, std::strin
6363

6464
void WfLauncherButton::update_icon()
6565
{
66-
image_set_icon(&m_icon, app_info->get_icon()->to_string());
66+
IconProvider::image_set_icon(m_icon, app_info->get_icon()->to_string());
6767
}
6868

6969
void WfLauncherButton::launch()

src/panel/widgets/menu.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ bool WayfireMenu::update_icon()
534534
icon = menu_icon;
535535
}
536536

537-
image_set_icon(&main_image, icon);
537+
IconProvider::image_set_icon(main_image, icon);
538538
return true;
539539
}
540540

0 commit comments

Comments
 (0)