Store all action info in action_context
The renderer is responsible for setting the start and end positions while dispatch does the rest
This commit is contained in:
parent
f359540b5d
commit
464bedb33c
@ -36,10 +36,10 @@ class renderer : public renderer_interface,
|
|||||||
public signal_receiver<SIGN_PRIORITY_RENDERER, signals::ui::request_snapshot> {
|
public signal_receiver<SIGN_PRIORITY_RENDERER, signals::ui::request_snapshot> {
|
||||||
public:
|
public:
|
||||||
using make_type = unique_ptr<renderer>;
|
using make_type = unique_ptr<renderer>;
|
||||||
static make_type make(const bar_settings& bar);
|
static make_type make(const bar_settings& bar, tags::action_context& action_ctxt);
|
||||||
|
|
||||||
explicit renderer(connection& conn, signal_emitter& sig, const config&, const logger& logger, const bar_settings& bar,
|
explicit renderer(connection& conn, signal_emitter& sig, const config&, const logger& logger, const bar_settings& bar,
|
||||||
background_manager& background_manager);
|
background_manager& background_manager, tags::action_context& action_ctxt);
|
||||||
~renderer();
|
~renderer();
|
||||||
|
|
||||||
xcb_window_t window() const;
|
xcb_window_t window() const;
|
||||||
@ -56,9 +56,6 @@ class renderer : public renderer_interface,
|
|||||||
void action_open(const tags::context& ctxt, mousebtn btn, tags::action_t id) override;
|
void action_open(const tags::context& ctxt, mousebtn btn, tags::action_t id) override;
|
||||||
void action_close(const tags::context& ctxt, tags::action_t id) override;
|
void action_close(const tags::context& ctxt, tags::action_t id) override;
|
||||||
|
|
||||||
std::map<mousebtn, tags::action_t> get_actions(int x) override;
|
|
||||||
tags::action_t get_action(mousebtn btn, int x) override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void fill_background();
|
void fill_background();
|
||||||
void fill_overline(rgba color, double x, double w);
|
void fill_overline(rgba color, double x, double w);
|
||||||
@ -114,7 +111,6 @@ class renderer : public renderer_interface,
|
|||||||
bool m_pseudo_transparency{false};
|
bool m_pseudo_transparency{false};
|
||||||
|
|
||||||
alignment m_align;
|
alignment m_align;
|
||||||
std::unordered_map<tags::action_t, action_block> m_actions;
|
|
||||||
|
|
||||||
bool m_fixedcenter;
|
bool m_fixedcenter;
|
||||||
string m_snapshot_dst;
|
string m_snapshot_dst;
|
||||||
|
@ -7,6 +7,8 @@ POLYBAR_NS
|
|||||||
|
|
||||||
class renderer_interface {
|
class renderer_interface {
|
||||||
public:
|
public:
|
||||||
|
renderer_interface(tags::action_context& action_ctxt) : m_action_ctxt(action_ctxt){};
|
||||||
|
|
||||||
virtual void render_offset(const tags::context& ctxt, int pixels) = 0;
|
virtual void render_offset(const tags::context& ctxt, int pixels) = 0;
|
||||||
virtual void render_text(const tags::context& ctxt, const string&& str) = 0;
|
virtual void render_text(const tags::context& ctxt, const string&& str) = 0;
|
||||||
virtual void change_alignment(const tags::context& ctxt) = 0;
|
virtual void change_alignment(const tags::context& ctxt) = 0;
|
||||||
@ -14,8 +16,14 @@ class renderer_interface {
|
|||||||
virtual void action_open(const tags::context& ctxt, mousebtn btn, tags::action_t id) = 0;
|
virtual void action_open(const tags::context& ctxt, mousebtn btn, tags::action_t id) = 0;
|
||||||
virtual void action_close(const tags::context& ctxt, tags::action_t id) = 0;
|
virtual void action_close(const tags::context& ctxt, tags::action_t id) = 0;
|
||||||
|
|
||||||
virtual std::map<mousebtn, tags::action_t> get_actions(int x) = 0;
|
protected:
|
||||||
virtual tags::action_t get_action(mousebtn btn, int x) = 0;
|
/**
|
||||||
|
* Stores information about actions in the current action cycle.
|
||||||
|
*
|
||||||
|
* The renderer is only responsible for updating the start and end positions
|
||||||
|
* of each action block.
|
||||||
|
*/
|
||||||
|
tags::action_context& m_action_ctxt;
|
||||||
};
|
};
|
||||||
|
|
||||||
POLYBAR_NS_END
|
POLYBAR_NS_END
|
||||||
|
@ -109,21 +109,6 @@ struct action {
|
|||||||
string command{};
|
string command{};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct action_block {
|
|
||||||
mousebtn button{mousebtn::NONE};
|
|
||||||
alignment align{alignment::NONE};
|
|
||||||
double start_x{0.0};
|
|
||||||
double end_x{0.0};
|
|
||||||
|
|
||||||
unsigned int width() const {
|
|
||||||
return static_cast<unsigned int>(end_x - start_x + 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool test(int point) const {
|
|
||||||
return static_cast<int>(start_x) <= point && static_cast<int>(end_x) > point;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bar_settings {
|
struct bar_settings {
|
||||||
explicit bar_settings() = default;
|
explicit bar_settings() = default;
|
||||||
bar_settings(const bar_settings& other) = default;
|
bar_settings(const bar_settings& other) = default;
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
#include "components/types.hpp"
|
#include "components/types.hpp"
|
||||||
#include "tags/types.hpp"
|
#include "tags/types.hpp"
|
||||||
@ -96,6 +98,26 @@ namespace tags {
|
|||||||
|
|
||||||
static constexpr action_t NO_ACTION = -1;
|
static constexpr action_t NO_ACTION = -1;
|
||||||
|
|
||||||
|
struct action_block {
|
||||||
|
action_block(const string&& cmd, mousebtn button, alignment align, bool is_open)
|
||||||
|
: cmd(std::move(cmd)), button(button), align(align), is_open(is_open){};
|
||||||
|
|
||||||
|
string cmd;
|
||||||
|
double start_x{0};
|
||||||
|
double end_x{0};
|
||||||
|
mousebtn button;
|
||||||
|
alignment align;
|
||||||
|
bool is_open;
|
||||||
|
|
||||||
|
unsigned int width() const {
|
||||||
|
return static_cast<unsigned int>(end_x - start_x + 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool test(int point) const {
|
||||||
|
return static_cast<int>(start_x) <= point && static_cast<int>(end_x) > point;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class action_context {
|
class action_context {
|
||||||
public:
|
public:
|
||||||
void reset();
|
void reset();
|
||||||
@ -103,22 +125,20 @@ namespace tags {
|
|||||||
action_t action_open(mousebtn btn, const string&& cmd, alignment align);
|
action_t action_open(mousebtn btn, const string&& cmd, alignment align);
|
||||||
std::pair<action_t, mousebtn> action_close(mousebtn btn, alignment align);
|
std::pair<action_t, mousebtn> action_close(mousebtn btn, alignment align);
|
||||||
|
|
||||||
|
void set_start(action_t id, double x);
|
||||||
|
void set_end(action_t id, double x);
|
||||||
|
|
||||||
|
std::map<mousebtn, tags::action_t> get_actions(int x) const;
|
||||||
|
action_t has_action(mousebtn btn, int x) const;
|
||||||
|
|
||||||
string get_action(action_t id) const;
|
string get_action(action_t id) const;
|
||||||
bool has_double_click() const;
|
bool has_double_click() const;
|
||||||
|
|
||||||
size_t num_actions() const;
|
size_t num_actions() const;
|
||||||
|
|
||||||
|
std::vector<action_block>& get_blocks();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct action_block {
|
|
||||||
action_block(const string&& cmd, mousebtn button, alignment align, bool is_open)
|
|
||||||
: cmd(std::move(cmd)), button(button), align(align), is_open(is_open){};
|
|
||||||
|
|
||||||
string cmd;
|
|
||||||
mousebtn button;
|
|
||||||
alignment align;
|
|
||||||
bool is_open;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores all currently known action blocks.
|
* Stores all currently known action blocks.
|
||||||
*
|
*
|
||||||
|
@ -649,10 +649,9 @@ void bar::handle(const evt::motion_notify& evt) {
|
|||||||
// scroll cursor is less important than click cursor, so we shouldn't return until we are sure there is no click
|
// scroll cursor is less important than click cursor, so we shouldn't return until we are sure there is no click
|
||||||
// action
|
// action
|
||||||
bool found_scroll = false;
|
bool found_scroll = false;
|
||||||
const auto& actions = m_renderer->get_actions(m_motion_pos);
|
|
||||||
const auto has_action = [&](const vector<mousebtn>& buttons) -> bool {
|
const auto has_action = [&](const vector<mousebtn>& buttons) -> bool {
|
||||||
for (auto btn : buttons) {
|
for (auto btn : buttons) {
|
||||||
if (actions.at(btn) != tags::NO_ACTION) {
|
if (m_action_ctxt->has_action(btn, m_motion_pos) != tags::NO_ACTION) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -741,7 +740,8 @@ void bar::handle(const evt::button_press& evt) {
|
|||||||
m_buttonpress_pos = evt->event_x;
|
m_buttonpress_pos = evt->event_x;
|
||||||
|
|
||||||
const auto deferred_fn = [&](size_t) {
|
const auto deferred_fn = [&](size_t) {
|
||||||
tags::action_t action = m_renderer->get_action(m_buttonpress_btn, m_buttonpress_pos);
|
tags::action_t action = m_action_ctxt->has_action(m_buttonpress_btn, m_buttonpress_pos);
|
||||||
|
;
|
||||||
|
|
||||||
if (action != tags::NO_ACTION) {
|
if (action != tags::NO_ACTION) {
|
||||||
m_log.trace("Found matching input area");
|
m_log.trace("Found matching input area");
|
||||||
@ -830,7 +830,7 @@ void bar::handle(const evt::configure_notify&) {
|
|||||||
|
|
||||||
bool bar::on(const signals::eventqueue::start&) {
|
bool bar::on(const signals::eventqueue::start&) {
|
||||||
m_log.trace("bar: Create renderer");
|
m_log.trace("bar: Create renderer");
|
||||||
m_renderer = renderer::make(m_opts);
|
m_renderer = renderer::make(m_opts, *m_action_ctxt);
|
||||||
m_opts.window = m_renderer->window();
|
m_opts.window = m_renderer->window();
|
||||||
|
|
||||||
// Subscribe to window enter and leave events
|
// Subscribe to window enter and leave events
|
||||||
|
@ -21,7 +21,7 @@ static constexpr double BLOCK_GAP{20.0};
|
|||||||
/**
|
/**
|
||||||
* Create instance
|
* Create instance
|
||||||
*/
|
*/
|
||||||
renderer::make_type renderer::make(const bar_settings& bar) {
|
renderer::make_type renderer::make(const bar_settings& bar, tags::action_context& action_ctxt) {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
return factory_util::unique<renderer>(
|
return factory_util::unique<renderer>(
|
||||||
connection::make(),
|
connection::make(),
|
||||||
@ -29,7 +29,8 @@ renderer::make_type renderer::make(const bar_settings& bar) {
|
|||||||
config::make(),
|
config::make(),
|
||||||
logger::make(),
|
logger::make(),
|
||||||
forward<decltype(bar)>(bar),
|
forward<decltype(bar)>(bar),
|
||||||
background_manager::make());
|
background_manager::make(),
|
||||||
|
action_ctxt);
|
||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,8 +38,9 @@ renderer::make_type renderer::make(const bar_settings& bar) {
|
|||||||
* Construct renderer instance
|
* Construct renderer instance
|
||||||
*/
|
*/
|
||||||
renderer::renderer(connection& conn, signal_emitter& sig, const config& conf, const logger& logger,
|
renderer::renderer(connection& conn, signal_emitter& sig, const config& conf, const logger& logger,
|
||||||
const bar_settings& bar, background_manager& background)
|
const bar_settings& bar, background_manager& background, tags::action_context& action_ctxt)
|
||||||
: m_connection(conn)
|
: renderer_interface(action_ctxt)
|
||||||
|
, m_connection(conn)
|
||||||
, m_sig(sig)
|
, m_sig(sig)
|
||||||
, m_conf(conf)
|
, m_conf(conf)
|
||||||
, m_log(logger)
|
, m_log(logger)
|
||||||
@ -203,7 +205,6 @@ void renderer::begin(xcb_rectangle_t rect) {
|
|||||||
|
|
||||||
// Reset state
|
// Reset state
|
||||||
m_rect = rect;
|
m_rect = rect;
|
||||||
m_actions.clear();
|
|
||||||
m_align = alignment::NONE;
|
m_align = alignment::NONE;
|
||||||
|
|
||||||
// Clear canvas
|
// Clear canvas
|
||||||
@ -250,8 +251,7 @@ void renderer::begin(xcb_rectangle_t rect) {
|
|||||||
void renderer::end() {
|
void renderer::end() {
|
||||||
m_log.trace_x("renderer: end");
|
m_log.trace_x("renderer: end");
|
||||||
|
|
||||||
for (auto& entry : m_actions) {
|
for (auto& a : m_action_ctxt.get_blocks()) {
|
||||||
auto& a = entry.second;
|
|
||||||
a.start_x += block_x(a.align) + m_rect.x;
|
a.start_x += block_x(a.align) + m_rect.x;
|
||||||
a.end_x += block_x(a.align) + m_rect.x;
|
a.end_x += block_x(a.align) + m_rect.x;
|
||||||
}
|
}
|
||||||
@ -700,43 +700,11 @@ void renderer::change_alignment(const tags::context& ctxt) {
|
|||||||
|
|
||||||
void renderer::action_open(const tags::context&, mousebtn btn, tags::action_t id) {
|
void renderer::action_open(const tags::context&, mousebtn btn, tags::action_t id) {
|
||||||
assert(btn != mousebtn::NONE);
|
assert(btn != mousebtn::NONE);
|
||||||
action_block block;
|
m_action_ctxt.set_start(id, m_blocks.at(m_align).x);
|
||||||
block.align = m_align;
|
|
||||||
block.button = btn;
|
|
||||||
block.start_x = m_blocks.at(block.align).x;
|
|
||||||
m_actions[id] = block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderer::action_close(const tags::context&, tags::action_t id) {
|
void renderer::action_close(const tags::context&, tags::action_t id) {
|
||||||
auto& block = m_actions[id];
|
m_action_ctxt.set_end(id, m_blocks.at(m_align).x);
|
||||||
block.end_x = m_blocks.at(block.align).x;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<mousebtn, tags::action_t> renderer::get_actions(int x) {
|
|
||||||
std::map<mousebtn, tags::action_t> buttons;
|
|
||||||
|
|
||||||
for (int i = static_cast<int>(mousebtn::NONE); i < static_cast<int>(mousebtn::BTN_COUNT); i++) {
|
|
||||||
buttons[static_cast<mousebtn>(i)] = tags::NO_ACTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto&& entry : m_actions) {
|
|
||||||
tags::action_t id;
|
|
||||||
action_block action;
|
|
||||||
std::tie(id, action) = entry;
|
|
||||||
|
|
||||||
mousebtn btn = action.button;
|
|
||||||
|
|
||||||
// Higher IDs are higher in the action stack.
|
|
||||||
if (id > buttons[btn] && action.test(x)) {
|
|
||||||
buttons[action.button] = id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return buttons;
|
|
||||||
}
|
|
||||||
|
|
||||||
tags::action_t renderer::get_action(mousebtn btn, int x) {
|
|
||||||
return get_actions(x)[btn];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -745,8 +713,7 @@ tags::action_t renderer::get_action(mousebtn btn, int x) {
|
|||||||
void renderer::highlight_clickable_areas() {
|
void renderer::highlight_clickable_areas() {
|
||||||
#ifdef DEBUG_HINTS
|
#ifdef DEBUG_HINTS
|
||||||
map<alignment, int> hint_num{};
|
map<alignment, int> hint_num{};
|
||||||
for (auto&& entry : m_actions) {
|
for (auto&& action : m_action_ctxt.get_blocks()) {
|
||||||
auto&& action = entry.second;
|
|
||||||
int n = hint_num.find(action.align)->second++;
|
int n = hint_num.find(action.align)->second++;
|
||||||
double x = action.start_x;
|
double x = action.start_x;
|
||||||
double y = m_rect.y;
|
double y = m_rect.y;
|
||||||
|
@ -137,6 +137,39 @@ namespace tags {
|
|||||||
return {NO_ACTION, mousebtn::NONE};
|
return {NO_ACTION, mousebtn::NONE};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void action_context::set_start(action_t id, double x) {
|
||||||
|
m_action_blocks[id].start_x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void action_context::set_end(action_t id, double x) {
|
||||||
|
m_action_blocks[id].end_x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<mousebtn, tags::action_t> action_context::get_actions(int x) const {
|
||||||
|
std::map<mousebtn, tags::action_t> buttons;
|
||||||
|
|
||||||
|
for (int i = static_cast<int>(mousebtn::NONE); i < static_cast<int>(mousebtn::BTN_COUNT); i++) {
|
||||||
|
buttons[static_cast<mousebtn>(i)] = tags::NO_ACTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (action_t id = 0; (unsigned)id < m_action_blocks.size(); id++) {
|
||||||
|
auto action = m_action_blocks[id];
|
||||||
|
mousebtn btn = action.button;
|
||||||
|
|
||||||
|
// Higher IDs are higher in the action stack.
|
||||||
|
if (id > buttons[btn] && action.test(x)) {
|
||||||
|
buttons[action.button] = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buttons;
|
||||||
|
}
|
||||||
|
|
||||||
|
action_t action_context::has_action(mousebtn btn, int x) const {
|
||||||
|
// TODO optimize
|
||||||
|
return get_actions(x)[btn];
|
||||||
|
}
|
||||||
|
|
||||||
string action_context::get_action(action_t id) const {
|
string action_context::get_action(action_t id) const {
|
||||||
assert(id >= 0 && (unsigned)id < num_actions());
|
assert(id >= 0 && (unsigned)id < num_actions());
|
||||||
|
|
||||||
@ -158,6 +191,10 @@ namespace tags {
|
|||||||
return m_action_blocks.size();
|
return m_action_blocks.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<action_block>& action_context::get_blocks() {
|
||||||
|
return m_action_blocks;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace tags
|
} // namespace tags
|
||||||
|
|
||||||
POLYBAR_NS_END
|
POLYBAR_NS_END
|
||||||
|
Loading…
Reference in New Issue
Block a user