Add mouse support
This commit is contained in:
parent
cc34dab746
commit
1efcc61006
|
@ -68,3 +68,4 @@ 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)
|
||||||
```
|
```
|
||||||
|
Clickable areas can be defined with \\ab text \\ac command \\ae.
|
||||||
|
|
156
bar.c
156
bar.c
|
@ -45,6 +45,17 @@ typedef struct screen_t {
|
||||||
xcb_window_t window;
|
xcb_window_t window;
|
||||||
} screen_t;
|
} screen_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 xcb_connection_t *c;
|
static xcb_connection_t *c;
|
||||||
static xcb_drawable_t canvas;
|
static xcb_drawable_t canvas;
|
||||||
static xcb_gcontext_t draw_gc;
|
static xcb_gcontext_t draw_gc;
|
||||||
|
@ -59,11 +70,13 @@ static fontset_item_t *sel_font = NULL;
|
||||||
static screen_t *screens;
|
static screen_t *screens;
|
||||||
static int num_screens;
|
static int num_screens;
|
||||||
static const unsigned palette[] = {COLOR0,COLOR1,COLOR2,COLOR3,COLOR4,COLOR5,COLOR6,COLOR7,COLOR8,COLOR9,BACKGROUND,FOREGROUND};
|
static const unsigned palette[] = {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;
|
||||||
|
|
||||||
#if XINERAMA
|
#if XINERAMA
|
||||||
static const char *control_characters = "fbulcsr";
|
static const char *control_characters = "afbulcsr";
|
||||||
#else
|
#else
|
||||||
static const char *control_characters = "fbulcr";
|
static const char *control_characters = "afbulcr";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
@ -100,6 +113,19 @@ xcb_set_fontset (int i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
xcb_handle_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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
draw_char (screen_t *screen, int x, int align, wchar_t ch)
|
draw_char (screen_t *screen, int x, int align, wchar_t ch)
|
||||||
{
|
{
|
||||||
|
@ -143,6 +169,84 @@ draw_char (screen_t *screen, int x, int align, wchar_t ch)
|
||||||
return ch_width;
|
return ch_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_area_begin (screen_t *screen, 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;
|
||||||
|
break;
|
||||||
|
case ALIGN_C:
|
||||||
|
area->begin = screen->width / 2 + x / 2;
|
||||||
|
break;
|
||||||
|
case ALIGN_R:
|
||||||
|
area->begin = screen->width;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_area_end (screen_t *screen, int x, int align)
|
||||||
|
{
|
||||||
|
cmd_area_t *area = cmd_area_list_tail;
|
||||||
|
area->end_x = x;
|
||||||
|
|
||||||
|
switch (align) {
|
||||||
|
case ALIGN_L:
|
||||||
|
area->end = x;
|
||||||
|
break;
|
||||||
|
case ALIGN_C:
|
||||||
|
area->begin -= (x - area->begin_x) / 2;
|
||||||
|
area->end = screen->width / 2 + x / 2;
|
||||||
|
/*
|
||||||
|
* 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 = screen->width;
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
{
|
{
|
||||||
|
@ -150,6 +254,7 @@ parse (char *text)
|
||||||
|
|
||||||
int pos_x = 0;
|
int pos_x = 0;
|
||||||
int align = 0;
|
int align = 0;
|
||||||
|
char *cmd_start = 0;
|
||||||
screen_t *screen = &screens[0];
|
screen_t *screen = &screens[0];
|
||||||
|
|
||||||
xcb_fill_rect (clear_gc, 0, 0, bar_width, BAR_HEIGHT);
|
xcb_fill_rect (clear_gc, 0, 0, bar_width, BAR_HEIGHT);
|
||||||
|
@ -215,6 +320,26 @@ 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 (screen, pos_x, align);
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
if (p++)
|
||||||
|
cmd_start = p;
|
||||||
|
while (p++ && *p != '\0' && *p != '\n' && *p != '\\')
|
||||||
|
;
|
||||||
|
continue;
|
||||||
|
case 'e':
|
||||||
|
cmd_area_end (screen, 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 */
|
||||||
wchar_t t;
|
wchar_t t;
|
||||||
|
@ -356,7 +481,7 @@ set_ewmh_atoms ()
|
||||||
xcb_window_t
|
xcb_window_t
|
||||||
create_window(xcb_window_t root, int x, int y, int width, int height, xcb_visualid_t visual) {
|
create_window(xcb_window_t root, int x, int y, int width, int height, xcb_visualid_t visual) {
|
||||||
xcb_window_t window = xcb_generate_id(c);
|
xcb_window_t window = xcb_generate_id(c);
|
||||||
xcb_create_window(c, XCB_COPY_FROM_PARENT, window, root, x, y, width, height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, visual, XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK, (const uint32_t []){ palette[10], XCB_EVENT_MASK_EXPOSURE });
|
xcb_create_window(c, XCB_COPY_FROM_PARENT, window, root, x, y, width, height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, visual, XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK, (const uint32_t []){ palette[10], XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_RELEASE });
|
||||||
|
|
||||||
xcb_change_window_attributes (c, window, XCB_CW_OVERRIDE_REDIRECT, (const uint32_t []){ force_docking });
|
xcb_change_window_attributes (c, window, XCB_CW_OVERRIDE_REDIRECT, (const uint32_t []){ force_docking });
|
||||||
|
|
||||||
|
@ -485,6 +610,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)
|
||||||
{
|
{
|
||||||
|
@ -509,6 +645,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
|
||||||
|
@ -529,6 +667,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;
|
||||||
|
|
||||||
int permanent = 0;
|
int permanent = 0;
|
||||||
|
|
||||||
|
@ -568,17 +707,22 @@ main (int argc, char **argv)
|
||||||
}
|
}
|
||||||
if (pollin[0].revents & POLLIN) { /* New input, process it */
|
if (pollin[0].revents & POLLIN) { /* New input, process it */
|
||||||
fgets (input, sizeof(input), stdin);
|
fgets (input, sizeof(input), stdin);
|
||||||
|
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_event (button_ev->event_x);
|
||||||
}
|
}
|
||||||
|
|
||||||
free (ev);
|
free (ev);
|
||||||
|
|
|
@ -29,3 +29,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