Added -hover-select option that automatically selects the entry under the cursor (#1234)

This commit is contained in:
rahulaggarwal965 2021-04-13 05:45:20 -04:00 committed by GitHub
parent 318a6d40ca
commit e304dbc883
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 70 additions and 12 deletions

View File

@ -722,6 +722,19 @@ rofi \-show run \-sidebar\-mode \-lines 0
.fi
.RE
.PP
Automatically select the entry the mouse is hovering over. This option is best combined with custom mouse bindings.
To utilize hover\-select and accept an entry in a single click, use:
.PP
.RS
.nf
rofi \-show run \-hover\-select \-me\-select\-entry '' -me\-accept\-entry MousePrimary
.fi
.RE
.PP
\fB\fC\-eh\fR \fInumber\fP

View File

@ -411,6 +411,13 @@ To show sidebar, use:
rofi -show run -sidebar-mode -lines 0
`-hover-select`
Automatically select the entry the mouse is hovering over. This option is best combined with custom mouse bindings.
To utilize hover-select and accept an entry in a single click, use:
rofi -show run -hover-select -me-select-entry '' -me-accept-entry MousePrimary
`-eh` *number*
Set row height (in chars)

View File

@ -139,6 +139,8 @@ typedef struct
int element_height;
/** Sidebar mode, show the modi */
unsigned int sidebar_mode;
/** Mouse hover automatically selects */
unsigned int hover_select;
/** Lazy filter limit. */
unsigned int lazy_filter_limit;
/** Auto select. */

View File

@ -100,10 +100,11 @@ void rofi_view_handle_text ( RofiViewState *state, char *text );
* @param state the Menu handle
* @param x The X coordinates of the motion
* @param y The Y coordinates of the motion
* @param find_mouse_target if we should handle pure mouse motion
*
* Update the state if needed.
*/
void rofi_view_handle_mouse_motion ( RofiViewState *state, gint x, gint y );
void rofi_view_handle_mouse_motion ( RofiViewState *state, gint x, gint y, gboolean find_mouse_target );
/**
* @param state the Menu handle
*

View File

@ -737,14 +737,18 @@ static void rofi_view_setup_fake_transparency ( widget *win, const char* const f
}
void __create_window ( MenuFlags menu_flags )
{
uint32_t selmask = XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY | XCB_CW_BACKING_STORE | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP;
uint32_t selmask = XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY | XCB_CW_BACKING_STORE | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP;
uint32_t xcb_event_masks = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE |
XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_KEYMAP_STATE |
XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_BUTTON_1_MOTION;
if ( config.hover_select == TRUE ) {
xcb_event_masks |= XCB_EVENT_MASK_POINTER_MOTION;
}
uint32_t selval[] = {
XCB_BACK_PIXMAP_NONE, 0,
XCB_BACK_PIXMAP_NONE, 0,
XCB_GRAVITY_STATIC,
XCB_BACKING_STORE_NOT_USEFUL,
XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE |
XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_KEYMAP_STATE |
XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_BUTTON_1_MOTION,
xcb_event_masks,
map
};
@ -1488,13 +1492,22 @@ void rofi_view_handle_text ( RofiViewState *state, char *text )
}
}
void rofi_view_handle_mouse_motion ( RofiViewState *state, gint x, gint y )
void rofi_view_handle_mouse_motion ( RofiViewState *state, gint x, gint y, gboolean find_mouse_target )
{
state->mouse.x = x;
state->mouse.y = y;
if ( find_mouse_target ) {
widget *target = widget_find_mouse_target ( WIDGET ( state->main_window ), SCOPE_MOUSE_LISTVIEW_ELEMENT, x, y );
if ( target != NULL ) {
state->mouse.motion_target = target;
}
}
if ( state->mouse.motion_target != NULL ) {
widget_xy_to_relative ( state->mouse.motion_target, &x, &y );
widget_motion_notify ( state->mouse.motion_target, x, y );
if ( find_mouse_target ) {
state->mouse.motion_target = NULL;
}
}
}

View File

@ -467,6 +467,7 @@ static void listview_draw ( widget *wid, cairo_t *draw )
widget_draw ( WIDGET ( lv->scrollbar ), draw );
}
static WidgetTriggerActionResult listview_element_trigger_action ( widget *wid, MouseBindingListviewElementAction action, gint x, gint y, void *user_data );
static gboolean listview_element_motion_notify ( widget *wid, gint x, gint y );
static void _listview_draw ( widget *wid, cairo_t *draw )
{
@ -502,7 +503,12 @@ static void listview_recompute_elements ( listview *lv )
if ( newne > 0 ) {
for ( unsigned int i = lv->cur_elements; i < newne; i++ ) {
listview_create_row ( lv, &( lv->boxes[i] ) );
widget_set_trigger_action_handler ( WIDGET ( lv->boxes[i].box ), listview_element_trigger_action, lv );
widget *wid = WIDGET ( lv->boxes[i].box );
widget_set_trigger_action_handler ( wid, listview_element_trigger_action, lv );
if ( wid != NULL ) {
wid->motion_notify = listview_element_motion_notify;
}
listview_set_state ( lv->boxes[i], NORMAL );
}
}
@ -640,6 +646,19 @@ static WidgetTriggerActionResult listview_element_trigger_action ( widget *wid,
return WIDGET_TRIGGER_ACTION_RESULT_HANDLED;
}
static gboolean listview_element_motion_notify ( widget *wid, G_GNUC_UNUSED gint x, G_GNUC_UNUSED gint y )
{
listview *lv = (listview *) wid->parent;
unsigned int max = MIN ( lv->cur_elements, lv->req_elements - lv->last_offset );
unsigned int i;
for ( i = 0; i < max && WIDGET ( lv->boxes[i].box ) != wid; i++ ) {
}
if ( i < max && i != listview_get_selected ( lv ) ) {
listview_set_selected ( lv, lv->last_offset + i );
}
return TRUE;
}
listview *listview_create ( widget *parent, const char *name, listview_update_callback cb, void *udata, unsigned int eh, gboolean reverse )
{
listview *lv = g_malloc0 ( sizeof ( listview ) );

View File

@ -1052,11 +1052,12 @@ static void main_loop_x11_event_handler_view ( xcb_generic_event_t *event )
}
case XCB_MOTION_NOTIFY:
{
if ( config.click_to_exit == TRUE ) {
xcb_motion_notify_event_t *xme = (xcb_motion_notify_event_t *) event;
gboolean button_mask = xme->state & XCB_EVENT_MASK_BUTTON_1_MOTION;
if ( button_mask && config.click_to_exit == TRUE ) {
xcb->mouse_seen = TRUE;
}
xcb_motion_notify_event_t *xme = (xcb_motion_notify_event_t *) event;
rofi_view_handle_mouse_motion ( state, xme->event_x, xme->event_y );
rofi_view_handle_mouse_motion ( state, xme->event_x, xme->event_y, !button_mask );
break;
}
case XCB_BUTTON_PRESS:
@ -1067,7 +1068,7 @@ static void main_loop_x11_event_handler_view ( xcb_generic_event_t *event )
gint32 steps;
xcb->last_timestamp = bpe->time;
rofi_view_handle_mouse_motion ( state, bpe->event_x, bpe->event_y );
rofi_view_handle_mouse_motion ( state, bpe->event_x, bpe->event_y, FALSE );
if ( x11_button_to_nk_bindings_button ( bpe->detail, &button ) ) {
nk_bindings_seat_handle_button ( xcb->bindings_seat, NULL, button, NK_BINDINGS_BUTTON_STATE_PRESS, bpe->time );
}

View File

@ -158,6 +158,8 @@ static XrmOption xrmOptions[] = {
"Cycle through the results list", CONFIG_DEFAULT },
{ xrm_Boolean, "sidebar-mode", { .num = &config.sidebar_mode }, NULL,
"Enable sidebar-mode", CONFIG_DEFAULT },
{ xrm_Boolean, "hover-select", { .num = &config.hover_select }, NULL,
"Enable hover-select", CONFIG_DEFAULT },
{ xrm_SNumber, "eh", { .snum = &config.element_height }, NULL,
"Row height (in chars)", CONFIG_DEFAULT },
{ xrm_Boolean, "auto-select", { .num = &config.auto_select }, NULL,