Implementation of GET_TREE

This commit is contained in:
Sergey Naumov
2016-04-20 21:01:20 +03:00
parent 5c269f5532
commit 456c27b114
2 changed files with 131 additions and 0 deletions

View File

@@ -67,6 +67,7 @@ struct version_t {
uint32_t patch; /**< Patch number of i3 */
};
/**
* Types of the events of i3
*/
@@ -102,6 +103,56 @@ enum class WindowEventType : char {
URGENT = 'u', /**< Window became urgent */
};
/**
* A style of a container's border
*/
enum class BorderStyle : char {
UNKNOWN = '?', //< If got an unknown border style in reply
NONE = 'N',
NORMAL = 'n',
ONE_PIXEL = '1',
};
/**
* A type of a container's layout
*/
enum class ContainerLayout : char {
UNKNOWN = '?', //< If got an unknown border style in reply
SPLIT_H = 'h',
SPLIT_V = 'v',
STACKED = 's',
TABBED = 't',
DOCKAREA = 'd',
OUTPUT = 'o',
};
/**
* A node of tree of windows
*/
struct container_t {
uint64_t id; ///< The internal ID (actually a C pointer value) of this container. Do not make any assumptions about it. You can use it to (re-)identify and address containers when talking to i3
uint64_t xwindow_id; ///< The X11 window ID of the actual client window inside this container. This field is set to null for split containers or otherwise empty containers. This ID corresponds to what xwininfo(1) and other X11-related tools display (usually in hex)
std::string name; ///< The internal name of this container. For all containers which are part of the tree structure down to the workspace contents, this is set to a nice human-readable name of the container. For containers that have an X11 window, the content is the title (_NET_WM_NAME property) of that window. For all other containers, the content is not defined (yet)
std::string type; ///< Type of this container
BorderStyle border; ///< A style of the container's border
std::string border_raw; ///< A "border" field of TREE reply. NOT empty only if border equals BorderStyle::UNKNOWN
uint32_t current_border_width; ///< Number of pixels of the border width
ContainerLayout layout; ///< A type of the container's layout
std::string layout_raw; ///< A "layout" field of TREE reply. NOT empty only if layout equals ContainerLayout::UNKNOWN
float percent; ///< The percentage which this container takes in its parent. A value of < 0 means that the percent property does not make sense for this container, for example for the root container.
rect_t rect; ///< The absolute display coordinates for this container
rect_t window_rect; ///< The coordinates of the actual client window inside its container. These coordinates are relative to the container and do not include the window decoration (which is actually rendered on the parent container)
rect_t deco_rect; ///< The coordinates of the window decoration inside its container. These coordinates are relative to the container and do not include the actual client window
rect_t geometry; ///< The original geometry the window specified when i3 mapped it. Used when switching a window to floating mode, for example
bool urgent;
bool focused;
std::list< std::shared_ptr<container_t> > nodes;
};
struct buf_t;
/**
* Connection to the i3
@@ -140,6 +191,12 @@ public:
*/
version_t get_version() const;
/**
* Request a tree of windows
* @return A root container
*/
std::shared_ptr<container_t> get_tree() const;
/**
* Subscribe on an events of i3
*

View File

@@ -224,6 +224,80 @@ version_t I3Connection::get_version() const {
}
static std::shared_ptr<container_t> parse_container_from_json(const Json::Value& o) {
#define i3IPC_TYPE_STR "GET_TREE"
std::shared_ptr<container_t> container (new container_t());
IPC_JSON_ASSERT_TYPE_OBJECT(o, "o")
container->id = o["id"].asUInt64();
container->xwindow_id= o["window"].asUInt64();
container->name = o["name"].asString();
container->type = o["type"].asString();
container->current_border_width = o["current_border_width"].asInt();
container->percent = o["percent"].asFloat();
container->rect = parse_rect_from_json(o["rect"]);
container->window_rect = parse_rect_from_json(o["window_rect"]);
container->deco_rect = parse_rect_from_json(o["deco_rect"]);
container->geometry = parse_rect_from_json(o["geometry"]);
container->urgent = o["urgent"].asBool();
container->focused = o["focused"].asBool();
container->border = BorderStyle::UNKNOWN;
std::string border = o["border"].asString();
if (border == "normal") {
container->border = BorderStyle::NORMAL;
} else if (border == "none") {
container->border = BorderStyle::NONE;
} else if (border == "1pixel") {
container->border = BorderStyle::ONE_PIXEL;
} else {
container->border_raw = border;
I3IPC_WARN("Got a unknown \"border\" property: \"" << border << "\". Perhaps its neccessary to update i3ipc++. If you are using latest, note maintainer about this")
}
container->layout = ContainerLayout::UNKNOWN;
std::string layout = o["layout"].asString();
if (layout == "splith") {
container->layout = ContainerLayout::SPLIT_H;
} else if (layout == "splitv") {
container->layout = ContainerLayout::SPLIT_V;
} else if (layout == "stacked") {
container->layout = ContainerLayout::STACKED;
} else if (layout == "tabbed") {
container->layout = ContainerLayout::TABBED;
} else if (layout == "dockarea") {
container->layout = ContainerLayout::DOCKAREA;
} else if (layout == "output") {
container->layout = ContainerLayout::OUTPUT;
} else {
container->layout_raw = border;
I3IPC_WARN("Got a unknown \"layout\" property: \"" << layout << "\". Perhaps its neccessary to update i3ipc++. If you are using latest, note maintainer about this")
}
Json::Value nodes = o["nodes"];
if (!nodes.isNull()) {
IPC_JSON_ASSERT_TYPE_ARRAY(nodes, "nodes")
for (Json::ArrayIndex i = 0; i < nodes.size(); i++) {
container->nodes.push_back(parse_container_from_json(nodes[i]));
}
}
return container;
#undef i3IPC_TYPE_STR
}
std::shared_ptr<container_t> I3Connection::get_tree() const {
#define i3IPC_TYPE_STR "GET_TREE"
auto buf = i3_msg(m_main_socket, ClientMessageType::GET_TREE);
Json::Value root;
IPC_JSON_READ(root);
return parse_container_from_json(root);
#undef i3IPC_TYPE_STR
}
std::vector<output_t> I3Connection::get_outputs() const {
#define i3IPC_TYPE_STR "GET_OUTPUTS"
auto buf = i3_msg(m_main_socket, ClientMessageType::GET_OUTPUTS);