updated on Thu Jan 12 08:01:00 UTC 2012
[aur-mirror.git] / fvwm+ / 01-TranslucentMenus.patch
blob126b8a1cb16c78a9cea203d8647a1a73a07574b0
1 diff -U3 -r fvwm/colorset.c fvwm/colorset.c
2 --- fvwm/colorset.c 2010-04-28 18:55:22.000000000 +0200
3 +++ fvwm/colorset.c 2011-12-09 18:11:15.995378109 +0100
4 @@ -165,6 +165,8 @@
5 "NoIconTint",
6 "IconAlpha",
8 + "Translucent",
9 + "NoTranslucent",
10 NULL
13 @@ -626,6 +628,7 @@
14 char *fg_tint = NULL;
15 char *bg_tint = NULL;
16 char *icon_tint = NULL;
17 + char *translucent_tint = NULL;
18 Bool have_pixels_changed = False;
19 Bool has_icon_pixels_changed = False;
20 Bool has_fg_changed = False;
21 @@ -638,6 +641,7 @@
22 Bool has_fg_tint_changed = False;
23 Bool has_bg_tint_changed = False;
24 Bool has_icon_tint_changed = False;
25 + Bool has_translucent_tint_changed = False;
26 Bool has_pixmap_changed = False;
27 Bool has_shape_changed = False;
28 Bool has_image_alpha_changed = False;
29 @@ -765,6 +769,10 @@
30 case 21: /* Plain */
31 has_pixmap_changed = True;
32 free_colorset_background(cs, True);
33 + cs->is_translucent = False;
34 + cs->translucent_tint_percent = 0;
35 + cs->color_flags &= ~TRANSLUCENT_TINT_SUPPLIED;
36 + has_translucent_tint_changed = True;
37 break;
38 case 22: /* NoShape */
39 has_shape_changed = True;
40 @@ -931,6 +939,24 @@
41 cs->icon_alpha_percent = tmp;
43 break;
44 + case 42: /* Translucent */
45 + cs->is_translucent = True;
46 + parse_simple_tint(
47 + cs, args, &translucent_tint,
48 + TRANSLUCENT_TINT_SUPPLIED,
49 + &has_translucent_tint_changed, &percent,
50 + "Translucent");
51 + if (has_translucent_tint_changed)
52 + {
53 + cs->translucent_tint_percent = percent;
54 + }
55 + break;
56 + case 43: /* NoTranslucent */
57 + cs->is_translucent = False;
58 + cs->translucent_tint_percent = 0;
59 + cs->color_flags &= ~TRANSLUCENT_TINT_SUPPLIED;
60 + has_translucent_tint_changed = True;
61 + break;
62 default:
63 /* test for ?Gradient */
64 if (option[0] && StrEquals(&option[1], "Gradient"))
65 @@ -1634,6 +1660,27 @@
69 + * ---------- change the translucent tint colour ----------
70 + */
71 + if (has_translucent_tint_changed)
72 + {
73 + /* user specified colour */
74 + if (translucent_tint != NULL)
75 + {
76 + PictureFreeColors(
77 + dpy, Pcmap, &cs->translucent_tint, 1, 0, True);
78 + cs->translucent_tint = GetColor(translucent_tint);
79 + }
80 + else
81 + {
82 + /* default */
83 + PictureFreeColors(
84 + dpy, Pcmap, &cs->translucent_tint, 1, 0, True);
85 + cs->translucent_tint = GetColor(black);
86 + }
87 + }
89 + /*
90 * ---------- send new colorset to fvwm and clean up ----------
92 /* make sure the server has this to avoid races */
93 @@ -1729,6 +1776,7 @@
94 ncs->fgsh = GetColor(white);
95 ncs->tint = GetColor(black);
96 ncs->icon_tint = GetColor(black);
97 + ncs->translucent_tint = GetColor(black);
98 ncs->pixmap = XCreatePixmapFromBitmapData(
99 dpy, Scr.NoFocusWin,
100 &g_bits[4 * (nColorsets % 3)], 4, 4,
101 @@ -1746,6 +1794,7 @@
102 ncs->fgsh = GetForeShadow(ncs->fg, ncs->bg);
103 ncs->tint = GetColor(black);
104 ncs->icon_tint = GetColor(black);
105 + ncs->translucent_tint = GetColor(black);
107 ncs->fg_tint = ncs->bg_tint = GetColor(black);
108 /* set flags for fg contrast, bg average */
109 @@ -1757,6 +1806,7 @@
110 ncs->icon_alpha_percent = 100;
111 ncs->tint_percent = 0;
112 ncs->icon_tint_percent = 0;
113 + ncs->translucent_tint_percent = 0;
114 ncs->fg_tint_percent = ncs->bg_tint_percent = 0;
115 ncs->dither = (PictureDitherByDefault())? True:False;
116 nColorsets++;
117 diff -U3 -r fvwm/menuroot.h fvwm/menuroot.h
118 --- fvwm/menuroot.h 2007-01-13 16:07:14.000000000 +0100
119 +++ fvwm/menuroot.h 2011-12-09 18:11:15.998711359 +0100
120 @@ -146,6 +146,9 @@
121 int d_npixels;
122 } stored_pixels;
123 /* alloc pixels when dithering is used for gradients */
124 + /* x,y XMapRaise */
125 + int x;
126 + int y;
127 } MenuRootDynamic;
129 /* access macros to dynamic menu members */
130 diff -U3 -r fvwm/menus.c fvwm/menus.c
131 --- fvwm/menus.c 2011-08-07 00:03:31.000000000 +0200
132 +++ fvwm/menus.c 2011-12-09 18:11:15.998711359 +0100
133 @@ -85,6 +85,19 @@
134 #define SCTX_GET_MR(ctx) ((ctx).type == SCTX_MENU_ROOT ? \
135 (ctx).menu_root.menu_root : NULL)
137 +#define MENU_IS_TRANSLUCENT(mr,cs) \
138 + (!MR_IS_TEAR_OFF_MENU(mr) && CSET_IS_TRANSLUCENT(cs))
139 +#define MENU_IS_TRANSPARENT(mr,cs) \
140 + (MENU_IS_TRANSLUCENT(mr,cs) || CSET_IS_TRANSPARENT(cs))
141 +#define MR_IS_TRANSLUCENT_MENU(mr) \
142 + (!MR_IS_TEAR_OFF_MENU(mr) && MR_STYLE(mr) && \
143 + ST_HAS_MENU_CSET(MR_STYLE(mr)) && CSET_IS_TRANSLUCENT( \
144 + ST_CSET_MENU(MR_STYLE(mr))))
145 +#define MR_IS_TRANSPARENT_MENU(mr) \
146 + (MR_IS_TRANSLUCENT_MENU(mr) || (MR_STYLE(mr) && \
147 + ST_HAS_MENU_CSET(MR_STYLE(mr)) && CSET_IS_TRANSPARENT( \
148 + ST_CSET_MENU(MR_STYLE(mr)))))
150 /* ---------------------------- imports ------------------------------------ */
152 /* This external is safe. It's written only during startup. */
153 @@ -227,6 +240,8 @@
154 } mloop_static_info_t;
156 /* ---------------------------- forward declarations ----------------------- */
157 +static MenuRoot *seek_submenu_instance(
158 + MenuRoot *parent_menu, MenuItem *parent_item);
160 /* ---------------------------- local variables ---------------------------- */
162 @@ -392,12 +407,22 @@
163 Bool transparent_bg = False;
165 /* move it back */
166 - if (ST_HAS_MENU_CSET(MR_STYLE(mr)) &&
167 - CSET_IS_TRANSPARENT(ST_CSET_MENU(MR_STYLE(mr))))
168 + if (MR_IS_TRANSPARENT_MENU(mr))
170 transparent_bg = True;
171 get_menu_repaint_transparent_parameters(
172 &mrtp, mr, fw);
173 + if (MR_IS_TRANSLUCENT_MENU(mr) && MR_SUBMENU_ITEM(mr))
175 + MenuRoot *smr;
176 + smr = seek_submenu_instance(
177 + mr, MR_SUBMENU_ITEM(mr));
178 + if (smr)
180 + /* just unmap it here, popdown later */
181 + XUnmapWindow(dpy, MR_WINDOW(smr));
185 AnimatedMoveOfWindow(
186 MR_WINDOW(mr), act_x, act_y, act_x - MR_XANIMATION(mr),
187 @@ -1915,6 +1940,7 @@
188 /* Doh. Use the standard display instead. */
189 MR_CREATE_DPY(mr) = dpy;
191 + MR_IS_TEAR_OFF_MENU(mr) = 1;
193 else
195 @@ -2719,7 +2745,37 @@
197 MR_IS_PAINTED(mr) = 1;
198 /* paint the menu background */
199 - if (ms && ST_HAS_MENU_CSET(ms))
200 + if (MR_IS_TRANSLUCENT_MENU(mr))
202 + Pixmap trans = None;
203 + FvwmRenderAttributes fra;
204 + colorset_t *colorset = &Colorset[ST_CSET_MENU(ms)];
206 + fra.mask = 0;
207 + if (colorset->translucent_tint_percent > 0)
209 + fra.mask = FRAM_HAVE_TINT;
210 + fra.tint = colorset->translucent_tint;
211 + fra.tint_percent = colorset->translucent_tint_percent;
213 + if (MR_IS_BACKGROUND_SET(mr) == False)
215 + trans = PGraphicsCreateTranslucent(
216 + dpy, MR_WINDOW(mr), &fra,
217 + BACK_GC(ST_MENU_INACTIVE_GCS(ms)),
218 + MR_X(mr), MR_Y(mr), MR_WIDTH(mr), MR_HEIGHT(mr));
219 + XMapRaised(dpy, MR_WINDOW(mr));
220 + if (trans != None)
222 + XSetWindowBackgroundPixmap(
223 + dpy, MR_WINDOW(mr), trans);
224 + MR_IS_BACKGROUND_SET(mr) = True;
225 + clear_expose_menu_area(MR_WINDOW(mr), pevent);
226 + XFreePixmap(dpy, trans);
230 + else if (ms && ST_HAS_MENU_CSET(ms))
232 if (MR_IS_BACKGROUND_SET(mr) == False)
234 @@ -3526,10 +3582,7 @@
235 MR_HAS_POPPED_UP_RIGHT(mr) = 0;
237 MR_XANIMATION(parent_menu) += end_x - prev_x;
238 - if (ST_HAS_MENU_CSET(MR_STYLE(parent_menu)) &&
239 - CSET_IS_TRANSPARENT(
240 - ST_CSET_MENU(
241 - MR_STYLE(parent_menu))))
242 + if (MR_IS_TRANSPARENT_MENU(parent_menu))
244 transparent_bg = True;
245 get_menu_repaint_transparent_parameters(
246 @@ -3708,10 +3761,21 @@
249 XMoveWindow(dpy, MR_WINDOW(mr), x, y);
250 + MR_X(mr) = x;
251 + MR_Y(mr) = y;
252 XSelectInput(dpy, MR_WINDOW(mr), event_mask);
253 - XMapRaised(dpy, MR_WINDOW(mr));
254 - if (popdown_window)
255 - XUnmapWindow(dpy, popdown_window);
256 + if (MR_IS_TRANSLUCENT_MENU(mr))
258 + if (popdown_window)
259 + XUnmapWindow(dpy, popdown_window);
260 + paint_menu(mr, NULL, fw);
262 + else
264 + XMapRaised(dpy, MR_WINDOW(mr));
265 + if (popdown_window)
266 + XUnmapWindow(dpy, popdown_window);
268 XFlush(dpy);
269 MR_MAPPED_COPIES(mr)++;
270 MST_USAGE_COUNT(mr)++;
271 @@ -6252,16 +6316,122 @@
273 last = True;
275 - if (!last && CSET_IS_TRANSPARENT_PR_TINT(ST_CSET_MENU(ms)))
276 + if (!last &&
277 + (CSET_IS_TRANSPARENT_PR_TINT(ST_CSET_MENU(ms)) ||
278 + MR_IS_TRANSLUCENT_MENU(mr)))
280 /* too slow ... */
281 return;
283 - SetWindowBackgroundWithOffset(
284 - dpy, MR_WINDOW(mr), step_x - current_x, step_y - current_y,
285 - MR_WIDTH(mr), MR_HEIGHT(mr),
286 - &Colorset[ST_CSET_MENU(ms)], Pdepth,
287 - FORE_GC(MST_MENU_INACTIVE_GCS(mr)), False);
288 + if (MR_IS_TRANSLUCENT_MENU(mr))
290 + Pixmap trans, tmp;
291 + FvwmRenderAttributes fra;
292 + colorset_t *colorset = &Colorset[ST_CSET_MENU(ms)];
294 + fra.mask = 0;
295 + if (colorset->translucent_tint_percent > 0)
297 + fra.mask = FRAM_HAVE_TINT;
298 + fra.tint = colorset->translucent_tint;
299 + fra.tint_percent = colorset->translucent_tint_percent;
301 + if (current_x == step_x)
303 + /* Reuse the old pixmap for the part of the menu
304 + * that has not moved. (This can be extended to get
305 + * two new rectangles, one in each direction)
306 + *
307 + * It saves the unmapping of the window and makes
308 + * Things less flickering.
309 + */
310 + GC my_gc;
311 + unsigned long valuemask = GCSubwindowMode;
312 + XGCValues values;
313 + int out_y=0;
314 + values.subwindow_mode = IncludeInferiors;
315 + if (step_y < 0)
317 + out_y = -step_y;
319 + trans = XCreatePixmap(dpy, MR_WINDOW(mr), MR_WIDTH(mr),
320 + MR_HEIGHT(mr), Pdepth);
321 + my_gc = fvwmlib_XCreateGC(dpy, MR_WINDOW(mr), 0, NULL);
322 + XChangeGC(dpy, my_gc, valuemask, &values);
324 + XClearWindow(dpy, MR_WINDOW(mr));
326 + if (current_y < step_y)
328 + XCopyArea(dpy, MR_WINDOW(mr), trans, my_gc, 0,
329 + step_y-current_y, MR_WIDTH(mr),
330 + MR_HEIGHT(mr)-(step_y-current_y),
331 + 0,0);
332 + tmp = PGraphicsCreateTranslucent(
333 + dpy, MR_WINDOW(mr), &fra,
334 + BACK_GC(ST_MENU_INACTIVE_GCS(ms)),
335 + current_x, current_y+MR_HEIGHT(mr),
336 + MR_WIDTH(mr), step_y-current_y);
338 + XCopyArea(dpy, tmp, trans, my_gc, 0, 0,
339 + MR_WIDTH(mr), step_y-current_y,0,
340 + MR_HEIGHT(mr)-(step_y-current_y));
342 + else
344 + XCopyArea(dpy, MR_WINDOW(mr), trans, my_gc, 0,
345 + 0, MR_WIDTH(mr),
346 + MR_HEIGHT(mr)-(current_y-step_y), 0,
347 + current_y-step_y);
348 + tmp = PGraphicsCreateTranslucent(
349 + dpy, MR_WINDOW(mr), &fra,
350 + BACK_GC(ST_MENU_INACTIVE_GCS(ms)),
351 + current_x,step_y, MR_WIDTH(mr),
352 + current_y-step_y);
353 + XCopyArea(dpy, tmp, trans, my_gc, 0, 0,
354 + MR_WIDTH(mr), current_y-step_y,0,
355 + out_y);
357 + MR_X(mr) = step_x;
358 + MR_Y(mr) = step_y;
359 + XFreePixmap(dpy, tmp);
360 + XFreeGC(dpy,my_gc);
361 + }
362 + else
364 + XUnmapWindow(dpy, MR_WINDOW(mr));
365 + MR_X(mr) = step_x;
366 + MR_Y(mr) = step_y;
367 + trans = PGraphicsCreateTranslucent(
368 + dpy, MR_WINDOW(mr), &fra,
369 + BACK_GC(ST_MENU_INACTIVE_GCS(ms)),
370 + step_x, step_y, MR_WIDTH(mr),
371 + MR_HEIGHT(mr));
372 + XMapRaised(dpy, MR_WINDOW(mr));
374 + XSetWindowBackgroundPixmap(
375 + dpy, MR_WINDOW(mr), trans);
376 + XFreePixmap(dpy, trans);
377 + if (current_x == step_x)
379 + /* Redraw the border */
380 + RelieveRectangle(
381 + dpy, MR_WINDOW(mr), 0, 0, MR_WIDTH(mr) - 1,
382 + MR_HEIGHT(mr) - 1, (Pdepth < 2) ?
383 + SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)) :
384 + HILIGHT_GC(MST_MENU_INACTIVE_GCS(mr)),
385 + SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)),
386 + MST_BORDER_WIDTH(mr));
389 + else
391 + SetWindowBackgroundWithOffset(
392 + dpy, MR_WINDOW(mr), step_x - current_x,
393 + step_y - current_y, MR_WIDTH(mr), MR_HEIGHT(mr),
394 + &Colorset[ST_CSET_MENU(ms)], Pdepth,
395 + FORE_GC(MST_MENU_INACTIVE_GCS(mr)), False);
400 @@ -6302,10 +6472,7 @@
402 if (!is_bg_set)
404 - SetWindowBackground(
405 - dpy, MR_WINDOW(mr), MR_WIDTH(mr), MR_HEIGHT(mr),
406 - &Colorset[ST_CSET_MENU(ms)], Pdepth,
407 - FORE_GC(MST_MENU_INACTIVE_GCS(mr)), False);
408 + update_transparent_menu_bg(prtm, x, y, x, y, end_x, end_y);
410 /* redraw the background of non active item */
411 for (mi = MR_FIRST_ITEM(mr); mi != NULL; mi = MI_NEXT_ITEM(mi))
412 @@ -6929,10 +7096,12 @@
413 SetWindowBackground(
414 dpy, MR_WINDOW(mr), MR_WIDTH(mr),
415 MR_HEIGHT(mr),
416 - &Colorset[ST_CSET_MENU(ms)],
417 - Pdepth,
418 + &Colorset[ST_CSET_MENU(ms)], Pdepth,
419 FORE_GC(MST_MENU_INACTIVE_GCS(mr)),
420 - True);
421 + False);
422 + XClearArea(
423 + dpy, MR_WINDOW(mr), 0, 0, MR_WIDTH(mr),
424 + MR_HEIGHT(mr), True);
426 else if ((ST_HAS_ACTIVE_CSET(ms) &&
427 ST_CSET_ACTIVE(ms) == cset) ||
428 diff -U3 -r fvwm/menus.h fvwm/menus.h
429 --- fvwm/menus.h 2007-01-27 12:51:15.000000000 +0100
430 +++ fvwm/menus.h 2011-12-09 18:11:16.002044610 +0100
431 @@ -15,6 +15,9 @@
432 #define IS_MENU_RETURN(x) \
433 ((x)==MENU_DONE || (x)==MENU_ABORTED || (x)==MENU_SUBMENU_TORN_OFF)
435 +#define MR_X(m) ((m)->d->x)
436 +#define MR_Y(m) ((m)->d->y)
438 struct MenuRoot;
439 struct MenuStyle;
440 struct MenuReturn;
441 diff -U3 -r libs/Colorset.h libs/Colorset.h
442 --- libs/Colorset.h 2011-04-28 00:35:21.000000000 +0200
443 +++ libs/Colorset.h 2011-12-09 18:11:16.002044610 +0100
444 @@ -51,6 +51,10 @@
445 Bool dither;
446 Bool allows_buffered_transparency;
447 Bool is_maybe_root_transparent;
448 + /* only use by fvwm menu (non tear-off) */
449 + Bool is_translucent;
450 + Pixel translucent_tint;
451 + unsigned int translucent_tint_percent : 7;
452 #endif
453 } colorset_t;
455 @@ -78,6 +82,7 @@
456 #define FG_TINT_SUPPLIED 0x100
457 #define BG_TINT_SUPPLIED 0x200
458 #define ICON_TINT_SUPPLIED 0x400
459 +#define TRANSLUCENT_TINT_SUPPLIED 0x800
460 #endif
462 /* colorsets are stored as an array of structs to permit fast dereferencing */
463 @@ -153,6 +158,11 @@
464 (cset != NULL && cset->pixmap == ParentRelative && \
465 cset->tint_percent > 0)
467 +#define CSET_IS_TRANSLUCENT(cset) \
468 + (cset >= 0 && Colorset[cset].is_translucent)
469 +#define CSETS_IS_TRANSLUCENT(cset) \
470 + (cset && cset->is_translucent)
472 #ifndef FVWM_COLORSET_PRIVATE
473 /* Create n new colorsets, fvwm/colorset.c does its own thing (different size)
475 diff -U3 -r libs/PictureGraphics.c libs/PictureGraphics.c
476 --- libs/PictureGraphics.c 2008-02-04 00:12:19.000000000 +0100
477 +++ libs/PictureGraphics.c 2011-12-09 18:11:16.002044610 +0100
478 @@ -1361,7 +1361,7 @@
482 -#if 0 /* humm... maybe useful one day with menus */
483 +#if 1 /* humm... maybe useful one day with menus */
484 Pixmap PGraphicsCreateTranslucent(
485 Display *dpy, Window win, FvwmRenderAttributes *fra, GC gc,
486 int x, int y, int width, int height)
487 diff -U3 -r libs/PictureGraphics.h libs/PictureGraphics.h
488 --- libs/PictureGraphics.h 2006-05-09 22:46:29.000000000 +0200
489 +++ libs/PictureGraphics.h 2011-12-09 18:11:16.002044610 +0100
490 @@ -122,7 +122,9 @@
491 Display *dpy, Window win, Pixel tint, int tint_percent,
492 Drawable dest, Bool dest_is_a_window, GC gc, GC mono_gc, GC alpha_gc,
493 int dest_x, int dest_y, int dest_w, int dest_h);
495 +Pixmap PGraphicsCreateTranslucent(
496 + Display *dpy, Window win, FvwmRenderAttributes *fra, GC gc,
497 + int x, int y, int width, int height);
498 /* never used ! */
499 Pixmap PGraphicsCreateDitherPixmap(
500 Display *dpy, Window win, Drawable src, Pixmap mask, int depth, GC gc,