+# This configuration uses Mod1 and Mod3. Make sure they are mapped properly using xev(1)
+# and xmodmap(1). Usually, Mod1 is Alt (Alt_L) and Mod3 is Windows (Super_L)
+
terminal /usr/bin/urxvt
+
+# ISO 10646 = Unicode
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
# Fullscreen (Mod1+f)
bind Mod1+47 l
# Focus Container (Mod1+j/k/l/;)
-bind Mod1+Control+44 wch
-bind Mod1+Control+45 wcj
-bind Mod1+Control+46 wck
-bind Mod1+Control+47 wcl
+bind Mod3+44 wch
+bind Mod3+45 wcj
+bind Mod3+46 wck
+bind Mod3+47 wcl
# Snap (Mod1+Control+j/k/l/;)
-bind Mod1+Shift+Control+44 sh
-bind Mod1+Shift+Control+45 sj
-bind Mod1+Shift+Control+46 sk
-bind Mod1+Shift+Control+47 sl
+bind Mod1+Control+44 sh
+bind Mod1+Control+45 sj
+bind Mod1+Control+46 sk
+bind Mod1+Control+47 sl
# Move (Mod1+Shift+j/k/l/;)
bind Mod1+Shift+44 mh
bind Mod1+Shift+46 mk
bind Mod1+Shift+47 ml
+# Move Container (Mod3+Shift+j/k/l/;)
+bind Mod3+Shift+44 wcmh
+bind Mod3+Shift+45 wcmj
+bind Mod3+Shift+46 wcmk
+bind Mod3+Shift+47 wcml
+
# Workspaces (Mod1+1/2/…)
bind Mod1+10 1
bind Mod1+11 2
}
/*
- * Moves the current window to the given direction, creating a column/row if
- * necessary
+ * Moves the current window or whole container to the given direction, creating a column/row if
+ * necessary.
*
*/
static void move_current_window(xcb_connection_t *conn, direction_t direction) {
LOG("moving window to direction %s\n", (direction == D_UP ? "up" : (direction == D_DOWN ? "down" :
- (direction == D_LEFT ? "left" : "right"))));
+ (direction == D_LEFT ? "left" : "right"))));
/* Get current window */
Container *container = CUR_CELL,
*new = NULL;
/* If we’re at the left-most position, move the rest of the table right */
if (current_col == 0) {
expand_table_cols_at_head(c_ws);
- new = CUR_TABLE[current_col][current_row];
+ new = CUR_CELL;
} else
new = CUR_TABLE[--current_col][current_row];
-
break;
case D_RIGHT:
if (current_col == (c_ws->cols-1))
new = CUR_TABLE[++current_col][current_row];
break;
case D_UP:
- /* TODO: if we’re at the up-most position, move the rest of the table down */
- if (move_current_window_in_container(conn, current_client, D_UP) ||
- current_row == 0)
+ if (move_current_window_in_container(conn, current_client, D_UP))
return;
- new = CUR_TABLE[current_col][--current_row];
+ /* if we’re at the up-most position, move the rest of the table down */
+ if (current_row == 0) {
+ expand_table_rows_at_head(c_ws);
+ new = CUR_CELL;
+ } else
+ new = CUR_TABLE[current_col][--current_row];
break;
case D_DOWN:
if (move_current_window_in_container(conn, current_client, D_DOWN))
set_focus(conn, current_client);
}
+static void move_current_container(xcb_connection_t *conn, direction_t direction) {
+ LOG("moving container to direction %s\n", (direction == D_UP ? "up" : (direction == D_DOWN ? "down" :
+ (direction == D_LEFT ? "left" : "right"))));
+ /* Get current window */
+ Container *container = CUR_CELL,
+ *new = NULL;
+
+ Container **old = &CUR_CELL;
+
+ /* There has to be a container, see focus_window() */
+ assert(container != NULL);
+
+ switch (direction) {
+ case D_LEFT:
+ /* If we’re at the left-most position, move the rest of the table right */
+ if (current_col == 0) {
+ expand_table_cols_at_head(c_ws);
+ new = CUR_CELL;
+ old = &CUR_TABLE[current_col+1][current_row];
+ } else
+ new = CUR_TABLE[--current_col][current_row];
+ break;
+ case D_RIGHT:
+ if (current_col == (c_ws->cols-1))
+ expand_table_cols(c_ws);
+
+ new = CUR_TABLE[++current_col][current_row];
+ break;
+ case D_UP:
+ /* if we’re at the up-most position, move the rest of the table down */
+ if (current_row == 0) {
+ expand_table_rows_at_head(c_ws);
+ new = CUR_CELL;
+ old = &CUR_TABLE[current_col][current_row+1];
+ } else
+ new = CUR_TABLE[current_col][--current_row];
+ break;
+ case D_DOWN:
+ if (current_row == (c_ws->rows-1))
+ expand_table_rows(c_ws);
+
+ new = CUR_TABLE[current_col][++current_row];
+ break;
+ }
+
+ LOG("old = %d,%d and new = %d,%d\n", container->col, container->row, new->col, new->row);
+
+ /* Swap the containers */
+ int col = new->col;
+ int row = new->row;
+
+ *old = new;
+ new->col = container->col;
+ new->row = container->row;
+
+ CUR_CELL = container;
+ container->col = col;
+ container->row = row;
+
+ Workspace *workspace = container->workspace;
+
+ /* delete all empty columns/rows */
+ cleanup_table(conn, workspace);
+
+ /* Fix colspan/rowspan if it’d overlap */
+ fix_colrowspan(conn, workspace);
+
+ render_layout(conn);
+}
+
/*
* "Snaps" the current container (not possible for windows, because it works at table base)
* to the given direction, that is, adjusts cellspan/rowspan
return;
}
- if (action == ACTION_FOCUS) {
+ if (action == ACTION_FOCUS)
focus_thing(conn, direction, (with == WITH_WINDOW ? THING_WINDOW : THING_CONTAINER));
+ else if (action == ACTION_MOVE) {
+ if (with == WITH_WINDOW)
+ move_current_window(conn, direction);
+ else move_current_container(conn, direction);
}
- else if (action == ACTION_MOVE)
- move_current_window(conn, direction);
else if (action == ACTION_SNAP)
snap_current_container(conn, direction);
}
}
+/*
+ * Adds one row at the head of the table
+ *
+ */
+void expand_table_rows_at_head(Workspace *workspace) {
+ workspace->rows++;
+
+ for (int cols = 0; cols < workspace->cols; cols++)
+ workspace->table[cols] = realloc(workspace->table[cols], sizeof(Container*) * workspace->rows);
+
+ /* Move the other rows */
+ for (int cols = 0; cols < workspace->cols; cols++)
+ for (int rows = workspace->rows - 1; rows > 0; rows--) {
+ LOG("Moving row %d to %d\n", rows-1, rows);
+ workspace->table[cols][rows] = workspace->table[cols][rows-1];
+ workspace->table[cols][rows]->row = rows;
+ }
+ for (int cols = 0; cols < workspace->cols; cols++)
+ new_container(workspace, &(workspace->table[cols][0]), cols, 0);
+}
+
/*
* Add one column to the table
*