diff --git a/RELEASE-NOTES-next b/RELEASE-NOTES-next index 406fbe2a1..c99e27d7b 100644 --- a/RELEASE-NOTES-next +++ b/RELEASE-NOTES-next @@ -28,6 +28,7 @@ working. Please reach out to us in that case! • mention rofi in default config file • i3-input: add different exit codes for when i3-input fails • allow ppt values in move direction and move position commands + • i3bar: add coordinates relative to the current output in i3bar click events ┌────────────────────────────┐ │ Bugfixes │ diff --git a/docs/i3bar-protocol b/docs/i3bar-protocol index 62b1222f2..c1bf8f808 100644 --- a/docs/i3bar-protocol +++ b/docs/i3bar-protocol @@ -260,6 +260,8 @@ button:: relative_x, relative_y:: Coordinates where the click occurred, with respect to the top left corner of the block +output_x, output_y:: + Coordinates relative to the current output where the click occurred width, height:: Width and height (in px) of the block modifiers:: @@ -273,10 +275,12 @@ modifiers:: "instance": "eth0", "button": 1, "modifiers": ["Shift", "Mod1"], - "x": 1320, + "x": 1925, "y": 1400, "relative_x": 12, "relative_y": 8, + "output_x": 5, + "output_y": 1400, "width": 50, "height": 22 } diff --git a/i3bar/include/child.h b/i3bar/include/child.h index 3afed8194..adc638bed 100644 --- a/i3bar/include/child.h +++ b/i3bar/include/child.h @@ -85,4 +85,4 @@ bool child_want_click_events(void); * Generates a click event, if enabled. * */ -void send_block_clicked(int button, const char *name, const char *instance, int x, int y, int x_rel, int y_rel, int width, int height, int mods); +void send_block_clicked(int button, const char *name, const char *instance, int x, int y, int x_rel, int y_rel, int out_x, int out_y, int width, int height, int mods); diff --git a/i3bar/src/child.c b/i3bar/src/child.c index 871c23052..bece314f2 100644 --- a/i3bar/src/child.c +++ b/i3bar/src/child.c @@ -634,7 +634,7 @@ static void child_click_events_initialize(void) { * Generates a click event, if enabled. * */ -void send_block_clicked(int button, const char *name, const char *instance, int x, int y, int x_rel, int y_rel, int width, int height, int mods) { +void send_block_clicked(int button, const char *name, const char *instance, int x, int y, int x_rel, int y_rel, int out_x, int out_y, int width, int height, int mods) { if (!child.click_events) { return; } @@ -686,6 +686,12 @@ void send_block_clicked(int button, const char *name, const char *instance, int ystr("relative_y"); yajl_gen_integer(gen, y_rel); + ystr("output_x"); + yajl_gen_integer(gen, out_x); + + ystr("output_y"); + yajl_gen_integer(gen, out_y); + ystr("width"); yajl_gen_integer(gen, width); diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c index 5f01c1d8c..ab59209de 100644 --- a/i3bar/src/xcb.c +++ b/i3bar/src/xcb.c @@ -443,7 +443,7 @@ static bool execute_custom_command(xcb_keycode_t input_code, bool event_is_relea return false; } -static void child_handle_button(xcb_button_press_event_t *event, i3_output *output, uint32_t statusline_x) { +static void child_handle_button(xcb_button_press_event_t *event, i3_output *output, uint32_t statusline_x, uint32_t statusline_y) { if (statusline_x > (uint32_t)output->statusline_width) { return; } @@ -472,9 +472,13 @@ static void child_handle_button(xcb_button_press_event_t *event, i3_output *outp /* x of the click event relative to the current block. */ const uint32_t relative_x = statusline_x - last_block_x; if (relative_x <= full_render_width) { + const uint32_t output_x = event->event_x; + const uint32_t output_y = statusline_y + event->event_y; + send_block_clicked(event->detail, block->name, block->instance, event->root_x, event->root_y, relative_x, - event->event_y, full_render_width, bar_height, + event->event_y, output_x, output_y, + full_render_width, bar_height, event->state); return; } @@ -542,9 +546,9 @@ static void handle_button(xcb_button_press_event_t *event) { /* Calculate the horizontal coordinate (x) of the start of the * statusline by subtracting its width and the width of the tray from * the bar width. */ - const int offset = walk->rect.w - walk->statusline_width - - tray_width - logical_px((tray_width > 0) * sb_hoff_px); - if (x >= offset) { + const int offset_x = walk->rect.w - walk->statusline_width - + tray_width - logical_px((tray_width > 0) * sb_hoff_px); + if (x >= offset_x) { /* Click was after the start of the statusline, return to avoid * executing any other actions even if a click event is not * produced eventually. */ @@ -552,8 +556,10 @@ static void handle_button(xcb_button_press_event_t *event) { if (!event_is_release) { /* x of the click event relative to the start of the * statusline. */ - const uint32_t statusline_x = x - offset; - child_handle_button(event, walk, statusline_x); + const uint32_t statusline_x = x - offset_x; + const uint32_t statusline_y = event->root_y - walk->rect.y - event->event_y; + + child_handle_button(event, walk, statusline_x, statusline_y); } return;