Merge branch 'master' into master
commit
b12b500bfc
|
@ -20,7 +20,7 @@ class Workspaces : public AModule, public sigc::trackable {
|
||||||
auto update() -> void;
|
auto update() -> void;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static inline const std::string workspace_switch_cmd_ = "workspace --no-auto-back-and-forth \"{}\"";
|
static inline const std::string workspace_switch_cmd_ = "workspace {} \"{}\"";
|
||||||
|
|
||||||
static int convertWorkspaceNameToNum(std::string name);
|
static int convertWorkspaceNameToNum(std::string name);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
#include <glibmm/ustring.h>
|
||||||
|
|
||||||
|
// calculate column width of ustring
|
||||||
|
int ustring_clen(const Glib::ustring &str);
|
|
@ -24,6 +24,14 @@ The *backlight* module displays the current backlight level.
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
The maximum length in characters the module should display.
|
The maximum length in characters the module should display.
|
||||||
|
|
||||||
|
*min-length*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
The minimum length in characters the module should take up.
|
||||||
|
|
||||||
|
*align*: ++
|
||||||
|
typeof: float ++
|
||||||
|
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||||
|
|
||||||
*rotate*: ++
|
*rotate*: ++
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
Positive value to rotate the text label.
|
Positive value to rotate the text label.
|
||||||
|
|
|
@ -55,6 +55,14 @@ The *battery* module displays the current capacity and state (eg. charging) of y
|
||||||
typeof: integer++
|
typeof: integer++
|
||||||
The maximum length in character the module should display.
|
The maximum length in character the module should display.
|
||||||
|
|
||||||
|
*min-length*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
The minimum length in characters the module should take up.
|
||||||
|
|
||||||
|
*align*: ++
|
||||||
|
typeof: float ++
|
||||||
|
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||||
|
|
||||||
*rotate*: ++
|
*rotate*: ++
|
||||||
typeof: integer++
|
typeof: integer++
|
||||||
Positive value to rotate the text label.
|
Positive value to rotate the text label.
|
||||||
|
|
|
@ -35,6 +35,14 @@ Addressed by *bluetooth*
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
The maximum length in character the module should display.
|
The maximum length in character the module should display.
|
||||||
|
|
||||||
|
*min-length*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
The minimum length in characters the module should take up.
|
||||||
|
|
||||||
|
*align*: ++
|
||||||
|
typeof: float ++
|
||||||
|
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||||
|
|
||||||
*on-click*: ++
|
*on-click*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when clicked on the module.
|
Command to execute when clicked on the module.
|
||||||
|
|
|
@ -45,6 +45,14 @@ The *clock* module displays the current date and time.
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
The maximum length in character the module should display.
|
The maximum length in character the module should display.
|
||||||
|
|
||||||
|
*min-length*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
The minimum length in characters the module should take up.
|
||||||
|
|
||||||
|
*align*: ++
|
||||||
|
typeof: float ++
|
||||||
|
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||||
|
|
||||||
*rotate*: ++
|
*rotate*: ++
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
Positive value to rotate the text label.
|
Positive value to rotate the text label.
|
||||||
|
|
|
@ -24,6 +24,14 @@ The *cpu* module displays the current cpu utilization.
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
The maximum length in character the module should display.
|
The maximum length in character the module should display.
|
||||||
|
|
||||||
|
*min-length*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
The minimum length in characters the module should take up.
|
||||||
|
|
||||||
|
*align*: ++
|
||||||
|
typeof: float ++
|
||||||
|
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||||
|
|
||||||
*rotate*: ++
|
*rotate*: ++
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
Positive value to rotate the text label.
|
Positive value to rotate the text label.
|
||||||
|
|
|
@ -67,6 +67,14 @@ Addressed by *custom/<name>*
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
The maximum length in character the module should display.
|
The maximum length in character the module should display.
|
||||||
|
|
||||||
|
*min-length*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
The minimum length in characters the module should take up.
|
||||||
|
|
||||||
|
*align*: ++
|
||||||
|
typeof: float ++
|
||||||
|
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||||
|
|
||||||
*on-click*: ++
|
*on-click*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when clicked on the module.
|
Command to execute when clicked on the module.
|
||||||
|
|
|
@ -39,6 +39,14 @@ Addressed by *disk*
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
The maximum length in character the module should display.
|
The maximum length in character the module should display.
|
||||||
|
|
||||||
|
*min-length*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
The minimum length in characters the module should take up.
|
||||||
|
|
||||||
|
*align*: ++
|
||||||
|
typeof: float ++
|
||||||
|
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||||
|
|
||||||
*on-click*: ++
|
*on-click*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when clicked on the module.
|
Command to execute when clicked on the module.
|
||||||
|
|
|
@ -27,6 +27,14 @@ screensaving, also known as "presentation mode".
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
The maximum length in character the module should display.
|
The maximum length in character the module should display.
|
||||||
|
|
||||||
|
*min-length*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
The minimum length in characters the module should take up.
|
||||||
|
|
||||||
|
*align*: ++
|
||||||
|
typeof: float ++
|
||||||
|
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||||
|
|
||||||
*on-click*: ++
|
*on-click*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when clicked on the module. A click also toggles the state
|
Command to execute when clicked on the module. A click also toggles the state
|
||||||
|
|
|
@ -34,6 +34,14 @@ Addressed by *memory*
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
The maximum length in character the module should display.
|
The maximum length in character the module should display.
|
||||||
|
|
||||||
|
*min-length*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
The minimum length in characters the module should take up.
|
||||||
|
|
||||||
|
*align*: ++
|
||||||
|
typeof: float ++
|
||||||
|
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||||
|
|
||||||
*on-click*: ++
|
*on-click*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when clicked on the module.
|
Command to execute when clicked on the module.
|
||||||
|
|
|
@ -97,6 +97,14 @@ Addressed by *mpd*
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
The maximum length in character the module should display.
|
The maximum length in character the module should display.
|
||||||
|
|
||||||
|
*min-length*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
The minimum length in characters the module should take up.
|
||||||
|
|
||||||
|
*align*: ++
|
||||||
|
typeof: float ++
|
||||||
|
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||||
|
|
||||||
*on-click*: ++
|
*on-click*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when clicked on the module.
|
Command to execute when clicked on the module.
|
||||||
|
|
|
@ -64,6 +64,14 @@ Addressed by *network*
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
The maximum length in character the module should display.
|
The maximum length in character the module should display.
|
||||||
|
|
||||||
|
*min-length*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
The minimum length in characters the module should take up.
|
||||||
|
|
||||||
|
*align*: ++
|
||||||
|
typeof: float ++
|
||||||
|
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||||
|
|
||||||
*on-click*: ++
|
*on-click*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when clicked on the module.
|
Command to execute when clicked on the module.
|
||||||
|
|
|
@ -50,6 +50,14 @@ Additionally you can control the volume by scrolling *up* or *down* while the cu
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
The maximum length in character the module should display.
|
The maximum length in character the module should display.
|
||||||
|
|
||||||
|
*min-length*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
The minimum length in characters the module should take up.
|
||||||
|
|
||||||
|
*align*: ++
|
||||||
|
typeof: float ++
|
||||||
|
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||||
|
|
||||||
*scroll-step*: ++
|
*scroll-step*: ++
|
||||||
typeof: float ++
|
typeof: float ++
|
||||||
default: 1.0 ++
|
default: 1.0 ++
|
||||||
|
|
|
@ -26,6 +26,14 @@ cursor is over the module, and clicking on the module toggles mute.
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
The maximum length in character the module should display.
|
The maximum length in character the module should display.
|
||||||
|
|
||||||
|
*min-length*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
The minimum length in characters the module should take up.
|
||||||
|
|
||||||
|
*align*: ++
|
||||||
|
typeof: float ++
|
||||||
|
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||||
|
|
||||||
*scroll-step*: ++
|
*scroll-step*: ++
|
||||||
typeof: int ++
|
typeof: int ++
|
||||||
default: 5 ++
|
default: 5 ++
|
||||||
|
|
|
@ -25,6 +25,14 @@ Addressed by *sway/language*
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
The maximum length in character the module should display.
|
The maximum length in character the module should display.
|
||||||
|
|
||||||
|
*min-length*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
The minimum length in characters the module should take up.
|
||||||
|
|
||||||
|
*align*: ++
|
||||||
|
typeof: float ++
|
||||||
|
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||||
|
|
||||||
*on-click*: ++
|
*on-click*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when clicked on the module.
|
Command to execute when clicked on the module.
|
||||||
|
|
|
@ -25,6 +25,14 @@ Addressed by *sway/mode*
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
The maximum length in character the module should display.
|
The maximum length in character the module should display.
|
||||||
|
|
||||||
|
*min-length*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
The minimum length in characters the module should take up.
|
||||||
|
|
||||||
|
*align*: ++
|
||||||
|
typeof: float ++
|
||||||
|
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||||
|
|
||||||
*on-click*: ++
|
*on-click*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when clicked on the module.
|
Command to execute when clicked on the module.
|
||||||
|
|
|
@ -25,6 +25,14 @@ Addressed by *sway/window*
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
The maximum length in character the module should display.
|
The maximum length in character the module should display.
|
||||||
|
|
||||||
|
*min-length*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
The minimum length in characters the module should take up.
|
||||||
|
|
||||||
|
*align*: ++
|
||||||
|
typeof: float ++
|
||||||
|
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||||
|
|
||||||
*on-click*: ++
|
*on-click*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when clicked on the module.
|
Command to execute when clicked on the module.
|
||||||
|
|
|
@ -73,6 +73,10 @@ Addressed by *sway/workspaces*
|
||||||
typeof: bool ++
|
typeof: bool ++
|
||||||
Whether to put workspaces starting with numbers before workspaces that do not start with a number.
|
Whether to put workspaces starting with numbers before workspaces that do not start with a number.
|
||||||
|
|
||||||
|
*disable-auto-back-and-forth*: ++
|
||||||
|
typeof: bool ++
|
||||||
|
Whether to disable *workspace_auto_back_and_forth* when clicking on workspaces. If this is set to *true*, clicking on a workspace you are already on won't do anything, even if *workspace_auto_back_and_forth* is enabled in the Sway configuration.
|
||||||
|
|
||||||
# FORMAT REPLACEMENTS
|
# FORMAT REPLACEMENTS
|
||||||
|
|
||||||
*{value}*: Name of the workspace, as defined by sway.
|
*{value}*: Name of the workspace, as defined by sway.
|
||||||
|
|
|
@ -63,6 +63,14 @@ Addressed by *temperature*
|
||||||
typeof: integer ++
|
typeof: integer ++
|
||||||
The maximum length in characters the module should display.
|
The maximum length in characters the module should display.
|
||||||
|
|
||||||
|
*min-length*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
The minimum length in characters the module should take up.
|
||||||
|
|
||||||
|
*align*: ++
|
||||||
|
typeof: float ++
|
||||||
|
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||||
|
|
||||||
*on-click*: ++
|
*on-click*: ++
|
||||||
typeof: string ++
|
typeof: string ++
|
||||||
Command to execute when you clicked on the module.
|
Command to execute when you clicked on the module.
|
||||||
|
|
|
@ -147,6 +147,7 @@ src_files = files(
|
||||||
'src/main.cpp',
|
'src/main.cpp',
|
||||||
'src/bar.cpp',
|
'src/bar.cpp',
|
||||||
'src/client.cpp',
|
'src/client.cpp',
|
||||||
|
'src/util/ustring_clen.cpp'
|
||||||
)
|
)
|
||||||
|
|
||||||
if is_linux
|
if is_linux
|
||||||
|
|
|
@ -20,7 +20,7 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st
|
||||||
}
|
}
|
||||||
event_box_.add(label_);
|
event_box_.add(label_);
|
||||||
if (config_["max-length"].isUInt()) {
|
if (config_["max-length"].isUInt()) {
|
||||||
label_.set_max_width_chars(config_["max-length"].asUInt());
|
label_.set_max_width_chars(config_["max-length"].asInt());
|
||||||
label_.set_ellipsize(Pango::EllipsizeMode::ELLIPSIZE_END);
|
label_.set_ellipsize(Pango::EllipsizeMode::ELLIPSIZE_END);
|
||||||
label_.set_single_line_mode(true);
|
label_.set_single_line_mode(true);
|
||||||
} else if (ellipsize && label_.get_max_width_chars() == -1) {
|
} else if (ellipsize && label_.get_max_width_chars() == -1) {
|
||||||
|
@ -28,9 +28,28 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st
|
||||||
label_.set_single_line_mode(true);
|
label_.set_single_line_mode(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config_["rotate"].isUInt()) {
|
if (config_["min-length"].isUInt()) {
|
||||||
label_.set_angle(config["rotate"].asUInt());
|
label_.set_width_chars(config_["min-length"].asUInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint rotate = 0;
|
||||||
|
|
||||||
|
if (config_["rotate"].isUInt()) {
|
||||||
|
rotate = config["rotate"].asUInt();
|
||||||
|
label_.set_angle(rotate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config_["align"].isDouble()) {
|
||||||
|
auto align = config_["align"].asFloat();
|
||||||
|
if (rotate == 90 || rotate == 270) {
|
||||||
|
label_.set_yalign(align);
|
||||||
|
} else {
|
||||||
|
label_.set_xalign(align);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ALabel::update() -> void {
|
auto ALabel::update() -> void {
|
||||||
|
|
|
@ -120,17 +120,26 @@ void waybar::Client::handleOutputDone(void *data, struct zxdg_output_v1 * /*xdg_
|
||||||
auto client = waybar::Client::inst();
|
auto client = waybar::Client::inst();
|
||||||
try {
|
try {
|
||||||
auto &output = client->getOutput(data);
|
auto &output = client->getOutput(data);
|
||||||
|
/**
|
||||||
|
* Multiple .done events may arrive in batch. In this case libwayland would queue
|
||||||
|
* xdg_output.destroy and dispatch all pending events, triggering this callback several times
|
||||||
|
* for the same output. .done events can also arrive after that for a scale or position changes.
|
||||||
|
* We wouldn't want to draw a duplicate bar for each such event either.
|
||||||
|
*
|
||||||
|
* All the properties we care about are immutable so it's safe to delete the xdg_output object
|
||||||
|
* on the first event and use the ptr value to check that the callback was already invoked.
|
||||||
|
*/
|
||||||
|
if (output.xdg_output) {
|
||||||
|
output.xdg_output.reset();
|
||||||
spdlog::debug("Output detection done: {} ({})", output.name, output.identifier);
|
spdlog::debug("Output detection done: {} ({})", output.name, output.identifier);
|
||||||
|
|
||||||
auto configs = client->getOutputConfigs(output);
|
auto configs = client->getOutputConfigs(output);
|
||||||
if (!configs.empty()) {
|
if (!configs.empty()) {
|
||||||
wl_display_roundtrip(client->wl_display);
|
|
||||||
for (const auto &config : configs) {
|
for (const auto &config : configs) {
|
||||||
client->bars.emplace_back(std::make_unique<Bar>(&output, config));
|
client->bars.emplace_back(std::make_unique<Bar>(&output, config));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// unsubscribe
|
}
|
||||||
output.xdg_output.reset();
|
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include "util/ustring_clen.hpp"
|
||||||
#ifdef HAVE_LANGINFO_1STDAY
|
#ifdef HAVE_LANGINFO_1STDAY
|
||||||
#include <langinfo.h>
|
#include <langinfo.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
@ -154,12 +155,14 @@ auto waybar::modules::Clock::weekdays_header(const date::weekday& first_dow, std
|
||||||
do {
|
do {
|
||||||
if (wd != first_dow) os << ' ';
|
if (wd != first_dow) os << ' ';
|
||||||
Glib::ustring wd_ustring(date::format(locale_, "%a", wd));
|
Glib::ustring wd_ustring(date::format(locale_, "%a", wd));
|
||||||
|
auto clen = ustring_clen(wd_ustring);
|
||||||
auto wd_len = wd_ustring.length();
|
auto wd_len = wd_ustring.length();
|
||||||
if (wd_len > 2) {
|
while (clen > 2) {
|
||||||
wd_ustring = wd_ustring.substr(0, 2);
|
wd_ustring = wd_ustring.substr(0, wd_len-1);
|
||||||
wd_len = 2;
|
wd_len--;
|
||||||
|
clen = ustring_clen(wd_ustring);
|
||||||
}
|
}
|
||||||
const std::string pad(2 - wd_len, ' ');
|
const std::string pad(2 - clen, ' ');
|
||||||
os << pad << wd_ustring;
|
os << pad << wd_ustring;
|
||||||
} while (++wd != first_dow);
|
} while (++wd != first_dow);
|
||||||
os << "\n";
|
os << "\n";
|
||||||
|
|
|
@ -12,6 +12,10 @@ waybar::modules::IdleInhibitor::IdleInhibitor(const std::string& id, const Bar&
|
||||||
bar_(bar),
|
bar_(bar),
|
||||||
idle_inhibitor_(nullptr),
|
idle_inhibitor_(nullptr),
|
||||||
pid_(-1) {
|
pid_(-1) {
|
||||||
|
if (waybar::Client::inst()->idle_inhibit_manager == nullptr) {
|
||||||
|
throw std::runtime_error("idle-inhibit not available");
|
||||||
|
}
|
||||||
|
|
||||||
event_box_.add_events(Gdk::BUTTON_PRESS_MASK);
|
event_box_.add_events(Gdk::BUTTON_PRESS_MASK);
|
||||||
event_box_.signal_button_press_event().connect(
|
event_box_.signal_button_press_event().connect(
|
||||||
sigc::mem_fun(*this, &IdleInhibitor::handleToggle));
|
sigc::mem_fun(*this, &IdleInhibitor::handleToggle));
|
||||||
|
|
|
@ -56,7 +56,8 @@ auto Window::update() -> void {
|
||||||
bar_.window.get_style_context()->remove_class("solo");
|
bar_.window.get_style_context()->remove_class("solo");
|
||||||
bar_.window.get_style_context()->remove_class("empty");
|
bar_.window.get_style_context()->remove_class("empty");
|
||||||
}
|
}
|
||||||
label_.set_markup(fmt::format(format_, window_));
|
label_.set_markup(fmt::format(format_, fmt::arg("title", window_),
|
||||||
|
fmt::arg("app_id", app_id_)));
|
||||||
if (tooltipEnabled()) {
|
if (tooltipEnabled()) {
|
||||||
label_.set_tooltip_text(window_);
|
label_.set_tooltip_text(window_);
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,11 +257,19 @@ Gtk::Button &Workspaces::addButton(const Json::Value &node) {
|
||||||
ipc_.sendCmd(
|
ipc_.sendCmd(
|
||||||
IPC_COMMAND,
|
IPC_COMMAND,
|
||||||
fmt::format(workspace_switch_cmd_ + "; move workspace to output \"{}\"; " + workspace_switch_cmd_,
|
fmt::format(workspace_switch_cmd_ + "; move workspace to output \"{}\"; " + workspace_switch_cmd_,
|
||||||
|
"--no-auto-back-and-forth",
|
||||||
node["name"].asString(),
|
node["name"].asString(),
|
||||||
node["target_output"].asString(),
|
node["target_output"].asString(),
|
||||||
|
"--no-auto-back-and-forth",
|
||||||
node["name"].asString()));
|
node["name"].asString()));
|
||||||
} else {
|
} else {
|
||||||
ipc_.sendCmd(IPC_COMMAND, fmt::format(workspace_switch_cmd_, node["name"].asString()));
|
ipc_.sendCmd(
|
||||||
|
IPC_COMMAND,
|
||||||
|
fmt::format("workspace {} \"{}\"",
|
||||||
|
config_["disable-auto-back-and-forth"].asBool()
|
||||||
|
? "--no-auto-back-and-forth"
|
||||||
|
: "",
|
||||||
|
node["name"].asString()));
|
||||||
}
|
}
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
spdlog::error("Workspaces: {}", e.what());
|
spdlog::error("Workspaces: {}", e.what());
|
||||||
|
@ -322,7 +330,9 @@ bool Workspaces::handleScroll(GdkEventScroll *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
ipc_.sendCmd(IPC_COMMAND, fmt::format(workspace_switch_cmd_, name));
|
ipc_.sendCmd(
|
||||||
|
IPC_COMMAND,
|
||||||
|
fmt::format(workspace_switch_cmd_, "--no-auto-back-and-forth", name));
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
spdlog::error("Workspaces: {}", e.what());
|
spdlog::error("Workspaces: {}", e.what());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "modules/wlr/taskbar.hpp"
|
#include "modules/wlr/taskbar.hpp"
|
||||||
|
|
||||||
|
#include "glibmm/error.h"
|
||||||
|
#include "glibmm/fileutils.h"
|
||||||
#include "glibmm/refptr.h"
|
#include "glibmm/refptr.h"
|
||||||
#include "util/format.hpp"
|
#include "util/format.hpp"
|
||||||
|
|
||||||
|
@ -15,6 +17,7 @@
|
||||||
#include <gtkmm/icontheme.h>
|
#include <gtkmm/icontheme.h>
|
||||||
|
|
||||||
#include <giomm/desktopappinfo.h>
|
#include <giomm/desktopappinfo.h>
|
||||||
|
#include <gio/gdesktopappinfo.h>
|
||||||
|
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
|
@ -64,12 +67,25 @@ static std::vector<std::string> search_prefix()
|
||||||
} while(end != std::string::npos);
|
} while(end != std::string::npos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string home_dir = std::getenv("HOME");
|
||||||
|
prefixes.push_back(home_dir + "/.local/share/");
|
||||||
|
|
||||||
for (auto& p : prefixes)
|
for (auto& p : prefixes)
|
||||||
spdlog::debug("Using 'desktop' search path prefix: {}", p);
|
spdlog::debug("Using 'desktop' search path prefix: {}", p);
|
||||||
|
|
||||||
return prefixes;
|
return prefixes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Glib::RefPtr<Gdk::Pixbuf> load_icon_from_file(std::string icon_path, int size)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
auto pb = Gdk::Pixbuf::create_from_file(icon_path, size, size);
|
||||||
|
return pb;
|
||||||
|
} catch(...) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Method 1 - get the correct icon name from the desktop file */
|
/* Method 1 - get the correct icon name from the desktop file */
|
||||||
static std::string get_from_desktop_app_info(const std::string &app_id)
|
static std::string get_from_desktop_app_info(const std::string &app_id)
|
||||||
{
|
{
|
||||||
|
@ -111,6 +127,33 @@ static std::string get_from_icon_theme(const Glib::RefPtr<Gtk::IconTheme>& icon_
|
||||||
return "";
|
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 = "";
|
||||||
|
|
||||||
|
gchar*** desktop_list = g_desktop_app_info_search(app_id.c_str());
|
||||||
|
if (desktop_list != nullptr && desktop_list[0] != nullptr) {
|
||||||
|
for (size_t i=0; desktop_list[0][i]; i++) {
|
||||||
|
if (desktop_file == "") {
|
||||||
|
desktop_file = desktop_list[0][i];
|
||||||
|
} else {
|
||||||
|
auto tmp_info = Gio::DesktopAppInfo::create(desktop_list[0][i]);
|
||||||
|
auto startup_class = tmp_info->get_startup_wm_class();
|
||||||
|
|
||||||
|
if (startup_class == app_id) {
|
||||||
|
desktop_file = desktop_list[0][i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_strfreev(desktop_list[0]);
|
||||||
|
}
|
||||||
|
g_free(desktop_list);
|
||||||
|
|
||||||
|
return get_from_desktop_app_info(desktop_file);
|
||||||
|
}
|
||||||
|
|
||||||
static bool image_load_icon(Gtk::Image& image, const Glib::RefPtr<Gtk::IconTheme>& icon_theme,
|
static bool image_load_icon(Gtk::Image& image, const Glib::RefPtr<Gtk::IconTheme>& icon_theme,
|
||||||
const std::string &app_id_list, int size)
|
const std::string &app_id_list, int size)
|
||||||
{
|
{
|
||||||
|
@ -142,11 +185,23 @@ static bool image_load_icon(Gtk::Image& image, const Glib::RefPtr<Gtk::IconTheme
|
||||||
icon_name = get_from_desktop_app_info(lower_app_id);
|
icon_name = get_from_desktop_app_info(lower_app_id);
|
||||||
if (icon_name.empty())
|
if (icon_name.empty())
|
||||||
icon_name = get_from_desktop_app_info(app_name);
|
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())
|
if (icon_name.empty())
|
||||||
continue;
|
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 = {};
|
||||||
|
}
|
||||||
|
|
||||||
auto pixbuf = icon_theme->load_icon(icon_name, size, Gtk::ICON_LOOKUP_FORCE_SIZE);
|
|
||||||
if (pixbuf) {
|
if (pixbuf) {
|
||||||
image.set(pixbuf);
|
image.set(pixbuf);
|
||||||
found = true;
|
found = true;
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include "util/ustring_clen.hpp"
|
||||||
|
|
||||||
|
int ustring_clen(const Glib::ustring &str){
|
||||||
|
int total = 0;
|
||||||
|
for (auto i = str.begin(); i != str.end(); ++i) {
|
||||||
|
total += g_unichar_iswide(*i) + 1;
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
Loading…
Reference in New Issue