From 4fe60d1f50fa5e8ad01ec90407b364d9cea42ee1 Mon Sep 17 00:00:00 2001 From: Alec Cox Date: Mon, 8 Feb 2021 10:00:12 -0800 Subject: [PATCH 1/5] added options entries to support --bg-preserve --- src/options.c | 4 ++++ src/options.h | 1 + 2 files changed, 5 insertions(+) diff --git a/src/options.c b/src/options.c index 4744bb0c..85a80d7e 100644 --- a/src/options.c +++ b/src/options.c @@ -434,6 +434,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) {"class" , 1, 0, 249}, {"no-conversion-cache", 0, 0, 250}, {"window-id", 1, 0, 251}, + {"bg-preserve", 0, 0, 252}, {0, 0, 0, 0} }; int optch = 0, cmdx = 0; @@ -837,6 +838,9 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) case 251: opt.x11_windowid = atol(optarg); break; + case 252: + opt.bg_preserve = 1; + break; default: break; } diff --git a/src/options.h b/src/options.h index 7ca699b3..eb8d5a71 100644 --- a/src/options.h +++ b/src/options.h @@ -91,6 +91,7 @@ struct __fehoptions { char *output_dir; char *bg_file; char *image_bg; + int bg_preserve; char *font; char *title_font; char *title; From 76d144e606b40b36aadd4dbcdfd5ce25185d1b98 Mon Sep 17 00:00:00 2001 From: Alec Cox Date: Mon, 8 Feb 2021 10:02:26 -0800 Subject: [PATCH 2/5] added specification of custom geometery for bg-center --- src/wallpaper.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/wallpaper.c b/src/wallpaper.c index b62d28b2..b96a53f8 100644 --- a/src/wallpaper.c +++ b/src/wallpaper.c @@ -103,25 +103,38 @@ static void feh_wm_set_bg_centered(Pixmap pmap, Imlib_Image im, int use_filelist int x, int y, int w, int h) { int offset_x, offset_y; + int img_w, img_h; if (use_filelist) feh_wm_load_next(&im); + img_w = gib_imlib_image_get_width(im); + img_h = gib_imlib_image_get_height(im); + if (opt.geom_w != 0 && opt.geom_h != 0) { + + Imlib_Image im_old = im; + im = gib_imlib_create_cropped_scaled_image(im_old, 0, 0, img_w, img_h, opt.geom_w, opt.geom_h, 1); + gib_imlib_free_image_and_decache(im_old); + + img_w = opt.geom_w; + img_h = opt.geom_h; + } + if(opt.geom_flags & XValue) if(opt.geom_flags & XNegative) - offset_x = (w - gib_imlib_image_get_width(im)) + opt.geom_x; + offset_x = (w - img_w) + opt.geom_x; else offset_x = opt.geom_x; else - offset_x = (w - gib_imlib_image_get_width(im)) >> 1; + offset_x = (w - img_w) >> 1; if(opt.geom_flags & YValue) if(opt.geom_flags & YNegative) - offset_y = (h - gib_imlib_image_get_height(im)) + opt.geom_y; + offset_y = (h - img_h) + opt.geom_y; else offset_y = opt.geom_y; else - offset_y = (h - gib_imlib_image_get_height(im)) >> 1; + offset_y = (h - img_h) >> 1; gib_imlib_render_image_part_on_drawable_at_size(pmap, im, ((offset_x < 0) ? -offset_x : 0), From c6bf64f3778d09c3b7eec9463ea63f52f4a9258a Mon Sep 17 00:00:00 2001 From: Alec Cox Date: Mon, 8 Feb 2021 10:03:23 -0800 Subject: [PATCH 3/5] added ability to specify one axis of geometry width to preserve ratio --- src/wallpaper.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/wallpaper.c b/src/wallpaper.c index b96a53f8..b44c8601 100644 --- a/src/wallpaper.c +++ b/src/wallpaper.c @@ -111,6 +111,13 @@ static void feh_wm_set_bg_centered(Pixmap pmap, Imlib_Image im, int use_filelist img_w = gib_imlib_image_get_width(im); img_h = gib_imlib_image_get_height(im); if (opt.geom_w != 0 && opt.geom_h != 0) { + if (opt.geom_w == 0) { + double ratio = (double)img_w / (double)img_h; + opt.geom_w = (int) ((double)opt.geom_h * ratio); + } else if (opt.geom_h == 0) { + double ratio = (double)img_h / (double)img_w; + opt.geom_h = (int) ((double)opt.geom_w * ratio); + } Imlib_Image im_old = im; im = gib_imlib_create_cropped_scaled_image(im_old, 0, 0, img_w, img_h, opt.geom_w, opt.geom_h, 1); From d35d5ff5bcfd6e3e97f989f5ae3538062f80df25 Mon Sep 17 00:00:00 2001 From: Alec Cox Date: Mon, 8 Feb 2021 10:06:42 -0800 Subject: [PATCH 4/5] implimented loading of existing bg pixmap, changed property indentation --- src/wallpaper.c | 50 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/src/wallpaper.c b/src/wallpaper.c index b44c8601..3c69fe10 100644 --- a/src/wallpaper.c +++ b/src/wallpaper.c @@ -441,6 +441,7 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, unsigned long length, after; unsigned char *data_root = NULL, *data_esetroot = NULL; Pixmap pmap_d1, pmap_d2; + unsigned int pmap_d1_freeable = 0; /* local display to set closedownmode on */ Display *disp2; @@ -485,10 +486,40 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, D(("centering\n")); - pmap_d1 = XCreatePixmap(disp, root, scr->width, scr->height, depth); - gcval.foreground = color.pixel; - gc = XCreateGC(disp, root, GCForeground, &gcval); - XFillRectangle(disp, pmap_d1, gc, 0, 0, scr->width, scr->height); + + + unsigned char *data = NULL; + if (opt.bg_preserve) { + Atom act_type; + int act_format; + unsigned long nitems, bytes_after; + Atom _XROOTPMAP_ID; + + _XROOTPMAP_ID = XInternAtom(disp, "_XROOTPMAP_ID", False); + + if (XGetWindowProperty(disp, root, _XROOTPMAP_ID, 0, 1, False, XA_PIXMAP, + &act_type, &act_format, &nitems, &bytes_after, + &data) == Success) { + if (data) { + D(("preserving background\n")); + pmap_d1 = *((Pixmap *) data); + XFree(data); + } + } else { + // XOrg documentation is not clear if a non-success event can + // set data. + data = NULL; + } + } + + // if bg_preserve wasn't run or bg_preserve found no existing background + if (!data) { + pmap_d1 = XCreatePixmap(disp, root, scr->width, scr->height, depth); + gcval.foreground = color.pixel; + gc = XCreateGC(disp, root, GCForeground, &gcval); + XFillRectangle(disp, pmap_d1, gc, 0, 0, scr->width, scr->height); + pmap_d1_freeable = 1; + } #ifdef HAVE_LIBXINERAMA if (opt.xinerama && xinerama_screens) { @@ -505,7 +536,8 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, feh_wm_set_bg_centered(pmap_d1, im, use_filelist, 0, 0, scr->width, scr->height); - XFreeGC(disp, gc); + if (!data) + XFreeGC(disp, gc); } else if (filled == 1) { @@ -584,7 +616,8 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, XFreeGC(disp2, gc); XSync(disp2, False); XSync(disp, False); - XFreePixmap(disp, pmap_d1); + if(pmap_d1_freeable) + XFreePixmap(disp, pmap_d1); prop_root = XInternAtom(disp2, "_XROOTPMAP_ID", True); prop_esetroot = XInternAtom(disp2, "ESETROOT_PMAP_ID", True); @@ -619,9 +652,10 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, if (prop_root == None || prop_esetroot == None) eprintf("creation of pixmap property failed."); - XChangeProperty(disp2, root2, prop_root, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &pmap_d2, 1); + XChangeProperty(disp2, root2, prop_root, XA_PIXMAP, 32, + PropModeReplace, (unsigned char *) &pmap_d2, 1); XChangeProperty(disp2, root2, prop_esetroot, XA_PIXMAP, 32, - PropModeReplace, (unsigned char *) &pmap_d2, 1); + PropModeReplace, (unsigned char *) &pmap_d2, 1); XSetWindowBackgroundPixmap(disp2, root2, pmap_d2); XClearWindow(disp2, root2); From 3d90a1ab3b429f1ab6411e55bdc8b585fbce9114 Mon Sep 17 00:00:00 2001 From: Alec Cox Date: Mon, 8 Feb 2021 12:34:06 -0800 Subject: [PATCH 5/5] added man/help entry for bg-preserve --- man/feh.pre | 3 +++ src/help.raw | 2 ++ 2 files changed, 5 insertions(+) diff --git a/man/feh.pre b/man/feh.pre index 79aa3551..5e900459 100644 --- a/man/feh.pre +++ b/man/feh.pre @@ -1223,6 +1223,9 @@ Tile .Pq repeat the image in case it is too small for the screen . +.It Cm --bg-preserve +Combines the results of the addition of the new background with any possibly existing background. +. .It Cm --no-fehbg . Do not write a diff --git a/src/help.raw b/src/help.raw index 18469084..61eac06c 100644 --- a/src/help.raw +++ b/src/help.raw @@ -82,6 +82,8 @@ OPTIONS fill the whole background, but the images' aspect ratio may not be preserved --bg-tile FILE Set FILE as tiled desktop background + --bg-preserve Combines the results of the addition of the new + background with any possibly existing background. --no-fehbg Do not write a ~/.fehbg file -C, --fontpath PATH Specify an extra directory to look in for fonts, can be used multiple times to add multiple paths.