* Conversion functions *
************************/
+/* State names */
+static char *state_map[] = {
+ [ST_HIDE ] "hide ",
+ [ST_SHOW ] "show ",
+ [ST_FULL ] "full ",
+ [ST_MAX ] "max ",
+ [ST_SHADE] "shade",
+ [ST_ICON ] "icon ",
+ [ST_CLOSE] "close",
+};
+
/* Key presses */
static struct {
event_t ev;
{ EV_F12, 0xFFC9 },
};
+/************************
+ * Conversion functions *
+ ************************/
+
static xcb_keycode_t *event_to_keycodes(event_t ev)
{
xcb_keycode_t *codes = NULL;
return ninfo;
}
+static int do_get_input_focus(void)
+{
+ xcb_get_input_focus_cookie_t cookie =
+ xcb_get_input_focus(conn);
+ if (!cookie.sequence)
+ return warn("do_get_input_focus: bad cookie");
+
+ xcb_get_input_focus_reply_t *reply =
+ xcb_get_input_focus_reply(conn, cookie, NULL);
+ if (!reply)
+ return warn("do_get_input_focus: no reply");
+
+ return reply->focus;
+}
+
static xcb_pixmap_t do_alloc_color(uint32_t rgb)
{
uint16_t r = (rgb & 0xFF0000) >> 8;
xcb_ungrab_pointer(conn, XCB_CURRENT_TIME);
}
+static void do_configure_window(xcb_window_t win,
+ int x, int y, int w, int h,
+ int b, int s, int r)
+{
+ int table[][2] = {
+ { x, XCB_CONFIG_WINDOW_X },
+ { y, XCB_CONFIG_WINDOW_Y },
+ { w, XCB_CONFIG_WINDOW_WIDTH },
+ { h, XCB_CONFIG_WINDOW_HEIGHT },
+ { b, XCB_CONFIG_WINDOW_BORDER_WIDTH },
+ { s, XCB_CONFIG_WINDOW_SIBLING },
+ { r, XCB_CONFIG_WINDOW_STACK_MODE },
+ };
+
+ uint16_t mask = 0;
+ uint32_t list[7] = {};
+ for (int i = 0; i < 7; i++) {
+ if (table[i][0] >= 0) {
+ list[i] = table[i][0];
+ mask |= table[i][1];
+ }
+ }
+
+ xcb_configure_window(conn, win, mask, list);
+}
+
/**************************
* Window Manager Helpers *
**************************/
static void on_key_event(xcb_key_press_event_t *event, int up)
{
printf("on_key_event: xcb=%-8u\n", event->event);
+ xcb_window_t focus = do_get_input_focus();
event_t ev = keycode_to_event(event->detail);
send_event_info(ev, event->state, up, &event->root_x,
- event->root, event->event, event->child);
+ event->root, focus, event->child);
}
static void on_button_event(xcb_button_press_event_t *event, int up)
tsearch(win, &cache, win_cmp);
}
-static void on_destroy_notify(win_t *win, xcb_destroy_notify_event_t *event)
+static void on_destroy_notify(xcb_destroy_notify_event_t *event)
{
+ win_t *win = win_get(event->window);
printf("on_destroy_notify: xcb=%-8u -> win=%p\n",
event->window, win);
+ if (!win) return;
tdelete(win, &cache, win_cmp);
free(win);
}
-static void on_map_request(win_t *win, xcb_map_request_event_t *event)
+static void on_map_request(xcb_map_request_event_t *event)
{
+ win_t *win = win_get(event->window);
printf("on_map_request: xcb=%-8u -> win=%p\n",
event->window, win);
+ if (!win) return;
if (!win->sys->override && !win->sys->mapped)
wm_insert(win);
sys_move(win, win->x, win->y, win->w, win->h);
}
-static void on_configure_request(win_t *win, xcb_configure_request_event_t *event)
+static void on_configure_request(xcb_configure_request_event_t *event)
{
+ win_t *win = win_get(event->window);
printf("on_configure_request: xcb=%-8u -> win=%p -- %dx%d @ %d,%d\n",
event->window, win,
event->width, event->height,
event->x, event->y);
+ if (!win) return;
win->x = event->x;
win->y = event->y;
/* Generic Event */
static void on_event(xcb_generic_event_t *event)
{
- win_t *win = NULL;
-
int type = XCB_EVENT_RESPONSE_TYPE(event);
- int sent = XCB_EVENT_SENT(event);
- const char *name = NULL;
switch (type) {
/* Input handling */
on_create_notify((xcb_create_notify_event_t *)event);
break;
case XCB_DESTROY_NOTIFY:
- if ((win = win_get(((xcb_destroy_notify_event_t *)event)->window)))
- on_destroy_notify(win, (xcb_destroy_notify_event_t *)event);
+ on_destroy_notify((xcb_destroy_notify_event_t *)event);
break;
case XCB_MAP_REQUEST:
- if ((win = win_get(((xcb_map_request_event_t *)event)->window)))
- on_map_request(win, (xcb_map_request_event_t *)event);
+ on_map_request((xcb_map_request_event_t *)event);
break;
case XCB_CONFIGURE_REQUEST:
- if ((win = win_get(((xcb_configure_request_event_t *)event)->window)))
- on_configure_request(win, (xcb_configure_request_event_t *)event);
+ on_configure_request((xcb_configure_request_event_t *)event);
break;
/* Unknown events */
default:
- name = xcb_event_get_label(type);
printf("on_event: %d:%02X -> %s\n",
- !!sent, type, name?:"unknown_event");
+ XCB_EVENT_SENT(event) != 0,
+ XCB_EVENT_RESPONSE_TYPE(event),
+ xcb_event_get_label(type) ?: "unknown_event");
break;
}
}
w = MAX(w-b,1);
h = MAX(h-b,1);
- uint16_t mask = XCB_CONFIG_WINDOW_X
- | XCB_CONFIG_WINDOW_Y
- | XCB_CONFIG_WINDOW_WIDTH
- | XCB_CONFIG_WINDOW_HEIGHT
- | XCB_CONFIG_WINDOW_BORDER_WIDTH;
- uint32_t list[] = {x, y, w, h, border};
-
- xcb_configure_window(conn, win->sys->xcb, mask, list);
+ do_configure_window(win->sys->xcb, x, y, w, h, -1, -1, -1);
}
void sys_raise(win_t *win)
{
printf("sys_raise: %p\n", win);
- xcb_circulate_window(conn, XCB_CIRCULATE_RAISE_LOWEST, win->sys->xcb);
+
+ uint16_t mask = XCB_CONFIG_WINDOW_STACK_MODE;
+ uint32_t list = XCB_STACK_MODE_ABOVE;
+
+ xcb_configure_window(conn, win->sys->xcb, mask, &list);
}
void sys_focus(win_t *win)
void sys_show(win_t *win, state_t state)
{
- printf("sys_show: %p - %d\n", win, state);
+ printf("sys_show: %p - %s -> %s\n", win,
+ state_map[win->state], state_map[state]);
+ xcb_window_t xcb = win ? win->sys->xcb : root;
+
+ /* Find screen */
+ win_t *screen = NULL;
+ if (state == ST_FULL || state == ST_MAX) {
+ for (list_t *cur = screens; cur; cur = cur->next) {
+ screen = cur->data;
+ if (win->x >= screen->x && win->x <= screen->x+screen->w &&
+ win->y >= screen->y && win->y <= screen->y+screen->h)
+ break;
+ }
+ }
+
+ /* Change window state */
+ switch (state) {
+ case ST_HIDE:
+ xcb_unmap_window(conn, xcb);
+ break;
+
+ case ST_SHOW:
+ xcb_map_window(conn, xcb);
+ do_configure_window(xcb, win->x, win->y,
+ MAX(win->w - 2*border, 1),
+ MAX(win->h - 2*border, 1),
+ border, -1, -1);
+ break;
+
+ case ST_FULL:
+ xcb_map_window(conn, xcb);
+ do_configure_window(xcb, screen->x, screen->y, screen->w, screen->h,
+ 0, -1, XCB_STACK_MODE_ABOVE);
+ xcb_circulate_window(conn, XCB_CIRCULATE_RAISE_LOWEST, xcb);
+ break;
+
+ case ST_MAX:
+ xcb_map_window(conn, xcb);
+ do_configure_window(xcb, screen->x, screen->y,
+ MAX(screen->w - 2*border, 1),
+ MAX(screen->h - 2*border, 1),
+ border, -1, XCB_STACK_MODE_ABOVE);
+ break;
+
+ case ST_SHADE:
+ xcb_map_window(conn, xcb);
+ do_configure_window(xcb, -1, -1, -1, stack,
+ border, -1, -1);
+ break;
+
+ case ST_ICON:
+ xcb_map_window(conn, xcb);
+ do_configure_window(xcb, -1, -1, 100, 100,
+ border, -1, -1);
+ break;
+
+ case ST_CLOSE:
+ // TODO
+ // if (!win_msg(win, WM_DELETE)) {
+ // XGrabServer(win->sys->dpy);
+ // XSetErrorHandler(xnoerror);
+ // XSetCloseDownMode(win->sys->dpy, DestroyAll);
+ // XKillClient(win->sys->dpy, win->sys->xid);
+ // XSync(win->sys->dpy, False);
+ // XSetErrorHandler(xerror);
+ // XUngrabServer(win->sys->dpy);
+ // }
+ break;
+ }
+
+ /* Update state */
+ win->state = state;
}
void sys_watch(win_t *win, event_t ev, mod_t mod)