diff options
Diffstat (limited to 'swaybar')
-rw-r--r-- | swaybar/bar.c | 10 | ||||
-rw-r--r-- | swaybar/config.c | 4 | ||||
-rw-r--r-- | swaybar/i3bar.c | 7 | ||||
-rw-r--r-- | swaybar/input.c | 25 | ||||
-rw-r--r-- | swaybar/ipc.c | 9 | ||||
-rw-r--r-- | swaybar/meson.build | 4 | ||||
-rw-r--r-- | swaybar/render.c | 56 | ||||
-rw-r--r-- | swaybar/tray/item.c | 12 |
8 files changed, 76 insertions, 51 deletions
diff --git a/swaybar/bar.c b/swaybar/bar.c index 6ffdc9b4..5e4ebd97 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -51,9 +51,6 @@ static void swaybar_output_free(struct swaybar_output *output) { if (output->surface != NULL) { wl_surface_destroy(output->surface); } - if (output->input_region != NULL) { - wl_region_destroy(output->input_region); - } wl_output_destroy(output->output); destroy_buffer(&output->buffers[0]); destroy_buffer(&output->buffers[1]); @@ -113,10 +110,9 @@ static void add_layer_surface(struct swaybar_output *output) { if (overlay) { // Empty input region - output->input_region = wl_compositor_create_region(bar->compositor); - assert(output->input_region); - - wl_surface_set_input_region(output->surface, output->input_region); + struct wl_region *region = wl_compositor_create_region(bar->compositor); + wl_surface_set_input_region(output->surface, region); + wl_region_destroy(region); } zwlr_layer_surface_v1_set_anchor(output->layer_surface, config->position); diff --git a/swaybar/config.c b/swaybar/config.c index abedaec0..5e828773 100644 --- a/swaybar/config.c +++ b/swaybar/config.c @@ -26,7 +26,7 @@ struct swaybar_config *init_config(void) { config->status_command = NULL; config->pango_markup = false; config->position = parse_position("bottom"); - config->font = strdup("monospace 10"); + config->font_description = pango_font_description_from_string("monospace 10"); config->mode = strdup("dock"); config->hidden_state = strdup("hide"); config->sep_symbol = NULL; @@ -105,7 +105,7 @@ void free_tray_binding(struct tray_binding *binding) { void free_config(struct swaybar_config *config) { free(config->status_command); - free(config->font); + pango_font_description_free(config->font_description); free(config->mode); free(config->hidden_state); free(config->sep_symbol); diff --git a/swaybar/i3bar.c b/swaybar/i3bar.c index 6d00befb..ccd5a076 100644 --- a/swaybar/i3bar.c +++ b/swaybar/i3bar.c @@ -269,11 +269,16 @@ bool i3bar_handle_readable(struct status_line *status) { enum hotspot_event_handling i3bar_block_send_click(struct status_line *status, struct i3bar_block *block, double x, double y, double rx, double ry, - double w, double h, int scale, uint32_t button) { + double w, double h, int scale, uint32_t button, bool released) { sway_log(SWAY_DEBUG, "block %s clicked", block->name); if (!block->name || !status->click_events) { return HOTSPOT_PROCESS; } + if (released) { + // Since we handle the pressed event, also handle the released event + // to block it from falling through to a binding in the bar + return HOTSPOT_IGNORE; + } struct json_object *event_json = json_object_new_object(); json_object_object_add(event_json, "name", diff --git a/swaybar/input.c b/swaybar/input.c index c8c8f0d4..8eccf542 100644 --- a/swaybar/input.c +++ b/swaybar/input.c @@ -141,14 +141,15 @@ static bool check_bindings(struct swaybar *bar, uint32_t button, } static bool process_hotspots(struct swaybar_output *output, - double x, double y, uint32_t button) { + double x, double y, uint32_t button, uint32_t state) { + bool released = state == WL_POINTER_BUTTON_STATE_RELEASED; struct swaybar_hotspot *hotspot; wl_list_for_each(hotspot, &output->hotspots, link) { if (x >= hotspot->x && y >= hotspot->y && x < hotspot->x + hotspot->width && y < hotspot->y + hotspot->height) { if (HOTSPOT_IGNORE == hotspot->callback(output, hotspot, x, y, - button, hotspot->data)) { + button, released, hotspot->data)) { return true; } } @@ -166,14 +167,11 @@ static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, return; } - if (check_bindings(seat->bar, button, state)) { + if (process_hotspots(output, pointer->x, pointer->y, button, state)) { return; } - if (state != WL_POINTER_BUTTON_STATE_PRESSED) { - return; - } - process_hotspots(output, pointer->x, pointer->y, button); + check_bindings(seat->bar, button, state); } static void workspace_next(struct swaybar *bar, struct swaybar_output *output, @@ -222,15 +220,15 @@ static void workspace_next(struct swaybar *bar, struct swaybar_output *output, static void process_discrete_scroll(struct swaybar_seat *seat, struct swaybar_output *output, struct swaybar_pointer *pointer, uint32_t axis, wl_fixed_t value) { - // If there is a button press binding, execute it, skip default behavior, - // and check button release bindings uint32_t button = wl_axis_to_button(axis, value); - if (check_bindings(seat->bar, button, WL_POINTER_BUTTON_STATE_PRESSED)) { - check_bindings(seat->bar, button, WL_POINTER_BUTTON_STATE_RELEASED); + if (process_hotspots(output, pointer->x, pointer->y, button, WL_POINTER_BUTTON_STATE_PRESSED)) { + // (Currently hotspots don't do anything on release events, so no need to emit one) return; } - if (process_hotspots(output, pointer->x, pointer->y, button)) { + // If there is a button press binding, execute it, and check button release bindings + if (check_bindings(seat->bar, button, WL_POINTER_BUTTON_STATE_PRESSED)) { + check_bindings(seat->bar, button, WL_POINTER_BUTTON_STATE_RELEASED); return; } @@ -403,7 +401,8 @@ static void wl_touch_up(void *data, struct wl_touch *wl_touch, } if (time - slot->time < 500) { // Tap, treat it like a pointer click - process_hotspots(slot->output, slot->x, slot->y, BTN_LEFT); + process_hotspots(slot->output, slot->x, slot->y, BTN_LEFT, WL_POINTER_BUTTON_STATE_PRESSED); + // (Currently hotspots don't do anything on release events, so no need to emit one) } slot->output = NULL; } diff --git a/swaybar/ipc.c b/swaybar/ipc.c index 2cb235bf..9d81a9fb 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c @@ -147,8 +147,10 @@ static bool ipc_parse_config( json_object *font = json_object_object_get(bar_config, "font"); if (font) { - free(config->font); - config->font = parse_font(json_object_get_string(font)); + pango_font_description_free(config->font_description); + char *font_value = parse_font(json_object_get_string(font)); + config->font_description = pango_font_description_from_string(font_value); + free(font_value); } json_object *gaps = json_object_object_get(bar_config, "gaps"); @@ -485,8 +487,7 @@ static bool handle_barconfig_update(struct swaybar *bar, const char *payload, destroy_layer_surface(output); wl_list_remove(&output->link); wl_list_insert(&bar->unused_outputs, &output->link); - } else if (!oldcfg->font || !newcfg->font || - strcmp(oldcfg->font, newcfg->font) != 0) { + } else if (!pango_font_description_equal(oldcfg->font_description, newcfg->font_description)) { output->height = 0; // force update height } } diff --git a/swaybar/meson.build b/swaybar/meson.build index 9feb3cd2..e5f1811e 100644 --- a/swaybar/meson.build +++ b/swaybar/meson.build @@ -8,7 +8,6 @@ tray_files = have_tray ? [ swaybar_deps = [ cairo, - client_protos, gdk_pixbuf, jsonc, math, @@ -32,7 +31,8 @@ executable( 'main.c', 'render.c', 'status_line.c', - tray_files + tray_files, + wl_protos_src, ], include_directories: [sway_inc], dependencies: swaybar_deps, diff --git a/swaybar/render.c b/swaybar/render.c index dcde6b9e..95f6e5be 100644 --- a/swaybar/render.c +++ b/swaybar/render.c @@ -62,7 +62,7 @@ static uint32_t render_status_line_error(struct render_context *ctx, double *x) int margin = 3; double ws_vertical_padding = output->bar->config->status_padding; - char *font = output->bar->config->font; + PangoFontDescription *font = output->bar->config->font_description; int text_width, text_height; get_text_size(cairo, font, &text_width, &text_height, NULL, 1, false, "%s", error); @@ -97,7 +97,7 @@ static uint32_t render_status_line_text(struct render_context *ctx, double *x) { cairo_set_source_u32(cairo, fontcolor); int text_width, text_height; - get_text_size(cairo, config->font, &text_width, &text_height, NULL, + get_text_size(cairo, config->font_description, &text_width, &text_height, NULL, 1, config->pango_markup, "%s", text); double ws_vertical_padding = config->status_padding; @@ -115,7 +115,7 @@ static uint32_t render_status_line_text(struct render_context *ctx, double *x) { double text_y = height / 2.0 - text_height / 2.0; cairo_move_to(cairo, *x, (int)floor(text_y)); choose_text_aa_mode(ctx, fontcolor); - render_text(cairo, config->font, 1, config->pango_markup, "%s", text); + render_text(cairo, config->font_description, 1, config->pango_markup, "%s", text); *x -= margin; return output->height; } @@ -160,7 +160,7 @@ static void render_sharp_line(cairo_t *cairo, uint32_t color, static enum hotspot_event_handling block_hotspot_callback( struct swaybar_output *output, struct swaybar_hotspot *hotspot, - double x, double y, uint32_t button, void *data) { + double x, double y, uint32_t button, bool released, void *data) { struct i3bar_block *block = data; struct status_line *status = output->bar->status; return i3bar_block_send_click(status, block, x, y, @@ -168,7 +168,7 @@ static enum hotspot_event_handling block_hotspot_callback( y - (double)hotspot->y, (double)hotspot->width, (double)hotspot->height, - output->scale, button); + output->scale, button, released); } static void i3bar_block_unref_callback(void *data) { @@ -190,7 +190,7 @@ static uint32_t render_status_block(struct render_context *ctx, struct swaybar_output *output = ctx->output; struct swaybar_config *config = output->bar->config; int text_width, text_height; - get_text_size(cairo, config->font, &text_width, &text_height, NULL, 1, + get_text_size(cairo, config->font_description, &text_width, &text_height, NULL, 1, block->markup, "%s", text); int margin = 3; @@ -199,7 +199,7 @@ static uint32_t render_status_block(struct render_context *ctx, int width = text_width; if (block->min_width_str) { int w; - get_text_size(cairo, config->font, &w, NULL, NULL, 1, block->markup, + get_text_size(cairo, config->font_description, &w, NULL, NULL, 1, block->markup, "%s", block->min_width_str); block->min_width = w; } @@ -229,7 +229,7 @@ static uint32_t render_status_block(struct render_context *ctx, int sep_block_width = block->separator_block_width; if (!edge) { if (config->sep_symbol) { - get_text_size(cairo, config->font, &sep_width, &sep_height, NULL, + get_text_size(cairo, config->font_description, &sep_width, &sep_height, NULL, 1, false, "%s", config->sep_symbol); uint32_t _ideal_height = sep_height + ws_vertical_padding * 2; uint32_t _ideal_surface_height = _ideal_height; @@ -307,7 +307,7 @@ static uint32_t render_status_block(struct render_context *ctx, color = block->urgent ? config->colors.urgent_workspace.text : color; cairo_set_source_u32(cairo, color); choose_text_aa_mode(ctx, color); - render_text(cairo, config->font, 1, block->markup, "%s", text); + render_text(cairo, config->font_description, 1, block->markup, "%s", text); x_pos += width; if (block->border_set || block->urgent) { @@ -331,7 +331,7 @@ static uint32_t render_status_block(struct render_context *ctx, double sep_y = height / 2.0 - sep_height / 2.0; cairo_move_to(cairo, offset, (int)floor(sep_y)); choose_text_aa_mode(ctx, color); - render_text(cairo, config->font, 1, false, + render_text(cairo, config->font_description, 1, false, "%s", config->sep_symbol); } else { cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); @@ -354,7 +354,7 @@ static void predict_status_block_pos(cairo_t *cairo, struct swaybar_config *config = output->bar->config; int text_width, text_height; - get_text_size(cairo, config->font, &text_width, &text_height, NULL, 1, + get_text_size(cairo, config->font_description, &text_width, &text_height, NULL, 1, block->markup, "%s", block->full_text); int margin = 3; @@ -364,7 +364,7 @@ static void predict_status_block_pos(cairo_t *cairo, if (block->min_width_str) { int w; - get_text_size(cairo, config->font, &w, NULL, NULL, + get_text_size(cairo, config->font_description, &w, NULL, NULL, 1, block->markup, "%s", block->min_width_str); block->min_width = w; } @@ -391,7 +391,7 @@ static void predict_status_block_pos(cairo_t *cairo, int sep_block_width = block->separator_block_width; if (!edge) { if (config->sep_symbol) { - get_text_size(cairo, config->font, &sep_width, &sep_height, NULL, + get_text_size(cairo, config->font_description, &sep_width, &sep_height, NULL, 1, false, "%s", config->sep_symbol); uint32_t _ideal_height = sep_height + ws_vertical_padding * 2; uint32_t _ideal_surface_height = _ideal_height; @@ -426,7 +426,7 @@ static uint32_t predict_workspace_button_length(cairo_t *cairo, struct swaybar_config *config = output->bar->config; int text_width, text_height; - get_text_size(cairo, config->font, &text_width, &text_height, NULL, 1, + get_text_size(cairo, config->font_description, &text_width, &text_height, NULL, 1, config->pango_markup, "%s", ws->label); int ws_vertical_padding = WS_VERTICAL_PADDING; @@ -474,7 +474,7 @@ static uint32_t predict_binding_mode_indicator_length(cairo_t *cairo, } int text_width, text_height; - get_text_size(cairo, config->font, &text_width, &text_height, NULL, + get_text_size(cairo, config->font_description, &text_width, &text_height, NULL, 1, output->bar->mode_pango_markup, "%s", mode); @@ -551,7 +551,7 @@ static uint32_t render_binding_mode_indicator(struct render_context *ctx, cairo_t *cairo = ctx->cairo; struct swaybar_config *config = output->bar->config; int text_width, text_height; - get_text_size(cairo, config->font, &text_width, &text_height, NULL, + get_text_size(cairo, config->font_description, &text_width, &text_height, NULL, 1, output->bar->mode_pango_markup, "%s", mode); @@ -592,17 +592,22 @@ static uint32_t render_binding_mode_indicator(struct render_context *ctx, cairo_set_source_u32(cairo, config->colors.binding_mode.text); cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y)); choose_text_aa_mode(ctx, config->colors.binding_mode.text); - render_text(cairo, config->font, 1, output->bar->mode_pango_markup, + render_text(cairo, config->font_description, 1, output->bar->mode_pango_markup, "%s", mode); return output->height; } static enum hotspot_event_handling workspace_hotspot_callback( struct swaybar_output *output, struct swaybar_hotspot *hotspot, - double x, double y, uint32_t button, void *data) { + double x, double y, uint32_t button, bool released, void *data) { if (button != BTN_LEFT) { return HOTSPOT_PROCESS; } + if (released) { + // Since we handle the pressed event, also handle the released event + // to block it from falling through to a binding in the bar + return HOTSPOT_IGNORE; + } ipc_send_workspace_command(output->bar, (const char *)data); return HOTSPOT_IGNORE; } @@ -626,7 +631,7 @@ static uint32_t render_workspace_button(struct render_context *ctx, cairo_t *cairo = ctx->cairo; int text_width, text_height; - get_text_size(cairo, config->font, &text_width, &text_height, NULL, + get_text_size(cairo, config->font_description, &text_width, &text_height, NULL, 1, config->pango_markup, "%s", ws->label); int ws_vertical_padding = WS_VERTICAL_PADDING; @@ -666,7 +671,7 @@ static uint32_t render_workspace_button(struct render_context *ctx, cairo_set_source_u32(cairo, box_colors.text); cairo_move_to(cairo, *x + width / 2 - text_width / 2, (int)floor(text_y)); choose_text_aa_mode(ctx, box_colors.text); - render_text(cairo, config->font, 1, config->pango_markup, + render_text(cairo, config->font_description, 1, config->pango_markup, "%s", ws->label); struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); @@ -699,7 +704,7 @@ static uint32_t render_to_cairo(struct render_context *ctx) { cairo_paint(cairo); int th; - get_text_size(cairo, config->font, NULL, &th, NULL, 1, false, ""); + get_text_size(cairo, config->font_description, NULL, &th, NULL, 1, false, ""); uint32_t max_height = (th + WS_VERTICAL_PADDING * 4); /* * Each render_* function takes the actual height of the bar, and returns @@ -831,6 +836,15 @@ void render_frame(struct swaybar_output *output) { wl_surface_damage(output->surface, 0, 0, output->width, output->height); + uint32_t bg_alpha = ctx.background_color & 0xFF; + if (bg_alpha == 0xFF) { + struct wl_region *region = + wl_compositor_create_region(output->bar->compositor); + wl_region_add(region, 0, 0, INT32_MAX, INT32_MAX); + wl_surface_set_opaque_region(output->surface, region); + wl_region_destroy(region); + } + struct wl_callback *frame_callback = wl_surface_frame(output->surface); wl_callback_add_listener(frame_callback, &output_frame_listener, output); output->frame_scheduled = true; diff --git a/swaybar/tray/item.c b/swaybar/tray/item.c index 6d4b17bf..1f18b8bb 100644 --- a/swaybar/tray/item.c +++ b/swaybar/tray/item.c @@ -385,13 +385,18 @@ static int cmp_sni_id(const void *item, const void *cmp_to) { static enum hotspot_event_handling icon_hotspot_callback( struct swaybar_output *output, struct swaybar_hotspot *hotspot, - double x, double y, uint32_t button, void *data) { + double x, double y, uint32_t button, bool released, void *data) { sway_log(SWAY_DEBUG, "Clicked on %s", (char *)data); struct swaybar_tray *tray = output->bar->tray; int idx = list_seq_find(tray->items, cmp_sni_id, data); if (idx != -1) { + if (released) { + // Since we handle the pressed event, also handle the released event + // to block it from falling through to a binding in the bar + return HOTSPOT_IGNORE; + } struct swaybar_sni *sni = tray->items->items[idx]; // guess global position since wayland doesn't expose it struct swaybar_config *config = tray->bar->config; @@ -466,6 +471,11 @@ uint32_t render_sni(cairo_t *cairo, struct swaybar_output *output, double *x, sni->target_size = target_size; } + // Passive + if (sni->status && sni->status[0] == 'P') { + return 0; + } + int icon_size; cairo_surface_t *icon; if (sni->icon) { |