Make number of workspaces dynamic (no longer limited by 10)
Warning: This is not yet thoroughly tested, so be prepared to encounter some segfaults. Please enable logging and coredumps, so we can fix bugs quickly.
This commit is contained in:
parent
a55d0b77fe
commit
f38809288a
|
@ -21,7 +21,8 @@
|
||||||
#define CUR_CELL (CUR_TABLE[current_col][current_row])
|
#define CUR_CELL (CUR_TABLE[current_col][current_row])
|
||||||
|
|
||||||
extern Workspace *c_ws;
|
extern Workspace *c_ws;
|
||||||
extern Workspace workspaces[10];
|
extern Workspace *workspaces;
|
||||||
|
extern int num_workspaces;
|
||||||
extern int current_col;
|
extern int current_col;
|
||||||
extern int current_row;
|
extern int current_row;
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,9 @@
|
||||||
#ifndef _WORKSPACE_H
|
#ifndef _WORKSPACE_H
|
||||||
#define _WORKSPACE_H
|
#define _WORKSPACE_H
|
||||||
|
|
||||||
|
|
||||||
|
Workspace *workspace_get(int number);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the name (or just its number) for the given workspace. This has to
|
* Sets the name (or just its number) for the given workspace. This has to
|
||||||
* be called for every workspace as the rendering function
|
* be called for every workspace as the rendering function
|
||||||
|
|
19
src/click.c
19
src/click.c
|
@ -129,7 +129,7 @@ static bool button_press_bar(xcb_connection_t *conn, xcb_button_press_event_t *e
|
||||||
/* Check if the button was one of button4 or button5 (scroll up / scroll down) */
|
/* Check if the button was one of button4 or button5 (scroll up / scroll down) */
|
||||||
if (event->detail == XCB_BUTTON_INDEX_4 || event->detail == XCB_BUTTON_INDEX_5) {
|
if (event->detail == XCB_BUTTON_INDEX_4 || event->detail == XCB_BUTTON_INDEX_5) {
|
||||||
int add = (event->detail == XCB_BUTTON_INDEX_4 ? -1 : 1);
|
int add = (event->detail == XCB_BUTTON_INDEX_4 ? -1 : 1);
|
||||||
for (int i = c_ws->num + add; (i >= 0) && (i < 10); i += add)
|
for (int i = c_ws->num + add; (i >= 0) && (i < num_workspaces); i += add)
|
||||||
if (workspaces[i].screen == screen) {
|
if (workspaces[i].screen == screen) {
|
||||||
workspace_show(conn, i+1);
|
workspace_show(conn, i+1);
|
||||||
return true;
|
return true;
|
||||||
|
@ -139,7 +139,7 @@ static bool button_press_bar(xcb_connection_t *conn, xcb_button_press_event_t *e
|
||||||
int drawn = 0;
|
int drawn = 0;
|
||||||
/* Because workspaces can be on different screens, we need to loop
|
/* Because workspaces can be on different screens, we need to loop
|
||||||
through all of them and decide to count it based on its ->screen */
|
through all of them and decide to count it based on its ->screen */
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < num_workspaces; i++) {
|
||||||
if (workspaces[i].screen != screen)
|
if (workspaces[i].screen != screen)
|
||||||
continue;
|
continue;
|
||||||
LOG("Checking if click was on workspace %d with drawn = %d, tw = %d\n",
|
LOG("Checking if click was on workspace %d with drawn = %d, tw = %d\n",
|
||||||
|
@ -198,6 +198,7 @@ int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_
|
||||||
to_bottom = client->rect.height - event->event_y;
|
to_bottom = client->rect.height - event->event_y;
|
||||||
resize_orientation_t orientation = O_VERTICAL;
|
resize_orientation_t orientation = O_VERTICAL;
|
||||||
Container *con = client->container;
|
Container *con = client->container;
|
||||||
|
Workspace *ws = con->workspace;
|
||||||
int first = 0, second = 0;
|
int first = 0, second = 0;
|
||||||
|
|
||||||
LOG("click was %d px to the right, %d px to the left, %d px to top, %d px to bottom\n",
|
LOG("click was %d px to the right, %d px to the left, %d px to top, %d px to bottom\n",
|
||||||
|
@ -211,7 +212,7 @@ int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_
|
||||||
LOG("column %d\n", first);
|
LOG("column %d\n", first);
|
||||||
|
|
||||||
if (!cell_exists(first, con->row) ||
|
if (!cell_exists(first, con->row) ||
|
||||||
(first == (con->workspace->cols-1)))
|
(first == (ws->cols-1)))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
second = first + 1;
|
second = first + 1;
|
||||||
|
@ -239,14 +240,14 @@ int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_
|
||||||
/* …bottom border */
|
/* …bottom border */
|
||||||
first = con->row + (con->rowspan - 1);
|
first = con->row + (con->rowspan - 1);
|
||||||
if (!cell_exists(con->col, first) ||
|
if (!cell_exists(con->col, first) ||
|
||||||
(first == (con->workspace->rows-1)))
|
(first == (ws->rows-1)))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
second = first + 1;
|
second = first + 1;
|
||||||
orientation = O_HORIZONTAL;
|
orientation = O_HORIZONTAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return resize_graphical_handler(conn, con->workspace, first, second, orientation, event);
|
return resize_graphical_handler(conn, ws, first, second, orientation, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,6 +324,8 @@ int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_
|
||||||
if (client_is_floating(client))
|
if (client_is_floating(client))
|
||||||
return floating_border_click(conn, client, event);
|
return floating_border_click(conn, client, event);
|
||||||
|
|
||||||
|
Workspace *ws = con->workspace;
|
||||||
|
|
||||||
if (event->event_y < 2) {
|
if (event->event_y < 2) {
|
||||||
/* This was a press on the top border */
|
/* This was a press on the top border */
|
||||||
if (con->row == 0)
|
if (con->row == 0)
|
||||||
|
@ -334,7 +337,7 @@ int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_
|
||||||
/* …bottom border */
|
/* …bottom border */
|
||||||
first = con->row + (con->rowspan - 1);
|
first = con->row + (con->rowspan - 1);
|
||||||
if (!cell_exists(con->col, first) ||
|
if (!cell_exists(con->col, first) ||
|
||||||
(first == (con->workspace->rows-1)))
|
(first == (ws->rows-1)))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
second = first + 1;
|
second = first + 1;
|
||||||
|
@ -352,11 +355,11 @@ int handle_button_press(void *ignored, xcb_connection_t *conn, xcb_button_press_
|
||||||
LOG("column %d\n", first);
|
LOG("column %d\n", first);
|
||||||
|
|
||||||
if (!cell_exists(first, con->row) ||
|
if (!cell_exists(first, con->row) ||
|
||||||
(first == (con->workspace->cols-1)))
|
(first == (ws->cols-1)))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
second = first + 1;
|
second = first + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return resize_graphical_handler(conn, con->workspace, first, second, orientation, event);
|
return resize_graphical_handler(conn, ws, first, second, orientation, event);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
|
#include "workspace.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Removes the given client from the container, either because it will be inserted into another
|
* Removes the given client from the container, either because it will be inserted into another
|
||||||
|
@ -236,8 +237,9 @@ void client_toggle_fullscreen(xcb_connection_t *conn, Client *client) {
|
||||||
*/
|
*/
|
||||||
void client_set_below_floating(xcb_connection_t *conn, Client *client) {
|
void client_set_below_floating(xcb_connection_t *conn, Client *client) {
|
||||||
/* Ensure that it is below all floating clients */
|
/* Ensure that it is below all floating clients */
|
||||||
Client *first_floating = TAILQ_FIRST(&(client->workspace->floating_clients));
|
Workspace *ws = client->workspace;
|
||||||
if (first_floating != TAILQ_END(&(client->workspace->floating_clients))) {
|
Client *first_floating = TAILQ_FIRST(&(ws->floating_clients));
|
||||||
|
if (first_floating != TAILQ_END(&(ws->floating_clients))) {
|
||||||
LOG("Setting below floating\n");
|
LOG("Setting below floating\n");
|
||||||
uint32_t values[] = { first_floating->frame, XCB_STACK_MODE_BELOW };
|
uint32_t values[] = { first_floating->frame, XCB_STACK_MODE_BELOW };
|
||||||
xcb_configure_window(conn, client->frame, XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE, values);
|
xcb_configure_window(conn, client->frame, XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE, values);
|
||||||
|
|
|
@ -63,7 +63,7 @@ static void jump_to_mark(xcb_connection_t *conn, const char *mark) {
|
||||||
Client *current;
|
Client *current;
|
||||||
LOG("Jumping to \"%s\"\n", mark);
|
LOG("Jumping to \"%s\"\n", mark);
|
||||||
|
|
||||||
for (int c = 0; c < 10; c++)
|
for (int c = 0; c < num_workspaces; c++)
|
||||||
SLIST_FOREACH(current, &(workspaces[c].focus_stack), focus_clients) {
|
SLIST_FOREACH(current, &(workspaces[c].focus_stack), focus_clients) {
|
||||||
if (current->mark == NULL || strcmp(current->mark, mark) != 0)
|
if (current->mark == NULL || strcmp(current->mark, mark) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
@ -165,7 +165,7 @@ static void focus_thing(xcb_connection_t *conn, direction_t direction, thing_t t
|
||||||
/* No screen found? Then wrap */
|
/* No screen found? Then wrap */
|
||||||
screen = get_screen_most((direction == D_UP ? D_DOWN : D_UP), container->workspace->screen);
|
screen = get_screen_most((direction == D_UP ? D_DOWN : D_UP), container->workspace->screen);
|
||||||
}
|
}
|
||||||
t_ws = &(workspaces[screen->current_workspace]);
|
t_ws = workspace_get(screen->current_workspace);
|
||||||
new_row = (direction == D_UP ? (t_ws->rows - 1) : 0);
|
new_row = (direction == D_UP ? (t_ws->rows - 1) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ static void focus_thing(xcb_connection_t *conn, direction_t direction, thing_t t
|
||||||
LOG("Wrapping screen around horizontally\n");
|
LOG("Wrapping screen around horizontally\n");
|
||||||
screen = get_screen_most((direction == D_LEFT ? D_RIGHT : D_LEFT), container->workspace->screen);
|
screen = get_screen_most((direction == D_LEFT ? D_RIGHT : D_LEFT), container->workspace->screen);
|
||||||
}
|
}
|
||||||
t_ws = &(workspaces[screen->current_workspace]);
|
t_ws = workspace_get(screen->current_workspace);
|
||||||
new_col = (direction == D_LEFT ? (t_ws->cols - 1) : 0);
|
new_col = (direction == D_LEFT ? (t_ws->cols - 1) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,7 +523,7 @@ static void snap_current_container(xcb_connection_t *conn, direction_t direction
|
||||||
|
|
||||||
static void move_floating_window_to_workspace(xcb_connection_t *conn, Client *client, int workspace) {
|
static void move_floating_window_to_workspace(xcb_connection_t *conn, Client *client, int workspace) {
|
||||||
/* t_ws (to workspace) is just a container pointer to the workspace we’re switching to */
|
/* t_ws (to workspace) is just a container pointer to the workspace we’re switching to */
|
||||||
Workspace *t_ws = &(workspaces[workspace-1]),
|
Workspace *t_ws = workspace_get(workspace-1),
|
||||||
*old_ws = client->workspace;
|
*old_ws = client->workspace;
|
||||||
|
|
||||||
LOG("moving floating\n");
|
LOG("moving floating\n");
|
||||||
|
@ -578,7 +578,7 @@ static void move_current_window_to_workspace(xcb_connection_t *conn, int workspa
|
||||||
assert(container != NULL);
|
assert(container != NULL);
|
||||||
|
|
||||||
/* t_ws (to workspace) is just a container pointer to the workspace we’re switching to */
|
/* t_ws (to workspace) is just a container pointer to the workspace we’re switching to */
|
||||||
Workspace *t_ws = &(workspaces[workspace-1]);
|
Workspace *t_ws = workspace_get(workspace-1);
|
||||||
|
|
||||||
Client *current_client = container->currently_focused;
|
Client *current_client = container->currently_focused;
|
||||||
if (current_client == NULL) {
|
if (current_client == NULL) {
|
||||||
|
@ -789,10 +789,10 @@ static void next_previous_workspace(xcb_connection_t *conn, int direction) {
|
||||||
|
|
||||||
if (direction == 'n') {
|
if (direction == 'n') {
|
||||||
/* If we are on the last workspace, we cannot go any further */
|
/* If we are on the last workspace, we cannot go any further */
|
||||||
if (c_ws->num == 9)
|
if (c_ws->num == (num_workspaces-1))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = c_ws->num + 1; i <= 9; i++) {
|
for (i = c_ws->num + 1; i < num_workspaces; i++) {
|
||||||
t_ws = &(workspaces[i]);
|
t_ws = &(workspaces[i]);
|
||||||
if (t_ws->screen != NULL)
|
if (t_ws->screen != NULL)
|
||||||
break;
|
break;
|
||||||
|
@ -815,6 +815,7 @@ static void parse_resize_command(xcb_connection_t *conn, Client *last_focused, c
|
||||||
int first, second;
|
int first, second;
|
||||||
resize_orientation_t orientation = O_VERTICAL;
|
resize_orientation_t orientation = O_VERTICAL;
|
||||||
Container *con = last_focused->container;
|
Container *con = last_focused->container;
|
||||||
|
Workspace *ws = con->workspace;
|
||||||
|
|
||||||
if (STARTS_WITH(command, "left")) {
|
if (STARTS_WITH(command, "left")) {
|
||||||
if (con->col == 0)
|
if (con->col == 0)
|
||||||
|
@ -827,7 +828,7 @@ static void parse_resize_command(xcb_connection_t *conn, Client *last_focused, c
|
||||||
LOG("column %d\n", first);
|
LOG("column %d\n", first);
|
||||||
|
|
||||||
if (!cell_exists(first, con->row) ||
|
if (!cell_exists(first, con->row) ||
|
||||||
(first == (con->workspace->cols-1)))
|
(first == (ws->cols-1)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
second = first + 1;
|
second = first + 1;
|
||||||
|
@ -842,7 +843,7 @@ static void parse_resize_command(xcb_connection_t *conn, Client *last_focused, c
|
||||||
} else if (STARTS_WITH(command, "bottom")) {
|
} else if (STARTS_WITH(command, "bottom")) {
|
||||||
first = con->row + (con->rowspan - 1);
|
first = con->row + (con->rowspan - 1);
|
||||||
if (!cell_exists(con->col, first) ||
|
if (!cell_exists(con->col, first) ||
|
||||||
(first == (con->workspace->rows-1)))
|
(first == (ws->rows-1)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
second = first + 1;
|
second = first + 1;
|
||||||
|
@ -857,7 +858,7 @@ static void parse_resize_command(xcb_connection_t *conn, Client *last_focused, c
|
||||||
if (pixels == 0)
|
if (pixels == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
resize_container(conn, con->workspace, first, second, orientation, pixels);
|
resize_container(conn, ws, first, second, orientation, pixels);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1082,14 +1083,16 @@ void parse_command(xcb_connection_t *conn, const char *command) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Workspace *ws = last_focused->workspace;
|
||||||
|
|
||||||
toggle_floating_mode(conn, last_focused, false);
|
toggle_floating_mode(conn, last_focused, false);
|
||||||
/* delete all empty columns/rows */
|
/* delete all empty columns/rows */
|
||||||
cleanup_table(conn, last_focused->workspace);
|
cleanup_table(conn, ws);
|
||||||
|
|
||||||
/* Fix colspan/rowspan if it’d overlap */
|
/* Fix colspan/rowspan if it’d overlap */
|
||||||
fix_colrowspan(conn, last_focused->workspace);
|
fix_colrowspan(conn, ws);
|
||||||
|
|
||||||
render_workspace(conn, last_focused->workspace->screen, last_focused->workspace);
|
render_workspace(conn, ws->screen, ws);
|
||||||
|
|
||||||
/* Re-focus the client because cleanup_table sets the focus to the last
|
/* Re-focus the client because cleanup_table sets the focus to the last
|
||||||
* focused client inside a container only. */
|
* focused client inside a container only. */
|
||||||
|
|
|
@ -418,7 +418,7 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath,
|
||||||
if ((end = strchr(screen, ' ')) != NULL)
|
if ((end = strchr(screen, ' ')) != NULL)
|
||||||
*end = '\0';
|
*end = '\0';
|
||||||
LOG("Setting preferred screen for workspace %d to \"%s\"\n", ws_num, screen);
|
LOG("Setting preferred screen for workspace %d to \"%s\"\n", ws_num, screen);
|
||||||
workspaces[ws_num - 1].preferred_screen = screen;
|
workspace_get(ws_num-1)->preferred_screen = screen;
|
||||||
|
|
||||||
name += strlen("screen ") + strlen(screen);
|
name += strlen("screen ") + strlen(screen);
|
||||||
}
|
}
|
||||||
|
@ -484,7 +484,7 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath,
|
||||||
while (*target == '~')
|
while (*target == '~')
|
||||||
target++;
|
target++;
|
||||||
|
|
||||||
if (atoi(target) >= 1 && atoi(target) <= 10) {
|
if (atoi(target) >= 1) {
|
||||||
if (new->floating == ASSIGN_FLOATING_ONLY)
|
if (new->floating == ASSIGN_FLOATING_ONLY)
|
||||||
new->floating = ASSIGN_FLOATING;
|
new->floating = ASSIGN_FLOATING;
|
||||||
new->workspace = atoi(target);
|
new->workspace = atoi(target);
|
||||||
|
@ -546,7 +546,7 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath,
|
||||||
REQUIRED_OPTION(font);
|
REQUIRED_OPTION(font);
|
||||||
|
|
||||||
/* Set an empty name for every workspace which got no name */
|
/* Set an empty name for every workspace which got no name */
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < num_workspaces; i++) {
|
||||||
Workspace *ws = &(workspaces[i]);
|
Workspace *ws = &(workspaces[i]);
|
||||||
if (ws->name != NULL) {
|
if (ws->name != NULL) {
|
||||||
/* If the font was not specified when the workspace name
|
/* If the font was not specified when the workspace name
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "floating.h"
|
#include "floating.h"
|
||||||
|
#include "workspace.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Toggles floating mode for the given client.
|
* Toggles floating mode for the given client.
|
||||||
|
@ -43,17 +44,18 @@ void toggle_floating_mode(xcb_connection_t *conn, Client *client, bool automatic
|
||||||
if (con == NULL) {
|
if (con == NULL) {
|
||||||
LOG("This client is already in floating (container == NULL), re-inserting\n");
|
LOG("This client is already in floating (container == NULL), re-inserting\n");
|
||||||
Client *next_tiling;
|
Client *next_tiling;
|
||||||
SLIST_FOREACH(next_tiling, &(client->workspace->focus_stack), focus_clients)
|
Workspace *ws = client->workspace;
|
||||||
|
SLIST_FOREACH(next_tiling, &(ws->focus_stack), focus_clients)
|
||||||
if (!client_is_floating(next_tiling))
|
if (!client_is_floating(next_tiling))
|
||||||
break;
|
break;
|
||||||
/* If there are no tiling clients on this workspace, there can only be one
|
/* If there are no tiling clients on this workspace, there can only be one
|
||||||
* container: the first one */
|
* container: the first one */
|
||||||
if (next_tiling == TAILQ_END(&(client->workspace->focus_stack)))
|
if (next_tiling == TAILQ_END(&(ws->focus_stack)))
|
||||||
con = client->workspace->table[0][0];
|
con = ws->table[0][0];
|
||||||
else con = next_tiling->container;
|
else con = next_tiling->container;
|
||||||
|
|
||||||
/* Remove the client from the list of floating clients */
|
/* Remove the client from the list of floating clients */
|
||||||
TAILQ_REMOVE(&(client->workspace->floating_clients), client, floating_clients);
|
TAILQ_REMOVE(&(ws->floating_clients), client, floating_clients);
|
||||||
|
|
||||||
LOG("destination container = %p\n", con);
|
LOG("destination container = %p\n", con);
|
||||||
Client *old_focused = con->currently_focused;
|
Client *old_focused = con->currently_focused;
|
||||||
|
@ -139,20 +141,21 @@ void toggle_floating_mode(xcb_connection_t *conn, Client *client, bool automatic
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void floating_assign_to_workspace(Client *client, Workspace *new_workspace) {
|
void floating_assign_to_workspace(Client *client, Workspace *new_workspace) {
|
||||||
/* Remove from focus stack and list of floating clients */
|
Workspace *ws = client->workspace;
|
||||||
SLIST_REMOVE(&(client->workspace->focus_stack), client, Client, focus_clients);
|
|
||||||
TAILQ_REMOVE(&(client->workspace->floating_clients), client, floating_clients);
|
|
||||||
|
|
||||||
if (client->workspace->fullscreen_client == client)
|
/* Remove from focus stack and list of floating clients */
|
||||||
client->workspace->fullscreen_client = NULL;
|
SLIST_REMOVE(&(ws->focus_stack), client, Client, focus_clients);
|
||||||
|
TAILQ_REMOVE(&(ws->floating_clients), client, floating_clients);
|
||||||
|
|
||||||
|
if (ws->fullscreen_client == client)
|
||||||
|
ws->fullscreen_client = NULL;
|
||||||
|
|
||||||
/* Insert into destination focus stack and list of floating clients */
|
/* Insert into destination focus stack and list of floating clients */
|
||||||
client->workspace = new_workspace;
|
ws = new_workspace;
|
||||||
SLIST_INSERT_HEAD(&(client->workspace->focus_stack), client, focus_clients);
|
SLIST_INSERT_HEAD(&(ws->focus_stack), client, focus_clients);
|
||||||
TAILQ_INSERT_TAIL(&(client->workspace->floating_clients), client, floating_clients);
|
TAILQ_INSERT_TAIL(&(ws->floating_clients), client, floating_clients);
|
||||||
if (client->fullscreen)
|
if (client->fullscreen)
|
||||||
client->workspace->fullscreen_client = client;
|
ws->fullscreen_client = client;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "floating.h"
|
#include "floating.h"
|
||||||
#include "handlers.h"
|
#include "handlers.h"
|
||||||
|
#include "workspace.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Updates *destination with new_value and returns true if it was changed or false
|
* Updates *destination with new_value and returns true if it was changed or false
|
||||||
|
@ -237,7 +238,7 @@ void reposition_client(xcb_connection_t *conn, Client *client) {
|
||||||
|
|
||||||
LOG("Client is on workspace %p with screen %p\n", client->workspace, client->workspace->screen);
|
LOG("Client is on workspace %p with screen %p\n", client->workspace, client->workspace->screen);
|
||||||
LOG("but screen at %d, %d is %p\n", client->rect.x, client->rect.y, screen);
|
LOG("but screen at %d, %d is %p\n", client->rect.x, client->rect.y, screen);
|
||||||
floating_assign_to_workspace(client, &workspaces[screen->current_workspace]);
|
floating_assign_to_workspace(client, workspace_get(screen->current_workspace));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -585,7 +586,7 @@ static void render_internal_bar(xcb_connection_t *conn, Workspace *r_ws, int wid
|
||||||
xcb_change_gc_single(conn, screen->bargc, XCB_GC_FONT, font->id);
|
xcb_change_gc_single(conn, screen->bargc, XCB_GC_FONT, font->id);
|
||||||
|
|
||||||
int drawn = 0;
|
int drawn = 0;
|
||||||
for (int c = 0; c < 10; c++) {
|
for (int c = 0; c < num_workspaces; c++) {
|
||||||
if (workspaces[c].screen != screen)
|
if (workspaces[c].screen != screen)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -335,7 +335,7 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child,
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG("Changing container/workspace and unmapping the client\n");
|
LOG("Changing container/workspace and unmapping the client\n");
|
||||||
Workspace *t_ws = &(workspaces[assign->workspace-1]);
|
Workspace *t_ws = workspace_get(assign->workspace-1);
|
||||||
workspace_initialize(t_ws, c_ws->screen);
|
workspace_initialize(t_ws, c_ws->screen);
|
||||||
|
|
||||||
new->container = t_ws->table[t_ws->current_col][t_ws->current_row];
|
new->container = t_ws->table[t_ws->current_col][t_ws->current_row];
|
||||||
|
|
20
src/table.c
20
src/table.c
|
@ -27,9 +27,10 @@
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
|
|
||||||
int current_workspace = 0;
|
int current_workspace = 0;
|
||||||
Workspace workspaces[10];
|
int num_workspaces = 1;
|
||||||
|
Workspace *workspaces;
|
||||||
/* Convenience pointer to the current workspace */
|
/* Convenience pointer to the current workspace */
|
||||||
Workspace *c_ws = &workspaces[0];
|
Workspace *c_ws;
|
||||||
int current_col = 0;
|
int current_col = 0;
|
||||||
int current_row = 0;
|
int current_row = 0;
|
||||||
|
|
||||||
|
@ -38,15 +39,14 @@ int current_row = 0;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void init_table() {
|
void init_table() {
|
||||||
memset(workspaces, 0, sizeof(workspaces));
|
workspaces = scalloc(sizeof(Workspace));
|
||||||
|
c_ws = workspaces;
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
workspaces[0].screen = NULL;
|
||||||
workspaces[i].screen = NULL;
|
workspaces[0].num = 0;
|
||||||
workspaces[i].num = i;
|
TAILQ_INIT(&(workspaces[0].floating_clients));
|
||||||
TAILQ_INIT(&(workspaces[i].floating_clients));
|
expand_table_cols(&(workspaces[0]));
|
||||||
expand_table_cols(&(workspaces[i]));
|
expand_table_rows(&(workspaces[0]));
|
||||||
expand_table_rows(&(workspaces[i]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void new_container(Workspace *workspace, Container **container, int col, int row) {
|
static void new_container(Workspace *workspace, Container **container, int col, int row) {
|
||||||
|
|
|
@ -455,7 +455,7 @@ Client *get_matching_client(xcb_connection_t *conn, const char *window_classtitl
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG("Getting clients for class \"%s\" / title \"%s\"\n", to_class, to_title);
|
LOG("Getting clients for class \"%s\" / title \"%s\"\n", to_class, to_title);
|
||||||
for (int workspace = 0; workspace < 10; workspace++) {
|
for (int workspace = 0; workspace < num_workspaces; workspace++) {
|
||||||
if (workspaces[workspace].screen == NULL)
|
if (workspaces[workspace].screen == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,74 @@
|
||||||
#include "workspace.h"
|
#include "workspace.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
|
|
||||||
|
Workspace *workspace_get(int number) {
|
||||||
|
if (number > (num_workspaces-1)) {
|
||||||
|
int old_num_workspaces = num_workspaces;
|
||||||
|
|
||||||
|
/* Convert all container->workspace and client->workspace
|
||||||
|
* pointers to numbers representing their workspace. Necessary
|
||||||
|
* because the realloc() may make all the pointers invalid, so
|
||||||
|
* we need to preserve them this way and restore them later.
|
||||||
|
*
|
||||||
|
* To distinguish between the first workspace and a NULL
|
||||||
|
* pointer, we store <workspace number> + 1. */
|
||||||
|
for (int c = 0; c < num_workspaces; c++)
|
||||||
|
FOR_TABLE(&(workspaces[c])) {
|
||||||
|
Container *con = workspaces[c].table[cols][rows];
|
||||||
|
if (con->workspace != NULL) {
|
||||||
|
LOG("Handling con %p with pointer %p (num %d)\n", con, con->workspace, con->workspace->num);
|
||||||
|
con->workspace = (Workspace*)(con->workspace->num + 1);
|
||||||
|
}
|
||||||
|
Client *current;
|
||||||
|
SLIST_FOREACH(current, &(workspaces[c].focus_stack), focus_clients) {
|
||||||
|
if (current->workspace == NULL)
|
||||||
|
continue;
|
||||||
|
LOG("Handling client %p with pointer %p (num %d)\n", current, current->workspace, current->workspace->num);
|
||||||
|
current->workspace = (Workspace*)(current->workspace->num + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* preserve c_ws */
|
||||||
|
c_ws = (Workspace*)(c_ws->num);
|
||||||
|
|
||||||
|
LOG("We need to initialize that one\n");
|
||||||
|
num_workspaces = number+1;
|
||||||
|
workspaces = realloc(workspaces, num_workspaces * sizeof(Workspace));
|
||||||
|
for (int c = old_num_workspaces; c < num_workspaces; c++) {
|
||||||
|
memset(&workspaces[c], 0, sizeof(Workspace));
|
||||||
|
workspaces[c].screen = NULL;
|
||||||
|
workspaces[c].num = c;
|
||||||
|
TAILQ_INIT(&(workspaces[c].floating_clients));
|
||||||
|
expand_table_cols(&(workspaces[c]));
|
||||||
|
expand_table_rows(&(workspaces[c]));
|
||||||
|
workspace_set_name(&(workspaces[c]), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
c_ws = workspace_get((int)c_ws);
|
||||||
|
|
||||||
|
for (int c = 0; c < old_num_workspaces; c++)
|
||||||
|
FOR_TABLE(&(workspaces[c])) {
|
||||||
|
Container *con = workspaces[c].table[cols][rows];
|
||||||
|
if (con->workspace != NULL) {
|
||||||
|
LOG("Handling con %p with (num %d)\n", con, con->workspace);
|
||||||
|
con->workspace = workspace_get((int)con->workspace - 1);
|
||||||
|
}
|
||||||
|
Client *current;
|
||||||
|
SLIST_FOREACH(current, &(workspaces[c].focus_stack), focus_clients) {
|
||||||
|
if (current->workspace == NULL)
|
||||||
|
continue;
|
||||||
|
LOG("Handling client %p with (num %d)\n", current, current->workspace);
|
||||||
|
current->workspace = workspace_get((int)current->workspace - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LOG("done\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return &(workspaces[number]);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sets the name (or just its number) for the given workspace. This has to
|
* Sets the name (or just its number) for the given workspace. This has to
|
||||||
* be called for every workspace as the rendering function
|
* be called for every workspace as the rendering function
|
||||||
|
@ -73,7 +141,7 @@ void workspace_show(xcb_connection_t *conn, int workspace) {
|
||||||
bool need_warp = false;
|
bool need_warp = false;
|
||||||
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;
|
||||||
/* t_ws (to workspace) is just a convenience pointer to the workspace we’re switching to */
|
/* t_ws (to workspace) is just a convenience pointer to the workspace we’re switching to */
|
||||||
Workspace *t_ws = &(workspaces[workspace-1]);
|
Workspace *t_ws = workspace_get(workspace-1);
|
||||||
|
|
||||||
LOG("show_workspace(%d)\n", workspace);
|
LOG("show_workspace(%d)\n", workspace);
|
||||||
|
|
||||||
|
@ -91,7 +159,7 @@ void workspace_show(xcb_connection_t *conn, int workspace) {
|
||||||
/* Store the old client */
|
/* Store the old client */
|
||||||
Client *old_client = CUR_CELL->currently_focused;
|
Client *old_client = CUR_CELL->currently_focused;
|
||||||
|
|
||||||
c_ws = &(workspaces[t_ws->screen->current_workspace]);
|
c_ws = workspace_get(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;
|
||||||
if (CUR_CELL->currently_focused != NULL)
|
if (CUR_CELL->currently_focused != NULL)
|
||||||
|
@ -123,7 +191,7 @@ void workspace_show(xcb_connection_t *conn, int workspace) {
|
||||||
|
|
||||||
t_ws->screen->current_workspace = workspace-1;
|
t_ws->screen->current_workspace = workspace-1;
|
||||||
Workspace *old_workspace = c_ws;
|
Workspace *old_workspace = c_ws;
|
||||||
c_ws = &workspaces[workspace-1];
|
c_ws = workspace_get(workspace-1);
|
||||||
|
|
||||||
/* Unmap all clients of the old workspace */
|
/* Unmap all clients of the old workspace */
|
||||||
workspace_unmap_clients(conn, old_workspace);
|
workspace_unmap_clients(conn, old_workspace);
|
||||||
|
@ -243,8 +311,8 @@ void workspace_initialize(Workspace *ws, i3Screen *screen) {
|
||||||
Workspace *get_first_workspace_for_screen(struct screens_head *slist, i3Screen *screen) {
|
Workspace *get_first_workspace_for_screen(struct screens_head *slist, i3Screen *screen) {
|
||||||
Workspace *result = NULL;
|
Workspace *result = NULL;
|
||||||
|
|
||||||
for (int c = 0; c < 10; c++) {
|
for (int c = 0; c < num_workspaces; c++) {
|
||||||
Workspace *ws = &(workspaces[c]);
|
Workspace *ws = workspace_get(c);
|
||||||
if (ws->preferred_screen == NULL ||
|
if (ws->preferred_screen == NULL ||
|
||||||
!screens_are_equal(get_screen_from_preference(slist, ws->preferred_screen), screen))
|
!screens_are_equal(get_screen_from_preference(slist, ws->preferred_screen), screen))
|
||||||
continue;
|
continue;
|
||||||
|
@ -255,11 +323,11 @@ Workspace *get_first_workspace_for_screen(struct screens_head *slist, i3Screen *
|
||||||
|
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
/* No assignment found, returning first unused workspace */
|
/* No assignment found, returning first unused workspace */
|
||||||
for (int c = 0; c < 10; c++) {
|
for (int c = 0; c < num_workspaces; c++) {
|
||||||
if (workspaces[c].screen != NULL)
|
if (workspaces[c].screen != NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
result = &(workspaces[c]);
|
result = workspace_get(c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -298,7 +298,7 @@ void xinerama_requery_screens(xcb_connection_t *conn) {
|
||||||
int screen_count = 0;
|
int screen_count = 0;
|
||||||
/* Mark each workspace which currently is assigned to a screen, so we
|
/* Mark each workspace which currently is assigned to a screen, so we
|
||||||
* can garbage-collect afterwards */
|
* can garbage-collect afterwards */
|
||||||
for (int c = 0; c < 10; c++)
|
for (int c = 0; c < num_workspaces; c++)
|
||||||
workspaces[c].reassigned = (workspaces[c].screen == NULL);
|
workspaces[c].reassigned = (workspaces[c].screen == NULL);
|
||||||
|
|
||||||
TAILQ_FOREACH(screen, new_screens, screens) {
|
TAILQ_FOREACH(screen, new_screens, screens) {
|
||||||
|
@ -334,7 +334,7 @@ void xinerama_requery_screens(xcb_connection_t *conn) {
|
||||||
screen->dock_clients = old_screen->dock_clients;
|
screen->dock_clients = old_screen->dock_clients;
|
||||||
|
|
||||||
/* Update the dimensions */
|
/* Update the dimensions */
|
||||||
for (int c = 0; c < 10; c++) {
|
for (int c = 0; c < num_workspaces; c++) {
|
||||||
Workspace *ws = &(workspaces[c]);
|
Workspace *ws = &(workspaces[c]);
|
||||||
if (ws->screen != old_screen)
|
if (ws->screen != old_screen)
|
||||||
continue;
|
continue;
|
||||||
|
@ -363,7 +363,7 @@ void xinerama_requery_screens(xcb_connection_t *conn) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for workspaces which are out of bounds */
|
/* Check for workspaces which are out of bounds */
|
||||||
for (int c = 0; c < 10; c++) {
|
for (int c = 0; c < num_workspaces; c++) {
|
||||||
if (workspaces[c].reassigned)
|
if (workspaces[c].reassigned)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue