mirror of
https://github.com/rad4day/Waybar.git
synced 2023-12-21 10:22:59 +01:00
Merge branch 'master' of https://github.com/Alexays/Waybar into pr/anakael/fix-invisible-application
This commit is contained in:
commit
19069482e2
@ -69,6 +69,7 @@ libdbusmenu-gtk3 [Tray module]
|
|||||||
libmpdclient [MPD module]
|
libmpdclient [MPD module]
|
||||||
libsndio [sndio module]
|
libsndio [sndio module]
|
||||||
libevdev [KeyboardState module]
|
libevdev [KeyboardState module]
|
||||||
|
xkbregistry
|
||||||
```
|
```
|
||||||
|
|
||||||
**Build dependencies**
|
**Build dependencies**
|
||||||
@ -101,7 +102,8 @@ sudo apt install \
|
|||||||
libsigc++-2.0-dev \
|
libsigc++-2.0-dev \
|
||||||
libspdlog-dev \
|
libspdlog-dev \
|
||||||
libwayland-dev \
|
libwayland-dev \
|
||||||
scdoc
|
scdoc \
|
||||||
|
libxkbregistry-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,7 +73,8 @@ class Network : public ALabel {
|
|||||||
int cidr_;
|
int cidr_;
|
||||||
int32_t signal_strength_dbm_;
|
int32_t signal_strength_dbm_;
|
||||||
uint8_t signal_strength_;
|
uint8_t signal_strength_;
|
||||||
uint32_t frequency_;
|
std::string signal_strength_app_;
|
||||||
|
float frequency_;
|
||||||
uint32_t route_priority;
|
uint32_t route_priority;
|
||||||
|
|
||||||
util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
|
@ -3,11 +3,13 @@
|
|||||||
#include "AModule.hpp"
|
#include "AModule.hpp"
|
||||||
#include "bar.hpp"
|
#include "bar.hpp"
|
||||||
#include "client.hpp"
|
#include "client.hpp"
|
||||||
|
#include "giomm/desktopappinfo.h"
|
||||||
#include "util/json.hpp"
|
#include "util/json.hpp"
|
||||||
|
|
||||||
#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>
|
||||||
@ -61,15 +63,18 @@ class Task
|
|||||||
Gtk::Image icon_;
|
Gtk::Image icon_;
|
||||||
Gtk::Label text_before_;
|
Gtk::Label text_before_;
|
||||||
Gtk::Label text_after_;
|
Gtk::Label text_after_;
|
||||||
bool button_visible_ = false;
|
Glib::RefPtr<Gio::DesktopAppInfo> app_info_;
|
||||||
bool ignored_ = false;
|
bool button_visible_;
|
||||||
|
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_;
|
||||||
|
|
||||||
std::string format_tooltip_;
|
std::string format_tooltip_;
|
||||||
|
|
||||||
|
std::string name_;
|
||||||
std::string title_;
|
std::string title_;
|
||||||
std::string app_id_;
|
std::string app_id_;
|
||||||
uint32_t state_ = 0;
|
uint32_t state_ = 0;
|
||||||
@ -77,6 +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_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);
|
||||||
void hide_if_ignored();
|
void hide_if_ignored();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -136,6 +143,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_;
|
||||||
@ -158,8 +166,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/titles to be invisible.
|
List of app_id/titles to be invisible.
|
||||||
|
|
||||||
|
*app_ids-mapping*: ++
|
||||||
|
typeof: object ++
|
||||||
|
Dictionary 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"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -82,6 +82,12 @@ Also a minimal example configuration can be found on the at the bottom of this m
|
|||||||
default: *true* ++
|
default: *true* ++
|
||||||
Option to request an exclusive zone from the compositor. Disable this to allow drawing application windows underneath or on top of the bar.
|
Option to request an exclusive zone from the compositor. Disable this to allow drawing application windows underneath or on top of the bar.
|
||||||
|
|
||||||
|
*fixed-center* ++
|
||||||
|
typeof: bool ++
|
||||||
|
default: *true*
|
||||||
|
Prefer fixed center position for the `modules-center` block. The center block will stay in the middle of the bar whenever possible. It can still be pushed around if other blocks need more space.
|
||||||
|
When false, the center block is centered in the space between the left and right block.
|
||||||
|
|
||||||
*passthrough* ++
|
*passthrough* ++
|
||||||
typeof: bool ++
|
typeof: bool ++
|
||||||
default: *false* ++
|
default: *false* ++
|
||||||
|
@ -295,7 +295,7 @@ executable(
|
|||||||
gtk_layer_shell,
|
gtk_layer_shell,
|
||||||
libsndio,
|
libsndio,
|
||||||
tz_dep,
|
tz_dep,
|
||||||
xkbregistry
|
xkbregistry
|
||||||
],
|
],
|
||||||
include_directories: [include_directories('include')],
|
include_directories: [include_directories('include')],
|
||||||
install: true,
|
install: true,
|
||||||
|
@ -767,7 +767,11 @@ void waybar::Bar::getModules(const Factory& factory, const std::string& pos, Gtk
|
|||||||
auto waybar::Bar::setupWidgets() -> void {
|
auto waybar::Bar::setupWidgets() -> void {
|
||||||
window.add(box_);
|
window.add(box_);
|
||||||
box_.pack_start(left_, false, false);
|
box_.pack_start(left_, false, false);
|
||||||
box_.set_center_widget(center_);
|
if (config["fixed-center"].isBool() ? config["fixed-center"].asBool() : true) {
|
||||||
|
box_.set_center_widget(center_);
|
||||||
|
} else {
|
||||||
|
box_.pack_start(center_, true, false);
|
||||||
|
}
|
||||||
box_.pack_end(right_, false, false);
|
box_.pack_end(right_, false, false);
|
||||||
|
|
||||||
// Convert to button code for every module that is used.
|
// Convert to button code for every module that is used.
|
||||||
|
@ -88,7 +88,7 @@ waybar::modules::Network::Network(const std::string &id, const Json::Value &conf
|
|||||||
#ifdef WANT_RFKILL
|
#ifdef WANT_RFKILL
|
||||||
rfkill_{RFKILL_TYPE_WLAN},
|
rfkill_{RFKILL_TYPE_WLAN},
|
||||||
#endif
|
#endif
|
||||||
frequency_(0) {
|
frequency_(0.0) {
|
||||||
|
|
||||||
// Start with some "text" in the module's label_, update() will then
|
// Start with some "text" in the module's label_, update() will then
|
||||||
// update it. Since the text should be different, update() will be able
|
// update it. Since the text should be different, update() will be able
|
||||||
@ -331,12 +331,13 @@ auto waybar::modules::Network::update() -> void {
|
|||||||
fmt::arg("essid", essid_),
|
fmt::arg("essid", essid_),
|
||||||
fmt::arg("signaldBm", signal_strength_dbm_),
|
fmt::arg("signaldBm", signal_strength_dbm_),
|
||||||
fmt::arg("signalStrength", signal_strength_),
|
fmt::arg("signalStrength", signal_strength_),
|
||||||
|
fmt::arg("signalStrengthApp", signal_strength_app_),
|
||||||
fmt::arg("ifname", ifname_),
|
fmt::arg("ifname", ifname_),
|
||||||
fmt::arg("netmask", netmask_),
|
fmt::arg("netmask", netmask_),
|
||||||
fmt::arg("ipaddr", ipaddr_),
|
fmt::arg("ipaddr", ipaddr_),
|
||||||
fmt::arg("gwaddr", gwaddr_),
|
fmt::arg("gwaddr", gwaddr_),
|
||||||
fmt::arg("cidr", cidr_),
|
fmt::arg("cidr", cidr_),
|
||||||
fmt::arg("frequency", frequency_),
|
fmt::arg("frequency", fmt::format("{:.1f}", frequency_)),
|
||||||
fmt::arg("icon", getIcon(signal_strength_, state_)),
|
fmt::arg("icon", getIcon(signal_strength_, state_)),
|
||||||
fmt::arg("bandwidthDownBits", pow_format(bandwidth_down * 8ull / interval_.count(), "b/s")),
|
fmt::arg("bandwidthDownBits", pow_format(bandwidth_down * 8ull / interval_.count(), "b/s")),
|
||||||
fmt::arg("bandwidthUpBits", pow_format(bandwidth_up * 8ull / interval_.count(), "b/s")),
|
fmt::arg("bandwidthUpBits", pow_format(bandwidth_up * 8ull / interval_.count(), "b/s")),
|
||||||
@ -360,12 +361,13 @@ auto waybar::modules::Network::update() -> void {
|
|||||||
fmt::arg("essid", essid_),
|
fmt::arg("essid", essid_),
|
||||||
fmt::arg("signaldBm", signal_strength_dbm_),
|
fmt::arg("signaldBm", signal_strength_dbm_),
|
||||||
fmt::arg("signalStrength", signal_strength_),
|
fmt::arg("signalStrength", signal_strength_),
|
||||||
|
fmt::arg("signalStrengthApp", signal_strength_app_),
|
||||||
fmt::arg("ifname", ifname_),
|
fmt::arg("ifname", ifname_),
|
||||||
fmt::arg("netmask", netmask_),
|
fmt::arg("netmask", netmask_),
|
||||||
fmt::arg("ipaddr", ipaddr_),
|
fmt::arg("ipaddr", ipaddr_),
|
||||||
fmt::arg("gwaddr", gwaddr_),
|
fmt::arg("gwaddr", gwaddr_),
|
||||||
fmt::arg("cidr", cidr_),
|
fmt::arg("cidr", cidr_),
|
||||||
fmt::arg("frequency", frequency_),
|
fmt::arg("frequency", fmt::format("{:.1f}", frequency_)),
|
||||||
fmt::arg("icon", getIcon(signal_strength_, state_)),
|
fmt::arg("icon", getIcon(signal_strength_, state_)),
|
||||||
fmt::arg("bandwidthDownBits",
|
fmt::arg("bandwidthDownBits",
|
||||||
pow_format(bandwidth_down * 8ull / interval_.count(), "b/s")),
|
pow_format(bandwidth_down * 8ull / interval_.count(), "b/s")),
|
||||||
@ -403,7 +405,8 @@ void waybar::modules::Network::clearIface() {
|
|||||||
cidr_ = 0;
|
cidr_ = 0;
|
||||||
signal_strength_dbm_ = 0;
|
signal_strength_dbm_ = 0;
|
||||||
signal_strength_ = 0;
|
signal_strength_ = 0;
|
||||||
frequency_ = 0;
|
signal_strength_app_.clear();
|
||||||
|
frequency_ = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) {
|
int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) {
|
||||||
@ -470,7 +473,8 @@ int waybar::modules::Network::handleEvents(struct nl_msg *msg, void *data) {
|
|||||||
net->essid_.clear();
|
net->essid_.clear();
|
||||||
net->signal_strength_dbm_ = 0;
|
net->signal_strength_dbm_ = 0;
|
||||||
net->signal_strength_ = 0;
|
net->signal_strength_ = 0;
|
||||||
net->frequency_ = 0;
|
net->signal_strength_app_.clear();
|
||||||
|
net->frequency_ = 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
net->carrier_ = carrier.value();
|
net->carrier_ = carrier.value();
|
||||||
@ -788,13 +792,30 @@ void waybar::modules::Network::parseSignal(struct nlattr **bss) {
|
|||||||
if (bss[NL80211_BSS_SIGNAL_MBM] != nullptr) {
|
if (bss[NL80211_BSS_SIGNAL_MBM] != nullptr) {
|
||||||
// signalstrength in dBm from mBm
|
// signalstrength in dBm from mBm
|
||||||
signal_strength_dbm_ = nla_get_s32(bss[NL80211_BSS_SIGNAL_MBM]) / 100;
|
signal_strength_dbm_ = nla_get_s32(bss[NL80211_BSS_SIGNAL_MBM]) / 100;
|
||||||
|
|
||||||
// WiFi-hardware usually operates in the range -90 to -30dBm.
|
// WiFi-hardware usually operates in the range -90 to -30dBm.
|
||||||
const int hardwareMax = -30;
|
|
||||||
|
// If a signal is too strong, it can overwhelm receiving circuity that is designed
|
||||||
|
// to pick up and process a certain signal level. The following percentage is scaled to
|
||||||
|
// punish signals that are too strong (>= -45dBm) or too weak (<= -45 dBm).
|
||||||
|
const int hardwareOptimum = -45;
|
||||||
const int hardwareMin = -90;
|
const int hardwareMin = -90;
|
||||||
const int strength =
|
const int strength =
|
||||||
((signal_strength_dbm_ - hardwareMin) / double{hardwareMax - hardwareMin}) * 100;
|
100 - ((abs(signal_strength_dbm_ - hardwareOptimum) / double{hardwareOptimum - hardwareMin}) * 100);
|
||||||
signal_strength_ = std::clamp(strength, 0, 100);
|
signal_strength_ = std::clamp(strength, 0, 100);
|
||||||
|
|
||||||
|
if (signal_strength_dbm_ >= -50) {
|
||||||
|
signal_strength_app_ = "Great Connectivity";
|
||||||
|
} else if (signal_strength_dbm_ >= -60) {
|
||||||
|
signal_strength_app_ = "Good Connectivity";
|
||||||
|
} else if (signal_strength_dbm_ >= -67) {
|
||||||
|
signal_strength_app_ = "Streaming";
|
||||||
|
} else if (signal_strength_dbm_ >= -70) {
|
||||||
|
signal_strength_app_ = "Web Surfing";
|
||||||
|
} else if (signal_strength_dbm_ >= -80) {
|
||||||
|
signal_strength_app_ = "Basic Connectivity";
|
||||||
|
} else {
|
||||||
|
signal_strength_app_ = "Poor Connectivity";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (bss[NL80211_BSS_SIGNAL_UNSPEC] != nullptr) {
|
if (bss[NL80211_BSS_SIGNAL_UNSPEC] != nullptr) {
|
||||||
signal_strength_ = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]);
|
signal_strength_ = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]);
|
||||||
@ -803,8 +824,8 @@ void waybar::modules::Network::parseSignal(struct nlattr **bss) {
|
|||||||
|
|
||||||
void waybar::modules::Network::parseFreq(struct nlattr **bss) {
|
void waybar::modules::Network::parseFreq(struct nlattr **bss) {
|
||||||
if (bss[NL80211_BSS_FREQUENCY] != nullptr) {
|
if (bss[NL80211_BSS_FREQUENCY] != nullptr) {
|
||||||
// in MHz
|
// in GHz
|
||||||
frequency_ = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
|
frequency_ = (double) nla_get_u32(bss[NL80211_BSS_FREQUENCY]) / 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,8 +88,7 @@ static Glib::RefPtr<Gdk::Pixbuf> load_icon_from_file(std::string icon_path, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Method 1 - get the correct icon name from the desktop file */
|
static Glib::RefPtr<Gio::DesktopAppInfo> get_app_info_by_name(const std::string& app_id)
|
||||||
static std::string get_from_desktop_app_info(const std::string &app_id)
|
|
||||||
{
|
{
|
||||||
static std::vector<std::string> prefixes = search_prefix();
|
static std::vector<std::string> prefixes = search_prefix();
|
||||||
|
|
||||||
@ -103,33 +104,29 @@ static std::string get_from_desktop_app_info(const std::string &app_id)
|
|||||||
".desktop"
|
".desktop"
|
||||||
};
|
};
|
||||||
|
|
||||||
Glib::RefPtr<Gio::DesktopAppInfo> app_info;
|
for (auto& prefix : prefixes) {
|
||||||
|
for (auto& folder : app_folders) {
|
||||||
|
for (auto& suffix : suffixes) {
|
||||||
|
auto app_info_ = Gio::DesktopAppInfo::create_from_filename(prefix + folder + app_id + suffix);
|
||||||
|
if (!app_info_) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& prefix : prefixes)
|
return app_info_;
|
||||||
for (auto& folder : app_folders)
|
}
|
||||||
for (auto& suffix : suffixes)
|
}
|
||||||
if (!app_info)
|
}
|
||||||
app_info = Gio::DesktopAppInfo::create_from_filename(prefix + folder + app_id + suffix);
|
|
||||||
|
|
||||||
if (app_info && app_info->get_icon())
|
return {};
|
||||||
return app_info->get_icon()->to_string();
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Method 2 - use the app_id and check whether there is an icon with this name in the icon theme */
|
Glib::RefPtr<Gio::DesktopAppInfo> get_desktop_app_info(const std::string &app_id)
|
||||||
static std::string get_from_icon_theme(const Glib::RefPtr<Gtk::IconTheme>& icon_theme,
|
|
||||||
const std::string &app_id)
|
|
||||||
{
|
{
|
||||||
if (icon_theme->lookup_icon(app_id, 24))
|
auto app_info = get_app_info_by_name(app_id);
|
||||||
return app_id;
|
if (app_info) {
|
||||||
|
return app_info;
|
||||||
|
}
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Method 3 - as last resort perform a search for most appropriate desktop info file */
|
|
||||||
static std::string get_from_desktop_app_info_search(const std::string &app_id)
|
|
||||||
{
|
|
||||||
std::string desktop_file = "";
|
std::string desktop_file = "";
|
||||||
|
|
||||||
gchar*** desktop_list = g_desktop_app_info_search(app_id.c_str());
|
gchar*** desktop_list = g_desktop_app_info_search(app_id.c_str());
|
||||||
@ -151,65 +148,84 @@ static std::string get_from_desktop_app_info_search(const std::string &app_id)
|
|||||||
}
|
}
|
||||||
g_free(desktop_list);
|
g_free(desktop_list);
|
||||||
|
|
||||||
return get_from_desktop_app_info(desktop_file);
|
return get_app_info_by_name(desktop_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool image_load_icon(Gtk::Image& image, const Glib::RefPtr<Gtk::IconTheme>& icon_theme,
|
void Task::set_app_info_from_app_id_list(const std::string& app_id_list) {
|
||||||
const std::string &app_id_list, int size)
|
|
||||||
{
|
|
||||||
std::string app_id;
|
std::string app_id;
|
||||||
std::istringstream stream(app_id_list);
|
std::istringstream stream(app_id_list);
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
/* Wayfire sends a list of app-id's in space separated format, other compositors
|
/* 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 */
|
* send a single app-id, but in any case this works fine */
|
||||||
while (stream >> app_id)
|
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();
|
size_t start = 0, end = app_id.size();
|
||||||
start = app_id.rfind(".", end);
|
start = app_id.rfind(".", end);
|
||||||
std::string app_name = app_id.substr(start+1, app_id.size());
|
std::string app_name = app_id.substr(start+1, app_id.size());
|
||||||
|
app_info_ = get_desktop_app_info(app_name);
|
||||||
|
if (app_info_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto lower_app_id = app_id;
|
start = app_id.find("-");
|
||||||
std::transform(lower_app_id.begin(), lower_app_id.end(), lower_app_id.begin(),
|
app_name = app_id.substr(0, start);
|
||||||
[](char c){ return std::tolower(c); });
|
app_info_ = get_desktop_app_info(app_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string icon_name = get_from_icon_theme(icon_theme, app_id);
|
static std::string get_icon_name_from_icon_theme(const Glib::RefPtr<Gtk::IconTheme>& icon_theme,
|
||||||
|
const std::string &app_id)
|
||||||
|
{
|
||||||
|
if (icon_theme->lookup_icon(app_id, 24))
|
||||||
|
return app_id;
|
||||||
|
|
||||||
if (icon_name.empty())
|
return "";
|
||||||
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())
|
bool Task::image_load_icon(Gtk::Image& image, const Glib::RefPtr<Gtk::IconTheme>& icon_theme, Glib::RefPtr<Gio::DesktopAppInfo> app_info, int size)
|
||||||
icon_name = "unknown";
|
{
|
||||||
|
std::string ret_icon_name = "unknown";
|
||||||
|
if (app_info) {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Glib::RefPtr<Gdk::Pixbuf> pixbuf;
|
Glib::RefPtr<Gdk::Pixbuf> pixbuf;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
pixbuf = icon_theme->load_icon(icon_name, size, Gtk::ICON_LOOKUP_FORCE_SIZE);
|
pixbuf = icon_theme->load_icon(ret_icon_name, size, Gtk::ICON_LOOKUP_FORCE_SIZE);
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
if (Glib::file_test(icon_name, Glib::FILE_TEST_EXISTS))
|
if (Glib::file_test(ret_icon_name, Glib::FILE_TEST_EXISTS))
|
||||||
pixbuf = load_icon_from_file(icon_name, size);
|
pixbuf = load_icon_from_file(ret_icon_name, size);
|
||||||
else
|
else
|
||||||
pixbuf = {};
|
pixbuf = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pixbuf) {
|
if (pixbuf) {
|
||||||
image.set(pixbuf);
|
image.set(pixbuf);
|
||||||
found = true;
|
return true;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return found;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Task class implementation */
|
/* Task class implementation */
|
||||||
@ -289,13 +305,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) {
|
||||||
@ -402,13 +420,28 @@ void Task::handle_app_id(const char *app_id)
|
|||||||
app_id_ = app_id;
|
app_id_ = app_id;
|
||||||
hide_if_ignored();
|
hide_if_ignored();
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
@ -564,14 +597,17 @@ void Task::update()
|
|||||||
{
|
{
|
||||||
bool markup = config_["markup"].isBool() ? config_["markup"].asBool() : false;
|
bool markup = config_["markup"].isBool() ? config_["markup"].asBool() : false;
|
||||||
std::string title = title_;
|
std::string title = title_;
|
||||||
|
std::string name = name_;
|
||||||
std::string app_id = app_id_;
|
std::string app_id = app_id_;
|
||||||
if (markup) {
|
if (markup) {
|
||||||
title = Glib::Markup::escape_text(title);
|
title = Glib::Markup::escape_text(title);
|
||||||
|
name = Glib::Markup::escape_text(name);
|
||||||
app_id = Glib::Markup::escape_text(app_id);
|
app_id = Glib::Markup::escape_text(app_id);
|
||||||
}
|
}
|
||||||
if (!format_before_.empty()) {
|
if (!format_before_.empty()) {
|
||||||
auto txt = fmt::format(format_before_,
|
auto txt = fmt::format(format_before_,
|
||||||
fmt::arg("title", title),
|
fmt::arg("title", title),
|
||||||
|
fmt::arg("name", name),
|
||||||
fmt::arg("app_id", app_id),
|
fmt::arg("app_id", app_id),
|
||||||
fmt::arg("state", state_string()),
|
fmt::arg("state", state_string()),
|
||||||
fmt::arg("short_state", state_string(true))
|
fmt::arg("short_state", state_string(true))
|
||||||
@ -585,6 +621,7 @@ void Task::update()
|
|||||||
if (!format_after_.empty()) {
|
if (!format_after_.empty()) {
|
||||||
auto txt = fmt::format(format_after_,
|
auto txt = fmt::format(format_after_,
|
||||||
fmt::arg("title", title),
|
fmt::arg("title", title),
|
||||||
|
fmt::arg("name", name),
|
||||||
fmt::arg("app_id", app_id),
|
fmt::arg("app_id", app_id),
|
||||||
fmt::arg("state", state_string()),
|
fmt::arg("state", state_string()),
|
||||||
fmt::arg("short_state", state_string(true))
|
fmt::arg("short_state", state_string(true))
|
||||||
@ -599,6 +636,7 @@ void Task::update()
|
|||||||
if (!format_tooltip_.empty()) {
|
if (!format_tooltip_.empty()) {
|
||||||
auto txt = fmt::format(format_tooltip_,
|
auto txt = fmt::format(format_tooltip_,
|
||||||
fmt::arg("title", title),
|
fmt::arg("title", title),
|
||||||
|
fmt::arg("name", name),
|
||||||
fmt::arg("app_id", app_id),
|
fmt::arg("app_id", app_id),
|
||||||
fmt::arg("state", state_string()),
|
fmt::arg("state", state_string()),
|
||||||
fmt::arg("short_state", state_string(true))
|
fmt::arg("short_state", state_string(true))
|
||||||
@ -726,6 +764,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());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -857,10 +904,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
Block a user