Compare commits

...

5 Commits

5 changed files with 176 additions and 20 deletions

View File

@ -67,7 +67,7 @@ Client* wm_client_create(Wm *wm, Window w)
c->prev = NULL;
c->window = w;
c->m = wm->smon;
c->ws = wm->smon->selws;
c->ws = &wm->smon->workspaces[wm->smon->selws];
c->hidden = true;
c->is_floating = false;

81
util.c Normal file
View File

@ -0,0 +1,81 @@
#include "util.h"
#include <string.h>
#include <assert.h>
void wm_treenode_init(TreeNode *node, NodeType type, TreeNode *parent)
{
assert(node);
node->parent = parent;
node->type = type;
node->children = (NodeArray) {0};
wm_nodearray_init(&node->children);
}
void wm_nodearray_init(NodeArray *arr)
{
assert(arr);
arr->capacity = 10;
arr->nodes = calloc(arr->capacity, sizeof(TreeNode));
arr->size = 0;
}
void wm_nodearray_push(NodeArray *arr, TreeNode node)
{
assert(arr);
arr->size++;
if (arr->size >= arr->capacity) {
TreeNode* temp = calloc(arr->capacity, sizeof(TreeNode));
memcpy(temp, arr->nodes, arr->capacity * sizeof(TreeNode));
free(arr->nodes);
size_t old_capacity = arr->capacity;
arr->capacity = old_capacity * 2;
arr->nodes = calloc(arr->capacity, sizeof(TreeNode));
memcpy(arr->nodes, temp, old_capacity);
free(temp);
arr->nodes[arr->size - 1] = node;
return;
}
arr->nodes[arr->size - 1] = node;
}
bool wm_nodearray_pop(NodeArray *arr, TreeNode *ret)
{
assert(arr);
if (!ret || !arr)
return false;
if (arr->size == 0)
return false;
*ret = arr->nodes[arr->size - 1];
arr->size--;
return true;
}
bool wm_nodearray_remove(NodeArray *arr, size_t index)
{
assert(arr);
if (!arr)
return false;
if (index >= arr->size)
return false;
if (index == arr->size - 1) {
arr->size--;
return true;
}
memmove(arr->nodes + index, arr->nodes + index+1, arr->size-1 * sizeof(TreeNode));
return true;
}

53
util.h Normal file
View File

@ -0,0 +1,53 @@
#ifndef UTIL_H
#define UTIL_H
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#define WM_VERT_LEFT 0
#define WM_VERT_RIGHT 1
#define WM_HORIZ_TOP 0
#define WM_HORIZ_BOT 1
typedef enum NodeType {
NODE_VERTICAL,
NODE_HORIZONTAL,
NODE_TAB,
NODE_CLIENT,
NODE_COUNT
} NodeType;
typedef struct TreeNode TreeNode;
typedef struct NodeArray NodeArray;
typedef struct Client Client;
struct NodeArray {
TreeNode *nodes;
size_t size;
size_t capacity;
};
struct TreeNode {
NodeType type;
TreeNode *parent;
NodeArray children;
int x;
int y;
int w;
int h;
Client *client;
};
void wm_treenode_init(TreeNode *node, NodeType type, TreeNode *parent);
void wm_nodearray_init(NodeArray *arr);
void wm_nodearray_push(NodeArray *arr, TreeNode node);
bool wm_nodearray_pop(NodeArray *arr, TreeNode *ret);
bool wm_nodearray_remove(NodeArray *arr, size_t index);
#endif

33
wm.c
View File

