From bc190e7b657f715c5dc21eda1d910d1d3c52664f Mon Sep 17 00:00:00 2001 From: Victor Kareh Date: Thu, 11 Jul 2019 00:23:18 -0400 Subject: Render icons as cairo surfaces for HiDPI support --- src/disks.cpp | 35 ++++++++++++++---------- src/iconthemewrapper.cpp | 6 ++-- src/iconthemewrapper.h | 2 +- src/lsof.cpp | 16 +++++------ src/prettytable.cpp | 12 ++++---- src/procman.h | 20 +++++++------- src/proctable.cpp | 71 ++++++++++++++++++++++++------------------------ src/proctable.h | 2 +- 8 files changed, 86 insertions(+), 78 deletions(-) diff --git a/src/disks.cpp b/src/disks.cpp index 3498cae..a44572c 100644 --- a/src/disks.cpp +++ b/src/disks.cpp @@ -13,6 +13,11 @@ #include "interface.h" #include "iconthemewrapper.h" +namespace +{ + const unsigned DISK_ICON_SIZE = 24; +} + enum DiskColumns { /* string columns* */ @@ -25,7 +30,7 @@ enum DiskColumns /* USED has to be the last column */ DISK_USED, // then unvisible columns - /* PixBuf column */ + /* Surface column */ DISK_ICON, /* numeric columns */ DISK_USED_PERCENTAGE, @@ -99,7 +104,7 @@ get_icon_for_device(const char *mountpoint) if (icon_name == "") // FIXME: defaults to a safe value icon_name = "drive-harddisk"; // get_icon_for_path("/"); - return icon_theme->load_icon(icon_name, 24, Gtk::ICON_LOOKUP_USE_BUILTIN); + return icon_theme->load_icon(icon_name, DISK_ICON_SIZE); } @@ -177,6 +182,7 @@ static void add_disk(GtkListStore *list, const glibtop_mountentry *entry, bool show_all_fs) { Glib::RefPtr pixbuf; + cairo_surface_t *surface; GtkTreeIter iter; glibtop_fsusage usage; guint64 bused, bfree, bavail, btotal; @@ -192,6 +198,7 @@ add_disk(GtkListStore *list, const glibtop_mountentry *entry, bool show_all_fs) fsusage_stats(&usage, &bused, &bfree, &bavail, &btotal, &percentage); pixbuf = get_icon_for_device(entry->mountdir); + surface = gdk_cairo_surface_create_from_pixbuf (pixbuf->gobj(), 0, NULL); /* if we can find a row with the same mountpoint, we get it but we still need to update all the fields. @@ -201,7 +208,7 @@ add_disk(GtkListStore *list, const glibtop_mountentry *entry, bool show_all_fs) gtk_list_store_append(list, &iter); gtk_list_store_set(list, &iter, - DISK_ICON, pixbuf->gobj(), + DISK_ICON, surface, DISK_DEVICE, entry->devname, DISK_DIR, entry->mountdir, DISK_TYPE, entry->type, @@ -357,16 +364,16 @@ create_disk_view(ProcData *procdata) gtk_box_pack_start(GTK_BOX(disk_box), scrolled, TRUE, TRUE, 0); - model = gtk_list_store_new(DISK_N_COLUMNS, /* n columns */ - G_TYPE_STRING, /* DISK_DEVICE */ - G_TYPE_STRING, /* DISK_DIR */ - G_TYPE_STRING, /* DISK_TYPE */ - G_TYPE_UINT64, /* DISK_TOTAL */ - G_TYPE_UINT64, /* DISK_FREE */ - G_TYPE_UINT64, /* DISK_AVAIL */ - G_TYPE_UINT64, /* DISK_USED */ - GDK_TYPE_PIXBUF, /* DISK_ICON */ - G_TYPE_INT /* DISK_USED_PERCENTAGE */ + model = gtk_list_store_new(DISK_N_COLUMNS, /* n columns */ + G_TYPE_STRING, /* DISK_DEVICE */ + G_TYPE_STRING, /* DISK_DIR */ + G_TYPE_STRING, /* DISK_TYPE */ + G_TYPE_UINT64, /* DISK_TOTAL */ + G_TYPE_UINT64, /* DISK_FREE */ + G_TYPE_UINT64, /* DISK_AVAIL */ + G_TYPE_UINT64, /* DISK_USED */ + CAIRO_GOBJECT_TYPE_SURFACE, /* DISK_ICON */ + G_TYPE_INT /* DISK_USED_PERCENTAGE */ ); disk_tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model)); @@ -380,7 +387,7 @@ create_disk_view(ProcData *procdata) col = gtk_tree_view_column_new(); cell = gtk_cell_renderer_pixbuf_new(); gtk_tree_view_column_pack_start(col, cell, FALSE); - gtk_tree_view_column_set_attributes(col, cell, "pixbuf", DISK_ICON, + gtk_tree_view_column_set_attributes(col, cell, "surface", DISK_ICON, NULL); cell = gtk_cell_renderer_text_new(); diff --git a/src/iconthemewrapper.cpp b/src/iconthemewrapper.cpp index 1e84b31..e44bdcd 100644 --- a/src/iconthemewrapper.cpp +++ b/src/iconthemewrapper.cpp @@ -7,12 +7,12 @@ Glib::RefPtr -procman::IconThemeWrapper::load_icon(const Glib::ustring& icon_name, - int size, Gtk::IconLookupFlags flags) const +procman::IconThemeWrapper::load_icon(const Glib::ustring& icon_name, int size) const { + gint scale = gdk_window_get_scale_factor (gdk_get_default_root_window ()); try { - return Gtk::IconTheme::get_default()->load_icon(icon_name, size, flags); + return Gtk::IconTheme::get_default()->load_icon(icon_name, size, scale, Gtk::ICON_LOOKUP_USE_BUILTIN | Gtk::ICON_LOOKUP_FORCE_SIZE); } catch (Gtk::IconThemeError &error) { diff --git a/src/iconthemewrapper.h b/src/iconthemewrapper.h index 81fb8d8..3a8bde5 100644 --- a/src/iconthemewrapper.h +++ b/src/iconthemewrapper.h @@ -13,7 +13,7 @@ namespace procman public: // returns 0 instead of raising an exception Glib::RefPtr - load_icon(const Glib::ustring& icon_name, int size, Gtk::IconLookupFlags flags) const; + load_icon(const Glib::ustring& icon_name, int size) const; const IconThemeWrapper* operator->() const { return this; } diff --git a/src/lsof.cpp b/src/lsof.cpp index c2c0fda..121205f 100644 --- a/src/lsof.cpp +++ b/src/lsof.cpp @@ -73,7 +73,7 @@ namespace enum ProcmanLsof { - PROCMAN_LSOF_COL_PIXBUF, + PROCMAN_LSOF_COL_SURFACE, PROCMAN_LSOF_COL_PROCESS, PROCMAN_LSOF_COL_PID, PROCMAN_LSOF_COL_FILENAME, @@ -174,7 +174,7 @@ namespace GtkTreeIter file; gtk_list_store_append(this->model, &file); gtk_list_store_set(this->model, &file, - PROCMAN_LSOF_COL_PIXBUF, info.pixbuf->gobj(), + PROCMAN_LSOF_COL_SURFACE, info.surface, PROCMAN_LSOF_COL_PROCESS, info.name, PROCMAN_LSOF_COL_PID, info.pid, PROCMAN_LSOF_COL_FILENAME, it->c_str(), @@ -239,10 +239,10 @@ void procman_lsof(ProcData *procdata) { GtkListStore *model = \ gtk_list_store_new(PROCMAN_LSOF_NCOLS, - GDK_TYPE_PIXBUF, // PROCMAN_LSOF_COL_PIXBUF - G_TYPE_STRING, // PROCMAN_LSOF_COL_PROCESS - G_TYPE_UINT, // PROCMAN_LSOF_COL_PID - G_TYPE_STRING // PROCMAN_LSOF_COL_FILENAME + CAIRO_GOBJECT_TYPE_SURFACE, // PROCMAN_LSOF_COL_SURFACE + G_TYPE_STRING, // PROCMAN_LSOF_COL_PROCESS + G_TYPE_UINT, // PROCMAN_LSOF_COL_PID + G_TYPE_STRING // PROCMAN_LSOF_COL_FILENAME ); GtkWidget *tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model)); @@ -251,14 +251,14 @@ void procman_lsof(ProcData *procdata) GtkTreeViewColumn *column; GtkCellRenderer *renderer; - // PIXBUF / PROCESS + // SURFACE / PROCESS column = gtk_tree_view_column_new(); renderer = gtk_cell_renderer_pixbuf_new(); gtk_tree_view_column_pack_start(column, renderer, FALSE); gtk_tree_view_column_set_attributes(column, renderer, - "pixbuf", PROCMAN_LSOF_COL_PIXBUF, + "surface", PROCMAN_LSOF_COL_SURFACE, NULL); renderer = gtk_cell_renderer_text_new(); diff --git a/src/prettytable.cpp b/src/prettytable.cpp index 647e15b..7b8bed6 100644 --- a/src/prettytable.cpp +++ b/src/prettytable.cpp @@ -57,7 +57,7 @@ PrettyTable::on_application_opened(WnckScreen* screen, WnckApplication* app, gpo f = fopen (icon_name, "r"); if (f != NULL) { fclose (f); - icon = that->theme->load_icon(icon_name, APP_ICON_SIZE, Gtk::ICON_LOOKUP_USE_BUILTIN); + icon = that->theme->load_icon(icon_name, APP_ICON_SIZE); } if (not icon) { @@ -116,7 +116,7 @@ PrettyTable::unregister_application(pid_t pid) Glib::RefPtr PrettyTable::get_icon_from_theme(const ProcInfo &info) { - return this->theme->load_icon(info.name, APP_ICON_SIZE, Gtk::ICON_LOOKUP_USE_BUILTIN | Gtk::ICON_LOOKUP_FORCE_SIZE); + return this->theme->load_icon(info.name, APP_ICON_SIZE); } @@ -149,7 +149,7 @@ PrettyTable::get_icon_from_default(const ProcInfo &info) IconCache::iterator it(this->defaults.find(name)); if (it == this->defaults.end()) { - pix = this->theme->load_icon(name, APP_ICON_SIZE, Gtk::ICON_LOOKUP_USE_BUILTIN | Gtk::ICON_LOOKUP_FORCE_SIZE); + pix = this->theme->load_icon(name, APP_ICON_SIZE); if (pix) this->defaults[name] = pix; } else @@ -179,14 +179,14 @@ PrettyTable::get_icon_from_wnck(const ProcInfo &info) Glib::RefPtr PrettyTable::get_icon_from_name(const ProcInfo &info) { - return this->theme->load_icon(info.name, APP_ICON_SIZE, Gtk::ICON_LOOKUP_USE_BUILTIN | Gtk::ICON_LOOKUP_FORCE_SIZE); + return this->theme->load_icon(info.name, APP_ICON_SIZE); } Glib::RefPtr PrettyTable::get_icon_dummy(const ProcInfo &) { - return this->theme->load_icon("application-x-executable", APP_ICON_SIZE, Gtk::ICON_LOOKUP_USE_BUILTIN); + return this->theme->load_icon("application-x-executable", APP_ICON_SIZE); } @@ -212,7 +212,7 @@ Glib::RefPtr PrettyTable::get_icon_for_kernel(const ProcInfo &info) { if (is_kthread(info)) - return this->theme->load_icon("applications-system", APP_ICON_SIZE, Gtk::ICON_LOOKUP_USE_BUILTIN); + return this->theme->load_icon("applications-system", APP_ICON_SIZE); return Glib::RefPtr(); } diff --git a/src/procman.h b/src/procman.h index 44ef2bc..ca58cbf 100644 --- a/src/procman.h +++ b/src/procman.h @@ -21,6 +21,7 @@ #include +#include #include #include #include @@ -190,17 +191,16 @@ class ProcInfo void set_user(guint uid); std::string lookup_user(guint uid); - GtkTreeIter node; - Glib::RefPtr pixbuf; - gchar *tooltip; - gchar *name; - gchar *arguments; + GtkTreeIter node; + cairo_surface_t *surface; + gchar *tooltip; + gchar *name; + gchar *arguments; + gchar *security_context; - gchar *security_context; - - const pid_t pid; - pid_t ppid; - guint uid; + const pid_t pid; + pid_t ppid; + guint uid; // private: // tracks cpu time per process keeps growing because if a diff --git a/src/proctable.cpp b/src/proctable.cpp index 7b309da..b9b0a75 100644 --- a/src/proctable.cpp +++ b/src/proctable.cpp @@ -20,7 +20,7 @@ #include - +#include #include #include #include @@ -281,36 +281,36 @@ proctable_new (ProcData * const procdata) GTK_POLICY_AUTOMATIC); model = gtk_tree_store_new (NUM_COLUMNS, - G_TYPE_STRING, /* Process Name */ - G_TYPE_STRING, /* User */ - G_TYPE_UINT, /* Status */ - G_TYPE_ULONG, /* VM Size */ - G_TYPE_ULONG, /* Resident Memory */ - G_TYPE_ULONG, /* Writable Memory */ - G_TYPE_ULONG, /* Shared Memory */ - G_TYPE_ULONG, /* X Server Memory */ - G_TYPE_UINT, /* % CPU */ - G_TYPE_UINT64, /* CPU time */ - G_TYPE_ULONG, /* Started */ - G_TYPE_INT, /* Nice */ - G_TYPE_UINT, /* ID */ - G_TYPE_STRING, /* Security Context */ - G_TYPE_STRING, /* Arguments */ - G_TYPE_ULONG, /* Memory */ - G_TYPE_STRING, /* wchan */ - G_TYPE_STRING, /* Cgroup */ - G_TYPE_STRING, /* Unit */ - G_TYPE_STRING, /* Session */ - G_TYPE_STRING, /* Seat */ - G_TYPE_STRING, /* Owner */ - G_TYPE_UINT64, /* Disk read total */ - G_TYPE_UINT64, /* Disk write total*/ - G_TYPE_UINT64, /* Disk read */ - G_TYPE_UINT64, /* Disk write */ - G_TYPE_STRING, /* Priority */ - GDK_TYPE_PIXBUF, /* Icon */ - G_TYPE_POINTER, /* ProcInfo */ - G_TYPE_STRING /* Sexy tooltip */ + G_TYPE_STRING, /* Process Name */ + G_TYPE_STRING, /* User */ + G_TYPE_UINT, /* Status */ + G_TYPE_ULONG, /* VM Size */ + G_TYPE_ULONG, /* Resident Memory */ + G_TYPE_ULONG, /* Writable Memory */ + G_TYPE_ULONG, /* Shared Memory */ + G_TYPE_ULONG, /* X Server Memory */ + G_TYPE_UINT, /* % CPU */ + G_TYPE_UINT64, /* CPU time */ + G_TYPE_ULONG, /* Started */ + G_TYPE_INT, /* Nice */ + G_TYPE_UINT, /* ID */ + G_TYPE_STRING, /* Security Context */ + G_TYPE_STRING, /* Arguments */ + G_TYPE_ULONG, /* Memory */ + G_TYPE_STRING, /* wchan */ + G_TYPE_STRING, /* Cgroup */ + G_TYPE_STRING, /* Unit */ + G_TYPE_STRING, /* Session */ + G_TYPE_STRING, /* Seat */ + G_TYPE_STRING, /* Owner */ + G_TYPE_UINT64, /* Disk read total */ + G_TYPE_UINT64, /* Disk write total*/ + G_TYPE_UINT64, /* Disk read */ + G_TYPE_UINT64, /* Disk write */ + G_TYPE_STRING, /* Priority */ + CAIRO_GOBJECT_TYPE_SURFACE, /* Icon */ + G_TYPE_POINTER, /* ProcInfo */ + G_TYPE_STRING /* Sexy tooltip */ ); proctree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model)); @@ -332,7 +332,7 @@ proctable_new (ProcData * const procdata) cell_renderer = gtk_cell_renderer_pixbuf_new (); gtk_tree_view_column_pack_start (column, cell_renderer, FALSE); gtk_tree_view_column_set_attributes (column, cell_renderer, - "pixbuf", COL_PIXBUF, + "surface", COL_SURFACE, NULL); cell_renderer = gtk_cell_renderer_text_new (); @@ -549,6 +549,7 @@ ProcInfo::~ProcInfo() g_free(this->unit); g_free(this->session); g_free(this->seat); + cairo_surface_destroy(this->surface); } @@ -875,7 +876,7 @@ update_info (ProcData *procdata, ProcInfo *info) ProcInfo::ProcInfo(pid_t pid) : node(), - pixbuf(), + surface(), tooltip(NULL), name(NULL), arguments(NULL), @@ -1161,11 +1162,11 @@ make_loadavg_string(void) void ProcInfo::set_icon(Glib::RefPtr icon) { - this->pixbuf = icon; + this->surface = gdk_cairo_surface_create_from_pixbuf (icon->gobj(), 0, NULL); GtkTreeModel *model; model = gtk_tree_view_get_model(GTK_TREE_VIEW(ProcData::get_instance()->tree)); gtk_tree_store_set(GTK_TREE_STORE(model), &this->node, - COL_PIXBUF, (this->pixbuf ? this->pixbuf->gobj() : NULL), + COL_SURFACE, this->surface, -1); } diff --git a/src/proctable.h b/src/proctable.h index a3dce05..e47c6d8 100644 --- a/src/proctable.h +++ b/src/proctable.h @@ -53,7 +53,7 @@ enum COL_DISK_WRITE_CURRENT, COL_DISK_READ_CURRENT, COL_PRIORITY, - COL_PIXBUF, + COL_SURFACE, COL_POINTER, COL_TOOLTIP, NUM_COLUMNS -- cgit v1.2.1