summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Zandr Martin <zandrmartin@gmail.com>2016-07-04 13:34:44 -0500
committerLibravatar Zandr Martin <zandrmartin@gmail.com>2016-07-04 13:34:44 -0500
commit15a324b0d3c0d15405286794d2c8b88b764835cf (patch)
treeb2c2cf4c7e7d509b515fd6b93aa34f959fb666e1
parentSpawn windows as floating if they have a parent (diff)
downloadsway-15a324b0d3c0d15405286794d2c8b88b764835cf.tar.gz
sway-15a324b0d3c0d15405286794d2c8b88b764835cf.tar.zst
sway-15a324b0d3c0d15405286794d2c8b88b764835cf.zip
implement `get_tree` command
-rw-r--r--include/ipc-json.h13
-rw-r--r--sway/CMakeLists.txt1
-rw-r--r--sway/container.c28
-rw-r--r--sway/ipc-json.c326
-rw-r--r--sway/ipc-server.c168
-rw-r--r--sway/layout.c1
6 files changed, 385 insertions, 152 deletions
diff --git a/include/ipc-json.h b/include/ipc-json.h
new file mode 100644
index 00000000..f90d801e
--- /dev/null
+++ b/include/ipc-json.h
@@ -0,0 +1,13 @@
1#ifndef _SWAY_IPC_JSON_H
2#define _SWAY_IPC_JSON_H
3
4#include <json-c/json.h>
5#include "config.h"
6#include "container.h"
7
8json_object *ipc_json_get_version();
9json_object *ipc_json_describe_bar_config(struct bar_config *bar);
10json_object *ipc_json_describe_container(swayc_t *c);
11json_object *ipc_json_describe_container_recursive(swayc_t *c);
12
13#endif
diff --git a/sway/CMakeLists.txt b/sway/CMakeLists.txt
index 73df3b1b..be63c944 100644
--- a/sway/CMakeLists.txt
+++ b/sway/CMakeLists.txt
@@ -21,6 +21,7 @@ add_executable(sway
21 handlers.c 21 handlers.c
22 input.c 22 input.c
23 input_state.c 23 input_state.c
24 ipc-json.c
24 ipc-server.c 25 ipc-server.c
25 layout.c 26 layout.c
26 main.c 27 main.c
diff --git a/sway/container.c b/sway/container.c
index 21538ab4..a7e46571 100644
--- a/sway/container.c
+++ b/sway/container.c
@@ -75,6 +75,30 @@ static void free_swayc(swayc_t *cont) {
75 free(cont); 75 free(cont);
76} 76}
77 77
78static void update_root_geometry() {
79 int width = 0;
80 int height = 0;
81 swayc_t *child;
82 int child_width;
83 int child_height;
84
85 for (int i = 0; i < root_container.children->length; ++i) {
86 child = root_container.children->items[i];
87 child_width = child->width + child->x;
88 child_height = child->height + child->y;
89 if (child_width > width) {
90 width = child_width;
91 }
92
93 if (child_height > height) {
94 height = child_height;
95 }
96 }
97
98 root_container.width = width;
99 root_container.height = height;
100}
101
78// New containers 102// New containers
79 103
80swayc_t *new_output(wlc_handle handle) { 104swayc_t *new_output(wlc_handle handle) {
@@ -167,6 +191,7 @@ swayc_t *new_output(wlc_handle handle) {
167 } 191 }
168 192
169 free(ws_name); 193 free(ws_name);
194 update_root_geometry();
170 return output; 195 return output;
171} 196}
172 197
@@ -361,7 +386,7 @@ void floating_view_sane_size(swayc_t *view) {
361 view->desired_width = config->floating_maximum_width; 386 view->desired_width = config->floating_maximum_width;
362 } 387 }
363 388
364 sway_log(L_DEBUG, "Sane values for view to %d x %d @ %.f, %.f", 389 sway_log(L_DEBUG, "Sane values for view to %d x %d @ %.f, %.f",
365 view->desired_width, view->desired_height, view->x, view->y); 390 view->desired_width, view->desired_height, view->x, view->y);
366 391
367 return; 392 return;
@@ -393,6 +418,7 @@ swayc_t *destroy_output(swayc_t *output) {
393 } 418 }
394 sway_log(L_DEBUG, "OUTPUT: Destroying output '%" PRIuPTR "'", output->handle); 419 sway_log(L_DEBUG, "OUTPUT: Destroying output '%" PRIuPTR "'", output->handle);
395 free_swayc(output); 420 free_swayc(output);
421 update_root_geometry();
396 return &root_container; 422 return &root_container;
397} 423}
398 424
diff --git a/sway/ipc-json.c b/sway/ipc-json.c
new file mode 100644
index 00000000..46caad9c
--- /dev/null
+++ b/sway/ipc-json.c
@@ -0,0 +1,326 @@
1#include <json-c/json.h>
2#include <ctype.h>
3#include <string.h>
4#include "container.h"
5#include "util.h"
6#include "ipc-json.h"
7
8static json_object *ipc_json_create_rect(swayc_t *c) {
9 json_object *rect = json_object_new_object();
10
11 json_object_object_add(rect, "x", json_object_new_int((int32_t)c->x));
12 json_object_object_add(rect, "y", json_object_new_int((int32_t)c->y));
13 json_object_object_add(rect, "width", json_object_new_int((int32_t)c->width));
14 json_object_object_add(rect, "height", json_object_new_int((int32_t)c->height));
15
16 return rect;
17}
18
19static const char *ipc_json_border_description(swayc_t *c) {
20 const char *border;
21
22 switch (c->border_type) {
23 case B_PIXEL:
24 border = "1pixel";
25 break;
26
27 case B_NORMAL:
28 border = "normal";
29 break;
30
31 case B_NONE: // fallthrough
32 default:
33 border = "none";
34 break;
35 }
36
37 return border;
38}
39
40static const char *ipc_json_layout_description(swayc_t *c) {
41 const char *layout;
42
43 switch (c->layout) {
44 case L_VERT:
45 layout = "splitv";
46 break;
47
48 case L_HORIZ:
49 layout = "splith";
50 break;
51
52 case L_TABBED:
53 layout = "tabbed";
54 break;
55
56 case L_STACKED:
57 layout = "stacked";
58 break;
59
60 case L_FLOATING:
61 layout = "floating";
62 break;
63
64 case L_NONE: // fallthrough
65 case L_LAYOUTS: // fallthrough; this should never happen, I'm just trying to silence compiler warnings
66 default:
67 layout = "null";
68 break;
69 }
70
71 return layout;
72}
73
74static float ipc_json_child_percentage(swayc_t *c) {
75 float percent = 0;
76 swayc_t *parent = c->parent;
77
78 if (parent) {
79 switch (parent->layout) {
80 case L_VERT:
81 percent = c->height / parent->height;
82 break;
83
84 case L_HORIZ:
85 percent = c->width / parent->width;
86 break;
87
88 case L_STACKED: // fallthrough
89 case L_TABBED: // fallthrough
90 percent = 1.0;
91 break;
92
93 default:
94 break;
95 }
96 }
97
98 return percent;
99}
100
101static void ipc_json_describe_output(swayc_t *output, json_object *object) {
102 json_object_object_add(object, "active", json_object_new_boolean(true));
103 json_object_object_add(object, "primary", json_object_new_boolean(false));
104 json_object_object_add(object, "layout", json_object_new_string("output"));
105 json_object_object_add(object, "type", json_object_new_string("output"));
106 json_object_object_add(object, "current_workspace",
107 (output->focused) ? json_object_new_string(output->focused->name) : NULL);
108}
109
110static void ipc_json_describe_workspace(swayc_t *workspace, json_object *object) {
111 int num = (isdigit(workspace->name[0])) ? atoi(workspace->name) : -1;
112 bool focused = root_container.focused == workspace->parent && workspace->parent->focused == workspace;
113
114 json_object_object_add(object, "num", json_object_new_int(num));
115 json_object_object_add(object, "visible", json_object_new_boolean(workspace->visible));
116 json_object_object_add(object, "focused", json_object_new_boolean(focused));
117 json_object_object_add(object, "output", json_object_new_string((workspace->parent) ? workspace->parent->name : "null"));
118 json_object_object_add(object, "urgent", json_object_new_boolean(false));
119 json_object_object_add(object, "type", json_object_new_string("workspace"));
120 json_object_object_add(object, "layout", json_object_new_string(ipc_json_layout_description(workspace)));
121}
122
123static void ipc_json_describe_view(swayc_t *view, json_object *object) {
124 float percent = ipc_json_child_percentage(view);
125
126 json_object_object_add(object, "border", json_object_new_string(ipc_json_border_description(view)));
127 json_object_object_add(object, "current_border_width", json_object_new_int(view->border_thickness));
128 json_object_object_add(object, "percent", (percent > 0) ? json_object_new_double(percent) : json_object_new_string("null"));
129 // TODO: make urgency actually work once Sway supports it
130 json_object_object_add(object, "urgent", json_object_new_boolean(false));
131 json_object_object_add(object, "focused", json_object_new_boolean(view->is_focused));
132 json_object_object_add(object, "type", json_object_new_string((view->is_floating) ? "floating_con" : "con"));
133 json_object_object_add(object, "layout", json_object_new_string(ipc_json_layout_description(view)));
134
135 if (view->class) {
136 json_object_object_add(object, "class", json_object_new_string(view->class));
137 }
138
139 if (view->app_id) {
140 json_object_object_add(object, "app_id", json_object_new_string(view->app_id));
141 }
142}
143
144json_object *ipc_json_describe_container(swayc_t *c) {
145 if (!(sway_assert(c, "Container must not be null."))) {
146 return NULL;
147 }
148
149 json_object *object = json_object_new_object();
150
151 json_object_object_add(object, "id", json_object_new_int((int64_t)&c));
152 json_object_object_add(object, "name", json_object_new_string(c->name));
153 json_object_object_add(object, "rect", ipc_json_create_rect(c));
154
155 switch (c->type) {
156 case C_ROOT:
157 json_object_object_add(object, "type", json_object_new_string("root"));
158 break;
159
160 case C_OUTPUT:
161 ipc_json_describe_output(c, object);
162 break;
163
164 case C_CONTAINER: // fallthrough
165 case C_VIEW:
166 ipc_json_describe_view(c, object);
167 break;
168
169 case C_WORKSPACE:
170 ipc_json_describe_workspace(c, object);
171 break;
172
173 case C_TYPES: // fallthrough; this should never happen, I'm just trying to silence compiler warnings
174 default:
175 break;
176 }
177
178 return object;
179}
180
181json_object *ipc_json_get_version() {
182 json_object *version = json_object_new_object();
183
184#if defined SWAY_GIT_VERSION && defined SWAY_GIT_BRANCH && defined SWAY_VERSION_DATE
185 char *full_version = calloc(strlen(SWAY_GIT_VERSION) + strlen(SWAY_GIT_BRANCH) + strlen(SWAY_VERSION_DATE) + 20, 1);
186 strcat(full_version, SWAY_GIT_VERSION);
187 strcat(full_version, " (");
188 strcat(full_version, SWAY_VERSION_DATE);
189 strcat(full_version, ", branch \"");
190 strcat(full_version, SWAY_GIT_BRANCH);
191 strcat(full_version, "\")");
192
193 json_object_object_add(version, "human_readable", json_object_new_string(full_version));
194 json_object_object_add(version, "variant", json_object_new_string("sway"));
195 // Todo once we actually release a version
196 json_object_object_add(version, "major", json_object_new_int(0));
197 json_object_object_add(version, "minor", json_object_new_int(0));
198 json_object_object_add(version, "patch", json_object_new_int(1));
199#else
200 json_object_object_add(version, "human_readable", json_object_new_string("version not found"));
201 json_object_object_add(version, "major", json_object_new_int(0));
202 json_object_object_add(version, "minor", json_object_new_int(0));
203 json_object_object_add(version, "patch", json_object_new_int(0));
204#endif
205
206 return version;
207}
208
209json_object *ipc_json_describe_bar_config(struct bar_config *bar) {
210 if (!sway_assert(bar, "Bar must not be NULL")) {
211 return NULL;
212 }
213
214 json_object *json = json_object_new_object();
215 json_object_object_add(json, "id", json_object_new_string(bar->id));
216 json_object_object_add(json, "tray_output", NULL);
217 json_object_object_add(json, "mode", json_object_new_string(bar->mode));
218 json_object_object_add(json, "hidden_state", json_object_new_string(bar->hidden_state));
219 json_object_object_add(json, "modifier", json_object_new_string(get_modifier_name_by_mask(bar->modifier)));
220 switch (bar->position) {
221 case DESKTOP_SHELL_PANEL_POSITION_TOP:
222 json_object_object_add(json, "position", json_object_new_string("top"));
223 break;
224 case DESKTOP_SHELL_PANEL_POSITION_BOTTOM:
225 json_object_object_add(json, "position", json_object_new_string("bottom"));
226 break;
227 case DESKTOP_SHELL_PANEL_POSITION_LEFT:
228 json_object_object_add(json, "position", json_object_new_string("left"));
229 break;
230 case DESKTOP_SHELL_PANEL_POSITION_RIGHT:
231 json_object_object_add(json, "position", json_object_new_string("right"));
232 break;
233 }
234 json_object_object_add(json, "status_command", json_object_new_string(bar->status_command));
235 json_object_object_add(json, "font", json_object_new_string((bar->font) ? bar->font : config->font));
236 if (bar->separator_symbol) {
237 json_object_object_add(json, "separator_symbol", json_object_new_string(bar->separator_symbol));
238 }
239 json_object_object_add(json, "bar_height", json_object_new_int(bar->height));
240 json_object_object_add(json, "workspace_buttons", json_object_new_boolean(bar->workspace_buttons));
241 json_object_object_add(json, "strip_workspace_numbers", json_object_new_boolean(bar->strip_workspace_numbers));
242 json_object_object_add(json, "binding_mode_indicator", json_object_new_boolean(bar->binding_mode_indicator));
243 json_object_object_add(json, "verbose", json_object_new_boolean(bar->verbose));
244 json_object_object_add(json, "pango_markup", json_object_new_boolean(bar->pango_markup));
245
246 json_object *colors = json_object_new_object();
247 json_object_object_add(colors, "background", json_object_new_string(bar->colors.background));
248 json_object_object_add(colors, "statusline", json_object_new_string(bar->colors.statusline));
249 json_object_object_add(colors, "separator", json_object_new_string(bar->colors.separator));
250
251 json_object_object_add(colors, "focused_workspace_border", json_object_new_string(bar->colors.focused_workspace_border));
252 json_object_object_add(colors, "focused_workspace_bg", json_object_new_string(bar->colors.focused_workspace_bg));
253 json_object_object_add(colors, "focused_workspace_text", json_object_new_string(bar->colors.focused_workspace_text));
254
255 json_object_object_add(colors, "inactive_workspace_border", json_object_new_string(bar->colors.inactive_workspace_border));
256 json_object_object_add(colors, "inactive_workspace_bg", json_object_new_string(bar->colors.inactive_workspace_bg));
257 json_object_object_add(colors, "inactive_workspace_text", json_object_new_string(bar->colors.inactive_workspace_text));
258
259 json_object_object_add(colors, "active_workspace_border", json_object_new_string(bar->colors.active_workspace_border));
260 json_object_object_add(colors, "active_workspace_bg", json_object_new_string(bar->colors.active_workspace_bg));
261 json_object_object_add(colors, "active_workspace_text", json_object_new_string(bar->colors.active_workspace_text));
262
263 json_object_object_add(colors, "urgent_workspace_border", json_object_new_string(bar->colors.urgent_workspace_border));
264 json_object_object_add(colors, "urgent_workspace_bg", json_object_new_string(bar->colors.urgent_workspace_bg));
265 json_object_object_add(colors, "urgent_workspace_text", json_object_new_string(bar->colors.urgent_workspace_text));
266
267 json_object_object_add(colors, "binding_mode_border", json_object_new_string(bar->colors.binding_mode_border));
268 json_object_object_add(colors, "binding_mode_bg", json_object_new_string(bar->colors.binding_mode_bg));
269 json_object_object_add(colors, "binding_mode_text", json_object_new_string(bar->colors.binding_mode_text));
270
271 json_object_object_add(json, "colors", colors);
272
273 // Add outputs if defined
274 if (bar->outputs && bar->outputs->length > 0) {
275 json_object *outputs = json_object_new_array();
276 int i;
277 for (i = 0; i < bar->outputs->length; ++i) {
278 const char *name = bar->outputs->items[i];
279 json_object_array_add(outputs, json_object_new_string(name));
280 }
281 json_object_object_add(json, "outputs", outputs);
282 }
283
284 return json;
285}
286
287json_object *ipc_json_describe_container_recursive(swayc_t *c) {
288 json_object *object = ipc_json_describe_container(c);
289 int i;
290
291 json_object *floating = json_object_new_array();
292 if (c->floating && c->floating->length > 0) {
293 for (i = 0; i < c->floating->length; ++i) {
294 json_object_array_add(floating, ipc_json_describe_container_recursive(c->floating->items[i]));
295 }
296 }
297 json_object_object_add(object, "floating_nodes", floating);
298
299 json_object *children = json_object_new_array();
300 if (c->children && c->children->length > 0) {
301 for (i = 0; i < c->children->length; ++i) {
302 json_object_array_add(children, ipc_json_describe_container_recursive(c->children->items[i]));
303 }
304 }
305 json_object_object_add(object, "nodes", children);
306
307 json_object *unmanaged = json_object_new_array();
308 if (c->unmanaged && c->unmanaged->length > 0) {
309 for (i = 0; i < c->unmanaged->length; ++i) {
310 json_object_array_add(unmanaged, ipc_json_describe_container_recursive(c->unmanaged->items[i]));
311 }
312 }
313 json_object_object_add(object, "unmanaged_nodes", unmanaged);
314
315 if (c->type == C_ROOT) {
316 json_object *scratchpad_json = json_object_new_array();
317 if (scratchpad->length > 0) {
318 for (i = 0; i < scratchpad->length; ++i) {
319 json_object_array_add(scratchpad_json, ipc_json_describe_container_recursive(scratchpad->items[i]));
320 }
321 }
322 json_object_object_add(object, "scratchpad", unmanaged);
323 }
324
325 return object;
326}
diff --git a/sway/ipc-server.c b/sway/ipc-server.c
index 484d7e51..0729bfd5 100644
--- a/sway/ipc-server.c
+++ b/sway/ipc-server.c
@@ -10,10 +10,10 @@
10#include <stdlib.h> 10#include <stdlib.h>
11#include <sys/ioctl.h> 11#include <sys/ioctl.h>
12#include <fcntl.h> 12#include <fcntl.h>
13#include <ctype.h>
14#include <json-c/json.h> 13#include <json-c/json.h>
15#include <list.h> 14#include <list.h>
16#include <libinput.h> 15#include <libinput.h>
16#include "ipc-json.h"
17#include "ipc-server.h" 17#include "ipc-server.h"
18#include "log.h" 18#include "log.h"
19#include "config.h" 19#include "config.h"
@@ -53,7 +53,6 @@ void ipc_client_handle_command(struct ipc_client *client);
53bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length); 53bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length);
54void ipc_get_workspaces_callback(swayc_t *workspace, void *data); 54void ipc_get_workspaces_callback(swayc_t *workspace, void *data);
55void ipc_get_outputs_callback(swayc_t *container, void *data); 55void ipc_get_outputs_callback(swayc_t *container, void *data);
56json_object *ipc_json_describe_bar_config(struct bar_config *bar);
57 56
58void ipc_init(void) { 57void ipc_init(void) {
59 ipc_socket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); 58 ipc_socket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
@@ -399,33 +398,21 @@ void ipc_client_handle_command(struct ipc_client *client) {
399 goto exit_cleanup; 398 goto exit_cleanup;
400 } 399 }
401 400
401 case IPC_GET_TREE:
402 {
403 json_object *tree = ipc_json_describe_container_recursive(&root_container);
404 const char *json_string = json_object_to_json_string(tree);
405 ipc_send_reply(client, json_string, (uint32_t) strlen(json_string));
406 json_object_put(tree);
407 goto exit_cleanup;
408 }
409
402 case IPC_GET_VERSION: 410 case IPC_GET_VERSION:
403 { 411 {
404#if defined SWAY_GIT_VERSION && defined SWAY_GIT_BRANCH && defined SWAY_VERSION_DATE 412 json_object *version = ipc_json_get_version();
405 char *full_version = calloc(strlen(SWAY_GIT_VERSION) + strlen(SWAY_GIT_BRANCH) + strlen(SWAY_VERSION_DATE) + 20, 1); 413 const char *json_string = json_object_to_json_string(version);
406 strcat(full_version, SWAY_GIT_VERSION);
407 strcat(full_version, " (");
408 strcat(full_version, SWAY_VERSION_DATE);
409 strcat(full_version, ", branch \"");
410 strcat(full_version, SWAY_GIT_BRANCH);
411 strcat(full_version, "\")");
412 json_object *json = json_object_new_object();
413 json_object_object_add(json, "human_readable", json_object_new_string(full_version));
414 json_object_object_add(json, "variant", json_object_new_string("sway"));
415 // Todo once we actually release a version
416 json_object_object_add(json, "major", json_object_new_int(0));
417 json_object_object_add(json, "minor", json_object_new_int(0));
418 json_object_object_add(json, "patch", json_object_new_int(1));
419#else
420 json_object_object_add(json, "human_readable", json_object_new_string("version not found"));
421 json_object_object_add(json, "major", json_object_new_int(0));
422 json_object_object_add(json, "minor", json_object_new_int(0));
423 json_object_object_add(json, "patch", json_object_new_int(0));
424#endif
425 const char *json_string = json_object_to_json_string(json);
426 ipc_send_reply(client, json_string, (uint32_t)strlen(json_string)); 414 ipc_send_reply(client, json_string, (uint32_t)strlen(json_string));
427 json_object_put(json); // free 415 json_object_put(version); // free
428 free(full_version);
429 goto exit_cleanup; 416 goto exit_cleanup;
430 } 417 }
431 418
@@ -518,137 +505,16 @@ bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t pay
518 return true; 505 return true;
519} 506}
520 507
521json_object *ipc_json_describe_workspace(swayc_t *workspace) {
522 if (!sway_assert(workspace, "Workspace must not be NULL")) {
523 return NULL;
524 }
525
526 int num = isdigit(workspace->name[0]) ? atoi(workspace->name) : -1;
527 json_object *object = json_object_new_object();
528 json_object *rect = json_object_new_object();
529 json_object_object_add(rect, "x", json_object_new_int((int32_t) workspace->x));
530 json_object_object_add(rect, "y", json_object_new_int((int32_t) workspace->y));
531 json_object_object_add(rect, "width", json_object_new_int((int32_t) workspace->width));
532 json_object_object_add(rect, "height", json_object_new_int((int32_t) workspace->height));
533
534 json_object_object_add(object, "num", json_object_new_int(num));
535 json_object_object_add(object, "name", json_object_new_string(workspace->name));
536 json_object_object_add(object, "visible", json_object_new_boolean(workspace->visible));
537 bool focused = root_container.focused == workspace->parent && workspace->parent->focused == workspace;
538 json_object_object_add(object, "focused", json_object_new_boolean(focused));
539 json_object_object_add(object, "rect", rect);
540 json_object_object_add(object, "output", json_object_new_string(workspace->parent ? workspace->parent->name : "null"));
541 json_object_object_add(object, "urgent", json_object_new_boolean(false));
542
543 return object;
544}
545
546void ipc_get_workspaces_callback(swayc_t *workspace, void *data) { 508void ipc_get_workspaces_callback(swayc_t *workspace, void *data) {
547 if (workspace->type == C_WORKSPACE) { 509 if (workspace->type == C_WORKSPACE) {
548 json_object_array_add((json_object *)data, ipc_json_describe_workspace(workspace)); 510 json_object_array_add((json_object *)data, ipc_json_describe_container(workspace));
549 } 511 }
550} 512}
551 513
552json_object *ipc_json_describe_output(swayc_t *output) {
553 json_object *object = json_object_new_object();
554 json_object *rect = json_object_new_object();
555 json_object_object_add(rect, "x", json_object_new_int((int32_t) output->x));
556 json_object_object_add(rect, "y", json_object_new_int((int32_t) output->y));
557 json_object_object_add(rect, "width", json_object_new_int((int32_t) output->width));
558 json_object_object_add(rect, "height", json_object_new_int((int32_t) output->height));
559
560 json_object_object_add(object, "name", json_object_new_string(output->name));
561 json_object_object_add(object, "active", json_object_new_boolean(true));
562 json_object_object_add(object, "primary", json_object_new_boolean(false));
563 json_object_object_add(object, "rect", rect);
564 json_object_object_add(object, "current_workspace",
565 output->focused ? json_object_new_string(output->focused->name) : NULL);
566
567 return object;
568}
569
570void ipc_get_outputs_callback(swayc_t *container, void *data) { 514void ipc_get_outputs_callback(swayc_t *container, void *data) {
571 if (container->type == C_OUTPUT) { 515 if (container->type == C_OUTPUT) {
572 json_object_array_add((json_object *)data, ipc_json_describe_output(container)); 516 json_object_array_add((json_object *)data, ipc_json_describe_container(container));
573 }
574}
575
576json_object *ipc_json_describe_bar_config(struct bar_config *bar) {
577 if (!sway_assert(bar, "Bar must not be NULL")) {
578 return NULL;
579 }
580
581 json_object *json = json_object_new_object();
582 json_object_object_add(json, "id", json_object_new_string(bar->id));
583 json_object_object_add(json, "tray_output", NULL);
584 json_object_object_add(json, "mode", json_object_new_string(bar->mode));
585 json_object_object_add(json, "hidden_state", json_object_new_string(bar->hidden_state));
586 json_object_object_add(json, "modifier", json_object_new_string(get_modifier_name_by_mask(bar->modifier)));
587 switch (bar->position) {
588 case DESKTOP_SHELL_PANEL_POSITION_TOP:
589 json_object_object_add(json, "position", json_object_new_string("top"));
590 break;
591 case DESKTOP_SHELL_PANEL_POSITION_BOTTOM:
592 json_object_object_add(json, "position", json_object_new_string("bottom"));
593 break;
594 case DESKTOP_SHELL_PANEL_POSITION_LEFT:
595 json_object_object_add(json, "position", json_object_new_string("left"));
596 break;
597 case DESKTOP_SHELL_PANEL_POSITION_RIGHT:
598 json_object_object_add(json, "position", json_object_new_string("right"));
599 break;
600 }
601 json_object_object_add(json, "status_command", json_object_new_string(bar->status_command));
602 json_object_object_add(json, "font", json_object_new_string(bar->font ? bar->font : config->font));
603 if (bar->separator_symbol) {
604 json_object_object_add(json, "separator_symbol", json_object_new_string(bar->separator_symbol));
605 }
606 json_object_object_add(json, "bar_height", json_object_new_int(bar->height));
607 json_object_object_add(json, "workspace_buttons", json_object_new_boolean(bar->workspace_buttons));
608 json_object_object_add(json, "strip_workspace_numbers", json_object_new_boolean(bar->strip_workspace_numbers));
609 json_object_object_add(json, "binding_mode_indicator", json_object_new_boolean(bar->binding_mode_indicator));
610 json_object_object_add(json, "verbose", json_object_new_boolean(bar->verbose));
611 json_object_object_add(json, "pango_markup", json_object_new_boolean(bar->pango_markup));
612
613 json_object *colors = json_object_new_object();
614 json_object_object_add(colors, "background", json_object_new_string(bar->colors.background));
615 json_object_object_add(colors, "statusline", json_object_new_string(bar->colors.statusline));
616 json_object_object_add(colors, "separator", json_object_new_string(bar->colors.separator));
617
618 json_object_object_add(colors, "focused_workspace_border", json_object_new_string(bar->colors.focused_workspace_border));
619 json_object_object_add(colors, "focused_workspace_bg", json_object_new_string(bar->colors.focused_workspace_bg));
620 json_object_object_add(colors, "focused_workspace_text", json_object_new_string(bar->colors.focused_workspace_text));
621
622 json_object_object_add(colors, "inactive_workspace_border", json_object_new_string(bar->colors.inactive_workspace_border));
623 json_object_object_add(colors, "inactive_workspace_bg", json_object_new_string(bar->colors.inactive_workspace_bg));
624 json_object_object_add(colors, "inactive_workspace_text", json_object_new_string(bar->colors.inactive_workspace_text));
625
626 json_object_object_add(colors, "active_workspace_border", json_object_new_string(bar->colors.active_workspace_border));
627 json_object_object_add(colors, "active_workspace_bg", json_object_new_string(bar->colors.active_workspace_bg));
628 json_object_object_add(colors, "active_workspace_text", json_object_new_string(bar->colors.active_workspace_text));
629
630 json_object_object_add(colors, "urgent_workspace_border", json_object_new_string(bar->colors.urgent_workspace_border));
631 json_object_object_add(colors, "urgent_workspace_bg", json_object_new_string(bar->colors.urgent_workspace_bg));
632 json_object_object_add(colors, "urgent_workspace_text", json_object_new_string(bar->colors.urgent_workspace_text));
633
634 json_object_object_add(colors, "binding_mode_border", json_object_new_string(bar->colors.binding_mode_border));
635 json_object_object_add(colors, "binding_mode_bg", json_object_new_string(bar->colors.binding_mode_bg));
636 json_object_object_add(colors, "binding_mode_text", json_object_new_string(bar->colors.binding_mode_text));
637
638 json_object_object_add(json, "colors", colors);
639
640 // Add outputs if defined
641 if (bar->outputs && bar->outputs->length > 0) {
642 json_object *outputs = json_object_new_array();
643 int i;
644 for (i = 0; i < bar->outputs->length; ++i) {
645 const char *name = bar->outputs->items[i];
646 json_object_array_add(outputs, json_object_new_string(name));
647 }
648 json_object_object_add(json, "outputs", outputs);
649 } 517 }
650
651 return json;
652} 518}
653 519
654void ipc_send_event(const char *json_string, enum ipc_command_type event) { 520void ipc_send_event(const char *json_string, enum ipc_command_type event) {
@@ -672,14 +538,14 @@ void ipc_event_workspace(swayc_t *old, swayc_t *new, const char *change) {
672 json_object_object_add(obj, "change", json_object_new_string(change)); 538 json_object_object_add(obj, "change", json_object_new_string(change));
673 if (strcmp("focus", change) == 0) { 539 if (strcmp("focus", change) == 0) {
674 if (old) { 540 if (old) {
675 json_object_object_add(obj, "old", ipc_json_describe_workspace(old)); 541 json_object_object_add(obj, "old", ipc_json_describe_container(old));
676 } else { 542 } else {
677 json_object_object_add(obj, "old", NULL); 543 json_object_object_add(obj, "old", NULL);
678 } 544 }
679 } 545 }
680 546
681 if (new) { 547 if (new) {
682 json_object_object_add(obj, "current", ipc_json_describe_workspace(new)); 548 json_object_object_add(obj, "current", ipc_json_describe_container(new));
683 } else { 549 } else {
684 json_object_object_add(obj, "current", NULL); 550 json_object_object_add(obj, "current", NULL);
685 } 551 }
diff --git a/sway/layout.c b/sway/layout.c
index 952bcf1c..27760f35 100644
--- a/sway/layout.c
+++ b/sway/layout.c
@@ -23,6 +23,7 @@ int min_sane_w = 100;
23void init_layout(void) { 23void init_layout(void) {
24 root_container.type = C_ROOT; 24 root_container.type = C_ROOT;
25 root_container.layout = L_NONE; 25 root_container.layout = L_NONE;
26 root_container.name = strdup("root");
26 root_container.children = create_list(); 27 root_container.children = create_list();
27 root_container.handle = -1; 28 root_container.handle = -1;
28 root_container.visible = true; 29 root_container.visible = true;