From 65edba33216420eee276175a4fdb669265bd2444 Mon Sep 17 00:00:00 2001 From: NBonaparte Date: Sat, 2 Sep 2017 21:45:45 -0700 Subject: [PATCH 1/9] feat: add cursor change --- cmake/02-opts.cmake | 2 + cmake/03-libs.cmake | 1 + cmake/05-summary.cmake | 1 + include/components/bar.hpp | 7 ++- include/components/types.hpp | 4 ++ include/events/signal.hpp | 3 ++ include/events/signal_fwd.hpp | 1 + include/x11/cursor.hpp | 22 ++++++++++ src/components/bar.cpp | 80 ++++++++++++++++++++++++++++++++++- src/x11/cursor.cpp | 33 +++++++++++++++ 10 files changed, 150 insertions(+), 4 deletions(-) create mode 100644 include/x11/cursor.hpp create mode 100644 src/x11/cursor.cpp diff --git a/cmake/02-opts.cmake b/cmake/02-opts.cmake index 905696f4..70ec1fbf 100644 --- a/cmake/02-opts.cmake +++ b/cmake/02-opts.cmake @@ -9,6 +9,7 @@ checklib(ENABLE_MPD "pkg-config" libmpdclient) checklib(ENABLE_NETWORK "cmake" Libiw) checklib(WITH_XRM "pkg-config" xcb-xrm) checklib(WITH_XRANDR_MONITORS "pkg-config" "xcb-randr>=1.12") +checklib(WITH_CURSOR "pkg-config" "xcb-cursor") if(NOT DEFINED ENABLE_CCACHE AND CMAKE_BUILD_TYPE_UPPER MATCHES DEBUG) set(ENABLE_CCACHE ON) @@ -36,6 +37,7 @@ option(WITH_XSYNC "xcb-sync support" OFF) option(WITH_XCOMPOSITE "xcb-composite support" OFF) option(WITH_XKB "xcb-xkb support" ON) option(WITH_XRM "xcb-xrm support" ON) +option(WITH_CURSOR "xcb-cursor support" ON) if(CMAKE_BUILD_TYPE_UPPER MATCHES DEBUG) option(DEBUG_LOGGER "Debug logging" ON) diff --git a/cmake/03-libs.cmake b/cmake/03-libs.cmake index de176a91..e7cea39c 100644 --- a/cmake/03-libs.cmake +++ b/cmake/03-libs.cmake @@ -20,3 +20,4 @@ querylib(WITH_XRANDR_MONITORS "pkg-config" "xcb-randr>=1.12" libs dirs) querylib(WITH_XRENDER "pkg-config" xcb-render libs dirs) querylib(WITH_XRM "pkg-config" xcb-xrm libs dirs) querylib(WITH_XSYNC "pkg-config" xcb-sync libs dirs) +querylib(WITH_CURSOR "pkg-config" xcb-cursor libs dirs) diff --git a/cmake/05-summary.cmake b/cmake/05-summary.cmake index b5c3f58b..f56b13ee 100644 --- a/cmake/05-summary.cmake +++ b/cmake/05-summary.cmake @@ -28,6 +28,7 @@ colored_option(" xcb-sync" WITH_XSYNC) colored_option(" xcb-composite" WITH_XCOMPOSITE) colored_option(" xcb-xkb" WITH_XKB) colored_option(" xcb-xrm" WITH_XRM) +colored_option(" xcb-cursor" WITH_CURSOR) if(CMAKE_BUILD_TYPE_UPPER MATCHES DEBUG) message(STATUS " Debug options:") diff --git a/include/components/bar.hpp b/include/components/bar.hpp index 616ecdcc..cf90c5b3 100644 --- a/include/components/bar.hpp +++ b/include/components/bar.hpp @@ -26,9 +26,9 @@ class tray_manager; // }}} class bar : public xpp::event::sink, + evt::leave_notify, evt::motion_notify, evt::destroy_notify, evt::client_message>, public signal_receiver { + signals::ui::shade_window, signals::ui::unshade_window, signals::ui::dim_window, signals::ui::cursor_change> { public: using make_type = unique_ptr; static make_type make(bool only_initialize_values = false); @@ -56,6 +56,7 @@ class bar : public xpp::event::sink actions{}; bool dimmed{false}; diff --git a/include/events/signal.hpp b/include/events/signal.hpp index b9fc4250..986a6125 100644 --- a/include/events/signal.hpp +++ b/include/events/signal.hpp @@ -102,6 +102,9 @@ 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; }; diff --git a/include/events/signal_fwd.hpp b/include/events/signal_fwd.hpp index a2ffb911..f7da2f89 100644 --- a/include/events/signal_fwd.hpp +++ b/include/events/signal_fwd.hpp @@ -32,6 +32,7 @@ namespace signals { struct changed; struct tick; struct button_press; + struct cursor_change; struct visibility_change; struct dim_window; struct shade_window; diff --git a/include/x11/cursor.hpp b/include/x11/cursor.hpp new file mode 100644 index 00000000..9653f628 --- /dev/null +++ b/include/x11/cursor.hpp @@ -0,0 +1,22 @@ +#pragma once + +//#if not WITH_CURSOR +//#error "Not built with support for xcb-cursor..." +//#endif + +#include + +#include "common.hpp" +#include "x11/connection.hpp" +#include "utils/string.hpp" + +POLYBAR_NS + +namespace cursor_util { + static const vector pointer_names {"pointing_hand", "pointer", "hand", "hand1", "hand2", "e29285e634086352946a0e7090d73106", "9d800788f1b08800ae810202380a0822"}; + static const vector arrow_names {"left_ptr", "arrow", "dnd-none", "op_left_arrow"}; + static const vector ns_resize_names {"size_ver", "sb_v_double_arrow", "v_double_arrow", "n-resize", "s-resize", "col-resize", "top_side", "bottom_side", "base_arrow_up", "base_arrow_down", "based_arrow_down", "based_arrow_up", "00008160000006810000408080010102"}; + bool set_cursor(xcb_connection_t *c, xcb_screen_t *screen, xcb_window_t w, string name); +} + +POLYBAR_NS_END diff --git a/src/components/bar.cpp b/src/components/bar.cpp index 4807f8f6..6274a5bb 100644 --- a/src/components/bar.cpp +++ b/src/components/bar.cpp @@ -16,6 +16,7 @@ #include "utils/string.hpp" #include "x11/atoms.hpp" #include "x11/connection.hpp" +#include "x11/cursor.hpp" #include "x11/ewmh.hpp" #include "x11/extensions/all.hpp" #include "x11/icccm.hpp" @@ -126,6 +127,8 @@ bar::bar(connection& conn, signal_emitter& emitter, const config& config, const m_opts.dimvalue = m_conf.get(bs, "dim-value", 1.0); m_opts.dimvalue = math_util::cap(m_opts.dimvalue, 0.0, 1.0); + m_opts.cursor_click = m_conf.get(bs, "cursor-click", ""s); + m_opts.cursor_scroll = m_conf.get(bs, "cursor-scroll", ""s); // Build WM_NAME m_opts.wmname = m_conf.get(bs, "wm-name", "polybar-" + bs.substr(4) + "_" + m_opts.monitor->name); m_opts.wmname = string_util::replace(m_opts.wmname, " ", "-"); @@ -554,7 +557,6 @@ void bar::handle(const evt::enter_notify&) { } #endif #endif - if (m_opts.dimmed) { m_taskqueue->defer_unique("window-dim", 25ms, [&](size_t) { m_opts.dimmed = false; @@ -580,7 +582,6 @@ void bar::handle(const evt::leave_notify&) { } #endif #endif - if (!m_opts.dimmed) { m_taskqueue->defer_unique("window-dim", 3s, [&](size_t) { m_opts.dimmed = true; @@ -589,6 +590,70 @@ void bar::handle(const evt::leave_notify&) { } } +/** + * Event handler for XCB_MOTION_NOTIFY events + * + * Used to change the cursor depending on the module + */ +void bar::handle(const evt::motion_notify& evt) { + m_log.trace("bar: Detected motion: %i at pos(%i, %i)", evt->detail, evt->event_x, evt->event_y); + + m_motion_pos = evt->event_x; + // scroll cursor is less important than click cursor, so we shouldn't return until we are sure there is no click action + bool found_scroll = false; + const auto find_click_area = [&](action action) { + if (!m_opts.cursor_click.empty() && + (action.button == mousebtn::LEFT || action.button == mousebtn::MIDDLE || action.button == mousebtn::RIGHT)) { + if (!string_util::compare(m_opts.cursor, m_opts.cursor_click)) { + m_opts.cursor = m_opts.cursor_click; + m_sig.emit(cursor_change{string{m_opts.cursor}}); + } + return true; + } else if (!m_opts.cursor_scroll.empty() && (action.button == mousebtn::SCROLL_UP || action.button == mousebtn::SCROLL_DOWN)) { + if (!found_scroll) { + if (!string_util::compare(m_opts.cursor, m_opts.cursor_scroll)) { + found_scroll = true; + } else { + return true; + } + } + } + return false; + }; + + for (auto&& action : m_renderer->actions()) { + if (action.test(m_motion_pos)) { + m_log.trace("Found matching input area"); + if(find_click_area(action)) + return; + } + } + if(found_scroll) { + m_opts.cursor = m_opts.cursor_scroll; + m_sig.emit(cursor_change{string{m_opts.cursor}}); + return; + } + for (auto&& action : m_opts.actions) { + if (!action.command.empty()) { + m_log.trace("Found matching fallback handler"); + if(find_click_area(action)) + return; + } + } + if(found_scroll) { + m_opts.cursor = m_opts.cursor_scroll; + m_sig.emit(cursor_change{string{m_opts.cursor}}); + return; + } + if (!string_util::compare(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; + } + +} + /** * Event handler for XCB_BUTTON_PRESS events * @@ -703,6 +768,9 @@ bool bar::on(const signals::eventqueue::start&) { if (m_opts.dimvalue != 1.0) { m_connection.ensure_event_mask(m_opts.window, XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW); } + if (!m_opts.cursor_click.empty() || !m_opts.cursor_scroll.empty() ) { + m_connection.ensure_event_mask(m_opts.window, XCB_EVENT_MASK_POINTER_MOTION); + } m_log.info("Bar window: %s", m_connection.id(m_opts.window)); restack_window(); @@ -841,4 +909,12 @@ bool bar::on(const signals::ui::dim_window& sig) { return false; } +bool bar::on(const signals::ui::cursor_change& sig) { + if(!cursor_util::set_cursor(m_connection, m_connection.screen(), m_opts.window, sig.cast())) { + m_log.warn("Failed to create cursor context"); + } + m_connection.flush(); + return false; +} + POLYBAR_NS_END diff --git a/src/x11/cursor.cpp b/src/x11/cursor.cpp new file mode 100644 index 00000000..708154b0 --- /dev/null +++ b/src/x11/cursor.cpp @@ -0,0 +1,33 @@ +#include "x11/cursor.hpp" + +POLYBAR_NS + +namespace cursor_util { + bool set_cursor(xcb_connection_t *c, xcb_screen_t *screen, xcb_window_t w, string name) { + xcb_cursor_t cursor = XCB_CURSOR_NONE; + xcb_cursor_context_t *ctx; + + if (xcb_cursor_context_new(c, screen, &ctx) < 0) { + return false; + } + + const vector *name_list; + if (string_util::compare("pointer", name)) { + name_list = &pointer_names; + } else if (string_util::compare("ns-resize", name)) { + name_list = &ns_resize_names; + } else { //default + name_list = &arrow_names; + } + + for (auto&& cursor_name : *name_list) { + cursor = xcb_cursor_load_cursor(ctx, cursor_name.c_str()); + if (cursor != XCB_CURSOR_NONE) + break; + } + xcb_change_window_attributes(c, w, XCB_CW_CURSOR, &cursor); + xcb_cursor_context_free(ctx); + return true; + } +} +POLYBAR_NS_END From 1dc111c0fab1db7a9d1249f3934eb4730eff6dde Mon Sep 17 00:00:00 2001 From: NBonaparte Date: Tue, 5 Sep 2017 23:35:29 -0700 Subject: [PATCH 2/9] fix: make xcb-cursor optional for now --- cmake/02-opts.cmake | 4 ++-- cmake/03-libs.cmake | 2 +- cmake/05-summary.cmake | 2 +- include/components/bar.hpp | 10 +++++++++- include/settings.hpp.cmake | 6 ++++-- include/x11/cursor.hpp | 8 +++++--- src/CMakeLists.txt | 3 +++ src/components/bar.cpp | 11 ++++++++--- 8 files changed, 33 insertions(+), 13 deletions(-) diff --git a/cmake/02-opts.cmake b/cmake/02-opts.cmake index 70ec1fbf..adefa582 100644 --- a/cmake/02-opts.cmake +++ b/cmake/02-opts.cmake @@ -9,7 +9,7 @@ checklib(ENABLE_MPD "pkg-config" libmpdclient) checklib(ENABLE_NETWORK "cmake" Libiw) checklib(WITH_XRM "pkg-config" xcb-xrm) checklib(WITH_XRANDR_MONITORS "pkg-config" "xcb-randr>=1.12") -checklib(WITH_CURSOR "pkg-config" "xcb-cursor") +checklib(WITH_XCURSOR "pkg-config" "xcb-cursor") if(NOT DEFINED ENABLE_CCACHE AND CMAKE_BUILD_TYPE_UPPER MATCHES DEBUG) set(ENABLE_CCACHE ON) @@ -37,7 +37,7 @@ option(WITH_XSYNC "xcb-sync support" OFF) option(WITH_XCOMPOSITE "xcb-composite support" OFF) option(WITH_XKB "xcb-xkb support" ON) option(WITH_XRM "xcb-xrm support" ON) -option(WITH_CURSOR "xcb-cursor support" ON) +option(WITH_XCURSOR "xcb-cursor support" ON) if(CMAKE_BUILD_TYPE_UPPER MATCHES DEBUG) option(DEBUG_LOGGER "Debug logging" ON) diff --git a/cmake/03-libs.cmake b/cmake/03-libs.cmake index e7cea39c..44ddf098 100644 --- a/cmake/03-libs.cmake +++ b/cmake/03-libs.cmake @@ -20,4 +20,4 @@ querylib(WITH_XRANDR_MONITORS "pkg-config" "xcb-randr>=1.12" libs dirs) querylib(WITH_XRENDER "pkg-config" xcb-render libs dirs) querylib(WITH_XRM "pkg-config" xcb-xrm libs dirs) querylib(WITH_XSYNC "pkg-config" xcb-sync libs dirs) -querylib(WITH_CURSOR "pkg-config" xcb-cursor libs dirs) +querylib(WITH_XCURSOR "pkg-config" xcb-cursor libs dirs) diff --git a/cmake/05-summary.cmake b/cmake/05-summary.cmake index f56b13ee..0e3924c9 100644 --- a/cmake/05-summary.cmake +++ b/cmake/05-summary.cmake @@ -28,7 +28,7 @@ colored_option(" xcb-sync" WITH_XSYNC) colored_option(" xcb-composite" WITH_XCOMPOSITE) colored_option(" xcb-xkb" WITH_XKB) colored_option(" xcb-xrm" WITH_XRM) -colored_option(" xcb-cursor" WITH_CURSOR) +colored_option(" xcb-cursor" WITH_XCURSOR) if(CMAKE_BUILD_TYPE_UPPER MATCHES DEBUG) message(STATUS " Debug options:") diff --git a/include/components/bar.hpp b/include/components/bar.hpp index cf90c5b3..8e5d1762 100644 --- a/include/components/bar.hpp +++ b/include/components/bar.hpp @@ -28,7 +28,11 @@ class tray_manager; class bar : public xpp::event::sink, public signal_receiver { + signals::ui::shade_window, signals::ui::unshade_window, signals::ui::dim_window +#if WITH_XCURSOR + , signals::ui::cursor_change +#endif + > { public: using make_type = unique_ptr; static make_type make(bool only_initialize_values = false); @@ -66,7 +70,9 @@ class bar : public xpp::event::sink diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 04a8a490..d2ef77fd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -49,6 +49,9 @@ endif() if(NOT WITH_XRM) list(REMOVE_ITEM files x11/xresources.cpp) endif() +if(NOT WITH_XCURSOR) + list(REMOVE_ITEM files x11/cursor.cpp) +endif() # }}} diff --git a/src/components/bar.cpp b/src/components/bar.cpp index 6274a5bb..616f7ac3 100644 --- a/src/components/bar.cpp +++ b/src/components/bar.cpp @@ -16,12 +16,15 @@ #include "utils/string.hpp" #include "x11/atoms.hpp" #include "x11/connection.hpp" -#include "x11/cursor.hpp" #include "x11/ewmh.hpp" #include "x11/extensions/all.hpp" #include "x11/icccm.hpp" #include "x11/tray_manager.hpp" +#if WITH_XCURSOR +#include "x11/cursor.hpp" +#endif + #if ENABLE_I3 #include "utils/i3.hpp" #endif @@ -597,7 +600,7 @@ void bar::handle(const evt::leave_notify&) { */ void bar::handle(const evt::motion_notify& evt) { m_log.trace("bar: Detected motion: %i at pos(%i, %i)", evt->detail, evt->event_x, evt->event_y); - +#if WITH_XCURSOR m_motion_pos = evt->event_x; // scroll cursor is less important than click cursor, so we shouldn't return until we are sure there is no click action bool found_scroll = false; @@ -651,7 +654,7 @@ void bar::handle(const evt::motion_notify& evt) { m_sig.emit(cursor_change{string{m_opts.cursor}}); return; } - +#endif } /** @@ -909,6 +912,7 @@ bool bar::on(const signals::ui::dim_window& sig) { return false; } +#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())) { m_log.warn("Failed to create cursor context"); @@ -916,5 +920,6 @@ bool bar::on(const signals::ui::cursor_change& sig) { m_connection.flush(); return false; } +#endif POLYBAR_NS_END From 014a9f4c318a97973da6dd66e58f1efc49f4e12b Mon Sep 17 00:00:00 2001 From: NBonaparte Date: Wed, 6 Sep 2017 00:07:49 -0700 Subject: [PATCH 3/9] fix(travis): Install xcb-util-cursor --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 61045757..d5a31130 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,6 +29,7 @@ addons: - libxcb-randr0-dev - libxcb-util0-dev - libxcb-xkb-dev + - libxcb-cursor-dev - libxcb1-dev - python-xcbgen - xcb-proto From 1886cf97a8dcbded3673a64945596a83590c1d02 Mon Sep 17 00:00:00 2001 From: NBonaparte Date: Wed, 6 Sep 2017 15:18:56 -0700 Subject: [PATCH 4/9] fix: pass action by reference --- src/components/bar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/bar.cpp b/src/components/bar.cpp index 616f7ac3..d16cce65 100644 --- a/src/components/bar.cpp +++ b/src/components/bar.cpp @@ -604,7 +604,7 @@ void bar::handle(const evt::motion_notify& evt) { m_motion_pos = evt->event_x; // scroll cursor is less important than click cursor, so we shouldn't return until we are sure there is no click action bool found_scroll = false; - const auto find_click_area = [&](action action) { + const auto find_click_area = [&](const action& action) { if (!m_opts.cursor_click.empty() && (action.button == mousebtn::LEFT || action.button == mousebtn::MIDDLE || action.button == mousebtn::RIGHT)) { if (!string_util::compare(m_opts.cursor, m_opts.cursor_click)) { From b7f1960a0a70795dc3179727d856efd61ebb03aa Mon Sep 17 00:00:00 2001 From: NBonaparte Date: Fri, 8 Sep 2017 13:38:24 -0700 Subject: [PATCH 5/9] fix(cursor): change arrow_names to default_names --- include/x11/cursor.hpp | 2 +- src/x11/cursor.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/x11/cursor.hpp b/include/x11/cursor.hpp index c9df4e0e..7be50c89 100644 --- a/include/x11/cursor.hpp +++ b/include/x11/cursor.hpp @@ -16,7 +16,7 @@ POLYBAR_NS namespace cursor_util { static const vector pointer_names {"pointing_hand", "pointer", "hand", "hand1", "hand2", "e29285e634086352946a0e7090d73106", "9d800788f1b08800ae810202380a0822"}; - static const vector arrow_names {"left_ptr", "arrow", "dnd-none", "op_left_arrow"}; + static const vector default_names {"left_ptr", "arrow", "dnd-none", "op_left_arrow"}; static const vector ns_resize_names {"size_ver", "sb_v_double_arrow", "v_double_arrow", "n-resize", "s-resize", "col-resize", "top_side", "bottom_side", "base_arrow_up", "base_arrow_down", "based_arrow_down", "based_arrow_up", "00008160000006810000408080010102"}; bool set_cursor(xcb_connection_t *c, xcb_screen_t *screen, xcb_window_t w, string name); } diff --git a/src/x11/cursor.cpp b/src/x11/cursor.cpp index 708154b0..01d7d7a9 100644 --- a/src/x11/cursor.cpp +++ b/src/x11/cursor.cpp @@ -16,8 +16,8 @@ namespace cursor_util { name_list = &pointer_names; } else if (string_util::compare("ns-resize", name)) { name_list = &ns_resize_names; - } else { //default - name_list = &arrow_names; + } else { + name_list = &default_names; } for (auto&& cursor_name : *name_list) { From e612fe16240478c3c7dfdd80c337c28898bcf38b Mon Sep 17 00:00:00 2001 From: NBonaparte Date: Fri, 8 Sep 2017 16:45:16 -0700 Subject: [PATCH 6/9] refactor(cursor): use map for cursor list --- include/x11/cursor.hpp | 9 ++++++--- src/components/bar.cpp | 11 +++++++++++ src/x11/cursor.cpp | 18 +++++++----------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/include/x11/cursor.hpp b/include/x11/cursor.hpp index 7be50c89..514aa1eb 100644 --- a/include/x11/cursor.hpp +++ b/include/x11/cursor.hpp @@ -15,9 +15,12 @@ POLYBAR_NS namespace cursor_util { - static const vector pointer_names {"pointing_hand", "pointer", "hand", "hand1", "hand2", "e29285e634086352946a0e7090d73106", "9d800788f1b08800ae810202380a0822"}; - static const vector default_names {"left_ptr", "arrow", "dnd-none", "op_left_arrow"}; - static const vector ns_resize_names {"size_ver", "sb_v_double_arrow", "v_double_arrow", "n-resize", "s-resize", "col-resize", "top_side", "bottom_side", "base_arrow_up", "base_arrow_down", "based_arrow_down", "based_arrow_up", "00008160000006810000408080010102"}; + static const map> cursors = { + {"pointer", {"pointing_hand", "pointer", "hand", "hand1", "hand2", "e29285e634086352946a0e7090d73106", "9d800788f1b08800ae810202380a0822"}}, + {"default", {"left_ptr", "arrow", "dnd-none", "op_left_arrow"}}, + {"ns-resize", {"size_ver", "sb_v_double_arrow", "v_double_arrow", "n-resize", "s-resize", "col-resize", "top_side", "bottom_side", "base_arrow_up", "base_arrow_down", "based_arrow_down", "based_arrow_up", "00008160000006810000408080010102"}} + }; + bool valid(string name); bool set_cursor(xcb_connection_t *c, xcb_screen_t *screen, xcb_window_t w, string name); } diff --git a/src/components/bar.cpp b/src/components/bar.cpp index d16cce65..adb2c32b 100644 --- a/src/components/bar.cpp +++ b/src/components/bar.cpp @@ -132,6 +132,17 @@ bar::bar(connection& conn, signal_emitter& emitter, const config& config, const m_opts.cursor_click = m_conf.get(bs, "cursor-click", ""s); m_opts.cursor_scroll = m_conf.get(bs, "cursor-scroll", ""s); +#if WITH_XCURSOR + if (!m_opts.cursor_click.empty() && !cursor_util::valid(m_opts.cursor_click)) { + m_log.warn("Ignoring unsupported cursor-click option '%s'", m_opts.cursor_click); + m_opts.cursor_click.clear(); + } + if (!m_opts.cursor_scroll.empty() && !cursor_util::valid(m_opts.cursor_scroll)) { + m_log.warn("Ignoring unsupported cursor-scroll option '%s'", m_opts.cursor_scroll); + m_opts.cursor_scroll.clear(); + } +#endif + // Build WM_NAME m_opts.wmname = m_conf.get(bs, "wm-name", "polybar-" + bs.substr(4) + "_" + m_opts.monitor->name); m_opts.wmname = string_util::replace(m_opts.wmname, " ", "-"); diff --git a/src/x11/cursor.cpp b/src/x11/cursor.cpp index 01d7d7a9..8ecdcb1d 100644 --- a/src/x11/cursor.cpp +++ b/src/x11/cursor.cpp @@ -3,6 +3,12 @@ POLYBAR_NS namespace cursor_util { + bool valid(string name) { + if (cursors.find(name) != cursors.end()) + return true; + return false; + } + bool set_cursor(xcb_connection_t *c, xcb_screen_t *screen, xcb_window_t w, string name) { xcb_cursor_t cursor = XCB_CURSOR_NONE; xcb_cursor_context_t *ctx; @@ -10,17 +16,7 @@ namespace cursor_util { if (xcb_cursor_context_new(c, screen, &ctx) < 0) { return false; } - - const vector *name_list; - if (string_util::compare("pointer", name)) { - name_list = &pointer_names; - } else if (string_util::compare("ns-resize", name)) { - name_list = &ns_resize_names; - } else { - name_list = &default_names; - } - - for (auto&& cursor_name : *name_list) { + for (auto&& cursor_name : cursors.at(name)) { cursor = xcb_cursor_load_cursor(ctx, cursor_name.c_str()); if (cursor != XCB_CURSOR_NONE) break; From 81c83c4364bbc96fcf00fb8d247f8b94fea2d269 Mon Sep 17 00:00:00 2001 From: NBonaparte Date: Mon, 11 Sep 2017 20:26:00 -0700 Subject: [PATCH 7/9] fix(aur): Add xcb-util-cursor as dep --- contrib/polybar-git.aur/PKGBUILD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/polybar-git.aur/PKGBUILD b/contrib/polybar-git.aur/PKGBUILD index 02e004f8..7cc43c9f 100644 --- a/contrib/polybar-git.aur/PKGBUILD +++ b/contrib/polybar-git.aur/PKGBUILD @@ -3,12 +3,12 @@ _pkgname=polybar pkgname="${_pkgname}-git" pkgver=3.0.5 -pkgrel=3 +pkgrel=4 pkgdesc="A fast and easy-to-use status bar" arch=("i686" "x86_64") url="https://github.com/jaagr/polybar" license=("MIT") -depends=("cairo" "xcb-util-image" "xcb-util-wm" "xcb-util-xrm") +depends=("cairo" "xcb-util-image" "xcb-util-wm" "xcb-util-xrm" "xcb-util-cursor") optdepends=("alsa-lib: volume module support" "libmpdclient: mpd module support" "wireless_tools: network module support" From 70023b07c172e0d26cde59aa0853925b8658f51f Mon Sep 17 00:00:00 2001 From: NBonaparte Date: Sat, 16 Sep 2017 19:17:07 -0700 Subject: [PATCH 8/9] refactor(cursor): Include double clicks and fix scroll to click changes --- src/components/bar.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/components/bar.cpp b/src/components/bar.cpp index adb2c32b..6e7dfbe0 100644 --- a/src/components/bar.cpp +++ b/src/components/bar.cpp @@ -616,8 +616,7 @@ 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 action bool found_scroll = false; const auto find_click_area = [&](const action& action) { - if (!m_opts.cursor_click.empty() && - (action.button == mousebtn::LEFT || action.button == mousebtn::MIDDLE || action.button == mousebtn::RIGHT)) { + if (!m_opts.cursor_click.empty() && !(action.button == mousebtn::SCROLL_UP || action.button == mousebtn::SCROLL_DOWN || action.button == mousebtn::NONE)) { if (!string_util::compare(m_opts.cursor, m_opts.cursor_click)) { m_opts.cursor = m_opts.cursor_click; m_sig.emit(cursor_change{string{m_opts.cursor}}); @@ -625,11 +624,7 @@ void bar::handle(const evt::motion_notify& evt) { return true; } else if (!m_opts.cursor_scroll.empty() && (action.button == mousebtn::SCROLL_UP || action.button == mousebtn::SCROLL_DOWN)) { if (!found_scroll) { - if (!string_util::compare(m_opts.cursor, m_opts.cursor_scroll)) { found_scroll = true; - } else { - return true; - } } } return false; @@ -643,8 +638,10 @@ void bar::handle(const evt::motion_notify& evt) { } } if(found_scroll) { - m_opts.cursor = m_opts.cursor_scroll; - m_sig.emit(cursor_change{string{m_opts.cursor}}); + if (!string_util::compare(m_opts.cursor, m_opts.cursor_scroll)) { + m_opts.cursor = m_opts.cursor_scroll; + m_sig.emit(cursor_change{string{m_opts.cursor}}); + } return; } for (auto&& action : m_opts.actions) { @@ -655,8 +652,10 @@ void bar::handle(const evt::motion_notify& evt) { } } if(found_scroll) { - m_opts.cursor = m_opts.cursor_scroll; - m_sig.emit(cursor_change{string{m_opts.cursor}}); + if (!string_util::compare(m_opts.cursor, m_opts.cursor_scroll)) { + m_opts.cursor = m_opts.cursor_scroll; + m_sig.emit(cursor_change{string{m_opts.cursor}}); + } return; } if (!string_util::compare(m_opts.cursor, "default")) { From 60f8451b3449387bd7a3ff01f7f4be67d1b69b6e Mon Sep 17 00:00:00 2001 From: NBonaparte Date: Sun, 17 Sep 2017 13:17:04 -0700 Subject: [PATCH 9/9] fix(docs): Add cursor options to example --- doc/config.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/config.cmake b/doc/config.cmake index 37930853..462fc93f 100644 --- a/doc/config.cmake +++ b/doc/config.cmake @@ -66,6 +66,9 @@ tray-padding = 2 ;scroll-up = i3wm-wsnext ;scroll-down = i3wm-wsprev +cursor-click = pointer +cursor-scroll = ns-resize + [module/xwindow] type = internal/xwindow label = %title:0:30:...%