aboutsummaryrefslogtreecommitdiff
path: root/sway
diff options
context:
space:
mode:
Diffstat (limited to 'sway')
-rw-r--r--sway/commands.c154
-rw-r--r--sway/config.c2
-rw-r--r--sway/focus.c15
-rw-r--r--sway/ipc-server.c171
-rw-r--r--sway/layout.c7
5 files changed, 248 insertions, 101 deletions
diff --git a/sway/commands.c b/sway/commands.c
index f6d9b947..b1b1c5b6 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -25,6 +25,7 @@
#include "resize.h"
#include "input_state.h"
#include "criteria.h"
+#include "ipc-server.h"
typedef struct cmd_results *sway_cmd(int argc, char **argv);
@@ -1147,16 +1148,26 @@ static struct cmd_results *cmd_resize(int argc, char **argv) {
static struct cmd_results *cmd_bar(int argc, char **argv) {
struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "bar", EXPECTED_EQUAL_TO, 1))) {
+ if ((error = checkarg(argc, "bar", EXPECTED_AT_LEAST, 1))) {
return error;
}
- if (strcmp("{", argv[0]) != 0) {
+ if (config->reading && strcmp("{", argv[0]) != 0) {
return cmd_results_new(CMD_INVALID, "bar",
"Expected '{' at start of bar config definition.");
}
if (!config->reading) {
+ if (argc > 1) {
+ if (strcasecmp("mode", argv[0]) == 0) {
+ return bar_cmd_mode(argc-1, argv + 1);
+ }
+
+ if (strcasecmp("hidden_state", argv[0]) == 0) {
+ return bar_cmd_hidden_state(argc-1, argv + 1);
+ }
+ }
+
return cmd_results_new(CMD_FAILURE, "bar", "Can only be used in config file.");
}
@@ -1679,53 +1690,144 @@ static struct cmd_results *bar_cmd_height(int argc, char **argv) {
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
+static struct cmd_results *bar_set_hidden_state(struct bar_config *bar, const char *hidden_state) {
+ char *old_state = bar->hidden_state;
+ if (strcasecmp("toggle", hidden_state) == 0 && !config->reading) {
+ if (strcasecmp("hide", bar->hidden_state) == 0) {
+ bar->hidden_state = strdup("show");
+ } else if (strcasecmp("show", bar->hidden_state) == 0) {
+ bar->hidden_state = strdup("hide");
+ }
+ } else if (strcasecmp("hide", hidden_state) == 0) {
+ bar->hidden_state = strdup("hide");
+ } else if (strcasecmp("show", hidden_state) == 0) {
+ bar->hidden_state = strdup("show");
+ } else {
+ return cmd_results_new(CMD_INVALID, "hidden_state", "Invalid value %s", hidden_state);
+ }
+
+ if (strcmp(old_state, bar->hidden_state) != 0) {
+ if (!config->reading) {
+ ipc_event_barconfig_update(bar);
+ }
+ sway_log(L_DEBUG, "Setting hidden_state: '%s' for bar: %s", bar->hidden_state, bar->id);
+ }
+
+ // free old mode
+ free(old_state);
+ return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+}
+
+
static struct cmd_results *bar_cmd_hidden_state(int argc, char **argv) {
struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "hidden_state", EXPECTED_EQUAL_TO, 1))) {
+ if ((error = checkarg(argc, "hidden_state", EXPECTED_AT_LEAST, 1))) {
+ return error;
+ }
+ if ((error = checkarg(argc, "hidden_state", EXPECTED_LESS_THAN, 3))) {
return error;
}
+ if (config->reading && argc > 1) {
+ return cmd_results_new(CMD_INVALID, "hidden_state", "Unexpected value %s in config mode", argv[1]);
+ }
+
const char *state = argv[0];
- char *old_state = config->current_bar->hidden_state;
- if (strcasecmp("hide", state) == 0) {
- config->current_bar->hidden_state = strdup(state);
- } else if(strcmp("show", state) == 0) {
- config->current_bar->hidden_state = strdup(state);
+ if (config->reading) {
+ return bar_set_hidden_state(config->current_bar, state);
+ }
+
+ const char *id;
+ if (argc == 2) {
+ id = argv[1];
+ }
+
+ int i;
+ struct bar_config *bar;
+ for (i = 0; i < config->bars->length; ++i) {
+ bar = config->bars->items[i];
+ if (id && strcmp(id, bar->id) == 0) {
+ return bar_set_hidden_state(bar, state);
+ }
+
+ error = bar_set_hidden_state(bar, state);
+ if (error) {
+ return error;
+ }
+ }
+
+ return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+}
+
+static struct cmd_results *bar_set_mode(struct bar_config *bar, const char *mode) {
+ char *old_mode = bar->mode;
+ if (strcasecmp("toggle", mode) == 0 && !config->reading) {
+ if (strcasecmp("dock", bar->mode) == 0) {
+ bar->mode = strdup("hide");
+ } else if (strcasecmp("hide", bar->mode) == 0) {
+ bar->mode = strdup("dock");
+ }
+ } else if (strcasecmp("dock", mode) == 0) {
+ bar->mode = strdup("dock");
+ } else if (strcasecmp("hide", mode) == 0) {
+ bar->mode = strdup("hide");
+ } else if (strcasecmp("invisible", mode) == 0) {
+ bar->mode = strdup("invisible");
} else {
- return cmd_results_new(CMD_INVALID, "hidden_state", "Invalid value %s", state);
+ return cmd_results_new(CMD_INVALID, "mode", "Invalid value %s", mode);
}
- sway_log(L_DEBUG, "Setting hidden_state: '%s' for bar: %s", state, config->current_bar->id);
+ if (strcmp(old_mode, bar->mode) != 0) {
+ if (!config->reading) {
+ ipc_event_barconfig_update(bar);
+ }
+ sway_log(L_DEBUG, "Setting mode: '%s' for bar: %s", bar->mode, bar->id);
+ }
- // free old state
- free(old_state);
+ // free old mode
+ free(old_mode);
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
static struct cmd_results *bar_cmd_mode(int argc, char **argv) {
struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "mode", EXPECTED_EQUAL_TO, 1))) {
+ if ((error = checkarg(argc, "mode", EXPECTED_AT_LEAST, 1))) {
+ return error;
+ }
+ if ((error = checkarg(argc, "mode", EXPECTED_LESS_THAN, 3))) {
return error;
}
+ if (config->reading && argc > 1) {
+ return cmd_results_new(CMD_INVALID, "mode", "Unexpected value %s in config mode", argv[1]);
+ }
+
const char *mode = argv[0];
- char *old_mode = config->current_bar->mode;
-
- if (strcasecmp("dock", mode) == 0) {
- config->current_bar->mode = strdup(mode);
- } else if(strcmp("hide", mode) == 0) {
- config->current_bar->mode = strdup(mode);
- } else if(strcmp("invisible", mode) == 0) {
- config->current_bar->mode = strdup(mode);
- } else {
- return cmd_results_new(CMD_INVALID, "mode", "Invalid value %s", mode);
+
+ if (config->reading) {
+ return bar_set_mode(config->current_bar, mode);
}
- sway_log(L_DEBUG, "Setting mode: '%s' for bar: %s", mode, config->current_bar->id);
+ const char *id;
+ if (argc == 2) {
+ id = argv[1];
+ }
+
+ int i;
+ struct bar_config *bar;
+ for (i = 0; i < config->bars->length; ++i) {
+ bar = config->bars->items[i];
+ if (id && strcmp(id, bar->id) == 0) {
+ return bar_set_mode(bar, mode);
+ }
+
+ error = bar_set_mode(bar, mode);
+ if (error) {
+ return error;
+ }
+ }
- // free old mode
- free(old_mode);
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
diff --git a/sway/config.c b/sway/config.c
index e86eda53..853a7111 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -701,7 +701,7 @@ struct bar_config *default_bar_config(void) {
bar->bindings = create_list();
bar->status_command = strdup("while :; do date +'%Y-%m-%d %l:%M:%S %p' && sleep 1; done");
bar->swaybar_command = NULL;
- bar->font = strdup("monospace 10");
+ bar->font = strdup("pango:monospace 10");
bar->height = -1;
bar->workspace_buttons = true;
bar->separator_symbol = NULL;
diff --git a/sway/focus.c b/sway/focus.c
index c1170ca4..cf0ee7f6 100644
--- a/sway/focus.c
+++ b/sway/focus.c
@@ -34,7 +34,7 @@ static void update_focus(swayc_t *c) {
// Case where workspace changes
case C_WORKSPACE:
if (prev) {
- ipc_event_workspace(prev, c);
+ ipc_event_workspace(prev, c, "focus");
// update visibility of old workspace
update_visibility(prev);
@@ -122,11 +122,6 @@ bool set_focused_container(swayc_t *c) {
p = p->parent;
p->is_focused = false;
}
- // active_ws might have been destroyed by now
- // (focus swap away from empty ws = destroy ws)
- if (active_ws_child_count == 0) {
- active_ws = NULL;
- }
// get new focused view and set focus to it.
p = get_focused_view(c);
@@ -146,7 +141,13 @@ bool set_focused_container(swayc_t *c) {
}
if (active_ws != workspace) {
- ipc_event_workspace(active_ws, workspace);
+ // active_ws might have been destroyed by now
+ // (focus swap away from empty ws = destroy ws)
+ if (active_ws_child_count == 0) {
+ active_ws = NULL;
+ }
+
+ ipc_event_workspace(active_ws, workspace, "focus");
}
return true;
}
diff --git a/sway/ipc-server.c b/sway/ipc-server.c
index 9dd3e1a5..e161c756 100644
--- a/sway/ipc-server.c
+++ b/sway/ipc-server.c
@@ -43,6 +43,7 @@ void ipc_client_handle_command(struct ipc_client *client);
bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length);
void ipc_get_workspaces_callback(swayc_t *workspace, void *data);
void ipc_get_outputs_callback(swayc_t *container, void *data);
+json_object *ipc_json_describe_bar_config(struct bar_config *bar);
void ipc_init(void) {
ipc_socket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
@@ -290,8 +291,9 @@ void ipc_client_handle_command(struct ipc_client *client) {
const char *event_type = json_object_get_string(json_object_array_get_idx(request, i));
if (strcmp(event_type, "workspace") == 0) {
client->subscribed_events |= IPC_GET_WORKSPACES;
- }
- else {
+ } else if (strcmp(event_type, "barconfig_update") == 0) {
+ client->subscribed_events |= IPC_GET_BAR_CONFIG;
+ } else {
ipc_send_reply(client, "{\"success\": false}", 18);
ipc_client_disconnect(client);
json_object_put(request);
@@ -397,64 +399,7 @@ void ipc_client_handle_command(struct ipc_client *client) {
ipc_send_reply(client, error, (uint32_t)strlen(error));
break;
}
- json_object *json = json_object_new_object();
- json_object_object_add(json, "id", json_object_new_string(bar->id));
- json_object_object_add(json, "tray_output", NULL);
- json_object_object_add(json, "mode", json_object_new_string(bar->mode));
- json_object_object_add(json, "hidden_state", json_object_new_string(bar->hidden_state));
- //json_object_object_add(json, "modifier", json_object_new_string(bar->modifier)); // TODO: Fix modifier
- switch (bar->position) {
- case DESKTOP_SHELL_PANEL_POSITION_TOP:
- json_object_object_add(json, "position", json_object_new_string("top"));
- break;
- case DESKTOP_SHELL_PANEL_POSITION_BOTTOM:
- json_object_object_add(json, "position", json_object_new_string("bottom"));
- break;
- case DESKTOP_SHELL_PANEL_POSITION_LEFT:
- json_object_object_add(json, "position", json_object_new_string("left"));
- break;
- case DESKTOP_SHELL_PANEL_POSITION_RIGHT:
- json_object_object_add(json, "position", json_object_new_string("right"));
- break;
- }
- json_object_object_add(json, "status_command", json_object_new_string(bar->status_command));
- json_object_object_add(json, "font", json_object_new_string(bar->font));
- if (bar->separator_symbol) {
- json_object_object_add(json, "separator_symbol", json_object_new_string(bar->separator_symbol));
- }
- json_object_object_add(json, "bar_height", json_object_new_int(bar->height));
- json_object_object_add(json, "workspace_buttons", json_object_new_boolean(bar->workspace_buttons));
- json_object_object_add(json, "strip_workspace_numbers", json_object_new_boolean(bar->strip_workspace_numbers));
- json_object_object_add(json, "binding_mode_indicator", json_object_new_boolean(bar->binding_mode_indicator));
- json_object_object_add(json, "verbose", json_object_new_boolean(bar->verbose));
-
- json_object *colors = json_object_new_object();
- json_object_object_add(colors, "background", json_object_new_string(bar->colors.background));
- json_object_object_add(colors, "statusline", json_object_new_string(bar->colors.statusline));
- json_object_object_add(colors, "separator", json_object_new_string(bar->colors.separator));
-
- json_object_object_add(colors, "focused_workspace_border", json_object_new_string(bar->colors.focused_workspace_border));
- json_object_object_add(colors, "focused_workspace_bg", json_object_new_string(bar->colors.focused_workspace_bg));
- json_object_object_add(colors, "focused_workspace_text", json_object_new_string(bar->colors.focused_workspace_text));
-
- json_object_object_add(colors, "inactive_workspace_border", json_object_new_string(bar->colors.inactive_workspace_border));
- json_object_object_add(colors, "inactive_workspace_bg", json_object_new_string(bar->colors.inactive_workspace_bg));
- json_object_object_add(colors, "inactive_workspace_text", json_object_new_string(bar->colors.inactive_workspace_text));
-
- json_object_object_add(colors, "active_workspace_border", json_object_new_string(bar->colors.active_workspace_border));
- json_object_object_add(colors, "active_workspace_bg", json_object_new_string(bar->colors.active_workspace_bg));
- json_object_object_add(colors, "active_workspace_text", json_object_new_string(bar->colors.active_workspace_text));
-
- json_object_object_add(colors, "urgent_workspace_border", json_object_new_string(bar->colors.urgent_workspace_border));
- json_object_object_add(colors, "urgent_workspace_bg", json_object_new_string(bar->colors.urgent_workspace_bg));
- json_object_object_add(colors, "urgent_workspace_text", json_object_new_string(bar->colors.urgent_workspace_text));
-
- json_object_object_add(colors, "binding_mode_border", json_object_new_string(bar->colors.binding_mode_border));
- json_object_object_add(colors, "binding_mode_bg", json_object_new_string(bar->colors.binding_mode_bg));
- json_object_object_add(colors, "binding_mode_text", json_object_new_string(bar->colors.binding_mode_text));
-
- json_object_object_add(json, "colors", colors);
-
+ json_object *json = ipc_json_describe_bar_config(bar);
const char *json_string = json_object_to_json_string(json);
ipc_send_reply(client, json_string, (uint32_t)strlen(json_string));
json_object_put(json); // free
@@ -551,22 +496,114 @@ void ipc_get_outputs_callback(swayc_t *container, void *data) {
}
}
-void ipc_event_workspace(swayc_t *old, swayc_t *new) {
+json_object *ipc_json_describe_bar_config(struct bar_config *bar) {
+ if (!sway_assert(bar, "Bar must not be NULL")) {
+ return NULL;
+ }
+
+ json_object *json = json_object_new_object();
+ json_object_object_add(json, "id", json_object_new_string(bar->id));
+ json_object_object_add(json, "tray_output", NULL);
+ json_object_object_add(json, "mode", json_object_new_string(bar->mode));
+ json_object_object_add(json, "hidden_state", json_object_new_string(bar->hidden_state));
+ //json_object_object_add(json, "modifier", json_object_new_string(bar->modifier)); // TODO: Fix modifier
+ switch (bar->position) {
+ case DESKTOP_SHELL_PANEL_POSITION_TOP:
+ json_object_object_add(json, "position", json_object_new_string("top"));
+ break;
+ case DESKTOP_SHELL_PANEL_POSITION_BOTTOM:
+ json_object_object_add(json, "position", json_object_new_string("bottom"));
+ break;
+ case DESKTOP_SHELL_PANEL_POSITION_LEFT:
+ json_object_object_add(json, "position", json_object_new_string("left"));
+ break;
+ case DESKTOP_SHELL_PANEL_POSITION_RIGHT:
+ json_object_object_add(json, "position", json_object_new_string("right"));
+ break;
+ }
+ json_object_object_add(json, "status_command", json_object_new_string(bar->status_command));
+ json_object_object_add(json, "font", json_object_new_string(bar->font));
+ if (bar->separator_symbol) {
+ json_object_object_add(json, "separator_symbol", json_object_new_string(bar->separator_symbol));
+ }
+ json_object_object_add(json, "bar_height", json_object_new_int(bar->height));
+ json_object_object_add(json, "workspace_buttons", json_object_new_boolean(bar->workspace_buttons));
+ json_object_object_add(json, "strip_workspace_numbers", json_object_new_boolean(bar->strip_workspace_numbers));
+ json_object_object_add(json, "binding_mode_indicator", json_object_new_boolean(bar->binding_mode_indicator));
+ json_object_object_add(json, "verbose", json_object_new_boolean(bar->verbose));
+
+ json_object *colors = json_object_new_object();
+ json_object_object_add(colors, "background", json_object_new_string(bar->colors.background));
+ json_object_object_add(colors, "statusline", json_object_new_string(bar->colors.statusline));
+ json_object_object_add(colors, "separator", json_object_new_string(bar->colors.separator));
+
+ json_object_object_add(colors, "focused_workspace_border", json_object_new_string(bar->colors.focused_workspace_border));
+ json_object_object_add(colors, "focused_workspace_bg", json_object_new_string(bar->colors.focused_workspace_bg));
+ json_object_object_add(colors, "focused_workspace_text", json_object_new_string(bar->colors.focused_workspace_text));
+
+ json_object_object_add(colors, "inactive_workspace_border", json_object_new_string(bar->colors.inactive_workspace_border));
+ json_object_object_add(colors, "inactive_workspace_bg", json_object_new_string(bar->colors.inactive_workspace_bg));
+ json_object_object_add(colors, "inactive_workspace_text", json_object_new_string(bar->colors.inactive_workspace_text));
+
+ json_object_object_add(colors, "active_workspace_border", json_object_new_string(bar->colors.active_workspace_border));
+ json_object_object_add(colors, "active_workspace_bg", json_object_new_string(bar->colors.active_workspace_bg));
+ json_object_object_add(colors, "active_workspace_text", json_object_new_string(bar->colors.active_workspace_text));
+
+ json_object_object_add(colors, "urgent_workspace_border", json_object_new_string(bar->colors.urgent_workspace_border));
+ json_object_object_add(colors, "urgent_workspace_bg", json_object_new_string(bar->colors.urgent_workspace_bg));
+ json_object_object_add(colors, "urgent_workspace_text", json_object_new_string(bar->colors.urgent_workspace_text));
+
+ json_object_object_add(colors, "binding_mode_border", json_object_new_string(bar->colors.binding_mode_border));
+ json_object_object_add(colors, "binding_mode_bg", json_object_new_string(bar->colors.binding_mode_bg));
+ json_object_object_add(colors, "binding_mode_text", json_object_new_string(bar->colors.binding_mode_text));
+
+ json_object_object_add(json, "colors", colors);
+
+ return json;
+}
+
+void ipc_event_workspace(swayc_t *old, swayc_t *new, const char *change) {
json_object *obj = json_object_new_object();
- json_object_object_add(obj, "change", json_object_new_string("focus"));
- if (old) {
- json_object_object_add(obj, "old", ipc_json_describe_workspace(old));
+ json_object_object_add(obj, "change", json_object_new_string(change));
+ if (strcmp("focus", change) == 0) {
+ if (old) {
+ json_object_object_add(obj, "old", ipc_json_describe_workspace(old));
+ } else {
+ json_object_object_add(obj, "old", NULL);
+ }
+ }
+
+ if (new) {
+ json_object_object_add(obj, "current", ipc_json_describe_workspace(new));
} else {
- json_object_object_add(obj, "old", NULL);
+ json_object_object_add(obj, "current", NULL);
}
- json_object_object_add(obj, "current", ipc_json_describe_workspace(new));
+
const char *json_string = json_object_to_json_string(obj);
for (int i = 0; i < ipc_client_list->length; i++) {
struct ipc_client *client = ipc_client_list->items[i];
- if ((client->subscribed_events & IPC_GET_WORKSPACES) == 0) break;
+ if ((client->subscribed_events & IPC_GET_WORKSPACES) == 0) {
+ continue;
+ }
ipc_send_reply(client, json_string, (uint32_t) strlen(json_string));
}
json_object_put(obj); // free
}
+
+void ipc_event_barconfig_update(struct bar_config *bar) {
+ json_object *json = ipc_json_describe_bar_config(bar);
+ const char *json_string = json_object_to_json_string(json);
+ int i;
+ struct ipc_client *client;
+ for (i = 0; i < ipc_client_list->length; ++i) {
+ client = ipc_client_list->items[i];
+ if ((client->subscribed_events & IPC_GET_BAR_CONFIG) == 0) {
+ continue;
+ }
+ ipc_send_reply(client, json_string, (uint32_t)strlen(json_string));
+ }
+
+ json_object_put(json); // free
+}
diff --git a/sway/layout.c b/sway/layout.c
index a9e7c7f1..563e9d11 100644
--- a/sway/layout.c
+++ b/sway/layout.c
@@ -10,6 +10,7 @@
#include "workspace.h"
#include "focus.h"
#include "output.h"
+#include "ipc-server.h"
swayc_t root_container;
list_t *scratchpad;
@@ -312,6 +313,12 @@ void move_container_to(swayc_t* container, swayc_t* destination) {
// reset container geometry
container->width = container->height = 0;
add_child(destination, container);
+
+ // If the workspace only has one child after adding one, it
+ // means that the workspace was just initialized.
+ if (destination->children->length + destination->floating->length == 1) {
+ ipc_event_workspace(NULL, destination, "init");
+ }
} else {
// reset container geometry
container->width = container->height = 0;