From ec398590933a8300d1f6b385c015e2032c9251b1 Mon Sep 17 00:00:00 2001 From: Michael Carlberg Date: Mon, 5 Dec 2016 13:17:09 +0100 Subject: [PATCH] feat: Window click handlers New parameters for defining fallback click handlers that will be triggered for the whole window unless a module action is matched. Parameters added to all [bar/foo] sections: - `click-left = ...` - `click-middle= ...` - `click-right= ...` - `scroll-up= ...` - `scroll-down= ...` Ref #226 --- examples/config.cmake | 19 ++++++++++++++++++ include/components/types.hpp | 31 +++++++++++++++++------------ include/modules/i3.hpp | 8 ++++---- src/components/bar.cpp | 38 +++++++++++++++++++++++++++++++++--- src/modules/i3.cpp | 14 +++++-------- 5 files changed, 81 insertions(+), 29 deletions(-) diff --git a/examples/config.cmake b/examples/config.cmake index 4cff7b0f..2bfe4ce0 100644 --- a/examples/config.cmake +++ b/examples/config.cmake @@ -63,6 +63,25 @@ tray-padding = 2 ;override-redirect = true +; Cycle bspwm desktops when scrolling on the bar (unless caught by module) +; +; NOTE: You should probably disable scrolling for +; the bspwm module by setting `enable-scroll = false` +; in the module section +; +;scroll-up = bspc desktop -f prev.local +;scroll-down = bspc desktop -f next.local + +; Cycle i3 workspaces when scrolling on the bar (unless caught by module) +; +; NOTE: You should probably disable scrolling for +; the i3 module by setting `enable-scroll = false` +; in the module section +; +;scroll-up = i3-msg workspace prev_on_output +;scroll-down = i3-msg workspace next_on_output + + [module/xwindow] type = internal/xwindow label = %title:0:30:...% diff --git a/include/components/types.hpp b/include/components/types.hpp index cedd83c1..9e8e9fe4 100644 --- a/include/components/types.hpp +++ b/include/components/types.hpp @@ -73,6 +73,22 @@ struct line_settings { uint16_t size{0U}; }; +struct action { + mousebtn button{mousebtn::NONE}; + string command; +}; + +struct action_block : public action { + alignment align{alignment::NONE}; + double start_x{0.0}; + double end_x{0.0}; + bool active{true}; + + uint16_t width() const { + return static_cast(end_x - start_x + 0.5); + } +}; + struct bar_settings { monitor_t monitor; edge origin{edge::TOP}; @@ -103,6 +119,8 @@ struct bar_settings { bool override_redirect{false}; + vector actions; + const xcb_rectangle_t inner_area(bool abspos = false) const { xcb_rectangle_t rect{0, 0, size.w, size.h}; @@ -121,19 +139,6 @@ struct bar_settings { } }; -struct action_block { - alignment align{alignment::NONE}; - double start_x{0.0}; - double end_x{0.0}; - mousebtn button{mousebtn::NONE}; - string command; - bool active{true}; - - uint16_t width() const { - return static_cast(end_x - start_x + 0.5); - } -}; - struct event_timer { xcb_timestamp_t event{0L}; xcb_timestamp_t offset{1L}; diff --git a/include/modules/i3.hpp b/include/modules/i3.hpp index f2b035f0..91caae13 100644 --- a/include/modules/i3.hpp +++ b/include/modules/i3.hpp @@ -53,10 +53,10 @@ namespace modules { static constexpr const char* TAG_LABEL_STATE{""}; static constexpr const char* TAG_LABEL_MODE{""}; - static constexpr const char* EVENT_PREFIX{"i3"}; - static constexpr const char* EVENT_CLICK{"i3-wsfocus-"}; - static constexpr const char* EVENT_SCROLL_UP{"i3-wsnext"}; - static constexpr const char* EVENT_SCROLL_DOWN{"i3-wsprev"}; + static constexpr const char* EVENT_PREFIX{"i3wm"}; + static constexpr const char* EVENT_CLICK{"i3wm-wsfocus-"}; + static constexpr const char* EVENT_SCROLL_UP{"i3wm-wsnext"}; + static constexpr const char* EVENT_SCROLL_DOWN{"i3wm-wsprev"}; map m_statelabels; vector> m_workspaces; diff --git a/src/components/bar.cpp b/src/components/bar.cpp index 3ce2ff55..2b6462d5 100644 --- a/src/components/bar.cpp +++ b/src/components/bar.cpp @@ -94,6 +94,29 @@ void bar::bootstrap(bool nodraw) { m_opts.strut.bottom = m_conf.get("global/wm", "margin-bottom", 0); m_buttonpress.offset = xutils::event_timer_ms(m_conf, xcb_button_press_event_t{}); + + // Get fallback click handlers + auto click_left = m_conf.get(bs, "click-left", ""); + auto click_middle = m_conf.get(bs, "click-middle", ""); + auto click_right = m_conf.get(bs, "click-right", ""); + auto scroll_up = m_conf.get(bs, "scroll-up", ""); + auto scroll_down = m_conf.get(bs, "scroll-down", ""); + + if (!click_left.empty()) { + m_opts.actions.emplace_back(action{mousebtn::LEFT, move(click_left)}); + } + if (!click_middle.empty()) { + m_opts.actions.emplace_back(action{mousebtn::MIDDLE, move(click_middle)}); + } + if (!click_right.empty()) { + m_opts.actions.emplace_back(action{mousebtn::RIGHT, move(click_right)}); + } + if (!scroll_up.empty()) { + m_opts.actions.emplace_back(action{mousebtn::SCROLL_UP, move(scroll_up)}); + } + if (!scroll_down.empty()) { + m_opts.actions.emplace_back(action{mousebtn::SCROLL_DOWN, move(scroll_down)}); + } } m_log.trace("bar: Load color values"); @@ -638,7 +661,6 @@ void bar::handle(const evt::button_press& evt) { m_log.trace_x("bar: Ignoring action: end_x(%i) < event_x(%i)", action.end_x, event_x); continue; } - m_log.trace("Found matching input area"); m_log.trace_x("action.command = %s", action.command); m_log.trace_x("action.button = %i", static_cast(action.button)); @@ -647,13 +669,23 @@ void bar::handle(const evt::button_press& evt) { if (g_signals::bar::action_click) { g_signals::bar::action_click(action.command); - } else { - m_log.warn("No signal handler's connected to 'action_click'"); } return; } + for (auto&& action : m_opts.actions) { + if (action.button == button && !action.command.empty()) { + m_log.trace("Triggering fallback click handler: %s", action.command); + + if (g_signals::bar::action_click) { + g_signals::bar::action_click(action.command); + } + + return; + } + } + m_log.warn("No matching input area found"); } diff --git a/src/modules/i3.cpp b/src/modules/i3.cpp index a2735dc0..6e04791a 100644 --- a/src/modules/i3.cpp +++ b/src/modules/i3.cpp @@ -206,22 +206,18 @@ namespace modules { } bool i3_module::handle_event(string cmd) { - if (cmd.compare(0, 2, EVENT_PREFIX) != 0) { - return false; - } - try { - i3_util::connection_t ipc; - if (cmd.compare(0, strlen(EVENT_CLICK), EVENT_CLICK) == 0) { m_log.info("%s: Sending workspace focus command to ipc handler", name()); - ipc.send_command("workspace number " + cmd.substr(strlen(EVENT_CLICK))); + i3_util::connection_t{}.send_command("workspace number " + cmd.substr(strlen(EVENT_CLICK))); } else if (cmd.compare(0, strlen(EVENT_SCROLL_DOWN), EVENT_SCROLL_DOWN) == 0) { m_log.info("%s: Sending workspace prev command to ipc handler", name()); - ipc.send_command("workspace next_on_output"); + i3_util::connection_t{}.send_command("workspace next_on_output"); } else if (cmd.compare(0, strlen(EVENT_SCROLL_UP), EVENT_SCROLL_UP) == 0) { m_log.info("%s: Sending workspace next command to ipc handler", name()); - ipc.send_command("workspace prev_on_output"); + i3_util::connection_t{}.send_command("workspace prev_on_output"); + } else { + return false; } } catch (const exception& err) { m_log.err("%s: %s", name(), err.what());