mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-06-14 12:31:25 +00:00
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:
parent
e604d196e7
commit
45a067fe09
7 changed files with 34 additions and 14 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue