mirror of
				https://github.com/swaywm/sway.git
				synced 2025-11-03 09:01:43 -05:00 
			
		
		
		
	IPC: Add scratchpad containers to get_tree reply
This patch lists all hidden scratchpad containers as floating nodes on "__i3_scratch" workspace. This workspace resides on "__i3" output.
This commit is contained in:
		
							parent
							
								
									6aafdd2321
								
							
						
					
					
						commit
						65c32e41d4
					
				
					 1 changed files with 98 additions and 38 deletions
				
			
		
							
								
								
									
										136
									
								
								sway/ipc-json.c
									
										
									
									
									
								
							
							
						
						
									
										136
									
								
								sway/ipc-json.c
									
										
									
									
									
								
							| 
						 | 
					@ -15,6 +15,9 @@
 | 
				
			||||||
#include <xkbcommon/xkbcommon.h>
 | 
					#include <xkbcommon/xkbcommon.h>
 | 
				
			||||||
#include "wlr-layer-shell-unstable-v1-protocol.h"
 | 
					#include "wlr-layer-shell-unstable-v1-protocol.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const int i3_output_id = INT32_MAX;
 | 
				
			||||||
 | 
					static const int i3_scratch_id = INT32_MAX - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *ipc_json_layout_description(enum sway_container_layout l) {
 | 
					static const char *ipc_json_layout_description(enum sway_container_layout l) {
 | 
				
			||||||
	switch (l) {
 | 
						switch (l) {
 | 
				
			||||||
	case L_VERT:
 | 
						case L_VERT:
 | 
				
			||||||
| 
						 | 
					@ -43,6 +46,20 @@ static const char *ipc_json_orientation_description(enum sway_container_layout l
 | 
				
			||||||
	return "none";
 | 
						return "none";
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char *describe_container_border(enum sway_container_border border) {
 | 
				
			||||||
 | 
						switch (border) {
 | 
				
			||||||
 | 
						case B_NONE:
 | 
				
			||||||
 | 
							return "none";
 | 
				
			||||||
 | 
						case B_PIXEL:
 | 
				
			||||||
 | 
							return "pixel";
 | 
				
			||||||
 | 
						case B_NORMAL:
 | 
				
			||||||
 | 
							return "normal";
 | 
				
			||||||
 | 
						case B_CSD:
 | 
				
			||||||
 | 
							return "csd";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return "unknown";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
json_object *ipc_json_get_version(void) {
 | 
					json_object *ipc_json_get_version(void) {
 | 
				
			||||||
	int major = 0, minor = 0, patch = 0;
 | 
						int major = 0, minor = 0, patch = 0;
 | 
				
			||||||
	json_object *version = json_object_new_object();
 | 
						json_object *version = json_object_new_object();
 | 
				
			||||||
| 
						 | 
					@ -76,6 +93,37 @@ static json_object *ipc_json_create_empty_rect(void) {
 | 
				
			||||||
	return ipc_json_create_rect(&empty);
 | 
						return ipc_json_create_rect(&empty);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static json_object *ipc_json_create_node(int id, char *name,
 | 
				
			||||||
 | 
							bool focused, json_object *focus, struct wlr_box *box) {
 | 
				
			||||||
 | 
						json_object *object = json_object_new_object();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						json_object_object_add(object, "id", json_object_new_int(id));
 | 
				
			||||||
 | 
						json_object_object_add(object, "name",
 | 
				
			||||||
 | 
								name ? json_object_new_string(name) : NULL);
 | 
				
			||||||
 | 
						json_object_object_add(object, "rect", ipc_json_create_rect(box));
 | 
				
			||||||
 | 
						json_object_object_add(object, "focused", json_object_new_boolean(focused));
 | 
				
			||||||
 | 
						json_object_object_add(object, "focus", focus);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// set default values to be compatible with i3
 | 
				
			||||||
 | 
						json_object_object_add(object, "border",
 | 
				
			||||||
 | 
								json_object_new_string(describe_container_border(B_NONE)));
 | 
				
			||||||
 | 
						json_object_object_add(object, "current_border_width", json_object_new_int(0));
 | 
				
			||||||
 | 
						json_object_object_add(object, "layout",
 | 
				
			||||||
 | 
								json_object_new_string(ipc_json_layout_description(L_HORIZ)));
 | 
				
			||||||
 | 
						json_object_object_add(object, "orientation",
 | 
				
			||||||
 | 
								json_object_new_string(ipc_json_orientation_description(L_HORIZ)));
 | 
				
			||||||
 | 
						json_object_object_add(object, "percent", NULL);
 | 
				
			||||||
 | 
						json_object_object_add(object, "window_rect", ipc_json_create_empty_rect());
 | 
				
			||||||
 | 
						json_object_object_add(object, "deco_rect", ipc_json_create_empty_rect());
 | 
				
			||||||
 | 
						json_object_object_add(object, "geometry", ipc_json_create_empty_rect());
 | 
				
			||||||
 | 
						json_object_object_add(object, "window", NULL);
 | 
				
			||||||
 | 
						json_object_object_add(object, "urgent", json_object_new_boolean(false));
 | 
				
			||||||
 | 
						json_object_object_add(object, "floating_nodes", json_object_new_array());
 | 
				
			||||||
 | 
						json_object_object_add(object, "sticky", json_object_new_boolean(false));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return object;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void ipc_json_describe_root(struct sway_root *root, json_object *object) {
 | 
					static void ipc_json_describe_root(struct sway_root *root, json_object *object) {
 | 
				
			||||||
	json_object_object_add(object, "type", json_object_new_string("root"));
 | 
						json_object_object_add(object, "type", json_object_new_string("root"));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -187,6 +235,52 @@ json_object *ipc_json_describe_disabled_output(struct sway_output *output) {
 | 
				
			||||||
	return object;
 | 
						return object;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static json_object *ipc_json_describe_scratchpad_output(void) {
 | 
				
			||||||
 | 
						struct wlr_box box;
 | 
				
			||||||
 | 
						root_get_box(root, &box);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Create focus stack for __i3_scratch workspace
 | 
				
			||||||
 | 
						json_object *workspace_focus = json_object_new_array();
 | 
				
			||||||
 | 
						for (int i = root->scratchpad->length - 1; i >= 0; --i) {
 | 
				
			||||||
 | 
							struct sway_container *container = root->scratchpad->items[i];
 | 
				
			||||||
 | 
							json_object_array_add(workspace_focus,
 | 
				
			||||||
 | 
									json_object_new_int(container->node.id));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						json_object *workspace = ipc_json_create_node(i3_scratch_id,
 | 
				
			||||||
 | 
									"__i3_scratch", false, workspace_focus, &box);
 | 
				
			||||||
 | 
						json_object_object_add(workspace, "type",
 | 
				
			||||||
 | 
								json_object_new_string("workspace"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// List all hidden scratchpad containers as floating nodes
 | 
				
			||||||
 | 
						json_object *floating_array = json_object_new_array();
 | 
				
			||||||
 | 
						for (int i = 0; i < root->scratchpad->length; ++i) {
 | 
				
			||||||
 | 
							struct sway_container *container = root->scratchpad->items[i];
 | 
				
			||||||
 | 
							if (!container->workspace) {
 | 
				
			||||||
 | 
								json_object_array_add(floating_array,
 | 
				
			||||||
 | 
									ipc_json_describe_node_recursive(&container->node));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						json_object_object_add(workspace, "floating_nodes", floating_array);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Create focus stack for __i3 output
 | 
				
			||||||
 | 
						json_object *output_focus = json_object_new_array();
 | 
				
			||||||
 | 
						json_object_array_add(output_focus, json_object_new_int(i3_scratch_id));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						json_object *output = ipc_json_create_node(i3_output_id,
 | 
				
			||||||
 | 
										"__i3", false, output_focus, &box);
 | 
				
			||||||
 | 
						json_object_object_add(output, "type",
 | 
				
			||||||
 | 
								json_object_new_string("output"));
 | 
				
			||||||
 | 
						json_object_object_add(output, "layout",
 | 
				
			||||||
 | 
								json_object_new_string("output"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						json_object *nodes = json_object_new_array();
 | 
				
			||||||
 | 
						json_object_array_add(nodes, workspace);
 | 
				
			||||||
 | 
						json_object_object_add(output, "nodes", nodes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return output;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void ipc_json_describe_workspace(struct sway_workspace *workspace,
 | 
					static void ipc_json_describe_workspace(struct sway_workspace *workspace,
 | 
				
			||||||
		json_object *object) {
 | 
							json_object *object) {
 | 
				
			||||||
	int num = isdigit(workspace->name[0]) ? atoi(workspace->name) : -1;
 | 
						int num = isdigit(workspace->name[0]) ? atoi(workspace->name) : -1;
 | 
				
			||||||
| 
						 | 
					@ -216,20 +310,6 @@ static void ipc_json_describe_workspace(struct sway_workspace *workspace,
 | 
				
			||||||
	json_object_object_add(object, "floating_nodes", floating_array);
 | 
						json_object_object_add(object, "floating_nodes", floating_array);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *describe_container_border(enum sway_container_border border) {
 | 
					 | 
				
			||||||
	switch (border) {
 | 
					 | 
				
			||||||
	case B_NONE:
 | 
					 | 
				
			||||||
		return "none";
 | 
					 | 
				
			||||||
	case B_PIXEL:
 | 
					 | 
				
			||||||
		return "pixel";
 | 
					 | 
				
			||||||
	case B_NORMAL:
 | 
					 | 
				
			||||||
		return "normal";
 | 
					 | 
				
			||||||
	case B_CSD:
 | 
					 | 
				
			||||||
		return "csd";
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return "unknown";
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void ipc_json_describe_view(struct sway_container *c, json_object *object) {
 | 
					static void ipc_json_describe_view(struct sway_container *c, json_object *object) {
 | 
				
			||||||
	json_object_object_add(object, "pid", json_object_new_int(c->view->pid));
 | 
						json_object_object_add(object, "pid", json_object_new_int(c->view->pid));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -372,17 +452,10 @@ static void focus_inactive_children_iterator(struct sway_node *node,
 | 
				
			||||||
json_object *ipc_json_describe_node(struct sway_node *node) {
 | 
					json_object *ipc_json_describe_node(struct sway_node *node) {
 | 
				
			||||||
	struct sway_seat *seat = input_manager_get_default_seat();
 | 
						struct sway_seat *seat = input_manager_get_default_seat();
 | 
				
			||||||
	bool focused = seat_get_focus(seat) == node;
 | 
						bool focused = seat_get_focus(seat) == node;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	json_object *object = json_object_new_object();
 | 
					 | 
				
			||||||
	char *name = node_get_name(node);
 | 
						char *name = node_get_name(node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_box box;
 | 
						struct wlr_box box;
 | 
				
			||||||
	node_get_box(node, &box);
 | 
						node_get_box(node, &box);
 | 
				
			||||||
	json_object_object_add(object, "id", json_object_new_int((int)node->id));
 | 
					 | 
				
			||||||
	json_object_object_add(object, "name",
 | 
					 | 
				
			||||||
			name ? json_object_new_string(name) : NULL);
 | 
					 | 
				
			||||||
	json_object_object_add(object, "rect", ipc_json_create_rect(&box));
 | 
					 | 
				
			||||||
	json_object_object_add(object, "focused", json_object_new_boolean(focused));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	json_object *focus = json_object_new_array();
 | 
						json_object *focus = json_object_new_array();
 | 
				
			||||||
	struct focus_inactive_data data = {
 | 
						struct focus_inactive_data data = {
 | 
				
			||||||
| 
						 | 
					@ -390,24 +463,9 @@ json_object *ipc_json_describe_node(struct sway_node *node) {
 | 
				
			||||||
		.object = focus,
 | 
							.object = focus,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	seat_for_each_node(seat, focus_inactive_children_iterator, &data);
 | 
						seat_for_each_node(seat, focus_inactive_children_iterator, &data);
 | 
				
			||||||
	json_object_object_add(object, "focus", focus);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// set default values to be compatible with i3
 | 
						json_object *object = ipc_json_create_node(
 | 
				
			||||||
	json_object_object_add(object, "border",
 | 
									(int)node->id, name, focused, focus, &box);
 | 
				
			||||||
			json_object_new_string(describe_container_border(B_NONE)));
 | 
					 | 
				
			||||||
	json_object_object_add(object, "current_border_width", json_object_new_int(0));
 | 
					 | 
				
			||||||
	json_object_object_add(object, "layout",
 | 
					 | 
				
			||||||
			json_object_new_string(ipc_json_layout_description(L_HORIZ)));
 | 
					 | 
				
			||||||
	json_object_object_add(object, "orientation",
 | 
					 | 
				
			||||||
			json_object_new_string(ipc_json_orientation_description(L_HORIZ)));
 | 
					 | 
				
			||||||
	json_object_object_add(object, "percent", NULL);
 | 
					 | 
				
			||||||
	json_object_object_add(object, "window_rect", ipc_json_create_empty_rect());
 | 
					 | 
				
			||||||
	json_object_object_add(object, "deco_rect", ipc_json_create_empty_rect());
 | 
					 | 
				
			||||||
	json_object_object_add(object, "geometry", ipc_json_create_empty_rect());
 | 
					 | 
				
			||||||
	json_object_object_add(object, "window", NULL);
 | 
					 | 
				
			||||||
	json_object_object_add(object, "urgent", json_object_new_boolean(false));
 | 
					 | 
				
			||||||
	json_object_object_add(object, "floating_nodes", json_object_new_array());
 | 
					 | 
				
			||||||
	json_object_object_add(object, "sticky", json_object_new_boolean(false));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (node->type) {
 | 
						switch (node->type) {
 | 
				
			||||||
	case N_ROOT:
 | 
						case N_ROOT:
 | 
				
			||||||
| 
						 | 
					@ -434,6 +492,8 @@ json_object *ipc_json_describe_node_recursive(struct sway_node *node) {
 | 
				
			||||||
	json_object *children = json_object_new_array();
 | 
						json_object *children = json_object_new_array();
 | 
				
			||||||
	switch (node->type) {
 | 
						switch (node->type) {
 | 
				
			||||||
	case N_ROOT:
 | 
						case N_ROOT:
 | 
				
			||||||
 | 
							json_object_array_add(children,
 | 
				
			||||||
 | 
									ipc_json_describe_scratchpad_output());
 | 
				
			||||||
		for (i = 0; i < root->outputs->length; ++i) {
 | 
							for (i = 0; i < root->outputs->length; ++i) {
 | 
				
			||||||
			struct sway_output *output = root->outputs->items[i];
 | 
								struct sway_output *output = root->outputs->items[i];
 | 
				
			||||||
			json_object_array_add(children,
 | 
								json_object_array_add(children,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue