diff options
Diffstat (limited to 'sway/ipc-json.c')
-rw-r--r-- | sway/ipc-json.c | 361 |
1 files changed, 253 insertions, 108 deletions
diff --git a/sway/ipc-json.c b/sway/ipc-json.c index fceee84d..58356d4e 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 | |||
23 | static const int i3_output_id = INT32_MAX; | 28 | static const int i3_output_id = INT32_MAX; |
24 | static const int i3_scratch_id = INT32_MAX - 1; | 29 | static const int i3_scratch_id = INT32_MAX - 1; |
25 | 30 | ||
31 | static 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 | |||
26 | static const char *ipc_json_layout_description(enum sway_container_layout l) { | 45 | static 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 | ||
124 | static 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 | |||
141 | static 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 |
108 | static const char *ipc_json_xwindow_type_description(struct sway_view *view) { | 158 | static 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 | ||
209 | static 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 | |||
159 | json_object *ipc_json_get_version(void) { | 223 | json_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 | ||
192 | static json_object *ipc_json_create_node(int id, char *name, | 256 | static 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,66 @@ 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)); |
226 | 291 | ||
227 | return object; | 292 | return object; |
228 | } | 293 | } |
229 | 294 | ||
230 | static void ipc_json_describe_root(struct sway_root *root, json_object *object) { | 295 | static 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")); | 296 | json_object_object_add(object, "primary", json_object_new_boolean(false)); |
297 | json_object_object_add(object, "make", | ||
298 | json_object_new_string(wlr_output->make ? wlr_output->make : "Unknown")); | ||
299 | json_object_object_add(object, "model", | ||
300 | json_object_new_string(wlr_output->model ? wlr_output->model : "Unknown")); | ||
301 | json_object_object_add(object, "serial", | ||
302 | json_object_new_string(wlr_output->serial ? wlr_output->serial : "Unknown")); | ||
303 | |||
304 | json_object *modes_array = json_object_new_array(); | ||
305 | struct wlr_output_mode *mode; | ||
306 | wl_list_for_each(mode, &wlr_output->modes, link) { | ||
307 | json_object *mode_object = json_object_new_object(); | ||
308 | json_object_object_add(mode_object, "width", | ||
309 | json_object_new_int(mode->width)); | ||
310 | json_object_object_add(mode_object, "height", | ||
311 | json_object_new_int(mode->height)); | ||
312 | json_object_object_add(mode_object, "refresh", | ||
313 | json_object_new_int(mode->refresh)); | ||
314 | json_object_array_add(modes_array, mode_object); | ||
315 | } | ||
316 | json_object_object_add(object, "modes", modes_array); | ||
232 | } | 317 | } |
233 | 318 | ||
234 | static void ipc_json_describe_output(struct sway_output *output, | 319 | static void ipc_json_describe_output(struct sway_output *output, |
235 | json_object *object) { | 320 | json_object *object) { |
321 | ipc_json_describe_wlr_output(output->wlr_output, object); | ||
322 | } | ||
323 | |||
324 | static void ipc_json_describe_enabled_output(struct sway_output *output, | ||
325 | json_object *object) { | ||
326 | ipc_json_describe_output(output, object); | ||
327 | |||
236 | struct wlr_output *wlr_output = output->wlr_output; | 328 | struct wlr_output *wlr_output = output->wlr_output; |
237 | json_object_object_add(object, "type", json_object_new_string("output")); | 329 | json_object_object_add(object, "non_desktop", json_object_new_boolean(false)); |
238 | json_object_object_add(object, "active", json_object_new_boolean(true)); | 330 | json_object_object_add(object, "active", json_object_new_boolean(true)); |
239 | json_object_object_add(object, "dpms", | 331 | json_object_object_add(object, "dpms", |
240 | json_object_new_boolean(wlr_output->enabled)); | 332 | json_object_new_boolean(wlr_output->enabled)); |
241 | json_object_object_add(object, "primary", json_object_new_boolean(false)); | 333 | json_object_object_add(object, "power", |
334 | json_object_new_boolean(wlr_output->enabled)); | ||
242 | json_object_object_add(object, "layout", json_object_new_string("output")); | 335 | json_object_object_add(object, "layout", json_object_new_string("output")); |
243 | json_object_object_add(object, "orientation", | 336 | json_object_object_add(object, "orientation", |
244 | json_object_new_string( | 337 | json_object_new_string( |
245 | ipc_json_orientation_description(L_NONE))); | 338 | 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", | 339 | json_object_object_add(object, "scale", |
253 | json_object_new_double(wlr_output->scale)); | 340 | json_object_new_double(wlr_output->scale)); |
254 | json_object_object_add(object, "scale_filter", | 341 | json_object_object_add(object, "scale_filter", |
@@ -273,25 +360,26 @@ static void ipc_json_describe_output(struct sway_output *output, | |||
273 | json_object *modes_array = json_object_new_array(); | 360 | json_object *modes_array = json_object_new_array(); |
274 | struct wlr_output_mode *mode; | 361 | struct wlr_output_mode *mode; |
275 | wl_list_for_each(mode, &wlr_output->modes, link) { | 362 | wl_list_for_each(mode, &wlr_output->modes, link) { |
276 | json_object *mode_object = json_object_new_object(); | 363 | json_object *mode_object = |
277 | json_object_object_add(mode_object, "width", | 364 | 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); | 365 | json_object_array_add(modes_array, mode_object); |
284 | } | 366 | } |
285 | 367 | ||
286 | json_object_object_add(object, "modes", modes_array); | 368 | json_object_object_add(object, "modes", modes_array); |
287 | 369 | ||
288 | json_object *current_mode_object = json_object_new_object(); | 370 | json_object *current_mode_object; |
289 | json_object_object_add(current_mode_object, "width", | 371 | if (wlr_output->current_mode != NULL) { |
290 | json_object_new_int(wlr_output->width)); | 372 | current_mode_object = |
291 | json_object_object_add(current_mode_object, "height", | 373 | ipc_json_output_mode_description(wlr_output->current_mode); |
292 | json_object_new_int(wlr_output->height)); | 374 | } else { |
293 | json_object_object_add(current_mode_object, "refresh", | 375 | current_mode_object = json_object_new_object(); |
294 | json_object_new_int(wlr_output->refresh)); | 376 | json_object_object_add(current_mode_object, "width", |
377 | json_object_new_int(wlr_output->width)); | ||
378 | json_object_object_add(current_mode_object, "height", | ||
379 | json_object_new_int(wlr_output->height)); | ||
380 | json_object_object_add(current_mode_object, "refresh", | ||
381 | json_object_new_int(wlr_output->refresh)); | ||
382 | } | ||
295 | json_object_object_add(object, "current_mode", current_mode_object); | 383 | json_object_object_add(object, "current_mode", current_mode_object); |
296 | 384 | ||
297 | struct sway_node *parent = node_get_parent(&output->node); | 385 | struct sway_node *parent = node_get_parent(&output->node); |
@@ -315,33 +403,15 @@ json_object *ipc_json_describe_disabled_output(struct sway_output *output) { | |||
315 | 403 | ||
316 | json_object *object = json_object_new_object(); | 404 | json_object *object = json_object_new_object(); |
317 | 405 | ||
406 | ipc_json_describe_output(output, object); | ||
407 | |||
408 | json_object_object_add(object, "non_desktop", json_object_new_boolean(false)); | ||
318 | json_object_object_add(object, "type", json_object_new_string("output")); | 409 | json_object_object_add(object, "type", json_object_new_string("output")); |
319 | json_object_object_add(object, "name", | 410 | json_object_object_add(object, "name", |
320 | json_object_new_string(wlr_output->name)); | 411 | json_object_new_string(wlr_output->name)); |
321 | json_object_object_add(object, "active", json_object_new_boolean(false)); | 412 | json_object_object_add(object, "active", json_object_new_boolean(false)); |
322 | json_object_object_add(object, "dpms", json_object_new_boolean(false)); | 413 | json_object_object_add(object, "dpms", json_object_new_boolean(false)); |
323 | json_object_object_add(object, "primary", json_object_new_boolean(false)); | 414 | 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 | 415 | ||
346 | json_object_object_add(object, "current_workspace", NULL); | 416 | json_object_object_add(object, "current_workspace", NULL); |
347 | 417 | ||
@@ -357,6 +427,21 @@ json_object *ipc_json_describe_disabled_output(struct sway_output *output) { | |||
357 | return object; | 427 | return object; |
358 | } | 428 | } |
359 | 429 | ||
430 | json_object *ipc_json_describe_non_desktop_output(struct sway_output_non_desktop *output) { | ||
431 | struct wlr_output *wlr_output = output->wlr_output; | ||
432 | |||
433 | json_object *object = json_object_new_object(); | ||
434 | |||
435 | ipc_json_describe_wlr_output(wlr_output, object); | ||
436 | |||
437 | json_object_object_add(object, "non_desktop", json_object_new_boolean(true)); | ||
438 | json_object_object_add(object, "type", json_object_new_string("output")); | ||
439 | json_object_object_add(object, "name", | ||
440 | json_object_new_string(wlr_output->name)); | ||
441 | |||
442 | return object; | ||
443 | } | ||
444 | |||
360 | static json_object *ipc_json_describe_scratchpad_output(void) { | 445 | static json_object *ipc_json_describe_scratchpad_output(void) { |
361 | struct wlr_box box; | 446 | struct wlr_box box; |
362 | root_get_box(root, &box); | 447 | root_get_box(root, &box); |
@@ -369,11 +454,9 @@ static json_object *ipc_json_describe_scratchpad_output(void) { | |||
369 | json_object_new_int(container->node.id)); | 454 | json_object_new_int(container->node.id)); |
370 | } | 455 | } |
371 | 456 | ||
372 | json_object *workspace = ipc_json_create_node(i3_scratch_id, | 457 | json_object *workspace = ipc_json_create_node(i3_scratch_id, "workspace", |
373 | "__i3_scratch", false, workspace_focus, &box); | 458 | "__i3_scratch", false, workspace_focus, &box); |
374 | json_object_object_add(workspace, "fullscreen_mode", json_object_new_int(1)); | 459 | 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 | 460 | ||
378 | // List all hidden scratchpad containers as floating nodes | 461 | // List all hidden scratchpad containers as floating nodes |
379 | json_object *floating_array = json_object_new_array(); | 462 | json_object *floating_array = json_object_new_array(); |
@@ -390,10 +473,8 @@ static json_object *ipc_json_describe_scratchpad_output(void) { | |||
390 | json_object *output_focus = json_object_new_array(); | 473 | json_object *output_focus = json_object_new_array(); |
391 | json_object_array_add(output_focus, json_object_new_int(i3_scratch_id)); | 474 | json_object_array_add(output_focus, json_object_new_int(i3_scratch_id)); |
392 | 475 | ||
393 | json_object *output = ipc_json_create_node(i3_output_id, | 476 | json_object *output = ipc_json_create_node(i3_output_id, "output", |
394 | "__i3", false, output_focus, &box); | 477 | "__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", | 478 | json_object_object_add(output, "layout", |
398 | json_object_new_string("output")); | 479 | json_object_new_string("output")); |
399 | 480 | ||
@@ -423,7 +504,6 @@ static void ipc_json_describe_workspace(struct sway_workspace *workspace, | |||
423 | json_object_object_add(object, "fullscreen_mode", json_object_new_int(1)); | 504 | json_object_object_add(object, "fullscreen_mode", json_object_new_int(1)); |
424 | json_object_object_add(object, "output", workspace->output ? | 505 | json_object_object_add(object, "output", workspace->output ? |
425 | json_object_new_string(workspace->output->wlr_output->name) : NULL); | 506 | 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", | 507 | json_object_object_add(object, "urgent", |
428 | json_object_new_boolean(workspace->urgent)); | 508 | json_object_new_boolean(workspace->urgent)); |
429 | json_object_object_add(object, "representation", workspace->representation ? | 509 | json_object_object_add(object, "representation", workspace->representation ? |
@@ -448,30 +528,32 @@ static void ipc_json_describe_workspace(struct sway_workspace *workspace, | |||
448 | 528 | ||
449 | static void get_deco_rect(struct sway_container *c, struct wlr_box *deco_rect) { | 529 | static void get_deco_rect(struct sway_container *c, struct wlr_box *deco_rect) { |
450 | enum sway_container_layout parent_layout = container_parent_layout(c); | 530 | enum sway_container_layout parent_layout = container_parent_layout(c); |
451 | bool tab_or_stack = parent_layout == L_TABBED || parent_layout == L_STACKED; | 531 | list_t *siblings = container_get_siblings(c); |
532 | bool tab_or_stack = (parent_layout == L_TABBED || parent_layout == L_STACKED) | ||
533 | && ((siblings && siblings->length > 1) || !config->hide_lone_tab); | ||
452 | if (((!tab_or_stack || container_is_floating(c)) && | 534 | if (((!tab_or_stack || container_is_floating(c)) && |
453 | c->current.border != B_NORMAL) || | 535 | c->current.border != B_NORMAL) || |
454 | c->fullscreen_mode != FULLSCREEN_NONE || | 536 | c->pending.fullscreen_mode != FULLSCREEN_NONE || |
455 | c->workspace == NULL) { | 537 | c->pending.workspace == NULL) { |
456 | deco_rect->x = deco_rect->y = deco_rect->width = deco_rect->height = 0; | 538 | deco_rect->x = deco_rect->y = deco_rect->width = deco_rect->height = 0; |
457 | return; | 539 | return; |
458 | } | 540 | } |
459 | 541 | ||
460 | if (c->parent) { | 542 | if (c->pending.parent) { |
461 | deco_rect->x = c->x - c->parent->x; | 543 | deco_rect->x = c->pending.x - c->pending.parent->pending.x; |
462 | deco_rect->y = c->y - c->parent->y; | 544 | deco_rect->y = c->pending.y - c->pending.parent->pending.y; |
463 | } else { | 545 | } else { |
464 | deco_rect->x = c->x - c->workspace->x; | 546 | deco_rect->x = c->pending.x - c->pending.workspace->x; |
465 | deco_rect->y = c->y - c->workspace->y; | 547 | deco_rect->y = c->pending.y - c->pending.workspace->y; |
466 | } | 548 | } |
467 | deco_rect->width = c->width; | 549 | deco_rect->width = c->pending.width; |
468 | deco_rect->height = container_titlebar_height(); | 550 | deco_rect->height = container_titlebar_height(); |
469 | 551 | ||
470 | if (!container_is_floating(c)) { | 552 | if (!container_is_floating(c)) { |
471 | if (parent_layout == L_TABBED) { | 553 | if (parent_layout == L_TABBED) { |
472 | deco_rect->width = c->parent | 554 | deco_rect->width = c->pending.parent |
473 | ? c->parent->width / c->parent->children->length | 555 | ? c->pending.parent->pending.width / c->pending.parent->pending.children->length |
474 | : c->workspace->width / c->workspace->tiling->length; | 556 | : c->pending.workspace->width / c->pending.workspace->tiling->length; |
475 | deco_rect->x += deco_rect->width * container_sibling_index(c); | 557 | deco_rect->x += deco_rect->width * container_sibling_index(c); |
476 | } else if (parent_layout == L_STACKED) { | 558 | } else if (parent_layout == L_STACKED) { |
477 | if (!c->view) { | 559 | if (!c->view) { |
@@ -494,10 +576,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)); | 576 | json_object_object_add(object, "visible", json_object_new_boolean(visible)); |
495 | 577 | ||
496 | struct wlr_box window_box = { | 578 | struct wlr_box window_box = { |
497 | c->content_x - c->x, | 579 | c->pending.content_x - c->pending.x, |
498 | (c->current.border == B_PIXEL) ? c->current.border_thickness : 0, | 580 | (c->current.border == B_PIXEL) ? c->pending.content_y - c->pending.y : 0, |
499 | c->content_width, | 581 | c->pending.content_width, |
500 | c->content_height | 582 | c->pending.content_height |
501 | }; | 583 | }; |
502 | 584 | ||
503 | json_object_object_add(object, "window_rect", ipc_json_create_rect(&window_box)); | 585 | json_object_object_add(object, "window_rect", ipc_json_create_rect(&window_box)); |
@@ -539,6 +621,16 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object | |||
539 | 621 | ||
540 | json_object_object_add(object, "idle_inhibitors", idle_inhibitors); | 622 | json_object_object_add(object, "idle_inhibitors", idle_inhibitors); |
541 | 623 | ||
624 | enum wp_content_type_v1_type content_type = WP_CONTENT_TYPE_V1_TYPE_NONE; | ||
625 | if (c->view->surface != NULL) { | ||
626 | content_type = wlr_surface_get_content_type_v1(server.content_type_manager_v1, | ||
627 | c->view->surface); | ||
628 | } | ||
629 | if (content_type != WP_CONTENT_TYPE_V1_TYPE_NONE) { | ||
630 | json_object_object_add(object, "content_type", | ||
631 | json_object_new_string(ipc_json_content_type_description(content_type))); | ||
632 | } | ||
633 | |||
542 | #if HAVE_XWAYLAND | 634 | #if HAVE_XWAYLAND |
543 | if (c->view->type == SWAY_VIEW_XWAYLAND) { | 635 | if (c->view->type == SWAY_VIEW_XWAYLAND) { |
544 | json_object_object_add(object, "window", | 636 | json_object_object_add(object, "window", |
@@ -583,16 +675,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) { | 675 | static void ipc_json_describe_container(struct sway_container *c, json_object *object) { |
584 | json_object_object_add(object, "name", | 676 | json_object_object_add(object, "name", |
585 | c->title ? json_object_new_string(c->title) : NULL); | 677 | c->title ? json_object_new_string(c->title) : NULL); |
586 | json_object_object_add(object, "type", | 678 | if (container_is_floating(c)) { |
587 | json_object_new_string(container_is_floating(c) ? "floating_con" : "con")); | 679 | json_object_object_add(object, "type", |
680 | json_object_new_string("floating_con")); | ||
681 | } | ||
588 | 682 | ||
589 | json_object_object_add(object, "layout", | 683 | json_object_object_add(object, "layout", |
590 | json_object_new_string( | 684 | json_object_new_string( |
591 | ipc_json_layout_description(c->layout))); | 685 | ipc_json_layout_description(c->pending.layout))); |
592 | 686 | ||
593 | json_object_object_add(object, "orientation", | 687 | json_object_object_add(object, "orientation", |
594 | json_object_new_string( | 688 | json_object_new_string( |
595 | ipc_json_orientation_description(c->layout))); | 689 | ipc_json_orientation_description(c->pending.layout))); |
596 | 690 | ||
597 | bool urgent = c->view ? | 691 | bool urgent = c->view ? |
598 | view_is_urgent(c->view) : container_has_urgent_child(c); | 692 | view_is_urgent(c->view) : container_has_urgent_child(c); |
@@ -600,7 +694,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)); | 694 | json_object_object_add(object, "sticky", json_object_new_boolean(c->is_sticky)); |
601 | 695 | ||
602 | json_object_object_add(object, "fullscreen_mode", | 696 | json_object_object_add(object, "fullscreen_mode", |
603 | json_object_new_int(c->fullscreen_mode)); | 697 | json_object_new_int(c->pending.fullscreen_mode)); |
604 | 698 | ||
605 | struct sway_node *parent = node_get_parent(&c->node); | 699 | struct sway_node *parent = node_get_parent(&c->node); |
606 | struct wlr_box parent_box = {0, 0, 0, 0}; | 700 | struct wlr_box parent_box = {0, 0, 0, 0}; |
@@ -610,8 +704,8 @@ static void ipc_json_describe_container(struct sway_container *c, json_object *o | |||
610 | } | 704 | } |
611 | 705 | ||
612 | if (parent_box.width != 0 && parent_box.height != 0) { | 706 | if (parent_box.width != 0 && parent_box.height != 0) { |
613 | double percent = ((double)c->width / parent_box.width) | 707 | double percent = ((double)c->pending.width / parent_box.width) |
614 | * ((double)c->height / parent_box.height); | 708 | * ((double)c->pending.height / parent_box.height); |
615 | json_object_object_add(object, "percent", json_object_new_double(percent)); | 709 | json_object_object_add(object, "percent", json_object_new_double(percent)); |
616 | } | 710 | } |
617 | 711 | ||
@@ -692,15 +786,14 @@ json_object *ipc_json_describe_node(struct sway_node *node) { | |||
692 | }; | 786 | }; |
693 | seat_for_each_node(seat, focus_inactive_children_iterator, &data); | 787 | seat_for_each_node(seat, focus_inactive_children_iterator, &data); |
694 | 788 | ||
695 | json_object *object = ipc_json_create_node( | 789 | json_object *object = ipc_json_create_node((int)node->id, |
696 | (int)node->id, name, focused, focus, &box); | 790 | ipc_json_node_type_description(node->type), name, focused, focus, &box); |
697 | 791 | ||
698 | switch (node->type) { | 792 | switch (node->type) { |
699 | case N_ROOT: | 793 | case N_ROOT: |
700 | ipc_json_describe_root(root, object); | ||
701 | break; | 794 | break; |
702 | case N_OUTPUT: | 795 | case N_OUTPUT: |
703 | ipc_json_describe_output(node->sway_output, object); | 796 | ipc_json_describe_enabled_output(node->sway_output, object); |
704 | break; | 797 | break; |
705 | case N_CONTAINER: | 798 | case N_CONTAINER: |
706 | ipc_json_describe_container(node->sway_container, object); | 799 | ipc_json_describe_container(node->sway_container, object); |
@@ -743,10 +836,10 @@ json_object *ipc_json_describe_node_recursive(struct sway_node *node) { | |||
743 | } | 836 | } |
744 | break; | 837 | break; |
745 | case N_CONTAINER: | 838 | case N_CONTAINER: |
746 | if (node->sway_container->children) { | 839 | if (node->sway_container->pending.children) { |
747 | for (i = 0; i < node->sway_container->children->length; ++i) { | 840 | for (i = 0; i < node->sway_container->pending.children->length; ++i) { |
748 | struct sway_container *child = | 841 | struct sway_container *child = |
749 | node->sway_container->children->items[i]; | 842 | node->sway_container->pending.children->items[i]; |
750 | json_object_array_add(children, | 843 | json_object_array_add(children, |
751 | ipc_json_describe_node_recursive(&child->node)); | 844 | ipc_json_describe_node_recursive(&child->node)); |
752 | } | 845 | } |
@@ -758,6 +851,7 @@ json_object *ipc_json_describe_node_recursive(struct sway_node *node) { | |||
758 | return object; | 851 | return object; |
759 | } | 852 | } |
760 | 853 | ||
854 | #if WLR_HAS_LIBINPUT_BACKEND | ||
761 | static json_object *describe_libinput_device(struct libinput_device *device) { | 855 | static json_object *describe_libinput_device(struct libinput_device *device) { |
762 | json_object *object = json_object_new_object(); | 856 | json_object *object = json_object_new_object(); |
763 | 857 | ||
@@ -841,6 +935,11 @@ static json_object *describe_libinput_device(struct libinput_device *device) { | |||
841 | case LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE: | 935 | case LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE: |
842 | accel_profile = "adaptive"; | 936 | accel_profile = "adaptive"; |
843 | break; | 937 | break; |
938 | #if HAVE_LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM | ||
939 | case LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM: | ||
940 | accel_profile = "custom"; | ||
941 | break; | ||
942 | #endif | ||
844 | } | 943 | } |
845 | json_object_object_add(object, "accel_profile", | 944 | json_object_object_add(object, "accel_profile", |
846 | json_object_new_string(accel_profile)); | 945 | json_object_new_string(accel_profile)); |
@@ -920,6 +1019,17 @@ static json_object *describe_libinput_device(struct libinput_device *device) { | |||
920 | uint32_t button = libinput_device_config_scroll_get_button(device); | 1019 | uint32_t button = libinput_device_config_scroll_get_button(device); |
921 | json_object_object_add(object, "scroll_button", | 1020 | json_object_object_add(object, "scroll_button", |
922 | json_object_new_int(button)); | 1021 | json_object_new_int(button)); |
1022 | const char *lock = "unknown"; | ||
1023 | switch (libinput_device_config_scroll_get_button_lock(device)) { | ||
1024 | case LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_ENABLED: | ||
1025 | lock = "enabled"; | ||
1026 | break; | ||
1027 | case LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED: | ||
1028 | lock = "disabled"; | ||
1029 | break; | ||
1030 | } | ||
1031 | json_object_object_add(object, "scroll_button_lock", | ||
1032 | json_object_new_string(lock)); | ||
923 | } | 1033 | } |
924 | } | 1034 | } |
925 | 1035 | ||
@@ -936,6 +1046,19 @@ static json_object *describe_libinput_device(struct libinput_device *device) { | |||
936 | json_object_object_add(object, "dwt", json_object_new_string(dwt)); | 1046 | json_object_object_add(object, "dwt", json_object_new_string(dwt)); |
937 | } | 1047 | } |
938 | 1048 | ||
1049 | if (libinput_device_config_dwtp_is_available(device)) { | ||
1050 | const char *dwtp = "unknown"; | ||
1051 | switch (libinput_device_config_dwtp_get_enabled(device)) { | ||
1052 | case LIBINPUT_CONFIG_DWTP_ENABLED: | ||
1053 | dwtp = "enabled"; | ||
1054 | break; | ||
1055 | case LIBINPUT_CONFIG_DWTP_DISABLED: | ||
1056 | dwtp = "disabled"; | ||
1057 | break; | ||
1058 | } | ||
1059 | json_object_object_add(object, "dwtp", json_object_new_string(dwtp)); | ||
1060 | } | ||
1061 | |||
939 | if (libinput_device_config_calibration_has_matrix(device)) { | 1062 | if (libinput_device_config_calibration_has_matrix(device)) { |
940 | float matrix[6]; | 1063 | float matrix[6]; |
941 | libinput_device_config_calibration_get_matrix(device, matrix); | 1064 | libinput_device_config_calibration_get_matrix(device, matrix); |
@@ -950,6 +1073,7 @@ static json_object *describe_libinput_device(struct libinput_device *device) { | |||
950 | 1073 | ||
951 | return object; | 1074 | return object; |
952 | } | 1075 | } |
1076 | #endif | ||
953 | 1077 | ||
954 | json_object *ipc_json_describe_input(struct sway_input_device *device) { | 1078 | json_object *ipc_json_describe_input(struct sway_input_device *device) { |
955 | if (!(sway_assert(device, "Device must not be null"))) { | 1079 | if (!(sway_assert(device, "Device must not be null"))) { |
@@ -971,10 +1095,16 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) { | |||
971 | input_device_get_type(device))); | 1095 | input_device_get_type(device))); |
972 | 1096 | ||
973 | if (device->wlr_device->type == WLR_INPUT_DEVICE_KEYBOARD) { | 1097 | if (device->wlr_device->type == WLR_INPUT_DEVICE_KEYBOARD) { |
974 | struct wlr_keyboard *keyboard = device->wlr_device->keyboard; | 1098 | struct wlr_keyboard *keyboard = |
1099 | wlr_keyboard_from_input_device(device->wlr_device); | ||
975 | struct xkb_keymap *keymap = keyboard->keymap; | 1100 | struct xkb_keymap *keymap = keyboard->keymap; |
976 | struct xkb_state *state = keyboard->xkb_state; | 1101 | struct xkb_state *state = keyboard->xkb_state; |
977 | 1102 | ||
1103 | json_object_object_add(object, "repeat_delay", | ||
1104 | json_object_new_int(keyboard->repeat_info.delay)); | ||
1105 | json_object_object_add(object, "repeat_rate", | ||
1106 | json_object_new_int(keyboard->repeat_info.rate)); | ||
1107 | |||
978 | json_object *layouts_arr = json_object_new_array(); | 1108 | json_object *layouts_arr = json_object_new_array(); |
979 | json_object_object_add(object, "xkb_layout_names", layouts_arr); | 1109 | json_object_object_add(object, "xkb_layout_names", layouts_arr); |
980 | 1110 | ||
@@ -996,12 +1126,25 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) { | |||
996 | } | 1126 | } |
997 | } | 1127 | } |
998 | 1128 | ||
1129 | if (device->wlr_device->type == WLR_INPUT_DEVICE_POINTER) { | ||
1130 | struct input_config *ic = input_device_get_config(device); | ||
1131 | float scroll_factor = 1.0f; | ||
1132 | if (ic != NULL && !isnan(ic->scroll_factor) && | ||
1133 | ic->scroll_factor != FLT_MIN) { | ||
1134 | scroll_factor = ic->scroll_factor; | ||
1135 | } | ||
1136 | json_object_object_add(object, "scroll_factor", | ||
1137 | json_object_new_double(scroll_factor)); | ||
1138 | } | ||
1139 | |||
1140 | #if WLR_HAS_LIBINPUT_BACKEND | ||
999 | if (wlr_input_device_is_libinput(device->wlr_device)) { | 1141 | if (wlr_input_device_is_libinput(device->wlr_device)) { |
1000 | struct libinput_device *libinput_dev; | 1142 | struct libinput_device *libinput_dev; |
1001 | libinput_dev = wlr_libinput_get_device_handle(device->wlr_device); | 1143 | libinput_dev = wlr_libinput_get_device_handle(device->wlr_device); |
1002 | json_object_object_add(object, "libinput", | 1144 | json_object_object_add(object, "libinput", |
1003 | describe_libinput_device(libinput_dev)); | 1145 | describe_libinput_device(libinput_dev)); |
1004 | } | 1146 | } |
1147 | #endif | ||
1005 | 1148 | ||
1006 | return object; | 1149 | return object; |
1007 | } | 1150 | } |
@@ -1109,7 +1252,9 @@ json_object *ipc_json_describe_bar_config(struct bar_config *bar) { | |||
1109 | json_object_object_add(json, "verbose", | 1252 | json_object_object_add(json, "verbose", |
1110 | json_object_new_boolean(bar->verbose)); | 1253 | json_object_new_boolean(bar->verbose)); |
1111 | json_object_object_add(json, "pango_markup", | 1254 | json_object_object_add(json, "pango_markup", |
1112 | json_object_new_boolean(bar->pango_markup)); | 1255 | json_object_new_boolean(bar->pango_markup == PANGO_MARKUP_DEFAULT |
1256 | ? config->pango_markup | ||
1257 | : bar->pango_markup)); | ||
1113 | 1258 | ||
1114 | json_object *colors = json_object_new_object(); | 1259 | json_object *colors = json_object_new_object(); |
1115 | json_object_object_add(colors, "background", | 1260 | json_object_object_add(colors, "background", |