static void xkeypress(XEvent* e)
{
- (void)e;
+ keys_run(&(e->xkey));
}
int main(void)
check_for_wm();
mons_init();
client_initall();
+ keys_init();
/* setup event handlers */
X.eventfns[ButtonPress] = xbtnpress;
#include <X11/X.h>
#include <X11/Xlib.h>
+#include <X11/keysym.h>
+#include <X11/XKBlib.h>
#include <X11/extensions/Xinerama.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
+#include <assert.h>
#define min(a,b) (a < b ? a : b)
#define max(a,b) (a > b ? a : b)
Client* client;
} Location;
+typedef union {
+ int i;
+} Arg;
+
+typedef struct {
+ unsigned int mod;
+ KeySym keysym;
+ void (*func)(Arg* arg);
+ Arg arg;
+} Key;
+
#define BORDER_WIDTH 5
#define TITLE_HEIGHT 10
/* anvil.c */
extern XConf X;
+/* keys.c */
+void keys_init(void);
+void keys_run(XKeyEvent* ev);
+
/* mons.c */
extern Monitor* Monitors;
void mons_init(void);
void mons_delclient(Client* c);
int mons_find(Window win, Location* loc);
void mons_place(Client* c);
+void mons_wspace(int i);
+void mons_towspace(Client* c, int i);
/* client.c */
extern Client* Focused;
void client_resize(Client* c, int xdiff, int ydiff);
void client_close(Client* c);
void client_focus(Client* c);
+void client_show(Client* c, int show);
/* error.c */
extern int (*error_default)(Display* disp, XErrorEvent* ev);
client_draw(prev);
}
XSync(X.disp, False);
+}
+
+void client_show(Client* c, int show)
+{
+ if (show)
+ {
+ XMapWindow(X.disp, c->frame);
+ XMapWindow(X.disp, c->win);
+ }
+ else
+ {
+ XUnmapWindow(X.disp, c->frame);
+ XUnmapWindow(X.disp, c->win);
+ }
}
\ No newline at end of file
--- /dev/null
+#include "anvil.h"
+
+static void set_workspace(Arg* arg)
+{
+ mons_wspace(arg->i);
+}
+
+static void to_workspace(Arg* arg)
+{
+ mons_towspace(Focused, arg->i);
+}
+
+#define MODKEY Mod4Mask
+
+static Key keys[] = {
+ { MODKEY, XK_1, set_workspace, {.i = 0 } },
+ { MODKEY, XK_2, set_workspace, {.i = 1 } },
+ { MODKEY, XK_3, set_workspace, {.i = 2 } },
+ { MODKEY, XK_4, set_workspace, {.i = 3 } },
+ { MODKEY, XK_5, set_workspace, {.i = 4 } },
+ { MODKEY, XK_6, set_workspace, {.i = 5 } },
+ { MODKEY, XK_7, set_workspace, {.i = 6 } },
+ { MODKEY, XK_8, set_workspace, {.i = 7 } },
+ { MODKEY, XK_9, set_workspace, {.i = 8 } },
+ { MODKEY, XK_0, set_workspace, {.i = 9 } },
+
+ { MODKEY|ShiftMask, XK_1, to_workspace, {.i = 0 } },
+ { MODKEY|ShiftMask, XK_2, to_workspace, {.i = 1 } },
+ { MODKEY|ShiftMask, XK_3, to_workspace, {.i = 2 } },
+ { MODKEY|ShiftMask, XK_4, to_workspace, {.i = 3 } },
+ { MODKEY|ShiftMask, XK_5, to_workspace, {.i = 4 } },
+ { MODKEY|ShiftMask, XK_6, to_workspace, {.i = 5 } },
+ { MODKEY|ShiftMask, XK_7, to_workspace, {.i = 6 } },
+ { MODKEY|ShiftMask, XK_8, to_workspace, {.i = 7 } },
+ { MODKEY|ShiftMask, XK_9, to_workspace, {.i = 8 } },
+ { MODKEY|ShiftMask, XK_0, to_workspace, {.i = 9 } },
+};
+
+void keys_init(void)
+{
+ KeyCode code;
+ for (unsigned int i = 0; i < sizeof(keys)/sizeof(keys[0]); i++)
+ {
+ if ((code = XKeysymToKeycode(X.disp, keys[i].keysym)))
+ {
+ XGrabKey(X.disp, code, keys[i].mod, X.root, True, GrabModeAsync, GrabModeAsync);
+ }
+ }
+}
+
+void keys_run(XKeyEvent* ev)
+{
+ KeySym keysym = XkbKeycodeToKeysym(X.disp, ev->keycode, 0, 0);
+ for (unsigned int i = 0; i < sizeof(keys)/sizeof(keys[0]); i++)
+ {
+ printf("%d: (%d == %d) && (%d == %d)\n",
+ (int)i,
+ (int)keysym,
+ (int)keys[i].keysym,
+ (int)keys[i].mod,
+ (int)ev->state
+ );
+ if (keysym == keys[i].keysym && keys[i].mod == ev->state && keys[i].func)
+ {
+ keys[i].func(&(keys[i].arg));
+ break;
+ }
+ }
+}
#include "anvil.h"
#include <math.h>
+static Monitor* pickmon(void);
+static Workspace* pickws(Monitor* mon, int wsid);
+static Client* delclient(Client* list, Client* dead);
+static void client_visibility(Workspace* wspace, int show);
+
Monitor* Monitors = NULL;
void mons_init(void)
for (int i = 0; i < nmons; i++)
{
Monitor* m = ecalloc(1, sizeof(Monitor));
- m->wspaces = ecalloc(1, sizeof(Workspace));
+ for (int i = 0; i < 10; i++)
+ {
+ Workspace* wspace = ecalloc(1, sizeof(Workspace));
+ wspace->next = m->wspaces;
+ m->wspaces = wspace;
+ }
m->cspace = m->wspaces;
m->x = mons[i].x_org;
m->y = mons[i].y_org;
mons_place(c);
}
-Client* delclient(Client* list, Client* dead)
-{
- if (list == dead)
- {
- list = list->next;
- }
- else
- {
- list->next = delclient(list->next, dead);
- }
- return list;
-}
-
void mons_delclient(Client* c)
{
Location loc = {0};
closest->cspace->floating = c;
}
}
-}
\ No newline at end of file
+}
+
+void mons_wspace(int wsid)
+{
+ Monitor* mon = pickmon();
+ Workspace* wspace = pickws(mon, wsid);
+ if (mon->cspace != wspace)
+ {
+ client_visibility(mon->cspace, 0);
+ client_visibility(wspace, 1);
+ mon->cspace = wspace;
+ }
+}
+
+void mons_towspace(Client* c, int wsid)
+{
+ Location loc;
+ printf("%p to %d\n", c, wsid);
+ if (mons_find(c->win, &loc))
+ {
+ Workspace* wspace = pickws(loc.monitor, wsid);
+ if (wspace != loc.workspace)
+ {
+ client_show(c, 0);
+ loc.workspace->floating = delclient(loc.workspace->floating, c);
+ c->next = wspace->floating;
+ wspace->floating = c;
+ }
+ }
+}
+
+static Monitor* pickmon(void)
+{
+ Window root = 0, child = 0;
+ int ptrx = 0, ptry = 0, winx = 0, winy = 0, mask = 0;
+ XQueryPointer(X.disp, X.root, &root, &child, &ptrx, &ptry, &winx, &winy, (unsigned int*)&mask);
+ Monitor* mon = Monitors;
+ for (; mon; mon = mon->next)
+ {
+ if ((mon->x <= ptrx && ptrx < mon->x+mon->w) && (mon->y <= ptry && ptry < mon->y+mon->h))
+ {
+ break;
+ }
+ }
+ assert(mon);
+ return mon;
+}
+
+static Workspace* pickws(Monitor* mon, int wsid)
+{
+ Workspace* wspace = mon->wspaces;
+ int i = 0;
+ for (; wspace; wspace = wspace->next, i++)
+ {
+ if (i == wsid)
+ {
+ break;
+ }
+ }
+ return wspace;
+}
+
+static Client* delclient(Client* list, Client* dead)
+{
+ if (list == dead)
+ {
+ list = list->next;
+ }
+ else
+ {
+ list->next = delclient(list->next, dead);
+ }
+ return list;
+}
+
+static void client_visibility(Workspace* wspace, int show)
+{
+ for (Client* client = wspace->floating; client; client = client->next)
+ {
+ client_show(client, show);
+ }
+ XSync(X.disp, False);
+}