diff options
-rw-r--r-- | src/iconthemewrapper.cpp | 28 | ||||
-rw-r--r-- | src/iconthemewrapper.h | 2 | ||||
-rw-r--r-- | src/prettytable.cpp | 59 | ||||
-rw-r--r-- | src/prettytable.h | 11 |
4 files changed, 98 insertions, 2 deletions
diff --git a/src/iconthemewrapper.cpp b/src/iconthemewrapper.cpp index e44bdcd..f5ab4ef 100644 --- a/src/iconthemewrapper.cpp +++ b/src/iconthemewrapper.cpp @@ -27,3 +27,31 @@ procman::IconThemeWrapper::load_icon(const Glib::ustring& icon_name, int size) c } } +Glib::RefPtr<Gdk::Pixbuf> +procman::IconThemeWrapper::load_gicon(const Glib::RefPtr<Gio::Icon>& gicon, + int size, Gtk::IconLookupFlags flags) const +{ + Gtk::IconInfo icon_info; + gint scale = gdk_window_get_scale_factor (gdk_get_default_root_window ()); + icon_info = Gtk::IconTheme::get_default()->lookup_icon(gicon, size, scale, flags); + + if (!icon_info) { + return Glib::RefPtr<Gdk::Pixbuf>(); + } + + try + { + return icon_info.load_icon(); + } + catch (Gtk::IconThemeError &error) + { + if (error.code() != Gtk::IconThemeError::ICON_THEME_NOT_FOUND) + g_error("Cannot load gicon from theme: %s", error.what().c_str()); + return Glib::RefPtr<Gdk::Pixbuf>(); + } + catch (Gio::Error &error) + { + g_debug("Could not load gicon: %s", error.what().c_str()); + return Glib::RefPtr<Gdk::Pixbuf>(); + } +} diff --git a/src/iconthemewrapper.h b/src/iconthemewrapper.h index 3a8bde5..81222b9 100644 --- a/src/iconthemewrapper.h +++ b/src/iconthemewrapper.h @@ -14,6 +14,8 @@ namespace procman // returns 0 instead of raising an exception Glib::RefPtr<Gdk::Pixbuf> load_icon(const Glib::ustring& icon_name, int size) const; + Glib::RefPtr<Gdk::Pixbuf> + load_gicon(const Glib::RefPtr<Gio::Icon>& gicon, int size, Gtk::IconLookupFlags flags) const; const IconThemeWrapper* operator->() const { return this; } diff --git a/src/prettytable.cpp b/src/prettytable.cpp index 7b8bed6..cbc5f0d 100644 --- a/src/prettytable.cpp +++ b/src/prettytable.cpp @@ -7,6 +7,10 @@ #include <string.h> #include <gdk-pixbuf/gdk-pixbuf.h> #include <glibtop/procstate.h> +#include <giomm/error.h> +#include <giomm/file.h> +#include <glibmm/miscutils.h> +#include <iostream> #include <vector> @@ -29,6 +33,20 @@ PrettyTable::PrettyTable() G_CALLBACK(PrettyTable::on_application_opened), this); g_signal_connect(G_OBJECT(screen), "application_closed", G_CALLBACK(PrettyTable::on_application_closed), this); + + // init GIO apps cache + std::vector<std::string> dirs = Glib::get_system_data_dirs(); + for (std::vector<std::string>::iterator it = dirs.begin(); it != dirs.end(); ++it) { + std::string path = (*it).append("/applications"); + Glib::RefPtr<Gio::File> file = Gio::File::create_for_path(path); + Glib::RefPtr<Gio::FileMonitor> monitor = file->monitor_directory(); + monitor->set_rate_limit(1000); // 1 second + + monitor->signal_changed().connect(sigc::mem_fun(this, &PrettyTable::file_monitor_event)); + monitors[path] = monitor; + } + + this->init_gio_app_cache(); } @@ -87,8 +105,6 @@ PrettyTable::register_application(pid_t pid, Glib::RefPtr<Gdk::Pixbuf> icon) } } - - void PrettyTable::on_application_closed(WnckScreen* screen, WnckApplication* app, gpointer data) { @@ -100,7 +116,25 @@ PrettyTable::on_application_closed(WnckScreen* screen, WnckApplication* app, gpo static_cast<PrettyTable*>(data)->unregister_application(pid); } +void PrettyTable::init_gio_app_cache () +{ + this->gio_apps.clear(); + + Glib::ListHandle<Glib::RefPtr<Gio::AppInfo>> registered_apps = Gio::AppInfo::get_all(); + for (Glib::ListHandle<Glib::RefPtr<Gio::AppInfo>>::const_iterator it = registered_apps.begin(); it != registered_apps.end(); ++it) { + Glib::RefPtr<Gio::AppInfo> app = *it; + std::string executable = app->get_executable(); + if (executable != "sh" && executable != "env") + this->gio_apps[executable] = app; + } +} +void PrettyTable::file_monitor_event(Glib::RefPtr<Gio::File>, + Glib::RefPtr<Gio::File>, + Gio::FileMonitorEvent) +{ + this->init_gio_app_cache(); +} void PrettyTable::unregister_application(pid_t pid) @@ -159,7 +193,27 @@ PrettyTable::get_icon_from_default(const ProcInfo &info) return pix; } +Glib::RefPtr<Gdk::Pixbuf> +PrettyTable::get_icon_from_gio(const ProcInfo &info) +{ + gchar **cmdline = g_strsplit(info.name, " ", 2); + const gchar *executable = cmdline[0]; + Glib::RefPtr<Gdk::Pixbuf> icon; + + if (executable) { + Glib::RefPtr<Gio::AppInfo> app = this->gio_apps[executable]; + Glib::RefPtr<Gio::Icon> gicon; + if (app) + gicon = app->get_icon(); + + if (gicon) + icon = this->theme->load_gicon(gicon, APP_ICON_SIZE, Gtk::ICON_LOOKUP_USE_BUILTIN | Gtk::ICON_LOOKUP_FORCE_SIZE); + } + + g_strfreev(cmdline); + return icon; +} Glib::RefPtr<Gdk::Pixbuf> PrettyTable::get_icon_from_wnck(const ProcInfo &info) @@ -229,6 +283,7 @@ PrettyTable::set_icon(ProcInfo &info) if (getters.empty()) { + getters.push_back(&PrettyTable::get_icon_from_gio); getters.push_back(&PrettyTable::get_icon_from_wnck); getters.push_back(&PrettyTable::get_icon_from_theme); getters.push_back(&PrettyTable::get_icon_from_default); diff --git a/src/prettytable.h b/src/prettytable.h index 2109121..ac150de 100644 --- a/src/prettytable.h +++ b/src/prettytable.h @@ -7,6 +7,7 @@ #include <gdk-pixbuf/gdk-pixbuf.h> #include <glibmm/refptr.h> #include <gdkmm/pixbuf.h> +#include <giomm/filemonitor.h> #include <map> #include <string> @@ -43,18 +44,28 @@ private: Glib::RefPtr<Gdk::Pixbuf> get_icon_from_theme(const ProcInfo &); Glib::RefPtr<Gdk::Pixbuf> get_icon_from_default(const ProcInfo &); + Glib::RefPtr<Gdk::Pixbuf> get_icon_from_gio(const ProcInfo &); Glib::RefPtr<Gdk::Pixbuf> get_icon_from_wnck(const ProcInfo &); Glib::RefPtr<Gdk::Pixbuf> get_icon_from_name(const ProcInfo &); Glib::RefPtr<Gdk::Pixbuf> get_icon_for_kernel(const ProcInfo &); Glib::RefPtr<Gdk::Pixbuf> get_icon_dummy(const ProcInfo &); bool get_default_icon_name(const string &cmd, string &name); + void file_monitor_event (Glib::RefPtr<Gio::File>, + Glib::RefPtr<Gio::File>, + Gio::FileMonitorEvent); + void init_gio_app_cache (); + typedef std::map<string, Glib::RefPtr<Gdk::Pixbuf> > IconCache; typedef std::map<pid_t, Glib::RefPtr<Gdk::Pixbuf> > IconsForPID; + typedef std::map<string, Glib::RefPtr<Gio::AppInfo> > AppCache; + typedef std::map<string, Glib::RefPtr<Gio::FileMonitor> > DesktopDirMonitors; IconsForPID apps; IconCache defaults; + DesktopDirMonitors monitors; + AppCache gio_apps; procman::IconThemeWrapper theme; }; |