diff --git a/include/modules/wlr/taskbar.hpp b/include/modules/wlr/taskbar.hpp index 07110ddee..f32974ce8 100644 --- a/include/modules/wlr/taskbar.hpp +++ b/include/modules/wlr/taskbar.hpp @@ -146,7 +146,8 @@ class Taskbar : public waybar::AModule { public: Taskbar(const std::string &, const waybar::Bar &, const Json::Value &); ~Taskbar(); - void update(); + auto update() -> void override; + auto doAction(const std::string &) -> void override; private: const waybar::Bar &bar_; @@ -156,6 +157,7 @@ class Taskbar : public waybar::AModule { std::vector> icon_themes_; std::unordered_set ignore_list_; std::map app_ids_replace_map_; + std::map task_actions_; struct zwlr_foreign_toplevel_manager_v1 *manager_; struct wl_seat *seat_; @@ -181,6 +183,7 @@ class Taskbar : public waybar::AModule { const std::vector> &icon_themes() const; const std::unordered_set &ignore_list() const; const std::map &app_ids_replace_map() const; + const std::map &task_actions() const; }; } /* namespace waybar::modules::wlr */ diff --git a/man/waybar-wlr-taskbar.5.scd b/man/waybar-wlr-taskbar.5.scd index af1ba97f7..a2ebb95b1 100644 --- a/man/waybar-wlr-taskbar.5.scd +++ b/man/waybar-wlr-taskbar.5.scd @@ -59,15 +59,15 @@ Addressed by *wlr/taskbar* *on-click*: ++ typeof: string ++ - The action which should be triggered when clicking on the application button with the left mouse button. + The action which should be triggered when clicking on the application button with the left mouse button. Needs to be defined in actions object. *on-click-middle*: ++ typeof: string ++ - The action which should be triggered when clicking on the application button with the middle mouse button. + The action which should be triggered when clicking on the application button with the middle mouse button. Needs to be defined in actions object. *on-click-right*: ++ typeof: string ++ - The action which should be triggered when clicking on the application button with the right mouse button. + The action which should be triggered when clicking on the application button with the right mouse button. Needs to be defined in actions object. *on-update*: ++ typeof: string ++ @@ -133,8 +133,10 @@ Invalid expressions (e.g., mismatched parentheses) are skipped. "icon-size": 14, "icon-theme": "Numix-Circle", "tooltip-format": "{title}", - "on-click": "activate", - "on-click-middle": "close", + "actions" : { + "on-click": "activate", + "on-click-middle": "close", + }, "ignore-list": [ "Alacritty" ], diff --git a/src/modules/wlr/taskbar.cpp b/src/modules/wlr/taskbar.cpp index 30e4ee488..944424709 100644 --- a/src/modules/wlr/taskbar.cpp +++ b/src/modules/wlr/taskbar.cpp @@ -328,11 +328,6 @@ Task::Task(const waybar::Bar &bar, const Json::Value &config, Taskbar *tbar, format_tooltip_ = "{title}"; } - /* Handle click events if configured */ - if (config_["on-click"].isString() || config_["on-click-middle"].isString() || - config_["on-click-right"].isString()) { - } - button.add_events(Gdk::BUTTON_PRESS_MASK); button.signal_button_release_event().connect(sigc::mem_fun(*this, &Task::handle_clicked), false); @@ -556,21 +551,27 @@ bool Task::handle_clicked(GdkEventButton *bt) { } std::string action; - if (config_["on-click"].isString() && bt->button == 1) - action = config_["on-click"].asString(); - else if (config_["on-click-middle"].isString() && bt->button == 2) - action = config_["on-click-middle"].asString(); - else if (config_["on-click-right"].isString() && bt->button == 3) - action = config_["on-click-right"].asString(); - - if (action.empty()) + auto actions = tbar_->task_actions(); + + if (actions.contains("on-click") && bt->button == 1) + action = actions["on-click"]; + else if (actions.contains("on-click-middle") && bt->button == 2) + action = actions["on-click-middle"]; + else if (actions.contains("on-click-right") && bt->button == 3) + action = actions["on-click-right"]; + + if (action.empty()) { + spdlog::trace("wlr/taskbar: no action bound"); return true; - else if (action == "activate") + } else if (action == "activate") { + spdlog::trace("wlr/taskbar: activate"); activate(); - else if (action == "minimize") { + } else if (action == "minimize") { + spdlog::trace("wlr/taskbar: minimize"); set_minimize_hint(); minimize(!minimized()); } else if (action == "minimize-raise") { + spdlog::trace("wlr/taskbar: minimize-raise"); set_minimize_hint(); if (minimized()) minimize(false); @@ -578,14 +579,20 @@ bool Task::handle_clicked(GdkEventButton *bt) { minimize(true); else activate(); - } else if (action == "maximize") + } else if (action == "maximize") { + spdlog::trace("wlr/taskbar: maximize"); maximize(!maximized()); - else if (action == "fullscreen") + } else if (action == "fullscreen") { + spdlog::trace("wlr/taskbar: fullscreen"); fullscreen(!fullscreen()); - else if (action == "close") + } else if (action == "close") { + spdlog::trace("wlr/taskbar: close"); close(); - else + } else { + // this should probably not happen anymore + spdlog::trace("wlr/taskbar: unknown action"); spdlog::warn("Unknown action {}", action); + } drag_start_button = -1; return true; @@ -803,6 +810,37 @@ Taskbar::Taskbar(const std::string &id, const waybar::Bar &bar, const Json::Valu } } + // valid actions + const std::vector actions = {"activate", "minimize", "minimize-raise", + "maximize", "fullscreen", "close"}; + // valid triggers for the actions + const std::vector triggers = {"on-click", "on-click-right", "on-click-middle"}; + + for (auto &t : triggers) { + if (config_["actions"].isObject() && config["actions"][t].isString()) { + if (std::find(actions.begin(), actions.end(), config_["actions"][t].asString()) != + actions.end()) { + task_actions_.emplace(t, config["actions"][t].asString()); + } else { + spdlog::warn("wlr/taskbar: unknown action {}", config["actions"][t].asString()); + } + } + + // commands can still be executed by AModule on the whole module. + // But if it is an action, it should ideally be within "actions", give a warning. + // If there was an action within the actions object, ignore this one. + if (config_[t].isString() && + std::find(actions.begin(), actions.end(), config_[t].asString()) != actions.end()) { + if (task_actions_.emplace(t, config_[t].asString()).second) { + spdlog::warn("wlr/taskbar: {} action should be within actions object", t); + } else { + spdlog::warn( + "wlr/taskbar: ignoring action {} because there is another within the actions object", + t); + } + } + } + icon_themes_.push_back(Gtk::IconTheme::get_default()); for (auto &t : tasks_) { @@ -862,6 +900,8 @@ static const struct zwlr_foreign_toplevel_manager_v1_listener toplevel_manager_i .finished = tm_handle_finished, }; +auto Taskbar::doAction(const std::string &name) -> void {} + void Taskbar::register_manager(struct wl_registry *registry, uint32_t name, uint32_t version) { if (manager_) { spdlog::warn("Register foreign toplevel manager again although already existing!"); @@ -949,4 +989,6 @@ const std::map &Taskbar::app_ids_replace_map() const { return app_ids_replace_map_; } +const std::map &Taskbar::task_actions() const { return task_actions_; } + } /* namespace waybar::modules::wlr */