From f4529dde99182c040cad9e70f617dcfe4e897b41 Mon Sep 17 00:00:00 2001 From: Michael Carlberg Date: Wed, 14 Dec 2016 00:46:33 +0100 Subject: [PATCH] feat(i3): Conditional wrap around on scroll Ref #242 --- examples/config.cmake | 1 + include/modules/i3.hpp | 13 +++++++------ include/utils/i3.hpp | 3 +++ src/modules/i3.cpp | 33 +++++++++++++++++++++++++++------ src/utils/i3.cpp | 12 ++++++++++++ 5 files changed, 50 insertions(+), 12 deletions(-) diff --git a/examples/config.cmake b/examples/config.cmake index 7d9adef5..993596e7 100644 --- a/examples/config.cmake +++ b/examples/config.cmake @@ -125,6 +125,7 @@ label-empty-padding = 2 type = internal/i3 format = index-sort = true +wrapping-scroll = false label-mode = %mode% label-mode-padding = 2 diff --git a/include/modules/i3.hpp b/include/modules/i3.hpp index 91caae13..18c09541 100644 --- a/include/modules/i3.hpp +++ b/include/modules/i3.hpp @@ -65,12 +65,13 @@ namespace modules { label_t m_modelabel; bool m_modeactive{false}; - bool m_click = true; - bool m_scroll = true; - bool m_indexsort = false; - bool m_pinworkspaces = false; - bool m_strip_wsnumbers = false; - size_t m_wsname_maxlen = 0; + bool m_click{true}; + bool m_scroll{true}; + bool m_wrap{true}; + bool m_indexsort{false}; + bool m_pinworkspaces{false}; + bool m_strip_wsnumbers{false}; + size_t m_wsname_maxlen{0}; unique_ptr m_ipc; }; diff --git a/include/utils/i3.hpp b/include/utils/i3.hpp index bd9289ca..a5aa1cd2 100644 --- a/include/utils/i3.hpp +++ b/include/utils/i3.hpp @@ -11,6 +11,9 @@ class connection; namespace i3_util { using connection_t = i3ipc::connection; + using workspace_t = i3ipc::workspace_t; + + shared_ptr focused_workspace(const connection_t&); vector root_windows(connection& conn, const string& output_name = ""); bool restack_above_root(connection& conn, const monitor_t& mon, const xcb_window_t win); diff --git a/src/modules/i3.cpp b/src/modules/i3.cpp index 6e04791a..de5c2c5c 100644 --- a/src/modules/i3.cpp +++ b/src/modules/i3.cpp @@ -30,6 +30,7 @@ namespace modules { // Load configuration values GET_CONFIG_VALUE(name(), m_click, "enable-click"); GET_CONFIG_VALUE(name(), m_scroll, "enable-scroll"); + GET_CONFIG_VALUE(name(), m_wrap, "wrapping-scroll"); GET_CONFIG_VALUE(name(), m_indexsort, "index-sort"); GET_CONFIG_VALUE(name(), m_pinworkspaces, "pin-workspaces"); GET_CONFIG_VALUE(name(), m_strip_wsnumbers, "strip-wsnumbers"); @@ -207,15 +208,35 @@ namespace modules { bool i3_module::handle_event(string cmd) { try { + if (cmd.compare(0, strlen(EVENT_CLICK), EVENT_CLICK) == 0) { - m_log.info("%s: Sending workspace focus command to ipc handler", name()); - i3_util::connection_t{}.send_command("workspace number " + cmd.substr(strlen(EVENT_CLICK))); + const i3_util::connection_t conn{}; + const string workspace_num{cmd.substr(strlen(EVENT_CLICK))}; + + if (i3_util::focused_workspace(conn)->num != atoi(workspace_num.c_str())) { + m_log.info("%s: Sending workspace focus command to ipc handler", name()); + conn.send_command("workspace number " + workspace_num); + } else { + m_log.warn("%s: Ignoring workspace focus command (reason: workspace already focused)", name()); + } } 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()); - i3_util::connection_t{}.send_command("workspace next_on_output"); + const i3_util::connection_t conn{}; + + if (m_wrap || conn.get_workspaces().back()->num != i3_util::focused_workspace(conn)->num) { + m_log.info("%s: Sending workspace next command to ipc handler", name()); + conn.send_command("workspace next_on_output"); + } else { + m_log.warn("%s: Ignoring workspace next command (reason: `wrap = false`)", name()); + } } 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()); - i3_util::connection_t{}.send_command("workspace prev_on_output"); + const i3_util::connection_t conn{}; + + if (m_wrap || conn.get_workspaces().front()->num != i3_util::focused_workspace(conn)->num) { + m_log.info("%s: Sending workspace prev command to ipc handler", name()); + conn.send_command("workspace prev_on_output"); + } else { + m_log.warn("%s: Ignoring workspace prev command (reason: `wrapping-scroll = false`)", name()); + } } else { return false; } diff --git a/src/utils/i3.cpp b/src/utils/i3.cpp index bd2190e6..70a4bd71 100644 --- a/src/utils/i3.cpp +++ b/src/utils/i3.cpp @@ -12,6 +12,18 @@ POLYBAR_NS namespace i3_util { + /** + * Get currently focused workspace + */ + shared_ptr focused_workspace(const connection_t& conn) { + for (auto&& ws : conn.get_workspaces()) { + if (ws->focused) { + return ws; + } + } + return nullptr; + } + /** * Get all i3 root windows */