@ -32,6 +32,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <unistd.h>
#include "handler.h"
#include "client.h"
#include "util.h"
Monitor wm_monitor_open(Display *d, XineramaScreenInfo info)
{
@ -60,12 +61,18 @@ void wm_monitors_open_all(Wm *wm, Display *d)
wm->monitors[i] = wm_monitor_open(d, xsi[i]);
//TODO: cfg
wm->monitors[i].wscount = 9;
wm->monitors[i].wss = malloc(wm->monitors[i].wscount*sizeof(int));
memset(wm->monitors[i].wss, 0, wm->monitors[i].wscount);
wm->monitors[i].selws = wm->monitors[i].wss[0];
wm->monitors[i].workspaces = calloc(wm->monitors[i].wscount, sizeof(Workspace));
wm->monitors[i].selws = 0;
for (int j = 0; j < wm->monitors[i].wscount; j++)
wm->monitors[i].wss[i] = j;
for (int j = 0; j < wm->monitors[i].wscount; j++) {
Workspace *ws = &wm->monitors[i].workspaces[i];
ws->index = j;
ws->monitor = &wm->monitors[i];
// TODO config
snprintf(ws->name, WM_WS_NAME_LEN, "%d", j);
wm_treenode_init(&ws->tree, NODE_CLIENT, NULL);
}
//wm->monitors[i].clients = &wm->root;
wm->monitors[i].clients = NULL;
@ -138,8 +145,8 @@ void wm_switch_ws(Wm *wm, int ws)
Client *c;
for (c = wm->smon->clients; c; c = c->next) {
if (c->ws == wm->smon->selws) {
DEBUG_PRINT("wm_switch_ws hide client selws: %d\n", c->ws)
if (c->ws->index == wm->smon->selws) {
DEBUG_PRINT("wm_switch_ws hide client selws: %ld\n", c->ws->index)
wm_client_hide(wm, c);
}
}
@ -148,12 +155,9 @@ void wm_switch_ws(Wm *wm, int ws)
wm_client_set_atom(wm, &wm-> root, "_NET_CURRENT_DESKTOP",
(unsigned char*) &(ws), XA_CARDINAL, 1);
// XChangeProperty(wm->display, root.window,
// XInternAtom(wm->display, "_NET_CURRENT_DESKTOP", False), XA_CARDINAL,
// 32, PropModeReplace, (unsigned char *) &(xasws), 1);
for (c = wm->smon->clients; c; c = c->next) {
if (c->ws == wm->smon->selws) {
if (c->ws->index == wm->smon->selws) {
wscc++;
wm_client_show(wm, c);
}
@ -194,7 +198,7 @@ void wm_mstack(Wm *wm, Monitor *m)
}
for (c = m->clients; c; c = c->next) {
if (c->ws == m->selws && c != &wm->root && !c->is_floating) {
if (c->ws->index == m->selws && c != &wm->root && !c->is_floating) {
cc_sws++;
}
}
@ -209,7 +213,7 @@ void wm_mstack(Wm *wm, Monitor *m)
// dynamic
if (cc_sws == 1) {
for (c = m->clients; c; c = c->next) {
if (c->ws == m->selws && c != &wm->root)
if (c->ws->index == m->selws && c != &wm->root)
break;
}
c->x = 0;
@ -231,7 +235,7 @@ void wm_mstack(Wm *wm, Monitor *m)
else {
// FIXME not working with dock
for (c = m->clients; c; c = c->next) {
if (c->ws == m->selws && c->window != wm->root.window && !c->is_floating) {
if (c->ws->index == m->selws && c->window != wm->root.window && !c->is_floating) {
if (n == 0) {
c->x = 0;
c->y = sy;
@ -419,7 +423,6 @@ void wm_init(Wm *wm)
// wm_socket_init();
wm->root.window = XRootWindow(wm->display, DefaultScreen(wm->display));
wm->root.ws = 999;
DEBUG_PRINT("root window: %ld\n", wm->root.window);

27
wm.h
View File

@ -36,6 +36,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <sys/socket.h>
#include <sys/un.h>
#include "util.h"
// TODO: when only 1 window on ws it is not focused
// TODO: dont draw border on not normal windows, floating dialog window,
// window type/name/... atom member variable on Client struct
@ -55,7 +57,10 @@ if (c == NULL) \
#define DEBUG_PRINT(fmt, ...) \
do { if (DEBUG) fprintf(stderr, fmt, ##__VA_ARGS__); } while (0);
#define WM_WS_NAME_LEN 64
typedef struct Client Client;
typedef struct Workspace Workspace;
typedef struct Monitor Monitor;
typedef struct Keybind Keybind;
typedef struct Arg Arg;
@ -68,13 +73,19 @@ enum Direction {
RIGHT
};
typedef enum {
SPLIT_VERTICAL,
SPLIT_HORIZ,
SPLIT_TAB
} SplitMode;
struct Monitor {
Display *display;
XineramaScreenInfo info;
Client *clients;
int *wss;
int selws;
int wscount;
Workspace *workspaces;
size_t selws;
size_t wscount;
};
struct Client {
@ -82,7 +93,7 @@ struct Client {
int y;
int w;
int h;
int ws;
Workspace *ws;
bool hidden;
Monitor *m;
Window window;
@ -95,6 +106,14 @@ struct Client {
// will propably need a tree.
};
struct Workspace {
TreeNode tree;
size_t index;
char name[WM_WS_NAME_LEN];
Monitor *monitor;
SplitMode split;
};
struct Arg {
int i;
unsigned int ui;