feat: add cursor change

This commit is contained in:
NBonaparte 2017-09-02 21:45:45 -07:00
parent a682d2af91
commit 65edba3321
10 changed files with 150 additions and 4 deletions
src/components

View file

@ -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