Finish
This commit is contained in:
		
							parent
							
								
									61783aafaa
								
							
						
					
					
						commit
						38afa345dd
					
				|  | @ -9,6 +9,7 @@ | ||||||
| #include <memory> | #include <memory> | ||||||
| #include <string> | #include <string> | ||||||
| #include <vector> | #include <vector> | ||||||
|  | #include <map> | ||||||
| #include <unordered_set> | #include <unordered_set> | ||||||
| 
 | 
 | ||||||
| #include <gdk/gdk.h> | #include <gdk/gdk.h> | ||||||
|  | @ -66,7 +67,8 @@ class Task | ||||||
|     bool button_visible_; |     bool button_visible_; | ||||||
|     bool ignored_; |     bool ignored_; | ||||||
| 
 | 
 | ||||||
|     bool with_icon_; |     bool with_icon_ = false; | ||||||
|  |     bool with_name_ = false; | ||||||
|     std::string format_before_; |     std::string format_before_; | ||||||
|     std::string format_after_; |     std::string format_after_; | ||||||
| 
 | 
 | ||||||
|  | @ -80,7 +82,8 @@ class Task | ||||||
|    private: |    private: | ||||||
|     std::string repr() const; |     std::string repr() const; | ||||||
|     std::string state_string(bool = false) const; |     std::string state_string(bool = false) const; | ||||||
| 	void set_desktop_app_info(const std::string &app_id); | 	void set_app_info_from_app_id_list(const std::string& app_id_list); | ||||||
|  | 	bool image_load_icon(Gtk::Image& image, const Glib::RefPtr<Gtk::IconTheme>& icon_theme, Glib::RefPtr<Gio::DesktopAppInfo> app_info, int size); | ||||||
| 
 | 
 | ||||||
|    public: |    public: | ||||||
|     /* Getter functions */ |     /* Getter functions */ | ||||||
|  | @ -139,6 +142,7 @@ class Taskbar : public waybar::AModule | ||||||
| 
 | 
 | ||||||
|     std::vector<Glib::RefPtr<Gtk::IconTheme>> icon_themes_; |     std::vector<Glib::RefPtr<Gtk::IconTheme>> icon_themes_; | ||||||
|     std::unordered_set<std::string> ignore_list_; |     std::unordered_set<std::string> ignore_list_; | ||||||
|  | 	std::map<std::string, std::string> app_ids_replace_map_; | ||||||
| 
 | 
 | ||||||
|     struct zwlr_foreign_toplevel_manager_v1 *manager_; |     struct zwlr_foreign_toplevel_manager_v1 *manager_; | ||||||
|     struct wl_seat *seat_; |     struct wl_seat *seat_; | ||||||
|  | @ -161,8 +165,9 @@ class Taskbar : public waybar::AModule | ||||||
|     bool show_output(struct wl_output *) const; |     bool show_output(struct wl_output *) const; | ||||||
|     bool all_outputs() const; |     bool all_outputs() const; | ||||||
| 
 | 
 | ||||||
|     std::vector<Glib::RefPtr<Gtk::IconTheme>> icon_themes() const; |     const std::vector<Glib::RefPtr<Gtk::IconTheme>>& icon_themes() const; | ||||||
|     const std::unordered_set<std::string>& ignore_list() const; |     const std::unordered_set<std::string>& ignore_list() const; | ||||||
|  |     const std::map<std::string, std::string>& app_ids_replace_map() const; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } /* namespace waybar::modules::wlr */ | } /* namespace waybar::modules::wlr */ | ||||||
|  |  | ||||||
|  | @ -72,10 +72,16 @@ Addressed by *wlr/taskbar* | ||||||
| 	typeof: array ++ | 	typeof: array ++ | ||||||
| 	List of app_id to be invisible. | 	List of app_id to be invisible. | ||||||
| 
 | 
 | ||||||
|  | *app_ids-mapping*: ++ | ||||||
|  | 	typeof: object ++ | ||||||
|  | 	Directory of app_id to be replaced with | ||||||
|  | 
 | ||||||
| # FORMAT REPLACEMENTS | # FORMAT REPLACEMENTS | ||||||
| 
 | 
 | ||||||
| *{icon}*: The icon of the application. | *{icon}*: The icon of the application. | ||||||
| 
 | 
 | ||||||
|  | *{title}*: The application name as in desktop file if appropriate desktop fils found, otherwise same as {app_id} | ||||||
|  | 
 | ||||||
| *{title}*: The title of the application. | *{title}*: The title of the application. | ||||||
| 
 | 
 | ||||||
