diff options
Diffstat (limited to 'sway/ipc-json.c')
-rw-r--r-- | sway/ipc-json.c | 141 |
1 files changed, 80 insertions, 61 deletions
diff --git a/sway/ipc-json.c b/sway/ipc-json.c index fceee84d..1b64f86e 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c | |||
@@ -1,7 +1,11 @@ | |||
1 | #include <ctype.h> | ||
2 | #include <float.h> | ||
1 | #include <json.h> | 3 | #include <json.h> |
2 | #include <libevdev/libevdev.h> | 4 | #include <libevdev/libevdev.h> |
3 | #include <stdio.h> | 5 | #include <stdio.h> |
4 | #include <ctype.h> | 6 | #include <wlr/backend/libinput.h> |
7 | #include <wlr/types/wlr_output.h> | ||
8 | #include <xkbcommon/xkbcommon.h> | ||
5 | #include "config.h" | 9 | #include "config.h" |
6 | #include "log.h" | 10 | #include "log.h" |
7 | #include "sway/config.h" | 11 | #include "sway/config.h" |
@@ -13,16 +17,26 @@ | |||
13 | #include "sway/input/input-manager.h" | 17 | #include "sway/input/input-manager.h" |
14 | #include "sway/input/cursor.h" | 18 | #include "sway/input/cursor.h" |
15 | #include "sway/input/seat.h" | 19 | #include "sway/input/seat.h" |
16 | #include <wlr/backend/libinput.h> | ||
17 | #include <wlr/types/wlr_box.h> | ||
18 | #include <wlr/types/wlr_output.h> | ||
19 | #include <xkbcommon/xkbcommon.h> | ||
20 | #include "wlr-layer-shell-unstable-v1-protocol.h" | 20 | #include "wlr-layer-shell-unstable-v1-protocol.h" |
21 | #include "sway/desktop/idle_inhibit_v1.h" | 21 | #include "sway/desktop/idle_inhibit_v1.h" |
22 | 22 | ||
23 | static const int i3_output_id = INT32_MAX; | 23 | static const int i3_output_id = INT32_MAX; |
24 | static const int i3_scratch_id = INT32_MAX - 1; | 24 | static const int i3_scratch_id = INT32_MAX - 1; |
25 | 25 | ||
26 | static const char *ipc_json_node_type_description(enum sway_node_type node_type) { | ||
27 | switch (node_type) { | ||
28 | case N_ROOT: | ||
29 | return "root"; | ||
30 | case N_OUTPUT: | ||
31 | return "output"; | ||
32 | case N_WORKSPACE: | ||
33 | return "workspace"; | ||
34 | case N_CONTAINER: | ||
35 | return "con"; | ||
36 | } | ||
37 | return "none"; | ||
38 | } | ||
39 | |||
26 | static const char *ipc_json_layout_description(enum sway_container_layout l) { | 40 | static const char *ipc_json_layout_description(enum sway_container_layout l) { |
27 | switch (l) { | 41 | switch (l) { |
28 | case L_VERT: | 42 | case L_VERT: |
@@ -189,16 +203,22 @@ static json_object *ipc_json_create_empty_rect(void) { | |||
189 | return ipc_json_create_rect(&empty); | 203 | return ipc_json_create_rect(&empty); |
190 | } | 204 | } |
191 | 205 | ||
192 | static json_object *ipc_json_create_node(int id, char *name, | 206 | static json_object *ipc_json_create_node(int id, const char* type, char *name, |
193 | bool focused, json_object *focus, struct wlr_box *box) { | 207 | bool focused, json_object *focus, struct wlr_box *box) { |
194 | json_object *object = json_object_new_object(); | 208 | json_object *object = json_object_new_object(); |
195 | 209 | ||
196 | json_object_object_add(object, "id", json_object_new_int(id)); | 210 | json_object_object_add(object, "id", json_object_new_int(id)); |
197 | json_object_object_add(object, "name", | 211 | json_object_object_add(object, "type", json_object_new_string(type)); |
198 | name ? json_object_new_string(name) : NULL); | 212 | json_object_object_add(object, "orientation", |
199 | json_object_object_add(object, "rect", ipc_json_create_rect(box)); | 213 | json_object_new_string( |
214 | ipc_json_orientation_description(L_HORIZ))); | ||
215 | json_object_object_add(object, "percent", NULL); | ||
216 | json_object_object_add(object, "urgent", json_object_new_boolean(false)); | ||
217 | json_object_object_add(object, "marks", json_object_new_array()); | ||
200 | json_object_object_add(object, "focused", json_object_new_boolean(focused)); | 218 | json_object_object_add(object, "focused", json_object_new_boolean(focused)); |
201 | json_object_object_add(object, "focus", focus); | 219 | json_object_object_add(object, "layout", |
220 | json_object_new_string( | ||
221 | ipc_json_layout_description(L_HORIZ))); | ||
202 | 222 | ||
203 | // set default values to be compatible with i3 | 223 | // set default values to be compatible with i3 |
204 | json_object_object_add(object, "border", | 224 | json_object_object_add(object, "border", |
@@ -206,35 +226,25 @@ static json_object *ipc_json_create_node(int id, char *name, | |||
206 | ipc_json_border_description(B_NONE))); | 226 | ipc_json_border_description(B_NONE))); |
207 | json_object_object_add(object, "current_border_width", | 227 | json_object_object_add(object, "current_border_width", |
208 | json_object_new_int(0)); | 228 | json_object_new_int(0)); |
209 | json_object_object_add(object, "layout", | 229 | json_object_object_add(object, "rect", ipc_json_create_rect(box)); |
210 | json_object_new_string( | ||
211 | ipc_json_layout_description(L_HORIZ))); | ||
212 | json_object_object_add(object, "orientation", | ||
213 | json_object_new_string( | ||
214 | ipc_json_orientation_description(L_HORIZ))); | ||
215 | json_object_object_add(object, "percent", NULL); | ||
216 | json_object_object_add(object, "window_rect", ipc_json_create_empty_rect()); | ||
217 | json_object_object_add(object, "deco_rect", ipc_json_create_empty_rect()); | 230 | json_object_object_add(object, "deco_rect", ipc_json_create_empty_rect()); |
231 | json_object_object_add(object, "window_rect", ipc_json_create_empty_rect()); | ||
218 | json_object_object_add(object, "geometry", ipc_json_create_empty_rect()); | 232 | json_object_object_add(object, "geometry", ipc_json_create_empty_rect()); |
233 | json_object_object_add(object, "name", | ||
234 | name ? json_object_new_string(name) : NULL); | ||
219 | json_object_object_add(object, "window", NULL); | 235 | json_object_object_add(object, "window", NULL); |
220 | json_object_object_add(object, "urgent", json_object_new_boolean(false)); | ||
221 | json_object_object_add(object, "marks", json_object_new_array()); | ||
222 | json_object_object_add(object, "fullscreen_mode", json_object_new_int(0)); | ||
223 | json_object_object_add(object, "nodes", json_object_new_array()); | 236 | json_object_object_add(object, "nodes", json_object_new_array()); |
224 | json_object_object_add(object, "floating_nodes", json_object_new_array()); | 237 | json_object_object_add(object, "floating_nodes", json_object_new_array()); |
238 | json_object_object_add(object, "focus", focus); | ||
239 | json_object_object_add(object, "fullscreen_mode", json_object_new_int(0)); | ||
225 | json_object_object_add(object, "sticky", json_object_new_boolean(false)); | 240 | json_object_object_add(object, "sticky", json_object_new_boolean(false)); |
226 | 241 | ||
227 | return object; | 242 | return object; |
228 | } | 243 | } |
229 | 244 | ||
230 | static void ipc_json_describe_root(struct sway_root *root, json_object *object) { | ||
231 | json_object_object_add(object, "type", json_object_new_string("root")); | ||
232 | } | ||
233 | |||
234 | static void ipc_json_describe_output(struct sway_output *output, | 245 | static void ipc_json_describe_output(struct sway_output *output, |
235 | json_object *object) { | 246 | json_object *object) { |
236 | struct wlr_output *wlr_output = output->wlr_output; | 247 | struct wlr_output *wlr_output = output->wlr_output; |
237 | json_object_object_add(object, "type", json_object_new_string("output")); | ||
238 | json_object_object_add(object, "active", json_object_new_boolean(true)); | 248 | json_object_object_add(object, "active", json_object_new_boolean(true)); |
239 | json_object_object_add(object, "dpms", | 249 | json_object_object_add(object, "dpms", |
240 | json_object_new_boolean(wlr_output->enabled)); | 250 | json_object_new_boolean(wlr_output->enabled)); |
@@ -369,11 +379,9 @@ static json_object *ipc_json_describe_scratchpad_output(void) { | |||
369 | json_object_new_int(container->node.id)); | 379 | json_object_new_int(container->node.id)); |
370 | } | 380 | } |
371 | 381 | ||
372 | json_object *workspace = ipc_json_create_node(i3_scratch_id, | 382 | json_object *workspace = ipc_json_create_node(i3_scratch_id, "workspace", |
373 | "__i3_scratch", false, workspace_focus, &box); | 383 | "__i3_scratch", false, workspace_focus, &box); |
374 | json_object_object_add(workspace, "fullscreen_mode", json_object_new_int(1)); | 384 | json_object_object_add(workspace, "fullscreen_mode", json_object_new_int(1)); |
375 | json_object_object_add(workspace, "type", | ||
376 | json_object_new_string("workspace")); | ||
377 | 385 | ||
378 | // List all hidden scratchpad containers as floating nodes | 386 | // List all hidden scratchpad containers as floating nodes |
379 | json_object *floating_array = json_object_new_array(); | 387 | json_object *floating_array = json_object_new_array(); |
@@ -390,10 +398,8 @@ static json_object *ipc_json_describe_scratchpad_output(void) { | |||
390 | json_object *output_focus = json_object_new_array(); | 398 | json_object *output_focus = json_object_new_array(); |
391 | json_object_array_add(output_focus, json_object_new_int(i3_scratch_id)); | 399 | json_object_array_add(output_focus, json_object_new_int(i3_scratch_id)); |
392 | 400 | ||
393 | json_object *output = ipc_json_create_node(i3_output_id, | 401 | json_object *output = ipc_json_create_node(i3_output_id, "output", |
394 | "__i3", false, output_focus, &box); | 402 | "__i3", false, output_focus, &box); |
395 | json_object_object_add(output, "type", | ||
396 | json_object_new_string("output")); | ||
397 | json_object_object_add(output, "layout", | 403 | json_object_object_add(output, "layout", |
398 | json_object_new_string("output")); | 404 | json_object_new_string("output")); |
399 | 405 | ||
@@ -423,7 +429,6 @@ static void ipc_json_describe_workspace(struct sway_workspace *workspace, | |||
423 | json_object_object_add(object, "fullscreen_mode", json_object_new_int(1)); | 429 | json_object_object_add(object, "fullscreen_mode", json_object_new_int(1)); |
424 | json_object_object_add(object, "output", workspace->output ? | 430 | json_object_object_add(object, "output", workspace->output ? |
425 | json_object_new_string(workspace->output->wlr_output->name) : NULL); | 431 | json_object_new_string(workspace->output->wlr_output->name) : NULL); |
426 | json_object_object_add(object, "type", json_object_new_string("workspace")); | ||
427 | json_object_object_add(object, "urgent", | 432 | json_object_object_add(object, "urgent", |
428 | json_object_new_boolean(workspace->urgent)); | 433 | json_object_new_boolean(workspace->urgent)); |
429 | json_object_object_add(object, "representation", workspace->representation ? | 434 | json_object_object_add(object, "representation", workspace->representation ? |
@@ -451,27 +456,27 @@ static void get_deco_rect(struct sway_container *c, struct wlr_box *deco_rect) { | |||
451 | bool tab_or_stack = parent_layout == L_TABBED || parent_layout == L_STACKED; | 456 | bool tab_or_stack = parent_layout == L_TABBED || parent_layout == L_STACKED; |
452 | if (((!tab_or_stack || container_is_floating(c)) && | 457 | if (((!tab_or_stack || container_is_floating(c)) && |
453 | c->current.border != B_NORMAL) || | 458 | c->current.border != B_NORMAL) || |
454 | c->fullscreen_mode != FULLSCREEN_NONE || | 459 | c->pending.fullscreen_mode != FULLSCREEN_NONE || |
455 | c->workspace == NULL) { | 460 | c->pending.workspace == NULL) { |
456 | deco_rect->x = deco_rect->y = deco_rect->width = deco_rect->height = 0; | 461 | deco_rect->x = deco_rect->y = deco_rect->width = deco_rect->height = 0; |
457 | return; | 462 | return; |
458 | } | 463 | } |
459 | 464 | ||
460 | if (c->parent) { | 465 | if (c->pending.parent) { |
461 | deco_rect->x = c->x - c->parent->x; | 466 | deco_rect->x = c->pending.x - c->pending.parent->pending.x; |
462 | deco_rect->y = c->y - c->parent->y; | 467 | deco_rect->y = c->pending.y - c->pending.parent->pending.y; |
463 | } else { | 468 | } else { |
464 | deco_rect->x = c->x - c->workspace->x; | 469 | deco_rect->x = c->pending.x - c->pending.workspace->x; |
465 | deco_rect->y = c->y - c->workspace->y; | 470 | deco_rect->y = c->pending.y - c->pending.workspace->y; |
466 | } | 471 | } |
467 | deco_rect->width = c->width; | 472 | deco_rect->width = c->pending.width; |
468 | deco_rect->height = container_titlebar_height(); | 473 | deco_rect->height = container_titlebar_height(); |
469 | 474 | ||
470 | if (!container_is_floating(c)) { | 475 | if (!container_is_floating(c)) { |
471 | if (parent_layout == L_TABBED) { | 476 | if (parent_layout == L_TABBED) { |
472 | deco_rect->width = c->parent | 477 | deco_rect->width = c->pending.parent |
473 | ? c->parent->width / c->parent->children->length | 478 | ? c->pending.parent->pending.width / c->pending.parent->pending.children->length |
474 | : c->workspace->width / c->workspace->tiling->length; | 479 | : c->pending.workspace->width / c->pending.workspace->tiling->length; |
475 | deco_rect->x += deco_rect->width * container_sibling_index(c); | 480 | deco_rect->x += deco_rect->width * container_sibling_index(c); |
476 | } else if (parent_layout == L_STACKED) { | 481 | } else if (parent_layout == L_STACKED) { |
477 | if (!c->view) { | 482 | if (!c->view) { |
@@ -494,10 +499,10 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object | |||
494 | json_object_object_add(object, "visible", json_object_new_boolean(visible)); | 499 | json_object_object_add(object, "visible", json_object_new_boolean(visible)); |
495 | 500 | ||
496 | struct wlr_box window_box = { | 501 | struct wlr_box window_box = { |
497 | c->content_x - c->x, | 502 | c->pending.content_x - c->pending.x, |
498 | (c->current.border == B_PIXEL) ? c->current.border_thickness : 0, | 503 | (c->current.border == B_PIXEL) ? c->current.border_thickness : 0, |
499 | c->content_width, | 504 | c->pending.content_width, |
500 | c->content_height | 505 | c->pending.content_height |
501 | }; | 506 | }; |
502 | 507 | ||
503 | json_object_object_add(object, "window_rect", ipc_json_create_rect(&window_box)); | 508 | json_object_object_add(object, "window_rect", ipc_json_create_rect(&window_box)); |
@@ -583,16 +588,18 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object | |||
583 | static void ipc_json_describe_container(struct sway_container *c, json_object *object) { | 588 | static void ipc_json_describe_container(struct sway_container *c, json_object *object) { |
584 | json_object_object_add(object, "name", | 589 | json_object_object_add(object, "name", |
585 | c->title ? json_object_new_string(c->title) : NULL); | 590 | c->title ? json_object_new_string(c->title) : NULL); |
586 | json_object_object_add(object, "type", | 591 | if (container_is_floating(c)) { |
587 | json_object_new_string(container_is_floating(c) ? "floating_con" : "con")); | 592 | json_object_object_add(object, "type", |
593 | json_object_new_string("floating_con")); | ||
594 | } | ||
588 | 595 | ||
589 | json_object_object_add(object, "layout", | 596 | json_object_object_add(object, "layout", |
590 | json_object_new_string( | 597 | json_object_new_string( |
591 | ipc_json_layout_description(c->layout))); | 598 | ipc_json_layout_description(c->pending.layout))); |
592 | 599 | ||
593 | json_object_object_add(object, "orientation", | 600 | json_object_object_add(object, "orientation", |
594 | json_object_new_string( | 601 | json_object_new_string( |
595 | ipc_json_orientation_description(c->layout))); | 602 | ipc_json_orientation_description(c->pending.layout))); |
596 | 603 | ||
597 | bool urgent = c->view ? | 604 | bool urgent = c->view ? |
598 | view_is_urgent(c->view) : container_has_urgent_child(c); | 605 | view_is_urgent(c->view) : container_has_urgent_child(c); |
@@ -600,7 +607,7 @@ static void ipc_json_describe_container(struct sway_container *c, json_object *o | |||
600 | json_object_object_add(object, "sticky", json_object_new_boolean(c->is_sticky)); | 607 | json_object_object_add(object, "sticky", json_object_new_boolean(c->is_sticky)); |
601 | 608 | ||
602 | json_object_object_add(object, "fullscreen_mode", | 609 | json_object_object_add(object, "fullscreen_mode", |
603 | json_object_new_int(c->fullscreen_mode)); | 610 | json_object_new_int(c->pending.fullscreen_mode)); |
604 | 611 | ||
605 | struct sway_node *parent = node_get_parent(&c->node); | 612 | struct sway_node *parent = node_get_parent(&c->node); |
606 | struct wlr_box parent_box = {0, 0, 0, 0}; | 613 | struct wlr_box parent_box = {0, 0, 0, 0}; |
@@ -610,8 +617,8 @@ static void ipc_json_describe_container(struct sway_container *c, json_object *o | |||
610 | } | 617 | } |
611 | 618 | ||
612 | if (parent_box.width != 0 && parent_box.height != 0) { | 619 | if (parent_box.width != 0 && parent_box.height != 0) { |
613 | double percent = ((double)c->width / parent_box.width) | 620 | double percent = ((double)c->pending.width / parent_box.width) |
614 | * ((double)c->height / parent_box.height); | 621 | * ((double)c->pending.height / parent_box.height); |
615 | json_object_object_add(object, "percent", json_object_new_double(percent)); | 622 | json_object_object_add(object, "percent", json_object_new_double(percent)); |
616 | } | 623 | } |
617 | 624 | ||
@@ -692,12 +699,11 @@ json_object *ipc_json_describe_node(struct sway_node *node) { | |||
692 | }; | 699 | }; |
693 | seat_for_each_node(seat, focus_inactive_children_iterator, &data); | 700 | seat_for_each_node(seat, focus_inactive_children_iterator, &data); |
694 | 701 | ||
695 | json_object *object = ipc_json_create_node( | 702 | json_object *object = ipc_json_create_node((int)node->id, |
696 | (int)node->id, name, focused, focus, &box); | 703 | ipc_json_node_type_description(node->type), name, focused, focus, &box); |
697 | 704 | ||
698 | switch (node->type) { | 705 | switch (node->type) { |
699 | case N_ROOT: | 706 | case N_ROOT: |
700 | ipc_json_describe_root(root, object); | ||
701 | break; | 707 | break; |
702 | case N_OUTPUT: | 708 | case N_OUTPUT: |
703 | ipc_json_describe_output(node->sway_output, object); | 709 | ipc_json_describe_output(node->sway_output, object); |
@@ -743,10 +749,10 @@ json_object *ipc_json_describe_node_recursive(struct sway_node *node) { | |||
743 | } | 749 | } |
744 | break; | 750 | break; |
745 | case N_CONTAINER: | 751 | case N_CONTAINER: |
746 | if (node->sway_container->children) { | 752 | if (node->sway_container->pending.children) { |
747 | for (i = 0; i < node->sway_container->children->length; ++i) { | 753 | for (i = 0; i < node->sway_container->pending.children->length; ++i) { |
748 | struct sway_container *child = | 754 | struct sway_container *child = |
749 | node->sway_container->children->items[i]; | 755 | node->sway_container->pending.children->items[i]; |
750 | json_object_array_add(children, | 756 | json_object_array_add(children, |
751 | ipc_json_describe_node_recursive(&child->node)); | 757 | ipc_json_describe_node_recursive(&child->node)); |
752 | } | 758 | } |
@@ -996,6 +1002,17 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) { | |||
996 | } | 1002 | } |
997 | } | 1003 | } |
998 | 1004 | ||
1005 | if (device->wlr_device->type == WLR_INPUT_DEVICE_POINTER) { | ||
1006 | struct input_config *ic = input_device_get_config(device); | ||
1007 | float scroll_factor = 1.0f; | ||
1008 | if (ic != NULL && !isnan(ic->scroll_factor) && | ||
1009 | ic->scroll_factor != FLT_MIN) { | ||
1010 | scroll_factor = ic->scroll_factor; | ||
1011 | } | ||
1012 | json_object_object_add(object, "scroll_factor", | ||
1013 | json_object_new_double(scroll_factor)); | ||
1014 | } | ||
1015 | |||
999 | if (wlr_input_device_is_libinput(device->wlr_device)) { | 1016 | if (wlr_input_device_is_libinput(device->wlr_device)) { |
1000 | struct libinput_device *libinput_dev; | 1017 | struct libinput_device *libinput_dev; |
1001 | libinput_dev = wlr_libinput_get_device_handle(device->wlr_device); | 1018 | libinput_dev = wlr_libinput_get_device_handle(device->wlr_device); |
@@ -1109,7 +1126,9 @@ json_object *ipc_json_describe_bar_config(struct bar_config *bar) { | |||
1109 | json_object_object_add(json, "verbose", | 1126 | json_object_object_add(json, "verbose", |
1110 | json_object_new_boolean(bar->verbose)); | 1127 | json_object_new_boolean(bar->verbose)); |
1111 | json_object_object_add(json, "pango_markup", | 1128 | json_object_object_add(json, "pango_markup", |
1112 | json_object_new_boolean(bar->pango_markup)); | 1129 | json_object_new_boolean(bar->pango_markup == PANGO_MARKUP_DEFAULT |
1130 | ? config->pango_markup | ||
1131 | : bar->pango_markup)); | ||
1113 | 1132 | ||
1114 | json_object *colors = json_object_new_object(); | 1133 | json_object *colors = json_object_new_object(); |
1115 | json_object_object_add(colors, "background", | 1134 | json_object_object_add(colors, "background", |