From 642bc148caade5734f560ab95417e8acac86cc35 Mon Sep 17 00:00:00 2001 From: project-repo Date: Sun, 17 Sep 2023 21:56:36 +0200 Subject: [PATCH] Add fix for layout changes on disconnect --- output.c | 88 ++++++++++++++++++++++++++++++++++---------------------- view.c | 2 +- 2 files changed, 54 insertions(+), 36 deletions(-) diff --git a/output.c b/output.c index 625e966..17e215a 100644 --- a/output.c +++ b/output.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #if CG_HAS_XWAYLAND @@ -114,9 +115,14 @@ output_get_num(const struct cg_output *output) { struct wlr_box output_get_layout_box(struct cg_output *output) { - if(!output->destroyed) { - wlr_output_layout_get_box(output->server->output_layout, - output->wlr_output, &output->layout_box); + struct wlr_box box; + wlr_output_layout_get_box(output->server->output_layout, output->wlr_output, + &box); + if(!output->destroyed && !wlr_box_empty(&box)) { + output->layout_box.x = box.x; + output->layout_box.y = box.y; + output->layout_box.width = box.width; + output->layout_box.height = box.height; } return output->layout_box; } @@ -281,8 +287,11 @@ output_apply_config(struct cg_server *server, struct cg_output *output, struct cg_output_config *config) { struct wlr_output *wlr_output = output->wlr_output; - wlr_output_layout_get_box(server->output_layout, output->wlr_output, - &output->layout_box); + struct wlr_box prev_box; + prev_box.x = output->layout_box.x; + prev_box.y = output->layout_box.y; + prev_box.width = output->layout_box.width; + prev_box.height = output->layout_box.height; if(config->role != OUTPUT_ROLE_DEFAULT) { output->role = config->role; if((output->role == OUTPUT_ROLE_PERIPHERAL) && @@ -293,10 +302,6 @@ output_apply_config(struct cg_server *server, struct cg_output *output, } } - if(output->wlr_output->enabled) { - wlr_output_layout_remove(server->output_layout, wlr_output); - } - if(config->priority != -1) { output->priority = config->priority; } @@ -318,38 +323,48 @@ output_apply_config(struct cg_server *server, struct cg_output *output, wlr_output_commit(wlr_output); return; } - wlr_output_layout_add(server->output_layout, wlr_output, config->pos.x, - config->pos.y); - /* Since the size of the output may have changed, we - * reinitialize all workspaces with a fullscreen layout */ - if(output->layout_box.width != config->pos.width || - output->layout_box.height != config->pos.height) { - for(unsigned int i = 0; i < output->server->nws; ++i) { - output_make_workspace_fullscreen(output, i); - } + if(wlr_box_empty(&output->layout_box)) { + wlr_output_layout_add(server->output_layout, wlr_output, + config->pos.x, config->pos.y); } else { + wlr_output_layout_move(server->output_layout, wlr_output, + config->pos.x, config->pos.y); + } + if(output->workspaces != NULL) { wlr_output_layout_get_box(server->output_layout, output->wlr_output, &output->layout_box); - for(unsigned int i = 0; i < server->nws; ++i) { - struct cg_workspace *ws = output->workspaces[i]; - bool first = true; - for(struct cg_tile *tile = ws->focused_tile; - first || output->workspaces[i]->focused_tile != tile; - tile = tile->next) { - first = false; - if(tile->view != NULL) { - wlr_scene_node_set_position( - &tile->view->scene_tree->node, - tile->view->ox + output->layout_box.x, - output->layout_box.y); + /* Since the size of the output may have changed, we + * reinitialize all workspaces with a fullscreen layout */ + if(output->layout_box.width != prev_box.width || + output->layout_box.height != prev_box.height) { + for(unsigned int i = 0; i < output->server->nws; ++i) { + output_make_workspace_fullscreen(output, i); + } + } + if(prev_box.x != output->layout_box.x || + prev_box.y != output->layout_box.y) { + for(unsigned int i = 0; i < server->nws; ++i) { + struct cg_workspace *ws = output->workspaces[i]; + bool first = true; + for(struct cg_tile *tile = ws->focused_tile; + first || output->workspaces[i]->focused_tile != tile; + tile = tile->next) { + first = false; + if(tile->view != NULL) { + wlr_scene_node_set_position( + &tile->view->scene_tree->node, + tile->view->ox + output->layout_box.x, + tile->view->oy + output->layout_box.y); + } } } } } - } else { + } else if(wlr_box_empty(&output->layout_box)) { wlr_output_layout_add_auto(server->output_layout, wlr_output); // The following two lines make sure that the output is "manually" - // managed, so that its position doesn't change anymore in the future. + // managed, so that its position doesn't change anymore in the + // future. wlr_output_layout_get_box(server->output_layout, output->wlr_output, &output->layout_box); wlr_output_layout_move(server->output_layout, output->wlr_output, @@ -541,9 +556,9 @@ handle_output_mode(struct wl_listener *listener, void *data) { void output_make_workspace_fullscreen(struct cg_output *output, int ws) { struct cg_server *server = output->server; - struct cg_view *current_view = seat_get_focus(server->seat); + struct cg_view *current_view = output->workspaces[ws]->focused_tile->view; - if(current_view == NULL || ws != output->curr_workspace) { + if(current_view == NULL) { struct cg_view *it = NULL; wl_list_for_each(it, &output->workspaces[ws]->views, link) { if(view_is_visible(it)) { @@ -566,7 +581,9 @@ output_make_workspace_fullscreen(struct cg_output *output, int ws) { it_view->tile = output->workspaces[ws]->focused_tile; } - if(ws == output->curr_workspace) { + workspace_tile_update_view(output->workspaces[ws]->focused_tile, + current_view); + if((ws == output->curr_workspace) && (output == server->curr_output)) { seat_set_focus(server->seat, current_view); } } @@ -579,6 +596,7 @@ void handle_new_output(struct wl_listener *listener, void *data) { struct cg_server *server = wl_container_of(listener, server, new_output); struct wlr_output *wlr_output = data; + wlr_output_enable(wlr_output, true); if(!wlr_output_init_render(wlr_output, server->allocator, server->renderer)) { diff --git a/view.c b/view.c index 425a6e1..5237c46 100644 --- a/view.c +++ b/view.c @@ -84,7 +84,7 @@ view_maximize(struct cg_view *view, struct cg_tile *tile) { wlr_scene_node_set_position( &view->scene_tree->node, view->ox + output_get_layout_box(view->workspace->output).x, - output_get_layout_box(view->oy + view->workspace->output).y); + view->oy + output_get_layout_box(view->workspace->output).y); view->impl->maximize(view, tile->tile.width, tile->tile.height); view->tile = tile; wlr_scene_node_raise_to_top(&view->scene_tree->node);