diff options
author | Ian Fan <ianfan0@gmail.com> | 2018-09-12 08:28:28 +0100 |
---|---|---|
committer | Ian Fan <ianfan0@gmail.com> | 2018-09-12 08:28:28 +0100 |
commit | 2eaef802061836dd83bbf753174fcb8488b2d8cd (patch) | |
tree | 33fcd285cc70a6cea257b1f3b6d24121d340a270 /swaybar/i3bar.c | |
parent | Merge pull request #2620 from ianyfan/commands (diff) | |
download | sway-2eaef802061836dd83bbf753174fcb8488b2d8cd.tar.gz sway-2eaef802061836dd83bbf753174fcb8488b2d8cd.tar.zst sway-2eaef802061836dd83bbf753174fcb8488b2d8cd.zip |
i3bar: count references to blocks
This prevents blocks from being destroyed before their hotspots are destroyed,
in case it is used for a pending click event that fires between the bar
receiving a new status, which destroys the block, and the bar rendering the new
status, which destroys the hotspot; this problem can be easily produced by
scrolling on a block that immediately causes a new status to be sent, with
multiple outputs
Diffstat (limited to 'swaybar/i3bar.c')
-rw-r--r-- | swaybar/i3bar.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/swaybar/i3bar.c b/swaybar/i3bar.c index ae37eeb9..1345ee9b 100644 --- a/swaybar/i3bar.c +++ b/swaybar/i3bar.c | |||
@@ -8,11 +8,10 @@ | |||
8 | #include "swaybar/config.h" | 8 | #include "swaybar/config.h" |
9 | #include "swaybar/status_line.h" | 9 | #include "swaybar/status_line.h" |
10 | 10 | ||
11 | void i3bar_block_free(struct i3bar_block *block) { | 11 | static void i3bar_block_free(struct i3bar_block *block) { |
12 | if (!block) { | 12 | if (!block) { |
13 | return; | 13 | return; |
14 | } | 14 | } |
15 | wl_list_remove(&block->link); | ||
16 | free(block->full_text); | 15 | free(block->full_text); |
17 | free(block->short_text); | 16 | free(block->short_text); |
18 | free(block->align); | 17 | free(block->align); |
@@ -22,10 +21,17 @@ void i3bar_block_free(struct i3bar_block *block) { | |||
22 | free(block); | 21 | free(block); |
23 | } | 22 | } |
24 | 23 | ||
24 | void i3bar_block_unref(struct i3bar_block *block) { | ||
25 | if (--block->ref_count == 0) { | ||
26 | i3bar_block_free(block); | ||
27 | } | ||
28 | } | ||
29 | |||
25 | static bool i3bar_parse_json(struct status_line *status, const char *text) { | 30 | static bool i3bar_parse_json(struct status_line *status, const char *text) { |
26 | struct i3bar_block *block, *tmp; | 31 | struct i3bar_block *block, *tmp; |
27 | wl_list_for_each_safe(block, tmp, &status->blocks, link) { | 32 | wl_list_for_each_safe(block, tmp, &status->blocks, link) { |
28 | i3bar_block_free(block); | 33 | wl_list_remove(&block->link); |
34 | i3bar_block_unref(block); | ||
29 | } | 35 | } |
30 | json_object *results = json_tokener_parse(text); | 36 | json_object *results = json_tokener_parse(text); |
31 | if (!results) { | 37 | if (!results) { |
@@ -61,6 +67,7 @@ static bool i3bar_parse_json(struct status_line *status, const char *text) { | |||
61 | json_object_object_get_ex(json, "border_right", &border_right); | 67 | json_object_object_get_ex(json, "border_right", &border_right); |
62 | 68 | ||
63 | struct i3bar_block *block = calloc(1, sizeof(struct i3bar_block)); | 69 | struct i3bar_block *block = calloc(1, sizeof(struct i3bar_block)); |
70 | block->ref_count = 1; | ||
64 | block->full_text = full_text ? | 71 | block->full_text = full_text ? |
65 | strdup(json_object_get_string(full_text)) : NULL; | 72 | strdup(json_object_get_string(full_text)) : NULL; |
66 | block->short_text = short_text ? | 73 | block->short_text = short_text ? |