From: Manuel Giraud <manuel@ledu-giraud.fr>
To: 56538@debbugs.gnu.org
Subject: bug#56538: 29.0.50; [PATCH] Colored highlight in Lucid backend
Date: Wed, 13 Jul 2022 15:38:35 +0200 [thread overview]
Message-ID: <87wnch16as.fsf@elite.giraud> (raw)
[-- Attachment #1: Type: text/plain, Size: 499 bytes --]
Hi,
Here is a patch that add a X resource to color the highlighted menu
entry in the Lucid backend. There is much going on here because I
needed to understand this code and end up needed to refactor some part
to implement this feature. This was about ten clunky patches that I
finally squashed into this one.
I have tested that it works with the 2 following configuration
- --with-x-toolkit=athena
- --with-x-toolkit=athena --without-xft --without-cairo
Here is how it looks like:
[-- Attachment #2: sshot.png --]
[-- Type: image/png, Size: 98806 bytes --]
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0001-Colored-menu-highlight-in-Lucid-backend.patch --]
[-- Type: text/x-patch, Size: 26131 bytes --]
From f51e1dbd3174d727a12e673e0b820b4cf35e7046 Mon Sep 17 00:00:00 2001
From: Manuel Giraud <manuel@ledu-giraud.fr>
Date: Mon, 11 Jul 2022 11:14:08 +0200
Subject: [PATCH] Colored menu highlight in Lucid backend
* lwlib/xlwmenuP.h:
* lwlib/xlwmenu.h:
* lwlib/xlwmenu.c: Introduce resources to handle colored highlighting
of menu entries.
* doc/emacs/xresources.texi (Lucid Resources): Documentation.
---
doc/emacs/xresources.texi | 4 +
etc/NEWS | 4 +
| 341 ++++++++++++++++++++++++++++----------
| 14 ++
| 18 +-
5 files changed, 293 insertions(+), 88 deletions(-)
diff --git a/doc/emacs/xresources.texi b/doc/emacs/xresources.texi
index 2c2700bc15..f8be06b5e7 100644
--- a/doc/emacs/xresources.texi
+++ b/doc/emacs/xresources.texi
@@ -449,6 +449,10 @@ Lucid Resources
Foreground color.
@item disabledForeground
Foreground color for a disabled menu item.
+@item highlightForeground
+Foreground color for a highlighted menu item.
+@item highlightBackground
+Background color for a highlighted menu item.
@ifnottex
@item horizontalSpacing
Horizontal spacing in pixels between items. Default is 3.
diff --git a/etc/NEWS b/etc/NEWS
index bf36316890..b33d604a6f 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -544,6 +544,10 @@ and pop-up menus.
This controls the style of the pre-edit and status areas of X input
methods.
++++
+** New X resources: "highlightForeground" and "highlightBackground"
+This controls colors used for highlighted menu item.
+
+++
** On X11, Emacs now tries to synchronize window resize with the window manager.
This leads to less flicker and empty areas of a frame being displayed
--git a/lwlib/xlwmenu.c b/lwlib/xlwmenu.c
index 68f49e646d..32310e18ef 100644
--- a/lwlib/xlwmenu.c
+++ b/lwlib/xlwmenu.c
@@ -121,6 +121,10 @@ #define DEFAULT_FONTNAME "XtDefaultFont"
offset(menu.disabled_foreground), XtRString, (XtPointer)NULL},
{XtNbuttonForeground, XtCButtonForeground, XtRPixel, sizeof(Pixel),
offset(menu.button_foreground), XtRString, "XtDefaultForeground"},
+ {XtNhighlightForeground, XtCHighlightForeground, XtRPixel, sizeof(Pixel),
+ offset(menu.highlight_foreground), XtRString, "XtDefaultForeground"},
+ {XtNhighlightBackground, XtCHighlightBackground, XtRPixel, sizeof(Pixel),
+ offset(menu.highlight_background), XtRImmediate, (XtPointer)-1},
{XtNmargin, XtCMargin, XtRDimension, sizeof(Dimension),
offset(menu.margin), XtRImmediate, (XtPointer)1},
{XtNhorizontalSpacing, XtCMargin, XtRDimension, sizeof(Dimension),
@@ -142,6 +146,19 @@ #define DEFAULT_FONTNAME "XtDefaultFont"
{XmNbottomShadowPixmap, XmCBottomShadowPixmap, XtRPixmap, sizeof (Pixmap),
offset (menu.bottom_shadow_pixmap), XtRImmediate, (XtPointer)None},
+ {XmNtopHighlightShadowColor, XmCTopHighlightShadowColor, XtRPixel,
+ sizeof (Pixel), offset (menu.top_highlight_shadow_color),
+ XtRImmediate, (XtPointer)-1},
+ {XmNbottomHighlightShadowColor, XmCBottomHighlightShadowColor, XtRPixel,
+ sizeof (Pixel), offset (menu.bottom_highlight_shadow_color),
+ XtRImmediate, (XtPointer)-1},
+ {XmNtopHighlightShadowPixmap, XmCTopHighlightShadowPixmap, XtRPixmap,
+ sizeof (Pixmap), offset (menu.top_highlight_shadow_pixmap),XtRImmediate,
+ (XtPointer)None},
+ {XmNbottomHighlightShadowPixmap, XmCBottomHighlightShadowPixmap, XtRPixmap,
+ sizeof (Pixmap), offset (menu.bottom_highlight_shadow_pixmap),XtRImmediate,
+ (XtPointer)None},
+
{XtNopen, XtCCallback, XtRCallback, sizeof(XtPointer),
offset(menu.open), XtRCallback, (XtPointer)NULL},
{XtNselect, XtCCallback, XtRCallback, sizeof(XtPointer),
@@ -570,8 +587,7 @@ draw_arrow (XlwMenuWidget mw,
int down_p)
{
Display *dpy = XtDisplay (mw);
- GC top_gc = mw->menu.shadow_top_gc;
- GC bottom_gc = mw->menu.shadow_bottom_gc;
+ GC top_gc, bottom_gc;
int thickness = mw->menu.shadow_thickness;
int height = width;
XPoint pt[10];
@@ -584,10 +600,14 @@ draw_arrow (XlwMenuWidget mw,
if (down_p)
{
- GC temp;
- temp = top_gc;
- top_gc = bottom_gc;
- bottom_gc = temp;
+ /* XXX the following permutation is on purpose */
+ top_gc = mw->menu.highlight_shadow_bottom_gc;
+ bottom_gc = mw->menu.highlight_shadow_top_gc;
+ }
+ else
+ {
+ top_gc = mw->menu.shadow_top_gc;
+ bottom_gc = mw->menu.shadow_bottom_gc;
}
pt[0].x = x;
@@ -621,8 +641,12 @@ draw_arrow (XlwMenuWidget mw,
XFillPolygon (dpy, window, bottom_gc, pt, 4, Convex, CoordModeOrigin);
}
-
-
+/*
+ * Generic draw shadow rectangle function. It is used to draw menus, menu items
+ * and also toggle buttons. When ERASE_P is true, it clears shadows. DOWN_P is
+ * true when a menu item is pushed or a button toggled. TOP_GC and BOTTOM_GC
+ * are the graphic contexts used to draw the top and bottom shadow respectively.
+ */
static void
draw_shadow_rectangle (XlwMenuWidget mw,
Window window,
@@ -631,14 +655,28 @@ draw_shadow_rectangle (XlwMenuWidget mw,
int width,
int height,
int erase_p,
- int down_p)
+ int down_p,
+ GC top_gc,
+ GC bottom_gc)
{
Display *dpy = XtDisplay (mw);
- GC top_gc = !erase_p ? mw->menu.shadow_top_gc : mw->menu.background_gc;
- GC bottom_gc = !erase_p ? mw->menu.shadow_bottom_gc : mw->menu.background_gc;
int thickness = !x && !y ? mw->menu.border_thickness : mw->menu.shadow_thickness;
XPoint points [4];
+ /* Choose correct GC with a standard default if NULL */
+ if (erase_p)
+ {
+ top_gc = mw->menu.background_gc;
+ bottom_gc = mw->menu.background_gc;
+ }
+ else
+ {
+ if (top_gc == NULL)
+ top_gc = mw->menu.shadow_top_gc;
+ if (bottom_gc == NULL)
+ bottom_gc = mw->menu.shadow_bottom_gc;
+ }
+
if (!erase_p && width == height && width == toggle_button_width (mw))
{
points [0].x = x;
@@ -654,6 +692,7 @@ draw_shadow_rectangle (XlwMenuWidget mw,
points, 4, Convex, CoordModeOrigin);
}
+
if (!erase_p && down_p)
{
GC temp;
@@ -662,6 +701,7 @@ draw_shadow_rectangle (XlwMenuWidget mw,
bottom_gc = temp;
}
+ /* Do draw (or erase) shadows */
points [0].x = x;
points [0].y = y;
points [1].x = x + width;
@@ -709,14 +749,28 @@ draw_shadow_rhombus (XlwMenuWidget mw,
int width,
int height,
int erase_p,
- int down_p)
+ int down_p,
+ GC top_gc,
+ GC bottom_gc)
{
Display *dpy = XtDisplay (mw);
- GC top_gc = !erase_p ? mw->menu.shadow_top_gc : mw->menu.background_gc;
- GC bottom_gc = !erase_p ? mw->menu.shadow_bottom_gc : mw->menu.background_gc;
int thickness = mw->menu.shadow_thickness;
XPoint points [4];
+ /* Choose correct GC with a standard default if NULL */
+ if (erase_p)
+ {
+ top_gc = mw->menu.background_gc;
+ bottom_gc = mw->menu.background_gc;
+ }
+ else
+ {
+ if (top_gc == NULL)
+ top_gc = mw->menu.shadow_top_gc;
+ if (bottom_gc == NULL)
+ top_gc = mw->menu.shadow_bottom_gc;
+ }
+
if (!erase_p && width == height && width == radio_button_width (mw))
{
points [0].x = x;
@@ -784,15 +838,29 @@ draw_shadow_rhombus (XlwMenuWidget mw,
toggle button is selected. */
static void
-draw_toggle (XlwMenuWidget mw, Window window, int x, int y, int selected_p)
+draw_toggle (XlwMenuWidget mw, Window window, int x, int y, int selected_p,
+ int highlighted_p)
{
int width, height;
+ GC top_gc, bottom_gc;
+
+ if (highlighted_p)
+ {
+ top_gc = mw->menu.highlight_shadow_top_gc;
+ bottom_gc = mw->menu.highlight_shadow_bottom_gc;
+ }
+ else
+ {
+ top_gc = mw->menu.shadow_top_gc;
+ bottom_gc = mw->menu.shadow_bottom_gc;
+ }
width = toggle_button_width (mw);
height = width;
x += mw->menu.horizontal_spacing;
y += (MENU_FONT_ASCENT (mw) - height) / 2;
- draw_shadow_rectangle (mw, window, x, y, width, height, False, selected_p);
+ draw_shadow_rectangle (mw, window, x, y, width, height, False,
+ selected_p, top_gc, bottom_gc);
}
@@ -801,15 +869,29 @@ draw_toggle (XlwMenuWidget mw, Window window, int x, int y, int selected_p)
toggle button is selected. */
static void
-draw_radio (XlwMenuWidget mw, Window window, int x, int y, int selected_p)
+draw_radio (XlwMenuWidget mw, Window window, int x, int y, int selected_p,
+ int highlighted_p)
{
int width, height;
+ GC top_gc, bottom_gc;
+
+ if (highlighted_p)
+ {
+ top_gc = mw->menu.highlight_shadow_top_gc;
+ bottom_gc = mw->menu.highlight_shadow_bottom_gc;
+ }
+ else
+ {
+ top_gc = mw->menu.shadow_top_gc;
+ bottom_gc = mw->menu.shadow_bottom_gc;
+ }
width = radio_button_width (mw);
height = width;
x += mw->menu.horizontal_spacing;
y += (MENU_FONT_ASCENT (mw) - height) / 2;
- draw_shadow_rhombus (mw, window, x, y, width, height, False, selected_p);
+ draw_shadow_rhombus (mw, window, x, y, width, height, False, selected_p,
+ top_gc, bottom_gc);
}
@@ -968,6 +1050,33 @@ separator_height (enum menu_separator separator)
}
}
+static void
+draw_highlight (XlwMenuWidget mw,
+ Window window,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ Display *dpy = XtDisplay (mw);
+ XPoint points [4];
+
+ points [0].x = x;
+ points [0].y = y;
+ points [1].x = x + width;
+ points [1].y = y;
+ points [2].x = x + width;
+ points [2].y = y + height;
+ points [3].x = x;
+ points [3].y = y + height;
+ XFillPolygon (dpy, window,
+ mw->menu.highlight_background_gc,
+ points, 4, Convex, CoordModeOrigin);
+
+ draw_shadow_rectangle(mw, window, x, y, width, height, False, False,
+ mw->menu.highlight_shadow_top_gc,
+ mw->menu.highlight_shadow_bottom_gc);
+}
/* Display the menu item and increment where.x and where.y to show how large
the menu item was. */
@@ -983,7 +1092,6 @@ display_menu_item (XlwMenuWidget mw,
{
GC deco_gc;
GC text_gc;
- int font_height = MENU_FONT_HEIGHT (mw);
int font_ascent = MENU_FONT_ASCENT (mw);
int shadow = mw->menu.shadow_thickness;
int margin = mw->menu.margin;
@@ -1032,12 +1140,21 @@ display_menu_item (XlwMenuWidget mw,
/* pick the foreground and background GC. */
if (val->enabled)
- text_gc = mw->menu.foreground_gc;
+ if (highlighted_p)
+ text_gc = mw->menu.highlight_foreground_gc;
+ else
+ text_gc = mw->menu.foreground_gc;
else
text_gc = mw->menu.disabled_gc;
deco_gc = mw->menu.foreground_gc;
#if defined USE_CAIRO || defined HAVE_XFT
- xftfg = val->enabled ? &mw->menu.xft_fg : &mw->menu.xft_disabled_fg;
+ if (val->enabled)
+ if (highlighted_p)
+ xftfg = &mw->menu.xft_highlight_fg;
+ else
+ xftfg = &mw->menu.xft_fg;
+ else
+ xftfg = &mw->menu.xft_disabled_fg;
#endif
if (separator_p)
@@ -1048,8 +1165,11 @@ display_menu_item (XlwMenuWidget mw,
{
int x_offset = x + h_spacing + shadow;
char* display_string = resource_widget_value (mw, val);
- draw_shadow_rectangle (mw, ws->pixmap, x, y, width, height, True,
- False);
+ /* Clears shadows and maybe highlight */
+ draw_shadow_rectangle (mw, ws->pixmap, x, y, width, height,
+ True, False, NULL, NULL);
+ if (highlighted_p)
+ draw_highlight (mw, ws->pixmap, x, y, width, height);
/* Deal with centering a menu title. */
if (!horizontal_p && !val->contents && !val->call_data)
@@ -1095,10 +1215,10 @@ display_menu_item (XlwMenuWidget mw,
{
if (val->button_type == BUTTON_TYPE_TOGGLE)
draw_toggle (mw, ws->pixmap, x, y + v_spacing + shadow,
- val->selected);
+ val->selected, highlighted_p);
else if (val->button_type == BUTTON_TYPE_RADIO)
draw_radio (mw, ws->pixmap, x, y + v_spacing + shadow,
- val->selected);
+ val->selected, highlighted_p);
if (val->contents)
{
@@ -1145,25 +1265,18 @@ display_menu_item (XlwMenuWidget mw,
}
else
{
- XDrawRectangle (XtDisplay (mw), ws->pixmap,
- mw->menu.background_gc,
- x + shadow, y + shadow,
- label_width + h_spacing - 1,
- font_height + 2 * v_spacing - 1);
- draw_shadow_rectangle (mw, ws->pixmap, x, y, width, height,
- True, False);
+ /* If not highlighted, clears shadows for horizontal
+ menu item */
+ if (!highlighted_p)
+ draw_shadow_rectangle (mw, ws->pixmap, x, y, width, height,
+ True, False, NULL, NULL);
}
#ifdef USE_CAIRO
if (ws->xft_draw)
cairo_surface_flush (cairo_get_target (ws->xft_draw));
#endif
-
- if (highlighted_p)
- draw_shadow_rectangle (mw, ws->pixmap, x, y, width, height, False,
- False);
}
}
-
where->x += width;
where->y += height;
}
@@ -1257,7 +1370,7 @@ display_menu (XlwMenuWidget mw,
if (!just_compute_p)
{
draw_shadow_rectangle (mw, ws->pixmap, 0, 0, ws->width, ws->height,
- False, False);
+ False, False, NULL, NULL);
XCopyArea (XtDisplay (mw), ws->pixmap, ws->window,
mw->menu.foreground_gc, 0, 0, ws->width, ws->height, 0, 0);
}
@@ -1714,6 +1827,16 @@ #define BRIGHTNESS(color) (((color) & 0xff) + (((color) >> 8) & 0xff) + (((color
xgcv.foreground = mw->core.background_pixel;
xgcv.background = mw->menu.foreground;
mw->menu.background_gc = XtGetGC ((Widget)mw, mask, &xgcv);
+
+ xgcv.foreground = mw->menu.highlight_foreground;
+ xgcv.background = (mw->menu.highlight_background == -1) ?
+ mw->core.background_pixel : mw->menu.highlight_background;
+ mw->menu.highlight_foreground_gc = XtGetGC ((Widget)mw, mask, &xgcv);
+
+ xgcv.foreground = (mw->menu.highlight_background == -1) ?
+ mw->core.background_pixel : mw->menu.highlight_background;
+ xgcv.background = mw->menu.foreground;
+ mw->menu.highlight_background_gc = XtGetGC ((Widget)mw, mask, &xgcv);
}
static void
@@ -1724,12 +1847,16 @@ release_drawing_gcs (XlwMenuWidget mw)
XtReleaseGC ((Widget) mw, mw->menu.disabled_gc);
XtReleaseGC ((Widget) mw, mw->menu.inactive_button_gc);
XtReleaseGC ((Widget) mw, mw->menu.background_gc);
+ XtReleaseGC ((Widget) mw, mw->menu.highlight_foreground_gc);
+ XtReleaseGC ((Widget) mw, mw->menu.highlight_background_gc);
/* let's get some segvs if we try to use these... */
mw->menu.foreground_gc = (GC) -1;
mw->menu.button_gc = (GC) -1;
mw->menu.disabled_gc = (GC) -1;
mw->menu.inactive_button_gc = (GC) -1;
mw->menu.background_gc = (GC) -1;
+ mw->menu.highlight_foreground_gc = (GC) -1;
+ mw->menu.highlight_background_gc = (GC) -1;
}
#ifndef emacs
@@ -1738,29 +1865,34 @@ #define MINL(x,y) ((((unsigned long) (x)) < ((unsigned long) (y))) \
#endif
static void
-make_shadow_gcs (XlwMenuWidget mw)
+compute_shadow_colors(XlwMenuWidget mw,
+ Pixel *top_color,
+ Pixel *bottom_color,
+ Boolean *free_top_p,
+ Boolean *free_bottom_p,
+ Pixmap *top_pixmap,
+ Pixmap *bottom_pixmap,
+ Pixel fore_color,
+ Pixel back_color)
{
- XGCValues xgcv;
- unsigned long pm = 0;
Display *dpy = XtDisplay ((Widget) mw);
Screen *screen = XtScreen ((Widget) mw);
Colormap cmap = mw->core.colormap;
XColor topc, botc;
int top_frobbed = 0, bottom_frobbed = 0;
- mw->menu.free_top_shadow_color_p = 0;
- mw->menu.free_bottom_shadow_color_p = 0;
+ *free_top_p = False;
+ *free_bottom_p = False;
- if (mw->menu.top_shadow_color == -1)
- mw->menu.top_shadow_color = mw->core.background_pixel;
+ if (*top_color == -1)
+ *top_color = back_color;
- if (mw->menu.bottom_shadow_color == -1)
- mw->menu.bottom_shadow_color = mw->menu.foreground;
+ if (*bottom_color == -1)
+ *bottom_color = fore_color;
- if (mw->menu.top_shadow_color == mw->core.background_pixel ||
- mw->menu.top_shadow_color == mw->menu.foreground)
+ if (*top_color == back_color || *top_color == fore_color)
{
- topc.pixel = mw->core.background_pixel;
+ topc.pixel = back_color;
#ifdef emacs
if (x_alloc_lighter_color_for_widget ((Widget) mw, dpy, cmap,
&topc.pixel,
@@ -1774,15 +1906,14 @@ make_shadow_gcs (XlwMenuWidget mw)
if (XAllocColor (dpy, cmap, &topc))
#endif
{
- mw->menu.top_shadow_color = topc.pixel;
- mw->menu.free_top_shadow_color_p = 1;
+ *top_color = topc.pixel;
+ *free_top_p = True;
top_frobbed = 1;
}
}
- if (mw->menu.bottom_shadow_color == mw->menu.foreground ||
- mw->menu.bottom_shadow_color == mw->core.background_pixel)
+ if (*bottom_color == fore_color || *bottom_color == back_color)
{
- botc.pixel = mw->core.background_pixel;
+ botc.pixel = back_color;
#ifdef emacs
if (x_alloc_lighter_color_for_widget ((Widget) mw, dpy, cmap,
&botc.pixel,
@@ -1795,8 +1926,8 @@ make_shadow_gcs (XlwMenuWidget mw)
if (XAllocColor (dpy, cmap, &botc))
#endif
{
- mw->menu.bottom_shadow_color = botc.pixel;
- mw->menu.free_bottom_shadow_color_p = 1;
+ *bottom_color = botc.pixel;
+ *free_bottom_p = True;
bottom_frobbed = 1;
}
}
@@ -1805,52 +1936,76 @@ make_shadow_gcs (XlwMenuWidget mw)
{
if (topc.pixel == botc.pixel)
{
- if (botc.pixel == mw->menu.foreground)
+ if (botc.pixel == fore_color)
{
- if (mw->menu.free_top_shadow_color_p)
+ if (*free_top_p)
{
- x_free_dpy_colors (dpy, screen, cmap,
- &mw->menu.top_shadow_color, 1);
- mw->menu.free_top_shadow_color_p = 0;
+ x_free_dpy_colors (dpy, screen, cmap, top_color, 1);
+ *free_top_p = False;
}
- mw->menu.top_shadow_color = mw->core.background_pixel;
+ *top_color = back_color;
}
else
{
- if (mw->menu.free_bottom_shadow_color_p)
+ if (*free_bottom_p)
{
- x_free_dpy_colors (dpy, screen, cmap,
- &mw->menu.bottom_shadow_color, 1);
- mw->menu.free_bottom_shadow_color_p = 0;
+ x_free_dpy_colors (dpy, screen, cmap, bottom_color, 1);
+ *free_bottom_p = False;
}
- mw->menu.bottom_shadow_color = mw->menu.foreground;
+ *bottom_color = fore_color;
}
}
}
- if (!mw->menu.top_shadow_pixmap
- && mw->menu.top_shadow_color == mw->core.background_pixel)
+ if (!*top_pixmap && *top_color == back_color)
{
- mw->menu.top_shadow_pixmap = mw->menu.gray_pixmap;
- if (mw->menu.free_top_shadow_color_p)
+ *top_pixmap = mw->menu.gray_pixmap;
+ if (*free_top_p)
{
- x_free_dpy_colors (dpy, screen, cmap, &mw->menu.top_shadow_color, 1);
- mw->menu.free_top_shadow_color_p = 0;
+ x_free_dpy_colors (dpy, screen, cmap, top_color, 1);
+ *free_top_p = False;
}
- mw->menu.top_shadow_color = mw->menu.foreground;
+ *top_color = fore_color;
}
- if (!mw->menu.bottom_shadow_pixmap
- && mw->menu.bottom_shadow_color == mw->core.background_pixel)
+ if (!*bottom_pixmap && *bottom_color == back_color)
{
- mw->menu.bottom_shadow_pixmap = mw->menu.gray_pixmap;
- if (mw->menu.free_bottom_shadow_color_p)
+ *bottom_pixmap = mw->menu.gray_pixmap;
+ if (*free_bottom_p)
{
- x_free_dpy_colors (dpy, screen, cmap,
- &mw->menu.bottom_shadow_color, 1);
- mw->menu.free_bottom_shadow_color_p = 0;
+ x_free_dpy_colors (dpy, screen, cmap, bottom_color, 1);
+ *free_bottom_p = False;
}
- mw->menu.bottom_shadow_color = mw->menu.foreground;
+ *bottom_color = fore_color;
}
+}
+
+static void
+make_shadow_gcs (XlwMenuWidget mw)
+{
+ XGCValues xgcv;
+ unsigned long pm = 0;
+
+ /* Normal shadows */
+ compute_shadow_colors(mw,
+ &(mw->menu.top_shadow_color),
+ &(mw->menu.bottom_shadow_color),
+ &(mw->menu.free_top_shadow_color_p),
+ &(mw->menu.free_bottom_shadow_color_p),
+ &(mw->menu.top_shadow_pixmap),
+ &(mw->menu.bottom_shadow_pixmap),
+ mw->menu.foreground,
+ mw->core.background_pixel);
+
+ /* Highlight shadows */
+ compute_shadow_colors(mw,
+ &(mw->menu.top_highlight_shadow_color),
+ &(mw->menu.bottom_highlight_shadow_color),
+ &(mw->menu.free_top_highlight_shadow_color_p),
+ &(mw->menu.free_bottom_highlight_shadow_color_p),
+ &(mw->menu.top_highlight_shadow_pixmap),
+ &(mw->menu.bottom_highlight_shadow_pixmap),
+ mw->menu.highlight_foreground,
+ mw->menu.highlight_background);
xgcv.fill_style = FillStippled;
xgcv.foreground = mw->menu.top_shadow_color;
@@ -1862,6 +2017,16 @@ make_shadow_gcs (XlwMenuWidget mw)
xgcv.stipple = mw->menu.bottom_shadow_pixmap;
pm = (xgcv.stipple ? GCStipple|GCFillStyle : 0);
mw->menu.shadow_bottom_gc = XtGetGC ((Widget)mw, GCForeground | pm, &xgcv);
+
+ xgcv.foreground = mw->menu.top_highlight_shadow_color;
+ xgcv.stipple = mw->menu.top_highlight_shadow_pixmap;
+ pm = (xgcv.stipple ? GCStipple|GCFillStyle : 0);
+ mw->menu.highlight_shadow_top_gc = XtGetGC ((Widget)mw, GCForeground | pm, &xgcv);
+
+ xgcv.foreground = mw->menu.bottom_highlight_shadow_color;
+ xgcv.stipple = mw->menu.bottom_highlight_shadow_pixmap;
+ pm = (xgcv.stipple ? GCStipple|GCFillStyle : 0);
+ mw->menu.highlight_shadow_bottom_gc = XtGetGC ((Widget)mw, GCForeground | pm, &xgcv);
}
@@ -2038,12 +2203,14 @@ XlwMenuRealize (Widget w, Mask *valueMask, XSetWindowAttributes *attributes)
#if defined USE_CAIRO || defined HAVE_XFT
if (mw->menu.xft_font)
{
- XColor colors[3];
+ XColor colors[4];
colors[0].pixel = mw->menu.xft_fg.pixel = mw->menu.foreground;
colors[1].pixel = mw->menu.xft_bg.pixel = mw->core.background_pixel;
colors[2].pixel = mw->menu.xft_disabled_fg.pixel
= mw->menu.disabled_foreground;
- XQueryColors (XtDisplay (mw), mw->core.colormap, colors, 3);
+ colors[3].pixel = mw->menu.xft_highlight_fg.pixel
+ = mw->menu.highlight_foreground;
+ XQueryColors (XtDisplay (mw), mw->core.colormap, colors, 4);
mw->menu.xft_fg.color.alpha = 0xFFFF;
mw->menu.xft_fg.color.red = colors[0].red;
mw->menu.xft_fg.color.green = colors[0].green;
@@ -2056,6 +2223,10 @@ XlwMenuRealize (Widget w, Mask *valueMask, XSetWindowAttributes *attributes)
mw->menu.xft_disabled_fg.color.red = colors[2].red;
mw->menu.xft_disabled_fg.color.green = colors[2].green;
mw->menu.xft_disabled_fg.color.blue = colors[2].blue;
+ mw->menu.xft_highlight_fg.color.alpha = 0xFFFF;
+ mw->menu.xft_highlight_fg.color.red = colors[3].red;
+ mw->menu.xft_highlight_fg.color.green = colors[3].green;
+ mw->menu.xft_highlight_fg.color.blue = colors[3].blue;
}
#endif
}
--git a/lwlib/xlwmenu.h b/lwlib/xlwmenu.h
index 7f4bf35939..f68d913b5a 100644
--- a/lwlib/xlwmenu.h
+++ b/lwlib/xlwmenu.h
@@ -58,6 +58,10 @@ #define XtNallowResize "allowResize"
#define XtCAllowResize "AllowResize"
#define XtNborderThickness "borderThickness"
#define XtCBorderThickness "BorderThickness"
+#define XtNhighlightForeground "highlightForeground"
+#define XtCHighlightForeground "HighlightForeground"
+#define XtNhighlightBackground "highlightBackground"
+#define XtCHighlightBackground "HighlightBackground"
/* Motif-compatible resource names */
#define XmNshadowThickness "shadowThickness"
@@ -70,6 +74,16 @@ #define XmNtopShadowPixmap "topShadowPixmap"
#define XmCTopShadowPixmap "TopShadowPixmap"
#define XmNbottomShadowPixmap "bottomShadowPixmap"
#define XmCBottomShadowPixmap "BottomShadowPixmap"
+
+#define XmNtopHighlightShadowColor "topHighlightShadowColor"
+#define XmCTopHighlightShadowColor "TopHighlightShadowColor"
+#define XmNbottomHighlightShadowColor "bottomHighlightShadowColor"
+#define XmCBottomHighlightShadowColor "BottomHighlightShadowColor"
+#define XmNtopHighlightShadowPixmap "topHighlightShadowPixmap"
+#define XmCTopHighlightShadowPixmap "TopHighlightShadowPixmap"
+#define XmNbottomHighlightShadowPixmap "bottomHighlightShadowPixmap"
+#define XmCBottomHighlightShadowPixmap "BottomHighlightShadowPixmap"
+
#define XmRHorizontalDimension "HorizontalDimension"
typedef struct _XlwMenuRec *XlwMenuWidget;
--git a/lwlib/xlwmenuP.h b/lwlib/xlwmenuP.h
index 455ecdbce0..c314eb3e91 100644
--- a/lwlib/xlwmenuP.h
+++ b/lwlib/xlwmenuP.h
@@ -63,13 +63,15 @@ #define _XlwMenuP_h
#if defined USE_CAIRO || defined HAVE_XFT
int default_face;
XftFont* xft_font;
- XftColor xft_fg, xft_bg, xft_disabled_fg;
+ XftColor xft_fg, xft_bg, xft_disabled_fg, xft_highlight_fg;
#endif
String fontName;
XFontStruct* font;
Pixel foreground;
Pixel disabled_foreground;
Pixel button_foreground;
+ Pixel highlight_foreground;
+ Pixel highlight_background;
Dimension margin;
Dimension horizontal_spacing;
Dimension vertical_spacing;
@@ -80,6 +82,10 @@ #define _XlwMenuP_h
Pixel bottom_shadow_color;
Pixmap top_shadow_pixmap;
Pixmap bottom_shadow_pixmap;
+ Pixel top_highlight_shadow_color;
+ Pixel bottom_highlight_shadow_color;
+ Pixmap top_highlight_shadow_pixmap;
+ Pixmap bottom_highlight_shadow_pixmap;
Cursor cursor_shape;
XtCallbackList open;
XtCallbackList select, highlight;
@@ -88,8 +94,10 @@ #define _XlwMenuP_h
int horizontal;
/* True means top_shadow_color and/or bottom_shadow_color must be freed. */
- bool_bf free_top_shadow_color_p : 1;
- bool_bf free_bottom_shadow_color_p : 1;
+ Boolean free_top_shadow_color_p;
+ Boolean free_bottom_shadow_color_p;
+ Boolean free_top_highlight_shadow_color_p;
+ Boolean free_bottom_highlight_shadow_color_p;
/* State of the XlwMenu */
int top_depth;
@@ -112,9 +120,13 @@ #define _XlwMenuP_h
GC button_gc;
GC background_gc;
GC disabled_gc;
+ GC highlight_foreground_gc;
+ GC highlight_background_gc;
GC inactive_button_gc;
GC shadow_top_gc;
GC shadow_bottom_gc;
+ GC highlight_shadow_top_gc;
+ GC highlight_shadow_bottom_gc;
Cursor cursor;
Boolean popped_up;
Pixmap gray_pixmap;
--
2.36.1
[-- Attachment #4: Type: text/plain, Size: 6968 bytes --]
In GNU Emacs 29.0.50 (build 1, x86_64-unknown-openbsd7.1, X toolkit, cairo version 1.17.6, Xaw scroll bars)
of 2022-07-13 built on elite.giraud
Repository revision: f51e1dbd3174d727a12e673e0b820b4cf35e7046
Repository branch: mgi/ui3
Windowing system distributor 'The X.Org Foundation', version 11.0.12101003
System Description: OpenBSD elite.giraud 7.1 GENERIC.MP#579 amd64
Configured using:
'configure --prefix=/home/manuel/emacs --bindir=/home/manuel/bin
--with-x-toolkit=athena --without-sound --without-compress-install
CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib'
Configured features:
CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GSETTINGS HARFBUZZ JPEG JSON
LCMS2 LIBOTF LIBXML2 MODULES NOTIFY KQUEUE PDUMPER PNG RSVG SQLITE3
THREADS TIFF TOOLKIT_SCROLL_BARS WEBP X11 XDBE XIM XINPUT2 XPM LUCID
ZLIB
Important settings:
value of $LC_ALL: en_US.UTF-8
locale-coding-system: utf-8-unix
Major mode: Lisp Interaction
Minor modes in effect:
global-git-commit-mode: t
magit-auto-revert-mode: t
paredit-mode: t
icomplete-mode: t
display-time-mode: t
shell-dirtrack-mode: t
global-so-long-mode: t
repeat-mode: t
global-eldoc-mode: t
eldoc-mode: t
show-paren-mode: t
electric-indent-mode: t
mouse-wheel-mode: t
menu-bar-mode: t
file-name-shadow-mode: t
global-font-lock-mode: t
font-lock-mode: t
line-number-mode: t
indent-tabs-mode: t
transient-mark-mode: t
auto-composition-mode: t
auto-encryption-mode: t
auto-compression-mode: t
Load-path shadows:
/home/manuel/.emacs.d/elpa/transient-20220527.2213/transient hides /home/manuel/emacs/share/emacs/29.0.50/lisp/transient
Features:
(shadow sort mail-extr emacsbug vc-git whitespace magit-patch
magit-extras face-remap magit-bookmark magit-submodule magit-obsolete
magit-blame magit-stash magit-reflog magit-bisect magit-push magit-pull
magit-fetch magit-clone magit-remote magit-commit magit-sequence
magit-notes magit-worktree magit-tag magit-merge magit-branch
magit-reset magit-files magit-refs magit-status magit magit-repos
magit-apply magit-wip magit-log which-func imenu magit-diff smerge-mode
diff git-commit log-edit pcvs-util add-log magit-core magit-autorevert
autorevert magit-margin magit-transient magit-process with-editor
magit-mode transient magit-git magit-base magit-section dash compat-27
compat-26 compat pulse vc-hg diff-mode vc-dispatcher vc-svn conf-mode
facemenu paredit edmacro icomplete time battery exwm-randr xcb-randr
exwm-config exwm exwm-input xcb-keysyms xcb-xkb exwm-manage
exwm-floating xcb-cursor xcb-render exwm-layout exwm-workspace exwm-core
xcb-ewmh xcb-icccm xcb xcb-xproto xcb-types xcb-debug kmacro server
stimmung-themes modus-operandi-theme modus-themes osm bookmark mingus
libmpdee transmission diary-lib diary-loaddefs color calc-bin calc-ext
calc calc-loaddefs rect calc-macs w3m-load mu4e mu4e-org mu4e-main
mu4e-view mu4e-view-gnus mu4e-view-common mu4e-headers mu4e-compose
mu4e-context mu4e-draft mu4e-actions ido rfc2368 smtpmail mu4e-mark
mu4e-proc mu4e-utils doc-view filenotify jka-compr image-mode exif
mu4e-lists mu4e-message flow-fill mule-util hl-line mu4e-vars mu4e-meta
supercite regi ebdb-message ebdb-gnus gnus-msg gnus-art mm-uu mml2015
mm-view mml-smime smime gnutls dig gnus-sum shr pixel-fill kinsoku
url-file url-dired svg dom gnus-group gnus-undo gnus-start gnus-dbus
gnus-cloud nnimap nnmail mail-source utf7 netrc nnoo gnus-spec gnus-int
gnus-range message sendmail yank-media puny rfc822 mml mml-sec epa
derived epg rfc6068 epg-config mm-decode mm-bodies mm-encode mail-parse
rfc2231 rfc2047 rfc2045 ietf-drums gmm-utils mailheader gnus-win gnus
nnheader gnus-util mail-utils range mm-util mail-prsvr ebdb-mua ebdb-com
crm ebdb-format ebdb mailabbrev eieio-opt cl-extra help-mode speedbar
ezimage dframe eieio-base pcase timezone org ob ob-tangle ob-ref ob-lob
ob-table ob-exp org-macro org-footnote org-src ob-comint org-pcomplete
org-list org-faces org-entities org-version ob-emacs-lisp ob-core
ob-eval org-table oc-basic bibtex ol rx org-keys oc org-compat org-macs
org-loaddefs find-func cal-menu calendar cal-loaddefs visual-basic-mode
cl web-mode disp-table erlang-start smart-tabs-mode skeleton cc-mode
cc-fonts cc-guess cc-menus cc-cmds cc-styles cc-align cc-engine cc-vars
cc-defs slime-asdf grep slime-tramp tramp tramp-loaddefs trampver
tramp-integration cus-edit cus-load wid-edit files-x tramp-compat shell
pcomplete parse-time iso8601 time-date ls-lisp format-spec slime-fancy
slime-indentation slime-cl-indent cl-indent slime-trace-dialog
slime-fontifying-fu slime-package-fu slime-references
slime-compiler-notes-tree advice slime-scratch slime-presentations
bridge slime-macrostep macrostep slime-mdot-fu slime-enclosing-context
slime-fuzzy slime-fancy-trace slime-fancy-inspector slime-c-p-c
slime-editing-commands slime-autodoc slime-repl slime-parse slime
compile text-property-search etags fileloop generator xref project
arc-mode archive-mode noutline outline pp comint ansi-color ring
hyperspec thingatpt slime-autoloads dired-aux dired-x dired
dired-loaddefs so-long notifications dbus xml repeat easy-mmode tex-site
hyperbole-autoloads magit-autoloads git-commit-autoloads
magit-section-autoloads dash-autoloads rust-mode-autoloads
stimmung-themes-autoloads with-editor-autoloads info compat-autoloads
package browse-url url url-proxy url-privacy url-expand url-methods
url-history url-cookie generate-lisp-file url-domsuf url-util mailcap
url-handlers url-parse auth-source cl-seq eieio eieio-core cl-macs
password-cache json subr-x map byte-opt gv bytecomp byte-compile cconv
url-vars cl-loaddefs cl-lib rmc iso-transl tooltip eldoc paren electric
uniquify ediff-hook vc-hooks lisp-float-type elisp-mode mwheel
term/x-win x-win term/common-win x-dnd tool-bar dnd fontset image
regexp-opt fringe tabulated-list replace newcomment text-mode lisp-mode
prog-mode register page tab-bar menu-bar rfn-eshadow isearch easymenu
timer select scroll-bar mouse jit-lock font-lock syntax font-core
term/tty-colors frame minibuffer nadvice seq simple cl-generic
indonesian philippine cham georgian utf-8-lang misc-lang vietnamese
tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek
romanian slovak czech european ethiopic indian cyrillic chinese
composite emoji-zwj charscript charprop case-table epa-hook
jka-cmpr-hook help abbrev obarray oclosure cl-preloaded button loaddefs
faces cus-face macroexp files window text-properties overlay sha1 md5
base64 format env code-pages mule custom widget keymap
hashtable-print-readable backquote threads dbusbind kqueue lcms2
dynamic-setting system-font-setting font-render-setting cairo x-toolkit
xinput2 x multi-tty make-network-process emacs)
Memory information:
((conses 16 563139 59476)
(symbols 48 54905 4)
(strings 32 171200 8786)
(string-bytes 1 5703800)
(vectors 16 99692)
(vector-slots 8 1289985 58168)
(floats 8 522 566)
(intervals 56 2981 2094)
(buffers 992 16))
--
Manuel Giraud
next reply other threads:[~2022-07-13 13:38 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-13 13:38 Manuel Giraud [this message]
2022-07-14 0:53 ` bug#56538: 29.0.50; [PATCH] Colored highlight in Lucid backend Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-14 9:42 ` Manuel Giraud
2022-07-14 10:34 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-14 13:17 ` Manuel Giraud
2022-07-15 2:06 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-15 11:50 ` Manuel Giraud
2022-07-15 11:56 ` Manuel Giraud
2022-07-15 12:58 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-15 13:27 ` Manuel Giraud
2022-07-16 3:04 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-16 10:56 ` Manuel Giraud
2022-07-16 10:59 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87wnch16as.fsf@elite.giraud \
--to=manuel@ledu-giraud.fr \
--cc=56538@debbugs.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.