Add XKB for getting correct state, add colspan test code
This commit is contained in:
parent
91022f069e
commit
df9fa0dd8f
9
Makefile
9
Makefile
|
@ -7,16 +7,19 @@ CFLAGS += -g3
|
||||||
CFLAGS += -I/usr/include/xcb
|
CFLAGS += -I/usr/include/xcb
|
||||||
CFLAGS += -I/usr/local/include/
|
CFLAGS += -I/usr/local/include/
|
||||||
CFLAGS += -I/usr/local/include/xcb
|
CFLAGS += -I/usr/local/include/xcb
|
||||||
|
CFLAGS += -I/usr/pkg/include
|
||||||
|
|
||||||
LDFLAGS += -lxcb-wm
|
LDFLAGS += -lxcb-wm
|
||||||
LDFLAGS += -L/usr/local/lib
|
LDFLAGS += -lxcb-keysyms
|
||||||
|
LDFLAGS += -lX11
|
||||||
|
LDFLAGS += -L/usr/local/lib -L/usr/pkg/lib
|
||||||
ifeq ($(UNAME),NetBSD)
|
ifeq ($(UNAME),NetBSD)
|
||||||
LDFLAGS += -Wl,-rpath,/usr/local/lib
|
LDFLAGS += -Wl,-rpath,/usr/local/lib -Wl,-rpath,/usr/pkg/lib
|
||||||
endif
|
endif
|
||||||
|
|
||||||
FILES=$(patsubst %.c,%.o,$(wildcard *.c))
|
FILES=$(patsubst %.c,%.o,$(wildcard *.c))
|
||||||
|
|
||||||
%.o: %.c %.h
|
%.o: %.c %.h data.h
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
all: ${FILES}
|
all: ${FILES}
|
||||||
|
|
5
data.h
5
data.h
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
/* Forward definitions */
|
/* Forward definitions */
|
||||||
typedef struct Cell Cell;
|
typedef struct Cell Cell;
|
||||||
typedef struct Font Font;
|
typedef struct Font i3Font;
|
||||||
typedef struct Container Container;
|
typedef struct Container Container;
|
||||||
typedef struct Client Client;
|
typedef struct Client Client;
|
||||||
|
|
||||||
|
@ -77,6 +77,8 @@ struct Client {
|
||||||
struct Container {
|
struct Container {
|
||||||
/* Those are speaking for themselves: */
|
/* Those are speaking for themselves: */
|
||||||
Client *currently_focused;
|
Client *currently_focused;
|
||||||
|
int colspan;
|
||||||
|
int rowspan;
|
||||||
|
|
||||||
/* Position of the container inside our table */
|
/* Position of the container inside our table */
|
||||||
int row;
|
int row;
|
||||||
|
@ -84,6 +86,7 @@ struct Container {
|
||||||
/* Width/Height of the container. Changeable by the user */
|
/* Width/Height of the container. Changeable by the user */
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
|
|
||||||
/* Ensure MODE_DEFAULT maps to 0 because we use calloc for initialization later */
|
/* Ensure MODE_DEFAULT maps to 0 because we use calloc for initialization later */
|
||||||
enum { MODE_DEFAULT = 0, MODE_STACK = 1 } mode;
|
enum { MODE_DEFAULT = 0, MODE_STACK = 1 } mode;
|
||||||
CIRCLEQ_HEAD(client_head, Client) clients;
|
CIRCLEQ_HEAD(client_head, Client) clients;
|
||||||
|
|
4
font.c
4
font.c
|
@ -20,9 +20,9 @@ void check_error(xcb_connection_t *connection, xcb_void_cookie_t cookie, char *e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Font *load_font(xcb_connection_t *c, const char *pattern) {
|
i3Font *load_font(xcb_connection_t *c, const char *pattern) {
|
||||||
/* TODO: this function should be caching */
|
/* TODO: this function should be caching */
|
||||||
Font *new = malloc(sizeof(Font));
|
i3Font *new = malloc(sizeof(i3Font));
|
||||||
|
|
||||||
xcb_list_fonts_with_info_cookie_t cookie = xcb_list_fonts_with_info(c, 1, strlen(pattern), pattern);
|
xcb_list_fonts_with_info_cookie_t cookie = xcb_list_fonts_with_info(c, 1, strlen(pattern), pattern);
|
||||||
xcb_list_fonts_with_info_reply_t *reply = xcb_list_fonts_with_info_reply(c, cookie, NULL);
|
xcb_list_fonts_with_info_reply_t *reply = xcb_list_fonts_with_info_reply(c, cookie, NULL);
|
||||||
|
|
2
font.h
2
font.h
|
@ -5,6 +5,6 @@
|
||||||
#ifndef _FONT_H
|
#ifndef _FONT_H
|
||||||
#define _FONT_H
|
#define _FONT_H
|
||||||
|
|
||||||
Font *load_font(xcb_connection_t *c, const char *pattern);
|
i3Font *load_font(xcb_connection_t *c, const char *pattern);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
79
mainx.c
79
mainx.c
|
@ -10,6 +10,9 @@
|
||||||
|
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
|
|
||||||
|
#include <X11/XKBlib.h>
|
||||||
|
#include <X11/extensions/XKB.h>
|
||||||
|
|
||||||
#include "xcb_wm.h"
|
#include "xcb_wm.h"
|
||||||
#include "xcb_aux.h"
|
#include "xcb_aux.h"
|
||||||
#include "xcb_event.h"
|
#include "xcb_event.h"
|
||||||
|
@ -23,7 +26,8 @@
|
||||||
|
|
||||||
#define TERMINAL "/usr/pkg/bin/urxvt"
|
#define TERMINAL "/usr/pkg/bin/urxvt"
|
||||||
|
|
||||||
Font *myfont;
|
i3Font *myfont;
|
||||||
|
Display *xkbdpy;
|
||||||
|
|
||||||
static const int TOP = 20;
|
static const int TOP = 20;
|
||||||
static const int LEFT = 5;
|
static const int LEFT = 5;
|
||||||
|
@ -344,7 +348,7 @@ void decorate_window(xcb_connection_t *conn, Client *client) {
|
||||||
uint32_t mask = 0;
|
uint32_t mask = 0;
|
||||||
uint32_t values[3];
|
uint32_t values[3];
|
||||||
xcb_screen_t *root_screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
|
xcb_screen_t *root_screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
|
||||||
Font *font = load_font(conn, pattern);
|
i3Font *font = load_font(conn, pattern);
|
||||||
uint32_t background_color,
|
uint32_t background_color,
|
||||||
text_color,
|
text_color,
|
||||||
border_color;
|
border_color;
|
||||||
|
@ -412,7 +416,7 @@ void render_container(xcb_connection_t *connection, Container *container) {
|
||||||
XCB_CONFIG_WINDOW_Y |
|
XCB_CONFIG_WINDOW_Y |
|
||||||
XCB_CONFIG_WINDOW_WIDTH |
|
XCB_CONFIG_WINDOW_WIDTH |
|
||||||
XCB_CONFIG_WINDOW_HEIGHT;
|
XCB_CONFIG_WINDOW_HEIGHT;
|
||||||
Font *font = load_font(connection, pattern);
|
i3Font *font = load_font(connection, pattern);
|
||||||
|
|
||||||
if (container->mode == MODE_DEFAULT) {
|
if (container->mode == MODE_DEFAULT) {
|
||||||
int num_clients = 0;
|
int num_clients = 0;
|
||||||
|
@ -476,11 +480,14 @@ void render_layout(xcb_connection_t *conn) {
|
||||||
for (cols = 0; cols < table_dims.x; cols++)
|
for (cols = 0; cols < table_dims.x; cols++)
|
||||||
for (rows = 0; rows < table_dims.y; rows++)
|
for (rows = 0; rows < table_dims.y; rows++)
|
||||||
if (table[cols][rows] != NULL) {
|
if (table[cols][rows] != NULL) {
|
||||||
|
Container *con = table[cols][rows];
|
||||||
|
printf("container has %d colspan, %d rowspan\n",
|
||||||
|
con->colspan, con->rowspan);
|
||||||
/* Update position of the container */
|
/* Update position of the container */
|
||||||
table[cols][rows]->row = rows;
|
con->row = rows;
|
||||||
table[cols][rows]->col = cols;
|
con->col = cols;
|
||||||
table[cols][rows]->width = width / num_cols;
|
con->width = (width / num_cols) * con->colspan;
|
||||||
table[cols][rows]->height = height / num_rows;
|
con->height = (height / num_rows) * con->rowspan;
|
||||||
|
|
||||||
/* Render it */
|
/* Render it */
|
||||||
render_container(conn, table[cols][rows]);
|
render_container(conn, table[cols][rows]);
|
||||||
|
@ -562,7 +569,7 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child,
|
||||||
table_put(byChild, child, new);
|
table_put(byChild, child, new);
|
||||||
|
|
||||||
/* Moves the original window into the new frame we've created for it */
|
/* Moves the original window into the new frame we've created for it */
|
||||||
Font *font = load_font(conn, pattern);
|
i3Font *font = load_font(conn, pattern);
|
||||||
xcb_reparent_window(conn, child, new->frame, 0, font->height);
|
xcb_reparent_window(conn, child, new->frame, 0, font->height);
|
||||||
|
|
||||||
/* We are interested in property changes */
|
/* We are interested in property changes */
|
||||||
|
@ -797,14 +804,32 @@ static void start_application(char *path, char *args) {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press_event_t *event) {
|
static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press_event_t *event) {
|
||||||
|
|
||||||
/* FIXME: We need to translate the keypress + state into a string (like, ä)
|
/* FIXME: We need to translate the keypress + state into a string (like, ä)
|
||||||
because they do not generate keysyms (use xev and see for yourself) */
|
because they do not generate keysyms (use xev and see for yourself) */
|
||||||
|
|
||||||
printf("oh yay!\n");
|
printf("oh yay!\n");
|
||||||
printf("gots press %d\n", event->detail);
|
printf("gots press %d\n", event->detail);
|
||||||
|
|
||||||
|
/* We need to get the keysym group (There are group 1 to group 4, each holding
|
||||||
|
two keysyms (without shift and with shift) using Xkb because X fails to
|
||||||
|
provide them reliably (it works in Xephyr, it does not in real X) */
|
||||||
|
XkbStateRec state;
|
||||||
|
if (XkbGetState(xkbdpy, XkbUseCoreKbd, &state) == Success) {
|
||||||
|
if (state.group+1 == 2)
|
||||||
|
event->state |= 0x2;
|
||||||
|
}
|
||||||
printf("i'm in state %d\n", event->state);
|
printf("i'm in state %d\n", event->state);
|
||||||
|
|
||||||
|
|
||||||
|
xcb_key_symbols_t *keysyms = xcb_key_symbols_alloc(conn);
|
||||||
|
|
||||||
|
xcb_keysym_t k0 = xcb_key_symbols_get_keysym(keysyms, event->detail, event->state);
|
||||||
|
if (k0 == XCB_NONE)
|
||||||
|
printf("couldn't get k0\n");
|
||||||
|
|
||||||
|
printf("gots keysym %d and \n", k0);
|
||||||
|
|
||||||
|
|
||||||
/* 30 = u
|
/* 30 = u
|
||||||
* 57 = n
|
* 57 = n
|
||||||
* 27 = r
|
* 27 = r
|
||||||
|
@ -817,6 +842,7 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press
|
||||||
if (event->detail == 30) {
|
if (event->detail == 30) {
|
||||||
/* 'u' */
|
/* 'u' */
|
||||||
start_application(TERMINAL, NULL);
|
start_application(TERMINAL, NULL);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
} else if (event->detail == 57) {
|
} else if (event->detail == 57) {
|
||||||
direction = D_LEFT;
|
direction = D_LEFT;
|
||||||
|
@ -826,6 +852,14 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press
|
||||||
direction = D_UP;
|
direction = D_UP;
|
||||||
} else if (event->detail == 40) {
|
} else if (event->detail == 40) {
|
||||||
direction = D_RIGHT;
|
direction = D_RIGHT;
|
||||||
|
} else if (event->detail == 25) {
|
||||||
|
Container *con = CUR_CELL;
|
||||||
|
if (con->colspan == 1)
|
||||||
|
con->colspan++;
|
||||||
|
else con->colspan--;
|
||||||
|
render_layout(conn);
|
||||||
|
xcb_flush(conn);
|
||||||
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
printf("don't want this.\n");
|
printf("don't want this.\n");
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -865,6 +899,9 @@ static int handle_enter_notify(void *ignored, xcb_connection_t *conn, xcb_enter_
|
||||||
old_client = client->container->currently_focused;
|
old_client = client->container->currently_focused;
|
||||||
client->container->currently_focused = client;
|
client->container->currently_focused = client;
|
||||||
|
|
||||||
|
current_col = client->container->col;
|
||||||
|
current_row = client->container->row;
|
||||||
|
|
||||||
/* Set focus to the entered window, and flush xcb buffer immediately */
|
/* Set focus to the entered window, and flush xcb buffer immediately */
|
||||||
xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, client->child, XCB_CURRENT_TIME);
|
xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, client->child, XCB_CURRENT_TIME);
|
||||||
/* Update last/current client’s titlebar */
|
/* Update last/current client’s titlebar */
|
||||||
|
@ -876,6 +913,7 @@ static int handle_enter_notify(void *ignored, xcb_connection_t *conn, xcb_enter_
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int handle_map_notify_event(void *prophs, xcb_connection_t *c, xcb_map_notify_event_t *e)
|
int handle_map_notify_event(void *prophs, xcb_connection_t *c, xcb_map_notify_event_t *e)
|
||||||
{
|
{
|
||||||
window_attributes_t wa = { TAG_VALUE };
|
window_attributes_t wa = { TAG_VALUE };
|
||||||
|
@ -1002,6 +1040,24 @@ int main(int argc, char *argv[], char *env[]) {
|
||||||
|
|
||||||
printf("x screen is %d\n", screens);
|
printf("x screen is %d\n", screens);
|
||||||
|
|
||||||
|
int major, minor, error;
|
||||||
|
|
||||||
|
major = XkbMajorVersion;
|
||||||
|
minor = XkbMinorVersion;
|
||||||
|
|
||||||
|
int evBase, errBase;
|
||||||
|
|
||||||
|
if ((xkbdpy = XkbOpenDisplay(getenv("DISPLAY"), &evBase, &errBase, &major, &minor, &error)) == NULL) {
|
||||||
|
fprintf(stderr, "XkbOpenDisplay() failed\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i1;
|
||||||
|
if (!XkbQueryExtension(xkbdpy,&i1,&evBase,&errBase,&major,&minor)) {
|
||||||
|
fprintf(stderr, "XKB not supported by X-server\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Font loading */
|
/* Font loading */
|
||||||
myfont = load_font(c, pattern);
|
myfont = load_font(c, pattern);
|
||||||
|
|
||||||
|
@ -1038,6 +1094,9 @@ int main(int argc, char *argv[], char *env[]) {
|
||||||
//xcb_grab_key(c, 0, root, 0, 38, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
|
//xcb_grab_key(c, 0, root, 0, 38, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
|
||||||
|
|
||||||
xcb_grab_key(c, 0, root, 0, 30, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
|
xcb_grab_key(c, 0, root, 0, 30, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
|
||||||
|
xcb_grab_key(c, 0, root, 0, 38, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
|
||||||
|
|
||||||
|
|
||||||
xcb_grab_key(c, 0, root, XCB_MOD_MASK_1, 57, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
|
xcb_grab_key(c, 0, root, XCB_MOD_MASK_1, 57, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
|
||||||
xcb_grab_key(c, 0, root, XCB_MOD_MASK_1, 28, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
|
xcb_grab_key(c, 0, root, XCB_MOD_MASK_1, 28, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
|
||||||
xcb_grab_key(c, 0, root, XCB_MOD_MASK_1, 27, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
|
xcb_grab_key(c, 0, root, XCB_MOD_MASK_1, 27, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
|
||||||
|
@ -1047,6 +1106,8 @@ int main(int argc, char *argv[], char *env[]) {
|
||||||
xcb_grab_key(c, 0, root, XCB_MOD_MASK_CONTROL, 28, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
|
xcb_grab_key(c, 0, root, XCB_MOD_MASK_CONTROL, 28, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
|
||||||
xcb_grab_key(c, 0, root, XCB_MOD_MASK_CONTROL, 27, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
|
xcb_grab_key(c, 0, root, XCB_MOD_MASK_CONTROL, 27, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
|
||||||
xcb_grab_key(c, 0, root, XCB_MOD_MASK_CONTROL, 40, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
|
xcb_grab_key(c, 0, root, XCB_MOD_MASK_CONTROL, 40, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
|
||||||
|
xcb_grab_key(c, 0, root, XCB_MOD_MASK_CONTROL, 25, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//xcb_grab_key(c, 0, root, XCB_BUTTON_MASK_ANY, 40, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
|
//xcb_grab_key(c, 0, root, XCB_BUTTON_MASK_ANY, 40, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
|
||||||
|
|
19
table.c
19
table.c
|
@ -29,20 +29,26 @@ void init_table() {
|
||||||
expand_table_rows();
|
expand_table_rows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void new_container(Container **container) {
|
||||||
|
Container *new;
|
||||||
|
new = *container = calloc(sizeof(Container), 1);
|
||||||
|
CIRCLEQ_INIT(&(new->clients));
|
||||||
|
new->colspan = 1;
|
||||||
|
new->rowspan = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add one row to the table
|
* Add one row to the table
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void expand_table_rows() {
|
void expand_table_rows() {
|
||||||
int c;
|
int c;
|
||||||
Container *new;
|
|
||||||
|
|
||||||
table_dims.y++;
|
table_dims.y++;
|
||||||
|
|
||||||
for (c = 0; c < table_dims.x; c++) {
|
for (c = 0; c < table_dims.x; c++) {
|
||||||
table[c] = realloc(table[c], sizeof(Container*) * table_dims.y);
|
table[c] = realloc(table[c], sizeof(Container*) * table_dims.y);
|
||||||
new = table[c][table_dims.y-1] = calloc(sizeof(Container), 1);
|
new_container(&(table[c][table_dims.y-1]));
|
||||||
CIRCLEQ_INIT(&(new->clients));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,15 +58,12 @@ void expand_table_rows() {
|
||||||
*/
|
*/
|
||||||
void expand_table_cols() {
|
void expand_table_cols() {
|
||||||
int c;
|
int c;
|
||||||
Container *new;
|
|
||||||
|
|
||||||
table_dims.x++;
|
table_dims.x++;
|
||||||
table = realloc(table, sizeof(Container**) * table_dims.x);
|
table = realloc(table, sizeof(Container**) * table_dims.x);
|
||||||
table[table_dims.x-1] = calloc(sizeof(Container*) * table_dims.y, 1);
|
table[table_dims.x-1] = calloc(sizeof(Container*) * table_dims.y, 1);
|
||||||
for (c = 0; c < table_dims.y; c++) {
|
for (c = 0; c < table_dims.y; c++)
|
||||||
new = table[table_dims.x-1][c] = calloc(sizeof(Container), 1);
|
new_container(&(table[table_dims.x-1][c]));
|
||||||
CIRCLEQ_INIT(&(new->clients));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue