Skip to content

Commit 456c27b

Browse files
committed
Implementation of GET_TREE
1 parent 5c269f5 commit 456c27b

File tree

2 files changed

+131
-0
lines changed

2 files changed

+131
-0
lines changed

include/i3ipc++/ipc.hpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ struct version_t {
6767
uint32_t patch; /**< Patch number of i3 */
6868
};
6969

70+
7071
/**
7172
* Types of the events of i3
7273
*/
@@ -102,6 +103,56 @@ enum class WindowEventType : char {
102103
URGENT = 'u', /**< Window became urgent */
103104
};
104105

106+
107+
/**
108+
* A style of a container's border
109+
*/
110+
enum class BorderStyle : char {
111+
UNKNOWN = '?', //< If got an unknown border style in reply
112+
NONE = 'N',
113+
NORMAL = 'n',
114+
ONE_PIXEL = '1',
115+
};
116+
117+
118+
/**
119+
* A type of a container's layout
120+
*/
121+
enum class ContainerLayout : char {
122+
UNKNOWN = '?', //< If got an unknown border style in reply
123+
SPLIT_H = 'h',
124+
SPLIT_V = 'v',
125+
STACKED = 's',
126+
TABBED = 't',
127+
DOCKAREA = 'd',
128+
OUTPUT = 'o',
129+
};
130+
131+
132+
/**
133+
* A node of tree of windows
134+
*/
135+
struct container_t {
136+
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
137+
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)
138+
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)
139+
std::string type; ///< Type of this container
140+
BorderStyle border; ///< A style of the container's border
141+
std::string border_raw; ///< A "border" field of TREE reply. NOT empty only if border equals BorderStyle::UNKNOWN
142+
uint32_t current_border_width; ///< Number of pixels of the border width
143+
ContainerLayout layout; ///< A type of the container's layout
144+
std::string layout_raw; ///< A "layout" field of TREE reply. NOT empty only if layout equals ContainerLayout::UNKNOWN
145+
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.
146+
rect_t rect; ///< The absolute display coordinates for this container
147+
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)
148+
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
149+
rect_t geometry; ///< The original geometry the window specified when i3 mapped it. Used when switching a window to floating mode, for example
150+
bool urgent;
151+
bool focused;
152+
153+
std::list< std::shared_ptr<container_t> > nodes;
154+
};
155+
105156
struct buf_t;
106157
/**
107158
* Connection to the i3
@@ -140,6 +191,12 @@ class I3Connection {
140191
*/
141192
version_t get_version() const;
142193

194+
/**
195+
* Request a tree of windows
196+
* @return A root container
197+
*/
198+
std::shared_ptr<container_t> get_tree() const;
199+
143200
/**
144201
* Subscribe on an events of i3
145202
*

src/ipc.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,80 @@ version_t I3Connection::get_version() const {
224224
}
225225

226226

227+
static std::shared_ptr<container_t> parse_container_from_json(const Json::Value& o) {
228+
#define i3IPC_TYPE_STR "GET_TREE"
229+
std::shared_ptr<container_t> container (new container_t());
230+
IPC_JSON_ASSERT_TYPE_OBJECT(o, "o")
231+
232+
container->id = o["id"].asUInt64();
233+
container->xwindow_id= o["window"].asUInt64();
234+
container->name = o["name"].asString();
235+
container->type = o["type"].asString();
236+
container->current_border_width = o["current_border_width"].asInt();
237+
container->percent = o["percent"].asFloat();
238+
container->rect = parse_rect_from_json(o["rect"]);
239+
container->window_rect = parse_rect_from_json(o["window_rect"]);
240+
container->deco_rect = parse_rect_from_json(o["deco_rect"]);
241+
container->geometry = parse_rect_from_json(o["geometry"]);
242+
container->urgent = o["urgent"].asBool();
243+
container->focused = o["focused"].asBool();
244+
245+
container->border = BorderStyle::UNKNOWN;
246+
std::string border = o["border"].asString();
247+
if (border == "normal") {
248+
container->border = BorderStyle::NORMAL;
249+
} else if (border == "none") {
250+
container->border = BorderStyle::NONE;
251+
} else if (border == "1pixel") {
252+
container->border = BorderStyle::ONE_PIXEL;
253+
} else {
254+
container->border_raw = border;
255+
I3IPC_WARN("Got a unknown \"border\" property: \"" << border << "\". Perhaps its neccessary to update i3ipc++. If you are using latest, note maintainer about this")
256+
}
257+
258+
container->layout = ContainerLayout::UNKNOWN;
259+
std::string layout = o["layout"].asString();
260+
261+
if (layout == "splith") {
262+
container->layout = ContainerLayout::SPLIT_H;
263+
} else if (layout == "splitv") {
264+
container->layout = ContainerLayout::SPLIT_V;
265+
} else if (layout == "stacked") {
266+
container->layout = ContainerLayout::STACKED;
267+
} else if (layout == "tabbed") {
268+
container->layout = ContainerLayout::TABBED;
269+
} else if (layout == "dockarea") {
270+
container->layout = ContainerLayout::DOCKAREA;
271+
} else if (layout == "output") {
272+
container->layout = ContainerLayout::OUTPUT;
273+
} else {
274+
container->layout_raw = border;
275+
I3IPC_WARN("Got a unknown \"layout\" property: \"" << layout << "\". Perhaps its neccessary to update i3ipc++. If you are using latest, note maintainer about this")
276+
}
277+
278+
Json::Value nodes = o["nodes"];
279+
if (!nodes.isNull()) {
280+
IPC_JSON_ASSERT_TYPE_ARRAY(nodes, "nodes")
281+
for (Json::ArrayIndex i = 0; i < nodes.size(); i++) {
282+
container->nodes.push_back(parse_container_from_json(nodes[i]));
283+
}
284+
}
285+
286+
return container;
287+
#undef i3IPC_TYPE_STR
288+
}
289+
290+
291+
std::shared_ptr<container_t> I3Connection::get_tree() const {
292+
#define i3IPC_TYPE_STR "GET_TREE"
293+
auto buf = i3_msg(m_main_socket, ClientMessageType::GET_TREE);
294+
Json::Value root;
295+
IPC_JSON_READ(root);
296+
return parse_container_from_json(root);
297+
#undef i3IPC_TYPE_STR
298+
}
299+
300+
227301
std::vector<output_t> I3Connection::get_outputs() const {
228302
#define i3IPC_TYPE_STR "GET_OUTPUTS"
229303
auto buf = i3_msg(m_main_socket, ClientMessageType::GET_OUTPUTS);

0 commit comments

Comments
 (0)