From 3f89d73374b2137b413d2a1eac68761399733c27 Mon Sep 17 00:00:00 2001 From: patrick96 Date: Sun, 20 Mar 2022 19:09:45 +0100 Subject: [PATCH] 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. --- include/components/bar.hpp | 15 ++++---- include/events/signal.hpp | 15 +++----- include/events/signal_fwd.hpp | 9 ++--- src/components/bar.cpp | 70 +++++++++++++++-------------------- 4 files changed, 48 insertions(+), 61 deletions(-) diff --git a/include/components/bar.hpp b/include/components/bar.hpp index 0408c42f..76df44c4 100644 --- a/include/components/bar.hpp +++ b/include/components/bar.hpp @@ -31,12 +31,7 @@ namespace tags { class bar : public xpp::event::sink, - public signal_receiver { + public signal_receiver { public: using make_type = unique_ptr; static make_type make(eventloop::loop&, bool only_initialize_values = false); @@ -80,8 +75,14 @@ class bar : public xpp::event::sink { @@ -60,7 +60,7 @@ namespace signals { struct check_state : public detail::base_signal { using base_type::base_type; }; - } // namespace eventqueue + } // namespace eventqueue namespace ipc { struct command : public detail::value_signal { @@ -72,7 +72,7 @@ namespace signals { struct action : public detail::value_signal { using base_type::base_type; }; - } // namespace ipc + } // namespace ipc namespace ui { struct changed : public detail::base_signal { @@ -81,9 +81,6 @@ namespace signals { struct button_press : public detail::value_signal { using base_type::base_type; }; - struct cursor_change : public detail::value_signal { - using base_type::base_type; - }; struct visibility_change : public detail::value_signal { using base_type::base_type; }; @@ -101,13 +98,13 @@ namespace signals { struct update_geometry : public detail::base_signal { using base_type::base_type; }; - } // namespace ui + } // namespace ui namespace ui_tray { struct mapped_clients : public detail::value_signal { using base_type::base_type; }; - } // namespace ui_tray -} // namespace signals + } // namespace ui_tray +} // namespace signals POLYBAR_NS_END diff --git a/include/events/signal_fwd.hpp b/include/events/signal_fwd.hpp index 376683a0..2c7abbb7 100644 --- a/include/events/signal_fwd.hpp +++ b/include/events/signal_fwd.hpp @@ -19,25 +19,24 @@ namespace signals { struct notify_change; struct notify_forcechange; struct check_state; - } // namespace eventqueue + } // namespace eventqueue namespace ipc { struct command; struct hook; struct action; - } // namespace ipc + } // namespace ipc namespace ui { struct changed; struct button_press; - struct cursor_change; struct visibility_change; struct dim_window; struct request_snapshot; struct update_background; struct update_geometry; - } // namespace ui + } // namespace ui namespace ui_tray { struct mapped_clients; } -} // namespace signals +} // namespace signals POLYBAR_NS_END diff --git a/src/components/bar.cpp b/src/components/bar.cpp index 2cff94f1..72ee640b 100644 --- a/src/components/bar.cpp +++ b/src/components/bar.cpp @@ -43,16 +43,16 @@ bar::make_type bar::make(loop& loop, bool only_initialize_values) { // clang-format off return std::make_unique( - connection::make(), - signal_emitter::make(), - config::make(), - logger::make(), - loop, - screen::make(), - tray_manager::make(), - tags::dispatch::make(*action_ctxt), - std::move(action_ctxt), - only_initialize_values); + connection::make(), + signal_emitter::make(), + config::make(), + logger::make(), + loop, + screen::make(), + tray_manager::make(), + tags::dispatch::make(*action_ctxt), + std::move(action_ctxt), + only_initialize_values); // clang-format on } @@ -747,21 +747,14 @@ void bar::handle(const evt::motion_notify& evt) { return false; }; - if (has_action({mousebtn::LEFT, mousebtn::MIDDLE, mousebtn::RIGHT, mousebtn::DOUBLE_LEFT, mousebtn::DOUBLE_MIDDLE, - mousebtn::DOUBLE_RIGHT})) { - if (m_opts.cursor != m_opts.cursor_click) { - m_opts.cursor = m_opts.cursor_click; - m_sig.emit(cursor_change{string{m_opts.cursor}}); - } - + if (!m_opts.cursor_click.empty() && has_action({mousebtn::LEFT, mousebtn::MIDDLE, mousebtn::RIGHT, + mousebtn::DOUBLE_LEFT, mousebtn::DOUBLE_MIDDLE, mousebtn::DOUBLE_RIGHT})) { + change_cursor(m_opts.cursor_click); return; } - if (has_action({mousebtn::SCROLL_DOWN, mousebtn::SCROLL_UP})) { - if (m_opts.cursor != m_opts.cursor_scroll) { - m_opts.cursor = m_opts.cursor_scroll; - m_sig.emit(cursor_change{string{m_opts.cursor}}); - } + if (!m_opts.cursor_scroll.empty() && has_action({mousebtn::SCROLL_DOWN, mousebtn::SCROLL_UP})) { + change_cursor(m_opts.cursor_scroll); return; } @@ -769,10 +762,7 @@ void bar::handle(const evt::motion_notify& evt) { if (!m_opts.cursor_click.empty() && !(action.button == mousebtn::SCROLL_UP || action.button == mousebtn::SCROLL_DOWN || action.button == mousebtn::NONE)) { - if (m_opts.cursor != m_opts.cursor_click) { - m_opts.cursor = m_opts.cursor_click; - m_sig.emit(cursor_change{string{m_opts.cursor}}); - } + change_cursor(m_opts.cursor_click); return true; } else if (!m_opts.cursor_scroll.empty() && (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) { if (!action.command.empty()) { m_log.trace("Found matching fallback handler"); - if (find_click_area(action)) + if (find_click_area(action)) { return; + } } } if (found_scroll) { - if (m_opts.cursor != m_opts.cursor_scroll) { - m_opts.cursor = m_opts.cursor_scroll; - m_sig.emit(cursor_change{string{m_opts.cursor}}); - } + change_cursor(m_opts.cursor_scroll); return; } - if (m_opts.cursor != "default") { - m_log.trace("No matching cursor area found"); - m_opts.cursor = "default"; - m_sig.emit(cursor_change{string{m_opts.cursor}}); - return; - } + m_log.trace("No matching cursor area found"); + change_cursor("default"); + return; #endif } @@ -931,12 +916,17 @@ bool bar::on(const signals::ui::dim_window& sig) { } #if WITH_XCURSOR -bool bar::on(const signals::ui::cursor_change& sig) { - if (!cursor_util::set_cursor(m_connection, m_connection.screen(), m_opts.window, sig.cast())) { +void bar::change_cursor(const string& name) { + // 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_connection.flush(); - return false; } #endif