15#include <yajl/yajl_parse.h>
55static int json_start_map(
void *
ctx) {
58 LOG(
"creating new swallow\n");
72 DLOG(
"New floating_node\n");
77 DLOG(
"Parent is workspace = %p\n", ws);
103 DLOG(
"Setting layout = L_SPLITH\n");
110 DLOG(
"sanity check: removing swallows specification from split container\n");
155 DLOG(
"Geometry not set, combining children\n");
181 LOG(
"Creating window\n");
188 LOG(
"Fixing floating node without CT_FLOATING_CON parent\n");
204 ELOG(
"Layout file is invalid: found an empty swallow definition.\n");
218 LOG(
"end of array\n");
233 LOG(
"focus (reverse) %d\n", mapping->
old_id);
239 LOG(
"got it! %p\n", con);
256static int json_key(
void *
ctx,
const unsigned char *val,
size_t len) {
257 LOG(
"key: %.*s\n", (
int)len, val);
261 if (strcasecmp(
last_key,
"swallows") == 0) {
265 if (strcasecmp(
last_key,
"gaps") == 0) {
269 if (strcasecmp(
last_key,
"rect") == 0) {
273 if (strcasecmp(
last_key,
"actual_deco_rect") == 0) {
277 if (strcasecmp(
last_key,
"deco_rect") == 0) {
281 if (strcasecmp(
last_key,
"window_rect") == 0) {
285 if (strcasecmp(
last_key,
"geometry") == 0) {
289 if (strcasecmp(
last_key,
"focus") == 0) {
293 if (strcasecmp(
last_key,
"marks") == 0) {
302 LOG(
"string: %.*s for key %s\n", (
int)len, val,
last_key);
306 if (strcasecmp(
last_key,
"class") == 0) {
309 }
else if (strcasecmp(
last_key,
"instance") == 0) {
312 }
else if (strcasecmp(
last_key,
"window_role") == 0) {
315 }
else if (strcasecmp(
last_key,
"title") == 0) {
318 }
else if (strcasecmp(
last_key,
"machine") == 0) {
333 if (strcasecmp(
last_key,
"name") == 0) {
336 }
else if (strcasecmp(
last_key,
"title_format") == 0) {
339 }
else if (strcasecmp(
last_key,
"sticky_group") == 0) {
343 }
else if (strcasecmp(
last_key,
"orientation") == 0) {
352 if (strcasecmp(buf,
"none") == 0 ||
353 strcasecmp(buf,
"horizontal") == 0) {
355 }
else if (strcasecmp(buf,
"vertical") == 0) {
358 LOG(
"Unhandled orientation: %s\n", buf);
361 }
else if (strcasecmp(
last_key,
"border") == 0) {
364 if (strcasecmp(buf,
"none") == 0) {
366 }
else if (strcasecmp(buf,
"1pixel") == 0) {
369 }
else if (strcasecmp(buf,
"pixel") == 0) {
371 }
else if (strcasecmp(buf,
"normal") == 0) {
374 LOG(
"Unhandled \"border\": %s\n", buf);
377 }
else if (strcasecmp(
last_key,
"type") == 0) {
380 if (strcasecmp(buf,
"root") == 0) {
382 }
else if (strcasecmp(buf,
"output") == 0) {
384 }
else if (strcasecmp(buf,
"con") == 0) {
386 }
else if (strcasecmp(buf,
"floating_con") == 0) {
388 }
else if (strcasecmp(buf,
"workspace") == 0) {
390 }
else if (strcasecmp(buf,
"dockarea") == 0) {
393 LOG(
"Unhandled \"type\": %s\n", buf);
396 }
else if (strcasecmp(
last_key,
"layout") == 0) {
399 if (strcasecmp(buf,
"default") == 0) {
402 }
else if (strcasecmp(buf,
"stacked") == 0) {
404 }
else if (strcasecmp(buf,
"tabbed") == 0) {
406 }
else if (strcasecmp(buf,
"dockarea") == 0) {
408 }
else if (strcasecmp(buf,
"output") == 0) {
410 }
else if (strcasecmp(buf,
"splith") == 0) {
412 }
else if (strcasecmp(buf,
"splitv") == 0) {
415 LOG(
"Unhandled \"layout\": %s\n", buf);
418 }
else if (strcasecmp(
last_key,
"workspace_layout") == 0) {
421 if (strcasecmp(buf,
"default") == 0) {
423 }
else if (strcasecmp(buf,
"stacked") == 0) {
425 }
else if (strcasecmp(buf,
"tabbed") == 0) {
428 LOG(
"Unhandled \"workspace_layout\": %s\n", buf);
431 }
else if (strcasecmp(
last_key,
"last_split_layout") == 0) {
434 if (strcasecmp(buf,
"splith") == 0) {
436 }
else if (strcasecmp(buf,
"splitv") == 0) {
439 LOG(
"Unhandled \"last_splitlayout\": %s\n", buf);
442 }
else if (strcasecmp(
last_key,
"mark") == 0) {
443 DLOG(
"Found deprecated key \"mark\".\n");
449 }
else if (strcasecmp(
last_key,
"floating") == 0) {
452 if (strcasecmp(buf,
"auto_off") == 0) {
454 }
else if (strcasecmp(buf,
"auto_on") == 0) {
456 }
else if (strcasecmp(buf,
"user_off") == 0) {
458 }
else if (strcasecmp(buf,
"user_on") == 0) {
462 }
else if (strcasecmp(
last_key,
"scratchpad_state") == 0) {
465 if (strcasecmp(buf,
"none") == 0) {
467 }
else if (strcasecmp(buf,
"fresh") == 0) {
469 }
else if (strcasecmp(buf,
"changed") == 0) {
473 }
else if (strcasecmp(
last_key,
"previous_workspace_name") == 0) {
484 if (strcasecmp(
last_key,
"type") == 0) {
488 if (strcasecmp(
last_key,
"fullscreen_mode") == 0) {
492 if (strcasecmp(
last_key,
"num") == 0) {
496 if (strcasecmp(
last_key,
"current_border_width") == 0) {
500 if (strcasecmp(
last_key,
"window_icon_padding") == 0) {
504 if (strcasecmp(
last_key,
"depth") == 0) {
527 if (strcasecmp(
last_key,
"x") == 0) {
529 }
else if (strcasecmp(
last_key,
"y") == 0) {
531 }
else if (strcasecmp(
last_key,
"width") == 0) {
533 }
else if (strcasecmp(
last_key,
"height") == 0) {
538 DLOG(
"rect now: (%d, %d, %d, %d)\n",
542 if (strcasecmp(
last_key,
"id") == 0) {
546 if (strcasecmp(
last_key,
"dock") == 0) {
550 if (strcasecmp(
last_key,
"insert_where") == 0) {
556 if (strcasecmp(
last_key,
"inner") == 0) {
558 }
else if (strcasecmp(
last_key,
"top") == 0) {
560 }
else if (strcasecmp(
last_key,
"right") == 0) {
562 }
else if (strcasecmp(
last_key,
"bottom") == 0) {
564 }
else if (strcasecmp(
last_key,
"left") == 0) {
574 if (strcasecmp(
last_key,
"focused") == 0 && val) {
578 if (strcasecmp(
last_key,
"sticky") == 0) {
583 if (strcasecmp(
last_key,
"restart_mode") == 0) {
594 if (strcasecmp(
last_key,
"percent") == 0) {
618 DLOG(
"string = %.*s, last_key = %s\n", (
int)len, val,
last_key);
619 if (strncasecmp((
const char *)val,
"workspace", len) == 0) {
631 yajl_handle hand = yajl_alloc(NULL, NULL, NULL);
633 yajl_config(hand, yajl_allow_comments,
true);
635 yajl_config(hand, yajl_allow_multiple_values,
true);
637 setlocale(LC_NUMERIC,
"C");
638 if (yajl_parse(hand, (
const unsigned char *)buf, len) != yajl_status_ok) {
639 unsigned char *str = yajl_get_error(hand, 1, (
const unsigned char *)buf, len);
640 ELOG(
"JSON parsing error: %s\n", str);
641 yajl_free_error(hand, str);
644 setlocale(LC_NUMERIC,
"");
646 yajl_complete_parse(hand);
661 static yajl_callbacks callbacks = {
669 yajl_handle hand = yajl_alloc(&callbacks, NULL, NULL);
671 yajl_config(hand, yajl_allow_comments,
true);
673 yajl_config(hand, yajl_allow_multiple_values,
true);
674 setlocale(LC_NUMERIC,
"C");
675 const yajl_status stat = yajl_parse(hand, (
const unsigned char *)buf, len);
676 if (stat != yajl_status_ok && stat != yajl_status_client_canceled) {
677 unsigned char *str = yajl_get_error(hand, 1, (
const unsigned char *)buf, len);
678 ELOG(
"JSON parsing error: %s\n", str);
679 yajl_free_error(hand, str);
682 setlocale(LC_NUMERIC,
"");
683 yajl_complete_parse(hand);
690 static yajl_callbacks callbacks = {
695 .yajl_start_map = json_start_map,
700 yajl_handle hand = yajl_alloc(&callbacks, NULL, NULL);
702 yajl_config(hand, yajl_allow_comments,
true);
704 yajl_config(hand, yajl_allow_multiple_values,
true);
715 yajl_config(hand, yajl_dont_validate_strings,
true);
728 setlocale(LC_NUMERIC,
"C");
729 const yajl_status stat = yajl_parse(hand, (
const unsigned char *)buf, len);
730 if (stat != yajl_status_ok) {
731 unsigned char *str = yajl_get_error(hand, 1, (
const unsigned char *)buf, len);
732 ELOG(
"JSON parsing error: %s\n", str);
733 if (errormsg != NULL) {
734 *errormsg =
sstrdup((
const char *)str);
736 yajl_free_error(hand, str);
753 setlocale(LC_NUMERIC,
"");
754 yajl_complete_parse(hand);
Con * con_get_workspace(Con *con)
Gets the workspace container this node is on.
bool con_is_split(Con *con)
Returns true if a container should be considered split.
Con * con_new_skeleton(Con *parent, i3Window *window)
Create a new container (and attach it to the given parent, if not NULL).
void con_mark(Con *con, const char *mark, mark_mode_t mode)
Assigns a mark to the container.
void con_fix_percent(Con *con)
Updates the percent attribute of the children of the given container.
void con_attach(Con *con, Con *parent, bool ignore_focus)
Attaches the given container to the given parent.
void con_free(Con *con)
Frees the specified container.
void con_activate(Con *con)
Sets input focus to the given container and raises it to the top.
void floating_check_size(Con *floating_con, bool prefer_height)
Called when a floating window is created or resized.
bool floating_enable(Con *con, bool automatic)
Enables floating mode for the given container by detaching it from its parent, creating a new contain...
static bool parsing_focus
static int json_end_array(void *ctx)
static int json_determine_content_deeper(void *ctx)
static int json_determine_content_string(void *ctx, const unsigned char *val, size_t len)
static bool parsing_geometry
struct pending_marks * marks
static json_content_t content_result
bool json_validate(const char *buf, const size_t len)
Returns true if the provided JSON could be parsed by yajl.
static bool parsing_deco_rect
static int json_int(void *ctx, long long val)
static int json_bool(void *ctx, int val)
struct Match * current_swallow
static int json_end_map(void *ctx)
static bool parsing_actual_deco_rect
json_content_t json_determine_content(const char *buf, const size_t len)
static int json_double(void *ctx, double val)
static bool swallow_is_empty
static int json_key(void *ctx, const unsigned char *val, size_t len)
static bool parsing_marks
static bool parsing_swallows
static int json_string(void *ctx, const unsigned char *val, size_t len)
static int json_determine_content_shallower(void *ctx)
static bool parsing_window_rect
void tree_append_json(Con *con, const char *buf, const size_t len, char **errormsg)
void match_init(Match *match)
Initializes the Match data structure.
void match_free(Match *match)
Frees the given match.
struct regex * regex_new(const char *pattern)
Creates a new 'regex' struct containing the given pattern and a PCRE compiled regular expression.
int ws_name_to_number(const char *name)
Parses the workspace name as a number.
bool rect_equals(Rect a, Rect b)
Con * get_existing_workspace_by_name(const char *name)
Returns the workspace with the given name or NULL if such a workspace does not exist.
char * previous_workspace_name
Stores a copy of the name of the last used workspace for the workspace back-and-forth switching.
void x_con_init(Con *con)
Initializes the X11 part for the given container.
static xcb_cursor_context_t * ctx
char * sstrdup(const char *str)
Safe-wrapper around strdup which exits if malloc returns NULL (meaning that there is no more memory a...
void * scalloc(size_t num, size_t size)
Safe-wrapper around calloc which exits if malloc returns NULL (meaning that there is no more memory a...
int sasprintf(char **strp, const char *fmt,...)
Safe-wrapper around asprintf which exits if it returns -1 (meaning that there is no more memory avail...
char * sstrndup(const char *str, size_t size)
Safe-wrapper around strndup which exits if strndup returns NULL (meaning that there is no more memory...
void * srealloc(void *ptr, size_t size)
Safe-wrapper around realloc which exits if realloc returns NULL (meaning that there is no more memory...
void * smalloc(size_t size)
Safe-wrapper around malloc which exits if malloc returns NULL (meaning that there is no more memory a...
#define TAILQ_FOREACH(var, head, field)
#define TAILQ_HEAD(name, type)
#define TAILQ_INSERT_TAIL(head, elm, field)
#define TAILQ_FIRST(head)
#define TAILQ_FOREACH_REVERSE(var, head, headname, field)
#define TAILQ_REMOVE(head, elm, field)
#define TAILQ_HEAD_INITIALIZER(head)
#define TAILQ_EMPTY(head)
#define TAILQ_INSERT_HEAD(head, elm, field)
#define TAILQ_ENTRY(type)
Stores a rectangle, for example the size of a window, the child window etc.
A "match" is a data structure which acts like a mask or expression to match certain windows or not.
struct regex * window_role
enum Match::@15 insert_where
A 'Con' represents everything from the X11 root window down to a single X11 window.
enum Con::@20 scratchpad_state
layout_t workspace_layout
layout_t last_split_layout
gaps_t gaps
Only applicable for containers of type CT_WORKSPACE.
border_style_t max_user_border_style
int num
the workspace number, if this Con is of type CT_WORKSPACE and the workspace is not a named workspace ...
int window_icon_padding
Whether the window icon should be displayed, and with what padding.
char * title_format
The format with which the window's name should be displayed.
border_style_t border_style
struct Rect geometry
the geometry this window requested when getting mapped
enum Con::@19 floating
floating? (= not in tiling layout) This cannot be simply a bool because we want to keep track of whet...
fullscreen_mode_t fullscreen_mode