From 906914fe618b538308704cea81a5b9392bd34aa1 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Thu, 5 Mar 2009 17:17:37 +0100 Subject: [PATCH] Bugfix: Rendering of colspan/rowspan was wrong --- include/table.h | 3 +++ src/commands.c | 11 +++++++++++ src/layout.c | 7 +++++-- src/table.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 2 deletions(-) diff --git a/include/table.h b/include/table.h index 884e2c8c..9d1d19f9 100644 --- a/include/table.h +++ b/include/table.h @@ -30,5 +30,8 @@ void expand_table_rows(Workspace *workspace); void expand_table_cols(Workspace *workspace); bool cell_exists(int col, int row); void cleanup_table(xcb_connection_t *conn, Workspace *workspace); +void fix_colrowspan(xcb_connection_t *conn, Workspace *workspace); +void dump_table(xcb_connection_t *conn, Workspace *workspace); + #endif diff --git a/src/commands.c b/src/commands.c index e2ebcfe1..57d4dc03 100644 --- a/src/commands.c +++ b/src/commands.c @@ -138,6 +138,7 @@ static bool move_current_window_in_container(xcb_connection_t *conn, Client *cli printf("i can do that\n"); /* We can move the client inside its current container */ + /* TODO: needs wrapping */ CIRCLEQ_REMOVE(&(client->container->clients), client, clients); if (direction == D_UP) CIRCLEQ_INSERT_BEFORE(&(client->container->clients), other, client, clients); @@ -217,6 +218,10 @@ static void move_current_window(xcb_connection_t *conn, direction_t direction) { /* delete all empty columns/rows */ cleanup_table(conn, container->workspace); + + /* Fix colspan/rowspan if it’d overlap */ + fix_colrowspan(conn, container->workspace); + render_layout(conn); set_focus(conn, current_client); @@ -237,6 +242,12 @@ static void snap_current_container(xcb_connection_t *conn, direction_t direction switch (direction) { case D_LEFT: /* Snap to the left is actually a move to the left and then a snap right */ + if (!cell_exists(container->col - 1, container->row) || + CUR_TABLE[container->col-1][container->row]->currently_focused != NULL) { + printf("cannot snap to right - the cell is already used\n"); + return; + } + move_current_window(conn, D_LEFT); snap_current_container(conn, D_RIGHT); return; diff --git a/src/layout.c b/src/layout.c index a6507f3a..7994b7fc 100644 --- a/src/layout.c +++ b/src/layout.c @@ -435,6 +435,7 @@ void render_layout(xcb_connection_t *conn) { for (int cols = 0; cols < r_ws->cols; cols++) for (int rows = 0; rows < r_ws->rows; rows++) { Container *container = r_ws->table[cols][rows]; + int single_width, single_height; printf("\n========\ncontainer has %d colspan, %d rowspan\n", container->colspan, container->rowspan); printf("container at %d, %d\n", xoffset[rows], yoffset[cols]); @@ -447,18 +448,20 @@ void render_layout(xcb_connection_t *conn) { if (container->width_factor == 0) container->width = (width / r_ws->cols); else container->width = get_unoccupied_x(r_ws, rows) * container->width_factor; + single_width = container->width; container->width *= container->colspan; if (container->height_factor == 0) container->height = (height / r_ws->rows); else container->height = get_unoccupied_y(r_ws, cols) * container->height_factor; + single_height = container->height; container->height *= container->rowspan; /* Render the container if it is not empty */ render_container(conn, container); - xoffset[rows] += container->width; - yoffset[cols] += container->height; + xoffset[rows] += single_width; + yoffset[cols] += single_height; printf("==========\n"); } diff --git a/src/table.c b/src/table.c index 733acb6c..559fd064 100644 --- a/src/table.c +++ b/src/table.c @@ -154,6 +154,24 @@ static void move_rows_from(xcb_connection_t *conn, Workspace *workspace, int row } } +void dump_table(xcb_connection_t *conn, Workspace *workspace) { + printf("dump_table()\n"); + for (int cols = 0; cols < workspace->cols; cols++) { + for (int rows = 0; rows < workspace->rows; rows++) { + Container *con = workspace->table[cols][rows]; + printf("----\n"); + printf("at col=%d, row=%d\n", cols, rows); + printf("currently_focused = %p\n", con->currently_focused); + Client *loop; + CIRCLEQ_FOREACH(loop, &(con->clients), clients) { + printf("got client %08x / %s\n", loop->child, loop->name); + } + printf("----\n"); + } + } + printf("done\n"); +} + /* * Shrinks the table by "compacting" it, that is, removing completely empty rows/columns * @@ -209,3 +227,30 @@ void cleanup_table(xcb_connection_t *conn, Workspace *workspace) { if (CUR_CELL->currently_focused != NULL) set_focus(conn, CUR_CELL->currently_focused); } + +/* + * Fixes col/rowspan (makes sure there are no overlapping windows) + * + */ +void fix_colrowspan(xcb_connection_t *conn, Workspace *workspace) { + printf("Fixing col/rowspan\n"); + + for (int cols = 0; cols < workspace->cols; cols++) + for (int rows = 0; rows < workspace->rows; rows++) { + Container *con = workspace->table[cols][rows]; + if (con->colspan > 1) { + printf("gots one with colspan %d\n", con->colspan); + while (con->colspan > 1 && + workspace->table[cols + (con->colspan - 1)][rows]->currently_focused != NULL) + con->colspan--; + printf("fixed it to %d\n", con->colspan); + } + if (con->rowspan > 1) { + printf("gots one with rowspan %d\n", con->rowspan); + while (con->rowspan > 1 && + workspace->table[cols][rows + (con->rowspan - 1)]->currently_focused != NULL) + con->rowspan--; + printf("fixed it to %d\n", con->rowspan); + } + } +} -- 2.39.5