diff options
author | Qball Cow <qball@gmpclient.org> | 2014-04-24 18:03:27 +0200 |
---|---|---|
committer | Qball Cow <qball@gmpclient.org> | 2014-04-24 18:03:27 +0200 |
commit | aeefabe7a07cb7eae135dac7296bf93c16888239 (patch) | |
tree | 67698f9e2d3c012ffeaefeeee467f682445b8606 /source | |
parent | 7887344d4434a676dde55ff1fb04dd855ff82bcb (diff) |
Fix unclosable window bug.
Fix annoyance, when it failed to grab keyboard, it still shows windows and waits for
input. This causes an unaccessible Rofi instance.
Diffstat (limited to 'source')
-rw-r--r-- | source/rofi.c | 370 |
1 files changed, 185 insertions, 185 deletions
diff --git a/source/rofi.c b/source/rofi.c index 7c926d5f..5a1d956e 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -485,7 +485,7 @@ int pointer_get ( Window root, int *x, int *y ) return 0; } -int take_keyboard ( Window w ) +static int take_keyboard ( Window w ) { int i; @@ -1131,274 +1131,276 @@ MenuReturn menu ( char **lines, char **input, char *prompt, Time *time, int *shi // Determine window location switch ( config.location ) { - case WL_NORTH_WEST: - x = mon.x; + case WL_NORTH_WEST: + x = mon.x; - case WL_NORTH: - y = mon.y; - break; + case WL_NORTH: + y = mon.y; + break; - case WL_NORTH_EAST: - y = mon.y; + case WL_NORTH_EAST: + y = mon.y; - case WL_EAST: - x = mon.x + mon.w - w; - break; + case WL_EAST: + x = mon.x + mon.w - w; + break; - case WL_EAST_SOUTH: - x = mon.x + mon.w - w; + case WL_EAST_SOUTH: + x = mon.x + mon.w - w; - case WL_SOUTH: - y = mon.y + mon.h - h; - break; + case WL_SOUTH: + y = mon.y + mon.h - h; + break; - case WL_SOUTH_WEST: - y = mon.y + mon.h - h; + case WL_SOUTH_WEST: + y = mon.y + mon.h - h; - case WL_WEST: - x = mon.x; - break; + case WL_WEST: + x = mon.x; + break; - case WL_CENTER: - default: - break; + case WL_CENTER: + default: + break; } XMoveResizeWindow ( display, box, x, y, w, h ); XMapRaised ( display, box ); - take_keyboard ( box ); - - for (;; ) + // if grabbing keyboard failed, fall through + if(take_keyboard ( box )) { - XEvent ev; - XNextEvent ( display, &ev ); - - if ( ev.type == Expose ) + for (;; ) { - while ( XCheckTypedEvent ( display, Expose, &ev ) ) + XEvent ev; + XNextEvent ( display, &ev ); + + if ( ev.type == Expose ) { - ; - } + while ( XCheckTypedEvent ( display, Expose, &ev ) ) + { + ; + } - menu_draw ( text, boxes, max_lines, num_lines, &last_offset, selected, filtered ); + menu_draw ( text, boxes, max_lines, num_lines, &last_offset, selected, filtered ); - // Why do we need the specian -1? - if ( config.wmode == VERTICAL ) - { - XDrawLine ( display, main_window, gc, ( config.padding ), + // Why do we need the specian -1? + if ( config.wmode == VERTICAL ) + { + XDrawLine ( display, main_window, gc, ( config.padding ), line_height + ( config.padding ) + ( LINE_MARGIN - 2 ) / 2, w - ( ( config.padding ) ) - 1, line_height + ( config.padding ) + ( LINE_MARGIN - 2 ) / 2 ); - } - } - else if ( ev.type == KeyPress ) - { - while ( XCheckTypedEvent ( display, KeyPress, &ev ) ) - { - ; - } - - if ( time ) - { - *time = ev.xkey.time; - } - - KeySym key = XkbKeycodeToKeysym ( display, ev.xkey.keycode, 0, 0 ); - - if ( ( ( ev.xkey.state & ShiftMask ) == ShiftMask ) && - key == XK_slash ) - { - retv = MENU_NEXT; - *selected_line = 0; - break; - } - else if ( ( ( ev.xkey.state & ShiftMask ) == ShiftMask ) && - key == XK_Delete ) - { - if ( filtered[selected] != NULL ) - { - *selected_line = line_map[selected]; - retv = MENU_ENTRY_DELETE; - break; } } - - int rc = textbox_keypress ( text, &ev ); - - if ( rc < 0 ) + else if ( ev.type == KeyPress ) { - if ( shift != NULL ) + while ( XCheckTypedEvent ( display, KeyPress, &ev ) ) { - ( *shift ) = ( ( ev.xkey.state & ShiftMask ) == ShiftMask ); + ; } - if ( filtered && filtered[selected] ) + if ( time ) { - retv = MENU_OK; - *selected_line = line_map[selected]; - } - else - { - retv = MENU_CUSTOM_INPUT; + *time = ev.xkey.time; } - break; - } - else if ( rc ) - { - char **tokens = tokenize ( text->text ); + KeySym key = XkbKeycodeToKeysym ( display, ev.xkey.keycode, 0, 0 ); - // input changed - for ( i = 0, j = 0; i < num_lines; i++ ) + if ( ( ( ev.xkey.state & ShiftMask ) == ShiftMask ) && + key == XK_slash ) { - int match = mmc ( tokens, lines[i], i, mmc_data ); - - // If each token was matched, add it to list. - if ( match ) + retv = MENU_NEXT; + *selected_line = 0; + break; + } + else if ( ( ( ev.xkey.state & ShiftMask ) == ShiftMask ) && + key == XK_Delete ) + { + if ( filtered[selected] != NULL ) { - line_map[j] = i; - filtered[j++] = lines[i]; + *selected_line = line_map[selected]; + retv = MENU_ENTRY_DELETE; + break; } } - // Cleanup + bookkeeping. - filtered_lines = j; - selected = MIN ( selected, j - 1 ); + int rc = textbox_keypress ( text, &ev ); - for (; j < num_lines; j++ ) + if ( rc < 0 ) { - filtered[j] = NULL; - } + if ( shift != NULL ) + { + ( *shift ) = ( ( ev.xkey.state & ShiftMask ) == ShiftMask ); + } - if ( config.zeltak_mode && filtered_lines == 1 ) - { - if ( filtered[selected] ) + if ( filtered && filtered[selected] ) { retv = MENU_OK; *selected_line = line_map[selected]; } else { - fprintf ( stderr, "We should never hit this." ); - abort (); + retv = MENU_CUSTOM_INPUT; } break; } - - tokenize_free ( tokens ); - } - else - { - // unhandled key - KeySym key = XkbKeycodeToKeysym ( display, ev.xkey.keycode, 0, 0 ); - - if ( key == XK_Escape - // pressing one of the global key bindings closes the switcher. this allows fast closing of the menu if an item is not selected - || ( ( windows_modmask == AnyModifier || ev.xkey.state & windows_modmask ) && key == windows_keysym ) - || ( ( rundialog_modmask == AnyModifier || ev.xkey.state & rundialog_modmask ) && key == rundialog_keysym ) - || ( ( sshdialog_modmask == AnyModifier || ev.xkey.state & sshdialog_modmask ) && key == sshdialog_keysym ) - ) + else if ( rc ) { - retv = MENU_CANCEL; - break; - } - else - { - // Up or Shift-Tab - if ( key == XK_Up || ( key == XK_Tab && ev.xkey.state & ShiftMask ) || - ( key == XK_j && ev.xkey.state & ControlMask ) ) + char **tokens = tokenize ( text->text ); + + // input changed + for ( i = 0, j = 0; i < num_lines; i++ ) { - if ( selected == 0 ) - { - selected = filtered_lines; - } + int match = mmc ( tokens, lines[i], i, mmc_data ); - if ( selected > 0 ) + // If each token was matched, add it to list. + if ( match ) { - selected--; + line_map[j] = i; + filtered[j++] = lines[i]; } } - else if ( key == XK_Down || - ( key == XK_k && ev.xkey.state & ControlMask ) ) + + // Cleanup + bookkeeping. + filtered_lines = j; + selected = MIN ( selected, j - 1 ); + + for (; j < num_lines; j++ ) { - selected = selected < filtered_lines - 1 ? MIN ( filtered_lines - 1, selected + 1 ) : 0; + filtered[j] = NULL; } - else if ( key == XK_Page_Up ) + + if ( config.zeltak_mode && filtered_lines == 1 ) { - if ( selected < max_lines ) + if ( filtered[selected] ) { - selected = 0; + retv = MENU_OK; + *selected_line = line_map[selected]; } else { - selected -= ( max_lines - 1 ); + fprintf ( stderr, "We should never hit this." ); + abort (); } - } - else if ( key == XK_Page_Down ) - { - selected += ( max_lines - 1 ); - if ( selected >= num_lines ) - { - selected = num_lines - 1; - } + break; } - else if ( key == XK_Home || key == XK_KP_Home ) - { - selected = 0; - } - else if ( key == XK_End || key == XK_KP_End ) + + tokenize_free ( tokens ); + } + else + { + // unhandled key + KeySym key = XkbKeycodeToKeysym ( display, ev.xkey.keycode, 0, 0 ); + + if ( key == XK_Escape + // pressing one of the global key bindings closes the switcher. this allows fast closing of the menu if an item is not selected + || ( ( windows_modmask == AnyModifier || ev.xkey.state & windows_modmask ) && key == windows_keysym ) + || ( ( rundialog_modmask == AnyModifier || ev.xkey.state & rundialog_modmask ) && key == rundialog_keysym ) + || ( ( sshdialog_modmask == AnyModifier || ev.xkey.state & sshdialog_modmask ) && key == sshdialog_keysym ) + ) { - selected = num_lines - 1; + retv = MENU_CANCEL; + break; } - else if ( key == XK_Tab ) + else { - if ( filtered_lines == 1 ) + // Up or Shift-Tab + if ( key == XK_Up || ( key == XK_Tab && ev.xkey.state & ShiftMask ) || + ( key == XK_j && ev.xkey.state & ControlMask ) ) + { + if ( selected == 0 ) + { + selected = filtered_lines; + } + + if ( selected > 0 ) + { + selected--; + } + } + else if ( key == XK_Down || + ( key == XK_k && ev.xkey.state & ControlMask ) ) + { + selected = selected < filtered_lines - 1 ? MIN ( filtered_lines - 1, selected + 1 ) : 0; + } + else if ( key == XK_Page_Up ) { - if ( filtered[selected] ) + if ( selected < max_lines ) { - retv = MENU_OK; - *selected_line = line_map[selected]; + selected = 0; } else { - fprintf ( stderr, "We should never hit this." ); - abort (); + selected -= ( max_lines - 1 ); } - - break; } + else if ( key == XK_Page_Down ) + { + selected += ( max_lines - 1 ); - int length_prefix = calculate_common_prefix ( filtered, num_lines ); - - // TODO: memcmp to utf8 aware cmp. - if ( length_prefix && memcmp ( filtered[0], text->text, length_prefix ) ) + if ( selected >= num_lines ) + { + selected = num_lines - 1; + } + } + else if ( key == XK_Home || key == XK_KP_Home ) { - // Do not want to modify original string, so make copy. - // not eff.. - char * str = allocate ( sizeof ( char ) * ( length_prefix + 1 ) ); - memcpy ( str, filtered[0], length_prefix ); - str[length_prefix] = '\0'; - textbox_text ( text, str ); - textbox_cursor_end ( text ); - free ( str ); + selected = 0; } - else + else if ( key == XK_End || key == XK_KP_End ) { - selected = selected < filtered_lines - 1 ? MIN ( filtered_lines - 1, selected + 1 ) : 0; + selected = num_lines - 1; + } + else if ( key == XK_Tab ) + { + if ( filtered_lines == 1 ) + { + if ( filtered[selected] ) + { + retv = MENU_OK; + *selected_line = line_map[selected]; + } + else + { + fprintf ( stderr, "We should never hit this." ); + abort (); + } + + break; + } + + int length_prefix = calculate_common_prefix ( filtered, num_lines ); + + // TODO: memcmp to utf8 aware cmp. + if ( length_prefix && memcmp ( filtered[0], text->text, length_prefix ) ) + { + // Do not want to modify original string, so make copy. + // not eff.. + char * str = allocate ( sizeof ( char ) * ( length_prefix + 1 ) ); + memcpy ( str, filtered[0], length_prefix ); + str[length_prefix] = '\0'; + textbox_text ( text, str ); + textbox_cursor_end ( text ); + free ( str ); + } + else + { + selected = selected < filtered_lines - 1 ? MIN ( filtered_lines - 1, selected + 1 ) : 0; + } } } } - } - menu_draw ( text, boxes, max_lines, num_lines, &last_offset, selected, filtered ); + menu_draw ( text, boxes, max_lines, num_lines, &last_offset, selected, filtered ); + } } - } - release_keyboard (); + release_keyboard (); + } if ( *input != NULL ) { @@ -1407,8 +1409,6 @@ MenuReturn menu ( char **lines, char **input, char *prompt, Time *time, int *shi *input = strdup ( text->text ); - - textbox_free ( text ); for ( i = 0; i < max_lines; i++ ) |