Add mouse support
This commit is contained in:
parent
6fb75424e8
commit
372c5bf8dc
10
README.md
10
README.md
|
@ -68,3 +68,13 @@ sp Switches to previous screen
|
||||||
sr Switches to the rightmost screen (the latest)
|
sr Switches to the rightmost screen (the latest)
|
||||||
sl Switches to the leftmost screen (the first)
|
sl Switches to the leftmost screen (the first)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Mouse support
|
||||||
|
-------------
|
||||||
|
You can have any number of clickable areas defined.
|
||||||
|
|
||||||
|
```
|
||||||
|
ab Begins a new clickable area
|
||||||
|
ac The command to execute when clicked
|
||||||
|
ae Ends the current clickable area
|
||||||
|
```
|
||||||
|
|
155
bar.c
155
bar.c
|
@ -34,6 +34,17 @@ typedef struct monitor_t {
|
||||||
struct monitor_t *prev, *next;
|
struct monitor_t *prev, *next;
|
||||||
} monitor_t;
|
} monitor_t;
|
||||||
|
|
||||||
|
typedef struct cmd_area_t {
|
||||||
|
struct cmd_area_t *next;
|
||||||
|
struct cmd_area_t *prev;
|
||||||
|
char *cmd;
|
||||||
|
int begin;
|
||||||
|
int end;
|
||||||
|
int begin_x;
|
||||||
|
int end_x;
|
||||||
|
int align;
|
||||||
|
} cmd_area_t;
|
||||||
|
|
||||||
static struct config_t {
|
static struct config_t {
|
||||||
int place_bottom;
|
int place_bottom;
|
||||||
int force_docking;
|
int force_docking;
|
||||||
|
@ -66,6 +77,9 @@ static const uint32_t palette[] = {
|
||||||
COLOR0,COLOR1,COLOR2,COLOR3,COLOR4,COLOR5,COLOR6,COLOR7,COLOR8,COLOR9,BACKGROUND,FOREGROUND
|
COLOR0,COLOR1,COLOR2,COLOR3,COLOR4,COLOR5,COLOR6,COLOR7,COLOR8,COLOR9,BACKGROUND,FOREGROUND
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static cmd_area_t *cmd_area_list_head;
|
||||||
|
static cmd_area_t *cmd_area_list_tail;
|
||||||
|
|
||||||
void
|
void
|
||||||
set_bg (int i)
|
set_bg (int i)
|
||||||
{
|
{
|
||||||
|
@ -130,10 +144,102 @@ draw_char (monitor_t *mon, font_t *cur_font, int x, int align, int underline, ui
|
||||||
return ch_width;
|
return ch_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xcb_handle_mouse_event (int16_t x)
|
||||||
|
{
|
||||||
|
cmd_area_t *area = cmd_area_list_head;
|
||||||
|
while (area) {
|
||||||
|
if (area->begin <=x && area->end >= x) {
|
||||||
|
system (area->cmd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
area = area->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cmd_area_begin (monitor_t *mon, int x, int align)
|
||||||
|
{
|
||||||
|
cmd_area_t *area = calloc (1, sizeof (*area));
|
||||||
|
|
||||||
|
area->align = align;
|
||||||
|
area->begin_x = x;
|
||||||
|
|
||||||
|
switch (align) {
|
||||||
|
case ALIGN_L:
|
||||||
|
area->begin = x + mon->x;
|
||||||
|
break;
|
||||||
|
case ALIGN_C:
|
||||||
|
area->begin = mon->width / 2 + x / 2 + mon->x;
|
||||||
|
break;
|
||||||
|
case ALIGN_R:
|
||||||
|
area->begin = mon->width + mon->x;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cmd_area_list_head) {
|
||||||
|
cmd_area_list_head = area;
|
||||||
|
cmd_area_list_tail = area;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cmd_area_list_tail->next = area;
|
||||||
|
area->prev = cmd_area_list_tail;
|
||||||
|
cmd_area_list_tail = area;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cmd_area_end (monitor_t *mon, int x, int align)
|
||||||
|
{
|
||||||
|
cmd_area_t *area = cmd_area_list_tail;
|
||||||
|
area->end_x = x;
|
||||||
|
|
||||||
|
switch (align) {
|
||||||
|
case ALIGN_L:
|
||||||
|
area->end = x + mon->x;
|
||||||
|
break;
|
||||||
|
case ALIGN_C:
|
||||||
|
area->begin -= (x - area->begin_x) / 2;
|
||||||
|
area->end = mon->width / 2 + x / 2 + mon->x;
|
||||||
|
/*
|
||||||
|
* if there were any other center aligned areas
|
||||||
|
* before this one, adjust their position
|
||||||
|
*/
|
||||||
|
cmd_area_t *a = area->prev;
|
||||||
|
if (a && a->align == ALIGN_C) {
|
||||||
|
int diff = (area->begin_x - a->end_x + area->end - area->begin) / 2;
|
||||||
|
while (a && a->align == ALIGN_C) {
|
||||||
|
a->begin -= diff;
|
||||||
|
a->end -= diff;
|
||||||
|
a = a->prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ALIGN_R:
|
||||||
|
area->begin -= (x - area->begin_x);
|
||||||
|
area->end = mon->width + mon->x;
|
||||||
|
/*
|
||||||
|
* if there were any other right aligned areas
|
||||||
|
* before this one, adjust their position
|
||||||
|
*/
|
||||||
|
a = area->prev;
|
||||||
|
if (a && a->align == ALIGN_R) {
|
||||||
|
int diff = area->begin_x - a->end_x + area->end - area->begin;
|
||||||
|
while (a && a->align == ALIGN_R) {
|
||||||
|
a->begin -= diff;
|
||||||
|
a->end -= diff;
|
||||||
|
a = a->prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
parse (char *text)
|
parse (char *text)
|
||||||
{
|
{
|
||||||
char *p = text;
|
char *p = text;
|
||||||
|
char *cmd_start = 0;
|
||||||
|
|
||||||
int pos_x = 0;
|
int pos_x = 0;
|
||||||
int align = 0;
|
int align = 0;
|
||||||
|
@ -151,7 +257,7 @@ parse (char *text)
|
||||||
if (*p == '\0' || *p == '\n')
|
if (*p == '\0' || *p == '\n')
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (*p == '^' && p++ && *p != '^' && strchr ("_-fbulcrs", *p)) {
|
if (*p == '^' && p++ && *p != '^' && strchr ("_-afbulcrs", *p)) {
|
||||||
switch (*p++) {
|
switch (*p++) {
|
||||||
case 'f':
|
case 'f':
|
||||||
set_fg (isdigit(*p) ? *p-'0' : 11);
|
set_fg (isdigit(*p) ? *p-'0' : 11);
|
||||||
|
@ -214,6 +320,25 @@ parse (char *text)
|
||||||
align = ALIGN_R;
|
align = ALIGN_R;
|
||||||
pos_x = 0;
|
pos_x = 0;
|
||||||
break;
|
break;
|
||||||
|
case 'a':
|
||||||
|
switch (*p) {
|
||||||
|
case 'b':
|
||||||
|
cmd_area_begin (cur_mon, pos_x, align);
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
cmd_start = ++p;
|
||||||
|
while (*p != '\0' && *p != '\n' && *p != '^')
|
||||||
|
p++;
|
||||||
|
continue;
|
||||||
|
case 'e':
|
||||||
|
cmd_area_end (cur_mon, pos_x, align);
|
||||||
|
size_t cmd_len = (size_t)(p - cmd_start) - 2;
|
||||||
|
cmd_area_list_tail->cmd = calloc (cmd_len + 1, sizeof(char));
|
||||||
|
strncpy (cmd_area_list_tail->cmd, cmd_start, cmd_len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else { /* utf-8 -> ucs-2 */
|
} else { /* utf-8 -> ucs-2 */
|
||||||
uint8_t *utf = (uint8_t *)p;
|
uint8_t *utf = (uint8_t *)p;
|
||||||
|
@ -369,7 +494,8 @@ monitor_new (int x, int y, int width, int height)
|
||||||
x, win_y, width, cfg.height, 0,
|
x, win_y, width, cfg.height, 0,
|
||||||
XCB_WINDOW_CLASS_INPUT_OUTPUT, scr->root_visual,
|
XCB_WINDOW_CLASS_INPUT_OUTPUT, scr->root_visual,
|
||||||
XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK,
|
XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK,
|
||||||
(const uint32_t []){ palette[10], XCB_EVENT_MASK_EXPOSURE });
|
(const uint32_t []){ palette[10], XCB_EVENT_MASK_EXPOSURE
|
||||||
|
| XCB_EVENT_MASK_BUTTON_RELEASE });
|
||||||
|
|
||||||
xcb_change_window_attributes (c, ret->window, XCB_CW_OVERRIDE_REDIRECT,
|
xcb_change_window_attributes (c, ret->window, XCB_CW_OVERRIDE_REDIRECT,
|
||||||
(const uint32_t []){ cfg.force_docking });
|
(const uint32_t []){ cfg.force_docking });
|
||||||
|
@ -621,6 +747,17 @@ init (void)
|
||||||
xcb_flush (c);
|
xcb_flush (c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clear_cmd_area_list (void)
|
||||||
|
{
|
||||||
|
while (cmd_area_list_head) {
|
||||||
|
cmd_area_t *area = cmd_area_list_head;
|
||||||
|
cmd_area_list_head = cmd_area_list_head->next;
|
||||||
|
free (area->cmd);
|
||||||
|
free (area);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cleanup (void)
|
cleanup (void)
|
||||||
{
|
{
|
||||||
|
@ -650,6 +787,8 @@ cleanup (void)
|
||||||
xcb_free_gc (c, underl_gc);
|
xcb_free_gc (c, underl_gc);
|
||||||
if (c)
|
if (c)
|
||||||
xcb_disconnect (c);
|
xcb_disconnect (c);
|
||||||
|
|
||||||
|
clear_cmd_area_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -705,7 +844,7 @@ parse_font_list (char *str)
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
char input[1024] = {0, };
|
char input[2048] = {0, };
|
||||||
struct pollfd pollin[2] = {
|
struct pollfd pollin[2] = {
|
||||||
{ .fd = STDIN_FILENO, .events = POLLIN },
|
{ .fd = STDIN_FILENO, .events = POLLIN },
|
||||||
{ .fd = -1 , .events = POLLIN },
|
{ .fd = -1 , .events = POLLIN },
|
||||||
|
@ -713,6 +852,7 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
xcb_generic_event_t *ev;
|
xcb_generic_event_t *ev;
|
||||||
xcb_expose_event_t *expose_ev;
|
xcb_expose_event_t *expose_ev;
|
||||||
|
xcb_button_release_event_t *button_ev;
|
||||||
|
|
||||||
char ch;
|
char ch;
|
||||||
while ((ch = getopt (argc, argv, "hg:bdf:a:o:p")) != -1) {
|
while ((ch = getopt (argc, argv, "hg:bdf:a:o:p")) != -1) {
|
||||||
|
@ -764,17 +904,22 @@ main (int argc, char **argv)
|
||||||
if (fgets (input, sizeof(input), stdin) == NULL)
|
if (fgets (input, sizeof(input), stdin) == NULL)
|
||||||
break; /* EOF received */
|
break; /* EOF received */
|
||||||
|
|
||||||
|
clear_cmd_area_list();
|
||||||
parse (input);
|
parse (input);
|
||||||
redraw = 1;
|
redraw = 1;
|
||||||
}
|
}
|
||||||
if (pollin[1].revents & POLLIN) { /* Xserver broadcasted an event */
|
if (pollin[1].revents & POLLIN) { /* Xserver broadcasted an event */
|
||||||
while ((ev = xcb_poll_for_event (c))) {
|
while ((ev = xcb_poll_for_event (c))) {
|
||||||
expose_ev = (xcb_expose_event_t *)ev;
|
|
||||||
|
|
||||||
switch (ev->response_type & 0x7F) {
|
switch (ev->response_type & ~0x80) {
|
||||||
case XCB_EXPOSE:
|
case XCB_EXPOSE:
|
||||||
|
expose_ev = (xcb_expose_event_t *)ev;
|
||||||
if (expose_ev->count == 0) redraw = 1;
|
if (expose_ev->count == 0) redraw = 1;
|
||||||
break;
|
break;
|
||||||
|
case XCB_BUTTON_RELEASE:
|
||||||
|
button_ev = (xcb_button_release_event_t *)ev;
|
||||||
|
if (button_ev->detail == MOUSE_BUTTON)
|
||||||
|
xcb_handle_mouse_event (button_ev->root_x);
|
||||||
}
|
}
|
||||||
|
|
||||||
free (ev);
|
free (ev);
|
||||||
|
|
|
@ -13,3 +13,6 @@
|
||||||
#define COLOR8 0x425059
|
#define COLOR8 0x425059
|
||||||
#define COLOR9 0xcc6666
|
#define COLOR9 0xcc6666
|
||||||
#define FOREGROUND 0xc5c8c6
|
#define FOREGROUND 0xc5c8c6
|
||||||
|
|
||||||
|
/* Mouse button to react to */
|
||||||
|
#define MOUSE_BUTTON 1
|
||||||
|
|
Loading…
Reference in New Issue
Block a user