diff --git a/include/i3ipc++/ipc.hpp b/include/i3ipc++/ipc.hpp index 72d4e99..85c6443 100644 --- a/include/i3ipc++/ipc.hpp +++ b/include/i3ipc++/ipc.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include @@ -141,6 +142,26 @@ enum class InputType : char { }; +/** + * A mode of a bar + */ +enum class BarMode : char { + UNKNOWN = '?', + DOCK = 'd', ///< The bar sets the dock window type + HIDE = 'h', ///< The bar does not show unless a specific key is pressed +}; + + +/** + * A position (of a bar?) + */ +enum class Position : char { + UNKNOWN = '?', + TOP = 't', + BOTTOM = 'b', +}; + + /** * A node of tree of windows */ @@ -197,6 +218,22 @@ struct binding_t { }; +/** + * A bar configuration + */ +struct bar_config_t { + std::string id; ///< The ID for this bar. Included in case you request multiple configurations and want to differentiate the different replies. + BarMode mode; + Position position; + std::string status_command; ///< Command which will be run to generate a statusline. Each line on stdout of this command will be displayed in the bar. At the moment, no formatting is supported + std::string font; ///< The font to use for text on the bar + bool workspace_buttons; ///< Display workspace buttons or not? Defaults to true. + bool binding_mode_indicator; ///< Display the mode indicator or not? Defaults to true. + bool verbose; ///< Should the bar enable verbose output for debugging? Defaults to false. + std::map colors; ///< Contains key/value pairs of colors. Each value is a color code in format 0xRRGGBB +}; + + struct buf_t; /** * Connection to the i3 @@ -241,6 +278,19 @@ public: */ std::shared_ptr get_tree() const; + /** + * Request a list of names of available barconfigs + * @return A list of names of barconfigs + */ + std::vector get_bar_configs_list() const; + + /** + * Request a barconfig + * @param name name of barconfig + * @return The barconfig + */ + std::shared_ptr get_bar_config(const std::string& name) const; + /** * Subscribe on an events of i3 * @@ -280,7 +330,7 @@ public: sigc::signal signal_output_event; ///< Output event signal sigc::signal signal_mode_event; ///< Output mode event signal sigc::signal signal_window_event; ///< Window event signal - sigc::signal signal_barconfig_update_event; ///< Barconfig update event signal + sigc::signal signal_barconfig_update_event; ///< Barconfig update event signal sigc::signal signal_binding_event; ///< Binding event signal sigc::signal&> signal_event; ///< i3 event signal @note Default handler routes event to signal according to type protected: diff --git a/src/ipc.cpp b/src/ipc.cpp index eb4f671..171f147 100644 --- a/src/ipc.cpp +++ b/src/ipc.cpp @@ -189,6 +189,52 @@ static std::shared_ptr parse_binding_from_json(const Json::Value& v } +static std::shared_ptr parse_bar_config_from_json(const Json::Value& value) { +#define i3IPC_TYPE_STR "PARSE BAR CONFIG FROM JSON" + if (value.isNull()) + return std::shared_ptr(); + IPC_JSON_ASSERT_TYPE_OBJECT(value, "(root)") + std::shared_ptr bc (new bar_config_t()); + + bc->id = value["id"].asString(); + bc->status_command = value["status_command"].asString(); + bc->font = value["font"].asString(); + bc->workspace_buttons = value["workspace_buttons"].asBool(); + bc->binding_mode_indicator = value["binding_mode_indicator"].asBool(); + bc->verbose = value["verbose"].asBool(); + + std::string mode = value["mode"].asString(); + if (mode == "dock") { + bc->mode = BarMode::DOCK; + } else if (mode == "hide") { + bc->mode = BarMode::HIDE; + } else { + bc->mode = BarMode::UNKNOWN; + I3IPC_WARN("Got a unknown \"mode\" property: \"" << mode << "\". Perhaps its neccessary to update i3ipc++. If you are using latest, note maintainer about this") + } + + std::string position = value["position"].asString(); + if (position == "top") { + bc->position = Position::TOP; + } else if (mode == "bottom") { + bc->position = Position::BOTTOM; + } else { + bc->position = Position::UNKNOWN; + I3IPC_WARN("Got a unknown \"position\" property: \"" << position << "\". Perhaps its neccessary to update i3ipc++. If you are using latest, note maintainer about this") + } + + Json::Value colors = value["colors"]; + IPC_JSON_ASSERT_TYPE_OBJECT(value, "colors") + auto colors_list = colors.getMemberNames(); + for (auto& m : colors_list) { + bc->colors[m] = std::stoul(colors[m].asString().substr(1), nullptr, 16); + } + + return bc; +#undef i3IPC_TYPE_STR +} + + std::string get_socketpath() { std::string str; { @@ -288,10 +334,14 @@ connection::connection(const std::string& socket_path) : m_main_socket(i3_conne signal_window_event.emit(ev); break; } - case ET_BARCONFIG_UPDATE: + case ET_BARCONFIG_UPDATE: { I3IPC_DEBUG("BARCONFIG_UPDATE") - signal_barconfig_update_event.emit(); + Json::Value root; + IPC_JSON_READ(root); + std::shared_ptr barconf = parse_bar_config_from_json(root); + signal_barconfig_update_event.emit(*barconf); break; + } case ET_BINDING: { Json::Value root; IPC_JSON_READ(root); @@ -450,6 +500,34 @@ std::vector< std::shared_ptr > connection::get_workspaces() const } +std::vector connection::get_bar_configs_list() const { +#define i3IPC_TYPE_STR "GET_BAR_CONFIG (get_bar_configs_list)" + auto buf = i3_msg(m_main_socket, ClientMessageType::GET_BAR_CONFIG); + Json::Value root; + IPC_JSON_READ(root) + IPC_JSON_ASSERT_TYPE_ARRAY(root, "root") + + std::vector l; + + for (auto w : root) { + l.push_back(w.asString()); + } + + return l; +#undef i3IPC_TYPE_STR +} + + +std::shared_ptr connection::get_bar_config(const std::string& name) const { +#define i3IPC_TYPE_STR "GET_BAR_CONFIG" + auto buf = i3_msg(m_main_socket, ClientMessageType::GET_BAR_CONFIG, name); + Json::Value root; + IPC_JSON_READ(root) + return parse_bar_config_from_json(root); +#undef i3IPC_TYPE_STR +} + + bool connection::send_command(const std::string& command) const { #define i3IPC_TYPE_STR "COMMAND" auto buf = i3_msg(m_main_socket, ClientMessageType::COMMAND, command);