Implement enough IPC for swaybar to work

This commit is contained in:
Drew DeVault 2018-03-29 16:51:36 -04:00
parent b72825441b
commit 6836074fed
8 changed files with 251 additions and 31 deletions

View File

@ -158,17 +158,6 @@ struct bar_config {
char *swaybar_command;
char *font;
int height; // -1 not defined
#ifdef ENABLE_TRAY
// Tray
char *tray_output;
char *icon_theme;
uint32_t tray_padding;
uint32_t activate_button;
uint32_t context_button;
uint32_t secondary_button;
#endif
bool workspace_buttons;
bool wrap_scroll;
char *separator_symbol;

View File

@ -9,5 +9,6 @@ json_object *ipc_json_get_version();
json_object *ipc_json_describe_container(swayc_t *c);
json_object *ipc_json_describe_container_recursive(swayc_t *c);
json_object *ipc_json_describe_input(struct sway_input_device *device);
json_object *ipc_json_describe_bar_config(struct bar_config *bar);
#endif

View File

@ -10,6 +10,7 @@ void ipc_init(struct sway_server *server);
void ipc_terminate(void);
struct sockaddr_un *ipc_user_sockaddr(void);
void ipc_event_workspace(swayc_t *old, swayc_t *new, const char *change);
void ipc_event_window(swayc_t *window, const char *change);
#endif

View File

@ -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;
}

View File

@ -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) {

View File

@ -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;

View File

@ -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;
}

View File

@ -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;