From a0d23c53b34c341671904f36f5b697acb098e88b Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sun, 3 May 2009 14:29:58 +0200 Subject: [PATCH] Bugfix: Re-distribute free space when closing customly resized containers, re-evaluate for other containers This fixes ticket #4 --- include/layout.h | 8 ++++++++ src/handlers.c | 31 +++++++++++++++++++++++++++++++ src/layout.c | 8 +++----- src/table.c | 19 +++++++++++++++++++ 4 files changed, 61 insertions(+), 5 deletions(-) diff --git a/include/layout.h b/include/layout.h index 7f930160..40df0ad1 100644 --- a/include/layout.h +++ b/include/layout.h @@ -13,6 +13,14 @@ #ifndef _LAYOUT_H #define _LAYOUT_H +/** + * Gets the unoccupied space (= space which is available for windows which were resized by the user) + * for the given row. This is necessary to render both, customly resized windows and never touched + * windows correctly, meaning that the aspect ratio will be maintained when opening new windows. + * + */ +int get_unoccupied_x(Workspace *workspace, int row); + /** * (Re-)draws window decorations for a given Client onto the given drawable/graphic context. * When in stacking mode, the window decorations are drawn onto an own window. diff --git a/src/handlers.c b/src/handlers.c index 150a7516..1113b826 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -468,14 +468,45 @@ int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_ return 1; } + /* Save the old unoccupied space to re-evaluate the other containers (not first or second) later */ + int old_unoccupied_x = get_unoccupied_x(ws, first->row); + /* Convert 0 (for default width_factor) to actual numbers */ if (first->width_factor == 0) first->width_factor = ((float)ws->rect.width / ws->cols) / ws->rect.width; + else first->width_factor = ((first->width_factor * old_unoccupied_x) / ws->rect.width); + if (second->width_factor == 0) second->width_factor = ((float)ws->rect.width / ws->cols) / ws->rect.width; + else second->width_factor = ((second->width_factor * old_unoccupied_x) / ws->rect.width); + + LOG("\n\n\n"); + + LOG("old_unoccupied_x = %d\n", old_unoccupied_x); + + LOG("Old first->width_factor = %f\n", first->width_factor); + LOG("Old second->width_factor = %f\n", second->width_factor); first->width_factor *= (float)(first->width + (new_position - event->root_x)) / first->width; second->width_factor *= (float)(second->width - (new_position - event->root_x)) / second->width; + + LOG("new unoccupied_x = %d\n", get_unoccupied_x(ws, first->row)); + LOG("old_unoccupied_x = %d\n", old_unoccupied_x); + + for (int col = 0; col < ws->cols; col++) { + Container *con = ws->table[col][first->row]; + if (con == first || con == second) + continue; + + LOG("Updating other container (current width_factor = %f)\n", con->width_factor); + con->width_factor = ((con->width_factor * old_unoccupied_x) / get_unoccupied_x(ws, first->row)); + LOG("to %f\n", con->width_factor); + } + + LOG("New first->width_factor = %f\n", first->width_factor); + LOG("New second->width_factor = %f\n", second->width_factor); + + LOG("\n\n\n"); } else { LOG("Resize was from Y = %d to Y = %d\n", event->root_y, new_position); if (event->root_y == new_position) { diff --git a/src/layout.c b/src/layout.c index 4c18989f..033e2a4c 100644 --- a/src/layout.c +++ b/src/layout.c @@ -51,13 +51,13 @@ int get_unoccupied_x(Workspace *workspace, int row) { for (int cols = 0; cols < workspace->cols;) { Container *con = workspace->table[cols][row]; LOG("width_factor[%d][%d] = %f, colspan = %d\n", cols, row, con->width_factor, con->colspan); - if (con->width_factor == 0) + if (con->width_factor == 0) { + LOG("- %d * %f * %d = %f\n", workspace->rect.width, default_factor, con->colspan, workspace->rect.width * default_factor * con->colspan); unoccupied -= workspace->rect.width * default_factor * con->colspan; + } cols += con->colspan; } - assert(unoccupied != 0); - LOG("unoccupied space: %d\n", unoccupied); return unoccupied; } @@ -77,8 +77,6 @@ int get_unoccupied_y(Workspace *workspace, int col) { rows += con->rowspan; } - assert(unoccupied != 0); - LOG("unoccupied space: %d\n", unoccupied); return unoccupied; } diff --git a/src/table.c b/src/table.c index 491d3bc8..27c4af47 100644 --- a/src/table.c +++ b/src/table.c @@ -171,6 +171,25 @@ static void free_container(xcb_connection_t *conn, Workspace *workspace, int col if (old_container->mode == MODE_STACK) leave_stack_mode(conn, old_container); + /* We need to distribute the space which will now be freed to other containers */ + if (old_container->width_factor > 0) { + Container *dest_container = NULL; + /* Check if we got a container to the left… */ + if (col > 0) + dest_container = workspace->table[col-1][row]; + /* …or to the right */ + else if ((col+1) < workspace->cols) + dest_container = workspace->table[col+1][row]; + + if (dest_container != NULL) { + if (dest_container->width_factor == 0) + dest_container->width_factor = ((float)workspace->rect.width / workspace->cols) / workspace->rect.width; + LOG("dest_container->width_factor = %f\n", dest_container->width_factor); + dest_container->width_factor += old_container->width_factor; + LOG("afterwards it's %f\n", dest_container->width_factor); + } + } + free(old_container); }