Skip to content

Commit

Permalink
Implement scrolling on the background of the waybar
Browse files Browse the repository at this point in the history
This experience made me hate GTK 3.0. There's some duplicate code as a
result of this too, for checking scroll direction. Smooth scrolling is
not handled at all for the bar itself.

Signed-off-by: John M. Harris Jr. <johnmh@johnmh.me>
  • Loading branch information
JohnMH committed Jul 2, 2024
1 parent 034760e commit a45032a
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/bar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class Bar {
void setVisible(bool visible);
void toggle();
void handleSignal(int);
bool handleScroll(GdkEventScroll*);

struct waybar_output *output;
Json::Value config;
Expand Down
55 changes: 55 additions & 0 deletions src/bar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "modules/sway/bar.hpp"
#endif

#include "util/command.hpp"

namespace waybar {
static constexpr const char* MIN_HEIGHT_MSG =
"Requested height: {} is less than the minimum height: {} required by the modules";
Expand Down Expand Up @@ -257,6 +259,12 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config)
setVisible(false);
}

if (config["on-scroll-up"].isString() || config["on-scroll-down"].isString() ||
config["on-scroll-left"].isString() || config["on-scroll-right"].isString()) {
window.add_events(Gdk::SCROLL_MASK);
window.signal_scroll_event().connect(sigc::mem_fun(*this, &Bar::handleScroll));
}

window.signal_map_event().connect_notify(sigc::mem_fun(*this, &Bar::onMap));

#if HAVE_SWAY
Expand Down Expand Up @@ -471,6 +479,53 @@ void waybar::Bar::handleSignal(int signal) {
}
}

bool _rect_contains_evt(const Gdk::Rectangle& rect, GdkEventScroll* e) {
return e->x >= rect.get_x() && e->x < rect.get_x() + rect.get_width() &&
e->y >= rect.get_y() && e->y < rect.get_y() + rect.get_height();
}

bool waybar::Bar::handleScroll(GdkEventScroll* e) {
if (_rect_contains_evt(left_.get_allocation(), e) ||
_rect_contains_evt(center_.get_allocation(), e) ||
_rect_contains_evt(right_.get_allocation(), e)) {
return false;
}

std::string eventName{};

// only affects up/down
bool reverse = config["reverse-scrolling"].asBool();
bool reverse_mouse = config["reverse-mouse-scrolling"].asBool();

// ignore reverse-scrolling if event comes from a mouse wheel
GdkDevice* device = gdk_event_get_source_device((GdkEvent*)e);
if (device != NULL && gdk_device_get_source(device) == GDK_SOURCE_MOUSE) {
reverse = reverse_mouse;
}

switch (e->direction) {
case GDK_SCROLL_UP:
eventName = (reverse ? "on-scroll-down" : "on-scroll-up");
break;
case GDK_SCROLL_DOWN:
eventName = (reverse ? "on-scroll-up" : "on-scroll-down");
break;
case GDK_SCROLL_LEFT:
eventName = "on-scroll-left";
break;
case GDK_SCROLL_RIGHT:
eventName = "on-scroll-right";
break;
}

if (config[eventName].isString()) {
util::command::forkExec(config[eventName].asString());
return true;
}

return false;
}

void waybar::Bar::getModules(const Factory& factory, const std::string& pos,
waybar::Group* group = nullptr) {
auto module_list = group ? config[pos]["modules"] : config[pos];
Expand Down

0 comments on commit a45032a

Please sign in to comment.