예제 #1
0
파일: dmenu.c 프로젝트: domidimi/rofi
int dmenu_switcher_dialog ( void )
{
    mode_init ( &dmenu_mode );
    MenuFlags            menu_flags      = MENU_NORMAL;
    DmenuModePrivateData *pd             = (DmenuModePrivateData *) dmenu_mode.private_data;
    char                 *input          = NULL;
    unsigned int         cmd_list_length = pd->cmd_list_length;
    char                 **cmd_list      = pd->cmd_list;

    pd->only_selected = FALSE;
    if ( find_arg ( "-markup-rows" ) >= 0 ) {
        pd->do_markup = TRUE;
    }
    if ( find_arg ( "-only-match" ) >= 0 || find_arg ( "-no-custom" ) >= 0 ) {
        pd->only_selected = TRUE;
        if ( cmd_list_length == 0 ) {
            return TRUE;
        }
    }
    if ( config.auto_select && cmd_list_length == 1 ) {
        dmenu_output_formatted_line ( pd->format, cmd_list[0], 0, config.filter );
        return TRUE;
    }
    if ( find_arg ( "-password" ) >= 0 ) {
        menu_flags |= MENU_PASSWORD;
    }
    /* copy filter string */
    input = g_strdup ( config.filter );

    char *select = NULL;
    find_arg_str ( "-select", &select );
    if ( select != NULL ) {
        char         **tokens = tokenize ( select, config.case_sensitive );
        unsigned int i        = 0;
        for ( i = 0; i < cmd_list_length; i++ ) {
            if ( token_match ( tokens, cmd_list[i], !g_str_is_ascii ( cmd_list[i] ), config.case_sensitive ) ) {
                pd->selected_line = i;
                break;
            }
        }
        g_strfreev ( tokens );
    }
    if ( find_arg ( "-dump" ) >= 0 ) {
        char         **tokens = tokenize ( config.filter ? config.filter : "", config.case_sensitive );
        unsigned int i        = 0;
        for ( i = 0; i < cmd_list_length; i++ ) {
            if ( token_match ( tokens, cmd_list[i], !g_str_is_ascii ( cmd_list[i] ), config.case_sensitive ) ) {
                dmenu_output_formatted_line ( pd->format, cmd_list[i], i, config.filter );
            }
        }
        g_strfreev ( tokens );
        return TRUE;
    }
    // TODO remove
    RofiViewState *state = rofi_view_create ( &dmenu_mode, input, pd->prompt, pd->message, menu_flags, dmenu_finalize );
    rofi_view_set_selected_line ( state, pd->selected_line );
    rofi_view_set_active ( state );

    return FALSE;
}
예제 #2
0
파일: dmenu.c 프로젝트: Tarrasch/rofi
int dmenu_switcher_dialog ( char **input )
{
    char          *dmenu_prompt = "dmenu ";
    int           selected_line = -1;
    int           retv          = FALSE;
    int           length        = 0;
    char          **list        = get_dmenu ( &length );
    int           restart       = FALSE;
    char          *message      = NULL;
    menu_match_cb filter        = token_match;

    find_arg_str ( "-mesg", &message );

    // By default we print the unescaped line back.
    char *format = "s";
    // This is here for compatibility reason.
    // Use -format 'i' instead.
    if ( find_arg (  "-i" ) >= 0 ) {
        format = "i";
    }
    // Allow user to override the output format.
    find_arg_str ( "-format", &format );
    // Check prompt
    find_arg_str (  "-p", &dmenu_prompt );
    find_arg_int (  "-l", &selected_line );
    // Urgent.
    char *str = NULL;
    find_arg_str (  "-u", &str );
    if ( str != NULL ) {
        parse_ranges ( str, &urgent_list, &num_urgent_list );
    }
    // Active
    str = NULL;
    find_arg_str (  "-a", &str );
    if ( str != NULL ) {
        parse_ranges ( str, &active_list, &num_active_list );
    }

    int only_selected = FALSE;
    if ( find_arg ( "-only-match" ) >= 0 || find_arg ( "-no-custom" ) >= 0 ) {
        only_selected = TRUE;
        if ( length == 0 ) {
            return TRUE;
        }
    }
    find_arg_str_alloc ( "-filter", input );

    if ( find_arg ( "-z" ) >= 0 ) {
        filter = fuzzy_token_match;
    }

    char *select = NULL;
    find_arg_str ( "-select", &select );
    if ( select != NULL ) {
        char **tokens = tokenize ( select, config.case_sensitive );
        int  i        = 0;
        for ( i = 0; i < length; i++ ) {
            if ( token_match ( tokens, list[i], config.case_sensitive, 0, NULL ) ) {
                selected_line = i;
                break;
            }
        }
        g_strfreev ( tokens );
    }

    do {
        int next_pos = selected_line;
        int mretv    = menu ( list, length, input, dmenu_prompt,
                              filter, NULL, &selected_line, config.levenshtein_sort, get_display_data, list, &next_pos, message );
        // Special behavior.
        if ( only_selected ) {
            /**
             * Select item mode.
             */
            restart = ( find_arg ( "-only-match" ) >= 0 );
            if ( ( mretv & ( MENU_OK | MENU_QUICK_SWITCH ) ) && list[selected_line] != NULL ) {
                dmenu_output_formatted_line ( format, list[selected_line], selected_line, *input );
                retv = TRUE;
                if ( ( mretv & MENU_QUICK_SWITCH ) ) {
                    retv = 10 + ( mretv & MENU_LOWER_MASK );
                }
                return retv;
            }
            selected_line = next_pos - 1;
            continue;
        }
        // We normally do not want to restart the loop.
        restart = FALSE;
        // Normal mode
        if ( ( mretv & MENU_OK  ) && list[selected_line] != NULL ) {
            dmenu_output_formatted_line ( format, list[selected_line], selected_line, *input );
            if ( ( mretv & MENU_SHIFT ) ) {
                restart = TRUE;
                // Move to next line.
                selected_line = MIN ( next_pos, length - 1 );
            }
            retv = TRUE;
        }
        // Custom input
        else if ( ( mretv & ( MENU_CUSTOM_INPUT ) ) ) {
            dmenu_output_formatted_line ( format, *input, -1, *input );
            if ( ( mretv & MENU_SHIFT ) ) {
                restart = TRUE;
                // Move to next line.
                selected_line = MIN ( next_pos, length - 1 );
            }

            retv = TRUE;
        }
        // Quick switch with entry selected.
        else if ( ( mretv & MENU_QUICK_SWITCH ) && selected_line >= 0 ) {
            dmenu_output_formatted_line ( format, list[selected_line], selected_line, *input );

            restart = FALSE;
            retv    = 10 + ( mretv & MENU_LOWER_MASK );
        }
        // Quick switch without entry selected.
        else if ( ( mretv & MENU_QUICK_SWITCH ) && selected_line == -1 ) {
            dmenu_output_formatted_line ( format, *input, -1, *input );

            restart = FALSE;
            retv    = 10 + ( mretv & MENU_LOWER_MASK );
        }
    } while ( restart );

    g_strfreev ( list );
    g_free ( urgent_list );
    g_free ( active_list );

    return retv;
}
예제 #3
0
파일: dmenu.c 프로젝트: domidimi/rofi
static void dmenu_finalize ( RofiViewState *state )
{
    int                  retv            = FALSE;
    DmenuModePrivateData *pd             = (DmenuModePrivateData *) rofi_view_get_mode ( state )->private_data;
    unsigned int         cmd_list_length = pd->cmd_list_length;
    char                 **cmd_list      = pd->cmd_list;

    char                 *input = g_strdup ( rofi_view_get_user_input ( state ) );
    pd->selected_line = rofi_view_get_selected_line ( state );;
    MenuReturn           mretv    = rofi_view_get_return_value ( state );
    unsigned int         next_pos = rofi_view_get_next_position ( state );

    int                  restart = 0;
    // Special behavior.
    if ( pd->only_selected ) {
        /**
         * Select item mode.
         */
        restart = 1;
        // Skip if no valid item is selected.
        if ( ( mretv & MENU_CANCEL ) == MENU_CANCEL ) {
            // In no custom mode we allow canceling.
            restart = ( find_arg ( "-only-match" ) >= 0 );
        }
        else if ( pd->selected_line != UINT32_MAX ) {
            if ( ( mretv & ( MENU_OK | MENU_QUICK_SWITCH ) ) && cmd_list[pd->selected_line] != NULL ) {
                dmenu_output_formatted_line ( pd->format, cmd_list[pd->selected_line], pd->selected_line, input );
                retv = TRUE;
                if ( ( mretv & MENU_QUICK_SWITCH ) ) {
                    retv = 10 + ( mretv & MENU_LOWER_MASK );
                }
                g_free ( input );
                dmenu_finish ( state, retv );
                return;
            }
            pd->selected_line = next_pos - 1;
        }
        // Restart
        rofi_view_restart ( state );
        rofi_view_set_selected_line ( state, pd->selected_line );
        if ( !restart ) {
            dmenu_finish ( state, retv );
        }
        return;
    }
    // We normally do not want to restart the loop.
    restart = FALSE;
    // Normal mode
    if ( ( mretv & MENU_OK  ) && pd->selected_line != UINT32_MAX && cmd_list[pd->selected_line] != NULL ) {
        dmenu_output_formatted_line ( pd->format, cmd_list[pd->selected_line], pd->selected_line, input );
        if ( ( mretv & MENU_CUSTOM_ACTION ) ) {
            restart = TRUE;
            int seen = FALSE;
            if ( pd->selected_list != NULL ) {
                if ( pd->selected_list[pd->num_selected_list - 1].stop == ( pd->selected_line - 1 ) ) {
                    pd->selected_list[pd->num_selected_list - 1].stop = pd->selected_line;
                    seen                                              = TRUE;
                }
            }
            if ( !seen ) {
                pd->selected_list = g_realloc ( pd->selected_list,
                                                ( pd->num_selected_list + 1 ) * sizeof ( struct range_pair ) );
                pd->selected_list[pd->num_selected_list].start = pd->selected_line;
                pd->selected_list[pd->num_selected_list].stop  = pd->selected_line;
                ( pd->num_selected_list )++;
            }

            // Move to next line.
            pd->selected_line = MIN ( next_pos, cmd_list_length - 1 );
        }
        retv = TRUE;
    }
    // Custom input
    else if ( ( mretv & ( MENU_CUSTOM_INPUT ) ) ) {
        dmenu_output_formatted_line ( pd->format, input, -1, input );
        if ( ( mretv & MENU_CUSTOM_ACTION ) ) {
            restart = TRUE;
            // Move to next line.
            pd->selected_line = MIN ( next_pos, cmd_list_length - 1 );
        }

        retv = TRUE;
    }
    // Quick switch with entry selected.
    else if ( ( mretv & MENU_QUICK_SWITCH ) && pd->selected_line < UINT32_MAX ) {
        dmenu_output_formatted_line ( pd->format, cmd_list[pd->selected_line], pd->selected_line, input );

        restart = FALSE;
        retv    = 10 + ( mretv & MENU_LOWER_MASK );
    }
    // Quick switch without entry selected.
    else if ( ( mretv & MENU_QUICK_SWITCH ) && pd->selected_line == UINT32_MAX ) {
        dmenu_output_formatted_line ( pd->format, input, -1, input );

        restart = FALSE;
        retv    = 10 + ( mretv & MENU_LOWER_MASK );
    }
    g_free ( input );
    if ( restart ) {
        rofi_view_restart ( state );
        rofi_view_set_selected_line ( state, pd->selected_line );
    }
    else {
        dmenu_finish ( state, retv );
    }
}