mirror of https://github.com/polybar/polybar.git
fix: Make sure clickable areas are aligned properly
- Avoid odd glyph width's for center-aligned text since it breaks the positioning of clickable area's - Added visual hints for clickable areas for debugging
This commit is contained in:
parent
b4b563dda6
commit
20350e5fe6
|
@ -18,6 +18,8 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "config.hpp"
|
||||||
|
|
||||||
#define LEMONBUDDY_NS \
|
#define LEMONBUDDY_NS \
|
||||||
namespace lemonbuddy { \
|
namespace lemonbuddy { \
|
||||||
inline namespace v2_0_0 {
|
inline namespace v2_0_0 {
|
||||||
|
|
|
@ -425,6 +425,13 @@ class bar : public xpp::event::sink<evt::button_press> {
|
||||||
m_bar.align = alignment::LEFT;
|
m_bar.align = alignment::LEFT;
|
||||||
m_xpos = m_borders[border::LEFT].size;
|
m_xpos = m_borders[border::LEFT].size;
|
||||||
m_attributes = 0;
|
m_attributes = 0;
|
||||||
|
|
||||||
|
#if DEBUG and DRAW_CLICKABLE_AREA_HINTS
|
||||||
|
for (auto&& action : m_actions) {
|
||||||
|
m_connection.destroy_window(action.clickable_area);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
m_actions.clear();
|
m_actions.clear();
|
||||||
|
|
||||||
draw_background();
|
draw_background();
|
||||||
|
@ -465,6 +472,14 @@ class bar : public xpp::event::sink<evt::button_press> {
|
||||||
m_connection.copy_area(
|
m_connection.copy_area(
|
||||||
m_pixmap, m_window, m_gcontexts.at(gc::BR), 0, 0, 0, 0, m_bar.width, m_bar.height);
|
m_pixmap, m_window, m_gcontexts.at(gc::BR), 0, 0, 0, 0, m_bar.width, m_bar.height);
|
||||||
|
|
||||||
|
#if DEBUG and DRAW_CLICKABLE_AREA_HINTS
|
||||||
|
map<alignment, int> hint_num{
|
||||||
|
{ {alignment::LEFT, 0},
|
||||||
|
{alignment::CENTER, 0},
|
||||||
|
{alignment::RIGHT, 0},
|
||||||
|
}};
|
||||||
|
#endif
|
||||||
|
|
||||||
for (auto&& action : m_actions) {
|
for (auto&& action : m_actions) {
|
||||||
if (action.active) {
|
if (action.active) {
|
||||||
m_log.warn("Action block not closed");
|
m_log.warn("Action block not closed");
|
||||||
|
@ -475,6 +490,29 @@ class bar : public xpp::event::sink<evt::button_press> {
|
||||||
m_log.trace("action.mousebtn = %i", static_cast<int>(action.mousebtn));
|
m_log.trace("action.mousebtn = %i", static_cast<int>(action.mousebtn));
|
||||||
m_log.trace("action.start_x = %i", action.start_x);
|
m_log.trace("action.start_x = %i", action.start_x);
|
||||||
m_log.trace("action.end_x = %i", action.end_x);
|
m_log.trace("action.end_x = %i", action.end_x);
|
||||||
|
#if DEBUG and DRAW_CLICKABLE_AREA_HINTS
|
||||||
|
m_log.info("Drawing clickable area hints");
|
||||||
|
|
||||||
|
hint_num[action.align]++;
|
||||||
|
|
||||||
|
auto x = action.start_x;
|
||||||
|
auto y = m_bar.y + hint_num[action.align]++ * DRAW_CLICKABLE_AREA_HINTS_OFFSET_Y;
|
||||||
|
auto w = action.end_x - action.start_x - 2;
|
||||||
|
auto h = m_bar.height - 2;
|
||||||
|
|
||||||
|
const uint32_t mask = XCB_CW_BORDER_PIXEL | XCB_CW_OVERRIDE_REDIRECT;
|
||||||
|
const uint32_t border_color = hint_num[action.align] % 2 ? 0xff0000 : 0x00ff00;
|
||||||
|
const uint32_t values[2]{border_color, true};
|
||||||
|
|
||||||
|
auto scr = m_connection.screen();
|
||||||
|
|
||||||
|
action.clickable_area = m_connection.generate_id();
|
||||||
|
m_connection.create_window_checked(scr->root_depth, action.clickable_area, scr->root, x, y,
|
||||||
|
w, h, 1, XCB_WINDOW_CLASS_INPUT_OUTPUT, scr->root_visual, mask, values);
|
||||||
|
m_connection.map_window_checked(action.clickable_area);
|
||||||
|
#else
|
||||||
|
m_log.trace("bar: Visual hints for clickable area's disabled");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} //}}}
|
} //}}}
|
||||||
|
@ -600,8 +638,7 @@ class bar : public xpp::event::sink<evt::button_press> {
|
||||||
action.align = m_bar.align;
|
action.align = m_bar.align;
|
||||||
action.mousebtn = btn;
|
action.mousebtn = btn;
|
||||||
action.start_x = m_xpos;
|
action.start_x = m_xpos;
|
||||||
action.command = cmd;
|
action.command = string_util::replace_all(cmd, ":", "\\:");
|
||||||
action.command = string_util::replace_all(action.command, ":", "\\:");
|
|
||||||
m_actions.emplace_back(action);
|
m_actions.emplace_back(action);
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
|
@ -610,29 +647,33 @@ class bar : public xpp::event::sink<evt::button_press> {
|
||||||
*/
|
*/
|
||||||
void on_action_block_close(mousebtn btn) { //{{{
|
void on_action_block_close(mousebtn btn) { //{{{
|
||||||
m_log.trace("bar: action_block_close(%i)", static_cast<int>(btn));
|
m_log.trace("bar: action_block_close(%i)", static_cast<int>(btn));
|
||||||
auto n_actions = m_actions.size();
|
|
||||||
while (n_actions--) {
|
for (auto i = m_actions.size(); i > 0; i--) {
|
||||||
action_block& action = m_actions[n_actions];
|
auto& action = m_actions[i - 1];
|
||||||
|
|
||||||
if (!action.active || action.mousebtn != btn)
|
if (!action.active || action.mousebtn != btn)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
action.end_x = m_xpos;
|
|
||||||
action.active = false;
|
action.active = false;
|
||||||
|
|
||||||
if (action.align == alignment::CENTER) {
|
if (action.align == alignment::LEFT) {
|
||||||
auto width = action.end_x - action.start_x;
|
action.end_x = m_xpos;
|
||||||
auto center = m_bar.width / 2;
|
} else if (action.align == alignment::CENTER) {
|
||||||
auto x1 = center - width / 2;
|
int base_x = m_bar.width;
|
||||||
auto x2 = center + width / 2;
|
base_x -= m_borders[border::RIGHT].size;
|
||||||
action.start_x = x1;
|
base_x /= 2;
|
||||||
action.end_x = x2;
|
base_x += m_borders[border::LEFT].size;
|
||||||
|
|
||||||
|
int clickable_width = m_xpos - action.start_x;
|
||||||
|
action.start_x = base_x - clickable_width / 2 + action.start_x / 2;
|
||||||
|
action.end_x = action.start_x + clickable_width;
|
||||||
} else if (action.align == alignment::RIGHT) {
|
} else if (action.align == alignment::RIGHT) {
|
||||||
auto x1 = m_bar.width - action.end_x;
|
int base_x = m_bar.width - m_borders[border::RIGHT].size;
|
||||||
auto x2 = m_bar.width - action.start_x;
|
action.start_x = base_x - m_xpos + action.start_x;
|
||||||
action.start_x = x1;
|
action.end_x = base_x;
|
||||||
action.end_x = x2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
|
@ -759,36 +800,33 @@ class bar : public xpp::event::sink<evt::button_press> {
|
||||||
* Shift the contents of the pixmap horizontally
|
* Shift the contents of the pixmap horizontally
|
||||||
*/
|
*/
|
||||||
int draw_shift(int x, int chr_width) { //{{{
|
int draw_shift(int x, int chr_width) { //{{{
|
||||||
int delta = 0;
|
int delta = chr_width;
|
||||||
|
|
||||||
switch (m_bar.align) {
|
if (m_bar.align == alignment::CENTER) {
|
||||||
case alignment::CENTER:
|
int base_x = m_bar.width;
|
||||||
m_connection.copy_area(m_pixmap, m_pixmap, m_gcontexts.at(gc::FG), m_bar.width / 2 - x / 2,
|
base_x -= m_borders[border::RIGHT].size;
|
||||||
0, m_bar.width / 2 - (x + chr_width) / 2, 0, x, m_bar.height);
|
base_x /= 2;
|
||||||
x = m_bar.width / 2 - (x + chr_width) / 2 + x;
|
base_x += m_borders[border::LEFT].size;
|
||||||
delta = chr_width / 2;
|
m_connection.copy_area(m_pixmap, m_pixmap, m_gcontexts.at(gc::FG), base_x - x / 2, 0,
|
||||||
break;
|
base_x - (x + chr_width) / 2, 0, x, m_bar.height);
|
||||||
case alignment::RIGHT:
|
x = base_x - (x + chr_width) / 2 + x;
|
||||||
m_connection.copy_area(m_pixmap, m_pixmap, m_gcontexts.at(gc::FG), m_bar.width - x, 0,
|
delta /= 2;
|
||||||
m_bar.width - x - chr_width, 0, x, m_bar.height);
|
} else if (m_bar.align == alignment::RIGHT) {
|
||||||
x = m_bar.width - chr_width - m_borders[border::RIGHT].size;
|
m_connection.copy_area(m_pixmap, m_pixmap, m_gcontexts.at(gc::FG), m_bar.width - x, 0,
|
||||||
delta = chr_width;
|
m_bar.width - x - chr_width, 0, x, m_bar.height);
|
||||||
break;
|
x = m_bar.width - chr_width - m_borders[border::RIGHT].size;
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
draw_util::fill(m_connection, m_pixmap, m_gcontexts.at(gc::BG), x, 0, chr_width, m_bar.height);
|
draw_util::fill(m_connection, m_pixmap, m_gcontexts.at(gc::BG), x, 0, chr_width, m_bar.height);
|
||||||
|
|
||||||
if (delta != 0 && !m_actions.empty()) {
|
// Translate pos of clickable areas
|
||||||
|
if (m_bar.align != alignment::LEFT)
|
||||||
for (auto&& action : m_actions) {
|
for (auto&& action : m_actions) {
|
||||||
if (action.active || action.align != m_bar.align)
|
if (action.active || action.align != m_bar.align)
|
||||||
continue;
|
continue;
|
||||||
action.start_x -= delta;
|
action.start_x -= delta;
|
||||||
action.end_x -= delta;
|
action.end_x -= delta;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
} //}}}
|
} //}}}
|
||||||
|
@ -801,7 +839,7 @@ class bar : public xpp::event::sink<evt::button_press> {
|
||||||
auto& font = m_fontmanager->match_char(character);
|
auto& font = m_fontmanager->match_char(character);
|
||||||
|
|
||||||
if (!font) {
|
if (!font) {
|
||||||
// m_log.warn("No suitable font found");
|
m_log.warn("No suitable font found for character at index %i", character);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -813,6 +851,11 @@ class bar : public xpp::event::sink<evt::button_press> {
|
||||||
// TODO: cache
|
// TODO: cache
|
||||||
auto chr_width = m_fontmanager->char_width(font, character);
|
auto chr_width = m_fontmanager->char_width(font, character);
|
||||||
|
|
||||||
|
// Avoid odd glyph width's for center-aligned text
|
||||||
|
// since it breaks the positioning of clickable area's
|
||||||
|
if (m_bar.align == alignment::CENTER && chr_width % 2)
|
||||||
|
chr_width++;
|
||||||
|
|
||||||
auto x = draw_shift(m_xpos, chr_width);
|
auto x = draw_shift(m_xpos, chr_width);
|
||||||
auto y = m_bar.vertical_mid + font->height / 2 - font->descent + font->offset_y;
|
auto y = m_bar.vertical_mid + font->height / 2 - font->descent + font->offset_y;
|
||||||
|
|
||||||
|
|
|
@ -96,6 +96,9 @@ struct action_block {
|
||||||
int16_t end_x{0};
|
int16_t end_x{0};
|
||||||
alignment align;
|
alignment align;
|
||||||
bool active{true};
|
bool active{true};
|
||||||
|
#if DEBUG and DRAW_CLICKABLE_AREA_HINTS
|
||||||
|
xcb_window_t clickable_area;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
LEMONBUDDY_NS_END
|
LEMONBUDDY_NS_END
|
||||||
|
|
|
@ -16,6 +16,14 @@
|
||||||
#cmakedefine DISABLE_TRAY
|
#cmakedefine DISABLE_TRAY
|
||||||
#cmakedefine DISABLE_DRAW
|
#cmakedefine DISABLE_DRAW
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#cmakedefine01 DRAW_CLICKABLE_AREA_HINTS
|
||||||
|
#cmakedefine DRAW_CLICKABLE_AREA_HINTS_OFFSET_Y @DRAW_CLICKABLE_AREA_HINTS_OFFSET_Y@
|
||||||
|
#ifndef DRAW_CLICKABLE_AREA_HINTS_OFFSET_Y
|
||||||
|
#define DRAW_CLICKABLE_AREA_HINTS_OFFSET_Y 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#define BUILDER_SPACE_TOKEN "%__"
|
#define BUILDER_SPACE_TOKEN "%__"
|
||||||
#define ALSA_SOUNDCARD "@SETTING_ALSA_SOUNDCARD@"
|
#define ALSA_SOUNDCARD "@SETTING_ALSA_SOUNDCARD@"
|
||||||
#define CONNECTION_TEST_IP "@SETTING_CONNECTION_TEST_IP@"
|
#define CONNECTION_TEST_IP "@SETTING_CONNECTION_TEST_IP@"
|
||||||
|
|
Loading…
Reference in New Issue