aboutsummaryrefslogtreecommitdiffstats
path: root/sway/ipc-json.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/ipc-json.c')
-rw-r--r--sway/ipc-json.c380
1 files changed, 268 insertions, 112 deletions
diff --git a/sway/ipc-json.c b/sway/ipc-json.c
index fceee84d..81ca3483 100644
--- a/sway/ipc-json.c
+++ b/sway/ipc-json.c
@@ -1,7 +1,12 @@
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/config.h>
7#include <wlr/types/wlr_content_type_v1.h>
8#include <wlr/types/wlr_output.h>
9#include <xkbcommon/xkbcommon.h>
5#include "config.h" 10#include "config.h"
6#include "log.h" 11#include "log.h"
7#include "sway/config.h" 12#include "sway/config.h"
@@ -13,16 +18,30 @@
13#include "sway/input/input-manager.h" 18#include "sway/input/input-manager.h"
14#include "sway/input/cursor.h" 19#include "sway/input/cursor.h"
15#include "sway/input/seat.h" 20#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" 21#include "wlr-layer-shell-unstable-v1-protocol.h"
21#include "sway/desktop/idle_inhibit_v1.h" 22#include "sway/desktop/idle_inhibit_v1.h"
22 23
24#if WLR_HAS_LIBINPUT_BACKEND
25#include <wlr/backend/libinput.h>
26#endif
27
23static const int i3_output_id = INT32_MAX; 28static const int i3_output_id = INT32_MAX;
24static const int i3_scratch_id = INT32_MAX - 1; 29static const int i3_scratch_id = INT32_MAX - 1;
25 30
31static const char *ipc_json_node_type_description(enum sway_node_type node_type) {
32 switch (node_type) {
33 case N_ROOT:
34 return "root";
35 case N_OUTPUT:
36 return "output";
37 case N_WORKSPACE:
38 return "workspace";
39 case N_CONTAINER:
40 return "con";
41 }
42 return "none";
43}
44
26static const char *ipc_json_layout_description(enum sway_container_layout l) { 45static const char *ipc_json_layout_description(enum sway_container_layout l) {
27 switch (l) { 46 switch (l) {
28 case L_VERT: 47 case L_VERT:
@@ -98,12 +117,43 @@ static const char *ipc_json_output_adaptive_sync_status_description(
98 return "disabled"; 117 return "disabled";
99 case WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED: 118 case WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED:
100 return "enabled"; 119 return "enabled";
101 case WLR_OUTPUT_ADAPTIVE_SYNC_UNKNOWN:
102 return "unknown";
103 } 120 }
104 return NULL; 121 return NULL;
105} 122}
106 123
124static const char *ipc_json_output_mode_aspect_ratio_description(
125 enum wlr_output_mode_aspect_ratio aspect_ratio) {
126 switch (aspect_ratio) {
127 case WLR_OUTPUT_MODE_ASPECT_RATIO_NONE:
128 return "none";
129 case WLR_OUTPUT_MODE_ASPECT_RATIO_4_3:
130 return "4:3";
131 case WLR_OUTPUT_MODE_ASPECT_RATIO_16_9:
132 return "16:9";
133 case WLR_OUTPUT_MODE_ASPECT_RATIO_64_27:
134 return "64:27";
135 case WLR_OUTPUT_MODE_ASPECT_RATIO_256_135:
136 return "256:135";
137 }
138 return NULL;
139}
140
141static json_object *ipc_json_output_mode_description(
142 const struct wlr_output_mode *mode) {
143 const char *pic_ar =
144 ipc_json_output_mode_aspect_ratio_description(mode->picture_aspect_ratio);
145 json_object *mode_object = json_object_new_object();
146 json_object_object_add(mode_object, "width",
147 json_object_new_int(mode->width));
148 json_object_object_add(mode_object, "height",
149 json_object_new_int(mode->height));
150 json_object_object_add(mode_object, "refresh",
151 json_object_new_int(mode->refresh));
152 json_object_object_add(mode_object, "picture_aspect_ratio",
153 json_object_new_string(pic_ar));
154 return mode_object;
155}
156
107#if HAVE_XWAYLAND 157#if HAVE_XWAYLAND
108static const char *ipc_json_xwindow_type_description(struct sway_view *view) { 158static const char *ipc_json_xwindow_type_description(struct sway_view *view) {
109 struct wlr_xwayland_surface *surface = view->wlr_xwayland_surface; 159 struct wlr_xwayland_surface *surface = view->wlr_xwayland_surface;
@@ -156,6 +206,20 @@ static const char *ipc_json_user_idle_inhibitor_description(enum sway_idle_inhib
156 return NULL; 206 return NULL;
157} 207}
158 208
209static const char *ipc_json_content_type_description(enum wp_content_type_v1_type type) {
210 switch (type) {
211 case WP_CONTENT_TYPE_V1_TYPE_NONE:
212 return "none";
213 case WP_CONTENT_TYPE_V1_TYPE_PHOTO:
214 return "photo";
215 case WP_CONTENT_TYPE_V1_TYPE_VIDEO:
216 return "video";
217 case WP_CONTENT_TYPE_V1_TYPE_GAME:
218 return "game";
219 }
220 return NULL;
221}
222
159json_object *ipc_json_get_version(void) { 223json_object *ipc_json_get_version(void) {
160 int major = 0, minor = 0, patch = 0; 224 int major = 0, minor = 0, patch = 0;
161 json_object *version = json_object_new_object(); 225 json_object *version = json_object_new_object();
@@ -189,16 +253,22 @@ static json_object *ipc_json_create_empty_rect(void) {
189 return ipc_json_create_rect(&empty); 253 return ipc_json_create_rect(&empty);
190} 254}
191 255
192static json_object *ipc_json_create_node(int id, char *name, 256static json_object *ipc_json_create_node(int id, const char* type, char *name,
193 bool focused, json_object *focus, struct wlr_box *box) { 257 bool focused, json_object *focus, struct wlr_box *box) {
194 json_object *object = json_object_new_object(); 258 json_object *object = json_object_new_object();
195 259
196 json_object_object_add(object, "id", json_object_new_int(id)); 260 json_object_object_add(object, "id", json_object_new_int(id));
197 json_object_object_add(object, "name", 261 json_object_object_add(object, "type", json_object_new_string(type));
198 name ? json_object_new_string(name) : NULL); 262 json_object_object_add(object, "orientation",
199 json_object_object_add(object, "rect", ipc_json_create_rect(box)); 263 json_object_new_string(
264 ipc_json_orientation_description(L_HORIZ)));
265 json_object_object_add(object, "percent", NULL);
266 json_object_object_add(object, "urgent", json_object_new_boolean(false));
267 json_object_object_add(object, "marks", json_object_new_array());
200 json_object_object_add(object, "focused", json_object_new_boolean(focused)); 268 json_object_object_add(object, "focused", json_object_new_boolean(focused));
201 json_object_object_add(object, "focus", focus); 269 json_object_object_add(object, "layout",
270 json_object_new_string(
271 ipc_json_layout_description(L_HORIZ)));
202 272
203 // set default values to be compatible with i3 273 // set default values to be compatible with i3
204 json_object_object_add(object, "border", 274 json_object_object_add(object, "border",
@@ -206,49 +276,68 @@ static json_object *ipc_json_create_node(int id, char *name,
206 ipc_json_border_description(B_NONE))); 276 ipc_json_border_description(B_NONE)));
207 json_object_object_add(object, "current_border_width", 277 json_object_object_add(object, "current_border_width",
208 json_object_new_int(0)); 278 json_object_new_int(0));
209 json_object_object_add(object, "layout", 279 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()); 280 json_object_object_add(object, "deco_rect", ipc_json_create_empty_rect());
281 json_object_object_add(object, "window_rect", ipc_json_create_empty_rect());
218 json_object_object_add(object, "geometry", ipc_json_create_empty_rect()); 282 json_object_object_add(object, "geometry", ipc_json_create_empty_rect());
283 json_object_object_add(object, "name",
284 name ? json_object_new_string(name) : NULL);
219 json_object_object_add(object, "window", NULL); 285 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()); 286 json_object_object_add(object, "nodes", json_object_new_array());
224 json_object_object_add(object, "floating_nodes", json_object_new_array()); 287 json_object_object_add(object, "floating_nodes", json_object_new_array());
288 json_object_object_add(object, "focus", focus);
289 json_object_object_add(object, "fullscreen_mode", json_object_new_int(0));
225 json_object_object_add(object, "sticky", json_object_new_boolean(false)); 290 json_object_object_add(object, "sticky", json_object_new_boolean(false));
291 json_object_object_add(object, "floating", NULL);
292 json_object_object_add(object, "scratchpad_state", NULL);
226 293
227 return object; 294 return object;
228} 295}
229 296
230static void ipc_json_describe_root(struct sway_root *root, json_object *object) { 297static void ipc_json_describe_wlr_output(struct wlr_output *wlr_output, json_object *object) {
231 json_object_object_add(object, "type", json_object_new_string("root")); 298 json_object_object_add(object, "primary", json_object_new_boolean(false));
299 json_object_object_add(object, "make",
300 json_object_new_string(wlr_output->make ? wlr_output->make : "Unknown"));
301 json_object_object_add(object, "model",
302 json_object_new_string(wlr_output->model ? wlr_output->model : "Unknown"));
303 json_object_object_add(object, "serial",
304 json_object_new_string(wlr_output->serial ? wlr_output->serial : "Unknown"));
305
306 json_object *modes_array = json_object_new_array();
307 struct wlr_output_mode *mode;
308 wl_list_for_each(mode, &wlr_output->modes, link) {
309 json_object *mode_object = json_object_new_object();
310 json_object_object_add(mode_object, "width",
311 json_object_new_int(mode->width));
312 json_object_object_add(mode_object, "height",
313 json_object_new_int(mode->height));
314 json_object_object_add(mode_object, "refresh",
315 json_object_new_int(mode->refresh));
316 json_object_array_add(modes_array, mode_object);
317 }
318 json_object_object_add(object, "modes", modes_array);
232} 319}
233 320
234static void ipc_json_describe_output(struct sway_output *output, 321static void ipc_json_describe_output(struct sway_output *output,
235 json_object *object) { 322 json_object *object) {
323 ipc_json_describe_wlr_output(output->wlr_output, object);
324}
325
326static void ipc_json_describe_enabled_output(struct sway_output *output,
327 json_object *object) {
328 ipc_json_describe_output(output, object);
329
236 struct wlr_output *wlr_output = output->wlr_output; 330 struct wlr_output *wlr_output = output->wlr_output;
237 json_object_object_add(object, "type", json_object_new_string("output")); 331 json_object_object_add(object, "non_desktop", json_object_new_boolean(false));
238 json_object_object_add(object, "active", json_object_new_boolean(true)); 332 json_object_object_add(object, "active", json_object_new_boolean(true));
239 json_object_object_add(object, "dpms", 333 json_object_object_add(object, "dpms",
240 json_object_new_boolean(wlr_output->enabled)); 334 json_object_new_boolean(wlr_output->enabled));
241 json_object_object_add(object, "primary", json_object_new_boolean(false)); 335 json_object_object_add(object, "power",
336 json_object_new_boolean(wlr_output->enabled));
242 json_object_object_add(object, "layout", json_object_new_string("output")); 337 json_object_object_add(object, "layout", json_object_new_string("output"));
243 json_object_object_add(object, "orientation", 338 json_object_object_add(object, "orientation",
244 json_object_new_string( 339 json_object_new_string(
245 ipc_json_orientation_description(L_NONE))); 340 ipc_json_orientation_description(L_NONE)));
246 json_object_object_add(object, "make",
247 json_object_new_string(wlr_output->make));
248 json_object_object_add(object, "model",
249 json_object_new_string(wlr_output->model));
250 json_object_object_add(object, "serial",
251 json_object_new_string(wlr_output->serial));
252 json_object_object_add(object, "scale", 341 json_object_object_add(object, "scale",
253 json_object_new_double(wlr_output->scale)); 342 json_object_new_double(wlr_output->scale));
254 json_object_object_add(object, "scale_filter", 343 json_object_object_add(object, "scale_filter",
@@ -273,25 +362,26 @@ static void ipc_json_describe_output(struct sway_output *output,
273 json_object *modes_array = json_object_new_array(); 362 json_object *modes_array = json_object_new_array();
274 struct wlr_output_mode *mode; 363 struct wlr_output_mode *mode;
275 wl_list_for_each(mode, &wlr_output->modes, link) { 364 wl_list_for_each(mode, &wlr_output->modes, link) {
276 json_object *mode_object = json_object_new_object(); 365 json_object *mode_object =
277 json_object_object_add(mode_object, "width", 366 ipc_json_output_mode_description(mode);
278 json_object_new_int(mode->width));
279 json_object_object_add(mode_object, "height",
280 json_object_new_int(mode->height));
281 json_object_object_add(mode_object, "refresh",
282 json_object_new_int(mode->refresh));
283 json_object_array_add(modes_array, mode_object); 367 json_object_array_add(modes_array, mode_object);
284 } 368 }
285 369
286 json_object_object_add(object, "modes", modes_array); 370 json_object_object_add(object, "modes", modes_array);
287 371
288 json_object *current_mode_object = json_object_new_object(); 372 json_object *current_mode_object;
289 json_object_object_add(current_mode_object, "width", 373 if (wlr_output->current_mode != NULL) {
290 json_object_new_int(wlr_output->width)); 374 current_mode_object =
291 json_object_object_add(current_mode_object, "height", 375 ipc_json_output_mode_description(wlr_output->current_mode);
292 json_object_new_int(wlr_output->height)); 376 } else {
293 json_object_object_add(current_mode_object, "refresh", 377 current_mode_object = json_object_new_object();
294 json_object_new_int(wlr_output->refresh)); 378 json_object_object_add(current_mode_object, "width",
379 json_object_new_int(wlr_output->width));
380 json_object_object_add(current_mode_object, "height",
381 json_object_new_int(wlr_output->height));
382 json_object_object_add(current_mode_object, "refresh",
383 json_object_new_int(wlr_output->refresh));
384 }
295 json_object_object_add(object, "current_mode", current_mode_object); 385 json_object_object_add(object, "current_mode", current_mode_object);
296 386
297 struct sway_node *parent = node_get_parent(&output->node); 387 struct sway_node *parent = node_get_parent(&output->node);
@@ -315,33 +405,15 @@ json_object *ipc_json_describe_disabled_output(struct sway_output *output) {
315 405
316 json_object *object = json_object_new_object(); 406 json_object *object = json_object_new_object();
317 407
408 ipc_json_describe_output(output, object);
409
410 json_object_object_add(object, "non_desktop", json_object_new_boolean(false));
318 json_object_object_add(object, "type", json_object_new_string("output")); 411 json_object_object_add(object, "type", json_object_new_string("output"));
319 json_object_object_add(object, "name", 412 json_object_object_add(object, "name",
320 json_object_new_string(wlr_output->name)); 413 json_object_new_string(wlr_output->name));
321 json_object_object_add(object, "active", json_object_new_boolean(false)); 414 json_object_object_add(object, "active", json_object_new_boolean(false));
322 json_object_object_add(object, "dpms", json_object_new_boolean(false)); 415 json_object_object_add(object, "dpms", json_object_new_boolean(false));
323 json_object_object_add(object, "primary", json_object_new_boolean(false)); 416 json_object_object_add(object, "power", json_object_new_boolean(false));
324 json_object_object_add(object, "make",
325 json_object_new_string(wlr_output->make));
326 json_object_object_add(object, "model",
327 json_object_new_string(wlr_output->model));
328 json_object_object_add(object, "serial",
329 json_object_new_string(wlr_output->serial));
330
331 json_object *modes_array = json_object_new_array();
332 struct wlr_output_mode *mode;
333 wl_list_for_each(mode, &wlr_output->modes, link) {
334 json_object *mode_object = json_object_new_object();
335 json_object_object_add(mode_object, "width",
336 json_object_new_int(mode->width));
337 json_object_object_add(mode_object, "height",
338 json_object_new_int(mode->height));
339 json_object_object_add(mode_object, "refresh",
340 json_object_new_int(mode->refresh));
341 json_object_array_add(modes_array, mode_object);
342 }
343
344 json_object_object_add(object, "modes", modes_array);
345 417
346 json_object_object_add(object, "current_workspace", NULL); 418 json_object_object_add(object, "current_workspace", NULL);
347 419
@@ -357,6 +429,21 @@ json_object *ipc_json_describe_disabled_output(struct sway_output *output) {
357 return object; 429 return object;
358} 430}
359 431
432json_object *ipc_json_describe_non_desktop_output(struct sway_output_non_desktop *output) {
433 struct wlr_output *wlr_output = output->wlr_output;
434
435 json_object *object = json_object_new_object();
436
437 ipc_json_describe_wlr_output(wlr_output, object);
438
439 json_object_object_add(object, "non_desktop", json_object_new_boolean(true));
440 json_object_object_add(object, "type", json_object_new_string("output"));
441 json_object_object_add(object, "name",
442 json_object_new_string(wlr_output->name));
443
444 return object;
445}
446
360static json_object *ipc_json_describe_scratchpad_output(void) { 447static json_object *ipc_json_describe_scratchpad_output(void) {
361 struct wlr_box box; 448 struct wlr_box box;
362 root_get_box(root, &box); 449 root_get_box(root, &box);
@@ -369,11 +456,9 @@ static json_object *ipc_json_describe_scratchpad_output(void) {
369 json_object_new_int(container->node.id)); 456 json_object_new_int(container->node.id));
370 } 457 }
371 458
372 json_object *workspace = ipc_json_create_node(i3_scratch_id, 459 json_object *workspace = ipc_json_create_node(i3_scratch_id, "workspace",
373 "__i3_scratch", false, workspace_focus, &box); 460 "__i3_scratch", false, workspace_focus, &box);
374 json_object_object_add(workspace, "fullscreen_mode", json_object_new_int(1)); 461 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 462
378 // List all hidden scratchpad containers as floating nodes 463 // List all hidden scratchpad containers as floating nodes
379 json_object *floating_array = json_object_new_array(); 464 json_object *floating_array = json_object_new_array();
@@ -390,10 +475,8 @@ static json_object *ipc_json_describe_scratchpad_output(void) {
390 json_object *output_focus = json_object_new_array(); 475 json_object *output_focus = json_object_new_array();
391 json_object_array_add(output_focus, json_object_new_int(i3_scratch_id)); 476 json_object_array_add(output_focus, json_object_new_int(i3_scratch_id));
392 477
393 json_object *output = ipc_json_create_node(i3_output_id, 478 json_object *output = ipc_json_create_node(i3_output_id, "output",
394 "__i3", false, output_focus, &box); 479 "__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", 480 json_object_object_add(output, "layout",
398 json_object_new_string("output")); 481 json_object_new_string("output"));
399 482
@@ -423,7 +506,6 @@ static void ipc_json_describe_workspace(struct sway_workspace *workspace,
423 json_object_object_add(object, "fullscreen_mode", json_object_new_int(1)); 506 json_object_object_add(object, "fullscreen_mode", json_object_new_int(1));
424 json_object_object_add(object, "output", workspace->output ? 507 json_object_object_add(object, "output", workspace->output ?
425 json_object_new_string(workspace->output->wlr_output->name) : NULL); 508 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", 509 json_object_object_add(object, "urgent",
428 json_object_new_boolean(workspace->urgent)); 510 json_object_new_boolean(workspace->urgent));
429 json_object_object_add(object, "representation", workspace->representation ? 511 json_object_object_add(object, "representation", workspace->representation ?
@@ -448,30 +530,32 @@ static void ipc_json_describe_workspace(struct sway_workspace *workspace,
448 530
449static void get_deco_rect(struct sway_container *c, struct wlr_box *deco_rect) { 531static void get_deco_rect(struct sway_container *c, struct wlr_box *deco_rect) {
450 enum sway_container_layout parent_layout = container_parent_layout(c); 532 enum sway_container_layout parent_layout = container_parent_layout(c);
451 bool tab_or_stack = parent_layout == L_TABBED || parent_layout == L_STACKED; 533 list_t *siblings = container_get_siblings(c);
534 bool tab_or_stack = (parent_layout == L_TABBED || parent_layout == L_STACKED)
535 && ((siblings && siblings->length > 1) || !config->hide_lone_tab);
452 if (((!tab_or_stack || container_is_floating(c)) && 536 if (((!tab_or_stack || container_is_floating(c)) &&
453 c->current.border != B_NORMAL) || 537 c->current.border != B_NORMAL) ||
454 c->fullscreen_mode != FULLSCREEN_NONE || 538 c->pending.fullscreen_mode != FULLSCREEN_NONE ||
455 c->workspace == NULL) { 539 c->pending.workspace == NULL) {
456 deco_rect->x = deco_rect->y = deco_rect->width = deco_rect->height = 0; 540 deco_rect->x = deco_rect->y = deco_rect->width = deco_rect->height = 0;
457 return; 541 return;
458 } 542 }
459 543
460 if (c->parent) { 544 if (c->pending.parent) {
461 deco_rect->x = c->x - c->parent->x; 545 deco_rect->x = c->pending.x - c->pending.parent->pending.x;
462 deco_rect->y = c->y - c->parent->y; 546 deco_rect->y = c->pending.y - c->pending.parent->pending.y;
463 } else { 547 } else {
464 deco_rect->x = c->x - c->workspace->x; 548 deco_rect->x = c->pending.x - c->pending.workspace->x;
465 deco_rect->y = c->y - c->workspace->y; 549 deco_rect->y = c->pending.y - c->pending.workspace->y;
466 } 550 }
467 deco_rect->width = c->width; 551 deco_rect->width = c->pending.width;
468 deco_rect->height = container_titlebar_height(); 552 deco_rect->height = container_titlebar_height();
469 553
470 if (!container_is_floating(c)) { 554 if (!container_is_floating(c)) {
471 if (parent_layout == L_TABBED) { 555 if (parent_layout == L_TABBED) {
472 deco_rect->width = c->parent 556 deco_rect->width = c->pending.parent
473 ? c->parent->width / c->parent->children->length 557 ? c->pending.parent->pending.width / c->pending.parent->pending.children->length
474 : c->workspace->width / c->workspace->tiling->length; 558 : c->pending.workspace->width / c->pending.workspace->tiling->length;
475 deco_rect->x += deco_rect->width * container_sibling_index(c); 559 deco_rect->x += deco_rect->width * container_sibling_index(c);
476 } else if (parent_layout == L_STACKED) { 560 } else if (parent_layout == L_STACKED) {
477 if (!c->view) { 561 if (!c->view) {
@@ -494,10 +578,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)); 578 json_object_object_add(object, "visible", json_object_new_boolean(visible));
495 579
496 struct wlr_box window_box = { 580 struct wlr_box window_box = {
497 c->content_x - c->x, 581 c->pending.content_x - c->pending.x,
498 (c->current.border == B_PIXEL) ? c->current.border_thickness : 0, 582 (c->current.border == B_PIXEL) ? c->pending.content_y - c->pending.y : 0,
499 c->content_width, 583 c->pending.content_width,
500 c->content_height 584 c->pending.content_height
501 }; 585 };
502 586
503 json_object_object_add(object, "window_rect", ipc_json_create_rect(&window_box)); 587 json_object_object_add(object, "window_rect", ipc_json_create_rect(&window_box));
@@ -539,6 +623,16 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object
539 623
540 json_object_object_add(object, "idle_inhibitors", idle_inhibitors); 624 json_object_object_add(object, "idle_inhibitors", idle_inhibitors);
541 625
626 enum wp_content_type_v1_type content_type = WP_CONTENT_TYPE_V1_TYPE_NONE;
627 if (c->view->surface != NULL) {
628 content_type = wlr_surface_get_content_type_v1(server.content_type_manager_v1,
629 c->view->surface);
630 }
631 if (content_type != WP_CONTENT_TYPE_V1_TYPE_NONE) {
632 json_object_object_add(object, "content_type",
633 json_object_new_string(ipc_json_content_type_description(content_type)));
634 }
635
542#if HAVE_XWAYLAND 636#if HAVE_XWAYLAND
543 if (c->view->type == SWAY_VIEW_XWAYLAND) { 637 if (c->view->type == SWAY_VIEW_XWAYLAND) {
544 json_object_object_add(object, "window", 638 json_object_object_add(object, "window",
@@ -583,24 +677,35 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object
583static void ipc_json_describe_container(struct sway_container *c, json_object *object) { 677static void ipc_json_describe_container(struct sway_container *c, json_object *object) {
584 json_object_object_add(object, "name", 678 json_object_object_add(object, "name",
585 c->title ? json_object_new_string(c->title) : NULL); 679 c->title ? json_object_new_string(c->title) : NULL);
586 json_object_object_add(object, "type", 680 bool floating = container_is_floating(c);
587 json_object_new_string(container_is_floating(c) ? "floating_con" : "con")); 681 if (floating) {
682 json_object_object_add(object, "type",
683 json_object_new_string("floating_con"));
684 }
588 685
589 json_object_object_add(object, "layout", 686 json_object_object_add(object, "layout",
590 json_object_new_string( 687 json_object_new_string(
591 ipc_json_layout_description(c->layout))); 688 ipc_json_layout_description(c->pending.layout)));
592 689
593 json_object_object_add(object, "orientation", 690 json_object_object_add(object, "orientation",
594 json_object_new_string( 691 json_object_new_string(
595 ipc_json_orientation_description(c->layout))); 692 ipc_json_orientation_description(c->pending.layout)));
596 693
597 bool urgent = c->view ? 694 bool urgent = c->view ?
598 view_is_urgent(c->view) : container_has_urgent_child(c); 695 view_is_urgent(c->view) : container_has_urgent_child(c);
599 json_object_object_add(object, "urgent", json_object_new_boolean(urgent)); 696 json_object_object_add(object, "urgent", json_object_new_boolean(urgent));
600 json_object_object_add(object, "sticky", json_object_new_boolean(c->is_sticky)); 697 json_object_object_add(object, "sticky", json_object_new_boolean(c->is_sticky));
601 698
699 // sway doesn't track the floating reason, so we can't use "auto_on" or "user_off"
700 json_object_object_add(object, "floating",
701 json_object_new_string(floating ? "user_on" : "auto_off"));
702
602 json_object_object_add(object, "fullscreen_mode", 703 json_object_object_add(object, "fullscreen_mode",
603 json_object_new_int(c->fullscreen_mode)); 704 json_object_new_int(c->pending.fullscreen_mode));
705
706 // sway doesn't track if window was resized in scratchpad, so we can't use "changed"
707 json_object_object_add(object, "scratchpad_state",
708 json_object_new_string(!c->scratchpad ? "none" : "fresh"));
604 709
605 struct sway_node *parent = node_get_parent(&c->node); 710 struct sway_node *parent = node_get_parent(&c->node);
606 struct wlr_box parent_box = {0, 0, 0, 0}; 711 struct wlr_box parent_box = {0, 0, 0, 0};
@@ -610,8 +715,8 @@ static void ipc_json_describe_container(struct sway_container *c, json_object *o
610 } 715 }
611 716
612 if (parent_box.width != 0 && parent_box.height != 0) { 717 if (parent_box.width != 0 && parent_box.height != 0) {
613 double percent = ((double)c->width / parent_box.width) 718 double percent = ((double)c->pending.width / parent_box.width)
614 * ((double)c->height / parent_box.height); 719 * ((double)c->pending.height / parent_box.height);
615 json_object_object_add(object, "percent", json_object_new_double(percent)); 720 json_object_object_add(object, "percent", json_object_new_double(percent));
616 } 721 }
617 722
@@ -692,15 +797,14 @@ json_object *ipc_json_describe_node(struct sway_node *node) {
692 }; 797 };
693 seat_for_each_node(seat, focus_inactive_children_iterator, &data); 798 seat_for_each_node(seat, focus_inactive_children_iterator, &data);
694 799
695 json_object *object = ipc_json_create_node( 800 json_object *object = ipc_json_create_node((int)node->id,
696 (int)node->id, name, focused, focus, &box); 801 ipc_json_node_type_description(node->type), name, focused, focus, &box);
697 802
698 switch (node->type) { 803 switch (node->type) {
699 case N_ROOT: 804 case N_ROOT:
700 ipc_json_describe_root(root, object);
701 break; 805 break;
702 case N_OUTPUT: 806 case N_OUTPUT:
703 ipc_json_describe_output(node->sway_output, object); 807 ipc_json_describe_enabled_output(node->sway_output, object);
704 break; 808 break;
705 case N_CONTAINER: 809 case N_CONTAINER:
706 ipc_json_describe_container(node->sway_container, object); 810 ipc_json_describe_container(node->sway_container, object);
@@ -743,10 +847,10 @@ json_object *ipc_json_describe_node_recursive(struct sway_node *node) {
743 } 847 }
744 break; 848 break;
745 case N_CONTAINER: 849 case N_CONTAINER:
746 if (node->sway_container->children) { 850 if (node->sway_container->pending.children) {
747 for (i = 0; i < node->sway_container->children->length; ++i) { 851 for (i = 0; i < node->sway_container->pending.children->length; ++i) {
748 struct sway_container *child = 852 struct sway_container *child =
749 node->sway_container->children->items[i]; 853 node->sway_container->pending.children->items[i];
750 json_object_array_add(children, 854 json_object_array_add(children,
751 ipc_json_describe_node_recursive(&child->node)); 855 ipc_json_describe_node_recursive(&child->node));
752 } 856 }
@@ -758,6 +862,7 @@ json_object *ipc_json_describe_node_recursive(struct sway_node *node) {
758 return object; 862 return object;
759} 863}
760 864
865#if WLR_HAS_LIBINPUT_BACKEND
761static json_object *describe_libinput_device(struct libinput_device *device) { 866static json_object *describe_libinput_device(struct libinput_device *device) {
762 json_object *object = json_object_new_object(); 867 json_object *object = json_object_new_object();
763 868
@@ -841,6 +946,11 @@ static json_object *describe_libinput_device(struct libinput_device *device) {
841 case LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE: 946 case LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE:
842 accel_profile = "adaptive"; 947 accel_profile = "adaptive";
843 break; 948 break;
949#if HAVE_LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM
950 case LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM:
951 accel_profile = "custom";
952 break;
953#endif
844 } 954 }
845 json_object_object_add(object, "accel_profile", 955 json_object_object_add(object, "accel_profile",
846 json_object_new_string(accel_profile)); 956 json_object_new_string(accel_profile));
@@ -920,6 +1030,17 @@ static json_object *describe_libinput_device(struct libinput_device *device) {
920 uint32_t button = libinput_device_config_scroll_get_button(device); 1030 uint32_t button = libinput_device_config_scroll_get_button(device);
921 json_object_object_add(object, "scroll_button", 1031 json_object_object_add(object, "scroll_button",
922 json_object_new_int(button)); 1032 json_object_new_int(button));
1033 const char *lock = "unknown";
1034 switch (libinput_device_config_scroll_get_button_lock(device)) {
1035 case LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_ENABLED:
1036 lock = "enabled";
1037 break;
1038 case LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED:
1039 lock = "disabled";
1040 break;
1041 }
1042 json_object_object_add(object, "scroll_button_lock",
1043 json_object_new_string(lock));
923 } 1044 }
924 } 1045 }
925 1046
@@ -936,6 +1057,19 @@ static json_object *describe_libinput_device(struct libinput_device *device) {
936 json_object_object_add(object, "dwt", json_object_new_string(dwt)); 1057 json_object_object_add(object, "dwt", json_object_new_string(dwt));
937 } 1058 }
938 1059
1060 if (libinput_device_config_dwtp_is_available(device)) {
1061 const char *dwtp = "unknown";
1062 switch (libinput_device_config_dwtp_get_enabled(device)) {
1063 case LIBINPUT_CONFIG_DWTP_ENABLED:
1064 dwtp = "enabled";
1065 break;
1066 case LIBINPUT_CONFIG_DWTP_DISABLED:
1067 dwtp = "disabled";
1068 break;
1069 }
1070 json_object_object_add(object, "dwtp", json_object_new_string(dwtp));
1071 }
1072
939 if (libinput_device_config_calibration_has_matrix(device)) { 1073 if (libinput_device_config_calibration_has_matrix(device)) {
940 float matrix[6]; 1074 float matrix[6];
941 libinput_device_config_calibration_get_matrix(device, matrix); 1075 libinput_device_config_calibration_get_matrix(device, matrix);
@@ -950,6 +1084,7 @@ static json_object *describe_libinput_device(struct libinput_device *device) {
950 1084
951 return object; 1085 return object;
952} 1086}
1087#endif
953 1088
954json_object *ipc_json_describe_input(struct sway_input_device *device) { 1089json_object *ipc_json_describe_input(struct sway_input_device *device) {
955 if (!(sway_assert(device, "Device must not be null"))) { 1090 if (!(sway_assert(device, "Device must not be null"))) {
@@ -962,19 +1097,21 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) {
962 json_object_new_string(device->identifier)); 1097 json_object_new_string(device->identifier));
963 json_object_object_add(object, "name", 1098 json_object_object_add(object, "name",
964 json_object_new_string(device->wlr_device->name)); 1099 json_object_new_string(device->wlr_device->name));
965 json_object_object_add(object, "vendor",
966 json_object_new_int(device->wlr_device->vendor));
967 json_object_object_add(object, "product",
968 json_object_new_int(device->wlr_device->product));
969 json_object_object_add(object, "type", 1100 json_object_object_add(object, "type",
970 json_object_new_string( 1101 json_object_new_string(
971 input_device_get_type(device))); 1102 input_device_get_type(device)));
972 1103
973 if (device->wlr_device->type == WLR_INPUT_DEVICE_KEYBOARD) { 1104 if (device->wlr_device->type == WLR_INPUT_DEVICE_KEYBOARD) {
974 struct wlr_keyboard *keyboard = device->wlr_device->keyboard; 1105 struct wlr_keyboard *keyboard =
1106 wlr_keyboard_from_input_device(device->wlr_device);
975 struct xkb_keymap *keymap = keyboard->keymap; 1107 struct xkb_keymap *keymap = keyboard->keymap;
976 struct xkb_state *state = keyboard->xkb_state; 1108 struct xkb_state *state = keyboard->xkb_state;
977 1109
1110 json_object_object_add(object, "repeat_delay",
1111 json_object_new_int(keyboard->repeat_info.delay));
1112 json_object_object_add(object, "repeat_rate",
1113 json_object_new_int(keyboard->repeat_info.rate));
1114
978 json_object *layouts_arr = json_object_new_array(); 1115 json_object *layouts_arr = json_object_new_array();
979 json_object_object_add(object, "xkb_layout_names", layouts_arr); 1116 json_object_object_add(object, "xkb_layout_names", layouts_arr);
980 1117
@@ -996,12 +1133,29 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) {
996 } 1133 }
997 } 1134 }
998 1135
1136 if (device->wlr_device->type == WLR_INPUT_DEVICE_POINTER) {
1137 struct input_config *ic = input_device_get_config(device);
1138 float scroll_factor = 1.0f;
1139 if (ic != NULL && !isnan(ic->scroll_factor) &&
1140 ic->scroll_factor != FLT_MIN) {
1141 scroll_factor = ic->scroll_factor;
1142 }
1143 json_object_object_add(object, "scroll_factor",
1144 json_object_new_double(scroll_factor));
1145 }
1146
1147#if WLR_HAS_LIBINPUT_BACKEND
999 if (wlr_input_device_is_libinput(device->wlr_device)) { 1148 if (wlr_input_device_is_libinput(device->wlr_device)) {
1000 struct libinput_device *libinput_dev; 1149 struct libinput_device *libinput_dev;
1001 libinput_dev = wlr_libinput_get_device_handle(device->wlr_device); 1150 libinput_dev = wlr_libinput_get_device_handle(device->wlr_device);
1002 json_object_object_add(object, "libinput", 1151 json_object_object_add(object, "libinput",
1003 describe_libinput_device(libinput_dev)); 1152 describe_libinput_device(libinput_dev));
1153 json_object_object_add(object, "vendor",
1154 json_object_new_int(libinput_device_get_id_vendor(libinput_dev)));
1155 json_object_object_add(object, "product",
1156 json_object_new_int(libinput_device_get_id_product(libinput_dev)));
1004 } 1157 }
1158#endif
1005 1159
1006 return object; 1160 return object;
1007} 1161}
@@ -1109,7 +1263,9 @@ json_object *ipc_json_describe_bar_config(struct bar_config *bar) {
1109 json_object_object_add(json, "verbose", 1263 json_object_object_add(json, "verbose",
1110 json_object_new_boolean(bar->verbose)); 1264 json_object_new_boolean(bar->verbose));
1111 json_object_object_add(json, "pango_markup", 1265 json_object_object_add(json, "pango_markup",
1112 json_object_new_boolean(bar->pango_markup)); 1266 json_object_new_boolean(bar->pango_markup == PANGO_MARKUP_DEFAULT
1267 ? config->pango_markup
1268 : bar->pango_markup));
1113 1269
1114 json_object *colors = json_object_new_object(); 1270 json_object *colors = json_object_new_object();
1115 json_object_object_add(colors, "background", 1271 json_object_object_add(colors, "background",