Map requests slowly being taken care of

This commit is contained in:
Bastien Dejean 2012-09-01 21:55:35 +02:00
parent 25750a9f80
commit c81516c0dc
7 changed files with 115 additions and 28 deletions

View file

@ -97,6 +97,13 @@ void setup(int default_screen)
/* xcb_change_property(dpy, XCB_PROP_MODE_REPLACE, screen->root, netatoms[NET_SUPPORTED], XCB_ATOM_ATOM, 32, NET_COUNT, netatoms); */
xcb_ewmh_set_supported(&ewmh, default_screen, LENGTH(net_atoms), net_atoms);
xcb_ewmh_set_wm_name(&ewmh, screen->root, LENGTH(WM_NAME), WM_NAME);
desk = make_desktop();
last_desk = NULL;
desk_head = desk;
desk_tail = desk;
split_mode = MODE_AUTOMATIC;
}
int main(void)

View file

@ -7,6 +7,7 @@
#include "bspwm.h"
#include "utils.h"
#include "events.h"
#include "tree.h"
void handle_event(xcb_generic_event_t *evt)
{
@ -45,19 +46,72 @@ void map_request(xcb_generic_event_t *evt)
if ((wa != NULL && wa->override_redirect) || win_to_node(win) != NULL)
return;
free(wa);
bool takes_focus = true;
client_t *c = make_client();
c->window = win;
num_clients++;
node_t *focus = desk->focus;
node_t *birth = make_node();
birth->client = c;
if (focus == NULL) {
focus = make_node();
focus->client = c;
desk->root = desk->view = desk->head = desk->tail = birth;
} else {
node_t *dad = make_node();
birth->parent = dad;
switch (split_mode) {
case MODE_AUTOMATIC:
if (focus->parent == NULL) {
} else {
node_t *grandpa = focus->parent->parent;
dad->parent = grandpa;
if (grandpa != NULL) {
if (is_first_child(focus->parent))
grandpa->first_child = dad;
else
grandpa->second_child = dad;
}
if (is_first_child(focus)) {
dad->first_child = birth;
dad->second_child = focus->parent;
} else {
dad->first_child = focus->parent;
dad->second_child = birth;
}
}
break;
case MODE_MANUAL:
focus->parent = dad;
switch (split_dir) {
case DIR_LEFT:
dad->split_type = TYPE_VERTICAL;
dad->first_child = birth;
dad->second_child = focus;
break;
case DIR_RIGHT:
dad->split_type = TYPE_VERTICAL;
dad->first_child = focus;
dad->second_child = birth;
break;
case DIR_UP:
dad->split_type = TYPE_HORIZONTAL;
dad->first_child = birth;
dad->second_child = focus;
break;
case DIR_DOWN:
dad->split_type = TYPE_HORIZONTAL;
dad->first_child = focus;
dad->second_child = birth;
break;
}
if (desk->root == focus)
desk->root = dad;
if (desk->view == focus)
desk->view = dad;
split_mode = MODE_AUTOMATIC;
break;
}
if (takes_focus)
desk->focus = birth;
}
}

6
tree.c
View file

