Add feature multiple actions #66
This commit is contained in:
		
							
								
								
									
										101
									
								
								bar.c
									
									
									
									
									
								
							
							
						
						
									
										101
									
								
								bar.c
									
									
									
									
									
								
							@@ -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)
 | 
				
			||||||
@@ -189,7 +195,6 @@ parse_color (const char *str, char **end, const uint32_t def)
 | 
				
			|||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
set_attribute (const char modifier, const char attribute)
 | 
					set_attribute (const char modifier, const char attribute)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -207,14 +212,53 @@ set_attribute (const char modifier, const char attribute)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
area_t *
 | 
					area_handle_click (xcb_window_t win, const int x, const int button)
 | 
				
			||||||
area_get (xcb_window_t win, const int x)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    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
 | 
				
			||||||
            return &astack.slot[i];
 | 
					                && button == astack.slot[i].button) {
 | 
				
			||||||
    return NULL;
 | 
					            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
 | 
					void
 | 
				
			||||||
@@ -227,8 +271,11 @@ area_shift (xcb_window_t win, const int align, int delta)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    for (int i = 0; i < astack.pos; i++) {
 | 
					    for (int i = 0; i < astack.pos; i++) {
 | 
				
			||||||
        if (astack.slot[i].window == win && astack.slot[i].align == align) {
 | 
					        if (astack.slot[i].window == win && astack.slot[i].align == align) {
 | 
				
			||||||
            astack.slot[i].begin -= delta;
 | 
					            /* make sure area tag is closed before moving the bounds */
 | 
				
			||||||
            astack.slot[i].end -= delta;
 | 
					            if (astack.slot[i].end != 0) {
 | 
				
			||||||
 | 
					                astack.slot[i].begin -= delta;
 | 
				
			||||||
 | 
					                astack.slot[i].end -= delta;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -237,7 +284,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 +294,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 +321,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 +334,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 +344,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 +388,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 +796,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);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -855,6 +909,9 @@ init (void)
 | 
				
			|||||||
    /* Initialiaze monitor list head and tail */
 | 
					    /* Initialiaze monitor list head and tail */
 | 
				
			||||||
    monhead = montail = NULL;
 | 
					    monhead = montail = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Initialize area queue list head */
 | 
				
			||||||
 | 
					    aqueuehead = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Check if RandR is present */
 | 
					    /* Check if RandR is present */
 | 
				
			||||||
    qe_reply = xcb_get_extension_data(c, &xcb_randr_id);
 | 
					    qe_reply = xcb_get_extension_data(c, &xcb_randr_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -922,6 +979,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,12 +1178,8 @@ 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);
 | 
					 | 
				
			||||||
                                /* Respond to the click */
 | 
					                                /* Respond to the click */
 | 
				
			||||||
                                if (area && area->button == press_ev->detail) {
 | 
					                                area_handle_click(press_ev->event, press_ev->event_x, press_ev->detail);
 | 
				
			||||||
                                    write(STDOUT_FILENO, area->cmd, strlen(area->cmd)); 
 | 
					 | 
				
			||||||
                                    write(STDOUT_FILENO, "\n", 1); 
 | 
					 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user