aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-03-29 16:51:36 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2018-03-29 22:11:08 -0400
commit6836074fed83255438960fdc9597532d8bcae4bd (patch)
treeafc1f5292e934ef012800c6575f7fb8e0e303eee
parentFixed laggy focused output boolean (diff)
downloadsway-6836074fed83255438960fdc9597532d8bcae4bd.tar.gz
sway-6836074fed83255438960fdc9597532d8bcae4bd.tar.zst
sway-6836074fed83255438960fdc9597532d8bcae4bd.zip
Implement enough IPC for swaybar to work
-rw-r--r--include/sway/config.h11
-rw-r--r--include/sway/ipc-json.h1
-rw-r--r--include/sway/ipc-server.h1
-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
8 files changed, 251 insertions, 31 deletions
diff --git a/include/sway/config.h b/include/sway/config.h
index 8c9e04de..f9ab6778 100644
--- a/include/sway/config.h
+++ b/include/sway/config.h
@@ -158,17 +158,6 @@ struct bar_config {
158 char *swaybar_command; 158 char *swaybar_command;
159 char *font; 159 char *font;
160 int height; // -1 not defined 160 int height; // -1 not defined
161
162#ifdef ENABLE_TRAY
163 // Tray
164 char *tray_output;
165 char *icon_theme;
166 uint32_t tray_padding;
167 uint32_t activate_button;
168 uint32_t context_button;
169 uint32_t secondary_button;
170#endif
171
172 bool workspace_buttons; 161 bool workspace_buttons;
173 bool wrap_scroll; 162 bool wrap_scroll;
174 char *separator_symbol; 163 char *separator_symbol;
diff --git a/include/sway/ipc-json.h b/include/sway/ipc-json.h
index eef5a018..19c5b5bc 100644
--- a/include/sway/ipc-json.h
+++ b/include/sway/ipc-json.h
@@ -9,5 +9,6 @@ json_object *ipc_json_get_version();
9json_object *ipc_json_describe_container(swayc_t *c); 9json_object *ipc_json_describe_container(swayc_t *c);
10json_object *ipc_json_describe_container_recursive(swayc_t *c); 10json_object *ipc_json_describe_container_recursive(swayc_t *c);
11json_object *ipc_json_describe_input(struct sway_input_device *device); 11json_object *ipc_json_describe_input(struct sway_input_device *device);
12json_object *ipc_json_describe_bar_config(struct bar_config *bar);
12 13
13#endif 14#endif
diff --git a/include/sway/ipc-server.h b/include/sway/ipc-server.h
index bcf1c433..6b7404e5 100644
--- a/include/sway/ipc-server.h
+++ b/include/sway/ipc-server.h
@@ -10,6 +10,7 @@ void ipc_init(struct sway_server *server);
10void ipc_terminate(void); 10void ipc_terminate(void);
11struct sockaddr_un *ipc_user_sockaddr(void); 11struct sockaddr_un *ipc_user_sockaddr(void);
12 12
13void ipc_event_workspace(swayc_t *old, swayc_t *new, const char *change);
13void ipc_event_window(swayc_t *window, const char *change); 14void ipc_event_window(swayc_t *window, const char *change);
14 15
15#endif 16#endif
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) {
403 free_config(old_config); 403 free_config(old_config);
404 } 404 }
405 config->reading = false; 405 config->reading = false;
406
407 if (success) {
408 // TODO: bar
409 //update_active_bar_modifiers();
410 }
411
412 return success; 406 return success;
413} 407}
414 408
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) {
156 struct wlr_box usable_area = { 0 }; 156 struct wlr_box usable_area = { 0 };
157 wlr_output_effective_resolution(output->wlr_output, 157 wlr_output_effective_resolution(output->wlr_output,
158 &usable_area.width, &usable_area.height); 158 &usable_area.width, &usable_area.height);
159 struct wlr_box usable_area_before = output->usable_area;
160 159
161 // Arrange exclusive surfaces from top->bottom 160 // Arrange exclusive surfaces from top->bottom
162 arrange_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], 161 arrange_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
@@ -169,11 +168,7 @@ void arrange_layers(struct sway_output *output) {
169 &usable_area, true); 168 &usable_area, true);
170 memcpy(&output->usable_area, &usable_area, sizeof(struct wlr_box)); 169 memcpy(&output->usable_area, &usable_area, sizeof(struct wlr_box));
171 170
172 if (memcmp(&usable_area_before, 171 arrange_windows(output->swayc, -1, -1);
173 &usable_area, sizeof(struct wlr_box)) != 0) {
174 wlr_log(L_DEBUG, "arrange");
175 arrange_windows(output->swayc, -1, -1);
176 }
177 172
178 // Arrange non-exlusive surfaces from top->bottom 173 // Arrange non-exlusive surfaces from top->bottom
179 usable_area.x = usable_area.y = 0; 174 usable_area.x = usable_area.y = 0;
@@ -221,6 +216,7 @@ static void unmap(struct wlr_layer_surface *layer_surface) {
221static void handle_destroy(struct wl_listener *listener, void *data) { 216static void handle_destroy(struct wl_listener *listener, void *data) {
222 struct sway_layer_surface *sway_layer = wl_container_of( 217 struct sway_layer_surface *sway_layer = wl_container_of(
223 listener, sway_layer, destroy); 218 listener, sway_layer, destroy);
219 wlr_log(L_DEBUG, "layer surface removed");
224 if (sway_layer->layer_surface->mapped) { 220 if (sway_layer->layer_surface->mapped) {
225 unmap(sway_layer->layer_surface); 221 unmap(sway_layer->layer_surface);
226 } 222 }
@@ -233,8 +229,8 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
233 wl_list_remove(&sway_layer->output_destroy.link); 229 wl_list_remove(&sway_layer->output_destroy.link);
234 } 230 }
235 struct sway_output *output = sway_layer->layer_surface->output->data; 231 struct sway_output *output = sway_layer->layer_surface->output->data;
236 arrange_layers(output);
237 free(sway_layer); 232 free(sway_layer);
233 arrange_layers(output);
238} 234}
239 235
240static void handle_map(struct wl_listener *listener, void *data) { 236static 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 @@
6#include "sway/input/cursor.h" 6#include "sway/input/cursor.h"
7#include "sway/input/input-manager.h" 7#include "sway/input/input-manager.h"
8#include "sway/input/keyboard.h" 8#include "sway/input/keyboard.h"
9#include "sway/ipc-server.h"
9#include "sway/output.h" 10#include "sway/output.h"
10#include "sway/view.h" 11#include "sway/view.h"
11#include "log.h" 12#include "log.h"
@@ -309,18 +310,31 @@ void sway_seat_set_focus(struct sway_seat *seat, swayc_t *container) {
309 if (container->type == C_VIEW) { 310 if (container->type == C_VIEW) {
310 struct sway_view *view = container->sway_view; 311 struct sway_view *view = container->sway_view;
311 view_set_activated(view, true); 312 view_set_activated(view, true);
312 struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat); 313 struct wlr_keyboard *keyboard =
314 wlr_seat_get_keyboard(seat->wlr_seat);
313 if (keyboard) { 315 if (keyboard) {
314 wlr_seat_keyboard_notify_enter(seat->wlr_seat, view->surface, 316 wlr_seat_keyboard_notify_enter(seat->wlr_seat,
315 keyboard->keycodes, keyboard->num_keycodes, 317 view->surface, keyboard->keycodes,
316 &keyboard->modifiers); 318 keyboard->num_keycodes, &keyboard->modifiers);
317 } else { 319 } else {
318 wlr_seat_keyboard_notify_enter(seat->wlr_seat, view->surface, 320 wlr_seat_keyboard_notify_enter(
319 NULL, 0, NULL); 321 seat->wlr_seat, view->surface, NULL, 0, NULL);
320 } 322 }
321 } 323 }
322 } 324 }
323 325
326 if (last_focus) {
327 swayc_t *last_ws = last_focus;
328 if (last_ws && last_ws->type != C_WORKSPACE) {
329 last_ws = swayc_parent_by_type(
330 last_focus, C_WORKSPACE);
331 }
332 if (last_ws) {
333 wlr_log(L_DEBUG, "sending workspace event");
334 ipc_event_workspace(last_ws, container, "focus");
335 }
336 }
337
324 if (last_focus && last_focus->type == C_VIEW && 338 if (last_focus && last_focus->type == C_VIEW &&
325 !sway_input_manager_has_focus(seat->input, last_focus)) { 339 !sway_input_manager_has_focus(seat->input, last_focus)) {
326 struct sway_view *view = last_focus->sway_view; 340 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 @@
9#include "sway/input/seat.h" 9#include "sway/input/seat.h"
10#include <wlr/types/wlr_box.h> 10#include <wlr/types/wlr_box.h>
11#include <wlr/types/wlr_output.h> 11#include <wlr/types/wlr_output.h>
12#include "wlr-layer-shell-unstable-v1-protocol.h"
12 13
13json_object *ipc_json_get_version() { 14json_object *ipc_json_get_version() {
14 int major = 0, minor = 0, patch = 0; 15 int major = 0, minor = 0, patch = 0;
@@ -198,3 +199,136 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) {
198 199
199 return object; 200 return object;
200} 201}
202
203json_object *ipc_json_describe_bar_config(struct bar_config *bar) {
204 if (!sway_assert(bar, "Bar must not be NULL")) {
205 return NULL;
206 }
207
208 json_object *json = json_object_new_object();
209 json_object_object_add(json, "id", json_object_new_string(bar->id));
210 json_object_object_add(json, "mode", json_object_new_string(bar->mode));
211 json_object_object_add(json, "hidden_state",
212 json_object_new_string(bar->hidden_state));
213 json_object_object_add(json, "position",
214 json_object_new_string(bar->position));
215 json_object_object_add(json, "status_command",
216 json_object_new_string(bar->status_command));
217 json_object_object_add(json, "font",
218 json_object_new_string((bar->font) ? bar->font : config->font));
219 if (bar->separator_symbol) {
220 json_object_object_add(json, "separator_symbol",
221 json_object_new_string(bar->separator_symbol));
222 }
223 json_object_object_add(json, "bar_height",
224 json_object_new_int(bar->height));
225 json_object_object_add(json, "wrap_scroll",
226 json_object_new_boolean(bar->wrap_scroll));
227 json_object_object_add(json, "workspace_buttons",
228 json_object_new_boolean(bar->workspace_buttons));
229 json_object_object_add(json, "strip_workspace_numbers",
230 json_object_new_boolean(bar->strip_workspace_numbers));
231 json_object_object_add(json, "binding_mode_indicator",
232 json_object_new_boolean(bar->binding_mode_indicator));
233 json_object_object_add(json, "verbose",
234 json_object_new_boolean(bar->verbose));
235 json_object_object_add(json, "pango_markup",
236 json_object_new_boolean(bar->pango_markup));
237
238 json_object *colors = json_object_new_object();
239 json_object_object_add(colors, "background",
240 json_object_new_string(bar->colors.background));
241 json_object_object_add(colors, "statusline",
242 json_object_new_string(bar->colors.statusline));
243 json_object_object_add(colors, "separator",
244 json_object_new_string(bar->colors.separator));
245
246 if (bar->colors.focused_background) {
247 json_object_object_add(colors, "focused_background",
248 json_object_new_string(bar->colors.focused_background));
249 } else {
250 json_object_object_add(colors, "focused_background",
251 json_object_new_string(bar->colors.background));
252 }
253
254 if (bar->colors.focused_statusline) {
255 json_object_object_add(colors, "focused_statusline",
256 json_object_new_string(bar->colors.focused_statusline));
257 } else {
258 json_object_object_add(colors, "focused_statusline",
259 json_object_new_string(bar->colors.statusline));
260 }
261
262 if (bar->colors.focused_separator) {
263 json_object_object_add(colors, "focused_separator",
264 json_object_new_string(bar->colors.focused_separator));
265 } else {
266 json_object_object_add(colors, "focused_separator",
267 json_object_new_string(bar->colors.separator));
268 }
269
270 json_object_object_add(colors, "focused_workspace_border",
271 json_object_new_string(bar->colors.focused_workspace_border));
272 json_object_object_add(colors, "focused_workspace_bg",
273 json_object_new_string(bar->colors.focused_workspace_bg));
274 json_object_object_add(colors, "focused_workspace_text",
275 json_object_new_string(bar->colors.focused_workspace_text));
276
277 json_object_object_add(colors, "inactive_workspace_border",
278 json_object_new_string(bar->colors.inactive_workspace_border));
279 json_object_object_add(colors, "inactive_workspace_bg",
280 json_object_new_string(bar->colors.inactive_workspace_bg));
281 json_object_object_add(colors, "inactive_workspace_text",
282 json_object_new_string(bar->colors.inactive_workspace_text));
283
284 json_object_object_add(colors, "active_workspace_border",
285 json_object_new_string(bar->colors.active_workspace_border));
286 json_object_object_add(colors, "active_workspace_bg",
287 json_object_new_string(bar->colors.active_workspace_bg));
288 json_object_object_add(colors, "active_workspace_text",
289 json_object_new_string(bar->colors.active_workspace_text));
290
291 json_object_object_add(colors, "urgent_workspace_border",
292 json_object_new_string(bar->colors.urgent_workspace_border));
293 json_object_object_add(colors, "urgent_workspace_bg",
294 json_object_new_string(bar->colors.urgent_workspace_bg));
295 json_object_object_add(colors, "urgent_workspace_text",
296 json_object_new_string(bar->colors.urgent_workspace_text));
297
298 if (bar->colors.binding_mode_border) {
299 json_object_object_add(colors, "binding_mode_border",
300 json_object_new_string(bar->colors.binding_mode_border));
301 } else {
302 json_object_object_add(colors, "binding_mode_border",
303 json_object_new_string(bar->colors.urgent_workspace_border));
304 }
305
306 if (bar->colors.binding_mode_bg) {
307 json_object_object_add(colors, "binding_mode_bg",
308 json_object_new_string(bar->colors.binding_mode_bg));
309 } else {
310 json_object_object_add(colors, "binding_mode_bg",
311 json_object_new_string(bar->colors.urgent_workspace_bg));
312 }
313
314 if (bar->colors.binding_mode_text) {
315 json_object_object_add(colors, "binding_mode_text",
316 json_object_new_string(bar->colors.binding_mode_text));
317 } else {
318 json_object_object_add(colors, "binding_mode_text",
319 json_object_new_string(bar->colors.urgent_workspace_text));
320 }
321
322 json_object_object_add(json, "colors", colors);
323
324 // Add outputs if defined
325 if (bar->outputs && bar->outputs->length > 0) {
326 json_object *outputs = json_object_new_array();
327 for (int i = 0; i < bar->outputs->length; ++i) {
328 const char *name = bar->outputs->items[i];
329 json_object_array_add(outputs, json_object_new_string(name));
330 }
331 json_object_object_add(json, "outputs", outputs);
332 }
333 return json;
334}
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 @@
21#include "sway/ipc-server.h" 21#include "sway/ipc-server.h"
22#include "sway/server.h" 22#include "sway/server.h"
23#include "sway/input/input-manager.h" 23#include "sway/input/input-manager.h"
24#include "sway/input/seat.h"
24#include "list.h" 25#include "list.h"
25#include "log.h" 26#include "log.h"
26 27
@@ -279,6 +280,31 @@ static void ipc_send_event(const char *json_string, enum ipc_command_type event)
279 } 280 }
280} 281}
281 282
283void ipc_event_workspace(swayc_t *old, swayc_t *new, const char *change) {
284 wlr_log(L_DEBUG, "Sending workspace::%s event", change);
285 json_object *obj = json_object_new_object();
286 json_object_object_add(obj, "change", json_object_new_string(change));
287 if (strcmp("focus", change) == 0) {
288 if (old) {
289 json_object_object_add(obj, "old",
290 ipc_json_describe_container_recursive(old));
291 } else {
292 json_object_object_add(obj, "old", NULL);
293 }
294 }
295
296 if (new) {
297 json_object_object_add(obj, "current",
298 ipc_json_describe_container_recursive(new));
299 } else {
300 json_object_object_add(obj, "current", NULL);
301 }
302
303 const char *json_string = json_object_to_json_string(obj);
304 ipc_send_event(json_string, IPC_EVENT_WORKSPACE);
305 json_object_put(obj);
306}
307
282void ipc_event_window(swayc_t *window, const char *change) { 308void ipc_event_window(swayc_t *window, const char *change) {
283 wlr_log(L_DEBUG, "Sending window::%s event", change); 309 wlr_log(L_DEBUG, "Sending window::%s event", change);
284 json_object *obj = json_object_new_object(); 310 json_object *obj = json_object_new_object();
@@ -357,6 +383,25 @@ void ipc_client_disconnect(struct ipc_client *client) {
357 free(client); 383 free(client);
358} 384}
359 385
386static void ipc_get_workspaces_callback(swayc_t *workspace, void *data) {
387 if (workspace->type == C_WORKSPACE) {
388 json_object *workspace_json = ipc_json_describe_container(workspace);
389 // override the default focused indicator because
390 // it's set differently for the get_workspaces reply
391 struct sway_seat *seat =
392 sway_input_manager_get_default_seat(input_manager);
393 swayc_t *focused_ws = sway_seat_get_focus(seat);
394 if (focused_ws->type != C_WORKSPACE) {
395 focused_ws = swayc_parent_by_type(focused_ws, C_WORKSPACE);
396 }
397 bool focused = workspace == focused_ws;
398 json_object_object_del(workspace_json, "focused");
399 json_object_object_add(workspace_json, "focused",
400 json_object_new_boolean(focused));
401 json_object_array_add((json_object *)data, workspace_json);
402 }
403}
404
360void ipc_client_handle_command(struct ipc_client *client) { 405void ipc_client_handle_command(struct ipc_client *client) {
361 if (!sway_assert(client != NULL, "client != NULL")) { 406 if (!sway_assert(client != NULL, "client != NULL")) {
362 return; 407 return;
@@ -412,6 +457,16 @@ void ipc_client_handle_command(struct ipc_client *client) {
412 goto exit_cleanup; 457 goto exit_cleanup;
413 } 458 }
414 459
460 case IPC_GET_WORKSPACES:
461 {
462 json_object *workspaces = json_object_new_array();
463 container_map(&root_container, ipc_get_workspaces_callback, workspaces);
464 const char *json_string = json_object_to_json_string(workspaces);
465 ipc_send_reply(client, json_string, (uint32_t) strlen(json_string));
466 json_object_put(workspaces); // free
467 goto exit_cleanup;
468 }
469
415 case IPC_SUBSCRIBE: 470 case IPC_SUBSCRIBE:
416 { 471 {
417 // TODO: Check if they're permitted to use these events 472 // TODO: Check if they're permitted to use these events
@@ -446,7 +501,6 @@ void ipc_client_handle_command(struct ipc_client *client) {
446 } 501 }
447 502
448 json_object_put(request); 503 json_object_put(request);
449
450 ipc_send_reply(client, "{\"success\": true}", 17); 504 ipc_send_reply(client, "{\"success\": true}", 17);
451 goto exit_cleanup; 505 goto exit_cleanup;
452 } 506 }
@@ -483,6 +537,43 @@ void ipc_client_handle_command(struct ipc_client *client) {
483 goto exit_cleanup; 537 goto exit_cleanup;
484 } 538 }
485 539
540 case IPC_GET_BAR_CONFIG:
541 {
542 if (!buf[0]) {
543 // Send list of configured bar IDs
544 json_object *bars = json_object_new_array();
545 int i;
546 for (i = 0; i < config->bars->length; ++i) {
547 struct bar_config *bar = config->bars->items[i];
548 json_object_array_add(bars, json_object_new_string(bar->id));
549 }
550 const char *json_string = json_object_to_json_string(bars);
551 ipc_send_reply(client, json_string, (uint32_t)strlen(json_string));
552 json_object_put(bars); // free
553 } else {
554 // Send particular bar's details
555 struct bar_config *bar = NULL;
556 int i;
557 for (i = 0; i < config->bars->length; ++i) {
558 bar = config->bars->items[i];
559 if (strcmp(buf, bar->id) == 0) {
560 break;
561 }
562 bar = NULL;
563 }
564 if (!bar) {
565 const char *error = "{ \"success\": false, \"error\": \"No bar with that ID\" }";
566 ipc_send_reply(client, error, (uint32_t)strlen(error));
567 goto exit_cleanup;
568 }
569 json_object *json = ipc_json_describe_bar_config(bar);
570 const char *json_string = json_object_to_json_string(json);
571 ipc_send_reply(client, json_string, (uint32_t)strlen(json_string));
572 json_object_put(json); // free
573 }
574 goto exit_cleanup;
575 }
576
486 default: 577 default:
487 wlr_log(L_INFO, "Unknown IPC command type %i", client->current_command); 578 wlr_log(L_INFO, "Unknown IPC command type %i", client->current_command);
488 goto exit_cleanup; 579 goto exit_cleanup;