Add feature multiple actions #66
This commit is contained in:
		
							
								
								
									
										89
									
								
								bar.c
									
									
									
									
									
								
							
							
						
						
									
										89
									
								
								bar.c
									
									
									
									
									
								
							@@ -46,6 +46,11 @@ typedef struct area_stack_t {
 | 
			
		||||
    area_t slot[N];
 | 
			
		||||
} area_stack_t;
 | 
			
		||||
 | 
			
		||||
typedef struct area_queue_t {
 | 
			
		||||
    int pos;
 | 
			
		||||
    struct area_queue_t *next;
 | 
			
		||||
} area_queue_t;
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    ATTR_OVERL = (1<<0),
 | 
			
		||||
    ATTR_UNDERL = (1<<1),
 | 
			
		||||
@@ -85,6 +90,7 @@ static int bu = 1; /* Underline height */
 | 
			
		||||
static uint32_t fgc, bgc, ugc;
 | 
			
		||||
static uint32_t dfgc, dbgc;
 | 
			
		||||
static area_stack_t astack;
 | 
			
		||||
static area_queue_t *aqueuehead;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
update_gc (void)
 | 
			
		||||
@@ -189,7 +195,6 @@ parse_color (const char *str, char **end, const uint32_t def)
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
set_attribute (const char modifier, const char attribute)
 | 
			
		||||
{
 | 
			
		||||
@@ -207,14 +212,53 @@ set_attribute (const char modifier, const char attribute)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
area_t *
 | 
			
		||||
area_get (xcb_window_t win, const int x)
 | 
			
		||||
void
 | 
			
		||||
area_handle_click (xcb_window_t win, const int x, const int button)
 | 
			
		||||
{
 | 
			
		||||
    for (int i = 0; i < astack.pos; i++)
 | 
			
		||||
        if (astack.slot[i].window == win && x > astack.slot[i].begin && x < astack.slot[i].end)
 | 
			
		||||
            return &astack.slot[i];
 | 
			
		||||
    return NULL;
 | 
			
		||||
        if (astack.slot[i].window == win && x > astack.slot[i].begin && x < astack.slot[i].end
 | 
			
		||||
                && button == astack.slot[i].button) {
 | 
			
		||||
            write(STDOUT_FILENO, astack.slot[i].cmd, strlen(astack.slot[i].cmd)); 
 | 
			
		||||
            write(STDOUT_FILENO, "\n", 1); 
 | 
			
		||||
        }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
@@ -227,17 +271,19 @@ area_shift (xcb_window_t win, const int align, int delta)
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < astack.pos; i++) {
 | 
			
		||||
        if (astack.slot[i].window == win && astack.slot[i].align == align) {
 | 
			
		||||
            /* make sure area tag is closed before moving the bounds */
 | 
			
		||||
            if (astack.slot[i].end != 0) {
 | 
			
		||||
                astack.slot[i].begin -= delta;
 | 
			
		||||
                astack.slot[i].end -= delta;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
area_add (char *str, const char *optend, char **end, monitor_t *mon, const int x, const int align, const int button)
 | 
			
		||||
{
 | 
			
		||||
    char *p = str;
 | 
			
		||||
    area_t *a = &astack.slot[astack.pos];
 | 
			
		||||
 | 
			
		||||
    if (astack.pos == N) {
 | 
			
		||||
        fprintf(stderr, "astack overflow!\n");
 | 
			
		||||
@@ -248,8 +294,14 @@ area_add (char *str, const char *optend, char **end, monitor_t *mon, const int x
 | 
			
		||||
    if (*p != ':') {
 | 
			
		||||
        *end = p;
 | 
			
		||||
 | 
			
		||||
        const int pos = area_queue_pop();
 | 
			
		||||
        if (pos == -1)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        area_t *a = &astack.slot[pos];
 | 
			
		||||
 | 
			
		||||
        /* 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;
 | 
			
		||||
 | 
			
		||||
        const int size = x - a->begin;
 | 
			
		||||
@@ -269,8 +321,6 @@ area_add (char *str, const char *optend, char **end, monitor_t *mon, const int x
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        astack.pos++;
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -284,6 +334,8 @@ area_add (char *str, const char *optend, char **end, monitor_t *mon, const int x
 | 
			
		||||
 | 
			
		||||
    *trail = '\0';
 | 
			
		||||
 | 
			
		||||
    area_t *a = &astack.slot[astack.pos];
 | 
			
		||||
 | 
			
		||||
    /* This is a pointer to the string buffer allocated in the main */
 | 
			
		||||
    a->cmd = p;
 | 
			
		||||
    a->align = align;
 | 
			
		||||
@@ -292,7 +344,8 @@ area_add (char *str, const char *optend, char **end, monitor_t *mon, const int x
 | 
			
		||||
    a->button = button;
 | 
			
		||||
 | 
			
		||||
    *end = trail + 1;
 | 
			
		||||
 | 
			
		||||
    area_queue_add(astack.pos);
 | 
			
		||||
    astack.pos++;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -335,6 +388,7 @@ parse (char *text)
 | 
			
		||||
    align = ALIGN_L;
 | 
			
		||||
    cur_mon = monhead;
 | 
			
		||||
 | 
			
		||||
    area_queue_free();
 | 
			
		||||
    memset(&astack, 0, sizeof(area_stack_t));
 | 
			
		||||
 | 
			
		||||
    for (monitor_t *m = monhead; m != NULL; m = m->next)
 | 
			
		||||
@@ -855,6 +909,9 @@ init (void)
 | 
			
		||||
    /* Initialiaze monitor list head and tail */
 | 
			
		||||
    monhead = montail = NULL;
 | 
			
		||||
 | 
			
		||||
    /* Initialize area queue list head */
 | 
			
		||||
    aqueuehead = NULL;
 | 
			
		||||
 | 
			
		||||
    /* Check if RandR is present */
 | 
			
		||||
    qe_reply = xcb_get_extension_data(c, &xcb_randr_id);
 | 
			
		||||
 | 
			
		||||
@@ -922,6 +979,8 @@ init (void)
 | 
			
		||||
void
 | 
			
		||||
cleanup (void)
 | 
			
		||||
{
 | 
			
		||||
    area_queue_free();
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; font_list[i]; i++) {
 | 
			
		||||
        xcb_close_font(c, font_list[i]->ptr);
 | 
			
		||||
        free(font_list[i]);
 | 
			
		||||
@@ -1119,12 +1178,8 @@ main (int argc, char **argv)
 | 
			
		||||
                        case XCB_BUTTON_PRESS:
 | 
			
		||||
                            press_ev = (xcb_button_press_event_t *)ev;
 | 
			
		||||
                            {
 | 
			
		||||
                                area_t *area = area_get(press_ev->event, press_ev->event_x);
 | 
			
		||||
                                /* Respond to the click */
 | 
			
		||||
                                if (area && area->button == press_ev->detail) {
 | 
			
		||||
                                    write(STDOUT_FILENO, area->cmd, strlen(area->cmd)); 
 | 
			
		||||
                                    write(STDOUT_FILENO, "\n", 1); 
 | 
			
		||||
                                }
 | 
			
		||||
                                area_handle_click(press_ev->event, press_ev->event_x, press_ev->detail);
 | 
			
		||||
                            }
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user