@ -10,6 +10,12 @@ bool is_leaf(node_t *n)
{
return (n != NULL && n->first_child == NULL && n->second_child == NULL);
}
bool is_first_child(node_t *n)
{
return (n != NULL && n->parent != NULL && n->parent->first_child == n);
}
void change_split_ratio(node_t *n, value_change_t chg) {
n->split_ratio = pow(n->split_ratio, (chg == CHANGE_INCREASE ? INC_EXP : DEC_EXP));

1
tree.h
View file

@ -5,6 +5,7 @@
#define DEC_EXP 1.1
bool is_leaf(node_t *);
bool is_first_child(node_t *n);
void change_split_ratio(node_t *, value_change_t);
node_t *first_extrema(node_t *);
node_t *second_extrema(node_t *);

View file

@ -1,4 +1,7 @@
#define _BSD_SOURCE
#include <stdlib.h>
#include <string.h>
#include <xcb/xcb.h>
#include <xcb/xcb_event.h>
#include "types.h"
@ -8,13 +11,16 @@ node_t *make_node(void)
node_t *n = malloc(sizeof(node_t));
n->parent = n->first_child = n->second_child = n->next_leaf = n->prev_leaf = NULL;
n->client = NULL;
n->vacant = false;
n->split_ratio = SPLIT_RATIO;
n->split_type = TYPE_VERTICAL;
return n;
}
desktop_t *make_desktop(void)
{
desktop_t *d = malloc(sizeof(desktop_t));
d->name = NULL;
d->name = strdup(DESK_NAME);
d->layout = LAYOUT_TILED;
d->prev = d->next = NULL;
d->root = d->view = d->focus = d->last_focus = d->head = d->tail = NULL;

23
types.h
View file

@ -5,7 +5,8 @@
#include <xcb/xcb_event.h>
#include "helpers.h"
#define DEFAULT_NAME "one"
#define SPLIT_RATIO 0.5
#define DESK_NAME "One"
typedef enum {
TYPE_HORIZONTAL,
@ -78,16 +79,6 @@ struct node_t {
node_t *next_leaf;
};
typedef struct rule_t rule_t;
struct rule_t {
char *class_name;
char *desk_name;
bool floating;
bool fullscreen;
bool locked;
rule_t *next;
};
typedef struct desktop_t desktop_t;
struct desktop_t {
char *name;
@ -102,6 +93,16 @@ struct desktop_t {
desktop_t *next;
};
typedef struct rule_t rule_t;
struct rule_t {
char *class_name;
char *win_title;
bool floating;
bool fullscreen;
bool locked;
rule_t *next;
};
node_t *make_node(void);
desktop_t *make_desktop(void);
client_t *make_client(void);

40
utils.c
View file

@ -1,6 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <xcb/xcb.h>
#include <xcb/xcb_event.h>
#include "helpers.h"
@ -50,20 +51,31 @@ uint32_t get_color(char *col)
{
xcb_colormap_t map = screen->default_colormap;
xcb_alloc_color_reply_t *rpl;
xcb_alloc_named_color_reply_t *rpln;
uint32_t rgb, pxl;
uint16_t r, g, b;
rgb = color_pixel(col);
r = rgb >> 16;
g = rgb >> 8 & 0xFF;
b = rgb & 0xFF;
rpl = xcb_alloc_color_reply(dpy, xcb_alloc_color(dpy, map, r * 257, g * 257, b * 257), NULL);
if (col[0] == '#') {
rgb = color_pixel(col);
r = rgb >> 16;
g = rgb >> 8 & 0xFF;
b = rgb & 0xFF;
rpl = xcb_alloc_color_reply(dpy, xcb_alloc_color(dpy, map, r * 257, g * 257, b * 257), NULL);
if (rpl != NULL) {
pxl = rpl->pixel;
free(rpl);
}
} else {
rpln = xcb_alloc_named_color_reply(dpy, xcb_alloc_named_color(dpy, map, strlen(col), col), NULL);
if (rpln != NULL) {
pxl = rpln->pixel;
free(rpln);
}
}
if (!rpl)
die("error: cannot allocate color '%s'\n", col);
/* if (!rpl) */
/* die("error: cannot allocate color '%s'\n", col); */
pxl = rpl->pixel;
free(rpl);
return pxl;
}
@ -82,7 +94,7 @@ void draw_triple_border(node_t *n, uint32_t main_border_color_pxl)
uint16_t full_width = width + 2 * border_width;
uint16_t full_height = height + 2 * border_width;
uint16_t split_pos;
xcb_rectangle_t inner_rectangles[] =
@ -137,19 +149,19 @@ void draw_triple_border(node_t *n, uint32_t main_border_color_pxl)
case DIR_UP:
presel_rectangles[0] = (xcb_rectangle_t) {width, 0, 2 * border_width, split_pos};
presel_rectangles[1] = (xcb_rectangle_t) {0, height + border_width, full_width, border_width};
break;
break;
case DIR_DOWN:
presel_rectangles[0] = (xcb_rectangle_t) {width, split_pos + 1, 2 * border_width, height + border_width - (split_pos + 1)};
presel_rectangles[1] = (xcb_rectangle_t) {0, height + border_width, full_width, border_width};
break;
break;
case DIR_LEFT:
presel_rectangles[0] = (xcb_rectangle_t) {0, height, split_pos, 2 * border_width};
presel_rectangles[1] = (xcb_rectangle_t) {width + border_width, 0, border_width, full_height};
break;
break;
case DIR_RIGHT:
presel_rectangles[0] = (xcb_rectangle_t) {split_pos + 1, height, width + border_width - (split_pos + 1), 2 * border_width};
presel_rectangles[1] = (xcb_rectangle_t) {width, 0, border_width, full_height};
break;
break;
}
xcb_change_gc(dpy, gc, XCB_GC_FOREGROUND, &presel_border_color_pxl);
xcb_poly_fill_rectangle(dpy, pix, gc, LENGTH(presel_rectangles), presel_rectangles);