diff options
Diffstat (limited to 'taro/attic')
| -rw-r--r-- | taro/attic/sway_background_covered.diff | 314 | ||||
| -rw-r--r-- | taro/attic/sway_test_config | 9 |
2 files changed, 323 insertions, 0 deletions
diff --git a/taro/attic/sway_background_covered.diff b/taro/attic/sway_background_covered.diff new file mode 100644 index 0000000..fe375e2 --- /dev/null +++ b/taro/attic/sway_background_covered.diff @@ -0,0 +1,314 @@ +diff --git a/include/ipc.h b/include/ipc.h +index ff011750..e417b421 100644 +--- a/include/ipc.h ++++ b/include/ipc.h +@@ -29,9 +29,10 @@ enum ipc_command_type { + IPC_EVENT_MODE = ((1<<31) | 2), + IPC_EVENT_WINDOW = ((1<<31) | 3), + IPC_EVENT_BARCONFIG_UPDATE = ((1<<31) | 4), +- IPC_EVENT_BINDING = ((1<<31) | 5), +- IPC_EVENT_SHUTDOWN = ((1<<31) | 6), +- IPC_EVENT_TICK = ((1<<31) | 7), ++ IPC_EVENT_BACKGROUND_COVERED = ((1<<31) | 5), ++ IPC_EVENT_BINDING = ((1<<31) | 6), ++ IPC_EVENT_SHUTDOWN = ((1<<31) | 7), ++ IPC_EVENT_TICK = ((1<<31) | 8), + + // sway-specific event types + IPC_EVENT_BAR_STATE_UPDATE = ((1<<31) | 20), +diff --git a/include/sway/ipc-server.h b/include/sway/ipc-server.h +index d4c00942..41e00679 100644 +--- a/include/sway/ipc-server.h ++++ b/include/sway/ipc-server.h +@@ -17,6 +17,7 @@ void ipc_event_workspace(struct sway_workspace *old, + void ipc_event_window(struct sway_container *window, const char *change); + void ipc_event_barconfig_update(struct bar_config *bar); + void ipc_event_bar_state_update(struct bar_config *bar); ++void ipc_event_background_covered(struct sway_output *output, bool covered); + void ipc_event_mode(const char *mode, bool pango); + void ipc_event_shutdown(const char *reason); + void ipc_event_binding(struct sway_binding *binding); +diff --git a/include/sway/output.h b/include/sway/output.h +index 4584ea45..83e3cd7f 100644 +--- a/include/sway/output.h ++++ b/include/sway/output.h +@@ -53,6 +53,8 @@ struct sway_output { + bool enabled; + list_t *workspaces; + ++ bool background_covered; ++ + struct sway_output_state current; + + struct wl_listener layout_destroy; +diff --git a/include/sway/tree/workspace.h b/include/sway/tree/workspace.h +index 58bde20c..1fcd5017 100644 +--- a/include/sway/tree/workspace.h ++++ b/include/sway/tree/workspace.h +@@ -40,6 +40,9 @@ struct sway_workspace { + enum sway_container_layout layout; + enum sway_container_layout prev_split_layout; + ++ bool background_covered; ++ bool pending_background_check; ++ + struct side_gaps current_gaps; + int gaps_inner; + struct side_gaps gaps_outer; +@@ -47,6 +50,7 @@ struct sway_workspace { + struct sway_output *output; // NULL if no outputs are connected + list_t *floating; // struct sway_container + list_t *tiling; // struct sway_container ++ list_t *sorted; // struct sway_container + list_t *output_priority; + bool urgent; + +@@ -89,6 +93,8 @@ bool workspace_is_visible(struct sway_workspace *ws); + + bool workspace_is_empty(struct sway_workspace *ws); + ++void workspace_check_background_covered(struct sway_workspace *ws); ++ + void workspace_output_raise_priority(struct sway_workspace *workspace, + struct sway_output *old_output, struct sway_output *new_output); + +diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c +index 8f12832a..9869c934 100644 +--- a/sway/desktop/transaction.c ++++ b/sway/desktop/transaction.c +@@ -702,30 +702,60 @@ static void transaction_apply(struct sway_transaction *transaction) { + "(%.1f frames if 60Hz)", transaction, ms, ms / (1000.0f / 60)); + } + ++ struct sway_transaction_instruction *instruction; ++ struct sway_node *node; ++ struct sway_workspace *ws = NULL; ++ + // Apply the instruction state to the node's current state + for (int i = 0; i < transaction->instructions->length; ++i) { +- struct sway_transaction_instruction *instruction = +- transaction->instructions->items[i]; +- struct sway_node *node = instruction->node; ++ instruction = transaction->instructions->items[i]; ++ node = instruction->node; + + switch (node->type) { + case N_ROOT: ++ ws = NULL; + break; + case N_OUTPUT: + apply_output_state(node->sway_output, &instruction->output_state); ++ ws = node->sway_output->current.active_workspace; + break; + case N_WORKSPACE: + apply_workspace_state(node->sway_workspace, + &instruction->workspace_state); ++ ws = node->sway_workspace; + break; + case N_CONTAINER: + apply_container_state(node->sway_container, + &instruction->container_state); ++ ws = node->sway_container->current.workspace; + break; + } + ++ if (ws) ws->pending_background_check = true; ++ + node->instruction = NULL; + } ++ ++ for (int i = 0; i < transaction->instructions->length; ++i) { ++ instruction = transaction->instructions->items[i]; ++ node = instruction->node; ++ ++ switch (node->type) { ++ case N_ROOT: ++ continue; ++ case N_OUTPUT: ++ ws = node->sway_output->current.active_workspace; ++ break; ++ case N_WORKSPACE: ++ ws = node->sway_workspace; ++ break; ++ case N_CONTAINER: ++ ws = node->sway_container->current.workspace; ++ break; ++ } ++ ++ if (ws) workspace_check_background_covered(ws); ++ } + } + + static void transaction_commit_pending(void); +diff --git a/sway/ipc-json.c b/sway/ipc-json.c +index 571338a4..f9bdcfae 100644 +--- a/sway/ipc-json.c ++++ b/sway/ipc-json.c +@@ -16,6 +16,7 @@ + #include "sway/tree/view.h" + #include "sway/tree/workspace.h" + #include "sway/output.h" ++#include "sway/layers.h" + #include "sway/input/input-manager.h" + #include "sway/input/cursor.h" + #include "sway/input/seat.h" +@@ -360,6 +361,9 @@ static void ipc_json_describe_enabled_output(struct sway_output *output, + json_object_object_add(object, "current_workspace", + json_object_new_string(ws->name)); + ++ json_object_object_add(object, "covered", ++ json_object_new_boolean(ws->background_covered)); ++ + json_object *modes_array = json_object_new_array(); + struct wlr_output_mode *mode; + wl_list_for_each(mode, &wlr_output->modes, link) { +diff --git a/sway/ipc-server.c b/sway/ipc-server.c +index 7f353c0e..f3093505 100644 +--- a/sway/ipc-server.c ++++ b/sway/ipc-server.c +@@ -362,6 +362,20 @@ void ipc_event_bar_state_update(struct bar_config *bar) { + json_object_put(json); + } + ++void ipc_event_background_covered(struct sway_output *output, bool covered) { ++ if (!ipc_has_event_listeners(IPC_EVENT_BACKGROUND_COVERED)) { ++ return; ++ } ++ sway_log(SWAY_DEBUG, "Sending background_covered event"); ++ ++ json_object *json = json_object_new_object(); ++ json_object_object_add(json, "output", json_object_new_string(output->wlr_output->name)); ++ json_object_object_add(json, "covered", json_object_new_boolean(covered)); ++ const char *json_string = json_object_to_json_string(json); ++ ipc_send_event(json_string, IPC_EVENT_BACKGROUND_COVERED); ++ json_object_put(json); ++} ++ + void ipc_event_mode(const char *mode, bool pango) { + if (!ipc_has_event_listeners(IPC_EVENT_MODE)) { + return; +@@ -744,6 +758,8 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt + client->subscribed_events |= event_mask(IPC_EVENT_BARCONFIG_UPDATE); + } else if (strcmp(event_type, "bar_state_update") == 0) { + client->subscribed_events |= event_mask(IPC_EVENT_BAR_STATE_UPDATE); ++ } else if (strcmp(event_type, "background_covered") == 0) { ++ client->subscribed_events |= event_mask(IPC_EVENT_BACKGROUND_COVERED); + } else if (strcmp(event_type, "mode") == 0) { + client->subscribed_events |= event_mask(IPC_EVENT_MODE); + } else if (strcmp(event_type, "shutdown") == 0) { +diff --git a/sway/tree/output.c b/sway/tree/output.c +index 44b941ca..9004c3cb 100644 +--- a/sway/tree/output.c ++++ b/sway/tree/output.c +@@ -142,6 +142,7 @@ struct sway_output *output_create(struct wlr_output *wlr_output) { + + output->workspaces = create_list(); + output->current.workspaces = create_list(); ++ output->background_covered = false; + + return output; + } +diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c +index f8709a4c..3727116d 100644 +--- a/sway/tree/workspace.c ++++ b/sway/tree/workspace.c +@@ -88,8 +88,12 @@ struct sway_workspace *workspace_create(struct sway_output *output, + ws->layout = output_get_default_layout(output); + ws->floating = create_list(); + ws->tiling = create_list(); ++ ws->sorted = create_list(); + ws->output_priority = create_list(); + ++ ws->background_covered = false; ++ ws->pending_background_check = true; ++ + ws->gaps_outer = config->gaps_outer; + ws->gaps_inner = config->gaps_inner; + if (name) { +@@ -153,6 +157,7 @@ void workspace_destroy(struct sway_workspace *workspace) { + list_free_items_and_destroy(workspace->output_priority); + list_free(workspace->floating); + list_free(workspace->tiling); ++ list_free(workspace->sorted); + list_free(workspace->current.floating); + list_free(workspace->current.tiling); + free(workspace); +@@ -616,6 +621,78 @@ bool workspace_is_empty(struct sway_workspace *ws) { + return true; + } + ++static bool x_covered_at_y(list_t *containers, double y, double x, double width) ++{ ++ double end = x + width; ++ double extent = x; ++ for (int i = 0; i < containers->length; ++i) { ++ struct sway_container *n = containers->items[i]; ++ if (!(n->current.y <= y && n->current.y + n->current.height >= y)) { ++ continue; ++ } ++ if (n->current.x > extent) return false; ++ x = n->current.x + n->current.width; ++ if (x >= end) return true; ++ if (x > extent) extent = x; ++ } ++ return false; ++} ++ ++static int sort_containers_x_cmp(const void *_a, const void *_b) { ++ struct sway_container *a = *(void **)_a; ++ struct sway_container *b = *(void **)_b; ++ return a->current.x - b->current.x; ++} ++ ++#define TERMINAL_APP_ID "kitty" ++ ++static void add_con_and_or_children_to_list(list_t *result, list_t *list) ++{ ++ struct sway_container *con; ++ const char *app_id; ++ for (int i = 0; i < list->length; ++i) { ++ con = list->items[i]; ++ if (con->current.children) { ++ add_con_and_or_children_to_list(result, con->current.children); ++ if (con->current.layout != L_NONE) return; ++ } ++ if (!con->view || !con->view->wlr_xdg_toplevel) continue; // Hack. ++ if ((app_id = view_get_app_id(con->view)) && strcmp(app_id, TERMINAL_APP_ID) != 0) { ++ list_add(result, con); ++ } ++ } ++} ++ ++void workspace_check_background_covered(struct sway_workspace *ws) { ++ if (!ws->output || !ws->pending_background_check) return; ++ ws->sorted->length = 0; ++ add_con_and_or_children_to_list(ws->sorted, ws->tiling); ++ add_con_and_or_children_to_list(ws->sorted, ws->floating); ++ list_stable_sort(ws->sorted, sort_containers_x_cmp); ++ ws->background_covered = ws->sorted->length > 0; ++ struct sway_container *con; ++ for (int i = 0; i < ws->sorted->length; ++i) { ++ con = ws->sorted->items[i]; ++ double y = con->current.y - 1.0; ++ if (y < ws->y) y = ws->y; ++ double span = con->current.y + con->current.height + 1.0; ++ if (span > ws->y + ws->height) span = ws->y + ws->height; ++ bool top = x_covered_at_y(ws->sorted, y, ws->x, ws->width); ++ if (!top || !x_covered_at_y(ws->sorted, span, ws->x, ws->width)) { ++ ws->background_covered = false; ++ break; ++ } ++ } ++ if (ws == ws->output->current.active_workspace) { ++ if (ws->background_covered != ws->output->background_covered) { ++ ws->output->background_covered = ws->background_covered; ++ ipc_event_background_covered(ws->output, ws->output->background_covered); ++ } ++ ws->pending_background_check = false; ++ } ++} ++ ++ + static int find_output(const void *id1, const void *id2) { + return strcmp(id1, id2); + } diff --git a/taro/attic/sway_test_config b/taro/attic/sway_test_config new file mode 100644 index 0000000..1223428 --- /dev/null +++ b/taro/attic/sway_test_config @@ -0,0 +1,9 @@ +workspace "1" output "WL-1" +workspace "2" output "WL-1" +bindsym Mod4+Return exec kitty +bindsym Mod4+Shift+q kill +bindsym Mod2+1 workspace 1 +bindsym Mod2+2 workspace 2 +bindsym Mod4+v split v +floating_modifier Mod4 +bindsym Mod4+space floating toggle |