summarylogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.SRCINFO40
-rw-r--r--01-TranslucentMenus.patch503
-rw-r--r--02-ColourBorders.patch1619
-rw-r--r--03-ResizeOutlineThin.patch352
-rw-r--r--04-Conditionals.patch41
-rw-r--r--05-FlatSeparators.patch172
-rw-r--r--06-BorderUnderTitle.patch213
-rw-r--r--07-InactiveFont.patch345
-rw-r--r--08-FluxRoundedCorners.patch (renamed from 02-FluxRoundedCorners.patch)316
-rw-r--r--09-TopBorder.patch200
-rw-r--r--10-ButtonWidth.patch26
-rw-r--r--11-MultiBorder.patch546
-rw-r--r--12-FvwmButtonsTips.patch322
-rw-r--r--13-FvwmIconMan.patch114
-rw-r--r--14-Hover.patch295
-rw-r--r--15-FirstItemUnderPointer.patch18
-rw-r--r--16-ThinGeometryProxy.patch25
-rw-r--r--17-MiniIconSize.patch (renamed from 01-MiniIconSize.patch)4
-rw-r--r--PKGBUILD112
19 files changed, 5091 insertions, 172 deletions
diff --git a/.SRCINFO b/.SRCINFO
index 80981c4a6061..4b992356ff81 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,7 +1,7 @@
pkgbase = fvwm-patched
pkgdesc = A multiple large virtual desktop window manager originally derived from twm with patches
pkgver = 2.6.9
- pkgrel = 1
+ pkgrel = 2
url = https://github.com/willscreel/fvwm-patched
arch = x86_64
license = GPL
@@ -23,12 +23,42 @@ pkgbase = fvwm-patched
options = !makeflags
source = https://github.com/fvwmorg/fvwm/releases/download/2.6.9/fvwm-2.6.9.tar.gz
source = fvwm.desktop
- source = 01-MiniIconSize.patch
- source = 02-FluxRoundedCorners.patch
+ source = 01-TranslucentMenus.patch
+ source = 02-ColourBorders.patch
+ source = 03-ResizeOutlineThin.patch
+ source = 04-Conditionals.patch
+ source = 05-FlatSeparators.patch
+ source = 06-BorderUnderTitle.patch
+ source = 07-InactiveFont.patch
+ source = 08-FluxRoundedCorners.patch
+ source = 09-TopBorder.patch
+ source = 10-ButtonWidth.patch
+ source = 11-MultiBorder.patch
+ source = 12-FvwmButtonsTips.patch
+ source = 13-FvwmIconMan.patch
+ source = 14-Hover.patch
+ source = 15-FirstItemUnderPointer.patch
+ source = 16-ThinGeometryProxy.patch
+ source = 17-MiniIconSize.patch
sha256sums = 1bc64cf3ccd0073008758168327a8265b8059def9b239b451d6b9fab2cc391ae
sha256sums = 51d345f995f57c6d881d48bf535f71d75041a9bf1f0fa41dd99e1b22fd66aaf3
- sha256sums = ceef06afc53282e4a0095994258a7a40708c54bd8decc395eff8bb72d64a6b49
- sha256sums = 3c44bbf465a89bbb078ce6be2c6e6a02dca02983cec9252c2a628b5210c24c0a
+ sha256sums = 08d7fef7d0f3216b39f41932705ea68c0d255a0c2a1138bf4614070c7250a4a7
+ sha256sums = 749c536ff838e528f1e9345f18ca3948559cc788bdeb49f03c9676756576fc62
+ sha256sums = fe235e46d24a33ea7c1b6ba0753f93c5733d6e5de29e5efae71ba7bdbe49f9ac
+ sha256sums = 0d202215543f52b4b3249ac7f0117ca8abba35e913c45cb9173dfc10fe8746a7
+ sha256sums = b3eedf33687f3b76cc3940867af8068285226a9b8f83dbde1152ee7b72dac446
+ sha256sums = 2fdf0723b790890a1740e7bd2e1d064dda4e468661fcabd659a374613ea84b46
+ sha256sums = 15d197d8fb630725a65dd9007a0eedf0910e9956d8796a0aedcd9507dcab668e
+ sha256sums = b4767f0fe0dd67ab586d0d64d368ff91bb257221d978db207c731c7f5e3a7049
+ sha256sums = 9f27e247cad58b3a91f90921cff4603cdf9e481c13e1c97b035a7f5634208a7e
+ sha256sums = 6d9daadaa1bdc7d1b050e50fa5a887d495c0ecf6770ef9a74b495cd9cbb0ad3f
+ sha256sums = 5d51807b3c8b3b4c1706abbe21d8d64af76ea5d2b9fb33355ffc5f17ce2bbd38
+ sha256sums = 973cc5dbef67522bfb4745fb5b8a3f1c22b82d1ff3124796b5fb5bb5cd429eaa
+ sha256sums = 24349e5cf1089fa26f8e94f0ba66adecba403eb0d13c95eb02441a4306db5ed8
+ sha256sums = 5a784682602f338c7b724c864f0b4f024ff9c4e86ee815124f168e8b94b85002
+ sha256sums = df8053d234883e21fe59ef7f3c117612be61740f86d392d2b3c3ee2ae314e0a0
+ sha256sums = 78d40d1181bac4f54b111eda7d3bbd1fcb704e36ac44b4e21ea786a1636f9d2e
+ sha256sums = cb1a593ebd65a06cdc1d6d26f95de5473269130969ce83ca2259948cbf4d6c33
pkgname = fvwm-patched
diff --git a/01-TranslucentMenus.patch b/01-TranslucentMenus.patch
new file mode 100644
index 000000000000..795ee6a77a0d
--- /dev/null
+++ b/01-TranslucentMenus.patch
@@ -0,0 +1,503 @@
+diff --unified --recursive --text fvwm-2.6.9/fvwm/colorset.c fvwm-patched/fvwm/colorset.c
+--- fvwm-2.6.9/fvwm/colorset.c 2018-05-26 05:35:26.000000000 -0600
++++ fvwm-patched/fvwm/colorset.c 2020-08-21 15:22:28.542638787 -0600
+@@ -164,6 +164,8 @@
+ "NoIconTint",
+ "IconAlpha",
+
++ "Translucent",
++ "NoTranslucent",
+ NULL
+ };
+
+@@ -625,6 +627,7 @@
+ char *fg_tint = NULL;
+ char *bg_tint = NULL;
+ char *icon_tint = NULL;
++ char *translucent_tint = NULL;
+ Bool have_pixels_changed = False;
+ Bool has_icon_pixels_changed = False;
+ Bool has_fg_changed = False;
+@@ -637,6 +640,7 @@
+ Bool has_fg_tint_changed = False;
+ Bool has_bg_tint_changed = False;
+ Bool has_icon_tint_changed = False;
++ Bool has_translucent_tint_changed = False;
+ Bool has_pixmap_changed = False;
+ Bool has_shape_changed = False;
+ Bool has_image_alpha_changed = False;
+@@ -764,6 +768,10 @@
+ case 21: /* Plain */
+ has_pixmap_changed = True;
+ free_colorset_background(cs, True);
++ cs->is_translucent = False;
++ cs->translucent_tint_percent = 0;
++ cs->color_flags &= ~TRANSLUCENT_TINT_SUPPLIED;
++ has_translucent_tint_changed = True;
+ break;
+ case 22: /* NoShape */
+ has_shape_changed = True;
+@@ -930,6 +938,24 @@
+ cs->icon_alpha_percent = tmp;
+ }
+ break;
++ case 42: /* Translucent */
++ cs->is_translucent = True;
++ parse_simple_tint(
++ cs, args, &translucent_tint,
++ TRANSLUCENT_TINT_SUPPLIED,
++ &has_translucent_tint_changed, &percent,
++ "Translucent");
++ if (has_translucent_tint_changed)
++ {
++ cs->translucent_tint_percent = percent;
++ }
++ break;
++ case 43: /* NoTranslucent */
++ cs->is_translucent = False;
++ cs->translucent_tint_percent = 0;
++ cs->color_flags &= ~TRANSLUCENT_TINT_SUPPLIED;
++ has_translucent_tint_changed = True;
++ break;
+ default:
+ /* test for ?Gradient */
+ if (option[0] && StrEquals(&option[1], "Gradient"))
+@@ -1633,6 +1659,27 @@
+ }
+
+ /*
++ * ---------- change the translucent tint colour ----------
++ */
++ if (has_translucent_tint_changed)
++ {
++ /* user specified colour */
++ if (translucent_tint != NULL)
++ {
++ PictureFreeColors(
++ dpy, Pcmap, &cs->translucent_tint, 1, 0, True);
++ cs->translucent_tint = GetColor(translucent_tint);
++ }
++ else
++ {
++ /* default */
++ PictureFreeColors(
++ dpy, Pcmap, &cs->translucent_tint, 1, 0, True);
++ cs->translucent_tint = GetColor(black);
++ }
++ }
++
++ /*
+ * ---------- send new colorset to fvwm and clean up ----------
+ */
+ /* make sure the server has this to avoid races */
+@@ -1728,6 +1775,7 @@
+ ncs->fgsh = GetColor(white);
+ ncs->tint = GetColor(black);
+ ncs->icon_tint = GetColor(black);
++ ncs->translucent_tint = GetColor(black);
+ ncs->pixmap = XCreatePixmapFromBitmapData(
+ dpy, Scr.NoFocusWin,
+ &g_bits[4 * (nColorsets % 3)], 4, 4,
+@@ -1745,6 +1793,7 @@
+ ncs->fgsh = GetForeShadow(ncs->fg, ncs->bg);
+ ncs->tint = GetColor(black);
+ ncs->icon_tint = GetColor(black);
++ ncs->translucent_tint = GetColor(black);
+ }
+ ncs->fg_tint = ncs->bg_tint = GetColor(black);
+ /* set flags for fg contrast, bg average */
+@@ -1756,6 +1805,7 @@
+ ncs->icon_alpha_percent = 100;
+ ncs->tint_percent = 0;
+ ncs->icon_tint_percent = 0;
++ ncs->translucent_tint_percent = 0;
+ ncs->fg_tint_percent = ncs->bg_tint_percent = 0;
+ ncs->dither = (PictureDitherByDefault())? True:False;
+ nColorsets++;
+Only in fvwm-patched/fvwm: colorset.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/menuroot.h fvwm-patched/fvwm/menuroot.h
+--- fvwm-2.6.9/fvwm/menuroot.h 2016-10-15 08:51:45.000000000 -0600
++++ fvwm-patched/fvwm/menuroot.h 2020-08-21 15:22:28.542638787 -0600
+@@ -146,6 +146,9 @@
+ int d_npixels;
+ } stored_pixels;
+ /* alloc pixels when dithering is used for gradients */
++ /* x,y XMapRaise */
++ int x;
++ int y;
+ } MenuRootDynamic;
+
+ /* access macros to dynamic menu members */
+diff --unified --recursive --text fvwm-2.6.9/fvwm/menus.c fvwm-patched/fvwm/menus.c
+--- fvwm-2.6.9/fvwm/menus.c 2018-05-26 05:35:26.000000000 -0600
++++ fvwm-patched/fvwm/menus.c 2020-08-21 15:22:28.542638787 -0600
+@@ -78,6 +78,19 @@
+ #define SCTX_GET_MR(ctx) ((ctx).type == SCTX_MENU_ROOT ? \
+ (ctx).menu_root.menu_root : NULL)
+
++#define MENU_IS_TRANSLUCENT(mr,cs) \
++ (!MR_IS_TEAR_OFF_MENU(mr) && CSET_IS_TRANSLUCENT(cs))
++#define MENU_IS_TRANSPARENT(mr,cs) \
++ (MENU_IS_TRANSLUCENT(mr,cs) || CSET_IS_TRANSPARENT(cs))
++#define MR_IS_TRANSLUCENT_MENU(mr) \
++ (!MR_IS_TEAR_OFF_MENU(mr) && MR_STYLE(mr) && \
++ ST_HAS_MENU_CSET(MR_STYLE(mr)) && CSET_IS_TRANSLUCENT( \
++ ST_CSET_MENU(MR_STYLE(mr))))
++#define MR_IS_TRANSPARENT_MENU(mr) \
++ (MR_IS_TRANSLUCENT_MENU(mr) || (MR_STYLE(mr) && \
++ ST_HAS_MENU_CSET(MR_STYLE(mr)) && CSET_IS_TRANSPARENT( \
++ ST_CSET_MENU(MR_STYLE(mr)))))
++
+ /* ---------------------------- imports ------------------------------------ */
+
+ /* This external is safe. It's written only during startup. */
+@@ -220,6 +233,8 @@
+ } mloop_static_info_t;
+
+ /* ---------------------------- forward declarations ----------------------- */
++static MenuRoot *seek_submenu_instance(
++ MenuRoot *parent_menu, MenuItem *parent_item);
+
+ /* ---------------------------- local variables ---------------------------- */
+
+@@ -381,12 +396,22 @@
+ Bool transparent_bg = False;
+
+ /* move it back */
+- if (ST_HAS_MENU_CSET(MR_STYLE(mr)) &&
+- CSET_IS_TRANSPARENT(ST_CSET_MENU(MR_STYLE(mr))))
++ if (MR_IS_TRANSPARENT_MENU(mr))
+ {
+ transparent_bg = True;
+ get_menu_repaint_transparent_parameters(
+ &mrtp, mr, fw);
++ if (MR_IS_TRANSLUCENT_MENU(mr) && MR_SUBMENU_ITEM(mr))
++ {
++ MenuRoot *smr;
++ smr = seek_submenu_instance(
++ mr, MR_SUBMENU_ITEM(mr));
++ if (smr)
++ {
++ /* just unmap it here, popdown later */
++ XUnmapWindow(dpy, MR_WINDOW(smr));
++ }
++ }
+ }
+ AnimatedMoveOfWindow(
+ MR_WINDOW(mr), act_x, act_y, act_x - MR_XANIMATION(mr),
+@@ -1912,6 +1937,7 @@
+ /* Doh. Use the standard display instead. */
+ MR_CREATE_DPY(mr) = dpy;
+ }
++ MR_IS_TEAR_OFF_MENU(mr) = 1;
+ }
+ else
+ {
+@@ -2716,7 +2742,37 @@
+ }
+ MR_IS_PAINTED(mr) = 1;
+ /* paint the menu background */
+- if (ms && ST_HAS_MENU_CSET(ms))
++ if (MR_IS_TRANSLUCENT_MENU(mr))
++ {
++ Pixmap trans = None;
++ FvwmRenderAttributes fra;
++ colorset_t *colorset = &Colorset[ST_CSET_MENU(ms)];
++
++ fra.mask = 0;
++ if (colorset->translucent_tint_percent > 0)
++ {
++ fra.mask = FRAM_HAVE_TINT;
++ fra.tint = colorset->translucent_tint;
++ fra.tint_percent = colorset->translucent_tint_percent;
++ }
++ if (MR_IS_BACKGROUND_SET(mr) == False)
++ {
++ trans = PGraphicsCreateTranslucent(
++ dpy, MR_WINDOW(mr), &fra,
++ BACK_GC(ST_MENU_INACTIVE_GCS(ms)),
++ MR_X(mr), MR_Y(mr), MR_WIDTH(mr), MR_HEIGHT(mr));
++ XMapRaised(dpy, MR_WINDOW(mr));
++ if (trans != None)
++ {
++ XSetWindowBackgroundPixmap(
++ dpy, MR_WINDOW(mr), trans);
++ MR_IS_BACKGROUND_SET(mr) = True;
++ clear_expose_menu_area(MR_WINDOW(mr), pevent);
++ XFreePixmap(dpy, trans);
++ }
++ }
++ }
++ else if (ms && ST_HAS_MENU_CSET(ms))
+ {
+ if (MR_IS_BACKGROUND_SET(mr) == False)
+ {
+@@ -3525,10 +3581,7 @@
+ MR_HAS_POPPED_UP_RIGHT(mr) = 0;
+ }
+ MR_XANIMATION(parent_menu) += end_x - prev_x;
+- if (ST_HAS_MENU_CSET(MR_STYLE(parent_menu)) &&
+- CSET_IS_TRANSPARENT(
+- ST_CSET_MENU(
+- MR_STYLE(parent_menu))))
++ if (MR_IS_TRANSPARENT_MENU(parent_menu))
+ {
+ transparent_bg = True;
+ get_menu_repaint_transparent_parameters(
+@@ -3707,10 +3760,21 @@
+ */
+
+ XMoveWindow(dpy, MR_WINDOW(mr), x, y);
++ MR_X(mr) = x;
++ MR_Y(mr) = y;
+ XSelectInput(dpy, MR_WINDOW(mr), event_mask);
+- XMapRaised(dpy, MR_WINDOW(mr));
+- if (popdown_window)
+- XUnmapWindow(dpy, popdown_window);
++ if (MR_IS_TRANSLUCENT_MENU(mr))
++ {
++ if (popdown_window)
++ XUnmapWindow(dpy, popdown_window);
++ paint_menu(mr, NULL, fw);
++ }
++ else
++ {
++ XMapRaised(dpy, MR_WINDOW(mr));
++ if (popdown_window)
++ XUnmapWindow(dpy, popdown_window);
++ }
+ XFlush(dpy);
+ MR_MAPPED_COPIES(mr)++;
+ MST_USAGE_COUNT(mr)++;
+@@ -6274,16 +6338,122 @@
+ {
+ last = True;
+ }
+- if (!last && CSET_IS_TRANSPARENT_PR_TINT(ST_CSET_MENU(ms)))
++ if (!last &&
++ (CSET_IS_TRANSPARENT_PR_TINT(ST_CSET_MENU(ms)) ||
++ MR_IS_TRANSLUCENT_MENU(mr)))
+ {
+ /* too slow ... */
+ return;
+ }
+- SetWindowBackgroundWithOffset(
+- dpy, MR_WINDOW(mr), step_x - current_x, step_y - current_y,
+- MR_WIDTH(mr), MR_HEIGHT(mr),
+- &Colorset[ST_CSET_MENU(ms)], Pdepth,
+- FORE_GC(MST_MENU_INACTIVE_GCS(mr)), False);
++ if (MR_IS_TRANSLUCENT_MENU(mr))
++ {
++ Pixmap trans, tmp;
++ FvwmRenderAttributes fra;
++ colorset_t *colorset = &Colorset[ST_CSET_MENU(ms)];
++
++ fra.mask = 0;
++ if (colorset->translucent_tint_percent > 0)
++ {
++ fra.mask = FRAM_HAVE_TINT;
++ fra.tint = colorset->translucent_tint;
++ fra.tint_percent = colorset->translucent_tint_percent;
++ }
++ if (current_x == step_x)
++ {
++ /* Reuse the old pixmap for the part of the menu
++ * that has not moved. (This can be extended to get
++ * two new rectangles, one in each direction)
++ *
++ * It saves the unmapping of the window and makes
++ * Things less flickering.
++ */
++ GC my_gc;
++ unsigned long valuemask = GCSubwindowMode;
++ XGCValues values;
++ int out_y=0;
++ values.subwindow_mode = IncludeInferiors;
++ if (step_y < 0)
++ {
++ out_y = -step_y;
++ }
++ trans = XCreatePixmap(dpy, MR_WINDOW(mr), MR_WIDTH(mr),
++ MR_HEIGHT(mr), Pdepth);
++ my_gc = fvwmlib_XCreateGC(dpy, MR_WINDOW(mr), 0, NULL);
++ XChangeGC(dpy, my_gc, valuemask, &values);
++
++ XClearWindow(dpy, MR_WINDOW(mr));
++
++ if (current_y < step_y)
++ {
++ XCopyArea(dpy, MR_WINDOW(mr), trans, my_gc, 0,
++ step_y-current_y, MR_WIDTH(mr),
++ MR_HEIGHT(mr)-(step_y-current_y),
++ 0,0);
++ tmp = PGraphicsCreateTranslucent(
++ dpy, MR_WINDOW(mr), &fra,
++ BACK_GC(ST_MENU_INACTIVE_GCS(ms)),
++ current_x, current_y+MR_HEIGHT(mr),
++ MR_WIDTH(mr), step_y-current_y);
++
++ XCopyArea(dpy, tmp, trans, my_gc, 0, 0,
++ MR_WIDTH(mr), step_y-current_y,0,
++ MR_HEIGHT(mr)-(step_y-current_y));
++ }
++ else
++ {
++ XCopyArea(dpy, MR_WINDOW(mr), trans, my_gc, 0,
++ 0, MR_WIDTH(mr),
++ MR_HEIGHT(mr)-(current_y-step_y), 0,
++ current_y-step_y);
++ tmp = PGraphicsCreateTranslucent(
++ dpy, MR_WINDOW(mr), &fra,
++ BACK_GC(ST_MENU_INACTIVE_GCS(ms)),
++ current_x,step_y, MR_WIDTH(mr),
++ current_y-step_y);
++ XCopyArea(dpy, tmp, trans, my_gc, 0, 0,
++ MR_WIDTH(mr), current_y-step_y,0,
++ out_y);
++ }
++ MR_X(mr) = step_x;
++ MR_Y(mr) = step_y;
++ XFreePixmap(dpy, tmp);
++ XFreeGC(dpy,my_gc);
++ }
++ else
++ {
++ XUnmapWindow(dpy, MR_WINDOW(mr));
++ MR_X(mr) = step_x;
++ MR_Y(mr) = step_y;
++ trans = PGraphicsCreateTranslucent(
++ dpy, MR_WINDOW(mr), &fra,
++ BACK_GC(ST_MENU_INACTIVE_GCS(ms)),
++ step_x, step_y, MR_WIDTH(mr),
++ MR_HEIGHT(mr));
++ XMapRaised(dpy, MR_WINDOW(mr));
++ }
++ XSetWindowBackgroundPixmap(
++ dpy, MR_WINDOW(mr), trans);
++ XFreePixmap(dpy, trans);
++ if (current_x == step_x)
++ {
++ /* Redraw the border */
++ RelieveRectangle(
++ dpy, MR_WINDOW(mr), 0, 0, MR_WIDTH(mr) - 1,
++ MR_HEIGHT(mr) - 1, (Pdepth < 2) ?
++ SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)) :
++ HILIGHT_GC(MST_MENU_INACTIVE_GCS(mr)),
++ SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)),
++ MST_BORDER_WIDTH(mr));
++ }
++ }
++ else
++ {
++ SetWindowBackgroundWithOffset(
++ dpy, MR_WINDOW(mr), step_x - current_x,
++ step_y - current_y, MR_WIDTH(mr), MR_HEIGHT(mr),
++ &Colorset[ST_CSET_MENU(ms)], Pdepth,
++ FORE_GC(MST_MENU_INACTIVE_GCS(mr)), False);
++ }
+ }
+
+
+@@ -6324,10 +6494,7 @@
+ }
+ if (!is_bg_set)
+ {
+- SetWindowBackground(
+- dpy, MR_WINDOW(mr), MR_WIDTH(mr), MR_HEIGHT(mr),
+- &Colorset[ST_CSET_MENU(ms)], Pdepth,
+- FORE_GC(MST_MENU_INACTIVE_GCS(mr)), False);
++ update_transparent_menu_bg(prtm, x, y, x, y, end_x, end_y);
+ }
+ /* redraw the background of non active item */
+ for (mi = MR_FIRST_ITEM(mr); mi != NULL; mi = MI_NEXT_ITEM(mi))
+@@ -6951,10 +7118,12 @@
+ SetWindowBackground(
+ dpy, MR_WINDOW(mr), MR_WIDTH(mr),
+ MR_HEIGHT(mr),
+- &Colorset[ST_CSET_MENU(ms)],
+- Pdepth,
++ &Colorset[ST_CSET_MENU(ms)], Pdepth,
+ FORE_GC(MST_MENU_INACTIVE_GCS(mr)),
+- True);
++ False);
++ XClearArea(
++ dpy, MR_WINDOW(mr), 0, 0, MR_WIDTH(mr),
++ MR_HEIGHT(mr), True);
+ }
+ else if ((ST_HAS_ACTIVE_CSET(ms) &&
+ ST_CSET_ACTIVE(ms) == cset) ||
+Only in fvwm-patched/fvwm: menus.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/menus.h fvwm-patched/fvwm/menus.h
+--- fvwm-2.6.9/fvwm/menus.h 2016-10-15 08:51:45.000000000 -0600
++++ fvwm-patched/fvwm/menus.h 2020-08-21 15:22:28.542638787 -0600
+@@ -15,6 +15,9 @@
+ #define IS_MENU_RETURN(x) \
+ ((x)==MENU_DONE || (x)==MENU_ABORTED || (x)==MENU_SUBMENU_TORN_OFF)
+
++#define MR_X(m) ((m)->d->x)
++#define MR_Y(m) ((m)->d->y)
++
+ struct MenuRoot;
+ struct MenuStyle;
+ struct MenuReturn;
+diff --unified --recursive --text fvwm-2.6.9/libs/Colorset.h fvwm-patched/libs/Colorset.h
+--- fvwm-2.6.9/libs/Colorset.h 2016-10-15 08:51:45.000000000 -0600
++++ fvwm-patched/libs/Colorset.h 2020-08-21 15:22:28.542638787 -0600
+@@ -51,6 +51,10 @@
+ Bool dither;
+ Bool allows_buffered_transparency;
+ Bool is_maybe_root_transparent;
++ /* only use by fvwm menu (non tear-off) */
++ Bool is_translucent;
++ Pixel translucent_tint;
++ unsigned int translucent_tint_percent : 7;
+ #endif
+ } colorset_t;
+
+@@ -78,6 +82,7 @@
+ #define FG_TINT_SUPPLIED 0x100
+ #define BG_TINT_SUPPLIED 0x200
+ #define ICON_TINT_SUPPLIED 0x400
++#define TRANSLUCENT_TINT_SUPPLIED 0x800
+ #endif
+
+ /* colorsets are stored as an array of structs to permit fast dereferencing */
+@@ -153,6 +158,11 @@
+ (cset != NULL && cset->pixmap == ParentRelative && \
+ cset->tint_percent > 0)
+
++#define CSET_IS_TRANSLUCENT(cset) \
++ (cset >= 0 && Colorset[cset].is_translucent)
++#define CSETS_IS_TRANSLUCENT(cset) \
++ (cset && cset->is_translucent)
++
+ #ifndef FVWM_COLORSET_PRIVATE
+ /* Create n new colorsets, fvwm/colorset.c does its own thing (different size)
+ */
+diff --unified --recursive --text fvwm-2.6.9/libs/PictureGraphics.c fvwm-patched/libs/PictureGraphics.c
+--- fvwm-2.6.9/libs/PictureGraphics.c 2018-05-26 05:35:26.000000000 -0600
++++ fvwm-patched/libs/PictureGraphics.c 2020-08-21 15:22:28.542638787 -0600
+@@ -1360,7 +1360,7 @@
+ }
+ }
+
+-#if 0 /* humm... maybe useful one day with menus */
++#if 1 /* humm... maybe useful one day with menus */
+ Pixmap PGraphicsCreateTranslucent(
+ Display *dpy, Window win, FvwmRenderAttributes *fra, GC gc,
+ int x, int y, int width, int height)
+Only in fvwm-patched/libs: PictureGraphics.c.orig
+diff --unified --recursive --text fvwm-2.6.9/libs/PictureGraphics.h fvwm-patched/libs/PictureGraphics.h
+--- fvwm-2.6.9/libs/PictureGraphics.h 2016-10-15 08:51:45.000000000 -0600
++++ fvwm-patched/libs/PictureGraphics.h 2020-08-21 15:22:28.542638787 -0600
+@@ -122,7 +122,9 @@
+ Display *dpy, Window win, Pixel tint, int tint_percent,
+ Drawable dest, Bool dest_is_a_window, GC gc, GC mono_gc, GC alpha_gc,
+ int dest_x, int dest_y, int dest_w, int dest_h);
+-
++Pixmap PGraphicsCreateTranslucent(
++ Display *dpy, Window win, FvwmRenderAttributes *fra, GC gc,
++ int x, int y, int width, int height);
+ /* never used ! */
+ Pixmap PGraphicsCreateDitherPixmap(
+ Display *dpy, Window win, Drawable src, Pixmap mask, int depth, GC gc,
diff --git a/02-ColourBorders.patch b/02-ColourBorders.patch
new file mode 100644
index 000000000000..68489814e8d8
--- /dev/null
+++ b/02-ColourBorders.patch
@@ -0,0 +1,1619 @@
+diff --unified --recursive --text fvwm-2.6.9/fvwm/borders.c fvwm-patched/fvwm/borders.c
+--- fvwm-2.6.9/fvwm/borders.c 2018-05-26 05:35:26.000000000 -0600
++++ fvwm-patched/fvwm/borders.c 2020-08-21 15:29:14.150834565 -0600
+@@ -115,14 +115,71 @@
+ int relief_width;
+ GC relief_gc;
+ GC shadow_gc;
++ GC relief_gc_north;
++ GC shadow_gc_north;
++ GC relief_gc_south;
++ GC shadow_gc_south;
++ GC relief_gc_east;
++ GC shadow_gc_east;
++ GC relief_gc_west;
++ GC shadow_gc_west;
++ GC relief_gc_nw;
++ GC shadow_gc_nw;
++ GC relief_gc_ne;
++ GC shadow_gc_ne;
++ GC relief_gc_sw;
++ GC shadow_gc_sw;
++ GC relief_gc_se;
++ GC shadow_gc_se;
++
+ Pixel fore_color;
+ Pixel back_color;
+- int cs;
++ Pixel fore_color_north;
++ Pixel back_color_north;
++ Pixel fore_color_south;
++ Pixel back_color_south;
++ Pixel fore_color_east;
++ Pixel back_color_east;
++ Pixel fore_color_west;
++ Pixel back_color_west;
++ Pixel fore_color_nw;
++ Pixel back_color_nw;
++ Pixel fore_color_ne;
++ Pixel back_color_ne;
++ Pixel fore_color_sw;
++ Pixel back_color_sw;
++ Pixel fore_color_se;
++ Pixel back_color_se;
++
++ int cs;
++ int cs_north;
++ int cs_south;
++ int cs_east;
++ int cs_west;
+ int border_cs; /* for UseBorderStyle */
++ int border_cs_north;
++ int border_cs_south;
++ int border_cs_east;
++ int border_cs_west;
++
++ int cs_nw;
++ int cs_ne;
++ int cs_sw;
++ int cs_se;
+ int bg_border_cs; /* for UseBorderStyle */
+ Pixmap back_pixmap;
+- XSetWindowAttributes attributes;
+- unsigned long valuemask;
++
++ XSetWindowAttributes attributes;
++ XSetWindowAttributes attributes_north;
++ XSetWindowAttributes attributes_ne;
++ XSetWindowAttributes attributes_nw;
++ XSetWindowAttributes attributes_sw;
++ XSetWindowAttributes attributes_se;
++ XSetWindowAttributes attributes_south;
++ XSetWindowAttributes attributes_east;
++ XSetWindowAttributes attributes_west;
++
++ unsigned long valuemask;
+ Pixmap texture_pixmap;
+ int texture_pixmap_width;
+ int texture_pixmap_height;
+@@ -320,10 +377,29 @@
+ {
+ DecorFace *df;
+ color_quad *draw_colors;
++ color_quad *draw_colors_north;
++ color_quad *draw_colors_south;
++ color_quad *draw_colors_east;
++ color_quad *draw_colors_west;
++
++ color_quad *draw_colors_nw;
++ color_quad *draw_colors_ne;
++ color_quad *draw_colors_sw;
++ color_quad *draw_colors_se;
+
+ df = border_get_border_style(t, has_focus);
+ cd->bg_border_cs = -1;
+ cd->cs = -1;
++ cd->cs_north = -1;
++ cd->cs_south = -1;
++ cd->cs_east = -1;
++ cd->cs_west = -1;
++
++ cd->cs_nw = -1;
++ cd->cs_ne = -1;
++ cd->cs_sw = -1;
++ cd->cs_se = -1;
++
+ if (has_focus)
+ {
+ /* are we using textured borders? */
+@@ -347,11 +423,61 @@
+ {
+ draw_colors = &(t->border_hicolors);
+ cd->cs = t->border_cs_hi;
++
++ draw_colors_north = &(t->border_hicolors_north);
++ cd->cs_north = t->border_cs_hi_north;
++
++ draw_colors_south = &(t->border_hicolors_south);
++ cd->cs_south = t->border_cs_hi_south;
++
++ draw_colors_east = &(t->border_hicolors_east);
++ cd->cs_east = t->border_cs_hi_east;
++
++ draw_colors_west = &(t->border_hicolors_west);
++ cd->cs_west = t->border_cs_hi_west;
++
++ /* handles */
++ draw_colors_nw = &(t->border_hicolors_handles_nw);
++ cd->cs_nw = t->border_cs_hi_handles_nw;
++
++ draw_colors_ne = &(t->border_hicolors_handles_ne);
++ cd->cs_ne = t->border_cs_hi_handles_ne;
++
++ draw_colors_sw = &(t->border_hicolors_handles_sw);
++ cd->cs_sw = t->border_cs_hi_handles_sw;
++
++ draw_colors_se = &(t->border_hicolors_handles_se);
++ cd->cs_se = t->border_cs_hi_handles_se;
+ }
+ else
+ {
+ draw_colors = &(t->hicolors);
+ cd->cs = t->cs_hi;
++
++ draw_colors_north = &(t->hicolors);
++ cd->cs_north = t->cs_hi;
++
++ draw_colors_south = &(t->hicolors);
++ cd->cs_south = t->cs_hi;
++
++ draw_colors_east = &(t->hicolors);
++ cd->cs_east = t->cs_hi;
++
++ draw_colors_west = &(t->hicolors);
++ cd->cs_west = t->cs_hi;
++
++ /* handles */
++ draw_colors_nw = &(t->hicolors);
++ cd->cs_nw = t->cs_hi;
++
++ draw_colors_ne = &(t->hicolors);
++ cd->cs_ne = t->cs_hi;
++
++ draw_colors_sw = &(t->hicolors);
++ cd->cs_sw = t->cs_hi;
++
++ draw_colors_se = &(t->hicolors);
++ cd->cs_se = t->cs_hi;
+ }
+ }
+ else
+@@ -383,24 +509,167 @@
+ {
+ draw_colors = &(t->border_colors);
+ cd->cs = t->border_cs;
++
++ draw_colors_north = &(t->border_colors_north);
++ cd->cs_north = t->border_cs_north;
++
++ draw_colors_south = &(t->border_colors_south);
++ cd->cs_south = t->border_cs_south;
++
++ draw_colors_east = &(t->border_colors_east);
++ cd->cs_east = t->border_cs_east;
++
++ draw_colors_west = &(t->border_colors_west);
++ cd->cs_west = t->border_cs_west;
++
++ /* handles */
++ draw_colors_nw = &(t->border_colors_handles_nw);
++ cd->cs_nw = t->border_cs_handles_nw;
++
++ draw_colors_ne = &(t->border_colors_handles_ne);
++ cd->cs_ne = t->border_cs_handles_ne;
++
++ draw_colors_sw = &(t->border_colors_handles_sw);
++ cd->cs_sw = t->border_cs_handles_sw;
++
++ draw_colors_se = &(t->border_colors_handles_se);
++ cd->cs_se = t->border_cs_handles_se;
++
+ }
+ else
+ {
+ draw_colors = &(t->colors);
+ cd->cs = t->cs;
++
++ draw_colors_north = &(t->border_colors_north);
++ cd->cs_north = t->cs;
++
++ draw_colors_south = &(t->border_colors_south);
++ cd->cs_south = t->cs;
++
++ draw_colors_east = &(t->border_colors_east);
++ cd->cs_east = t->cs;
++
++ draw_colors_west = &(t->border_colors_west);
++ cd->cs_west = t->cs;
++
++ /* handles */
++ draw_colors_nw = &(t->border_colors_handles_nw);
++ cd->cs_nw = t->border_cs_handles_nw;
++
++ draw_colors_ne = &(t->border_colors_handles_ne);
++ cd->cs_ne = t->border_cs_handles_ne;
++
++ draw_colors_sw = &(t->border_colors_handles_sw);
++ cd->cs_sw = t->border_cs_handles_sw;
++
++ draw_colors_se = &(t->border_colors_handles_se);
++ cd->cs_se = t->border_cs_handles_se;
+ }
+ }
+ cd->fore_color = draw_colors->fore;
+ cd->back_color = draw_colors->back;
+- if (do_change_gcs)
++
++ cd->fore_color_north = draw_colors_north->fore;
++ cd->back_color_north = draw_colors_north->back;
++
++ cd->fore_color_south = draw_colors_south->fore;
++ cd->back_color_south = draw_colors_south->back;
++
++ cd->fore_color_east = draw_colors_east->fore;
++ cd->back_color_east = draw_colors_east->back;
++
++ cd->fore_color_west = draw_colors_west->fore;
++ cd->back_color_west = draw_colors_west->back;
++
++ cd->fore_color_nw = draw_colors_nw->fore;
++ cd->back_color_nw = draw_colors_nw->back;
++
++ cd->fore_color_ne = draw_colors_ne->fore;
++ cd->back_color_ne = draw_colors_ne->back;
++
++ cd->fore_color_sw = draw_colors_nw->fore;
++ cd->back_color_sw = draw_colors_nw->back;
++
++ cd->fore_color_se = draw_colors_se->fore;
++ cd->back_color_se = draw_colors_se->back;
++
++ if (do_change_gcs)
+ {
+ Globalgcv.foreground = draw_colors->hilight;
+ Globalgcm = GCForeground;
+ XChangeGC(dpy, Scr.ScratchGC1, Globalgcm, &Globalgcv);
+ Globalgcv.foreground = draw_colors->shadow;
+ XChangeGC(dpy, Scr.ScratchGC2, Globalgcm, &Globalgcv);
++
++ Globalgcv.foreground = draw_colors_north->hilight;
++ XChangeGC(dpy, Scr.ScratchGC3, Globalgcm, &Globalgcv);
++ Globalgcv.foreground = draw_colors_north->shadow;
++ XChangeGC(dpy, Scr.ScratchGC4, Globalgcm, &Globalgcv);
++
++ Globalgcv.foreground = draw_colors_south->hilight;
++ XChangeGC(dpy, Scr.ScratchGC5, Globalgcm, &Globalgcv);
++ Globalgcv.foreground = draw_colors_south->shadow;
++ XChangeGC(dpy, Scr.ScratchGC6, Globalgcm, &Globalgcv);
++
++ Globalgcv.foreground = draw_colors_east->hilight;
++ XChangeGC(dpy, Scr.ScratchGC7, Globalgcm, &Globalgcv);
++ Globalgcv.foreground = draw_colors_east->shadow;
++ XChangeGC(dpy, Scr.ScratchGC8, Globalgcm, &Globalgcv);
++
++ Globalgcv.foreground = draw_colors_west->hilight;
++ XChangeGC(dpy, Scr.ScratchGC9, Globalgcm, &Globalgcv);
++ Globalgcv.foreground = draw_colors_west->shadow;
++ XChangeGC(dpy, Scr.ScratchGC10, Globalgcm, &Globalgcv);
++
++ /* handles. */
++ Globalgcv.foreground = draw_colors_nw->hilight;
++ XChangeGC(dpy, Scr.ScratchGC11, Globalgcm, &Globalgcv);
++ Globalgcv.foreground = draw_colors_nw->shadow;
++ XChangeGC(dpy, Scr.ScratchGC12, Globalgcm, &Globalgcv);
++
++ Globalgcv.foreground = draw_colors_ne->hilight;
++ XChangeGC(dpy, Scr.ScratchGC13, Globalgcm, &Globalgcv);
++ Globalgcv.foreground = draw_colors_ne->shadow;
++ XChangeGC(dpy, Scr.ScratchGC14, Globalgcm, &Globalgcv);
++
++ Globalgcv.foreground = draw_colors_sw->hilight;
++ XChangeGC(dpy, Scr.ScratchGC15, Globalgcm, &Globalgcv);
++ Globalgcv.foreground = draw_colors_sw->shadow;
++ XChangeGC(dpy, Scr.ScratchGC16, Globalgcm, &Globalgcv);
++
++ Globalgcv.foreground = draw_colors_se->hilight;
++ XChangeGC(dpy, Scr.ScratchGC17, Globalgcm, &Globalgcv);
++ Globalgcv.foreground = draw_colors_se->shadow;
++ XChangeGC(dpy, Scr.ScratchGC18, Globalgcm, &Globalgcv);
++
+ cd->relief_gc = Scr.ScratchGC1;
+ cd->shadow_gc = Scr.ScratchGC2;
++
++ cd->relief_gc_north = Scr.ScratchGC3;
++ cd->shadow_gc_north = Scr.ScratchGC4;
++
++ cd->relief_gc_south = Scr.ScratchGC5;
++ cd->shadow_gc_south = Scr.ScratchGC6;
++
++ cd->relief_gc_east = Scr.ScratchGC7;
++ cd->shadow_gc_east = Scr.ScratchGC8;
++
++ cd->relief_gc_west = Scr.ScratchGC9;
++ cd->shadow_gc_west = Scr.ScratchGC10;
++
++ /* Handles */
++ cd->relief_gc_nw = Scr.ScratchGC11;
++ cd->shadow_gc_nw = Scr.ScratchGC12;
++
++ cd->relief_gc_ne = Scr.ScratchGC13;
++ cd->shadow_gc_ne = Scr.ScratchGC14;
++
++ cd->relief_gc_sw = Scr.ScratchGC15;
++ cd->shadow_gc_sw = Scr.ScratchGC16;
++
++ cd->relief_gc_se = Scr.ScratchGC17;
++ cd->shadow_gc_se = Scr.ScratchGC18;
+ }
+
+ /* MWMBorder style means thin 3d effects */
+@@ -421,6 +690,17 @@
+ else
+ {
+ cd->attributes.background_pixel = cd->back_color;
++ cd->attributes_north.background_pixel = cd->back_color_north;
++ cd->attributes_south.background_pixel = cd->back_color_south;
++ cd->attributes_east.background_pixel = cd->back_color_east;
++ cd->attributes_west.background_pixel = cd->back_color_west;
++
++ /* handles */
++ cd->attributes_nw.background_pixel = cd->back_color_nw;
++ cd->attributes_ne.background_pixel = cd->back_color_ne;
++ cd->attributes_sw.background_pixel = cd->back_color_sw;
++ cd->attributes_se.background_pixel = cd->back_color_se;
++
+ cd->valuemask = CWBackPixel;
+ }
+ }
+@@ -790,7 +1070,7 @@
+
+ static void border_get_border_gcs(
+ draw_border_gcs *ret_gcs, common_decorations_type *cd, FvwmWindow *fw,
+- Bool do_hilight)
++ Bool do_hilight, window_parts part)
+ {
+ static GC transparent_gc = None;
+ DecorFaceStyle *borderstyle;
+@@ -814,17 +1094,102 @@
+ {
+ is_reversed = True;
+ }
+- if (is_reversed)
+- {
+- ret_gcs->shadow = cd->relief_gc;
+- ret_gcs->relief = cd->shadow_gc;
+- }
+- else
+- {
+- ret_gcs->relief = cd->relief_gc;
+- ret_gcs->shadow = cd->shadow_gc;
+- }
+-
++
++ switch ( part )
++ {
++ case PART_BORDER_N:
++ if( is_reversed )
++ {
++ ret_gcs->shadow = cd->relief_gc_north;
++ ret_gcs->relief = cd->shadow_gc_north;
++ } else {
++ ret_gcs->relief = cd->relief_gc_north;
++ ret_gcs->shadow = cd->shadow_gc_north;
++ }
++ break;
++ case PART_BORDER_S:
++ if( is_reversed )
++ {
++ ret_gcs->shadow = cd->relief_gc_south;
++ ret_gcs->relief = cd->shadow_gc_south;
++ } else {
++ ret_gcs->relief = cd->relief_gc_south;
++ ret_gcs->shadow = cd->shadow_gc_south;
++ }
++ break;
++ case PART_BORDER_E:
++ if( is_reversed )
++ {
++ ret_gcs->shadow = cd->relief_gc_east;
++ ret_gcs->relief = cd->shadow_gc_east;
++ } else {
++ ret_gcs->relief = cd->relief_gc_east;
++ ret_gcs->shadow = cd->shadow_gc_east;
++ }
++ break;
++ case PART_BORDER_W:
++ if( is_reversed )
++ {
++ ret_gcs->shadow = cd->relief_gc_west;
++ ret_gcs->relief = cd->shadow_gc_west;
++ } else {
++ ret_gcs->relief = cd->relief_gc_west;
++ ret_gcs->shadow = cd->shadow_gc_west;
++ }
++ break;
++ case PART_BORDER_NW:
++ if( is_reversed )
++ {
++ ret_gcs->shadow = cd->relief_gc_nw;
++ ret_gcs->relief = cd->shadow_gc_nw;
++ } else {
++ ret_gcs->relief = cd->relief_gc_nw;
++ ret_gcs->shadow = cd->shadow_gc_nw;
++ }
++ break;
++ case PART_BORDER_NE:
++ if( is_reversed )
++ {
++ ret_gcs->shadow = cd->relief_gc_ne;
++ ret_gcs->relief = cd->shadow_gc_ne;
++ } else {
++ ret_gcs->relief = cd->relief_gc_ne;
++ ret_gcs->shadow = cd->shadow_gc_ne;
++ }
++ break;
++ case PART_BORDER_SW:
++ if( is_reversed )
++ {
++ ret_gcs->shadow = cd->relief_gc_sw;
++ ret_gcs->relief = cd->shadow_gc_sw;
++ } else {
++ ret_gcs->relief = cd->relief_gc_sw;
++ ret_gcs->shadow = cd->shadow_gc_sw;
++ }
++ break;
++ case PART_BORDER_SE:
++ if( is_reversed )
++ {
++ ret_gcs->shadow = cd->relief_gc_se;
++ ret_gcs->relief = cd->shadow_gc_se;
++ } else {
++ ret_gcs->relief = cd->relief_gc_se;
++ ret_gcs->shadow = cd->shadow_gc_se;
++ }
++ break;
++ default:
++ if (is_reversed)
++ {
++ ret_gcs->shadow = cd->relief_gc;
++ ret_gcs->relief = cd->shadow_gc;
++ }
++ else
++ {
++ ret_gcs->relief = cd->relief_gc;
++ ret_gcs->shadow = cd->shadow_gc;
++ }
++ break;
++ }
+ return;
+ }
+
+@@ -1126,12 +1491,13 @@
+ }
+ if (do_draw_shadow)
+ {
+- x1 = x + k;
++ //x1 = x + k;
++ x1 = x;
+ y1 = y - 1 - k;
+ }
+ else
+ {
+- x1 = x;
++ x1 = x - k;
+ y1 = y + k;
+ }
+ x2 = x1 + length;
+@@ -1282,9 +1648,11 @@
+ valuemask |= GCForeground | GCClipMask | GCClipXOrigin |
+ GCClipYOrigin;
+ XChangeGC(dpy, Scr.BordersGC, valuemask, &xgcv);
+- XFillRectangle(
++
++ XFillRectangle(
+ dpy, dest_pix, Scr.BordersGC, dest_g->x, dest_g->y,
+ dest_g->width - dest_g->x, dest_g->height - dest_g->y);
++
+ return;
+ }
+
+@@ -1444,7 +1812,7 @@
+
+ static void border_get_border_background(
+ pixmap_background_type *bg, common_decorations_type *cd,
+- rectangle *part_g, rectangle *relative_g, int *free_bg_pixmap, Window w)
++ rectangle *part_g, rectangle *relative_g, int *free_bg_pixmap, Window w, window_parts part)
+ {
+ *free_bg_pixmap = False;
+
+@@ -1510,9 +1878,38 @@
+ else
+ {
+ bg->flags.use_pixmap = 0;
+- bg->pixel = cd->attributes.background_pixel;
+- }
+
++ switch ( part )
++ {
++ case PART_BORDER_N:
++ bg->pixel = cd->attributes_north.background_pixel;
++ break;
++ case PART_BORDER_S:
++ bg->pixel = cd->attributes_south.background_pixel;
++ break;
++ case PART_BORDER_E:
++ bg->pixel = cd->attributes_east.background_pixel;
++ break;
++ case PART_BORDER_W:
++ bg->pixel = cd->attributes_west.background_pixel;
++ break;
++ case PART_BORDER_NW:
++ bg->pixel = cd->attributes_nw.background_pixel;
++ break;
++ case PART_BORDER_NE:
++ bg->pixel = cd->attributes_ne.background_pixel;
++ break;
++ case PART_BORDER_SW:
++ bg->pixel = cd->attributes_sw.background_pixel;
++ break;
++ case PART_BORDER_SE:
++ bg->pixel = cd->attributes_se.background_pixel;
++ break;
++ default:
++ bg->pixel = cd->attributes.background_pixel;
++ break;
++ }
++ }
+ return;
+ }
+
+@@ -1542,7 +1939,7 @@
+ relative_g.x = part_g.x;
+ relative_g.y = part_g.y;
+ border_get_border_background(
+- &bg, cd, &part_g, &relative_g, &free_bg_pixmap, w);
++ &bg, cd, &part_g, &relative_g, &free_bg_pixmap, w, part);
+ if (cd->texture_pixmap)
+ {
+ switch (part)
+@@ -1629,7 +2026,7 @@
+ border_get_border_relief_size_descr(&br->relief, fw, do_hilight);
+ border_get_border_marks_descr(cd, br, fw);
+ /* fetch the gcs used to draw the border */
+- border_get_border_gcs(&br->gcs, cd, fw, do_hilight);
++ //border_get_border_gcs(&br->gcs, cd, fw, do_hilight);
+ /* draw everything in a big loop */
+ draw_parts &= (PART_FRAME | PART_HANDLES);
+ draw_handles = (draw_parts & PART_HANDLES);
+@@ -1638,11 +2035,12 @@
+ {
+ if (part & draw_parts)
+ {
+- border_draw_one_border_part(
+- cd, fw, &br->sidebar_g, frame_g, br, part,
+- draw_handles,
+- (pressed_parts & part) ? True : False,
+- do_clear);
++ border_get_border_gcs(&br->gcs, cd, fw, do_hilight, part);
++ border_draw_one_border_part(
++ cd, fw, &br->sidebar_g, frame_g, br, part,
++ draw_handles,
++ (pressed_parts & part) ? True : False,
++ do_clear);
+ }
+ }
+
+@@ -3270,7 +3668,7 @@
+ relative_g.x = button_g->x;
+ relative_g.y = button_g->y;
+ border_get_border_background(
+- &bg, td->cd, button_g, &relative_g, &free_bg_pixmap, w);
++ &bg, td->cd, button_g, &relative_g, &free_bg_pixmap, w, PART_NONE);
+ bg.pixmap.g.x = 0;
+ bg.pixmap.g.y = 0;
+ /* set the geometry for drawing the Tiled pixmap;
+@@ -3714,7 +4112,7 @@
+ relative_g.y = td->layout.title_g.y;
+ border_get_border_background(
+ &bg, td->cd, &td->layout.title_g, &relative_g,
+- &free_bg_pixmap, w);
++ &free_bg_pixmap, w, PART_NONE);
+ bg.pixmap.g.x = 0;
+ bg.pixmap.g.y = 0;
+ /* set the geometry for drawing the Tiled pixmap;
+Only in fvwm-patched/fvwm: borders.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/fvwm.c fvwm-patched/fvwm/fvwm.c
+--- fvwm-2.6.9/fvwm/fvwm.c 2018-05-26 05:35:26.000000000 -0600
++++ fvwm-patched/fvwm/fvwm.c 2020-08-21 15:29:14.150834565 -0600
+@@ -1076,7 +1076,22 @@
+ Scr.ScratchGC2 = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv);
+ Scr.ScratchGC3 = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv);
+ Scr.ScratchGC4 = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv);
+- Scr.TitleGC = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv);
++ Scr.ScratchGC5 = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv);
++ Scr.ScratchGC6 = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv);
++ Scr.ScratchGC7 = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv);
++ Scr.ScratchGC8 = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv);
++ Scr.ScratchGC9 = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv);
++ Scr.ScratchGC10 = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv);
++ Scr.ScratchGC11 = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv);
++ Scr.ScratchGC12 = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv);
++ Scr.ScratchGC13 = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv);
++ Scr.ScratchGC14 = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv);
++ Scr.ScratchGC15 = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv);
++ Scr.ScratchGC16 = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv);
++ Scr.ScratchGC17 = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv);
++ Scr.ScratchGC18 = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv);
++
++ Scr.TitleGC = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv);
+ Scr.BordersGC = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv);
+ Scr.TransMaskGC = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, &gcv);
+ Scr.ScratchMonoPixmap = XCreatePixmap(dpy, Scr.Root, 1, 1, 1);
+Only in fvwm-patched/fvwm: fvwm.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/fvwm.h fvwm-patched/fvwm/fvwm.h
+--- fvwm-2.6.9/fvwm/fvwm.h 2019-08-24 16:50:07.000000000 -0600
++++ fvwm-patched/fvwm/fvwm.h 2020-08-21 15:29:14.154834594 -0600
+@@ -579,7 +579,23 @@
+ unsigned use_colorset : 1;
+ unsigned use_colorset_hi : 1;
+ unsigned use_border_colorset : 1;
++ unsigned use_border_colorset_north : 1;
++ unsigned use_border_colorset_south : 1;
++ unsigned use_border_colorset_east : 1;
++ unsigned use_border_colorset_west : 1;
++ unsigned use_border_colorset_handles_nw : 1;
++ unsigned use_border_colorset_handles_ne : 1;
++ unsigned use_border_colorset_handles_sw : 1;
++ unsigned use_border_colorset_handles_se : 1;
+ unsigned use_border_colorset_hi : 1;
++ unsigned use_border_colorset_hi_north : 1;
++ unsigned use_border_colorset_hi_south : 1;
++ unsigned use_border_colorset_hi_east : 1;
++ unsigned use_border_colorset_hi_west : 1;
++ unsigned use_border_colorset_hi_handles_nw : 1;
++ unsigned use_border_colorset_hi_handles_ne : 1;
++ unsigned use_border_colorset_hi_handles_sw : 1;
++ unsigned use_border_colorset_hi_handles_se : 1;
+ unsigned use_icon_title_colorset : 1;
+ unsigned use_icon_title_colorset_hi : 1;
+ unsigned use_icon_background_colorset : 1;
+@@ -668,7 +684,23 @@
+ int colorset;
+ int colorset_hi;
+ int border_colorset;
++ int border_colorset_north;
++ int border_colorset_south;
++ int border_colorset_east;
++ int border_colorset_west;
++ int border_colorset_handles_nw;
++ int border_colorset_handles_ne;
++ int border_colorset_handles_sw;
++ int border_colorset_handles_se;
+ int border_colorset_hi;
++ int border_colorset_hi_north;
++ int border_colorset_hi_south;
++ int border_colorset_hi_east;
++ int border_colorset_hi_west;
++ int border_colorset_hi_handles_nw;
++ int border_colorset_hi_handles_ne;
++ int border_colorset_hi_handles_sw;
++ int border_colorset_hi_handles_se;
+ int icon_title_colorset;
+ int icon_title_colorset_hi;
+ int icon_background_colorset;
+@@ -881,12 +913,51 @@
+ color_quad colors;
+ color_quad hicolors;
+ color_quad border_colors;
++ color_quad border_colors_north;
++ color_quad border_colors_south;
++ color_quad border_colors_east;
++ color_quad border_colors_west;
++
++ color_quad border_colors_handles_nw;
++ color_quad border_colors_handles_ne;
++ color_quad border_colors_handles_sw;
++ color_quad border_colors_handles_se;
++
+ color_quad border_hicolors;
++ color_quad border_hicolors_north;
++ color_quad border_hicolors_south;
++ color_quad border_hicolors_east;
++ color_quad border_hicolors_west;
++
++ color_quad border_hicolors_handles_nw;
++ color_quad border_hicolors_handles_ne;
++ color_quad border_hicolors_handles_sw;
++ color_quad border_hicolors_handles_se;
+
+ int cs;
+ int cs_hi;
+ int border_cs;
++ int border_cs_north;
++ int border_cs_south;
++ int border_cs_east;
++ int border_cs_west;
++
++ int border_cs_handles_nw;
++ int border_cs_handles_ne;
++ int border_cs_handles_sw;
++ int border_cs_handles_se;
++
+ int border_cs_hi;
++ int border_cs_hi_north;
++ int border_cs_hi_south;
++ int border_cs_hi_east;
++ int border_cs_hi_west;
++
++ int border_cs_hi_handles_nw;
++ int border_cs_hi_handles_ne;
++ int border_cs_hi_handles_sw;
++ int border_cs_hi_handles_se;
++
+ int icon_title_cs;
+ int icon_title_cs_hi;
+ int icon_background_cs;
+Only in fvwm-patched/fvwm: fvwm.h.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/screen.h fvwm-patched/fvwm/screen.h
+--- fvwm-2.6.9/fvwm/screen.h 2018-05-26 05:35:26.000000000 -0600
++++ fvwm-patched/fvwm/screen.h 2020-08-21 15:29:14.154834594 -0600
+@@ -405,6 +405,21 @@
+ GC ScratchGC2;
+ GC ScratchGC3;
+ GC ScratchGC4;
++ GC ScratchGC5;
++ GC ScratchGC6;
++ GC ScratchGC7;
++ GC ScratchGC8;
++ GC ScratchGC9;
++ GC ScratchGC10;
++ GC ScratchGC11;
++ GC ScratchGC12;
++ GC ScratchGC13;
++ GC ScratchGC14;
++ GC ScratchGC15;
++ GC ScratchGC16;
++ GC ScratchGC17;
++ GC ScratchGC18;
++
+ GC TitleGC;
+ GC BordersGC;
+ /* minimum width of size window */
+Only in fvwm-patched/fvwm: screen.h.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/style.c fvwm-patched/fvwm/style.c
+--- fvwm-2.6.9/fvwm/style.c 2018-05-26 05:35:26.000000000 -0600
++++ fvwm-patched/fvwm/style.c 2020-08-21 15:29:14.154834594 -0600
+@@ -663,11 +663,91 @@
+ SSET_BORDER_COLORSET(
+ *merged_style, SGET_BORDER_COLORSET(*add_style));
+ }
++ if (add_style->flags.use_border_colorset_north)
++ {
++ SSET_BORDER_COLORSET_NORTH(
++ *merged_style,SGET_BORDER_COLORSET_NORTH(*add_style));
++ }
++ if (add_style->flags.use_border_colorset_south)
++ {
++ SSET_BORDER_COLORSET_SOUTH(
++ *merged_style,SGET_BORDER_COLORSET_SOUTH(*add_style));
++ }
++ if (add_style->flags.use_border_colorset_east)
++ {
++ SSET_BORDER_COLORSET_EAST(
++ *merged_style,SGET_BORDER_COLORSET_EAST(*add_style));
++ }
++ if (add_style->flags.use_border_colorset_west)
++ {
++ SSET_BORDER_COLORSET_WEST(
++ *merged_style,SGET_BORDER_COLORSET_WEST(*add_style));
++ }
++ if (add_style->flags.use_border_colorset_handles_nw)
++ {
++ SSET_BORDER_COLORSET_HANDLES_NW(
++ *merged_style,SGET_BORDER_COLORSET_HANDLES_NW(*add_style));
++ }
++ if (add_style->flags.use_border_colorset_handles_ne)
++ {
++ SSET_BORDER_COLORSET_HANDLES_NE(
++ *merged_style,SGET_BORDER_COLORSET_HANDLES_NE(*add_style));
++ }
++ if (add_style->flags.use_border_colorset_handles_sw)
++ {
++ SSET_BORDER_COLORSET_HANDLES_SW(
++ *merged_style,SGET_BORDER_COLORSET_HANDLES_SW(*add_style));
++ }
++ if (add_style->flags.use_border_colorset_handles_se)
++ {
++ SSET_BORDER_COLORSET_HANDLES_SE(
++ *merged_style,SGET_BORDER_COLORSET_HANDLES_SE(*add_style));
++ }
+ if (add_style->flags.use_border_colorset_hi)
+ {
+ SSET_BORDER_COLORSET_HI(
+ *merged_style,SGET_BORDER_COLORSET_HI(*add_style));
+ }
++ if (add_style->flags.use_border_colorset_hi_north)
++ {
++ SSET_BORDER_COLORSET_HI_NORTH(
++ *merged_style,SGET_BORDER_COLORSET_HI_NORTH(*add_style));
++ }
++ if (add_style->flags.use_border_colorset_hi_south)
++ {
++ SSET_BORDER_COLORSET_HI_SOUTH(
++ *merged_style,SGET_BORDER_COLORSET_HI_SOUTH(*add_style));
++ }
++ if (add_style->flags.use_border_colorset_hi_east)
++ {
++ SSET_BORDER_COLORSET_HI_EAST(
++ *merged_style,SGET_BORDER_COLORSET_HI_EAST(*add_style));
++ }
++ if (add_style->flags.use_border_colorset_hi_west)
++ {
++ SSET_BORDER_COLORSET_HI_WEST(
++ *merged_style,SGET_BORDER_COLORSET_HI_WEST(*add_style));
++ }
++ if (add_style->flags.use_border_colorset_hi_handles_nw)
++ {
++ SSET_BORDER_COLORSET_HI_HANDLES_NW(
++ *merged_style,SGET_BORDER_COLORSET_HI_HANDLES_NW(*add_style));
++ }
++ if (add_style->flags.use_border_colorset_hi_handles_ne)
++ {
++ SSET_BORDER_COLORSET_HI_HANDLES_NE(
++ *merged_style,SGET_BORDER_COLORSET_HI_HANDLES_NE(*add_style));
++ }
++ if (add_style->flags.use_border_colorset_hi_handles_sw)
++ {
++ SSET_BORDER_COLORSET_HI_HANDLES_SW(
++ *merged_style,SGET_BORDER_COLORSET_HI_HANDLES_SW(*add_style));
++ }
++ if (add_style->flags.use_border_colorset_hi_handles_se)
++ {
++ SSET_BORDER_COLORSET_HI_HANDLES_SE(
++ *merged_style,SGET_BORDER_COLORSET_HI_HANDLES_SE(*add_style));
++ }
+ if (add_style->flags.use_icon_title_colorset)
+ {
+ SSET_ICON_TITLE_COLORSET(
+@@ -2211,6 +2291,120 @@
+ ps->flag_mask.use_border_colorset = 1;
+ ps->change_mask.use_border_colorset = 1;
+ }
++ else if (StrEquals(token, "BorderColorsetRegions"))
++ {
++ int f[4] = {-1, -1, -1, -1};
++ Bool bad = False;
++
++ num = 0;
++ if (on != 0)
++ {
++ num = GetIntegerArguments(rest, &rest, val, 4);
++
++ for (i=0; i < num; i++)
++ {
++ if (val[i] < 0)
++ {
++ bad = True;
++ } else {
++ f[i] = val[i];
++ }
++ }
++ }
++ if (bad)
++ {
++ fvwm_msg(
++ ERR, "style_parse_one_style_option",
++ "Bad argument to BorderColorsetRegions"
++ ": %s", rest);
++ break;
++ }
++
++ /* If 'f' defines our array of colorsets then dispatch
++ * them here.
++ */
++
++ SSET_BORDER_COLORSET_NORTH(*ps, f[0]);
++ alloc_colorset(f[0]);
++ ps->flags.use_border_colorset_north = (f[0] >= 0);
++ ps->flag_mask.use_border_colorset_north = 1;
++ ps->change_mask.use_border_colorset_north = 1;
++
++
++ SSET_BORDER_COLORSET_SOUTH(*ps, f[1]);
++ alloc_colorset(f[1]);
++ ps->flags.use_border_colorset_south = (f[1] >= 0);
++ ps->flag_mask.use_border_colorset_south = 1;
++ ps->change_mask.use_border_colorset_south = 1;
++
++ SSET_BORDER_COLORSET_EAST(*ps, f[2]);
++ alloc_colorset(f[2]);
++ ps->flags.use_border_colorset_east = (f[2] >= 0);
++ ps->flag_mask.use_border_colorset_east = 1;
++ ps->change_mask.use_border_colorset_east = 1;
++
++ SSET_BORDER_COLORSET_WEST(*ps, f[3]);
++ alloc_colorset(f[3]);
++ ps->flags.use_border_colorset_west = (f[3] >= 0);
++ ps->flag_mask.use_border_colorset_west = 1;
++ ps->change_mask.use_border_colorset_west = 1;
++ }
++ else if (StrEquals(token, "BorderHandlesColorsetRegions"))
++ {
++ int f[4] = {-1, -1, -1, -1};
++ Bool bad = False;
++
++ num = 0;
++ if (on != 0)
++ {
++ num = GetIntegerArguments(rest, &rest, val, 4);
++
++ for (i=0; i < num; i++)
++ {
++ if (val[i] < 0)
++ bad = True;
++ f[i] = val[i];
++ }
++ }
++ if (bad)
++ {
++ fvwm_msg(
++ ERR, "style_parse_one_style_option",
++ "Bad argument to HandlesColorsetRegions"
++ ": %s", rest);
++ break;
++ }
++
++ /* If 'f' defines our array of colorsets then dispatch
++ * them here.
++ */
++
++ SSET_BORDER_COLORSET_HANDLES_NW(*ps, f[0]);
++ alloc_colorset(f[0]);
++ ps->flags.use_border_colorset_handles_nw = (f[0] >= 0);
++ ps->flag_mask.use_border_colorset_handles_nw = 1;
++ ps->change_mask.use_border_colorset_handles_nw = 1;
++
++ SSET_BORDER_COLORSET_HANDLES_NE(*ps, f[1]);
++ alloc_colorset(f[1]);
++ ps->flags.use_border_colorset_handles_ne = (f[1] >= 0);
++ ps->flag_mask.use_border_colorset_handles_ne = 1;
++ ps->change_mask.use_border_colorset_handles_ne = 1;
++
++ SSET_BORDER_COLORSET_HANDLES_SW(*ps, f[2]);
++ alloc_colorset(f[2]);
++ ps->flags.use_border_colorset_handles_sw = (f[2] >= 0);
++ ps->flag_mask.use_border_colorset_handles_sw = 1;
++ ps->change_mask.use_border_colorset_handles_sw = 1;
++
++ SSET_BORDER_COLORSET_HANDLES_SE(*ps, f[3]);
++ alloc_colorset(f[3]);
++ ps->flags.use_border_colorset_handles_se = (f[3] >= 0);
++ ps->flag_mask.use_border_colorset_handles_se = 1;
++ ps->change_mask.use_border_colorset_handles_se = 1;
++
++ }
++
+ else if (StrEquals(token, "BottomTitleRotated"))
+ {
+ S_SET_IS_BOTTOM_TITLE_ROTATED(SCF(*ps), on);
+@@ -2849,7 +3043,117 @@
+ ps->flag_mask.use_border_colorset_hi = 1;
+ ps->change_mask.use_border_colorset_hi = 1;
+ }
+- else if (StrEquals(token, "HilightIconTitleColorset"))
++ else if (StrEquals(token, "HilightBorderColorsetRegions"))
++ {
++ int f[4] = {-1, -1, -1, -1};
++ Bool bad = False;
++
++ num = 0;
++ if (on != 0)
++ {
++ num = GetIntegerArguments(rest, &rest, val, 4);
++
++ for (i=0; i < num; i++)
++ {
++ if (val[i] < 0)
++ bad = True;
++ f[i] = val[i];
++ }
++ }
++ if (bad)
++ {
++ fvwm_msg(
++ ERR, "style_parse_one_style_option",
++ "Bad argument to HilightBorderColorsetRegions"
++ ": %s", rest);
++ break;
++ }
++
++ /* If 'f' defines our array of colorsets then dispatch
++ * them here.
++ */
++
++ SSET_BORDER_COLORSET_HI_NORTH(*ps, f[0]);
++ alloc_colorset(f[0]);
++ ps->flags.use_border_colorset_hi_north = (f[0] >= 0);
++ ps->flag_mask.use_border_colorset_hi_north = 1;
++ ps->change_mask.use_border_colorset_hi_north = 1;
++
++ SSET_BORDER_COLORSET_HI_SOUTH(*ps, f[1]);
++ alloc_colorset(f[1]);
++ ps->flags.use_border_colorset_hi_south = (f[1] >= 0);
++ ps->flag_mask.use_border_colorset_hi_south = 1;
++ ps->change_mask.use_border_colorset_hi_south = 1;
++
++ SSET_BORDER_COLORSET_HI_EAST(*ps, f[2]);
++ alloc_colorset(f[2]);
++ ps->flags.use_border_colorset_hi_east = (f[2] >= 0);
++ ps->flag_mask.use_border_colorset_hi_east = 1;
++ ps->change_mask.use_border_colorset_hi_east = 1;
++
++ SSET_BORDER_COLORSET_HI_WEST(*ps, f[3]);
++ alloc_colorset(f[3]);
++ ps->flags.use_border_colorset_hi_west = (f[3] >= 0);
++ ps->flag_mask.use_border_colorset_hi_west = 1;
++ ps->change_mask.use_border_colorset_hi_west = 1;
++
++ }
++ else if (StrEquals(token, "HilightHandlesColorsetRegions"))
++ {
++ int f[4] = {-1, -1, -1, -1};
++ Bool bad = False;
++
++ num = 0;
++ if (on != 0)
++ {
++ num = GetIntegerArguments(rest, &rest, val, 4);
++
++ for (i=0; i < num; i++)
++ {
++ if (val[i] < 0)
++ bad = True;
++ f[i] = val[i];
++ }
++ }
++ if (bad)
++ {
++ fvwm_msg(
++ ERR, "style_parse_one_style_option",
++ "Bad argument to HilightHandlesColorsetRegions"
++ ": %s", rest);
++ break;
++ }
++
++ /* If 'f' defines our array of colorsets then dispatch
++ * them here.
++ */
++
++ SSET_BORDER_COLORSET_HI_HANDLES_NW(*ps, f[0]);
++ alloc_colorset(f[0]);
++ ps->flags.use_border_colorset_hi_handles_nw = (f[0] >= 0);
++ ps->flag_mask.use_border_colorset_hi_handles_nw = 1;
++ ps->change_mask.use_border_colorset_hi_handles_nw = 1;
++
++ SSET_BORDER_COLORSET_HI_HANDLES_NE(*ps, f[1]);
++ alloc_colorset(f[1]);
++ ps->flags.use_border_colorset_hi_handles_ne = (f[1] >= 0);
++ ps->flag_mask.use_border_colorset_hi_handles_ne = 1;
++ ps->change_mask.use_border_colorset_hi_handles_ne = 1;
++
++ SSET_BORDER_COLORSET_HI_HANDLES_SW(*ps, f[2]);
++ alloc_colorset(f[2]);
++ ps->flags.use_border_colorset_hi_handles_sw = (f[2] >= 0);
++ ps->flag_mask.use_border_colorset_hi_handles_sw = 1;
++ ps->change_mask.use_border_colorset_hi_handles_sw = 1;
++
++ SSET_BORDER_COLORSET_HI_HANDLES_SE(*ps, f[3]);
++ alloc_colorset(f[3]);
++ ps->flags.use_border_colorset_hi_handles_se = (f[3] >= 0);
++ ps->flag_mask.use_border_colorset_hi_handles_se = 1;
++ ps->change_mask.use_border_colorset_hi_handles_se = 1;
++
++ }
++ else if (StrEquals(token, "HilightIconTitleColorset"))
+ {
+ *val = -1;
+ GetIntegerArguments(rest, &rest, val, 1);
+@@ -5245,6 +5549,62 @@
+ temp->change_mask.use_border_colorset = 1;
+ Scr.flags.do_need_window_update = 1;
+ }
++ if (SUSE_BORDER_COLORSET_NORTH(&temp->flags) &&
++ SGET_BORDER_COLORSET_NORTH(*temp) == colorset)
++ {
++ temp->has_style_changed = 1;
++ temp->change_mask.use_border_colorset_north = 1;
++ Scr.flags.do_need_window_update = 1;
++ }
++ if (SUSE_BORDER_COLORSET_SOUTH(&temp->flags) &&
++ SGET_BORDER_COLORSET_SOUTH(*temp) == colorset)
++ {
++ temp->has_style_changed = 1;
++ temp->change_mask.use_border_colorset_south = 1;
++ Scr.flags.do_need_window_update = 1;
++ }
++ if (SUSE_BORDER_COLORSET_EAST(&temp->flags) &&
++ SGET_BORDER_COLORSET_EAST(*temp) == colorset)
++ {
++ temp->has_style_changed = 1;
++ temp->change_mask.use_border_colorset_east = 1;
++ Scr.flags.do_need_window_update = 1;
++ }
++ if (SUSE_BORDER_COLORSET_WEST(&temp->flags) &&
++ SGET_BORDER_COLORSET_WEST(*temp) == colorset)
++ {
++ temp->has_style_changed = 1;
++ temp->change_mask.use_border_colorset_west = 1;
++ Scr.flags.do_need_window_update = 1;
++ }
++ if (SUSE_BORDER_COLORSET_HANDLES_NW(&temp->flags) &&
++ SGET_BORDER_COLORSET_HANDLES_NW(*temp) == colorset)
++ {
++ temp->has_style_changed = 1;
++ temp->change_mask.use_border_colorset_handles_nw = 1;
++ Scr.flags.do_need_window_update = 1;
++ }
++ if (SUSE_BORDER_COLORSET_HANDLES_NE(&temp->flags) &&
++ SGET_BORDER_COLORSET_HANDLES_NE(*temp) == colorset)
++ {
++ temp->has_style_changed = 1;
++ temp->change_mask.use_border_colorset_handles_ne = 1;
++ Scr.flags.do_need_window_update = 1;
++ }
++ if (SUSE_BORDER_COLORSET_HANDLES_SW(&temp->flags) &&
++ SGET_BORDER_COLORSET_HANDLES_SW(*temp) == colorset)
++ {
++ temp->has_style_changed = 1;
++ temp->change_mask.use_border_colorset_handles_sw = 1;
++ Scr.flags.do_need_window_update = 1;
++ }
++ if (SUSE_BORDER_COLORSET_HANDLES_SE(&temp->flags) &&
++ SGET_BORDER_COLORSET_HANDLES_SE(*temp) == colorset)
++ {
++ temp->has_style_changed = 1;
++ temp->change_mask.use_border_colorset_handles_se = 1;
++ Scr.flags.do_need_window_update = 1;
++ }
+ if (SUSE_BORDER_COLORSET_HI(&temp->flags) &&
+ SGET_BORDER_COLORSET_HI(*temp) == colorset)
+ {
+@@ -5252,6 +5612,62 @@
+ temp->change_mask.use_border_colorset_hi = 1;
+ Scr.flags.do_need_window_update = 1;
+ }
++ if (SUSE_BORDER_COLORSET_HI_NORTH(&temp->flags) &&
++ SGET_BORDER_COLORSET_HI_NORTH(*temp) == colorset)
++ {
++ temp->has_style_changed = 1;
++ temp->change_mask.use_border_colorset_hi_north = 1;
++ Scr.flags.do_need_window_update = 1;
++ }
++ if (SUSE_BORDER_COLORSET_HI_SOUTH(&temp->flags) &&
++ SGET_BORDER_COLORSET_HI_SOUTH(*temp) == colorset)
++ {
++ temp->has_style_changed = 1;
++ temp->change_mask.use_border_colorset_hi_south = 1;
++ Scr.flags.do_need_window_update = 1;
++ }
++ if (SUSE_BORDER_COLORSET_HI_EAST(&temp->flags) &&
++ SGET_BORDER_COLORSET_HI_EAST(*temp) == colorset)
++ {
++ temp->has_style_changed = 1;
++ temp->change_mask.use_border_colorset_hi_east = 1;
++ Scr.flags.do_need_window_update = 1;
++ }
++ if (SUSE_BORDER_COLORSET_HI_WEST(&temp->flags) &&
++ SGET_BORDER_COLORSET_HI_WEST(*temp) == colorset)
++ {
++ temp->has_style_changed = 1;
++ temp->change_mask.use_border_colorset_hi_west = 1;
++ Scr.flags.do_need_window_update = 1;
++ }
++ if (SUSE_BORDER_COLORSET_HI_HANDLES_NW(&temp->flags) &&
++ SGET_BORDER_COLORSET_HI_HANDLES_NW(*temp) == colorset)
++ {
++ temp->has_style_changed = 1;
++ temp->change_mask.use_border_colorset_hi_handles_nw = 1;
++ Scr.flags.do_need_window_update = 1;
++ }
++ if (SUSE_BORDER_COLORSET_HI_HANDLES_NE(&temp->flags) &&
++ SGET_BORDER_COLORSET_HI_HANDLES_NE(*temp) == colorset)
++ {
++ temp->has_style_changed = 1;
++ temp->change_mask.use_border_colorset_hi_handles_ne = 1;
++ Scr.flags.do_need_window_update = 1;
++ }
++ if (SUSE_BORDER_COLORSET_HI_HANDLES_SW(&temp->flags) &&
++ SGET_BORDER_COLORSET_HI_HANDLES_SW(*temp) == colorset)
++ {
++ temp->has_style_changed = 1;
++ temp->change_mask.use_border_colorset_hi_handles_sw = 1;
++ Scr.flags.do_need_window_update = 1;
++ }
++ if (SUSE_BORDER_COLORSET_HI_HANDLES_SE(&temp->flags) &&
++ SGET_BORDER_COLORSET_HI_HANDLES_SE(*temp) == colorset)
++ {
++ temp->has_style_changed = 1;
++ temp->change_mask.use_border_colorset_hi_handles_se = 1;
++ Scr.flags.do_need_window_update = 1;
++ }
+ if (SUSE_ICON_TITLE_COLORSET(&temp->flags) &&
+ SGET_ICON_TITLE_COLORSET(*temp) == colorset)
+ {
+@@ -5329,7 +5745,129 @@
+ fw->border_colors.shadow = fw->colors.shadow;
+ fw->border_colors.back = fw->colors.back;
+ }
+-}
++ if (SUSE_BORDER_COLORSET_NORTH(&pstyle->flags))
++ {
++ cs = SGET_BORDER_COLORSET_NORTH(*pstyle);
++ fw->border_cs_north = cs;
++ fw->border_colors_north.hilight = Colorset[cs].hilite;
++ fw->border_colors_north.shadow = Colorset[cs].shadow;
++ fw->border_colors_north.back = Colorset[cs].bg;
++ }
++ else
++ {
++ fw->border_cs_north = -1;
++ fw->border_colors_north.hilight = fw->colors.hilight;
++ fw->border_colors_north.shadow = fw->colors.shadow;
++ fw->border_colors_north.back = fw->colors.back;
++ }
++ if (SUSE_BORDER_COLORSET_SOUTH(&pstyle->flags))
++ {
++ cs = SGET_BORDER_COLORSET_SOUTH(*pstyle);
++ fw->border_cs_south = cs;
++ fw->border_colors_south.hilight = Colorset[cs].hilite;
++ fw->border_colors_south.shadow = Colorset[cs].shadow;
++ fw->border_colors_south.back = Colorset[cs].bg;
++ }
++ else
++ {
++ fw->border_cs_south = -1;
++ fw->border_colors_south.hilight = fw->colors.hilight;
++ fw->border_colors_south.shadow = fw->colors.shadow;
++ fw->border_colors_south.back = fw->colors.back;
++ }
++ if (SUSE_BORDER_COLORSET_EAST(&pstyle->flags))
++ {
++ cs = SGET_BORDER_COLORSET_EAST(*pstyle);
++ fw->border_cs_east = cs;
++ fw->border_colors_east.hilight = Colorset[cs].hilite;
++ fw->border_colors_east.shadow = Colorset[cs].shadow;
++ fw->border_colors_east.back = Colorset[cs].bg;
++ }
++ else
++ {
++ fw->border_cs_east = -1;
++ fw->border_colors_east.hilight = fw->colors.hilight;
++ fw->border_colors_east.shadow = fw->colors.shadow;
++ fw->border_colors_east.back = fw->colors.back;
++ }
++ if (SUSE_BORDER_COLORSET_WEST(&pstyle->flags))
++ {
++ cs = SGET_BORDER_COLORSET_WEST(*pstyle);
++ fw->border_cs_west = cs;
++ fw->border_colors_west.hilight = Colorset[cs].hilite;
++ fw->border_colors_west.shadow = Colorset[cs].shadow;
++ fw->border_colors_west.back = Colorset[cs].bg;
++ }
++ else
++ {
++ fw->border_cs_west = -1;
++ fw->border_colors_west.hilight = fw->colors.hilight;
++ fw->border_colors_west.shadow = fw->colors.shadow;
++ fw->border_colors_west.back = fw->colors.back;
++ }
++ /* handles */
++ if (SUSE_BORDER_COLORSET_HANDLES_NW(&pstyle->flags))
++ {
++ cs = SGET_BORDER_COLORSET_HANDLES_NW(*pstyle);
++ fw->border_cs_handles_nw = cs;
++ fw->border_colors_handles_nw.hilight = Colorset[cs].hilite;
++ fw->border_colors_handles_nw.shadow = Colorset[cs].shadow;
++ fw->border_colors_handles_nw.back = Colorset[cs].bg;
++ }
++ else
++ {
++ fw->border_cs_handles_nw = -1;
++ fw->border_colors_handles_nw.hilight = fw->colors.hilight;
++ fw->border_colors_handles_nw.shadow = fw->colors.shadow;
++ fw->border_colors_handles_nw.back = fw->colors.back;
++ }
++ if (SUSE_BORDER_COLORSET_HANDLES_NE(&pstyle->flags))
++ {
++ cs = SGET_BORDER_COLORSET_HANDLES_NE(*pstyle);
++ fw->border_cs_handles_ne = cs;
++ fw->border_colors_handles_ne.hilight = Colorset[cs].hilite;
++ fw->border_colors_handles_ne.shadow = Colorset[cs].shadow;
++ fw->border_colors_handles_ne.back = Colorset[cs].bg;
++ }
++ else
++ {
++ fw->border_cs_handles_ne = -1;
++ fw->border_colors_handles_ne.hilight = fw->colors.hilight;
++ fw->border_colors_handles_ne.shadow = fw->colors.shadow;
++ fw->border_colors_handles_ne.back = fw->colors.back;
++ }
++ if (SUSE_BORDER_COLORSET_HANDLES_SW(&pstyle->flags))
++ {
++ cs = SGET_BORDER_COLORSET_HANDLES_SW(*pstyle);
++ fw->border_cs_handles_sw = cs;
++ fw->border_colors_handles_sw.hilight = Colorset[cs].hilite;
++ fw->border_colors_handles_sw.shadow = Colorset[cs].shadow;
++ fw->border_colors_handles_sw.back = Colorset[cs].bg;
++ }
++ else
++ {
++ fw->border_cs_handles_sw = -1;
++ fw->border_colors_handles_sw.hilight = fw->colors.hilight;
++ fw->border_colors_handles_sw.shadow = fw->colors.shadow;
++ fw->border_colors_handles_sw.back = fw->colors.back;
++ }
++ if (SUSE_BORDER_COLORSET_HANDLES_SE(&pstyle->flags))
++ {
++ cs = SGET_BORDER_COLORSET_HANDLES_SE(*pstyle);
++ fw->border_cs_handles_se = cs;
++ fw->border_colors_handles_se.hilight = Colorset[cs].hilite;
++ fw->border_colors_handles_se.shadow = Colorset[cs].shadow;
++ fw->border_colors_handles_se.back = Colorset[cs].bg;
++ }
++ else
++ {
++ fw->border_cs_handles_se = -1;
++ fw->border_colors_handles_se.hilight = fw->colors.hilight;
++ fw->border_colors_handles_se.shadow = fw->colors.shadow;
++ fw->border_colors_handles_se.back = fw->colors.back;
++ }
++
++}
+
+ void update_window_color_hi_style(FvwmWindow *fw, window_style *pstyle)
+ {
+@@ -5383,6 +5921,127 @@
+ fw->border_hicolors.shadow = fw->hicolors.shadow;
+ fw->border_hicolors.back = fw->hicolors.back;
+ }
++ if (SUSE_BORDER_COLORSET_HI_NORTH(&pstyle->flags))
++ {
++ cs = SGET_BORDER_COLORSET_HI_NORTH(*pstyle);
++ fw->border_cs_hi_north = cs;
++ fw->border_hicolors_north.hilight = Colorset[cs].hilite;
++ fw->border_hicolors_north.shadow = Colorset[cs].shadow;
++ fw->border_hicolors_north.back = Colorset[cs].bg;
++ }
++ else
++ {
++ fw->border_cs_hi_north = -1;
++ fw->border_hicolors_north.hilight = fw->hicolors.hilight;
++ fw->border_hicolors_north.shadow = fw->hicolors.shadow;
++ fw->border_hicolors_north.back = fw->hicolors.back;
++ }
++ if (SUSE_BORDER_COLORSET_HI_SOUTH(&pstyle->flags))
++ {
++ cs = SGET_BORDER_COLORSET_HI_SOUTH(*pstyle);
++ fw->border_cs_hi_south = cs;
++ fw->border_hicolors_south.hilight = Colorset[cs].hilite;
++ fw->border_hicolors_south.shadow = Colorset[cs].shadow;
++ fw->border_hicolors_south.back = Colorset[cs].bg;
++ }
++ else
++ {
++ fw->border_cs_hi_south = -1;
++ fw->border_hicolors_south.hilight = fw->hicolors.hilight;
++ fw->border_hicolors_south.shadow = fw->hicolors.shadow;
++ fw->border_hicolors_south.back = fw->hicolors.back;
++ }
++ if (SUSE_BORDER_COLORSET_HI_EAST(&pstyle->flags))
++ {
++ cs = SGET_BORDER_COLORSET_HI_EAST(*pstyle);
++ fw->border_cs_hi_east = cs;
++ fw->border_hicolors_east.hilight = Colorset[cs].hilite;
++ fw->border_hicolors_east.shadow = Colorset[cs].shadow;
++ fw->border_hicolors_east.back = Colorset[cs].bg;
++ }
++ else
++ {
++ fw->border_cs_hi_east = -1;
++ fw->border_hicolors_east.hilight = fw->hicolors.hilight;
++ fw->border_hicolors_east.shadow = fw->hicolors.shadow;
++ fw->border_hicolors_east.back = fw->hicolors.back;
++ }
++ if (SUSE_BORDER_COLORSET_HI_WEST(&pstyle->flags))
++ {
++ cs = SGET_BORDER_COLORSET_HI_WEST(*pstyle);
++ fw->border_cs_hi_west = cs;
++ fw->border_hicolors_west.hilight = Colorset[cs].hilite;
++ fw->border_hicolors_west.shadow = Colorset[cs].shadow;
++ fw->border_hicolors_west.back = Colorset[cs].bg;
++ }
++ else
++ {
++ fw->border_cs_hi_west = -1;
++ fw->border_hicolors_west.hilight = fw->hicolors.hilight;
++ fw->border_hicolors_west.shadow = fw->hicolors.shadow;
++ fw->border_hicolors_west.back = fw->hicolors.back;
++ }
++ /* Handles */
++ if (SUSE_BORDER_COLORSET_HI_HANDLES_NW(&pstyle->flags))
++ {
++ cs = SGET_BORDER_COLORSET_HI_HANDLES_NW(*pstyle);
++ fw->border_cs_hi_handles_nw = cs;
++ fw->border_hicolors_handles_nw.hilight = Colorset[cs].hilite;
++ fw->border_hicolors_handles_nw.shadow = Colorset[cs].shadow;
++ fw->border_hicolors_handles_nw.back = Colorset[cs].bg;
++ }
++ else
++ {
++ fw->border_cs_hi_handles_nw = -1;
++ fw->border_hicolors_handles_nw.hilight = fw->hicolors.hilight;
++ fw->border_hicolors_handles_nw.shadow = fw->hicolors.shadow;
++ fw->border_hicolors_handles_nw.back = fw->hicolors.back;
++ }
++ if (SUSE_BORDER_COLORSET_HI_HANDLES_NE(&pstyle->flags))
++ {
++ cs = SGET_BORDER_COLORSET_HI_HANDLES_NE(*pstyle);
++ fw->border_cs_hi_handles_ne = cs;
++ fw->border_hicolors_handles_ne.hilight = Colorset[cs].hilite;
++ fw->border_hicolors_handles_ne.shadow = Colorset[cs].shadow;
++ fw->border_hicolors_handles_ne.back = Colorset[cs].bg;
++ }
++ else
++ {
++ fw->border_cs_hi_handles_ne = -1;
++ fw->border_hicolors_handles_ne.hilight = fw->hicolors.hilight;
++ fw->border_hicolors_handles_ne.shadow = fw->hicolors.shadow;
++ fw->border_hicolors_handles_ne.back = fw->hicolors.back;
++ }
++ if (SUSE_BORDER_COLORSET_HI_HANDLES_SW(&pstyle->flags))
++ {
++ cs = SGET_BORDER_COLORSET_HI_HANDLES_SW(*pstyle);
++ fw->border_cs_hi_handles_sw = cs;
++ fw->border_hicolors_handles_sw.hilight = Colorset[cs].hilite;
++ fw->border_hicolors_handles_sw.shadow = Colorset[cs].shadow;
++ fw->border_hicolors_handles_sw.back = Colorset[cs].bg;
++ }
++ else
++ {
++ fw->border_cs_hi_handles_sw = -1;
++ fw->border_hicolors_handles_sw.hilight = fw->hicolors.hilight;
++ fw->border_hicolors_handles_sw.shadow = fw->hicolors.shadow;
++ fw->border_hicolors_handles_sw.back = fw->hicolors.back;
++ }
++ if (SUSE_BORDER_COLORSET_HI_HANDLES_SE(&pstyle->flags))
++ {
++ cs = SGET_BORDER_COLORSET_HI_HANDLES_SE(*pstyle);
++ fw->border_cs_hi_handles_se = cs;
++ fw->border_hicolors_handles_se.hilight = Colorset[cs].hilite;
++ fw->border_hicolors_handles_se.shadow = Colorset[cs].shadow;
++ fw->border_hicolors_handles_se.back = Colorset[cs].bg;
++ }
++ else
++ {
++ fw->border_cs_hi_handles_se = -1;
++ fw->border_hicolors_handles_se.hilight = fw->hicolors.hilight;
++ fw->border_hicolors_handles_se.shadow = fw->hicolors.shadow;
++ fw->border_hicolors_handles_se.back = fw->hicolors.back;
++ }
+ }
+
+ void update_icon_title_cs_style(FvwmWindow *fw, window_style *pstyle)
+Only in fvwm-patched/fvwm: style.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/style.h fvwm-patched/fvwm/style.h
+--- fvwm-2.6.9/fvwm/style.h 2018-05-26 05:35:26.000000000 -0600
++++ fvwm-patched/fvwm/style.h 2020-08-21 15:29:14.154834594 -0600
+@@ -69,8 +69,40 @@
+ ((sf)->use_colorset_hi)
+ #define SUSE_BORDER_COLORSET(sf) \
+ ((sf)->use_border_colorset)
++#define SUSE_BORDER_COLORSET_NORTH(sf) \
++ ((sf)->use_border_colorset_north)
++#define SUSE_BORDER_COLORSET_SOUTH(sf) \
++ ((sf)->use_border_colorset_south)
++#define SUSE_BORDER_COLORSET_EAST(sf) \
++ ((sf)->use_border_colorset_east)
++#define SUSE_BORDER_COLORSET_WEST(sf) \
++ ((sf)->use_border_colorset_west)
++#define SUSE_BORDER_COLORSET_HANDLES_NW(sf) \
++ ((sf)->use_border_colorset_handles_nw)
++#define SUSE_BORDER_COLORSET_HANDLES_NE(sf) \
++ ((sf)->use_border_colorset_handles_ne)
++#define SUSE_BORDER_COLORSET_HANDLES_SW(sf) \
++ ((sf)->use_border_colorset_handles_sw)
++#define SUSE_BORDER_COLORSET_HANDLES_SE(sf) \
++ ((sf)->use_border_colorset_handles_se)
+ #define SUSE_BORDER_COLORSET_HI(sf) \
+ ((sf)->use_border_colorset_hi)
++#define SUSE_BORDER_COLORSET_HI_NORTH(sf) \
++ ((sf)->use_border_colorset_hi_north)
++#define SUSE_BORDER_COLORSET_HI_SOUTH(sf) \
++ ((sf)->use_border_colorset_hi_south)
++#define SUSE_BORDER_COLORSET_HI_EAST(sf) \
++ ((sf)->use_border_colorset_hi_east)
++#define SUSE_BORDER_COLORSET_HI_WEST(sf) \
++ ((sf)->use_border_colorset_hi_west)
++#define SUSE_BORDER_COLORSET_HI_HANDLES_NW(sf) \
++ ((sf)->use_border_colorset_hi_handles_nw)
++#define SUSE_BORDER_COLORSET_HI_HANDLES_NE(sf) \
++ ((sf)->use_border_colorset_hi_handles_ne)
++#define SUSE_BORDER_COLORSET_HI_HANDLES_SW(sf) \
++ ((sf)->use_border_colorset_hi_handles_sw)
++#define SUSE_BORDER_COLORSET_HI_HANDLES_SE(sf) \
++ ((sf)->use_border_colorset_hi_handles_se)
+ #define SUSE_ICON_TITLE_COLORSET(sf) \
+ ((sf)->use_icon_title_colorset)
+ #define SUSE_ICON_TITLE_COLORSET_HI(sf) \
+@@ -455,6 +487,38 @@
+ ((s).border_colorset = (x))
+ #define SGET_BORDER_COLORSET(s) \
+ ((s).border_colorset)
++#define SSET_BORDER_COLORSET_NORTH(s,x) \
++ ((s).border_colorset_north = (x))
++#define SGET_BORDER_COLORSET_NORTH(s) \
++ ((s).border_colorset_north)
++#define SSET_BORDER_COLORSET_SOUTH(s,x) \
++ ((s).border_colorset_south = (x))
++#define SGET_BORDER_COLORSET_SOUTH(s) \
++ ((s).border_colorset_south)
++#define SSET_BORDER_COLORSET_EAST(s,x) \
++ ((s).border_colorset_east = (x))
++#define SGET_BORDER_COLORSET_EAST(s) \
++ ((s).border_colorset_east)
++#define SSET_BORDER_COLORSET_WEST(s,x) \
++ ((s).border_colorset_west = (x))
++#define SGET_BORDER_COLORSET_WEST(s) \
++ ((s).border_colorset_west)
++#define SSET_BORDER_COLORSET_HANDLES_NW(s,x) \
++ ((s).border_colorset_handles_nw = (x))
++#define SGET_BORDER_COLORSET_HANDLES_NW(s) \
++ ((s).border_colorset_handles_nw)
++#define SSET_BORDER_COLORSET_HANDLES_NE(s,x) \
++ ((s).border_colorset_handles_ne = (x))
++#define SGET_BORDER_COLORSET_HANDLES_NE(s) \
++ ((s).border_colorset_handles_ne)
++#define SSET_BORDER_COLORSET_HANDLES_SW(s,x) \
++ ((s).border_colorset_handles_sw = (x))
++#define SGET_BORDER_COLORSET_HANDLES_SW(s) \
++ ((s).border_colorset_handles_sw)
++#define SSET_BORDER_COLORSET_HANDLES_SE(s,x) \
++ ((s).border_colorset_handles_se = (x))
++#define SGET_BORDER_COLORSET_HANDLES_SE(s) \
++ ((s).border_colorset_handles_se)
+ #define SGET_COLORSET_HI(s) \
+ ((s).colorset_hi)
+ #define SSET_COLORSET_HI(s,x) \
+@@ -463,8 +527,40 @@
+ ((s).border_colorset_hi)
+ #define SSET_BORDER_COLORSET_HI(s,x) \
+ ((s).border_colorset_hi = (x))
++#define SGET_BORDER_COLORSET_HI_NORTH(s) \
++ ((s).border_colorset_hi_north)
++#define SSET_BORDER_COLORSET_HI_NORTH(s,x) \
++ ((s).border_colorset_hi_north = (x))
++#define SGET_BORDER_COLORSET_HI_SOUTH(s) \
++ ((s).border_colorset_hi_south)
++#define SSET_BORDER_COLORSET_HI_SOUTH(s,x) \
++ ((s).border_colorset_hi_south = (x))
++#define SGET_BORDER_COLORSET_HI_EAST(s) \
++ ((s).border_colorset_hi_east)
++#define SSET_BORDER_COLORSET_HI_EAST(s,x) \
++ ((s).border_colorset_hi_east = (x))
++#define SGET_BORDER_COLORSET_HI_WEST(s) \
++ ((s).border_colorset_hi_west)
++#define SSET_BORDER_COLORSET_HI_WEST(s,x) \
++ ((s).border_colorset_hi_west = (x))
++#define SSET_BORDER_COLORSET_HI_HANDLES_NW(s,x) \
++ ((s).border_colorset_hi_handles_nw = (x))
++#define SGET_BORDER_COLORSET_HI_HANDLES_NW(s) \
++ ((s).border_colorset_hi_handles_nw)
++#define SSET_BORDER_COLORSET_HI_HANDLES_NE(s,x) \
++ ((s).border_colorset_hi_handles_ne = (x))
++#define SGET_BORDER_COLORSET_HI_HANDLES_NE(s) \
++ ((s).border_colorset_hi_handles_ne)
++#define SSET_BORDER_COLORSET_HI_HANDLES_SW(s,x) \
++ ((s).border_colorset_hi_handles_sw = (x))
++#define SGET_BORDER_COLORSET_HI_HANDLES_SW(s) \
++ ((s).border_colorset_hi_handles_sw)
++#define SSET_BORDER_COLORSET_HI_HANDLES_SE(s,x) \
++ ((s).border_colorset_hi_handles_se = (x))
++#define SGET_BORDER_COLORSET_HI_HANDLES_SE(s) \
++ ((s).border_colorset_hi_handles_se)
+ #define SSET_ICON_TITLE_COLORSET(s,x) \
+- ((s).icon_title_colorset = (x))
++ ((s).icon_title_colorset = (x))
+ #define SGET_ICON_TITLE_COLORSET(s) \
+ ((s).icon_title_colorset)
+ #define SSET_ICON_TITLE_COLORSET_HI(s,x) \
+Only in fvwm-patched/fvwm: style.h.orig
diff --git a/03-ResizeOutlineThin.patch b/03-ResizeOutlineThin.patch
new file mode 100644
index 000000000000..e7229146ac3d
--- /dev/null
+++ b/03-ResizeOutlineThin.patch
@@ -0,0 +1,352 @@
+diff --unified --recursive --text fvwm-2.6.9/fvwm/fvwm.h fvwm-patched/fvwm/fvwm.h
+--- fvwm-2.6.9/fvwm/fvwm.h 2020-08-21 15:30:39.091737766 -0600
++++ fvwm-patched/fvwm/fvwm.h 2020-08-21 15:42:30.000309012 -0600
+@@ -222,6 +222,7 @@
+ unsigned do_not_show_on_map : 1;
+ unsigned do_raise_transient : 1;
+ unsigned do_resize_opaque : 1;
++ unsigned do_resize_outline_thin : 1;
+ unsigned do_shrink_windowshade : 1;
+ unsigned do_stack_transient_parent : 1;
+ unsigned do_window_list_skip : 1;
+diff --unified --recursive --text fvwm-2.6.9/fvwm/move_resize.c fvwm-patched/fvwm/move_resize.c
+--- fvwm-2.6.9/fvwm/move_resize.c 2018-05-30 16:28:25.000000000 -0600
++++ fvwm-patched/fvwm/move_resize.c 2020-08-21 15:45:34.999041350 -0600
+@@ -98,7 +98,7 @@
+
+ extern Window PressedW;
+
+-static void draw_move_resize_grid(int x, int y, int width, int height);
++static void draw_move_resize_grid(int x, int y, int width, int height, Bool thin);
+
+ /* ----- end of resize globals ----- */
+
+@@ -116,26 +116,33 @@
+ *
+ */
+ static int get_outline_rects(
+- XRectangle *rects, int x, int y, int width, int height)
++ XRectangle *rects, int x, int y, int width, int height, Bool do_outline_thin)
+ {
+ int i;
+ int n;
+ int m;
+
+- n = 3;
+- m = (width - 5) / 2;
+- if (m < n)
++ if (do_outline_thin)
+ {
+- n = m;
+- }
+- m = (height - 5) / 2;
+- if (m < n)
+- {
+- n = m;
++ n = 1;
+ }
+- if (n < 1)
++ else
+ {
+- n = 1;
++ n = 3;
++ m = (width - 5) / 2;
++ if (m < n)
++ {
++ n = m;
++ }
++ m = (height - 5) / 2;
++ if (m < n)
++ {
++ n = m;
++ }
++ if (n < 1)
++ {
++ n = 1;
++ }
+ }
+
+ for (i = 0; i < n; i++)
+@@ -145,25 +152,28 @@
+ rects[i].width = width - (i << 1);
+ rects[i].height = height - (i << 1);
+ }
+- if (width - (n << 1) >= 5 && height - (n << 1) >= 5)
++ if (!do_outline_thin)
+ {
+- if (width - (n << 1) >= 10)
++ if (width - (n << 1) >= 5 && height - (n << 1) >= 5)
+ {
+- int off = (width - (n << 1)) / 3 + n;
+- rects[i].x = x + off;
+- rects[i].y = y + n;
+- rects[i].width = width - (off << 1);
+- rects[i].height = height - (n << 1);
+- i++;
+- }
+- if (height - (n << 1) >= 10)
+- {
+- int off = (height - (n << 1)) / 3 + n;
+- rects[i].x = x + n;
+- rects[i].y = y + off;
+- rects[i].width = width - (n << 1);
+- rects[i].height = height - (off << 1);
+- i++;
++ if (width - (n << 1) >= 10)
++ {
++ int off = (width - (n << 1)) / 3 + n;
++ rects[i].x = x + off;
++ rects[i].y = y + n;
++ rects[i].width = width - (off << 1);
++ rects[i].height = height - (n << 1);
++ i++;
++ }
++ if (height - (n << 1) >= 10)
++ {
++ int off = (height - (n << 1)) / 3 + n;
++ rects[i].x = x + n;
++ rects[i].y = y + off;
++ rects[i].width = width - (n << 1);
++ rects[i].height = height - (off << 1);
++ i++;
++ }
+ }
+ }
+
+@@ -176,14 +186,15 @@
+ struct
+ {
+ unsigned is_enabled : 1;
++ unsigned do_outline_thin : 1;
+ } flags;
+ } move_resize_grid =
+ {
+ { 0, 0, 0, 0 },
+- { 0 }
++ { 0, 0 }
+ };
+
+-static void draw_move_resize_grid(int x, int y, int width, int height)
++static void draw_move_resize_grid(int x, int y, int width, int height, Bool do_outline_thin)
+ {
+ int nrects = 0;
+ XRectangle rects[10];
+@@ -192,7 +203,8 @@
+ x == move_resize_grid.geom.x &&
+ y == move_resize_grid.geom.y &&
+ width == move_resize_grid.geom.width &&
+- height == move_resize_grid.geom.height)
++ height == move_resize_grid.geom.height &&
++ do_outline_thin == move_resize_grid.flags.do_outline_thin)
+ {
+ return;
+ }
+@@ -210,7 +222,8 @@
+ &(rects[0]), move_resize_grid.geom.x,
+ move_resize_grid.geom.y,
+ move_resize_grid.geom.width,
+- move_resize_grid.geom.height);
++ move_resize_grid.geom.height,
++ move_resize_grid.flags.do_outline_thin);
+ }
+ if (width && height)
+ {
+@@ -219,8 +232,9 @@
+ move_resize_grid.geom.y = y;
+ move_resize_grid.geom.width = width;
+ move_resize_grid.geom.height = height;
++ move_resize_grid.flags.do_outline_thin = do_outline_thin;
+ nrects += get_outline_rects(
+- &(rects[nrects]), x, y, width, height);
++ &(rects[nrects]), x, y, width, height, do_outline_thin);
+ }
+ if (nrects > 0)
+ {
+@@ -237,14 +251,15 @@
+ {
+ if (move_resize_grid.flags.is_enabled)
+ {
+- draw_move_resize_grid(0, 0, 0, 0);
++ draw_move_resize_grid(0, 0, 0, 0, 0);
+ }
+ else
+ {
+ move_resize_grid.geom.x = 0;
+ move_resize_grid.geom.y = 0;
+ move_resize_grid.geom.width = 0;
+- move_resize_grid.geom.height = 0;
++ move_resize_grid.geom.height = 0;
++ move_resize_grid.flags.do_outline_thin = 0;
+ }
+ }
+ else if (!move_resize_grid.flags.is_enabled)
+@@ -256,7 +271,8 @@
+ move_resize_grid.geom.x,
+ move_resize_grid.geom.y,
+ move_resize_grid.geom.width,
+- move_resize_grid.geom.height);
++ move_resize_grid.geom.height,
++ move_resize_grid.flags.do_outline_thin);
+ }
+ }
+
+@@ -2341,6 +2357,7 @@
+ /* Must not set placed by button if the event is a modified KeyEvent */
+ Bool is_fake_event;
+ FvwmWindow *fw = exc->w.fw;
++ Bool do_outline_thin = DO_RESIZE_OUTLINE_THIN(fw);
+ unsigned int draw_parts = PART_NONE;
+ XEvent e;
+
+@@ -2414,7 +2431,7 @@
+ if (!IS_ICONIFIED(fw) &&
+ ((!do_move_opaque && !Scr.gs.do_emulate_mwm) || !IS_MAPPED(fw)))
+ {
+- draw_move_resize_grid(xl, yt, Width - 1, Height - 1);
++ draw_move_resize_grid(xl, yt, Width - 1, Height - 1, do_outline_thin);
+ }
+
+ if (move_w == FW_W_FRAME(fw) && do_move_opaque)
+@@ -2757,7 +2774,7 @@
+ if (!do_move_opaque)
+ {
+ draw_move_resize_grid(
+- xl, yt, Width - 1, Height - 1);
++ xl, yt, Width - 1, Height - 1, do_outline_thin);
+ }
+ else
+ {
+@@ -2833,7 +2850,7 @@
+ if (!do_move_opaque)
+ {
+ draw_move_resize_grid(
+- xl, yt, Width - 1, Height - 1);
++ xl, yt, Width - 1, Height - 1, do_outline_thin);
+ }
+ break;
+
+@@ -3453,7 +3470,7 @@
+ static void __resize_step(
+ const exec_context_t *exc, int x_root, int y_root, int *x_off,
+ int *y_off, rectangle *drag, const rectangle *orig, int *xmotionp,
+- int *ymotionp, Bool do_resize_opaque, Bool is_direction_fixed)
++ int *ymotionp, Bool do_resize_opaque, Bool is_direction_fixed, Bool do_outline_thin)
+ {
+ int action = 0;
+ int x2;
+@@ -3575,7 +3592,7 @@
+ {
+ draw_move_resize_grid(
+ drag->x, drag->y, drag->width - 1,
+- drag->height - 1);
++ drag->height - 1, do_outline_thin);
+ }
+ else
+ {
+@@ -3634,6 +3651,7 @@
+ int x_off;
+ int y_off;
+ direction_t dir;
++ Bool do_outline_thin = DO_RESIZE_OUTLINE_THIN(fw);
+ int warp_x = 0;
+ int warp_y = 0;
+
+@@ -3956,7 +3974,7 @@
+ if (!do_resize_opaque)
+ {
+ draw_move_resize_grid(
+- drag->x, drag->y, drag->width - 1, drag->height - 1);
++ drag->x, drag->y, drag->width - 1, drag->height - 1, do_outline_thin);
+ }
+ /* kick off resizing without requiring any motion if invoked with a key
+ * press */
+@@ -3977,7 +3995,7 @@
+ yo = 0;
+ __resize_step(
+ exc, stashed_x, stashed_y, &xo, &yo, drag, orig,
+- &xmotion, &ymotion, do_resize_opaque, True);
++ &xmotion, &ymotion, do_resize_opaque, True, do_outline_thin);
+ }
+ else
+ {
+@@ -4139,7 +4157,7 @@
+ __resize_step(
+ exc, x, y, &x_off, &y_off, drag, orig,
+ &xmotion, &ymotion, do_resize_opaque,
+- is_direction_fixed);
++ is_direction_fixed, do_outline_thin);
+ is_resized = True;
+ /* need to move the viewport */
+ HandlePaging(
+@@ -4158,7 +4176,7 @@
+ __resize_step(
+ exc, x, y, &x_off, &y_off, drag, orig,
+ &xmotion, &ymotion, do_resize_opaque,
+- is_direction_fixed);
++ is_direction_fixed, do_outline_thin);
+ is_resized = True;
+ }
+ fForceRedraw = False;
+@@ -4194,7 +4212,7 @@
+ {
+ draw_move_resize_grid(
+ drag->x, drag->y, drag->width - 1,
+- drag->height - 1);
++ drag->height - 1, do_outline_thin);
+ }
+ }
+ else
+@@ -4255,7 +4273,7 @@
+ g = sorig;
+ __resize_step(
+ exc, sorig.x, sorig.y, &xo, &yo, &g, orig,
+- &xmotion, &ymotion, do_resize_opaque, True);
++ &xmotion, &ymotion, do_resize_opaque, True, do_outline_thin);
+ }
+ if (vx != Scr.Vx || vy != Scr.Vy)
+ {
+Only in fvwm-patched/fvwm: move_resize.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/style.c fvwm-patched/fvwm/style.c
+--- fvwm-2.6.9/fvwm/style.c 2020-08-21 15:30:39.091737766 -0600
++++ fvwm-patched/fvwm/style.c 2020-08-21 15:40:46.901822038 -0600
+@@ -4044,6 +4044,12 @@
+ S_SET_DO_RESIZE_OPAQUE(SCM(*ps), 1);
+ S_SET_DO_RESIZE_OPAQUE(SCC(*ps), 1);
+ }
++ else if (StrEquals(token, "ResizeOutlineThin"))
++ {
++ S_SET_DO_RESIZE_OUTLINE_THIN(SCF(*ps), on);
++ S_SET_DO_RESIZE_OUTLINE_THIN(SCM(*ps), 1);
++ S_SET_DO_RESIZE_OUTLINE_THIN(SCC(*ps), 1);
++ }
+ else if (StrEquals(token, "RightTitleRotatedCW"))
+ {
+ S_SET_IS_RIGHT_TITLE_ROTATED_CW(SCF(*ps), on);
+Only in fvwm-patched/fvwm: style.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/style.h fvwm-patched/fvwm/style.h
+--- fvwm-2.6.9/fvwm/style.h 2020-08-21 15:30:39.091737766 -0600
++++ fvwm-patched/fvwm/style.h 2020-08-21 15:40:46.901822038 -0600
+@@ -225,6 +225,10 @@
+ ((c).s.do_resize_opaque)
+ #define S_SET_DO_RESIZE_OPAQUE(c,x) \
+ ((c).s.do_resize_opaque = !!(x))
++#define S_DO_RESIZE_OUTLINE_THIN(c) \
++ ((c).s.do_resize_outline_thin)
++#define S_SET_DO_RESIZE_OUTLINE_THIN(c,x) \
++ ((c).s.do_resize_outline_thin = !!(x))
+ #define S_DO_SHRINK_WINDOWSHADE(c) \
+ ((c).s.do_shrink_windowshade)
+ #define S_SET_DO_SHRINK_WINDOWSHADE(c,x) \
+Only in fvwm-patched/fvwm: style.h.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/window_flags.h fvwm-patched/fvwm/window_flags.h
+--- fvwm-2.6.9/fvwm/window_flags.h 2016-10-15 08:51:45.000000000 -0600
++++ fvwm-patched/fvwm/window_flags.h 2020-08-21 15:40:46.905822149 -0600
+@@ -21,6 +21,8 @@
+ ((fw)->flags.common.s.do_raise_transient)
+ #define DO_RESIZE_OPAQUE(fw) \
+ ((fw)->flags.common.s.do_resize_opaque)
++#define DO_RESIZE_OUTLINE_THIN(fw) \
++ ((fw)->flags.common.s.do_resize_outline_thin)
+ #define DO_SHRINK_WINDOWSHADE(fw) \
+ ((fw)->flags.common.s.do_shrink_windowshade)
+ #define SET_DO_SHRINK_WINDOWSHADE(fw,x) \
diff --git a/04-Conditionals.patch b/04-Conditionals.patch
new file mode 100644
index 000000000000..9138809678fe
--- /dev/null
+++ b/04-Conditionals.patch
@@ -0,0 +1,41 @@
+diff --unified --recursive --text fvwm-2.6.9/fvwm/conditional.c fvwm-patched/fvwm/conditional.c
+--- fvwm-2.6.9/fvwm/conditional.c 2019-08-24 16:50:07.000000000 -0600
++++ fvwm-patched/fvwm/conditional.c 2020-08-21 15:49:23.879779609 -0600
+@@ -596,6 +596,36 @@
+ SET_HAS_HANDLES(mask, on);
+ SETM_HAS_HANDLES(mask, 1);
+ }
++ else if (StrEquals(cond, "HasTitle"))
++ {
++ SET_HAS_TITLE(mask, on);
++ SETM_HAS_TITLE(mask, 1);
++ }
++ else if (StrEquals(cond, "HasBorders"))
++ {
++ SET_HAS_NO_BORDER(mask, !on);
++ SETM_HAS_NO_BORDER(mask, 1);
++ }
++ else if (StrEquals(cond, "TitleAtBottom"))
++ {
++ SET_TITLE_DIR(mask, DIR_S);
++ SETM_TITLE_DIR(mask, 1);
++ }
++ else if (StrEquals(cond, "TitleAtTop"))
++ {
++ SET_TITLE_DIR(mask, DIR_N);
++ SETM_TITLE_DIR(mask, 1);
++ }
++ else if (StrEquals(cond, "TitleAtLeft"))
++ {
++ SET_TITLE_DIR(mask, DIR_W);
++ SETM_TITLE_DIR(mask, 1);
++ }
++ else if (StrEquals(cond, "TitleAtRight"))
++ {
++ SET_TITLE_DIR(mask, DIR_E);
++ SETM_TITLE_DIR(mask, 1);
++ }
+ else if (StrEquals(cond,"Iconifiable"))
+ {
+ SET_IS_UNICONIFIABLE(mask, !on);
+Only in fvwm-patched/fvwm: conditional.c.orig
diff --git a/05-FlatSeparators.patch b/05-FlatSeparators.patch
new file mode 100644
index 000000000000..4918a9af172c
--- /dev/null
+++ b/05-FlatSeparators.patch
@@ -0,0 +1,172 @@
+diff --unified --recursive --text fvwm-2.6.9/doc/commands/MenuStyle.xml fvwm-patched/doc/commands/MenuStyle.xml
+--- fvwm-2.6.9/doc/commands/MenuStyle.xml 2016-10-15 08:51:45.000000000 -0600
++++ fvwm-patched/doc/commands/MenuStyle.xml 2020-08-21 15:51:37.721036428 -0600
+@@ -58,7 +58,7 @@
+ PopupOffset,
+ TitleWarp / !TitleWarp,
+ TitleUnderlines0 / TitleUnderlines1 / TitleUnderlines2,
+-SeparatorsLong / SeparatorsShort,
++SeparatorsLong / SeparatorsShort / FlatSeparators,
+ TrianglesSolid / TrianglesRelief,
+ PopupImmediately / PopupDelayed,
+ PopdownImmediately / PopdownDelayed,
+@@ -436,6 +436,11 @@
+ few pixels to the edges of the menu.</para>
+
+ <para>
++<fvwmopt cmd="MenuStyle" opt="FlatSeparators"/>
++changes the separators so that they are a single pixel thick and
++colored the same as the text.</para>
++
++<para>
+ <fvwmopt cmd="MenuStyle" opt="TrianglesSolid"/> and
+ <fvwmopt cmd="MenuStyle" opt="TrianglesRelief"/>
+ affect how the small triangles for sub menus is drawn. Solid
+diff --unified --recursive --text fvwm-2.6.9/fvwm/menuitem.c fvwm-patched/fvwm/menuitem.c
+--- fvwm-2.6.9/fvwm/menuitem.c 2018-05-26 05:35:26.000000000 -0600
++++ fvwm-patched/fvwm/menuitem.c 2020-08-21 15:51:37.721036428 -0600
+@@ -81,10 +81,14 @@
+ *
+ */
+ static void draw_separator(
+- Window w, GC TopGC, GC BottomGC, int x1, int y, int x2)
++ Window w, GC TopGC, GC BottomGC, GC ForeGC, int x1, int y, int x2,
++ Bool do_flat_separators)
+ {
+ XDrawLine(dpy, w, TopGC , x1, y, x2, y);
+- XDrawLine(dpy, w, BottomGC, x1-1, y+1, x2+1, y+1);
++ if (!do_flat_separators)
++ {
++ XDrawLine(dpy, w, BottomGC, x1-1, y+1, x2+1, y+1);
++ }
+
+ return;
+ }
+@@ -380,6 +384,7 @@
+ /*Pixel fg, fgsh;*/
+ int relief_thickness = ST_RELIEF_THICKNESS(ms);
+ Bool is_item_selected;
++ Bool do_flat_separators;
+ Bool item_cleared = False;
+ Bool xft_clear = False;
+ Bool empty_inter = False;
+@@ -598,6 +603,8 @@
+ * Draw the item itself.
+ */
+
++ do_flat_separators = ST_DO_FLAT_SEPARATOR(ms);
++
+ /* Calculate the separator offsets. */
+ if (ST_HAS_LONG_SEPARATORS(ms))
+ {
+@@ -618,9 +625,9 @@
+ {
+ /* It's a separator. */
+ draw_separator(
+- mpip->w, gcs.shadow_gc, gcs.hilight_gc, sx1,
+- y_offset + y_height - MENU_SEPARATOR_HEIGHT,
+- sx2);
++ mpip->w, gcs.shadow_gc, gcs.hilight_gc, gcs.fore_gc,
++ sx1, y_offset + y_height - MENU_SEPARATOR_HEIGHT,
++ sx2, do_flat_separators);
+ /* Nothing else to do. */
+ }
+ return;
+@@ -660,8 +667,8 @@
+ if (sx1 < sx2)
+ {
+ draw_separator(
+- mpip->w, gcs.shadow_gc, gcs.hilight_gc,
+- sx1, y, sx2);
++ mpip->w, gcs.shadow_gc, gcs.hilight_gc, gcs.fore_gc,
++ sx1, y, sx2, do_flat_separators);
+ }
+ }
+ /* Underline the title. */
+@@ -674,8 +681,8 @@
+ {
+ y = y_offset + y_height - MENU_SEPARATOR_HEIGHT;
+ draw_separator(
+- mpip->w, gcs.shadow_gc, gcs.hilight_gc,
+- sx1, y, sx2);
++ mpip->w, gcs.shadow_gc, gcs.hilight_gc, gcs.fore_gc,
++ sx1, y, sx2, do_flat_separators);
+ }
+ break;
+ default:
+Only in fvwm-patched/fvwm: menuitem.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/menus.c fvwm-patched/fvwm/menus.c
+--- fvwm-2.6.9/fvwm/menus.c 2020-08-21 15:25:59.047514850 -0600
++++ fvwm-patched/fvwm/menus.c 2020-08-21 15:51:37.725036473 -0600
+@@ -1651,6 +1651,10 @@
+ separator_height = (last_item_has_relief) ?
+ MENU_SEPARATOR_HEIGHT + relief_thickness :
+ MENU_SEPARATOR_TOTAL_HEIGHT;
++ if (MST_DO_FLAT_SEPARATOR(msp->menu))
++ {
++ separator_height += 1;
++ }
+ MI_Y_OFFSET(mi) = y;
+ if (MI_IS_TITLE(mi))
+ {
+Only in fvwm-patched/fvwm: menus.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/menustyle.c fvwm-patched/fvwm/menustyle.c
+--- fvwm-2.6.9/fvwm/menustyle.c 2018-05-26 05:35:26.000000000 -0600
++++ fvwm-patched/fvwm/menustyle.c 2020-08-21 15:51:37.725036473 -0600
+@@ -430,7 +430,7 @@
+ "TrianglesUseFore",
+ "TitleColorset", "HilightTitleBack",
+ "TitleFont",
+- "VerticalMargins",
++ "VerticalMargins", "FlatSeparators",
+ "UniqueHotkeyActivatesImmediate",
+ NULL
+ };
+@@ -900,6 +900,7 @@
+ ST_SCROLL_OFF_PAGE(tmpms) = 1;
+ ST_DO_HILIGHT_TITLE_BACK(tmpms) = 0;
+ ST_USING_DEFAULT_TITLEFONT(tmpms) = True;
++ ST_DO_FLAT_SEPARATOR(tmpms) = 0;
+ has_gc_changed = True;
+ option = "fvwm";
+ }
+@@ -1605,6 +1606,9 @@
+ case 63: /* UniqueHotKeyActivatesImmediate */
+ ST_HOTKEY_ACTIVATES_IMMEDIATE(tmpms) = on;
+ break;
++ case 63: /* FlatSeparators */
++ ST_DO_FLAT_SEPARATOR(tmpms) = on;
++ break;
+
+ #if 0
+ case 99: /* PositionHints */
+@@ -1863,6 +1867,8 @@
+ ST_TRIANGLES_USE_FORE(destms) = ST_TRIANGLES_USE_FORE(origms);
+ /* Title */
+ ST_DO_HILIGHT_TITLE_BACK(destms) = ST_DO_HILIGHT_TITLE_BACK(origms);
++ /* FlatSeparators */
++ ST_DO_FLAT_SEPARATOR(destms) = ST_DO_FLAT_SEPARATOR(origms);
+
+ menustyle_update(destms);
+
+Only in fvwm-patched/fvwm: menustyle.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/menustyle.h fvwm-patched/fvwm/menustyle.h
+--- fvwm-2.6.9/fvwm/menustyle.h 2016-10-15 08:51:45.000000000 -0600
++++ fvwm-patched/fvwm/menustyle.h 2020-08-21 15:51:37.725036473 -0600
+@@ -23,6 +23,8 @@
+ #define MST_FACE(m) ((m)->s->ms->look.face)
+ #define ST_DO_HILIGHT_BACK(s) ((s)->look.flags.do_hilight_back)
+ #define MST_DO_HILIGHT_BACK(m) ((m)->s->ms->look.flags.do_hilight_back)
++#define ST_DO_FLAT_SEPARATOR(s) ((s)->look.flags.do_flat_separator)
++#define MST_DO_FLAT_SEPARATOR(m) ((m)->s->ms->look.flags.do_flat_separator)
+ #define ST_DO_HILIGHT_FORE(s) ((s)->look.flags.do_hilight_fore)
+ #define MST_DO_HILIGHT_FORE(m) ((m)->s->ms->look.flags.do_hilight_fore)
+ #define ST_DO_HILIGHT_TITLE_BACK(s) ((s)->look.flags.do_hilight_title_back)
+@@ -282,6 +284,7 @@
+ unsigned has_title_cset : 1;
+ unsigned do_hilight_title_back : 1;
+ unsigned using_default_titlefont : 1;
++ unsigned do_flat_separator : 1;
+ } flags;
+ unsigned char ReliefThickness;
+ unsigned char TitleUnderlines;
diff --git a/06-BorderUnderTitle.patch b/06-BorderUnderTitle.patch
new file mode 100644
index 000000000000..3d9d096e7421
--- /dev/null
+++ b/06-BorderUnderTitle.patch
@@ -0,0 +1,213 @@
+diff --unified --recursive --text fvwm-2.6.9/fvwm/borders.c fvwm-patched/fvwm/borders.c
+--- fvwm-2.6.9/fvwm/borders.c 2020-08-21 15:30:39.087737712 -0600
++++ fvwm-patched/fvwm/borders.c 2020-08-21 15:58:30.667261464 -0600
+@@ -4983,6 +4983,7 @@
+ rectangle *ret_g, Window *ret_w)
+ {
+ int bw;
++ Bool title;
+
+ bw = fw->boundary_width;
+ /* ret_g->x and ret->y is just an offset relatively to the w,
+@@ -5053,7 +5054,32 @@
+ ret_g->height = sidebar_g->y;
+ break;
+ default:
+- return;
++ break;
++ }
++
++ if (HAS_BORDER_UNDER_TITLE(fw))
++ {
++ title = False;
++ switch (GET_TITLE_DIR(fw))
++ {
++ case DIR_N: title = part & PART_TOP; break;
++ case DIR_E: title = part & PART_RIGHT; break;
++ case DIR_S: title = part & PART_BOTTOM; break;
++ case DIR_W: title = part & PART_LEFT; break;
++ }
++ if (title)
++ {
++ ret_g->width = max(ret_g->width, 2 * bw + fw->title_thickness);
++ ret_g->height = max(ret_g->height, 2 * bw + fw->title_thickness);
++ if (part & PART_RIGHT)
++ {
++ ret_g->x = 2 * sidebar_g->x + sidebar_g->width - ret_g->width;
++ }
++ if (part & PART_BOTTOM)
++ {
++ ret_g->y = 2 * sidebar_g->y + sidebar_g->height - ret_g->height;
++ }
++ }
+ }
+
+ return;
+Only in fvwm-patched/fvwm: borders.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/borders.h fvwm-patched/fvwm/borders.h
+--- fvwm-2.6.9/fvwm/borders.h 2016-10-15 08:51:45.000000000 -0600
++++ fvwm-patched/fvwm/borders.h 2020-08-21 15:58:30.667261464 -0600
+@@ -36,7 +36,12 @@
+ PART_FRAME = 0xff,
+ PART_TITLEBAR = 0x300,
+ PART_HANDLES = 0xc00,
+- PART_ALL = 0xfff
++ PART_ALL = 0xfff,
++
++ PART_TOP = 0x31,
++ PART_BOTTOM = 0xc2,
++ PART_LEFT = 0x58,
++ PART_RIGHT = 0xa4
+ } window_parts;
+
+ typedef enum
+diff --unified --recursive --text fvwm-2.6.9/fvwm/fvwm.h fvwm-patched/fvwm/fvwm.h
+--- fvwm-2.6.9/fvwm/fvwm.h 2020-08-21 15:48:43.507505372 -0600
++++ fvwm-patched/fvwm/fvwm.h 2020-08-21 15:58:30.667261464 -0600
+@@ -268,6 +268,7 @@
+ #define WINDOWSHADE_LAZY_MASK 0x3
+ unsigned windowshade_laziness : 2;
+ unsigned use_title_decor_rotation : 1;
++ unsigned has_border_under_title : 1;
+ focus_policy_t focus_policy;
+ } s;
+ } common_flags_t;
+Only in fvwm-patched/fvwm: fvwm.h.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/geometry.c fvwm-patched/fvwm/geometry.c
+--- fvwm-2.6.9/fvwm/geometry.c 2018-04-28 05:46:28.000000000 -0600
++++ fvwm-patched/fvwm/geometry.c 2020-08-21 16:02:53.280322490 -0600
+@@ -45,6 +45,9 @@
+
+ /* ---------------------------- forward declarations ----------------------- */
+
++static void __get_window_borders(
++ const FvwmWindow *fw, size_borders *borders, Bool is_shaded);
++
+ /* ---------------------------- local variables ---------------------------- */
+
+ /* ---------------------------- exported variables (globals) --------------- */
+@@ -351,7 +354,7 @@
+ get_window_borders_no_title(fw, &b);
+ break;
+ default:
+- get_window_borders(fw, &b);
++ __get_window_borders(fw, &b, 1);
+ break;
+ }
+ *small_g = *big_g;
+@@ -479,23 +482,38 @@
+ void get_window_borders(
+ const FvwmWindow *fw, size_borders *borders)
+ {
++ __get_window_borders(fw, borders, 0);
++}
++
++static void __get_window_borders(
++ const FvwmWindow *fw, size_borders *borders, Bool is_shaded)
++{
++ int title_thickness;
++
+ borders->top_left.width = fw->boundary_width;
+ borders->bottom_right.width = fw->boundary_width;
+ borders->top_left.height = fw->boundary_width;
+ borders->bottom_right.height = fw->boundary_width;
++
++ title_thickness = fw->title_thickness;
++ if (HAS_TITLE(fw) && HAS_BORDER_UNDER_TITLE(fw) && !is_shaded)
++ {
++ title_thickness += fw->boundary_width;
++ }
++
+ switch (GET_TITLE_DIR(fw))
+ {
+ case DIR_N:
+- borders->top_left.height += fw->title_thickness;
++ borders->top_left.height += title_thickness;
+ break;
+ case DIR_S:
+- borders->bottom_right.height += fw->title_thickness;
++ borders->bottom_right.height += title_thickness;
+ break;
+ case DIR_W:
+- borders->top_left.width += fw->title_thickness;
++ borders->top_left.width += title_thickness;
+ break;
+ case DIR_E:
+- borders->bottom_right.width += fw->title_thickness;
++ borders->bottom_right.width += title_thickness;
+ break;
+ }
+ borders->total_size.width =
+Only in fvwm-patched/fvwm: geometry.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/geometry.h fvwm-patched/fvwm/geometry.h
+--- fvwm-2.6.9/fvwm/geometry.h 2016-10-15 08:51:45.000000000 -0600
++++ fvwm-patched/fvwm/geometry.h 2020-08-21 15:58:30.667261464 -0600
+@@ -44,6 +44,8 @@
+ FvwmWindow *fw, rectangle *ret_g);
+ void get_window_borders(
+ const FvwmWindow *fw, size_borders *borders);
++void get_window_borders_shaded(
++ const FvwmWindow *fw, size_borders *borders);
+ void get_window_borders_no_title(
+ const FvwmWindow *fw, size_borders *borders);
+ void set_window_border_size(
+diff --unified --recursive --text fvwm-2.6.9/fvwm/style.c fvwm-patched/fvwm/style.c
+--- fvwm-2.6.9/fvwm/style.c 2020-08-21 15:48:43.507505372 -0600
++++ fvwm-patched/fvwm/style.c 2020-08-21 15:58:30.671261536 -0600
+@@ -2247,6 +2247,12 @@
+ {
+ rest = style_parse_button_style(ps, rest, on);
+ }
++ else if (StrEquals(token, "BORDERUNDERTITLE"))
++ {
++ S_SET_HAS_BORDER_UNDER_TITLE(SCF(*ps), on);
++ S_SET_HAS_BORDER_UNDER_TITLE(SCM(*ps), 1);
++ S_SET_HAS_BORDER_UNDER_TITLE(SCC(*ps), 1);
++ }
+ else if (StrEquals(token, "BorderWidth"))
+ {
+ if (GetIntegerArguments(rest, &rest, val, 1))
+@@ -5184,6 +5190,11 @@
+ {
+ flags->do_update_rotated_title = 1;
+ }
++
++ if (S_HAS_BORDER_UNDER_TITLE(SCC(*ret_style)))
++ {
++ flags->do_redecorate = True;
++ }
+
+ /* has_mwm_border
+ * has_mwm_buttons */
+Only in fvwm-patched/fvwm: style.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/style.h fvwm-patched/fvwm/style.h
+--- fvwm-2.6.9/fvwm/style.h 2020-08-21 15:48:43.511505397 -0600
++++ fvwm-patched/fvwm/style.h 2020-08-21 15:58:30.671261536 -0600
+@@ -369,6 +369,10 @@
+ ((c).s.use_title_decor_rotation)
+ #define S_SET_USE_TITLE_DECOR_ROTATION(c,x) \
+ ((c).s.use_title_decor_rotation = !!(x))
++#define S_HAS_BORDER_UNDER_TITLE(c) \
++ ((c).s.has_border_under_title)
++#define S_SET_HAS_BORDER_UNDER_TITLE(c,x) \
++ ((c).s.has_border_under_title = !!(x))
+ #define S_DO_EWMH_MINI_ICON_OVERRIDE(c) \
+ ((c).s.do_ewmh_mini_icon_override)
+ #define S_SET_DO_EWMH_MINI_ICON_OVERRIDE(c,x) \
+Only in fvwm-patched/fvwm: style.h.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/window_flags.h fvwm-patched/fvwm/window_flags.h
+--- fvwm-2.6.9/fvwm/window_flags.h 2020-08-21 15:48:43.511505397 -0600
++++ fvwm-patched/fvwm/window_flags.h 2020-08-21 15:58:30.671261536 -0600
+@@ -328,6 +328,12 @@
+ (fw)->flags.common.s.use_title_decor_rotation = !!(x)
+ #define SETM_USE_TITLE_DECOR_ROTATION(fw,x) \
+ (fw)->flag_mask.common.s.use_title_decor_rotation = !!(x)
++#define HAS_BORDER_UNDER_TITLE(fw) \
++ ((fw)->flags.common.s.has_border_under_title)
++#define SET_HAS_BORDER_UNDER_TITLE(fw,x) \
++ (fw)->flags.common.s.has_border_under_title = !!(x)
++#define SETM_HAS_BORDER_UNDER_TITLE(fw,x) \
++ (fw)->flag_mask.common.s.has_border_under_title = !!(x)
+
+ /* access to the special flags of a window */
+ #define DO_REUSE_DESTROYED(fw) \
diff --git a/07-InactiveFont.patch b/07-InactiveFont.patch
new file mode 100644
index 000000000000..682919e33b42
--- /dev/null
+++ b/07-InactiveFont.patch
@@ -0,0 +1,345 @@
+diff --unified --recursive --text fvwm-2.6.9/fvwm/add_window.c fvwm-patched/fvwm/add_window.c
+--- fvwm-2.6.9/fvwm/add_window.c 2018-05-26 05:35:26.000000000 -0600
++++ fvwm-patched/fvwm/add_window.c 2020-08-21 16:05:17.755315854 -0600
+@@ -763,6 +763,18 @@
+ fw->title_font = Scr.DefaultFont;
+ SET_USING_DEFAULT_WINDOW_FONT(fw, 1);
+
++ if (IS_INACTIVE_WINDOW_FONT_LOADED(fw) && !USING_DEFAULT_INACTIVE_WINDOW_FONT(fw) &&
++ fw->title_font != Scr.DefaultFont)
++ {
++ FlocaleUnloadFont(dpy, fw->title_font);
++ }
++ SET_INACTIVE_WINDOW_FONT_LOADED(fw, 0);
++ /* Fall back to default font. There are some race conditions when a
++ * window is destroyed and recaptured where an invalid font might be
++ * accessed otherwise. */
++ fw->title_font = Scr.DefaultFont;
++ SET_USING_DEFAULT_INACTIVE_WINDOW_FONT(fw, 1);
++
+ return;
+ }
+
+@@ -1963,6 +1975,25 @@
+ }
+ SET_WINDOW_FONT_LOADED(fw, 1);
+ }
++ /* load inactive font */
++ if (!IS_INACTIVE_WINDOW_FONT_LOADED(fw))
++ {
++ if (S_HAS_INACTIVE_WINDOW_FONT(SCF(*pstyle)) &&
++ SGET_INACTIVE_WINDOW_FONT(*pstyle) &&
++ (fw->inactive_title_font =
++ FlocaleLoadFont(dpy, SGET_INACTIVE_WINDOW_FONT(*pstyle), "FVWM")))
++ {
++ SET_USING_DEFAULT_INACTIVE_WINDOW_FONT(fw, 0);
++ }
++ else
++ {
++ /* no explicit font or failed to load, use active title font
++ * instead */
++ fw->inactive_title_font = fw->title_font;
++ SET_USING_DEFAULT_INACTIVE_WINDOW_FONT(fw, 1);
++ }
++ SET_INACTIVE_WINDOW_FONT_LOADED(fw, 1);
++ }
+ setup_title_geometry(fw, pstyle);
+
+ return;
+Only in fvwm-patched/fvwm: add_window.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/borders.c fvwm-patched/fvwm/borders.c
+--- fvwm-2.6.9/fvwm/borders.c 2020-08-21 16:04:22.090148699 -0600
++++ fvwm-patched/fvwm/borders.c 2020-08-21 16:05:17.759315938 -0600
+@@ -3912,7 +3912,7 @@
+
+ static void border_draw_title_mono(
+ FvwmWindow *fw, titlebar_descr *td, title_draw_descr *tdd,
+- FlocaleWinString *fstr, Pixmap dest_pix)
++ FlocaleWinString *fstr, Pixmap dest_pix, Bool do_hilight)
+ {
+ int has_vt;
+
+@@ -3922,7 +3922,8 @@
+ td->offset - 2, 0, td->length+4, fw->title_thickness);
+ if (fw->visible_name != (char *)NULL)
+ {
+- FlocaleDrawString(dpy, fw->title_font, fstr, 0);
++ FlocaleDrawString(dpy, do_hilight ? fw->title_font :
++ fw->inactive_title_font, fstr, 0);
+ }
+ /* for mono, we clear an area in the title bar where the window
+ * title goes, so that its more legible. For color, no need */
+@@ -3986,7 +3987,7 @@
+
+ static void border_draw_title_deep(
+ FvwmWindow *fw, titlebar_descr *td, title_draw_descr *tdd,
+- FlocaleWinString *fstr, Pixmap dest_pix, Window w)
++ FlocaleWinString *fstr, Pixmap dest_pix, Window w, Bool do_hilight)
+ {
+ DecorFace *df;
+ pixmap_background_type bg;
+@@ -4008,14 +4009,15 @@
+ 1);
+ }
+ }
+- FlocaleDrawString(dpy, fw->title_font, &tdd->fstr, 0);
++ FlocaleDrawString(dpy, do_hilight ? fw->title_font :
++ fw->inactive_title_font, &tdd->fstr, 0);
+
+ return;
+ }
+
+ static void border_get_titlebar_draw_descr(
+ FvwmWindow *fw, titlebar_descr *td, title_draw_descr *tdd,
+- Pixmap dest_pix)
++ Pixmap dest_pix, Bool do_hilight)
+ {
+ memset(tdd, 0, sizeof(*tdd));
+ /* prepare the gcs and variables */
+@@ -4029,7 +4031,8 @@
+ tdd->rgc = td->cd->relief_gc;
+ tdd->sgc = td->cd->shadow_gc;
+ }
+- NewFontAndColor(fw->title_font, td->cd->fore_color, td->cd->back_color);
++ NewFontAndColor(do_hilight ? fw->title_font : fw->inactive_title_font,
++ td->cd->fore_color, td->cd->back_color);
+ tdd->tstyle = &TB_STATE(
+ GetDecor(fw, titlebar))[td->tbstate.tstate].style;
+ tdd->df = &TB_STATE(GetDecor(fw, titlebar))[td->tbstate.tstate];
+@@ -4066,7 +4069,7 @@
+ }
+
+ static void border_set_title_pixmap(
+- FvwmWindow *fw, titlebar_descr *td, Pixmap *dest_pix, Window w)
++ FvwmWindow *fw, titlebar_descr *td, Pixmap *dest_pix, Window w, Bool do_hilight)
+ {
+ pixmap_background_type bg;
+ title_draw_descr tdd;
+@@ -4074,7 +4077,7 @@
+ Bool free_bg_pixmap = False;
+ rectangle pix_g;
+
+- border_get_titlebar_draw_descr(fw, td, &tdd, *dest_pix);
++ border_get_titlebar_draw_descr(fw, td, &tdd, *dest_pix, do_hilight);
+ /* prepare background, either from the window colour or from the
+ * border style */
+ if (!DFS_USE_BORDER_STYLE(*tdd.tstyle))
+@@ -4142,11 +4145,11 @@
+
+ if (Pdepth < 2)
+ {
+- border_draw_title_mono(fw, td, &tdd, &fstr, *dest_pix);
++ border_draw_title_mono(fw, td, &tdd, &fstr, *dest_pix, do_hilight);
+ }
+ else
+ {
+- border_draw_title_deep(fw, td, &tdd, &fstr, *dest_pix, w);
++ border_draw_title_deep(fw, td, &tdd, &fstr, *dest_pix, w, do_hilight);
+ }
+ border_draw_title_relief(fw, td, &tdd, *dest_pix);
+ border_draw_title_stick_lines(fw, td, &tdd, *dest_pix);
+@@ -4155,7 +4158,7 @@
+ }
+
+ static void border_draw_title(
+- FvwmWindow *fw, titlebar_descr *td)
++ FvwmWindow *fw, titlebar_descr *td, Bool do_hilight)
+ {
+ Pixmap p;
+
+@@ -4173,7 +4176,7 @@
+ #if 0
+ fprintf(stderr,"drawing title\n");
+ #endif
+- border_set_title_pixmap(fw, td, &p, FW_W_TITLE(fw));
++ border_set_title_pixmap(fw, td, &p, FW_W_TITLE(fw), do_hilight);
+ if (td->draw_rotation != ROTATION_0)
+ {
+ Pixmap tmp;
+@@ -4662,9 +4665,9 @@
+ if (fw->visible_name != (char *)NULL)
+ {
+ ret_td->length = FlocaleTextWidth(
+- fw->title_font, fw->visible_name,
+- (ret_td->has_vt) ? -strlen(fw->visible_name) :
+- strlen(fw->visible_name));
++ do_hilight ? fw->title_font : fw->inactive_title_font,
++ fw->visible_name, (ret_td->has_vt) ?
++ -strlen(fw->visible_name) : strlen(fw->visible_name));
+ if (ret_td->length > fw->title_length -
+ 2*MIN_WINDOW_TITLE_TEXT_OFFSET)
+ {
+@@ -4770,7 +4773,7 @@
+ }
+ if ((draw_parts & PART_TITLE) != PART_NONE)
+ {
+- border_draw_title(fw, &td);
++ border_draw_title(fw, &td, do_hilight);
+ }
+ if ((draw_parts & PART_BUTTONS) != PART_NONE)
+ {
+Only in fvwm-patched/fvwm: borders.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/fvwm.h fvwm-patched/fvwm/fvwm.h
+--- fvwm-2.6.9/fvwm/fvwm.h 2020-08-21 16:04:22.090148699 -0600
++++ fvwm-patched/fvwm/fvwm.h 2020-08-21 16:05:17.759315938 -0600
+@@ -198,6 +198,7 @@
+ unsigned has_icon_font : 1;
+ unsigned has_no_border : 1;
+ unsigned has_window_font : 1;
++ unsigned has_inactive_window_font : 1;
+ unsigned title_dir : 2;
+ unsigned user_states : 32;
+ /* static flags that do not change dynamically after the window has
+@@ -360,11 +361,13 @@
+ unsigned is_viewport_moved : 1;
+ unsigned is_window_being_moved_opaque : 1;
+ unsigned is_window_font_loaded : 1;
++ unsigned is_inactive_window_font_loaded : 1;
+ unsigned is_window_shaded : 1;
+ unsigned used_title_dir_for_shading : 1;
+ unsigned shaded_dir : 3;
+ unsigned using_default_icon_font : 1;
+ unsigned using_default_window_font : 1;
++ unsigned using_default_inactive_window_font : 1;
+ #define ICON_HINT_NEVER 0
+ #define ICON_HINT_ONCE 1
+ #define ICON_HINT_MULTIPLE 2
+@@ -679,6 +682,7 @@
+ signed char icon_title_relief;
+ char *icon_font;
+ char *window_font;
++ char *inactive_window_font;
+ char *fore_color_name;
+ char *back_color_name;
+ char *fore_color_name_hi;
+@@ -838,6 +842,7 @@
+
+ /* title font */
+ FlocaleFont *title_font;
++ FlocaleFont *inactive_title_font;
+ /* /Y coordinate to draw the title name */
+ short title_text_offset;
+ short title_length;
+Only in fvwm-patched/fvwm: fvwm.h.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/style.c fvwm-patched/fvwm/style.c
+--- fvwm-2.6.9/fvwm/style.c 2020-08-21 16:04:22.090148699 -0600
++++ fvwm-patched/fvwm/style.c 2020-08-21 16:05:17.759315938 -0600
+@@ -440,6 +440,22 @@
+ *merged_style, SGET_WINDOW_FONT(*add_style));
+ }
+ }
++ if (S_HAS_INACTIVE_WINDOW_FONT(SCF(*add_style)))
++ {
++ if (do_free_src_and_alloc_copy)
++ {
++ SAFEFREE(SGET_INACTIVE_WINDOW_FONT(*merged_style));
++ SSET_INACTIVE_WINDOW_FONT(
++ *merged_style, (SGET_INACTIVE_WINDOW_FONT(*add_style)) ?
++ safestrdup(SGET_INACTIVE_WINDOW_FONT(*add_style)) :
++ NULL);
++ }
++ else
++ {
++ SSET_INACTIVE_WINDOW_FONT(
++ *merged_style, SGET_INACTIVE_WINDOW_FONT(*add_style));
++ }
++ }
+ if (add_style->flags.use_start_on_desk)
+ {
+ SSET_START_DESK(*merged_style, SGET_START_DESK(*add_style));
+@@ -931,6 +947,10 @@
+ {
+ SAFEFREE(SGET_WINDOW_FONT(*style));
+ }
++ if (pmask->common.has_inactive_window_font)
++ {
++ SAFEFREE(SGET_INACTIVE_WINDOW_FONT(*style));
++ }
+ if (pmask->has_icon)
+ {
+ SAFEFREE(SGET_ICON_NAME(*style));
+@@ -3359,6 +3379,15 @@
+ S_SET_IS_UNICONIFIABLE(SCM(*ps), 1);
+ S_SET_IS_UNICONIFIABLE(SCC(*ps), 1);
+ }
++ else if (StrEquals(token, "InactiveFont"))
++ {
++ SAFEFREE(SGET_INACTIVE_WINDOW_FONT(*ps));
++ rest = GetNextToken(rest, &token);
++ SSET_INACTIVE_WINDOW_FONT(*ps, token);
++ S_SET_HAS_INACTIVE_WINDOW_FONT(SCF(*ps), (token != NULL));
++ S_SET_HAS_INACTIVE_WINDOW_FONT(SCM(*ps), 1);
++ S_SET_HAS_INACTIVE_WINDOW_FONT(SCC(*ps), 1);
++ }
+ else if (StrEquals(token, "IndexedWindowName"))
+ {
+ char *format;
+@@ -5216,6 +5245,12 @@
+ flags->do_update_window_font = 1;
+ }
+
++ /* has_inactive_window_font */
++ if (S_HAS_INACTIVE_WINDOW_FONT(SCC(*ret_style)))
++ {
++ flags->do_update_window_font = True;
++ }
++
+ /* has_stippled_title */
+ if (S_HAS_STIPPLED_TITLE(SCC(*ret_style)) ||
+ S_HAS_NO_STICKY_STIPPLED_TITLE(SCC(*ret_style)) ||
+Only in fvwm-patched/fvwm: style.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/style.h fvwm-patched/fvwm/style.h
+--- fvwm-2.6.9/fvwm/style.h 2020-08-21 16:04:22.090148699 -0600
++++ fvwm-patched/fvwm/style.h 2020-08-21 16:05:17.759315938 -0600
+@@ -293,6 +293,10 @@
+ ((c).has_window_font)
+ #define S_SET_HAS_WINDOW_FONT(c,x) \
+ ((c).has_window_font = !!(x))
++#define S_HAS_INACTIVE_WINDOW_FONT(c) \
++ ((c).has_inactive_window_font)
++#define S_SET_HAS_INACTIVE_WINDOW_FONT(c,x) \
++ ((c).has_inactive_window_font = !!(x))
+ #define S_ICON_OVERRIDE(c) \
+ ((c).s.icon_override)
+ #define S_SET_ICON_OVERRIDE(c,x) \
+@@ -487,6 +491,10 @@
+ ((s).window_font)
+ #define SSET_WINDOW_FONT(s,x) \
+ ((s).window_font = (x))
++#define SGET_INACTIVE_WINDOW_FONT(s) \
++ ((s).inactive_window_font)
++#define SSET_INACTIVE_WINDOW_FONT(s,x) \
++ ((s).inactive_window_font = (x))
+ #define SGET_COLORSET(s) \
+ ((s).colorset)
+ #define SSET_COLORSET(s,x) \
+Only in fvwm-patched/fvwm: style.h.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/window_flags.h fvwm-patched/fvwm/window_flags.h
+--- fvwm-2.6.9/fvwm/window_flags.h 2020-08-21 16:04:22.094148783 -0600
++++ fvwm-patched/fvwm/window_flags.h 2020-08-21 16:05:17.759315938 -0600
+@@ -580,6 +580,12 @@
+ (fw)->flags.is_window_font_loaded = !!(x)
+ #define SETM_WINDOW_FONT_LOADED(fw,x) \
+ (fw)->flag_mask.is_window_font_loaded = !!(x)
++#define IS_INACTIVE_WINDOW_FONT_LOADED(fw) \
++ ((fw)->flags.is_inactive_window_font_loaded)
++#define SET_INACTIVE_WINDOW_FONT_LOADED(fw,x) \
++ (fw)->flags.is_inactive_window_font_loaded = !!(x)
++#define SETM_INACTIVE_WINDOW_FONT_LOADED(fw,x) \
++ (fw)->flag_mask.is_inactive_window_font_loaded = !!(x)
+ #define CR_MOTION_METHOD(fw) \
+ ((fw)->flags.cr_motion_method)
+ #define SET_CR_MOTION_METHOD(fw,x) \
+@@ -622,6 +628,12 @@
+ (fw)->flags.using_default_window_font = !!(x)
+ #define SETM_USING_DEFAULT_WINDOW_FONT(fw,x) \
+ (fw)->flag_mask.using_default_window_font = !!(x)
++#define USING_DEFAULT_INACTIVE_WINDOW_FONT(fw) \
++ ((fw)->flags.using_default_inactive_window_font)
++#define SET_USING_DEFAULT_INACTIVE_WINDOW_FONT(fw,x) \
++ (fw)->flags.using_default_inactive_window_font = !!(x)
++#define SETM_USING_DEFAULT_INACTIVE_WINDOW_FONT(fw,x) \
++ (fw)->flag_mask.using_default_inactive_window_font = !!(x)
+ #define USING_DEFAULT_ICON_FONT(fw) \
+ ((fw)->flags.using_default_icon_font)
+ #define SET_USING_DEFAULT_ICON_FONT(fw,x) \
diff --git a/02-FluxRoundedCorners.patch b/08-FluxRoundedCorners.patch
index 3c0c53a4da6c..db73c63d062f 100644
--- a/02-FluxRoundedCorners.patch
+++ b/08-FluxRoundedCorners.patch
@@ -1,7 +1,7 @@
-diff --unified --recursive --text fvwm-2.6.9/fvwm/add_window.c new/fvwm/add_window.c
---- fvwm-2.6.9/fvwm/add_window.c 2018-05-26 05:35:26.000000000 -0600
-+++ new/fvwm/add_window.c 2020-02-02 16:19:32.245060960 -0700
-@@ -1916,6 +1916,7 @@
+diff --unified --recursive --text fvwm-2.6.9/fvwm/add_window.c fvwm-patched/fvwm/add_window.c
+--- fvwm-2.6.9/fvwm/add_window.c 2020-08-21 16:07:19.993929916 -0600
++++ fvwm-patched/fvwm/add_window.c 2020-08-21 16:08:05.602920846 -0600
+@@ -1928,6 +1928,7 @@
{
int width;
int offset;
@@ -9,7 +9,7 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/add_window.c new/fvwm/add_wind
get_title_font_size_and_offset(
fw, S_TITLE_DIR(SCF(*pstyle)),
-@@ -1927,6 +1928,10 @@
+@@ -1939,6 +1940,10 @@
fw->title_thickness = width;
fw->title_text_offset = offset;
fw->corner_width = fw->title_thickness + fw->boundary_width;
@@ -20,7 +20,7 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/add_window.c new/fvwm/add_wind
if (!HAS_TITLE(fw))
{
fw->title_thickness = 0;
-@@ -2828,6 +2833,8 @@
+@@ -2859,6 +2864,8 @@
fw = NULL;
}
@@ -29,11 +29,11 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/add_window.c new/fvwm/add_wind
return fw;
}
-Only in new/fvwm: add_window.c.orig
-diff --unified --recursive --text fvwm-2.6.9/fvwm/borders.c new/fvwm/borders.c
---- fvwm-2.6.9/fvwm/borders.c 2018-05-26 05:35:26.000000000 -0600
-+++ new/fvwm/borders.c 2020-02-02 16:19:32.245060960 -0700
-@@ -1377,6 +1377,24 @@
+Only in fvwm-patched/fvwm: add_window.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/borders.c fvwm-patched/fvwm/borders.c
+--- fvwm-2.6.9/fvwm/borders.c 2020-08-21 16:07:19.993929916 -0600
++++ fvwm-patched/fvwm/borders.c 2020-08-21 16:08:05.602920846 -0600
+@@ -1745,6 +1745,24 @@
return;
}
@@ -58,11 +58,11 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/borders.c new/fvwm/borders.c
/* create a root transparent colorset bg, we take in account a possible
* drawing rotation */
static Pixmap border_create_root_transparent_pixmap(
-@@ -1592,12 +1610,28 @@
+@@ -1989,12 +2007,28 @@
pix_g.width = part_g.width;
pix_g.height = part_g.height;
border_fill_pixmap_background(p, &pix_g, &bg, cd);
-+ if (HAS_FLUXBOX_HANDLES(fw))
++ if (HAS_FLUXBOX_HANDLES(fw) && (part & PART_BOTTOM))
+ {
+ pix_g.y = part_g.height - fw->boundary_width;
+ if (part != PART_BORDER_S)
@@ -88,7 +88,7 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/borders.c new/fvwm/borders.c
{
border_draw_part_relief(br, frame_g, &part_g, p, is_inverted);
/* draw the handle marks */
-@@ -4113,6 +4147,9 @@
+@@ -4514,6 +4548,9 @@
JustificationType just;
int lbl = 0;
int rbl = 0;
@@ -98,7 +98,7 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/borders.c new/fvwm/borders.c
ret_td->cd = cd;
ret_td->frame_g = *new_g;
-@@ -4150,16 +4187,16 @@
+@@ -4551,16 +4588,16 @@
/* geometry of the title bar title + buttons */
if (!ret_td->has_vt)
{
@@ -119,7 +119,7 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/borders.c new/fvwm/borders.c
ret_td->bar_g.x = ret_td->layout.title_g.x;
}
-@@ -4211,7 +4248,7 @@
+@@ -4612,7 +4649,7 @@
{
ret_td->left_buttons_g.height = rbl;
ret_td->right_buttons_g.height = lbl;
@@ -128,7 +128,7 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/borders.c new/fvwm/borders.c
ret_td->right_buttons_g.x = ret_td->bar_g.x;
ret_td->left_buttons_g.y = ret_td->layout.title_g.y +
ret_td->layout.title_g.height;
-@@ -4221,7 +4258,7 @@
+@@ -4622,7 +4659,7 @@
{
ret_td->left_buttons_g.width = rbl;
ret_td->right_buttons_g.width = lbl;
@@ -137,7 +137,7 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/borders.c new/fvwm/borders.c
ret_td->right_buttons_g.y = ret_td->bar_g.y;
ret_td->left_buttons_g.x = ret_td->layout.title_g.x +
ret_td->layout.title_g.width;
-@@ -4234,7 +4271,7 @@
+@@ -4635,7 +4672,7 @@
{
ret_td->left_buttons_g.height = lbl;
ret_td->right_buttons_g.height = rbl;
@@ -146,7 +146,7 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/borders.c new/fvwm/borders.c
ret_td->left_buttons_g.x = ret_td->bar_g.x;
ret_td->right_buttons_g.y = ret_td->layout.title_g.y +
ret_td->layout.title_g.height;
-@@ -4244,7 +4281,7 @@
+@@ -4645,7 +4682,7 @@
{
ret_td->left_buttons_g.width = lbl;
ret_td->right_buttons_g.width = rbl;
@@ -155,16 +155,16 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/borders.c new/fvwm/borders.c
ret_td->left_buttons_g.y = ret_td->bar_g.y;
ret_td->right_buttons_g.x = ret_td->layout.title_g.x +
ret_td->layout.title_g.width;
-@@ -4586,7 +4623,7 @@
- {
+@@ -4988,7 +5025,7 @@
int bw;
+ Bool title;
- bw = fw->boundary_width;
+ bw = HAS_FLUXBOX_HANDLES(fw) ? 1 : fw->boundary_width;
/* ret_g->x and ret->y is just an offset relatively to the w,
* maybe we can take the relief in account? */
switch (part)
-@@ -4604,6 +4641,10 @@
+@@ -5006,6 +5043,10 @@
case PART_BORDER_S:
ret_g->x = sidebar_g->x;
ret_g->y = 2 * sidebar_g->y + sidebar_g->height - bw;
@@ -175,7 +175,7 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/borders.c new/fvwm/borders.c
*ret_w = FW_W_SIDE(fw, 2);
break;
case PART_BORDER_W:
-@@ -4638,9 +4679,14 @@
+@@ -5040,9 +5081,14 @@
switch (part)
{
case PART_BORDER_N:
@@ -190,10 +190,10 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/borders.c new/fvwm/borders.c
break;
case PART_BORDER_E:
case PART_BORDER_W:
-Only in new/fvwm: borders.c.orig
-diff --unified --recursive --text fvwm-2.6.9/fvwm/frame.c new/fvwm/frame.c
+Only in fvwm-patched/fvwm: borders.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/frame.c fvwm-patched/fvwm/frame.c
--- fvwm-2.6.9/fvwm/frame.c 2018-05-26 05:35:26.000000000 -0600
-+++ new/fvwm/frame.c 2020-02-02 16:19:32.245060960 -0700
++++ fvwm-patched/fvwm/frame.c 2020-08-21 16:08:05.606920933 -0600
@@ -438,6 +438,8 @@
BroadcastConfig(M_CONFIGURE_WINDOW,fw);
}
@@ -422,10 +422,10 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/frame.c new/fvwm/frame.c
/****************************************************************************
*
* Sets up the shaped window borders
-Only in new/fvwm: frame.c.orig
-diff --unified --recursive --text fvwm-2.6.9/fvwm/frame.h new/fvwm/frame.h
+Only in fvwm-patched/fvwm: frame.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/frame.h fvwm-patched/fvwm/frame.h
--- fvwm-2.6.9/fvwm/frame.h 2016-10-15 08:51:45.000000000 -0600
-+++ new/fvwm/frame.h 2020-02-02 16:19:32.245060960 -0700
++++ fvwm-patched/fvwm/frame.h 2020-08-21 16:08:05.606920933 -0600
@@ -5,6 +5,8 @@
/* ---------------------------- included header files ---------------------- */
@@ -443,13 +443,13 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/frame.h new/fvwm/frame.h
+void draw_rounded_mask(Window win, int width, int height, Bool slightlyrounded, window_parts draw_parts, int col);
#endif /* FRAME_H */
-diff --unified --recursive --text fvwm-2.6.9/fvwm/fvwm.h new/fvwm/fvwm.h
---- fvwm-2.6.9/fvwm/fvwm.h 2019-08-24 16:50:07.000000000 -0600
-+++ new/fvwm/fvwm.h 2020-02-02 16:19:32.245060960 -0700
-@@ -267,6 +267,10 @@
- #define WINDOWSHADE_LAZY_MASK 0x3
+diff --unified --recursive --text fvwm-2.6.9/fvwm/fvwm.h fvwm-patched/fvwm/fvwm.h
+--- fvwm-2.6.9/fvwm/fvwm.h 2020-08-21 16:07:19.993929916 -0600
++++ fvwm-patched/fvwm/fvwm.h 2020-08-21 16:08:05.606920933 -0600
+@@ -270,6 +270,10 @@
unsigned windowshade_laziness : 2;
unsigned use_title_decor_rotation : 1;
+ unsigned has_border_under_title : 1;
+ unsigned has_fluxbox_handles : 1;
+ unsigned has_rounded_corners_top : 1;
+ unsigned has_rounded_corners_bottom : 1;
@@ -457,7 +457,7 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/fvwm.h new/fvwm/fvwm.h
focus_policy_t focus_policy;
} s;
} common_flags_t;
-@@ -548,6 +552,7 @@
+@@ -553,6 +557,7 @@
unsigned has_edge_resistance_move : 1;
unsigned has_edge_resistance_xinerama_move : 1;
unsigned has_handle_width : 1;
@@ -465,7 +465,7 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/fvwm.h new/fvwm/fvwm.h
unsigned has_icon : 1;
unsigned has_icon_boxes : 1;
unsigned has_icon_size_limits : 1;
-@@ -675,6 +680,7 @@
+@@ -713,6 +718,7 @@
short border_width;
/* resize handle width */
short handle_width;
@@ -473,36 +473,34 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/fvwm.h new/fvwm/fvwm.h
int layer;
int start_desk;
int start_page_x;
-Only in new/fvwm: fvwm.h.orig
-diff --unified --recursive --text fvwm-2.6.9/fvwm/geometry.c new/fvwm/geometry.c
---- fvwm-2.6.9/fvwm/geometry.c 2018-04-28 05:46:28.000000000 -0600
-+++ new/fvwm/geometry.c 2020-02-02 16:19:32.245060960 -0700
-@@ -479,10 +479,21 @@
- void get_window_borders(
- const FvwmWindow *fw, size_borders *borders)
+Only in fvwm-patched/fvwm: fvwm.h.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/geometry.c fvwm-patched/fvwm/geometry.c
+--- fvwm-2.6.9/fvwm/geometry.c 2020-08-21 16:04:22.090148699 -0600
++++ fvwm-patched/fvwm/geometry.c 2020-08-21 16:08:05.606920933 -0600
+@@ -489,16 +489,18 @@
+ const FvwmWindow *fw, size_borders *borders, Bool is_shaded)
{
+ int title_thickness;
++ int bw;
+
- borders->top_left.width = fw->boundary_width;
- borders->bottom_right.width = fw->boundary_width;
- borders->top_left.height = fw->boundary_width;
-+ int title_thickness;
-+ int bw;
-+
+ bw = HAS_FLUXBOX_HANDLES(fw) ? 1 : fw->boundary_width;
+ borders->top_left.width = bw;
+ borders->bottom_right.width = bw;
+ borders->top_left.height = bw;
borders->bottom_right.height = fw->boundary_width;
-+
-+ title_thickness = fw->title_thickness;
-+ if (HAS_TITLE(fw))
-+ {
+
+ title_thickness = fw->title_thickness;
+ if (HAS_TITLE(fw) && HAS_BORDER_UNDER_TITLE(fw) && !is_shaded)
+ {
+- title_thickness += fw->boundary_width;
+ title_thickness += bw;
-+ }
-+
+ }
+
switch (GET_TITLE_DIR(fw))
- {
- case DIR_N:
-@@ -510,9 +521,13 @@
+@@ -528,9 +530,13 @@
void get_window_borders_no_title(
const FvwmWindow *fw, size_borders *borders)
{
@@ -519,10 +517,10 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/geometry.c new/fvwm/geometry.c
borders->bottom_right.height = fw->boundary_width;
borders->total_size.width =
borders->top_left.width + borders->bottom_right.width;
-Only in new/fvwm: geometry.c.orig
-diff --unified --recursive --text fvwm-2.6.9/fvwm/menus.c new/fvwm/menus.c
---- fvwm-2.6.9/fvwm/menus.c 2018-05-26 05:35:26.000000000 -0600
-+++ new/fvwm/menus.c 2020-02-02 16:19:32.248394323 -0700
+Only in fvwm-patched/fvwm: geometry.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/menus.c fvwm-patched/fvwm/menus.c
+--- fvwm-2.6.9/fvwm/menus.c 2020-08-21 15:53:07.026125528 -0600
++++ fvwm-patched/fvwm/menus.c 2020-08-21 16:08:05.606920933 -0600
@@ -60,6 +60,7 @@
#include "menugeometry.h"
#include "menuparameters.h"
@@ -531,7 +529,7 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/menus.c new/fvwm/menus.c
#include "libs/FGettext.h"
/* ---------------------------- local definitions -------------------------- */
-@@ -3130,6 +3131,13 @@
+@@ -3190,6 +3191,13 @@
return x_overlap;
}
@@ -545,47 +543,57 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/menus.c new/fvwm/menus.c
/*
*
* Procedure:
-@@ -3706,6 +3714,8 @@
+@@ -3763,6 +3771,8 @@
* Pop up the menu
*/
+ menu_make_rounded_corners(mr);
+
XMoveWindow(dpy, MR_WINDOW(mr), x, y);
- XSelectInput(dpy, MR_WINDOW(mr), event_mask);
- XMapRaised(dpy, MR_WINDOW(mr));
-Only in new/fvwm: menus.c.orig
-diff --unified --recursive --text fvwm-2.6.9/fvwm/menustyle.c new/fvwm/menustyle.c
---- fvwm-2.6.9/fvwm/menustyle.c 2018-05-26 05:35:26.000000000 -0600
-+++ new/fvwm/menustyle.c 2020-02-02 16:19:32.248394323 -0700
+ MR_X(mr) = x;
+ MR_Y(mr) = y;
+Only in fvwm-patched/fvwm: menus.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/menustyle.c fvwm-patched/fvwm/menustyle.c
+--- fvwm-2.6.9/fvwm/menustyle.c 2020-08-21 15:53:07.026125528 -0600
++++ fvwm-patched/fvwm/menustyle.c 2020-08-21 16:08:05.606920933 -0600
@@ -431,6 +431,7 @@
"TitleColorset", "HilightTitleBack",
"TitleFont",
- "VerticalMargins",
+ "VerticalMargins", "FlatSeparators",
+ "RoundedCorners", "SlightlyRoundedCorners",
"UniqueHotkeyActivatesImmediate",
NULL
};
-@@ -1605,6 +1606,12 @@
- case 63: /* UniqueHotKeyActivatesImmediate */
- ST_HOTKEY_ACTIVATES_IMMEDIATE(tmpms) = on;
+@@ -1603,12 +1604,18 @@
+ &ST_VERTICAL_MARGIN_BOTTOM(tmpms),
+ 0, 0);
+ break;
+- case 63: /* UniqueHotKeyActivatesImmediate */
+- ST_HOTKEY_ACTIVATES_IMMEDIATE(tmpms) = on;
+- break;
+ case 63: /* FlatSeparators */
+ ST_DO_FLAT_SEPARATOR(tmpms) = on;
break;
-+ case 64: /* RoundedCorners */
-+ ST_HAS_ROUNDED_CORNERS(tmpms) = on;
-+ break;
-+ case 65: /* SlightlyRoundedCorners */
-+ ST_HAS_SLIGHTLY_ROUNDED_CORNERS(tmpms) = on;
-+ break;
++ case 64: /* UniqueHotKeyActivatesImmediate */
++ ST_HOTKEY_ACTIVATES_IMMEDIATE(tmpms) = on;
++ break;
++ case 65: /* RoundedCorners */
++ ST_HAS_ROUNDED_CORNERS(tmpms) = on;
++ break;
++ case 66: /* SlightlyRoundedCorners */
++ ST_HAS_SLIGHTLY_ROUNDED_CORNERS(tmpms) = on;
++ break;
#if 0
case 99: /* PositionHints */
-diff --unified --recursive --text fvwm-2.6.9/fvwm/menustyle.h new/fvwm/menustyle.h
---- fvwm-2.6.9/fvwm/menustyle.h 2016-10-15 08:51:45.000000000 -0600
-+++ new/fvwm/menustyle.h 2020-02-02 16:19:32.248394323 -0700
-@@ -23,6 +23,10 @@
- #define MST_FACE(m) ((m)->s->ms->look.face)
- #define ST_DO_HILIGHT_BACK(s) ((s)->look.flags.do_hilight_back)
+Only in fvwm-patched/fvwm: menustyle.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/menustyle.h fvwm-patched/fvwm/menustyle.h
+--- fvwm-2.6.9/fvwm/menustyle.h 2020-08-21 15:53:07.026125528 -0600
++++ fvwm-patched/fvwm/menustyle.h 2020-08-21 16:08:05.606920933 -0600
+@@ -25,6 +25,10 @@
#define MST_DO_HILIGHT_BACK(m) ((m)->s->ms->look.flags.do_hilight_back)
+ #define ST_DO_FLAT_SEPARATOR(s) ((s)->look.flags.do_flat_separator)
+ #define MST_DO_FLAT_SEPARATOR(m) ((m)->s->ms->look.flags.do_flat_separator)
+#define ST_HAS_ROUNDED_CORNERS(s) ((s)->look.flags.has_rounded_corners)
+#define MST_HAS_ROUNDED_CORNERS(m) ((m)->s->ms->look.flags.has_rounded_corners)
+#define ST_HAS_SLIGHTLY_ROUNDED_CORNERS(s) ((s)->look.flags.has_slightly_rounded_corners)
@@ -593,19 +601,19 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/menustyle.h new/fvwm/menustyle
#define ST_DO_HILIGHT_FORE(s) ((s)->look.flags.do_hilight_fore)
#define MST_DO_HILIGHT_FORE(m) ((m)->s->ms->look.flags.do_hilight_fore)
#define ST_DO_HILIGHT_TITLE_BACK(s) ((s)->look.flags.do_hilight_title_back)
-@@ -282,6 +286,8 @@
- unsigned has_title_cset : 1;
+@@ -285,6 +289,8 @@
unsigned do_hilight_title_back : 1;
unsigned using_default_titlefont : 1;
-+ unsigned has_rounded_corners : 1;
-+ unsigned has_slightly_rounded_corners : 1;
+ unsigned do_flat_separator : 1;
++ unsigned has_rounded_corners : 1;
++ unsigned has_slightly_rounded_corners : 1;
} flags;
unsigned char ReliefThickness;
unsigned char TitleUnderlines;
-diff --unified --recursive --text fvwm-2.6.9/fvwm/style.c new/fvwm/style.c
---- fvwm-2.6.9/fvwm/style.c 2018-05-26 05:35:26.000000000 -0600
-+++ new/fvwm/style.c 2020-02-02 16:19:32.248394323 -0700
-@@ -537,6 +537,10 @@
+diff --unified --recursive --text fvwm-2.6.9/fvwm/style.c fvwm-patched/fvwm/style.c
+--- fvwm-2.6.9/fvwm/style.c 2020-08-21 16:07:19.993929916 -0600
++++ fvwm-patched/fvwm/style.c 2020-08-21 16:08:05.606920933 -0600
+@@ -553,6 +553,10 @@
SSET_HANDLE_WIDTH(
*merged_style, SGET_HANDLE_WIDTH(*add_style));
}
@@ -616,7 +624,7 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/style.c new/fvwm/style.c
if (add_style->flags.has_icon_size_limits)
{
SSET_MIN_ICON_WIDTH(
-@@ -2370,6 +2374,20 @@
+@@ -2590,6 +2594,20 @@
ps->change_mask.has_color_back = 1;
break;
}
@@ -637,7 +645,7 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/style.c new/fvwm/style.c
else if (StrEquals(token, "CirculateSkipIcon"))
{
S_SET_DO_CIRCULATE_SKIP_ICON(SCF(*ps), on);
-@@ -2682,6 +2700,15 @@
+@@ -2902,6 +2920,15 @@
S_SET_HAS_MWM_BORDER(SCM(*ps), 1);
S_SET_HAS_MWM_BORDER(SCC(*ps), 1);
}
@@ -653,7 +661,7 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/style.c new/fvwm/style.c
else if (StrEquals(token, "FocusFollowsMouse"))
{
style_set_old_focus_policy(ps, 1);
-@@ -3752,6 +3779,50 @@
+@@ -4097,6 +4124,50 @@
S_SET_IS_RIGHT_TITLE_ROTATED_CW(SCM(*ps), 1);
S_SET_IS_RIGHT_TITLE_ROTATED_CW(SCC(*ps), 1);
}
@@ -704,7 +712,7 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/style.c new/fvwm/style.c
else
{
found = False;
-@@ -3886,6 +3957,12 @@
+@@ -4231,6 +4302,12 @@
S_SET_HAS_NO_STICKY_STIPPLED_ICON_TITLE(SCM(*ps), 1);
S_SET_HAS_NO_STICKY_STIPPLED_ICON_TITLE(SCC(*ps), 1);
}
@@ -717,28 +725,28 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/style.c new/fvwm/style.c
else if (StrEquals(token, "Slippery"))
{
S_SET_IS_STICKY_ACROSS_PAGES(SCF(*ps), !on);
-@@ -4875,6 +4952,20 @@
+@@ -5219,6 +5296,20 @@
+ {
flags->do_update_rotated_title = 1;
}
-
-+ /* has_fluxbox_handles */
-+ if (S_HAS_FLUXBOX_HANDLES(SCC(*ret_style)))
-+ {
-+ flags->do_redecorate = True;
-+ }
+
-+ /* has_rounded_corners */
-+ if (S_HAS_ROUNDED_CORNERS_TOP(SCC(*ret_style))
-+ || S_HAS_ROUNDED_CORNERS_BOTTOM(SCC(*ret_style))
-+ || S_HAS_SLIGHTLY_ROUNDED_CORNERS(SCC(*ret_style)))
-+ {
-+ flags->do_redecorate = True;
-+ }
++ /* has_fluxbox_handles */
++ if (S_HAS_FLUXBOX_HANDLES(SCC(*ret_style)))
++ {
++ flags->do_redecorate = True;
++ }
+
- /* has_mwm_border
- * has_mwm_buttons */
- if (S_HAS_MWM_BORDER(SCC(*ret_style)) ||
-@@ -5127,6 +5218,12 @@
++ /* has_rounded_corners */
++ if (S_HAS_ROUNDED_CORNERS_TOP(SCC(*ret_style))
++ || S_HAS_ROUNDED_CORNERS_BOTTOM(SCC(*ret_style))
++ || S_HAS_SLIGHTLY_ROUNDED_CORNERS(SCC(*ret_style)))
++ {
++ flags->do_redecorate = True;
++ }
+
+ if (S_HAS_BORDER_UNDER_TITLE(SCC(*ret_style)))
+ {
+@@ -5483,6 +5574,12 @@
flags->do_update_modules_flags = 1;
}
@@ -751,10 +759,10 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/style.c new/fvwm/style.c
if (ret_style->change_mask.do_save_under ||
ret_style->change_mask.use_backing_store ||
ret_style->change_mask.use_parent_relative)
-Only in new/fvwm: style.c.orig
-diff --unified --recursive --text fvwm-2.6.9/fvwm/style.h new/fvwm/style.h
---- fvwm-2.6.9/fvwm/style.h 2018-05-26 05:35:26.000000000 -0600
-+++ new/fvwm/style.h 2020-02-02 16:19:32.248394323 -0700
+Only in fvwm-patched/fvwm: style.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/style.h fvwm-patched/fvwm/style.h
+--- fvwm-2.6.9/fvwm/style.h 2020-08-21 16:07:19.993929916 -0600
++++ fvwm-patched/fvwm/style.h 2020-08-21 16:08:05.606920933 -0600
@@ -21,6 +21,8 @@
((sf)->has_color_fore)
#define SHAS_HANDLE_WIDTH(sf) \
@@ -764,30 +772,30 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/style.h new/fvwm/style.h
#define SHAS_ICON(sf) \
((sf)->has_icon)
#define SHAS_ICON_BOXES(sf) \
-@@ -333,6 +335,22 @@
- ((c).s.use_title_decor_rotation)
- #define S_SET_USE_TITLE_DECOR_ROTATION(c,x) \
- ((c).s.use_title_decor_rotation = !!(x))
+@@ -377,6 +379,22 @@
+ ((c).s.has_border_under_title)
+ #define S_SET_HAS_BORDER_UNDER_TITLE(c,x) \
+ ((c).s.has_border_under_title = !!(x))
+#define S_HAS_FLUXBOX_HANDLES(c) \
-+ ((c).s.has_fluxbox_handles)
++ ((c).s.has_fluxbox_handles)
+#define S_SET_HAS_FLUXBOX_HANDLES(c,x) \
-+ ((c).s.has_fluxbox_handles = !!(x))
++ ((c).s.has_fluxbox_handles = !!(x))
+#define S_HAS_ROUNDED_CORNERS_TOP(c) \
-+ ((c).s.has_rounded_corners_top)
++ ((c).s.has_rounded_corners_top)
+#define S_SET_HAS_ROUNDED_CORNERS_TOP(c,x) \
-+ ((c).s.has_rounded_corners_top = !!(x))
++ ((c).s.has_rounded_corners_top = !!(x))
+#define S_HAS_ROUNDED_CORNERS_BOTTOM(c) \
-+ ((c).s.has_rounded_corners_bottom)
++ ((c).s.has_rounded_corners_bottom)
+#define S_SET_HAS_ROUNDED_CORNERS_BOTTOM(c,x) \
-+ ((c).s.has_rounded_corners_bottom = !!(x))
++ ((c).s.has_rounded_corners_bottom = !!(x))
+#define S_HAS_SLIGHTLY_ROUNDED_CORNERS(c) \
-+ ((c).s.has_slightly_rounded_corners)
++ ((c).s.has_slightly_rounded_corners)
+#define S_SET_HAS_SLIGHTLY_ROUNDED_CORNERS(c,x) \
-+ ((c).s.has_slightly_rounded_corners = !!(x))
++ ((c).s.has_slightly_rounded_corners = !!(x))
#define S_DO_EWMH_MINI_ICON_OVERRIDE(c) \
((c).s.do_ewmh_mini_icon_override)
#define S_SET_DO_EWMH_MINI_ICON_OVERRIDE(c,x) \
-@@ -485,6 +503,10 @@
+@@ -597,6 +615,10 @@
((s).handle_width)
#define SSET_HANDLE_WIDTH(s,x) \
((s).handle_width = (x))
@@ -798,11 +806,11 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/style.h new/fvwm/style.h
#define SGET_LAYER(s) \
((s).layer)
#define SSET_LAYER(s,x) \
-Only in new/fvwm: style.h.orig
-diff --unified --recursive --text fvwm-2.6.9/fvwm/window_flags.h new/fvwm/window_flags.h
---- fvwm-2.6.9/fvwm/window_flags.h 2016-10-15 08:51:45.000000000 -0600
-+++ new/fvwm/window_flags.h 2020-02-02 16:19:32.248394323 -0700
-@@ -314,18 +314,42 @@
+Only in fvwm-patched/fvwm: style.h.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/window_flags.h fvwm-patched/fvwm/window_flags.h
+--- fvwm-2.6.9/fvwm/window_flags.h 2020-08-21 16:07:19.993929916 -0600
++++ fvwm-patched/fvwm/window_flags.h 2020-08-21 16:08:05.610921020 -0600
+@@ -316,12 +316,12 @@
(fw)->flags.common.s.is_bottom_title_rotated = !!(x)
#define SETM_IS_BOTTOM_TITLE_ROTATED(fw,x) \
(fw)->flag_mask.common.s.is_bottom_title_rotated = !!(x)
@@ -821,40 +829,40 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/window_flags.h new/fvwm/window
#define USE_TITLE_DECOR_ROTATION(fw) \
((fw)->flags.common.s.use_title_decor_rotation)
#define SET_USE_TITLE_DECOR_ROTATION(fw,x) \
- (fw)->flags.common.s.use_title_decor_rotation = !!(x)
- #define SETM_USE_TITLE_DECOR_ROTATION(fw,x) \
- (fw)->flag_mask.common.s.use_title_decor_rotation = !!(x)
+@@ -334,6 +334,30 @@
+ (fw)->flags.common.s.has_border_under_title = !!(x)
+ #define SETM_HAS_BORDER_UNDER_TITLE(fw,x) \
+ (fw)->flag_mask.common.s.has_border_under_title = !!(x)
+#define HAS_FLUXBOX_HANDLES(fw) \
-+ ((fw)->flags.common.s.has_fluxbox_handles && (fw->flags.has_handles))
++ ((fw)->flags.common.s.has_fluxbox_handles && (fw->flags.has_handles))
+#define SET_HAS_FLUXBOX_HANDLES(fw,x) \
-+ (fw)->flags.common.s.has_fluxbox_handles = !!(x)
++ (fw)->flags.common.s.has_fluxbox_handles = !!(x)
+#define SETM_HAS_FLUXBOX_HANDLES(fw,x) \
-+ (fw)->flag_mask.common.s.has_fluxbox_handles = !!(x)
++ (fw)->flag_mask.common.s.has_fluxbox_handles = !!(x)
+#define HAS_ROUNDED_CORNERS_TOP(fw) \
-+ ((fw)->flags.common.s.has_rounded_corners_top)
++ ((fw)->flags.common.s.has_rounded_corners_top)
+#define SET_HAS_ROUNDED_CORNERS_TOP(fw,x) \
-+ (fw)->flags.common.s.has_rounded_corners_top = !!(x)
++ (fw)->flags.common.s.has_rounded_corners_top = !!(x)
+#define SETM_HAS_ROUNDED_CORNERS_TOP(fw,x) \
-+ (fw)->flag_mask.common.s.has_rounded_corners_top = !!(x)
++ (fw)->flag_mask.common.s.has_rounded_corners_top = !!(x)
+#define HAS_ROUNDED_CORNERS_BOTTOM(fw) \
-+ ((fw)->flags.common.s.has_rounded_corners_bottom)
++ ((fw)->flags.common.s.has_rounded_corners_bottom)
+#define SET_HAS_ROUNDED_CORNERS_BOTTOM(fw,x) \
-+ (fw)->flags.common.s.has_rounded_corners_bottom = !!(x)
++ (fw)->flags.common.s.has_rounded_corners_bottom = !!(x)
+#define SETM_HAS_ROUNDED_CORNERS_BOTTOM(fw,x) \
-+ (fw)->flag_mask.common.s.has_rounded_corners_bottom = !!(x)
++ (fw)->flag_mask.common.s.has_rounded_corners_bottom = !!(x)
+#define HAS_SLIGHTLY_ROUNDED_CORNERS(fw) \
-+ ((fw)->flags.common.s.has_slightly_rounded_corners)
++ ((fw)->flags.common.s.has_slightly_rounded_corners)
+#define SET_HAS_SLIGHTLY_ROUNDED_CORNERS_BOTTOM(fw,x) \
-+ (fw)->flags.common.s.has_slightly_rounded_corners = !!(x)
++ (fw)->flags.common.s.has_slightly_rounded_corners = !!(x)
+#define SETM_HAS_SLIGHTLY_ROUNDED_CORNERS(fw,x) \
-+ (fw)->flag_mask.common.s.has_slightly_rounded_corners = !!(x)
++ (fw)->flag_mask.common.s.has_slightly_rounded_corners = !!(x)
/* access to the special flags of a window */
#define DO_REUSE_DESTROYED(fw) \
-Only in new/fvwm: window_flags.h.orig
-diff --unified --recursive --text fvwm-2.6.9/fvwm/windowshade.c new/fvwm/windowshade.c
+diff --unified --recursive --text fvwm-2.6.9/fvwm/windowshade.c fvwm-patched/fvwm/windowshade.c
--- fvwm-2.6.9/fvwm/windowshade.c 2018-05-26 05:35:26.000000000 -0600
-+++ new/fvwm/windowshade.c 2020-02-02 16:19:32.248394323 -0700
++++ fvwm-patched/fvwm/windowshade.c 2020-08-21 16:08:05.610921020 -0600
@@ -211,6 +211,7 @@
border_draw_decorations(
fw, PART_TITLEBAR, (fw == get_focus_window()) ? True : False,
@@ -863,4 +871,4 @@ diff --unified --recursive --text fvwm-2.6.9/fvwm/windowshade.c new/fvwm/windows
/* update hints and inform modules */
BroadcastConfig(M_CONFIGURE_WINDOW, fw);
BroadcastPacket(
-Only in new/fvwm: windowshade.c.orig
+Only in fvwm-patched/fvwm: windowshade.c.orig
diff --git a/09-TopBorder.patch b/09-TopBorder.patch
new file mode 100644
index 000000000000..3edb8ffb21ca
--- /dev/null
+++ b/09-TopBorder.patch
@@ -0,0 +1,200 @@
+diff --unified --recursive --text fvwm-2.6.9/fvwm/builtins.c fvwm-patched/fvwm/builtins.c
+--- fvwm-2.6.9/fvwm/builtins.c 2018-05-27 09:47:03.000000000 -0600
++++ fvwm-patched/fvwm/builtins.c 2020-08-21 16:10:56.462693301 -0600
+@@ -482,6 +482,21 @@
+ if (action)
+ action += next;
+ }
++ else if (!do_add && StrEquals(parm,"buttonwidth"))
++ {
++ int width = 0;
++ int next = 0;
++
++ sscanf(action, "%d%n", &width, &next);
++
++ if (decor->button_width != width)
++ {
++ decor->button_width = width;
++ decor->flags.has_changed = 1;
++ }
++ if (action)
++ action += next;
++ }
+ else if (!do_add && StrEquals(parm,"MinHeight"))
+ {
+ int height = 0;
+Only in fvwm-patched/fvwm: builtins.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/frame.c fvwm-patched/fvwm/frame.c
+--- fvwm-2.6.9/fvwm/frame.c 2020-08-21 16:09:27.172710920 -0600
++++ fvwm-patched/fvwm/frame.c 2020-08-21 16:10:56.466693390 -0600
+@@ -1372,7 +1372,14 @@
+ tb_thick = fw->title_thickness;
+ nbuttons = fw->nr_left_buttons + fw->nr_right_buttons;
+ nbuttons_big = 0;
+- b_length = tb_thick;
++ if (fw->decor->button_width == 0)
++ {
++ b_length = tb_thick;
++ }
++ else
++ {
++ b_length = fw->decor->button_width;
++ }
+ t_length = tb_length - nbuttons * b_length;
+ if (nbuttons > 0 && t_length < MIN_WINDOW_TITLE_LENGTH)
+ {
+Only in fvwm-patched/fvwm: frame.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/fvwm.h fvwm-patched/fvwm/fvwm.h
+--- fvwm-2.6.9/fvwm/fvwm.h 2020-08-21 16:09:27.172710920 -0600
++++ fvwm-patched/fvwm/fvwm.h 2020-08-21 16:10:56.466693390 -0600
+@@ -274,6 +274,7 @@
+ unsigned has_rounded_corners_top : 1;
+ unsigned has_rounded_corners_bottom : 1;
+ unsigned has_slightly_rounded_corners : 1;
++ unsigned has_no_top_border : 1;
+ focus_policy_t focus_policy;
+ } s;
+ } common_flags_t;
+Only in fvwm-patched/fvwm: fvwm.h.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/geometry.c fvwm-patched/fvwm/geometry.c
+--- fvwm-2.6.9/fvwm/geometry.c 2020-08-21 16:09:27.176711008 -0600
++++ fvwm-patched/fvwm/geometry.c 2020-08-21 16:10:56.466693390 -0600
+@@ -489,6 +489,7 @@
+ const FvwmWindow *fw, size_borders *borders, Bool is_shaded)
+ {
+ int title_thickness;
++ int *title_border = NULL;
+ int bw;
+
+ bw = HAS_FLUXBOX_HANDLES(fw) ? 1 : fw->boundary_width;
+@@ -506,18 +507,25 @@
+ switch (GET_TITLE_DIR(fw))
+ {
+ case DIR_N:
+- borders->top_left.height += title_thickness;
++ title_border = &borders->top_left.height;
+ break;
+ case DIR_S:
+- borders->bottom_right.height += title_thickness;
++ title_border = &borders->bottom_right.height;
+ break;
+ case DIR_W:
+- borders->top_left.width += title_thickness;
++ title_border = &borders->top_left.width;
+ break;
+ case DIR_E:
+- borders->bottom_right.width += title_thickness;
++ title_border = &borders->bottom_right.width;
+ break;
+ }
++
++ if (HAS_NO_TOP_BORDER(fw))
++ {
++ *title_border = 1;
++ }
++ *title_border += title_thickness;
++
+ borders->total_size.width =
+ borders->top_left.width + borders->bottom_right.width;
+ borders->total_size.height =
+@@ -538,6 +546,26 @@
+ borders->bottom_right.width = bw;
+ borders->top_left.height = bw;
+ borders->bottom_right.height = fw->boundary_width;
++
++ if (HAS_NO_TOP_BORDER(fw))
++ {
++ switch (GET_TITLE_DIR(fw))
++ {
++ case DIR_N:
++ borders->top_left.height = 1;
++ break;
++ case DIR_S:
++ borders->bottom_right.height = 1;
++ break;
++ case DIR_W:
++ borders->top_left.width = 1;
++ break;
++ case DIR_E:
++ borders->bottom_right.width = 1;
++ break;
++ }
++ }
++
+ borders->total_size.width =
+ borders->top_left.width + borders->bottom_right.width;
+ borders->total_size.height =
+Only in fvwm-patched/fvwm: geometry.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/screen.h fvwm-patched/fvwm/screen.h
+--- fvwm-2.6.9/fvwm/screen.h 2020-08-21 15:30:39.091737766 -0600
++++ fvwm-patched/fvwm/screen.h 2020-08-21 16:10:56.466693390 -0600
+@@ -284,6 +284,7 @@
+ char *tag; /* general style tag */
+ int title_height; /* explicitly specified title bar height */
+ int min_title_height;
++ int button_width;
+ /* titlebar buttons */
+ TitleButton buttons[NUMBER_OF_TITLE_BUTTONS];
+ TitleButton titlebar;
+Only in fvwm-patched/fvwm: screen.h.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/style.c fvwm-patched/fvwm/style.c
+--- fvwm-2.6.9/fvwm/style.c 2020-08-21 16:09:27.176711008 -0600
++++ fvwm-patched/fvwm/style.c 2020-08-21 16:10:56.466693390 -0600
+@@ -4714,6 +4714,12 @@
+ ps->change_mask.has_title_format_string = 1;
+
+ }
++ else if (StrEquals(token, "TopBorder"))
++ {
++ S_SET_HAS_NO_TOP_BORDER(SCF(*ps), !on);
++ S_SET_HAS_NO_TOP_BORDER(SCM(*ps), 1);
++ S_SET_HAS_NO_TOP_BORDER(SCC(*ps), 1);
++ }
+ else if (StrEquals(token, "TopTitleRotated"))
+ {
+ S_SET_IS_TOP_TITLE_ROTATED(SCF(*ps), on);
+@@ -5315,6 +5321,11 @@
+ {
+ flags->do_redecorate = True;
+ }
++
++ if (S_HAS_NO_TOP_BORDER(SCC(*ret_style)))
++ {
++ flags->do_redecorate = True;
++ }
+
+ /* has_mwm_border
+ * has_mwm_buttons */
+Only in fvwm-patched/fvwm: style.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/style.h fvwm-patched/fvwm/style.h
+--- fvwm-2.6.9/fvwm/style.h 2020-08-21 16:09:27.176711008 -0600
++++ fvwm-patched/fvwm/style.h 2020-08-21 16:10:56.466693390 -0600
+@@ -395,6 +395,11 @@
+ ((c).s.has_slightly_rounded_corners)
+ #define S_SET_HAS_SLIGHTLY_ROUNDED_CORNERS(c,x) \
+ ((c).s.has_slightly_rounded_corners = !!(x))
++#define S_HAS_NO_TOP_BORDER(c) \
++ ((c).s.has_no_top_border)
++#define S_SET_HAS_NO_TOP_BORDER(c,x) \
++ ((c).s.has_no_top_border = !!(x))
++
+ #define S_DO_EWMH_MINI_ICON_OVERRIDE(c) \
+ ((c).s.do_ewmh_mini_icon_override)
+ #define S_SET_DO_EWMH_MINI_ICON_OVERRIDE(c,x) \
+Only in fvwm-patched/fvwm: style.h.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/window_flags.h fvwm-patched/fvwm/window_flags.h
+--- fvwm-2.6.9/fvwm/window_flags.h 2020-08-21 16:09:27.176711008 -0600
++++ fvwm-patched/fvwm/window_flags.h 2020-08-21 16:10:56.466693390 -0600
+@@ -358,6 +358,12 @@
+ (fw)->flags.common.s.has_slightly_rounded_corners = !!(x)
+ #define SETM_HAS_SLIGHTLY_ROUNDED_CORNERS(fw,x) \
+ (fw)->flag_mask.common.s.has_slightly_rounded_corners = !!(x)
++#define HAS_NO_TOP_BORDER(fw) \
++ ((fw)->flags.common.s.has_no_top_border)
++#define SET_HAS_NO_TOP_BORDER(fw,x) \
++ (fw)->flags.common.s.has_no_top_border = !!(x)
++#define SETM_HAS_NO_TOP_BORDER(fw,x) \
++ (fw)->flag_mask.common.s.has_no_top_border = !!(x)
+
+ /* access to the special flags of a window */
+ #define DO_REUSE_DESTROYED(fw) \
diff --git a/10-ButtonWidth.patch b/10-ButtonWidth.patch
new file mode 100644
index 000000000000..634585dbeb6e
--- /dev/null
+++ b/10-ButtonWidth.patch
@@ -0,0 +1,26 @@
+diff --unified --recursive --text fvwm-2.6.9/fvwm/builtins.c fvwm-patched/fvwm/builtins.c
+--- fvwm-2.6.9/fvwm/builtins.c 2020-08-21 16:11:42.983734347 -0600
++++ fvwm-patched/fvwm/builtins.c 2020-08-21 16:12:21.224593859 -0600
+@@ -497,6 +497,21 @@
+ if (action)
+ action += next;
+ }
++ else if (!do_add && StrEquals(parm,"buttonwidth"))
++ {
++ int width = 0;
++ int next = 0;
++
++ sscanf(action, "%d%n", &width, &next);
++
++ if (decor->button_width != width)
++ {
++ decor->button_width = width;
++ decor->flags.has_changed = 1;
++ }
++ if (action)
++ action += next;
++ }
+ else if (!do_add && StrEquals(parm,"MinHeight"))
+ {
+ int height = 0;
+Only in fvwm-patched/fvwm: builtins.c.orig
diff --git a/11-MultiBorder.patch b/11-MultiBorder.patch
new file mode 100644
index 000000000000..c9c2f8f85e92
--- /dev/null
+++ b/11-MultiBorder.patch
@@ -0,0 +1,546 @@
+diff --unified --recursive --text fvwm-2.6.9/fvwm/borders.c fvwm-patched/fvwm/borders.c
+--- fvwm-2.6.9/fvwm/borders.c 2020-08-21 16:09:27.172710920 -0600
++++ fvwm-patched/fvwm/borders.c 2020-08-21 16:15:29.887392857 -0600
+@@ -1638,6 +1638,7 @@
+ True : False;
+ xgcv.fill_style = FillSolid;
+ valuemask = GCFillStyle;
++
+ if (!bg->flags.use_pixmap)
+ {
+ /* solid pixel */
+@@ -1830,13 +1831,26 @@
+
+ static void border_get_border_background(
+ pixmap_background_type *bg, common_decorations_type *cd,
+- rectangle *part_g, rectangle *relative_g, int *free_bg_pixmap, Window w, window_parts part)
++ rectangle *part_g, rectangle *relative_g, int *free_bg_pixmap, Window w, window_parts part, FvwmPicture *fp)
+ {
+ *free_bg_pixmap = False;
+
+- if (cd->texture_pixmap)
++ if (fp)
+ {
+ bg->flags.use_pixmap = 1;
++ bg->pixmap.p = fp->picture;
++ bg->pixmap.g.width = fp->width;
++ bg->pixmap.g.height = fp->height;
++ bg->pixmap.shape = None;
++ bg->pixmap.alpha = None;
++ bg->pixmap.depth = fp->depth;
++ bg->pixmap.flags.is_tiled = 1;
++ bg->pixmap.flags.is_stretched = 0;
++ bg->pixmap.fra.mask = 0;
++ }
++ else if (cd->texture_pixmap)
++ {
++ bg->flags.use_pixmap = 1;
+ bg->pixmap.p = cd->texture_pixmap;
+ bg->pixmap.g.width = cd->texture_pixmap_width;
+ bg->pixmap.g.height = cd->texture_pixmap_height;
+@@ -1931,6 +1945,18 @@
+ return;
+ }
+
++#define DRAWBORDER(PIX,X,Y,WIDTH,HEIGHT) \
++ { \
++ fp = df->u.mb.pixmaps[PIX]; \
++ border_get_border_background( \
++ &bg, cd, &part_g, &relative_g, &free_bg_pixmap, w, PART_NONE, fp); \
++ r.x = X; \
++ r.y = Y; \
++ r.width = WIDTH; \
++ r.height = HEIGHT; \
++ border_fill_pixmap_background(p, &r, &bg, cd); \
++ }
++
+ static void border_draw_one_border_part(
+ common_decorations_type *cd, FvwmWindow *fw, rectangle *sidebar_g,
+ rectangle *frame_g, border_relief_descr *br, window_parts part,
+@@ -1943,6 +1969,7 @@
+ Pixmap p;
+ Window w;
+ Bool free_bg_pixmap = False;
++ int x, y, width, height;
+
+ /* make a pixmap */
+ border_get_part_geometry(fw, part, sidebar_g, &part_g, &w);
+@@ -1956,8 +1983,28 @@
+ relative_g.height = fw->g.frame.height;
+ relative_g.x = part_g.x;
+ relative_g.y = part_g.y;
+- border_get_border_background(
+- &bg, cd, &part_g, &relative_g, &free_bg_pixmap, w, part);
++
++ DecorFace* df;
++ FvwmPicture* fp = 0;
++ df = border_get_border_style(fw, (Scr.Hilite == fw));
++ if (DFS_FACE_TYPE(df->style) == MultiBorder)
++ {
++ int id = -1;
++ if (part==PART_BORDER_NW) id = 0;
++ if (part==PART_BORDER_N) id = 1;
++ if (part==PART_BORDER_NE) id = 2;
++ if (part==PART_BORDER_E) id = 3;
++ if (part==PART_BORDER_SE) id = 4;
++ if (part==PART_BORDER_S) id = 5;
++ if (part==PART_BORDER_SW) id = 6;
++ if (part==PART_BORDER_W) id = 7;
++
++ if (id>=0 && df->u.mb.pixmaps[id])
++ {
++ fp = df->u.mb.pixmaps[id];
++ }
++ }
++
+ if (cd->texture_pixmap)
+ {
+ switch (part)
+@@ -2000,13 +2047,100 @@
+ bg.pixmap.g.x = 0;
+ bg.pixmap.g.y = 0;
+ }
+- /* set the geometry for drawing the Tiled pixmap; maybe add the relief
+- * as offset? */
+- pix_g.x = 0;
+- pix_g.y = 0;
+- pix_g.width = part_g.width;
+- pix_g.height = part_g.height;
+- border_fill_pixmap_background(p, &pix_g, &bg, cd);
++
++ border_get_border_background(
++ &bg, cd, &part_g, &relative_g, &free_bg_pixmap, w, PART_NONE, fp);
++
++ int px = bg.pixmap.g.x;
++ int py = bg.pixmap.g.y;
++
++ if (fp)
++ {
++ /* Position pixmap so that it's aligned to the edge of the window */
++ if (part & PART_BOTTOM)
++ {
++ bg.pixmap.g.y = fp->height - sidebar_g->y;
++ if (part == PART_BORDER_S)
++ {
++ bg.pixmap.g.y = fp->height - fw->boundary_width;
++ }
++ }
++ if (part & PART_RIGHT)
++ {
++ bg.pixmap.g.x = fp->width - sidebar_g->x;
++ if (part == PART_BORDER_E)
++ {
++ bg.pixmap.g.x = fp->width - fw->boundary_width;
++ }
++ }
++ }
++
++ /* set the geometry for drawing the Tiled pixmap; maybe add the relief
++ * as offset? */
++ pix_g.x = 0;
++ pix_g.y = 0;
++ pix_g.width = part_g.width;
++ pix_g.height = part_g.height;
++
++ border_fill_pixmap_background(p, &pix_g, &bg, cd);
++
++ bg.pixmap.g.x = px;
++ bg.pixmap.g.y = py;
++
++ if (fp)
++ {
++ height = pix_g.height;
++ width = pix_g.width;
++ x = pix_g.x;
++ y = pix_g.y;
++
++ /* draw parts from other borders that overflow because of their width/height */
++ rectangle r;
++ if (part==PART_BORDER_S)
++ {
++ DRAWBORDER(6, pix_g.x - sidebar_g->x, fw->boundary_width - fp->height, fp->width - sidebar_g->x, height);
++ DRAWBORDER(4, pix_g.width - fp->width + sidebar_g->x, fw->boundary_width - fp->height, fp->width - sidebar_g->x, height);
++ }
++ if (!IS_SHADED(fw))
++ {
++ if (part==PART_BORDER_E)
++ {
++ DRAWBORDER(2, fw->boundary_width - fp->width, pix_g.y - sidebar_g->y, width, fp->height - sidebar_g->y);
++ DRAWBORDER(4, fw->boundary_width - fp->width, pix_g.height - fp->height + sidebar_g->y, width, fp->height - sidebar_g->y);
++ }
++ if (part==PART_BORDER_W)
++ {
++ DRAWBORDER(0, x, pix_g.y - sidebar_g->y, width, fp->height - sidebar_g->y);
++ DRAWBORDER(6, x, pix_g.height - fp->height + sidebar_g->y, width, fp->height - sidebar_g->y);
++ }
++ }
++ if (part==PART_BORDER_N)
++ {
++ DRAWBORDER(2, pix_g.width - fp->width + sidebar_g->x, y, fp->width - sidebar_g->x, height);
++ DRAWBORDER(0, pix_g.x - fp->width + sidebar_g->x, y, fp->width - sidebar_g->x, height);
++ }
++ /* Use the top border for the whole height of the titlebar, overflowing to parts of the bottom corners if shaded */
++ if (IS_SHADED(fw))
++ {
++ if (part==PART_BORDER_W)
++ {
++ DRAWBORDER(0, 0, -height, width, height);
++ }
++ if (part==PART_BORDER_SW)
++ {
++ DRAWBORDER(0, 0, -height*2, width, height - fw->boundary_width);
++ }
++ if (part==PART_BORDER_E)
++ {
++ DRAWBORDER(2, fw->boundary_width - fp->width, -height, width, height);
++ }
++ if (part==PART_BORDER_SE)
++ {
++ DRAWBORDER(2, width - fp->width, -height*2, width, height - fw->boundary_width);
++ }
++ }
++ }
++
+ if (HAS_FLUXBOX_HANDLES(fw) && (part & PART_BOTTOM))
+ {
+ pix_g.y = part_g.height - fw->boundary_width;
+@@ -2023,6 +2157,7 @@
+ border_fill_fluxbox_handle(p, &pix_g, cd, !(part & PART_BORDER_S));
+ }
+ }
++
+ if (free_bg_pixmap && bg.pixmap.p)
+ {
+ XFreePixmap(dpy, bg.pixmap.p);
+@@ -2077,7 +2212,7 @@
+ do_clear);
+ }
+ }
+-
++
+ return;
+ }
+
+@@ -3702,7 +3837,7 @@
+ relative_g.x = button_g->x;
+ relative_g.y = button_g->y;
+ border_get_border_background(
+- &bg, td->cd, button_g, &relative_g, &free_bg_pixmap, w, PART_NONE);
++ &bg, td->cd, button_g, &relative_g, &free_bg_pixmap, w, PART_NONE, (FvwmPicture *)NULL);
+ bg.pixmap.g.x = 0;
+ bg.pixmap.g.y = 0;
+ /* set the geometry for drawing the Tiled pixmap;
+@@ -4149,7 +4284,7 @@
+ relative_g.y = td->layout.title_g.y;
+ border_get_border_background(
+ &bg, td->cd, &td->layout.title_g, &relative_g,
+- &free_bg_pixmap, w, PART_NONE);
++ &free_bg_pixmap, w, PART_NONE, (FvwmPicture *)NULL);
+ bg.pixmap.g.x = 0;
+ bg.pixmap.g.y = 0;
+ /* set the geometry for drawing the Tiled pixmap;
+Only in fvwm-patched/fvwm: borders.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/builtins.c fvwm-patched/fvwm/builtins.c
+--- fvwm-2.6.9/fvwm/builtins.c 2020-08-21 16:14:00.246833497 -0600
++++ fvwm-patched/fvwm/builtins.c 2020-08-21 16:15:29.887392857 -0600
+@@ -782,6 +782,50 @@
+ return s;
+ }
+
++static char *ReadMultiBorderDecor(char *s, DecorFace *df)
++{
++ FvwmPictureAttributes fpa;
++ FvwmPicture **pm;
++ char *token;
++ int x;
++ int y;
++
++ pm = df->u.mb.pixmaps;
++ df->style.face_type = MultiBorder;
++
++ for (x = 0; x < 8; x++)
++ {
++ s = DoPeekToken(s, &token, " ", NULL, NULL);
++ if (s == NULL)
++ {
++ break;
++ }
++ if (pm[x])
++ {
++ PDestroyFvwmPicture(dpy, pm[x]);
++ }
++ pm[x] = PCacheFvwmPicture(dpy, Scr.NoFocusWin, NULL,
++ token, fpa);
++
++ if (!pm[x])
++ {
++ fvwm_msg(ERR, "ReadMultiBorderDecor",
++ "Pixmap '%s' could not be loaded",
++ token);
++ for(y = 0; y < x; y++)
++ {
++ if (pm[y])
++ {
++ PDestroyFvwmPicture(dpy, pm[y]);
++ }
++ }
++ return NULL;
++ }
++ }
++
++ return s;
++}
++
+ /*
+ *
+ * DestroyFvwmDecor -- frees all memory assocated with an FvwmDecor
+@@ -1481,6 +1525,14 @@
+ free(df->u.mp.pixels);
+ }
+ break;
++ case MultiBorder:
++ for (i = 0; i < 8; i++)
++ {
++ if (df->u.mb.pixmaps[i])
++ {
++ PDestroyFvwmPicture(dpy, df->u.mb.pixmaps[i]);
++ }
++ }
+ case VectorButton:
+ case DefaultVectorButton:
+ if (df->u.vector.x)
+@@ -1850,6 +1902,15 @@
+ return False;
+ }
+ }
++ else if (strncasecmp(style,"MultiBorder",11)==0)
++ {
++ s = ReadMultiBorderDecor(s, df);
++ if (!s)
++ {
++ return False;
++ }
++ DFS_FACE_TYPE(df->style) = MultiBorder;
++ }
+ else if (FMiniIconsSupported &&
+ strncasecmp (style, "MiniIcon", 8) == 0)
+ {
+Only in fvwm-patched/fvwm: builtins.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/menus.c fvwm-patched/fvwm/menus.c
+--- fvwm-2.6.9/fvwm/menus.c 2020-08-21 16:09:27.176711008 -0600
++++ fvwm-patched/fvwm/menus.c 2020-08-21 16:15:29.887392857 -0600
+@@ -2633,6 +2633,41 @@
+ return do_clear;
+ }
+
++#define DRAWMENUBORDER(NUM, XX, YY) XCopyArea(\
++ dpy, pm[(NUM)]->picture, MR_WINDOW(mr), Scr.TransMaskGC,\
++ 0, 0, pm[(NUM)]->width, pm[(NUM)]->height, (XX), (YY))
++static Bool paint_menu_multipixmap_background(
++ MenuRoot *mr, XEvent *pevent)
++{
++ MenuStyle *ms = MR_STYLE(mr);
++ int width, height, x, y;
++ int bw = MST_BORDER_WIDTH(mr);
++ FvwmPicture **pm;
++ pm = ST_FACE(ms).u.mb.pixmaps;
++
++ width = MR_WIDTH(mr);
++ height = MR_HEIGHT(mr);
++
++ FvwmPicture *p = pm[0];
++
++ width = MR_WIDTH(mr);
++ height = MR_HEIGHT(mr);
++
++ x = 0;
++
++ for (x = 0; x < width; x+=pm[1]->width) DRAWMENUBORDER(1, x, 0);
++ for (x = 0; x < width; x+=pm[5]->width) DRAWMENUBORDER(5, x, height-pm[5]->height);
++ for (x = 0; x < height; x+=pm[3]->height) DRAWMENUBORDER(3, width-pm[3]->height, x);
++ for (x = 0; x < height; x+=pm[7]->height) DRAWMENUBORDER(7, 0, x);
++
++ DRAWMENUBORDER(0, 0, 0);
++ DRAWMENUBORDER(2, width-pm[2]->width, 0);
++ DRAWMENUBORDER(4, width-pm[4]->width, height-pm[4]->height);
++ DRAWMENUBORDER(6, 0, height-pm[6]->height);
++
++ return False;
++}
++
+ static Bool paint_menu_pixmap_background(
+ MenuRoot *mr, XEvent *pevent)
+ {
+@@ -2735,15 +2770,20 @@
+ {
+ /* Only the border was obscured. Redraw it centrally instead of
+ * redrawing several menu items. */
+- RelieveRectangle(
+- dpy, MR_WINDOW(mr), 0, 0, MR_WIDTH(mr) - 1,
+- MR_HEIGHT(mr) - 1, (Pdepth < 2) ?
+- SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)) :
+- HILIGHT_GC(MST_MENU_INACTIVE_GCS(mr)),
+- SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)), bw);
++ if (ms && ST_FACE(ms).type == MultiPixmapMenu)
+ {
+- return;
++ paint_menu_multipixmap_background(mr, pevent);
+ }
++ else
++ {
++ RelieveRectangle(
++ dpy, MR_WINDOW(mr), 0, 0, MR_WIDTH(mr) - 1,
++ MR_HEIGHT(mr) - 1, (Pdepth < 2) ?
++ SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)) :
++ HILIGHT_GC(MST_MENU_INACTIVE_GCS(mr)),
++ SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)), bw);
++ }
++ return;
+ }
+ MR_IS_PAINTED(mr) = 1;
+ /* paint the menu background */
+@@ -2808,6 +2848,9 @@
+ case PixmapMenu:
+ do_clear = paint_menu_pixmap_background(mr, pevent);
+ break;
++ case MultiPixmapMenu:
++ do_clear = paint_menu_multipixmap_background(mr, pevent);
++ break;
+ case TiledPixmapMenu:
+ XSetWindowBackgroundPixmap(
+ dpy, MR_WINDOW(mr), ST_FACE(ms).u.p->picture);
+@@ -2820,11 +2863,14 @@
+ }
+ } /* if (ms) */
+ /* draw the relief */
+- RelieveRectangle(dpy, MR_WINDOW(mr), 0, 0, MR_WIDTH(mr) - 1,
+- MR_HEIGHT(mr) - 1, (Pdepth < 2) ?
+- SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)) :
+- HILIGHT_GC(MST_MENU_INACTIVE_GCS(mr)),
+- SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)), bw);
++ if (!(ms && ST_FACE(ms).type == MultiPixmapMenu))
++ {
++ RelieveRectangle(dpy, MR_WINDOW(mr), 0, 0, MR_WIDTH(mr) - 1,
++ MR_HEIGHT(mr) - 1, (Pdepth < 2) ?
++ SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)) :
++ HILIGHT_GC(MST_MENU_INACTIVE_GCS(mr)),
++ SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)), bw);
++ }
+ /* paint the menu items */
+ for (mi = MR_FIRST_ITEM(mr); mi != NULL; mi = MI_NEXT_ITEM(mi))
+ {
+Only in fvwm-patched/fvwm: menus.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/menustyle.c fvwm-patched/fvwm/menustyle.c
+--- fvwm-2.6.9/fvwm/menustyle.c 2020-08-21 16:09:27.176711008 -0600
++++ fvwm-patched/fvwm/menustyle.c 2020-08-21 16:15:29.887392857 -0600
+@@ -159,6 +159,8 @@
+ char *token;
+ char *action = s;
+ FvwmPictureAttributes fpa;
++ FvwmPicture **pm;
++ int x, y;
+
+ s = GetNextToken(s, &style);
+ if (style && strncasecmp(style, "--", 2) == 0)
+@@ -270,6 +272,58 @@
+ return False;
+ }
+ }
++ else if (StrEquals(style,"MultiBorder"))
++ {
++ fpa.mask = (Pdepth <= 8)? FPAM_DITHER:0;
++ pm = mf->u.mb.pixmaps;
++
++ for (x = 0; x < 8; x++)
++ {
++ if (pm[x])
++ {
++ PDestroyFvwmPicture(dpy, pm[x]);
++ }
++ s = GetNextToken(s, &token);
++ if (token)
++ {
++ pm[x] = PCacheFvwmPicture(dpy, Scr.NoFocusWin, NULL, token, fpa);
++ if (!pm[x])
++ {
++ fvwm_msg(ERR,
++ "menustyle_parse_face", "Pixmap '%s' could not be loaded",
++ token);
++ }
++ }
++ else
++ {
++ fvwm_msg(ERR,
++ "menustyle_parse_face", "Too few parameters for MultiBorder");
++ }
++ if (!token || !pm[x])
++ {
++ for (y = 0; y < x; y++)
++ {
++ if (pm[y])
++ {
++ PDestroyFvwmPicture(dpy, pm[y]);
++ pm[y] = 0;
++ }
++ }
++ free(style);
++ if (token)
++ {
++ free(token);
++ }
++ if (mf->type == MultiPixmapMenu)
++ {
++ mf->type = SimpleMenu;
++ }
++ return False;
++ }
++ mf->type = MultiPixmapMenu;
++ free(token);
++ }
++ }
+ else
+ {
+ if (verbose)
+Only in fvwm-patched/fvwm: menustyle.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/menustyle.h fvwm-patched/fvwm/menustyle.h
+--- fvwm-2.6.9/fvwm/menustyle.h 2020-08-21 16:09:27.176711008 -0600
++++ fvwm-patched/fvwm/menustyle.h 2020-08-21 16:15:29.887392857 -0600
+@@ -195,6 +195,7 @@
+ GradientMenu,
+ PixmapMenu,
+ TiledPixmapMenu,
++ MultiPixmapMenu,
+ SolidMenu
+ /* max button is 8 (0x8) */
+ } MenuFaceType;
+@@ -245,6 +246,9 @@
+ {
+ union
+ {
++ struct {
++ FvwmPicture *pixmaps[8];
++ } mb;
+ FvwmPicture *p;
+ Pixel back;
+ struct
+diff --unified --recursive --text fvwm-2.6.9/fvwm/screen.h fvwm-patched/fvwm/screen.h
+--- fvwm-2.6.9/fvwm/screen.h 2020-08-21 16:11:42.983734347 -0600
++++ fvwm-patched/fvwm/screen.h 2020-08-21 16:15:29.887392857 -0600
+@@ -99,6 +99,7 @@
+ AdjustedPixmapButton,
+ ShrunkPixmapButton,
+ MultiPixmap,
++ MultiBorder,
+ MiniIconButton,
+ SolidButton,
+ ColorsetButton
+@@ -158,6 +159,9 @@
+ Pixel *pixels;
+ unsigned short solid_flags;
+ } mp;
++ struct {
++ FvwmPicture *pixmaps[8];
++ } mb;
+ struct
+ {
+ int cs;
diff --git a/12-FvwmButtonsTips.patch b/12-FvwmButtonsTips.patch
new file mode 100644
index 000000000000..b07babaa6139
--- /dev/null
+++ b/12-FvwmButtonsTips.patch
@@ -0,0 +1,322 @@
+diff --unified --recursive --text fvwm-2.6.9/libs/FTips.c fvwm-patched/libs/FTips.c
+--- fvwm-2.6.9/libs/FTips.c 2018-05-26 05:35:26.000000000 -0600
++++ fvwm-patched/libs/FTips.c 2020-08-21 16:20:45.638664630 -0600
+@@ -504,7 +504,7 @@
+ if (fc == NULL)
+ {
+ fc = default_config;
+- }
++ }
+ current_config = fc;
+
+ if (label != NULL)
+Only in fvwm-patched/libs: FTips.c.orig
+diff --unified --recursive --text fvwm-2.6.9/modules/FvwmButtons/FvwmButtons.c fvwm-patched/modules/FvwmButtons/FvwmButtons.c
+--- fvwm-2.6.9/modules/FvwmButtons/FvwmButtons.c 2018-05-26 05:35:26.000000000 -0600
++++ fvwm-patched/modules/FvwmButtons/FvwmButtons.c 2020-08-21 16:28:07.722997146 -0600
+@@ -55,6 +55,7 @@
+ #include "libs/Colorset.h"
+ #include "libs/vpacket.h"
+ #include "libs/FRender.h"
++#include "libs/FTips.h"
+ #include "libs/fsm.h"
+ #include "libs/ColorUtils.h"
+ #include "libs/Graphics.h"
+@@ -900,6 +901,7 @@
+ button_info *tmp = ActiveButton;
+ ActiveButton = b;
+ RedrawButton(tmp, DRAW_FORCE, NULL);
++
+ }
+ if (
+ b->flags.b_ActiveIcon ||
+@@ -1040,6 +1042,9 @@
+
+ tmp.name = NULL;
+ tmp.name_list = NULL;
++
++ FTipsInit(Dpy);
++
+ while ( !isTerminated )
+ {
+ if (My_FNextEvent(Dpy, &Event))
+@@ -1166,6 +1171,10 @@
+ if (!event.xconfigure.send_event &&
+ Event.xconfigure.window != MyWindow)
+ continue;
++
++ if(FTipsHandleEvents(Dpy, &event))
++ continue;
++
+ fev_sanitise_configure_notify(&event.xconfigure);
+ Event.xconfigure.x = event.xconfigure.x;
+ Event.xconfigure.y = event.xconfigure.y;
+@@ -1209,10 +1218,33 @@
+ case EnterNotify:
+ b = handle_new_position(
+ b, Event.xcrossing.x, Event.xcrossing.y);
++
++ if(Event.xcrossing.mode == NotifyNormal)
++ {
++ b = handle_new_position(
++ b, Event.xcrossing.x, Event.xcrossing.y);
++ FTipsOn(Dpy,MyWindow,UberButton->c->tips_config,
++ (void *)UberButton, b->tipslabel,
++ b->x, b->y, Width,Height);
++ FTipsUpdateLabel(Dpy, b->tipslabel);
++ }
+ break;
+
+ case MotionNotify:
++
+ b = handle_new_position(b, Event.xmotion.x, Event.xmotion.y);
++
++ x = Event.xbutton.x;
++ y = Event.xbutton.y;
++
++ if(b->tipslabel != NULL)
++ {
++ FTipsOn(Dpy,MyWindow,UberButton->c->tips_config, (void *)UberButton, b->tipslabel, x, y, w, h);
++ FTipsUpdateLabel(Dpy, b->tipslabel);
++ } else {
++ FTipsCancel(Dpy);
++ }
++
+ break;
+
+ case LeaveNotify:
+@@ -1235,11 +1267,13 @@
+ b = ActiveButton;
+ ActiveButton = NULL;
+ RedrawButton(b, DRAW_FORCE, NULL);
++
+ }
+ if (CurrentButton)
+ {
+ RedrawButton(b, DRAW_FORCE, NULL);
+ }
++ FTipsCancel(Dpy);
+ }
+ break;
+
+@@ -1261,8 +1295,8 @@
+ Window dummy;
+
+ XTranslateCoordinates(
+- Dpy, Event.xbutton.window, MyWindow, Event.xbutton.x,
+- Event.xbutton.y, &x, &y, &dummy);
++ Dpy, Event.xbutton.window, MyWindow, Event.xbutton.x,
++ Event.xbutton.y, &x, &y, &dummy);
+ }
+ if (CurrentButton)
+ {
+@@ -1304,7 +1338,10 @@
+ RedrawButton(tmp, DRAW_FORCE, NULL);
+ }
+ else
++ {
+ RedrawButton(b, DRAW_FORCE, NULL);
++ }
++
+ if (!act)
+ {
+ break;
+Only in fvwm-patched/modules/FvwmButtons: FvwmButtons.c.orig
+diff --unified --recursive --text fvwm-2.6.9/modules/FvwmButtons/FvwmButtons.h fvwm-patched/modules/FvwmButtons/FvwmButtons.h
+--- fvwm-2.6.9/modules/FvwmButtons/FvwmButtons.h 2018-05-26 05:35:26.000000000 -0600
++++ fvwm-patched/modules/FvwmButtons/FvwmButtons.h 2020-08-21 16:20:45.638664630 -0600
+@@ -32,6 +32,8 @@
+ #include "libs/fvwmlib.h"
+ #include "libs/Picture.h"
+ #include "libs/Flocale.h"
++#include "libs/FTips.h"
++#define FONT_STRING "-*-fixed-medium-r-normal--13-*"
+
+ /* ------------------------------- structs --------------------------------- */
+
+@@ -76,6 +78,7 @@
+ unsigned b_PressIcon : 1; /* Use alternate Icon on press */
+ unsigned b_PressColorset : 1; /* Use alternate Colorset on press */
+ unsigned b_PressTitle : 1; /* Use alternate Title text on press */
++ unsigned b_UseTips : 1; /* Whether to use tips or not. */
+ } flags_type;
+
+ /* Flags for b->swallow */
+@@ -125,6 +128,9 @@
+ int colorset; /* b_Colorset */
+ int activeColorset; /* b_ActiveColorset */
+ int pressColorset; /* b_PressColorset */
++ char *tipsfont; /* b_TipsFont*/
++ ftips_config *tips_config; /* Struct that holds tips info.*/
++
+ Pixel fc; /* b_Fore */
+ Pixel bc, hc, sc; /* b_Back && !b_IconBack */
+ FvwmPicture *backicon; /* b_Back && b_IconBack */
+@@ -181,6 +187,7 @@
+ FvwmPicture *pressicon; /* b_PressIcon */
+ int activeColorset; /* b_ActiveColorset */
+ int pressColorset; /* b_PressColorset */
++ char *tipslabel; /* b_TipsLabel */
+ Window IconWin; /* b_Swallow */
+ Window PanelWin; /* b_Panel */
+ Window BackIconWin; /* b_Back && b_IconBack */
+Only in fvwm-patched/modules/FvwmButtons: FvwmButtons.h.orig
+diff --unified --recursive --text fvwm-2.6.9/modules/FvwmButtons/parse.c fvwm-patched/modules/FvwmButtons/parse.c
+--- fvwm-2.6.9/modules/FvwmButtons/parse.c 2018-05-26 05:35:26.000000000 -0600
++++ fvwm-patched/modules/FvwmButtons/parse.c 2020-08-21 16:20:45.638664630 -0600
+@@ -882,6 +882,7 @@
+ "presstitle",
+ "activecolorset",
+ "presscolorset",
++ "tipslabel",
+ "top",
+ NULL
+ };
+@@ -1605,7 +1606,33 @@
+ b->flags.b_ActiveColorset = 0;
+ }
+ break;
++ /* --------- TipsLabel ---------*/
++ case 28:
++ s = trimleft(s);
++ t = seekright(&s);
++ if(ub->c->flags.b_UseTips)
++ {
++ if (*s == '(')
++ {
++ fprintf(stderr,
++ "%s: justification not allowed "
++ "for TipsLabel.\n", MyName);
++ }
++
++
++
++ if (t && *t && (t[0] != '-' || t[1] != 0))
++ {
++ if (b->tipslabel != NULL)
++ {
++ free(b->tipslabel);
++ } else {
++ b->tipslabel = t;
++ }
++ }
++ }
+
++ break;
+ /* --------------- --------------- */
+ case 26: /* PressColorset */
+ i = strtol(s, &t, 10);
+@@ -1777,6 +1804,14 @@
+ "colorset",
+ "activecolorset",
+ "presscolorset",
++ "usetips",
++ "tipsfont",
++ "tipsdelay",
++ "tipscolorset",
++ "tipsborderwidth",
++ "tipsplacement",
++ "tipsjustification",
++ "tipsoffset",
+ NULL
+ };
+ int i, j, k;
+@@ -1924,7 +1959,97 @@
+ ub->c->flags.b_PressColorset = 0;
+ }
+ break;
++ case 15: /* UseTips */
++ /* We're using tips.*/
++ ub->c->flags.b_UseTips = 1;
++
++ /* Set the defaults up. */
++ ub->c->tips_config = FTipsNewConfig();
++
++ /* Include fonts. */
++ CopyStringWithQuotes(&ub->c->tipsfont,FONT_STRING);
++ ub->c->tips_config->Ffont = FlocaleLoadFont(Dpy,
++ ub->c->tipsfont, MyName);
++ break;
++ case 16: /* TipsFont */
++ if(ub->c->flags.b_UseTips)
++ {
++ CopyStringWithQuotes(&ub->c->tipsfont,s);
+
++ ub->c->tips_config->Ffont = FlocaleLoadFont(Dpy, ub->c->tipsfont,
++ MyName);
++ }
++
++ break;
++ case 17: /*TipsDelay */
++ if(ub->c->flags.b_UseTips)
++ {
++ i = sscanf(s, "%d %d", &j, &k);
++ if( i > 0)
++ {
++ /* Then only one value was given. Set the
++ * mapped_delay option to this given value
++ * also since it's optional.
++ */
++ ub->c->tips_config->delay = ub->c->tips_config->mapped_delay = j;
++ }
++ if( i > 1)
++ {
++ /* Two values passed in. We only need to
++ * change the value for mapped_delay here.
++ */
++
++ ub->c->tips_config->mapped_delay = k;
++
++ }
++ }
++ break;
++ case 18: /* TipsColorset */
++ if (ub->c->flags.b_UseTips)
++ {
++ i = sscanf(s, "%d", &j);
++ if (i > 0)
++ {
++ ub->c->tips_config->colorset = j;
++ AllocColorset(j);
++ }
++ }
++ break;
++ case 19: /* TipsBorderWidth */
++ if (ub->c->flags.b_UseTips)
++ {
++ i = sscanf(s, "%d", &j);
++
++ if(i > 0)
++ {
++ ub->c->tips_config->border_width = j;
++ }
++ }
++ break;
++ case 20: /* TipsPlacement */
++ if(ub->c->flags.b_UseTips)
++ {
++ s = trimleft(s);
++
++ /* Options ... */
++ if(!strcasecmp(s, "up"))
++ {
++ i = FTIPS_PLACEMENT_UP;
++ } else if(!strcasecmp(s, "down")) {
++ i = FTIPS_PLACEMENT_DOWN;
++ } else if(!strcasecmp(s, "left")) {
++ i = FTIPS_PLACEMENT_LEFT;
++ } else if(!strcasecmp(s, "right")) {
++ i = FTIPS_PLACEMENT_RIGHT;
++ } else if(!strcasecmp(s, "updown")) {
++ i = FTIPS_PLACEMENT_AUTO_UPDOWN;
++ } else if(!strcasecmp(s, "leftright")) {
++ i = FTIPS_PLACEMENT_AUTO_LEFTRIGHT;
++ }
++
++ ub->c->tips_config->placement = i;
++ }
++ break;
+ default:
+ s = trimleft(s);
+ ParseButton(ubb, s);
+Only in fvwm-patched/modules/FvwmButtons: parse.c.orig
diff --git a/13-FvwmIconMan.patch b/13-FvwmIconMan.patch
new file mode 100644
index 000000000000..cf14f4f6ce49
--- /dev/null
+++ b/13-FvwmIconMan.patch
@@ -0,0 +1,114 @@
+diff --unified --recursive --text fvwm-2.6.9/modules/FvwmIconMan/FvwmIconMan.h fvwm-patched/modules/FvwmIconMan/FvwmIconMan.h
+--- fvwm-2.6.9/modules/FvwmIconMan/FvwmIconMan.h 2016-10-15 08:51:45.000000000 -0600
++++ fvwm-patched/modules/FvwmIconMan/FvwmIconMan.h 2020-08-21 16:30:38.324120869 -0600
+@@ -317,6 +317,8 @@
+ char *tips_fontname;
+ char *tips_formatstring;
+ ftips_config *tips_conf;
++ Uchar roundedcorners;
++ int padding;
+
+ /* X11 state */
+ Window theWindow, theFrame;
+Only in fvwm-patched/modules/FvwmIconMan: FvwmIconMan.h.orig
+diff --unified --recursive --text fvwm-2.6.9/modules/FvwmIconMan/readconfig.c fvwm-patched/modules/FvwmIconMan/readconfig.c
+--- fvwm-2.6.9/modules/FvwmIconMan/readconfig.c 2018-05-26 05:35:26.000000000 -0600
++++ fvwm-patched/modules/FvwmIconMan/readconfig.c 2020-08-21 16:30:38.324120869 -0600
+@@ -2037,6 +2037,40 @@
+ }
+ SET_MANAGER(manager, relief_thickness, n);
+ }
++ else if (!strcasecmp(option1, "padding")) {
++ p = read_next_cmd(READ_ARG);
++ if (!p) {
++ ConsoleMessage("Bad line: %s\n", current_line);
++ continue;
++ }
++ if (extract_int(p, &n) == 0) {
++ ConsoleMessage("This is not a number: %s\n", p);
++ ConsoleMessage("Bad line: %s\n", current_line);
++ continue;
++ }
++ SET_MANAGER(manager, padding, n);
++ }
++ else if (!strcasecmp(option1, "roundedcorners")) {
++ p = read_next_cmd(READ_ARG);
++ if (!p) {
++ ConsoleMessage("Bad line: %s\n", current_line);
++ ConsoleMessage("Need argument to roundedcorners\n");
++ continue;
++ }
++ if (!strcasecmp(p, "true")) {
++ i = 1;
++ }
++ else if (!strcasecmp(p, "false")) {
++ i = 0;
++ }
++ else {
++ ConsoleMessage("Bad line: %s\n", current_line);
++ ConsoleMessage("What is this: %s?\n", p);
++ continue;
++ }
++ ConsoleDebug(CONFIG, "Setting roundedcorners to: %d\n", i);
++ SET_MANAGER(manager, roundedcorners, i);
++ }
+ else if (!strcasecmp(option1, "tips")) {
+ p = read_next_cmd(READ_ARG);
+ if (!p) {
+Only in fvwm-patched/modules/FvwmIconMan: readconfig.c.orig
+diff --unified --recursive --text fvwm-2.6.9/modules/FvwmIconMan/xmanager.c fvwm-patched/modules/FvwmIconMan/xmanager.c
+--- fvwm-2.6.9/modules/FvwmIconMan/xmanager.c 2018-05-26 05:35:26.000000000 -0600
++++ fvwm-patched/modules/FvwmIconMan/xmanager.c 2020-08-21 16:30:38.324120869 -0600
+@@ -1397,6 +1397,8 @@
+
+ g->text_y = g->button_y + text_pad;
+ g->text_base = g->text_y + man->FButtonFont->ascent;
++
++ g->button_w -= man->padding;
+ }
+
+ static void draw_button_background(
+@@ -1669,6 +1671,33 @@
+ }
+ }
+
++static void __draw_rounded_corner(WinManager *man, ButtonGeometry *g,
++ int x, int y, int width, int height, GC gc)
++{
++ int x1 = g->button_x + x;
++ int x2 = g->button_x + g->button_w - x - width;
++ int y1 = g->button_y + y;
++ int y2 = g->button_y + g->button_h - y - height;
++
++ XFillRectangle(theDisplay, man->theWindow, gc, x1, y1, width, height);
++ XFillRectangle(theDisplay, man->theWindow, gc, x2, y1, width, height);
++ XFillRectangle(theDisplay, man->theWindow, gc, x1, y2, width, height);
++ XFillRectangle(theDisplay, man->theWindow, gc, x2, y2, width, height);
++}
++
++static void draw_rounded_corners(WinManager *man, ButtonGeometry *g, GC gc)
++{
++ if (man->roundedcorners)
++ {
++ __draw_rounded_corner(man, g, 0, 0, 2, 1, man->backContext[TITLE_CONTEXT]);
++ __draw_rounded_corner(man, g, 0, 1, 1, 1, man->backContext[TITLE_CONTEXT]);
++ __draw_rounded_corner(man, g, 1, 1, 1, 1, gc);
++ }
++
++ XFillRectangle(theDisplay, man->theWindow, man->backContext[TITLE_CONTEXT],
++ g->button_x + g->button_w, g->button_y, man->padding, g->button_h);
++}
++
+ static void draw_button(WinManager *man, int button, int force)
+ {
+ Button *b;
+@@ -1857,6 +1886,8 @@
+ draw_relief(
+ man, button_state, &g, context1,
+ context2);
++
++ draw_rounded_corners(man, &g, context1);
+ }
+ else if (button_state == SELECT_CONTEXT ||
+ button_state == FOCUS_SELECT_CONTEXT ||
+Only in fvwm-patched/modules/FvwmIconMan: xmanager.c.orig
diff --git a/14-Hover.patch b/14-Hover.patch
new file mode 100644
index 000000000000..b6a705a0d892
--- /dev/null
+++ b/14-Hover.patch
@@ -0,0 +1,295 @@
+diff --unified --recursive --text fvwm-2.6.9/fvwm/borders.c fvwm-patched/fvwm/borders.c
+--- fvwm-2.6.9/fvwm/borders.c 2020-08-21 16:16:28.114047517 -0600
++++ fvwm-patched/fvwm/borders.c 2020-08-21 16:34:52.530676541 -0600
+@@ -58,6 +58,7 @@
+ /* ---------------------------- imports ------------------------------------ */
+
+ extern Window PressedW;
++extern Window HoverW;
+
+ /* ---------------------------- included code files ------------------------ */
+
+@@ -235,6 +236,7 @@
+ unsigned clear_bmask : NUMBER_OF_TITLE_BUTTONS;
+ unsigned draw_bmask : NUMBER_OF_TITLE_BUTTONS;
+ unsigned max_bmask : NUMBER_OF_TITLE_BUTTONS;
++ unsigned hover_bmask : NUMBER_OF_TITLE_BUTTONS;
+ ButtonState bstate[NUMBER_OF_TITLE_BUTTONS];
+ unsigned is_title_pressed : 1;
+ unsigned is_title_lit : 1;
+@@ -340,8 +342,12 @@
+
+ /* rules to get button state */
+ static ButtonState border_flags_to_button_state(
+- int is_pressed, int is_lit, int is_toggled)
++ int is_pressed, int is_lit, int is_toggled, int is_hover)
+ {
++ if (is_lit && is_hover && Scr.gs.use_hover_buttons)
++ {
++ return BS_ActiveHover;
++ }
+ if (!is_lit && Scr.gs.use_inactive_buttons)
+ {
+ if (is_pressed && Scr.gs.use_inactive_down_buttons)
+@@ -862,7 +868,7 @@
+ /* check if state changed */
+ old_state = border_flags_to_button_state(
+ (fw->decor_state.parts_inverted & PART_TITLE),
+- (fw->decor_state.parts_lit & PART_TITLE), 0);
++ (fw->decor_state.parts_lit & PART_TITLE), 0, 0);
+ if (old_state != td->tbstate.tstate)
+ {
+ draw_parts |= PART_TITLE;
+@@ -886,7 +892,8 @@
+ old_state = border_flags_to_button_state(
+ (fw->decor_state.buttons_inverted & mask),
+ (fw->decor_state.buttons_lit & mask),
+- (fw->decor_state.buttons_toggled & mask));
++ (fw->decor_state.buttons_toggled & mask),
++ (fw->decor_state.buttons_hover & mask));
+ if (old_state != td->tbstate.bstate[i])
+ {
+ draw_parts |= PART_BUTTONS;
+@@ -4392,6 +4399,7 @@
+ fw->decor_state.buttons_inverted = td->tbstate.pressed_bmask;
+ fw->decor_state.buttons_lit = td->tbstate.lit_bmask;
+ fw->decor_state.buttons_toggled = td->tbstate.toggled_bmask;
++ fw->decor_state.buttons_hover = td->tbstate.hover_bmask;
+
+ return;
+ }
+@@ -4660,13 +4668,18 @@
+ {
+ tbstate->toggled_bmask |= mask;
+ }
++ if (FW_W_BUTTON(fw, i) == HoverW)
++ {
++ tbstate->hover_bmask |= mask;
++ }
+ tbstate->bstate[i] = border_flags_to_button_state(
+ tbstate->pressed_bmask & mask,
+ tbstate->lit_bmask & mask,
+- tbstate->toggled_bmask & mask);
++ tbstate->toggled_bmask & mask,
++ tbstate->hover_bmask & mask);
+ }
+ tbstate->tstate = border_flags_to_button_state(
+- tbstate->is_title_pressed, tbstate->is_title_lit, 0);
++ tbstate->is_title_pressed, tbstate->is_title_lit, 0, 0);
+ }
+
+ static window_parts border_get_titlebar_descr(
+@@ -4931,6 +4944,7 @@
+ fw->decor_state.buttons_lit = 0;
+ fw->decor_state.buttons_inverted = 0;
+ fw->decor_state.buttons_toggled = 0;
++ fw->decor_state.buttons_hover = 0;
+ return;
+ }
+ memset(&td, 0, sizeof(td));
+@@ -4982,6 +4996,7 @@
+ fw->decor_state.buttons_toggled =
+ (fw->decor_state.buttons_toggled &
+ ~td.tbstate.max_bmask) | td.tbstate.toggled_bmask;
++ fw->decor_state.buttons_hover &= td.tbstate.hover_bmask;
+ }
+
+ return;
+@@ -5072,11 +5087,12 @@
+ ButtonState bs;
+ int is_pressed;
+ int is_toggled;
++ int is_hover;
+ int i;
+
+ /* title */
+ is_pressed = (FW_W_TITLE(fw) == PressedW);
+- bs = border_flags_to_button_state(is_pressed, has_focus, 0);
++ bs = border_flags_to_button_state(is_pressed, has_focus, 0, 0);
+ if (DFS_USE_BORDER_STYLE(TB_STATE(GetDecor(fw, titlebar))[bs].style))
+ {
+ return 1;
+@@ -5089,8 +5105,9 @@
+ }
+ is_pressed = (FW_W_BUTTON(fw, i) == PressedW);
+ is_toggled = (is_button_toggled(fw, i) == True);
++ is_hover = (FW_W_BUTTON(fw, i) == HoverW);
+ bs = border_flags_to_button_state(
+- is_pressed, (has_focus == True), is_toggled);
++ is_pressed, (has_focus == True), is_toggled, is_hover);
+ if (DFS_USE_BORDER_STYLE(
+ TB_STATE(GetDecor(fw, buttons[i]))[bs].style))
+ {
+@@ -5551,6 +5568,7 @@
+ DEFAULT_USE_INACTIVE_BUTTONS;
+ Scr.gs.use_inactive_down_buttons =
+ DEFAULT_USE_INACTIVE_DOWN_BUTTONS;
++ Scr.gs.use_hover_buttons = 0;
+ return;
+ }
+ first = False;
+@@ -5572,6 +5590,12 @@
+ action, &action,
+ DEFAULT_USE_INACTIVE_DOWN_BUTTONS, True);
+ }
++ else if (StrEquals("hover", token))
++ {
++ Scr.gs.use_hover_buttons = ParseToggleArgument(
++ action, &action,
++ 0, True);
++ }
+ else
+ {
+ Scr.gs.use_active_down_buttons =
+@@ -5580,6 +5604,7 @@
+ DEFAULT_USE_INACTIVE_BUTTONS;
+ Scr.gs.use_inactive_down_buttons =
+ DEFAULT_USE_INACTIVE_DOWN_BUTTONS;
++ Scr.gs.use_hover_buttons = 0;
+ fvwm_msg(ERR, "cmd_button_state",
+ "Unknown button state %s", token);
+ return;
+Only in fvwm-patched/fvwm: borders.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/builtins.c fvwm-patched/fvwm/builtins.c
+--- fvwm-2.6.9/fvwm/builtins.c 2020-08-21 16:16:28.114047517 -0600
++++ fvwm-patched/fvwm/builtins.c 2020-08-21 16:34:52.530676541 -0600
+@@ -94,12 +94,16 @@
+ {
+ "ActiveUp",
+ "ActiveDown",
++ "ActiveHover",
+ "InactiveUp",
+ "InactiveDown",
++ "InactiveHover",
+ "ToggledActiveUp",
+ "ToggledActiveDown",
++ "ToggledActiveHover",
+ "ToggledInactiveUp",
+ "ToggledInactiveDown",
++ "ToggledInactiveHover",
+ "Active",
+ "Inactive",
+ "ToggledActive",
+@@ -110,10 +114,13 @@
+ "AllInactive",
+ "AllUp",
+ "AllDown",
++ "AllHover",
+ "AllActiveUp",
+ "AllActiveDown",
++ "AllActiveHover",
+ "AllInactiveUp",
+ "AllInactiveDown",
++ "AllInactiveHover",
+ NULL
+ };
+
+Only in fvwm-patched/fvwm: builtins.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/events.c fvwm-patched/fvwm/events.c
+--- fvwm-2.6.9/fvwm/events.c 2018-05-26 05:35:26.000000000 -0600
++++ fvwm-patched/fvwm/events.c 2020-08-21 16:38:28.601284882 -0600
+@@ -184,6 +184,7 @@
+
+ int last_event_type = 0;
+ Window PressedW = None;
++Window HoverW = None;
+
+ /* ---------------------------- local functions ---------------------------- */
+
+@@ -1785,6 +1786,23 @@
+ return;
+ }
+
++static void redraw_hover(FvwmWindow* fw, Window w)
++{
++ if (fw)
++ {
++ int i;
++ for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; i++)
++ {
++ if (w == FW_W_BUTTON(fw, i))
++ {
++ HoverW = FW_W_BUTTON(fw, i);
++ }
++ }
++ border_redraw_decorations(fw);
++ HoverW = None;
++ }
++}
++
+ /* ---------------------------- event handlers ----------------------------- */
+
+ void HandleButtonPress(const evh_args_t *ea)
+@@ -1980,6 +1998,8 @@
+ ewp = &te->xcrossing;
+ ENTER_DBG((stderr, "++++++++ en (%d): fw %p w 0x%08x sw 0x%08x mode 0x%x detail 0x%x '%s'\n", ++ecount, fw, (int)ewp->window, (int)ewp->subwindow, ewp->mode, ewp->detail, fw?fw->visible_name:"(none)"));
+
++ redraw_hover(fw, ewp->window);
++
+ if (
+ ewp->window == Scr.Root &&
+ ewp->detail == NotifyInferior && ewp->mode == NotifyNormal)
+@@ -2687,6 +2707,8 @@
+
+ DBUG("HandleLeaveNotify", "Routine Entered");
+
++ redraw_hover(fw, te->xcrossing.window);
++
+ ENTER_DBG((stderr, "-------- ln (%d): fw %p w 0x%08x sw 0x%08x mode 0x%x detail 0x%x '%s'\n", ++ecount, fw, (int)te->xcrossing.window, (int)te->xcrossing.subwindow, te->xcrossing.mode, te->xcrossing.detail, fw?fw->visible_name:"(none)"));
+ lwp = &te->xcrossing;
+ if (
+Only in fvwm-patched/fvwm: events.c.orig
+diff --unified --recursive --text fvwm-2.6.9/fvwm/fvwm.h fvwm-patched/fvwm/fvwm.h
+--- fvwm-2.6.9/fvwm/fvwm.h 2020-08-21 16:11:42.983734347 -0600
++++ fvwm-patched/fvwm/fvwm.h 2020-08-21 16:34:52.534676586 -0600
+@@ -827,6 +827,7 @@
+ unsigned buttons_lit : NUMBER_OF_TITLE_BUTTONS;
+ unsigned buttons_inverted : NUMBER_OF_TITLE_BUTTONS;
+ unsigned buttons_toggled : NUMBER_OF_TITLE_BUTTONS;
++ unsigned buttons_hover : NUMBER_OF_TITLE_BUTTONS;
+ unsigned parts_drawn : 12;
+ unsigned parts_lit : 12;
+ unsigned parts_inverted : 12;
+diff --unified --recursive --text fvwm-2.6.9/fvwm/screen.h fvwm-patched/fvwm/screen.h
+--- fvwm-2.6.9/fvwm/screen.h 2020-08-21 16:16:28.118047433 -0600
++++ fvwm-patched/fvwm/screen.h 2020-08-21 16:34:52.534676586 -0600
+@@ -202,12 +202,16 @@
+ BS_All = -1,
+ BS_ActiveUp,
+ BS_ActiveDown,
++ BS_ActiveHover,
+ BS_InactiveUp,
+ BS_InactiveDown,
++ BS_InactiveHover,
+ BS_ToggledActiveUp,
+ BS_ToggledActiveDown,
++ BS_ToggledActiveHover,
+ BS_ToggledInactiveUp,
+ BS_ToggledInactiveDown,
++ BS_ToggledInactiveHover,
+ BS_MaxButtonState,
+ BS_MaxButtonStateMask = BS_MaxButtonState - 1,
+ BS_Active,
+@@ -220,10 +224,13 @@
+ BS_AllInactive,
+ BS_AllUp,
+ BS_AllDown,
++ BS_AllHover,
+ BS_AllActiveUp,
+ BS_AllActiveDown,
++ BS_AllActiveHover,
+ BS_AllInactiveUp,
+ BS_AllInactiveDown,
++ BS_AllInactiveHover,
+ BS_MaxButtonStateName
+ } ButtonState;
+
+@@ -511,6 +518,7 @@
+ unsigned use_active_down_buttons : 1;
+ unsigned use_inactive_buttons : 1;
+ unsigned use_inactive_down_buttons : 1;
++ unsigned use_hover_buttons : 1;
+ } gs; /* global style structure */
+ struct
+ {
+Only in fvwm-patched/fvwm: screen.h.orig
diff --git a/15-FirstItemUnderPointer.patch b/15-FirstItemUnderPointer.patch
new file mode 100644
index 000000000000..c158c8447918
--- /dev/null
+++ b/15-FirstItemUnderPointer.patch
@@ -0,0 +1,18 @@
+diff --unified --recursive --text fvwm-2.6.9/fvwm/menus.c fvwm-patched/fvwm/menus.c
+--- fvwm-2.6.9/fvwm/menus.c 2020-08-21 16:16:28.114047517 -0600
++++ fvwm-patched/fvwm/menus.c 2020-08-21 16:40:31.318886523 -0600
+@@ -3348,6 +3348,13 @@
+ }
+ context = (*pexc)->w.wcontext;
+
++ /* Popup menu with first item (not title) under pointer */
++ if(MI_IS_TITLE(MR_FIRST_ITEM(mr)))
++ {
++ y-=MI_HEIGHT(MR_FIRST_ITEM(mr));
++ do_warp_to_item = True;
++ }
++
+ /*
+ * Create a new menu instance (if necessary)
+ */
+Only in fvwm-patched/fvwm: menus.c.orig
diff --git a/16-ThinGeometryProxy.patch b/16-ThinGeometryProxy.patch
new file mode 100644
index 000000000000..07d296021a9a
--- /dev/null
+++ b/16-ThinGeometryProxy.patch
@@ -0,0 +1,25 @@
+diff --unified --recursive --text fvwm-2.6.9/libs/defaults.h fvwm-patched/libs/defaults.h
+--- fvwm-2.6.9/libs/defaults.h 2018-03-25 13:01:09.000000000 -0600
++++ fvwm-patched/libs/defaults.h 2020-08-21 16:41:53.075990111 -0600
+@@ -153,7 +153,7 @@
+ #define BROKEN_MINSIZE_LIMIT 30000
+
+ /* geometry window */
+-#define GEOMETRY_WINDOW_BW 2 /* pixels */
++#define GEOMETRY_WINDOW_BW 1 /* pixels */
+ #define GEOMETRY_WINDOW_STRING " +8888 x +8888 "
+ #define GEOMETRY_WINDOW_POS_STRING " %+-4d %+-4d "
+ #define GEOMETRY_WINDOW_SIZE_STRING " %4d x %-4d "
+diff --unified --recursive --text fvwm-2.6.9/modules/FvwmProxy/FvwmProxy.c fvwm-patched/modules/FvwmProxy/FvwmProxy.c
+--- fvwm-2.6.9/modules/FvwmProxy/FvwmProxy.c 2018-05-26 05:35:26.000000000 -0600
++++ fvwm-patched/modules/FvwmProxy/FvwmProxy.c 2020-08-21 16:41:53.075990111 -0600
+@@ -1224,7 +1224,7 @@
+ {
+ XClearWindow(dpy,proxy->proxy);
+ }
+- RelieveRectangle(dpy,proxy->proxy, 0,0, w - 1,h - 1, hi_gc,sh_gc, 2);
++ RelieveRectangle(dpy,proxy->proxy, 0,0, w - 1,h - 1, hi_gc,sh_gc, 1);
+
+ #if 0
+ if (proxy->iconname != NULL)
+Only in fvwm-patched/modules/FvwmProxy: FvwmProxy.c.orig
diff --git a/01-MiniIconSize.patch b/17-MiniIconSize.patch
index 4db2a4b8ad4d..ec598bf91887 100644
--- a/01-MiniIconSize.patch
+++ b/17-MiniIconSize.patch
@@ -1,6 +1,6 @@
-diff --unified --recursive --text fvwm-2.6.9/fvwm/ewmh_icons.c fvwm-2.6.9.new/fvwm/ewmh_icons.c
+diff --unified --recursive --text fvwm-2.6.9/fvwm/ewmh_icons.c fvwm-patched/fvwm/ewmh_icons.c
--- fvwm-2.6.9/fvwm/ewmh_icons.c 2018-05-26 05:35:26.000000000 -0600
-+++ fvwm-2.6.9.new/fvwm/ewmh_icons.c 2020-01-31 18:45:31.860931662 -0700
++++ fvwm-patched/fvwm/ewmh_icons.c 2020-08-21 16:47:11.016481431 -0600
@@ -714,10 +714,10 @@
if (is_mini_icon)
diff --git a/PKGBUILD b/PKGBUILD
index 99922d181188..c9b1bdb3b1be 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -3,7 +3,7 @@
pkgname=fvwm-patched
_pkgname=fvwm
pkgver=2.6.9
-pkgrel=1
+pkgrel=2
pkgdesc="A multiple large virtual desktop window manager originally derived from twm with patches"
arch=('x86_64')
url="https://github.com/willscreel/fvwm-patched"
@@ -17,23 +17,113 @@ conflicts=(${_pkgname})
options=('!emptydirs' '!makeflags')
source=(https://github.com/fvwmorg/${_pkgname}/releases/download/${pkgver}/${_pkgname}-${pkgver}.tar.gz
fvwm.desktop
- 01-MiniIconSize.patch
- 02-FluxRoundedCorners.patch)
+ 01-TranslucentMenus.patch
+ 02-ColourBorders.patch
+ 03-ResizeOutlineThin.patch
+ 04-Conditionals.patch
+ 05-FlatSeparators.patch
+ 06-BorderUnderTitle.patch
+ 07-InactiveFont.patch
+ 08-FluxRoundedCorners.patch
+ 09-TopBorder.patch
+ 10-ButtonWidth.patch
+ 11-MultiBorder.patch
+ 12-FvwmButtonsTips.patch
+ 13-FvwmIconMan.patch
+ 14-Hover.patch
+ 15-FirstItemUnderPointer.patch
+ 16-ThinGeometryProxy.patch
+ 17-MiniIconSize.patch)
sha256sums=('1bc64cf3ccd0073008758168327a8265b8059def9b239b451d6b9fab2cc391ae'
'51d345f995f57c6d881d48bf535f71d75041a9bf1f0fa41dd99e1b22fd66aaf3'
- 'ceef06afc53282e4a0095994258a7a40708c54bd8decc395eff8bb72d64a6b49'
- '3c44bbf465a89bbb078ce6be2c6e6a02dca02983cec9252c2a628b5210c24c0a')
+ '08d7fef7d0f3216b39f41932705ea68c0d255a0c2a1138bf4614070c7250a4a7'
+ '749c536ff838e528f1e9345f18ca3948559cc788bdeb49f03c9676756576fc62'
+ 'fe235e46d24a33ea7c1b6ba0753f93c5733d6e5de29e5efae71ba7bdbe49f9ac'
+ '0d202215543f52b4b3249ac7f0117ca8abba35e913c45cb9173dfc10fe8746a7'
+ 'b3eedf33687f3b76cc3940867af8068285226a9b8f83dbde1152ee7b72dac446'
+ '2fdf0723b790890a1740e7bd2e1d064dda4e468661fcabd659a374613ea84b46'
+ '15d197d8fb630725a65dd9007a0eedf0910e9956d8796a0aedcd9507dcab668e'
+ 'b4767f0fe0dd67ab586d0d64d368ff91bb257221d978db207c731c7f5e3a7049'
+ '9f27e247cad58b3a91f90921cff4603cdf9e481c13e1c97b035a7f5634208a7e'
+ '6d9daadaa1bdc7d1b050e50fa5a887d495c0ecf6770ef9a74b495cd9cbb0ad3f'
+ '5d51807b3c8b3b4c1706abbe21d8d64af76ea5d2b9fb33355ffc5f17ce2bbd38'
+ '973cc5dbef67522bfb4745fb5b8a3f1c22b82d1ff3124796b5fb5bb5cd429eaa'
+ '24349e5cf1089fa26f8e94f0ba66adecba403eb0d13c95eb02441a4306db5ed8'
+ '5a784682602f338c7b724c864f0b4f024ff9c4e86ee815124f168e8b94b85002'
+ 'df8053d234883e21fe59ef7f3c117612be61740f86d392d2b3c3ee2ae314e0a0'
+ '78d40d1181bac4f54b111eda7d3bbd1fcb704e36ac44b4e21ea786a1636f9d2e'
+ 'cb1a593ebd65a06cdc1d6d26f95de5473269130969ce83ca2259948cbf4d6c33')
prepare() {
cd ${_pkgname}-${pkgver}
- # Enables the use of IconSize for MiniIcons
- echo "Applying 01-MiniIconSize.patch"
- patch --forward --strip=1 --input="${srcdir}/01-MiniIconSize.patch"
+ # Enables real transparency on menus
+ echo "Applying 01-TranslucentMenus.patch"
+ patch --forward --strip=1 --input="${srcdir}/01-TranslucentMenus.patch"
+
+ # Enables different colours on window's borders
+ echo "Applying 02-ColourBorders.patch"
+ patch --forward --strip=1 --input="${srcdir}/02-ColourBorders.patch"
+
+ # Enables a single pixel rectangle when resizing
+ echo "Applying 03-ResizeOutlineThin.patch"
+ patch --forward --strip=1 --input="${srcdir}/03-ResizeOutlineThin.patch"
+
+ # Enables other conditions for windows
+ echo "Applying 04-Conditionals.patch"
+ patch --forward --strip=1 --input="${srcdir}/04-Conditionals.patch"
+
+ # Enables the use of single pixel separators
+ echo "Applying 05-FlatSeparators.patch"
+ patch --forward --strip=1 --input="${srcdir}/05-FlatSeparators.patch"
+
+ # Adds a border under the titlebar
+ echo "Applying 06-BorderUnderTitle.patch"
+ patch --forward --strip=1 --input="${srcdir}/06-BorderUnderTitle.patch"
+
+ # Enables the use of a different font for Inactive windows
+ echo "Applying 07-InactiveFont.patch"
+ patch --forward --strip=1 --input="${srcdir}/07-InactiveFont.patch"
+
+ # Enables the use of FluxboxHandles or RoundedCorners
+ echo "Applying 08-FluxRoundedCorners.patch"
+ patch --forward --strip=1 --input="${srcdir}/08-FluxRoundedCorners.patch"
+
+ # Sets the top border to a single pixel
+ echo "Applying 09-TopBorder.patch"
+ patch --forward --strip=1 --input="${srcdir}/09-TopBorder.patch"
- # Enables the use of FluxboxHandles and RoundedCorners
- echo "Applying 02-FluxRoundedCorners.patch"
- patch --forward --strip=1 --input="${srcdir}/02-FluxRoundedCorners.patch"
+ # Sets the width of the title buttons
+ echo "Applying 10-ButtonWidth.patch"
+ patch --forward --strip=1 --input="${srcdir}/10-ButtonWidth.patch"
+
+ # Enables the use of 8 pixmaps for each border
+ echo "Applying 11-MultiBorder.patch"
+ patch --forward --strip=1 --input="${srcdir}/11-MultiBorder.patch"
+
+ # Enables the use of tips on FvwmButtons
+ echo "Applying 12-FvwmButtonsTips.patch"
+ patch --forward --strip=1 --input="${srcdir}/12-FvwmButtonsTips.patch"
+
+ # Enables rounded corners on FvwmIconMan
+ echo "Applying 13-FvwmIconMan.patch"
+ patch --forward --strip=1 --input="${srcdir}/13-FvwmIconMan.patch"
+
+ # Enables a hover event for buttons
+ echo "Applying 14-Hover.patch"
+ patch --forward --strip=1 --input="${srcdir}/14-Hover.patch"
+
+ # Menus with titles are opened so that the first item is under the pointer
+ #echo "Applying 15-FirstItemUnderPointer.patch"
+ #patch --forward --strip=1 --input="${srcdir}/15-FirstItemUnderPointer.patch"
+
+ # The geometry window and proxy windows have a single pixel border
+ echo "Applying 16-ThinGeometryProxy.patch"
+ patch --forward --strip=1 --input="${srcdir}/16-ThinGeometryProxy.patch"
+
+ # Enables the use of IconSize for MiniIcons
+ echo "Applying 17-MiniIconSize.patch"
+ patch --forward --strip=1 --input="${srcdir}/17-MiniIconSize.patch"
}
build() {