diff --git a/include/modules/xkeyboard.hpp b/include/modules/xkeyboard.hpp index ca7b8368..73187479 100644 --- a/include/modules/xkeyboard.hpp +++ b/include/modules/xkeyboard.hpp @@ -42,7 +42,9 @@ namespace modules { static constexpr const char* TAG_LABEL_LAYOUT{""}; static constexpr const char* TAG_LABEL_INDICATOR{""}; static constexpr const char* FORMAT_DEFAULT{" "}; - + static constexpr const char* DEFAULT_LAYOUT_ICON{"layout-icon-default"}; + static constexpr const char* DEFAULT_INDICATOR_ICON{"indicator-icon-default"}; + static constexpr const char* EVENT_SWITCH{"xkeyboard/switch"}; connection& m_connection; @@ -52,10 +54,16 @@ namespace modules { unique_ptr m_keyboard; label_t m_layout; - label_t m_indicator; + label_t m_indicator_state_on; + label_t m_indicator_state_off; map m_indicators; + map m_indicator_on_labels; + map m_indicator_off_labels; vector m_blacklist; + iconset_t m_layout_icons; + iconset_t m_indicator_icons_on; + iconset_t m_indicator_icons_off; }; } diff --git a/include/x11/extensions/xkb.hpp b/include/x11/extensions/xkb.hpp index 7ffcf42e..06f7f1ff 100644 --- a/include/x11/extensions/xkb.hpp +++ b/include/x11/extensions/xkb.hpp @@ -49,7 +49,7 @@ namespace evt { class keyboard { public: struct indicator { - enum class type { NONE = 0U, CAPS_LOCK, NUM_LOCK }; + enum class type { NONE = 0U, CAPS_LOCK, NUM_LOCK, SCROLL_LOCK }; xcb_atom_t atom{}; unsigned char mask{0}; string name{}; diff --git a/src/modules/xkeyboard.cpp b/src/modules/xkeyboard.cpp index fe0dd2d1..602ac447 100644 --- a/src/modules/xkeyboard.cpp +++ b/src/modules/xkeyboard.cpp @@ -12,13 +12,48 @@ POLYBAR_NS namespace modules { template class module; + // clang-format off + static const keyboard::indicator::type INDICATOR_TYPES[] { + keyboard::indicator::type::CAPS_LOCK, + keyboard::indicator::type::NUM_LOCK, + keyboard::indicator::type::SCROLL_LOCK + }; + // clang-format on + /** * Construct module */ xkeyboard_module::xkeyboard_module(const bar_settings& bar, string name_) : static_module(bar, move(name_)), m_connection(connection::make()) { + + + // Setup extension + // clang-format off + m_connection.xkb().select_events_checked(XCB_XKB_ID_USE_CORE_KBD, + XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY | + XCB_XKB_EVENT_TYPE_STATE_NOTIFY | + XCB_XKB_EVENT_TYPE_INDICATOR_STATE_NOTIFY, 0, + XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY | + XCB_XKB_EVENT_TYPE_STATE_NOTIFY | + XCB_XKB_EVENT_TYPE_INDICATOR_STATE_NOTIFY, 0, 0, nullptr); + // clang-format on + + // Create keyboard object + query_keyboard(); + // Load config values m_blacklist = m_conf.get_list(name(), "blacklist", {}); + + // load layout icons + m_layout_icons = factory_util::shared(); + m_layout_icons->add(DEFAULT_LAYOUT_ICON, load_optional_label(m_conf, name(), DEFAULT_LAYOUT_ICON, ""s)); + + for (const auto& it : m_conf.get_list(name(), "layout-icon", {})) { + auto vec = string_util::split(it, ';'); + if (vec.size() == 2) { + m_layout_icons->add(vec[0], factory_util::shared