| *{app_id}*: The app_id (== application name) of the application. | *{app_id}*: The app_id (== application name) of the application. | ||||||
|  | @ -105,7 +111,10 @@ Addressed by *wlr/taskbar* | ||||||
| 	"on-click-middle": "close", | 	"on-click-middle": "close", | ||||||
| 	"ignore-list": [ | 	"ignore-list": [ | ||||||
| 	    "Alacritty" | 	    "Alacritty" | ||||||
| 	] | 	], | ||||||
|  | 	"app_ids-mapping": { | ||||||
|  | 		"firefoxdeveloperedition": "firefox-developer-edition" | ||||||
|  | 	} | ||||||
| } | } | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -11,7 +11,9 @@ | ||||||
| #include <cstring> | #include <cstring> | ||||||
| #include <memory> | #include <memory> | ||||||
| #include <sstream> | #include <sstream> | ||||||
|  | #include <utility> | ||||||
| 
 | 
 | ||||||
|  | #include <fmt/core.h> | ||||||
| #include <gdkmm/monitor.h> | #include <gdkmm/monitor.h> | ||||||
| 
 | 
 | ||||||
| #include <gtkmm/icontheme.h> | #include <gtkmm/icontheme.h> | ||||||
|  | @ -86,7 +88,7 @@ static Glib::RefPtr<Gdk::Pixbuf> load_icon_from_file(std::string icon_path, int | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static Glib::RefPtr<GDesktopAppInfo> get_app_info_by_name(const std::string& app_id) | static Glib::RefPtr<Gio::DesktopAppInfo> get_app_info_by_name(const std::string& app_id) | ||||||
| { | { | ||||||
|     static std::vector<std::string> prefixes = search_prefix(); |     static std::vector<std::string> prefixes = search_prefix(); | ||||||
| 
 | 
 | ||||||
|  | @ -118,12 +120,11 @@ static Glib::RefPtr<GDesktopAppInfo> get_app_info_by_name(const std::string& app | ||||||
| 	return {}; | 	return {}; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Task::set_desktop_app_info(const std::string &app_id) | Glib::RefPtr<Gio::DesktopAppInfo> get_desktop_app_info(const std::string &app_id) | ||||||
| { | { | ||||||
| 	auto app_info = get_app_info_by_name(app_id); | 	auto app_info = get_app_info_by_name(app_id); | ||||||
| 	if (app_info) { | 	if (app_info) { | ||||||
| 		app_info_ =  app_info; | 		return app_info; | ||||||
| 		return; |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|     std::string desktop_file = ""; |     std::string desktop_file = ""; | ||||||
|  | @ -133,7 +134,6 @@ void Task::set_desktop_app_info(const std::string &app_id) | ||||||
|         for (size_t i=0; desktop_list[0][i]; i++) { |         for (size_t i=0; desktop_list[0][i]; i++) { | ||||||
|             if (desktop_file == "") { |             if (desktop_file == "") { | ||||||
|                 desktop_file = desktop_list[0][i]; |                 desktop_file = desktop_list[0][i]; | ||||||
| 				// TODO: debug. Possible error
 |  | ||||||
|             } else { |             } else { | ||||||
|                 auto tmp_info = Gio::DesktopAppInfo::create(desktop_list[0][i]); |                 auto tmp_info = Gio::DesktopAppInfo::create(desktop_list[0][i]); | ||||||
|                 auto startup_class = tmp_info->get_startup_wm_class(); |                 auto startup_class = tmp_info->get_startup_wm_class(); | ||||||
|  | @ -148,12 +148,45 @@ void Task::set_desktop_app_info(const std::string &app_id) | ||||||
|     } |     } | ||||||
|     g_free(desktop_list); |     g_free(desktop_list); | ||||||
| 
 | 
 | ||||||
|     app_info = get_app_info_by_name(desktop_file); |     return get_app_info_by_name(desktop_file); | ||||||
| 	app_info_ = app_info; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Method 2 - use the app_id and check whether there is an icon with this name in the icon theme */ | void Task::set_app_info_from_app_id_list(const std::string& app_id_list) { | ||||||
| static std::string get_from_icon_theme(const Glib::RefPtr<Gtk::IconTheme>& icon_theme, |     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) | ||||||
|  |     { | ||||||
|  |         app_info_ = get_desktop_app_info(app_id); | ||||||
|  | 		if (app_info_) { | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		auto lower_app_id = app_id; | ||||||
|  | 		std::transform(lower_app_id.begin(), lower_app_id.end(), lower_app_id.begin(), | ||||||
|  | 				[](char c){ return std::tolower(c); }); | ||||||
|  | 		app_info_ = get_desktop_app_info(lower_app_id); | ||||||
|  | 		if (app_info_) { | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 				 | ||||||
|  |         size_t start = 0, end = app_id.size(); | ||||||
|  |         start = app_id.rfind(".", end); | ||||||
|  |         std::string app_name = app_id.substr(start+1, app_id.size()); | ||||||
|  |         app_info_ = get_desktop_app_info(app_name); | ||||||
|  | 		if (app_info_) { | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  |         start = app_id.find("-"); | ||||||
|  |         app_name = app_id.substr(0, start); | ||||||
|  |         app_info_ = get_desktop_app_info(app_name); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static std::string get_icon_name_from_icon_theme(const Glib::RefPtr<Gtk::IconTheme>& icon_theme, | ||||||
|         const std::string &app_id) |         const std::string &app_id) | ||||||
| { | { | ||||||
|     if (icon_theme->lookup_icon(app_id, 24)) |     if (icon_theme->lookup_icon(app_id, 24)) | ||||||
|  | @ -162,62 +195,37 @@ static std::string get_from_icon_theme(const Glib::RefPtr<Gtk::IconTheme>& icon_ | ||||||
|     return ""; |     return ""; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static bool image_load_icon(Gtk::Image& image, const Glib::RefPtr<Gtk::IconTheme>& icon_theme, | bool Task::image_load_icon(Gtk::Image& image, const Glib::RefPtr<Gtk::IconTheme>& icon_theme, Glib::RefPtr<Gio::DesktopAppInfo> app_info, int size) | ||||||
|         const std::string &app_id_list, int size) |  | ||||||
| { | { | ||||||
|     std::string app_id; | 	std::string ret_icon_name = "unknown"; | ||||||
|     std::istringstream stream(app_id_list); | 	if (app_info) { | ||||||
|     bool found = false; | 		std::string icon_name = get_icon_name_from_icon_theme(icon_theme, app_info->get_startup_wm_class()); | ||||||
|  | 		if (!icon_name.empty()) { | ||||||
|  | 			ret_icon_name = icon_name; | ||||||
|  | 		} else { | ||||||
|  | 			if (app_info->get_icon()) { | ||||||
|  | 				ret_icon_name = app_info->get_icon()->to_string(); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
|     /* Wayfire sends a list of app-id's in space separated format, other compositors
 | 	Glib::RefPtr<Gdk::Pixbuf> pixbuf; | ||||||
|      * send a single app-id, but in any case this works fine */ |  | ||||||
|     while (stream >> app_id) |  | ||||||
|     { |  | ||||||
|         size_t start = 0, end = app_id.size(); |  | ||||||
|         start = app_id.rfind(".", end); |  | ||||||
|         std::string app_name = app_id.substr(start+1, app_id.size()); |  | ||||||
| 
 | 
 | ||||||
|         auto lower_app_id = app_id; | 	try { | ||||||
|         std::transform(lower_app_id.begin(), lower_app_id.end(), lower_app_id.begin(), | 		pixbuf = icon_theme->load_icon(ret_icon_name, size, Gtk::ICON_LOOKUP_FORCE_SIZE); | ||||||
|                 [](char c){ return std::tolower(c); }); | 	} catch(...) { | ||||||
|  | 		if (Glib::file_test(ret_icon_name, Glib::FILE_TEST_EXISTS)) | ||||||
|  | 			pixbuf = load_icon_from_file(ret_icon_name, size); | ||||||
|  | 		else | ||||||
|  | 			pixbuf = {}; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
|         std::string icon_name = get_from_icon_theme(icon_theme, app_id); | 	if (pixbuf) { | ||||||
|  | 		image.set(pixbuf); | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
|         if (icon_name.empty()) |     return false; | ||||||
|             icon_name = get_from_icon_theme(icon_theme, lower_app_id); |  | ||||||
|         if (icon_name.empty()) |  | ||||||
|             icon_name = get_from_icon_theme(icon_theme, app_name); |  | ||||||
|         if (icon_name.empty()) |  | ||||||
|             icon_name = get_from_desktop_app_info(app_id); |  | ||||||
|         if (icon_name.empty()) |  | ||||||
|             icon_name = get_from_desktop_app_info(lower_app_id); |  | ||||||
|         if (icon_name.empty()) |  | ||||||
|             icon_name = get_from_desktop_app_info(app_name); |  | ||||||
|         if (icon_name.empty()) |  | ||||||
|             icon_name = get_from_desktop_app_info_search(app_id); |  | ||||||
| 
 |  | ||||||
|         if (icon_name.empty()) |  | ||||||
|             icon_name = "unknown"; |  | ||||||
| 
 |  | ||||||
|         Glib::RefPtr<Gdk::Pixbuf> pixbuf; |  | ||||||
| 
 |  | ||||||
|         try { |  | ||||||
|             pixbuf = icon_theme->load_icon(icon_name, size, Gtk::ICON_LOOKUP_FORCE_SIZE); |  | ||||||
|         } catch(...) { |  | ||||||
|             if (Glib::file_test(icon_name, Glib::FILE_TEST_EXISTS)) |  | ||||||
|                 pixbuf = load_icon_from_file(icon_name, size); |  | ||||||
|             else |  | ||||||
|                 pixbuf = {}; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (pixbuf) { |  | ||||||
|             image.set(pixbuf); |  | ||||||
|             found = true; |  | ||||||
|             break; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return found; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Task class implementation */ | /* Task class implementation */ | ||||||
|  | @ -298,13 +306,15 @@ Task::Task(const waybar::Bar &bar, const Json::Value &config, Taskbar *tbar, | ||||||
|     content_.show(); |     content_.show(); | ||||||
|     button_.add(content_); |     button_.add(content_); | ||||||
| 
 | 
 | ||||||
|     with_icon_ = false; |  | ||||||
|     format_before_.clear(); |     format_before_.clear(); | ||||||
|     format_after_.clear(); |     format_after_.clear(); | ||||||
| 
 | 
 | ||||||
|     if (config_["format"].isString()) { |     if (config_["format"].isString()) { | ||||||
|         /* The user defined a format string, use it */ |         /* The user defined a format string, use it */ | ||||||
|         auto format = config_["format"].asString(); |         auto format = config_["format"].asString(); | ||||||
|  | 		if (format.find("{name}") != std::string::npos) { | ||||||
|  | 			with_name_ = true; | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
|         auto icon_pos = format.find("{icon}"); |         auto icon_pos = format.find("{icon}"); | ||||||
|         if (icon_pos == 0) { |         if (icon_pos == 0) { | ||||||
|  | @ -406,13 +416,28 @@ void Task::handle_app_id(const char *app_id) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (!with_icon_) | 	auto ids_replace_map = tbar_->app_ids_replace_map(); | ||||||
|  | 	if (ids_replace_map.count(app_id_)) { | ||||||
|  | 		auto replaced_id = ids_replace_map[app_id_]; | ||||||
|  | 		spdlog::debug(fmt::format("Task ({}) [{}] app_id was replaced with {}", id_, app_id_, replaced_id)); | ||||||
|  | 		app_id_ = replaced_id; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (!with_icon_ && !with_name_) { | ||||||
|         return; |         return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	set_app_info_from_app_id_list(app_id_); | ||||||
|  | 	name_ = app_info_ ? app_info_->get_display_name() : app_id; | ||||||
|  | 
 | ||||||
|  | 	if (!with_icon_) { | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
|     int icon_size = config_["icon-size"].isInt() ? config_["icon-size"].asInt() : 16; |     int icon_size = config_["icon-size"].isInt() ? config_["icon-size"].asInt() : 16; | ||||||
|     bool found = false; |     bool found = false; | ||||||
|     for (auto& icon_theme : tbar_->icon_themes()) { |     for (auto& icon_theme : tbar_->icon_themes()) { | ||||||
|         if (image_load_icon(icon_, icon_theme, app_id_, icon_size)) { |         if (image_load_icon(icon_, icon_theme, app_info_, icon_size)) { | ||||||
|             found = true; |             found = true; | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|  | @ -735,6 +760,15 @@ Taskbar::Taskbar(const std::string &id, const waybar::Bar &bar, const Json::Valu | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     // Load app_id remappings
 | ||||||
|  |     if (config_["app_ids-mapping"].isObject()) { | ||||||
|  | 		const Json::Value& mapping = config_["app_ids-mapping"]; | ||||||
|  | 		const std::vector<std::string> app_ids = config_["app_ids-mapping"].getMemberNames(); | ||||||
|  |         for (auto& app_id : app_ids) { | ||||||
|  |           app_ids_replace_map_.emplace(app_id, mapping[app_id].asString()); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     icon_themes_.push_back(Gtk::IconTheme::get_default()); |     icon_themes_.push_back(Gtk::IconTheme::get_default()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -866,10 +900,10 @@ bool Taskbar::all_outputs() const | ||||||
|     return config_["all-outputs"].isBool() && config_["all-outputs"].asBool(); |     return config_["all-outputs"].isBool() && config_["all-outputs"].asBool(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::vector<Glib::RefPtr<Gtk::IconTheme>> Taskbar::icon_themes() const | const std::vector<Glib::RefPtr<Gtk::IconTheme>>& Taskbar::icon_themes() const { return icon_themes_; } | ||||||
| { | 
 | ||||||
|     return icon_themes_; | const std::unordered_set<std::string>& Taskbar::ignore_list() const { return ignore_list_; } | ||||||
| } | 
 | ||||||
| const std::unordered_set<std::string> &Taskbar::ignore_list() const { return ignore_list_; } | const std::map<std::string, std::string>& Taskbar::app_ids_replace_map() const { return app_ids_replace_map_; } | ||||||
| 
 | 
 | ||||||
| } /* namespace waybar::modules::wlr */ | } /* namespace waybar::modules::wlr */ | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue