fix mouseover error when only one cursor is defined

If only cursor-click or cursor-scroll is defined, but not the other, the
bar could try to set the cursor to the empty string which resulted in an
error.
This commit is contained in:
patrick96 2022-03-20 19:09:45 +01:00 committed by Patrick Ziegler
parent cea9949be1
commit 3f89d73374
4 changed files with 48 additions and 61 deletions

View file

@ -31,12 +31,7 @@ namespace tags {
class bar : public xpp::event::sink<evt::button_press, evt::expose, evt::property_notify, evt::enter_notify, class bar : public xpp::event::sink<evt::button_press, evt::expose, evt::property_notify, evt::enter_notify,
evt::leave_notify, evt::motion_notify, evt::destroy_notify, evt::client_message, evt::configure_notify>, evt::leave_notify, evt::motion_notify, evt::destroy_notify, evt::client_message, evt::configure_notify>,
public signal_receiver<SIGN_PRIORITY_BAR, signals::ui::dim_window public signal_receiver<SIGN_PRIORITY_BAR, signals::ui::dim_window> {
#if WITH_XCURSOR
,
signals::ui::cursor_change
#endif
> {
public: public:
using make_type = unique_ptr<bar>; using make_type = unique_ptr<bar>;
static make_type make(eventloop::loop&, bool only_initialize_values = false); static make_type make(eventloop::loop&, bool only_initialize_values = false);
@ -80,8 +75,14 @@ class bar : public xpp::event::sink<evt::button_press, evt::expose, evt::propert
void handle(const evt::configure_notify& evt) override; void handle(const evt::configure_notify& evt) override;
bool on(const signals::ui::dim_window&) override; bool on(const signals::ui::dim_window&) override;
#if WITH_XCURSOR #if WITH_XCURSOR
bool on(const signals::ui::cursor_change&) override; /**
* Change cursor to the given cursor name.
*
* The cursor name must be valid (cursor_util::valid)
*/
void change_cursor(const string& name);
#endif #endif
private: private:

View file

@ -45,7 +45,7 @@ namespace signals {
private: private:
const void* m_ptr; const void* m_ptr;
}; };
} // namespace detail } // namespace detail
namespace eventqueue { namespace eventqueue {
struct exit_reload : public detail::base_signal<exit_reload> { struct exit_reload : public detail::base_signal<exit_reload> {
@ -60,7 +60,7 @@ namespace signals {
struct check_state : public detail::base_signal<check_state> { struct check_state : public detail::base_signal<check_state> {
using base_type::base_type; using base_type::base_type;
}; };
} // namespace eventqueue } // namespace eventqueue
namespace ipc { namespace ipc {
struct command : public detail::value_signal<command, string> { struct command : public detail::value_signal<command, string> {
@ -72,7 +72,7 @@ namespace signals {
struct action : public detail::value_signal<action, string> { struct action : public detail::value_signal<action, string> {
using base_type::base_type; using base_type::base_type;
}; };
} // namespace ipc } // namespace ipc
namespace ui { namespace ui {
struct changed : public detail::base_signal<changed> { struct changed : public detail::base_signal<changed> {
@ -81,9 +81,6 @@ namespace signals {
struct button_press : public detail::value_signal<button_press, string> { struct button_press : public detail::value_signal<button_press, string> {
using base_type::base_type; using base_type::base_type;
}; };
struct cursor_change : public detail::value_signal<cursor_change, string> {
using base_type::base_type;
};
struct visibility_change : public detail::value_signal<visibility_change, bool> { struct visibility_change : public detail::value_signal<visibility_change, bool> {
using base_type::base_type; using base_type::base_type;
}; };
@ -101,13 +98,13 @@ namespace signals {
struct update_geometry : public detail::base_signal<update_geometry> { struct update_geometry : public detail::base_signal<update_geometry> {
using base_type::base_type; using base_type::base_type;
}; };
} // namespace ui } // namespace ui
namespace ui_tray { namespace ui_tray {
struct mapped_clients : public detail::value_signal<mapped_clients, unsigned int> { struct mapped_clients : public detail::value_signal<mapped_clients, unsigned int> {
using base_type::base_type; using base_type::base_type;
}; };
} // namespace ui_tray } // namespace ui_tray
} // namespace signals } // namespace signals
POLYBAR_NS_END POLYBAR_NS_END

View file

@ -19,25 +19,24 @@ namespace signals {
struct notify_change; struct notify_change;
struct notify_forcechange; struct notify_forcechange;
struct check_state; struct check_state;
} // namespace eventqueue } // namespace eventqueue
namespace ipc { namespace ipc {
struct command; struct command;
struct hook; struct hook;
struct action; struct action;
} // namespace ipc } // namespace ipc
namespace ui { namespace ui {
struct changed; struct changed;
struct button_press; struct button_press;
struct cursor_change;
struct visibility_change; struct visibility_change;
struct dim_window; struct dim_window;
struct request_snapshot; struct request_snapshot;
struct update_background; struct update_background;
struct update_geometry; struct update_geometry;
} // namespace ui } // namespace ui
namespace ui_tray { namespace ui_tray {
struct mapped_clients; struct mapped_clients;
} }
} // namespace signals } // namespace signals
POLYBAR_NS_END POLYBAR_NS_END

View file

@ -43,16 +43,16 @@ bar::make_type bar::make(loop& loop, bool only_initialize_values) {
// clang-format off // clang-format off
return std::make_unique<bar>( return std::make_unique<bar>(
connection::make(), connection::make(),
signal_emitter::make(), signal_emitter::make(),
config::make(), config::make(),
logger::make(), logger::make(),
loop, loop,
screen::make(), screen::make(),
tray_manager::make(), tray_manager::make(),
tags::dispatch::make(*action_ctxt), tags::dispatch::make(*action_ctxt),
std::move(action_ctxt), std::move(action_ctxt),
only_initialize_values); only_initialize_values);
// clang-format on // clang-format on
} }
@ -747,21 +747,14 @@ void bar::handle(const evt::motion_notify& evt) {
return false; return false;
}; };
if (has_action({mousebtn::LEFT, mousebtn::MIDDLE, mousebtn::RIGHT, mousebtn::DOUBLE_LEFT, mousebtn::DOUBLE_MIDDLE, if (!m_opts.cursor_click.empty() && has_action({mousebtn::LEFT, mousebtn::MIDDLE, mousebtn::RIGHT,
mousebtn::DOUBLE_RIGHT})) { mousebtn::DOUBLE_LEFT, mousebtn::DOUBLE_MIDDLE, mousebtn::DOUBLE_RIGHT})) {
if (m_opts.cursor != m_opts.cursor_click) { change_cursor(m_opts.cursor_click);
m_opts.cursor = m_opts.cursor_click;
m_sig.emit(cursor_change{string{m_opts.cursor}});
}
return; return;
} }
if (has_action({mousebtn::SCROLL_DOWN, mousebtn::SCROLL_UP})) { if (!m_opts.cursor_scroll.empty() && has_action({mousebtn::SCROLL_DOWN, mousebtn::SCROLL_UP})) {
if (m_opts.cursor != m_opts.cursor_scroll) { change_cursor(m_opts.cursor_scroll);
m_opts.cursor = m_opts.cursor_scroll;
m_sig.emit(cursor_change{string{m_opts.cursor}});
}
return; return;
} }
@ -769,10 +762,7 @@ void bar::handle(const evt::motion_notify& evt) {
if (!m_opts.cursor_click.empty() && if (!m_opts.cursor_click.empty() &&
!(action.button == mousebtn::SCROLL_UP || action.button == mousebtn::SCROLL_DOWN || !(action.button == mousebtn::SCROLL_UP || action.button == mousebtn::SCROLL_DOWN ||
action.button == mousebtn::NONE)) { action.button == mousebtn::NONE)) {
if (m_opts.cursor != m_opts.cursor_click) { change_cursor(m_opts.cursor_click);
m_opts.cursor = m_opts.cursor_click;
m_sig.emit(cursor_change{string{m_opts.cursor}});
}
return true; return true;
} else if (!m_opts.cursor_scroll.empty() && } else if (!m_opts.cursor_scroll.empty() &&
(action.button == mousebtn::SCROLL_UP || action.button == mousebtn::SCROLL_DOWN)) { (action.button == mousebtn::SCROLL_UP || action.button == mousebtn::SCROLL_DOWN)) {
@ -786,25 +776,20 @@ void bar::handle(const evt::motion_notify& evt) {
for (auto&& action : m_opts.actions) { for (auto&& action : m_opts.actions) {
if (!action.command.empty()) { if (!action.command.empty()) {
m_log.trace("Found matching fallback handler"); m_log.trace("Found matching fallback handler");
if (find_click_area(action)) if (find_click_area(action)) {
return; return;
}
} }
} }
if (found_scroll) { if (found_scroll) {
if (m_opts.cursor != m_opts.cursor_scroll) { change_cursor(m_opts.cursor_scroll);
m_opts.cursor = m_opts.cursor_scroll;
m_sig.emit(cursor_change{string{m_opts.cursor}});
}
return; return;
} }
if (m_opts.cursor != "default") { m_log.trace("No matching cursor area found");
m_log.trace("No matching cursor area found"); change_cursor("default");
m_opts.cursor = "default"; return;
m_sig.emit(cursor_change{string{m_opts.cursor}});
return;
}
#endif #endif
} }
@ -931,12 +916,17 @@ bool bar::on(const signals::ui::dim_window& sig) {
} }
#if WITH_XCURSOR #if WITH_XCURSOR
bool bar::on(const signals::ui::cursor_change& sig) { void bar::change_cursor(const string& name) {
if (!cursor_util::set_cursor(m_connection, m_connection.screen(), m_opts.window, sig.cast())) { // This is already the same cursor, no need to update
if (m_opts.cursor == name) {
return;
}
m_opts.cursor = name;
if (!cursor_util::set_cursor(m_connection, m_connection.screen(), m_opts.window, name)) {
m_log.warn("Failed to create cursor context"); m_log.warn("Failed to create cursor context");
} }
m_connection.flush(); m_connection.flush();
return false;
} }
#endif #endif