diff --git a/include/modules/wlr/taskbar.hpp b/include/modules/wlr/taskbar.hpp index 742693208..2a3dbbf53 100644 --- a/include/modules/wlr/taskbar.hpp +++ b/include/modules/wlr/taskbar.hpp @@ -130,6 +130,7 @@ class Task { /* Callbacks for Gtk events */ bool handle_clicked(GdkEventButton*); bool handle_button_release(GdkEventButton*); + bool handle_scroll(GdkEventScroll* e); bool handle_motion_notify(GdkEventMotion*); void handle_drag_data_get(const Glib::RefPtr& context, Gtk::SelectionData& selection_data, guint info, guint time); diff --git a/man/waybar-wlr-taskbar.5.scd b/man/waybar-wlr-taskbar.5.scd index 5e20a541c..95747ef1a 100644 --- a/man/waybar-wlr-taskbar.5.scd +++ b/man/waybar-wlr-taskbar.5.scd @@ -101,6 +101,14 @@ Addressed by *wlr/taskbar* typeof: string ++ The action which should be triggered when clicking on the application button with the right mouse button. +*on-scroll-up*: ++ + typeof: string ++ + The action which should be triggered when scrolling up on the application button. + +*on-scroll-down*: ++ + typeof: string ++ + The action which should be triggered when scrolling down on the application button. + *on-update*: ++ typeof: string ++ Command to execute when the module is updated. @@ -146,6 +154,10 @@ value that must be escaped in XML. *minimize*: Toggle application's minimized state. +*minimize-only*: Minimize the application, one-way does not toggle. + +*unminimize*: Restore the application from its minimized state. + *minimize-raise*: Bring the application into foreground or toggle its minimized state. *maximize*: Toggle application's maximized state. diff --git a/src/modules/wlr/taskbar.cpp b/src/modules/wlr/taskbar.cpp index 349606245..832d18610 100644 --- a/src/modules/wlr/taskbar.cpp +++ b/src/modules/wlr/taskbar.cpp @@ -188,8 +188,9 @@ Task::Task(const waybar::Bar& bar, const Json::Value& config, Taskbar* tbar, config_["on-click-right"].isString()) { } - button.add_events(Gdk::BUTTON_PRESS_MASK); + button.add_events(Gdk::BUTTON_PRESS_MASK | Gdk::SCROLL_MASK); button.signal_button_release_event().connect(sigc::mem_fun(*this, &Task::handle_clicked), false); + button.signal_scroll_event().connect(sigc::mem_fun(*this, &Task::handle_scroll), false); button.signal_motion_notify_event().connect(sigc::mem_fun(*this, &Task::handle_motion_notify), false); @@ -539,13 +540,63 @@ bool Task::handle_clicked(GdkEventButton* bt) { fullscreen(!fullscreen()); else if (action == "close") close(); - else + else if (action == "unminimize") { + set_minimize_hint(); + minimize(false); + } else if (action == "minimize-only") { + set_minimize_hint(); + minimize(true); + } else spdlog::warn("Unknown action {}", action); drag_start_button = -1; return true; } +bool Task::handle_scroll(GdkEventScroll* e) { + std::string action; + + if ((e->direction == GDK_SCROLL_UP || (e->direction == GDK_SCROLL_SMOOTH && e->delta_y < 0)) && + config_["on-scroll-up"].isString()) { + action = config_["on-scroll-up"].asString(); + } else if ((e->direction == GDK_SCROLL_DOWN || + (e->direction == GDK_SCROLL_SMOOTH && e->delta_y > 0)) && + config_["on-scroll-down"].isString()) { + action = config_["on-scroll-down"].asString(); + } + if (action.empty()) return false; + + if (action == "activate") + activate(); + else if (action == "minimize") { + set_minimize_hint(); + minimize(!minimized()); + } else if (action == "minimize-raise") { + set_minimize_hint(); + if (minimized()) + minimize(false); + else if (active()) + minimize(true); + else + activate(); + } else if (action == "maximize") + maximize(!maximized()); + else if (action == "fullscreen") + fullscreen(!fullscreen()); + else if (action == "close") + close(); + else if (action == "unminimize") { + set_minimize_hint(); + minimize(false); + } else if (action == "minimize-only") { + set_minimize_hint(); + minimize(true); + } else + spdlog::warn("Unknown action {}", action); + + return true; +} + bool Task::handle_motion_notify(GdkEventMotion* mn) { if (drag_start_button == -1) return false; @@ -720,10 +771,11 @@ Taskbar::Taskbar(const std::string& id, const waybar::Bar& bar, const Json::Valu // commands (issue #3284). Values that are not built-in actions are left alone // and still run as user shell commands. const auto is_builtin_action = [](const std::string& v) { - return v == "activate" || v == "minimize" || v == "minimize-raise" || v == "maximize" || - v == "fullscreen" || v == "close"; + return v == "activate" || v == "minimize" || v == "minimize-only" || v == "unminimize" || + v == "minimize-raise" || v == "maximize" || v == "fullscreen" || v == "close"; }; - for (const auto* event : {"on-click", "on-click-middle", "on-click-right"}) { + for (const auto* event : + {"on-click", "on-click-middle", "on-click-right", "on-scroll-up", "on-scroll-down"}) { if (config_[event].isString() && is_builtin_action(config_[event].asString())) { eventActionMap_.insert({event, config_[event].asString()}); }