From 98de9b554f2abef9c039774b0f7bed328b7670ba Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Wed, 9 Dec 2015 08:29:18 +0100 Subject: [PATCH] Add screenshot keybinding. --- README.md | 1 + doc/rofi-manpage.markdown | 1 + doc/rofi.1 | 3 +++ include/keyb.h | 1 + source/keyb.c | 3 ++- source/rofi.c | 51 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 59 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cc3d8b13..e6d1e224 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,7 @@ Type `Shift-Right` to switch from Window list mode to Run mode and back. |`Ctrl-space` | Set selected item as input text. | |`Shift-Del` | Delete entry from history. | |`grave` | Toggle case sensitivity. | +|`Alt-Shift-S` | Take a screenshot and store this in the Pictures directory. | # Configuration diff --git a/doc/rofi-manpage.markdown b/doc/rofi-manpage.markdown index 13c10319..75aa0789 100644 --- a/doc/rofi-manpage.markdown +++ b/doc/rofi-manpage.markdown @@ -774,6 +774,7 @@ The first two fields specify the alpha level. This determines the amount of tran * `Ctrl-space`: Set selected item as input text. * `Shift-Del`: Delete entry from history. * `grave`: Toggle case sensitivity. + * `Alt-Shift-S`: Take a screenshot and store this in the Pictures directory. To get a full list of keybindings, see `rofi -dump-xresources | grep kb-`. Keybindings can be modified using the configuration systems. diff --git a/doc/rofi.1 b/doc/rofi.1 index df488892..fe0281ab 100644 --- a/doc/rofi.1 +++ b/doc/rofi.1 @@ -1293,6 +1293,9 @@ The first two fields specify the alpha level\. This determines the amount of tra .IP "\(bu" 4 \fBgrave\fR: Toggle case sensitivity\. . +.IP "\(bu" 4 +\fBAlt\-Shift\-S\fR: Take a screenshot and store this in the Pictures directory\. +. .IP "" 0 . .P diff --git a/include/keyb.h b/include/keyb.h index 89cf4b4f..86fe5de7 100644 --- a/include/keyb.h +++ b/include/keyb.h @@ -53,6 +53,7 @@ typedef enum _KeyBindingAction CUSTOM_17, CUSTOM_18, CUSTOM_19, + SCREENSHOT, NUM_ABE } KeyBindingAction; diff --git a/source/keyb.c b/source/keyb.c index 1288fe75..3d0c0ede 100644 --- a/source/keyb.c +++ b/source/keyb.c @@ -64,7 +64,7 @@ DefaultBinding bindings[NUM_ABE] = { .id = ROW_FIRST, .name = "kb-row-first", .keybinding = "Home,KP_Home" }, { .id = ROW_LAST, .name = "kb-row-last", .keybinding = "End,KP_End" }, { .id = ROW_SELECT, .name = "kb-row-select", .keybinding = "Control+space" }, - { .id = CANCEL, .name = "kb-cancel", .keybinding = "Escape" }, + { .id = CANCEL, .name = "kb-cancel", .keybinding = "Escape,Control+bracketleft" }, { .id = CUSTOM_1, .name = "kb-custom-1", .keybinding = "Alt+1" }, { .id = CUSTOM_2, .name = "kb-custom-2", .keybinding = "Alt+2" }, { .id = CUSTOM_3, .name = "kb-custom-3", .keybinding = "Alt+3" }, @@ -84,6 +84,7 @@ DefaultBinding bindings[NUM_ABE] = { .id = CUSTOM_18, .name = "kb-custom-18", .keybinding = "Alt+Shift+8" }, { .id = CUSTOM_17, .name = "kb-custom-17", .keybinding = "Alt+Shift+7" }, { .id = CUSTOM_19, .name = "kb-custom-19", .keybinding = "Alt+Shift+9" }, + { .id = SCREENSHOT, .name = "kb-screenshot", .keybinding = "Alt+Shift+S" }, }; void setup_abe ( void ) diff --git a/source/rofi.c b/source/rofi.c index 085ec98c..b364a063 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -567,6 +567,52 @@ static int locate_switcher ( KeySym key, unsigned int modstate ) } return -1; } + +/** + * Stores a screenshot of Rofi at that point in time. + */ +static void menu_capture_screenshot ( void ) +{ + int index = 0; + if ( surface == NULL ) { + // Nothing to store. + fprintf(stderr, "There is no rofi surface to store\n"); + return; + } + const char *xdg_pict_dir = g_get_user_special_dir(G_USER_DIRECTORY_PICTURES); + if ( xdg_pict_dir == NULL ) { + fprintf(stderr, "XDG user picture directory is not set. Cannot store screenshot.\n"); + return; + } + // Get current time. + GDateTime *now = g_date_time_new_now_local(); + // Format filename. + char *timestmp = g_date_time_format(now, "rofi-%Y-%m-%d-%H:%M"); + char *filename = g_strdup_printf("%s.png", timestmp); + // Build full path + char *fpath = g_build_filename(xdg_pict_dir, filename, NULL); + while(g_file_test(fpath, G_FILE_TEST_EXISTS) && index < 99) { + g_free(fpath); + g_free(filename); + // Try the next index. + index++; + // Format filename. + filename = g_strdup_printf("%s-%d.png", timestmp,index); + // Build full path + fpath = g_build_filename(xdg_pict_dir, filename, NULL); + } + fprintf(stderr, color_green"Storing screenshot %s\n"color_reset,fpath); + cairo_status_t status = cairo_surface_write_to_png(surface, fpath); + if ( status != CAIRO_STATUS_SUCCESS ) { + fprintf(stderr, "Failed to produce screenshot '%s', got error: '%s'\n",filename, + cairo_status_to_string(status)); + } + g_free(fpath); + g_free(filename); + g_free(timestmp); + g_date_time_unref(now); +} + /** * @param state Internal state of the menu. * @param key the Key being pressed. @@ -1508,6 +1554,10 @@ MenuReturn menu ( Mode *sw, char **input, char *prompt, unsigned int *selected_l XConvertSelection ( display, netatoms[CLIPBOARD], netatoms[UTF8_STRING], netatoms[UTF8_STRING], main_window, CurrentTime ); } + if ( abe_test_action ( SCREENSHOT, ev.xkey.state, key ) ) { + menu_capture_screenshot ( ); + break; + } else if ( abe_test_action ( MODE_PREVIOUS, ev.xkey.state, key ) ) { state.retv = MENU_PREVIOUS; *( state.selected_line ) = 0; @@ -1639,6 +1689,7 @@ MenuReturn menu ( Mode *sw, char **input, char *prompt, unsigned int *selected_l return retv; } + void error_dialog ( const char *msg, int markup ) { MenuState state = {