Add feature multiple actions #66

Multiple actions can overlap. Queue linked list holds area array position. Button number sent to area_get.
This commit is contained in:
rootcoma 2014-08-07 01:08:54 -07:00
parent 69e8ac6f07
commit 1a6143cd1f

81
bar.c
View File

@ -46,6 +46,11 @@ typedef struct area_stack_t {
area_t slot[N]; area_t slot[N];
} area_stack_t; } area_stack_t;
typedef struct area_queue_t {
int pos;
struct area_queue_t *next;
} area_queue_t;
enum { enum {
ATTR_OVERL = (1<<0), ATTR_OVERL = (1<<0),
ATTR_UNDERL = (1<<1), ATTR_UNDERL = (1<<1),
@ -85,6 +90,7 @@ static int bu = 1; /* Underline height */
static uint32_t fgc, bgc, ugc; static uint32_t fgc, bgc, ugc;
static uint32_t dfgc, dbgc; static uint32_t dfgc, dbgc;
static area_stack_t astack; static area_stack_t astack;
static area_queue_t *aqueuehead;
void void
update_gc (void) update_gc (void)
@ -209,14 +215,54 @@ set_attribute (const char modifier, const char attribute)
area_t * area_t *
area_get (xcb_window_t win, const int x) area_get (xcb_window_t win, const int x, const int button)
{ {
for (int i = 0; i < astack.pos; i++) for (int i = 0; i < astack.pos; i++)
if (astack.slot[i].window == win && x > astack.slot[i].begin && x < astack.slot[i].end) if (astack.slot[i].window == win && x > astack.slot[i].begin && x < astack.slot[i].end && button == astack.slot[i].button)
return &astack.slot[i]; return &astack.slot[i];
return NULL; return NULL;
} }
int
area_queue_pop ()
{
int pos = -1;
if(!aqueuehead)
return pos;
area_queue_t *a = aqueuehead->next;
pos = aqueuehead->pos;
free(aqueuehead);
aqueuehead = a;
return pos;
}
void
area_queue_free ()
{
while (aqueuehead) {
area_queue_t *a = aqueuehead->next;
free(aqueuehead);
aqueuehead = a;
}
}
void
area_queue_add (const int pos)
{
area_queue_t *ret;
ret = calloc(1, sizeof(area_queue_t));
if (!ret) {
fprintf(stderr, "Failed to allocate new area queue\n");
exit(EXIT_FAILURE);
}
ret->next = aqueuehead;
ret->pos = pos;
aqueuehead = ret;
}
void void
area_shift (xcb_window_t win, const int align, int delta) area_shift (xcb_window_t win, const int align, int delta)
{ {
@ -237,7 +283,6 @@ bool
area_add (char *str, const char *optend, char **end, monitor_t *mon, const int x, const int align, const int button) area_add (char *str, const char *optend, char **end, monitor_t *mon, const int x, const int align, const int button)
{ {
char *p = str; char *p = str;
area_t *a = &astack.slot[astack.pos];
if (astack.pos == N) { if (astack.pos == N) {
fprintf(stderr, "astack overflow!\n"); fprintf(stderr, "astack overflow!\n");
@ -248,8 +293,14 @@ area_add (char *str, const char *optend, char **end, monitor_t *mon, const int x
if (*p != ':') { if (*p != ':') {
*end = p; *end = p;
const int pos = area_queue_pop();
if (pos == -1)
return false;
area_t *a = &astack.slot[pos];
/* Basic safety checks */ /* Basic safety checks */
if (!a->cmd || a->align != align || a->window != mon->window) if (!a || !a->cmd || a->align != align || a->window != mon->window)
return false; return false;
const int size = x - a->begin; const int size = x - a->begin;
@ -269,8 +320,6 @@ area_add (char *str, const char *optend, char **end, monitor_t *mon, const int x
break; break;
} }
astack.pos++;
return true; return true;
} }
@ -284,6 +333,8 @@ area_add (char *str, const char *optend, char **end, monitor_t *mon, const int x
*trail = '\0'; *trail = '\0';
area_t *a = &astack.slot[astack.pos];
/* This is a pointer to the string buffer allocated in the main */ /* This is a pointer to the string buffer allocated in the main */
a->cmd = p; a->cmd = p;
a->align = align; a->align = align;
@ -292,7 +343,8 @@ area_add (char *str, const char *optend, char **end, monitor_t *mon, const int x
a->button = button; a->button = button;
*end = trail + 1; *end = trail + 1;
area_queue_add(astack.pos);
astack.pos++;
return true; return true;
} }
@ -335,6 +387,7 @@ parse (char *text)
align = ALIGN_L; align = ALIGN_L;
cur_mon = monhead; cur_mon = monhead;
area_queue_free();
memset(&astack, 0, sizeof(area_stack_t)); memset(&astack, 0, sizeof(area_stack_t));
for (monitor_t *m = monhead; m != NULL; m = m->next) for (monitor_t *m = monhead; m != NULL; m = m->next)
@ -742,11 +795,11 @@ get_randr_monitors (void)
return; return;
} }
xcb_rectangle_t r[valid]; xcb_rectangle_t r[valid];
for (i = j = 0; i < num && j < valid; i++) for (i = j = 0; i < num && j < valid; i++)
if (rects[i].width != 0) if (rects[i].width != 0)
r[j++] = rects[i]; r[j++] = rects[i];
monitor_create_chain(r, valid); monitor_create_chain(r, valid);
} }
@ -922,6 +975,8 @@ init (void)
void void
cleanup (void) cleanup (void)
{ {
area_queue_free();
for (int i = 0; font_list[i]; i++) { for (int i = 0; font_list[i]; i++) {
xcb_close_font(c, font_list[i]->ptr); xcb_close_font(c, font_list[i]->ptr);
free(font_list[i]); free(font_list[i]);
@ -1119,9 +1174,9 @@ main (int argc, char **argv)
case XCB_BUTTON_PRESS: case XCB_BUTTON_PRESS:
press_ev = (xcb_button_press_event_t *)ev; press_ev = (xcb_button_press_event_t *)ev;
{ {
area_t *area = area_get(press_ev->event, press_ev->event_x); area_t *area = area_get(press_ev->event, press_ev->event_x, press_ev->detail);
/* Respond to the click */ /* Respond to the click */
if (area && area->button == press_ev->detail) { if (area) {
write(STDOUT_FILENO, area->cmd, strlen(area->cmd)); write(STDOUT_FILENO, area->cmd, strlen(area->cmd));
write(STDOUT_FILENO, "\n", 1); write(STDOUT_FILENO, "\n", 1);
} }