Implement moving windows to other workspaces

This commit is contained in:
Michael Stapelberg 2009-03-04 08:59:03 +01:00
parent 6653c3a686
commit 3911d18982
4 changed files with 78 additions and 3 deletions

View File

@ -121,6 +121,9 @@ struct Stack_Window {
* *
*/ */
struct Workspace { struct Workspace {
/* Number of this workspace, starting from 0 */
int num;
/* x, y, width, height */ /* x, y, width, height */
Rect rect; Rect rect;

View File

@ -147,6 +147,11 @@ bind Mod1+Shift+46 mk
bind Mod1+Shift+47 ml bind Mod1+Shift+47 ml
# Workspaces # Workspaces
bind Mod1+10 1 bind Mod1+10 1
bind Mod1+11 2
...
# Move to Workspace
bind Mod1+Shift+10 1
bind Mod1+Shift+11 2
... ...
------------------------------------------------------------- -------------------------------------------------------------

View File

@ -140,6 +140,7 @@ static void move_current_window(xcb_connection_t *connection, direction_t direct
switch (direction) { switch (direction) {
case D_LEFT: case D_LEFT:
/* TODO: If were at the left-most position, move the rest of the table right */
if (current_col == 0) if (current_col == 0)
return; return;
@ -252,6 +253,60 @@ static void snap_current_container(xcb_connection_t *connection, direction_t dir
render_layout(connection); render_layout(connection);
} }
/*
* Moves the currently selected window to the given workspace
*
*/
static void move_current_window_to_workspace(xcb_connection_t *connection, int workspace) {
printf("Moving current window to workspace %d\n", workspace);
Container *container = CUR_CELL;
assert(container != NULL);
/* t_ws (to workspace) is just a container pointer to the workspace were switching to */
Workspace *t_ws = &(workspaces[workspace-1]);
Client *current_client = container->currently_focused;
if (current_client == NULL) {
printf("No currently focused client in current container.\n");
return;
}
Client *to_focus = CIRCLEQ_NEXT_OR_NULL(&(container->clients), current_client, clients);
if (to_focus == NULL)
to_focus = CIRCLEQ_PREV_OR_NULL(&(container->clients), current_client, clients);
if (t_ws->screen == NULL) {
printf("initializing new workspace, setting num to %d\n", workspace-1);
t_ws->screen = container->workspace->screen;
/* Copy the dimensions from the virtual screen */
memcpy(&(t_ws->rect), &(container->workspace->screen->rect), sizeof(Rect));
}
Container *to_container = t_ws->table[t_ws->current_col][t_ws->current_row];
assert(to_container != NULL);
CIRCLEQ_REMOVE(&(container->clients), current_client, clients);
CIRCLEQ_INSERT_TAIL(&(to_container->clients), current_client, clients);
printf("Moved.\n");
current_client->container = to_container;
container->currently_focused = to_focus;
to_container->currently_focused = current_client;
/* If were moving it to an invisible screen, we need to unmap it */
if (to_container->workspace->screen->current_workspace != to_container->workspace->num) {
printf("This workspace is not visible, unmapping\n");
xcb_unmap_window(connection, current_client->frame);
}
/* delete all empty columns/rows */
cleanup_table(connection, container->workspace);
render_layout(connection);
}
static void show_workspace(xcb_connection_t *conn, int workspace) { static void show_workspace(xcb_connection_t *conn, int workspace) {
Client *client; Client *client;
xcb_window_t root = xcb_setup_roots_iterator(xcb_get_setup(conn)).data->root; xcb_window_t root = xcb_setup_roots_iterator(xcb_get_setup(conn)).data->root;
@ -274,7 +329,7 @@ static void show_workspace(xcb_connection_t *conn, int workspace) {
if (c_ws->screen != t_ws->screen) { if (c_ws->screen != t_ws->screen) {
/* We need to switch to the other screen first */ /* We need to switch to the other screen first */
printf("Just moving over to other screen.\n"); printf("moving over to other screen.\n");
c_ws = &(workspaces[t_ws->screen->current_workspace]); c_ws = &(workspaces[t_ws->screen->current_workspace]);
current_col = c_ws->current_col; current_col = c_ws->current_col;
current_row = c_ws->current_row; current_row = c_ws->current_row;
@ -381,11 +436,10 @@ void parse_command(xcb_connection_t *conn, const char *command) {
} }
/* It's a normal <cmd> */ /* It's a normal <cmd> */
int times;
char *rest = NULL; char *rest = NULL;
enum { ACTION_FOCUS, ACTION_MOVE, ACTION_SNAP } action = ACTION_FOCUS; enum { ACTION_FOCUS, ACTION_MOVE, ACTION_SNAP } action = ACTION_FOCUS;
direction_t direction; direction_t direction;
times = strtol(command, &rest, 10); int times = strtol(command, &rest, 10);
if (rest == NULL) { if (rest == NULL) {
printf("Invalid command (\"%s\")\n", command); printf("Invalid command (\"%s\")\n", command);
return; return;
@ -402,6 +456,18 @@ void parse_command(xcb_connection_t *conn, const char *command) {
rest++; rest++;
} }
int workspace = strtol(rest, &rest, 10);
if (rest == NULL) {
printf("Invalid command (\"%s\")\n", command);
return;
}
if (*rest == '\0') {
move_current_window_to_workspace(conn, workspace);
return;
}
/* Now perform action to <where> */ /* Now perform action to <where> */
while (*rest != '\0') { while (*rest != '\0') {
if (*rest == 'h') if (*rest == 'h')

View File

@ -40,6 +40,7 @@ void init_table() {
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
workspaces[i].screen = NULL; workspaces[i].screen = NULL;
workspaces[i].num = i;
SLIST_INIT(&(workspaces[i].dock_clients)); SLIST_INIT(&(workspaces[i].dock_clients));
expand_table_cols(&(workspaces[i])); expand_table_cols(&(workspaces[i]));
expand_table_rows(&(workspaces[i])); expand_table_rows(&(workspaces[i]));