Fix help popups for Athena menus

* lwlib/lwlib-widget.h (struct _widget_value): Use a gc_handle for the
help field.
* lwlib/lwlib.c (free_widget_value_tree, copy_widget_value_tree)
(merge_widget_value): Adapt to gc_handles.
* src/gc-handles.h (gc_handle_for_gc_handle, gc_handle_assign): New
helpers.
* src/gc-handles.c (gc_handle_for_gc_handle, gc_handle_assign):
Implementation.
* src/menu.c (make_widget_value, free_menubar_widget_value_tree): Adapt
to gc_handles.
* src/xmenu.c (menu_highlight_callback): Adapt to gc_handles.
* src/gtkutil.c (make_menu_item, xg_create_one_menuitem)
(xg_update_menu_item): Adapted to changed widget_value.
This commit is contained in:
Helmut Eller 2025-11-07 18:30:23 +01:00
parent e604d196e7
commit 45a067fe09
7 changed files with 34 additions and 14 deletions

View file

@ -24,6 +24,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#define LWLIB_WIDGET_H
#include "../src/lisp.h"
#include "../src/gc-handles.h"
typedef enum
{
@ -53,10 +54,8 @@ typedef struct _widget_value
Lisp_Object lkey;
char *key;
/* Help string or nil if none.
GC finds this string through the frame's menu_bar_vector
or through menu_items. */
Lisp_Object help;
/* Help string or nil if none. */
gc_handle help;
/* True if enabled. */
bool enabled;

View file

@ -102,6 +102,7 @@ free_widget_value_tree (widget_value *wv)
xfree (wv->name);
xfree (wv->value);
xfree (wv->key);
free_gc_handle (wv->help);
wv->name = wv->value = wv->key = (char *) 0xDEADBEEF;
@ -139,7 +140,7 @@ copy_widget_value_tree (widget_value *val, change_type change)
copy->name = xstrdup (val->name);
copy->value = val->value ? xstrdup (val->value) : NULL;
copy->key = val->key ? xstrdup (val->key) : NULL;
copy->help = val->help;
copy->help = gc_handle_for_gc_handle (val->help);
copy->enabled = val->enabled;
copy->button_type = val->button_type;
copy->selected = val->selected;
@ -384,12 +385,13 @@ merge_widget_value (widget_value *val1,
change = max (change, VISIBLE_CHANGE);
dupstring (&val1->key, val2->key);
}
if (! EQ (val1->help, val2->help))
if (!EQ (gc_handle_value (val1->help),
gc_handle_value (val2->help)))
{
EXPLAIN (val1->name, change, VISIBLE_CHANGE, "help change",
val1->help, val2->help);
change = max (change, VISIBLE_CHANGE);
val1->help = val2->help;
gc_handle_assign (&val1->help, val2->help);
}
if (val1->enabled != val2->enabled)
{

View file

@ -154,6 +154,19 @@ gc_handle_for_pvec (union vectorlike_header *h)
return gc_handle_for (obj);
}
gc_handle
gc_handle_for_gc_handle (gc_handle gch)
{
return gc_handle_for (gc_handle_value (gch));
}
void
gc_handle_assign (gc_handle *dst, gc_handle src)
{
free_gc_handle (*dst);
*dst = gc_handle_for_gc_handle (src);
}
DEFUN ("gc-handles-info", Fgc_handles_info, Sgc_handles_info, 0, 0, 0,
doc: /* Return information about registered GC handles.
Return value is an list with the following entries:

View file

@ -27,9 +27,12 @@ typedef struct gc_handle_struct *gc_handle;
gc_handle gc_handle_for (Lisp_Object);
gc_handle gc_handle_for_pvec (union vectorlike_header *);
gc_handle gc_handle_for_gc_handle (gc_handle src);
void free_gc_handle (gc_handle);
Lisp_Object gc_handle_value (gc_handle);
void gc_handle_assign (gc_handle *dst, gc_handle src);
void syms_of_gc_handles (void);
#endif

View file

@ -3354,8 +3354,11 @@ make_menu_item (const char *utf8_label,
if (! item->enabled) gtk_widget_set_sensitive (w, FALSE);
#ifdef HAVE_PGTK
if (!NILP (item->help))
gtk_widget_set_tooltip_text (w, SSDATA (item->help));
{
Lisp_Object help = gc_handle_value (item->help);
if (!NILP (help))
gtk_widget_set_tooltip_text (w, SSDATA (help));
}
#endif
return w;
@ -3401,7 +3404,7 @@ xg_create_one_menuitem (widget_value *item,
xg_list_insert (&xg_menu_item_cb_list, &cb_data->ptrs);
cb_data->select_id = 0;
cb_data->help = gc_handle_for (item->help);
cb_data->help = gc_handle_for_gc_handle (item->help);
cb_data->cl_data = cl_data;
cb_data->call_data = item->call_data;
@ -3985,8 +3988,7 @@ xg_update_menu_item (widget_value *val,
if (cb_data)
{
cb_data->call_data = val->call_data;
free_gc_handle (cb_data->help);
cb_data->help = gc_handle_for (val->help);
gc_handle_assign (&cb_data->help, val->help);
cb_data->cl_data = cl_data;
/* We assume the callback functions don't change. */

View file

@ -581,7 +581,7 @@ make_widget_value (const char *name, char *value,
wv->name = (char *) name;
wv->value = value;
wv->enabled = enabled;
wv->help = help;
wv->help = gc_handle_for (help);
return wv;
}
@ -596,6 +596,7 @@ free_menubar_widget_value_tree (widget_value *wv)
if (! wv) return;
wv->name = wv->value = wv->key = (char *) 0xDEADBEEF;
free_gc_handle (wv->help);
if (wv->contents && (wv->contents != (widget_value *) 1))
{

View file

@ -772,7 +772,7 @@ static void
menu_highlight_callback (Widget widget, LWLIB_ID id, void *call_data)
{
widget_value *wv = call_data;
Lisp_Object help = wv ? wv->help : Qnil;
Lisp_Object help = wv ? gc_handle_value (wv->help) : Qnil;
/* Determine the frame for the help event. */
struct frame *f = menubar_id_to_frame (id);