From f8979957599468cd2f642caab8220456701f34b0 Mon Sep 17 00:00:00 2001 From: dmitry Date: Sun, 2 Aug 2020 04:24:24 +0300 Subject: [PATCH] Base implement --- include/sway/output.h | 3 +++ include/sway/server.h | 2 ++ include/sway/tree/workspace.h | 3 +++ sway/desktop/output.c | 2 ++ sway/server.c | 2 ++ sway/tree/output.c | 16 ++++++++++++++++ sway/tree/workspace.c | 19 +++++++++++++++++++ 7 files changed, 47 insertions(+) diff --git a/include/sway/output.h b/include/sway/output.h index f27f6344a..b9a4a01f2 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "config.h" #include "sway/tree/node.h" #include "sway/tree/view.h" @@ -57,6 +58,8 @@ struct sway_output { uint32_t refresh_nsec; int max_render_time; // In milliseconds struct wl_event_source *repaint_timer; + + struct wlr_workspace_group_handle_v1 *workspace_group; }; struct sway_output *output_create(struct wlr_output *wlr_output); diff --git a/include/sway/server.h b/include/sway/server.h index 0f5e3ab20..9e15fb394 100644 --- a/include/sway/server.h +++ b/include/sway/server.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -84,6 +85,7 @@ struct sway_server { struct wlr_input_method_manager_v2 *input_method; struct wlr_text_input_manager_v3 *text_input; struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager; + struct wlr_workspace_manager_v1 *workspace_manager; size_t txn_timeout_ms; list_t *transactions; diff --git a/include/sway/tree/workspace.h b/include/sway/tree/workspace.h index 1adbe68a2..b57dceaa7 100644 --- a/include/sway/tree/workspace.h +++ b/include/sway/tree/workspace.h @@ -43,6 +43,9 @@ struct sway_workspace { bool urgent; struct sway_workspace_state current; + + struct wlr_workspace_handle_v1 *workspace_handle; + struct wl_listener *workspace_activate_request; }; struct workspace_config *workspace_find_config(const char *ws_name); diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 90653fa16..4d0e9b33c 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -919,6 +919,8 @@ void handle_new_output(struct wl_listener *listener, void *data) { return; } output->server = server; + output->workspace_group = wlr_workspace_group_handle_v1_create(output->server->workspace_manager); + wlr_workspace_group_handle_v1_output_enter(output->workspace_group, wlr_output); output->damage = wlr_output_damage_create(wlr_output); wl_signal_add(&wlr_output->events.destroy, &output->destroy); diff --git a/sway/server.c b/sway/server.c index ff848450d..b1b84daef 100644 --- a/sway/server.c +++ b/sway/server.c @@ -144,6 +144,8 @@ bool server_init(struct sway_server *server) { server->text_input = wlr_text_input_manager_v3_create(server->wl_display); server->foreign_toplevel_manager = wlr_foreign_toplevel_manager_v1_create(server->wl_display); + server->workspace_manager = + wlr_workspace_manager_v1_create(server->wl_display); wlr_export_dmabuf_manager_v1_create(server->wl_display); wlr_screencopy_manager_v1_create(server->wl_display); diff --git a/sway/tree/output.c b/sway/tree/output.c index d600c5c31..a153a302e 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c @@ -233,6 +233,8 @@ void output_destroy(struct sway_output *output) { "which is still referenced by transactions")) { return; } + wlr_workspace_group_handle_v1_output_leave(output->workspace_group, output->wlr_output); + free(output->workspace_group); list_free(output->workspaces); list_free(output->current.workspaces); wl_event_source_remove(output->repaint_timer); @@ -377,8 +379,22 @@ static int sort_workspace_cmp_qsort(const void *_a, const void *_b) { return 0; } +static void set_workspace_coordinates(struct wlr_workspace_group_handle_v1 *workspace_group) { + struct wlr_workspace_handle_v1 *workspace_handle; + int i = wl_list_length(&workspace_group->workspaces); + wl_list_for_each(workspace_handle, &workspace_group->workspaces, link) { + struct wl_array coordinates; + wl_array_init(&coordinates); + *(int*)wl_array_add(&coordinates, sizeof(int)) = i; + wlr_workspace_handle_v1_set_coordinates(workspace_handle, &coordinates); + wl_array_release(&coordinates); + --i; + } +} + void output_sort_workspaces(struct sway_output *output) { list_stable_sort(output->workspaces, sort_workspace_cmp_qsort); + set_workspace_coordinates(output->workspace_group); } void output_get_box(struct sway_output *output, struct wlr_box *box) { diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 3bcba8e54..d096062d2 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -110,6 +110,9 @@ struct sway_workspace *workspace_create(struct sway_output *output, // If not already added, add the output to the lowest priority workspace_output_add_priority(ws, output); + ws->workspace_handle = wlr_workspace_handle_v1_create(output->workspace_group); + wlr_workspace_handle_v1_set_name(ws->workspace_handle, ws->name); + output_add_workspace(output, ws); output_sort_workspaces(output); @@ -129,6 +132,9 @@ void workspace_destroy(struct sway_workspace *workspace) { return; } + wlr_workspace_handle_v1_destroy(workspace->workspace_handle); + + free(workspace->workspace_handle); free(workspace->name); free(workspace->representation); list_free_items_and_destroy(workspace->output_priority); @@ -453,6 +459,16 @@ struct sway_workspace *workspace_prev(struct sway_workspace *current) { return workspace_prev_next_impl(current, -1); } +static void set_active_current_and_diactivate_others(struct wlr_workspace_handle_v1 *workspace) { + wlr_workspace_handle_v1_set_active(workspace, true); + struct wlr_workspace_handle_v1 *tmp_workspace; + wl_list_for_each(tmp_workspace, &workspace->group->workspaces, link) { + if (workspace != tmp_workspace) { + wlr_workspace_handle_v1_set_active(tmp_workspace, false); + } + } +} + bool workspace_switch(struct sway_workspace *workspace, bool no_auto_back_and_forth) { struct sway_seat *seat = input_manager_current_seat(); @@ -475,6 +491,9 @@ bool workspace_switch(struct sway_workspace *workspace, sway_log(SWAY_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name); + + set_active_current_and_diactivate_others(workspace->workspace_handle); + struct sway_node *next = seat_get_focus_inactive(seat, &workspace->node); if (next == NULL) { next = &workspace->node;