aboutsummaryrefslogtreecommitdiff
path: root/sway
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2018-03-29 16:51:36 -0400
committerDrew DeVault <sir@cmpwn.com>2018-03-29 22:11:08 -0400
commit6836074fed83255438960fdc9597532d8bcae4bd (patch)
treeafc1f5292e934ef012800c6575f7fb8e0e303eee /sway
parentb72825441b61f56478ef29372a41a6fa72e4c79d (diff)
Implement enough IPC for swaybar to work
Diffstat (limited to 'sway')
-rw-r--r--sway/config.c6
-rw-r--r--sway/desktop/layer_shell.c10
-rw-r--r--sway/input/seat.c26
-rw-r--r--sway/ipc-json.c134
-rw-r--r--sway/ipc-server.c93
5 files changed, 249 insertions, 20 deletions
diff --git a/sway/config.c b/sway/config.c
index 213e7680..0422fdd9 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -403,12 +403,6 @@ bool load_main_config(const char *file, bool is_active) {
free_config(old_config);
}
config->reading = false;
-
- if (success) {
- // TODO: bar
- //update_active_bar_modifiers();
- }
-
return success;
}
diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c
index 31679fb2..187c8664 100644
--- a/sway/desktop/layer_shell.c
+++ b/sway/desktop/layer_shell.c
@@ -156,7 +156,6 @@ void arrange_layers(struct sway_output *output) {
struct wlr_box usable_area = { 0 };
wlr_output_effective_resolution(output->wlr_output,
&usable_area.width, &usable_area.height);
- struct wlr_box usable_area_before = output->usable_area;
// Arrange exclusive surfaces from top->bottom
arrange_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
@@ -169,11 +168,7 @@ void arrange_layers(struct sway_output *output) {
&usable_area, true);
memcpy(&output->usable_area, &usable_area, sizeof(struct wlr_box));
- if (memcmp(&usable_area_before,
- &usable_area, sizeof(struct wlr_box)) != 0) {
- wlr_log(L_DEBUG, "arrange");
- arrange_windows(output->swayc, -1, -1);
- }
+ arrange_windows(output->swayc, -1, -1);
// Arrange non-exlusive surfaces from top->bottom
usable_area.x = usable_area.y = 0;
@@ -221,6 +216,7 @@ static void unmap(struct wlr_layer_surface *layer_surface) {
static void handle_destroy(struct wl_listener *listener, void *data) {
struct sway_layer_surface *sway_layer = wl_container_of(
listener, sway_layer, destroy);
+ wlr_log(L_DEBUG, "layer surface removed");
if (sway_layer->layer_surface->mapped) {
unmap(sway_layer->layer_surface);
}
@@ -233,8 +229,8 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
wl_list_remove(&sway_layer->output_destroy.link);
}
struct sway_output *output = sway_layer->layer_surface->output->data;
- arrange_layers(output);
free(sway_layer);
+ arrange_layers(output);
}
static void handle_map(struct wl_listener *listener, void *data) {
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 648e7914..81bef7bd 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -6,6 +6,7 @@
#include "sway/input/cursor.h"
#include "sway/input/input-manager.h"
#include "sway/input/keyboard.h"
+#include "sway/ipc-server.h"
#include "sway/output.h"
#include "sway/view.h"
#include "log.h"
@@ -309,18 +310,31 @@ void sway_seat_set_focus(struct sway_seat *seat, swayc_t *container) {
if (container->type == C_VIEW) {
struct sway_view *view = container->sway_view;
view_set_activated(view, true);
- struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat);
+ struct wlr_keyboard *keyboard =
+ wlr_seat_get_keyboard(seat->wlr_seat);
if (keyboard) {
- wlr_seat_keyboard_notify_enter(seat->wlr_seat, view->surface,
- keyboard->keycodes, keyboard->num_keycodes,
- &keyboard->modifiers);
+ wlr_seat_keyboard_notify_enter(seat->wlr_seat,
+ view->surface, keyboard->keycodes,
+ keyboard->num_keycodes, &keyboard->modifiers);
} else {
- wlr_seat_keyboard_notify_enter(seat->wlr_seat, view->surface,
- NULL, 0, NULL);
+ wlr_seat_keyboard_notify_enter(
+ seat->wlr_seat, view->surface, NULL, 0, NULL);
}
}
}
+ if (last_focus) {
+ swayc_t *last_ws = last_focus;
+ if (last_ws && last_ws->type != C_WORKSPACE) {
+ last_ws = swayc_parent_by_type(
+ last_focus, C_WORKSPACE);
+ }
+ if (last_ws) {
+ wlr_log(L_DEBUG, "sending workspace event");
+ ipc_event_workspace(last_ws, container, "focus");
+ }
+ }
+
if (last_focus && last_focus->type == C_VIEW &&
!sway_input_manager_has_focus(seat->input, last_focus)) {
struct sway_view *view = last_focus->sway_view;
diff --git a/sway/ipc-json.c b/sway/ipc-json.c
index 977f1ecb..24e41581 100644
--- a/sway/ipc-json.c
+++ b/sway/ipc-json.c
@@ -9,6 +9,7 @@
#include "sway/input/seat.h"
#include <wlr/types/wlr_box.h>
#include <wlr/types/wlr_output.h>
+#include "wlr-layer-shell-unstable-v1-protocol.h"
json_object *ipc_json_get_version() {
int major = 0, minor = 0, patch = 0;
@@ -198,3 +199,136 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) {
return object;
}
+
+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, "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, "position",
+ json_object_new_string(bar->position));
+ 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) ? bar->font : config->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, "wrap_scroll",
+ json_object_new_boolean(bar->wrap_scroll));
+ 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_object_add(json, "pango_markup",
+ json_object_new_boolean(bar->pango_markup));
+
+ 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));
+
+ if (bar->colors.focused_background) {
+ json_object_object_add(colors, "focused_background",
+ json_object_new_string(bar->colors.focused_background));
+ } else {
+ json_object_object_add(colors, "focused_background",
+ json_object_new_string(bar->colors.background));
+ }
+
+ if (bar->colors.focused_statusline) {
+ json_object_object_add(colors, "focused_statusline",
+ json_object_new_string(bar->colors.focused_statusline));
+ } else {
+ json_object_object_add(colors, "focused_statusline",
+ json_object_new_string(bar->colors.statusline));
+ }
+
+ if (bar->colors.focused_separator) {
+ json_object_object_add(colors, "focused_separator",
+ json_object_new_string(bar->colors.focused_separator));
+ } else {
+ json_object_object_add(colors, "focused_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));
+
+ if (bar->colors.binding_mode_border) {
+ json_object_object_add(colors, "binding_mode_border",
+ json_object_new_string(bar->colors.binding_mode_border));
+ } else {
+ json_object_object_add(colors, "binding_mode_border",
+ json_object_new_string(bar->colors.urgent_workspace_border));
+ }
+
+ if (bar->colors.binding_mode_bg) {
+ json_object_object_add(colors, "binding_mode_bg",
+ json_object_new_string(bar->colors.binding_mode_bg));
+ } else {
+ json_object_object_add(colors, "binding_mode_bg",
+ json_object_new_string(bar->colors.urgent_workspace_bg));
+ }
+
+ if (bar->colors.binding_mode_text) {
+ json_object_object_add(colors, "binding_mode_text",
+ json_object_new_string(bar->colors.binding_mode_text));
+ } else {
+ json_object_object_add(colors, "binding_mode_text",
+ json_object_new_string(bar->colors.urgent_workspace_text));
+ }
+
+ json_object_object_add(json, "colors", colors);
+
+ // Add outputs if defined
+ if (bar->outputs && bar->outputs->length > 0) {
+ json_object *outputs = json_object_new_array();
+ for (int i = 0; i < bar->outputs->length; ++i) {
+ const char *name = bar->outputs->items[i];
+ json_object_array_add(outputs, json_object_new_string(name));
+ }
+ json_object_object_add(json, "outputs", outputs);
+ }
+ return json;
+}
diff --git a/sway/ipc-server.c b/sway/ipc-server.c
index 156de380..408ed432 100644
--- a/sway/ipc-server.c
+++ b/sway/ipc-server.c
@@ -21,6 +21,7 @@
#include "sway/ipc-server.h"
#include "sway/server.h"
#include "sway/input/input-manager.h"
+#include "sway/input/seat.h"
#include "list.h"
#include "log.h"
@@ -279,6 +280,31 @@ static void ipc_send_event(const char *json_string, enum ipc_command_type event)
}
}
+void ipc_event_workspace(swayc_t *old, swayc_t *new, const char *change) {
+ wlr_log(L_DEBUG, "Sending workspace::%s event", change);
+ json_object *obj = json_object_new_object();
+ 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_container_recursive(old));
+ } else {
+ json_object_object_add(obj, "old", NULL);
+ }
+ }
+
+ if (new) {
+ json_object_object_add(obj, "current",
+ ipc_json_describe_container_recursive(new));
+ } else {
+ json_object_object_add(obj, "current", NULL);
+ }
+
+ const char *json_string = json_object_to_json_string(obj);
+ ipc_send_event(json_string, IPC_EVENT_WORKSPACE);
+ json_object_put(obj);
+}
+
void ipc_event_window(swayc_t *window, const char *change) {
wlr_log(L_DEBUG, "Sending window::%s event", change);
json_object *obj = json_object_new_object();
@@ -357,6 +383,25 @@ void ipc_client_disconnect(struct ipc_client *client) {
free(client);
}
+static void ipc_get_workspaces_callback(swayc_t *workspace, void *data) {
+ if (workspace->type == C_WORKSPACE) {
+ json_object *workspace_json = ipc_json_describe_container(workspace);
+ // override the default focused indicator because
+ // it's set differently for the get_workspaces reply
+ struct sway_seat *seat =
+ sway_input_manager_get_default_seat(input_manager);
+ swayc_t *focused_ws = sway_seat_get_focus(seat);
+ if (focused_ws->type != C_WORKSPACE) {
+ focused_ws = swayc_parent_by_type(focused_ws, C_WORKSPACE);
+ }
+ bool focused = workspace == focused_ws;
+ json_object_object_del(workspace_json, "focused");
+ json_object_object_add(workspace_json, "focused",
+ json_object_new_boolean(focused));
+ json_object_array_add((json_object *)data, workspace_json);
+ }
+}
+
void ipc_client_handle_command(struct ipc_client *client) {
if (!sway_assert(client != NULL, "client != NULL")) {
return;
@@ -412,6 +457,16 @@ void ipc_client_handle_command(struct ipc_client *client) {
goto exit_cleanup;
}
+ case IPC_GET_WORKSPACES:
+ {
+ json_object *workspaces = json_object_new_array();
+ container_map(&root_container, ipc_get_workspaces_callback, workspaces);
+ const char *json_string = json_object_to_json_string(workspaces);
+ ipc_send_reply(client, json_string, (uint32_t) strlen(json_string));
+ json_object_put(workspaces); // free
+ goto exit_cleanup;
+ }
+
case IPC_SUBSCRIBE:
{
// TODO: Check if they're permitted to use these events
@@ -446,7 +501,6 @@ void ipc_client_handle_command(struct ipc_client *client) {
}
json_object_put(request);
-
ipc_send_reply(client, "{\"success\": true}", 17);
goto exit_cleanup;
}
@@ -483,6 +537,43 @@ void ipc_client_handle_command(struct ipc_client *client) {
goto exit_cleanup;
}
+ case IPC_GET_BAR_CONFIG:
+ {
+ if (!buf[0]) {
+ // Send list of configured bar IDs
+ json_object *bars = json_object_new_array();
+ int i;
+ for (i = 0; i < config->bars->length; ++i) {
+ struct bar_config *bar = config->bars->items[i];
+ json_object_array_add(bars, json_object_new_string(bar->id));
+ }
+ const char *json_string = json_object_to_json_string(bars);
+ ipc_send_reply(client, json_string, (uint32_t)strlen(json_string));
+ json_object_put(bars); // free
+ } else {
+ // Send particular bar's details
+ struct bar_config *bar = NULL;
+ int i;
+ for (i = 0; i < config->bars->length; ++i) {
+ bar = config->bars->items[i];
+ if (strcmp(buf, bar->id) == 0) {
+ break;
+ }
+ bar = NULL;
+ }
+ if (!bar) {
+ const char *error = "{ \"success\": false, \"error\": \"No bar with that ID\" }";
+ ipc_send_reply(client, error, (uint32_t)strlen(error));
+ goto exit_cleanup;
+ }
+ 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
+ }
+ goto exit_cleanup;
+ }
+
default:
wlr_log(L_INFO, "Unknown IPC command type %i", client->current_command);
goto exit_cleanup;