Bugfix: Re-distribute free space when closing customly resized containers, re-evaluate for other containers

This fixes ticket #4
This commit is contained in:
Michael Stapelberg 2009-05-03 14:29:58 +02:00
parent eab895ac9e
commit a0d23c53b3
4 changed files with 61 additions and 5 deletions

View File

@ -13,6 +13,14 @@
#ifndef _LAYOUT_H #ifndef _LAYOUT_H
#define _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. * (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. * When in stacking mode, the window decorations are drawn onto an own window.

View File

@ -468,14 +468,45 @@ int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_
return 1; 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 */ /* Convert 0 (for default width_factor) to actual numbers */
if (first->width_factor == 0) if (first->width_factor == 0)
first->width_factor = ((float)ws->rect.width / ws->cols) / ws->rect.width; 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) if (second->width_factor == 0)
second->width_factor = ((float)ws->rect.width / ws->cols) / ws->rect.width; 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; 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; 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 { } else {
LOG("Resize was from Y = %d to Y = %d\n", event->root_y, new_position); LOG("Resize was from Y = %d to Y = %d\n", event->root_y, new_position);
if (event->root_y == new_position) { if (event->root_y == new_position) {

View File

@ -51,13 +51,13 @@ int get_unoccupied_x(Workspace *workspace, int row) {
for (int cols = 0; cols < workspace->cols;) { for (int cols = 0; cols < workspace->cols;) {
Container *con = workspace->table[cols][row]; Container *con = workspace->table[cols][row];
LOG("width_factor[%d][%d] = %f, colspan = %d\n", cols, row, con->width_factor, con->colspan); 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; unoccupied -= workspace->rect.width * default_factor * con->colspan;
}
cols += con->colspan; cols += con->colspan;
} }
assert(unoccupied != 0);
LOG("unoccupied space: %d\n", unoccupied); LOG("unoccupied space: %d\n", unoccupied);
return unoccupied; return unoccupied;
} }
@ -77,8 +77,6 @@ int get_unoccupied_y(Workspace *workspace, int col) {
rows += con->rowspan; rows += con->rowspan;
} }
assert(unoccupied != 0);
LOG("unoccupied space: %d\n", unoccupied); LOG("unoccupied space: %d\n", unoccupied);
return unoccupied; return unoccupied;
} }

View File

@ -171,6 +171,25 @@ static void free_container(xcb_connection_t *conn, Workspace *workspace, int col
if (old_container->mode == MODE_STACK) if (old_container->mode == MODE_STACK)
leave_stack_mode(conn, old_container); 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); free(old_container);
} }