#include "xinerama.h"
#include "client.h"
#include "floating.h"
+#include "xcb.h"
bool focus_window_in_container(xcb_connection_t *conn, Container *container, direction_t direction) {
/* If this container is empty, we’re done */
int new_row = current_row,
new_col = current_col;
-
Container *container = CUR_CELL;
Workspace *t_ws = c_ws;
+ /* Makes sure new_col and new_row are within bounds of the new workspace */
+ void check_colrow_boundaries() {
+ if (new_col >= t_ws->cols)
+ new_col = (t_ws->cols - 1);
+ if (new_row >= t_ws->rows)
+ new_row = (t_ws->rows - 1);
+ }
+
/* There always is a container. If not, current_col or current_row is wrong */
assert(container != NULL);
t_ws = &(workspaces[screen->current_workspace]);
new_row = (direction == D_UP ? (t_ws->rows - 1) : 0);
}
+
+ check_colrow_boundaries();
+
+ LOG("new_col = %d, new_row = %d\n", new_col, new_row);
+ if (t_ws->table[new_col][new_row]->currently_focused == NULL) {
+ LOG("Cell empty, checking for colspanned client above...\n");
+ for (int cols = 0; cols < new_col; cols += t_ws->table[cols][new_row]->colspan) {
+ if (new_col > (cols + (t_ws->table[cols][new_row]->colspan - 1)))
+ continue;
+
+ new_col = cols;
+ break;
+ }
+ LOG("Fixed it to new col %d\n", new_col);
+ }
} else if (direction == D_LEFT || direction == D_RIGHT) {
if (direction == D_RIGHT && cell_exists(current_col+1, current_row))
new_col = current_col + t_ws->table[current_col][current_row]->colspan;
t_ws = &(workspaces[screen->current_workspace]);
new_col = (direction == D_LEFT ? (t_ws->cols - 1) : 0);
}
+
+ check_colrow_boundaries();
+
+ LOG("new_col = %d, new_row = %d\n", new_col, new_row);
+ if (t_ws->table[new_col][new_row]->currently_focused == NULL) {
+ LOG("Cell empty, checking for rowspanned client above...\n");
+ for (int rows = 0; rows < new_row; rows += t_ws->table[new_col][rows]->rowspan) {
+ if (new_row > (rows + (t_ws->table[new_col][rows]->rowspan - 1)))
+ continue;
+
+ new_row = rows;
+ break;
+ }
+ LOG("Fixed it to new row %d\n", new_row);
+ }
} else {
LOG("direction unhandled\n");
return;
}
- /* Bounds checking */
- if (new_col >= t_ws->cols)
- new_col = (t_ws->cols - 1);
- if (new_row >= t_ws->rows)
- new_row = (t_ws->rows - 1);
+ check_colrow_boundaries();
if (t_ws->table[new_col][new_row]->currently_focused != NULL)
set_focus(conn, t_ws->table[new_col][new_row]->currently_focused, true);
}
}
- /* Remove from focus stack and list of floating clients */
- SLIST_REMOVE(&(client->workspace->focus_stack), client, Client, focus_clients);
- TAILQ_REMOVE(&(client->workspace->floating_clients), client, floating_clients);
+ floating_assign_to_workspace(client, t_ws);
- if (client->workspace->fullscreen_client == client)
- client->workspace->fullscreen_client = NULL;
-
- /* Insert into destination focus stack and list of floating clients */
- client->workspace = t_ws;
- SLIST_INSERT_HEAD(&(t_ws->focus_stack), client, focus_clients);
- TAILQ_INSERT_TAIL(&(t_ws->floating_clients), client, floating_clients);
- if (client->fullscreen)
- t_ws->fullscreen_client = client;
+ bool target_invisible = t_ws->screen->current_workspace != t_ws->num;
/* If we’re moving it to an invisible screen, we need to unmap it */
- if (t_ws->screen->current_workspace != t_ws->num) {
+ if (target_invisible) {
LOG("This workspace is not visible, unmapping\n");
xcb_unmap_window(conn, client->frame);
} else {
LOG("done\n");
render_layout(conn);
+
+ if (!target_invisible)
+ set_focus(conn, client, true);
}
/*
CIRCLEQ_INSERT_TAIL(&(to_container->clients), current_client, clients);
SLIST_INSERT_HEAD(&(to_container->workspace->focus_stack), current_client, focus_clients);
- if (current_client->fullscreen)
- t_ws->fullscreen_client = current_client;
LOG("Moved.\n");
current_client->container = to_container;
container->currently_focused = to_focus;
to_container->currently_focused = current_client;
+ bool target_invisible = (to_container->workspace->screen->current_workspace != to_container->workspace->num);
+
/* If we’re moving it to an invisible screen, we need to unmap it */
- if (to_container->workspace->screen->current_workspace != to_container->workspace->num) {
+ if (target_invisible) {
LOG("This workspace is not visible, unmapping\n");
xcb_unmap_window(conn, current_client->frame);
+ } else {
+ if (current_client->fullscreen) {
+ LOG("Calling client_enter_fullscreen again\n");
+ client_enter_fullscreen(conn, current_client);
+ }
}
/* delete all empty columns/rows */
cleanup_table(conn, container->workspace);
render_layout(conn);
+
+ if (!target_invisible)
+ set_focus(conn, current_client, true);
}
/*
fix_colrowspan(conn, last_focused->workspace);
render_workspace(conn, last_focused->workspace->screen, last_focused->workspace);
- xcb_flush(conn);
+
+ /* Re-focus the client because cleanup_table sets the focus to the last
+ * focused client inside a container only. */
+ set_focus(conn, last_focused, true);
+
return;
}