aboutsummaryrefslogtreecommitdiffstats
path: root/sway/ipc-server.c
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-08-30 21:00:10 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-09-05 18:01:43 +1000
commit7586f150c058997d9dde387ea7c091ffa7a3c3c7 (patch)
tree63d19027974c1db62ce3a74ca1d2314eb6d5049b /sway/ipc-server.c
parentMerge pull request #2569 from RyanDwyer/deny-reload-repeat (diff)
downloadsway-7586f150c058997d9dde387ea7c091ffa7a3c3c7.tar.gz
sway-7586f150c058997d9dde387ea7c091ffa7a3c3c7.tar.zst
sway-7586f150c058997d9dde387ea7c091ffa7a3c3c7.zip
Implement type safe arguments and demote sway_container
This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
Diffstat (limited to 'sway/ipc-server.c')
-rw-r--r--sway/ipc-server.c55
1 files changed, 22 insertions, 33 deletions
diff --git a/sway/ipc-server.c b/sway/ipc-server.c
index fb5be27b..8ae265f6 100644
--- a/sway/ipc-server.c
+++ b/sway/ipc-server.c
@@ -33,6 +33,7 @@
33#include "sway/input/seat.h" 33#include "sway/input/seat.h"
34#include "sway/tree/root.h" 34#include "sway/tree/root.h"
35#include "sway/tree/view.h" 35#include "sway/tree/view.h"
36#include "sway/tree/workspace.h"
36#include "list.h" 37#include "list.h"
37#include "log.h" 38#include "log.h"
38#include "util.h" 39#include "util.h"
@@ -291,8 +292,8 @@ static void ipc_send_event(const char *json_string, enum ipc_command_type event)
291 } 292 }
292} 293}
293 294
294void ipc_event_workspace(struct sway_container *old, 295void ipc_event_workspace(struct sway_workspace *old,
295 struct sway_container *new, const char *change) { 296 struct sway_workspace *new, const char *change) {
296 if (!ipc_has_event_listeners(IPC_EVENT_WORKSPACE)) { 297 if (!ipc_has_event_listeners(IPC_EVENT_WORKSPACE)) {
297 return; 298 return;
298 } 299 }
@@ -301,14 +302,14 @@ void ipc_event_workspace(struct sway_container *old,
301 json_object_object_add(obj, "change", json_object_new_string(change)); 302 json_object_object_add(obj, "change", json_object_new_string(change));
302 if (old) { 303 if (old) {
303 json_object_object_add(obj, "old", 304 json_object_object_add(obj, "old",
304 ipc_json_describe_container_recursive(old)); 305 ipc_json_describe_node_recursive(&old->node));
305 } else { 306 } else {
306 json_object_object_add(obj, "old", NULL); 307 json_object_object_add(obj, "old", NULL);
307 } 308 }
308 309
309 if (new) { 310 if (new) {
310 json_object_object_add(obj, "current", 311 json_object_object_add(obj, "current",
311 ipc_json_describe_container_recursive(new)); 312 ipc_json_describe_node_recursive(&new->node));
312 } else { 313 } else {
313 json_object_object_add(obj, "current", NULL); 314 json_object_object_add(obj, "current", NULL);
314 } 315 }
@@ -325,7 +326,8 @@ void ipc_event_window(struct sway_container *window, const char *change) {
325 wlr_log(WLR_DEBUG, "Sending window::%s event", change); 326 wlr_log(WLR_DEBUG, "Sending window::%s event", change);
326 json_object *obj = json_object_new_object(); 327 json_object *obj = json_object_new_object();
327 json_object_object_add(obj, "change", json_object_new_string(change)); 328 json_object_object_add(obj, "change", json_object_new_string(change));
328 json_object_object_add(obj, "container", ipc_json_describe_container_recursive(window)); 329 json_object_object_add(obj, "container",
330 ipc_json_describe_node_recursive(&window->node));
329 331
330 const char *json_string = json_object_to_json_string(obj); 332 const char *json_string = json_object_to_json_string(obj);
331 ipc_send_event(json_string, IPC_EVENT_WINDOW); 333 ipc_send_event(json_string, IPC_EVENT_WINDOW);
@@ -521,30 +523,20 @@ void ipc_client_disconnect(struct ipc_client *client) {
521 free(client); 523 free(client);
522} 524}
523 525
524static void ipc_get_workspaces_callback(struct sway_container *workspace, 526static void ipc_get_workspaces_callback(struct sway_workspace *workspace,
525 void *data) { 527 void *data) {
526 if (!sway_assert(workspace->type == C_WORKSPACE, "Expected a workspace")) { 528 json_object *workspace_json = ipc_json_describe_node(&workspace->node);
527 return;
528 }
529 json_object *workspace_json = ipc_json_describe_container(workspace);
530 // override the default focused indicator because 529 // override the default focused indicator because
531 // it's set differently for the get_workspaces reply 530 // it's set differently for the get_workspaces reply
532 struct sway_seat *seat = 531 struct sway_seat *seat = input_manager_get_default_seat(input_manager);
533 input_manager_get_default_seat(input_manager); 532 struct sway_workspace *focused_ws = seat_get_focused_workspace(seat);
534 struct sway_container *focused_ws = seat_get_focus(seat);
535 if (focused_ws != NULL && focused_ws->type != C_WORKSPACE) {
536 focused_ws = container_parent(focused_ws, C_WORKSPACE);
537 }
538 bool focused = workspace == focused_ws; 533 bool focused = workspace == focused_ws;
539 json_object_object_del(workspace_json, "focused"); 534 json_object_object_del(workspace_json, "focused");
540 json_object_object_add(workspace_json, "focused", 535 json_object_object_add(workspace_json, "focused",
541 json_object_new_boolean(focused)); 536 json_object_new_boolean(focused));
542 json_object_array_add((json_object *)data, workspace_json); 537 json_object_array_add((json_object *)data, workspace_json);
543 538
544 focused_ws = seat_get_focus_inactive(seat, workspace->parent); 539 focused_ws = output_get_active_workspace(workspace->output);
545 if (focused_ws->type != C_WORKSPACE) {
546 focused_ws = container_parent(focused_ws, C_WORKSPACE);
547 }
548 bool visible = workspace == focused_ws; 540 bool visible = workspace == focused_ws;
549 json_object_object_add(workspace_json, "visible", 541 json_object_object_add(workspace_json, "visible",
550 json_object_new_boolean(visible)); 542 json_object_new_boolean(visible));
@@ -552,9 +544,9 @@ static void ipc_get_workspaces_callback(struct sway_container *workspace,
552 544
553static void ipc_get_marks_callback(struct sway_container *con, void *data) { 545static void ipc_get_marks_callback(struct sway_container *con, void *data) {
554 json_object *marks = (json_object *)data; 546 json_object *marks = (json_object *)data;
555 if (con->type == C_VIEW && con->sway_view->marks) { 547 if (con->view && con->view->marks) {
556 for (int i = 0; i < con->sway_view->marks->length; ++i) { 548 for (int i = 0; i < con->view->marks->length; ++i) {
557 char *mark = (char *)con->sway_view->marks->items[i]; 549 char *mark = (char *)con->view->marks->items[i];
558 json_object_array_add(marks, json_object_new_string(mark)); 550 json_object_array_add(marks, json_object_new_string(mark));
559 } 551 }
560 } 552 }
@@ -608,16 +600,14 @@ void ipc_client_handle_command(struct ipc_client *client) {
608 case IPC_GET_OUTPUTS: 600 case IPC_GET_OUTPUTS:
609 { 601 {
610 json_object *outputs = json_object_new_array(); 602 json_object *outputs = json_object_new_array();
611 for (int i = 0; i < root_container.children->length; ++i) { 603 for (int i = 0; i < root->outputs->length; ++i) {
612 struct sway_container *container = root_container.children->items[i]; 604 struct sway_output *output = root->outputs->items[i];
613 if (container->type == C_OUTPUT) { 605 json_object_array_add(outputs,
614 json_object_array_add(outputs, 606 ipc_json_describe_node(&output->node));
615 ipc_json_describe_container(container));
616 }
617 } 607 }
618 struct sway_output *output; 608 struct sway_output *output;
619 wl_list_for_each(output, &root_container.sway_root->all_outputs, link) { 609 wl_list_for_each(output, &root->all_outputs, link) {
620 if (!output->swayc) { 610 if (!output->enabled) {
621 json_object_array_add(outputs, 611 json_object_array_add(outputs,
622 ipc_json_describe_disabled_output(output)); 612 ipc_json_describe_disabled_output(output));
623 } 613 }
@@ -717,8 +707,7 @@ void ipc_client_handle_command(struct ipc_client *client) {
717 707
718 case IPC_GET_TREE: 708 case IPC_GET_TREE:
719 { 709 {
720 json_object *tree = 710 json_object *tree = ipc_json_describe_node_recursive(&root->node);
721 ipc_json_describe_container_recursive(&root_container);
722 const char *json_string = json_object_to_json_string(tree); 711 const char *json_string = json_object_to_json_string(tree);
723 client_valid = 712 client_valid =
724 ipc_send_reply(client, json_string, (uint32_t) strlen(json_string)); 713 ipc_send_reply(client, json_string, (uint32_t) strlen(json_string));