Added signal support and wait-for-activity bool.
This commit is contained in:
@@ -10,21 +10,31 @@ namespace waybar::modules {
|
|||||||
|
|
||||||
class IdleInhibitor : public ALabel {
|
class IdleInhibitor : public ALabel {
|
||||||
sigc::connection timeout_;
|
sigc::connection timeout_;
|
||||||
|
sigc::connection activity_timeout_;
|
||||||
|
sigc::connection motion_connection_;
|
||||||
|
sigc::connection key_connection_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IdleInhibitor(const std::string&, const waybar::Bar&, const Json::Value&);
|
IdleInhibitor(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||||
virtual ~IdleInhibitor();
|
virtual ~IdleInhibitor();
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
auto refresh(int) -> void override;
|
||||||
static std::list<waybar::AModule*> modules;
|
static std::list<waybar::AModule*> modules;
|
||||||
static bool status;
|
static bool status;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool handleToggle(GdkEventButton* const& e) override;
|
bool handleToggle(GdkEventButton* const& e) override;
|
||||||
|
bool handleMotion(GdkEventMotion* const& e);
|
||||||
|
bool handleKey(GdkEventKey* const& e);
|
||||||
void toggleStatus();
|
void toggleStatus();
|
||||||
|
void resetActivityTimeout();
|
||||||
|
void setupActivityMonitoring();
|
||||||
|
void teardownActivityMonitoring();
|
||||||
|
|
||||||
const Bar& bar_;
|
const Bar& bar_;
|
||||||
struct zwp_idle_inhibitor_v1* idle_inhibitor_;
|
struct zwp_idle_inhibitor_v1* idle_inhibitor_;
|
||||||
int pid_;
|
int pid_;
|
||||||
|
bool wait_for_activity_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
|||||||
@@ -76,6 +76,17 @@ screensaver, also known as "presentation mode".
|
|||||||
typeof: double ++
|
typeof: double ++
|
||||||
The number of minutes the inhibition should last.
|
The number of minutes the inhibition should last.
|
||||||
|
|
||||||
|
*wait-for-activity*: ++
|
||||||
|
typeof: bool ++
|
||||||
|
default: *false* ++
|
||||||
|
When enabled, the idle inhibitor remains active as long as there is keyboard or mouse activity on the bar. If there is no activity for the duration specified in *timeout*, the inhibitor will automatically toggle off. This option requires *timeout* to be set.
|
||||||
|
|
||||||
|
*signal*: ++
|
||||||
|
typeof: integer ++
|
||||||
|
The signal number used to toggle the idle inhibitor externally. ++
|
||||||
|
The number is valid between 1 and N, where *SIGRTMIN+N* = *SIGRTMAX*. ++
|
||||||
|
Use `pkill -SIGRTMIN+N waybar` to toggle the idle inhibitor from scripts or keybindings.
|
||||||
|
|
||||||
*tooltip*: ++
|
*tooltip*: ++
|
||||||
typeof: bool ++
|
typeof: bool ++
|
||||||
default: true ++
|
default: true ++
|
||||||
@@ -115,17 +126,46 @@ screensaver, also known as "presentation mode".
|
|||||||
|
|
||||||
# EXAMPLES
|
# EXAMPLES
|
||||||
|
|
||||||
|
Basic usage with timeout:
|
||||||
|
|
||||||
```
|
```
|
||||||
"idle_inhibitor": {
|
"idle_inhibitor": {
|
||||||
"format": "{icon}",
|
"format": "{icon}",
|
||||||
"format-icons": {
|
"format-icons": {
|
||||||
"activated": "",
|
"activated": "",
|
||||||
"deactivated": ""
|
"deactivated": ""
|
||||||
},
|
},
|
||||||
"timeout": 30.5
|
"timeout": 30.5
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
With external control via signals (can be toggled with `pkill -SIGRTMIN+8 waybar`):
|
||||||
|
|
||||||
|
```
|
||||||
|
"idle_inhibitor": {
|
||||||
|
"format": "{icon}",
|
||||||
|
"format-icons": {
|
||||||
|
"activated": "",
|
||||||
|
"deactivated": ""
|
||||||
|
},
|
||||||
|
"signal": 8
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
With wait-for-activity feature:
|
||||||
|
|
||||||
|
```
|
||||||
|
"idle_inhibitor": {
|
||||||
|
"format": "{icon}",
|
||||||
|
"format-icons": {
|
||||||
|
"activated": "",
|
||||||
|
"deactivated": ""
|
||||||
|
},
|
||||||
|
"timeout": 5.0,
|
||||||
|
"wait-for-activity": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
# STYLE
|
# STYLE
|
||||||
|
|
||||||
- *#idle_inhibitor*
|
- *#idle_inhibitor*
|
||||||
|
|||||||
@@ -11,11 +11,17 @@ waybar::modules::IdleInhibitor::IdleInhibitor(const std::string& id, const Bar&
|
|||||||
: ALabel(config, "idle_inhibitor", id, "{status}", 0, false, true),
|
: ALabel(config, "idle_inhibitor", id, "{status}", 0, false, true),
|
||||||
bar_(bar),
|
bar_(bar),
|
||||||
idle_inhibitor_(nullptr),
|
idle_inhibitor_(nullptr),
|
||||||
pid_(-1) {
|
pid_(-1),
|
||||||
|
wait_for_activity_(false) {
|
||||||
if (waybar::Client::inst()->idle_inhibit_manager == nullptr) {
|
if (waybar::Client::inst()->idle_inhibit_manager == nullptr) {
|
||||||
throw std::runtime_error("idle-inhibit not available");
|
throw std::runtime_error("idle-inhibit not available");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read the wait-for-activity config option
|
||||||
|
if (config_["wait-for-activity"].isBool()) {
|
||||||
|
wait_for_activity_ = config_["wait-for-activity"].asBool();
|
||||||
|
}
|
||||||
|
|
||||||
if (waybar::modules::IdleInhibitor::modules.empty() && config_["start-activated"].isBool() &&
|
if (waybar::modules::IdleInhibitor::modules.empty() && config_["start-activated"].isBool() &&
|
||||||
config_["start-activated"].asBool() != status) {
|
config_["start-activated"].asBool() != status) {
|
||||||
toggleStatus();
|
toggleStatus();
|
||||||
@@ -32,6 +38,8 @@ waybar::modules::IdleInhibitor::IdleInhibitor(const std::string& id, const Bar&
|
|||||||
}
|
}
|
||||||
|
|
||||||
waybar::modules::IdleInhibitor::~IdleInhibitor() {
|
waybar::modules::IdleInhibitor::~IdleInhibitor() {
|
||||||
|
teardownActivityMonitoring();
|
||||||
|
|
||||||
if (idle_inhibitor_ != nullptr) {
|
if (idle_inhibitor_ != nullptr) {
|
||||||
zwp_idle_inhibitor_v1_destroy(idle_inhibitor_);
|
zwp_idle_inhibitor_v1_destroy(idle_inhibitor_);
|
||||||
idle_inhibitor_ = nullptr;
|
idle_inhibitor_ = nullptr;
|
||||||
@@ -77,6 +85,17 @@ auto waybar::modules::IdleInhibitor::update() -> void {
|
|||||||
ALabel::update();
|
ALabel::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto waybar::modules::IdleInhibitor::refresh(int sig) -> void {
|
||||||
|
if (config_["signal"].isInt() && sig == SIGRTMIN + config_["signal"].asInt()) {
|
||||||
|
toggleStatus();
|
||||||
|
|
||||||
|
// Make all other idle inhibitor modules update
|
||||||
|
for (auto const& module : waybar::modules::IdleInhibitor::modules) {
|
||||||
|
module->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void waybar::modules::IdleInhibitor::toggleStatus() {
|
void waybar::modules::IdleInhibitor::toggleStatus() {
|
||||||
status = !status;
|
status = !status;
|
||||||
|
|
||||||
@@ -89,6 +108,12 @@ void waybar::modules::IdleInhibitor::toggleStatus() {
|
|||||||
auto timeoutMins = config_["timeout"].asDouble();
|
auto timeoutMins = config_["timeout"].asDouble();
|
||||||
int timeoutSecs = timeoutMins * 60;
|
int timeoutSecs = timeoutMins * 60;
|
||||||
|
|
||||||
|
// If wait-for-activity is enabled, set up activity monitoring
|
||||||
|
if (wait_for_activity_) {
|
||||||
|
setupActivityMonitoring();
|
||||||
|
resetActivityTimeout();
|
||||||
|
} else {
|
||||||
|
// Original behavior: simple timeout
|
||||||
timeout_ = Glib::signal_timeout().connect_seconds(
|
timeout_ = Glib::signal_timeout().connect_seconds(
|
||||||
[]() {
|
[]() {
|
||||||
/* intentionally not tied to a module instance lifetime
|
/* intentionally not tied to a module instance lifetime
|
||||||
@@ -104,6 +129,10 @@ void waybar::modules::IdleInhibitor::toggleStatus() {
|
|||||||
},
|
},
|
||||||
timeoutSecs);
|
timeoutSecs);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// When deactivated, tear down activity monitoring
|
||||||
|
teardownActivityMonitoring();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool waybar::modules::IdleInhibitor::handleToggle(GdkEventButton* const& e) {
|
bool waybar::modules::IdleInhibitor::handleToggle(GdkEventButton* const& e) {
|
||||||
@@ -121,3 +150,74 @@ bool waybar::modules::IdleInhibitor::handleToggle(GdkEventButton* const& e) {
|
|||||||
ALabel::handleToggle(e);
|
ALabel::handleToggle(e);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool waybar::modules::IdleInhibitor::handleMotion(GdkEventMotion* const& e) {
|
||||||
|
if (wait_for_activity_ && status) {
|
||||||
|
resetActivityTimeout();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool waybar::modules::IdleInhibitor::handleKey(GdkEventKey* const& e) {
|
||||||
|
if (wait_for_activity_ && status) {
|
||||||
|
resetActivityTimeout();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void waybar::modules::IdleInhibitor::resetActivityTimeout() {
|
||||||
|
if (!config_["timeout"].isNumeric()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (activity_timeout_.connected()) {
|
||||||
|
activity_timeout_.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto timeoutMins = config_["timeout"].asDouble();
|
||||||
|
int timeoutSecs = timeoutMins * 60;
|
||||||
|
|
||||||
|
activity_timeout_ = Glib::signal_timeout().connect_seconds(
|
||||||
|
[]() {
|
||||||
|
spdlog::info("deactivating idle_inhibitor due to inactivity");
|
||||||
|
status = false;
|
||||||
|
for (auto const& module : waybar::modules::IdleInhibitor::modules) {
|
||||||
|
module->update();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
timeoutSecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void waybar::modules::IdleInhibitor::setupActivityMonitoring() {
|
||||||
|
// Don't set up if already connected
|
||||||
|
if (motion_connection_.connected() || key_connection_.connected()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable motion and key event monitoring on the bar window
|
||||||
|
auto window = bar_.window.get_window();
|
||||||
|
if (window) {
|
||||||
|
window->set_events(window->get_events() | Gdk::POINTER_MOTION_MASK | Gdk::KEY_PRESS_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect to the bar window's event signals
|
||||||
|
motion_connection_ = bar_.window.signal_motion_notify_event().connect(
|
||||||
|
sigc::mem_fun(*this, &IdleInhibitor::handleMotion));
|
||||||
|
key_connection_ = bar_.window.signal_key_press_event().connect(
|
||||||
|
sigc::mem_fun(*this, &IdleInhibitor::handleKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
void waybar::modules::IdleInhibitor::teardownActivityMonitoring() {
|
||||||
|
if (activity_timeout_.connected()) {
|
||||||
|
activity_timeout_.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (motion_connection_.connected()) {
|
||||||
|
motion_connection_.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key_connection_.connected()) {
|
||||||
|
key_connection_.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user