aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYuuki Harano2020-05-06 12:55:04 +0900
committerJeff Walsh2020-11-24 12:24:39 +1100
commit8669feb0c5c1b8fe3a9bf8489420e786c3367b2a (patch)
treef10ae8d747eb386f29f616cb8787e5bdf99a50d5 /src
parent5a72a07fa5bcec2ad5265284dfb2a5dec7485e7f (diff)
downloademacs-8669feb0c5c1b8fe3a9bf8489420e786c3367b2a.tar.gz
emacs-8669feb0c5c1b8fe3a9bf8489420e786c3367b2a.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/pgtkfns.c265
-rw-r--r--src/pgtkterm.c42
-rw-r--r--src/pgtkterm.h5
3 files changed, 169 insertions, 143 deletions
diff --git a/src/pgtkfns.c b/src/pgtkfns.c
index 9078a78e060..79c9aab1a22 100644
--- a/src/pgtkfns.c
+++ b/src/pgtkfns.c
@@ -50,7 +50,6 @@ static ptrdiff_t image_cache_refcount;
50 50
51static int x_decode_color (struct frame *f, Lisp_Object color_name, int mono_color); 51static int x_decode_color (struct frame *f, Lisp_Object color_name, int mono_color);
52static struct pgtk_display_info *pgtk_display_info_for_name (Lisp_Object); 52static struct pgtk_display_info *pgtk_display_info_for_name (Lisp_Object);
53static void pgtk_set_name_as_filename (struct frame *);
54 53
55static const char *pgtk_app_name = "Emacs"; 54static const char *pgtk_app_name = "Emacs";
56 55
@@ -253,58 +252,24 @@ x_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
253 update_face_from_frame_parameter (f, Qcursor_color, arg); 252 update_face_from_frame_parameter (f, Qcursor_color, arg);
254} 253}
255 254
256
257static void 255static void
258x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval) 256pgtk_set_name_internal (struct frame *f, Lisp_Object name)
259{ 257{
260 GtkWidget *widget = FRAME_GTK_OUTER_WIDGET(f); 258 if (FRAME_GTK_WIDGET (f))
261 PGTK_TRACE ("x_set_icon_name");
262
263 /* see if it's changed */
264 if (STRINGP (arg))
265 { 259 {
266 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt)) 260 block_input ();
267 return; 261 {
268 } 262 Lisp_Object encoded_name;
269 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
270 return;
271 263
272 fset_icon_name (f, arg); 264 /* As ENCODE_UTF_8 may cause GC and relocation of string data,
265 we use it before x_encode_text that may return string data. */
266 encoded_name = ENCODE_UTF_8 (name);
273 267
274 if (NILP (arg)) 268 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
275 { 269 SSDATA (encoded_name));
276 if (!NILP (f->title)) 270 }
277 arg = f->title; 271 unblock_input ();
278 else
279 /* Explicit name and no icon-name -> explicit_name. */
280 if (f->explicit_name)
281 arg = f->name;
282 else
283 {
284 /* No explicit name and no icon-name ->
285 name has to be rebuild from icon_title_format. */
286 windows_or_buffers_changed = 67;
287 return;
288 }
289 } 272 }
290
291 gtk_window_set_icon_name(GTK_WINDOW(widget), SSDATA(arg));
292}
293
294static void
295pgtk_set_name_internal (struct frame *f, Lisp_Object name)
296{
297 Lisp_Object encoded_name, encoded_icon_name;
298 GtkWidget *widget = FRAME_GTK_OUTER_WIDGET (f);
299
300 encoded_name = ENCODE_UTF_8 (name);
301 gtk_window_set_title(GTK_WINDOW(widget), SSDATA (encoded_name));
302
303 if (!STRINGP (f->icon_name))
304 encoded_icon_name = encoded_name;
305 else
306 encoded_icon_name = ENCODE_UTF_8 (f->icon_name);
307 gtk_window_set_icon_name(GTK_WINDOW(widget), SSDATA (encoded_icon_name));
308} 273}
309 274
310static void 275static void
@@ -352,7 +317,7 @@ static void
352x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval) 317x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
353{ 318{
354 PGTK_TRACE ("x_explicitly_set_name"); 319 PGTK_TRACE ("x_explicitly_set_name");
355 pgtk_set_name (f, arg, 1); 320 pgtk_set_name (f, arg, true);
356} 321}
357 322
358 323
@@ -363,17 +328,7 @@ void
363pgtk_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval) 328pgtk_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
364{ 329{
365 PGTK_TRACE ("x_implicitly_set_name"); 330 PGTK_TRACE ("x_implicitly_set_name");
366 331 pgtk_set_name (f, arg, false);
367 Lisp_Object frame_title = buffer_local_value
368 (Qframe_title_format, XWINDOW (f->selected_window)->contents);
369 Lisp_Object icon_title = buffer_local_value
370 (Qicon_title_format, XWINDOW (f->selected_window)->contents);
371
372 if (FRAME_PGTK_P (f) && ((FRAME_ICONIFIED_P (f) && EQ (icon_title, Qt))
373 || EQ (frame_title, Qt)))
374 pgtk_set_name_as_filename (f);
375 else
376 pgtk_set_name (f, arg, 0);
377} 332}
378 333
379 334
@@ -401,72 +356,6 @@ x_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
401} 356}
402 357
403 358
404static void
405pgtk_set_name_as_filename (struct frame *f)
406{
407 GtkWidget *widget;
408 Lisp_Object name, filename;
409 Lisp_Object buf = XWINDOW (f->selected_window)->contents;
410 const char *title;
411 Lisp_Object encoded_name, encoded_filename;
412 const char *str;
413 PGTK_TRACE ("pgtk_set_name_as_filename");
414
415 if (f->explicit_name || ! NILP (f->title))
416 return;
417
418 block_input ();
419 filename = BVAR (XBUFFER (buf), filename);
420 name = BVAR (XBUFFER (buf), name);
421
422 if (NILP (name))
423 {
424 if (! NILP (filename))
425 name = Ffile_name_nondirectory (filename);
426 else
427 name = build_string (pgtk_app_name);
428 }
429
430 encoded_name = ENCODE_UTF_8 (name);
431
432 widget = FRAME_GTK_OUTER_WIDGET (f);
433
434 title = FRAME_ICONIFIED_P (f) ? gtk_window_get_icon_name(GTK_WINDOW(widget))
435 : gtk_window_get_title(GTK_WINDOW(widget));
436
437 if (title && (! strcmp (title, SSDATA (encoded_name))))
438 {
439 unblock_input ();
440 return;
441 }
442
443 str = SSDATA (encoded_name);
444 if (str == NULL) str = "Bad coding";
445
446 if (FRAME_ICONIFIED_P (f))
447 gtk_window_set_icon_name(GTK_WINDOW(widget), str);
448 else
449 {
450 const char *fstr;
451
452 if (! NILP (filename))
453 {
454 encoded_filename = ENCODE_UTF_8 (filename);
455
456 fstr = SSDATA (encoded_filename);
457 if (fstr == NULL) fstr = "";
458 }
459 else
460 fstr = "";
461
462 gtk_window_set_title(GTK_WINDOW(widget), str);
463 fset_name (f, name);
464 }
465
466 unblock_input ();
467}
468
469
470void 359void
471pgtk_set_doc_edited (void) 360pgtk_set_doc_edited (void)
472{ 361{
@@ -665,26 +554,66 @@ x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldva
665static void 554static void
666x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) 555x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
667{ 556{
668 /* This does not work if on Wayland, or if icon is defined in emacs.desktop 557 bool result;
669 * even if on X11. 558
670 */ 559 if (STRINGP (arg))
671 GdkPixbuf *pixbuf; 560 {
672 if (NILP (arg) || EQ (arg, Qt)) 561 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
673 pixbuf = NULL; 562 return;
674 else {
675 GError *err = NULL;
676 CHECK_STRING (arg);
677 pixbuf = gdk_pixbuf_new_from_file (SSDATA (arg), &err);
678 if (pixbuf == NULL) {
679 Lisp_Object msg = build_string (err->message);
680 g_error_free (err);
681 error ("%s", SSDATA (msg));
682 } 563 }
683 } 564 else if (!STRINGP (oldval) && NILP (oldval) == NILP (arg))
565 return;
684 566
685 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf); 567 block_input ();
686 if (pixbuf != NULL) 568 if (NILP (arg))
687 g_object_unref (pixbuf); 569 result = pgtk_text_icon (f,
570 SSDATA ((!NILP (f->icon_name)
571 ? f->icon_name
572 : f->name)));
573 else
574 result = FRAME_TERMINAL (f)->set_bitmap_icon_hook (f, arg);
575
576 if (result)
577 {
578 unblock_input ();
579 error ("No icon window available");
580 }
581
582 unblock_input ();
583}
584
585
586static void
587x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
588{
589 bool result;
590
591 if (STRINGP (arg))
592 {
593 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
594 return;
595 }
596 else if (!NILP (arg) || NILP (oldval))
597 return;
598
599 fset_icon_name (f, arg);
600
601 block_input ();
602
603 result = pgtk_text_icon (f,
604 SSDATA ((!NILP (f->icon_name)
605 ? f->icon_name
606 : !NILP (f->title)
607 ? f->title
608 : f->name)));
609
610 if (result)
611 {
612 unblock_input ();
613 error ("No icon window available");
614 }
615
616 unblock_input ();
688} 617}
689 618
690/* This is the same as the xfns.c definition. */ 619/* 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
800 } 729 }
801} 730}
802 731
732/* Set icon from FILE for frame F. By using GTK functions the icon
733 may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
734
735bool
736xg_set_icon (struct frame *f, Lisp_Object file)
737{
738 bool result = false;
739 Lisp_Object found;
740
741 found = image_find_image_file (file);
742
743 if (! NILP (found))
744 {
745 GdkPixbuf *pixbuf;
746 GError *err = NULL;
747 char *filename = SSDATA (ENCODE_FILE (found));
748 block_input ();
749
750 pixbuf = gdk_pixbuf_new_from_file (filename, &err);
751
752 if (pixbuf)
753 {
754 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
755 pixbuf);
756 g_object_unref (pixbuf);
757
758 result = true;
759 }
760 else
761 g_error_free (err);
762
763 unblock_input ();
764 }
765
766 return result;
767}
768
769bool
770xg_set_icon_from_xpm_data (struct frame *f, const char **data)
771{
772 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data (data);
773
774 if (!pixbuf)
775 return false;
776
777 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
778 g_object_unref (pixbuf);
779 return true;
780}
781
803static void 782static void
804pgtk_set_sticky (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) 783pgtk_set_sticky (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
805{ 784{
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index 65d250b6def..2d1a990483f 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -2827,6 +2827,47 @@ pgtk_scroll_run (struct window *w, struct run *run)
2827 unblock_input (); 2827 unblock_input ();
2828} 2828}
2829 2829
2830/* Icons. */
2831
2832/* Make the x-window of frame F use the gnu icon bitmap. */
2833
2834static bool
2835pgtk_bitmap_icon (struct frame *f, Lisp_Object file)
2836{
2837 if (FRAME_GTK_WIDGET (f) == 0)
2838 return true;
2839
2840 if (STRINGP (file))
2841 {
2842 /* Use gtk_window_set_icon_from_file () if available,
2843 It's not restricted to bitmaps */
2844 if (xg_set_icon (f, file))
2845 return false;
2846
2847 return true;
2848 }
2849
2850 if (xg_set_icon (f, xg_default_icon_file))
2851 {
2852 return false;
2853 }
2854
2855 return true;
2856}
2857
2858
2859/* Make the x-window of frame F use a rectangle with text.
2860 Use ICON_NAME as the text. */
2861
2862bool
2863pgtk_text_icon (struct frame *f, const char *icon_name)
2864{
2865 gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), NULL);
2866 gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), icon_name);
2867
2868 return false;
2869}
2870
2830/*********************************************************************** 2871/***********************************************************************
2831 Starting and ending an update 2872 Starting and ending an update
2832 ***********************************************************************/ 2873 ***********************************************************************/
@@ -4620,6 +4661,7 @@ pgtk_create_terminal (struct pgtk_display_info *dpyinfo)
4620 terminal->query_frame_background_color = pgtk_query_frame_background_color; 4661 terminal->query_frame_background_color = pgtk_query_frame_background_color;
4621 terminal->defined_color_hook = pgtk_defined_color; 4662 terminal->defined_color_hook = pgtk_defined_color;
4622 terminal->set_new_font_hook = pgtk_new_font; 4663 terminal->set_new_font_hook = pgtk_new_font;
4664 terminal->set_bitmap_icon_hook = pgtk_bitmap_icon;
4623 terminal->implicit_set_name_hook = pgtk_implicitly_set_name; 4665 terminal->implicit_set_name_hook = pgtk_implicitly_set_name;
4624 terminal->iconify_frame_hook = pgtk_iconify_frame; 4666 terminal->iconify_frame_hook = pgtk_iconify_frame;
4625 terminal->set_scroll_bar_default_width_hook = pgtk_set_scroll_bar_default_width; 4667 terminal->set_scroll_bar_default_width_hook = pgtk_set_scroll_bar_default_width;
diff --git a/src/pgtkterm.h b/src/pgtkterm.h
index e7403184393..706198aa8a4 100644
--- a/src/pgtkterm.h
+++ b/src/pgtkterm.h
@@ -621,4 +621,9 @@ extern bool pgtk_im_filter_keypress(struct frame *f, GdkEventKey *ev);
621extern void pgtk_im_init(struct pgtk_display_info *dpyinfo); 621extern void pgtk_im_init(struct pgtk_display_info *dpyinfo);
622extern void pgtk_im_finish(struct pgtk_display_info *dpyinfo); 622extern void pgtk_im_finish(struct pgtk_display_info *dpyinfo);
623 623
624extern bool xg_set_icon (struct frame *, Lisp_Object);
625extern bool xg_set_icon_from_xpm_data (struct frame *f, const char **data);
626
627extern bool pgtk_text_icon (struct frame *f, const char *icon_name);
628
624#endif /* HAVE_PGTK */ 629#endif /* HAVE_PGTK */