ALabel: Add support for configurable mouse events

This patch adds 3 new configuration options applicable for
subclasses of ALabel. The options can be used to execute
user defined code in response to the 3 mouse events:
* on-click: The left mouse button click
* on-scroll-up
* on-scroll-down
This patch also modifies the behaviour of the format-alt toggle
such that when the on-click event is configured, format-alt is
toggled on any mouse click other than left click. When on-click
is not defined, any mouse button would toggle format-alt.

Signed-off-by: Harish Krupo <harishkrupo@gmail.com>
This commit is contained in:
Harish Krupo 2018-10-29 22:34:09 +05:30
parent 4307e4fd8e
commit d7d1ebd736
3 changed files with 119 additions and 32 deletions

View File

@ -12,15 +12,22 @@ class ALabel : public IModule {
virtual auto update() -> void; virtual auto update() -> void;
virtual std::string getIcon(uint16_t, const std::string& alt = ""); virtual std::string getIcon(uint16_t, const std::string& alt = "");
virtual operator Gtk::Widget&(); virtual operator Gtk::Widget&();
protected: protected:
Gtk::EventBox event_box_; Gtk::EventBox event_box_;
Gtk::Label label_; Gtk::Label label_;
const Json::Value& config_; const Json::Value& config_;
std::string format_; std::string format_;
std::string button_press_cmd_ = "";
std::string scroll_up_cmd_ = "";
std::string scroll_down_cmd_ = "";
std::mutex mutex_;
private: private:
bool handleToggle(GdkEventButton* const& ev); bool handleToggle(GdkEventButton* const& ev);
bool handleScroll(GdkEventScroll*);
bool alt = false; bool alt = false;
const std::string default_format_; const std::string default_format_;
}; };
} } // namespace waybar

View File

@ -32,4 +32,21 @@ inline struct res exec(const std::string cmd)
return {exit_code, output}; return {exit_code, output};
} }
inline bool forkExec(std::string cmd) {
if (cmd == "") return true;
printf("fork exec command %s\n", cmd.c_str());
int32_t pid = fork();
if (pid < 0) {
printf("Unable to exec cmd %s, error %s", cmd.c_str(), strerror(errno));
return false;
} }
// Child executes the command
if (!pid) execl("/bin/sh", "sh", "-c", cmd.c_str(), (char*)0);
return true;
}
} // namespace waybar::util::command

View File

@ -1,4 +1,5 @@
#include "ALabel.hpp" #include "ALabel.hpp"
#include <util/command.hpp>
#include <iostream> #include <iostream>
@ -14,30 +15,94 @@ waybar::ALabel::ALabel(const Json::Value& config, const std::string format)
} }
if (config_["format-alt"].isString()) { if (config_["format-alt"].isString()) {
event_box_.add_events(Gdk::BUTTON_PRESS_MASK); event_box_.add_events(Gdk::BUTTON_PRESS_MASK);
event_box_.signal_button_press_event() event_box_.signal_button_press_event().connect(
.connect(sigc::mem_fun(*this, &ALabel::handleToggle)); sigc::mem_fun(*this, &ALabel::handleToggle));
}
// configure events' user commands
if (config_["on-click"].isString()) {
std::string cmd = config_["on-click"].asString();
event_box_.add_events(Gdk::BUTTON_PRESS_MASK);
event_box_.signal_button_press_event().connect(
sigc::mem_fun(*this, &ALabel::handleToggle));
button_press_cmd_ = cmd;
}
if (config_["on-scroll-up"].isString()) {
std::string cmd = config_["on-scroll-up"].asString();
event_box_.add_events(Gdk::SCROLL_MASK);
event_box_.signal_scroll_event().connect(
sigc::mem_fun(*this, &ALabel::handleScroll));
scroll_up_cmd_ = cmd;
}
if (config_["on-scroll-down"].isString()) {
std::string cmd = config_["on-scroll-down"].asString();
event_box_.add_events(Gdk::SCROLL_MASK);
event_box_.signal_scroll_event().connect(
sigc::mem_fun(*this, &ALabel::handleScroll));
scroll_down_cmd_ = cmd;
} }
} }
auto waybar::ALabel::update() -> void auto waybar::ALabel::update() -> void {
{
// Nothing here // Nothing here
} }
bool waybar::ALabel::handleToggle(GdkEventButton* const& /*ev*/) bool waybar::ALabel::handleToggle(GdkEventButton* const& e) {
{ if (button_press_cmd_ != "" && e->button == 1) {
waybar::util::command::forkExec(button_press_cmd_);
} else {
alt = !alt; alt = !alt;
if (alt) { if (alt) {
format_ = config_["format-alt"].asString(); format_ = config_["format-alt"].asString();
} else { } else {
format_ = default_format_; format_ = default_format_;
} }
}
dp.emit(); dp.emit();
return true; return true;
} }
std::string waybar::ALabel::getIcon(uint16_t percentage, const std::string& alt) bool waybar::ALabel::handleScroll(GdkEventScroll* e) {
// Avoid concurrent scroll event
{ {
std::lock_guard<std::mutex> lock(mutex_);
bool direction_up = false;
if (e->direction == GDK_SCROLL_UP) {
direction_up = true;
}
if (e->direction == GDK_SCROLL_DOWN) {
direction_up = false;
}
if (e->direction == GDK_SCROLL_SMOOTH) {
gdouble delta_x, delta_y;
gdk_event_get_scroll_deltas(reinterpret_cast<const GdkEvent*>(e),
&delta_x, &delta_y);
if (delta_y < 0) {
direction_up = true;
} else if (delta_y > 0) {
direction_up = false;
}
}
if (direction_up)
waybar::util::command::forkExec(scroll_up_cmd_);
else
waybar::util::command::forkExec(scroll_down_cmd_);
dp.emit();
}
return true;
}
std::string waybar::ALabel::getIcon(uint16_t percentage,
const std::string& alt) {
auto format_icons = config_["format-icons"]; auto format_icons = config_["format-icons"];
if (format_icons.isObject()) { if (format_icons.isObject()) {
if (!alt.empty() && format_icons[alt].isString()) { if (!alt.empty() && format_icons[alt].isString()) {
@ -57,6 +122,4 @@ std::string waybar::ALabel::getIcon(uint16_t percentage, const std::string& alt)
return ""; return "";
} }
waybar::ALabel::operator Gtk::Widget &() { waybar::ALabel::operator Gtk::Widget&() { return event_box_; }
return event_box_;
}