Feature: Add the ability to take "screenshots" of spmenu.
It doesn't actually capture your screen, but rather saves the Cairo surface to an image. The path to the image and some other options can also be configured in the config file. By default, Print Screen can be pressed in Normal mode with no modifier to take a screenshot. The default location is the user's home directory, and the file has a date attached to it. Of course, this can be changed as well.
This commit is contained in:
parent
eefa047c6e
commit
3f456f3a37
|
@ -792,6 +792,7 @@ These are the default keybinds. You can generate these yourself from a
|
||||||
| 0 | 0 | Prior | moveprev | 0 |
|
| 0 | 0 | Prior | moveprev | 0 |
|
||||||
| 0 | Ctrl | p | navhistory | -1 |
|
| 0 | Ctrl | p | navhistory | -1 |
|
||||||
| 0 | Ctrl | n | navhistory | +1 |
|
| 0 | Ctrl | n | navhistory | +1 |
|
||||||
|
| 0 | 0 | Print | screenshot | 0 |
|
||||||
| 1 | 0 | Escape | switchmode | 0 |
|
| 1 | 0 | Escape | switchmode | 0 |
|
||||||
|
|
||||||
## .Xresources
|
## .Xresources
|
||||||
|
|
|
@ -213,6 +213,9 @@ spmenu = {
|
||||||
binds = 1; // Load binds (~/.config/spmenu/binds.conf) on runtime
|
binds = 1; // Load binds (~/.config/spmenu/binds.conf) on runtime
|
||||||
themefile = "NULL"; // Path to theme file to load on runtime. NULL means default.
|
themefile = "NULL"; // Path to theme file to load on runtime. NULL means default.
|
||||||
bindsfile = "NULL"; // Path to binds file to load on runtime. NULL means default.
|
bindsfile = "NULL"; // Path to binds file to load on runtime. NULL means default.
|
||||||
|
screenshotfile = "NULL"; // Screenshot file path. NULL means default.
|
||||||
|
screenshotname = "NULL"; // Screenshot file name. NULL means default.
|
||||||
|
screenshotdir = "NULL"; // Screenshot file directory. NULL means default.
|
||||||
} );
|
} );
|
||||||
|
|
||||||
/* Input options */
|
/* Input options */
|
||||||
|
@ -333,6 +336,7 @@ spmenu = {
|
||||||
{ mode = 0; modifier = "None"; key = "Prior"; function = "moveprev"; argument = "0"; }, // Prior: Move to the previous entry (undo)
|
{ mode = 0; modifier = "None"; key = "Prior"; function = "moveprev"; argument = "0"; }, // Prior: Move to the previous entry (undo)
|
||||||
{ mode = 0; modifier = "Ctrl"; key = "p"; function = "navhistory"; argument = "-1"; }, // Alt+p: Navigate to the previous entry in the history buffer
|
{ mode = 0; modifier = "Ctrl"; key = "p"; function = "navhistory"; argument = "-1"; }, // Alt+p: Navigate to the previous entry in the history buffer
|
||||||
{ mode = 0; modifier = "Ctrl"; key = "n"; function = "navhistory"; argument = "+1"; }, // Alt+n: Navigate to the next entry in the history buffer
|
{ mode = 0; modifier = "Ctrl"; key = "n"; function = "navhistory"; argument = "+1"; }, // Alt+n: Navigate to the next entry in the history buffer
|
||||||
|
{ mode = 0; modifier = "None"; key = "PrintScr"; function = "screenshot"; argument = "0"; }, // Print Screen: Screenshot spmenu
|
||||||
|
|
||||||
{ ignoreglobalkeys = 1; } ), // Ignore hardcoded keybinds (0/1)
|
{ ignoreglobalkeys = 1; } ), // Ignore hardcoded keybinds (0/1)
|
||||||
};
|
};
|
||||||
|
|
48
libs/arg.c
48
libs/arg.c
|
@ -507,3 +507,51 @@ void switchmode(Arg *arg) {
|
||||||
strncpy(tx.modetext, sp.mode ? instext : normtext, 15);
|
strncpy(tx.modetext, sp.mode ? instext : normtext, 15);
|
||||||
drawmenu();
|
drawmenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void screenshot(Arg *arg) {
|
||||||
|
char *file = NULL;
|
||||||
|
char *home = NULL;
|
||||||
|
time_t time_ = time(NULL);
|
||||||
|
struct tm t = *localtime(&time_);
|
||||||
|
|
||||||
|
if (!screenshotfile) {
|
||||||
|
if (!(home = getenv("HOME"))) {
|
||||||
|
fprintf(stderr, "spmenu: failed to determine home directory\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!screenshotdir && !screenshotname) { // default
|
||||||
|
if (!(file = malloc(snprintf(NULL, 0, "%s/%s-%02d-%02d-%02d%s", home, "spmenu-screenshot", t.tm_hour, t.tm_min, t.tm_sec, ".png") + 1))) {
|
||||||
|
die("spmenu: failed to malloc screenshot file");
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(file, "%s/%s-%02d-%02d-%02d%s", home, "spmenu-screenshot", t.tm_hour, t.tm_min, t.tm_sec, ".png");
|
||||||
|
} else if (!screenshotdir && screenshotname) { // no dir but name
|
||||||
|
if (!(file = malloc(snprintf(NULL, 0, "%s/%s", home, screenshotname) + 1))) {
|
||||||
|
die("spmenu: failed to malloc screenshot file");
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(file, "%s/%s", home, screenshotname);
|
||||||
|
} else if (screenshotdir && !screenshotname) { // dir but no name
|
||||||
|
if (!(file = malloc(snprintf(NULL, 0, "%s/%s-%02d-%02d-%02d%s", screenshotdir, "spmenu-screenshot", t.tm_hour, t.tm_min, t.tm_sec, ".png") + 1))) {
|
||||||
|
die("spmenu: failed to malloc screenshot file");
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(file, "%s/%s-%02d-%02d-%02d%s", screenshotdir, "spmenu-screenshot", t.tm_hour, t.tm_min, t.tm_sec, ".png");
|
||||||
|
} else { // dir and name
|
||||||
|
if (!(file = malloc(snprintf(NULL, 0, "%s/%s", screenshotdir, screenshotname) + 1))) {
|
||||||
|
die("spmenu: failed to malloc screenshot file");
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(file, "%s/%s", screenshotdir, screenshotname);
|
||||||
|
}
|
||||||
|
} else { // custom file
|
||||||
|
if (!(file = malloc(snprintf(NULL, 0, "%s", screenshotfile) + 1))) {
|
||||||
|
die("spmenu: failed to malloc screenshot file");
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(file, "%s", screenshotfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_save_screen(draw, file);
|
||||||
|
}
|
||||||
|
|
|
@ -43,3 +43,4 @@ static void spawn(Arg *arg);
|
||||||
static void togglehighlight(Arg *arg);
|
static void togglehighlight(Arg *arg);
|
||||||
static void setprofile(Arg *arg);
|
static void setprofile(Arg *arg);
|
||||||
static void switchmode(Arg *arg);
|
static void switchmode(Arg *arg);
|
||||||
|
static void screenshot(Arg *arg);
|
||||||
|
|
|
@ -441,6 +441,18 @@ void conf_init(void) {
|
||||||
if (config_setting_lookup_string(conf, "bindsfile", &dest)) {
|
if (config_setting_lookup_string(conf, "bindsfile", &dest)) {
|
||||||
bindsfile = strdup(dest);
|
bindsfile = strdup(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config_setting_lookup_string(conf, "screenshotfile", &dest) && strcmp(dest, "NULL")) {
|
||||||
|
screenshotfile = strdup(dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config_setting_lookup_string(conf, "screenshotname", &dest) && strcmp(dest, "NULL")) {
|
||||||
|
screenshotname = strdup(dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config_setting_lookup_string(conf, "screenshotdir", &dest) && strcmp(dest, "NULL")) {
|
||||||
|
screenshotdir = strdup(dest);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -384,6 +384,7 @@ static FuncList fl[] = {
|
||||||
{ "setimggaps", setimggaps },
|
{ "setimggaps", setimggaps },
|
||||||
{ "setlines", setlines },
|
{ "setlines", setlines },
|
||||||
{ "setlines", setlines },
|
{ "setlines", setlines },
|
||||||
|
{ "screenshot", screenshot },
|
||||||
{ "setcolumns", setcolumns },
|
{ "setcolumns", setcolumns },
|
||||||
{ "togglehighlight",togglehighlight },
|
{ "togglehighlight",togglehighlight },
|
||||||
{ "setprofile", setprofile },
|
{ "setprofile", setprofile },
|
||||||
|
|
|
@ -417,6 +417,16 @@ void draw_img(Draw_t *draw, int x, int y) {
|
||||||
cairo_set_source_surface(draw->d, draw->surface, draw->w, draw->h);
|
cairo_set_source_surface(draw->d, draw->surface, draw->w, draw->h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void draw_save_screen(Draw_t *draw, const char *file) {
|
||||||
|
if (!draw || !draw->surface) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cairo_surface_write_to_png(draw->surface, file)) {
|
||||||
|
fprintf(stderr, "spmenu: failed to write file %s\n", file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int draw_fontset_getwidth_clamp(Draw_t *draw, const char *text, unsigned int n, Bool markup) {
|
unsigned int draw_fontset_getwidth_clamp(Draw_t *draw, const char *text, unsigned int n, Bool markup) {
|
||||||
unsigned int tmp = 0;
|
unsigned int tmp = 0;
|
||||||
if (draw && draw->font && text && n)
|
if (draw && draw->font && text && n)
|
||||||
|
|
|
@ -64,3 +64,6 @@ void draw_map(Draw_t *draw, Window win, int x, int y, unsigned int w, unsigned i
|
||||||
/* Powerline functions */
|
/* Powerline functions */
|
||||||
void draw_arrow(Draw_t *draw, int x, int y, unsigned int w, unsigned int h, int direction, int slash, char *prevcol, char *nextcol, int prevalpha, int nextalpha);
|
void draw_arrow(Draw_t *draw, int x, int y, unsigned int w, unsigned int h, int direction, int slash, char *prevcol, char *nextcol, int prevalpha, int nextalpha);
|
||||||
void draw_circle(Draw_t *draw, int x, int y, unsigned int w, unsigned int h, int direction, char *prevcol, char *nextcol, int prevalpha, int nextalpha);
|
void draw_circle(Draw_t *draw, int x, int y, unsigned int w, unsigned int h, int direction, char *prevcol, char *nextcol, int prevalpha, int nextalpha);
|
||||||
|
|
||||||
|
/* Screenshot functions */
|
||||||
|
void draw_save_screen(Draw_t *draw, const char *file);
|
||||||
|
|
|
@ -71,6 +71,7 @@ static Key keys[] = {
|
||||||
{ 0, 0, XK_Prior, moveprev, {0} },
|
{ 0, 0, XK_Prior, moveprev, {0} },
|
||||||
{ 0, Ctrl, XK_p, navhistory, {.i = -1 } },
|
{ 0, Ctrl, XK_p, navhistory, {.i = -1 } },
|
||||||
{ 0, Ctrl, XK_n, navhistory, {.i = +1 } },
|
{ 0, Ctrl, XK_n, navhistory, {.i = +1 } },
|
||||||
|
{ 0, 0, XK_Print, screenshot, {0} },
|
||||||
|
|
||||||
/* insert mode */
|
/* insert mode */
|
||||||
{ 1, 0, XK_Escape, switchmode, {0} },
|
{ 1, 0, XK_Escape, switchmode, {0} },
|
||||||
|
@ -146,6 +147,7 @@ static WlKey wl_keys[] = {
|
||||||
{ 0, WL_None, XKB_KEY_Prior, moveprev, {0} },
|
{ 0, WL_None, XKB_KEY_Prior, moveprev, {0} },
|
||||||
{ 0, WL_Ctrl, XKB_KEY_p, navhistory, {.i = -1 } },
|
{ 0, WL_Ctrl, XKB_KEY_p, navhistory, {.i = -1 } },
|
||||||
{ 0, WL_Ctrl, XKB_KEY_n, navhistory, {.i = +1 } },
|
{ 0, WL_Ctrl, XKB_KEY_n, navhistory, {.i = +1 } },
|
||||||
|
{ 0, WL_None, XKB_KEY_Print, screenshot, {0} },
|
||||||
|
|
||||||
/* insert mode */
|
/* insert mode */
|
||||||
{ 1, WL_None, XKB_KEY_Escape, switchmode, {0} },
|
{ 1, WL_None, XKB_KEY_Escape, switchmode, {0} },
|
||||||
|
|
|
@ -56,6 +56,11 @@ static int generatecache = 1; /* Generate image cache by default *
|
||||||
static int maxcache = 512; /* Max image size to cache */
|
static int maxcache = 512; /* Max image size to cache */
|
||||||
static char *cachedir = "default"; /* Cache directory. Default means spmenu will determine automatically */
|
static char *cachedir = "default"; /* Cache directory. Default means spmenu will determine automatically */
|
||||||
|
|
||||||
|
/* Screenshot options */
|
||||||
|
static char *screenshotfile = NULL; /* Screenshot file path. If set to NULL, the default path will be used. */
|
||||||
|
static char *screenshotname = NULL; /* Screenshot file name. If set to NULL, the default name will be used. */
|
||||||
|
static char *screenshotdir = NULL; /* Screenshot file directory. If set to NULL, the default directory will be used. */
|
||||||
|
|
||||||
/* Mode options */
|
/* Mode options */
|
||||||
static int mode = 0; /* Mode to start speedwm in (0: Normal mode, 1: Insert mode) */
|
static int mode = 0; /* Mode to start speedwm in (0: Normal mode, 1: Insert mode) */
|
||||||
static char *normtext = "Normal"; /* Text to display for normal mode */
|
static char *normtext = "Normal"; /* Text to display for normal mode */
|
||||||
|
|
Loading…
Reference in a new issue