mirror of
				https://github.com/swaywm/sway.git
				synced 2025-11-03 09:01:43 -05:00 
			
		
		
		
	Merge pull request #1959 from RyanDwyer/ipc-get-seats
Implement IPC get_seats command
This commit is contained in:
		
						commit
						51b0b25587
					
				
					 9 changed files with 93 additions and 5 deletions
				
			
		| 
						 | 
					@ -15,6 +15,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
types=(
 | 
					types=(
 | 
				
			||||||
'get_workspaces'
 | 
					'get_workspaces'
 | 
				
			||||||
 | 
					'get_seats'
 | 
				
			||||||
'get_inputs'
 | 
					'get_inputs'
 | 
				
			||||||
'get_outputs'
 | 
					'get_outputs'
 | 
				
			||||||
'get_tree'
 | 
					'get_tree'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,7 @@
 | 
				
			||||||
#define event_mask(ev) (1 << (ev & 0x7F))
 | 
					#define event_mask(ev) (1 << (ev & 0x7F))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum ipc_command_type {
 | 
					enum ipc_command_type {
 | 
				
			||||||
 | 
						// i3 command types - see i3's I3_REPLY_TYPE constants
 | 
				
			||||||
	IPC_COMMAND = 0,
 | 
						IPC_COMMAND = 0,
 | 
				
			||||||
	IPC_GET_WORKSPACES = 1,
 | 
						IPC_GET_WORKSPACES = 1,
 | 
				
			||||||
	IPC_SUBSCRIBE = 2,
 | 
						IPC_SUBSCRIBE = 2,
 | 
				
			||||||
| 
						 | 
					@ -12,9 +13,13 @@ enum ipc_command_type {
 | 
				
			||||||
	IPC_GET_MARKS = 5,
 | 
						IPC_GET_MARKS = 5,
 | 
				
			||||||
	IPC_GET_BAR_CONFIG = 6,
 | 
						IPC_GET_BAR_CONFIG = 6,
 | 
				
			||||||
	IPC_GET_VERSION = 7,
 | 
						IPC_GET_VERSION = 7,
 | 
				
			||||||
	IPC_GET_INPUTS = 8,
 | 
					
 | 
				
			||||||
	IPC_GET_CLIPBOARD = 9,
 | 
						// sway-specific command types
 | 
				
			||||||
	// Events send from sway to clients. Events have the highest bits set.
 | 
						IPC_GET_INPUTS = 100,
 | 
				
			||||||
 | 
						IPC_GET_CLIPBOARD = 101,
 | 
				
			||||||
 | 
						IPC_GET_SEATS = 102,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Events sent from sway to clients. Events have the highest bits set.
 | 
				
			||||||
	IPC_EVENT_WORKSPACE = ((1<<31) | 0),
 | 
						IPC_EVENT_WORKSPACE = ((1<<31) | 0),
 | 
				
			||||||
	IPC_EVENT_OUTPUT = ((1<<31) | 1),
 | 
						IPC_EVENT_OUTPUT = ((1<<31) | 1),
 | 
				
			||||||
	IPC_EVENT_MODE = ((1<<31) | 2),
 | 
						IPC_EVENT_MODE = ((1<<31) | 2),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -263,8 +263,10 @@ enum ipc_feature {
 | 
				
			||||||
	IPC_FEATURE_EVENT_BINDING = 4096,
 | 
						IPC_FEATURE_EVENT_BINDING = 4096,
 | 
				
			||||||
	IPC_FEATURE_EVENT_INPUT = 8192,
 | 
						IPC_FEATURE_EVENT_INPUT = 8192,
 | 
				
			||||||
	IPC_FEATURE_GET_CLIPBOARD = 16384,
 | 
						IPC_FEATURE_GET_CLIPBOARD = 16384,
 | 
				
			||||||
 | 
						IPC_FEATURE_GET_SEATS = 32768,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	IPC_FEATURE_ALL_COMMANDS = 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 16384,
 | 
						IPC_FEATURE_ALL_COMMANDS =
 | 
				
			||||||
 | 
							1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 16384 | 32768,
 | 
				
			||||||
	IPC_FEATURE_ALL_EVENTS = 256 | 512 | 1024 | 2048 | 4096 | 8192,
 | 
						IPC_FEATURE_ALL_EVENTS = 256 | 512 | 1024 | 2048 | 4096 | 8192,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	IPC_FEATURE_ALL = IPC_FEATURE_ALL_COMMANDS | IPC_FEATURE_ALL_EVENTS,
 | 
						IPC_FEATURE_ALL = IPC_FEATURE_ALL_COMMANDS | IPC_FEATURE_ALL_EVENTS,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,7 @@ json_object *ipc_json_get_version();
 | 
				
			||||||
json_object *ipc_json_describe_container(struct sway_container *c);
 | 
					json_object *ipc_json_describe_container(struct sway_container *c);
 | 
				
			||||||
json_object *ipc_json_describe_container_recursive(struct sway_container *c);
 | 
					json_object *ipc_json_describe_container_recursive(struct sway_container *c);
 | 
				
			||||||
json_object *ipc_json_describe_input(struct sway_input_device *device);
 | 
					json_object *ipc_json_describe_input(struct sway_input_device *device);
 | 
				
			||||||
 | 
					json_object *ipc_json_describe_seat(struct sway_seat *seat);
 | 
				
			||||||
json_object *ipc_json_describe_bar_config(struct bar_config *bar);
 | 
					json_object *ipc_json_describe_bar_config(struct bar_config *bar);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -267,6 +267,31 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) {
 | 
				
			||||||
	return object;
 | 
						return object;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					json_object *ipc_json_describe_seat(struct sway_seat *seat) {
 | 
				
			||||||
 | 
						if (!(sway_assert(seat, "Seat must not be null"))) {
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						json_object *object = json_object_new_object();
 | 
				
			||||||
 | 
						struct sway_container *focus = seat_get_focus(seat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						json_object_object_add(object, "name",
 | 
				
			||||||
 | 
							json_object_new_string(seat->wlr_seat->name));
 | 
				
			||||||
 | 
						json_object_object_add(object, "capabilities",
 | 
				
			||||||
 | 
							json_object_new_int(seat->wlr_seat->capabilities));
 | 
				
			||||||
 | 
						json_object_object_add(object, "focus",
 | 
				
			||||||
 | 
							json_object_new_int(focus ? focus->id : 0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						json_object *devices = json_object_new_array();
 | 
				
			||||||
 | 
						struct sway_seat_device *device = NULL;
 | 
				
			||||||
 | 
						wl_list_for_each(device, &seat->devices, link) {
 | 
				
			||||||
 | 
							json_object_array_add(devices, ipc_json_describe_input(device->input_device));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						json_object_object_add(object, "devices", devices);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return object;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
json_object *ipc_json_describe_bar_config(struct bar_config *bar) {
 | 
					json_object *ipc_json_describe_bar_config(struct bar_config *bar) {
 | 
				
			||||||
	if (!sway_assert(bar, "Bar must not be NULL")) {
 | 
						if (!sway_assert(bar, "Bar must not be NULL")) {
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -546,6 +546,19 @@ void ipc_client_handle_command(struct ipc_client *client) {
 | 
				
			||||||
		goto exit_cleanup;
 | 
							goto exit_cleanup;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case IPC_GET_SEATS:
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							json_object *seats = json_object_new_array();
 | 
				
			||||||
 | 
							struct sway_seat *seat = NULL;
 | 
				
			||||||
 | 
							wl_list_for_each(seat, &input_manager->seats, link) {
 | 
				
			||||||
 | 
								json_object_array_add(seats, ipc_json_describe_seat(seat));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							const char *json_string = json_object_to_json_string(seats);
 | 
				
			||||||
 | 
							ipc_send_reply(client, json_string, (uint32_t)strlen(json_string));
 | 
				
			||||||
 | 
							json_object_put(seats); // free
 | 
				
			||||||
 | 
							goto exit_cleanup;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case IPC_GET_TREE:
 | 
						case IPC_GET_TREE:
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		json_object *tree =
 | 
							json_object *tree =
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -195,6 +195,9 @@ The following commands are available within this block:
 | 
				
			||||||
**outputs** <enabled|disabled>::
 | 
					**outputs** <enabled|disabled>::
 | 
				
			||||||
	Controls GET_OUTPUTS.
 | 
						Controls GET_OUTPUTS.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**seats** <enabled|disabled>::
 | 
				
			||||||
 | 
						Controls GET_SEATS.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**tree** <enabled|disabled>::
 | 
					**tree** <enabled|disabled>::
 | 
				
			||||||
	Controls GET_TREE.
 | 
						Controls GET_TREE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -106,6 +106,35 @@ static void pretty_print_input(json_object *i) {
 | 
				
			||||||
		json_object_get_int(vendor));
 | 
							json_object_get_int(vendor));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void pretty_print_seat(json_object *i) {
 | 
				
			||||||
 | 
						json_object *name, *capabilities, *devices;
 | 
				
			||||||
 | 
						json_object_object_get_ex(i, "name", &name);
 | 
				
			||||||
 | 
						json_object_object_get_ex(i, "capabilities", &capabilities);
 | 
				
			||||||
 | 
						json_object_object_get_ex(i, "devices", &devices);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const char *fmt =
 | 
				
			||||||
 | 
							"Seat: %s\n"
 | 
				
			||||||
 | 
							"  Capabilities: %d\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printf(fmt, json_object_get_string(name),
 | 
				
			||||||
 | 
							json_object_get_int(capabilities));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						size_t devices_len = json_object_array_length(devices);
 | 
				
			||||||
 | 
						if (devices_len > 0) {
 | 
				
			||||||
 | 
							printf("  Devices:\n");
 | 
				
			||||||
 | 
							for (size_t i = 0; i < devices_len; ++i) {
 | 
				
			||||||
 | 
								json_object *device = json_object_array_get_idx(devices, i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								json_object *device_name;
 | 
				
			||||||
 | 
								json_object_object_get_ex(device, "name", &device_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								printf("    %s\n", json_object_get_string(device_name));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printf("\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void pretty_print_output(json_object *o) {
 | 
					static void pretty_print_output(json_object *o) {
 | 
				
			||||||
	json_object *name, *rect, *focused, *active, *ws;
 | 
						json_object *name, *rect, *focused, *active, *ws;
 | 
				
			||||||
	json_object_object_get_ex(o, "name", &name);
 | 
						json_object_object_get_ex(o, "name", &name);
 | 
				
			||||||
| 
						 | 
					@ -211,7 +240,8 @@ static void pretty_print_clipboard(json_object *v) {
 | 
				
			||||||
static void pretty_print(int type, json_object *resp) {
 | 
					static void pretty_print(int type, json_object *resp) {
 | 
				
			||||||
	if (type != IPC_COMMAND && type != IPC_GET_WORKSPACES &&
 | 
						if (type != IPC_COMMAND && type != IPC_GET_WORKSPACES &&
 | 
				
			||||||
			type != IPC_GET_INPUTS && type != IPC_GET_OUTPUTS &&
 | 
								type != IPC_GET_INPUTS && type != IPC_GET_OUTPUTS &&
 | 
				
			||||||
			type != IPC_GET_VERSION && type != IPC_GET_CLIPBOARD) {
 | 
								type != IPC_GET_VERSION && type != IPC_GET_CLIPBOARD &&
 | 
				
			||||||
 | 
								type != IPC_GET_SEATS) {
 | 
				
			||||||
		printf("%s\n", json_object_to_json_string_ext(resp,
 | 
							printf("%s\n", json_object_to_json_string_ext(resp,
 | 
				
			||||||
			JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED));
 | 
								JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED));
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					@ -244,6 +274,9 @@ static void pretty_print(int type, json_object *resp) {
 | 
				
			||||||
		case IPC_GET_OUTPUTS:
 | 
							case IPC_GET_OUTPUTS:
 | 
				
			||||||
			pretty_print_output(obj);
 | 
								pretty_print_output(obj);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
							case IPC_GET_SEATS:
 | 
				
			||||||
 | 
								pretty_print_seat(obj);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -324,6 +357,8 @@ int main(int argc, char **argv) {
 | 
				
			||||||
		type = IPC_COMMAND;
 | 
							type = IPC_COMMAND;
 | 
				
			||||||
	} else if (strcasecmp(cmdtype, "get_workspaces") == 0) {
 | 
						} else if (strcasecmp(cmdtype, "get_workspaces") == 0) {
 | 
				
			||||||
		type = IPC_GET_WORKSPACES;
 | 
							type = IPC_GET_WORKSPACES;
 | 
				
			||||||
 | 
						} else if (strcasecmp(cmdtype, "get_seats") == 0) {
 | 
				
			||||||
 | 
							type = IPC_GET_SEATS;
 | 
				
			||||||
	} else if (strcasecmp(cmdtype, "get_inputs") == 0) {
 | 
						} else if (strcasecmp(cmdtype, "get_inputs") == 0) {
 | 
				
			||||||
		type = IPC_GET_INPUTS;
 | 
							type = IPC_GET_INPUTS;
 | 
				
			||||||
	} else if (strcasecmp(cmdtype, "get_outputs") == 0) {
 | 
						} else if (strcasecmp(cmdtype, "get_outputs") == 0) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,6 +48,9 @@ IPC Message Types
 | 
				
			||||||
*get_workspaces*::
 | 
					*get_workspaces*::
 | 
				
			||||||
	Gets a JSON-encoded list of workspaces and their status.
 | 
						Gets a JSON-encoded list of workspaces and their status.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*get_seats*::
 | 
				
			||||||
 | 
						Gets a JSON-encoded list of current seats.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
*get_inputs*::
 | 
					*get_inputs*::
 | 
				
			||||||
	Gets a JSON-encoded list of current inputs.
 | 
						Gets a JSON-encoded list of current inputs.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue