mirror of
https://github.com/davatorium/rofi.git
synced 2024-11-18 13:54:36 -05:00
Added -hover-select option that automatically selects the entry under the cursor (#1234)
This commit is contained in:
parent
318a6d40ca
commit
e304dbc883
8 changed files with 70 additions and 12 deletions
13
doc/rofi.1
13
doc/rofi.1
|
@ -722,6 +722,19 @@ rofi \-show run \-sidebar\-mode \-lines 0
|
||||||
.fi
|
.fi
|
||||||
.RE
|
.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
|
.PP
|
||||||
\fB\fC\-eh\fR \fInumber\fP
|
\fB\fC\-eh\fR \fInumber\fP
|
||||||
|
|
||||||
|
|
|
@ -411,6 +411,13 @@ To show sidebar, use:
|
||||||
|
|
||||||
rofi -show run -sidebar-mode -lines 0
|
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*
|
`-eh` *number*
|
||||||
|
|
||||||
Set row height (in chars)
|
Set row height (in chars)
|
||||||
|
|
|
@ -139,6 +139,8 @@ typedef struct
|
||||||
int element_height;
|
int element_height;
|
||||||
/** Sidebar mode, show the modi */
|
/** Sidebar mode, show the modi */
|
||||||
unsigned int sidebar_mode;
|
unsigned int sidebar_mode;
|
||||||
|
/** Mouse hover automatically selects */
|
||||||
|
unsigned int hover_select;
|
||||||
/** Lazy filter limit. */
|
/** Lazy filter limit. */
|
||||||
unsigned int lazy_filter_limit;
|
unsigned int lazy_filter_limit;
|
||||||
/** Auto select. */
|
/** Auto select. */
|
||||||
|
|
|
@ -100,10 +100,11 @@ void rofi_view_handle_text ( RofiViewState *state, char *text );
|
||||||
* @param state the Menu handle
|
* @param state the Menu handle
|
||||||
* @param x The X coordinates of the motion
|
* @param x The X coordinates of the motion
|
||||||
* @param y The Y 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.
|
* 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
|
* @param state the Menu handle
|
||||||
*
|
*
|
||||||
|
|
|
@ -737,14 +737,18 @@ static void rofi_view_setup_fake_transparency ( widget *win, const char* const f
|
||||||
}
|
}
|
||||||
void __create_window ( MenuFlags menu_flags )
|
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[] = {
|
uint32_t selval[] = {
|
||||||
XCB_BACK_PIXMAP_NONE, 0,
|
XCB_BACK_PIXMAP_NONE, 0,
|
||||||
XCB_GRAVITY_STATIC,
|
XCB_GRAVITY_STATIC,
|
||||||
XCB_BACKING_STORE_NOT_USEFUL,
|
XCB_BACKING_STORE_NOT_USEFUL,
|
||||||
XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE |
|
xcb_event_masks,
|
||||||
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,
|
|
||||||
map
|
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.x = x;
|
||||||
state->mouse.y = y;
|
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 ) {
|
if ( state->mouse.motion_target != NULL ) {
|
||||||
widget_xy_to_relative ( state->mouse.motion_target, &x, &y );
|
widget_xy_to_relative ( state->mouse.motion_target, &x, &y );
|
||||||
widget_motion_notify ( state->mouse.motion_target, x, y );
|
widget_motion_notify ( state->mouse.motion_target, x, y );
|
||||||
|
if ( find_mouse_target ) {
|
||||||
|
state->mouse.motion_target = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -467,6 +467,7 @@ static void listview_draw ( widget *wid, cairo_t *draw )
|
||||||
widget_draw ( WIDGET ( lv->scrollbar ), 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 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 )
|
static void _listview_draw ( widget *wid, cairo_t *draw )
|
||||||
{
|
{
|
||||||
|
@ -502,7 +503,12 @@ static void listview_recompute_elements ( listview *lv )
|
||||||
if ( newne > 0 ) {
|
if ( newne > 0 ) {
|
||||||
for ( unsigned int i = lv->cur_elements; i < newne; i++ ) {
|
for ( unsigned int i = lv->cur_elements; i < newne; i++ ) {
|
||||||
listview_create_row ( lv, &( lv->boxes[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 );
|
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;
|
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 *listview_create ( widget *parent, const char *name, listview_update_callback cb, void *udata, unsigned int eh, gboolean reverse )
|
||||||
{
|
{
|
||||||
listview *lv = g_malloc0 ( sizeof ( listview ) );
|
listview *lv = g_malloc0 ( sizeof ( listview ) );
|
||||||
|
|
|
@ -1052,11 +1052,12 @@ static void main_loop_x11_event_handler_view ( xcb_generic_event_t *event )
|
||||||
}
|
}
|
||||||
case XCB_MOTION_NOTIFY:
|
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->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, !button_mask );
|
||||||
rofi_view_handle_mouse_motion ( state, xme->event_x, xme->event_y );
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case XCB_BUTTON_PRESS:
|
case XCB_BUTTON_PRESS:
|
||||||
|
@ -1067,7 +1068,7 @@ static void main_loop_x11_event_handler_view ( xcb_generic_event_t *event )
|
||||||
gint32 steps;
|
gint32 steps;
|
||||||
|
|
||||||
xcb->last_timestamp = bpe->time;
|
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 ) ) {
|
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 );
|
nk_bindings_seat_handle_button ( xcb->bindings_seat, NULL, button, NK_BINDINGS_BUTTON_STATE_PRESS, bpe->time );
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,6 +158,8 @@ static XrmOption xrmOptions[] = {
|
||||||
"Cycle through the results list", CONFIG_DEFAULT },
|
"Cycle through the results list", CONFIG_DEFAULT },
|
||||||
{ xrm_Boolean, "sidebar-mode", { .num = &config.sidebar_mode }, NULL,
|
{ xrm_Boolean, "sidebar-mode", { .num = &config.sidebar_mode }, NULL,
|
||||||
"Enable sidebar-mode", CONFIG_DEFAULT },
|
"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,
|
{ xrm_SNumber, "eh", { .snum = &config.element_height }, NULL,
|
||||||
"Row height (in chars)", CONFIG_DEFAULT },
|
"Row height (in chars)", CONFIG_DEFAULT },
|
||||||
{ xrm_Boolean, "auto-select", { .num = &config.auto_select }, NULL,
|
{ xrm_Boolean, "auto-select", { .num = &config.auto_select }, NULL,
|
||||||
|
|
Loading…
Reference in a new issue