Skip to content

Commit

Permalink
#2180 select which fields to include in query output
Browse files Browse the repository at this point in the history
  • Loading branch information
koekeishiya committed Mar 21, 2024
1 parent 015ccb9 commit c5d3b27
Show file tree
Hide file tree
Showing 16 changed files with 1,110 additions and 401 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Whitelist zathura process for management because it incorrectly identifies as a background-only process [#2168](https://github.com/koekeishiya/yabai/issues/2168)
- Config should be executed if the exec-bit is set, but interpreted if it is not [#2169](https://github.com/koekeishiya/yabai/issues/2169)
- Window query property is-sticky would sometimes show the wrong value [#2175](https://github.com/koekeishiya/yabai/issues/2175)
- Query commands now take an optional list of properties to select which fields should be included in the output [#2180](https://github.com/koekeishiya/yabai/issues/2180)

## [7.0.2] - 2024-03-13
### Changed
Expand Down
11 changes: 8 additions & 3 deletions doc/yabai.1
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
.\" Title: yabai
.\" Author: [see the "AUTHOR(S)" section]
.\" Generator: Asciidoctor 2.0.20
.\" Date: 2024-03-18
.\" Date: 2024-03-22
.\" Manual: Yabai Manual
.\" Source: Yabai
.\" Language: English
.\"
.TH "YABAI" "1" "2024-03-18" "Yabai" "Yabai Manual"
.TH "YABAI" "1" "2024-03-22" "Yabai" "Yabai Manual"
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.ss \n[.ss] 0
Expand Down Expand Up @@ -649,7 +649,7 @@ System Integrity Protection must be partially disabled.
.SS "Query"
.SS "General Syntax"
.sp
yabai \-m query \fI<COMMAND>\fP [\fI<ARGUMENT>\fP]
yabai \-m query \fI<COMMAND>\fP [\fI<PROPERTIES>\fP] [\fI<ARGUMENT>\fP]
.SS "COMMAND"
.sp
\fB\-\-displays\fP
Expand Down Expand Up @@ -682,6 +682,11 @@ Constrain matches to the selected space.
.RS 4
Constrain matches to the selected window.
.RE
.SS "PROPERTIES"
.sp
A comma\-separated string containing the name of fields to include in the output.
.br
The name of the provided fields must be present in the dataformat of the corresponding entity.
.SS "DATAFORMAT"
.sp
DISPLAY
Expand Down
8 changes: 7 additions & 1 deletion doc/yabai.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ Query
General Syntax
^^^^^^^^^^^^^^

yabai -m query '<COMMAND>' ['<ARGUMENT>']
yabai -m query '<COMMAND>' ['<PROPERTIES>'] ['<ARGUMENT>']

COMMAND
^^^^^^^
Expand All @@ -464,6 +464,12 @@ ARGUMENT
*--window* ['<WINDOW_SEL>']::
Constrain matches to the selected window.

PROPERTIES
^^^^^^^^^^

A comma-separated string containing the name of fields to include in the output. +
The name of the provided fields must be present in the dataformat of the corresponding entity.

DATAFORMAT
^^^^^^^^^^

Expand Down
113 changes: 69 additions & 44 deletions src/display.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,60 +14,85 @@ static DISPLAY_EVENT_HANDLER(display_handler)
}
}

void display_serialize(FILE *rsp, uint32_t did)
void display_serialize(FILE *rsp, uint32_t did, uint64_t flags)
{
TIME_FUNCTION;

CGRect frame = CGDisplayBounds(did);
if (flags == 0x0) flags |= ~flags;

bool did_output = false;
fprintf(rsp, "{\n");

char *uuid = NULL;
CFStringRef uuid_ref = display_uuid(did);
if (uuid_ref) {
uuid = ts_cfstring_copy(uuid_ref);
CFRelease(uuid_ref);
if (flags & DISPLAY_PROPERTY_ID) {
fprintf(rsp, "\t\"id\":%d", did);
did_output = true;
}

int buffer_size = MAXLEN;
size_t bytes_written = 0;
char buffer[MAXLEN] = {};
char *cursor = buffer;

int count;
uint64_t *space_list = display_space_list(did, &count);
if (space_list) {
int first_mci = space_manager_mission_control_index(space_list[0]);
for (int i = 0; i < count; ++i) {
if (i < count - 1) {
bytes_written = snprintf(cursor, buffer_size, "%d, ", first_mci + i);
} else {
bytes_written = snprintf(cursor, buffer_size, "%d", first_mci + i);
}
if (flags & DISPLAY_PROPERTY_UUID) {
if (did_output) fprintf(rsp, ",\n");

char *uuid = NULL;
CFStringRef uuid_ref = display_uuid(did);
if (uuid_ref) {
uuid = ts_cfstring_copy(uuid_ref);
CFRelease(uuid_ref);
}

fprintf(rsp, "\t\"uuid\":\"%s\"", uuid ? uuid : "<unknown>");
did_output = true;
}

if (flags & DISPLAY_PROPERTY_INDEX) {
if (did_output) fprintf(rsp, ",\n");

fprintf(rsp, "\t\"index\":%d", display_manager_display_id_arrangement(did));
did_output = true;
}

cursor += bytes_written;
buffer_size -= bytes_written;
if (buffer_size <= 0) break;
if (flags & DISPLAY_PROPERTY_LABEL) {
if (did_output) fprintf(rsp, ",\n");

struct display_label *display_label = display_manager_get_label_for_display(&g_display_manager, did);
fprintf(rsp, "\t\"label\":\"%s\"", display_label ? display_label->label : "");
did_output = true;
}

if (flags & DISPLAY_PROPERTY_FRAME) {
if (did_output) fprintf(rsp, ",\n");

CGRect frame = CGDisplayBounds(did);
fprintf(rsp, "\t\"frame\":{\n\t\t\"x\":%.4f,\n\t\t\"y\":%.4f,\n\t\t\"w\":%.4f,\n\t\t\"h\":%.4f\n\t}", frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
did_output = true;
}

if (flags & DISPLAY_PROPERTY_SPACES) {
if (did_output) fprintf(rsp, ",\n");

int count;
uint64_t *space_list = display_space_list(did, &count);

fprintf(rsp, "\t\"spaces\":[");
if (space_list) {
int first_mci = space_manager_mission_control_index(space_list[0]);
for (int i = 0; i < count; ++i) {
if (i < count - 1) {
fprintf(rsp, "%d, ", first_mci + i);
} else {
fprintf(rsp, "%d", first_mci + i);
}
}
}
fprintf(rsp, "]");
did_output = true;
}

if (flags & DISPLAY_PROPERTY_HAS_FOCUS) {
if (did_output) fprintf(rsp, ",\n");

fprintf(rsp, "\t\"has-focus\":%s", json_bool(did == g_display_manager.current_display_id));
}

struct display_label *display_label = display_manager_get_label_for_display(&g_display_manager, did);

fprintf(rsp,
"{\n"
"\t\"id\":%d,\n"
"\t\"uuid\":\"%s\",\n"
"\t\"index\":%d,\n"
"\t\"label\":\"%s\",\n"
"\t\"frame\":{\n\t\t\"x\":%.4f,\n\t\t\"y\":%.4f,\n\t\t\"w\":%.4f,\n\t\t\"h\":%.4f\n\t},\n"
"\t\"spaces\":[%s],\n"
"\t\"has-focus\":%s\n"
"}",
did,
uuid ? uuid : "<unknown>",
display_manager_display_id_arrangement(did),
display_label ? display_label->label : "",
frame.origin.x, frame.origin.y, frame.size.width, frame.size.height,
buffer,
json_bool(did == g_display_manager.current_display_id));
fprintf(rsp, "\n}");
}

CFStringRef display_uuid(uint32_t did)
Expand Down
35 changes: 34 additions & 1 deletion src/display.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,40 @@
#define DISPLAY_EVENT_HANDLER(name) void name(uint32_t did, CGDisplayChangeSummaryFlags flags, void *context)
typedef DISPLAY_EVENT_HANDLER(display_callback);

void display_serialize(FILE *rsp, uint32_t did);
enum display_property
{
DISPLAY_PROPERTY_ID = 0x01,
DISPLAY_PROPERTY_UUID = 0x02,
DISPLAY_PROPERTY_INDEX = 0x04,
DISPLAY_PROPERTY_LABEL = 0x08,
DISPLAY_PROPERTY_FRAME = 0x10,
DISPLAY_PROPERTY_SPACES = 0x20,
DISPLAY_PROPERTY_HAS_FOCUS = 0x40
};

static int display_property_val[] =
{
[0] = DISPLAY_PROPERTY_ID,
[1] = DISPLAY_PROPERTY_UUID,
[2] = DISPLAY_PROPERTY_INDEX,
[3] = DISPLAY_PROPERTY_LABEL,
[4] = DISPLAY_PROPERTY_FRAME,
[5] = DISPLAY_PROPERTY_SPACES,
[6] = DISPLAY_PROPERTY_HAS_FOCUS
};

static char *display_property_str[] =
{
"id",
"uuid",
"index",
"label",
"frame",
"spaces",
"has-focus"
};

void display_serialize(FILE *rsp, uint32_t did, uint64_t flags);
CFStringRef display_uuid(uint32_t did);
uint32_t display_id(CFStringRef uuid);
CGRect display_bounds_constrained(uint32_t did);
Expand Down
4 changes: 2 additions & 2 deletions src/display_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ extern struct display_manager g_display_manager;
extern struct window_manager g_window_manager;
extern int g_connection;

bool display_manager_query_displays(FILE *rsp)
bool display_manager_query_displays(FILE *rsp, uint64_t flags)
{
TIME_FUNCTION;

Expand All @@ -12,7 +12,7 @@ bool display_manager_query_displays(FILE *rsp)

fprintf(rsp, "[");
for (int i = 0; i < count; ++i) {
display_serialize(rsp, display_list[i]);
display_serialize(rsp, display_list[i], flags);
fprintf(rsp, "%c", i < count - 1 ? ',' : ']');
}
fprintf(rsp, "\n");
Expand Down
2 changes: 1 addition & 1 deletion src/display_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ struct display_label *display_manager_get_label_for_display(struct display_manag
struct display_label *display_manager_get_display_for_label(struct display_manager *dm, char *label);
bool display_manager_remove_label_for_display(struct display_manager *dm, uint32_t did);
void display_manager_set_label_for_display(struct display_manager *dm, uint32_t did, char *label);
bool display_manager_query_displays(FILE *rsp);
bool display_manager_query_displays(FILE *rsp, uint64_t flags);
CFStringRef display_manager_main_display_uuid(void);
uint32_t display_manager_main_display_id(void);
CFStringRef display_manager_active_display_uuid(void);
Expand Down
Loading

0 comments on commit c5d3b27

Please sign in to comment.