summarylogtreecommitdiffstats
path: root/01-TranslucentMenus.patch
diff options
context:
space:
mode:
Diffstat (limited to '01-TranslucentMenus.patch')
-rw-r--r--01-TranslucentMenus.patch500
1 files changed, 500 insertions, 0 deletions
diff --git a/01-TranslucentMenus.patch b/01-TranslucentMenus.patch
new file mode 100644
index 000000000000..126b8a1cb16c
--- /dev/null
+++ b/01-TranslucentMenus.patch
@@ -0,0 +1,500 @@
+diff -U3 -r fvwm/colorset.c fvwm/colorset.c
+--- fvwm/colorset.c 2010-04-28 18:55:22.000000000 +0200
++++ fvwm/colorset.c 2011-12-09 18:11:15.995378109 +0100
+@@ -165,6 +165,8 @@
+ "NoIconTint",
+ "IconAlpha",
+
++ "Translucent",
++ "NoTranslucent",
+ NULL
+ };
+
+@@ -626,6 +628,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;
+@@ -638,6 +641,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;
+@@ -765,6 +769,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;
+@@ -931,6 +939,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"))
+@@ -1634,6 +1660,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 */
+@@ -1729,6 +1776,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,
+@@ -1746,6 +1794,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 */
+@@ -1757,6 +1806,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++;
+diff -U3 -r fvwm/menuroot.h fvwm/menuroot.h
+--- fvwm/menuroot.h 2007-01-13 16:07:14.000000000 +0100
++++ fvwm/menuroot.h 2011-12-09 18:11:15.998711359 +0100
+@@ -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 -U3 -r fvwm/menus.c fvwm/menus.c
+--- fvwm/menus.c 2011-08-07 00:03:31.000000000 +0200
++++ fvwm/menus.c 2011-12-09 18:11:15.998711359 +0100
+@@ -85,6 +85,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. */
+@@ -227,6 +240,8 @@
+ } mloop_static_info_t;
+
+ /* ---------------------------- forward declarations ----------------------- */
++static MenuRoot *seek_submenu_instance(
++ MenuRoot *parent_menu, MenuItem *parent_item);
+
+ /* ---------------------------- local variables ---------------------------- */
+
+@@ -392,12 +407,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),
+@@ -1915,6 +1940,7 @@
+ /* Doh. Use the standard display instead. */
+ MR_CREATE_DPY(mr) = dpy;
+ }
++ MR_IS_TEAR_OFF_MENU(mr) = 1;
+ }
+ else
+ {
+@@ -2719,7 +2745,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)
+ {
+@@ -3526,10 +3582,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(
+@@ -3708,10 +3761,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)++;
+@@ -6252,16 +6316,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);
++ }
+ }
+
+
+@@ -6302,10 +6472,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))
+@@ -6929,10 +7096,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) ||
+diff -U3 -r fvwm/menus.h fvwm/menus.h
+--- fvwm/menus.h 2007-01-27 12:51:15.000000000 +0100
++++ fvwm/menus.h 2011-12-09 18:11:16.002044610 +0100
+@@ -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 -U3 -r libs/Colorset.h libs/Colorset.h
+--- libs/Colorset.h 2011-04-28 00:35:21.000000000 +0200
++++ libs/Colorset.h 2011-12-09 18:11:16.002044610 +0100
+@@ -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 -U3 -r libs/PictureGraphics.c libs/PictureGraphics.c
+--- libs/PictureGraphics.c 2008-02-04 00:12:19.000000000 +0100
++++ libs/PictureGraphics.c 2011-12-09 18:11:16.002044610 +0100
+@@ -1361,7 +1361,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)
+diff -U3 -r libs/PictureGraphics.h libs/PictureGraphics.h
+--- libs/PictureGraphics.h 2006-05-09 22:46:29.000000000 +0200
++++ libs/PictureGraphics.h 2011-12-09 18:11:16.002044610 +0100
+@@ -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,