emacs-diffs
[Top][All Lists]
Advanced

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

feature/pgtk 8669feb 054/100: Make icons and titles work like on X


From: Yuuki Harano
Subject: feature/pgtk 8669feb 054/100: Make icons and titles work like on X
Date: Tue, 24 Nov 2020 08:02:36 -0500 (EST)

branch: feature/pgtk
commit 8669feb0c5c1b8fe3a9bf8489420e786c3367b2a
Author: Yuuki Harano <masm+github@masm11.me>
Commit: Jeff Walsh <jeff.walsh@drtusers-MacBook-Pro.local>

    Make icons and titles work like on X
    
    * pgtk-win.el (frame-title-format, icon-title-format): remove.
    * pgtkfns.c (pgtk_set_name_as_filename):  remove.
    * pgtkfns.c (pgtk_set_name_internal): remove gtk_window_set_icon_name call.
    * pgtkfns.c (pgtk_set_name): change value of update_mode_lines.
    * pgtkfns.c (pgtk_explicitly_set_name):
    prefer the symbol to an immediate value.
    * pgtkfns.c (pgtk_implicitly_set_name): remove pgtk_set_name_as_filename 
call.
    * pgtkfns.c (x_set_icon_type, x_set_icon_name): re-port from X code.
    * pgtkfns.c (xg_set_icon, xg_set_icon_from_xpm_data): port from X code.
    * pgtkterm.c (pgtk_bitmap_icon, pgtk_text_icon, pgtk_create_terminal):
    port from X code.
    * pgtkterm.h: add function declarations.
---
 lisp/term/pgtk-win.el |   4 -
 src/pgtkfns.c         | 265 +++++++++++++++++++++++---------------------------
 src/pgtkterm.c        |  42 ++++++++
 src/pgtkterm.h        |   5 +
 4 files changed, 169 insertions(+), 147 deletions(-)

