src/components/bar.cpp
/**
 * Event handler for XCB_MOTION_NOTIFY events
 *
 * Used to change the cursor depending on the module
 */
Event handler for XCB_MOTION_NOTIFY events
Used to change the cursor depending on the module
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);
#if WITH_XCURSOR
  m_motion_pos = evt->event_x;
  bool found_scroll = false;
  const auto has_action = [&](const vector<mousebtn>& buttons) -> bool {
    for (auto btn : buttons) {
      if (m_action_ctxt->has_action(btn, m_motion_pos) != tags::NO_ACTION) {
        return true;
      }
    }
    return false;
  };
  if (has_action({mousebtn::LEFT, mousebtn::MIDDLE, mousebtn::RIGHT, mousebtn::DOUBLE_LEFT, mousebtn::DOUBLE_MIDDLE,
          mousebtn::DOUBLE_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;
  }
  if (has_action({mousebtn::SCROLL_DOWN, mousebtn::SCROLL_UP})) {
    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;
  }
  const auto find_click_area = [&](const action& action) {
    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}});
      }
      return true;
    } else if (!m_opts.cursor_scroll.empty() &&
               (action.button == mousebtn::SCROLL_UP || action.button == mousebtn::SCROLL_DOWN)) {
      if (!found_scroll) {
        found_scroll = true;
      }
    }
    return false;
  };
  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) {
    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")) {
    m_log.trace("No matching cursor area found");
    m_opts.cursor = "default";
    m_sig.emit(cursor_change{string{m_opts.cursor}});
    return;
  }
#endif
}
void bar :: handle ( const evt :: motion_notify & evt ) { m_log . trace ( " " , evt -> detail , evt -> event_x , evt -> event_y ) ; #if WITH_XCURSOR m_motion_pos = evt -> event_x ; bool found_scroll = false ; const auto has_action = [ & ] ( const vector < mousebtn > & buttons ) -> bool { for ( auto btn : buttons ) { if ( m_action_ctxt -> has_action ( btn , m_motion_pos ) != tags :: NO_ACTION ) { return true ; } } return false ; } ; if ( has_action ( { mousebtn :: LEFT , mousebtn :: MIDDLE , mousebtn :: RIGHT , mousebtn :: DOUBLE_LEFT , mousebtn :: DOUBLE_MIDDLE , mousebtn :: DOUBLE_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 ; } if ( has_action ( { mousebtn :: SCROLL_DOWN , mousebtn :: SCROLL_UP } ) ) { 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 ; } const auto find_click_area = [ & ] ( const action & action ) { 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 } } ) ; } return true ; } else if ( ! m_opts . cursor_scroll . empty ( ) && ( action . button == mousebtn :: SCROLL_UP || action . button == mousebtn :: SCROLL_DOWN ) ) { if ( ! found_scroll ) { found_scroll = true ; } } return false ; } ; for ( auto && action : m_opts . actions ) { if ( ! action . command . empty ( ) ) { m_log . trace ( " " ) ; if ( find_click_area ( action ) ) return ; } } if ( found_scroll ) { 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 , " " ) ) { m_log . trace ( " " ) ; m_opts . cursor = " " ; m_sig . emit ( cursor_change { string { m_opts . cursor } } ) ; return ; } #endif }
Event handler for XCB_MOTION_NOTIFY events
 Used to change the cursor depending on the module
Event handler for XCB_MOTION_NOTIFY events Used to change the cursor depending on the module
// scroll cursor is less important than click cursor, so we shouldn't return until we are sure there is no click // action