help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Lucid menu faces


From: Po Lu
Subject: Re: Lucid menu faces
Date: Thu, 21 Jul 2022 09:21:26 +0800
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.91 (gnu/linux)

Eli Zaretskii <eliz@gnu.org> writes:

> Isn't it true that the appearance of toolkit menus can be fully
> controlled only through X resources?  Toolkits are not part of Emacs,
> so they don't abide by our Lisp trickery.  We are all spoiled rotten
> by Emacs letting us control everything via Lisp objects and
> properties, but the truth is that it only works because Emacs has code
> to make it work.  Toolkits don't: they have no idea what is a 'face'
> in its Emacs interpretation.

Yes.  There is a hack in xfaces.c wrt the `menu' face:

static void
x_update_menu_appearance (struct frame *f)
{
  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  XrmDatabase rdb;

  if (dpyinfo
      && (rdb = XrmGetDatabase (FRAME_X_DISPLAY (f)),
          rdb != NULL))
    {
      char line[512];
      char *buf = line;
      ptrdiff_t bufsize = sizeof line;
      Lisp_Object lface = lface_from_face_name (f, Qmenu, true);
      struct face *face = FACE_FROM_ID (f, MENU_FACE_ID);
      const char *myname = SSDATA (Vx_resource_name);
      bool changed_p = false;
#ifdef USE_MOTIF
      const char *popup_path = "popup_menu";
#else
      const char *popup_path = "menu.popup";
#endif

      if (STRINGP (LFACE_FOREGROUND (lface)))
        {
          exprintf (&buf, &bufsize, line, -1, "%s.%s*foreground: %s",
                    myname, popup_path,
                    SDATA (LFACE_FOREGROUND (lface)));
          XrmPutLineResource (&rdb, line);
          exprintf (&buf, &bufsize, line, -1, "%s.pane.menubar*foreground: %s",
                    myname, SDATA (LFACE_FOREGROUND (lface)));
          XrmPutLineResource (&rdb, line);
          changed_p = true;
        }

      if (STRINGP (LFACE_BACKGROUND (lface)))
        {
          exprintf (&buf, &bufsize, line, -1, "%s.%s*background: %s",
                    myname, popup_path,
                    SDATA (LFACE_BACKGROUND (lface)));
          XrmPutLineResource (&rdb, line);

          exprintf (&buf, &bufsize, line, -1, "%s.pane.menubar*background: %s",
                    myname, SDATA (LFACE_BACKGROUND (lface)));
          XrmPutLineResource (&rdb, line);
          changed_p = true;
        }

      if (face->font
          /* On Solaris 5.8, it's been reported that the `menu' face
             can be unspecified here, during startup.  Why this
             happens remains unknown.  -- cyd  */
          && FONTP (LFACE_FONT (lface))
          && (!UNSPECIFIEDP (LFACE_FAMILY (lface))
              || !UNSPECIFIEDP (LFACE_FOUNDRY (lface))
              || !UNSPECIFIEDP (LFACE_SWIDTH (lface))
              || !UNSPECIFIEDP (LFACE_WEIGHT (lface))
              || !UNSPECIFIEDP (LFACE_SLANT (lface))
              || !UNSPECIFIEDP (LFACE_HEIGHT (lface))))
        {
          Lisp_Object xlfd = Ffont_xlfd_name (LFACE_FONT (lface), Qnil);
#ifdef USE_MOTIF
          const char *suffix = "List";
          bool motif = true;
#else
#if defined HAVE_X_I18N

          const char *suffix = "Set";
#else
          const char *suffix = "";
#endif
          bool motif = false;
#endif

          if (! NILP (xlfd))
            {
#if defined HAVE_X_I18N
              char *fontsetname = xic_create_fontsetname (SSDATA (xlfd), motif);
#else
              char *fontsetname = SSDATA (xlfd);
#endif
              exprintf (&buf, &bufsize, line, -1, "%s.pane.menubar*font%s: %s",
                        myname, suffix, fontsetname);
              XrmPutLineResource (&rdb, line);

              exprintf (&buf, &bufsize, line, -1, "%s.%s*font%s: %s",
                        myname, popup_path, suffix, fontsetname);
              XrmPutLineResource (&rdb, line);
              changed_p = true;
              if (fontsetname != SSDATA (xlfd))
                xfree (fontsetname);
            }
        }

      if (changed_p && f->output_data.x->menubar_widget)
        free_frame_menubar (f);

      if (buf != line)
        xfree (buf);
    }
}


reply via email to

[Prev in Thread] Current Thread [Next in Thread]