From 0ed173b96eadae0e7d64329d93ee8cad78843755 Mon Sep 17 00:00:00 2001 From: Michael Carlberg Date: Wed, 14 Dec 2016 04:42:21 +0100 Subject: [PATCH] refactor(i3): Output based wrapping --- include/utils/i3.hpp | 12 +++++++++++ src/modules/i3.cpp | 48 +++++++++++++++++--------------------------- src/utils/i3.cpp | 13 ++++++++++++ 3 files changed, 43 insertions(+), 30 deletions(-) diff --git a/include/utils/i3.hpp b/include/utils/i3.hpp index a5aa1cd2..49a85396 100644 --- a/include/utils/i3.hpp +++ b/include/utils/i3.hpp @@ -13,10 +13,22 @@ namespace i3_util { using connection_t = i3ipc::connection; using workspace_t = i3ipc::workspace_t; + const auto ws_numsort = [](shared_ptr a, shared_ptr b) { return a->num < b->num; }; + + vector> workspaces(const connection_t& conn, const string& output = ""); 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); } +namespace { + inline bool operator==(i3_util::workspace_t& a, i3_util::workspace_t& b) { + return a.num == b.num && a.output == b.output; + } + inline bool operator!=(i3_util::workspace_t& a, i3_util::workspace_t& b) { + return !(a == b); + } +} + POLYBAR_NS_END diff --git a/src/modules/i3.cpp b/src/modules/i3.cpp index de5c2c5c..4828ae09 100644 --- a/src/modules/i3.cpp +++ b/src/modules/i3.cpp @@ -107,55 +107,44 @@ namespace modules { i3_util::connection_t ipc; try { - auto workspaces = ipc.get_workspaces(); - vector> sorted = workspaces; - string focused_output; + vector> workspaces; - for (auto&& ws : workspaces) { - if (ws->focused) { - focused_output = ws->output; - break; - } + if (m_pinworkspaces) { + workspaces = i3_util::workspaces(ipc, m_bar.monitor->name); + } else { + workspaces = i3_util::workspaces(ipc); } if (m_indexsort) { - using ws_t = shared_ptr; - // clang-format off - sort(sorted.begin(), sorted.end(), [](ws_t ws1, ws_t ws2){ - return ws1->num < ws2->num; - }); - // clang-format on + sort(workspaces.begin(), workspaces.end(), i3_util::ws_numsort); } - for (auto&& ws : sorted) { - if (m_pinworkspaces && ws->output != m_bar.monitor->name) { - continue; - } + for (auto&& ws : workspaces) { + state ws_state{state::NONE}; - auto ws_state = state::NONE; if (ws->focused) { ws_state = state::FOCUSED; } else if (ws->urgent) { ws_state = state::URGENT; - } else if (!ws->visible || (ws->visible && ws->output != focused_output)) { + } else if (!ws->visible || (ws->visible && ws->output != m_bar.monitor->name)) { ws_state = state::UNFOCUSED; } else { ws_state = state::VISIBLE; } - string wsname{ws->name}; + string ws_name{ws->name}; // Remove workspace numbers "0:" if (m_strip_wsnumbers) { - wsname.erase(0, string_util::find_nth(wsname, 0, ":", 1) + 1); + ws_name.erase(0, string_util::find_nth(ws_name, 0, ":", 1) + 1); } // Trim leading and trailing whitespace - wsname = string_util::trim(wsname, ' '); + ws_name = string_util::trim(ws_name, ' '); // Cap at configured max length - if (m_wsname_maxlen > 0 && wsname.length() > m_wsname_maxlen) { - wsname.erase(m_wsname_maxlen); + if (m_wsname_maxlen > 0 && ws_name.length() > m_wsname_maxlen) { + ws_name.erase(m_wsname_maxlen); } auto icon = m_icons->get(ws->name, DEFAULT_WS_ICON); @@ -163,7 +152,7 @@ namespace modules { label->reset_tokens(); label->replace_token("%output%", ws->output); - label->replace_token("%name%", wsname); + label->replace_token("%name%", ws_name); label->replace_token("%icon%", icon->get()); label->replace_token("%index%", to_string(ws->num)); m_workspaces.emplace_back(make_unique(ws->num, ws_state, move(label))); @@ -208,7 +197,6 @@ namespace modules { bool i3_module::handle_event(string cmd) { try { - if (cmd.compare(0, strlen(EVENT_CLICK), EVENT_CLICK) == 0) { const i3_util::connection_t conn{}; const string workspace_num{cmd.substr(strlen(EVENT_CLICK))}; @@ -222,16 +210,16 @@ namespace modules { } else if (cmd.compare(0, strlen(EVENT_SCROLL_DOWN), EVENT_SCROLL_DOWN) == 0) { const i3_util::connection_t conn{}; - if (m_wrap || conn.get_workspaces().back()->num != i3_util::focused_workspace(conn)->num) { + if (m_wrap || *i3_util::workspaces(conn, m_bar.monitor->name).back() != *i3_util::focused_workspace(conn)) { 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()); + m_log.warn("%s: Ignoring workspace next command (reason: `wrapping-scroll = false`)", name()); } } else if (cmd.compare(0, strlen(EVENT_SCROLL_UP), EVENT_SCROLL_UP) == 0) { const i3_util::connection_t conn{}; - if (m_wrap || conn.get_workspaces().front()->num != i3_util::focused_workspace(conn)->num) { + if (m_wrap || *i3_util::workspaces(conn, m_bar.monitor->name).front() != *i3_util::focused_workspace(conn)) { m_log.info("%s: Sending workspace prev command to ipc handler", name()); conn.send_command("workspace prev_on_output"); } else { diff --git a/src/utils/i3.cpp b/src/utils/i3.cpp index 70a4bd71..b76ca3c0 100644 --- a/src/utils/i3.cpp +++ b/src/utils/i3.cpp @@ -12,6 +12,19 @@ POLYBAR_NS namespace i3_util { + /** + * Get all workspaces for given output + */ + vector> workspaces(const connection_t& conn, const string& output) { + vector> result; + for (auto&& ws : conn.get_workspaces()) { + if (output.empty() || ws->output == output) { + result.emplace_back(forward(ws)); + } + } + return result; + } + /** * Get currently focused workspace */