diff --git a/lisp/term/pgtk-win.el b/lisp/term/pgtk-win.el
index f3239c6..4598ba0 100644
--- a/lisp/term/pgtk-win.el
+++ b/lisp/term/pgtk-win.el
@@ -281,10 +281,6 @@ See the documentation of 
`create-fontset-from-fontset-spec' for the format.")
       (error "Cannot suspend Emacs while a PGTK GUI frame exists")))
 
 
-;; Set some options to be as Nextstep-like as possible.
-(setq frame-title-format t
-      icon-title-format t)
-
 
 (defvar pgtk-initialized nil
   "Non-nil if pure-GTK windowing has been initialized.")
diff --git a/src/pgtkfns.c b/src/pgtkfns.c
index 9078a78..79c9aab 100644
--- a/src/pgtkfns.c
+++ b/src/pgtkfns.c
@@ -50,7 +50,6 @@ static ptrdiff_t image_cache_refcount;
 
 static int x_decode_color (struct frame *f, Lisp_Object color_name, int 
mono_color);
 static struct pgtk_display_info *pgtk_display_info_for_name (Lisp_Object);
-static void pgtk_set_name_as_filename (struct frame *);
 
 static const char *pgtk_app_name = "Emacs";
 
@@ -253,58 +252,24 @@ x_set_cursor_color (struct frame *f, Lisp_Object arg, 
Lisp_Object oldval)
   update_face_from_frame_parameter (f, Qcursor_color, arg);
 }
 
-
 static void
-x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+pgtk_set_name_internal (struct frame *f, Lisp_Object name)
 {
-  GtkWidget *widget = FRAME_GTK_OUTER_WIDGET(f);
-  PGTK_TRACE ("x_set_icon_name");
-
-  /* see if it's changed */
-  if (STRINGP (arg))
+  if (FRAME_GTK_WIDGET (f))
     {
-      if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
-        return;
-    }
-  else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
-    return;
+      block_input ();
+      {
+       Lisp_Object encoded_name;
 
-  fset_icon_name (f, arg);
+       /* As ENCODE_UTF_8 may cause GC and relocation of string data,
+          we use it before x_encode_text that may return string data.  */
+       encoded_name = ENCODE_UTF_8 (name);
 
-  if (NILP (arg))
-    {
-      if (!NILP (f->title))
-        arg = f->title;
-      else
-        /* Explicit name and no icon-name -> explicit_name.  */
-        if (f->explicit_name)
-          arg = f->name;
-        else
-          {
-            /* No explicit name and no icon-name ->
-               name has to be rebuild from icon_title_format.  */
-            windows_or_buffers_changed = 67;
-            return;
-          }
+        gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+                              SSDATA (encoded_name));
+      }
+      unblock_input ();
     }
-
-  gtk_window_set_icon_name(GTK_WINDOW(widget), SSDATA(arg));
-}
-
-static void
-pgtk_set_name_internal (struct frame *f, Lisp_Object name)
-{
-  Lisp_Object encoded_name, encoded_icon_name;
-  GtkWidget *widget = FRAME_GTK_OUTER_WIDGET (f);
-
-  encoded_name = ENCODE_UTF_8 (name);
-  gtk_window_set_title(GTK_WINDOW(widget), SSDATA (encoded_name));
-
-  if (!STRINGP (f->icon_name))
-    encoded_icon_name = encoded_name;
-  else
-    encoded_icon_name = ENCODE_UTF_8 (f->icon_name);
-  gtk_window_set_icon_name(GTK_WINDOW(widget), SSDATA (encoded_icon_name));
 }
 
 static void
@@ -352,7 +317,7 @@ static void
 x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 {
   PGTK_TRACE ("x_explicitly_set_name");
-  pgtk_set_name (f, arg, 1);
+  pgtk_set_name (f, arg, true);
 }
 
 
@@ -363,17 +328,7 @@ void
 pgtk_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 {
   PGTK_TRACE ("x_implicitly_set_name");
-
-  Lisp_Object frame_title = buffer_local_value
-    (Qframe_title_format, XWINDOW (f->selected_window)->contents);
-  Lisp_Object icon_title = buffer_local_value
-    (Qicon_title_format, XWINDOW (f->selected_window)->contents);
-
-  if (FRAME_PGTK_P (f) && ((FRAME_ICONIFIED_P (f) && EQ (icon_title, Qt))
-                         || EQ (frame_title, Qt)))
-    pgtk_set_name_as_filename (f);
-  else
-    pgtk_set_name (f, arg, 0);
+  pgtk_set_name (f, arg, false);
 }
 
 
@@ -401,72 +356,6 @@ x_set_title (struct frame *f, Lisp_Object name, 
Lisp_Object old_name)
 }
 
 
-static void
-pgtk_set_name_as_filename (struct frame *f)
-{
-  GtkWidget *widget;
-  Lisp_Object name, filename;
-  Lisp_Object buf = XWINDOW (f->selected_window)->contents;
-  const char *title;
-  Lisp_Object encoded_name, encoded_filename;
-  const char *str;
-  PGTK_TRACE ("pgtk_set_name_as_filename");
-
-  if (f->explicit_name || ! NILP (f->title))
-    return;
-
-  block_input ();
-  filename = BVAR (XBUFFER (buf), filename);
-  name = BVAR (XBUFFER (buf), name);
-
-  if (NILP (name))
-    {
-      if (! NILP (filename))
-        name = Ffile_name_nondirectory (filename);
-      else
-        name = build_string (pgtk_app_name);
-    }
-
-  encoded_name = ENCODE_UTF_8 (name);
-
-  widget = FRAME_GTK_OUTER_WIDGET (f);
-
-  title = FRAME_ICONIFIED_P (f) ? gtk_window_get_icon_name(GTK_WINDOW(widget))
-                               : gtk_window_get_title(GTK_WINDOW(widget));
-
-  if (title && (! strcmp (title, SSDATA (encoded_name))))
-    {
-      unblock_input ();
-      return;
-    }
-
-  str = SSDATA (encoded_name);
-  if (str == NULL) str = "Bad coding";
-
-  if (FRAME_ICONIFIED_P (f))
-    gtk_window_set_icon_name(GTK_WINDOW(widget), str);
-  else
-    {
-      const char *fstr;
-
-      if (! NILP (filename))
-        {
-          encoded_filename = ENCODE_UTF_8 (filename);
-
-          fstr = SSDATA (encoded_filename);
-          if (fstr == NULL) fstr = "";
-        }
-      else
-        fstr = "";
-
-      gtk_window_set_title(GTK_WINDOW(widget), str);
-      fset_name (f, name);
-    }
-
-  unblock_input ();
-}
-
-
 void
 pgtk_set_doc_edited (void)
 {
@@ -665,26 +554,66 @@ x_set_internal_border_width (struct frame *f, Lisp_Object 
arg, Lisp_Object oldva
 static void
 x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 {
-  /* This does not work if on Wayland, or if icon is defined in emacs.desktop
-   * even if on X11.
-   */
-  GdkPixbuf *pixbuf;
-  if (NILP (arg) || EQ (arg, Qt))
-    pixbuf = NULL;
-  else {
-    GError *err = NULL;
-    CHECK_STRING (arg);
-    pixbuf = gdk_pixbuf_new_from_file (SSDATA (arg), &err);
-    if (pixbuf == NULL) {
-      Lisp_Object msg = build_string (err->message);
-      g_error_free (err);
-      error ("%s", SSDATA (msg));
+  bool result;
+
+  if (STRINGP (arg))
+    {
+      if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
+       return;
     }
-  }
+  else if (!STRINGP (oldval) && NILP (oldval) == NILP (arg))
+    return;
 
-  gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
-  if (pixbuf != NULL)
-    g_object_unref (pixbuf);
+  block_input ();
+  if (NILP (arg))
+    result = pgtk_text_icon (f,
+                         SSDATA ((!NILP (f->icon_name)
+                                  ? f->icon_name
+                                  : f->name)));
+  else
+    result = FRAME_TERMINAL (f)->set_bitmap_icon_hook (f, arg);
+
+  if (result)
+    {
+      unblock_input ();
+      error ("No icon window available");
+    }
+
+  unblock_input ();
+}
+
+
+static void
+x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+  bool result;
+
+  if (STRINGP (arg))
+    {
+      if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
+       return;
+    }
+  else if (!NILP (arg) || NILP (oldval))
+    return;
+
+  fset_icon_name (f, arg);
+
+  block_input ();
+
+  result = pgtk_text_icon (f,
+                          SSDATA ((!NILP (f->icon_name)
+                                   ? f->icon_name
+                                   : !NILP (f->title)
+                                   ? f->title
+                                   : f->name)));
+
+  if (result)
+    {
+      unblock_input ();
+      error ("No icon window available");
+    }
+
+  unblock_input ();
 }
 
 /* This is the same as the xfns.c definition.  */
@@ -800,6 +729,56 @@ x_set_override_redirect (struct frame *f, Lisp_Object 
new_value, Lisp_Object old
     }
 }
 
+/* Set icon from FILE for frame F.  By using GTK functions the icon
+   may be any format that GdkPixbuf knows about, i.e. not just bitmaps.  */
+
+bool
+xg_set_icon (struct frame *f, Lisp_Object file)
+{
+  bool result = false;
+  Lisp_Object found;
+
+  found = image_find_image_file (file);
+
+  if (! NILP (found))
+    {
+      GdkPixbuf *pixbuf;
+      GError *err = NULL;
+      char *filename = SSDATA (ENCODE_FILE (found));
+      block_input ();
+
+      pixbuf = gdk_pixbuf_new_from_file (filename, &err);
+
+      if (pixbuf)
+       {
+         gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+                              pixbuf);
+         g_object_unref (pixbuf);
+
+         result = true;
+       }
+      else
+       g_error_free (err);
+
+      unblock_input ();
+    }
+
+  return result;
+}
+
+bool
+xg_set_icon_from_xpm_data (struct frame *f, const char **data)
+{
+  GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data (data);
+
+  if (!pixbuf)
+    return false;
+
+  gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
+  g_object_unref (pixbuf);
+  return true;
+}
+
 static void
 pgtk_set_sticky (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
 {
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index 65d250b..2d1a990 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -2827,6 +2827,47 @@ pgtk_scroll_run (struct window *w, struct run *run)
   unblock_input ();
 }
 
+/* Icons.  */
+
+/* Make the x-window of frame F use the gnu icon bitmap.  */
+
+static bool
+pgtk_bitmap_icon (struct frame *f, Lisp_Object file)
+{
+  if (FRAME_GTK_WIDGET (f) == 0)
+    return true;
+
+  if (STRINGP (file))
+    {
+      /* Use gtk_window_set_icon_from_file () if available,
+        It's not restricted to bitmaps */
+      if (xg_set_icon (f, file))
+       return false;
+
+      return true;
+    }
+
+  if (xg_set_icon (f, xg_default_icon_file))
+    {
+      return false;
+    }
+
+  return true;
+}
+
+
+/* Make the x-window of frame F use a rectangle with text.
+   Use ICON_NAME as the text.  */
+
+bool
+pgtk_text_icon (struct frame *f, const char *icon_name)
+{
+  gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), NULL);
+  gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), icon_name);
+
+  return false;
+}
+
 /***********************************************************************
                    Starting and ending an update
  ***********************************************************************/
@@ -4620,6 +4661,7 @@ pgtk_create_terminal (struct pgtk_display_info *dpyinfo)
   terminal->query_frame_background_color = pgtk_query_frame_background_color;
   terminal->defined_color_hook = pgtk_defined_color;
   terminal->set_new_font_hook = pgtk_new_font;
+  terminal->set_bitmap_icon_hook = pgtk_bitmap_icon;
   terminal->implicit_set_name_hook = pgtk_implicitly_set_name;
   terminal->iconify_frame_hook = pgtk_iconify_frame;
   terminal->set_scroll_bar_default_width_hook = 
pgtk_set_scroll_bar_default_width;
diff --git a/src/pgtkterm.h b/src/pgtkterm.h
index e740318..706198a 100644
--- a/src/pgtkterm.h
+++ b/src/pgtkterm.h
@@ -621,4 +621,9 @@ extern bool pgtk_im_filter_keypress(struct frame *f, 
GdkEventKey *ev);
 extern void pgtk_im_init(struct pgtk_display_info *dpyinfo);
 extern void pgtk_im_finish(struct pgtk_display_info *dpyinfo);
 
+extern bool xg_set_icon (struct frame *, Lisp_Object);
+extern bool xg_set_icon_from_xpm_data (struct frame *f, const char **data);
+
+extern bool pgtk_text_icon (struct frame *f, const char *icon_name);
+
 #endif /* HAVE_PGTK */



reply via email to

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