From 8b0bc8c3ff59e4478149144b119292824f6b0668 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Mon, 23 Feb 2009 03:27:59 +0100 Subject: [PATCH] Implement vertical resize --- src/handlers.c | 63 +++++++++++++++++++++++++++++++++++++------------- src/layout.c | 36 +++++++++++++++++++++++++---- 2 files changed, 78 insertions(+), 21 deletions(-) diff --git a/src/handlers.c b/src/handlers.c index ea285492..b4c5f94e 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -139,6 +139,7 @@ int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_ Container *con = client->container, *first = NULL, *second = NULL; + enum { O_HORIZONTAL, O_VERTICAL } orientation = O_VERTICAL; printf("event->event_x = %d, client->rect.width = %d\n", event->event_x, client->rect.width); @@ -151,14 +152,16 @@ int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_ /* This was a press on the top border */ if (con->row == 0) return 1; - return 0; /* TODO: impl */ - //neighbor_con = this_con->workspace->table[this_con->col][this_con->row-1]; + first = con->workspace->table[con->col][con->row-1]; + second = con; + orientation = O_HORIZONTAL; } else if (event->event_y >= (client->rect.height - 2)) { /* …bottom border */ if (con->row == (con->workspace->rows-1)) return 1; - return 0; /* TODO; impl */ - //neighbor_con = this_con->workspace->table[this_con->col][this_con->row+1]; + first = con; + second = con->workspace->table[con->col][con->row+1]; + orientation = O_HORIZONTAL; } else if (event->event_x < 2) { /* …left border */ if (con->col == 0) @@ -178,7 +181,18 @@ int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_ Rect grabrect = {0, 0, root_screen->width_in_pixels, root_screen->height_in_pixels}; xcb_window_t grabwin = create_window(conn, grabrect, XCB_WINDOW_CLASS_INPUT_ONLY, 0, NULL); - Rect helprect = {event->root_x, 0, 2, root_screen->height_in_pixels /* this has to be the cell’s height */}; + Rect helprect; + if (orientation == O_VERTICAL) { + helprect.x = event->root_x; + helprect.y = 0; + helprect.width = 2; + helprect.height = root_screen->height_in_pixels; /* this has to be the cell’s height */ + } else { + helprect.x = 0; + helprect.y = event->root_y; + helprect.width = root_screen->width_in_pixels; /* this has to be the cell’s width*/ + helprect.height = 2; + } xcb_window_t helpwin = create_window(conn, helprect, XCB_WINDOW_CLASS_INPUT_OUTPUT, 0, NULL); uint32_t values[1] = {get_colorpixel(conn, helpwin, "#4c7899")}; @@ -213,8 +227,14 @@ int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_ switch (nr) { case XCB_MOTION_NOTIFY: - values[0] = ((xcb_motion_notify_event_t*)inside_event)->root_x; - xcb_configure_window(conn, helpwin, XCB_CONFIG_WINDOW_X, values); + if (orientation == O_VERTICAL) { + values[0] = ((xcb_motion_notify_event_t*)inside_event)->root_x; + xcb_configure_window(conn, helpwin, XCB_CONFIG_WINDOW_X, values); + } else { + values[0] = ((xcb_motion_notify_event_t*)inside_event)->root_y; + xcb_configure_window(conn, helpwin, XCB_CONFIG_WINDOW_Y, values); + } + xcb_flush(conn); break; case XCB_EXPOSE: @@ -225,7 +245,6 @@ int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_ printf("Ignoring event of type %d\n", nr); break; } - printf("---\n"); free(inside_event); } @@ -235,17 +254,29 @@ int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_ xcb_flush(conn); Workspace *ws = con->workspace; + if (orientation == O_VERTICAL) { + printf("Resize was from X = %d to X = %d\n", event->root_x, values[0]); + + /* 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; + if (second->width_factor == 0) + second->width_factor = ((float)ws->rect.width / ws->cols) / ws->rect.width; - printf("Resize was from X = %d to X = %d\n", event->root_x, values[0]); + first->width_factor *= (float)(first->width + (values[0] - event->root_x)) / first->width; + second->width_factor *= (float)(second->width - (values[0] - event->root_x)) / second->width; + } else { + printf("Resize was from Y = %d to Y = %d\n", event->root_y, values[0]); - /* 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; - if (second->width_factor == 0) - second->width_factor = ((float)ws->rect.width / ws->cols) / ws->rect.width; + /* Convert 0 (for default height_factor) to actual numbers */ + if (first->height_factor == 0) + first->height_factor = ((float)ws->rect.height / ws->rows) / ws->rect.height; + if (second->height_factor == 0) + second->height_factor = ((float)ws->rect.height / ws->rows) / ws->rect.height; - first->width_factor *= (float)(first->width + (values[0] - event->root_x)) / first->width; - second->width_factor *= (float)(second->width - (values[0] - event->root_x)) / second->width; + first->height_factor *= (float)(first->height + (values[0] - event->root_y)) / first->height; + second->height_factor *= (float)(second->height - (values[0] - event->root_y)) / second->height; + } render_layout(conn); diff --git a/src/layout.c b/src/layout.c index b1e5951f..42b08541 100644 --- a/src/layout.c +++ b/src/layout.c @@ -52,6 +52,31 @@ int get_unoccupied_x(Workspace *workspace, int row) { return unoccupied; } +/* See get_unoccupied_x() */ +int get_unoccupied_y(Workspace *workspace, int col) { + int unoccupied = workspace->rect.height; + float default_factor = ((float)workspace->rect.height / workspace->rows) / workspace->rect.height; + + printf("get_unoccupied_y(), starting with %d, default_factor = %f\n", unoccupied, default_factor); + + for (int rows = 0; rows < workspace->rows;) { + Container *con = workspace->table[col][rows]; + printf("oh hai. wf[%d][%d] = %f\n", col, rows, con->height_factor); + printf("rowspan = %d\n", con->rowspan); + if (con->height_factor == 0) + unoccupied -= workspace->rect.height * default_factor * con->rowspan; + rows += con->rowspan; + } + + /* TODO: Check (as soon as the whole implementation is done) if this case does ever occur, + because this function only gets called when at least one client was resized */ + if (unoccupied == 0) + unoccupied = workspace->rect.height; + + printf("unoccupied space: %d\n", unoccupied); + return unoccupied; +} + /* * (Re-)draws window decorations for a given Client * @@ -188,10 +213,6 @@ static void render_container(xcb_connection_t *connection, Container *container) situation? Let’s find out… */ if (client->dock) continue; - /* TODO: at the moment, every column/row is screen / num_cols. This - * needs to be changed to "percentage of the screen" by - * default and adjustable by the user if necessary. - */ /* Check if we changed client->x or client->y by updating it… * Note the bitwise OR instead of logical OR to force evaluation of both statements */ @@ -279,11 +300,16 @@ void render_layout(xcb_connection_t *connection) { container->col = cols; container->x = xoffset[rows]; container->y = yoffset[cols]; + if (container->width_factor == 0) container->width = (width / r_ws->cols); else container->width = get_unoccupied_x(r_ws, rows) * container->width_factor; container->width *= container->colspan; - container->height = (height / r_ws->rows) * container->rowspan; + + if (container->height_factor == 0) + container->height = (height / r_ws->rows); + else container->height = get_unoccupied_y(r_ws, cols) * container->height_factor; + container->height *= container->rowspan; /* Render it */ render_container(connection, container); -- 2.39.5