Skip to content

Commit

Permalink
#119 ability to label the selected space, allowing that label to be u…
Browse files Browse the repository at this point in the history
…sed as an alias in commands that take a SPACE_SEL parameter
  • Loading branch information
koekeishiya committed Oct 16, 2019
1 parent 5695fcf commit e5deb0a
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 10 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
- Config option *window_border_radius* to specify roundness of corners [#281](https://github.com/koekeishiya/yabai/issues/281)
- Config option *window_border_placement* to specify placement of window borders (exterior, interior, inset) [#216](https://github.com/koekeishiya/yabai/issues/216)
- Config option *active_window_border_topmost* to specify if the active border should always stay on top of other windows (off, on) [#216](https://github.com/koekeishiya/yabai/issues/216)
- Ability to label spaces, making the given label an alias that can be passed to any command taking a `<SPACE_SEL>` parameter [#119](https://github.com/koekeishiya/yabai/issues/119)

### Changed
- Don't draw borders for minimized or hidden windows when a display is (dis)connected [#250](https://github.com/koekeishiya/yabai/issues/250)
Expand Down
7 changes: 6 additions & 1 deletion doc/yabai.1
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ WINDOW_SEL := prev | next | first | last | recent | mouse | largest | smallest

DISPLAY_SEL := prev | next | first | last | recent | arrangement index (1\-based)

SPACE_SEL := prev | next | first | last | recent | mission\-control index (1\-based)
SPACE_SEL := prev | next | first | last | recent | mission\-control index (1\-based) | LABEL

FLOAT_SEL := 0 < value <= 1.0

Expand Down Expand Up @@ -356,6 +356,11 @@ Toggle space setting on or off for the selected space.
.RS 4
Set the layout of the selected space.
.RE
.sp
\fB\-\-label\fP \fI<LABEL>\fP
.RS 4
Label the selected space, allowing that label to be used as an alias in commands that take a \f(CRSPACE_SEL\fP parameter.
.RE
.SS "Window"
.SS "General Syntax"
.sp
Expand Down
5 changes: 4 additions & 1 deletion doc/yabai.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ WINDOW_SEL := prev | next | first | last | recent | mouse | largest | smallest
DISPLAY_SEL := prev | next | first | last | recent | arrangement index (1-based)
SPACE_SEL := prev | next | first | last | recent | mission-control index (1-based)
SPACE_SEL := prev | next | first | last | recent | mission-control index (1-based) | LABEL
FLOAT_SEL := 0 < value <= 1.0
Expand Down Expand Up @@ -266,6 +266,9 @@ COMMAND
*--layout* 'bsp|float'::
Set the layout of the selected space.

*--label* '<LABEL>'::
Label the selected space, allowing that label to be used as an alias in commands that take a `SPACE_SEL` parameter.

Window
~~~~~~

Expand Down
60 changes: 52 additions & 8 deletions src/message.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ extern struct bar g_bar;
#define COMMAND_SPACE_GAP "--gap"
#define COMMAND_SPACE_TOGGLE "--toggle"
#define COMMAND_SPACE_LAYOUT "--layout"
#define COMMAND_SPACE_LABEL "--label"

#define ARGUMENT_SPACE_MIRROR_X "x-axis"
#define ARGUMENT_SPACE_MIRROR_Y "y-axis"
Expand Down Expand Up @@ -196,12 +197,6 @@ extern struct bar g_bar;
#define ARGUMENT_COMMON_SEL_RECENT "recent"
/* ----------------------------------------------------------------------------- */

struct token
{
char *text;
unsigned int length;
};

static bool token_equals(struct token token, char *match)
{
char *at = match;
Expand Down Expand Up @@ -829,6 +824,44 @@ struct selector
};
};

enum label_type
{
LABEL_SPACE,
};

static char *reserved_space_identifiers[] =
{
ARGUMENT_COMMON_SEL_PREV,
ARGUMENT_COMMON_SEL_NEXT,
ARGUMENT_COMMON_SEL_FIRST,
ARGUMENT_COMMON_SEL_LAST,
ARGUMENT_COMMON_SEL_RECENT
};

static char *parse_label(FILE *rsp, char **message, enum label_type type)
{
struct token value = get_token(message);

if ((!token_is_valid(value)) || (value.text[0] >= '0' && value.text[0] <= '9')) {
daemon_fail(rsp, "'%.*s' is not a valid label\n", value.length, value.text);
return NULL;
}

switch (type) {
case LABEL_SPACE: {
for (int i = 0; i < array_count(reserved_space_identifiers); ++i) {
if (token_equals(value, reserved_space_identifiers[i])) {
daemon_fail(rsp, "'%.*s' is a reserved keyword and cannot be used as a label\n", value.length, value.text);
return NULL;
}
}
} break;
default: {} break;
}

return token_to_string(value);
}

static uint8_t parse_value_type(char *type)
{
if (string_equals(type, "abs")) {
Expand Down Expand Up @@ -994,8 +1027,14 @@ static struct selector parse_space_selector(FILE *rsp, char **message, uint64_t
daemon_fail(rsp, "invalid mission-control index specified '%d'.\n", mci);
}
} else {
result.did_parse = false;
daemon_fail(rsp, "value '%.*s' is not a valid option for SPACE_SEL\n", result.token.length, result.token.text);
struct space_label *space_label = space_manager_get_space_for_label(&g_space_manager, result.token);
if (space_label) {
result.did_parse = true;
result.sid = space_label->sid;
} else {
result.did_parse = false;
daemon_fail(rsp, "value '%.*s' is not a valid option for SPACE_SEL\n", result.token.length, result.token.text);
}
}
} else {
result.did_parse = false;
Expand Down Expand Up @@ -1335,6 +1374,11 @@ static void handle_domain_space(FILE *rsp, struct token domain, char *message)
} else {
daemon_fail(rsp, "unknown value '%.*s' given to command '%.*s' for domain '%.*s'\n", value.length, value.text, command.length, command.text, domain.length, domain.text);
}
} else if (token_equals(command, COMMAND_SPACE_LABEL)) {
char *label = parse_label(rsp, &message, LABEL_SPACE);
if (label) {
space_manager_set_label_for_space(&g_space_manager, acting_sid, label);
}
} else {
daemon_fail(rsp, "unknown command '%.*s' for domain '%.*s'\n", command.length, command.text, domain.length, domain.text);
}
Expand Down
6 changes: 6 additions & 0 deletions src/message.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
#ifndef MESSAGE_H
#define MESSAGE_H

struct token
{
char *text;
unsigned int length;
};

static SOCKET_DAEMON_HANDLER(message_handler);
void handle_message(FILE *rsp, char *message);

Expand Down
39 changes: 39 additions & 0 deletions src/space_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,44 @@ void space_manager_untile_window(struct space_manager *sm, struct view *view, st
}
}

struct space_label *space_manager_get_space_for_label(struct space_manager *sm, struct token label)
{
for (int i = 0; i < buf_len(sm->labels); ++i) {
struct space_label *space_label = &sm->labels[i];
if (token_equals(label, space_label->label)) {
return space_label;
}
}

return NULL;
}

void space_manager_set_label_for_space(struct space_manager *sm, uint64_t sid, char *label)
{
for (int i = 0; i < buf_len(sm->labels); ++i) {
struct space_label *space_label = &sm->labels[i];
if (space_label->sid == sid) {
free(space_label->label);
buf_del(sm->labels, i);
break;
}
}

for (int i = 0; i < buf_len(sm->labels); ++i) {
struct space_label *space_label = &sm->labels[i];
if (string_equals(space_label->label, label)) {
free(space_label->label);
buf_del(sm->labels, i);
break;
}
}

buf_push(sm->labels, ((struct space_label) {
.sid = sid,
.label = label
}));
}

void space_manager_set_layout_for_space(struct space_manager *sm, uint64_t sid, enum view_type layout)
{
struct view *view = space_manager_find_view(sm, sid);
Expand Down Expand Up @@ -793,6 +831,7 @@ void space_manager_init(struct space_manager *sm)
sm->split_ratio = 0.5f;
sm->auto_balance = false;
sm->window_placement = CHILD_SECOND;
sm->labels = NULL;

table_init(&sm->view, 23, hash_view, compare_view);

Expand Down
9 changes: 9 additions & 0 deletions src/space_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ extern void SLSRemoveWindowsFromSpaces(int cid, CFArrayRef window_list, CFArrayR
extern void SLSAddWindowsToSpaces(int cid, CFArrayRef window_list, CFArrayRef space_list);
extern CGError CoreDockSendNotification(CFStringRef notification, int unknown);

struct space_label
{
uint64_t sid;
char *label;
};

struct space_manager
{
struct table view;
Expand All @@ -25,6 +31,7 @@ struct space_manager
float split_ratio;
enum window_node_child window_placement;
bool auto_balance;
struct space_label *labels;
};

enum space_op_error
Expand Down Expand Up @@ -59,6 +66,8 @@ uint64_t space_manager_next_space(uint64_t sid);
uint64_t space_manager_first_space(void);
uint64_t space_manager_last_space(void);
uint64_t space_manager_active_space(void);
struct space_label *space_manager_get_space_for_label(struct space_manager *sm, struct token label);
void space_manager_set_label_for_space(struct space_manager *sm, uint64_t sid, char *label);
void space_manager_set_layout_for_space(struct space_manager *sm, uint64_t sid, enum view_type type);
void space_manager_set_gap_for_space(struct space_manager *sm, uint64_t sid, int type, int gap);
void space_manager_toggle_gap_for_space(struct space_manager *sm, uint64_t sid);
Expand Down

0 comments on commit e5deb0a

Please sign in to comment.